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;
}