X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=userv-utils.git;a=blobdiff_plain;f=www-cgi%2Fucgicommon.c;h=0facfbb7bb20f39eb0201e7f2974a8869587b5ac;hp=43b7d945aa439ea36ef54ada5bd8534716fd0d00;hb=f601a2c663d9135dec19172a593502864d10393e;hpb=77a36cae0e59a1e17c12c71fd7ff49be0958b11d diff --git a/www-cgi/ucgicommon.c b/www-cgi/ucgicommon.c index 43b7d94..0facfbb 100644 --- a/www-cgi/ucgicommon.c +++ b/www-cgi/ucgicommon.c @@ -22,6 +22,8 @@ #include #include +#include + #include "ucgi.h" const char *const envok[]= { @@ -114,3 +116,76 @@ void *xrealloc(void *ptr, size_t sz) { 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:; + } +}