httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From r..@engelschall.com (Ralf S. Engelschall)
Subject mod_rewrite 3.0.0 for Apache 1.2b7 !!! (PATCH)
Date Fri, 31 Jan 1997 20:54:57 GMT

As a result of the current problems, I decided a change for mod_rewrite:

1. Version 2.4.x (currently 2.4.1) is the latest release available
   for Apache 1.1.x. There will be only bugfixes applied to 2.4.x
   to provide a stable version for the Apache 1.1.x users.

2. Version 3.0.0 was created by manually merging (hmm... I like
   those jobs) the 2.4.1 version and the aligned 2.3.10+ version currently
   found in the 1.2b7-dev snapshot sources. Actually this is 2.4.1 with Marcs
   snprintf/strncpy patches re-applied.  All other changes from the Apache
   Group (OS\2 EMX, const, etc.) were already included into 2.4.1.

Version 3.0.0 is still not released. Below is a standard patch for review
_AND_ a context diff to bring the current CVS sources up to date.

NOW, APACHE GROUP MEMBERS, ATTENTION PLEASE:

Go to the patch and review it. And do it immediately so it don't get lost in
the processing ;-) and Apache 1.2b7 can contain mod_rewrite 3.0.0. Please vote
for this change NOW!

Thanks!
                                       Ralf S. Engelschall
                                       rse@engelschall.com
                                       www.engelschall.com

=REVIEW DIFF===========================
0a1
>  
63c64
< **  URL Rewriting Module, Version 2.3.10 (20-12-1996)
---
> **  URL Rewriting Module, Version 3.0.0 (xx-02-1997)
83c84
< **  Copyright (c) 1996 Ralf S. Engelschall, All rights reserved.
---
> **  Copyright (c) 1996-1997 Ralf S. Engelschall, All rights reserved.
88c89
< **      http://www.engelschall.com/
---
> **      www.engelschall.com
98a100,102
> #include <errno.h>
> #include <pwd.h>
> #include <grp.h>
113,117d116
< #ifdef __EMX__
< /* OS/2 dosen't support links. */
< #define S_ISLNK
< #endif
< 
134c133
< **  keep in mind:
---
> **  keep in mind: 
231d229
< #ifdef HAS_APACHE_REGEX_LIB
235,238d232
< #else
< #define MAPFILE_OUTPUT "\\1,\\2"
< static regexp *lookup_map_txtfile_regexp = NULL;
< #endif
359c353
< static _const char *cmd_rewriteengine(cmd_parms *cmd, rewrite_perdir_conf *dconf, int flag)
---
> static const char *cmd_rewriteengine(cmd_parms *cmd, rewrite_perdir_conf *dconf, int flag)
372c366
< static _const char *cmd_rewriteoptions(cmd_parms *cmd, rewrite_perdir_conf *dconf, char *option)
---
> static const char *cmd_rewriteoptions(cmd_parms *cmd, rewrite_perdir_conf *dconf, char *option)
375c369
<     _const char *err;
---
>     const char *err;
386c380
< static _const char *cmd_rewriteoptions_setoption(pool *p, int *options, char *name)
---
> static const char *cmd_rewriteoptions_setoption(pool *p, int *options, char *name)
395c389
< static _const char *cmd_rewritelog(cmd_parms *cmd, void *dconf, char *a1)
---
> static const char *cmd_rewritelog(cmd_parms *cmd, void *dconf, char *a1)
405c399
< static _const char *cmd_rewriteloglevel(cmd_parms *cmd, void *dconf, char *a1)
---
> static const char *cmd_rewriteloglevel(cmd_parms *cmd, void *dconf, char *a1)
415c409
< static _const char *cmd_rewritemap(cmd_parms *cmd, void *dconf, char *a1, char *a2)
---
> static const char *cmd_rewritemap(cmd_parms *cmd, void *dconf, char *a1, char *a2)
459c453
< static _const char *cmd_rewritebase(cmd_parms *cmd, rewrite_perdir_conf *dconf, char *a1)
---
> static const char *cmd_rewritebase(cmd_parms *cmd, rewrite_perdir_conf *dconf, char *a1)
473c467
< static _const char *cmd_rewritecond(cmd_parms *cmd, rewrite_perdir_conf *dconf, char *str)
---
> static const char *cmd_rewritecond(cmd_parms *cmd, rewrite_perdir_conf *dconf, char *str)
477d470
< #ifdef HAS_APACHE_REGEX_LIB
479,482d471
< #else
<     regexp *regexp;
<     int i;
< #endif
487c476
<     _const char *err;
---
>     const char *err;
525d513
< #ifdef HAS_APACHE_REGEX_LIB
530,536d517
< #else
<     if (new->flags & CONDFLAG_NOCASE) {
<         for (i = 0; cp[i] != '\0'; i++)
<             cp[i] = tolower(cp[i]);
<     }
<     rc = ((regexp = regcomp(cp)) == NULL);
< #endif
545c526
< static _const char *cmd_rewritecond_parseflagfield(pool *p, rewritecond_entry *cfg, char *str)
---
> static const char *cmd_rewritecond_parseflagfield(pool *p, rewritecond_entry *cfg, char *str)
553c534
<     _const char *err;
---
>     const char *err;
579c560
<                 val = "yes";
---
>                 val = "";
591c572
< static _const char *cmd_rewritecond_setflag(pool *p, rewritecond_entry *cfg, char *key, char *val)
---
> static const char *cmd_rewritecond_setflag(pool *p, rewritecond_entry *cfg, char *key, char *val)
608c589
< _const char *cmd_rewriterule(cmd_parms *cmd, rewrite_perdir_conf *dconf, char *str)
---
> const char *cmd_rewriterule(cmd_parms *cmd, rewrite_perdir_conf *dconf, char *str)
612d592
< #ifdef HAS_APACHE_REGEX_LIB
614,617d593
< #else
<     regexp *regexp;
<     int i;
< #endif
622c598
<     _const char *err;
---
>     const char *err;
644d619
< #ifdef HAS_APACHE_REGEX_LIB
646,648d620
< #else
<     if ((regexp = regcomp(cp)) == NULL)
< #endif
656,661d627
< #ifndef HAS_APACHE_REGEX_LIB
<     for (i = 0; a2[i] != '\0'; i++) {
<         if (a2[i] == '$' && a2[i+1] >= '1' && a2[i+1] <= '9') 
<             a2[i] = '\\';
<     }
< #endif
665a632,633
>     new->forced_responsecode = HTTP_MOVED_TEMPORARILY;
>     new->env[0] = NULL;
687c655
< static _const char *cmd_rewriterule_parseflagfield(pool *p, rewriterule_entry *cfg, char *str)
---
> static const char *cmd_rewriterule_parseflagfield(pool *p, rewriterule_entry *cfg, char *str)
695c663
<     _const char *err;
---
>     const char *err;
721c689
<                 val = "yes";
---
>                 val = "";
733c701
< static _const char *cmd_rewriterule_setflag(pool *p, rewriterule_entry *cfg, char *key, char *val)
---
> static const char *cmd_rewriterule_setflag(pool *p, rewriterule_entry *cfg, char *key, char *val)
734a703,705
>     int status = 0;
>     int i;
> 
737a709,721
>         if (strlen(val) > 0) {
>             if (strcasecmp(val, "permanent") == 0)
>                 status = HTTP_MOVED_PERMANENTLY;
>             else if (strcasecmp(val, "temp") == 0)
>                 status = HTTP_MOVED_TEMPORARILY;
>             else if (strcasecmp(val, "seeother") == 0)
>                 status = HTTP_SEE_OTHER;
>             else if (isdigit(*val))
>                 status = atoi(val);
>             if (!is_HTTP_REDIRECT(status))
>                 return pstrdup(p, "RewriteRule: invalid HTTP response code for flag 'R'");
>             cfg->forced_responsecode = status;
>         }
754a739,749
>     else if (   strcasecmp(key, "env") == 0
>              || strcasecmp(key, "E") == 0   ) {
>         for (i = 0; (cfg->env[i] != NULL) && (i < MAX_ENV_FLAGS); i++)
>             ;
>         if (i < MAX_ENV_FLAGS) {
>             cfg->env[i] = pstrdup(p, val);
>             cfg->env[i+1] = NULL;
>         }
>         else 
>             return pstrdup(p, "RewriteRule: to much environment flags 'E'");
>     }
774a770,773
>     else if (   strcasecmp(key, "gone") == 0
>              || strcasecmp(key, "G") == 0   ) {
>         cfg->flags |= RULEFLAG_GONE;
>     }
808d806
< #ifdef HAS_APACHE_REGEX_LIB
810,812d807
< #else
<     lookup_map_txtfile_regexp = regcomp(MAPFILE_PATTERN);
< #endif
973a969,977
>             /* determine HTTP redirect response code */
>             if (is_HTTP_REDIRECT(r->status)) {
>                 n = r->status; 
>                 r->status = HTTP_OK; /* make Apache kernel happy */
>             }
>             else
>                 n = REDIRECT;
> 
>             /* now do the redirection */
975,976c979,980
<             rewritelog(r, 1, "redirect to %s [REDIRECT]", r->filename);
<             return REDIRECT;
---
>             rewritelog(r, 1, "redirect to %s [REDIRECT/%d]", r->filename, n);
>             return n;
982a987,991
>         else if (strlen(r->filename) > 5 &&
>                  strncmp(r->filename, "gone:", 5) == 0) {
>             /* This URLs is forced to be gone */
>             return HTTP_GONE; 
>         }
1012c1021
<                - when we allways prefix with document_root
---
>                - when we always prefix with document_root
1014,1015c1023,1024
<                  remulating a ScriptAlias directive, etc.
<                - when we allways NOT prefix with document_root
---
>                  emulating a ScriptAlias directive, etc.
>                - when we always NOT prefix with document_root
1030c1039
< 		    docroot[sizeof(docroot)-1] = '\0';
---
>                     docroot[sizeof(docroot)-1] = '\0';
1095a1105
>     int n;
1202a1213,1221
>             /* determine HTTP redirect response code */
>             if (is_HTTP_REDIRECT(r->status)) {
>                 n = r->status; 
>                 r->status = HTTP_OK; /* make Apache kernel happy */
>             }
>             else
>                 n = REDIRECT;
> 
>             /* now do the redirection */
1204,1205c1223,1224
<             rewritelog(r, 1, "[per-dir %s] redirect to %s [REDIRECT]", dconf->directory, r->filename);
<             return REDIRECT;
---
>             rewritelog(r, 1, "[per-dir %s] redirect to %s [REDIRECT/%d]", dconf->directory, r->filename, n);
>             return n;
1211a1231,1235
>         else if (strlen(r->filename) > 5 &&
>                  strncmp(r->filename, "gone:", 5) == 0) {
>             /* This URLs is forced to be gone */
>             return HTTP_GONE; 
>         }
1344a1369,1374
>             if (p->flags & RULEFLAG_GONE) {
>                 rewritelog(r, 2, "forcing '%s' to be gone", r->filename);
>                 r->filename = pstrcat(r->pool, "gone:", r->filename, NULL);
>                 changed = 1;
>                 break;
>             }
1381a1412
>     char env[MAX_STRING_LEN];
1383c1414
< #ifdef HAS_APACHE_REGEX_LIB
---
>     char env2[MAX_STRING_LEN];
1386,1388d1416
< #else
<     regexp *regexp;
< #endif
1421d1448
< #ifdef HAS_APACHE_REGEX_LIB
1423,1425d1449
< #else
<     rc = (regexec(regexp, uri) != 0);   /* try to match the pattern */
< #endif
1476c1500
< 		newuri[sizeof(newuri)-1] = '\0';
---
>                 newuri[sizeof(newuri)-1] = '\0';
1482d1505
< #ifdef HAS_APACHE_REGEX_LIB
1484,1487c1507,1511
< 		newuri[sizeof(newuri)-1] = '\0';
< #else
<                 regsub(regexp, output, newuri);                      /* substitute in output */
< #endif
---
>                 for (i = 0; p->env[i] != NULL; i++) {
>                     strcpy(env2, p->env[i]);
>                     strcpy(env, pregsub(r->pool, env2, uri, regexp->re_nsub+1, regmatch));    /* substitute in output */
>                     add_env_variable(r, env);
>                 }
1510c1534
< 		newuri[sizeof(newuri)-1] = '\0';
---
>                 newuri[sizeof(newuri)-1] = '\0';
1515d1538
< #ifdef HAS_APACHE_REGEX_LIB
1517,1520c1540,1545
< 		newuri[sizeof(newuri)-1] = '\0';
< #else
<                 regsub(regexp, output, newuri);                      /* substitute in output */
< #endif
---
>                 newuri[sizeof(newuri)-1] = '\0';
>                 for (i = 0; p->env[i] != NULL; i++) {
>                     strcpy(env2, p->env[i]);
>                     strcpy(env, pregsub(r->pool, env2, uri, regexp->re_nsub+1, regmatch));    /* substitute in output */
>                     add_env_variable(r, env);
>                 }
1541c1566
< 	    newuri[sizeof(newuri)-1] = '\0';
---
>             newuri[sizeof(newuri)-1] = '\0';
1545d1569
< #ifdef HAS_APACHE_REGEX_LIB
1547,1550c1571,1576
< 	    newuri[sizeof(newuri)-1] = '\0'; 
< #else
<             regsub(regexp, output, newuri);                      /* substitute in output */
< #endif
---
>             newuri[sizeof(newuri)-1] = '\0'; 
>             for (i = 0; p->env[i] != NULL; i++) {
>                 strcpy(env2, p->env[i]);
>                 strcpy(env, pregsub(r->pool, env2, uri, regexp->re_nsub+1, regmatch));    /* substitute in output */
>                 add_env_variable(r, env);
>             }
1553c1579
<         expand_map_lookups(r, newuri, sizeof(newuri));   /* expand ${...} */
---
>         expand_map_lookups(r, newuri, sizeof(newuri));         /* expand ${...} */
1613a1640
>                 r->status = p->forced_responsecode;
1625,1628d1651
< #ifndef HAS_APACHE_REGEX_LIB
<     char inputbuf[LONG_STRING_LEN];
<     int i;
< #endif
1631a1655
>     request_rec *rsub;
1647a1672,1673
> #ifndef __EMX__
> /* OS/2 dosen't support links. */
1650a1677
> #endif
1656a1684,1732
>     else if (strcmp(p->pattern, "-U") == 0) {
>         /* avoid infinite subrequest recursion */
>         if (strlen(input) > 0               /* nonempty path, and */
>             && (   r->main == NULL          /* - either not in a subrequest */
>                 || (   r->main->uri != NULL /* - or in a subrequest...*/
>                     && r->uri != NULL       /*   ...and then URIs aren't NULL... */
>                                             /*   ...and sub and main URIs differ */
>                     && strcmp(r->main->uri, r->uri) != 0) ) ) {
> 
>             /* run a URI-based subrequest */
>             rsub = sub_req_lookup_uri(input, r);
> 
>             /* URI exists for any result up to 3xx, redirects allowed */
>             if (rsub->status < 400)
>                 rc = 1;
> 
>             /* log it */
>             rewritelog(r, 5, "RewriteCond URI (-U) check: path=%s -> status=%d", input, rsub->status);
> 
>             /* cleanup by destroying the subrequest */
>             destroy_sub_req(rsub);
>         }
>     }
>     else if (strcmp(p->pattern, "-F") == 0) {
>         /* avoid infinite subrequest recursion */
>         if (strlen(input) > 0               /* nonempty path, and */
>             && (   r->main == NULL          /* - either not in a subrequest */
>                 || (   r->main->uri != NULL /* - or in a subrequest...*/
>                     && r->uri != NULL       /*   ...and then URIs aren't NULL... */
>                                             /*   ...and sub and main URIs differ */
>                     && strcmp(r->main->uri, r->uri) != 0) ) ) {
> 
>             /* process a file-based subrequest: 
>                this differs from -U in that no path translation is done. */
>             rsub = sub_req_lookup_file(input, r);
>  
>             /* file exists for any result up to 2xx, no redirects */
>             if (rsub->status < 300 &&
>                 /* double-check that file exists since default result is 200 */
>                 stat(rsub->filename, &sb) == 0)
>                 rc = 1;
> 
>             /* log it */
>             rewritelog(r, 5, "RewriteCond file (-F) check: path=%s -> file=%s status=%d", input, rsub->filename, rsub->status);
> 
>             /* cleanup by destroying the subrequest */
>             destroy_sub_req(rsub);
>         }
>     }
1659d1734
< #ifdef HAS_APACHE_REGEX_LIB
1661,1672d1735
< #else
<         if (p->flags & CONDFLAG_NOCASE) {
<             for (i = 0; input[i] != '\0' && i < sizeof(inputbuf)-1 ; i++)
<                 inputbuf[i] = tolower(input[i]);
<             inputbuf[i] = '\0';
<         }
<         else {
<             strncpy(inputbuf, input, sizeof(inputbuf)-1);
< 	    inputbuf[sizeof(inputbuf)-1] = '\0';
<         }
<         rc = (regexec(p->regexp, inputbuf) != 0);
< #endif
1758c1821
< 	buf[sizeof(buf)-1] = '\0';
---
>         buf[sizeof(buf)-1] = '\0';
1766c1829
< 	    host[sizeof(host)-1] = '\0';
---
>             host[sizeof(host)-1] = '\0';
1782c1845
< 	    host[sizeof(host)-1] = '\0';
---
>             host[sizeof(host)-1] = '\0';
1792c1855
< 	    host[sizeof(host)-1] = '\0';
---
>             host[sizeof(host)-1] = '\0';
1861c1924,1925
< #define limit_length(n)	(n > LONG_STRING_LEN-1 ? LONG_STRING_LEN-1 : n)
---
> #define limit_length(n) (n > LONG_STRING_LEN-1 ? LONG_STRING_LEN-1 : n)
> 
1921,1924c1985,1988
< 		if (cpO + n >= newuri + sizeof(newuri)) {
< 		    log_printf(r->server, "insufficient space in expand_map_lookups, aborting");
< 		    return;
< 		}
---
>                 if (cpO + n >= newuri + sizeof(newuri)) {
>                     log_printf(r->server, "insufficient space in expand_map_lookups, aborting");
>                     return;
>                 }
1930,1933c1994,1997
< 		if (cpO + n >= newuri + sizeof(newuri)) {
< 		    log_printf(r->server, "insufficient space in expand_map_lookups, aborting");
< 		    return;
< 		}
---
>                 if (cpO + n >= newuri + sizeof(newuri)) {
>                     log_printf(r->server, "insufficient space in expand_map_lookups, aborting");
>                     return;
>                 }
1943,1946c2007,2010
< 	    if (cpO + n >= newuri + sizeof(newuri)) {
< 		log_printf(r->server, "insufficient space in expand_map_lookups, aborting");
< 		return;
< 	    }
---
>             if (cpO + n >= newuri + sizeof(newuri)) {
>                 log_printf(r->server, "insufficient space in expand_map_lookups, aborting");
>                 return;
>             }
1957d2020
< #undef limit_length
1958a2022
> #undef limit_length
2064c2128
<     strncpy(output,  MAPFILE_OUTPUT, sizeof(output)-1);
---
>     strncpy(output, MAPFILE_OUTPUT, sizeof(output)-1);
2069d2132
< #ifdef HAS_APACHE_REGEX_LIB
2071,2074d2133
< #else
<         if (regexec(lookup_map_txtfile_regexp, line) != 0) {
< #endif
< #ifdef HAS_APACHE_REGEX_LIB
2076,2079c2135
< 	    result[sizeof(result)-1] = '\0';
< #else
<             regsub(lookup_map_txtfile_regexp, output, result);
< #endif
---
>             result[sizeof(result)-1] = '\0';
2105c2161
<     dbmkey.dsize = strlen(key) < sizeof(buf) - 1 : strlen(key) ? sizeof(buf)-1;
---
>     dbmkey.dsize = (strlen(key) < sizeof(buf) - 1 : strlen(key) ? sizeof(buf)-1);
2124a2181,2183
>     /* lock the channel */
>     fd_lock(fpin);
> 
2137a2197,2199
>     /* unlock the channel */
>     fd_unlock(fpin);
> 
2200c2262
<     /* For OS/2 we need to use a '/' */
---
>     /* OS/2 needs a '/' */
2217d2278
<     char *ruser;
2220a2282
>     char *ruser;
2238c2300,2301
<     } else if (strlen (connect->user) != 0) {
---
>     }
>     else if (strlen (connect->user) != 0) {
2240c2303,2304
<     } else {
---
>     }
>     else {
2242c2306
<     };
---
>     }
2246,2247c2310
<                             ruser,
<                             NULL);
---
>                             ruser, NULL);
2250,2256c2313,2316
<     if (r->main == NULL) {
<         strncpy(type, "initial", sizeof(type)-1);
< 	type[sizeof(type)-1] = '\0';
<     } else {
<         strncpy(type, "subreq", sizeof(type)-1);
< 	type[sizeof(type)-1] = '\0';
<     }
---
>     if (r->main == NULL)
>         strcpy(type, "initial");
>     else
>         strcpy(type, "subreq");
2261c2321
<         strcpy(redir, "");
---
>         redir[0] = '\0';
2266a2327
>     fd_lock(conf->rewritelogfp);
2267a2329
>     fd_unlock(conf->rewritelogfp);
2275d2336
< #ifdef IS_APACHE_12
2277,2279d2337
< #else
<     long timz;
< #endif
2289,2291c2347
<     strftime(tstr, 80,"[%d/%b/%Y:%H:%M:%S ",t);
< 
< #ifdef IS_APACHE_12
---
>     strftime(tstr, 80, "[%d/%b/%Y:%H:%M:%S ", t);
2293,2296d2348
< #else
<     ap_snprintf(tstr + strlen(tstr), 80-strlen(tstr), "%c%02ld%02ld]", sign, timz/3600, timz%3600);
< #endif
< 
2356c2408
<     /* For OS/2 we need to use a '/' */
---
>     /* OS/2 needs a '/' */
2360c2412
< #endif    
---
> #endif
2382c2434
< 	buf[buf_len-1] = '\0';
---
>         buf[buf_len-1] = '\0';
2404a2457
> 
2415c2468
< 	output[sizeof(output)-1] = '\0';
---
>         output[sizeof(output)-1] = '\0';
2426a2480,2483
>     request_rec *rsub;
>     struct passwd *pw;
>     struct group *gr;
>     struct stat finfo;
2493a2551,2553
>     else if (strcasecmp(var, "IS_SUBREQ") == 0) { /* non-standard */
>         result = (r->main != NULL ? "true" : "false");
>     }
2553c2613,2685
<         result = getenv(var+4);
---
>         /* first try the internal Apache notes structure */
>         result = table_get(r->notes, var+4);
>         /* second try the internal Apache env structure  */
>         if (result == NULL) 
>             result = table_get(r->subprocess_env, var+4);
>         /* third try the external OS env */
>         if (result == NULL) 
>             result = getenv(var+4);
>     }
> 
> #define LOOKAHEAD(subrecfunc) \
>         if ( \
>           /* filename is safe to use */ \
>           r->filename != NULL \
>               /* - and we're either not in a subrequest */ \
>               && ( r->main == NULL \
>                   /* - or in a subrequest where paths are non-NULL... */ \
>                     || ( r->main->uri != NULL && r->uri != NULL \
>                         /*   ...and sub and main paths differ */ \
>                         && strcmp(r->main->uri, r->uri) != 0))) { \
>             /* process a file-based subrequest */ \
>             rsub = subrecfunc(r->filename, r); \
>             /* now recursively lookup the variable in the sub_req */ \
>             result = lookup_variable(rsub, var+5); \
>             /* copy it up to our scope before we destroy the sub_req's pool */ \
>             result = pstrdup(r->pool, result); \
>             /* cleanup by destroying the subrequest */ \
>             destroy_sub_req(rsub); \
>             /* log it */ \
>             rewritelog(r, 5, "lookahead: path=%s var=%s -> val=%s", r->filename, var+5, result); \
>             /* return ourself to prevent re-pstrdup */ \
>             return result; \
>         }
> 
>     /* look-ahead for parameter through URI-based sub-request */
>     else if (strlen(var) > 5 && strncasecmp(var, "LA-U:", 5) == 0) {
>         LOOKAHEAD(sub_req_lookup_uri)
>     }
>     /* look-ahead for parameter through file-based sub-request */
>     else if (strlen(var) > 5 && strncasecmp(var, "LA-F:", 5) == 0) {
>         LOOKAHEAD(sub_req_lookup_file)
>     }
> 
>     /* file stuff */
>     else if (strcasecmp(var, "SCRIPT_USER") == 0) {
>         result = pstrdup(r->pool, "<unknown>");
>         if (r->finfo.st_mode != 0) {
>             if ((pw = getpwuid(r->finfo.st_uid)) != NULL) { 
>                 result = pstrdup(r->pool, pw->pw_name);
>             }
>         }
>         else {
>             if (stat(r->filename, &finfo) == 0) {
>                 if ((pw = getpwuid(finfo.st_uid)) != NULL) { 
>                     result = pstrdup(r->pool, pw->pw_name);
>                 }
>             }
>         }
>     }
>     else if (strcasecmp(var, "SCRIPT_GROUP") == 0) {
>         result = pstrdup(r->pool, "<unknown>");
>         if (r->finfo.st_mode != 0) {
>             if ((gr = getgrgid(r->finfo.st_gid)) != NULL) { 
>                 result = pstrdup(r->pool, gr->gr_name);
>             }
>         }
>         else {
>             if (stat(r->filename, &finfo) == 0) {
>                 if ((gr = getgrgid(finfo.st_gid)) != NULL) { 
>                     result = pstrdup(r->pool, gr->gr_name);
>                 }
>             }
>         }
2555,2556d2686
< 
<     /* uptime, load average, etc. .. */
2724d2853
< 
2738c2867
< 	substbuf[sizeof(substbuf)-1] = '\0';
---
>         substbuf[sizeof(substbuf)-1] = '\0';
2835a2965,2981
> void add_env_variable(request_rec *r, char *s)
> {
>     char var[MAX_STRING_LEN];
>     char val[MAX_STRING_LEN];
>     char *cp;
> 
>     if ((cp = strchr(s, ':')) != NULL) {
>         memcpy(var, s, cp-s);
>         var[cp-s] = '\0';
>         strcpy(val, cp+1);
>         table_set(r->subprocess_env, pstrdup(r->pool, var), pstrdup(r->pool, val));
>         rewritelog(r, 5, "setting env variable '%s' to '%s'", var, val);
>     }
> }
> 
> 
> 
2872c3018
<     _const char *names;
---
>     const char *names;
2995d3140
< #ifdef IS_APACHE_12
3011,3012c3156,3169
< #else
< int is_proxy_available(server_rec *s)
---
> 
> 
> /*
> **
> **  File locking
> **
> */
> 
> #ifdef USE_FCNTL
> static struct flock   lock_it = { F_WRLCK, 0, 0, 0 };
> static struct flock unlock_it = { F_UNLCK, 0, 0, 0 };
> #endif 
> 
> static void fd_lock(int fd)
3014,3020c3171,3186
<     extern char *module_names[];
<     int n;
<     
<     for (n = 0; module_names[n] != NULL; n++) {
<         if (strcmp(module_names[n], "proxy_module") == 0) {
<             return 1;
<         }
---
>     int rc;
> 
> #ifdef USE_FCNTL
>     while (   ((rc = fcntl(fd, F_SETLKW, &lock_it)) < 0) 
>            && (errno == EINTR)                               )
>         continue;
> #endif
> #ifdef USE_FLOCK
>     while (   ((rc = flock(fd, LOCK_EX)) < 0) 
>            && (errno == EINTR)               )
>         continue;
> #endif
> 
>     if (rc < 0) {
>         fprintf(stderr, "Error getting lock. Exiting!");
>         exit(1);
3022c3188
<     return 0;
---
>     return;
3023a3190,3196
> 
> static void fd_unlock(int fd)
> {
>     int rc;
> 
> #ifdef USE_FCNTL 
>     rc = fcntl(fd, F_SETLKW, &unlock_it);
3024a3198,3206
> #ifdef USE_FLOCK 
>     rc = flock(fd, LOCK_UN);
> #endif 
> 
>     if (rc < 0) {
>         fprintf(stderr, "Error freeing lock. Exiting!");
>         exit(1);
>     }
> }
0a1
> 
66c67
< **  URL Rewriting Module, Version 2.3.10 (20-12-1996)
---
> **  URL Rewriting Module, Version 3.0.0 (xx-02-1997)
86c87
< **  Copyright (c) 1996 Ralf S. Engelschall, All rights reserved.
---
> **  Copyright (c) 1996-1997 Ralf S. Engelschall, All rights reserved.
91c92
< **      http://www.engelschall.com/
---
> **      www.engelschall.com
97,123d97
<     /* Check Apache Release */
< #if (MODULE_MAGIC_NUMBER >= 19960725)
< #define IS_APACHE_12         1
< #define HAS_APACHE_REGEX_LIB 1
< #endif
< 
< 
<     /* The const problem:
<        The Apache Group changed some essential prototypes
<        to have an additional "const" qualifier. To be backward
<        compatible with Apache 1.1.1 we use a special define */
< #ifdef IS_APACHE_12
< #define _const const
< #else
< #define _const  
< #endif
< 
< 
<     /* The RegExp support:
<        For Apache 1.1.1 we provide our own Spencer V8 library,
<        for Apache 1.2 and higher there is a Spencer POSIX library
<        in the distribution */
< #ifndef HAS_APACHE_REGEX_LIB
< #include "regexp/regexp.h"
< #endif
< 
< 
137a112,135
>     /* The locking support:
>        Try to determine whether we should use
>        fcntl() or flock(). */
> #if defined(USE_FCNTL_SERIALIZED_ACCEPT)
> #define USE_FCNTL 1
> #include <fcntl.h>
> #endif
> #if defined(USE_FLOCK_SERIALIZED_ACCEPT)
> #define USE_FLOCK 1
> #include <sys/file.h>
> #endif
> #if !defined(USE_FCNTL) && !defined(USE_FLOCK)
> #define USE_FLOCK 1
> #include <sys/file.h>
> #ifndef LOCK_UN
> #undef USE_FLOCK
> #define USE_FCNTL 1
> #include <fcntl.h>
> #endif
> #endif
> 
> 
> 
> 
167a166
> #define RULEFLAG_GONE               1<<10
195a195,196
> #define MAX_ENV_FLAGS 5
> 
218d218
< #ifdef HAS_APACHE_REGEX_LIB
220,222d219
< #else
<     regexp  *regexp;               /* the RegExp pattern compilation */
< #endif
229d225
< #ifdef HAS_APACHE_REGEX_LIB
231,237c227,232
< #else
<     regexp       *regexp;
< #endif
<     char         *output;          /* the Substitution string */
<     int           flags;           /* Flags which control the substitution */
<     char         *forced_mimetype; /* forced MIME-type of substitution */
<     int           skip;            /* number of next rules to skip */
---
>     char         *output;              /* the Substitution string */
>     int           flags;               /* Flags which control the substitution */
>     char         *forced_mimetype;     /* forced MIME type of substitution */
>     int           forced_responsecode; /* forced HTTP redirect response status */
>     char         *env[MAX_ENV_FLAGS+1];/* added environment variables */
>     int           skip;                /* number of next rules to skip */
301,316c296,311
< static _const char *cmd_rewriteengine  (cmd_parms *cmd, rewrite_perdir_conf *dconf, int flag);
< static _const char *cmd_rewriteoptions (cmd_parms *cmd, rewrite_perdir_conf *dconf, char *option);
< static _const char *cmd_rewriteoptions_setoption(pool *p, int *options, char *name);
< static _const char *cmd_rewritelog     (cmd_parms *cmd, void *dconf, char *a1);
< static _const char *cmd_rewriteloglevel(cmd_parms *cmd, void *dconf, char *a1);
< static _const char *cmd_rewritemap     (cmd_parms *cmd, void *dconf, char *a1, char *a2);
< 
< static _const char *cmd_rewritebase(cmd_parms *cmd, rewrite_perdir_conf *dconf, char *a1);
< 
< static _const char *cmd_rewritecond    (cmd_parms *cmd, rewrite_perdir_conf *dconf, char *str);
< static _const char *cmd_rewritecond_parseflagfield(pool *p, rewritecond_entry *new, char *str);
< static _const char *cmd_rewritecond_setflag       (pool *p, rewritecond_entry *cfg, char *key, char *val);
< 
< extern _const char *cmd_rewriterule    (cmd_parms *cmd, rewrite_perdir_conf *dconf, char *str);
< static _const char *cmd_rewriterule_parseflagfield(pool *p, rewriterule_entry *new, char *str);
< static _const char *cmd_rewriterule_setflag       (pool *p, rewriterule_entry *cfg, char *key, char *val);
---
> static const char *cmd_rewriteengine  (cmd_parms *cmd, rewrite_perdir_conf *dconf, int flag);
> static const char *cmd_rewriteoptions (cmd_parms *cmd, rewrite_perdir_conf *dconf, char *option);
> static const char *cmd_rewriteoptions_setoption(pool *p, int *options, char *name);
> static const char *cmd_rewritelog     (cmd_parms *cmd, void *dconf, char *a1);
> static const char *cmd_rewriteloglevel(cmd_parms *cmd, void *dconf, char *a1);
> static const char *cmd_rewritemap     (cmd_parms *cmd, void *dconf, char *a1, char *a2);
> 
> static const char *cmd_rewritebase(cmd_parms *cmd, rewrite_perdir_conf *dconf, char *a1);
> 
> static const char *cmd_rewritecond    (cmd_parms *cmd, rewrite_perdir_conf *dconf, char *str);
> static const char *cmd_rewritecond_parseflagfield(pool *p, rewritecond_entry *new, char *str);
> static const char *cmd_rewritecond_setflag       (pool *p, rewritecond_entry *cfg, char *key, char *val);
> 
> extern const char *cmd_rewriterule    (cmd_parms *cmd, rewrite_perdir_conf *dconf, char *str);
> static const char *cmd_rewriterule_parseflagfield(pool *p, rewriterule_entry *new, char *str);
> static const char *cmd_rewriterule_setflag       (pool *p, rewriterule_entry *cfg, char *key, char *val);
372a368
> static void   add_env_variable(request_rec *r, char *s);
380a377,380
> 
>     /* File locking */
> static void fd_lock(int fd);
> static void fd_unlock(int fd);














=CONTEXT DIFF===========================
*** SNAP/src/mod_rewrite.c	Thu Jan 30 03:00:09 1997
--- src/mod_rewrite.c	Fri Jan 31 21:45:33 1997
***************
*** 1,3 ****
--- 1,4 ----
+  
  /* ====================================================================
   * Copyright (c) 1996,1997 The Apache Group.  All rights reserved.
   *
***************
*** 60,66 ****
  **  |_| |_| |_|\___/ \__,_|___|_|  \___| \_/\_/ |_|  |_|\__\___|
  **                       |_____|
  **
! **  URL Rewriting Module, Version 2.3.10 (20-12-1996)
  **
  **  This module uses a rule-based rewriting engine (based on a
  **  regular-expression parser) to rewrite requested URLs on the fly. 
--- 61,67 ----
  **  |_| |_| |_|\___/ \__,_|___|_|  \___| \_/\_/ |_|  |_|\__\___|
  **                       |_____|
  **
! **  URL Rewriting Module, Version 3.0.0 (xx-02-1997)
  **
  **  This module uses a rule-based rewriting engine (based on a
  **  regular-expression parser) to rewrite requested URLs on the fly. 
***************
*** 80,91 ****
  **  The documentation and latest release can be found on
  **  http://www.engelschall.com/sw/mod_rewrite/
  **
! **  Copyright (c) 1996 Ralf S. Engelschall, All rights reserved.
  **
  **  Written for The Apache Group by
  **      Ralf S. Engelschall
  **      rse@engelschall.com
! **      http://www.engelschall.com/
  */
  
  
--- 81,92 ----
  **  The documentation and latest release can be found on
  **  http://www.engelschall.com/sw/mod_rewrite/
  **
! **  Copyright (c) 1996-1997 Ralf S. Engelschall, All rights reserved.
  **
  **  Written for The Apache Group by
  **      Ralf S. Engelschall
  **      rse@engelschall.com
! **      www.engelschall.com
  */
  
  
***************
*** 96,101 ****
--- 97,105 ----
  #include <stdarg.h>
  #include <time.h>
  #include <signal.h>
+ #include <errno.h>
+ #include <pwd.h>
+ #include <grp.h>
  #include <sys/types.h>
  #include <sys/stat.h>
  #include <netinet/in.h>
***************
*** 110,120 ****
      /* now our own stuff ... */
  #include "mod_rewrite.h"
  
- #ifdef __EMX__
- /* OS/2 dosen't support links. */
- #define S_ISLNK
- #endif
- 
   
  
  
--- 114,119 ----
***************
*** 131,137 ****
  **
  **  our interface to the Apache server kernel
  **
! **  keep in mind:
  **
  **  o  Runtime logic of a request is as following:
  **
--- 130,136 ----
  **
  **  our interface to the Apache server kernel
  **
! **  keep in mind: 
  **
  **  o  Runtime logic of a request is as following:
  **
***************
*** 228,241 ****
  
      /* the txt mapfile parsing stuff */
  #define MAPFILE_PATTERN "^([^ ]+) +([^ ]+).*$"
- #ifdef HAS_APACHE_REGEX_LIB
  #define MAPFILE_OUTPUT "$1,$2"
  static regex_t   *lookup_map_txtfile_regexp = NULL;
  static regmatch_t lookup_map_txtfile_regmatch[10];
- #else
- #define MAPFILE_OUTPUT "\\1,\\2"
- static regexp *lookup_map_txtfile_regexp = NULL;
- #endif
  
  
  
--- 227,235 ----
***************
*** 356,362 ****
  **
  */
  
! static _const char *cmd_rewriteengine(cmd_parms *cmd, rewrite_perdir_conf *dconf, int flag)
  {
      rewrite_server_conf *sconf;
  
--- 350,356 ----
  **
  */
  
! static const char *cmd_rewriteengine(cmd_parms *cmd, rewrite_perdir_conf *dconf, int flag)
  {
      rewrite_server_conf *sconf;
  
***************
*** 369,378 ****
      return NULL;
  }
  
! static _const char *cmd_rewriteoptions(cmd_parms *cmd, rewrite_perdir_conf *dconf, char *option)
  {
      rewrite_server_conf *sconf;
!     _const char *err;
  
      sconf = (rewrite_server_conf *)get_module_config(cmd->server->module_config, &rewrite_module);
      if (cmd->path == NULL) /* is server command */
--- 363,372 ----
      return NULL;
  }
  
! static const char *cmd_rewriteoptions(cmd_parms *cmd, rewrite_perdir_conf *dconf, char *option)
  {
      rewrite_server_conf *sconf;
!     const char *err;
  
      sconf = (rewrite_server_conf *)get_module_config(cmd->server->module_config, &rewrite_module);
      if (cmd->path == NULL) /* is server command */
***************
*** 383,389 ****
      return err;
  }
  
! static _const char *cmd_rewriteoptions_setoption(pool *p, int *options, char *name)
  {
      if (strcasecmp(name, "inherit") == 0)
          *options |= OPTION_INHERIT;
--- 377,383 ----
      return err;
  }
  
! static const char *cmd_rewriteoptions_setoption(pool *p, int *options, char *name)
  {
      if (strcasecmp(name, "inherit") == 0)
          *options |= OPTION_INHERIT;
***************
*** 392,398 ****
      return NULL;
  }
  
! static _const char *cmd_rewritelog(cmd_parms *cmd, void *dconf, char *a1)
  {
      rewrite_server_conf *sconf;
  
--- 386,392 ----
      return NULL;
  }
  
! static const char *cmd_rewritelog(cmd_parms *cmd, void *dconf, char *a1)
  {
      rewrite_server_conf *sconf;
  
***************
*** 402,408 ****
      return NULL;
  }
  
! static _const char *cmd_rewriteloglevel(cmd_parms *cmd, void *dconf, char *a1)
  {
      rewrite_server_conf *sconf;
  
--- 396,402 ----
      return NULL;
  }
  
! static const char *cmd_rewriteloglevel(cmd_parms *cmd, void *dconf, char *a1)
  {
      rewrite_server_conf *sconf;
  
***************
*** 412,418 ****
      return NULL;
  }
  
! static _const char *cmd_rewritemap(cmd_parms *cmd, void *dconf, char *a1, char *a2)
  {
      rewrite_server_conf *sconf;
      rewritemap_entry *new;
--- 406,412 ----
      return NULL;
  }
  
! static const char *cmd_rewritemap(cmd_parms *cmd, void *dconf, char *a1, char *a2)
  {
      rewrite_server_conf *sconf;
      rewritemap_entry *new;
***************
*** 456,462 ****
      return NULL;
  }
  
! static _const char *cmd_rewritebase(cmd_parms *cmd, rewrite_perdir_conf *dconf, char *a1)
  {
      if (cmd->path == NULL || dconf == NULL)
          return "RewriteBase: only valid in per-directory config files";
--- 450,456 ----
      return NULL;
  }
  
! static const char *cmd_rewritebase(cmd_parms *cmd, rewrite_perdir_conf *dconf, char *a1)
  {
      if (cmd->path == NULL || dconf == NULL)
          return "RewriteBase: only valid in per-directory config files";
***************
*** 470,490 ****
      return NULL;
  }
  
! static _const char *cmd_rewritecond(cmd_parms *cmd, rewrite_perdir_conf *dconf, char *str)
  {
      rewrite_server_conf *sconf;
      rewritecond_entry *new;
- #ifdef HAS_APACHE_REGEX_LIB
      regex_t *regexp;
- #else
-     regexp *regexp;
-     int i;
- #endif
      char *a1;
      char *a2;
      char *a3;
      char *cp;
!     _const char *err;
      int rc;
  
      sconf = (rewrite_server_conf *)get_module_config(cmd->server->module_config, &rewrite_module);
--- 464,479 ----
      return NULL;
  }
  
! static const char *cmd_rewritecond(cmd_parms *cmd, rewrite_perdir_conf *dconf, char *str)
  {
      rewrite_server_conf *sconf;
      rewritecond_entry *new;
      regex_t *regexp;
      char *a1;
      char *a2;
      char *a3;
      char *cp;
!     const char *err;
      int rc;
  
      sconf = (rewrite_server_conf *)get_module_config(cmd->server->module_config, &rewrite_module);
***************
*** 522,539 ****
      /* now be careful: Under the POSIX regex library
         we can compile the pattern for case-insensitive matching,
         under the old V8 library we have to do it self via a hack */
- #ifdef HAS_APACHE_REGEX_LIB
      if (new->flags & CONDFLAG_NOCASE)
          rc = ((regexp = pregcomp(cmd->pool, cp, REG_EXTENDED|REG_ICASE)) == NULL);
      else
          rc = ((regexp = pregcomp(cmd->pool, cp, REG_EXTENDED)) == NULL);
- #else
-     if (new->flags & CONDFLAG_NOCASE) {
-         for (i = 0; cp[i] != '\0'; i++)
-             cp[i] = tolower(cp[i]);
-     }
-     rc = ((regexp = regcomp(cp)) == NULL);
- #endif
      if (rc)
          return pstrcat(cmd->pool, "RewriteCond: cannot compile regular expression '", a2, "'\n", NULL);
      new->pattern = pstrdup(cmd->pool, cp);
--- 511,520 ----
***************
*** 542,548 ****
      return NULL;
  }
  
! static _const char *cmd_rewritecond_parseflagfield(pool *p, rewritecond_entry *cfg, char *str)
  {
      char *cp;
      char *cp1;
--- 523,529 ----
      return NULL;
  }
  
! static const char *cmd_rewritecond_parseflagfield(pool *p, rewritecond_entry *cfg, char *str)
  {
      char *cp;
      char *cp1;
***************
*** 550,556 ****
      char *cp3;
      char *key;
      char *val;
!     _const char *err;
  
      if (str[0] != '[' || str[strlen(str)-1] != ']')
          return pstrdup(p, "RewriteCond: bad flag delimiters");
--- 531,537 ----
      char *cp3;
      char *key;
      char *val;
!     const char *err;
  
      if (str[0] != '[' || str[strlen(str)-1] != ']')
          return pstrdup(p, "RewriteCond: bad flag delimiters");
***************
*** 576,582 ****
              }
              else {
                  key = cp1;
!                 val = "yes";
              }
              if ((err = cmd_rewritecond_setflag(p, cfg, key, val)) != NULL)
                  return err;
--- 557,563 ----
              }
              else {
                  key = cp1;
!                 val = "";
              }
              if ((err = cmd_rewritecond_setflag(p, cfg, key, val)) != NULL)
                  return err;
***************
*** 588,594 ****
      return NULL;
  }
  
! static _const char *cmd_rewritecond_setflag(pool *p, rewritecond_entry *cfg, char *key, char *val)
  {
      if (   strcasecmp(key, "nocase") == 0
          || strcasecmp(key, "NC") == 0    ) {
--- 569,575 ----
      return NULL;
  }
  
! static const char *cmd_rewritecond_setflag(pool *p, rewritecond_entry *cfg, char *key, char *val)
  {
      if (   strcasecmp(key, "nocase") == 0
          || strcasecmp(key, "NC") == 0    ) {
***************
*** 605,625 ****
  }
  
  /* NON static */
! _const char *cmd_rewriterule(cmd_parms *cmd, rewrite_perdir_conf *dconf, char *str)
  {
      rewrite_server_conf *sconf;
      rewriterule_entry *new;
- #ifdef HAS_APACHE_REGEX_LIB
      regex_t *regexp;
- #else
-     regexp *regexp;
-     int i;
- #endif
      char *a1;
      char *a2;
      char *a3;
      char *cp;
!     _const char *err;
  
      sconf = (rewrite_server_conf *)get_module_config(cmd->server->module_config, &rewrite_module);
  
--- 586,601 ----
  }
  
  /* NON static */
! const char *cmd_rewriterule(cmd_parms *cmd, rewrite_perdir_conf *dconf, char *str)
  {
      rewrite_server_conf *sconf;
      rewriterule_entry *new;
      regex_t *regexp;
      char *a1;
      char *a2;
      char *a3;
      char *cp;
!     const char *err;
  
      sconf = (rewrite_server_conf *)get_module_config(cmd->server->module_config, &rewrite_module);
  
***************
*** 641,651 ****
          new->flags |= RULEFLAG_NOTMATCH;
          cp++;
      }
- #ifdef HAS_APACHE_REGEX_LIB
      if ((regexp = pregcomp(cmd->pool, cp, REG_EXTENDED)) == NULL)
- #else
-     if ((regexp = regcomp(cp)) == NULL)
- #endif
          return pstrcat(cmd->pool, "RewriteRule: cannot compile regular expression '", a1, "'\n", NULL);
      new->pattern = pstrdup(cmd->pool, cp);
      new->regexp  = regexp;
--- 617,623 ----
***************
*** 653,668 ****
      /*  arg2: the output string
          replace the $<N> by \<n> which is needed by the currently
          used Regular Expression library */
- #ifndef HAS_APACHE_REGEX_LIB
-     for (i = 0; a2[i] != '\0'; i++) {
-         if (a2[i] == '$' && a2[i+1] >= '1' && a2[i+1] <= '9') 
-             a2[i] = '\\';
-     }
- #endif
      new->output = pstrdup(cmd->pool, a2);
  
      /* arg3: optional flags field */
      new->forced_mimetype = NULL;
      new->skip = 0;
      if (a3 != NULL) {
          if ((err = cmd_rewriterule_parseflagfield(cmd->pool, new, a3)) != NULL)
--- 625,636 ----
      /*  arg2: the output string
          replace the $<N> by \<n> which is needed by the currently
          used Regular Expression library */
      new->output = pstrdup(cmd->pool, a2);
  
      /* arg3: optional flags field */
      new->forced_mimetype = NULL;
+     new->forced_responsecode = HTTP_MOVED_TEMPORARILY;
+     new->env[0] = NULL;
      new->skip = 0;
      if (a3 != NULL) {
          if ((err = cmd_rewriterule_parseflagfield(cmd->pool, new, a3)) != NULL)
***************
*** 684,690 ****
      return NULL;
  }
  
! static _const char *cmd_rewriterule_parseflagfield(pool *p, rewriterule_entry *cfg, char *str)
  {
      char *cp;
      char *cp1;
--- 652,658 ----
      return NULL;
  }
  
! static const char *cmd_rewriterule_parseflagfield(pool *p, rewriterule_entry *cfg, char *str)
  {
      char *cp;
      char *cp1;
***************
*** 692,698 ****
      char *cp3;
      char *key;
      char *val;
!     _const char *err;
  
      if (str[0] != '[' || str[strlen(str)-1] != ']')
          return pstrdup(p, "RewriteRule: bad flag delimiters");
--- 660,666 ----
      char *cp3;
      char *key;
      char *val;
!     const char *err;
  
      if (str[0] != '[' || str[strlen(str)-1] != ']')
          return pstrdup(p, "RewriteRule: bad flag delimiters");
***************
*** 718,724 ****
              }
              else {
                  key = cp1;
!                 val = "yes";
              }
              if ((err = cmd_rewriterule_setflag(p, cfg, key, val)) != NULL)
                  return err;
--- 686,692 ----
              }
              else {
                  key = cp1;
!                 val = "";
              }
              if ((err = cmd_rewriterule_setflag(p, cfg, key, val)) != NULL)
                  return err;
***************
*** 730,740 ****
      return NULL;
  }
  
! static _const char *cmd_rewriterule_setflag(pool *p, rewriterule_entry *cfg, char *key, char *val)
  {
      if (   strcasecmp(key, "redirect") == 0
          || strcasecmp(key, "R") == 0       ) {
          cfg->flags |= RULEFLAG_FORCEREDIRECT;
      }
      else if (   strcasecmp(key, "last") == 0
               || strcasecmp(key, "L") == 0   ) {
--- 698,724 ----
      return NULL;
  }
  
! static const char *cmd_rewriterule_setflag(pool *p, rewriterule_entry *cfg, char *key, char *val)
  {
+     int status = 0;
+     int i;
+ 
      if (   strcasecmp(key, "redirect") == 0
          || strcasecmp(key, "R") == 0       ) {
          cfg->flags |= RULEFLAG_FORCEREDIRECT;
+         if (strlen(val) > 0) {
+             if (strcasecmp(val, "permanent") == 0)
+                 status = HTTP_MOVED_PERMANENTLY;
+             else if (strcasecmp(val, "temp") == 0)
+                 status = HTTP_MOVED_TEMPORARILY;
+             else if (strcasecmp(val, "seeother") == 0)
+                 status = HTTP_SEE_OTHER;
+             else if (isdigit(*val))
+                 status = atoi(val);
+             if (!is_HTTP_REDIRECT(status))
+                 return pstrdup(p, "RewriteRule: invalid HTTP response code for flag 'R'");
+             cfg->forced_responsecode = status;
+         }
      }
      else if (   strcasecmp(key, "last") == 0
               || strcasecmp(key, "L") == 0   ) {
***************
*** 752,757 ****
--- 736,752 ----
               || strcasecmp(key, "T") == 0   ) {
          cfg->forced_mimetype = pstrdup(p, val);
      }
+     else if (   strcasecmp(key, "env") == 0
+              || strcasecmp(key, "E") == 0   ) {
+         for (i = 0; (cfg->env[i] != NULL) && (i < MAX_ENV_FLAGS); i++)
+             ;
+         if (i < MAX_ENV_FLAGS) {
+             cfg->env[i] = pstrdup(p, val);
+             cfg->env[i+1] = NULL;
+         }
+         else 
+             return pstrdup(p, "RewriteRule: to much environment flags 'E'");
+     }
      else if (   strcasecmp(key, "nosubreq") == 0
               || strcasecmp(key, "NS") == 0      ) {
          cfg->flags |= RULEFLAG_IGNOREONSUBREQ;
***************
*** 772,777 ****
--- 767,776 ----
               || strcasecmp(key, "F") == 0   ) {
          cfg->flags |= RULEFLAG_FORBIDDEN;
      }
+     else if (   strcasecmp(key, "gone") == 0
+              || strcasecmp(key, "G") == 0   ) {
+         cfg->flags |= RULEFLAG_GONE;
+     }
      else {
          return pstrcat(p, "RewriteRule: unknown flag '", key, "'\n", NULL);
      }
***************
*** 805,815 ****
  
      /* precompile a static pattern 
         for the txt mapfile parsing */
- #ifdef HAS_APACHE_REGEX_LIB
      lookup_map_txtfile_regexp = pregcomp(p, MAPFILE_PATTERN, REG_EXTENDED);
- #else
-     lookup_map_txtfile_regexp = regcomp(MAPFILE_PATTERN);
- #endif
  }
  
  
--- 804,810 ----
***************
*** 971,985 ****
              if (r->args != NULL)
                 r->filename = pstrcat(r->pool, r->filename, "?", r->args, NULL);
  
              table_set(r->headers_out, "Location", r->filename);
!             rewritelog(r, 1, "redirect to %s [REDIRECT]", r->filename);
!             return REDIRECT;
          }
          else if (strlen(r->filename) > 10 &&
                   strncmp(r->filename, "forbidden:", 10) == 0) {
              /* This URLs is forced to be forbidden for the requester */
              return FORBIDDEN; 
          }
          else if (strlen(r->filename) > 12 &&
                   strncmp(r->filename, "passthrough:", 12) == 0) {
              /* Hack because of underpowered API: passing the current
--- 966,994 ----
              if (r->args != NULL)
                 r->filename = pstrcat(r->pool, r->filename, "?", r->args, NULL);
  
+             /* determine HTTP redirect response code */
+             if (is_HTTP_REDIRECT(r->status)) {
+                 n = r->status; 
+                 r->status = HTTP_OK; /* make Apache kernel happy */
+             }
+             else
+                 n = REDIRECT;
+ 
+             /* now do the redirection */
              table_set(r->headers_out, "Location", r->filename);
!             rewritelog(r, 1, "redirect to %s [REDIRECT/%d]", r->filename, n);
!             return n;
          }
          else if (strlen(r->filename) > 10 &&
                   strncmp(r->filename, "forbidden:", 10) == 0) {
              /* This URLs is forced to be forbidden for the requester */
              return FORBIDDEN; 
          }
+         else if (strlen(r->filename) > 5 &&
+                  strncmp(r->filename, "gone:", 5) == 0) {
+             /* This URLs is forced to be gone */
+             return HTTP_GONE; 
+         }
          else if (strlen(r->filename) > 12 &&
                   strncmp(r->filename, "passthrough:", 12) == 0) {
              /* Hack because of underpowered API: passing the current
***************
*** 1009,1018 ****
  
                 NOTICE:
                 We cannot leave out the prefix_stat because
!                - when we allways prefix with document_root
                   then no absolute path can be created, e.g. via 
!                  remulating a ScriptAlias directive, etc.
!                - when we allways NOT prefix with document_root
                   then the files under document_root have to
                   be references directly and document_root
                   gets never used and will be a dummy parameter -
--- 1018,1027 ----
  
                 NOTICE:
                 We cannot leave out the prefix_stat because
!                - when we always prefix with document_root
                   then no absolute path can be created, e.g. via 
!                  emulating a ScriptAlias directive, etc.
!                - when we always NOT prefix with document_root
                   then the files under document_root have to
                   be references directly and document_root
                   gets never used and will be a dummy parameter -
***************
*** 1027,1033 ****
              if (n == 0) {
                  if ((cp = document_root(r)) != NULL) {
                      strncpy(docroot, cp, sizeof(docroot)-1);
! 		    docroot[sizeof(docroot)-1] = '\0';
  
                      /* allways NOT have a trailing slash */
                      l = strlen(docroot);
--- 1036,1042 ----
              if (n == 0) {
                  if ((cp = document_root(r)) != NULL) {
                      strncpy(docroot, cp, sizeof(docroot)-1);
!                     docroot[sizeof(docroot)-1] = '\0';
  
                      /* allways NOT have a trailing slash */
                      l = strlen(docroot);
***************
*** 1093,1098 ****
--- 1102,1108 ----
      char *cp2;
      char *prefix;
      int l;
+     int n;
  
      dconf = (rewrite_perdir_conf *)get_module_config(r->per_dir_config, &rewrite_module);
  
***************
*** 1200,1214 ****
              if (r->args != NULL)
                 r->filename = pstrcat(r->pool, r->filename, "?", r->args, NULL);
  
              table_set(r->headers_out, "Location", r->filename);
!             rewritelog(r, 1, "[per-dir %s] redirect to %s [REDIRECT]", dconf->directory, r->filename);
!             return REDIRECT;
          }
          else if (strlen(r->filename) > 10 &&
                   strncmp(r->filename, "forbidden:", 10) == 0) {
              /* This URLs is forced to be forbidden for the requester */
              return FORBIDDEN; 
          }
          else {
              /* it was finally rewritten to a local path */
  
--- 1210,1238 ----
              if (r->args != NULL)
                 r->filename = pstrcat(r->pool, r->filename, "?", r->args, NULL);
  
+             /* determine HTTP redirect response code */
+             if (is_HTTP_REDIRECT(r->status)) {
+                 n = r->status; 
+                 r->status = HTTP_OK; /* make Apache kernel happy */
+             }
+             else
+                 n = REDIRECT;
+ 
+             /* now do the redirection */
              table_set(r->headers_out, "Location", r->filename);
!             rewritelog(r, 1, "[per-dir %s] redirect to %s [REDIRECT/%d]", dconf->directory, r->filename, n);
!             return n;
          }
          else if (strlen(r->filename) > 10 &&
                   strncmp(r->filename, "forbidden:", 10) == 0) {
              /* This URLs is forced to be forbidden for the requester */
              return FORBIDDEN; 
          }
+         else if (strlen(r->filename) > 5 &&
+                  strncmp(r->filename, "gone:", 5) == 0) {
+             /* This URLs is forced to be gone */
+             return HTTP_GONE; 
+         }
          else {
              /* it was finally rewritten to a local path */
  
***************
*** 1342,1347 ****
--- 1366,1377 ----
                  changed = 1;
                  break;
              }
+             if (p->flags & RULEFLAG_GONE) {
+                 rewritelog(r, 2, "forcing '%s' to be gone", r->filename);
+                 r->filename = pstrcat(r->pool, "gone:", r->filename, NULL);
+                 changed = 1;
+                 break;
+             }
              if (p->flags & RULEFLAG_PROXY) 
                  break;
              if (p->flags & RULEFLAG_LASTRULE) 
***************
*** 1379,1391 ****
      char *output;
      int flags;
      char newuri[MAX_STRING_LEN];
      char port[32];
! #ifdef HAS_APACHE_REGEX_LIB
      regex_t *regexp;
      regmatch_t regmatch[10];
- #else
-     regexp *regexp;
- #endif
      int rc;
      int prefixstrip;
      int i;
--- 1409,1419 ----
      char *output;
      int flags;
      char newuri[MAX_STRING_LEN];
+     char env[MAX_STRING_LEN];
      char port[32];
!     char env2[MAX_STRING_LEN];
      regex_t *regexp;
      regmatch_t regmatch[10];
      int rc;
      int prefixstrip;
      int i;
***************
*** 1418,1428 ****
      if (perdir != NULL) 
          rewritelog(r, 3, "[per-dir %s] applying pattern '%s' to uri '%s'", perdir, p->pattern, uri);
  
- #ifdef HAS_APACHE_REGEX_LIB
      rc = (regexec(regexp, uri, regexp->re_nsub+1, regmatch, 0) == 0);   /* try to match the pattern */
- #else
-     rc = (regexec(regexp, uri) != 0);   /* try to match the pattern */
- #endif
      if (( rc && !(p->flags & RULEFLAG_NOTMATCH)) ||
          (!rc &&  (p->flags & RULEFLAG_NOTMATCH))   ) {     
  
--- 1446,1452 ----
***************
*** 1473,1490 ****
              if (p->flags & RULEFLAG_NOTMATCH) {
                  output = pstrcat(r->pool, "proxy:", output, NULL);
                  strncpy(newuri, output, sizeof(newuri)-1);
! 		newuri[sizeof(newuri)-1] = '\0';
                  expand_variables_inbuffer(r, newuri, sizeof(newuri));/* expand %{...} */
                  expand_map_lookups(r, newuri, sizeof(newuri));       /* expand ${...} */
              }
              else {
                  output = pstrcat(r->pool, "proxy:", output, NULL);
- #ifdef HAS_APACHE_REGEX_LIB
                  strncpy(newuri, pregsub(r->pool, output, uri, regexp->re_nsub+1, regmatch), sizeof(newuri)-1);    /* substitute in output */
! 		newuri[sizeof(newuri)-1] = '\0';
! #else
!                 regsub(regexp, output, newuri);                      /* substitute in output */
! #endif
                  expand_variables_inbuffer(r, newuri, sizeof(newuri));   /* expand %{...} */
                  expand_map_lookups(r, newuri, sizeof(newuri));          /* expand ${...} */
              }
--- 1497,1514 ----
              if (p->flags & RULEFLAG_NOTMATCH) {
                  output = pstrcat(r->pool, "proxy:", output, NULL);
                  strncpy(newuri, output, sizeof(newuri)-1);
!                 newuri[sizeof(newuri)-1] = '\0';
                  expand_variables_inbuffer(r, newuri, sizeof(newuri));/* expand %{...} */
                  expand_map_lookups(r, newuri, sizeof(newuri));       /* expand ${...} */
              }
              else {
                  output = pstrcat(r->pool, "proxy:", output, NULL);
                  strncpy(newuri, pregsub(r->pool, output, uri, regexp->re_nsub+1, regmatch), sizeof(newuri)-1);    /* substitute in output */
!                 for (i = 0; p->env[i] != NULL; i++) {
!                     strcpy(env2, p->env[i]);
!                     strcpy(env, pregsub(r->pool, env2, uri, regexp->re_nsub+1, regmatch));    /* substitute in output */
!                     add_env_variable(r, env);
!                 }
                  expand_variables_inbuffer(r, newuri, sizeof(newuri));   /* expand %{...} */
                  expand_map_lookups(r, newuri, sizeof(newuri));          /* expand ${...} */
              }
***************
*** 1507,1523 ****
  #endif
              if (p->flags & RULEFLAG_NOTMATCH) {
                  strncpy(newuri, output, sizeof(newuri)-1);
! 		newuri[sizeof(newuri)-1] = '\0';
                  expand_variables_inbuffer(r, newuri, sizeof(newuri));/* expand %{...} */
                  expand_map_lookups(r, newuri, sizeof(newuri));       /* expand ${...} */
              }
              else {
- #ifdef HAS_APACHE_REGEX_LIB
                  strncpy(newuri, pregsub(r->pool, output, uri, regexp->re_nsub+1, regmatch), sizeof(newuri)-1);    /* substitute in output */
! 		newuri[sizeof(newuri)-1] = '\0';
! #else
!                 regsub(regexp, output, newuri);                      /* substitute in output */
! #endif
                  expand_variables_inbuffer(r, newuri, sizeof(newuri));/* expand %{...} */
                  expand_map_lookups(r, newuri, sizeof(newuri));       /* expand ${...} */
              }
--- 1531,1548 ----
  #endif
              if (p->flags & RULEFLAG_NOTMATCH) {
                  strncpy(newuri, output, sizeof(newuri)-1);
!                 newuri[sizeof(newuri)-1] = '\0';
                  expand_variables_inbuffer(r, newuri, sizeof(newuri));/* expand %{...} */
                  expand_map_lookups(r, newuri, sizeof(newuri));       /* expand ${...} */
              }
              else {
                  strncpy(newuri, pregsub(r->pool, output, uri, regexp->re_nsub+1, regmatch), sizeof(newuri)-1);    /* substitute in output */
!                 newuri[sizeof(newuri)-1] = '\0';
!                 for (i = 0; p->env[i] != NULL; i++) {
!                     strcpy(env2, p->env[i]);
!                     strcpy(env, pregsub(r->pool, env2, uri, regexp->re_nsub+1, regmatch));    /* substitute in output */
!                     add_env_variable(r, env);
!                 }
                  expand_variables_inbuffer(r, newuri, sizeof(newuri));/* expand %{...} */
                  expand_map_lookups(r, newuri, sizeof(newuri));       /* expand ${...} */
              }
***************
*** 1538,1556 ****
          if (p->flags & RULEFLAG_NOTMATCH) {
              /* just overtake the URI */
              strncpy(newuri, output, sizeof(newuri)-1);
! 	    newuri[sizeof(newuri)-1] = '\0';
          }
          else {
              /* substitute in output */
- #ifdef HAS_APACHE_REGEX_LIB
              strncpy(newuri, pregsub(r->pool, output, uri, regexp->re_nsub+1, regmatch), sizeof(newuri)-1);    /* substitute in output */
! 	    newuri[sizeof(newuri)-1] = '\0'; 
! #else
!             regsub(regexp, output, newuri);                      /* substitute in output */
! #endif
          }
          expand_variables_inbuffer(r, newuri, sizeof(newuri));  /* expand %{...} */
!         expand_map_lookups(r, newuri, sizeof(newuri));   /* expand ${...} */
  
          if (perdir == NULL)
              rewritelog(r, 2, "rewrite %s -> %s", uri, newuri);
--- 1563,1582 ----
          if (p->flags & RULEFLAG_NOTMATCH) {
              /* just overtake the URI */
              strncpy(newuri, output, sizeof(newuri)-1);
!             newuri[sizeof(newuri)-1] = '\0';
          }
          else {
              /* substitute in output */
              strncpy(newuri, pregsub(r->pool, output, uri, regexp->re_nsub+1, regmatch), sizeof(newuri)-1);    /* substitute in output */
!             newuri[sizeof(newuri)-1] = '\0'; 
!             for (i = 0; p->env[i] != NULL; i++) {
!                 strcpy(env2, p->env[i]);
!                 strcpy(env, pregsub(r->pool, env2, uri, regexp->re_nsub+1, regmatch));    /* substitute in output */
!                 add_env_variable(r, env);
!             }
          }
          expand_variables_inbuffer(r, newuri, sizeof(newuri));  /* expand %{...} */
!         expand_map_lookups(r, newuri, sizeof(newuri));         /* expand ${...} */
  
          if (perdir == NULL)
              rewritelog(r, 2, "rewrite %s -> %s", uri, newuri);
***************
*** 1611,1616 ****
--- 1637,1643 ----
                  else
                      rewritelog(r, 2, "[per-dir %s] prepare forced redirect %s -> %s", perdir, r->filename, newuri);
                  r->filename = pstrdup(r->pool, newuri);
+                 r->status = p->forced_responsecode;
                  return 1;
              }
          }
***************
*** 1622,1634 ****
  
  static int apply_rewrite_cond(request_rec *r, rewritecond_entry *p, char *perdir)
  {
- #ifndef HAS_APACHE_REGEX_LIB
-     char inputbuf[LONG_STRING_LEN];
-     int i;
- #endif
      char *input;
      int rc;
      struct stat sb;
  
      /* first, we have to expand the input string to match */
      input = expand_variables(r, p->input);
--- 1649,1658 ----
  
  static int apply_rewrite_cond(request_rec *r, rewritecond_entry *p, char *perdir)
  {
      char *input;
      int rc;
      struct stat sb;
+     request_rec *rsub;
  
      /* first, we have to expand the input string to match */
      input = expand_variables(r, p->input);
***************
*** 1645,1675 ****
                  rc = 1;
      }
      else if (strcmp(p->pattern, "-l") == 0) {
          if (stat(input, &sb) == 0)
              if (S_ISLNK(sb.st_mode))
                  rc = 1;
      }
      else if (strcmp(p->pattern, "-d") == 0) {
          if (stat(input, &sb) == 0)
              if (S_ISDIR(sb.st_mode))
                  rc = 1;
      }
      else {
          /* it is really a regexp pattern, so apply it */
- #ifdef HAS_APACHE_REGEX_LIB
          rc = (regexec(p->regexp, input, 0, NULL, 0) == 0);
- #else
-         if (p->flags & CONDFLAG_NOCASE) {
-             for (i = 0; input[i] != '\0' && i < sizeof(inputbuf)-1 ; i++)
-                 inputbuf[i] = tolower(input[i]);
-             inputbuf[i] = '\0';
-         }
-         else {
-             strncpy(inputbuf, input, sizeof(inputbuf)-1);
- 	    inputbuf[sizeof(inputbuf)-1] = '\0';
-         }
-         rc = (regexec(p->regexp, inputbuf) != 0);
- #endif
      }
  
      /* if this is a non-matching regexp, just negate the result */ 
--- 1669,1738 ----
                  rc = 1;
      }
      else if (strcmp(p->pattern, "-l") == 0) {
+ #ifndef __EMX__
+ /* OS/2 dosen't support links. */
          if (stat(input, &sb) == 0)
              if (S_ISLNK(sb.st_mode))
                  rc = 1;
+ #endif
      }
      else if (strcmp(p->pattern, "-d") == 0) {
          if (stat(input, &sb) == 0)
              if (S_ISDIR(sb.st_mode))
                  rc = 1;
      }
+     else if (strcmp(p->pattern, "-U") == 0) {
+         /* avoid infinite subrequest recursion */
+         if (strlen(input) > 0               /* nonempty path, and */
+             && (   r->main == NULL          /* - either not in a subrequest */
+                 || (   r->main->uri != NULL /* - or in a subrequest...*/
+                     && r->uri != NULL       /*   ...and then URIs aren't NULL... */
+                                             /*   ...and sub and main URIs differ */
+                     && strcmp(r->main->uri, r->uri) != 0) ) ) {
+ 
+             /* run a URI-based subrequest */
+             rsub = sub_req_lookup_uri(input, r);
+ 
+             /* URI exists for any result up to 3xx, redirects allowed */
+             if (rsub->status < 400)
+                 rc = 1;
+ 
+             /* log it */
+             rewritelog(r, 5, "RewriteCond URI (-U) check: path=%s -> status=%d", input, rsub->status);
+ 
+             /* cleanup by destroying the subrequest */
+             destroy_sub_req(rsub);
+         }
+     }
+     else if (strcmp(p->pattern, "-F") == 0) {
+         /* avoid infinite subrequest recursion */
+         if (strlen(input) > 0               /* nonempty path, and */
+             && (   r->main == NULL          /* - either not in a subrequest */
+                 || (   r->main->uri != NULL /* - or in a subrequest...*/
+                     && r->uri != NULL       /*   ...and then URIs aren't NULL... */
+                                             /*   ...and sub and main URIs differ */
+                     && strcmp(r->main->uri, r->uri) != 0) ) ) {
+ 
+             /* process a file-based subrequest: 
+                this differs from -U in that no path translation is done. */
+             rsub = sub_req_lookup_file(input, r);
+  
+             /* file exists for any result up to 2xx, no redirects */
+             if (rsub->status < 300 &&
+                 /* double-check that file exists since default result is 200 */
+                 stat(rsub->filename, &sb) == 0)
+                 rc = 1;
+ 
+             /* log it */
+             rewritelog(r, 5, "RewriteCond file (-F) check: path=%s -> file=%s status=%d", input, rsub->filename, rsub->status);
+ 
+             /* cleanup by destroying the subrequest */
+             destroy_sub_req(rsub);
+         }
+     }
      else {
          /* it is really a regexp pattern, so apply it */
          rc = (regexec(p->regexp, input, 0, NULL, 0) == 0);
      }
  
      /* if this is a non-matching regexp, just negate the result */ 
***************
*** 1755,1761 ****
  #else
          strncpy(buf, r->filename+7, sizeof(buf)-1);
  #endif
! 	buf[sizeof(buf)-1] = '\0';
          hostp = buf;
          for (cp = hostp; *cp != '\0' && *cp != '/' && *cp != ':'; cp++)
              ;
--- 1818,1824 ----
  #else
          strncpy(buf, r->filename+7, sizeof(buf)-1);
  #endif
!         buf[sizeof(buf)-1] = '\0';
          hostp = buf;
          for (cp = hostp; *cp != '\0' && *cp != '/' && *cp != ':'; cp++)
              ;
***************
*** 1763,1769 ****
              /* set host */
              *cp++ = '\0';
              strncpy(host, hostp, sizeof(host)-1);
! 	    host[sizeof(host)-1] = '\0';
              /* set port */
              portp = cp;
              for (; *cp != '\0' && *cp != '/'; cp++)
--- 1826,1832 ----
              /* set host */
              *cp++ = '\0';
              strncpy(host, hostp, sizeof(host)-1);
!             host[sizeof(host)-1] = '\0';
              /* set port */
              portp = cp;
              for (; *cp != '\0' && *cp != '/'; cp++)
***************
*** 1779,1785 ****
              /* set host */
              *cp = '\0';
              strncpy(host, hostp, sizeof(host)-1);
! 	    host[sizeof(host)-1] = '\0';
              *cp = '/';
              /* set port */
              port = 80;
--- 1842,1848 ----
              /* set host */
              *cp = '\0';
              strncpy(host, hostp, sizeof(host)-1);
!             host[sizeof(host)-1] = '\0';
              *cp = '/';
              /* set port */
              port = 80;
***************
*** 1789,1795 ****
          else {
              /* set host */
              strncpy(host, hostp, sizeof(host)-1);
! 	    host[sizeof(host)-1] = '\0';
              /* set port */
              port = 80;
              /* set remaining url */
--- 1852,1858 ----
          else {
              /* set host */
              strncpy(host, hostp, sizeof(host)-1);
!             host[sizeof(host)-1] = '\0';
              /* set port */
              port = 80;
              /* set remaining url */
***************
*** 1858,1864 ****
  **
  */
  
! #define limit_length(n)	(n > LONG_STRING_LEN-1 ? LONG_STRING_LEN-1 : n)
  static void expand_map_lookups(request_rec *r, char *uri, int uri_len)
  {
      char newuri[MAX_STRING_LEN];
--- 1921,1928 ----
  **
  */
  
! #define limit_length(n) (n > LONG_STRING_LEN-1 ? LONG_STRING_LEN-1 : n)
! 
  static void expand_map_lookups(request_rec *r, char *uri, int uri_len)
  {
      char newuri[MAX_STRING_LEN];
***************
*** 1918,1936 ****
              cpT = lookup_map(r, mapname, mapkey);
              if (cpT != NULL) {
                  n = strlen(cpT);
! 		if (cpO + n >= newuri + sizeof(newuri)) {
! 		    log_printf(r->server, "insufficient space in expand_map_lookups, aborting");
! 		    return;
! 		}
                  memcpy(cpO, cpT, n);
                  cpO += n;
              }
              else {
                  n = strlen(defaultvalue);
! 		if (cpO + n >= newuri + sizeof(newuri)) {
! 		    log_printf(r->server, "insufficient space in expand_map_lookups, aborting");
! 		    return;
! 		}
                  memcpy(cpO, defaultvalue, n);
                  cpO += n;
              }
--- 1982,2000 ----
              cpT = lookup_map(r, mapname, mapkey);
              if (cpT != NULL) {
                  n = strlen(cpT);
!                 if (cpO + n >= newuri + sizeof(newuri)) {
!                     log_printf(r->server, "insufficient space in expand_map_lookups, aborting");
!                     return;
!                 }
                  memcpy(cpO, cpT, n);
                  cpO += n;
              }
              else {
                  n = strlen(defaultvalue);
!                 if (cpO + n >= newuri + sizeof(newuri)) {
!                     log_printf(r->server, "insufficient space in expand_map_lookups, aborting");
!                     return;
!                 }
                  memcpy(cpO, defaultvalue, n);
                  cpO += n;
              }
***************
*** 1940,1949 ****
              if (cpT == NULL)
                  cpT = cpI+strlen(cpI);
              n = cpT-cpI;
! 	    if (cpO + n >= newuri + sizeof(newuri)) {
! 		log_printf(r->server, "insufficient space in expand_map_lookups, aborting");
! 		return;
! 	    }
              memcpy(cpO, cpI, n);
              cpO += n;
              cpI += n;
--- 2004,2013 ----
              if (cpT == NULL)
                  cpT = cpI+strlen(cpI);
              n = cpT-cpI;
!             if (cpO + n >= newuri + sizeof(newuri)) {
!                 log_printf(r->server, "insufficient space in expand_map_lookups, aborting");
!                 return;
!             }
              memcpy(cpO, cpI, n);
              cpO += n;
              cpI += n;
***************
*** 1954,1961 ****
      uri[uri_len-1] = '\0';
      return;
  }
- #undef limit_length
  
  
  
  
--- 2018,2025 ----
      uri[uri_len-1] = '\0';
      return;
  }
  
+ #undef limit_length
  
  
  
***************
*** 2061,2082 ****
      if ((fp = pfopen(r->pool, file, "r")) == NULL)
          return NULL;
  
!     strncpy(output,  MAPFILE_OUTPUT, sizeof(output)-1);
      output[sizeof(output)-1] = '\0';
      while (fgets(line, sizeof(line), fp) != NULL) {
          if (line[strlen(line)-1] == '\n')
              line[strlen(line)-1] = '\0';
- #ifdef HAS_APACHE_REGEX_LIB
          if (regexec(lookup_map_txtfile_regexp, line, lookup_map_txtfile_regexp->re_nsub+1, lookup_map_txtfile_regmatch, 0) == 0) {
- #else
-         if (regexec(lookup_map_txtfile_regexp, line) != 0) {
- #endif
- #ifdef HAS_APACHE_REGEX_LIB
              strncpy(result, pregsub(r->pool, output, line, lookup_map_txtfile_regexp->re_nsub+1, lookup_map_txtfile_regmatch), sizeof(result)-1); /* substitute in output */
! 	    result[sizeof(result)-1] = '\0';
! #else
!             regsub(lookup_map_txtfile_regexp, output, result);
! #endif
              cpT = strchr(result, ',');
              *cpT = '\0';
              curkey = result;
--- 2125,2138 ----
      if ((fp = pfopen(r->pool, file, "r")) == NULL)
          return NULL;
  
!     strncpy(output, MAPFILE_OUTPUT, sizeof(output)-1);
      output[sizeof(output)-1] = '\0';
      while (fgets(line, sizeof(line), fp) != NULL) {
          if (line[strlen(line)-1] == '\n')
              line[strlen(line)-1] = '\0';
          if (regexec(lookup_map_txtfile_regexp, line, lookup_map_txtfile_regexp->re_nsub+1, lookup_map_txtfile_regmatch, 0) == 0) {
              strncpy(result, pregsub(r->pool, output, line, lookup_map_txtfile_regexp->re_nsub+1, lookup_map_txtfile_regmatch), sizeof(result)-1); /* substitute in output */
!             result[sizeof(result)-1] = '\0';
              cpT = strchr(result, ',');
              *cpT = '\0';
              curkey = result;
***************
*** 2102,2108 ****
      char buf[MAX_STRING_LEN];
  
      dbmkey.dptr  = key;
!     dbmkey.dsize = strlen(key) < sizeof(buf) - 1 : strlen(key) ? sizeof(buf)-1;
      if ((dbmfp = dbm_open(file, O_RDONLY, 0666)) != NULL) {
          dbmval = dbm_fetch(dbmfp, dbmkey);
          if (dbmval.dptr != NULL) {
--- 2158,2164 ----
      char buf[MAX_STRING_LEN];
  
      dbmkey.dptr  = key;
!     dbmkey.dsize = (strlen(key) < sizeof(buf) - 1 : strlen(key) ? sizeof(buf)-1);
      if ((dbmfp = dbm_open(file, O_RDONLY, 0666)) != NULL) {
          dbmval = dbm_fetch(dbmfp, dbmkey);
          if (dbmval.dptr != NULL) {
***************
*** 2122,2127 ****
--- 2178,2186 ----
      char c;
      int i;
  
+     /* lock the channel */
+     fd_lock(fpin);
+ 
      /* write out the request key */
      write(fpin, key, strlen(key));
      write(fpin, "\n", 1);
***************
*** 2135,2140 ****
--- 2194,2202 ----
      }
      buf[i] = '\0';
  
+     /* unlock the channel */
+     fd_unlock(fpin);
+ 
      if (strcasecmp(buf, "NULL") == 0)
          return NULL;
      else
***************
*** 2197,2203 ****
      cleanup_for_exec();
      signal(SIGHUP, SIG_IGN);
  #ifdef __EMX__
!     /* For OS/2 we need to use a '/' */
      execl(SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL);
  #else
      execl(SHELL_PATH, SHELL_PATH, "-c", (char *)cmd, NULL);
--- 2259,2265 ----
      cleanup_for_exec();
      signal(SIGHUP, SIG_IGN);
  #ifdef __EMX__
!     /* OS/2 needs a '/' */
      execl(SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL);
  #else
      execl(SHELL_PATH, SHELL_PATH, "-c", (char *)cmd, NULL);
***************
*** 2214,2223 ****
      static char str3[HUGE_STRING_LEN];
      static char type[20];
      static char redir[20];
-     char *ruser;
      va_list ap;
      int i;
      request_rec *req;
      
      va_start(ap, text);
      conf = get_module_config(r->server->module_config, &rewrite_module);
--- 2276,2285 ----
      static char str3[HUGE_STRING_LEN];
      static char type[20];
      static char redir[20];
      va_list ap;
      int i;
      request_rec *req;
+     char *ruser;
      
      va_start(ap, text);
      conf = get_module_config(r->server->module_config, &rewrite_module);
***************
*** 2235,2270 ****
  
      if (connect->user == NULL) {
          ruser = "-";
!     } else if (strlen (connect->user) != 0) {
          ruser = connect->user;
!     } else {
          ruser = "\"\"";
!     };
  
      str1 = pstrcat(r->pool, get_remote_host(connect, r->server->module_config, REMOTE_NAME), " ",
                              (connect->remote_logname != NULL ? connect->remote_logname : "-"), " ",
!                             ruser,
!                             NULL);
      ap_vsnprintf(str2, sizeof(str2), text, ap);
  
!     if (r->main == NULL) {
!         strncpy(type, "initial", sizeof(type)-1);
! 	type[sizeof(type)-1] = '\0';
!     } else {
!         strncpy(type, "subreq", sizeof(type)-1);
! 	type[sizeof(type)-1] = '\0';
!     }
  
      for (i = 0, req = r->prev; req != NULL; req = req->prev) 
          ;
      if (i == 0)
!         strcpy(redir, "");
      else
          ap_snprintf(redir, sizeof(redir), "/redir#%d", i);
  
      ap_snprintf(str3, sizeof(str3), "%s %s [%s/sid#%x][rid#%x/%s%s] (%d) %s\n", str1, current_logtime(r), r->server->server_hostname, (unsigned int)(r->server), (unsigned int)r, type, redir, level, str2);
  
      write(conf->rewritelogfp, str3, strlen(str3));
  
      va_end(ap);
      return;
--- 2297,2332 ----
  
      if (connect->user == NULL) {
          ruser = "-";
!     }
!     else if (strlen (connect->user) != 0) {
          ruser = connect->user;
!     }
!     else {
          ruser = "\"\"";
!     }
  
      str1 = pstrcat(r->pool, get_remote_host(connect, r->server->module_config, REMOTE_NAME), " ",
                              (connect->remote_logname != NULL ? connect->remote_logname : "-"), " ",
!                             ruser, NULL);
      ap_vsnprintf(str2, sizeof(str2), text, ap);
  
!     if (r->main == NULL)
!         strcpy(type, "initial");
!     else
!         strcpy(type, "subreq");
  
      for (i = 0, req = r->prev; req != NULL; req = req->prev) 
          ;
      if (i == 0)
!         redir[0] = '\0';
      else
          ap_snprintf(redir, sizeof(redir), "/redir#%d", i);
  
      ap_snprintf(str3, sizeof(str3), "%s %s [%s/sid#%x][rid#%x/%s%s] (%d) %s\n", str1, current_logtime(r), r->server->server_hostname, (unsigned int)(r->server), (unsigned int)r, type, redir, level, str2);
  
+     fd_lock(conf->rewritelogfp);
      write(conf->rewritelogfp, str3, strlen(str3));
+     fd_unlock(conf->rewritelogfp);
  
      va_end(ap);
      return;
***************
*** 2272,2282 ****
  
  static char *current_logtime(request_rec *r)
  {
- #ifdef IS_APACHE_12
      int timz;
- #else
-     long timz;
- #endif
      struct tm *t;
      char tstr[80];
      char sign;
--- 2334,2340 ----
***************
*** 2286,2299 ****
      if(timz < 0) 
          timz = -timz;
  
!     strftime(tstr, 80,"[%d/%b/%Y:%H:%M:%S ",t);
! 
! #ifdef IS_APACHE_12
      ap_snprintf(tstr + strlen(tstr), 80-strlen(tstr), "%c%.2d%.2d]", sign, timz/60, timz%60);
- #else
-     ap_snprintf(tstr + strlen(tstr), 80-strlen(tstr), "%c%02ld%02ld]", sign, timz/3600, timz%3600);
- #endif
- 
      return pstrdup(r->pool, tstr);
  }
  
--- 2344,2351 ----
      if(timz < 0) 
          timz = -timz;
  
!     strftime(tstr, 80, "[%d/%b/%Y:%H:%M:%S ", t);
      ap_snprintf(tstr + strlen(tstr), 80-strlen(tstr), "%c%.2d%.2d]", sign, timz/60, timz%60);
      return pstrdup(r->pool, tstr);
  }
  
***************
*** 2353,2363 ****
      cleanup_for_exec();
      signal(SIGHUP, SIG_IGN);
  #ifdef __EMX__
!     /* For OS/2 we need to use a '/' */
      execl(SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL);
  #else
      execl(SHELL_PATH, SHELL_PATH, "-c", (char *)cmd, NULL);
! #endif    
      exit(1);
  }
  
--- 2405,2415 ----
      cleanup_for_exec();
      signal(SIGHUP, SIG_IGN);
  #ifdef __EMX__
!     /* OS/2 needs a '/' */
      execl(SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL);
  #else
      execl(SHELL_PATH, SHELL_PATH, "-c", (char *)cmd, NULL);
! #endif
      exit(1);
  }
  
***************
*** 2379,2385 ****
      newbuf = expand_variables(r, buf);
      if (strcmp(newbuf, buf) != 0) {
          strncpy(buf, newbuf, buf_len-1);
! 	buf[buf_len-1] = '\0';
      }
      return;
  }
--- 2431,2437 ----
      newbuf = expand_variables(r, buf);
      if (strcmp(newbuf, buf) != 0) {
          strncpy(buf, newbuf, buf_len-1);
!         buf[buf_len-1] = '\0';
      }
      return;
  }
***************
*** 2402,2407 ****
--- 2454,2460 ----
              if ((cp3 = strstr(cp2, "}")) != NULL) {
                  *cp2 = '\0';
                  strncpy(&output[strlen(output)], cp, sizeof(output)-strlen(output)-1);
+ 
                  cp2 += 2;
                  *cp3 = '\0';
                  strncpy(&output[strlen(output)], lookup_variable(r, cp2), sizeof(output)-strlen(output)-1);
***************
*** 2412,2418 ****
              }
          }
          strncpy(&output[strlen(output)], cp, sizeof(output)-strlen(output)-1);
! 	output[sizeof(output)-1] = '\0';
          break;
      }
      return expanded ? pstrdup(r->pool, output) : str;
--- 2465,2471 ----
              }
          }
          strncpy(&output[strlen(output)], cp, sizeof(output)-strlen(output)-1);
!         output[sizeof(output)-1] = '\0';
          break;
      }
      return expanded ? pstrdup(r->pool, output) : str;
***************
*** 2424,2429 ****
--- 2477,2486 ----
      char resultbuf[LONG_STRING_LEN];
      time_t tc;
      struct tm *tm;
+     request_rec *rsub;
+     struct passwd *pw;
+     struct group *gr;
+     struct stat finfo;
  
      result = NULL;
  
***************
*** 2491,2496 ****
--- 2548,2556 ----
      else if (strcasecmp(var, "AUTH_TYPE") == 0) {
          result = r->connection->auth_type;
      }
+     else if (strcasecmp(var, "IS_SUBREQ") == 0) { /* non-standard */
+         result = (r->main != NULL ? "true" : "false");
+     }
  
      /* internal server stuff */
      else if (strcasecmp(var, "DOCUMENT_ROOT") == 0) {
***************
*** 2550,2559 ****
  
      /* all other env-variables from the parent Apache process */
      else if (strlen(var) > 4 && strncasecmp(var, "ENV:", 4) == 0) {
!         result = getenv(var+4);
      }
- 
-     /* uptime, load average, etc. .. */
  
      if (result == NULL)
          return pstrdup(r->pool, "");
--- 2610,2689 ----
  
      /* all other env-variables from the parent Apache process */
      else if (strlen(var) > 4 && strncasecmp(var, "ENV:", 4) == 0) {
!         /* first try the internal Apache notes structure */
!         result = table_get(r->notes, var+4);
!         /* second try the internal Apache env structure  */
!         if (result == NULL) 
!             result = table_get(r->subprocess_env, var+4);
!         /* third try the external OS env */
!         if (result == NULL) 
!             result = getenv(var+4);
!     }
! 
! #define LOOKAHEAD(subrecfunc) \
!         if ( \
!           /* filename is safe to use */ \
!           r->filename != NULL \
!               /* - and we're either not in a subrequest */ \
!               && ( r->main == NULL \
!                   /* - or in a subrequest where paths are non-NULL... */ \
!                     || ( r->main->uri != NULL && r->uri != NULL \
!                         /*   ...and sub and main paths differ */ \
!                         && strcmp(r->main->uri, r->uri) != 0))) { \
!             /* process a file-based subrequest */ \
!             rsub = subrecfunc(r->filename, r); \
!             /* now recursively lookup the variable in the sub_req */ \
!             result = lookup_variable(rsub, var+5); \
!             /* copy it up to our scope before we destroy the sub_req's pool */ \
!             result = pstrdup(r->pool, result); \
!             /* cleanup by destroying the subrequest */ \
!             destroy_sub_req(rsub); \
!             /* log it */ \
!             rewritelog(r, 5, "lookahead: path=%s var=%s -> val=%s", r->filename, var+5, result); \
!             /* return ourself to prevent re-pstrdup */ \
!             return result; \
!         }
! 
!     /* look-ahead for parameter through URI-based sub-request */
!     else if (strlen(var) > 5 && strncasecmp(var, "LA-U:", 5) == 0) {
!         LOOKAHEAD(sub_req_lookup_uri)
!     }
!     /* look-ahead for parameter through file-based sub-request */
!     else if (strlen(var) > 5 && strncasecmp(var, "LA-F:", 5) == 0) {
!         LOOKAHEAD(sub_req_lookup_file)
!     }
! 
!     /* file stuff */
!     else if (strcasecmp(var, "SCRIPT_USER") == 0) {
!         result = pstrdup(r->pool, "<unknown>");
!         if (r->finfo.st_mode != 0) {
!             if ((pw = getpwuid(r->finfo.st_uid)) != NULL) { 
!                 result = pstrdup(r->pool, pw->pw_name);
!             }
!         }
!         else {
!             if (stat(r->filename, &finfo) == 0) {
!                 if ((pw = getpwuid(finfo.st_uid)) != NULL) { 
!                     result = pstrdup(r->pool, pw->pw_name);
!                 }
!             }
!         }
!     }
!     else if (strcasecmp(var, "SCRIPT_GROUP") == 0) {
!         result = pstrdup(r->pool, "<unknown>");
!         if (r->finfo.st_mode != 0) {
!             if ((gr = getgrgid(r->finfo.st_gid)) != NULL) { 
!                 result = pstrdup(r->pool, gr->gr_name);
!             }
!         }
!         else {
!             if (stat(r->filename, &finfo) == 0) {
!                 if ((gr = getgrgid(finfo.st_gid)) != NULL) { 
!                     result = pstrdup(r->pool, gr->gr_name);
!                 }
!             }
!         }
      }
  
      if (result == NULL)
          return pstrdup(r->pool, "");
***************
*** 2721,2727 ****
      /* first, remove the local directory prefix */
      strncpy(matchbuf, match, sizeof(matchbuf)-1);
      matchbuf[sizeof(matchbuf)-1] = '\0';
- 
      /* allways have a trailing slash */
      l = strlen(matchbuf);
      if (matchbuf[l-1] != '/') {
--- 2851,2856 ----
***************
*** 2735,2741 ****
  
          /* and now add the base-URL as replacement prefix */
          strncpy(substbuf, subst, sizeof(substbuf)-1);
! 	substbuf[sizeof(substbuf)-1] = '\0';
          /* allways have a trailing slash */
          l = strlen(substbuf);
          if (substbuf[l-1] != '/') {
--- 2864,2870 ----
  
          /* and now add the base-URL as replacement prefix */
          strncpy(substbuf, subst, sizeof(substbuf)-1);
!         substbuf[sizeof(substbuf)-1] = '\0';
          /* allways have a trailing slash */
          l = strlen(substbuf);
          if (substbuf[l-1] != '/') {
***************
*** 2833,2838 ****
--- 2962,2984 ----
  }
  
  
+ void add_env_variable(request_rec *r, char *s)
+ {
+     char var[MAX_STRING_LEN];
+     char val[MAX_STRING_LEN];
+     char *cp;
+ 
+     if ((cp = strchr(s, ':')) != NULL) {
+         memcpy(var, s, cp-s);
+         var[cp-s] = '\0';
+         strcpy(val, cp+1);
+         table_set(r->subprocess_env, pstrdup(r->pool, var), pstrdup(r->pool, val));
+         rewritelog(r, 5, "setting env variable '%s' to '%s'", var, val);
+     }
+ }
+ 
+ 
+ 
  /*
  **
  **  stat() for only the prefix of a path
***************
*** 2869,2875 ****
      char **cppHNLtest;
      char *ourhostname;
      char *ourhostip;
!     _const char *names;
      char *name;
      int i, j;
  
--- 3015,3021 ----
      char **cppHNLtest;
      char *ourhostname;
      char *ourhostip;
!     const char *names;
      char *name;
      int i, j;
  
***************
*** 2992,2998 ****
  **
  */
  
- #ifdef IS_APACHE_12
  int is_proxy_available(server_rec *s)
  {
      extern module *preloaded_modules[];
--- 3138,3143 ----
***************
*** 3008,3027 ****
      }
      return 0;
  }
! #else
! int is_proxy_available(server_rec *s)
  {
!     extern char *module_names[];
!     int n;
!     
!     for (n = 0; module_names[n] != NULL; n++) {
!         if (strcmp(module_names[n], "proxy_module") == 0) {
!             return 1;
!         }
      }
!     return 0;
  }
  #endif
  
  
  /*EOF*/
--- 3153,3209 ----
      }
      return 0;
  }
! 
! 
! /*
! **
! **  File locking
! **
! */
! 
! #ifdef USE_FCNTL
! static struct flock   lock_it = { F_WRLCK, 0, 0, 0 };
! static struct flock unlock_it = { F_UNLCK, 0, 0, 0 };
! #endif 
! 
! static void fd_lock(int fd)
  {
!     int rc;
! 
! #ifdef USE_FCNTL
!     while (   ((rc = fcntl(fd, F_SETLKW, &lock_it)) < 0) 
!            && (errno == EINTR)                               )
!         continue;
! #endif
! #ifdef USE_FLOCK
!     while (   ((rc = flock(fd, LOCK_EX)) < 0) 
!            && (errno == EINTR)               )
!         continue;
! #endif
! 
!     if (rc < 0) {
!         fprintf(stderr, "Error getting lock. Exiting!");
!         exit(1);
      }
!     return;
  }
+ 
+ static void fd_unlock(int fd)
+ {
+     int rc;
+ 
+ #ifdef USE_FCNTL 
+     rc = fcntl(fd, F_SETLKW, &unlock_it);
  #endif
+ #ifdef USE_FLOCK 
+     rc = flock(fd, LOCK_UN);
+ #endif 
+ 
+     if (rc < 0) {
+         fprintf(stderr, "Error freeing lock. Exiting!");
+         exit(1);
+     }
+ }
  
  
  /*EOF*/
*** SNAP/src/mod_rewrite.h	Mon Jan 20 09:00:17 1997
--- src/mod_rewrite.h	Fri Jan 31 21:39:52 1997
***************
*** 1,3 ****
--- 1,4 ----
+ 
  /* ====================================================================
   * Copyright (c) 1996,1997 The Apache Group.  All rights reserved.
   *
***************
*** 63,69 ****
  **  |_| |_| |_|\___/ \__,_|___|_|  \___| \_/\_/ |_|  |_|\__\___|
  **                       |_____|
  **
! **  URL Rewriting Module, Version 2.3.10 (20-12-1996)
  **
  **  This module uses a rule-based rewriting engine (based on a
  **  regular-expression parser) to rewrite requested URLs on the fly. 
--- 64,70 ----
  **  |_| |_| |_|\___/ \__,_|___|_|  \___| \_/\_/ |_|  |_|\__\___|
  **                       |_____|
  **
! **  URL Rewriting Module, Version 3.0.0 (xx-02-1997)
  **
  **  This module uses a rule-based rewriting engine (based on a
  **  regular-expression parser) to rewrite requested URLs on the fly. 
***************
*** 83,126 ****
  **  The documentation and latest release can be found on
  **  http://www.engelschall.com/sw/mod_rewrite/
  **
! **  Copyright (c) 1996 Ralf S. Engelschall, All rights reserved.
  **
  **  Written for The Apache Group by
  **      Ralf S. Engelschall
  **      rse@engelschall.com
! **      http://www.engelschall.com/
  */
  
  
  
  
-     /* Check Apache Release */
- #if (MODULE_MAGIC_NUMBER >= 19960725)
- #define IS_APACHE_12         1
- #define HAS_APACHE_REGEX_LIB 1
- #endif
- 
- 
-     /* The const problem:
-        The Apache Group changed some essential prototypes
-        to have an additional "const" qualifier. To be backward
-        compatible with Apache 1.1.1 we use a special define */
- #ifdef IS_APACHE_12
- #define _const const
- #else
- #define _const  
- #endif
- 
- 
-     /* The RegExp support:
-        For Apache 1.1.1 we provide our own Spencer V8 library,
-        for Apache 1.2 and higher there is a Spencer POSIX library
-        in the distribution */
- #ifndef HAS_APACHE_REGEX_LIB
- #include "regexp/regexp.h"
- #endif
- 
- 
      /* The NDBM support:
         We support only NDBM files. 
         But we have to stat the file for the mtime,
--- 84,100 ----
  **  The documentation and latest release can be found on
  **  http://www.engelschall.com/sw/mod_rewrite/
  **
! **  Copyright (c) 1996-1997 Ralf S. Engelschall, All rights reserved.
  **
  **  Written for The Apache Group by
  **      Ralf S. Engelschall
  **      rse@engelschall.com
! **      www.engelschall.com
  */
  
  
  
  
      /* The NDBM support:
         We support only NDBM files. 
         But we have to stat the file for the mtime,
***************
*** 135,140 ****
--- 109,138 ----
  #endif
  
  
+     /* The locking support:
+        Try to determine whether we should use
+        fcntl() or flock(). */
+ #if defined(USE_FCNTL_SERIALIZED_ACCEPT)
+ #define USE_FCNTL 1
+ #include <fcntl.h>
+ #endif
+ #if defined(USE_FLOCK_SERIALIZED_ACCEPT)
+ #define USE_FLOCK 1
+ #include <sys/file.h>
+ #endif
+ #if !defined(USE_FCNTL) && !defined(USE_FLOCK)
+ #define USE_FLOCK 1
+ #include <sys/file.h>
+ #ifndef LOCK_UN
+ #undef USE_FLOCK
+ #define USE_FCNTL 1
+ #include <fcntl.h>
+ #endif
+ #endif
+ 
+ 
+ 
+ 
  /*
  **
  **  Some defines
***************
*** 165,170 ****
--- 163,169 ----
  #define RULEFLAG_PROXY              1<<7
  #define RULEFLAG_PASSTHROUGH        1<<8
  #define RULEFLAG_FORBIDDEN          1<<9
+ #define RULEFLAG_GONE               1<<10
  
  #define MAPTYPE_TXT                 1<<0
  #define MAPTYPE_DBM                 1<<1
***************
*** 193,198 ****
--- 192,199 ----
  #define LONG_STRING_LEN 2048
  #endif
  
+ #define MAX_ENV_FLAGS 5
+ 
  
  /*
  **
***************
*** 215,240 ****
  typedef struct {
      char    *input;                /* Input string of RewriteCond */
      char    *pattern;              /* the RegExp pattern string */
- #ifdef HAS_APACHE_REGEX_LIB
      regex_t *regexp;
- #else
-     regexp  *regexp;               /* the RegExp pattern compilation */
- #endif
      int      flags;                /* Flags which control the match */
  } rewritecond_entry;
  
  typedef struct {
      array_header *rewriteconds;    /* the corresponding RewriteCond entries */
      char         *pattern;         /* the RegExp pattern string */
- #ifdef HAS_APACHE_REGEX_LIB
      regex_t      *regexp;          /* the RegExp pattern compilation */
! #else
!     regexp       *regexp;
! #endif
!     char         *output;          /* the Substitution string */
!     int           flags;           /* Flags which control the substitution */
!     char         *forced_mimetype; /* forced MIME-type of substitution */
!     int           skip;            /* number of next rules to skip */
  } rewriterule_entry;
  
  
--- 216,235 ----
  typedef struct {
      char    *input;                /* Input string of RewriteCond */
      char    *pattern;              /* the RegExp pattern string */
      regex_t *regexp;
      int      flags;                /* Flags which control the match */
  } rewritecond_entry;
  
  typedef struct {
      array_header *rewriteconds;    /* the corresponding RewriteCond entries */
      char         *pattern;         /* the RegExp pattern string */
      regex_t      *regexp;          /* the RegExp pattern compilation */
!     char         *output;              /* the Substitution string */
!     int           flags;               /* Flags which control the substitution */
!     char         *forced_mimetype;     /* forced MIME type of substitution */
!     int           forced_responsecode; /* forced HTTP redirect response status */
!     char         *env[MAX_ENV_FLAGS+1];/* added environment variables */
!     int           skip;                /* number of next rules to skip */
  } rewriterule_entry;
  
  
***************
*** 298,319 ****
  static void *config_perdir_merge (pool *p, void *basev, void *overridesv);
  
      /* config directive handling */
! static _const char *cmd_rewriteengine  (cmd_parms *cmd, rewrite_perdir_conf *dconf, int flag);
! static _const char *cmd_rewriteoptions (cmd_parms *cmd, rewrite_perdir_conf *dconf, char *option);
! static _const char *cmd_rewriteoptions_setoption(pool *p, int *options, char *name);
! static _const char *cmd_rewritelog     (cmd_parms *cmd, void *dconf, char *a1);
! static _const char *cmd_rewriteloglevel(cmd_parms *cmd, void *dconf, char *a1);
! static _const char *cmd_rewritemap     (cmd_parms *cmd, void *dconf, char *a1, char *a2);
! 
! static _const char *cmd_rewritebase(cmd_parms *cmd, rewrite_perdir_conf *dconf, char *a1);
! 
! static _const char *cmd_rewritecond    (cmd_parms *cmd, rewrite_perdir_conf *dconf, char *str);
! static _const char *cmd_rewritecond_parseflagfield(pool *p, rewritecond_entry *new, char *str);
! static _const char *cmd_rewritecond_setflag       (pool *p, rewritecond_entry *cfg, char *key, char *val);
! 
! extern _const char *cmd_rewriterule    (cmd_parms *cmd, rewrite_perdir_conf *dconf, char *str);
! static _const char *cmd_rewriterule_parseflagfield(pool *p, rewriterule_entry *new, char *str);
! static _const char *cmd_rewriterule_setflag       (pool *p, rewriterule_entry *cfg, char *key, char *val);
  
      /* initialisation */
  static void init_module(server_rec *s, pool *p);
--- 293,314 ----
  static void *config_perdir_merge (pool *p, void *basev, void *overridesv);
  
      /* config directive handling */
! static const char *cmd_rewriteengine  (cmd_parms *cmd, rewrite_perdir_conf *dconf, int flag);
! static const char *cmd_rewriteoptions (cmd_parms *cmd, rewrite_perdir_conf *dconf, char *option);
! static const char *cmd_rewriteoptions_setoption(pool *p, int *options, char *name);
! static const char *cmd_rewritelog     (cmd_parms *cmd, void *dconf, char *a1);
! static const char *cmd_rewriteloglevel(cmd_parms *cmd, void *dconf, char *a1);
! static const char *cmd_rewritemap     (cmd_parms *cmd, void *dconf, char *a1, char *a2);
! 
! static const char *cmd_rewritebase(cmd_parms *cmd, rewrite_perdir_conf *dconf, char *a1);
! 
! static const char *cmd_rewritecond    (cmd_parms *cmd, rewrite_perdir_conf *dconf, char *str);
! static const char *cmd_rewritecond_parseflagfield(pool *p, rewritecond_entry *new, char *str);
! static const char *cmd_rewritecond_setflag       (pool *p, rewritecond_entry *cfg, char *key, char *val);
! 
! extern const char *cmd_rewriterule    (cmd_parms *cmd, rewrite_perdir_conf *dconf, char *str);
! static const char *cmd_rewriterule_parseflagfield(pool *p, rewriterule_entry *new, char *str);
! static const char *cmd_rewriterule_setflag       (pool *p, rewriterule_entry *cfg, char *key, char *val);
  
      /* initialisation */
  static void init_module(server_rec *s, pool *p);
***************
*** 370,375 ****
--- 365,371 ----
  static char  *subst_prefix_path(request_rec *r, char *input, char *match, char *subst);
  static int    parseargline(char *str, char **a1, char **a2, char **a3);
  static int    prefix_stat(const char *path, struct stat *sb);
+ static void   add_env_variable(request_rec *r, char *s);
  
      /* DNS functions */
  static int    is_this_our_host(request_rec *r, char *testhost);
***************
*** 378,383 ****
--- 374,383 ----
  
      /* Proxy Module check */
  static int is_proxy_available(server_rec *s);
+ 
+     /* File locking */
+ static void fd_lock(int fd);
+ static void fd_unlock(int fd);
  
  #endif /* _MOD_REWRITE_H */
  

Mime
View raw message