isplit libgcgi.h into a .c and .h file - libgcgi - REST library for Gopher Err bitreich.org 70
hgit clone git://bitreich.org/libgcgi git://hg6vgqziawt5s4dj.onion/libgcgi URL:git://bitreich.org/libgcgi git://hg6vgqziawt5s4dj.onion/libgcgi bitreich.org 70
1Log /scm/libgcgi/log.gph bitreich.org 70
1Files /scm/libgcgi/files.gph bitreich.org 70
1Refs /scm/libgcgi/refs.gph bitreich.org 70
1Tags /scm/libgcgi/tag bitreich.org 70
1README /scm/libgcgi/file/README.gph bitreich.org 70
1LICENSE /scm/libgcgi/file/LICENSE.gph bitreich.org 70
i--- Err bitreich.org 70
1commit 052f666afd7390d53ec4b3ad91882e7e76b7a49f /scm/libgcgi/commit/052f666afd7390d53ec4b3ad91882e7e76b7a49f.gph bitreich.org 70
1parent 5bc5afc6bfca4948fee87a59a87aede28f2de765 /scm/libgcgi/commit/5bc5afc6bfca4948fee87a59a87aede28f2de765.gph bitreich.org 70
hAuthor: Josuah Demangeon <me@josuah.net> URL:mailto:me@josuah.net bitreich.org 70
iDate: Sat, 30 Jul 2022 13:38:07 +0200 Err bitreich.org 70
i Err bitreich.org 70
isplit libgcgi.h into a .c and .h file Err bitreich.org 70
i Err bitreich.org 70
iDiffstat: Err bitreich.org 70
i M Makefile | 6 +++--- Err bitreich.org 70
i M index.c | 11 ++--------- Err bitreich.org 70
i A libgcgi.c | 283 +++++++++++++++++++++++++++++++ Err bitreich.org 70
i M libgcgi.h | 328 ++----------------------------- Err bitreich.org 70
i Err bitreich.org 70
i4 files changed, 303 insertions(+), 325 deletions(-) Err bitreich.org 70
i--- Err bitreich.org 70
1diff --git a/Makefile b/Makefile /scm/libgcgi/file/Makefile.gph bitreich.org 70
i@@ -1,10 +1,10 @@ Err bitreich.org 70
i LDFLAGS = -static Err bitreich.org 70
i-CFLAGS = -g -pedantic -std=c99 -Wall -Wextra -Wno-unused-function Err bitreich.org 70
i+CFLAGS = -g -pedantic -std=c99 -Wall -Wextra Err bitreich.org 70
i Err bitreich.org 70
i all: index.cgi Err bitreich.org 70
i Err bitreich.org 70
i clean: Err bitreich.org 70
i rm -f *.o index.cgi Err bitreich.org 70
i Err bitreich.org 70
i-index.cgi: index.c libgcgi.h Err bitreich.org 70
i- ${CC} ${LDFLAGS} ${CFLAGS} -o $@ index.c Err bitreich.org 70
i+index.cgi: index.c libgcgi.c libgcgi.h Err bitreich.org 70
i+ ${CC} ${LDFLAGS} ${CFLAGS} -o $@ index.c libgcgi.c Err bitreich.org 70
1diff --git a/index.c b/index.c /scm/libgcgi/file/index.c.gph bitreich.org 70
i@@ -1,13 +1,6 @@ Err bitreich.org 70
i-#include <assert.h> Err bitreich.org 70
i-#include <ctype.h> Err bitreich.org 70
i-#include <errno.h> Err bitreich.org 70
i-#include <stdarg.h> Err bitreich.org 70
i-#include <stdint.h> Err bitreich.org 70
i-#include <stdio.h> Err bitreich.org 70
i-#include <stdlib.h> Err bitreich.org 70
i-#include <string.h> Err bitreich.org 70
i+#include <stddef.h> Err bitreich.org 70
i #include <unistd.h> Err bitreich.org 70
i-#include <sys/stat.h> Err bitreich.org 70
i+#include <stdio.h> Err bitreich.org 70
i Err bitreich.org 70
i #include "libgcgi.h" Err bitreich.org 70
i Err bitreich.org 70
1diff --git a/libgcgi.c b/libgcgi.c /scm/libgcgi/file/libgcgi.c.gph bitreich.org 70
i@@ -0,0 +1,283 @@ Err bitreich.org 70
i+#include <assert.h> Err bitreich.org 70
i+#include <ctype.h> Err bitreich.org 70
i+#include <errno.h> Err bitreich.org 70
i+#include <stdarg.h> Err bitreich.org 70
i+#include <stdint.h> Err bitreich.org 70
i+#include <stdio.h> Err bitreich.org 70
i+#include <stdlib.h> Err bitreich.org 70
i+#include <string.h> Err bitreich.org 70
i+#include <unistd.h> Err bitreich.org 70
i+#include <sys/stat.h> Err bitreich.org 70
i+ Err bitreich.org 70
i+#include "libgcgi.h" Err bitreich.org 70
i+ Err bitreich.org 70
i+#define GCGI_MATCH_NUM 5 Err bitreich.org 70
i+ Err bitreich.org 70
i+char *gcgi_gopher_search; Err bitreich.org 70
i+char *gcgi_gopher_path; Err bitreich.org 70
i+char *gcgi_gopher_host; Err bitreich.org 70
i+char *gcgi_gopher_port; Err bitreich.org 70
i+struct gcgi_var_list gcgi_gopher_query; Err bitreich.org 70
i+ Err bitreich.org 70
i+void Err bitreich.org 70
i+gcgi_fatal(char *fmt, ...) Err bitreich.org 70
i+{ Err bitreich.org 70
i+ va_list va; Err bitreich.org 70
i+ char msg[1024]; Err bitreich.org 70
i+ Err bitreich.org 70
i+ va_start(va, fmt); Err bitreich.org 70
i+ vsnprintf(msg, sizeof msg, fmt, va); Err bitreich.org 70
i+ printf("error: %s\n", msg); Err bitreich.org 70
i+ exit(1); Err bitreich.org 70
i+} Err bitreich.org 70
i+ Err bitreich.org 70
i+static char * Err bitreich.org 70
i+gcgi_fopenread(char *path) Err bitreich.org 70
i+{ Err bitreich.org 70
i+ FILE *fp; Err bitreich.org 70
i+ char *buf; Err bitreich.org 70
i+ ssize_t ssz; Err bitreich.org 70
i+ size_t sz; Err bitreich.org 70
i+ Err bitreich.org 70
i+ if ((fp = fopen(path, "r")) == NULL) Err bitreich.org 70
i+ return NULL; Err bitreich.org 70
i+ if (fseek(fp, 0, SEEK_END) == -1) Err bitreich.org 70
i+ return NULL; Err bitreich.org 70
i+ if ((ssz = ftell(fp)) == -1) Err bitreich.org 70
i+ return NULL; Err bitreich.org 70
i+ sz = ssz; Err bitreich.org 70
i+ if (fseek(fp, 0, SEEK_SET) == -1) Err bitreich.org 70
i+ return NULL; Err bitreich.org 70
i+ if ((buf = malloc(sz + 1)) == NULL) Err bitreich.org 70
i+ return NULL; Err bitreich.org 70
i+ if (fread(buf, sz, 1, fp) == sz) { Err bitreich.org 70
i+ errno = EFBIG; Err bitreich.org 70
i+ goto error_free; Err bitreich.org 70
i+ } Err bitreich.org 70
i+ if (ferror(fp)) Err bitreich.org 70
i+ goto error_free; Err bitreich.org 70
i+ fclose(fp); Err bitreich.org 70
i+ buf[sz] = '\0'; Err bitreich.org 70
i+ return buf; Err bitreich.org 70
i+error_free: Err bitreich.org 70
i+ free(buf); Err bitreich.org 70
i+ return NULL; Err bitreich.org 70
i+} Err bitreich.org 70
i+ Err bitreich.org 70
i+static int Err bitreich.org 70
i+gcgi_cmp_var(const void *v1, const void *v2) Err bitreich.org 70
i+{ Err bitreich.org 70
i+ return strcasecmp(((struct gcgi_var *)v1)->key, ((struct gcgi_var *)v2)->key); Err bitreich.org 70
i+} Err bitreich.org 70
i+ Err bitreich.org 70
i+void Err bitreich.org 70
i+gcgi_add_var(struct gcgi_var_list *vars, char *key, char *val) Err bitreich.org 70
i+{ Err bitreich.org 70
i+ void *mem; Err bitreich.org 70
i+ Err bitreich.org 70
i+ vars->len++; Err bitreich.org 70
i+ if ((mem = realloc(vars->list, vars->len * sizeof *vars->list)) == NULL) Err bitreich.org 70
i+ gcgi_fatal("realloc"); Err bitreich.org 70
i+ vars->list = mem; Err bitreich.org 70
i+ vars->list[vars->len-1].key = key; Err bitreich.org 70
i+ vars->list[vars->len-1].val = val; Err bitreich.org 70
i+} Err bitreich.org 70
i+ Err bitreich.org 70
i+void Err bitreich.org 70
i+gcgi_sort_var_list(struct gcgi_var_list *vars) Err bitreich.org 70
i+{ Err bitreich.org 70
i+ qsort(vars->list, vars->len, sizeof *vars->list, gcgi_cmp_var); Err bitreich.org 70
i+} Err bitreich.org 70
i+ Err bitreich.org 70
i+char * Err bitreich.org 70
i+gcgi_get_var(struct gcgi_var_list *vars, char *key) Err bitreich.org 70
i+{ Err bitreich.org 70
i+ struct gcgi_var *v, q = { .key = key }; Err bitreich.org 70
i+ Err bitreich.org 70
i+ v = bsearch(&q, vars->list, vars->len, sizeof *vars->list, gcgi_cmp_var); Err bitreich.org 70
i+ return (v == NULL) ? NULL : v->val; Err bitreich.org 70
i+} Err bitreich.org 70
i+ Err bitreich.org 70
i+void Err bitreich.org 70
i+gcgi_set_var(struct gcgi_var_list *vars, char *key, char *val) Err bitreich.org 70
i+{ Err bitreich.org 70
i+ struct gcgi_var *v, q; Err bitreich.org 70
i+ Err bitreich.org 70
i+ q.key = key; Err bitreich.org 70
i+ v = bsearch(&q, vars->list, vars->len, sizeof *vars->list, gcgi_cmp_var); Err bitreich.org 70
i+ if (v != NULL) { Err bitreich.org 70
i+ v->val = val; Err bitreich.org 70
i+ return; Err bitreich.org 70
i+ } Err bitreich.org 70
i+ gcgi_add_var(vars, key, val); Err bitreich.org 70
i+ gcgi_sort_var_list(vars); Err bitreich.org 70
i+} Err bitreich.org 70
i+ Err bitreich.org 70
i+void Err bitreich.org 70
i+gcgi_read_var_list(struct gcgi_var_list *vars, char *path) Err bitreich.org 70
i+{ Err bitreich.org 70
i+ char *line, *tail, *key, *s; Err bitreich.org 70
i+ Err bitreich.org 70
i+ line = NULL; Err bitreich.org 70
i+ Err bitreich.org 70
i+ if ((tail = vars->buf = gcgi_fopenread(path)) == NULL) Err bitreich.org 70
i+ gcgi_fatal("opening %s: %s", path, strerror(errno)); Err bitreich.org 70
i+ while ((line = strsep(&tail, "\n")) != NULL) { Err bitreich.org 70
i+ if (line[0] == '\0') Err bitreich.org 70
i+ break; Err bitreich.org 70
i+ key = strsep(&line, ":"); Err bitreich.org 70
i+ if (line == NULL || *line++ != ' ') Err bitreich.org 70
i+ gcgi_fatal("%s: missing ': ' separator", path); Err bitreich.org 70
i+ gcgi_add_var(vars, key, line); Err bitreich.org 70
i+ } Err bitreich.org 70
i+ gcgi_set_var(vars, "text", tail ? tail : ""); Err bitreich.org 70
i+ gcgi_set_var(vars, "file", (s = strrchr(path, '/')) ? s + 1 : path); Err bitreich.org 70
i+ gcgi_sort_var_list(vars); Err bitreich.org 70
i+} Err bitreich.org 70
i+ Err bitreich.org 70
i+void Err bitreich.org 70
i+gcgi_free_var_list(struct gcgi_var_list *vars) Err bitreich.org 70
i+{ Err bitreich.org 70
i+ if (vars->buf != NULL) Err bitreich.org 70
i+ free(vars->buf); Err bitreich.org 70
i+ free(vars->list); Err bitreich.org 70
i+} Err bitreich.org 70
i+ Err bitreich.org 70
i+int Err bitreich.org 70
i+gcgi_write_var_list(struct gcgi_var_list *vars, char *dst) Err bitreich.org 70
i+{ Err bitreich.org 70
i+ FILE *fp; Err bitreich.org 70
i+ struct gcgi_var *v; Err bitreich.org 70
i+ size_t n; Err bitreich.org 70
i+ char path[1024]; Err bitreich.org 70
i+ char *text; Err bitreich.org 70
i+ Err bitreich.org 70
i+ text = NULL; Err bitreich.org 70
i+ Err bitreich.org 70
i+ snprintf(path, sizeof path, "%s.tmp", dst); Err bitreich.org 70
i+ if ((fp = fopen(path, "w")) == NULL) Err bitreich.org 70
i+ gcgi_fatal("opening '%s' for writing", path); Err bitreich.org 70
i+ Err bitreich.org 70
i+ for (v = vars->list, n = vars->len; n > 0; v++, n--) { Err bitreich.org 70
i+ if (strcasecmp(v->key, "Text") == 0) { Err bitreich.org 70
i+ text = text ? text : v->val; Err bitreich.org 70
i+ continue; Err bitreich.org 70
i+ } Err bitreich.org 70
i+ assert(strchr(v->key, '\n') == NULL); Err bitreich.org 70
i+ assert(strchr(v->val, '\n') == NULL); Err bitreich.org 70
i+ fprintf(fp, "%s: %s\n", v->key, v->val); Err bitreich.org 70
i+ } Err bitreich.org 70
i+ fprintf(fp, "\n%s", text ? text : ""); Err bitreich.org 70
i+ Err bitreich.org 70
i+ fclose(fp); Err bitreich.org 70
i+ if (rename(path, dst) == -1) Err bitreich.org 70
i+ gcgi_fatal( "renaming '%s' to '%s'", path, dst); Err bitreich.org 70
i+ return 0; Err bitreich.org 70
i+} Err bitreich.org 70
i+ Err bitreich.org 70
i+static int Err bitreich.org 70
i+gcgi_match(char const *glob, char *path, char **matches, size_t m) Err bitreich.org 70
i+{ Err bitreich.org 70
i+ if (m >= GCGI_MATCH_NUM) Err bitreich.org 70
i+ gcgi_fatal("too many wildcards in glob"); Err bitreich.org 70
i+ matches[m] = NULL; Err bitreich.org 70
i+ while (*glob != '*' && *path != '\0' && *glob == *path) Err bitreich.org 70
i+ glob++, path++; Err bitreich.org 70
i+ if (glob[0] == '*') { Err bitreich.org 70
i+ if (*glob != '\0' && gcgi_match(glob + 1, path, matches, m + 1)) { Err bitreich.org 70
i+ if (matches[m] == NULL) Err bitreich.org 70
i+ matches[m] = path; Err bitreich.org 70
i+ *path = '\0'; Err bitreich.org 70
i+ return 1; Err bitreich.org 70
i+ } else if (*path != '\0' && gcgi_match(glob, path + 1, matches, m)) { Err bitreich.org 70
i+ matches[m] = (char *)path; Err bitreich.org 70
i+ return 1; Err bitreich.org 70
i+ } Err bitreich.org 70
i+ } Err bitreich.org 70
i+ return *glob == '\0' && *path == '\0'; Err bitreich.org 70
i+} Err bitreich.org 70
i+ Err bitreich.org 70
i+static void Err bitreich.org 70
i+gcgi_decode_url(struct gcgi_var_list *vars, char *s) Err bitreich.org 70
i+{ Err bitreich.org 70
i+ char *tok, *eq; Err bitreich.org 70
i+ Err bitreich.org 70
i+ while ((tok = strsep(&s, "&"))) { Err bitreich.org 70
i+ //gcgi_decode_hex(tok); Err bitreich.org 70
i+ if ((eq = strchr(tok, '=')) == NULL) Err bitreich.org 70
i+ continue; Err bitreich.org 70
i+ *eq = '\0'; Err bitreich.org 70
i+ gcgi_add_var(vars, tok, eq + 1); Err bitreich.org 70
i+ } Err bitreich.org 70
i+ gcgi_sort_var_list(vars); Err bitreich.org 70
i+} Err bitreich.org 70
i+ Err bitreich.org 70
i+void Err bitreich.org 70
i+gcgi_handle_request(struct gcgi_handler h[], char **argv, int argc) Err bitreich.org 70
i+{ Err bitreich.org 70
i+ char *query_string; Err bitreich.org 70
i+ Err bitreich.org 70
i+ if (argc != 5) Err bitreich.org 70
i+ gcgi_fatal("wrong number of arguments: %c", argc); Err bitreich.org 70
i+ assert(argv[0] && argv[1] && argv[2] && argv[3]); Err bitreich.org 70
i+ Err bitreich.org 70
i+ /* executable.[d]cgi $search $arguments $host $port */ Err bitreich.org 70
i+ gcgi_gopher_search = argv[1]; Err bitreich.org 70
i+ gcgi_gopher_path = argv[2]; Err bitreich.org 70
i+ gcgi_gopher_host = argv[3]; Err bitreich.org 70
i+ gcgi_gopher_port = argv[4]; Err bitreich.org 70
i+ query_string = strchr(gcgi_gopher_path, '?'); Err bitreich.org 70
i+ if (query_string != NULL) { Err bitreich.org 70
i+ *query_string++ = '\0'; Err bitreich.org 70
i+ gcgi_decode_url(&gcgi_gopher_query, query_string); Err bitreich.org 70
i+ } Err bitreich.org 70
i+ Err bitreich.org 70
i+ for (; h->glob != NULL; h++) { Err bitreich.org 70
i+ char *matches[GCGI_MATCH_NUM + 1]; Err bitreich.org 70
i+ if (!gcgi_match(h->glob, gcgi_gopher_path, matches, 0)) Err bitreich.org 70
i+ continue; Err bitreich.org 70
i+ h->fn(matches); Err bitreich.org 70
i+ return; Err bitreich.org 70
i+ } Err bitreich.org 70
i+ gcgi_fatal("no handler for '%s'", gcgi_gopher_path); Err bitreich.org 70
i+} Err bitreich.org 70
i+ Err bitreich.org 70
i+static char* Err bitreich.org 70
i+gcgi_next_var(char *head, char **tail) Err bitreich.org 70
i+{ Err bitreich.org 70
i+ char *beg, *end; Err bitreich.org 70
i+ Err bitreich.org 70
i+ if ((beg = strstr(head, "{{")) == NULL Err bitreich.org 70
i+ || (end = strstr(beg, "}}")) == NULL) Err bitreich.org 70
i+ return NULL; Err bitreich.org 70
i+ *beg = *end = '\0'; Err bitreich.org 70
i+ *tail = end + strlen("}}"); Err bitreich.org 70
i+ return beg + strlen("{{"); Err bitreich.org 70
i+} Err bitreich.org 70
i+ Err bitreich.org 70
i+void Err bitreich.org 70
i+gcgi_template(char const *path, struct gcgi_var_list *vars) Err bitreich.org 70
i+{ Err bitreich.org 70
i+ FILE *fp; Err bitreich.org 70
i+ size_t sz; Err bitreich.org 70
i+ char *line, *head, *tail, *key, *val; Err bitreich.org 70
i+ Err bitreich.org 70
i+ if ((fp = fopen(path, "r")) == NULL) Err bitreich.org 70
i+ gcgi_fatal("opening template %s", path); Err bitreich.org 70
i+ sz = 0; Err bitreich.org 70
i+ line = NULL; Err bitreich.org 70
i+ while (getline(&line, &sz, fp) > 0) { Err bitreich.org 70
i+ head = tail = line; Err bitreich.org 70
i+ for (; (key = gcgi_next_var(head, &tail)); head = tail) { Err bitreich.org 70
i+ fputs(head, stdout); Err bitreich.org 70
i+ if ((val = gcgi_get_var(vars, key))) Err bitreich.org 70
i+ fputs(val, stdout); Err bitreich.org 70
i+ else Err bitreich.org 70
i+ fprintf(stdout, "{{error:%s}}", key); Err bitreich.org 70
i+ } Err bitreich.org 70
i+ fputs(tail, stdout); Err bitreich.org 70
i+ } Err bitreich.org 70
i+ if (ferror(fp)) Err bitreich.org 70
i+ gcgi_fatal("reading from template: %s", strerror(errno)); Err bitreich.org 70
i+ fclose(fp); Err bitreich.org 70
i+} Err bitreich.org 70
1diff --git a/libgcgi.h b/libgcgi.h /scm/libgcgi/file/libgcgi.h.gph bitreich.org 70
i@@ -19,328 +19,30 @@ struct gcgi_var_list { Err bitreich.org 70
i }; Err bitreich.org 70
i Err bitreich.org 70
i /* main loop executing h->fn() if h->glob is matching */ Err bitreich.org 70
i-static void gcgi_handle_request(struct gcgi_handler h[], char **argv, int argc); Err bitreich.org 70
i+void gcgi_handle_request(struct gcgi_handler h[], char **argv, int argc); Err bitreich.org 70
i Err bitreich.org 70
i /* abort the program with an error message sent to the client */ Err bitreich.org 70
i-static void gcgi_fatal(char *fmt, ...); Err bitreich.org 70
i+void gcgi_fatal(char *fmt, ...); Err bitreich.org 70
i Err bitreich.org 70
i /* print a template with every "{{name}}" looked up in `vars` */ Err bitreich.org 70
i-static void gcgi_template(char const *path, struct gcgi_var_list *vars); Err bitreich.org 70
i- Err bitreich.org 70
i-/* print `s` with all gophermap special characters escaped */ Err bitreich.org 70
i-static void gcgi_print_gophermap(char const *s); Err bitreich.org 70
i+void gcgi_template(char const *path, struct gcgi_var_list *vars); Err bitreich.org 70
i Err bitreich.org 70
i /* manage a `key`-`val` pair storage `vars`, as used with gcgi_template */ Err bitreich.org 70
i-static void gcgi_add_var(struct gcgi_var_list *vars, char *key, char *val); Err bitreich.org 70
i-static void gcgi_sort_var_list(struct gcgi_var_list *vars); Err bitreich.org 70
i-static void gcgi_set_var(struct gcgi_var_list *vars, char *key, char *val); Err bitreich.org 70
i-static char *gcgi_get_var(struct gcgi_var_list *vars, char *key); Err bitreich.org 70
i-static void gcgi_free_var_list(struct gcgi_var_list *vars); Err bitreich.org 70
i+void gcgi_add_var(struct gcgi_var_list *vars, char *key, char *val); Err bitreich.org 70
i+void gcgi_sort_var_list(struct gcgi_var_list *vars); Err bitreich.org 70
i+void gcgi_set_var(struct gcgi_var_list *vars, char *key, char *val); Err bitreich.org 70
i+char *gcgi_get_var(struct gcgi_var_list *vars, char *key); Err bitreich.org 70
i+void gcgi_free_var_list(struct gcgi_var_list *vars); Err bitreich.org 70
i Err bitreich.org 70
i /* store and read a list of variables onto a simple RFC822-like format */ Err bitreich.org 70
i-static void gcgi_read_var_list(struct gcgi_var_list *vars, char *path); Err bitreich.org 70
i-static int gcgi_write_var_list(struct gcgi_var_list *vars, char *path); Err bitreich.org 70
i+void gcgi_read_var_list(struct gcgi_var_list *vars, char *path); Err bitreich.org 70
i+int gcgi_write_var_list(struct gcgi_var_list *vars, char *path); Err bitreich.org 70
i Err bitreich.org 70
i /* components of the gopher request */ Err bitreich.org 70
i-char *gcgi_gopher_search; Err bitreich.org 70
i-char *gcgi_gopher_path; Err bitreich.org 70
i-char *gcgi_gopher_host; Err bitreich.org 70
i-char *gcgi_gopher_port; Err bitreich.org 70
i-static struct gcgi_var_list gcgi_gopher_query; Err bitreich.org 70
i- Err bitreich.org 70
i- Err bitreich.org 70
i-/// POLICE LINE /// DO NOT CROSS /// Err bitreich.org 70
i- Err bitreich.org 70
i- Err bitreich.org 70
i-#define GCGI_MATCH_NUM 5 Err bitreich.org 70
i- Err bitreich.org 70
i-static void Err bitreich.org 70
i-gcgi_fatal(char *fmt, ...) Err bitreich.org 70
i-{ Err bitreich.org 70
i- va_list va; Err bitreich.org 70
i- char msg[1024]; Err bitreich.org 70
i- Err bitreich.org 70
i- va_start(va, fmt); Err bitreich.org 70
i- vsnprintf(msg, sizeof msg, fmt, va); Err bitreich.org 70
i- printf("error: %s\n", msg); Err bitreich.org 70
i- exit(1); Err bitreich.org 70
i-} Err bitreich.org 70
i- Err bitreich.org 70
i-static inline char * Err bitreich.org 70
i-gcgi_fopenread(char *path) Err bitreich.org 70
i-{ Err bitreich.org 70
i- FILE *fp; Err bitreich.org 70
i- char *buf; Err bitreich.org 70
i- ssize_t ssz; Err bitreich.org 70
i- size_t sz; Err bitreich.org 70
i- Err bitreich.org 70
i- if ((fp = fopen(path, "r")) == NULL) Err bitreich.org 70
i- return NULL; Err bitreich.org 70
i- if (fseek(fp, 0, SEEK_END) == -1) Err bitreich.org 70
i- return NULL; Err bitreich.org 70
i- if ((ssz = ftell(fp)) == -1) Err bitreich.org 70
i- return NULL; Err bitreich.org 70
i- sz = ssz; Err bitreich.org 70
i- if (fseek(fp, 0, SEEK_SET) == -1) Err bitreich.org 70
i- return NULL; Err bitreich.org 70
i- if ((buf = malloc(sz + 1)) == NULL) Err bitreich.org 70
i- return NULL; Err bitreich.org 70
i- if (fread(buf, sz, 1, fp) == sz) { Err bitreich.org 70
i- errno = EFBIG; Err bitreich.org 70
i- goto error_free; Err bitreich.org 70
i- } Err bitreich.org 70
i- if (ferror(fp)) Err bitreich.org 70
i- goto error_free; Err bitreich.org 70
i- fclose(fp); Err bitreich.org 70
i- buf[sz] = '\0'; Err bitreich.org 70
i- return buf; Err bitreich.org 70
i-error_free: Err bitreich.org 70
i- free(buf); Err bitreich.org 70
i- return NULL; Err bitreich.org 70
i-} Err bitreich.org 70
i- Err bitreich.org 70
i-static int Err bitreich.org 70
i-gcgi_cmp_var(const void *v1, const void *v2) Err bitreich.org 70
i-{ Err bitreich.org 70
i- return strcasecmp(((struct gcgi_var *)v1)->key, ((struct gcgi_var *)v2)->key); Err bitreich.org 70
i-} Err bitreich.org 70
i- Err bitreich.org 70
i-static void Err bitreich.org 70
i-gcgi_add_var(struct gcgi_var_list *vars, char *key, char *val) Err bitreich.org 70
i-{ Err bitreich.org 70
i- void *mem; Err bitreich.org 70
i- Err bitreich.org 70
i- vars->len++; Err bitreich.org 70
i- if ((mem = realloc(vars->list, vars->len * sizeof *vars->list)) == NULL) Err bitreich.org 70
i- gcgi_fatal("realloc"); Err bitreich.org 70
i- vars->list = mem; Err bitreich.org 70
i- vars->list[vars->len-1].key = key; Err bitreich.org 70
i- vars->list[vars->len-1].val = val; Err bitreich.org 70
i-} Err bitreich.org 70
i- Err bitreich.org 70
i-static void Err bitreich.org 70
i-gcgi_sort_var_list(struct gcgi_var_list *vars) Err bitreich.org 70
i-{ Err bitreich.org 70
i- qsort(vars->list, vars->len, sizeof *vars->list, gcgi_cmp_var); Err bitreich.org 70
i-} Err bitreich.org 70
i- Err bitreich.org 70
i-static char * Err bitreich.org 70
i-gcgi_get_var(struct gcgi_var_list *vars, char *key) Err bitreich.org 70
i-{ Err bitreich.org 70
i- struct gcgi_var *v, q = { .key = key }; Err bitreich.org 70
i- Err bitreich.org 70
i- v = bsearch(&q, vars->list, vars->len, sizeof *vars->list, gcgi_cmp_var); Err bitreich.org 70
i- return (v == NULL) ? NULL : v->val; Err bitreich.org 70
i-} Err bitreich.org 70
i- Err bitreich.org 70
i-static void Err bitreich.org 70
i-gcgi_set_var(struct gcgi_var_list *vars, char *key, char *val) Err bitreich.org 70
i-{ Err bitreich.org 70
i- struct gcgi_var *v, q; Err bitreich.org 70
i- Err bitreich.org 70
i- q.key = key; Err bitreich.org 70
i- v = bsearch(&q, vars->list, vars->len, sizeof *vars->list, gcgi_cmp_var); Err bitreich.org 70
i- if (v != NULL) { Err bitreich.org 70
i- v->val = val; Err bitreich.org 70
i- return; Err bitreich.org 70
i- } Err bitreich.org 70
i- gcgi_add_var(vars, key, val); Err bitreich.org 70
i- gcgi_sort_var_list(vars); Err bitreich.org 70
i-} Err bitreich.org 70
i- Err bitreich.org 70
i-static void Err bitreich.org 70
i-gcgi_read_var_list(struct gcgi_var_list *vars, char *path) Err bitreich.org 70
i-{ Err bitreich.org 70
i- char *line, *tail, *key, *s; Err bitreich.org 70
i- Err bitreich.org 70
i- line = NULL; Err bitreich.org 70
i- Err bitreich.org 70
i- if ((tail = vars->buf = gcgi_fopenread(path)) == NULL) Err bitreich.org 70
i- gcgi_fatal("opening %s: %s", path, strerror(errno)); Err bitreich.org 70
i- while ((line = strsep(&tail, "\n")) != NULL) { Err bitreich.org 70
i- if (line[0] == '\0') Err bitreich.org 70
i- break; Err bitreich.org 70
i- key = strsep(&line, ":"); Err bitreich.org 70
i- if (line == NULL || *line++ != ' ') Err bitreich.org 70
i- gcgi_fatal("%s: missing ': ' separator", path); Err bitreich.org 70
i- gcgi_add_var(vars, key, line); Err bitreich.org 70
i- } Err bitreich.org 70
i- gcgi_set_var(vars, "text", tail ? tail : ""); Err bitreich.org 70
i- gcgi_set_var(vars, "file", (s = strrchr(path, '/')) ? s + 1 : path); Err bitreich.org 70
i- gcgi_sort_var_list(vars); Err bitreich.org 70
i-} Err bitreich.org 70
i- Err bitreich.org 70
i-static void Err bitreich.org 70
i-gcgi_free_var_list(struct gcgi_var_list *vars) Err bitreich.org 70
i-{ Err bitreich.org 70
i- if (vars->buf != NULL) Err bitreich.org 70
i- free(vars->buf); Err bitreich.org 70
i- free(vars->list); Err bitreich.org 70
i-} Err bitreich.org 70
i- Err bitreich.org 70
i-static int Err bitreich.org 70
i-gcgi_write_var_list(struct gcgi_var_list *vars, char *dst) Err bitreich.org 70
i-{ Err bitreich.org 70
i- FILE *fp; Err bitreich.org 70
i- struct gcgi_var *v; Err bitreich.org 70
i- size_t n; Err bitreich.org 70
i- char path[1024]; Err bitreich.org 70
i- char *text; Err bitreich.org 70
i- Err bitreich.org 70
i- text = NULL; Err bitreich.org 70
i- Err bitreich.org 70
i- snprintf(path, sizeof path, "%s.tmp", dst); Err bitreich.org 70
i- if ((fp = fopen(path, "w")) == NULL) Err bitreich.org 70
i- gcgi_fatal("opening '%s' for writing", path); Err bitreich.org 70
i- Err bitreich.org 70
i- for (v = vars->list, n = vars->len; n > 0; v++, n--) { Err bitreich.org 70
i- if (strcasecmp(v->key, "Text") == 0) { Err bitreich.org 70
i- text = text ? text : v->val; Err bitreich.org 70
i- continue; Err bitreich.org 70
i- } Err bitreich.org 70
i- assert(strchr(v->key, '\n') == NULL); Err bitreich.org 70
i- assert(strchr(v->val, '\n') == NULL); Err bitreich.org 70
i- fprintf(fp, "%s: %s\n", v->key, v->val); Err bitreich.org 70
i- } Err bitreich.org 70
i- fprintf(fp, "\n%s", text ? text : ""); Err bitreich.org 70
i- Err bitreich.org 70
i- fclose(fp); Err bitreich.org 70
i- if (rename(path, dst) == -1) Err bitreich.org 70
i- gcgi_fatal( "renaming '%s' to '%s'", path, dst); Err bitreich.org 70
i- return 0; Err bitreich.org 70
i-} Err bitreich.org 70
i- Err bitreich.org 70
i-static inline int Err bitreich.org 70
i-gcgi_match(char const *glob, char *path, char **matches, size_t m) Err bitreich.org 70
i-{ Err bitreich.org 70
i- if (m >= GCGI_MATCH_NUM) Err bitreich.org 70
i- gcgi_fatal("too many wildcards in glob"); Err bitreich.org 70
i- matches[m] = NULL; Err bitreich.org 70
i- while (*glob != '*' && *path != '\0' && *glob == *path) Err bitreich.org 70
i- glob++, path++; Err bitreich.org 70
i- if (glob[0] == '*') { Err bitreich.org 70
i- if (*glob != '\0' && gcgi_match(glob + 1, path, matches, m + 1)) { Err bitreich.org 70
i- if (matches[m] == NULL) Err bitreich.org 70
i- matches[m] = path; Err bitreich.org 70
i- *path = '\0'; Err bitreich.org 70
i- return 1; Err bitreich.org 70
i- } else if (*path != '\0' && gcgi_match(glob, path + 1, matches, m)) { Err bitreich.org 70
i- matches[m] = (char *)path; Err bitreich.org 70
i- return 1; Err bitreich.org 70
i- } Err bitreich.org 70
i- } Err bitreich.org 70
i- return *glob == '\0' && *path == '\0'; Err bitreich.org 70
i-} Err bitreich.org 70
i- Err bitreich.org 70
i-static inline void Err bitreich.org 70
i-gcgi_decode_url(struct gcgi_var_list *vars, char *s) Err bitreich.org 70
i-{ Err bitreich.org 70
i- char *tok, *eq; Err bitreich.org 70
i- Err bitreich.org 70
i- while ((tok = strsep(&s, "&"))) { Err bitreich.org 70
i- //gcgi_decode_hex(tok); Err bitreich.org 70
i- if ((eq = strchr(tok, '=')) == NULL) Err bitreich.org 70
i- continue; Err bitreich.org 70
i- *eq = '\0'; Err bitreich.org 70
i- gcgi_add_var(vars, tok, eq + 1); Err bitreich.org 70
i- } Err bitreich.org 70
i- gcgi_sort_var_list(vars); Err bitreich.org 70
i-} Err bitreich.org 70
i- Err bitreich.org 70
i-static void Err bitreich.org 70
i-gcgi_handle_request(struct gcgi_handler h[], char **argv, int argc) Err bitreich.org 70
i-{ Err bitreich.org 70
i- char *query_string; Err bitreich.org 70
i- Err bitreich.org 70
i- if (argc != 5) Err bitreich.org 70
i- gcgi_fatal("wrong number of arguments: %c", argc); Err bitreich.org 70
i- assert(argv[0] && argv[1] && argv[2] && argv[3]); Err bitreich.org 70
i- Err bitreich.org 70
i- /* executable.[d]cgi $search $arguments $host $port */ Err bitreich.org 70
i- gcgi_gopher_search = argv[1]; Err bitreich.org 70
i- gcgi_gopher_path = argv[2]; Err bitreich.org 70
i- gcgi_gopher_host = argv[3]; Err bitreich.org 70
i- gcgi_gopher_port = argv[4]; Err bitreich.org 70
i- query_string = strchr(gcgi_gopher_path, '?'); Err bitreich.org 70
i- if (query_string != NULL) { Err bitreich.org 70
i- *query_string++ = '\0'; Err bitreich.org 70
i- gcgi_decode_url(&gcgi_gopher_query, query_string); Err bitreich.org 70
i- } Err bitreich.org 70
i- Err bitreich.org 70
i- for (; h->glob != NULL; h++) { Err bitreich.org 70
i- char *matches[GCGI_MATCH_NUM + 1]; Err bitreich.org 70
i- if (!gcgi_match(h->glob, gcgi_gopher_path, matches, 0)) Err bitreich.org 70
i- continue; Err bitreich.org 70
i- h->fn(matches); Err bitreich.org 70
i- return; Err bitreich.org 70
i- } Err bitreich.org 70
i- gcgi_fatal("no handler for '%s'", gcgi_gopher_path); Err bitreich.org 70
i-} Err bitreich.org 70
i- Err bitreich.org 70
i-static void Err bitreich.org 70
i-gcgi_print_gophermap(char const *s) Err bitreich.org 70
i-{ Err bitreich.org 70
i- for (; *s != '\0'; s++) { Err bitreich.org 70
i- switch(*s) { Err bitreich.org 70
i- case '<': Err bitreich.org 70
i- fputs("<", stdout); Err bitreich.org 70
i- break; Err bitreich.org 70
i- case '>': Err bitreich.org 70
i- fputs(">", stdout); Err bitreich.org 70
i- break; Err bitreich.org 70
i- case '"': Err bitreich.org 70
i- fputs(""", stdout); Err bitreich.org 70
i- break; Err bitreich.org 70
i- case '\'': Err bitreich.org 70
i- fputs("'", stdout); Err bitreich.org 70
i- break; Err bitreich.org 70
i- case '&': Err bitreich.org 70
i- fputs("&", stdout); Err bitreich.org 70
i- break; Err bitreich.org 70
i- default: Err bitreich.org 70
i- fputc(*s, stdout); Err bitreich.org 70
i- } Err bitreich.org 70
i- } Err bitreich.org 70
i-} Err bitreich.org 70
i- Err bitreich.org 70
i-static inline char* Err bitreich.org 70
i-gcgi_next_var(char *head, char **tail) Err bitreich.org 70
i-{ Err bitreich.org 70
i- char *beg, *end; Err bitreich.org 70
i- Err bitreich.org 70
i- if ((beg = strstr(head, "{{")) == NULL Err bitreich.org 70
i- || (end = strstr(beg, "}}")) == NULL) Err bitreich.org 70
i- return NULL; Err bitreich.org 70
i- *beg = *end = '\0'; Err bitreich.org 70
i- *tail = end + strlen("}}"); Err bitreich.org 70
i- return beg + strlen("{{"); Err bitreich.org 70
i-} Err bitreich.org 70
i- Err bitreich.org 70
i-static void Err bitreich.org 70
i-gcgi_template(char const *path, struct gcgi_var_list *vars) Err bitreich.org 70
i-{ Err bitreich.org 70
i- FILE *fp; Err bitreich.org 70
i- size_t sz; Err bitreich.org 70
i- char *line, *head, *tail, *key, *val; Err bitreich.org 70
i- Err bitreich.org 70
i- if ((fp = fopen(path, "r")) == NULL) Err bitreich.org 70
i- gcgi_fatal("opening template %s", path); Err bitreich.org 70
i- sz = 0; Err bitreich.org 70
i- line = NULL; Err bitreich.org 70
i- while (getline(&line, &sz, fp) > 0) { Err bitreich.org 70
i- head = tail = line; Err bitreich.org 70
i- for (; (key = gcgi_next_var(head, &tail)); head = tail) { Err bitreich.org 70
i- fputs(head, stdout); Err bitreich.org 70
i- if ((val = gcgi_get_var(vars, key))) Err bitreich.org 70
i- gcgi_print_gophermap(val); Err bitreich.org 70
i- else Err bitreich.org 70
i- fprintf(stdout, "{{error:%s}}", key); Err bitreich.org 70
i- } Err bitreich.org 70
i- fputs(tail, stdout); Err bitreich.org 70
i- } Err bitreich.org 70
i- if (ferror(fp)) Err bitreich.org 70
i- gcgi_fatal("reading from template: %s", strerror(errno)); Err bitreich.org 70
i- fclose(fp); Err bitreich.org 70
i-} Err bitreich.org 70
i+extern char *gcgi_gopher_search; Err bitreich.org 70
i+extern char *gcgi_gopher_path; Err bitreich.org 70
i+extern char *gcgi_gopher_host; Err bitreich.org 70
i+extern char *gcgi_gopher_port; Err bitreich.org 70
i+extern struct gcgi_var_list gcgi_gopher_query; Err bitreich.org 70
i Err bitreich.org 70
i #endif Err bitreich.org 70
.
Response:
text/plain