2015-12-14 20:48:19 +00:00
|
|
|
|
#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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2015-12-14 21:00:05 +00:00
|
|
|
|
void MANAGE_RESPONSE(char** pAnswer, int* DUSER_SOCKET, int* DFTP_SOCKET){
|
2015-12-14 20:48:19 +00:00
|
|
|
|
if( DEBUGMOD ) printf("====== MANAGE_RESPONSE(%d, %s) ======\n\n", *SOCKET, *pAnswer);
|
|
|
|
|
|
2015-12-14 21:00:05 +00:00
|
|
|
|
char response[maxBuffLen]; // contiendra la réponse
|
2015-12-14 20:48:19 +00:00
|
|
|
|
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));
|
2015-12-14 21:00:05 +00:00
|
|
|
|
memset(&response, '\0', sizeof(response));
|
2015-12-14 20:48:19 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* [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 )
|
2015-12-14 21:00:05 +00:00
|
|
|
|
strcpy(response, WLCM_MSG);
|
2015-12-14 20:48:19 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* (3) username OK -> demande MDP
|
|
|
|
|
--------------------------------------------*/
|
|
|
|
|
else if( strcmp(ftpCode, "331") == 0 )
|
2015-12-14 21:00:05 +00:00
|
|
|
|
strcpy(response, USER_MSG);
|
2015-12-14 20:48:19 +00:00
|
|
|
|
|
|
|
|
|
/* (3) Bon mdp -> connection
|
|
|
|
|
--------------------------------------------*/
|
|
|
|
|
else if( strcmp(ftpCode, "230") == 0 )
|
2015-12-14 21:00:05 +00:00
|
|
|
|
strcpy(response, PASS_BON_MSG);
|
2015-12-14 20:48:19 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* (4) Mauvais mdp -> connection
|
|
|
|
|
--------------------------------------------*/
|
|
|
|
|
else if( strcmp(ftpCode, "530") == 0 )
|
2015-12-14 21:00:05 +00:00
|
|
|
|
strcpy(response, PASS_BAD_MSG);
|
2015-12-14 20:48:19 +00:00
|
|
|
|
|
|
|
|
|
/* (5) Info SYST
|
|
|
|
|
--------------------------------------------*/
|
|
|
|
|
// else if( strcmp(ftpCode, "215") == 0 )
|
2015-12-14 21:00:05 +00:00
|
|
|
|
// strcpy(response, "bla\n");
|
2015-12-14 20:48:19 +00:00
|
|
|
|
|
|
|
|
|
/* (6) LOGOUT => EXIT
|
|
|
|
|
--------------------------------------------*/
|
|
|
|
|
else if( strcmp(ftpCode, "221") == 0 )
|
2015-12-14 21:00:05 +00:00
|
|
|
|
strcpy(response, EXIT_MSG);
|
2015-12-14 20:48:19 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* (n) Commande inconnue
|
|
|
|
|
--------------------------------------------*/
|
|
|
|
|
else
|
2015-12-14 21:00:05 +00:00
|
|
|
|
strcpy(response, *pAnswer);
|
2015-12-14 20:48:19 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* [3] Retour de la réponse
|
|
|
|
|
================================================*/
|
2015-12-14 21:00:05 +00:00
|
|
|
|
strcpy(*pAnswer, response);
|
2015-12-14 20:48:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|