diff --git a/Makefile b/Makefile index 0e29fa3..8130c17 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,12 @@ CC?=cc CFLAGS?=-pedantic -Wall -Wextra -s -Os all: - $(CC) $(CFLAGS) img.c -o 8img + $(CC) -c -I src/ -o obj/db.o src/db.c + $(CC) -c -I src/ -o obj/config.o src/config.c + $(CC) -c -I src/ -o obj/builder.o src/builder.c + $(CC) -c -I src/ -o obj/funcs.o src/funcs.c + + $(CC) $(CFLAGS) -I src -o 8img obj/db.o obj/config.o obj/builder.o obj/funcs.o src/main.c clean: - rm 8img + rm obj/* diff --git a/config b/config index 037e767..b2ca522 100644 --- a/config +++ b/config @@ -2,19 +2,17 @@ ROOT www # Html generator -CSS style.css -LOGO logo.png - -DESC 8img -TITLE / img -POST_PER_PAGE 5 +CSS style.css +LOGO logo.png +DESC 8img +TITLE / img +POSTS_AT_PAGE 5 # RSS generator -LINK https://nlight.tilde.team/img/ -XML_FILE index.xml - -LANGUAGE en-US -MAX_POST_COUNT 20 +LINK https://nlight.tilde.team/img/ +XML_FILE index.xml +LANGUAGE en-US +MAX_POSTS 20 # Date DATE_FORMAT %a, %d %h %Y %H:%M:%S %z diff --git a/obj/.gitignore b/obj/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/src/builder.c b/src/builder.c index f3589ac..7f82400 100644 --- a/src/builder.c +++ b/src/builder.c @@ -25,7 +25,7 @@ char *GetDate(const char *fmt, time_t time) { } struct DB_STR *build_html_page(const struct CONFIG cfg, FILE *fp, const char *file, const struct UNIQ_TAGS ut, struct DB_STR *db, const size_t page, const size_t pages) { - fprintf(fp, "\n\n\n%s\n\n\n\n
\n

%s | RSS
%s/p%zu

\n", CSS, TITLE, LOGO, DESC, XML_FILE, file, page); + fprintf(fp, "\n\n\n%s\n\n\n\n
\n

%s | RSS
%s/p%zu

\n", cfg.css, cfg.title, cfg.logo, cfg.desc, cfg.xml_file, file, page); /* Tags */ fputs("
\nall", fp); @@ -150,7 +150,7 @@ void build_xml(const struct CONFIG cfg, struct DB_STR *db) { return; /* Header */ - fprintf(fp, "\n\n\n\t\n\t%s\n\t%s\n\t%s\n\t%s\n", LINK, TITLE, LINK, DESC, LANGUAGE); + fprintf(fp, "\n\n\n\t\n\t%s\n\t%s\n\t%s\n\t%s\n", cfg.link, cfg.desc, cfg.link, cfg.desc, cfg.language); /* Content */ size_t count = 0; @@ -161,15 +161,15 @@ void build_xml(const struct CONFIG cfg, struct DB_STR *db) { /* Post */ fprintf(fp, "\n\n\t%s\n\t%s%s%s\n\t%s%s%s\n\t\n\t\t%s\t\n\tplup

\n\t\t

", bckp->filename, - LINK, CHECK_URL(LINK), bckp->filename, - LINK, CHECK_URL(LINK), bckp->filename, + cfg.link, CHECK_URL(cfg.link), bckp->filename, + cfg.link, CHECK_URL(cfg.link), bckp->filename, GetDate(cfg.date_fmt, bckp->birthtime), - LINK, CHECK_URL(LINK), bckp->filename); + cfg.link, CHECK_URL(cfg.link), bckp->filename); /* Tags */ for (size_t i = 0; i < bckp->size; i++) fprintf(fp, " %s  ", - LINK, CHECK_URL(LINK), bckp->tags[i], + cfg.link, CHECK_URL(cfg.link), bckp->tags[i], bckp->tags[i]); fputs("

\n\t]]>
\n
", fp); diff --git a/src/config.c b/src/config.c index 062b5d4..9b043e1 100644 --- a/src/config.c +++ b/src/config.c @@ -1,7 +1,122 @@ +#include +#include +#include +#include +#include #include "funcs.h" #include "config.h" -int parse_config(struct CONFIG *cfg, const char *cfg_path) { - cfg->root = "www"; +void free_cfg(struct CONFIG *cfg) { + char **var1[] = {&cfg->root, &cfg->css, &cfg->logo, &cfg->desc, &cfg->title, &cfg->link, &cfg->xml_file, &cfg->language, &cfg->date_fmt}; + char var2[] = {cfg->root_alloc, cfg->css_alloc, cfg->logo_alloc, cfg->desc_alloc, cfg->title_alloc, cfg->link_alloc, cfg->xml_file_alloc, cfg->language_alloc, cfg->date_fmt_alloc}; + + for (size_t i = 0; i < sizeof(var2); i++) + if (var2[i] && *(var1[i])) + free(*(var1[i])); +} + +const char *skip_space(const char *str) { + const char *ptr = str; + while (isspace(*ptr)) + ptr++; + + return ptr; +} + +int add_str(const char *prog_name, char **dst, char *flag, const char *src) { + if (!(*src)) + return 1; + + *dst = strdup(skip_space(src)); + if (*dst == NULL) { + fprintf(stderr, "%s: strdup: %s\n", prog_name, strerror(errno)); + return 1; + } + + *flag = 1; return 0; } + +int add_int(const char *prog_name, size_t line, size_t *dst, const char *src) { + char *ptr = ""; + *dst = strtoul(skip_space(src), &ptr, 10); + + if (*ptr) { + fprintf(stderr, "%s: incorrect number at line %zu: %s\n", prog_name, line, ptr); + return 1; + } + + return 0; +} + +int parse_config(struct CONFIG *cfg, const char *cfg_path) { + FILE *fp = file_open(cfg->prog_name, cfg_path, "r"); + if (fp == NULL) + return 1; + + char *str = NULL; + ssize_t bytes = 0; + size_t n = 0; + + size_t line = 0; + int ret = 0; + + while ((bytes = getline(&str, &n, fp)) > 0 && ret == 0) { + line++; + if (str[0] == '\0' || str[0] == '\n' || str[0] == '#') + continue; + + char *ptr = strrchr(str, '\n'); + if (ptr != NULL) + *ptr = '\0'; + + if ((ptr = strstr(str, "ROOT"))) + ret = add_str(cfg->prog_name, &cfg->root, &cfg->root_alloc, ptr + sizeof("ROOT")); + + else if ((ptr = strstr(str, "CSS"))) + ret = add_str(cfg->prog_name, &cfg->css, &cfg->css_alloc, ptr + sizeof("CSS")); + + else if ((ptr = strstr(str, "LOGO"))) + ret = add_str(cfg->prog_name, &cfg->logo, &cfg->logo_alloc, ptr + sizeof("LOGO")); + + else if ((ptr = strstr(str, "DESC"))) + ret = add_str(cfg->prog_name, &cfg->desc, &cfg->desc_alloc, ptr + sizeof("DESC")); + + else if ((ptr = strstr(str, "TITLE"))) + ret = add_str(cfg->prog_name, &cfg->title, &cfg->title_alloc, ptr + sizeof("TITLE")); + + else if ((ptr = strstr(str, "LINK"))) + ret = add_str(cfg->prog_name, &cfg->link, &cfg->link_alloc, ptr + sizeof("LINK")); + + else if ((ptr = strstr(str, "XML_FILE"))) + ret = add_str(cfg->prog_name, &cfg->xml_file, &cfg->xml_file_alloc, ptr + sizeof("XML_FILE")); + + else if ((ptr = strstr(str, "LANGUAGE"))) + ret = add_str(cfg->prog_name, &cfg->language, &cfg->language_alloc, ptr + sizeof("LANGUAGE")); + + else if ((ptr = strstr(str, "DATE_FORMAT"))) + ret = add_str(cfg->prog_name, &cfg->date_fmt, &cfg->date_fmt_alloc, ptr + sizeof("DATE_FORMAT")); + + else if ((ptr = strstr(str, "POSTS_AT_PAGE"))) + ret = add_int(cfg->prog_name, line, &cfg->posts_at_page, ptr + sizeof("POSTS_AT_PAGE")); + + else if ((ptr = strstr(str, "MAX_POSTS"))) + ret = add_int(cfg->prog_name, line, &cfg->max_posts, ptr + sizeof("MAX_POSTS")); + + else { + fprintf(stderr, "%s: syntax error on %zu: %s\n", cfg->prog_name, line, str); + ret = 1; + } + } + + fclose(fp); + if (str) + free(str); + + if (ret) { + fprintf(stderr, "%s: parser error\n", cfg->prog_name); + free_cfg(cfg); + } + + return ret; +} diff --git a/src/config.h b/src/config.h index 329cc6a..c51da09 100644 --- a/src/config.h +++ b/src/config.h @@ -56,25 +56,41 @@ struct CONFIG { char *prog_name; char *root; + char root_alloc; /* HTML */ char *css; - char *logo; - char *desc; - char *title; - size_t posts_at_page; + char css_alloc; + char *logo; + char logo_alloc; + + char *desc; + char desc_alloc; + + char *title; + char title_alloc; + + size_t posts_at_page; /* RSS */ char *link; + char link_alloc; + char *xml_file; + char xml_file_alloc; + char *language; + char language_alloc; + size_t max_posts; /* Date format */ char *date_fmt; + char date_fmt_alloc; }; +void free_cfg(struct CONFIG *cfg); int parse_config(struct CONFIG *cfg, const char *cfg_path); #endif diff --git a/src/main.c b/src/main.c index 0faa8a4..82b10b4 100644 --- a/src/main.c +++ b/src/main.c @@ -11,7 +11,7 @@ struct CONFIG cfg; void help(void) { - //// + free_cfg(&cfg); printf("%s -[f:d:h] [add/rebuild/version/del]:\n\tadd [img] [tag1] [tag2]...\n\trebuild\n\tversion\n\tdel [image id]\n\nOptions:\n\t-d STR set description\n\t-f STR Path to config file\n\t-h This menu\n", cfg.prog_name); exit(0); @@ -196,7 +196,7 @@ int main(int argc, char **argv) { if (chdir(cfg.root) < 0) { fprintf(stderr, "%s: chdir: %s\n", cfg.prog_name, strerror(errno)); - //// + free_cfg(&cfg); return 1; } @@ -216,12 +216,11 @@ int main(int argc, char **argv) { ret = rebuild(cfg); else if (!strcmp(argv[0], "version")) - printf("%s (8img) version: 2.0.1\nWritten under WTFPL License.\n", cfg.prog_name); + printf("%s (8img) version: 2.0.2\nWritten under WTFPL License.\n", cfg.prog_name); else help(); - //// + free_cfg(&cfg); return ret; } -