coar 97/07/16 16:08:20
Modified: src mod_include.c Log: Added string relational operators (<, >, <=, >=). Also a significant amount of cleanup to bring this closer to the style guide. PR: 41 Submitted by: Bruno Wolff III <[EMAIL PROTECTED]> Reviewd by: Dean Gaudet, Ken Coar, Paul Sutton, Brian Behlendorf Revision Changes Path 1.41 +582 -441 apache/src/mod_include.c Index: mod_include.c =================================================================== RCS file: /export/home/cvs/apache/src/mod_include.c,v retrieving revision 1.40 retrieving revision 1.41 diff -C3 -r1.40 -r1.41 *** mod_include.c 1997/07/14 02:38:04 1.40 --- mod_include.c 1997/07/16 23:08:18 1.41 *************** *** 113,142 **** table_set(e, "DATE_LOCAL", ht_time(r->pool, date, timefmt, 0)); table_set(e, "DATE_GMT", ht_time(r->pool, date, timefmt, 1)); ! table_set(e, "LAST_MODIFIED",ht_time(r->pool,r->finfo.st_mtime,timefmt,0)); table_set(e, "DOCUMENT_URI", r->uri); table_set(e, "DOCUMENT_PATH_INFO", r->path_info); #ifndef WIN32 pw = getpwuid(r->finfo.st_uid); if (pw) { ! table_set(e, "USER_NAME", pw->pw_name); } else { ! char uid[16]; ! ap_snprintf(uid, sizeof(uid), "user#%lu", (unsigned long)r->finfo.st_uid); ! table_set(e, "USER_NAME", uid); } #endif /* ndef WIN32 */ ! if((t = strrchr(r->filename, '/'))) table_set (e, "DOCUMENT_NAME", ++t); else table_set (e, "DOCUMENT_NAME", r->uri); if (r->args) { ! char *arg_copy = pstrdup (r->pool, r->args); unescape_url (arg_copy); ! table_set (e, "QUERY_STRING_UNESCAPED", ! escape_shell_cmd (r->pool, arg_copy)); } } --- 113,142 ---- table_set(e, "DATE_LOCAL", ht_time(r->pool, date, timefmt, 0)); table_set(e, "DATE_GMT", ht_time(r->pool, date, timefmt, 1)); ! table_set(e, "LAST_MODIFIED", ht_time(r->pool, r->finfo.st_mtime, timefmt, 0)); table_set(e, "DOCUMENT_URI", r->uri); table_set(e, "DOCUMENT_PATH_INFO", r->path_info); #ifndef WIN32 pw = getpwuid(r->finfo.st_uid); if (pw) { ! table_set(e, "USER_NAME", pw->pw_name); } else { ! char uid[16]; ! ap_snprintf(uid, sizeof(uid), "user#%lu", (unsigned long)r->finfo.st_uid); ! table_set(e, "USER_NAME", uid); } #endif /* ndef WIN32 */ ! if ((t = strrchr(r->filename, '/'))) table_set (e, "DOCUMENT_NAME", ++t); else table_set (e, "DOCUMENT_NAME", r->uri); if (r->args) { ! char *arg_copy = pstrdup (r->pool, r->args); unescape_url (arg_copy); ! table_set (e, "QUERY_STRING_UNESCAPED", ! escape_shell_cmd (r->pool, arg_copy)); } } *************** *** 152,159 **** */ #define PUT_CHAR(c,r) \ { \ ! outbuf[outind++] = c; \ ! if (outind == OUTBUFSIZE) { FLUSH_BUF(r) }; \ } /* there SHOULD be some error checking on the return value of --- 152,161 ---- */ #define PUT_CHAR(c,r) \ { \ ! outbuf[outind++] = c; \ ! if (outind == OUTBUFSIZE) { \ ! FLUSH_BUF(r) \ ! }; \ } /* there SHOULD be some error checking on the return value of *************** *** 180,218 **** #define GET_CHAR(f,c,ret,r) \ { \ int i = getc(f); \ ! if(i == EOF) { /* either EOF or error -- needs error handling if latter */ \ if (ferror(f)) \ ! fprintf(stderr, "encountered error in GET_CHAR macro, mod_include.\n"); \ FLUSH_BUF(r); \ ! pfclose(r->pool,f); \ return ret; \ } \ c = (char)i; \ } ! int find_string(FILE *in,char *str, request_rec *r, int printing) { ! int x,l=strlen(str),p; char outbuf[OUTBUFSIZE]; int outind = 0; char c; ! p=0; ! while(1) { ! GET_CHAR(in,c,1,r); ! if(c == str[p]) { ! if((++p) == l) { ! FLUSH_BUF(r); return 0; ! } } else { if (printing) { ! for(x=0;x<p;x++) { ! PUT_CHAR(str[x],r); } ! PUT_CHAR(c,r); } ! p=0; } } } --- 182,220 ---- #define GET_CHAR(f,c,ret,r) \ { \ int i = getc(f); \ ! if (i == EOF) { /* either EOF or error -- needs error handling if latter */ \ if (ferror(f)) \ ! fprintf(stderr, "encountered error in GET_CHAR macro, mod_include.\n"); \ FLUSH_BUF(r); \ ! pfclose(r->pool, f); \ return ret; \ } \ c = (char)i; \ } ! int find_string(FILE *in, char *str, request_rec *r, int printing) { ! int x, l = strlen(str), p; char outbuf[OUTBUFSIZE]; int outind = 0; char c; ! p = 0; ! while (1) { ! GET_CHAR(in, c, 1, r); ! if (c == str[p]) { ! if ((++p) == l) { ! FLUSH_BUF(r); return 0; ! } } else { if (printing) { ! for (x = 0; x < p; x++) { ! PUT_CHAR(str[x], r); } ! PUT_CHAR(c, r); } ! p = 0; } } } *************** *** 223,232 **** #define GET_CHAR(f,c,r,p) \ { \ int i = getc(f); \ ! if(i == EOF) { /* either EOF or error -- needs error handling if latter */ \ if (ferror(f)) \ ! fprintf(stderr, "encountered error in GET_CHAR macro, mod_include.\n"); \ ! pfclose(p,f); \ return r; \ } \ c = (char)i; \ --- 225,234 ---- #define GET_CHAR(f,c,r,p) \ { \ int i = getc(f); \ ! if (i == EOF) { /* either EOF or error -- needs error handling if latter */ \ if (ferror(f)) \ ! fprintf(stderr, "encountered error in GET_CHAR macro, mod_include.\n"); \ ! pfclose(p, f); \ return r; \ } \ c = (char)i; \ *************** *** 252,270 **** decodehtml(char *s) { int val, i, j; ! char *p=s; char *ents; ! static char *entlist[MAXENTLEN+1]={ ! NULL, /* 0 */ ! NULL, /* 1 */ ! "lt\074gt\076", /* 2 */ ! "amp\046ETH\320eth\360", /* 3 */ ! "quot\042Auml\304Euml\313Iuml\317Ouml\326Uuml\334auml\344euml\353\ iuml\357ouml\366uuml\374yuml\377", /* 4 */ ! "Acirc\302Aring\305AElig\306Ecirc\312Icirc\316Ocirc\324Ucirc\333\ THORN\336szlig\337acirc\342aring\345aelig\346ecirc\352icirc\356ocirc\364\ ucirc\373thorn\376", /* 5 */ ! "Agrave\300Aacute\301Atilde\303Ccedil\307Egrave\310Eacute\311\ Igrave\314Iacute\315Ntilde\321Ograve\322Oacute\323Otilde\325Oslash\330\ Ugrave\331Uacute\332Yacute\335agrave\340aacute\341atilde\343ccedil\347\ egrave\350eacute\351igrave\354iacute\355ntilde\361ograve\362oacute\363\ --- 254,272 ---- decodehtml(char *s) { int val, i, j; ! char *p = s; char *ents; ! static char *entlist[MAXENTLEN+1] = { ! NULL, /* 0 */ ! NULL, /* 1 */ ! "lt\074gt\076", /* 2 */ ! "amp\046ETH\320eth\360", /* 3 */ ! "quot\042Auml\304Euml\313Iuml\317Ouml\326Uuml\334auml\344euml\353\ iuml\357ouml\366uuml\374yuml\377", /* 4 */ ! "Acirc\302Aring\305AElig\306Ecirc\312Icirc\316Ocirc\324Ucirc\333\ THORN\336szlig\337acirc\342aring\345aelig\346ecirc\352icirc\356ocirc\364\ ucirc\373thorn\376", /* 5 */ ! "Agrave\300Aacute\301Atilde\303Ccedil\307Egrave\310Eacute\311\ Igrave\314Iacute\315Ntilde\321Ograve\322Oacute\323Otilde\325Oslash\330\ Ugrave\331Uacute\332Yacute\335agrave\340aacute\341atilde\343ccedil\347\ egrave\350eacute\351igrave\354iacute\355ntilde\361ograve\362oacute\363\ *************** *** 272,316 **** }; for (; *s != '\0'; s++, p++) { ! if (*s != '&') { ! *p = *s; ! continue; ! } ! /* find end of entity */ ! for (i=1; s[i] != ';' && s[i] != '\0'; i++) ! continue; ! ! if (s[i] == '\0') { /* treat as normal data */ ! *p = *s; ! continue; ! } ! ! /* is it numeric ? */ ! if (s[1] == '#') { ! for (j=2, val=0; j < i && isdigit(s[j]); j++) ! val = val * 10 + s[j] - '0'; ! s += i; ! if (j < i || val <= 8 || (val >= 11 && val <= 31) || ! (val >= 127 && val <= 160) || val >= 256) ! p--; /* no data to output */ ! else ! *p = val; ! } else{ ! j = i-1; ! if (i-1 > MAXENTLEN || entlist[i-1] == NULL) { /* wrong length */ ! *p = '&'; ! continue; /* skip it */ ! } ! for (ents=entlist[i-1]; *ents != '\0'; ents += i) ! if (strncmp(s+1, ents, i-1) == 0) break; ! ! if (*ents == '\0') ! *p = '&'; /* unknown */ ! else { ! *p = ((const unsigned char *)ents)[i-1]; ! s += i; ! } ! } } *p = '\0'; --- 274,318 ---- }; for (; *s != '\0'; s++, p++) { ! if (*s != '&') { ! *p = *s; ! continue; ! } ! /* find end of entity */ ! for (i = 1; s[i] != ';' && s[i] != '\0'; i++) ! continue; ! ! if (s[i] == '\0') { /* treat as normal data */ ! *p = *s; ! continue; ! } ! ! /* is it numeric ? */ ! if (s[1] == '#') { ! for (j = 2, val = 0; j < i && isdigit(s[j]); j++) ! val = val * 10 + s[j] - '0'; ! s += i; ! if (j < i || val <= 8 || (val >= 11 && val <= 31) || ! (val >= 127 && val <= 160) || val >= 256) ! p--; /* no data to output */ ! else ! *p = val; ! } else{ ! j = i - 1; ! if (i - 1 > MAXENTLEN || entlist[i - 1] == NULL) { /* wrong length */ ! *p = '&'; ! continue; /* skip it */ ! } ! for (ents = entlist[i - 1]; *ents != '\0'; ents += i) ! if (strncmp(s + 1, ents, i - 1) == 0) break; ! ! if (*ents == '\0') ! *p = '&'; /* unknown */ ! else { ! *p = ((const unsigned char *)ents)[i - 1]; ! s += i; ! } ! } } *p = '\0'; *************** *** 330,399 **** n = 0; do { /* skip whitespace */ ! GET_CHAR(in,c,NULL,p); } while (isspace(c)); /* tags can't start with - */ ! if(c == '-') { ! GET_CHAR(in,c,NULL,p); ! if(c == '-') { do { ! GET_CHAR(in,c,NULL,p); ! } while (isspace(c)); ! if(c == '>') { ! strncpy(tag,"done", tagbuf_len-1); ! tag[tagbuf_len-1] = '\0'; return tag; } } ! return NULL; /* failed */ } /* find end of tag name */ ! while(1) { ! if(++n == tagbuf_len) { t[tagbuf_len - 1] = '\0'; return NULL; } ! if(c == '=' || isspace(c)) break; ! *(t++) = tolower(c); ! GET_CHAR(in,c,NULL,p); } *t++ = '\0'; 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 = */ } while (isspace(c)); /* we should allow a 'name' as a value */ ! if (c != '"' && c != '\'') return NULL; term = c; ! while(1) { ! GET_CHAR(in,c,NULL,p); ! if(++n == tagbuf_len) { ! t[tagbuf_len - 1] = '\0'; ! return NULL; ! } /* Want to accept \" as a valid character within a string. */ ! if (c == '\\') { ! *(t++) = c; /* Add backslash */ ! GET_CHAR(in,c,NULL,p); ! if (c == term) /* Only if */ ! *(--t) = c; /* Replace backslash ONLY for terminator */ ! } else if (c == term) break; ! *(t++) = c; } *t = '\0'; ! if (dodecode) decodehtml(tag_val); return pstrdup (p, tag_val); } --- 332,405 ---- n = 0; do { /* skip whitespace */ ! GET_CHAR(in, c, NULL, p); } while (isspace(c)); /* tags can't start with - */ ! if (c == '-') { ! GET_CHAR(in, c, NULL, p); ! if (c == '-') { do { ! GET_CHAR(in, c, NULL, p); ! } while (isspace(c)); ! if (c == '>') { ! strncpy(tag, "done", tagbuf_len - 1); ! tag[tagbuf_len - 1] = '\0'; return tag; } } ! return NULL; /* failed */ } /* find end of tag name */ ! while (1) { ! if (++n == tagbuf_len) { t[tagbuf_len - 1] = '\0'; return NULL; } ! if (c == '=' || isspace(c)) ! break; ! *(t++) = tolower(c); ! GET_CHAR(in, c, NULL, p); } *t++ = '\0'; 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 = */ } while (isspace(c)); /* we should allow a 'name' as a value */ ! if (c != '"' && c != '\'') ! return NULL; term = c; ! while (1) { ! GET_CHAR(in, c, NULL, p); ! if (++n == tagbuf_len) { ! t[tagbuf_len - 1] = '\0'; ! return NULL; ! } /* Want to accept \" as a valid character within a string. */ ! if (c == '\\') { ! *(t++) = c; /* Add backslash */ ! GET_CHAR(in, c, NULL, p); ! if (c == term) /* Only if */ ! *(--t) = c; /* Replace backslash ONLY for terminator */ ! } else if (c == term) ! break; ! *(t++) = c; } *t = '\0'; ! if (dodecode) ! decodehtml(tag_val); return pstrdup (p, tag_val); } *************** *** 402,417 **** char c; /* skip initial whitespace */ ! while(1) { ! GET_CHAR(in,c,1,p); ! if(!isspace(c)) break; } /* now get directive */ ! while(1) { *d++ = tolower(c); ! GET_CHAR(in,c,1,p); ! if(isspace(c)) break; } *d = '\0'; --- 408,423 ---- char c; /* skip initial whitespace */ ! while (1) { ! GET_CHAR(in, c, 1, p); ! if (!isspace(c)) break; } /* now get directive */ ! while (1) { *d++ = tolower(c); ! GET_CHAR(in, c, 1, p); ! if (isspace(c)) break; } *d = '\0'; *************** *** 431,447 **** while ((ch = *in++) != '\0') { switch(ch) { case '\\': ! if(*in == '$') ! *next++=*in++; ! else ! *next++=ch; 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 --- 437,453 ---- while ((ch = *in++) != '\0') { switch(ch) { case '\\': ! if (*in == '$') ! *next++ = *in++; ! else ! *next++ = ch; 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 *************** *** 449,468 **** */ 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; } ! else 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 --- 455,481 ---- */ 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; } ! else 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 *************** *** 479,485 **** } while ((val != (char *)NULL) && (*val != '\0')) { *next++ = *val++; ! if (++numchars == (length -1)) break; } break; } --- 492,499 ---- } while ((val != (char *)NULL) && (*val != '\0')) { *next++ = *val++; ! if (++numchars == (length - 1)) ! break; } break; } *************** *** 487,493 **** *next++ = ch; break; } ! if (++numchars == (length -1)) break; } *next = '\0'; return; --- 501,508 ---- *next++ = ch; break; } ! if (++numchars == (length - 1)) ! break; } *next = '\0'; return; *************** *** 499,510 **** { request_rec *rr = sub_req_lookup_uri (s, r); ! if (rr->status != 200) return -1; /* No hardwired path info or query allowed */ ! if ((rr->path_info && rr->path_info[0]) || rr->args) return -1; ! if (rr->finfo.st_mode == 0) return -1; /* Script gets parameters of the *document*, for back compatibility */ --- 514,528 ---- { request_rec *rr = sub_req_lookup_uri (s, r); ! if (rr->status != 200) ! return -1; /* No hardwired path info or query allowed */ ! if ((rr->path_info && rr->path_info[0]) || rr->args) ! return -1; ! if (rr->finfo.st_mode == 0) ! return -1; /* Script gets parameters of the *document*, for back compatibility */ *************** *** 522,528 **** 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); } destroy_sub_req (rr); --- 540,546 ---- 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); } destroy_sub_req (rr); *************** *** 536,589 **** char parsed_string[MAX_STRING_LEN]; char *tag_val; ! while(1) { ! if(!(tag_val = get_tag(r->pool, in, tag, MAX_STRING_LEN, 1))) return 1; ! if(!strcmp(tag,"file") || !strcmp (tag, "virtual")) { ! request_rec *rr=NULL; ! char *error_fmt = NULL; parse_string(r, tag_val, parsed_string, MAX_STRING_LEN, 0); ! if (tag[0] == 'f') ! { /* be safe; only files in this directory or below allowed */ ! char tmp[MAX_STRING_LEN+2]; ! ap_snprintf(tmp, sizeof(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"; ! ! if (!error_fmt && noexec && rr->content_type ! && (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"; ! chdir_file(r->filename); ! if (error_fmt) { log_printf(r->server, error_fmt, tag_val, r->filename); rputs(error, r); } ! if (rr != NULL) destroy_sub_req (rr); } ! else if(!strcmp(tag,"done")) return 0; else { log_printf(r->server, "unknown parameter \"%s\" to tag include in %s", --- 554,608 ---- char parsed_string[MAX_STRING_LEN]; char *tag_val; ! while (1) { ! if (!(tag_val = get_tag(r->pool, in, tag, MAX_STRING_LEN, 1))) return 1; ! if (!strcmp(tag, "file") || !strcmp (tag, "virtual")) { ! request_rec *rr = NULL; ! char *error_fmt = NULL; parse_string(r, tag_val, parsed_string, MAX_STRING_LEN, 0); ! if (tag[0] == 'f') { ! /* be safe; only files in this directory or below allowed */ ! char tmp[MAX_STRING_LEN+2]; ! ap_snprintf(tmp, sizeof(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"; ! ! if (!error_fmt && noexec && rr->content_type ! && (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"; ! chdir_file(r->filename); ! if (error_fmt) { log_printf(r->server, error_fmt, tag_val, r->filename); rputs(error, r); } ! if (rr != NULL) ! destroy_sub_req (rr); } ! else if (!strcmp(tag, "done")) return 0; else { log_printf(r->server, "unknown parameter \"%s\" to tag include in %s", *************** *** 620,645 **** #endif #endif ! if (r->path_info && r->path_info[0] != '\0') ! { ! request_rec *pa_req; ! ! table_set (env, "PATH_INFO", escape_shell_cmd (r->pool, r->path_info)); ! ! pa_req = sub_req_lookup_uri(escape_uri(r->pool, r->path_info), r); ! if (pa_req->filename) ! table_set(env, "PATH_TRANSLATED", ! pstrcat(r->pool, pa_req->filename, pa_req->path_info, ! NULL)); } if (r->args) { ! char *arg_copy = pstrdup (r->pool, r->args); table_set (env, "QUERY_STRING", r->args); ! unescape_url (arg_copy); ! table_set (env, "QUERY_STRING_UNESCAPED", ! escape_shell_cmd (r->pool, arg_copy)); } error_log2stderr (r->server); --- 639,663 ---- #endif #endif ! if (r->path_info && r->path_info[0] != '\0') { ! request_rec *pa_req; ! ! table_set (env, "PATH_INFO", escape_shell_cmd (r->pool, r->path_info)); ! ! pa_req = sub_req_lookup_uri(escape_uri(r->pool, r->path_info), r); ! if (pa_req->filename) ! table_set(env, "PATH_TRANSLATED", ! pstrcat(r->pool, pa_req->filename, pa_req->path_info, ! NULL)); } if (r->args) { ! char *arg_copy = pstrdup (r->pool, r->args); table_set (env, "QUERY_STRING", r->args); ! unescape_url (arg_copy); ! table_set (env, "QUERY_STRING_UNESCAPED", ! escape_shell_cmd (r->pool, arg_copy)); } error_log2stderr (r->server); *************** *** 661,668 **** fprintf (dbg, "Exec failed\n"); #endif ap_snprintf(err_string, sizeof(err_string), ! "httpd: exec of %s failed, reason: %s (errno = %d)\n", ! SHELL_PATH, strerror(errno), errno); write (STDERR_FILENO, err_string, strlen(err_string)); exit(0); /* NOT REACHED */ --- 679,686 ---- fprintf (dbg, "Exec failed\n"); #endif ap_snprintf(err_string, sizeof(err_string), ! "httpd: exec of %s failed, reason: %s (errno = %d)\n", ! SHELL_PATH, strerror(errno), errno); write (STDERR_FILENO, err_string, strlen(err_string)); exit(0); /* NOT REACHED */ *************** *** 677,689 **** arg.r = r; arg.s = s; if (!spawn_child (r->pool, include_cmd_child, &arg, ! kill_after_timeout, NULL, &f)) return -1; ! send_fd(f,r); ! pfclose(r->pool, f); /* will wait for zombie when ! * r->pool is cleared ! */ return 0; } --- 695,707 ---- arg.r = r; arg.s = s; if (!spawn_child (r->pool, include_cmd_child, &arg, ! kill_after_timeout, NULL, &f)) return -1; ! send_fd(f, r); ! pfclose(r->pool, f); /* will wait for zombie when ! * r->pool is cleared ! */ return 0; } *************** *** 695,706 **** 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, 1); ! if(include_cmd(parsed_string, r) == -1) { log_printf(r->server, "execution failure for parameter \"%s\" to tag exec in file %s", tag, r->filename); rputs(error, r); --- 713,724 ---- 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, 1); ! if (include_cmd(parsed_string, r) == -1) { log_printf(r->server, "execution failure for parameter \"%s\" to tag exec in file %s", tag, r->filename); rputs(error, r); *************** *** 708,723 **** /* 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, 0); ! if(include_cgi(parsed_string, r) == -1) { ! log_printf(r->server, "invalid CGI ref \"%s\" in %s",tag_val,file); rputs(error, r); } /* grumble groan */ chdir_file(r->filename); } ! else if(!strcmp(tag,"done")) return 0; else { log_printf(r->server, "unknown parameter \"%s\" to tag exec in %s", --- 726,741 ---- /* 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, 0); ! if (include_cgi(parsed_string, r) == -1) { ! log_printf(r->server, "invalid CGI ref \"%s\" in %s", tag_val, file); rputs(error, r); } /* grumble groan */ chdir_file(r->filename); } ! else if (!strcmp(tag, "done")) return 0; else { log_printf(r->server, "unknown parameter \"%s\" to tag exec in %s", *************** *** 732,746 **** char tag[MAX_STRING_LEN]; char *tag_val; ! while(1) { ! if(!(tag_val = get_tag (r->pool, in, tag, MAX_STRING_LEN, 1))) return 1; ! if(!strcmp(tag,"var")) { ! char *val = table_get (r->subprocess_env, tag_val); ! if (val) rputs(val, r); ! else rputs("(none)", r); ! } else if(!strcmp(tag,"done")) return 0; else { log_printf(r->server, "unknown parameter \"%s\" to tag echo in %s", --- 750,765 ---- char tag[MAX_STRING_LEN]; char *tag_val; ! while (1) { ! if (!(tag_val = get_tag (r->pool, in, tag, MAX_STRING_LEN, 1))) return 1; ! if (!strcmp(tag, "var")) { ! char *val = table_get (r->subprocess_env, tag_val); ! if (val) ! rputs(val, r); ! else rputs("(none)", r); ! } else if (!strcmp(tag, "done")) return 0; else { log_printf(r->server, "unknown parameter \"%s\" to tag echo in %s", *************** *** 759,775 **** if (!(allow_options (r) & OPT_INCLUDES)) { log_printf(r->server, "httpd: #perl SSI disallowed by IncludesNoExec in %s", r->filename); ! return DECLINED; } ! while(1) { ! if(!(tag_val = get_tag (r->pool, in, tag, MAX_STRING_LEN, 1))) ! break; ! if(strnEQ(tag, "sub", 3)) ! sub = newSVpv(tag_val,0); ! else if(strnEQ(tag, "arg", 3)) ! av_push(av, newSVpv(tag_val,0)); ! else if(strnEQ(tag,"done", 4)) ! break; } perl_stdout2client(r); perl_call_handler(sub, r, av); --- 778,794 ---- if (!(allow_options (r) & OPT_INCLUDES)) { log_printf(r->server, "httpd: #perl SSI disallowed by IncludesNoExec in %s", r->filename); ! return DECLINED; } ! while (1) { ! if (!(tag_val = get_tag (r->pool, in, tag, MAX_STRING_LEN, 1))) ! break; ! if (strnEQ(tag, "sub", 3)) ! sub = newSVpv(tag_val, 0); ! else if (strnEQ(tag, "arg", 3)) ! av_push(av, newSVpv(tag_val, 0)); ! else if (strnEQ(tag, "done", 4)) ! break; } perl_stdout2client(r); perl_call_handler(sub, r, av); *************** *** 787,820 **** char parsed_string[MAX_STRING_LEN]; table *env = r->subprocess_env; ! while(1) { ! if(!(tag_val = get_tag(r->pool, in, tag, MAX_STRING_LEN, 0))) return 1; ! if(!strcmp(tag,"errmsg")) { parse_string(r, tag_val, parsed_string, MAX_STRING_LEN, 0); ! strncpy(error,parsed_string,MAX_STRING_LEN-1); ! error[MAX_STRING_LEN-1] = '\0'; ! } else if(!strcmp(tag,"timefmt")) { ! time_t date = r->request_time; parse_string(r, tag_val, parsed_string, MAX_STRING_LEN, 0); ! strncpy(tf,parsed_string,MAX_STRING_LEN-1); ! tf[MAX_STRING_LEN-1] = '\0'; ! 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, 0); ! 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); } --- 806,839 ---- char parsed_string[MAX_STRING_LEN]; table *env = r->subprocess_env; ! while (1) { ! if (!(tag_val = get_tag(r->pool, in, tag, MAX_STRING_LEN, 0))) return 1; ! if (!strcmp(tag, "errmsg")) { parse_string(r, tag_val, parsed_string, MAX_STRING_LEN, 0); ! strncpy(error, parsed_string, MAX_STRING_LEN - 1); ! error[MAX_STRING_LEN - 1] = '\0'; ! } else if (!strcmp(tag, "timefmt")) { ! time_t date = r->request_time; parse_string(r, tag_val, parsed_string, MAX_STRING_LEN, 0); ! strncpy(tf, parsed_string, MAX_STRING_LEN - 1); ! tf[MAX_STRING_LEN - 1] = '\0'; ! 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, 0); ! 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); } *************** *** 829,838 **** char *dir = "./"; char *to_send; ! if(!strcmp(tag,"file")) { getparents(tag_val); /* get rid of any nasties */ to_send = make_full_path (r->pool, dir, tag_val); ! if(stat(to_send,finfo) == -1) { log_printf(r->server, "unable to get information about \"%s\" in parsed file %s", to_send, r->filename); --- 848,857 ---- char *dir = "./"; char *to_send; ! if (!strcmp(tag, "file")) { getparents(tag_val); /* get rid of any nasties */ to_send = make_full_path (r->pool, dir, tag_val); ! if (stat(to_send, finfo) == -1) { log_printf(r->server, "unable to get information about \"%s\" in parsed file %s", to_send, r->filename); *************** *** 841,864 **** } return 0; } ! else if(!strcmp(tag,"virtual")) { ! request_rec *rr = sub_req_lookup_uri (tag_val, r); ! ! if (rr->status == 200 && rr->finfo.st_mode != 0) { ! memcpy ((char*)finfo, (const char *)&rr->finfo, sizeof (struct stat)); ! destroy_sub_req (rr); ! return 0; } else { log_printf(r->server, "unable to get information about \"%s\" in parsed file %s", tag_val, r->filename); rputs(error, r); ! destroy_sub_req (rr); return -1; } } else { ! log_printf(r->server,"unknown parameter \"%s\" to tag %s in %s", tag, directive, r->filename); rputs(error, r); return -1; --- 860,883 ---- } return 0; } ! else if (!strcmp(tag, "virtual")) { ! request_rec *rr = sub_req_lookup_uri (tag_val, r); ! ! if (rr->status == 200 && rr->finfo.st_mode != 0) { ! memcpy ((char*)finfo, (const char *)&rr->finfo, sizeof (struct stat)); ! destroy_sub_req (rr); ! return 0; } else { log_printf(r->server, "unable to get information about \"%s\" in parsed file %s", tag_val, r->filename); rputs(error, r); ! destroy_sub_req (rr); return -1; } } else { ! log_printf(r->server, "unknown parameter \"%s\" to tag %s in %s", tag, directive, r->filename); rputs(error, r); return -1; *************** *** 873,903 **** 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, 0); ! 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 ! /* ap_snprintf can't handle %qd */ ! sprintf(tag,"%qd", finfo.st_size); #else ! ap_snprintf(tag, sizeof(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); } } } --- 892,922 ---- 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, 0); ! 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 ! /* ap_snprintf can't handle %qd */ ! sprintf(tag, "%qd", finfo.st_size); #else ! ap_snprintf(tag, sizeof(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); } } } *************** *** 912,925 **** 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, 0); ! if(!find_file(r,"flastmod",tag,parsed_string,&finfo,error)) rputs(ht_time(r->pool, finfo.st_mtime, tf, 0), r); } } --- 931,944 ---- 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, 0); ! if (!find_file(r, "flastmod", tag, parsed_string, &finfo, error)) rputs(ht_time(r->pool, finfo.st_mtime, tf, 0), r); } } *************** *** 942,948 **** 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; --- 961,968 ---- enum token_type { token_string, token_and, token_or, token_not, token_eq, token_ne, ! token_rbrace, token_lbrace, token_group, ! token_ge, token_le, token_gt, token_lt }; struct token { enum token_type type; *************** *** 951,964 **** 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 '(': --- 971,987 ---- 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 '(': *************** *** 992,1003 **** 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 --- 1015,1043 ---- token->type = token_and; return(string+1); } + case '>': + if (*string == '=') { + token->type = token_ge; + return(string+1); + } else { + token->type = token_gt; + return(string); + } + case '<': + if (*string == '=') { + token->type = token_le; + return(string+1); + } else { + token->type = token_lt; + return(string); + } 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 *************** *** 1010,1038 **** */ 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); } --- 1050,1099 ---- */ 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; ! case '<': ! goto TOKEN_DONE; ! case '>': 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); } *************** *** 1057,1063 **** 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 processing file %s", r->filename); --- 1118,1125 ---- 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 processing file %s", r->filename); *************** *** 1069,1075 **** 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 processing file %s", r->filename); rputs(error, r); goto RETURN; } --- 1131,1137 ---- 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 processing file %s", r->filename); rputs(error, r); goto RETURN; } *************** *** 1081,1087 **** 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; --- 1143,1149 ---- 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; *************** *** 1091,1099 **** case token_string: if (current->token.value[0] != '\0') strncat(current->token.value, " ", ! MAX_STRING_LEN-strlen(current->token.value)-1); strncat(current->token.value, new->token.value, ! MAX_STRING_LEN-strlen(current->token.value)-1); break; case token_eq: case token_ne: --- 1153,1161 ---- case token_string: if (current->token.value[0] != '\0') strncat(current->token.value, " ", ! MAX_STRING_LEN - strlen(current->token.value) - 1); strncat(current->token.value, new->token.value, ! MAX_STRING_LEN - strlen(current->token.value) - 1); break; case token_eq: case token_ne: *************** *** 1101,1106 **** --- 1163,1172 ---- case token_or: case token_lbrace: case token_not: + case token_ge: + case token_gt: + case token_le: + case token_lt: new->parent = current; current = current->right = new; break; *************** *** 1133,1138 **** --- 1199,1208 ---- case token_ne: case token_and: case token_or: + case token_ge: + case token_gt: + case token_le: + case token_lt: current = current->parent; continue; case token_lbrace: *************** *** 1175,1180 **** --- 1245,1254 ---- case token_and: case token_or: case token_lbrace: + case token_ge: + case token_gt: + case token_le: + case token_lt: break; default: log_printf(r->server, *************** *** 1199,1206 **** 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, --- 1273,1284 ---- case token_eq: case token_ne: + case token_ge: + case token_gt: + case token_le: + case token_lt: #ifdef DEBUG_INCLUDE ! rputs(" Token: eq/ne/ge/gt/le/lt\n", r); #endif if (current == (struct parse_node*)NULL) { log_printf(r->server, *************** *** 1222,1227 **** --- 1300,1309 ---- case token_not: case token_eq: case token_ne: + case token_ge: + case token_gt: + case token_le: + case token_lt: default: log_printf(r->server, "Invalid expression \"%s\" in file %s", *************** *** 1256,1262 **** current = current->parent; } if (current == (struct parse_node*)NULL) { ! log_printf(r->server,"Unmatched ')' in %s", expr, r->filename); rputs(error, r); goto RETURN; } --- 1338,1344 ---- current = current->parent; } if (current == (struct parse_node*)NULL) { ! log_printf(r->server, "Unmatched ')' in %s", expr, r->filename); rputs(error, r); goto RETURN; } *************** *** 1279,1291 **** case token_and: case token_or: case token_lbrace: break; case token_string: case token_group: default: log_printf(r->server, "Invalid expression \"%s\" in file %s", ! expr, r->filename); rputs(error, r); goto RETURN; } --- 1361,1377 ---- case token_and: case token_or: case token_lbrace: + case token_ge: + case token_gt: + case token_le: + case token_lt: break; case token_string: case token_group: default: log_printf(r->server, "Invalid expression \"%s\" in file %s", ! expr, r->filename); rputs(error, r); goto RETURN; } *************** *** 1303,1310 **** } current = new; break; ! default: ! break; } } --- 1389,1396 ---- } current = new; break; ! default: ! break; } } *************** *** 1317,1324 **** rputs(" Evaluate string\n", r); #endif parse_string(r, current->token.value, buffer, MAX_STRING_LEN, 0); ! strncpy(current->token.value, buffer, MAX_STRING_LEN-1); ! current->token.value[MAX_STRING_LEN-1] = '\0'; current->value = (current->token.value[0] != '\0'); current->done = 1; current = current->parent; --- 1403,1410 ---- rputs(" Evaluate string\n", r); #endif parse_string(r, current->token.value, buffer, MAX_STRING_LEN, 0); ! strncpy(current->token.value, buffer, MAX_STRING_LEN - 1); ! current->token.value[MAX_STRING_LEN - 1] = '\0'; current->value = (current->token.value[0] != '\0'); current->done = 1; current = current->parent; *************** *** 1342,1349 **** parse_string(r, current->left->token.value, buffer, MAX_STRING_LEN, 0); strncpy(current->left->token.value, buffer, ! MAX_STRING_LEN-1); ! current->left->token.value[MAX_STRING_LEN-1] = '\0'; current->left->done = 1; break; default: --- 1428,1435 ---- parse_string(r, current->left->token.value, buffer, MAX_STRING_LEN, 0); strncpy(current->left->token.value, buffer, ! MAX_STRING_LEN - 1); ! current->left->token.value[MAX_STRING_LEN - 1] = '\0'; current->left->done = 1; break; default: *************** *** 1357,1364 **** parse_string(r, current->right->token.value, buffer, MAX_STRING_LEN, 0); strncpy(current->right->token.value, buffer, ! MAX_STRING_LEN-1); ! current->right->token.value[MAX_STRING_LEN-1] = '\0'; current->right->done = 1; break; default: --- 1443,1450 ---- parse_string(r, current->right->token.value, buffer, MAX_STRING_LEN, 0); strncpy(current->right->token.value, buffer, ! MAX_STRING_LEN - 1); ! current->right->token.value[MAX_STRING_LEN - 1] = '\0'; current->right->done = 1; break; default: *************** *** 1367,1374 **** } } #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 = --- 1453,1460 ---- } } #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 = *************** *** 1377,1383 **** 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; --- 1463,1469 ---- 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; *************** *** 1399,1423 **** } parse_string(r, current->left->token.value, buffer, MAX_STRING_LEN, 0); ! strncpy(current->left->token.value, buffer, MAX_STRING_LEN-1); ! current->left->token.value[MAX_STRING_LEN-1] = '\0'; parse_string(r, current->right->token.value, buffer, MAX_STRING_LEN, 0); ! strncpy(current->right->token.value, buffer, MAX_STRING_LEN-1); ! current->right->token.value[MAX_STRING_LEN-1] = '\0'; 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\" in file %s", current->right->token.value, r->filename); rputs(error, r); goto RETURN; } #ifdef DEBUG_INCLUDE ! rvputs(r," Re Compare (", current->left->token.value, ") with /", ¤t->right->token.value[1], "/\n", NULL); #endif current->value = --- 1485,1509 ---- } parse_string(r, current->left->token.value, buffer, MAX_STRING_LEN, 0); ! strncpy(current->left->token.value, buffer, MAX_STRING_LEN - 1); ! current->left->token.value[MAX_STRING_LEN - 1] = '\0'; parse_string(r, current->right->token.value, buffer, MAX_STRING_LEN, 0); ! strncpy(current->right->token.value, buffer, MAX_STRING_LEN - 1); ! current->right->token.value[MAX_STRING_LEN - 1] = '\0'; 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\" in file %s", current->right->token.value, r->filename); rputs(error, r); goto RETURN; } #ifdef DEBUG_INCLUDE ! rvputs(r, " Re Compare (", current->left->token.value, ") with /", ¤t->right->token.value[1], "/\n", NULL); #endif current->value = *************** *** 1425,1431 **** ¤t->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 = --- 1511,1517 ---- ¤t->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 = *************** *** 1435,1441 **** 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; --- 1521,1571 ---- 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_ge: ! case token_gt: ! case token_le: ! case token_lt: ! #ifdef DEBUG_INCLUDE ! rputs(" Evaluate ge/gt/le/lt\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, 0); ! strncpy(current->left->token.value, buffer, MAX_STRING_LEN - 1); ! parse_string(r, current->right->token.value, ! buffer, MAX_STRING_LEN, 0); ! strncpy(current->right->token.value, buffer, MAX_STRING_LEN - 1); ! #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); ! if (current->token.type == token_ge) ! current->value = current->value >= 0; ! else if (current->token.type == token_gt) ! current->value = current->value > 0; ! else if (current->token.type == token_le) ! current->value = current->value <= 0; ! else if (current->token.type == token_lt) ! current->value = current->value < 0; ! else current->value = 0; /* Don't return -1 if unknown token */ ! #ifdef DEBUG_INCLUDE ! rvputs(r, " Returning ", current->value ? "1" : "0", "\n", NULL); #endif current->done = 1; current = current->parent; *************** *** 1452,1458 **** current->value = 0; } #ifdef DEBUG_INCLUDE ! rvputs(r," Evaluate !: ", current->value ? "1" : "0", "\n", NULL); #endif current->done = 1; current = current->parent; --- 1582,1588 ---- current->value = 0; } #ifdef DEBUG_INCLUDE ! rvputs(r, " Evaluate !: ", current->value ? "1" : "0", "\n", NULL); #endif current->done = 1; current = current->parent; *************** *** 1469,1494 **** 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 in file %s", ! expr, r->filename); rputs(error, r); goto RETURN; case token_rbrace: ! log_printf(r->server,"Unmatched ')' in %s in file %s\n", ! expr, r->filename); rputs(error, r); goto RETURN; default: ! log_printf(r->server,"bad token type"); rputs(error, r); goto RETURN; } --- 1599,1624 ---- 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 in file %s", ! expr, r->filename); rputs(error, r); goto RETURN; case token_rbrace: ! log_printf(r->server, "Unmatched ')' in %s in file %s\n", ! expr, r->filename); rputs(error, r); goto RETURN; default: ! log_printf(r->server, "bad token type"); rputs(error, r); goto RETURN; } *************** *** 1507,1529 **** 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); } --- 1637,1659 ---- 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); } *************** *** 1537,1549 **** 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; --- 1667,1679 ---- 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; *************** *** 1551,1566 **** } *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); } --- 1681,1696 ---- } *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); } *************** *** 1573,1590 **** 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; } } --- 1703,1721 ---- 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; } } *************** *** 1595,1605 **** 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; --- 1726,1736 ---- 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; *************** *** 1619,1631 **** 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"); --- 1750,1762 ---- 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"); *************** *** 1645,1653 **** 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; --- 1776,1784 ---- 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; *************** *** 1674,1683 **** int printing; int conditional_status; ! strncpy(error,DEFAULT_ERROR_MSG, sizeof(error)-1); ! error[sizeof(error)-1] = '\0'; ! strncpy(timefmt,DEFAULT_TIME_FORMAT, sizeof(timefmt)-1); ! timefmt[sizeof(timefmt)-1] = '\0'; sizefmt = SIZEFMT_KMG; /* Turn printing on */ --- 1805,1814 ---- int printing; int conditional_status; ! strncpy(error, DEFAULT_ERROR_MSG, sizeof(error) - 1); ! error[sizeof(error) - 1] = '\0'; ! strncpy(timefmt, DEFAULT_TIME_FORMAT, sizeof(timefmt) - 1); ! timefmt[sizeof(timefmt) - 1] = '\0'; sizefmt = SIZEFMT_KMG; /* Turn printing on */ *************** *** 1686,1692 **** chdir_file (r->filename); if (r->args) { /* add QUERY stuff to env cause it ain't yet */ ! char *arg_copy = pstrdup (r->pool, r->args); table_set (r->subprocess_env, "QUERY_STRING", r->args); unescape_url (arg_copy); --- 1817,1823 ---- chdir_file (r->filename); if (r->args) { /* add QUERY stuff to env cause it ain't yet */ ! char *arg_copy = pstrdup (r->pool, r->args); table_set (r->subprocess_env, "QUERY_STRING", r->args); unescape_url (arg_copy); *************** *** 1694,1765 **** escape_shell_cmd (r->pool, arg_copy)); } ! 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,r,0); } 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")) ! ret=handle_echo(f, r, error); ! else if(!strcmp(directive,"fsize")) ! 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); #ifdef USE_PERL_SSI ! else if(!strcmp(directive,"perl")) ! ret=handle_perl(f, r, error); #endif 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,r,0); ! } ! if(ret) { ! log_printf(r->server,"httpd: premature EOF in parsed file %s", ! r->filename); return; } } else --- 1825,1899 ---- escape_shell_cmd (r->pool, arg_copy)); } ! 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, r, 0); } 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")) ! ret = handle_echo(f, r, error); ! else if (!strcmp(directive, "fsize")) ! 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); #ifdef USE_PERL_SSI ! else if (!strcmp(directive, "perl")) ! ret = handle_perl(f, r, error); #endif 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, r, 0); ! } ! if (ret) { ! log_printf(r->server, "httpd: premature EOF in parsed file %s", ! r->filename); return; } } else *************** *** 1776,1782 **** module includes_module; enum xbithack { xbithack_off, xbithack_on, xbithack_full }; ! #ifdef XBITHACK #define DEFAULT_XBITHACK xbithack_full #else #define DEFAULT_XBITHACK xbithack_off --- 1910,1916 ---- module includes_module; enum xbithack { xbithack_off, xbithack_on, xbithack_full }; ! #ifdef XBITHACK #define DEFAULT_XBITHACK xbithack_full #else #define DEFAULT_XBITHACK xbithack_off *************** *** 1791,1802 **** const char *set_xbithack (cmd_parms *cmd, void *xbp, char *arg) { ! enum xbithack *state = (enum xbithack *)xbp; ! if (!strcasecmp (arg, "off")) *state = xbithack_off; ! else if (!strcasecmp (arg, "on")) *state = xbithack_on; ! else if (!strcasecmp (arg, "full")) *state = xbithack_full; ! else return "XBitHack must be set to Off, On, or Full"; return NULL; } --- 1925,1939 ---- const char *set_xbithack (cmd_parms *cmd, void *xbp, char *arg) { ! enum xbithack *state = (enum xbithack *)xbp; ! if (!strcasecmp (arg, "off")) ! *state = xbithack_off; ! else if (!strcasecmp (arg, "on")) ! *state = xbithack_on; ! else if (!strcasecmp (arg, "full")) ! *state = xbithack_full; ! else return "XBitHack must be set to Off, On, or Full"; return NULL; } *************** *** 1805,1855 **** { FILE *f; enum xbithack *state = ! (enum xbithack *)get_module_config(r->per_dir_config,&includes_module); int errstatus; ! if (!(allow_options (r) & OPT_INCLUDES)) return DECLINED; ! if (r->method_number != M_GET) return DECLINED; if (r->finfo.st_mode == 0) { log_reason("File does not exist", r->path_info ? pstrcat(r->pool, r->filename, r->path_info, NULL) : r->filename, r); ! return NOT_FOUND; } ! if(!(f=pfopen(r->pool, r->filename, "r"))) { log_reason("file permissions deny server access", r->filename, r); ! return FORBIDDEN; } if (*state == xbithack_full #if !defined(__EMX__) && !defined(WIN32) /* OS/2 dosen't support Groups. */ ! && (r->finfo.st_mode & S_IXGRP) #endif ! && (errstatus = set_last_modified (r, r->finfo.st_mtime))) return errstatus; send_http_header(r); if (r->header_only) { ! pfclose (r->pool, f); ! return OK; } if (r->main) { ! /* Kludge --- for nested includes, we want to keep the ! * subprocess environment of the base document (for compatibility); ! * that means torquing our own last_modified date as well so that ! * the LAST_MODIFIED variable gets reset to the proper value if ! * the nested document resets <!--#config timefmt--> ! */ ! r->subprocess_env = r->main->subprocess_env; ! r->finfo.st_mtime= r->main->finfo.st_mtime; } else { ! add_common_vars (r); ! add_cgi_vars(r); ! add_include_vars (r, DEFAULT_TIME_FORMAT); } hard_timeout("send SSI", r); --- 1942,1994 ---- { FILE *f; enum xbithack *state = ! (enum xbithack *)get_module_config(r->per_dir_config, &includes_module); int errstatus; ! if (!(allow_options (r) & OPT_INCLUDES)) ! return DECLINED; ! if (r->method_number != M_GET) ! return DECLINED; if (r->finfo.st_mode == 0) { log_reason("File does not exist", r->path_info ? pstrcat(r->pool, r->filename, r->path_info, NULL) : r->filename, r); ! return NOT_FOUND; } ! if (!(f = pfopen(r->pool, r->filename, "r"))) { log_reason("file permissions deny server access", r->filename, r); ! return FORBIDDEN; } if (*state == xbithack_full #if !defined(__EMX__) && !defined(WIN32) /* OS/2 dosen't support Groups. */ ! && (r->finfo.st_mode & S_IXGRP) #endif ! && (errstatus = set_last_modified (r, r->finfo.st_mtime))) return errstatus; send_http_header(r); if (r->header_only) { ! pfclose (r->pool, f); ! return OK; } if (r->main) { ! /* Kludge --- for nested includes, we want to keep the ! * subprocess environment of the base document (for compatibility); ! * that means torquing our own last_modified date as well so that ! * the LAST_MODIFIED variable gets reset to the proper value if ! * the nested document resets <!--#config timefmt--> ! */ ! r->subprocess_env = r->main->subprocess_env; ! r->finfo.st_mtime = r->main->finfo.st_mtime; } else { ! add_common_vars (r); ! add_cgi_vars(r); ! add_include_vars (r, DEFAULT_TIME_FORMAT); } hard_timeout("send SSI", r); *************** *** 1872,1916 **** return DECLINED; #else enum xbithack *state; ! ! if (!(r->finfo.st_mode & S_IXUSR)) return DECLINED; state = (enum xbithack *)get_module_config(r->per_dir_config, ! &includes_module); ! if (*state == xbithack_off) return DECLINED; return send_parsed_file (r); #endif } command_rec includes_cmds[] = { ! { "XBitHack", set_xbithack, NULL, OR_OPTIONS, TAKE1, "Off, On, or Full" }, ! { NULL } }; handler_rec includes_handlers[] = { ! { INCLUDES_MAGIC_TYPE, send_shtml_file }, ! { INCLUDES_MAGIC_TYPE3, send_shtml_file }, ! { "server-parsed", send_parsed_file }, ! { "text/html", xbithack_handler }, ! { NULL } }; module includes_module = { ! STANDARD_MODULE_STUFF, ! NULL, /* initializer */ ! create_includes_dir_config, /* dir config creater */ ! NULL, /* dir merger --- default is to override */ ! NULL, /* server config */ ! NULL, /* merge server config */ ! includes_cmds, /* command table */ ! includes_handlers, /* handlers */ ! NULL, /* filename translation */ ! NULL, /* check_user_id */ ! NULL, /* check auth */ ! NULL, /* check access */ ! NULL, /* type_checker */ ! NULL, /* fixups */ ! NULL, /* logger */ ! NULL /* header parser */ }; --- 2011,2057 ---- return DECLINED; #else enum xbithack *state; ! ! if (!(r->finfo.st_mode & S_IXUSR)) ! return DECLINED; state = (enum xbithack *)get_module_config(r->per_dir_config, ! &includes_module); ! if (*state == xbithack_off) ! return DECLINED; return send_parsed_file (r); #endif } command_rec includes_cmds[] = { ! { "XBitHack", set_xbithack, NULL, OR_OPTIONS, TAKE1, "Off, On, or Full" }, ! { NULL } }; handler_rec includes_handlers[] = { ! { INCLUDES_MAGIC_TYPE, send_shtml_file }, ! { INCLUDES_MAGIC_TYPE3, send_shtml_file }, ! { "server-parsed", send_parsed_file }, ! { "text/html", xbithack_handler }, ! { NULL } }; module includes_module = { ! STANDARD_MODULE_STUFF, ! NULL, /* initializer */ ! create_includes_dir_config, /* dir config creater */ ! NULL, /* dir merger --- default is to override */ ! NULL, /* server config */ ! NULL, /* merge server config */ ! includes_cmds, /* command table */ ! includes_handlers, /* handlers */ ! NULL, /* filename translation */ ! NULL, /* check_user_id */ ! NULL, /* check auth */ ! NULL, /* check access */ ! NULL, /* type_checker */ ! NULL, /* fixups */ ! NULL, /* logger */ ! NULL /* header parser */ };