/*
- * Copyright (C) 1998-1999,2003 Ian Jackson
+ * Copyright 1996-2013,2016 Ian Jackson <ijackson@chiark.greenend.org.uk>
+ * Copyright 1998 David Damerell <damerell@chiark.greenend.org.uk>
+ * Copyright 1999,2003
+ * Chancellor Masters and Scholars of the University of Cambridge
+ * Copyright 2010 Tony Finch <fanf@dotat.at>
+ * Copyright 2013,2016 Mark Wooding <mdw@distorted.org.uk>
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with userv-utils; if not, write to the Free Software
- * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * $Id$
+ * along with userv-utils; if not, see http://www.gnu.org/licenses/.
*/
+#include <assert.h>
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
}
void syserror(const char *m) {
- if (printf("Content-Type: text/plain\n\n"
+ if (printf("Content-Type: text/plain\n"
+ "Status: 500\n\n"
"ucgi: system call error:\n"
"%s: %s\n",
m,strerror(errno))==EOF || fflush(stdout)) outerror();
exit(0);
}
-void error(const char *m) {
- if (printf("Content-Type: text/plain\n\n"
+void error(const char *m, int st) {
+ if (printf("Content-Type: text/plain\n"
+ "Status: %d\n\n"
"ucgi: error:\n"
"%s\n",
- m)==EOF || fflush(stdout)) outerror();
+ st, m)==EOF || fflush(stdout)) outerror();
exit(0);
}
if (setenv(en,ev,overwrite)) syserror("setenv");
}
-const char **load_filters(unsigned flags, const char *first, ...)
-{
+const char **load_filters(unsigned flags, const char *first, ...) {
va_list ap;
const char *name, *p, *q, **v;
char *pp;
l= strlen(buf);
if (buf[l - 1] == '\n') buf[--l]= 0;
if (l + 1 == sizeof(buf))
- error("line too long in environment filter file");
+ error("line too long in environment filter file", 500);
p= buf; q= p + l;
while (isspace((unsigned char)*p)) p++;
while (q > p && isspace((unsigned char)q[-1])) q--;
static int envvar_match(unsigned flags, const char *en,
const char *const *patv,
- const char **ev)
-{
+ const char *const *defaults,
+ const char **ev) {
const char *const *patp;
const char *q, *pat;
int acceptp;
+ int rc;
+ if (!patv) { patv= defaults; defaults= 0; }
for (patp= patv; (pat= *patp); patp++) {
q= en;
acceptp= 1;
if (*pat == '!' && (flags & FILTF_WILDCARD)) { acceptp= 0; pat++; }
+ else if (*pat == '?') {
+ if (strcmp(pat + 1, "DEFAULTS") == 0) {
+ assert(defaults);
+ rc= envvar_match(flags, en, defaults, 0, ev);
+ if (rc) return rc;
+ } else
+ error("unknown pattern directive", 500);
+ continue;
+ }
for (;;) {
if (!*pat) {
void filter_environment(unsigned flags, const char *prefix_in,
const char *const *patv,
+ const char *const *defaults,
void (*foundone)(const char *fulln,
const char *en, const char *ev,
void *p),
- void *p)
-{
+ void *p) {
char *const *ep;
const char *en, *ev;
char enbuf[MAX_ENVVAR_NAME];
D( if (debugmode) printf(";; doesn't match prefix\n"); )
continue;
}
- if (envvar_match(flags, en + pn, patv, &ev) > 0) {
+ if (envvar_match(flags, en + pn, patv, defaults, &ev) > 0) {
n= strcspn(en, "=");
if (n >= sizeof(enbuf))
- error("environment variable name too long");
+ error("environment variable name too long", 500);
memcpy(enbuf, en, n);
enbuf[n]= 0;
D( if (debugmode)