diff --git a/Makefile b/Makefile index cc6ecf9..932528c 100644 --- a/Makefile +++ b/Makefile @@ -22,10 +22,12 @@ CCOPTS=-pthread -Wall -g -Os LDFLAGS= -lc -lpthread BINDIR=bin +INCDIR=include SRCDIR=src DEBDIR=debian -OBJ= $(BINDIR)/scheduler.o $(BINDIR)/server.o $(BINDIR)/localworker.o \ - $(BINDIR)/centers.o $(BINDIR)/main.o +SERVEROBJ= $(BINDIR)/scheduler.o $(BINDIR)/server.o $(BINDIR)/localworker.o \ + $(BINDIR)/centers.o $(BINDIR)/main.o +CLIOBJ= $(BINDIR)/cli.o .DEFAULT_GOAL:= all .PHONY: all clean deb tests install run @@ -40,21 +42,30 @@ $(BINDIR)/tests/centers: $(SRCDIR)/tests/centers.c # ---- General recipes ------------------------------------------------------- # -$(BINDIR)/%.o: $(SRCDIR)/%.c +$(BINDIR)/%.o: $(SRCDIR)/%.c $(INCDIR)/%.h $(INCDIR)/base.h @echo "Compiling $<" @$(CC) $(CCINCLUDES) $(CCOPTS) $(CCFLAGS) -c -o $@ $< # ---- Main recipe ----------------------------------------------------------- # -$(BINDIR)/gem-graph-server: $(OBJ) +$(BINDIR)/main.o: $(SRCDIR)/main.c $(INCDIR)/base.h + @echo "Compiling $<" + @$(CC) $(CCINCLUDES) $(CCOPTS) $(CCFLAGS) -c -o $@ $< + +$(BINDIR)/gem-graph-server: $(SERVEROBJ) $(INCDIR)/base.h @echo "Building program to $@" - @$(CC) -o $@ $(OBJ) $(LDFLAGS) + @$(CC) -o $@ $(SERVEROBJ) $(LDFLAGS) + @echo "Success!" + +$(BINDIR)/gem-graph-ctl: $(CLIOBJ) $(INCDIR)/base.h + @echo "Building program to $@" + @$(CC) -o $@ $(CLIOBJ) $(LDFLAGS) @echo "Success!" # ---- Misc recipes ---------------------------------------------------------- # clean: -rm -f $(SRCDIR)/*.o $(BINDIR)/* $(BINDIR)/tests/* *.deb -all: $(BINDIR)/gem-graph-server +all: $(BINDIR)/gem-graph-server $(BINDIR)/gem-graph-ctl tests: $(TESTS) diff --git a/include/base.h b/include/base.h index 2a50586..66da1f6 100644 --- a/include/base.h +++ b/include/base.h @@ -19,14 +19,15 @@ // along with this program. If not, see . // //=-------------------------------------------------------------------------=// +#include #include #include #include -#include #include #include #include -#include +#include +#include #define BASE_H diff --git a/include/cli.h b/include/cli.h new file mode 100644 index 0000000..50a3aa2 --- /dev/null +++ b/include/cli.h @@ -0,0 +1,24 @@ +//=-------------------------------------------------------------------------=// +// CLI definition // +// // +// 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 . // +//=-------------------------------------------------------------------------=// + +#ifndef BASE_H + #include "../include/base.h" +#endif diff --git a/include/server.h b/include/server.h index 7de0ea9..6efa0a1 100644 --- a/include/server.h +++ b/include/server.h @@ -42,3 +42,4 @@ static inline void ServerDestroy(Server_t *server) static inline void ServerWait(Server_t *server) { pthread_join(*server->id, NULL); +} diff --git a/src/cli.c b/src/cli.c new file mode 100644 index 0000000..1492d78 --- /dev/null +++ b/src/cli.c @@ -0,0 +1,157 @@ +//=-------------------------------------------------------------------------=// +// Command line interface 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 + +#define SERVER_IP_ADDR "127.0.0.1" + +// -------------------------------------------------------------------------- // +// Socket init function // +// -------------------------------------------------------------------------- // +static inline int createSocket(void) +{ + int socketDescriptor; + + //printLog("Create the socket\n"); + + socketDescriptor = socket(AF_INET, SOCK_STREAM, 0); + return socketDescriptor; +} + +static inline int connectSocket(int newSocket) +{ + int effectiveSocket = -1; + int serverPort = 90190; + struct sockaddr_in remote = {0}; + + remote.sin_addr.s_addr = inet_addr(SERVER_IP_ADDR); + remote.sin_family = AF_INET; + remote.sin_port = htons(serverPort); + + effectiveSocket = + connect(newSocket, + (struct sockaddr*)&remote, + sizeof(struct sockaddr_in) + ); + + return effectiveSocket; +} + +static inline int sendSocket(int effectiveSocket, char *request, + short requestSize) +{ + int returnSocket = -1; + struct timeval tv; + + tv.tv_sec = 20; /* 20 Secs Timeout */ + tv.tv_usec = 0; + + if (setsockopt(effectiveSocket, + SOL_SOCKET,SO_SNDTIMEO, + (char *)&tv,sizeof(tv)) < 0) { + printLog("Time Out\n"); + return -1; + } + + returnSocket = send(effectiveSocket, request, requestSize, 0); + + return returnSocket; +} + +static inline int receiveSocket(int effectiveSocket, char *serverAnswer, + short receiveSize) +{ + int returnSocket = -1; + struct timeval tv; + + tv.tv_sec = 20; /* 20 Secs Timeout */ + tv.tv_usec = 0; + + if (setsockopt(effectiveSocket, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, + sizeof(tv)) < 0) { + printLog("Time Out\n"); + return -1; + } + + returnSocket = recv(effectiveSocket, serverAnswer, receiveSize, 0); + //printLog("Anwer %s\n", serverAnswer); + + return returnSocket; +} + +int main(int argc, char **argv) +{ + int socketDescriptor, nextSocketDescriptor, readSize; + struct sockaddr_in server; + + char clientMessage[255] = {0}; + char serverReply[255] = {0}; + char *exitCommand = "exit"; + + while(1) { + printf("\ngem-graph console> "); + + fgets(clientMessage, 255, stdin); + clientMessage[strcspn(clientMessage, "\n")] = '\0'; + + if (strcmp(exitCommand,clientMessage) == 0) + { + close(socketDescriptor); + shutdown(socketDescriptor, 0); + shutdown(socketDescriptor, 1); + shutdown(socketDescriptor, 2); + return 0; + } + + //Create socket + socketDescriptor = createSocket(); + + if(socketDescriptor == -1) { + printLog("Could not create socket\n"); + continue; + } + + //Connect to remote server + if (connectSocket(socketDescriptor) < 0) { + printLog("Connection failed\n"); + continue; + } + + //Send data to the server + sendSocket(socketDescriptor, clientMessage, strlen(clientMessage)); + + //Received the data from the server + readSize = receiveSocket(socketDescriptor, serverReply, 200); + printf("%s\n", serverReply); + + memset(serverReply, 0, 255); + + close(socketDescriptor); + shutdown(socketDescriptor, 0); + shutdown(socketDescriptor, 1); + shutdown(socketDescriptor, 2); + } + + return 0; +} diff --git a/src/server.c b/src/server.c index 2dfa559..d176dff 100644 --- a/src/server.c +++ b/src/server.c @@ -21,12 +21,8 @@ #include "../include/base.h" -#include -#include -#include #include #include -#include static void *serverMain(void *server); @@ -47,49 +43,58 @@ pthread_t *ServerInit(Server_t *scheduler) // -------------------------------------------------------------------------- // static inline int createSocket(void) { - int hSocket; + int newSocket; printLog("Create the socket\n"); - hSocket = socket(AF_INET, SOCK_STREAM, 0); - return hSocket; + newSocket = socket(AF_INET, SOCK_STREAM, 0); + return newSocket; } // -------------------------------------------------------------------------- // // Soecket binding function // // -------------------------------------------------------------------------- // -static inline int bindSocket(int hSocket) +static inline int bindSocket(int newSocket) { - int iRetval=-1; - int ClientPort = 90190; - struct sockaddr_in remote= {0}; - /* Internet address family */ + int effectiveSocket = -1; + int clientPort = 90190; + struct sockaddr_in remote = {0}; + + // Internet address family remote.sin_family = AF_INET; - /* Any incoming interface */ + + // Any incoming interface remote.sin_addr.s_addr = htonl(INADDR_ANY); - remote.sin_port = htons(ClientPort); /* Local port */ - iRetval = bind(hSocket,(struct sockaddr *)&remote,sizeof(remote)); - return iRetval; + remote.sin_port = htons(clientPort); // Local port + effectiveSocket = bind(newSocket,(struct sockaddr*)&remote,sizeof(remote)); + + return effectiveSocket; } +// +// Commands understood by the server +// + + // -------------------------------------------------------------------------- // // Server main function // // -------------------------------------------------------------------------- // static void *serverMain(void *server) { Server_t *args; - int socketDescriptor, sock, clientLen, readSize; + int socketDescriptor, effectiveSocket, clientLen; struct sockaddr_in client; - char clientMessage[255]= {0}; - char message[255] = {0}; - const char *pMessage = "hello world!\n"; + char clientRequest[255]= {0}; + char serverAnswer[255] = {0}; + const char *pMessage = "hello"; // Get args args = (Server_t*) server; + printLog("Server #%lu online\n", *args->id); //Create socket socketDescriptor = createSocket(); - if (socketDescriptor) + if (socketDescriptor < 0) { printLog("Could not create socket\n"); return NULL; @@ -99,12 +104,12 @@ static void *serverMain(void *server) //Bind if( bindSocket(socketDescriptor) < 0) { - //print the error message - printLog("bind failed.\n"); + //print the error serverAnswer + printLog("Socket bind failed\n"); return NULL; } - printLog("bind done\n"); + printLog("Socket bind succeeded\n"); //Listen listen(socketDescriptor, 3); @@ -114,38 +119,47 @@ static void *serverMain(void *server) { printLog("Waiting for incoming connections...\n"); clientLen = sizeof(struct sockaddr_in); + //accept connection from an incoming client - sock = accept(socketDescriptor,(struct sockaddr *)&client,(socklen_t*)&clientLen); - if (sock < 0) + effectiveSocket = accept(socketDescriptor,(struct sockaddr *)&client,(socklen_t*)&clientLen); + + if (effectiveSocket < 0) { - printLog("accept failed"); + printLog("Acceptation failed\n"); return NULL; } + printLog("Connection accepted\n"); - memset(clientMessage, '\0', sizeof clientMessage); - memset(message, '\0', sizeof message); + + memset(clientRequest, '\0', sizeof(clientRequest)); + memset(serverAnswer, '\0', sizeof(serverAnswer)); + //Receive a reply from the client - if( recv(sock, clientMessage, 200, 0) < 0) + if (recv(effectiveSocket, clientRequest, 200, 0) < 0) { - printLog("recv failed"); + printLog("Reception failed"); break; } - printLog("Client reply : %s\n",clientMessage); - if(strcmp(pMessage,clientMessage)==0) + printLog("Client reply : %s\n",clientRequest); + if (strcmp(pMessage,clientRequest) == 0) { - strcpy(message,"Hi there !"); + strcpy(serverAnswer,"Hello there."); } else { - strcpy(message,"Invalid Message !"); + strcpy(serverAnswer,"Invalid command"); } // Send some data - if( send(sock, message, strlen(message), 0) < 0) + if (send(effectiveSocket, serverAnswer, strlen(serverAnswer), 0) < 0) { - printLog("Send failed"); + printLog("Send failed\n"); return NULL; } - close(sock); + + close(effectiveSocket); } - return 0; + + printLog("Server #%lu offline\n", *args->id); + + return NULL; }