aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSyndamia <kamen@syndamia.com>2023-12-08 17:55:57 +0200
committerSyndamia <kamen@syndamia.com>2023-12-08 17:55:57 +0200
commit7ad507e3ec8efb0cdbc32474ea7c1ccbf031b960 (patch)
tree712dd3f5acf72ba621bd3eeed282467e2e258636
parentde1e66d00a5469f02eb7323553b3b087e6255980 (diff)
downloadpico-web-7ad507e3ec8efb0cdbc32474ea7c1ccbf031b960.tar
pico-web-7ad507e3ec8efb0cdbc32474ea7c1ccbf031b960.tar.gz
pico-web-7ad507e3ec8efb0cdbc32474ea7c1ccbf031b960.zip
[server] Moved server-cli to it's own file and reorganized server and server-cli
-rw-r--r--Makefile2
-rw-r--r--server-cli.c46
-rw-r--r--server-cli.h8
-rw-r--r--server.c220
-rw-r--r--util.c4
-rw-r--r--util.h3
6 files changed, 159 insertions, 124 deletions
diff --git a/Makefile b/Makefile
index bc90075..0a0f6c5 100644
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@ all: server browser
.PHONY: server
server:
- gcc -g -o server -I. sds/sds.c util.c server.c server-connection.c
+ gcc -g -o server -I. sds/sds.c util.c server.c server-connection.c server-cli.c
.PHONY: browser
browser:
diff --git a/server-cli.c b/server-cli.c
new file mode 100644
index 0000000..82c9501
--- /dev/null
+++ b/server-cli.c
@@ -0,0 +1,46 @@
+#include <util.h>
+#include <server-connection.h>
+#include <stdio.h>
+#include <signal.h>
+#include <unistd.h>
+
+#define MAX_LEN_COMMAND 16
+#define COMMAND_FORMAT ": %16s"
+
+void handleCLI(sds **vhosts, int vhostsc) {
+ // Get a line
+ char line[256];
+ fgets(line, 256, stdin);
+
+ // Get command name and it's arguments
+ // Currently no command takes arguments
+ char name[MAX_LEN_COMMAND+1];
+ int argsAssigned = sscanf(line, COMMAND_FORMAT, name);
+
+ while (name[0] != 'q' && name[0] != 'e' && !streq(name, "quit") && !streq(name, "exit")) {
+ if (argsAssigned < 1) {
+ printf("Bad command syntax!\n");
+ }
+ else if (streq(name, "vhosts")) {
+ for (int i = 0; i < vhostsc; i++) {
+ printf("Name: \"%s\" Root dir: \"%s\" Error file: \"%s\"\n",
+ vhosts[i][vh_user],
+ vhosts[i][vh_path],
+ vhosts[i][vh_error]);
+ }
+ }
+ else if (streq(name, "help")) {
+ printf("help\tPrints this message\nvhosts\tPrints all registered virtual hosts\n");
+ }
+ else {
+ printf("Unknown command %s!\n", name);
+ }
+
+ // Get line and divided it into command name and arguments
+ fgets(line, 256, stdin);
+ argsAssigned = sscanf(line, COMMAND_FORMAT, name);
+ }
+
+ printf("Exiting...\n");
+ kill(getppid(), SIGTERM);
+}
diff --git a/server-cli.h b/server-cli.h
new file mode 100644
index 0000000..b5b5875
--- /dev/null
+++ b/server-cli.h
@@ -0,0 +1,8 @@
+#ifndef H_SERVER_CLI
+#define H_SERVER_CLI
+
+#include <sds/sds.h>
+
+void handleCLI(sds **vhosts, int vhostsc);
+
+#endif
diff --git a/server.c b/server.c
index 02c9f5a..8592b10 100644
--- a/server.c
+++ b/server.c
@@ -1,7 +1,5 @@
/* The server recieves connections and passes files to the clients
*/
-#include <server-connection.h>
-
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
@@ -19,18 +17,39 @@
#include <sds/sds.h>
#include <util.h>
-#define MAX_LEN_COMMAND 16
-#define COMMAND_FORMAT ": %16s"
+#include <server-connection.h>
+#include <server-cli.h>
-void freeVhosts(sds **vhosts, int argc) {
- for (int i = 1; i < argc; i++) {
- sdsfreesplitres(vhosts[i-1], 3);
- }
- free(vhosts);
+int createCommunicationSocket(const char* ip, const char* port) {
+ int fd_socket = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);
+ herr(fd_socket, "socket");
+
+ int aton_status = 0;
+ struct sockaddr_in sa_socket = {
+ .sin_family = AF_INET,
+ .sin_port = atop(port),
+ .sin_addr = aton(ip, &aton_status),
+ };
+ herr(aton_status, "inet_aton");
+
+ // Reuse address when in TIME_WAIT state, after listening socket was closed
+ // https://stackoverflow.com/a/10651048/12036073
+ // https://superuser.com/questions/173535/what-are-close-wait-and-time-wait-states#comment951880_173543
+ int true = 1;
+ herr(setsockopt(fd_socket, SOL_SOCKET, SO_REUSEADDR, &true, sizeof(int)), "setsockopt");
+
+ herr(bind(fd_socket, (struct sockaddr*)&sa_socket, sizeof(struct sockaddr_in)), "bind");
+
+ herr(listen(fd_socket, 50), "listen");
+
+ return fd_socket;
}
-int streq(const char* first, const char* second) {
- return strcmp(first, second) == 0;
+void freeVhosts(sds **vhosts, int vhostsc) {
+ for (int i = 1; i < vhostsc; i++) {
+ sdsfreesplitres(vhosts[i], 3);
+ }
+ free(vhosts);
}
int acceptConnections = 1;
@@ -52,135 +71,92 @@ int main(int argc, char* argv[]) {
/*
* Create socket for accepting connections
*/
- int fd_socket;
- herr(fd_socket = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0), "socket");
-
- struct sockaddr_in sa_socket = {
- .sin_family = AF_INET,
- .sin_port = inet_atop("8080"),
- };
- herr(inet_aton("127.0.0.1", &sa_socket.sin_addr.s_addr), "inet_aton");
-
- // Reuse address when in TIME_WAIT state, after listening socket was closed
- // https://stackoverflow.com/a/10651048/12036073
- // https://superuser.com/questions/173535/what-are-close-wait-and-time-wait-states#comment951880_173543
- int true = 1;
- herr(setsockopt(fd_socket, SOL_SOCKET, SO_REUSEADDR, &true, sizeof(int)), "setsockopt");
-
- herr(bind(fd_socket, (struct sockaddr*)&sa_socket, sizeof(struct sockaddr_in)), "bind");
-
- herr(listen(fd_socket, 50), "listen");
+ int fd_socket = createCommunicationSocket("127.0.0.1", "8080");
printf("Listening on %s:%s\n", "127.0.0.1", "8080");
/*
- * Accept connection on the socket
+ * Server command-line interface
*/
- int pid_connections = fork();
- if (pid_connections == 0) {
- // Client address
- struct sockaddr_in sa_client = {
- .sin_family = AF_INET,
- .sin_port = 0,
- .sin_addr.s_addr = 0,
- };
- socklen_t sa_client_size = sizeof(struct sockaddr_in);
-
- // Data for pselect
- fd_set rfds;
- struct timespec tv = {
- .tv_sec = 0,
- .tv_nsec = 100000,
- };
-
- int fd_client;
- int count = 0;
- int pselectStat = 0;
-
- // Effecitvely stops the cycle on SIGTERM
- signal(SIGTERM, handler_refuseConnections);
-
- while (acceptConnections) {
- /* Check if fd_socket has something we can read */
- FD_ZERO(&rfds);
- FD_SET(fd_socket, &rfds);
-
- herrc(pselect(fd_socket + 1, &rfds, NULL, NULL, &tv, NULL), "pselect");
- if (!FD_ISSET(fd_socket, &rfds)) continue;
-
- /* If so, accept the connection and pass execution to the "main" logic */
- fd_client = accept(fd_socket, (struct sockaddr*)&sa_client, &sa_client_size);
- herrc(fd_client, "accept");
- if (fd_client < 0) continue;
-
- char* strAddr = inet_ntoa(sa_client.sin_addr);
- count++;
-
- int fp = fork();
- if (fp == 0) {
- close(fd_socket);
- on_connection(strAddr, fd_client, vhosts, argc - 1);
- close(fd_client);
- freeVhosts(vhosts, argc);
- return 0;
- }
- close(fd_client);
- }
-
- while(wait(NULL) > 0);
- freeVhosts(vhosts, argc);
+ int pid_cli = fork();
+ if (pid_cli == 0) {
close(fd_socket);
-
+ handleCLI(vhosts, argc-1);
+ freeVhosts(vhosts, argc);
+ //while(wait(NULL) > 0);
return 0;
}
/*
- * Server command-line interface
+ * Define variables
*/
- close(fd_socket);
+ // Client address
+ struct sockaddr_in sa_client = {
+ .sin_family = AF_INET,
+ .sin_port = 0,
+ .sin_addr.s_addr = 0,
+ };
+ socklen_t sa_client_size = sizeof(struct sockaddr_in);
- // Get a line
- char line[256];
- fgets(line, 256, stdin);
+ int fd_client;
+ int count = 0;
+ int pselectStat = 0;
- // Get command name and it's arguments
- // Currently no command takes arguments
- char name[MAX_LEN_COMMAND+1];
- int argsAssigned = sscanf(line, COMMAND_FORMAT, name);
+ /*
+ * Handle connection requests
+ */
- while (name[0] != 'q' && name[0] != 'e' && !streq(name, "quit") && !streq(name, "exit")) {
- if (argsAssigned < 1) {
- printf("Bad command syntax!\n");
- }
- else if (streq(name, "vhosts")) {
- for (int i = 1; i < argc; i++) {
- printf("Name: \"%s\" Root dir: \"%s\" Error file: \"%s\"\n",
- vhosts[i-1][vh_user],
- vhosts[i-1][vh_path],
- vhosts[i-1][vh_error]);
- }
- }
- else if (streq(name, "help")) {
- printf("help\tPrints this message\nvhosts\tPrints all registered virtual hosts\n");
- }
- else {
- printf("Unknown command %s!\n", name);
- }
+ // Data for pselect
+ fd_set rfds;
+ struct timespec tv = {
+ /* How long should we block (wait) for fd_socket to have a request */
+ .tv_sec = 0,
+ .tv_nsec = 100000,
+ };
- // Get line and divided it into command name and arguments
- fgets(line, 256, stdin);
- argsAssigned = sscanf(line, COMMAND_FORMAT, name);
- }
+ // Stop accepting connections on SIGTERM
+ signal(SIGTERM, handler_refuseConnections);
- /*
- * Upon termination
- */
+ while (acceptConnections) {
+ /*
+ * Check if fd_socket has something we can read
+ */
- printf("Exiting...\n");
- kill(pid_connections, SIGTERM);
- while(wait(NULL) > 0);
+ FD_ZERO(&rfds);
+ FD_SET(fd_socket, &rfds);
+
+ herrc(pselect(fd_socket + 1, &rfds, NULL, NULL, &tv, NULL), "pselect");
+ if (!FD_ISSET(fd_socket, &rfds)) continue;
+
+ /*
+ * Accept the connection
+ */
+
+ fd_client = accept(fd_socket, (struct sockaddr*)&sa_client, &sa_client_size);
+ herrc(fd_client, "accept");
+ if (fd_client < 0) continue;
- freeVhosts(vhosts, argc);
+ char* strAddr = inet_ntoa(sa_client.sin_addr);
+ count++;
+
+ /*
+ * Logic when connected with client
+ */
+
+ int fp = fork();
+ if (fp == 0) {
+ close(fd_socket);
+ on_connection(strAddr, fd_client, vhosts, argc - 1);
+ close(fd_client);
+ freeVhosts(vhosts, argc);
+ return 0;
+ }
+ close(fd_client);
+ }
+
+ while(wait(NULL) > 0);
+ freeVhosts(vhosts, argc - 1);
+ close(fd_socket);
}
diff --git a/util.c b/util.c
index eae228e..8d1fa60 100644
--- a/util.c
+++ b/util.c
@@ -147,3 +147,7 @@ int digits(int num) {
// 2147483647 (2^31-1) is max value of int
return 10;
}
+
+int streq(const char* first, const char* second) {
+ return strcmp(first, second) == 0;
+}
diff --git a/util.h b/util.h
index 3bea3c2..d3e5168 100644
--- a/util.h
+++ b/util.h
@@ -19,7 +19,8 @@ sds gsub(sds str, const regex_t* regex, const char* repl);
sds gsub_getm(sds str, const regex_t *regex, const char* repl, int* *matches, int *matchesCount);
/* Other */
-int digits(int num);
#define clear_arr(arr) memset(arr, 0, sizeof(arr)/sizeof(*arr))
+int digits(int num);
+int streq(const char* first, const char* second);
#endif