/*
- * Copyright (C) 1998-1999 Ian Jackson
+ * Copyright (C) 1998-1999,2003 Ian Jackson
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
#include <string.h>
#include <errno.h>
+#include <unistd.h>
+
#include "ucgi.h"
const char *const envok[]= {
+ "AUTH_TYPE",
"CONTENT_LENGTH",
"CONTENT_TYPE",
"DOCUMENT_ROOT",
"GATEWAY_INTERFACE",
"HTTP_ACCEPT",
+ "HTTP_ACCEPT_CHARSET",
"HTTP_ACCEPT_ENCODING",
"HTTP_ACCEPT_LANGUAGE",
"HTTP_CACHE_CONTROL",
+ "HTTP_CONNECTION",
+ "HTTP_CONTENT_ENCODING",
"HTTP_COOKIE",
+ "HTTP_DNT",
"HTTP_HOST",
+ "HTTP_KEEP_ALIVE",
"HTTP_NEGOTIATE",
"HTTP_PRAGMA",
+ "HTTP_REFERER",
"HTTP_USER_AGENT",
+ "HTTP_VIA",
+ "HTTP_X_FORWARDED_FOR",
+ "HTTPS",
"PATH_INFO",
"PATH_TRANSLATED",
"QUERY_STRING",
"REMOTE_USER",
"REMOTE_IDENT",
"REQUEST_METHOD",
+ "REQUEST_URI",
"SCRIPT_FILENAME",
"SCRIPT_NAME",
"SCRIPT_URI",
"SCRIPT_URL",
+ "SERVER_ADDR",
"SERVER_ADMIN",
"SERVER_NAME",
"SERVER_PORT",
"SERVER_PROTOCOL",
+ "SERVER_SIGNATURE",
"SERVER_SOFTWARE",
0
};
return r;
}
+void *xrealloc(void *ptr, size_t sz) {
+ void *r;
+
+ r= realloc(ptr,sz);
+ if (!r) syserror("realloc failed");
+ return r;
+}
+
void xsetenv(const char *en, const char *ev, int overwrite) {
if (setenv(en,ev,overwrite)) syserror("setenv");
}
+
+void filter_environment(unsigned flags, const char *prefix_in,
+ const char *const *patv,
+ void (*foundone)(const char *fulln,
+ const char *en, const char *ev,
+ void *p),
+ void *p)
+{
+ char *const *ep;
+ const char *const *patp;
+ const char *en, *ev, *pat, *q;
+ char enbuf[MAX_ENVVAR_NAME];
+ size_t n, pn = strlen(prefix_in);
+ int acceptp;
+
+ D( if (debugmode) printf(";; filter_environment...\n"); )
+ for (ep= environ; (en= *ep); ep++) {
+ D( if (debugmode) printf(";; consider env-var `%s'\n", en); )
+ if (strncmp(en, prefix_in, pn) != 0 || !en[pn]) {
+ D( if (debugmode) printf(";; doesn't match prefix\n"); )
+ goto next_ev;
+ }
+ for (patp= patv; (pat= *patp); patp++) {
+ q= en + pn;
+ acceptp= 1;
+ if (*pat == '!' && (flags & FILTF_WILDCARD)) {
+ acceptp= 0; pat++;
+ }
+ for (;;) {
+ if (!*pat) {
+ if (*q != '=') {
+ D( if (debugmode)
+ printf(";; mismatch `%s' (prefix)\n", *patp); )
+ goto next_pat;
+ }
+ D( if (debugmode) printf(";; matched `%s'\n", *patp); )
+ ev = q + 1;
+ break;
+ } else if (*pat == '*' && (flags & FILTF_WILDCARD)) {
+ q = strchr(q, '=');
+ if (!q) {
+ D( if (debugmode)
+ printf(";; mismatch `%s' (discard: no `=')\n", *patp); )
+ goto next_ev;
+ }
+ D( if (debugmode)
+ printf(";; wildcard match for `%s'\n", *patp); )
+ ev = q + 1;
+ break;
+ } else
+ if (*pat++ != *q++) {
+ D( if (debugmode) printf(";; mismatch `%s'\n", *patp); )
+ goto next_pat;
+ }
+ }
+ if (acceptp) {
+ n= q - en;
+ if (n >= sizeof(enbuf))
+ error("environment variable name too long");
+ memcpy(enbuf, en, n);
+ enbuf[n]= 0;
+ D( if (debugmode)
+ printf(";; full = `%s'; tail = `%s'; value = `%s'\n",
+ enbuf, enbuf + pn, ev); )
+ foundone(enbuf, enbuf + pn, ev, p);
+ } D( else if (debugmode)
+ printf(";; matched negated pattern\n"); )
+ goto next_ev;
+ next_pat:;
+ }
+ next_ev:;
+ }
+}