--- apache_1.3.28/src/modules/standard/mod_setenvif.c	2003-02-04 02:13:29.000000000 +0900
+++ mod_setenvif.c	2003-09-21 08:05:51.000000000 +0900
@@ -117,11 +117,24 @@
  *    SetEnvIf remote_addr (127.0.0.1|192.168.10.) LOCAL
  */
 
+/*
+ * SetEnvIfAll and SetEnvIfEither were added by Nakamura Minoru 
+ * <nminoru@nminoru.jp> in Sep 20, 2003. 
+ * 
+ * Usage:
+ *
+ *    SetEnvIfAll    name value expr1 [expr2 expr3 ...]   
+ *    SetEnvIfEither name value epxr1 [epxr2 epxr3 ...]   
+ *
+ */
+
 #include "httpd.h"
 #include "http_config.h"
 #include "http_core.h"
 #include "http_log.h"
 
+#define EXTEND_IFALLL
+
 enum special {
     SPECIAL_NOT,
     SPECIAL_REMOTE_ADDR,
@@ -141,12 +154,19 @@
 	enum special,
 	special_type,4);
     unsigned icase : 1;		/* ignoring case? */
+#ifdef  EXTEND_IFALLL
+    unsigned is_extend : 1;	/* ignoring case? */    
+    unsigned is_and : 1;	/* ignoring case? */
+    char*    value;    
+    table*   vars;
+#endif  EXTEND_IFALLL
 } sei_entry;
 
 typedef struct {
     array_header *conditionals;
 } sei_cfg_rec;
 
+
 module MODULE_VAR_EXPORT setenvif_module;
 
 /*
@@ -193,6 +213,13 @@
 #define ICASE_MAGIC	((void *)(&setenvif_module))
 #define SEI_MAGIC_HEIRLOOM "setenvif-phase-flag"
 
+#ifdef  EXTEND_IFALLL
+#define COND_IF_ALL_VARS    1
+#define COND_IF_EITHER_VARS 0
+const char* keyword_defined   = "1";
+const char* keyword_undefined = "!";
+#endif  EXTEND_IFALLL
+
 static const char *add_setenvif_core(cmd_parms *cmd, void *mconfig,
 				     char *fname, const char *args)
 {
@@ -255,6 +282,9 @@
 	new->name = fname;
 	new->regex = regex;
 	new->icase = icase;
+#ifdef  EXTEND_IFALLL
+	new->is_extend = 0;
+#endif  EXTEND_IFALLL
 	new->preg = ap_pregcomp(cmd->pool, regex,
 				(REG_EXTENDED | REG_NOSUB
 				 | (icase ? REG_ICASE : 0)));
@@ -344,6 +374,95 @@
     return add_setenvif_core(cmd, mconfig, "User-Agent", args);
 }
 
+#ifdef EXTEND_IFALLL
+static const char *add_setenvifall_core(cmd_parms* cmd, 
+				     int        is_and,
+				     void*      mconfig,
+				     char*      fname, 
+				     const char *args)
+{
+  sei_cfg_rec* sconf;
+  sei_entry*   entries;
+  int i;
+  int beenhere = 0;
+  int perdir;
+  char* arg;
+
+  sei_entry *new = NULL;
+
+  perdir = (cmd->path != NULL);
+  sconf = perdir ? 
+    (sei_cfg_rec *) mconfig : 
+    (sei_cfg_rec *) ap_get_module_config(cmd->server->module_config,  
+					    &setenvif_module);
+    
+  entries = (sei_entry *) sconf->conditionals->elts;
+
+  if( new == NULL ){
+    /* i = sconf->conditionals->nelts - 1; */
+    new = ap_push_array(sconf->conditionals);
+    new->name      = fname;
+    new->is_extend = 1;
+    new->is_and    = is_and ;
+    new->vars      = ap_make_table(cmd->pool, 2);
+  }
+  
+  arg = ap_getword_conf(cmd->pool, &args);
+  if( !*arg ){
+    return ap_pstrcat(cmd->pool, "Missing envariable expression for ",
+		      cmd->cmd->name, NULL);    
+  }
+  new->value = arg ;
+
+  for ( ; ; ) {
+    char* arg = ap_getword_conf(cmd->pool, &args);
+    if (!*arg) {
+      break;
+    }
+    beenhere++;
+    
+    if (*arg == '!') {
+      ap_table_setn(new->vars, arg + 1, keyword_undefined );
+    }
+    else {
+      ap_table_setn(new->vars, arg,     keyword_defined );
+    }
+  }
+
+  if (!beenhere) {
+    return ap_pstrcat(cmd->pool, "Missing envariable expression for ",
+		      cmd->cmd->name, NULL);
+  }
+
+  return NULL;
+}
+
+
+static const char *add_setenvifall(cmd_parms *cmd, void *mconfig,
+				   const char *args)
+{
+    char* fname =  ap_getword_conf(cmd->pool, &args); /* get header name */
+    if (!*fname) {
+        return ap_pstrcat(cmd->pool, "Missing header-field name for ",
+			  cmd->cmd->name, NULL);
+    }
+
+    return add_setenvifall_core(cmd, COND_IF_ALL_VARS, mconfig, fname, args);
+}
+
+static const char *add_setenvifeither(cmd_parms *cmd, void *mconfig,
+				      const char *args)
+{
+    char* fname =  ap_getword_conf(cmd->pool, &args); /* get header name */
+    if (!*fname) {
+      return ap_pstrcat(cmd->pool, "Missing header-field name for ",
+			cmd->cmd->name, NULL);
+    }
+
+    return add_setenvifall_core(cmd, COND_IF_EITHER_VARS, mconfig, fname, args); 
+}
+#endif EXTEND_IFALL
+
 static const command_rec setenvif_module_cmds[] =
 {
     { "SetEnvIf", add_setenvif, NULL,
@@ -354,6 +473,10 @@
       OR_FILEINFO, RAW_ARGS, "A browser regex and a list of variables." },
     { "BrowserMatchNoCase", add_browser, ICASE_MAGIC,
       OR_FILEINFO, RAW_ARGS, "A browser regex and a list of variables." },
+#ifdef EXTEND_IFALLL
+    { "SetEnvIfAll",    add_setenvifall,    NULL,  OR_FILEINFO, RAW_ARGS,  "an environment variable name and conditions." },
+    { "SetEnvIfEither", add_setenvifeither, NULL,  OR_FILEINFO, RAW_ARGS, "an environment variable name and conditions." },    
+#endif EXTEND_IFALL
     { NULL },
 };
 
@@ -392,6 +515,58 @@
     for (i = 0; i < sconf->conditionals->nelts; ++i) {
         sei_entry *b = &entries[i];
 
+#ifdef EXTEND_IFALLL
+	if( b->is_extend ){
+	  int flag ;
+
+	  array_header *arr = ap_table_elts(b->vars);
+	  elts = (table_entry *) arr->elts;
+
+	  if( b->is_and == COND_IF_ALL_VARS ){
+	    /* SetEnvIfAll */
+	    flag = 1; 
+	    for (j = 0; j < arr->nelts; ++j) {
+	      const char* var  = elts[j].key;
+	      const char* cond = elts[j].val;
+	      const char* val  = ap_table_get(r->headers_in, var);
+	      
+	      if (val == NULL) {
+		val = ap_table_get(r->subprocess_env, var);
+	      }
+	      
+	      if( (cond == keyword_defined && val == NULL ) ||
+		  (cond != keyword_defined && val != NULL ) ){
+		flag = 0;
+		break;
+	      }
+	    }
+	  } else {
+	    /* SetEnvIfEither */
+	    flag = 0; 
+	    for (j = 0; j < arr->nelts; ++j) {
+	      const char* var  = elts[j].key;
+	      const char* cond = elts[j].val;
+	      const char* val  = ap_table_get(r->headers_in, var);
+	      
+	      if (val == NULL) {
+		val = ap_table_get(r->subprocess_env, var);
+	      }
+	      
+	      if( (cond == keyword_defined && val != NULL ) ||
+		  (cond != keyword_defined && val == NULL ) ){
+		flag = 1;
+		break;
+	      }	  
+	    }
+	  }
+	  if( flag ){
+	    /* set environment variable */
+	    ap_table_setn(r->subprocess_env, b->name, b->value);
+	  }
+	  continue;
+	}
+#endif EXTEND_IFALLL
+
 	/* Optimize the case where a bunch of directives in a row use the
 	 * same header.  Remember we don't need to strcmp the two header
 	 * names because we made sure the pointers were equal during