itadd hiltjo posthuma's utilities - vote - simple cgi voting system for web and gopher Err mx1.adamsgaard.dk 70 hgit clone git://src.adamsgaard.dk/vote URL:git://src.adamsgaard.dk/vote mx1.adamsgaard.dk 70 1Log /src/vote/log.gph mx1.adamsgaard.dk 70 1Files /src/vote/files.gph mx1.adamsgaard.dk 70 1Refs /src/vote/refs.gph mx1.adamsgaard.dk 70 1README /src/vote/file/README.gph mx1.adamsgaard.dk 70 1LICENSE /src/vote/file/LICENSE.gph mx1.adamsgaard.dk 70 i--- Err mx1.adamsgaard.dk 70 1commit 93cfbe7466a3f69bcdf8928fdef8e3dde1d732e5 /src/vote/commit/93cfbe7466a3f69bcdf8928fdef8e3dde1d732e5.gph mx1.adamsgaard.dk 70 1parent f49595b9c30a3a21c5380807654b1b43379e5b0d /src/vote/commit/f49595b9c30a3a21c5380807654b1b43379e5b0d.gph mx1.adamsgaard.dk 70 hAuthor: Anders Damsgaard URL:mailto:anders@adamsgaard.dk mx1.adamsgaard.dk 70 iDate: Sun, 27 Sep 2020 08:03:51 +0200 Err mx1.adamsgaard.dk 70 i Err mx1.adamsgaard.dk 70 iadd hiltjo posthuma's utilities Err mx1.adamsgaard.dk 70 i Err mx1.adamsgaard.dk 70 ifrom git://git.codemadness.org/frontends Err mx1.adamsgaard.dk 70 i Err mx1.adamsgaard.dk 70 iDiffstat: Err mx1.adamsgaard.dk 70 i M Makefile | 2 +- Err mx1.adamsgaard.dk 70 i A util.c | 206 +++++++++++++++++++++++++++++++ Err mx1.adamsgaard.dk 70 i A util.h | 18 ++++++++++++++++++ Err mx1.adamsgaard.dk 70 i M vote.c | 68 +++++++++++++++++-------------- Err mx1.adamsgaard.dk 70 i Err mx1.adamsgaard.dk 70 i4 files changed, 263 insertions(+), 31 deletions(-) Err mx1.adamsgaard.dk 70 i--- Err mx1.adamsgaard.dk 70 1diff --git a/Makefile b/Makefile /src/vote/file/Makefile.gph mx1.adamsgaard.dk 70 it@@ -5,7 +5,7 @@ NAME = vote Err mx1.adamsgaard.dk 70 i HERE_CFLAGS = ${CFLAGS} Err mx1.adamsgaard.dk 70 i HERE_LDFLAGS = -static ${LDFLAGS} Err mx1.adamsgaard.dk 70 i Err mx1.adamsgaard.dk 70 i-SRC = vote.c Err mx1.adamsgaard.dk 70 i+SRC = vote.c util.c Err mx1.adamsgaard.dk 70 i OBJ = ${SRC:.c=.o} Err mx1.adamsgaard.dk 70 i Err mx1.adamsgaard.dk 70 i all: ${NAME} Err mx1.adamsgaard.dk 70 1diff --git a/util.c b/util.c /src/vote/file/util.c.gph mx1.adamsgaard.dk 70 it@@ -0,0 +1,206 @@ Err mx1.adamsgaard.dk 70 i+#include Err mx1.adamsgaard.dk 70 i+#include Err mx1.adamsgaard.dk 70 i+ Err mx1.adamsgaard.dk 70 i+#include Err mx1.adamsgaard.dk 70 i+#include Err mx1.adamsgaard.dk 70 i+#include Err mx1.adamsgaard.dk 70 i+#include Err mx1.adamsgaard.dk 70 i+#include Err mx1.adamsgaard.dk 70 i+#include Err mx1.adamsgaard.dk 70 i+#include Err mx1.adamsgaard.dk 70 i+#include Err mx1.adamsgaard.dk 70 i+#include Err mx1.adamsgaard.dk 70 i+#include Err mx1.adamsgaard.dk 70 i+ Err mx1.adamsgaard.dk 70 i+int Err mx1.adamsgaard.dk 70 i+uriencode(const char *s, char *buf, size_t bufsiz) Err mx1.adamsgaard.dk 70 i+{ Err mx1.adamsgaard.dk 70 i+ static char hex[] = "0123456789ABCDEF"; Err mx1.adamsgaard.dk 70 i+ char *d = buf, *e = buf + bufsiz; Err mx1.adamsgaard.dk 70 i+ unsigned char c; Err mx1.adamsgaard.dk 70 i+ Err mx1.adamsgaard.dk 70 i+ if (!bufsiz) Err mx1.adamsgaard.dk 70 i+ return 0; Err mx1.adamsgaard.dk 70 i+ Err mx1.adamsgaard.dk 70 i+ for (; *s; ++s) { Err mx1.adamsgaard.dk 70 i+ c = (unsigned char)*s; Err mx1.adamsgaard.dk 70 i+ if (d + 4 >= e) Err mx1.adamsgaard.dk 70 i+ return 0; Err mx1.adamsgaard.dk 70 i+ if (c == ' ' || c == '#' || c == '%' || c == '?' || c == '"' || Err mx1.adamsgaard.dk 70 i+ c == '&' || c == '<' || c <= 0x1f || c >= 0x7f) { Err mx1.adamsgaard.dk 70 i+ *d++ = '%'; Err mx1.adamsgaard.dk 70 i+ *d++ = hex[c >> 4]; Err mx1.adamsgaard.dk 70 i+ *d++ = hex[c & 0x0f]; Err mx1.adamsgaard.dk 70 i+ } else { Err mx1.adamsgaard.dk 70 i+ *d++ = *s; Err mx1.adamsgaard.dk 70 i+ } Err mx1.adamsgaard.dk 70 i+ } Err mx1.adamsgaard.dk 70 i+ *d = '\0'; Err mx1.adamsgaard.dk 70 i+ Err mx1.adamsgaard.dk 70 i+ return 1; Err mx1.adamsgaard.dk 70 i+} Err mx1.adamsgaard.dk 70 i+ Err mx1.adamsgaard.dk 70 i+int Err mx1.adamsgaard.dk 70 i+hexdigit(int c) Err mx1.adamsgaard.dk 70 i+{ Err mx1.adamsgaard.dk 70 i+ if (c >= '0' && c <= '9') Err mx1.adamsgaard.dk 70 i+ return c - '0'; Err mx1.adamsgaard.dk 70 i+ else if (c >= 'A' && c <= 'F') Err mx1.adamsgaard.dk 70 i+ return c - 'A' + 10; Err mx1.adamsgaard.dk 70 i+ else if (c >= 'a' && c <= 'f') Err mx1.adamsgaard.dk 70 i+ return c - 'a' + 10; Err mx1.adamsgaard.dk 70 i+ Err mx1.adamsgaard.dk 70 i+ return 0; Err mx1.adamsgaard.dk 70 i+} Err mx1.adamsgaard.dk 70 i+ Err mx1.adamsgaard.dk 70 i+/* decode until NUL separator or end of "key". */ Err mx1.adamsgaard.dk 70 i+int Err mx1.adamsgaard.dk 70 i+decodeparam(char *buf, size_t bufsiz, const char *s) Err mx1.adamsgaard.dk 70 i+{ Err mx1.adamsgaard.dk 70 i+ size_t i; Err mx1.adamsgaard.dk 70 i+ Err mx1.adamsgaard.dk 70 i+ if (!bufsiz) Err mx1.adamsgaard.dk 70 i+ return -1; Err mx1.adamsgaard.dk 70 i+ Err mx1.adamsgaard.dk 70 i+ for (i = 0; *s && *s != '&'; s++) { Err mx1.adamsgaard.dk 70 i+ switch (*s) { Err mx1.adamsgaard.dk 70 i+ case '%': Err mx1.adamsgaard.dk 70 i+ if (i + 3 >= bufsiz) Err mx1.adamsgaard.dk 70 i+ return -1; Err mx1.adamsgaard.dk 70 i+ if (!isxdigit((unsigned char)*(s+1)) || Err mx1.adamsgaard.dk 70 i+ !isxdigit((unsigned char)*(s+2))) Err mx1.adamsgaard.dk 70 i+ return -1; Err mx1.adamsgaard.dk 70 i+ buf[i++] = hexdigit(*(s+1)) * 16 + hexdigit(*(s+2)); Err mx1.adamsgaard.dk 70 i+ s += 2; Err mx1.adamsgaard.dk 70 i+ break; Err mx1.adamsgaard.dk 70 i+ case '+': Err mx1.adamsgaard.dk 70 i+ if (i + 1 >= bufsiz) Err mx1.adamsgaard.dk 70 i+ return -1; Err mx1.adamsgaard.dk 70 i+ buf[i++] = ' '; Err mx1.adamsgaard.dk 70 i+ break; Err mx1.adamsgaard.dk 70 i+ default: Err mx1.adamsgaard.dk 70 i+ if (i + 1 >= bufsiz) Err mx1.adamsgaard.dk 70 i+ return -1; Err mx1.adamsgaard.dk 70 i+ buf[i++] = *s; Err mx1.adamsgaard.dk 70 i+ break; Err mx1.adamsgaard.dk 70 i+ } Err mx1.adamsgaard.dk 70 i+ } Err mx1.adamsgaard.dk 70 i+ buf[i] = '\0'; Err mx1.adamsgaard.dk 70 i+ Err mx1.adamsgaard.dk 70 i+ return i; Err mx1.adamsgaard.dk 70 i+} Err mx1.adamsgaard.dk 70 i+ Err mx1.adamsgaard.dk 70 i+char * Err mx1.adamsgaard.dk 70 i+getparam(const char *query, const char *s) Err mx1.adamsgaard.dk 70 i+{ Err mx1.adamsgaard.dk 70 i+ const char *p, *last = NULL; Err mx1.adamsgaard.dk 70 i+ size_t len; Err mx1.adamsgaard.dk 70 i+ Err mx1.adamsgaard.dk 70 i+ len = strlen(s); Err mx1.adamsgaard.dk 70 i+ for (p = query; (p = strstr(p, s)); p += len) { Err mx1.adamsgaard.dk 70 i+ if (p[len] == '=' && (p == query || p[-1] == '&' || p[-1] == '?')) Err mx1.adamsgaard.dk 70 i+ last = p + len + 1; Err mx1.adamsgaard.dk 70 i+ } Err mx1.adamsgaard.dk 70 i+ Err mx1.adamsgaard.dk 70 i+ return (char *)last; Err mx1.adamsgaard.dk 70 i+} Err mx1.adamsgaard.dk 70 i+ Err mx1.adamsgaard.dk 70 i+int Err mx1.adamsgaard.dk 70 i+friendlytime(time_t now, time_t t) Err mx1.adamsgaard.dk 70 i+{ Err mx1.adamsgaard.dk 70 i+ long long d = now - t; Err mx1.adamsgaard.dk 70 i+ Err mx1.adamsgaard.dk 70 i+ if (d < 60) { Err mx1.adamsgaard.dk 70 i+ printf("just now"); Err mx1.adamsgaard.dk 70 i+ } else if (d < 3600) { Err mx1.adamsgaard.dk 70 i+ printf("%lld minutes ago", d / 60); Err mx1.adamsgaard.dk 70 i+ } else if (d <= 24*3600) { Err mx1.adamsgaard.dk 70 i+ printf("%lld hours ago", d / 3600); Err mx1.adamsgaard.dk 70 i+ } else { Err mx1.adamsgaard.dk 70 i+ return 0; Err mx1.adamsgaard.dk 70 i+ } Err mx1.adamsgaard.dk 70 i+ return 1; Err mx1.adamsgaard.dk 70 i+} Err mx1.adamsgaard.dk 70 i+ Err mx1.adamsgaard.dk 70 i+/* Escape characters below as HTML 2.0 / XML 1.0. */ Err mx1.adamsgaard.dk 70 i+void Err mx1.adamsgaard.dk 70 i+xmlencode(const char *s) Err mx1.adamsgaard.dk 70 i+{ Err mx1.adamsgaard.dk 70 i+ for (; *s; s++) { Err mx1.adamsgaard.dk 70 i+ switch(*s) { Err mx1.adamsgaard.dk 70 i+ case '<': fputs("<", stdout); break; Err mx1.adamsgaard.dk 70 i+ case '>': fputs(">", stdout); break; Err mx1.adamsgaard.dk 70 i+ case '\'': fputs("'", stdout); break; Err mx1.adamsgaard.dk 70 i+ case '&': fputs("&", stdout); break; Err mx1.adamsgaard.dk 70 i+ case '"': fputs(""", stdout); break; Err mx1.adamsgaard.dk 70 i+ default: putchar(*s); Err mx1.adamsgaard.dk 70 i+ } Err mx1.adamsgaard.dk 70 i+ } Err mx1.adamsgaard.dk 70 i+} Err mx1.adamsgaard.dk 70 i+ Err mx1.adamsgaard.dk 70 i+/* format `len' columns of characters. If string is shorter pad the rest Err mx1.adamsgaard.dk 70 i+ * with characters `pad`. */ Err mx1.adamsgaard.dk 70 i+int Err mx1.adamsgaard.dk 70 i+utf8pad(char *buf, size_t bufsiz, const char *s, size_t len, int pad) Err mx1.adamsgaard.dk 70 i+{ Err mx1.adamsgaard.dk 70 i+ wchar_t wc; Err mx1.adamsgaard.dk 70 i+ size_t col = 0, i, slen, siz = 0; Err mx1.adamsgaard.dk 70 i+ int rl, w; Err mx1.adamsgaard.dk 70 i+ Err mx1.adamsgaard.dk 70 i+ if (!len) Err mx1.adamsgaard.dk 70 i+ return -1; Err mx1.adamsgaard.dk 70 i+ Err mx1.adamsgaard.dk 70 i+ slen = strlen(s); Err mx1.adamsgaard.dk 70 i+ for (i = 0; i < slen; i += rl) { Err mx1.adamsgaard.dk 70 i+ if ((rl = mbtowc(&wc, &s[i], slen - i < 4 ? slen - i : 4)) <= 0) Err mx1.adamsgaard.dk 70 i+ break; Err mx1.adamsgaard.dk 70 i+ if ((w = wcwidth(wc)) == -1) Err mx1.adamsgaard.dk 70 i+ continue; Err mx1.adamsgaard.dk 70 i+ if (col + w > len || (col + w == len && s[i + rl])) { Err mx1.adamsgaard.dk 70 i+ if (siz + 4 >= bufsiz) Err mx1.adamsgaard.dk 70 i+ return -1; Err mx1.adamsgaard.dk 70 i+ memcpy(&buf[siz], "\xe2\x80\xa6", 3); Err mx1.adamsgaard.dk 70 i+ siz += 3; Err mx1.adamsgaard.dk 70 i+ if (col + w == len && w > 1) Err mx1.adamsgaard.dk 70 i+ buf[siz++] = pad; Err mx1.adamsgaard.dk 70 i+ buf[siz] = '\0'; Err mx1.adamsgaard.dk 70 i+ return 0; Err mx1.adamsgaard.dk 70 i+ } Err mx1.adamsgaard.dk 70 i+ if (siz + rl + 1 >= bufsiz) Err mx1.adamsgaard.dk 70 i+ return -1; Err mx1.adamsgaard.dk 70 i+ memcpy(&buf[siz], &s[i], rl); Err mx1.adamsgaard.dk 70 i+ col += w; Err mx1.adamsgaard.dk 70 i+ siz += rl; Err mx1.adamsgaard.dk 70 i+ buf[siz] = '\0'; Err mx1.adamsgaard.dk 70 i+ } Err mx1.adamsgaard.dk 70 i+ Err mx1.adamsgaard.dk 70 i+ len -= col; Err mx1.adamsgaard.dk 70 i+ if (siz + len + 1 >= bufsiz) Err mx1.adamsgaard.dk 70 i+ return -1; Err mx1.adamsgaard.dk 70 i+ memset(&buf[siz], pad, len); Err mx1.adamsgaard.dk 70 i+ siz += len; Err mx1.adamsgaard.dk 70 i+ buf[siz] = '\0'; Err mx1.adamsgaard.dk 70 i+ Err mx1.adamsgaard.dk 70 i+ return 0; Err mx1.adamsgaard.dk 70 i+} Err mx1.adamsgaard.dk 70 i+ Err mx1.adamsgaard.dk 70 i+/* Escape characters in gopher, CR and LF are ignored */ Err mx1.adamsgaard.dk 70 i+void Err mx1.adamsgaard.dk 70 i+gophertext(FILE *fp, const char *s, size_t len) Err mx1.adamsgaard.dk 70 i+{ Err mx1.adamsgaard.dk 70 i+ size_t i; Err mx1.adamsgaard.dk 70 i+ Err mx1.adamsgaard.dk 70 i+ for (i = 0; *s && i < len; s++, i++) { Err mx1.adamsgaard.dk 70 i+ switch (*s) { Err mx1.adamsgaard.dk 70 i+ case '\r': /* ignore CR */ Err mx1.adamsgaard.dk 70 i+ case '\n': /* ignore LF */ Err mx1.adamsgaard.dk 70 i+ break; Err mx1.adamsgaard.dk 70 i+ case '\t': Err mx1.adamsgaard.dk 70 i+ fputs(" ", fp); Err mx1.adamsgaard.dk 70 i+ break; Err mx1.adamsgaard.dk 70 i+ default: Err mx1.adamsgaard.dk 70 i+ fputc(*s, fp); Err mx1.adamsgaard.dk 70 i+ break; Err mx1.adamsgaard.dk 70 i+ } Err mx1.adamsgaard.dk 70 i+ } Err mx1.adamsgaard.dk 70 i+} Err mx1.adamsgaard.dk 70 1diff --git a/util.h b/util.h /src/vote/file/util.h.gph mx1.adamsgaard.dk 70 it@@ -0,0 +1,18 @@ Err mx1.adamsgaard.dk 70 i+#ifndef __OpenBSD__ Err mx1.adamsgaard.dk 70 i+#define pledge(p1,p2) 0 Err mx1.adamsgaard.dk 70 i+#define unveil(p1,p2) 0 Err mx1.adamsgaard.dk 70 i+#endif Err mx1.adamsgaard.dk 70 i+ Err mx1.adamsgaard.dk 70 i+#undef strlcat Err mx1.adamsgaard.dk 70 i+size_t strlcat(char *, const char *, size_t); Err mx1.adamsgaard.dk 70 i+#undef strlcpy Err mx1.adamsgaard.dk 70 i+size_t strlcpy(char *, const char *, size_t); Err mx1.adamsgaard.dk 70 i+ Err mx1.adamsgaard.dk 70 i+int decodeparam(char *buf, size_t bufsiz, const char *s); Err mx1.adamsgaard.dk 70 i+int friendlytime(time_t now, time_t t); Err mx1.adamsgaard.dk 70 i+char *getparam(const char *query, const char *s); Err mx1.adamsgaard.dk 70 i+void gophertext(FILE *fp, const char *s, size_t len); Err mx1.adamsgaard.dk 70 i+int hexdigit(int c); Err mx1.adamsgaard.dk 70 i+int uriencode(const char *s, char *buf, size_t bufsiz); Err mx1.adamsgaard.dk 70 i+int utf8pad(char *buf, size_t bufsiz, const char *s, size_t len, int pad); Err mx1.adamsgaard.dk 70 i+void xmlencode(const char *s); Err mx1.adamsgaard.dk 70 1diff --git a/vote.c b/vote.c /src/vote/file/vote.c.gph mx1.adamsgaard.dk 70 it@@ -5,20 +5,34 @@ Err mx1.adamsgaard.dk 70 i #include Err mx1.adamsgaard.dk 70 i #include Err mx1.adamsgaard.dk 70 i #include Err mx1.adamsgaard.dk 70 i+#include "util.h" Err mx1.adamsgaard.dk 70 i Err mx1.adamsgaard.dk 70 i #define OUT(s) (fputs((s), stdout)) Err mx1.adamsgaard.dk 70 i #define POLLS_DIR "polls" Err mx1.adamsgaard.dk 70 i Err mx1.adamsgaard.dk 70 i-static char poll[1024]; Err mx1.adamsgaard.dk 70 i+static char rawpoll[1024], poll[1024]; Err mx1.adamsgaard.dk 70 i Err mx1.adamsgaard.dk 70 i void Err mx1.adamsgaard.dk 70 i-die_500() { Err mx1.adamsgaard.dk 70 i- OUT("Status: 500 Internal Server Error\r\n\r\n"); Err mx1.adamsgaard.dk 70 i- exit(1); Err mx1.adamsgaard.dk 70 i+die(int statuscode) Err mx1.adamsgaard.dk 70 i+{ Err mx1.adamsgaard.dk 70 i+ switch(statuscode) { Err mx1.adamsgaard.dk 70 i+ case 401: Err mx1.adamsgaard.dk 70 i+ OUT("Status: 401 Bad Request\r\n\r\n"); Err mx1.adamsgaard.dk 70 i+ break; Err mx1.adamsgaard.dk 70 i+ case 500: Err mx1.adamsgaard.dk 70 i+ OUT("Status: 500 Internal Server Error\r\n\r\n"); Err mx1.adamsgaard.dk 70 i+ break; Err mx1.adamsgaard.dk 70 i+ default: Err mx1.adamsgaard.dk 70 i+ fprintf(stderr, "unknown status code %d\n", statuscode); Err mx1.adamsgaard.dk 70 i+ OUT("Status: 500 Internal Server Error\r\n\r\n"); Err mx1.adamsgaard.dk 70 i+ } Err mx1.adamsgaard.dk 70 i+ Err mx1.adamsgaard.dk 70 i+ exit(statuscode); Err mx1.adamsgaard.dk 70 i } Err mx1.adamsgaard.dk 70 i Err mx1.adamsgaard.dk 70 i void Err mx1.adamsgaard.dk 70 i-print_html_head() { Err mx1.adamsgaard.dk 70 i+print_html_head() Err mx1.adamsgaard.dk 70 i+{ Err mx1.adamsgaard.dk 70 i OUT("Content-type: text/html; charset=utf-8\r\n\r\n"); Err mx1.adamsgaard.dk 70 i OUT("\n" Err mx1.adamsgaard.dk 70 i "\n" Err mx1.adamsgaard.dk 70 it@@ -26,39 +40,28 @@ print_html_head() { Err mx1.adamsgaard.dk 70 i } Err mx1.adamsgaard.dk 70 i Err mx1.adamsgaard.dk 70 i void Err mx1.adamsgaard.dk 70 i-print_html_foot() { Err mx1.adamsgaard.dk 70 i+print_html_foot() Err mx1.adamsgaard.dk 70 i+{ Err mx1.adamsgaard.dk 70 i OUT("\n" Err mx1.adamsgaard.dk 70 i "\n"); Err mx1.adamsgaard.dk 70 i } Err mx1.adamsgaard.dk 70 i Err mx1.adamsgaard.dk 70 i void Err mx1.adamsgaard.dk 70 i-show_poll(const char *poll_name) { Err mx1.adamsgaard.dk 70 i+show_poll(const char *poll_name) Err mx1.adamsgaard.dk 70 i+{ Err mx1.adamsgaard.dk 70 i FILE *fd; Err mx1.adamsgaard.dk 70 i if ((fd = fopen(poll_name, "r")) != NULL) { Err mx1.adamsgaard.dk 70 i fclose(fd); Err mx1.adamsgaard.dk 70 i } else { Err mx1.adamsgaard.dk 70 i fprintf(stderr, "poll_open %s: %s\n", poll_name, strerror(errno)); Err mx1.adamsgaard.dk 70 i- die_500(); Err mx1.adamsgaard.dk 70 i+ die(500); Err mx1.adamsgaard.dk 70 i } Err mx1.adamsgaard.dk 70 i Err mx1.adamsgaard.dk 70 i } Err mx1.adamsgaard.dk 70 i Err mx1.adamsgaard.dk 70 i-/* from hiltjo posthuma's frontends */ Err mx1.adamsgaard.dk 70 i-char * Err mx1.adamsgaard.dk 70 i-getparam(const char *query, const char *s) { Err mx1.adamsgaard.dk 70 i- const char *p, *last = NULL; Err mx1.adamsgaard.dk 70 i- size_t len; Err mx1.adamsgaard.dk 70 i- Err mx1.adamsgaard.dk 70 i- len = strlen(s); Err mx1.adamsgaard.dk 70 i- for (p = query; (p = strstr(p, s)); p += len) { Err mx1.adamsgaard.dk 70 i- if (p[len] == '=' && (p == query || p[-1] == '&' || p[-1] == '?')) Err mx1.adamsgaard.dk 70 i- last = p + len + 1; Err mx1.adamsgaard.dk 70 i- } Err mx1.adamsgaard.dk 70 i- return (char *)last; Err mx1.adamsgaard.dk 70 i-} Err mx1.adamsgaard.dk 70 i- Err mx1.adamsgaard.dk 70 i void Err mx1.adamsgaard.dk 70 i-parse_query() { Err mx1.adamsgaard.dk 70 i+parse_query() Err mx1.adamsgaard.dk 70 i+{ Err mx1.adamsgaard.dk 70 i char *query, *p; Err mx1.adamsgaard.dk 70 i size_t len; Err mx1.adamsgaard.dk 70 i Err mx1.adamsgaard.dk 70 it@@ -66,33 +69,38 @@ parse_query() { Err mx1.adamsgaard.dk 70 i query = ""; Err mx1.adamsgaard.dk 70 i Err mx1.adamsgaard.dk 70 i if ((p = getparam(query, "poll"))) { Err mx1.adamsgaard.dk 70 i- if ((len = strcspn(p, "&")) && len + 1 < sizeof(poll)) { Err mx1.adamsgaard.dk 70 i- memcpy(poll, p, len); Err mx1.adamsgaard.dk 70 i- poll[len] = '\0'; Err mx1.adamsgaard.dk 70 i+ if ((len = strcspn(p, "&")) && len + 1 < sizeof(rawpoll)) { Err mx1.adamsgaard.dk 70 i+ memcpy(rawpoll, p, len); Err mx1.adamsgaard.dk 70 i+ rawpoll[len] = '\0'; Err mx1.adamsgaard.dk 70 i+ } Err mx1.adamsgaard.dk 70 i+ Err mx1.adamsgaard.dk 70 i+ if (decodeparam(poll, sizeof(poll), p) == -1) { Err mx1.adamsgaard.dk 70 i+ die(401); Err mx1.adamsgaard.dk 70 i } Err mx1.adamsgaard.dk 70 i } Err mx1.adamsgaard.dk 70 i } Err mx1.adamsgaard.dk 70 i Err mx1.adamsgaard.dk 70 i int Err mx1.adamsgaard.dk 70 i-main() { Err mx1.adamsgaard.dk 70 i+main() Err mx1.adamsgaard.dk 70 i+{ Err mx1.adamsgaard.dk 70 i struct stat sb; Err mx1.adamsgaard.dk 70 i Err mx1.adamsgaard.dk 70 i #ifdef __OpenBSD__ Err mx1.adamsgaard.dk 70 i if (unveil(getenv("PWD"), NULL) == -1 || unveil(NULL, NULL) == -1) { Err mx1.adamsgaard.dk 70 i fprintf(stderr, "unveil: %s\n", strerror(errno)); Err mx1.adamsgaard.dk 70 i- die_500(); Err mx1.adamsgaard.dk 70 i+ die(500); Err mx1.adamsgaard.dk 70 i } Err mx1.adamsgaard.dk 70 i Err mx1.adamsgaard.dk 70 i if (pledge("stdio cpath rpath", NULL) == -1) { Err mx1.adamsgaard.dk 70 i fprintf(stderr, "pledge: %s\n", strerror(errno)); Err mx1.adamsgaard.dk 70 i- die_500(); Err mx1.adamsgaard.dk 70 i+ die(500); Err mx1.adamsgaard.dk 70 i } Err mx1.adamsgaard.dk 70 i #endif Err mx1.adamsgaard.dk 70 i Err mx1.adamsgaard.dk 70 i if (stat(POLLS_DIR, &sb) == -1) { Err mx1.adamsgaard.dk 70 i if (mkdir(POLLS_DIR, 0755) == -1) { Err mx1.adamsgaard.dk 70 i fprintf(stderr, "mkdir polls/ failed: %s\n", strerror(errno)); Err mx1.adamsgaard.dk 70 i- die_500(); Err mx1.adamsgaard.dk 70 i+ die(500); Err mx1.adamsgaard.dk 70 i } Err mx1.adamsgaard.dk 70 i } Err mx1.adamsgaard.dk 70 i Err mx1.adamsgaard.dk 70 .