aboutsummaryrefslogtreecommitdiff
path: root/ex.c
diff options
context:
space:
mode:
authorOmar Polo <op@omarpolo.com>2021-02-07 18:55:04 +0000
committerOmar Polo <op@omarpolo.com>2021-02-07 18:55:04 +0000
commit9f006a2127398af12ecf9159cd5ef28b3685e7a6 (patch)
tree5c9690dc757ae7b29c8b14ea391a6f252837de3f /ex.c
parenta13739138b17a21dbb50011cc65fb135e9f804c8 (diff)
[cgi] split the query in words if needed and add them to the argv
Diffstat (limited to 'ex.c')
-rw-r--r--ex.c48
1 files changed, 43 insertions, 5 deletions
diff --git a/ex.c b/ex.c
index 58f5004..0a65472 100644
--- a/ex.c
+++ b/ex.c
@@ -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;
}