From 91d4ce9f14668a5a04b51158b1921e83d51ba9a0 Mon Sep 17 00:00:00 2001 From: Wojtek Kosior Date: Thu, 22 Jul 2021 10:12:58 +0200 Subject: initial codebase --- main.c | 182 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 182 insertions(+) create mode 100644 main.c (limited to 'main.c') diff --git a/main.c b/main.c new file mode 100644 index 0000000..99769f2 --- /dev/null +++ b/main.c @@ -0,0 +1,182 @@ +/** + * part of Hydrilla + * Program entry point. + * + * Copyright (C) 2021 Wojtek Kosior + * Redistribution terms are gathered in the `copyright' file. + */ + +#define _POSIX_C_SOURCE 200809L /* S_IFMT, S_IFDIR */ + +#include +#include +#include +#include +#include + +#include + +#include "string_buf.h" +#include "hashtable.h" + +#include "scriptbase.h" + +#define PRESERVE_ERRNO(call) \ + do { \ + int VERY_UNLIKELY_TO_COLLIDE_NAME_$$$$$$$$##__LINE__ = errno; \ + call; \ + errno = VERY_UNLIKELY_TO_COLLIDE_NAME_$$$$$$$$##__LINE__; \ + } while (0) + +static const char default_search_path[] = "/var/lib/hydrilla/content/"; + +static int process_scriptbase_subdir(struct scriptbase *base, + struct dirent *subdir, + struct stringbuf *path_buf, + struct stringbuf *json_buf) +{ + struct stat statbuf; + cJSON *index_json; + int retval = -1; + size_t initial_len = path_buf->buf_filled, len_dirname; + + if (sb_string(path_buf, subdir->d_name)) + return -1; + + len_dirname = path_buf->buf_filled; + + if (stat(path_buf->buf, &statbuf)) + return -1; + + if ((statbuf.st_mode & S_IFMT) != S_IFDIR) + return 0; + + if (sb_string(path_buf, "/index.json")) + return -1; + + printf("Reading %s\n", path_buf->buf); + + stringbuf_truncate(json_buf, 0); + if (sb_filepath(json_buf, path_buf->buf)) + return -1; + + index_json = cJSON_Parse(json_buf->buf); + if (!index_json) { + fprintf(stderr, "Failed to parse json.\n"); + return -1; + } + + stringbuf_truncate(path_buf, len_dirname); + + retval = catalogue_component(path_buf->buf + initial_len, + index_json, base); + + PRESERVE_ERRNO(cJSON_Delete(index_json)); + + return retval; +} + +static int prepare_scriptbase_from_dir(const char *dir_path, + struct scriptbase *base) +{ + DIR *maindir; + struct dirent *subdir; + struct stringbuf path_buf; + struct stringbuf json_buf; + size_t base_path_len; + int retval = -1; + + printf("Searching %s\n", dir_path); + stringbuf_init(&path_buf); + stringbuf_init(&json_buf); + + maindir = opendir(dir_path); + if (!maindir) + goto end; + + if (scriptbase_init(base, "https://hydrilla.koszko.org/resources")) + goto end; + + if (sb_sprintf(&path_buf, "%s/", dir_path)) + goto end; + + base_path_len = path_buf.buf_filled; + + while (true) { + errno = 0; + subdir = readdir(maindir); + if (!subdir) { + if (!errno) + retval = 0; + break; + } + + if (!strcmp(subdir->d_name, "..") || + !strcmp(subdir->d_name, ".")) + continue; + + stringbuf_truncate(&path_buf, base_path_len); + + errno = 0; + if (process_scriptbase_subdir(base, subdir, + &path_buf, &json_buf)) { + fprintf(stderr, "Error processing subdirectory %s%s", + subdir->d_name, errno ? ": " : ".\n"); + if (errno) + perror(NULL); + } + } + +end: + if (errno) + perror(NULL); + stringbuf_destroy(&path_buf); + stringbuf_destroy(&json_buf); + if (maindir) + closedir(maindir); + if (retval) + scriptbase_destroy(base); + + printf("Search in %s %s.\n", dir_path, retval ? "failed" : "finished"); + + return retval; +} + +static void print_component_name(const void *key, void *val, void *arg) +{ + char type = (char) (size_t) arg; + bool unfilled; + + unfilled = + (type == 's' && !((struct script*) val)->filled) || + (type == 'b' && !((struct bag*) val)->filled); + + printf("%s%s\n", (const char*) key, + unfilled ? " (referenced only)" : ""); +} + +int serve_scriptbase(struct scriptbase *base); + +int main(int argc, char *argv[]) +{ + struct scriptbase base; + const char *search_path = default_search_path; + + if (argc > 1) + search_path = argv[1]; + + if (prepare_scriptbase_from_dir(search_path, &base)) + return -1; + puts("## LOADED SCRIPTS:"); + ht_map(&base.scripts, (void*) 's', print_component_name); + puts("## LOADED BAGS:"); + ht_map(&base.bags, (void*) 'b', print_component_name); + puts("## LOADED PAGES:"); + ht_map(&base.pages, (void*) 'p', print_component_name); + + if (serve_scriptbase(&base)) + fprintf(stderr, "Error serving scriptbase.\n"); + + scriptbase_destroy(&base); + return 0; +} -- cgit v1.2.3