#include "server.h" void DROP_SERVER(char* serverHost, char** givenPort, int* listenSocket){ if( DEBUGMOD ) 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 ) printf("============HINTS===========\n"); if( DEBUGMOD ) printf( "AI_FLAGS = %d\n", hints.ai_flags ); // int if( DEBUGMOD ) printf( "AI_FAMILY = %d\n", hints.ai_family ); // int if( DEBUGMOD ) printf( "AI_SOCKTYPE = %d\n", hints.ai_socktype ); // int if( DEBUGMOD ) printf( "AI_PROTOCOL = %d\n", hints.ai_protocol ); // int if( DEBUGMOD ) printf( "AI_ADDRLEN = %d\n", hints.ai_addrlen ); // int if( DEBUGMOD ) 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 ) printf("=============RES============\n"); if( DEBUGMOD ) printf( "AI_FLAGS = %d\n", addrinfo->ai_flags ); // int if( DEBUGMOD ) printf( "AI_FAMILY = %d\n", addrinfo->ai_family ); // int if( DEBUGMOD ) printf( "AI_SOCKTYPE = %d\n", addrinfo->ai_socktype ); // int if( DEBUGMOD ) printf( "AI_PROTOCOL = %d\n", addrinfo->ai_protocol ); // int if( DEBUGMOD ) printf( "AI_ADDRLEN = %d\n", addrinfo->ai_addrlen ); // int if( DEBUGMOD ) printf("\n"); /* [3] Création de la socket =======================================================*/ SOCKET = socket(addrinfo->ai_family, addrinfo->ai_socktype, 0); if( DEBUGMOD ) 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 ) 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 ) printf("Server host: %s\n", infoHost); if( DEBUGMOD ) 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 ) printf("LISTEN = %d\n", LISTEN); // si erreur if( LISTEN == -1 ) return; /* [7] On envoie les données par référence =======================================================*/ // port *givenPort = malloc( sizeof(infoPort) ); strcpy(*givenPort, infoPort); // socket d'écoute *listenSocket = SOCKET; } // CMD: CLIENT (SRV) PROXY (CLT) FTP // DTA: CLIENT (CLT) PROXY (CLT) FTP // // // // [1] Ecoute sur port p de localhost // [2-n] Si commande, envoi à FTP // Puis Reception de FTP, envoi à CLIENT void MANAGE_REQUEST(int* SOCKET, char* pRequest){ if( DEBUGMOD ) printf("====== MANAGE_REQUEST(%d, %s) ======\n\n", *SOCKET, pRequest); char answer[maxBuffLen]; // contiendra la réponse int nbSend; // contiendra le nombre de données envoyées char rCommand[10]; // 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(&answer, '\0', sizeof(answer)); /* [1] On découpe la requête en 2 parties ================================================*/ splitFtpRequest(pRequest, rCommand, rContent); // strcpy(answer, strcat(rCommand, rContent) ); /* [2] Selection en fonction de @rCommand ================================================*/ /* (1) Erreur de syntaxe --------------------------------------------*/ if( strcmp(rCommand, "ERROR") == 0 ) strcpy(answer, "666 Tu t'es chié!!\n"); /* (2) Connection (username) --------------------------------------------*/ else if( strcmp(rCommand, "USER") == 0 ) strcpy(answer, "331 C'est donc ça ton blase!\n"); /* (n) Commande inconnue --------------------------------------------*/ else strcpy(answer, "??? Connè pô!\n"); /* [3] Envoi de la réponse ================================================*/ formatBuffer(answer); nbSend = write(*SOCKET, answer, strlen(answer)); /* [4] Fermeture de la SOCKET ================================================*/ // close(*SOCKET); } void MANAGE_RESPONSE(char** pAnswer, int* DUSER_SOCKET, int* DFTP_SOCKET){ if( DEBUGMOD ) printf("====== MANAGE_RESPONSE(%d, %s) ======\n\n", *SOCKET, *pAnswer); char response[maxBuffLen]; // contiendra la réponse char ftpCode[4]; // contiendra le code FTP (1ère partie) char ftpText[maxBuffLen]; // contiendra le texte associé à la commande (2ème partie) // on vide les buffers memset(&ftpCode, '\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, ftpCode, ftpText); /* [2] Selection en fonction de @ftpCode ================================================*/ /* (2) Demande d'username --------------------------------------------*/ if( strcmp(ftpCode, "220") == 0 ) strcpy(response, WLCM_MSG); /* (3) username OK -> demande MDP --------------------------------------------*/ else if( strcmp(ftpCode, "331") == 0 ) strcpy(response, USER_MSG); /* (3) Bon mdp -> connection --------------------------------------------*/ else if( strcmp(ftpCode, "230") == 0 ) strcpy(response, PASS_BON_MSG); /* (4) Mauvais mdp -> connection --------------------------------------------*/ else if( strcmp(ftpCode, "530") == 0 ) strcpy(response, PASS_BAD_MSG); /* (5) Info SYST --------------------------------------------*/ // else if( strcmp(ftpCode, "215") == 0 ) // strcpy(response, "bla\n"); /* (6) LOGOUT => EXIT --------------------------------------------*/ else if( strcmp(ftpCode, "221") == 0 ) strcpy(response, EXIT_MSG); /* (n) Commande inconnue --------------------------------------------*/ else strcpy(response, *pAnswer); /* [3] Retour de la réponse ================================================*/ strcpy(*pAnswer, response); } int WAIT_CLIENT(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 ferme la SOCKET 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; }