topen poll files for reading when ?poll is passed - vote - simple cgi voting system for web and gopher
 (HTM) git clone git://src.adamsgaard.dk/vote
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit a6ae3f0db3f76e55a4ecc84bf09ee62e629881e3
 (DIR) parent c7fdf4bc6fe1740d10b874ce6da7005f7ca46635
 (HTM) Author: Anders Damsgaard <anders@adamsgaard.dk>
       Date:   Sun, 27 Sep 2020 08:54:15 +0200
       
       open poll files for reading when ?poll is passed
       
       Diffstat:
         M LICENSE                             |       1 +
         M util.c                              |      42 ++++++++++++++++++-------------
         M util.h                              |      19 +------------------
         M vote.c                              |      28 +++++++++++++++++++++-------
       
       4 files changed, 47 insertions(+), 43 deletions(-)
       ---
 (DIR) diff --git a/LICENSE b/LICENSE
       t@@ -1,6 +1,7 @@
        ISC License
        
        Copyright (c) 2020 Anders Damsgaard <anders@adamsgaard.dk>
       +Copyright (c) 2020 Hiltjo Posthuma <hiltjo@codemadness.org> (util.c, util.h)
        
        Permission to use, copy, modify, and/or distribute this software for any
        purpose with or without fee is hereby granted, provided that the above
 (DIR) diff --git a/util.c b/util.c
       t@@ -1,21 +1,3 @@
       -/*
       -* ISC License
       -* 
       -* Copyright (c) 2020 Hiltjo Posthuma <hiltjo@codemadness.org>
       -* 
       -* Permission to use, copy, modify, and/or distribute this software for any
       -* purpose with or without fee is hereby granted, provided that the above
       -* copyright notice and this permission notice appear in all copies.
       -* 
       -* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
       -* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
       -* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
       -* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
       -* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
       -* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
       -* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
       -*/
       -
        #include <sys/socket.h>
        #include <sys/types.h>
        
       t@@ -222,3 +204,27 @@ gophertext(FILE *fp, const char *s, size_t len)
                        }
                }
        }
       +
       +void
       +escapechars(char *s)
       +{
       +        for (; *s; s++) {
       +                switch (*s) {
       +                case '#':
       +                case ' ':
       +                case '\t':
       +                case ':':
       +                case '.':
       +                case '(':
       +                case ')':
       +                case '/':
       +                        *s = '_';
       +                        break;
       +                case '\n':
       +                        *s = '\0';
       +                        return;
       +                default:
       +                        break;
       +                }
       +        }
       +}
 (DIR) diff --git a/util.h b/util.h
       t@@ -1,21 +1,3 @@
       -/*
       -* ISC License
       -* 
       -* Copyright (c) 2020 Hiltjo Posthuma <hiltjo@codemadness.org>
       -* 
       -* Permission to use, copy, modify, and/or distribute this software for any
       -* purpose with or without fee is hereby granted, provided that the above
       -* copyright notice and this permission notice appear in all copies.
       -* 
       -* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
       -* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
       -* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
       -* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
       -* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
       -* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
       -* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
       -*/
       -
        #ifndef __OpenBSD__
        #define pledge(p1,p2) 0
        #define unveil(p1,p2) 0
       t@@ -34,3 +16,4 @@ int hexdigit(int c);
        int uriencode(const char *s, char *buf, size_t bufsiz);
        int utf8pad(char *buf, size_t bufsiz, const char *s, size_t len, int pad);
        void xmlencode(const char *s);
       +void escapechars(char *s);
 (DIR) diff --git a/vote.c b/vote.c
       t@@ -5,6 +5,7 @@
        #include <sys/stat.h>
        #include <errno.h>
        #include <fcntl.h>
       +#include <limits.h>
        #include "util.h"
        
        #define OUT(s) (fputs((s), stdout))
       t@@ -19,6 +20,9 @@ die(int statuscode)
                case 401:
                        OUT("Status: 401 Bad Request\r\n\r\n");
                        break;
       +        case 404:
       +                OUT("Status: 404 Not Found\r\n\r\n");
       +                break;
                case 500:
                        OUT("Status: 500 Internal Server Error\r\n\r\n");
                        break;
       t@@ -50,20 +54,30 @@ void
        show_poll(const char *poll_name)
        {
                FILE *fd;
       -        if ((fd = fopen(poll_name, "r")) != NULL) {
       -                fclose(fd);
       -        } else {
       -                fprintf(stderr, "poll_open %s: %s\n", poll_name, strerror(errno));
       +        char fname[PATH_MAX];
       +        char buf[PATH_MAX];
       +
       +        strlcpy(buf, poll_name, sizeof(buf));
       +        escapechars(buf);
       +        if (snprintf(fname, sizeof(fname), "%s/%s", POLLS_DIR, buf) < 0) {
       +                fprintf(stderr, "snprintf fname %s/%s\n", POLLS_DIR, buf);
                        die(500);
                }
       -        
       +
       +        if (!(fd = fopen(fname, "r"))) {
       +                fprintf(stderr, "poll_open %s: %s\n", poll, strerror(errno));
       +                die(404);
       +        } else {
       +                fclose(fd);
       +        }
       +
       +        printf("<h2>poll: '%s'</h2>\n", poll);
        }
        
        void
        parse_query()
        {
                char *query, *p;
       -        size_t len;
        
                if (!(query = getenv("QUERY_STRING")))
                        query = "";
       t@@ -101,7 +115,7 @@ main()
        
                parse_query();
                if (*poll)
       -                printf("<p>poll: '%s'</p>\n", poll);
       +                show_poll(poll);
        
                print_html_foot();