/* Chrysalide - Outil d'analyse de fichiers binaires * io.c - entrées sorties fiables * * Copyright (C) 2014 Cyrille Bagard * * This file is part of Chrysalide. * * Chrysalide is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Chrysalide is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Foobar. If not, see . */ #include "io.h" #include #include #include #include #include #include #include #include /****************************************************************************** * * * Paramètres : sockfd = flux ouvert en lecture. * * buf = données à recevoir. * * len = quantité de ces données. * * flags = options de réception. * * * * Description : Réceptionne des données depuis un flux réseau. * * * * Retour : true si toutes les données ont été reçues, false sinon. * * * * Remarques : - * * * ******************************************************************************/ bool safe_recv(int sockfd, const void *buf, size_t len, int flags) { uint8_t *iter; /* Données en attente */ size_t remaining; /* Quantité restante */ ssize_t got; /* Données envoyées */ iter = (uint8_t *)buf; remaining = len; while (remaining > 0) { got = recv(sockfd, iter, remaining, MSG_NOSIGNAL | flags); if (got == -1) { if (errno == EINTR) continue; else { perror("recv"); break; } } iter += got; remaining -= got; } return (remaining == 0); } /****************************************************************************** * * * Paramètres : sockfd = flux ouvert en écriture. * * buf = données à émettre. * * len = quantité de ces données. * * flags = options d'envoi. * * * * Description : Envoie des données au travers un flux réseau. * * * * Retour : true si toutes les données ont été émises, false sinon. * * * * Remarques : - * * * ******************************************************************************/ bool safe_send(int sockfd, const void *buf, size_t len, int flags) { uint8_t *iter; /* Données en attente */ size_t remaining; /* Quantité restante */ ssize_t sent; /* Données envoyées */ iter = (uint8_t *)buf; remaining = len; while (remaining > 0) { sent = send(sockfd, iter, remaining, MSG_NOSIGNAL | flags); if (sent == -1) { if (errno == EINTR) continue; else { perror("send"); break; } } iter += sent; remaining -= sent; } return (remaining == 0); } /****************************************************************************** * * * Paramètres : path = chemin d'accès à valider. * * * * Description : S'assure qu'un chemin donné existe dans le système. * * * * Retour : 0 si le chemin est actuellement présent, -1 sinon. * * * * Remarques : - * * * ******************************************************************************/ int ensure_path_exists(const char *path) { int result; /* Bilan de l'assurance */ char *copy; /* Chemin libérable */ char *tmp; /* Chemin altérable */ copy = strdup(path); tmp = dirname(copy); result = access(tmp, W_OK | X_OK); if (result != 0) { result = ensure_path_exists(tmp); if (result == 0) result = mkdir(tmp, 0700); } free(copy); return result; }