commit b41a8d304f162f698b6e6617e8fcbeb6c53ddfdc Author: xdrm-brackets Date: Tue Mar 28 18:45:18 2017 +0200 First commit Import diff --git a/central-manager/central-manager.c b/central-manager/central-manager.c new file mode 100644 index 0000000..cb1ced5 --- /dev/null +++ b/central-manager/central-manager.c @@ -0,0 +1,196 @@ +#include "central-manager.h" + + + + +/* +* +* @history +* [0] Initialisation des variables +* [1] On démarre le SERVEUR d'écoute globale +* [2] Attente d'une demande de connection, puis création d'un THREAD +* [3] On attends la fin de tous les THREADS +* [4] On ferme la SOCKET d'écoute globale +* +*/ +int main(int argc, char* argv[]){ + /* [0] Initialisation des variables + ==========================================================*/ + int THREADABLE_SOCKET = -1; // contiendra le BUS DE COMMANDE utilisateur à envoyer à un THREAD + struct sockaddr_storage clientInfo; // contiendra les infos client + char repeat; // sert à sortir de la boucle + socklen_t len = sizeof(struct sockaddr_storage); + + // retour de @DROP_SERVER + char* serverPort; // contiendra le port + int LISTENSOCK; // contiendra la socket d'écoute + + + /* [1] On démarre le SERVEUR d'écoute globale + ==========================================================*/ + serverPort = malloc(maxPortLen); + + // attribution du port si dans les arguments + if( argc > 1 ) strcpy(serverPort, argv[1]); + + DROP_SERVER(remoteHost, &serverPort, &LISTENSOCK); + printf("Port: %s\n", serverPort); + + + + /* [2] Attente d'une demande de connection, puis création d'un THREAD + ============================================================================*/ + int index = -1; + while( 1 ){ + /* 1. On initialise la SOCKET en attendant la connexion et le rang du "manager" inactif */ + THREADABLE_SOCKET = -1; + index = -1; + + /* 2. On attends une connection */ + THREADABLE_SOCKET = accept(LISTENSOCK, (struct sockaddr *) &clientInfo, &len); + + /* 3. On cherche un "manager" libre */ + int i; + + // si on trouve un "manager" inactif, on l'enregistre dans index + for( i = 0 ; i < maxListLen ; i++ ) + if( activeManagers[i] == 0 ){ index = i; break; } + + // si on a trouvé un "manager" libre + if( index != -1 ){ + + /* 4. On lance un thread pour le traitement de ce client */ + pthread_create(&managers[index], NULL, manageConnection, (void*)(intptr_t) THREADABLE_SOCKET); + if( DEBUGMOD&THR ) printf("THREAD[%d] démarré\n", index); + + /* 5. On signale que ce "manager" est maintenant actif */ + activeManagers[index] = 1; + }else + if( DEBUGMOD&THR ) printf("Demande de thread refusée!\n"); + } + + + /* [3] On attends la fin de tous les THREADS + ==========================================================*/ + int i; + for( i = 0 ; i < maxListLen ; i++ ) + pthread_join(managers[i], NULL); + + /* [4] On ferme la SOCKET d'écoute globale + ==========================================================*/ + printf("FERMETURE DE TOUTES LES CONNECTIONS!\n"); + close(LISTENSOCK); +} + + + + + + + + + + + +/* Gestion d'une connexion client +* +* @THREADABLE_SOCKET SOCKET de la connexion client +* +* @history +* [1] Initialisation des variables +* [2] Envoi de la séquence de bienvenue +* [3] Attente des données reçues et reception (CLIENT_FTP->PROXY) +* [4] Traitement de la requête client +* [5] Redirection de la requête vers le serveur FTP (PROXY->SERVER_FTP) +* [6] Traitement de la reponse du serveur FTP +* [7] Redirection de la réponse vers le client (PROXY->CLIENT_FTP) +* [8] On vide les buffers +* [9] Fermeture des connections (SOCKETS) +* [10] Arrêt du THREAD +* 1. On récupère le rang dans les "managers" +* 2. On met à jour "activeManagers" +* 3. On arrête le THREAD +* +*/ +void* manageConnection(void* THREADABLE_SOCKET){ + int USER_SOCKET = (intptr_t) THREADABLE_SOCKET; // BUS DE COMMANDE utilisateur + + /* [1] Variables + ============================================================================*/ + // int USER_SOCKET = -1; + int FTP_SOCKET = -1; // contiendra le BUS DE COMMANDE FTP + int DUSER_SOCKET = -1; // contiendra le BUS DE DONNES utilisateur + int DFTP_SOCKET = -1; // contiendra le BUS DE DONNEES FTP + + char* BUFFER; // contiendra le BUFFER + char* ftp_response; // contiendra le BUFFER de réponse du serveur FTP (commandes) + int nbReceived, nbSend; // contiendra les nb reçu && envoyé + BUFFER = malloc( maxBuffLen ); + int error; + + /* [2] Envoi de la séquence de bienvenue + ============================================================================*/ + swrite(&USER_SOCKET, WLCM_MSG); + + /* BOUCLE DE COMMANDES */ + while( USER_SOCKET != -1 ){ + + /* [3] On récupère les données reçues (+attente) + ============================================================================*/ + if( WAIT_SOCKET_UPDATE(&USER_SOCKET, BUFFER) == -1 ) break; + if( DEBUGMOD&CMD ) xPrint("C->P: %s\n", BUFFER); + + + /* [4] Traitement de la requête + ============================================================================*/ + error = MANAGE_REQUEST(BUFFER, &USER_SOCKET, &FTP_SOCKET, &DUSER_SOCKET, &DFTP_SOCKET); + + // si on a pas la connection FTP (commande) initialisée, on quitte + if( error == -1 ) break; + + + /* [5] Redirection vers le serveur FTP + ============================================================================*/ + if( DEBUGMOD&CMD ) xPrint("P->F: %s\n\n", BUFFER); + CLIENT_SEND(&FTP_SOCKET, BUFFER, &BUFFER); + if( DEBUGMOD&CMD ) xPrint("F->P: %s\n", BUFFER); + + /* [6] Traitement de la réponse (FTP) + ============================================================================*/ + MANAGE_RESPONSE(BUFFER, &USER_SOCKET, &FTP_SOCKET, &DUSER_SOCKET, &DFTP_SOCKET); + + + + /* [7] Redirection vers le CLIENT + ============================================================================*/ + if( swrite(&USER_SOCKET, BUFFER) == -1 ) break; + if( DEBUGMOD&CMD ) xPrint("P->C: %s\n", BUFFER); + + + /* [8] On vide les buffers + ============================================================================*/ + memset(BUFFER, '\0', maxBuffLen); // on vide le buffer + memset(BUFFER, '\0', maxBuffLen); + } + + /* [9] Fermeture des connections (SOCKETS) + ============================================================================*/ + printf("CLOSING CONNECTIONS\n"); + close(USER_SOCKET); + close(FTP_SOCKET); + + /* [10] Arrêt du THREAD + ============================================================================*/ + /* 1. On récupère le rang dans les "managers" */ + int i, index = -1; + for( i = 0 ; i < maxListLen ; i++ ) + if( managers[i] == pthread_self() ){ index = i; break; } + + /* 2. On met à jour "activeManagers" */ + if( index != -1 ) + activeManagers[index] = 0; + + /* 3. On arrête le THREAD */ + if( DEBUGMOD&THR ) printf("THREAD[%d] libéré\n", index); + pthread_exit(NULL); +} diff --git a/central-manager/central-manager.h b/central-manager/central-manager.h new file mode 100644 index 0000000..f40d1e8 --- /dev/null +++ b/central-manager/central-manager.h @@ -0,0 +1,57 @@ +/* global */ +#include +#include +#include +#include +#include + +/* sys */ +#include +#include + +/* socket */ +#include +#include // getaddrinfo, getnameinfo +#include + + +/* debug */ +#define SOCKETS 0x01 // debug RESEAU +#define COMMANDS 0x02 // debug COMMANDES +#define DATA 0x04 // debug DONNEES +#define REVEALS 0x08 // debug EXPLICITATION des strings +#define BUFFERS 0x10 // debug des BUFFERS +#define HEADERS 0x20 // debug des HEADERS de fonctions +#define THREADS 0x40 // debug des THREADS + +#define SCK 0x01 // FILTRE pour SOCKET +#define CMD 0x02 // FILTRE pour COMMAND +#define DAT 0x04 // FILTRE pour DATA +#define RVL 0x08 // FILTRE pour REVEALS +#define BUF 0x10 // FILTRE pour BUFFERS +#define HDR 0x20 // FILTRE pour HEADERS +#define THR 0x40 // FILTRE pour THREADS + +// possibilité de cumuler les DEBUGMODES +#define DEBUGMOD SOCKETS + THREADS // REVEALS + HEADER + THREADS + + +/* vars */ +#define remoteHost "localhost" +#define remotePort "80" +#define maxBuffLen 4096 +#define maxListLen 10 +#define maxHostLen 64 +#define maxPortLen 6 + +/* local dependencies */ +#include "dep/utility.c" +#include "dep/server.c" + + +/* headers */ +void* manageConnection(void* THREADABLE_SOCKET); + +// VARIABLES +static pthread_t managers[maxListLen]; // contiendra les THREADS +static int activeManagers[maxListLen] = {0}; // contiendra les THREADS actifs diff --git a/central-manager/dep/server.c b/central-manager/dep/server.c new file mode 100644 index 0000000..137e99c --- /dev/null +++ b/central-manager/dep/server.c @@ -0,0 +1,430 @@ +#include "server.h" + + + + + + + +void DROP_SERVER(const char* serverHost, char** givenPort, int* listenSocket){ + if( DEBUGMOD&HDR ) printf("====== DROP_SERVER(%s, %s, %d) ======\n\n", serverHost, *givenPort, *listenSocket); + + // FONCTIONNEMENT + struct addrinfo hints; // contiendra le filtre/format + struct addrinfo* addrinfo; // contiendra les infos du serveur + int SOCKET, BIND, LISTEN; // file_desc(s) + + // INFOS + struct sockaddr_storage serverInfo; // contiendra les informations du server + socklen_t sockaddr_len = sizeof(struct sockaddr_storage); + char infoHost[maxHostLen]; // contiendra l'adresse du server + char infoPort[maxPortLen]; // contiendra le port du server + + /* [1] On définit le filtre/format + =======================================================*/ + memset(&hints, 0, sizeof(struct addrinfo)); // on vide le filtre + hints.ai_family = AF_UNSPEC; // Allow IPv4 ou IPv6 + hints.ai_socktype = SOCK_STREAM; // TCP (SOCK_DGRAM = UDP) + hints.ai_flags = AI_PASSIVE; // mode SERVER + hints.ai_protocol = 0; // non spécifié + + if( DEBUGMOD&SCK ) printf("============HINTS===========\n"); + if( DEBUGMOD&SCK ) printf( "AI_FLAGS = %d\n", hints.ai_flags ); // int + if( DEBUGMOD&SCK ) printf( "AI_FAMILY = %d\n", hints.ai_family ); // int + if( DEBUGMOD&SCK ) printf( "AI_SOCKTYPE = %d\n", hints.ai_socktype ); // int + if( DEBUGMOD&SCK ) printf( "AI_PROTOCOL = %d\n", hints.ai_protocol ); // int + if( DEBUGMOD&SCK ) printf( "AI_ADDRLEN = %d\n", hints.ai_addrlen ); // int + if( DEBUGMOD&SCK ) printf("\n"); + + + /* [2] On récupère les infos + =======================================================*/ + if( strlen(*givenPort) == 0 ) // si pas défini, port dynamique + getaddrinfo(serverHost, 0, &hints, &addrinfo); + else // sinon manuel + getaddrinfo(serverHost, *givenPort, &hints, &addrinfo); + // Remarque: port=0 donc va être défini dynamiquement + + if( DEBUGMOD&SCK ) printf("=============RES============\n"); + if( DEBUGMOD&SCK ) printf( "AI_FLAGS = %d\n", addrinfo->ai_flags ); // int + if( DEBUGMOD&SCK ) printf( "AI_FAMILY = %d\n", addrinfo->ai_family ); // int + if( DEBUGMOD&SCK ) printf( "AI_SOCKTYPE = %d\n", addrinfo->ai_socktype ); // int + if( DEBUGMOD&SCK ) printf( "AI_PROTOCOL = %d\n", addrinfo->ai_protocol ); // int + if( DEBUGMOD&SCK ) printf( "AI_ADDRLEN = %d\n", addrinfo->ai_addrlen ); // int + if( DEBUGMOD&SCK ) printf("\n"); + + /* [3] Création de la socket + =======================================================*/ + + SOCKET = socket(addrinfo->ai_family, addrinfo->ai_socktype, 0); + + if( DEBUGMOD&SCK ) printf("SOCKET = %d\n", SOCKET); + + // si erreur + if( SOCKET == -1 ) return; + + + /* [4] On publie la SOCKET + =======================================================*/ + BIND = bind( + SOCKET, + addrinfo->ai_addr, + addrinfo->ai_addrlen + ); + + if( DEBUGMOD&SCK ) printf("BIND = %d\n", BIND); + + // si erreur + if( BIND == -1 ) return; + + /* [5] On récupère les informations du serveur (host/port) + =======================================================*/ + int getInfo = getsockname(SOCKET, (struct sockaddr *) &serverInfo, &sockaddr_len); + + if( getInfo == -1 ) return; + + getInfo = getnameinfo( // on récupère le host et le port + (struct sockaddr *) &serverInfo, + sizeof(serverInfo), + infoHost, maxHostLen, + infoPort, maxPortLen, + NI_NUMERICHOST | NI_NUMERICSERV + ); + + if( getInfo == -1 ) return; + + if( DEBUGMOD&SCK ) printf("Server host: %s\n", infoHost); + if( DEBUGMOD&SCK ) printf("Server port: %s\n", infoPort); + + + // on a plus besoin des infos de l'adresse + freeaddrinfo(addrinfo); + + + /* [6] On met la socket sur écoute + =======================================================*/ + LISTEN = listen(SOCKET, maxListLen); + + if( DEBUGMOD&SCK ) printf("LISTEN = %d\n", LISTEN); + + // si erreur + if( LISTEN == -1 ) return; + + /* [7] On envoie les données par référence + =======================================================*/ + // port + *givenPort = malloc( maxPortLen ); + strcpy(*givenPort, infoPort); + + // socket d'écoute + *listenSocket = SOCKET; +} + + + + + + + + + +int MANAGE_REQUEST(char* pRequest, int* USER_SOCKET, int* FTP_SOCKET, int* DUSER_SOCKET, int* DFTP_SOCKET){ + if( DEBUGMOD&HDR ) printf("====== MANAGE_REQUEST(%s, %d, %d, %d, %d) ======\n\n", pRequest, *USER_SOCKET, *FTP_SOCKET, *DUSER_SOCKET, *DFTP_SOCKET); + + + char response[maxBuffLen]; // contiendra la réponse (2*taille buffer pour strcat(BUFLEN, BUFLEN)) + int nbSend; // contiendra le nombre de données envoyées + char rCommand[5]; // contiendra les commandes (1ère partie) + char rContent[maxBuffLen]; // contiendra le contenu associé à la commande (2ème partie) + + // on vide les buffers + memset(&rCommand, '\0', sizeof(rCommand)); + memset(&rContent, '\0', sizeof(rContent)); + memset(&response, '\0', sizeof(response)); + + + /* [1] On découpe la requête en 2 parties + ================================================*/ + splitFtpRequest(pRequest, rCommand, rContent); + + + /* [2] Selection en fonction de @rCommand + ================================================*/ + + /* (1) USER username@serveur => connection FTP (commande) + --------------------------------------------*/ + if( strcmp(rCommand, "USER") == 0 && indexOf(rContent, '@') >= 0 ){ + char userName[100] = {0}; + char hostName[maxHostLen] = {0}; + // pour l'envoi de la séquence d'initialisation + char* ftp_response; ftp_response = malloc(maxBuffLen); + memset(ftp_response, 0, maxBuffLen); + + /* 1. On extrait @username et @hostname */ + sscanf(rContent, "%[^@]@%s\r\n", userName, hostName); + + if( DEBUGMOD&BUF ) printf("USERNAME [[%s]]\n", userName); + if( DEBUGMOD&BUF ) printf("HOSTNAME [[%s]]\n", hostName); + + + /* 2. On se connecte au serveur FTP (commandes) */ + int error = CONNECT_CLIENT(hostName, FTP_PORT, FTP_SOCKET); + + if( error == -1 || *FTP_SOCKET == -1 ){ // si erreur + printf("Impossible de se connecter au serveur (%s:%s)\n", hostName, FTP_PORT); + strcpy(pRequest, "421 ERREUR: impossible de se connecter au serveur!!\r\n"); + return -1; + } + + if( DEBUGMOD&SCK ) printf("FTP SOCKET CONNECTED AT %s:%s\n", hostName, FTP_PORT); + + + /* 3. On envoie la séquence d'initialisation */ + CLIENT_SEND(FTP_SOCKET, "", &ftp_response); + + if( DEBUGMOD&CMD ) xPrint("P->F: %s\n\n", "\r\n"); + if( DEBUGMOD&CMD ) xPrint("F->P: %s\n", ftp_response); + + + /* 4. On envoie la requête USER au serveur FTP auquel on vient de se connecter */ + char newRequest[maxBuffLen]; + strcat(newRequest, "USER "); + strcat(newRequest, userName); + strcat(newRequest, "\r\n"); + strcpy(response, "USER xdrm\r\n"); + } + + else if( strcmp(rCommand, "USER") == 0 ) // si oubli serveur + strcpy(response, "421 'username@FTPserver' attendu\n"); + + /* (2) PORT a1,a2,a3,a4,p1,p2 => utilisateur (actif) + --------------------------------------------*/ + else if( strcmp(rCommand, "PORT") == 0 ){ + int a1, a2, a3, a4 = 0; + int p1, p2 = 0; + + char serverHost[maxHostLen] = {0}; + char serverPort[maxPortLen] = {0}; + char BUFFER[maxBuffLen] = {0}; + + /* 1. On récupère l'ip et le port de la réponse */ + sscanf(pRequest, "PORT %d,%d,%d,%d,%d,%d", &a1, &a2, &a3, &a4, &p1, &p2); + // on récupère l'adresse en + sprintf(serverHost, "%d.%d.%d.%d", a1, a2, a3, a4); + // on récupère le port en + sprintf(serverPort, "%d", p1*256+p2); + + + /* 2. On se connecte au client */ + if( DEBUGMOD&SCK ) printf("CONNECTING TO CLIENT %s:%s\n", serverHost, serverPort); + CONNECT_CLIENT(serverHost, serverPort, DUSER_SOCKET); + if( DEBUGMOD&SCK ) printf("CONNECTED TO CLIENT %s:%s\n", serverHost, serverPort); + + /* 3. Envoi de "PASV" car on veut être en mode passif entre le proxy et le serveur FTP */ + strcpy(response, "PASV\r\n"); + } + + /* (n) Si aucun traitement on recopie la requête telquel + --------------------------------------------*/ + else + strcpy(response, pRequest); + + /* [3] Retour de la réponse + ================================================*/ + strcpy(pRequest, response); + printf("RESP: %s\n", pRequest); + + + return 0; +} + + + +void MANAGE_RESPONSE(char* pAnswer, int* USER_SOCKET, int* FTP_SOCKET, int* DUSER_SOCKET, int* DFTP_SOCKET){ + if( DEBUGMOD&HDR ) printf("====== MANAGE_RESPONSE(%s, %d, %d, %d, %d) ======\n\n", pAnswer, *USER_SOCKET, *FTP_SOCKET, *DUSER_SOCKET, *DFTP_SOCKET); + + char response[maxBuffLen]; // contiendra la réponse + char ftpCodeStr[4]; // contiendra le code FTP (1ère partie) + char ftpText[maxBuffLen]; // contiendra le texte associé à la commande (2ème partie) + int ftpCode; // contiendra le code FTP en numérique + + // on vide les buffers + memset(&ftpCodeStr, '\0', sizeof(ftpCode)); + memset(&ftpText, '\0', sizeof(ftpText)); + memset(&response, '\0', sizeof(response)); + + + /* [1] On découpe la requête en 2 parties + ================================================*/ + splitFtpResponse(pAnswer, ftpCodeStr, ftpText); + + // on met le code FTP en + ftpCode = atoi( ftpCodeStr ); + + // mise à disposition de variables temporaires + int tmp[6] = {0}; + char serverHost[maxHostLen]; + char serverPort[maxPortLen]; + char BUFFER[maxBuffLen] = {0}; + + /* [2] Selection en fonction de @ftpCode + ================================================*/ + switch(ftpCode){ + /* (1) Demande d'username + --------------------------------------------*/ + case 220: + strcpy(response, WLCM_MSG); + break; + + /* (2) username OK -> demande MDP + --------------------------------------------*/ + case 331: + strcpy(response, USER_MSG); + break; + + /* (3) Bon mdp -> connection + --------------------------------------------*/ + case 230: + strcpy(response, PASS_BON_MSG); + break; + + /* (4) Mauvais mdp -> message erreur + --------------------------------------------*/ + case 530: + strcpy(response, PASS_BAD_MSG); + break; + + /* (5) Info SYST + --------------------------------------------*/ + // case 215: + // strcpy(response, "bla\n"); + // break; + + + /* (6) LOGOUT => EXIT + --------------------------------------------*/ + case 221: + strcpy(response, EXIT_MSG); + break; + + + /* (7) Mode passif => On lance les SOCKETS du BUS DE DONNEES + --------------------------------------------*/ + case 227: // on lance la SOCKET FTP du BUS DE DONNEES + + /* 1. On récupère l'ip et le port de la réponse */ + sscanf(pAnswer, "227 Entering Passive Mode (%d,%d,%d,%d,%d,%d)", &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5]); + // on récupère l'adresse en + sprintf(serverHost, "%d.%d.%d.%d", tmp[0], tmp[1], tmp[2], tmp[3]); + // on récupère le port en + sprintf(serverPort, "%d", tmp[4]*256+tmp[5]); + + /* 2. Connexion au serveur FTP */ + if( DEBUGMOD&SCK ) printf("CONNECTING TO FTP %s:%s\n", serverHost, serverPort); + CONNECT_CLIENT(serverHost, serverPort, DFTP_SOCKET); + if( DEBUGMOD&SCK ) printf("CONNECTED TO FTP %s:%s\n", serverHost, serverPort); + + /* 3. Envoi du message de code 200 */ + strcpy(response, LIST_DAT_MSG); + break; + + + /* (8) On lit la SOCKET FTP du BUS DE DONNEES + --------------------------------------------*/ + case 150: + + /* 1. Envoi au client de l'écoute de la réponse (associée) du BUS DE DONNEES */ + // sread(FTP_SOCKET, BUFFER); + // if( DEBUGMOD&CMD ) xPrint("F->P: %s\n", BUFFER); + swrite(USER_SOCKET, READ_CON_MSG); + if( DEBUGMOD&CMD ) xPrint("P->C: %s\n", READ_CON_MSG); + + + /* 2. On lit la SOCKET FTP (BUS DE DONNEES) */ + tmp[0] = WAIT_SOCKET_UPDATE(DFTP_SOCKET, BUFFER); + + if( DEBUGMOD&DAT && tmp[0] == -1 ) printf("ERROR\n"); + else if( DEBUGMOD&DAT ) xPrint("[BUS_IN]: %s\n", BUFFER); + + + /* 3. On redirige sur la SOCKET utilisateur (BUS DE DONNEES) */ + tmp[1] = swrite(DUSER_SOCKET, BUFFER); + + if( DEBUGMOD&DAT && tmp[1] == -1 ) printf("ERROR\n"); + else if( DEBUGMOD&DAT ) xPrint("[BUS_OUT]: %s\n", BUFFER); + + if( DEBUGMOD&DAT ) xPrint("BUS_FTP->BUS_CLIENT: %s\n", BUFFER); + + + /* 4. On ferme les SOCKETS du BUS DE DONNEES */ + close(*DFTP_SOCKET); + if( DEBUGMOD&CMD ) printf("BUS_FTP fermé (%d)\n", *DFTP_SOCKET); + close(*DUSER_SOCKET); + if( DEBUGMOD&CMD ) printf("BUS_USER fermé (%d)\n", *DUSER_SOCKET); + + + // on vide les SOCKET FTP des 2 BUS + // WAIT_SOCKET_UPDATE(FTP_SOCKET, BUFFER); // command + // WAIT_SOCKET_UPDATE(DFTP_SOCKET, BUFFER); // données + // printf("") + + /* 5. On vide le BUS DE COMMANDE du serveur FTP */ + /* A. On définit un TIMEOUT (1 sec) */ + setSocketTimeout(FTP_SOCKET, 0, 50); + + /* B. On attends une réponse */ + tmp[2] = sread(FTP_SOCKET, BUFFER); + + /* C. On enlève le TIMEOUT (default) */ + setSocketTimeout(FTP_SOCKET, SOCKET_TIMEOUT); + + + /* 6. On transmet le message de fin de la transaction (226) */ + strcpy(response, STOP_DAT_MSG); + break; + + + /* (9) Fin de transfert de données (fermeture SOCKETS du BUS DE DONNEES) + --------------------------------------------*/ + case 226: + strcpy(response, "226 Fin de la transaction!\r\n"); + close(*DUSER_SOCKET); + close(*DFTP_SOCKET); + break; + + /* (n) Commande inconnue + --------------------------------------------*/ + default: + strcpy(response, pAnswer); + break; + } + + /* [3] Retour de la réponse + ================================================*/ + strcpy(pAnswer, response); +} + + + + + +int WAIT_SOCKET_UPDATE(int* pSocket, char* pBuffer){ + memset(pBuffer, 0, maxBuffLen); // on vide le buffer + + int nbRead = 0; + + do{ + nbRead = sread(pSocket, pBuffer); + + // si on est déconnecté, on renvoie une erreur + if( nbRead == -1 ){ + printf("Client déconnecté!\n"); + return -1; + } + + }while( pBuffer[nbRead-1] != '\n' && pBuffer[nbRead-2] != '\r' ); + + + // on retourne -1 si erreur, SINON 0 + return nbRead; +} \ No newline at end of file diff --git a/central-manager/dep/server.h b/central-manager/dep/server.h new file mode 100644 index 0000000..58d7184 --- /dev/null +++ b/central-manager/dep/server.h @@ -0,0 +1,123 @@ +/* Créé et met un serveur sur écoute +* +* ==IN== +* @serverHost Nom de l'hôte local (localhost) +* @givenPort Si renseigné, définit le port à utiliser +* +* ==OUT== +* @givenPort Pointeur sur le à remplir => contiendra le port donné par le système (si pas renseigné en entrée) +* @listenSocket Pointeur sur le à remplir => contiendra un pointeur sur la socket d'écoute +* +* +* +* @history +* [1] On définit le filtre/format +* [2] On récupère les infos (adresse, port) +* Note: Gestion IPv4/IPv6 +* [3] Création de la socket +* [4] On publie la SOCKET (bind) +* [5] On récupère les informations du serveur (host/port) +* [6] On met la socket sur écoute (listen) +* [7] On envoie les données par référence +* +*/ +void DROP_SERVER(const char* serverHost, char** givenPort, int* listenSocket); + + + +/* Gestion de la requête du client +* ==IN/OUT== +* @pBuffer Requête en question +* @USER_SOCKET Pointeur sur la SOCKET du BUS DE COMMANDES utilisateur +* @FTP_SOCKET Pointeur sur la SOCKET du BUS DE COMMANDES FTP +* @DUSER_SOCKET Pointeur sur la SOCKET du BUS DE DONNEES utilisateur +* @DFTP_SOCKET Pointeur sur la SOCKET du BUS DE DONNEES FTP +* +* +* +* @history +* [1] On découpe la requête en 2 parties (rCommand, rContent) +* [2] Selection en fonction de @rCommand +* (1) USER username@serveur => connection FTP (commande) +* 1. On extrait @username et @hostname +* 2. On se connecte au serveur FTP (commandes) +* 3. On envoie la séquence d'initialisation +* 4. On envoie la requête USER au serveur FTP auquel on vient de se connecter +* +* (2) PORT a1,a2,a3,a4,p1,p2 => utilisateur (actif) +* 1. On récupère l'ip et le port de la requête +* 2. On se connecte au client +* 3. Envoi de "PASV" car on veut être en mode passif entre le proxy et le serveur FTP +* (n) Si aucun traitement on recopie la requête telquel +* +* [3] Retour de la réponse +* +*/ +int MANAGE_REQUEST(char* pRequest, int* USER_SOCKET, int* FTP_SOCKET, int* DUSER_SOCKET, int* DFTP_SOCKET); + + + + + +/* Gestion de la réponse du serveur FTP et modification de la réponse +* +* @pAnswer Pointeur sur le buffer de réponse du serveur FTP +* @USER_SOCKET Pointeur sur la SOCKET du BUS DE COMMANDES utilisateur +* @FTP_SOCKET Pointeur sur la SOCKET du BUS DE COMMANDES FTP +* @DUSER_SOCKET Pointeur sur la SOCKET du BUS DE DONNEES utilisateur +* @DFTP_SOCKET Pointeur sur la SOCKET du BUS DE DONNEES FTP +* +* +* +* @history +* [1] On découpe la requête en 2 parties (ftpCode, ftpText) +* [2] Selection en fonction de @ftpCode +* (1) 220- Demande d'username +* (2) 331- username OK -> demande MDP +* (3) 230- Bon mdp -> connection +* (4) 530- Mauvais mdp -> message erreur +* (5) 215- Info SYST [COMMENTÉ] +* (6) 221- LOGOUT => EXIT (commande QUIT) +* (7) 227- Mode passif => On lance les SOCKETS du BUS DE DONNEES +* 1. On récupère l'ip et le port de la réponse +* 2. Connexion au serveur FTP +* 3. Envoi du message de code 200 +* +* (8) 150- On lit la SOCKET FTP du BUS DE DONNEES +* 1. Envoi au client de l'écoute de la réponse (associée) du BUS DE DONNEES +* 2. On lit la SOCKET FTP (BUS DE DONNEES) +* 3. On redirige sur la SOCKET utilisateur (BUS DE DONNEES) +* 4. On ferme les SOCKETS du BUS DE DONNEES +* 5. On vide le BUS DE COMMANDE du serveur FTP +* A. On définit un TIMEOUT (1 sec +* B. On attends une réponse +* C. On enlève le TIMEOUT (default) +* 6. On transmet le message de fin de la transaction (226) +* +* (9) 226- Fin de transfert de données (fermeture SOCKETS du BUS DE DONNEES) +* (n) xxx- Commande inconnue +* +* [3] Retour de la réponse +*/ +void MANAGE_RESPONSE(char* pAnswer, int* USER_SOCKET, int* FTP_SOCKET, int* DUSER_SOCKET, int* DFTP_SOCKET); + + + + + +/* Attends une réponse du client +* +* @pSocket Pointeur sur la SOCKET en question +* @pBuffer Buffer qui contiendra la réponse +* +* @return nbRead On retourne le nombre de char lus, sinon -1 si erreur +* +* +* +* @history +* [1] On read() tant qu'on a pas les symboles de fin "\r\n" +* [2] On écrit sur le BUFFER +* [3] Si une erreur se produit, on retourne -1 +* +*/ +int WAIT_CLIENT(int* pSocket, char* pBuffer); \ No newline at end of file diff --git a/central-manager/dep/utility.c b/central-manager/dep/utility.c new file mode 100644 index 0000000..faecd69 --- /dev/null +++ b/central-manager/dep/utility.c @@ -0,0 +1,169 @@ +#include "utility.h" + +void splitFtpRequest(char* pRequest, char* pCommand, char* pContent){ + /* [1] Vérification du format + ===========================================*/ + int firstSpaceIndex = indexOf(pRequest, ' '); + + if( firstSpaceIndex != 3 && firstSpaceIndex != 4){ // contient aucun espace en position 3 ou 4, on quitte + strcpy(pCommand, "ERROR"); + strcpy(pContent, ""); + return; + } + + + /* [2] Séparation des 2 parties + ===========================================*/ + int i; + + for( i = 0 ; i < strlen(pRequest) && pRequest[i] != '\0' ; i++ ){ + + if( i < firstSpaceIndex ) // première partie (pCommand) + strcat( pCommand, (char[2]){(char) pRequest[i], '\0'}); + if( i > firstSpaceIndex ) // seconde partie (pContent) + strcat( pContent, (char[2]){(char) pRequest[i], '\0'}); + } + + +} + + + + +void splitFtpResponse(char* pAnswer, char* ftpCode, char* ftpText){ + /* [1] Vérification du format + ===========================================*/ + int codeLength = 3; // taille du code + + /* [2] Séparation des 2 parties + ===========================================*/ + int i; + + for( i = 0 ; i < strlen(pAnswer) && pAnswer[i] != '\0' ; i++ ){ + + if( i < codeLength ) // première partie (ftpCode) + strcat(ftpCode, (char[2]){(char)pAnswer[i], '\0' }); + if( i > codeLength ) // seconde partie (ftpText) + strcat(ftpText, (char[2]){(char)pAnswer[i], '\0' }); + } + + +} + + + + + +int indexOf(char* haystack, char needle){ + int i; + + for( i = 0 ; i < strlen(haystack) && haystack[i] != '\0' ; i++ ) + if( haystack[i] == needle ) // si on trouve le caractère + return i; + + return -1; + +} + + +int swrite(int* pSocket, char* pBuffer){ + if( *pSocket == -1 ) return -1; // si SOCKET fermée, on retourne une erreur + if( strlen(pBuffer) == 0 ) return 0; // si on a rien à écrire, on n'écrit rien :p + + + /* 1. On écrit sur la SOCKET */ + if( DEBUGMOD&BUF ) printf("SENDLEN_1: %lu\n", strlen(pBuffer)); + int nbSent = write(*pSocket, pBuffer, strlen(pBuffer)); + if( DEBUGMOD&BUF ) printf("SENDLEN_2: %d\n", nbSent); + + /* 2. Si on est déconnecté, on retourne une erreur */ + if( nbSent <= 0 ){ + if( DEBUGMOD&BUF ) printf("NOTHING TO SEND\n"); + return -1; // on retourne une erreur + } + + if( DEBUGMOD&RVL ) printf("SEND_1\n"); + if( DEBUGMOD&RVL ) revealString(pBuffer); + if( DEBUGMOD&RVL ) printf("SEND_2\n"); + + + /* 3. On retourne le nombre de envoyés */ + return nbSent; +} + + +int sread(int* pSocket, char* pBuffer){ + if( *pSocket == -1 ) return -1; // si SOCKET fermée, on retourne une erreur + + + /* 1. On vide le buffer avant de lire */ + memset(pBuffer, '\0', maxBuffLen); + if( DEBUGMOD&BUF ) printf("READLEN_1: %lu\n", strlen(pBuffer)); + + /* 2. On lit la SOCKET */ + int nbRead = read(*pSocket, pBuffer, maxBuffLen); + if( DEBUGMOD&BUF ) printf("READLEN_3: %d\n", nbRead); + + + /* 3. Si on est déconnecté, on retourne une erreur */ + if( nbRead <= 0 ){ + if( DEBUGMOD&BUF ) printf("NOTHING TO READ\n"); + return -1; // on retourne une erreur + } + + if( DEBUGMOD&RVL ) printf("READ_1\n"); + if( DEBUGMOD&RVL ) revealString(pBuffer); + if( DEBUGMOD&RVL ) printf("READ_2\n"); + + /* 4. On retourne le nombre de caractères lus */ + return nbRead; +} + + +void setSocketTimeout(int* pSocket, const int pSec, const int pUSec){ + /* 1. On créé la structure contenant le timeout */ + struct timeval timeout; + timeout.tv_sec = pSec; + timeout.tv_usec = pUSec; + + setsockopt(*pSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(struct timeval)); + + if( DEBUGMOD&SCK ) printf("Set socket(%d) timeout to %lus\n", *pSocket, (long unsigned) timeout.tv_sec ); +} + + +void xPrint(char* pPattern, char* pBuffer){ + char tmpBuffer[maxBuffLen]; + strcpy(tmpBuffer, pBuffer); + + + int i; + + // on supprimes les retours à la ligne de la fin + for( i = strlen(tmpBuffer)-1 ; i >= 0 && tmpBuffer[i] != '\0' ; i-- ) + if( tmpBuffer[i] == '\n' || tmpBuffer[i] == '\r' ) // si c'est un retour chariot + tmpBuffer[i] = '\0'; // on efface + else + break; + + printf(pPattern, pBuffer); +} + + +void revealString(char* pString){ + /* 1. On créé une copie de @pString */ + char revealedString[maxBuffLen] = {0}; + + /* 2. On rend visible tous les caractères "invisibles" */ + int i; + for( i = 0 ; i < strlen(pString) && pString[i] != '\0' ; i++ ){ + if( pString[i] == '\r' ){ revealedString[strlen(revealedString)] = '\\'; revealedString[strlen(revealedString)] = 'r'; } + else if( pString[i] == '\n' ){ revealedString[strlen(revealedString)] = '\\'; revealedString[strlen(revealedString)] = 'n'; } + else revealedString[strlen(revealedString)] = pString[i]; + + revealedString[strlen(revealedString)] = '\0'; + } + + /* 3. On affiche la chaîne explicite */ + if( DEBUGMOD&RVL ) printf("[[%s]]\n", revealedString); +} \ No newline at end of file diff --git a/central-manager/dep/utility.h b/central-manager/dep/utility.h new file mode 100644 index 0000000..b6ef223 --- /dev/null +++ b/central-manager/dep/utility.h @@ -0,0 +1,60 @@ +/* Découpe la requête FTP en 2 parties +* +* @pRequest La requête en question +* +* @pCommand Remplissage: commande (1ère partie) +* @pContant Remplissage: contenu (2ème partie) +* +* +*/ +void splitFtpRequest(char* pRequest, char* pCommand, char* pContent); + +/* Découpe la réponse FTP en 2 parties +* +* @pAnswer La réponse en question +* +* @ftpCode Remplissage: code FTP (1ère partie) +* @ftpText Remplissage: text associé (2ème partie) +* +* +*/ +void splitFtpResponse(char* pAnswer, char* ftpCode, char* ftpText); + + +/* Retourne le rang d'un caractère dans une string +* +* @haystack La chaîne dans laquelle rechercher +* @needle Le caractère recherché +* +* @return position Retourne l'index de @needle dans @haystack ou -1 si ne trouve pas +* +*/ +int indexOf(char* haystack, char needle); + +void setSocketTimeout(int* pSocket, const int pSec, const int pUSec); + + +/* read/write socket */ +int swrite(int* pSocket, char* pBuffer); +int sread(int* pSocket, char* pBuffer); + + + +/* Affiche une string en supprimant les retours à la ligne de fin de chaînes +* +* @pPattern Schéma du print (1er arg) +* @pBuffer Buffer en question +* +*/ +void xPrint(char* pPattern, char* pBuffer); + + +/* Révèle les caractères spéciaux d'une string +* +* @pString La string à révéler +* +* +* @print explicitString On affiche la chaîne explicité +* +*/ +void revealString(char* pString); \ No newline at end of file diff --git a/command-terminal/java-code b/command-terminal/java-code new file mode 100644 index 0000000..e69de29 diff --git a/plane/dep/client.c b/plane/dep/client.c new file mode 100644 index 0000000..c6b5acb --- /dev/null +++ b/plane/dep/client.c @@ -0,0 +1,500 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + xdrm-brackets/proxy.ftp.c - xdrm-brackets' git server + + + + + + +
+ + + +
+
+
+
+ +
+
+
+
+ + + +
+ + +
+ + + + +

+ No Description + +

+ + +
+

+ + + client.c 3.9KB + + +
+
+ + Permalink + + History + Raw +
+ + + + + + + + +
+ +

+
+
+ + + + + + + + + + +
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. #include "client.h"
  2. +
  3. +
  4. +
  5. int CONNECT_CLIENT(char* serverHost, char* serverPort, int* pSocket){
  6. +
  7. if( DEBUGMOD&HDR ) printf("====== CONNECT_CLIENT(%s, %s, %d) ======\n\n", serverHost, serverPort, *pSocket);
  8. +
  9. +
  10. struct addrinfo hints; // contiendra le filtre/format
  11. +
  12. struct addrinfo* addrinfo; // contiendra les infos
  13. +
  14. int CONNECT; // file_desc(s)
  15. +
  16. int GETADDRINFO; // contiendra l'erreur ou pas de getaddrinfo()
  17. +
  18. char BUFFER[maxBuffLen]; // BUFFER de communication
  19. +
  20. +
  21. /* [1] On définit le filtre/format
  22. +
  23. =======================================================*/
  24. +
  25. memset(&hints, 0, sizeof(struct addrinfo)); // on vide le filtre
  26. +
  27. hints.ai_family = AF_UNSPEC; // Allow IPv4 ou IPv6
  28. +
  29. hints.ai_socktype = SOCK_STREAM; // TCP (SOCK_DGRAM = UDP)
  30. +
  31. hints.ai_flags = 0; // non spécifié
  32. +
  33. hints.ai_protocol = 0; // non spécifié
  34. +
  35. +
  36. if( DEBUGMOD&SCK ) printf("============HINTS===========\n");
  37. +
  38. if( DEBUGMOD&SCK ) printf( "AI_FLAGS = %d\n", hints.ai_flags ); // int
  39. +
  40. if( DEBUGMOD&SCK ) printf( "AI_FAMILY = %d\n", hints.ai_family ); // int
  41. +
  42. if( DEBUGMOD&SCK ) printf( "AI_SOCKTYPE = %d\n", hints.ai_socktype ); // int
  43. +
  44. if( DEBUGMOD&SCK ) printf( "AI_PROTOCOL = %d\n", hints.ai_protocol ); // int
  45. +
  46. if( DEBUGMOD&SCK ) printf( "AI_ADDRLEN = %d\n", hints.ai_addrlen ); // int
  47. +
  48. if( DEBUGMOD&SCK ) printf("\n");
  49. +
  50. +
  51. +
  52. /* [2] On récupère les infos
  53. +
  54. =======================================================*/
  55. +
  56. GETADDRINFO = getaddrinfo(serverHost, serverPort, &hints, &addrinfo);
  57. +
  58. +
  59. // si erreur
  60. +
  61. if( GETADDRINFO < 0 ) return -1;
  62. +
  63. +
  64. if( DEBUGMOD&SCK ) printf("=============RES============\n");
  65. +
  66. if( DEBUGMOD&SCK ) printf( "AI_FLAGS = %d\n", addrinfo->ai_flags ); // int
  67. +
  68. if( DEBUGMOD&SCK ) printf( "AI_FAMILY = %d\n", addrinfo->ai_family ); // int
  69. +
  70. if( DEBUGMOD&SCK ) printf( "AI_SOCKTYPE = %d\n", addrinfo->ai_socktype ); // int
  71. +
  72. if( DEBUGMOD&SCK ) printf( "AI_PROTOCOL = %d\n", addrinfo->ai_protocol ); // int
  73. +
  74. if( DEBUGMOD&SCK ) printf( "AI_ADDRLEN = %d\n", addrinfo->ai_addrlen ); // int
  75. +
  76. if( DEBUGMOD&SCK ) printf("\n");
  77. +
  78. +
  79. /* [3] Création de la socket
  80. +
  81. =======================================================*/
  82. +
  83. *pSocket = socket(addrinfo->ai_family, addrinfo->ai_socktype, 0);
  84. +
  85. +
  86. if( DEBUGMOD&SCK ) printf("SOCKET = %d\n", *pSocket);
  87. +
  88. +
  89. // si erreur
  90. +
  91. if( *pSocket == -1 ) return -1;
  92. +
  93. +
  94. +
  95. /* [4] On établit la connection
  96. +
  97. =======================================================*/
  98. +
  99. CONNECT = connect(
  100. +
  101. *pSocket,
  102. +
  103. addrinfo->ai_addr,
  104. +
  105. addrinfo->ai_addrlen
  106. +
  107. );
  108. +
  109. +
  110. if( DEBUGMOD&SCK ) printf("CONNECT = %d\n", CONNECT);
  111. +
  112. +
  113. // si erreur
  114. +
  115. if( CONNECT == -1 ) return -1;
  116. +
  117. +
  118. // on a plus besoin des infos de l'adresse
  119. +
  120. freeaddrinfo(addrinfo);
  121. +
  122. +
  123. +
  124. /* [5] On retourne la SOCKET
  125. +
  126. =======================================================*/
  127. +
  128. return *pSocket;
  129. +
  130. }
  131. +
  132. +
  133. +
  134. +
  135. +
  136. +
  137. +
  138. int CLIENT_SEND(int* pSocket, char* pRequest, char** pAnswer){
  139. +
  140. if( DEBUGMOD&HDR ) printf("====== CLIENT_SEND(%d, %s, %s) ======\n\n", *pSocket, pRequest, *pAnswer);
  141. +
  142. char BUFFER[maxBuffLen] = {0};
  143. +
  144. +
  145. /* [1] On écrit sur la socket
  146. +
  147. =======================================================*/
  148. +
  149. int nbSend = swrite(pSocket, pRequest);
  150. +
  151. +
  152. if( DEBUGMOD&BUF ) printf("nbSend: %d\n", nbSend);
  153. +
  154. if( DEBUGMOD&BUF ) printf("Message: %s\n", pRequest);
  155. +
  156. +
  157. // si pas tout envoyé
  158. +
  159. if( strlen(pRequest) != nbSend ) return -1;
  160. +
  161. +
  162. /* [2] On attends et lit la réponse
  163. +
  164. =======================================================*/
  165. +
  166. int nbRecup = WAIT_SOCKET_UPDATE(pSocket, BUFFER);
  167. +
  168. +
  169. /* [3] On retourne la réponse par référence
  170. +
  171. =======================================================*/
  172. +
  173. *pAnswer = malloc( maxBuffLen );
  174. +
  175. strcpy(*pAnswer, BUFFER);
  176. +
  177. +
  178. if( DEBUGMOD&BUF ) printf("nbReceived: %d\n", nbRecup);
  179. +
  180. if( DEBUGMOD&BUF ) printf("Message: %s\n", *pAnswer);
  181. +
  182. }
  183. +
+ +
+
+
+ + + + +
+
+ +
+ + + + + + + + + + + + + + + + + diff --git a/plane/dep/client.h b/plane/dep/client.h new file mode 100644 index 0000000..e1b95a4 --- /dev/null +++ b/plane/dep/client.h @@ -0,0 +1,433 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + xdrm-brackets/proxy.ftp.c - xdrm-brackets' git server + + + + + + +
+ + + +
+
+
+
+ +
+
+
+
+ + + +
+ + +
+ + + + +

+ No Description + +

+ + +
+

+ + + client.h 1.0KB + + +
+
+ + Permalink + + History + Raw +
+ + + + + + + + +
+ +

+
+
+ + + + + + + + + + +
12345678910111213141516171819202122232425262728293031323334353637383940
  1. /* Envoi d'une requête à un serveur et réception de la réponse
  2. +
  3. *
  4. +
  5. * @serverHost<char*> Nom de l'hôte distant (server)
  6. +
  7. * @serverPort<char*> Numéro du port distant (server)
  8. +
  9. * @pSocket<int*> Pointeur sur la requête à créer
  10. +
  11. *
  12. +
  13. *
  14. +
  15. * @return error<int> retourne -1 en cas d'erreur, sinon la SOCKET
  16. +
  17. *
  18. +
  19. *
  20. +
  21. *
  22. +
  23. * @history
  24. +
  25. * [1] On définit le filtre/format
  26. +
  27. * [2] On récupère les infos
  28. +
  29. * [3] Création de la socket
  30. +
  31. * [4] On établit la connection
  32. +
  33. * [5] On retourne la SOCKET
  34. +
  35. *
  36. +
  37. */
  38. +
  39. int CONNECT_CLIENT(char* serverHost, char* serverPort, int* pSocket);
  40. +
  41. +
  42. +
  43. +
  44. /* Envoi d'une requête vers une SOCKET et récupère la réponse
  45. +
  46. *
  47. +
  48. * @pSocket<int*> Pointeur sur la SOCKET en question
  49. +
  50. * @pRequest<char*> Requête à lui envoyer (swrite)
  51. +
  52. * @pAnswer<char**> Réponse qui se lira après la requête (sread)
  53. +
  54. *
  55. +
  56. * @return error<int> Retourne -1 en cas d'erreur
  57. +
  58. *
  59. +
  60. *
  61. +
  62. *
  63. +
  64. * @history
  65. +
  66. * [1] On écrit sur la socket
  67. +
  68. * [2] On attends et lit la réponse
  69. +
  70. * [3] On retourne la réponse par référence
  71. +
  72. *
  73. +
  74. */
  75. +
  76. int CLIENT_SEND(int* pSocket, char* pRequest, char** pAnswer);
  77. +
+ +
+
+
+ + + + +
+
+ +
+ + + + + + + + + + + + + + + + + diff --git a/plane/dep/utility.c b/plane/dep/utility.c new file mode 100644 index 0000000..faecd69 --- /dev/null +++ b/plane/dep/utility.c @@ -0,0 +1,169 @@ +#include "utility.h" + +void splitFtpRequest(char* pRequest, char* pCommand, char* pContent){ + /* [1] Vérification du format + ===========================================*/ + int firstSpaceIndex = indexOf(pRequest, ' '); + + if( firstSpaceIndex != 3 && firstSpaceIndex != 4){ // contient aucun espace en position 3 ou 4, on quitte + strcpy(pCommand, "ERROR"); + strcpy(pContent, ""); + return; + } + + + /* [2] Séparation des 2 parties + ===========================================*/ + int i; + + for( i = 0 ; i < strlen(pRequest) && pRequest[i] != '\0' ; i++ ){ + + if( i < firstSpaceIndex ) // première partie (pCommand) + strcat( pCommand, (char[2]){(char) pRequest[i], '\0'}); + if( i > firstSpaceIndex ) // seconde partie (pContent) + strcat( pContent, (char[2]){(char) pRequest[i], '\0'}); + } + + +} + + + + +void splitFtpResponse(char* pAnswer, char* ftpCode, char* ftpText){ + /* [1] Vérification du format + ===========================================*/ + int codeLength = 3; // taille du code + + /* [2] Séparation des 2 parties + ===========================================*/ + int i; + + for( i = 0 ; i < strlen(pAnswer) && pAnswer[i] != '\0' ; i++ ){ + + if( i < codeLength ) // première partie (ftpCode) + strcat(ftpCode, (char[2]){(char)pAnswer[i], '\0' }); + if( i > codeLength ) // seconde partie (ftpText) + strcat(ftpText, (char[2]){(char)pAnswer[i], '\0' }); + } + + +} + + + + + +int indexOf(char* haystack, char needle){ + int i; + + for( i = 0 ; i < strlen(haystack) && haystack[i] != '\0' ; i++ ) + if( haystack[i] == needle ) // si on trouve le caractère + return i; + + return -1; + +} + + +int swrite(int* pSocket, char* pBuffer){ + if( *pSocket == -1 ) return -1; // si SOCKET fermée, on retourne une erreur + if( strlen(pBuffer) == 0 ) return 0; // si on a rien à écrire, on n'écrit rien :p + + + /* 1. On écrit sur la SOCKET */ + if( DEBUGMOD&BUF ) printf("SENDLEN_1: %lu\n", strlen(pBuffer)); + int nbSent = write(*pSocket, pBuffer, strlen(pBuffer)); + if( DEBUGMOD&BUF ) printf("SENDLEN_2: %d\n", nbSent); + + /* 2. Si on est déconnecté, on retourne une erreur */ + if( nbSent <= 0 ){ + if( DEBUGMOD&BUF ) printf("NOTHING TO SEND\n"); + return -1; // on retourne une erreur + } + + if( DEBUGMOD&RVL ) printf("SEND_1\n"); + if( DEBUGMOD&RVL ) revealString(pBuffer); + if( DEBUGMOD&RVL ) printf("SEND_2\n"); + + + /* 3. On retourne le nombre de envoyés */ + return nbSent; +} + + +int sread(int* pSocket, char* pBuffer){ + if( *pSocket == -1 ) return -1; // si SOCKET fermée, on retourne une erreur + + + /* 1. On vide le buffer avant de lire */ + memset(pBuffer, '\0', maxBuffLen); + if( DEBUGMOD&BUF ) printf("READLEN_1: %lu\n", strlen(pBuffer)); + + /* 2. On lit la SOCKET */ + int nbRead = read(*pSocket, pBuffer, maxBuffLen); + if( DEBUGMOD&BUF ) printf("READLEN_3: %d\n", nbRead); + + + /* 3. Si on est déconnecté, on retourne une erreur */ + if( nbRead <= 0 ){ + if( DEBUGMOD&BUF ) printf("NOTHING TO READ\n"); + return -1; // on retourne une erreur + } + + if( DEBUGMOD&RVL ) printf("READ_1\n"); + if( DEBUGMOD&RVL ) revealString(pBuffer); + if( DEBUGMOD&RVL ) printf("READ_2\n"); + + /* 4. On retourne le nombre de caractères lus */ + return nbRead; +} + + +void setSocketTimeout(int* pSocket, const int pSec, const int pUSec){ + /* 1. On créé la structure contenant le timeout */ + struct timeval timeout; + timeout.tv_sec = pSec; + timeout.tv_usec = pUSec; + + setsockopt(*pSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(struct timeval)); + + if( DEBUGMOD&SCK ) printf("Set socket(%d) timeout to %lus\n", *pSocket, (long unsigned) timeout.tv_sec ); +} + + +void xPrint(char* pPattern, char* pBuffer){ + char tmpBuffer[maxBuffLen]; + strcpy(tmpBuffer, pBuffer); + + + int i; + + // on supprimes les retours à la ligne de la fin + for( i = strlen(tmpBuffer)-1 ; i >= 0 && tmpBuffer[i] != '\0' ; i-- ) + if( tmpBuffer[i] == '\n' || tmpBuffer[i] == '\r' ) // si c'est un retour chariot + tmpBuffer[i] = '\0'; // on efface + else + break; + + printf(pPattern, pBuffer); +} + + +void revealString(char* pString){ + /* 1. On créé une copie de @pString */ + char revealedString[maxBuffLen] = {0}; + + /* 2. On rend visible tous les caractères "invisibles" */ + int i; + for( i = 0 ; i < strlen(pString) && pString[i] != '\0' ; i++ ){ + if( pString[i] == '\r' ){ revealedString[strlen(revealedString)] = '\\'; revealedString[strlen(revealedString)] = 'r'; } + else if( pString[i] == '\n' ){ revealedString[strlen(revealedString)] = '\\'; revealedString[strlen(revealedString)] = 'n'; } + else revealedString[strlen(revealedString)] = pString[i]; + + revealedString[strlen(revealedString)] = '\0'; + } + + /* 3. On affiche la chaîne explicite */ + if( DEBUGMOD&RVL ) printf("[[%s]]\n", revealedString); +} \ No newline at end of file diff --git a/plane/dep/utility.h b/plane/dep/utility.h new file mode 100644 index 0000000..b6ef223 --- /dev/null +++ b/plane/dep/utility.h @@ -0,0 +1,60 @@ +/* Découpe la requête FTP en 2 parties +* +* @pRequest La requête en question +* +* @pCommand Remplissage: commande (1ère partie) +* @pContant Remplissage: contenu (2ème partie) +* +* +*/ +void splitFtpRequest(char* pRequest, char* pCommand, char* pContent); + +/* Découpe la réponse FTP en 2 parties +* +* @pAnswer La réponse en question +* +* @ftpCode Remplissage: code FTP (1ère partie) +* @ftpText Remplissage: text associé (2ème partie) +* +* +*/ +void splitFtpResponse(char* pAnswer, char* ftpCode, char* ftpText); + + +/* Retourne le rang d'un caractère dans une string +* +* @haystack La chaîne dans laquelle rechercher +* @needle Le caractère recherché +* +* @return position Retourne l'index de @needle dans @haystack ou -1 si ne trouve pas +* +*/ +int indexOf(char* haystack, char needle); + +void setSocketTimeout(int* pSocket, const int pSec, const int pUSec); + + +/* read/write socket */ +int swrite(int* pSocket, char* pBuffer); +int sread(int* pSocket, char* pBuffer); + + + +/* Affiche une string en supprimant les retours à la ligne de fin de chaînes +* +* @pPattern Schéma du print (1er arg) +* @pBuffer Buffer en question +* +*/ +void xPrint(char* pPattern, char* pBuffer); + + +/* Révèle les caractères spéciaux d'une string +* +* @pString La string à révéler +* +* +* @print explicitString On affiche la chaîne explicité +* +*/ +void revealString(char* pString); \ No newline at end of file diff --git a/plane/plane.c b/plane/plane.c new file mode 100644 index 0000000..e69de29 diff --git a/plane/plane.h b/plane/plane.h new file mode 100644 index 0000000..e69de29 diff --git a/viewer-terminal/java-code b/viewer-terminal/java-code new file mode 100644 index 0000000..e69de29