--- mod_log_config.c.orig	Tue May 21 14:03:56 2002
+++ mod_log_config.c	Fri Aug  9 16:06:18 2002
@@ -234,6 +234,22 @@
 } multi_log_state;
 
 /*
+ *
+ */
+typedef enum {
+    op_exists,
+    op_notexists,
+    op_equals,
+    op_notequals
+} condition_op;
+
+typedef struct {
+    char *env_var;
+    condition_op operator;
+    char *env_val;
+} custom_log_condition;
+
+/*
  * config_log_state holds the status of a single log file. fname might
  * be NULL, which means this module does no logging for this
  * request. format might be NULL, in which case the default_format
@@ -247,7 +263,7 @@
     char *format_string;
     array_header *format;
     int log_fd;
-    char *condition_var;
+    array_header *conditions;
 #ifdef BUFFERED_LOGS
     int outcnt;
     char outbuf[LOG_BUFSIZE];
@@ -752,6 +768,73 @@
     return a;
 }
 
+static array_header *parse_custom_conditions(pool *p, char *s, const char **err) {
+    array_header *a = ap_make_array(p, 3, sizeof(custom_log_condition));
+    char *t = s;
+    custom_log_condition *c;
+    char *env_var;
+    condition_op operator;
+
+    while (*t != '\0') {
+	operator = op_exists;
+
+	if (*t == '!') {
+	    operator = op_notexists;
+	    ++s;
+	    ++t;
+	}
+
+	while (*t != ',' && *t != '=' && *t != '\0')
+	    ++t;
+
+	if (t == s) {
+	    *err = "premature end of env condition (missing env var)";
+	    return NULL;
+	}
+
+	env_var = ap_pstrndup(p, s, t - s);
+	s = t + 1;
+
+	if (*t == ',' || *t == '\0') {
+	    c = ap_push_array(a);
+	    c->env_var = env_var;
+	    c->operator = operator;
+	    c->env_val = NULL;
+
+	    if (*t)
+		++t;
+
+	    continue;
+	}
+
+	/* must have been an '=' at the end of the var */
+
+	if (operator == op_exists)
+	    operator = op_equals;
+	else
+	    operator = op_notequals;
+
+	while (*++t != ',' && *t != '\0') 
+	    ;
+
+	if (t == s) {
+	    *err = "premature end of env condition (missing value)";
+	    return NULL;
+	}
+
+	c = ap_push_array(a);
+	c->env_var = env_var;
+	c->operator = operator;
+	c->env_val = ap_pstrndup(p, s, t - s);
+	s = t + 1;
+
+	if (*t)
+	    ++t;
+    }
+
+    return a;
+}
+
 /*****************************************************************
  *
  * Actually logging.
@@ -810,6 +893,8 @@
     int len = 0;
     array_header *format;
     char *envar;
+    const char *t;
+    custom_log_condition *clc_list, *clc;
 
     if (cls->fname == NULL) {
         return DECLINED;
@@ -819,16 +904,47 @@
      * See if we've got any conditional envariable-controlled logging decisions
      * to make.
      */
-    if (cls->condition_var != NULL) {
-	envar = cls->condition_var;
-	if (*envar != '!') {
-	    if (ap_table_get(r->subprocess_env, envar) == NULL) {
-		return DECLINED;
-	    }
-	}
-	else {
-	    if (ap_table_get(r->subprocess_env, &envar[1]) != NULL) {
-		return DECLINED;
+    if (cls->conditions != NULL) {
+	clc_list = (custom_log_condition *)cls->conditions->elts;
+
+	/*
+	 * All conditions must be satisfied.  Disjunctions can be achieved
+	 * using additional CustomLog directives.
+	 */
+	for (i = 0; i < cls->conditions->nelts; ++i) {
+	    clc = &clc_list[i];
+	    switch (clc->operator) {
+	    case op_exists:
+		if (ap_table_get(r->subprocess_env, clc->env_var) == NULL) {
+		    return DECLINED;
+		}
+		break;
+
+	    case op_notexists:
+		if (ap_table_get(r->subprocess_env, clc->env_var) != NULL) {
+		    return DECLINED;
+		}
+		break;
+
+	    case op_equals:
+		if (
+		    (t = ap_table_get(r->subprocess_env, clc->env_var)) == NULL
+		    ||
+		    strcmp(t, clc->env_val)
+		) {
+		    return DECLINED;
+		}
+		break;
+
+	    case op_notequals:
+		if (
+		    (t = ap_table_get(r->subprocess_env, clc->env_var)) == NULL
+		    ||
+		    !strcmp(t, clc->env_val)
+		) {
+		    return DECLINED;
+		}
+		break;
 	    }
 	}
     }
@@ -997,16 +1113,15 @@
     config_log_state *cls;
 
     cls = (config_log_state *) ap_push_array(mls->config_logs);
-    cls->condition_var = NULL;
+    cls->conditions = NULL;
     if (envclause != NULL) {
 	if (strncasecmp(envclause, "env=", 4) != 0) {
-	    return "error in condition clause";
+	    return "error in condition clause (expected 'env=')";
 	}
-	if ((envclause[4] == '\0')
-	    || ((envclause[4] == '!') && (envclause[5] == '\0'))) {
-	    return "missing environment variable name";
+
+	if ((cls->conditions = parse_custom_conditions(cmd->pool, &envclause[4], &err_string)) == NULL) {
+	    return err_string;
 	}
-	cls->condition_var = ap_pstrdup(cmd->pool, &envclause[4]);
     }
 
     cls->fname = fn;
