]> git.seodisparate.com - c_simple_http/commitdiff
Cleanup by separating "generate" to source files
authorStephen Seo <seo.disparate@gmail.com>
Sun, 10 Nov 2024 12:06:41 +0000 (21:06 +0900)
committerStephen Seo <seo.disparate@gmail.com>
Sun, 10 Nov 2024 12:06:41 +0000 (21:06 +0900)
CMakeLists.txt
Makefile
src/generate.c [new file with mode: 0644]
src/generate.h [new file with mode: 0644]
src/helpers.h
src/main.c

index 03651120b1eeb9de60d9c60203b8481448a6a689..3dd574339b1823af60c28373063945f8df4fb748 100644 (file)
@@ -13,6 +13,7 @@ set(c_simple_http_SOURCES
   "${CMAKE_CURRENT_SOURCE_DIR}/src/helpers.c"
   "${CMAKE_CURRENT_SOURCE_DIR}/src/html_cache.c"
   "${CMAKE_CURRENT_SOURCE_DIR}/src/static.c"
+  "${CMAKE_CURRENT_SOURCE_DIR}/src/generate.c"
   "${CMAKE_CURRENT_SOURCE_DIR}/third_party/SimpleArchiver/src/helpers.c"
   "${CMAKE_CURRENT_SOURCE_DIR}/third_party/SimpleArchiver/src/data_structures/linked_list.c"
   "${CMAKE_CURRENT_SOURCE_DIR}/third_party/SimpleArchiver/src/data_structures/hash_map.c"
index f6c80a8b892c388c5a5c1cd3e6259e937b67b668..492fd586e6ec8731f6d3448dd4205d8281e61a26 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -44,7 +44,8 @@ HEADERS = \
        src/http_template.h \
        src/helpers.h \
        src/html_cache.h \
-       src/static.h
+       src/static.h \
+       src/generate.h
 
 SOURCES = \
                src/main.c \
@@ -59,6 +60,7 @@ SOURCES = \
                src/helpers.c \
                src/html_cache.c \
                src/static.c \
+               src/generate.c \
                third_party/SimpleArchiver/src/helpers.c \
                third_party/SimpleArchiver/src/data_structures/linked_list.c \
                third_party/SimpleArchiver/src/data_structures/hash_map.c \
diff --git a/src/generate.c b/src/generate.c
new file mode 100644 (file)
index 0000000..1909071
--- /dev/null
@@ -0,0 +1,175 @@
+// ISC License
+// 
+// Copyright (c) 2024 Stephen Seo
+// 
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include "generate.h"
+
+// Standard library includes.
+#include <string.h>
+
+// Linux/Unix includes.
+#include <libgen.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <errno.h>
+#include <unistd.h>
+
+// Local includes.
+#include "helpers.h"
+#include "http_template.h"
+
+// Third party includes.
+#include <SimpleArchiver/src/helpers.h>
+#include <SimpleArchiver/src/data_structures/hash_map.h>
+#include <SimpleArchiver/src/data_structures/linked_list.h>
+
+int c_simple_http_generate_paths_fn(const void *key,
+                                    size_t key_size,
+                                    __attribute__((unused)) const void *value,
+                                    void *ud) {
+  const char *path = key;
+  const ConnectionContext *ctx = ud;
+  const char *generate_dir = ctx->args->generate_dir;
+
+  const unsigned long path_len = key_size - 1;
+  const unsigned long generate_dir_len = strlen(generate_dir);
+
+  __attribute__((cleanup(simple_archiver_list_free)))
+  SDArchiverLinkedList *string_parts = simple_archiver_list_init();
+
+  // Add generate_dir as first path of paths to join.
+  c_simple_http_add_string_part(string_parts, generate_dir, 0);
+
+  // Ensure next character after generate_dir contains a '/' if generate_dir
+  // didn't contain one at the end.
+  if (generate_dir_len > 0 && generate_dir[generate_dir_len - 1] != '/') {
+    c_simple_http_add_string_part(string_parts, "/", 0);
+  }
+
+  // Append the path.
+  if (strcmp(path, "/") != 0) {
+    // Is not root.
+    uint32_t idx = 0;
+    while (idx <= path_len && path[idx] == '/') {
+      ++idx;
+    }
+    c_simple_http_add_string_part(string_parts, path + idx, 0);
+  }
+
+  // Add the final '/'.
+  if (path_len > 0 && path[path_len - 1] != '/') {
+    c_simple_http_add_string_part(string_parts, "/", 0);
+  }
+
+  // Add the ending "index.html".
+  c_simple_http_add_string_part(string_parts, "index.html", 0);
+
+  // Get the combined string.
+  __attribute__((cleanup(simple_archiver_helper_cleanup_c_string)))
+  char *generated_path = c_simple_http_combine_string_parts(string_parts);
+  if (!generated_path) {
+    fprintf(stderr, "ERROR Failed to get generated path (path: %s)!\n", path);
+    return 1;
+  }
+
+  if ((ctx->args->flags & 4) == 0) {
+    // Overwrite not enabled, check if file already exists.
+    FILE *fd = fopen(generated_path, "rb");
+    if (fd) {
+      fclose(fd);
+      fprintf(
+        stderr,
+        "WARNING Path \"%s\" exists and \"--generate-enable-overwrite\" not "
+          "specified, skipping!\n",
+        generated_path);
+      return 0;
+    }
+  }
+
+  // Ensure the required dirs exist.
+  __attribute__((cleanup(simple_archiver_helper_cleanup_c_string)))
+  char *generated_path_dup = strdup(generated_path);
+
+  uint_fast8_t did_make_generated_path_dir = 0;
+  char *generated_path_dir = dirname(generated_path_dup);
+  if (generated_path_dir) {
+    DIR *fd = opendir(generated_path_dir);
+    if (!fd) {
+      if (errno == ENOENT) {
+        c_simple_http_helper_mkdir_tree(generated_path_dir);
+        did_make_generated_path_dir = 1;
+      } else {
+        fprintf(stderr,
+                "ERROR opendir on path dirname failed unexpectedly (path: %s)!"
+                  "\n",
+                path);
+        return 1;
+      }
+    } else {
+      // Directory already exists.
+      closedir(fd);
+    }
+  } else {
+    fprintf(stderr,
+            "ERROR Failed to get dirname of generated path dir (path: %s)"
+              "!\n",
+            path);
+    return 1;
+  }
+
+  // Generate the html.
+  size_t html_buf_size = 0;
+  __attribute__((cleanup(simple_archiver_helper_cleanup_c_string)))
+  char *html_buf = c_simple_http_path_to_generated(path,
+                                                   ctx->parsed,
+                                                   &html_buf_size,
+                                                   NULL);
+  if (!html_buf || html_buf_size == 0) {
+    fprintf(stderr,
+            "WARNING Failed to generate html for generate (path: %s), "
+              "skipping!\n",
+            path);
+    if (did_make_generated_path_dir) {
+      if (rmdir(generated_path_dir) == -1) {
+        fprintf(stderr,
+                "WARNING rmdir on generated_path_dir failed, errno: %d\n",
+                errno);
+      }
+    }
+    return 0;
+  }
+
+  // Save the html.
+  FILE *fd = fopen(generated_path, "wb");
+  if (!fd) {
+    fprintf(stderr,
+            "WARNING Failed to open \"%s\" for writing, skipping!\n",
+            generated_path);
+    return 0;
+  }
+  unsigned long fwrite_ret = fwrite(html_buf, 1, html_buf_size, fd);
+  if (fwrite_ret < html_buf_size) {
+    fclose(fd);
+    unlink(generated_path);
+    fprintf(stderr,
+            "ERROR Unable to write entirely to \"%s\"!\n",
+            generated_path);
+    return 1;
+  } else {
+    fclose(fd);
+  }
+
+  return 0;
+}
diff --git a/src/generate.h b/src/generate.h
new file mode 100644 (file)
index 0000000..9f5261a
--- /dev/null
@@ -0,0 +1,30 @@
+// ISC License
+// 
+// Copyright (c) 2024 Stephen Seo
+// 
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef SEODISPARATE_COM_C_SIMPLE_HTTP_GENERATE_H_
+#define SEODISPARATE_COM_C_SIMPLE_HTTP_GENERATE_H_
+
+#include <stdlib.h>
+
+/// See this function's usage in main.c.
+int c_simple_http_generate_paths_fn(const void *key,
+                                    size_t key_size,
+                                    const void *value,
+                                    void *ud);
+
+#endif
+
+// vim: et ts=2 sts=2 sw=2
index 5e1bd9f2280830055cc8e015d8f31cb6d529fbf0..a428388e48fe55dbb75b6824d49901de5e61b214 100644 (file)
 #include <stddef.h>
 #include <stdint.h>
 
+// libc includes.
+#include <time.h>
+
+// Local includes.
+#include "config.h"
+#include "arg_parse.h"
+
 // Third-party includes.
 #include <SimpleArchiver/src/data_structures/linked_list.h>
 
+typedef struct ConnectionContext {
+  char *buf;
+  const Args *args;
+  C_SIMPLE_HTTP_ParsedConfig *parsed;
+  struct timespec current_time;
+} ConnectionContext;
+
 typedef struct C_SIMPLE_HTTP_String_Part {
   char *buf;
   size_t size;
index 1f8466e37987231a2cbd188b7606ff39d530c764..988f67af4cb5a358a4a1d91d9b9b4d721848c973 100644 (file)
 #include <stdint.h>
 
 // Linux/Unix includes.
-#include <libgen.h>
 #include <sys/socket.h>
-#include <sys/types.h>
-#include <dirent.h>
 #include <netinet/in.h>
 #include <unistd.h>
 #include <signal.h>
@@ -46,6 +43,7 @@
 #include "http_template.h"
 #include "tcp_socket.h"
 #include "signal_handling.h"
+#include "generate.h"
 #include "globals.h"
 #include "constants.h"
 #include "http.h"
@@ -80,13 +78,6 @@ typedef struct ConnectionItem {
   struct in6_addr peer_addr;
 } ConnectionItem;
 
-typedef struct ConnectionContext {
-  char *buf;
-  const Args *args;
-  C_SIMPLE_HTTP_ParsedConfig *parsed;
-  struct timespec current_time;
-} ConnectionContext;
-
 void c_simple_http_cleanup_connection_item(void *data) {
   ConnectionItem *citem = data;
   if (citem) {
@@ -332,145 +323,6 @@ int c_simple_http_manage_connections(void *data, void *ud) {
   return 1;
 }
 
-int generate_paths_fn(const void *key,
-                      size_t key_size,
-                      const void *value,
-                      void *ud) {
-  const char *path = key;
-  const ConnectionContext *ctx = ud;
-  const char *generate_dir = ctx->args->generate_dir;
-
-  const unsigned long path_len = strlen(path);
-  const unsigned long generate_dir_len = strlen(generate_dir);
-
-  __attribute__((cleanup(simple_archiver_list_free)))
-  SDArchiverLinkedList *string_parts = simple_archiver_list_init();
-
-  // Add generate_dir as first path of paths to join.
-  c_simple_http_add_string_part(string_parts, generate_dir, 0);
-
-  // Ensure next character after generate_dir contains a '/' if generate_dir
-  // didn't contain one at the end.
-  if (generate_dir_len > 0 && generate_dir[generate_dir_len - 1] != '/') {
-    c_simple_http_add_string_part(string_parts, "/", 0);
-  }
-
-  // Append the path.
-  if (strcmp(path, "/") != 0) {
-    // Is not root.
-    uint32_t idx = 0;
-    while (idx <= path_len && path[idx] == '/') {
-      ++idx;
-    }
-    c_simple_http_add_string_part(string_parts, path + idx, 0);
-  }
-
-  // Add the final '/'.
-  if (path_len > 0 && path[path_len - 1] != '/') {
-    c_simple_http_add_string_part(string_parts, "/", 0);
-  }
-
-  // Add the ending "index.html".
-  c_simple_http_add_string_part(string_parts, "index.html", 0);
-
-  // Get the combined string.
-  __attribute__((cleanup(simple_archiver_helper_cleanup_c_string)))
-  char *generated_path = c_simple_http_combine_string_parts(string_parts);
-  if (!generated_path) {
-    fprintf(stderr, "ERROR Failed to get generated path (path: %s)!\n", path);
-    return 1;
-  }
-
-  if ((ctx->args->flags & 4) == 0) {
-    // Overwrite not enabled, check if file already exists.
-    FILE *fd = fopen(generated_path, "rb");
-    if (fd) {
-      fclose(fd);
-      fprintf(
-        stderr,
-        "WARNING Path \"%s\" exists and \"--generate-enable-overwrite\" not "
-          "specified, skipping!\n",
-        generated_path);
-      return 0;
-    }
-  }
-
-  // Ensure the required dirs exist.
-  __attribute__((cleanup(simple_archiver_helper_cleanup_c_string)))
-  char *generated_path_dup = strdup(generated_path);
-
-  uint_fast8_t did_make_generated_path_dir = 0;
-  char *generated_path_dir = dirname(generated_path_dup);
-  if (generated_path_dir) {
-    DIR *fd = opendir(generated_path_dir);
-    if (!fd) {
-      if (errno == ENOENT) {
-        c_simple_http_helper_mkdir_tree(generated_path_dir);
-        did_make_generated_path_dir = 1;
-      } else {
-        fprintf(stderr,
-                "ERROR opendir on path dirname failed unexpectedly (path: %s)!"
-                  "\n",
-                path);
-        return 1;
-      }
-    } else {
-      // Directory already exists.
-      closedir(fd);
-    }
-  } else {
-    fprintf(stderr,
-            "ERROR Failed to get dirname of generated path dir (path: %s)"
-              "!\n",
-            path);
-    return 1;
-  }
-
-  // Generate the html.
-  size_t html_buf_size = 0;
-  __attribute__((cleanup(simple_archiver_helper_cleanup_c_string)))
-  char *html_buf = c_simple_http_path_to_generated(path,
-                                                   ctx->parsed,
-                                                   &html_buf_size,
-                                                   NULL);
-  if (!html_buf || html_buf_size == 0) {
-    fprintf(stderr,
-            "WARNING Failed to generate html for generate (path: %s), "
-              "skipping!\n",
-            path);
-    if (did_make_generated_path_dir) {
-      if (rmdir(generated_path_dir) == -1) {
-        fprintf(stderr,
-                "WARNING rmdir on generated_path_dir failed, errno: %d\n",
-                errno);
-      }
-    }
-    return 0;
-  }
-
-  // Save the html.
-  FILE *fd = fopen(generated_path, "wb");
-  if (!fd) {
-    fprintf(stderr,
-            "WARNING Failed to open \"%s\" for writing, skipping!\n",
-            generated_path);
-    return 0;
-  }
-  unsigned long fwrite_ret = fwrite(html_buf, 1, html_buf_size, fd);
-  if (fwrite_ret < html_buf_size) {
-    fclose(fd);
-    unlink(generated_path);
-    fprintf(stderr,
-            "ERROR Unable to write entirely to \"%s\"!\n",
-            generated_path);
-    return 1;
-  } else {
-    fclose(fd);
-  }
-
-  return 0;
-}
-
 int main(int argc, char **argv) {
   __attribute__((cleanup(c_simple_http_free_args)))
   Args args = parse_args(argc, argv);
@@ -500,7 +352,7 @@ int main(int argc, char **argv) {
     ctx.args = &args;
     ctx.parsed = &parsed_config;
     if (simple_archiver_hash_map_iter(parsed_config.paths,
-                                      generate_paths_fn,
+                                      c_simple_http_generate_paths_fn,
                                       &ctx)) {
       fprintf(stderr, "ERROR during generating!\n");
       return 1;