httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Alexei Kosut <ako...@hyperreal.com>
Subject cvs commit: apache/src mod_include.c
Date Wed, 07 Aug 1996 00:15:06 GMT
akosut      96/08/06 17:15:06

  Modified:    src       mod_include.c
  Log:
  Add XSSI functionality.
  
  Submitted by: Howard Fear
  Reviewed by: Alexei Kosut, Rob Hartill, Randy Terbush
  
  Revision  Changes    Path
  1.13      +936 -78   apache/src/mod_include.c
  
  Index: mod_include.c
  ===================================================================
  RCS file: /export/home/cvs/apache/src/mod_include.c,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -C3 -r1.12 -r1.13
  *** mod_include.c	1996/07/28 19:27:48	1.12
  --- mod_include.c	1996/08/07 00:15:03	1.13
  ***************
  *** 68,73 ****
  --- 68,78 ----
    #include "http_log.h"
    #include "http_main.h"
    #include "util_script.h"
  + #ifdef HAVE_POSIX_REGEX
  + #include <regex.h>
  + #else
  + #include "regex.h"
  + #endif
    
    #define STARTING_SEQUENCE "<!--#"
    #define ENDING_SEQUENCE "-->"
  ***************
  *** 80,85 ****
  --- 85,91 ----
    static char *get_tag(pool *p, FILE *in, char *tag, int tag_len, int dodecode);
    static int get_directive(FILE *in, char *d, pool *p);
    
  + 
    /* ------------------------ Environment function -------------------------- */
    
    void add_include_vars(request_rec *r, char *timefmt)
  ***************
  *** 99,105 ****
          table_set(e, "USER_NAME", pw->pw_name);
        } else {
          char uid[16];
  !       sprintf(uid, "user#%ld", (unsigned long)r->finfo.st_uid);
          table_set(e, "USER_NAME", uid);
        }
    
  --- 105,111 ----
          table_set(e, "USER_NAME", pw->pw_name);
        } else {
          char uid[16];
  !       sprintf(uid, "user#%lu", (unsigned long)r->finfo.st_uid);
          table_set(e, "USER_NAME", uid);
        }
    
  ***************
  *** 118,124 ****
     { \
       int i = getc(f); \
       if(feof(f) || ferror(f) || (i == -1)) { \
  !         pfclose(p, f); \
            return r; \
       } \
       c = (char)i; \
  --- 124,130 ----
     { \
       int i = getc(f); \
       if(feof(f) || ferror(f) || (i == -1)) { \
  !         pfclose(p,f); \
            return r; \
       } \
       c = (char)i; \
  ***************
  *** 130,136 ****
     * matter much, but this is an inner loop...
     */
    
  ! int find_string(FILE *in,char *str, request_rec *r) {
        int x,l=strlen(str),p;
        char c;
    
  --- 136,142 ----
     * matter much, but this is an inner loop...
     */
    
  ! int find_string(FILE *in,char *str, request_rec *r, int printing) {
        int x,l=strlen(str),p;
        char c;
    
  ***************
  *** 145,154 ****
                if(r) {
                    if(p) {
                        for(x=0;x<p;x++) {
  !                         rputc(str[x],r);
                        }
                    }
  !                 rputc(c,r);
                }
                p=0;
            }
  --- 151,160 ----
                if(r) {
                    if(p) {
                        for(x=0;x<p;x++) {
  !                         if (printing) rputc(str[x],r);
                        }
                    }
  !                 if (printing) rputc(c,r);
                }
                p=0;
            }
  ***************
  *** 286,292 ****
        tag_val = t;
    
        while (isspace(c)) GET_CHAR(in, c, NULL,p); /* space before = */
  !     if (c != '=') return NULL;
    
        do {
    	GET_CHAR(in,c,NULL,p);  /* space after = */
  --- 292,301 ----
        tag_val = t;
    
        while (isspace(c)) GET_CHAR(in, c, NULL,p); /* space before = */
  !     if (c != '=') {
  !         ungetc(c, in);
  !         return NULL;
  !     }
    
        do {
    	GET_CHAR(in,c,NULL,p);  /* space after = */
  ***************
  *** 310,316 ****
        return pstrdup (p, tag_val);
    }
    
  - /* the pool is required to allow GET_CHAR to call pfclose */
    static int
    get_directive(FILE *in, char *d, pool *p) {
        char c;
  --- 319,324 ----
  ***************
  *** 332,337 ****
  --- 340,417 ----
        return 0;
    }
    
  + /*
  +  * Do variable substitution on strings
  +  */
  + void parse_string(request_rec *r, char *in, char *out, int length)
  + {
  +     char ch;
  +     char *next = out;
  +     int numchars = 0;
  + 
  +     while ((ch = *in++) != '\0') {
  +         switch(ch) {
  +           case '\\':
  +             *next++ = (*in != '\0') ? *in++ : '\0';
  +             break;
  +           case '$':
  +           {
  +             char var[MAX_STRING_LEN];
  +             char vtext[MAX_STRING_LEN];
  +             char *val;
  +             int braces=0;
  +             int vlen, vtlen;
  +             /* 
  +              * Keep the $ and { around because we do no substitution
  +              * if the variable isn't found
  +              */
  +             vlen = vtlen = 0;
  +             vtext[vtlen++] = ch;
  +             if (*in == '{') { braces = 1; vtext[vtlen++] = *in++; }
  +             while (*in != '\0') {
  +                 if (vlen == (MAX_STRING_LEN - 1)) continue;
  +                 if (braces == 1) {
  +                     if (*in == '}') break;
  +                 }
  +                 if (! (isalpha((int)*in) || (*in == '_') || isdigit((int)*in)) ) break;
  +                 if (vtlen < (MAX_STRING_LEN - 1)) vtext[vtlen++] = *in;
  +                 var[vlen++] = *in++;
  +             }
  +             var[vlen] = vtext[vtlen] = '\0';
  +             if (braces == 1) {
  +                 if (*in != '}') {
  +                     log_printf(r->server, "Invalid variable %s%s", vtext,in);
  +                     *next = '\0';
  +                     return;
  +                 } else
  +                     in++;
  +             } 
  + 
  +             /* Leave single dollar signs like the shell does */
  +             val = (char *)NULL;
  +             if (*var == '\0') {
  +                 if (strcmp(vtext, "$") == 0) {
  +                     var[0]='$', var[1]='\0';
  +                     val = &var[0];
  +                 }
  +             } else
  +                 val = table_get (r->subprocess_env, &var[0]); 
  +             while ((val != (char *)NULL) && (*val != '\0')) {
  +                 *next++ = *val++;
  +                 if (++numchars == (length -1)) break;
  +             }
  +             break;
  +           }
  +           default:
  +             *next++ = ch;
  +             break;
  +         }
  +         if (++numchars == (length -1)) break;
  +     }
  +     *next = '\0';
  +     return;
  + }
  + 
    /* --------------------------- Action handlers ---------------------------- */
    
    int include_cgi(char *s, request_rec *r)
  ***************
  *** 360,366 ****
        
        if (run_sub_req (rr) == REDIRECT) {
            char *location = table_get (rr->headers_out, "Location");
  ! 	location = escape_html(rr->pool, location);
    	rvputs(r,"<A HREF=\"", location, "\">", location, "</A>", NULL);
        }
        
  --- 440,446 ----
        
        if (run_sub_req (rr) == REDIRECT) {
            char *location = table_get (rr->headers_out, "Location");
  !         location = escape_html(rr->pool, location);
    	rvputs(r,"<A HREF=\"", location, "\">", location, "</A>", NULL);
        }
        
  ***************
  *** 371,376 ****
  --- 451,457 ----
    
    int handle_include(FILE *in, request_rec *r, char *error, int noexec) {
        char tag[MAX_STRING_LEN];
  +     char parsed_string[MAX_STRING_LEN];
        char *tag_val;
    
        while(1) {
  ***************
  *** 380,395 ****
    	    request_rec *rr=NULL;
    	    char *error_fmt = NULL;
    
    	    if (tag[0] == 'f')
    	    { /* be safe; only files in this directory or below allowed */
    		char tmp[MAX_STRING_LEN+2];
  ! 		sprintf(tmp, "/%s/", tag_val);
  ! 		if (tag_val[0] == '/' || strstr(tmp, "/../") != NULL)
    		    error_fmt = "unable to include file %s in parsed file %s";
    		else
  ! 		    rr = sub_req_lookup_file (tag_val, r);
    	    } else
  ! 		rr = sub_req_lookup_uri (tag_val, r);
    	    
    	    if (!error_fmt && rr->status != 200)
    	        error_fmt = "unable to include %s in parsed file %s";
  --- 461,477 ----
    	    request_rec *rr=NULL;
    	    char *error_fmt = NULL;
    
  +             parse_string(r, tag_val, parsed_string, MAX_STRING_LEN);
    	    if (tag[0] == 'f')
    	    { /* be safe; only files in this directory or below allowed */
    		char tmp[MAX_STRING_LEN+2];
  ! 		sprintf(tmp, "/%s/", parsed_string);
  ! 		if (parsed_string[0] == '/' || strstr(tmp, "/../") != NULL)
    		    error_fmt = "unable to include file %s in parsed file %s";
    		else
  ! 		    rr = sub_req_lookup_file (parsed_string, r);
    	    } else
  ! 		rr = sub_req_lookup_uri (parsed_string, r);
    	    
    	    if (!error_fmt && rr->status != 200)
    	        error_fmt = "unable to include %s in parsed file %s";
  ***************
  *** 398,413 ****
    		&& (strncmp (rr->content_type, "text/", 5)))
    	        error_fmt =
    		  "unable to include potential exec %s in parsed file %s";
  ! 
  ! 	    if (error_fmt == NULL)
  ! 	    {
  ! 		request_rec *p;
  ! 
  ! 		for (p=r; p != NULL; p=p->main)
  ! 		    if (strcmp(p->filename, rr->filename) == 0) break;
  ! 		if (p != NULL)
  ! 		    error_fmt = "Recursive include of %s in parsed file %s";
  ! 	    }
    	    
    	    if (!error_fmt && run_sub_req (rr))
    	        error_fmt = "unable to include %s in parsed file %s";
  --- 480,494 ----
    		&& (strncmp (rr->content_type, "text/", 5)))
    	        error_fmt =
    		  "unable to include potential exec %s in parsed file %s";
  !             if (error_fmt == NULL)
  !             {
  !                 request_rec *p;
  ! 
  !                 for (p=r; p != NULL; p=p->main)
  !                     if (strcmp(p->filename, rr->filename) == 0) break;
  !                 if (p != NULL)
  !                     error_fmt = "Recursive include of %s in parsed file %s";
  !             }
    	    
    	    if (!error_fmt && run_sub_req (rr))
    	        error_fmt = "unable to include %s in parsed file %s";
  ***************
  *** 423,429 ****
                return 0;
            else {
                log_printf(r->server, "unknown parameter %s to tag include in %s",
  ! 		       tag, r->filename);
                rputs(error, r);
            }
        }
  --- 504,510 ----
                return 0;
            else {
                log_printf(r->server, "unknown parameter %s to tag include in %s",
  !                        tag, r->filename);
                rputs(error, r);
            }
        }
  ***************
  *** 440,457 ****
        char *s = ((include_cmd_arg *)arg)->s;
        table *env = r->subprocess_env;
    #ifdef DEBUG_INCLUDE_CMD    
  ! #ifdef __EMX__
  !     /* under OS/2 /dev/tty is referenced as con */
  !     FILE *dbg = fopen ("con", "w");
  ! #else
  !         FILE *dbg = fopen ("/dev/tty", "w");
  ! #endif    
    #endif    
        char err_string [MAX_STRING_LEN];
    
    #ifdef DEBUG_INCLUDE_CMD    
        fprintf (dbg, "Attempting to include command '%s'\n", s);
    #endif    
    
        if (r->path_info && r->path_info[0] != '\0')
        {
  --- 521,538 ----
        char *s = ((include_cmd_arg *)arg)->s;
        table *env = r->subprocess_env;
    #ifdef DEBUG_INCLUDE_CMD    
  !     FILE *dbg = fopen ("/dev/tty", "w");
    #endif    
        char err_string [MAX_STRING_LEN];
    
    #ifdef DEBUG_INCLUDE_CMD    
  + #ifdef __EMX__
  +     /* under OS/2 /dev/tty is referenced as con */
  +     FILE *dbg = fopen ("con", "w");
  + #else
        fprintf (dbg, "Attempting to include command '%s'\n", s);
    #endif    
  + #endif    
    
        if (r->path_info && r->path_info[0] != '\0')
        {
  ***************
  *** 518,538 ****
        char tag[MAX_STRING_LEN];
        char *tag_val;
        char *file = r->filename;
    
        while(1) {
            if(!(tag_val = get_tag (r->pool, in, tag, MAX_STRING_LEN, 1)))
                return 1;
            if(!strcmp(tag,"cmd")) {
  !             if(include_cmd(tag_val, r) == -1) {
  !                 log_printf(r->server, "failed command exec %s in %s",
  ! 			   tag_val, file);
                    rputs(error, r);
                }
                /* just in case some stooge changed directories */
                chdir_file(r->filename);
            } 
            else if(!strcmp(tag,"cgi")) {
  !             if(include_cgi(tag_val, r) == -1) {
                    log_printf(r->server, "invalid CGI ref %s in %s",tag_val,file);
                    rputs(error, r);
                }
  --- 599,622 ----
        char tag[MAX_STRING_LEN];
        char *tag_val;
        char *file = r->filename;
  +     char parsed_string[MAX_STRING_LEN];
    
        while(1) {
            if(!(tag_val = get_tag (r->pool, in, tag, MAX_STRING_LEN, 1)))
                return 1;
            if(!strcmp(tag,"cmd")) {
  !             parse_string(r, tag_val, parsed_string, MAX_STRING_LEN);
  !             if(include_cmd(parsed_string, r) == -1) {
  !                 log_printf(r->server, "unknown parameter %s to tag include in %s",
  !                            tag, r->filename);
                    rputs(error, r);
                }
                /* just in case some stooge changed directories */
                chdir_file(r->filename);
            } 
            else if(!strcmp(tag,"cgi")) {
  !             parse_string(r, tag_val, parsed_string, MAX_STRING_LEN);
  !             if(include_cgi(parsed_string, r) == -1) {
                    log_printf(r->server, "invalid CGI ref %s in %s",tag_val,file);
                    rputs(error, r);
                }
  ***************
  *** 543,549 ****
                return 0;
            else {
                log_printf(r->server, "unknown parameter %s to tag exec in %s",
  ! 		       tag, file);
                rputs(error, r);
            }
        }
  --- 627,633 ----
                return 0;
            else {
                log_printf(r->server, "unknown parameter %s to tag exec in %s",
  !                        tag, file);
                rputs(error, r);
            }
        }
  ***************
  *** 566,572 ****
                return 0;
            else {
                log_printf(r->server, "unknown parameter %s to tag echo in %s",
  ! 		    tag, r->filename);
                rputs(error, r);
            }
        }
  --- 650,656 ----
                return 0;
            else {
                log_printf(r->server, "unknown parameter %s to tag echo in %s",
  !                 tag, r->filename);
                rputs(error, r);
            }
        }
  ***************
  *** 576,581 ****
  --- 660,666 ----
                      int *sizefmt) {
        char tag[MAX_STRING_LEN];
        char *tag_val;
  +     char parsed_string[MAX_STRING_LEN];
        table *env = r->subprocess_env;
    
        while(1) {
  ***************
  *** 584,606 ****
            if(!strcmp(tag,"errmsg"))
                strcpy(error,tag_val);
            else if(!strcmp(tag,"timefmt")) {
  ! 	    time_t date = r->request_time;
  !             strcpy(tf,tag_val);
                table_set (env, "DATE_LOCAL", ht_time(r->pool,date,tf,0));
                table_set (env, "DATE_GMT", ht_time(r->pool,date,tf,1));
                table_set (env, "LAST_MODIFIED", ht_time(r->pool,r->finfo.st_mtime,tf,0));
            }
            else if(!strcmp(tag,"sizefmt")) {
  ! 	    decodehtml(tag_val);
  !             if(!strcmp(tag_val,"bytes"))
                    *sizefmt = SIZEFMT_BYTES;
  !             else if(!strcmp(tag_val,"abbrev"))
                    *sizefmt = SIZEFMT_KMG;
            } 
            else if(!strcmp(tag,"done"))
                return 0;
            else {
  !             log_printf(r->server, "unknown parameter %s to tag config in %s",
                        tag, r->filename);
                rputs(error, r);
            }
  --- 669,693 ----
            if(!strcmp(tag,"errmsg"))
                strcpy(error,tag_val);
            else if(!strcmp(tag,"timefmt")) {
  !   	    time_t date = r->request_time;
  !             parse_string(r, tag_val, parsed_string, MAX_STRING_LEN);
  !             strcpy(tf,parsed_string);
                table_set (env, "DATE_LOCAL", ht_time(r->pool,date,tf,0));
                table_set (env, "DATE_GMT", ht_time(r->pool,date,tf,1));
                table_set (env, "LAST_MODIFIED", ht_time(r->pool,r->finfo.st_mtime,tf,0));
            }
            else if(!strcmp(tag,"sizefmt")) {
  !             parse_string(r, tag_val, parsed_string, MAX_STRING_LEN);
  ! 	    decodehtml(parsed_string);
  !             if(!strcmp(parsed_string,"bytes"))
                    *sizefmt = SIZEFMT_BYTES;
  !             else if(!strcmp(parsed_string,"abbrev"))
                    *sizefmt = SIZEFMT_KMG;
            } 
            else if(!strcmp(tag,"done"))
                return 0;
            else {
  !             log_printf(r->server,"unknown parameter %s to tag config in %s",
                        tag, r->filename);
                rputs(error, r);
            }
  ***************
  *** 645,653 ****
            }
        }
        else {
  !         log_printf(r->server, "unknown parameter %s to tag %s in %s",
                    tag, directive, r->filename);
  ! 	rputs(error, r);
            return -1;
        }
    }
  --- 732,740 ----
            }
        }
        else {
  !         log_printf(r->server,"unknown parameter %s to tag %s in %s",
                    tag, directive, r->filename);
  !         rputs(error, r);
            return -1;
        }
    }
  ***************
  *** 658,686 ****
        char tag[MAX_STRING_LEN];
        char *tag_val;
        struct stat finfo;
    
        while(1) {
            if(!(tag_val = get_tag(r->pool, in, tag, MAX_STRING_LEN, 1)))
                return 1;
            else if(!strcmp(tag,"done"))
                return 0;
  !         else if(!find_file(r,"fsize",tag,tag_val,&finfo,error)) {
  !             if(sizefmt == SIZEFMT_KMG) {
  !                 send_size(finfo.st_size, r);
  !             }
  !             else {
  !                 int l,x;
  ! #if defined(BSD) && BSD > 199305
  !                 sprintf(tag,"%qd",finfo.st_size);
  ! #else
  !                 sprintf(tag,"%ld",finfo.st_size);
  ! #endif
  !                 l = strlen(tag); /* grrr */
  !                 for(x=0;x<l;x++) {
  !                     if(x && (!((l-x) % 3))) {
  !                         rputc(',', r);
                        }
  -                     rputc (tag[x],r);
                    }
                }
            }
  --- 745,777 ----
        char tag[MAX_STRING_LEN];
        char *tag_val;
        struct stat finfo;
  +     char parsed_string[MAX_STRING_LEN];
    
        while(1) {
            if(!(tag_val = get_tag(r->pool, in, tag, MAX_STRING_LEN, 1)))
                return 1;
            else if(!strcmp(tag,"done"))
                return 0;
  !         else {
  !             parse_string(r, tag_val, parsed_string, MAX_STRING_LEN);
  !             if(!find_file(r,"fsize",tag,parsed_string,&finfo,error)) {
  !                 if(sizefmt == SIZEFMT_KMG) {
  !                     send_size(finfo.st_size, r);
  !                 }
  !                 else {
  !                     int l,x;
  !     #if defined(BSD) && BSD > 199305
  !                     sprintf(tag,"%qd",finfo.st_size);
  !     #else
  !                     sprintf(tag,"%ld",finfo.st_size);
  !     #endif
  !                     l = strlen(tag); /* grrr */
  !                     for(x=0;x<l;x++) {
  !                         if(x && (!((l-x) % 3))) {
  !                             rputc(',', r);
  !                         }
  !                         rputc (tag[x],r);
                        }
                    }
                }
            }
  ***************
  *** 692,705 ****
        char tag[MAX_STRING_LEN];
        char *tag_val;
        struct stat finfo;
    
        while(1) {
            if(!(tag_val = get_tag(r->pool, in, tag, MAX_STRING_LEN, 1)))
                return 1;
            else if(!strcmp(tag,"done"))
                return 0;
  !         else if(!find_file(r,"flastmod",tag,tag_val,&finfo,error))
  !             rputs(ht_time(r->pool, finfo.st_mtime, tf, 0), r);
        }
    }    
    
  --- 783,1523 ----
        char tag[MAX_STRING_LEN];
        char *tag_val;
        struct stat finfo;
  +     char parsed_string[MAX_STRING_LEN];
  + 
  +     while(1) {
  +         if(!(tag_val = get_tag(r->pool, in, tag, MAX_STRING_LEN, 1)))
  +             return 1;
  +         else if(!strcmp(tag,"done"))
  +             return 0;
  +         else {
  +             parse_string(r, tag_val, parsed_string, MAX_STRING_LEN);
  +             if(!find_file(r,"flastmod",tag,parsed_string,&finfo,error))
  +                 rputs(ht_time(r->pool, finfo.st_mtime, tf, 0), r);
  +         }
  +     }
  + }    
  + 
  + int re_check(request_rec *r, char *string, char *rexp) 
  + {
  +     regex_t compiled;
  +     char err_string[MAX_STRING_LEN];
  +     int regex_error;
  + 
  +     regex_error = regcomp(&compiled, rexp, REG_EXTENDED|REG_NOSUB);
  +     if (regex_error) {
  +         regerror(regex_error, &compiled, err_string, (size_t)MAX_STRING_LEN);
  +         log_printf(r->server,
  +             "unable to compile pattern %s [%s]", rexp, &err_string);
  +         return -1;
  +     }
  +     regex_error = regexec(&compiled, string, 0, (regmatch_t *)NULL, 0);
  +     regfree(&compiled);
  +     return(!regex_error);
  + }
  + 
  + enum token_type { token_string,
  +     token_and, token_or, token_not, token_eq, token_ne,
  +     token_rbrace, token_lbrace, token_group
  + };
  + struct token {
  +     enum token_type type;
  +     char value[MAX_STRING_LEN];
  + };
  + 
  + char *get_ptoken(request_rec *r, char *string, struct token *token) {
  +     char ch;
  +     int next=0;
  +     int qs=0;
  + 
  +     /* Skip leading white space */
  +     if (string == (char *)NULL) return (char *)NULL;
  +     while ((ch = *string++))
  +         if (!isspace(ch)) break;
  +     if (ch == '\0') return (char *)NULL;
  + 
  +     switch(ch) {
  +       case '(':
  +         token->type = token_lbrace;
  +         return(string);
  +       case ')':
  +         token->type = token_rbrace;
  +         return(string);
  +       case '=':
  +         token->type = token_eq;
  +         return(string);
  +       case '!':
  +         if (*string == '=') {
  +             token->type = token_ne;
  +             return(string+1);
  +         } else {
  +             token->type = token_not;
  +             return(string);
  +         }
  +       case '\'':
  +         token->type = token_string;
  +         qs = 1;
  +         break;
  +       case '|':
  +         if (*string == '|') {
  +             token->type = token_or;
  +             return(string+1);
  +         }
  +       case '&':
  +         if (*string == '&') {
  +             token->type = token_and;
  +             return(string+1);
  +         }
  +       default:
  +         token->type = token_string;
  +         break;
  +     }
  +     /* We should only be here if we are in a string */
  +     if (!qs) token->value[next++] = ch;
  + 
  +     /* 
  +      * Yes I know that goto's are BAD.  But, c doesn't allow me to
  +      * exit a loop from a switch statement.  Yes, I could use a flag,
  +      * but that is (IMHO) even less readable/maintainable than the goto.
  +      */ 
  +     /* 
  +      * I used the ++string throughout this section so that string
  +      * ends up pointing to the next token and I can just return it
  +      */ 
  +     for (ch = *string; ch != '\0'; ch = *++string) {
  +         if (ch == '\\') {
  +             if ((ch = *++string) == '\0') goto TOKEN_DONE;
  +             token->value[next++] = ch;
  +             continue;
  +         }
  +         if (!qs) {
  +             if (isspace(ch)) goto TOKEN_DONE;
  +             switch(ch) {
  +               case '(': goto TOKEN_DONE;
  +               case ')': goto TOKEN_DONE;
  +               case '=': goto TOKEN_DONE;
  +               case '!': goto TOKEN_DONE;
  +               case '|': if (*(string+1) == '|') goto TOKEN_DONE;
  +               case '&': if (*(string+1) == '&') goto TOKEN_DONE;
  +             }
  +             token->value[next++] = ch;
  +         } else {
  +             if (ch == '\'') { qs=0; ++string; goto TOKEN_DONE; }
  +             token->value[next++] = ch;
  +         }
  +     }
  + TOKEN_DONE:
  +     /* If qs is still set, I have an unmatched ' */
  +     if (qs) { rputs("\nUnmatched '\n", r); next=0; }
  +     token->value[next] = '\0';
  +     return(string);
  + }
  + 
  + 
  + /*
  +  * Hey I still know that goto's are BAD.  I don't think that I've ever
  +  * used two in the same project, let alone the same file before.  But,
  +  * I absolutely want to make sure that I clean up the memory in all
  +  * cases.  And, without rewriting this completely, the easiest way
  +  * is to just branch to the return code which cleans it up.
  +  */
  + int parse_expr(request_rec *r, char *expr, char *error)
  + {
  +     struct parse_node {
  +         struct parse_node *left, *right, *parent;
  +         struct token token;
  +         int value, done;
  +     } *root, *current, *new;
  +     char *parse;
  +     char buffer[MAX_STRING_LEN];
  +     struct pool *expr_pool;
  +     int retval = 0;
  + 
  +     if ((parse = expr) == (char *)NULL) return(0);
  +     root = current = (struct parse_node*)NULL;
  +     if ((expr_pool = make_sub_pool(r->pool)) == (struct pool *)NULL) {
  +         log_printf(r->server, "out of memory", r->filename);
  +         rputs(error, r);
  +         return(0);
  +     }
  + 
  +     /* Create Parse Tree */
  +     while (1) {
  +         new = (struct parse_node*)palloc(expr_pool, sizeof (struct parse_node));
  +         if (new == (struct parse_node*)NULL) {
  +             log_printf(r->server,"out of memory", r->filename);
  +             rputs(error, r);
  +             goto RETURN;
  +         }
  +         new->parent = new->left = new->right = (struct parse_node*)NULL;
  +         new->done = 0;
  +         if ((parse = get_ptoken(r, parse, &new->token)) == (char *)NULL)
  +             break;
  +         switch(new->token.type) {
  + 
  +           case token_string:
  + #ifdef DEBUG_INCLUDE
  +             rvputs(r,"     Token: string (", new->token.value, ")\n", NULL);
  + #endif
  +             if (current == (struct parse_node*)NULL) {
  +                 root = current = new;
  +                 break;
  +             }
  +             switch(current->token.type) {
  +               case token_string:
  +                 if (current->token.value[0] != '\0')
  +                     strncat(current->token.value, " ", MAX_STRING_LEN-1);
  +                 strncat(current->token.value, new->token.value, MAX_STRING_LEN-1);
  +                 break;
  +               case token_eq:
  +               case token_ne:
  +               case token_and:
  +               case token_or:
  +               case token_lbrace:
  +               case token_not:
  +                 new->parent = current;
  +                 current = current->right = new;
  +                 break;
  +               default:
  +                 log_printf(r->server,
  +                     "Invalid expression %s", expr, r->filename);
  +                 rputs(error, r);
  +                 goto RETURN;
  +             }
  +             break;
  + 
  +           case token_and:
  +           case token_or:
  + #ifdef DEBUG_INCLUDE
  + rputs ("     Token: and/or\n", r);
  + #endif
  +             if (current == (struct parse_node*)NULL) {
  +                 log_printf(r->server,
  +                     "Invalid expression %s", expr, r->filename);
  +                 rputs(error, r);
  +                 goto RETURN;
  +             }
  +             /* Percolate upwards */
  +             while (current != (struct parse_node *)NULL) {
  +                 switch(current->token.type) {
  +                   case token_string:
  +                   case token_group:
  +                   case token_not:
  +                   case token_eq:
  +                   case token_ne:
  +                   case token_and:
  +                   case token_or:
  +                     current = current->parent;
  +                     continue;
  +                   case token_lbrace:
  +                     break;
  +                   default:
  +                     log_printf(r->server,
  +                         "Invalid expression %s", expr, r->filename);
  +                     rputs(error, r);
  +                     goto RETURN;
  +                 }
  +                 break;
  +             }
  +             if (current == (struct parse_node*)NULL) {
  +                 new->left = root;
  +                 new->left->parent = new;
  +                 new->parent = (struct parse_node*)NULL;
  +                 root = new;
  +             } else {
  +                 new->left = current->right;
  +                 current->right = new;
  +                 new->parent = current;
  +             }
  +             current = new;
  +             break;
  + 
  +           case token_not:
  + #ifdef DEBUG_INCLUDE
  + rputs("     Token: not\n", r);
  + #endif
  +             if (current == (struct parse_node*)NULL) {
  +                 root = current = new;
  +                 break;
  +             }
  +             /* Percolate upwards */
  +             while (current != (struct parse_node *)NULL) {
  +                 switch(current->token.type) {
  +                   case token_not:
  +                   case token_eq:
  +                   case token_ne:
  +                   case token_and:
  +                   case token_or:
  +                   case token_lbrace:
  +                     break;
  +                   default:
  +                     log_printf(r->server,
  +                         "Invalid expression %s", expr, r->filename);
  +                     rputs(error, r);
  +                     goto RETURN;
  +                 }
  +                 break;
  +             }
  +             if (current == (struct parse_node*)NULL) {
  +                 new->left = root;
  +                 new->left->parent = new;
  +                 new->parent = (struct parse_node*)NULL;
  +                 root = new;
  +             } else {
  +                 new->left = current->right;
  +                 current->right = new;
  +                 new->parent = current;
  +             }
  +             current = new;
  +             break;
  + 
  +           case token_eq:
  +           case token_ne:
  + #ifdef DEBUG_INCLUDE
  + rputs("     Token: eq/ne\n", r);
  + #endif
  +             if (current == (struct parse_node*)NULL) {
  +                 log_printf(r->server,
  +                     "Invalid expression %s", expr, r->filename);
  +                 rputs(error, r);
  +                 goto RETURN;
  +             }
  +             /* Percolate upwards */
  +             while (current != (struct parse_node *)NULL) {
  +                 switch(current->token.type) {
  +                   case token_string:
  +                   case token_group:
  +                     current = current->parent;
  +                     continue;
  +                   case token_lbrace:
  +                   case token_and:
  +                   case token_or:
  +                     break;
  +                   case token_not:
  +                   case token_eq:
  +                   case token_ne:
  +                   default:
  +                     log_printf(r->server,
  +                         "Invalid expression %s", expr, r->filename);
  +                     rputs(error, r);
  +                     goto RETURN;
  +                 }
  +                 break;
  +             }
  +             if (current == (struct parse_node*)NULL) {
  +                 new->left = root;
  +                 new->left->parent = new;
  +                 new->parent = (struct parse_node*)NULL;
  +                 root = new;
  +             } else {
  +                 new->left = current->right;
  +                 current->right = new;
  +                 new->parent = current;
  +             }
  +             current = new;
  +             break;
  + 
  +           case token_rbrace:
  + #ifdef DEBUG_INCLUDE
  + rputs("     Token: rbrace\n", r);
  + #endif
  +             while (current != (struct parse_node*)NULL) {
  +                 if (current->token.type == token_lbrace) {
  +                     current->token.type = token_group;
  +                     break;
  +                 }
  +                 current = current->parent;
  +             }
  +             if (current == (struct parse_node*)NULL) {
  +                 log_printf(r->server,"Unmatched ')'in %s\n", expr, r->filename);
  +                 rputs(error, r);
  +                 goto RETURN;
  +             }
  +             break;
  + 
  +           case token_lbrace:
  + #ifdef DEBUG_INCLUDE
  + rputs("     Token: lbrace\n", r);
  + #endif
  +             if (current == (struct parse_node*)NULL) {
  +                 root = current = new;
  +                 break;
  +             }
  +             /* Percolate upwards */
  +             while (current != (struct parse_node *)NULL) {
  +                 switch(current->token.type) {
  +                   case token_not:
  +                   case token_eq:
  +                   case token_ne:
  +                   case token_and:
  +                   case token_or:
  +                   case token_lbrace:
  +                     break;
  +                   case token_string:
  +                   case token_group:
  +                   default:
  +                     log_printf(r->server,
  +                         "Invalid expression %s", expr, r->filename);
  +                     rputs(error, r);
  +                     goto RETURN;
  +                 }
  +                 break;
  +             }
  +             if (current == (struct parse_node*)NULL) {
  +                 new->left = root;
  +                 new->left->parent = new;
  +                 new->parent = (struct parse_node*)NULL;
  +                 root = new;
  +             } else {
  +                 new->left = current->right;
  +                 current->right = new;
  +                 new->parent = current;
  +             }
  +             current = new;
  +             break;
  + 	  default:
  + 	    break;
  +         }
  +     }
  + 
  +     /* Evaluate Parse Tree */
  +     current = root;
  +     while (current != (struct parse_node *)NULL) {
  +         switch(current->token.type) {
  +           case token_string:
  + #ifdef DEBUG_INCLUDE
  + rputs("     Evaluate string\n", r);
  + #endif
  +             parse_string(r, current->token.value, buffer, MAX_STRING_LEN);
  +             strncpy(current->token.value, buffer, MAX_STRING_LEN-1);
  +             current->value = (current->token.value[0] != '\0');
  +             current->done = 1;
  +             current = current->parent;
  +             break;
  + 
  +           case token_and:
  +           case token_or:
  + #ifdef DEBUG_INCLUDE
  + rputs("     Evaluate and/or\n", r);
  + #endif
  +             if (current->left == (struct parse_node*)NULL ||
  +                         current->right == (struct parse_node*)NULL) {
  +                 log_printf(r->server,
  +                     "Invalid expression %s", expr, r->filename);
  +                 rputs(error, r);
  +                 goto RETURN;
  +             }
  +             if (!current->left->done) {
  +                 switch(current->left->token.type) {
  +                   case token_string:
  +                     parse_string(r, current->left->token.value,
  +                             buffer, MAX_STRING_LEN);
  +                     strncpy(current->left->token.value, buffer,
  +                             MAX_STRING_LEN-1);
  +                     current->left->done = 1;
  +                     break;
  +                   default:
  +                     current = current->left;
  +                     continue;
  +                 }
  +             }
  +             if (!current->right->done) {
  +                 switch(current->right->token.type) {
  +                   case token_string:
  +                     parse_string(r, current->right->token.value,
  +                             buffer, MAX_STRING_LEN);
  +                     strncpy(current->right->token.value, buffer,
  +                             MAX_STRING_LEN-1);
  +                     current->right->done = 1;
  +                     break;
  +                   default:
  +                     current = current->right;
  +                     continue;
  +                 }
  +             }
  + #ifdef DEBUG_INCLUDE
  + rvputs(r,"     Left: ", current->left->value ? "1" : "0", "\n", NULL);
  + rvputs(r,"     Right: ", current->right->value ? "1" : "0", "\n", NULL);
  + #endif
  +             if (current->token.type == token_and)
  +                 current->value =
  +                     current->left->value && current->right->value;
  +             else
  +                 current->value =
  +                     current->left->value || current->right->value;
  + #ifdef DEBUG_INCLUDE
  + rvputs(r,"     Returning ", current->value ? "1" : "0", "\n", NULL);
  + #endif
  +             current->done = 1;
  +             current = current->parent;
  +             break;
  + 
  +           case token_eq:
  +           case token_ne:
  + #ifdef DEBUG_INCLUDE
  + rputs("     Evaluate eq/ne\n", r);
  + #endif
  +             if ((current->left == (struct parse_node*)NULL) ||
  +                         (current->right == (struct parse_node*)NULL) ||
  +                         (current->left->token.type != token_string) ||
  +                         (current->right->token.type != token_string)) {
  +                 log_printf(r->server,
  +                     "Invalid expression %s", expr, r->filename);
  +                 rputs(error, r);
  +                 goto RETURN;
  +             }
  +             parse_string(r, current->left->token.value, buffer, MAX_STRING_LEN);
  +             strncpy(current->left->token.value, buffer, MAX_STRING_LEN-1);
  +             parse_string(r, current->right->token.value, buffer, MAX_STRING_LEN);
  +             strncpy(current->right->token.value, buffer, MAX_STRING_LEN-1);
  +             if (current->right->token.value[0] == '/') {
  +                 int len;
  +                 len = strlen(current->right->token.value);
  +                 if (current->right->token.value[len-1] == '/') {
  +                     current->right->token.value[len-1] = '\0';
  +                 } else {
  +                     log_printf(r->server,"Invalid rexp %s",
  +                             current->right->token.value, r->filename);
  +                     rputs(error, r);
  +                     goto RETURN;
  +                 }
  + #ifdef DEBUG_INCLUDE
  + rvputs(r,"     Re Compare (", current->left->token.value,
  +          ") with /", &current->right->token.value[1], "/\n", NULL);
  + #endif
  +                 current->value =
  +                     re_check(r, current->left->token.value,
  +                             &current->right->token.value[1]);
  +             } else {
  + #ifdef DEBUG_INCLUDE
  + rvputs(r,"     Compare (", current->left->token.value,
  +          ") with (", current->right->token.value, ")\n", NULL);
  + #endif
  +                 current->value =
  +                         (strcmp(current->left->token.value,
  +                          current->right->token.value) == 0);
  +             }
  +             if (current->token.type == token_ne)
  +                 current->value = !current->value;
  + #ifdef DEBUG_INCLUDE
  + rvputs(r,"     Returning ", current->value ? "1" : "0", "\n", NULL);
  + #endif
  +             current->done = 1;
  +             current = current->parent;
  +             break;
  + 
  +           case token_not:
  +             if (current->right != (struct parse_node *)NULL) {
  +                 if (!current->right->done) {
  +                     current = current->right;
  +                     continue;
  +                 }
  +                 current->value = !current->right->value;
  +             } else {
  +                 current->value = 0;
  +             }
  + #ifdef DEBUG_INCLUDE
  + rvputs(r,"     Evaluate !: ", current->value ? "1" : "0", "\n", NULL);
  + #endif
  +             current->done = 1;
  +             current = current->parent;
  +             break;
  + 
  +           case token_group:
  +             if (current->right != (struct parse_node *)NULL) {
  +                 if (!current->right->done) {
  +                     current = current->right;
  +                     continue;
  +                 }
  +                 current->value = current->right->value;
  +             } else {
  +                 current->value = 1;
  +             }
  + #ifdef DEBUG_INCLUDE
  + rvputs(r,"     Evaluate (): ", current->value ? "1" : "0", "\n", NULL);
  + #endif
  +             current->done = 1;
  +             current = current->parent;
  +             break;
  + 
  +           case token_lbrace:
  +             log_printf(r->server,"Unmatched '(' in %s\n", expr, r->filename);
  +             rputs(error, r);
  +             goto RETURN;
  + 
  +           case token_rbrace:
  +             log_printf(r->server,"Unmatched ')' in %s\n", expr, r->filename);
  +             rputs(error, r);
  +             goto RETURN;
  + 
  +           default:
  +             log_printf(r->server,"bad token type");
  +             rputs(error, r);
  +             goto RETURN;
  +         }
  +     }
  + 
  +     retval =  (root == (struct parse_node *)NULL) ? 0 : root->value;
  + RETURN:
  +     destroy_pool(expr_pool);
  +     return (retval);
  + }    
  + 
  + int handle_if(FILE *in, request_rec *r, char *error,
  +               int *conditional_status, int *printing) 
  + {
  +     char tag[MAX_STRING_LEN];
  +     char *tag_val = '\0';
  +     char *expr = '\0';
  + 
  +     while(1) {
  +         tag_val = get_tag(r->pool, in, tag, MAX_STRING_LEN, 0);
  +         if(*tag == '\0')
  +             return 1;
  +         else if(!strcmp(tag,"done")) {
  +             *printing = *conditional_status = parse_expr(r, expr, error);
  + #ifdef DEBUG_INCLUDE
  + rvputs(r,"**** if conditional_status=\"", *conditional_status ? "1" : "0", "\"\n", NULL);
  + #endif
  +             return 0;
  +         } else if(!strcmp(tag,"expr")) {
  + 	    expr = tag_val;
  + #ifdef DEBUG_INCLUDE
  + rvputs(r,"**** if expr=\"", expr, "\"\n", NULL);
  + #endif
  +         } else {
  +             log_printf(r->server,"unknown parameter %s to tag if in %s",
  +                     tag, r->filename);
  +             rputs(error, r);
  +         }
  +     }
  + }    
  + 
  + int handle_elif(FILE *in, request_rec *r, char *error,
  +               int *conditional_status, int *printing) 
  + {
  +     char tag[MAX_STRING_LEN];
  +     char *tag_val = '\0';
  +     char *expr = '\0';
    
        while(1) {
  +         tag_val = get_tag(r->pool, in, tag, MAX_STRING_LEN, 0);
  +         if(*tag == '\0')
  +             return 1;
  +         else if(!strcmp(tag,"done")) {
  + #ifdef DEBUG_INCLUDE
  + rvputs(r,"**** elif conditional_status=\"", *conditional_status ? "1" : "0", "\"\n", NULL);
  + #endif
  +             if (*conditional_status) {
  +                 *printing = 0;
  +                 return(0);
  +             }
  +             *printing = *conditional_status = parse_expr(r, expr, error);
  + #ifdef DEBUG_INCLUDE
  + rvputs(r,"**** elif conditional_status=\"", *conditional_status ? "1" : "0", "\"\n", NULL);
  + #endif
  +             return 0;
  +         } else if(!strcmp(tag,"expr")) {
  + 	    expr = tag_val;
  + #ifdef DEBUG_INCLUDE
  + rvputs(r,"**** if expr=\"", expr, "\"\n", NULL);
  + #endif
  +         } else {
  +             log_printf(r->server,"unknown parameter %s to tag if in %s",
  +                     tag, r->filename);
  +             rputs(error, r);
  +         }
  +     }
  + }
  + 
  + int handle_else(FILE *in, request_rec *r, char *error,
  +               int *conditional_status, int *printing) 
  + {
  +     char tag[MAX_STRING_LEN];
  +     char *tag_val;
  + 
  +     if(!(tag_val = get_tag(r->pool, in, tag, MAX_STRING_LEN, 1)))
  +         return 1;
  +     else if(!strcmp(tag,"done")) {
  + #ifdef DEBUG_INCLUDE
  + rvputs(r,"**** else conditional_status=\"", *conditional_status ? "1" : "0", "\"\n", NULL);
  + #endif
  +         *printing = !(*conditional_status);
  +         *conditional_status = 1;
  +         return 0;
  +     } else {
  +         log_printf(r->server, "else directive does not take tags");
  +         if (*printing) rputs(error, r);
  +         return -1;
  +     }
  + }    
  + 
  + int handle_endif(FILE *in, request_rec *r, char *error, 
  +               int *conditional_status, int *printing) 
  + {
  +     char tag[MAX_STRING_LEN];
  +     char *tag_val;
  + 
  +     if(!(tag_val = get_tag(r->pool, in, tag, MAX_STRING_LEN, 1))) {
  +         return 1;
  +     } else if(!strcmp(tag,"done")) {
  + #ifdef DEBUG_INCLUDE
  + rvputs(r,"**** endif conditional_status=\"", *conditional_status ? "1" : "0", "\"\n", NULL);
  + #endif
  +         *conditional_status = 1;
  +         return 0;
  +     } else {
  +         log_printf(r->server, "endif directive does not take tags");
  +         rputs(error, r);
  +         return -1;
  +     }
  + }    
  + 
  + int handle_set(FILE *in, request_rec *r, char *error) 
  + {
  +     char tag[MAX_STRING_LEN];
  +     char parsed_string[MAX_STRING_LEN];
  +     char *tag_val;
  +     char *var;
  + 
  +     var = (char *)NULL;
  +     while (1) {
            if(!(tag_val = get_tag(r->pool, in, tag, MAX_STRING_LEN, 1)))
                return 1;
            else if(!strcmp(tag,"done"))
                return 0;
  !         else if (!strcmp(tag,"var")) {
  !             var = tag_val;
  !         } else if (!strcmp(tag,"value")) {
  !             if (var == (char *)NULL) {
  !                 log_printf(r->server,
  !                     "variable must precede value in set directive");
  !                 rputs(error, r);
  !                 return -1;
  !             } 
  !             parse_string(r, tag_val, parsed_string, MAX_STRING_LEN);
  !             table_set (r->subprocess_env, var, parsed_string);
  !         }
  !     }
  ! }    
  ! 
  ! int handle_printenv(FILE *in, request_rec *r, char *error) 
  ! {
  !     char tag[MAX_STRING_LEN];
  !     char *tag_val;
  !     table_entry *elts = (table_entry *) r->subprocess_env->elts;
  !     int i;
  ! 
  !     if(!(tag_val = get_tag(r->pool, in, tag, MAX_STRING_LEN, 1)))
  !         return 1;
  !     else if(!strcmp(tag,"done")) {
  !             for (i = 0; i < r->subprocess_env->nelts; ++i)
  !                 rvputs(r, elts[i].key, "=", elts[i].val, "\n", NULL);
  !             return 0;
  !     } else {
  !         log_printf(r->server, "printenv directive does not take tags");
  !         rputs(error, r);
  !         return -1;
        }
    }    
    
  ***************
  *** 715,743 ****
        char timefmt[MAX_STRING_LEN];
        int noexec = allow_options (r) & OPT_INCNOEXEC;
        int ret, sizefmt;
    
        strcpy(error,DEFAULT_ERROR_MSG);
        strcpy(timefmt,DEFAULT_TIME_FORMAT);
        sizefmt = SIZEFMT_KMG;
    
        chdir_file (r->filename);
    
        while(1) {
  !         if(!find_string(f,STARTING_SEQUENCE,r)) {
                if(get_directive(f,directive,r->pool))
                    return;
                if(!strcmp(directive,"exec")) {
                    if(noexec) {
  !                     log_printf(r->server,
  ! 			       "httpd: exec used but not allowed in %s",
  ! 			       r->filename);
  !                     rputs(error, r);
  !                     ret = find_string(f,ENDING_SEQUENCE,NULL);
                    } else 
                        ret=handle_exec(f, r, error);
  !             } 
  !             else if(!strcmp(directive,"config"))
                    ret=handle_config(f, r, error, timefmt, &sizefmt);
                else if(!strcmp(directive,"include"))
                    ret=handle_include(f, r, error, noexec);
                else if(!strcmp(directive,"echo"))
  --- 1533,1600 ----
        char timefmt[MAX_STRING_LEN];
        int noexec = allow_options (r) & OPT_INCNOEXEC;
        int ret, sizefmt;
  +     int if_nesting;
  +     int printing;
  +     int conditional_status;
    
        strcpy(error,DEFAULT_ERROR_MSG);
        strcpy(timefmt,DEFAULT_TIME_FORMAT);
        sizefmt = SIZEFMT_KMG;
    
  + /*  Turn printing on */
  +     printing = conditional_status = 1;
  +     if_nesting = 0;
  + 
        chdir_file (r->filename);
  +     if (r->args) { /* add QUERY stuff to env cause it ain't yet */
  +         table_set (r->subprocess_env, "QUERY_STRING", r->args);
  +         unescape_url (r->args);
  +         table_set (r->subprocess_env, "QUERY_STRING_UNESCAPED",
  +                 escape_shell_cmd (r->pool, r->args));
  +     }
    
        while(1) {
  !         if(!find_string(f,STARTING_SEQUENCE,r,printing)) {
                if(get_directive(f,directive,r->pool))
                    return;
  +             if(!strcmp(directive,"if")) {
  +                 if (!printing) {
  +                     if_nesting++;
  +                 } else {
  +                     ret=handle_if(f, r, error, &conditional_status, &printing);
  +                     if_nesting = 0;
  +                 }
  +                 continue;
  +             } else if(!strcmp(directive,"else")) {
  +                 if (!if_nesting)
  +                     ret=handle_else(f, r, error, &conditional_status, &printing);
  +                 continue;
  +             } else if(!strcmp(directive,"elif")) {
  +                 if (!if_nesting)
  +                     ret = handle_elif(f, r, error, &conditional_status, &printing);
  +                 continue;
  +             } else if(!strcmp(directive,"endif")) {
  +                 if (!if_nesting) {
  +                     ret=handle_else(f, r, error, &conditional_status, &printing);
  +                     printing = 1;
  +                 } else {
  +                     if_nesting--;
  +                 }
  +                 continue;
  +             } 
  +             if (!printing) continue;
                if(!strcmp(directive,"exec")) {
                    if(noexec) {
  !                     log_printf(r->server,"httpd: exec used but not allowed in %s",
  !                             r->filename);
  !                     if (printing) rputs(error, r);
  !                     ret = find_string(f,ENDING_SEQUENCE,NULL,printing);
                    } else 
                        ret=handle_exec(f, r, error);
  !             } else if(!strcmp(directive,"config"))
                    ret=handle_config(f, r, error, timefmt, &sizefmt);
  +             else if(!strcmp(directive,"set"))
  +                 ret=handle_set(f, r, error);
                else if(!strcmp(directive,"include"))
                    ret=handle_include(f, r, error, noexec);
                else if(!strcmp(directive,"echo"))
  ***************
  *** 746,761 ****
                    ret=handle_fsize(f, r, error, sizefmt);
                else if(!strcmp(directive,"flastmod"))
                    ret=handle_flastmod(f, r, error, timefmt);
                else {
  !                 log_printf(r->server, 
  ! 			   "httpd: unknown directive %s in parsed doc %s",
  ! 			   directive, r->filename);
  !                 rputs(error, r);
  !                 ret=find_string(f,ENDING_SEQUENCE,NULL);
                }
                if(ret) {
  !                 log_printf(r->server, "httpd: premature EOF in parsed file %s",
  ! 			   r->filename);
                    return;
                }
            } else 
  --- 1603,1620 ----
                    ret=handle_fsize(f, r, error, sizefmt);
                else if(!strcmp(directive,"flastmod"))
                    ret=handle_flastmod(f, r, error, timefmt);
  +             else if(!strcmp(directive,"printenv"))
  +                 ret=handle_printenv(f, r, error);
                else {
  !                 log_printf(r->server,
  !                         "httpd: unknown directive %s in parsed doc %s",
  !                         directive,r->filename);
  !                 if (printing) rputs(error, r);
  !                 ret=find_string(f,ENDING_SEQUENCE,NULL,printing);
                }
                if(ret) {
  !                 log_printf(r->server,"httpd: premature EOF in parsed file %s",
  ! 			r->filename);
                    return;
                }
            } else 
  ***************
  *** 865,871 ****
        /* OS/2 dosen't currently support the xbithack. This is being worked on. */
        return DECLINED;
    #else
  - 
        if (!(r->finfo.st_mode & S_IXUSR)) return DECLINED;
    
        state = (enum xbithack *)get_module_config(r->per_dir_config,
  --- 1724,1729 ----
  ***************
  *** 873,879 ****
        
        if (*state == xbithack_off) return DECLINED;
        return send_parsed_file (r);
  ! #endif    
    }
    
    command_rec includes_cmds[] = {
  --- 1731,1737 ----
        
        if (*state == xbithack_off) return DECLINED;
        return send_parsed_file (r);
  ! #endif
    }
    
    command_rec includes_cmds[] = {
  
  
  

Mime
View raw message