SMOLNET PORTAL home about changes
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("&lt;", stdout);	Err	bitreich.org	70
i-                        break;	Err	bitreich.org	70
i-                case '>':	Err	bitreich.org	70
i-                        fputs("&gt;", stdout);	Err	bitreich.org	70
i-                        break;	Err	bitreich.org	70
i-                case '"':	Err	bitreich.org	70
i-                        fputs("&quot;", stdout);	Err	bitreich.org	70
i-                        break;	Err	bitreich.org	70
i-                case '\'':	Err	bitreich.org	70
i-                        fputs("&#39;", stdout);	Err	bitreich.org	70
i-                        break;	Err	bitreich.org	70
i-                case '&':	Err	bitreich.org	70
i-                        fputs("&amp;", 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
Original URLgopher://bitreich.org/0/scm/libgcgi/commit/052f666afd7390...
Content-Typetext/plain; charset=utf-8