initial working version to proofread - libgcgi - REST library for Gopher
 (HTM) git clone git://bitreich.org/libgcgi git://hg6vgqziawt5s4dj.onion/libgcgi
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) Tags
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 092dce7972a8883e7532c848192785ed60ac9b67
 (DIR) parent 758508d75c969333c3f72f0e01faa0a5129153b9
 (HTM) Author: Josuah Demangeon <me@josuah.net>
       Date:   Sat, 30 Jul 2022 12:30:03 +0200
       
       initial working version to proofread
       
       Diffstat:
         M index.c                             |      12 +++++++++++-
         M libgcgi.h                           |      42 +++++++++++++++++++++-----------
       
       2 files changed, 39 insertions(+), 15 deletions(-)
       ---
 (DIR) diff --git a/index.c b/index.c
       @@ -10,8 +10,18 @@
        #include <sys/stat.h>
        #include "libgcgi.h"
        
       +static void
       +error_404(char **matches)
       +{
       +        char *var;
       +
       +        printf("sorry, I could not find %s\n", matches[0]);
       +        if ((var = gcgi_get_var(&gcgi_gopher_query, "var")) != NULL)
       +                printf("I got the $var though! -> '%s'\n", var);
       +}
       +
        static struct gcgi_handler handlers[] = {
       -//        { "*",                                error_404 },
       +        { "*",                                error_404 },
                { NULL,                                NULL },
        };
        
 (DIR) diff --git a/libgcgi.h b/libgcgi.h
       @@ -44,15 +44,12 @@ static void gcgi_free_var_list(struct gcgi_var_list *vars);
        static void gcgi_read_var_list(struct gcgi_var_list *vars, char *path);
        static int gcgi_write_var_list(struct gcgi_var_list *vars, char *path);
        
       -/* parse various components of the Gopher request */
       -static struct gcgi_var_list * gcgi_parse_query_string(void);
       -
        /* components of the gopher request */
        char *gcgi_gopher_search;
        char *gcgi_gopher_path;
        char *gcgi_gopher_host;
        char *gcgi_gopher_port;
       -char *gcgi_gopher_args;
       +static struct gcgi_var_list gcgi_gopher_query;
        
        
        /// POLICE LINE /// DO NOT CROSS ///
       @@ -68,7 +65,6 @@ gcgi_fatal(char *fmt, ...)
        
                va_start(va, fmt);
                vsnprintf(msg, sizeof msg, fmt, va);
       -        printf("Status: 500 Server Error\n\n");
                printf("error: %s\n", msg);
                exit(1);
        }
       @@ -237,9 +233,26 @@ gcgi_match(char const *glob, char *path, char **matches, size_t m)
                return *glob == '\0' && *path == '\0';
        }
        
       +static inline void
       +gcgi_decode_url(struct gcgi_var_list *vars, char *s)
       +{
       +        char *tok, *eq;
       +
       +        while ((tok = strsep(&s, "&"))) {
       +                //gcgi_decode_hex(tok);
       +                if ((eq = strchr(tok, '=')) == NULL)
       +                        continue;
       +                *eq = '\0';
       +                gcgi_add_var(vars, tok, eq + 1);
       +        }
       +        gcgi_sort_var_list(vars);
       +}
       +
        static void
        gcgi_handle_request(struct gcgi_handler h[], char **argv, int argc)
        {
       +        char *query_string;
       +
                if (argc != 5)
                        gcgi_fatal("wrong number of arguments: %c", argc);
                assert(argv[0] && argv[1] && argv[2] && argv[3]);
       @@ -249,11 +262,10 @@ gcgi_handle_request(struct gcgi_handler h[], char **argv, int argc)
                gcgi_gopher_path = argv[2];
                gcgi_gopher_host = argv[3];
                gcgi_gopher_port = argv[4];
       -        gcgi_gopher_args = strchr(gcgi_gopher_path, '?');
       -        if (gcgi_gopher_args == NULL) {
       -                gcgi_gopher_args = "";
       -        } else {
       -                *gcgi_gopher_args++ = '\0';
       +        query_string = strchr(gcgi_gopher_path, '?');
       +        if (query_string != NULL) {
       +                *query_string++ = '\0';
       +                gcgi_decode_url(&gcgi_gopher_query, query_string);
                }
        
                for (; h->glob != NULL; h++) {
       @@ -309,17 +321,17 @@ static void
        gcgi_template(char const *path, struct gcgi_var_list *vars)
        {
                FILE *fp;
       +        ssize_t ssz;
                size_t sz;
                char *line, *head, *tail, *key;
                char *val;
        
       -        sz = 0;
       -        line = NULL;
       -
                if ((fp = fopen(path, "r")) == NULL)
                        gcgi_fatal("opening template %s", path);
        
       -        while (getline(&line, &sz, fp) > 0) {
       +        sz = 0;
       +        line = NULL;
       +        while ((ssz = getline(&line, &sz, fp)) > 0) {
                        head = tail = line;
                        for (; (key = gcgi_next_var(head, &tail)); head = tail) {
                                fputs(head, stdout);
       @@ -330,6 +342,8 @@ gcgi_template(char const *path, struct gcgi_var_list *vars)
                        }
                        fputs(tail, stdout);
                }
       +        if (ssz == -1)
       +                gcgi_fatal("reading from template: %s", strerror(errno));
                fclose(fp);
        }