//=-------------------------------------------------------------------------=// // Server management module // // // // Copyright © 2021 The Gem-graph Project // // // // This file is part of gem-graph. // // // // This program is free software: you can redistribute it and/or modify // // it under the terms of the GNU Affero General Public License as // // published by the Free Software Foundation, either version 3 of the // // License, or (at your option) any later version. // // // // This program 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 Affero General Public License for more details. // // // // You should have received a copy of the GNU Affero General Public License // // along with this program. If not, see . // //=-------------------------------------------------------------------------=// #include "../include/base.h" #include "../include/cmds.h" #include #include static void *serverMain(void *server); /* -------------------------------------------------------------------------- */ // -------------------------------------------------------------------------- // // Scheduler init function // // -------------------------------------------------------------------------- // void ServerInit(Server_t *scheduler) { scheduler->id = (pthread_t*) calloc(1, sizeof(pthread_t)); pthread_create(scheduler->id, NULL, serverMain, scheduler); } // -------------------------------------------------------------------------- // // Socket init function // // -------------------------------------------------------------------------- // static inline int createSocket(void) { int newSocket; printLog("Create the socket\n"); newSocket = socket(AF_INET, SOCK_STREAM, 0); return newSocket; } // -------------------------------------------------------------------------- // // Soecket binding function // // -------------------------------------------------------------------------- // static inline int bindSocket(int newSocket) { int effectiveSocket = -1; int clientPort = 90190; struct sockaddr_in remote = {0}; // Internet address family remote.sin_family = AF_INET; // Any incoming interface remote.sin_addr.s_addr = htonl(INADDR_ANY); remote.sin_port = htons(clientPort); // Local port effectiveSocket = bind(newSocket,(struct sockaddr*)&remote,sizeof(remote)); return effectiveSocket; } // -------------------------------------------------------------------------- // // Server main function // // -------------------------------------------------------------------------- // static void *serverMain(void *server) { Server_t *args; int socketDescriptor, effectiveSocket, clientRequestLength; struct sockaddr_in client; char clientRequest[255]= {0}; char serverAnswer[255] = {0}; char **argv = NULL; char *commandReturn; int tokenIndex; // Get args args = (Server_t*) server; printLog("Server #%lu online\n", *args->id); //Create socket socketDescriptor = createSocket(); if (socketDescriptor < 0) { printLog("Could not create socket\n"); return NULL; } printLog("Socket created\n"); //Bind if( bindSocket(socketDescriptor) < 0) { //print the error serverAnswer printLog("Socket bind failed\n"); return NULL; } printLog("Socket bind succeeded\n"); //Listen listen(socketDescriptor, 3); //Accept and incoming connection while(!args->pleaseStop) { printLog("Waiting for incoming connections...\n"); clientRequestLength = sizeof(struct sockaddr_in); //accept connection from an incoming client effectiveSocket = accept(socketDescriptor,(struct sockaddr *)&client,(socklen_t*)&clientRequestLength); if (effectiveSocket < 0) { printLog("Acceptation failed\n"); return NULL; } printLog("Connection accepted\n"); memset(clientRequest, '\0', sizeof(clientRequest)); strcpy(serverAnswer,"Invalid command\0"); //Receive REQUEST from client if (recv(effectiveSocket, clientRequest, 200, 0) < 0) { printLog("Reception failed"); break; } printLog("Client request : %s\n",clientRequest); // get args in an array tokenIndex = 0; argv = (char**) realloc(argv, 1 * sizeof(char*)); argv[0] = strtok(clientRequest, " "); while (argv[tokenIndex]) { tokenIndex++; argv = (char**) realloc(argv, (tokenIndex+1) * sizeof(char*)); argv[tokenIndex] = strtok(NULL, " "); } // test first arg to find command in cmdList for (int i = 0; i < LEN(cmdList); i++) { if (strcmp(cmdList[i].name, argv[0]) == 0) { commandReturn = cmdList[i].execute(argv, args); strcpy(serverAnswer, commandReturn); free(commandReturn); } } // REPLY to client if (send(effectiveSocket, serverAnswer, strlen(serverAnswer), 0) < 0) { printLog("Send failed\n"); return NULL; } close(effectiveSocket); } free(argv); printLog("Server #%lu offline\n", *args->id); return NULL; }