From 3227e615feec1d84d132051b645b797cf9b2c859 Mon Sep 17 00:00:00 2001
From: Lorenz Stechauner <lorenz.stechauner@necronda.net>
Date: Thu, 15 Dec 2022 11:26:40 +0100
Subject: [PATCH] Use getopt_long

---
 src/client.c    |  3 +--
 src/lib/cache.c | 15 +++++++-------
 src/lib/cache.h |  6 +-----
 src/server.c    | 52 +++++++++++++++++++++++++++++++------------------
 4 files changed, 43 insertions(+), 33 deletions(-)

diff --git a/src/client.c b/src/client.c
index bb81b60..ba05004 100644
--- a/src/client.c
+++ b/src/client.c
@@ -254,8 +254,7 @@ int client_request_handler(client_ctx_t *cctx, sock *client, unsigned long clien
                 goto respond;
             }
 
-            ret = uri_cache_init(&uri);
-            if (ret != 0) {
+            if ((ret = cache_init_uri(&uri)) != 0) {
                 res.status = http_get_status(500);
                 sprintf(err_msg, "Unable to communicate with internal file cache.");
                 goto respond;
diff --git a/src/lib/cache.c b/src/lib/cache.c
index 468d99f..efe1f73 100644
--- a/src/lib/cache.c
+++ b/src/lib/cache.c
@@ -25,16 +25,17 @@ int cache_continue = 1;
 magic_t magic;
 cache_entry *cache;
 
-int magic_init(void) {
-    magic = magic_open(MAGIC_MIME);
-    if (magic == NULL) {
+static int magic_init(void) {
+    if ((magic = magic_open(MAGIC_MIME)) == NULL) {
         critical("Unable to open magic cookie");
-        return -1;
+        return 1;
     }
+
     if (magic_load(magic, CACHE_MAGIC_FILE) != 0) {
         critical("Unable to load magic cookie: %s", magic_error(magic));
-        return -2;
+        return 1;
     }
+
     return 0;
 }
 
@@ -288,7 +289,7 @@ int cache_unload(void) {
     return 0;
 }
 
-int cache_update_entry(int entry_num, const char *filename, const char *webroot) {
+static int cache_update_entry(int entry_num, const char *filename, const char *webroot) {
     void *cache_ro = cache;
     int shm_id = shmget(CACHE_SHM_KEY, 0, 0);
     void *shm_rw = shmat(shm_id, NULL, 0);
@@ -364,7 +365,7 @@ int cache_filename_comp_invalid(const char *filename) {
     return 0;
 }
 
-int uri_cache_init(http_uri *uri) {
+int cache_init_uri(http_uri *uri) {
     if (uri->filename == NULL) {
         return 0;
     }
diff --git a/src/lib/cache.h b/src/lib/cache.h
index 47ac23d..32f55ac 100644
--- a/src/lib/cache.h
+++ b/src/lib/cache.h
@@ -31,8 +31,6 @@ extern cache_entry *cache;
 
 extern int cache_continue;
 
-int magic_init(void);
-
 void cache_process_term(int _);
 
 int cache_process(void);
@@ -41,10 +39,8 @@ int cache_init(void);
 
 int cache_unload(void);
 
-int cache_update_entry(int entry_num, const char *filename, const char *webroot);
-
 int cache_filename_comp_invalid(const char *filename);
 
-int uri_cache_init(http_uri *uri);
+int cache_init_uri(http_uri *uri);
 
 #endif //SESIMOS_CACHE_H
diff --git a/src/server.c b/src/server.c
index 8600512..61d7d7c 100644
--- a/src/server.c
+++ b/src/server.c
@@ -19,6 +19,7 @@
 #include "lib/utils.h"
 
 #include <stdio.h>
+#include <getopt.h>
 #include <sys/socket.h>
 #include <signal.h>
 #include <unistd.h>
@@ -145,7 +146,7 @@ void terminate_gracefully(int sig) {
     exit(0);
 }
 
-int main(int argc, const char *argv[]) {
+int main(int argc, char *const argv[]) {
     const int YES = 1;
     struct pollfd poll_fds[NUM_SOCKETS];
     int ready_sockets_num;
@@ -171,32 +172,45 @@ int main(int argc, const char *argv[]) {
     }
     printf("Sesimos web server " SERVER_VERSION "\n");
 
+    static const struct option long_opts[] = {
+            {"help",    no_argument,        0, 'h'},
+            {"config",  required_argument,  0, 'c'},
+            { 0,        0,                  0,  0 }
+    };
+
     config_file = NULL;
-    for (int i = 1; i < argc; i++) {
-        const char *arg = argv[i];
-        if (strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0) {
-            printf("Usage: sesimos [-h] [-c <CONFIG-FILE>]\n"
-                   "\n"
-                   "Options:\n"
-                   "  -c, --config <CONFIG-FILE>  path to the config file. If not provided, default will be used\n"
-                   "  -h, --help                  print this dialogue\n");
-            return 0;
-        } else if (strcmp(arg, "-c") == 0 || strcmp(arg, "--config") == 0) {
-            if (i == argc - 1) {
-                critical("Unable to parse argument %s, usage: --config <CONFIG-FILE>", arg);
+    int c, opt_idx;
+    while ((c = getopt_long(argc, argv, "hc:", long_opts, &opt_idx)) != -1) {
+        switch (c) {
+            case 'h':
+                fprintf(stderr,
+                        "Usage: sesimos [-h] [-c <CONFIG FILE>]\n"
+                        "\n"
+                        "Options:\n"
+                        "  -c, --config <CONFIG-FILE>  path to the config file. If not provided, default will be used\n"
+                        "  -h, --help                  print this dialogue\n");
+                return 0;
+            case 'c':
+                config_file = optarg;
+                break;
+            case '?':
+            default:
+                critical("Unable to parse arguments");
                 return 1;
-            }
-            config_file = argv[++i];
-        } else {
-            critical("Unable to parse argument '%s'", arg);
-            return 1;
         }
     }
 
+    if (optind != argc) {
+        critical("No positional arguments expected");
+        return 1;
+    }
+
     if (config_load(config_file == NULL ? DEFAULT_CONFIG_FILE : config_file) != 0)
         return 1;
 
-    if ((sockets[0] = socket(AF_INET6, SOCK_STREAM, 0)) == - 1 || (sockets[1] = socket(AF_INET6, SOCK_STREAM, 0)) == -1) {
+    if ((sockets[0] = socket(AF_INET6, SOCK_STREAM, 0)) == -1 ||
+        (sockets[1] = socket(AF_INET6, SOCK_STREAM, 0)) == -1)
+    {
         critical("Unable to create socket");
         return 1;
     }