foo
authorJohn Tsiombikas <nuclear@member.fsf.org>
Tue, 28 Jul 2020 21:23:14 +0000 (00:23 +0300)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Tue, 28 Jul 2020 21:23:14 +0000 (00:23 +0300)
server/src/main.c

index a3174d1..12bb01f 100644 (file)
@@ -1,19 +1,30 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <errno.h>
 #include <limits.h>
 #include <time.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/select.h>
+#include <netinet/in.h>
 #include "repo.h"
-
-#include "md5.h"
+#include "client.h"
 
 static const char *guess_repo_name(const char *path);
 static int parse_args(int argc, char **argv);
 
 static const char *repo_path, *repo_name;
+static int lis = -1;
+static int port = 64357;
+
+static struct client *clients;
 
 int main(int argc, char **argv)
 {
+       struct sockaddr_in addr;
+
        if(parse_args(argc, argv) == -1) {
                return 1;
        }
@@ -31,15 +42,73 @@ int main(int argc, char **argv)
 
        printf("Serving %s from %s\n", repo_name, repo_path);
 
-       /* DBG */
-       {
-               struct md5_state sum;
-               int i, count = repo_num_files();
-               for(i=0; i<count; i++) {
-                       struct repo_file *file = repo_file(i);
-                       memcpy(sum.sum, file->chksum, sizeof sum.sum);
-                       printf("%s\tmd5:%s size:%lu mtime:%s", file->path, md5_sumstr(&sum),
-                                       (unsigned long)file->size, ctime(&file->mtime));
+       if(!(lis = socket(PF_INET, SOCK_STREAM, 0))) {
+               fprintf(stderr, "failed to create socket: %s\n", strerror(errno));
+               return 1;
+       }
+
+       memset(&addr, 0, sizeof addr);
+       addr.sin_family = AF_INET;
+       addr.sin_port = htons(port);
+       addr.sin_addr.s_addr = INADDR_ANY;
+
+       if(bind(lis, (struct sockaddr*)&addr, sizeof addr) == -1) {
+               fprintf(stderr, "failed to bind listening socket to port %d\n", port);
+               return 1;
+       }
+       listen(lis, 8);
+
+       for(;;) {
+               int res, max_fd, s;
+               fd_set rdset;
+               struct client *c, dummy;
+
+               FD_SET(lis, &rdset);
+               max_fd = lis;
+
+               c = clients;
+               while(c) {
+                       FD_SET(c->s, &rdset);
+                       if(c->s > max_fd) max_fd = c->s;
+                       c = c->next;
+               }
+
+               if((res = select(max_fd + 1, &rdset, 0, 0, 0)) == -1 && errno != EINTR) {
+                       perror("select failed");
+                       break;
+               }
+
+               if(res <= 0) continue;
+
+               dummy.next = clients;
+               c = &dummy;
+               while(c->next) {
+                       if(FD_ISSET(c->next->s, &rdset)) {
+                               if(handle_client(c->next) == -1) {
+                                       struct client *tmp = c->next;
+                                       c->next = tmp->next;
+                                       close(tmp->s);
+                                       free(tmp);
+                                       continue;
+                               }
+                       }
+                       c = c->next;
+               }
+               clients = dummy.next;
+
+               if(FD_ISSET(lis, &rdset)) {
+                       if((s = accept(lis, 0, 0)) == -1) {
+                               perror("failed to accept connection");
+                               continue;
+                       }
+                       if(!(c = malloc(sizeof *c))) {
+                               perror("failed to allocate memory for client structure");
+                               close(s);
+                               continue;
+                       }
+                       c->s = s;
+                       c->next = clients;
+                       clients = c;
                }
        }