diff options
author | Omar Polo <op@omarpolo.com> | 2021-02-07 18:55:04 +0000 |
---|---|---|
committer | Omar Polo <op@omarpolo.com> | 2021-02-07 18:55:04 +0000 |
commit | 9f006a2127398af12ecf9159cd5ef28b3685e7a6 (patch) | |
tree | 5c9690dc757ae7b29c8b14ea391a6f252837de3f /ex.c | |
parent | a13739138b17a21dbb50011cc65fb135e9f804c8 (diff) |
[cgi] split the query in words if needed and add them to the argv
Diffstat (limited to 'ex.c')
-rw-r--r-- | ex.c | 48 |
1 files changed, 43 insertions, 5 deletions
@@ -230,6 +230,46 @@ xasprintf(const char *fmt, ...) return s; } +static void +do_exec(const char *ex, const char *spath, char *query) +{ + char **argv, buf[PATH_MAX], *sname, *t; + size_t i, n; + + strlcpy(buf, spath, sizeof(buf)); + sname = basename(buf); + + if (query == NULL || strchr(query, '=') != NULL) { + if ((argv = calloc(2, sizeof(char*))) == NULL) + err(1, "calloc"); + argv[0] = sname; + execvp(ex, argv); + warn("execvp: %s", argv[0]); + return; + } + + n = 1; + for (t = query ;; t++, n++) { + if ((t = strchr(t, '+')) == NULL) + break; + } + + if ((argv = calloc(n+2, sizeof(char*))) == NULL) + err(1, "calloc"); + + argv[0] = sname; + for (i = 0; i < n; ++i) { + t = strchr(query, '+'); + if (t != NULL) + *t = '\0'; + argv[i+1] = pct_decode_str(query); + query = t+1; + } + + execvp(ex, argv); + warn("execvp: %s", argv[0]); +} + /* fd or -1 on error */ static int launch_cgi(struct iri *iri, const char *spath, char *relpath, @@ -246,7 +286,6 @@ launch_cgi(struct iri *iri, const char *spath, char *relpath, return -1; case 0: { /* child */ - char *argv[] = {NULL, NULL}; char *ex, *pwd; char iribuf[GEMINI_URL_LEN]; char path[PATH_MAX]; @@ -256,7 +295,6 @@ launch_cgi(struct iri *iri, const char *spath, char *relpath, goto childerr; ex = xasprintf("%s/%s", vhost->dir, spath); - argv[0] = ex; serialize_iri(iri, iribuf, sizeof(iribuf)); @@ -307,15 +345,15 @@ launch_cgi(struct iri *iri, const char *spath, char *relpath, safe_setenv("TLS_CLIENT_ISSUER", cissuer); safe_setenv("TLS_CLIENT_HASH", chash); - strlcpy(path, argv[0], sizeof(path)); + strlcpy(path, ex, sizeof(path)); + pwd = dirname(path); if (chdir(pwd)) { warn("chdir"); goto childerr; } - execvp(argv[0], argv); - warn("execvp: %s", argv[0]); + do_exec(ex, spath, iri->query); goto childerr; } |