aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hashtable.h2
-rw-r--r--main.c8
-rw-r--r--scriptbase_build.c104
3 files changed, 60 insertions, 54 deletions
diff --git a/hashtable.h b/hashtable.h
index 19a3897..7d85b33 100644
--- a/hashtable.h
+++ b/hashtable.h
@@ -1,7 +1,7 @@
/**
* C hashtable implementation
*
- * Copyright (C) 2021 Wojtek Kosior
+ * Copyright (C) 2018-2021 Wojtek Kosior
* Redistribution terms are gathered in the `copyright' file.
*/
diff --git a/main.c b/main.c
index b5619fe..4902585 100644
--- a/main.c
+++ b/main.c
@@ -80,7 +80,7 @@ static int process_scriptbase_subdir(struct scriptbase *base,
static int prepare_scriptbase_from_dir(const char *dir_path,
struct scriptbase *base)
{
- DIR *maindir;
+ DIR *maindir = NULL;
struct dirent *subdir;
struct stringbuf path_buf;
struct stringbuf json_buf;
@@ -91,11 +91,11 @@ static int prepare_scriptbase_from_dir(const char *dir_path,
stringbuf_init(&path_buf);
stringbuf_init(&json_buf);
- maindir = opendir(dir_path);
- if (!maindir)
+ if (scriptbase_init(base, "https://hydrilla.koszko.org/resources"))
goto end;
- if (scriptbase_init(base, "https://hydrilla.koszko.org/resources"))
+ maindir = opendir(dir_path);
+ if (!maindir)
goto end;
if (sb_sprintf(&path_buf, "%s/", dir_path))
diff --git a/scriptbase_build.c b/scriptbase_build.c
index 2bb9e80..433e839 100644
--- a/scriptbase_build.c
+++ b/scriptbase_build.c
@@ -303,47 +303,13 @@ void scriptbase_destroy(struct scriptbase *base)
free(base->repo_url);
}
-static int add_component_to_base(const char *name, const void *component,
- const char *type, struct scriptbase *base)
-{
- hashtable_t *ht = *type == 's' ? &base->scripts :
- *type == 'b' ? &base->bags : &base->pages;
- bool name_collision = false;
- void *old_val = NULL;
-
- if (ht_set(ht, name, component, NULL, &old_val)) {
- errno = ENOMEM;
- return -1;
- }
-
- if (old_val) {
- if (*type == 's') {
- name_collision = ((struct script*) old_val)->filled;
- script_free(old_val);
- } else if (*type == 'b') {
- name_collision = ((struct bag*) old_val)->filled;
- bag_free(old_val);
- } else {
- name_collision = true;
- page_free(old_val);
- }
- }
-
- if (name_collision) {
- fprintf(stderr, "Multiple occurences of %s %s.\n", type, name);
- errno = 0;
- return -1;
- }
-
- return 0;
-}
-
static int catalogue_script(const char *path, cJSON *index_json,
struct scriptbase *base)
{
const cJSON *name, *sha256, *location;
const char *bad = NULL;
struct script *script;
+ bool filling_existing = false;
name = cJSON_GetObjectItemCaseSensitive(index_json, "name");
sha256 = cJSON_GetObjectItemCaseSensitive(index_json, "sha256");
@@ -362,15 +328,32 @@ static int catalogue_script(const char *path, cJSON *index_json,
return -1;
}
- script = script_create(name->valuestring);
- if (!script)
- return -1;
+ filling_existing = !ht_get(&base->scripts, name->valuestring,
+ NULL, (void**) &script);
+
+ if (filling_existing) {
+ if (script->filled) {
+ fprintf(stderr, "Multiple occurences of script %s.\n",
+ name->valuestring);
+ errno = 0;
+ return -1;
+ }
+ } else {
+ script = script_create(name->valuestring);
+ if (!script)
+ return -1;
+ }
if (script_fill(script, path, location->valuestring,
sha256->valuestring))
goto free_script;
- return add_component_to_base(script->name, script, scriptstr, base);
+ if (!filling_existing && ht_add(&base->scripts, script->name, script)) {
+ errno = ENOMEM;
+ goto free_script;
+ }
+
+ return 0;
free_script:
script_free(script);
@@ -415,6 +398,7 @@ static int catalogue_bag(const char *path, cJSON *index_json,
const cJSON *name, *components, *component;
const char *component_type, *component_name;
struct bag *bag;
+ bool filling_existing = false;
name = cJSON_GetObjectItemCaseSensitive(index_json, "name");
@@ -424,9 +408,20 @@ static int catalogue_bag(const char *path, cJSON *index_json,
return -1;
}
- bag = bag_create(name->valuestring);
- if (!bag)
- return -1;
+ filling_existing = !ht_get(&base->bags, name->valuestring,
+ NULL, (void**) &bag);
+ if (filling_existing) {
+ if (bag->filled) {
+ fprintf(stderr, "Multiple occurences of bag %s.\n",
+ name->valuestring);
+ errno = 0;
+ return -1;
+ }
+ } else {
+ bag = bag_create(name->valuestring);
+ if (!bag)
+ return -1;
+ }
bag->filled = true;
@@ -450,8 +445,10 @@ static int catalogue_bag(const char *path, cJSON *index_json,
goto free_bag;
}
- if (add_component_to_base(bag->name, bag, bagstr, base))
+ if (!filling_existing && ht_add(&base->bags, bag->name, bag)) {
+ errno = ENOMEM;
goto free_bag;
+ }
return 0;
@@ -492,18 +489,27 @@ skip_payload:
if (!page)
goto free_page;
- if (add_component_to_base(page->pattern, page, pagestr, base))
- goto free_page;
+ switch (ht_add(&base->pages, page->pattern, page)) {
+ case 0:
+ return 0;
+ case HT_NO_MEM:
+ errno = ENOMEM;
+ break;
+ case HT_KEY_PRESENT:
+ fprintf(stderr, "Multiple occurences of pattern %s.\n",
+ page->pattern);
+ errno = 0;
+ }
- return 0;
+free_page:
+ page_free(page);
+ return -1;
invalid_payload:
fprintf(stderr, "Invalid field \"payload\"");
errno = 0;
-free_page:
- page_free(page);
- return -1;
+ return 0;
}
int catalogue_component(const char *path, cJSON *index_json,