] PR#1107
Changes with Apache 1.2.4
Index: apache-1.2-rus/src/CHANGES.rus
diff -c apache-1.2-rus/src/CHANGES.rus:1.26 apache-1.2-rus/src/CHANGES.rus:1.28
*** apache-1.2-rus/src/CHANGES.rus:1.26 Thu Jan 1 19:24:16 1998
--- apache-1.2-rus/src/CHANGES.rus Fri Jan 9 19:36:52 1998
***************
*** 1,5 ****
--- 1,12 ----
PL21
+
+ PL21.4, 05 Jan 1998, Alex Tutubalin
+ 1. ÷ÎÅÓÅÎÙ ÐÒÁ×ËÉ, ÎÅÏÂÈÏÄÉÍÙÅ ÄÌÑ ÒÁÂÏÔÙ Ó Apache-SSL
+ 2. Lynx2/OS2 ÄÏÂÁ×ÌÅÎ × bad-agent, ËÁË ÎÅ ÐÏÎÉÍÁÀÝÉÊ charset=...
+ 3. éÍÑ ÐÅÒÅÍÅÎÎÏÊ sc_flags ÉÚÍÅÎÅÎÏ ÎÁ zz_sc_flags (HP UX workaround)
+ 4. Diffs apache_1_2_4 -> apache_1_2_5 merged
+
PL21.3, 01 Jan 1998, Alex Tutubalin
1. îÅ ÏÂÒÁÂÁÔÙ×ÁÀÔÓÑ (É ÎÅ ÐÅÒÅËÏÄÉÒÕÀÔÓÑ) proxy requests
2. äÏÂÁ×ÌÅÎÁ ÄÉÒÅËÔÉ×Á CharsetStrictURIMatch On|Off. åÓÌÉ ÏÎÁ On,
***************
*** 21,43 ****
ÔÏÖÅ ÂÕÄÅÔ ËÏÒÒÅËÔÎÏ ÏÂÒÁÂÏÔÁÎ).
óÐÁÓÉÂÏ am@f1.ru (Andrew Maltsev)
! 2. ëÏÄ, ×ÙÄÁÀÝÉÊ ÐÅÒÅÍÅÎÎÕÀ SOURCE_CHARSET ÔÅÐÅÒØ ÎÅ ×ÙÄÁÅÔ core ÐÒÉ ÏÂÒÁÝÅÎÉÉ
! Ë ÄÉÒÅËÔÏÒÉÑÍ × ËÏÔÏÒÙÈ ÎÅÔ index.html
3. óÄÅÌÁÎ ÎÅËÏÔÏÒÙÊ speedup ÆÕÎËÃÉÉ convert_by_table. óÏÇÌÁÓÎÏ gprof,
ÏÎÁ ÓÔÁÌÁ ÚÁÎÉÍÁÔØ ~6% (×ÍÅÓÔÏ ~15-20 ÐÒÏÃÅÎÔÏ×!) ÐÒÏÃÅÓÓÏÒÎÏÇÏ ×ÒÅÍÅÎÉ.
è×ÁÔÉÌÏ ÏÄÎÏÇÏ ÓÌÏ×Á register. åÓÔÅÓÔ×ÅÎÎÏ, ÎÁ ÄÒÕÇÉÈ ÁÒÈÉÔÅËÔÕÒÁÈ
! ÕÓËÏÒÅÎÉÅ ÍÏÖÅÔ ÂÙÔØ É ÎÅ ÔÁËÉÍ ÚÁÍÅÔÎÙÍ (Ñ ÐÒÏ×ÅÒÑÌ ÎÁ AMD-K6 É gcc-2.7.2).
! ÷ÅÓØ ÐÒÏÞÉÊ ËÏÄ Apache-RUS ÔÒÅÂÕÅÔ ÎÁ Ó×ÏÅ ×ÙÐÏÌÎÅÎÉÅ ÓÕÝÉÅ ÇÒÏÛÉ, ÐÏÜÔÏÍÕ
! ÏÓÔÁÌØÎÙÅ ÏÐÔÉÍÉÚÁÃÉÉ ÍÏÖÎÏ É ÎÅ ÄÅÌÁÔØ.
4. äÏÂÁ×ÌÅÎÁ ÄÉÒÅËÔÉ×Á CharsetProcessType, ÒÁÚÒÅÛÁÀÝÁÑ ÏÂÒÁÂÏÔËÕ MIME-ÔÉÐÏ×,
ÏÔÌÉÞÎÙÈ ÏÔ text/*. îÁÐÒÉÍÅÒ,
CharsetProcessType image/gif
! ÒÁÚÒÅÛÉÔ ÐÅÒÅËÏÄÉÒÏ×ËÕ (É ×ÙÄÁÞÕ Expires, charset=... É ÔÁË ÄÁÌÅÅ) GIF'Ï×, a
! CharsetProcessType application/
ÓÄÅÌÁÅÔ ÔÏ ÖÅ ÓÁÍÏÅ Ó application/*
! åÓÌÉ ÐÁÒÁÍÅÔÒ ÄÉÒÅËÔÉ×Ù ÚÁËÁÎÞÉ×ÁÅÔÓÑ ÎÁ /, ÔÏ ÓÞÉÔÁÅÔÓÑ ÞÔÏ ÓÐÅÃÉÆÉÃÉÒÏ×ÁÎ
ÔÏÌØËÏ MIME type (ÓÍ ÐÒÉÍÅÒ Ó application/), ÅÓÌÉ ÐÁÒÁÍÅÔÒ ÚÁËÁÎÞÉ×ÁÅÔÓÑ
ÎÁ ÌÀÂÏÊ ÄÒÕÇÏÊ ÓÉÍ×ÏÌ, ÔÏ ÔÁËÉÍ ÏÂÒÁÚÏÍ ÓÐÅÃÉÆÉÃÉÒÕÅÔÓÑ ÐÁÒÁ type/subtype
--- 28,52 ----
ÔÏÖÅ ÂÕÄÅÔ ËÏÒÒÅËÔÎÏ ÏÂÒÁÂÏÔÁÎ).
óÐÁÓÉÂÏ am@f1.ru (Andrew Maltsev)
! 2. ëÏÄ, ×ÙÄÁÀÝÉÊ ÐÅÒÅÍÅÎÎÕÀ SOURCE_CHARSET ÔÅÐÅÒØ ÎÅ ×ÙÄÁÅÔ core ÐÒÉ
! ÏÂÒÁÝÅÎÉÉ Ë ÄÉÒÅËÔÏÒÉÑÍ × ËÏÔÏÒÙÈ ÎÅÔ index.html
3. óÄÅÌÁÎ ÎÅËÏÔÏÒÙÊ speedup ÆÕÎËÃÉÉ convert_by_table. óÏÇÌÁÓÎÏ gprof,
ÏÎÁ ÓÔÁÌÁ ÚÁÎÉÍÁÔØ ~6% (×ÍÅÓÔÏ ~15-20 ÐÒÏÃÅÎÔÏ×!) ÐÒÏÃÅÓÓÏÒÎÏÇÏ ×ÒÅÍÅÎÉ.
è×ÁÔÉÌÏ ÏÄÎÏÇÏ ÓÌÏ×Á register. åÓÔÅÓÔ×ÅÎÎÏ, ÎÁ ÄÒÕÇÉÈ ÁÒÈÉÔÅËÔÕÒÁÈ
! ÕÓËÏÒÅÎÉÅ ÍÏÖÅÔ ÂÙÔØ É ÎÅ ÔÁËÉÍ ÚÁÍÅÔÎÙÍ (Ñ ÐÒÏ×ÅÒÑÌ ÎÁ AMD-K6 É
! gcc-2.7.2).
! ÷ÅÓØ ÐÒÏÞÉÊ ËÏÄ Apache-RUS ÔÒÅÂÕÅÔ ÎÁ Ó×ÏÅ ×ÙÐÏÌÎÅÎÉÅ ÓÕÝÉÅ ÇÒÏÛÉ,
! ÐÏÜÔÏÍÕ ÏÓÔÁÌØÎÙÅ ÏÐÔÉÍÉÚÁÃÉÉ ÍÏÖÎÏ É ÎÅ ÄÅÌÁÔØ.
4. äÏÂÁ×ÌÅÎÁ ÄÉÒÅËÔÉ×Á CharsetProcessType, ÒÁÚÒÅÛÁÀÝÁÑ ÏÂÒÁÂÏÔËÕ MIME-ÔÉÐÏ×,
ÏÔÌÉÞÎÙÈ ÏÔ text/*. îÁÐÒÉÍÅÒ,
CharsetProcessType image/gif
! ÒÁÚÒÅÛÉÔ ÐÅÒÅËÏÄÉÒÏ×ËÕ (É ×ÙÄÁÞÕ Expires, charset=... É ÔÁË ÄÁÌÅÅ) GIF'Ï×,
! Á CharsetProcessType application/
ÓÄÅÌÁÅÔ ÔÏ ÖÅ ÓÁÍÏÅ Ó application/*
! åÓÌÉ ÐÁÒÁÍÅÔÒ ÄÉÒÅËÔÉ×Ù ÚÁËÁÎÞÉ×ÁÅÔÓÑ ÎÁ /, ÔÏ ÓÞÉÔÁÅÔÓÑ ÞÔÏ
! ÓÐÅÃÉÆÉÃÉÒÏ×ÁÎ
ÔÏÌØËÏ MIME type (ÓÍ ÐÒÉÍÅÒ Ó application/), ÅÓÌÉ ÐÁÒÁÍÅÔÒ ÚÁËÁÎÞÉ×ÁÅÔÓÑ
ÎÁ ÌÀÂÏÊ ÄÒÕÇÏÊ ÓÉÍ×ÏÌ, ÔÏ ÔÁËÉÍ ÏÂÒÁÚÏÍ ÓÐÅÃÉÆÉÃÉÒÕÅÔÓÑ ÐÁÒÁ type/subtype
Index: apache-1.2-rus/src/Configuration
diff -c apache-1.2-rus/src/Configuration:1.13 apache-1.2-rus/src/Configuration:1.14
*** apache-1.2-rus/src/Configuration:1.13 Sun Dec 28 23:02:26 1997
--- apache-1.2-rus/src/Configuration Fri Jan 9 22:25:17 1998
***************
*** 18,25 ****
# control Configure's behavior as far as how to create Makefile.
#
# Module selection lines, distinguished by having 'Module' at the front.
! # These list the configured modules, in priority order (highest priority
! # first). They're down at the bottom.
#
# Optional module selection lines, distinguished by having `%Module'
# at the front. These specify a module that is to be compiled in (but
--- 18,25 ----
# control Configure's behavior as far as how to create Makefile.
#
# Module selection lines, distinguished by having 'Module' at the front.
! # These list the configured modules, in reverse priority order (lowest
! # priority first). They're down at the bottom.
#
# Optional module selection lines, distinguished by having `%Module'
# at the front. These specify a module that is to be compiled in (but
Index: apache-1.2-rus/src/Configuration.tmpl
diff -c apache-1.2-rus/src/Configuration.tmpl:1.1.1.1 apache-1.2-rus/src/Configuration.tmpl:1.2
*** apache-1.2-rus/src/Configuration.tmpl:1.1.1.1 Wed Jun 18 00:20:07 1997
--- apache-1.2-rus/src/Configuration.tmpl Fri Jan 9 22:25:19 1998
***************
*** 18,25 ****
# control Configure's behavior as far as how to create Makefile.
#
# Module selection lines, distinguished by having 'Module' at the front.
! # These list the configured modules, in priority order (highest priority
! # first). They're down at the bottom.
#
# Optional module selection lines, distinguished by having `%Module'
# at the front. These specify a module that is to be compiled in (but
--- 18,25 ----
# control Configure's behavior as far as how to create Makefile.
#
# Module selection lines, distinguished by having 'Module' at the front.
! # These list the configured modules, in reverse priority order (lowest
! # priority first). They're down at the bottom.
#
# Optional module selection lines, distinguished by having `%Module'
# at the front. These specify a module that is to be compiled in (but
Index: apache-1.2-rus/src/http_config.c
diff -c apache-1.2-rus/src/http_config.c:1.2 apache-1.2-rus/src/http_config.c:1.3
*** apache-1.2-rus/src/http_config.c:1.2 Mon Jul 7 16:46:03 1997
--- apache-1.2-rus/src/http_config.c Fri Jan 9 22:25:21 1998
***************
*** 821,828 ****
}
*result = dc;
! } else
! dc = NULL;
/* cache it */
new = palloc(r->pool, sizeof(struct htaccess_result));
--- 821,836 ----
}
*result = dc;
! } else {
! if (errno == ENOENT || errno == ENOTDIR)
! dc = NULL;
! else {
! log_unixerr("pfopen", filename,
! "unable to check htaccess file, ensure it is readable",
! r->server);
! return HTTP_FORBIDDEN;
! }
! }
/* cache it */
new = palloc(r->pool, sizeof(struct htaccess_result));
Index: apache-1.2-rus/src/http_main.c
diff -c apache-1.2-rus/src/http_main.c:1.3 apache-1.2-rus/src/http_main.c:1.4
*** apache-1.2-rus/src/http_main.c:1.3 Sat Aug 23 17:03:11 1997
--- apache-1.2-rus/src/http_main.c Fri Jan 9 22:25:22 1998
***************
*** 1776,1783 ****
exit(0);
errno = errsave;
! if (srv < 0 && errno != EINTR)
log_unixerr("select", "(listen)", NULL, server_conf);
if (srv <= 0)
continue;
--- 1776,1791 ----
exit(0);
errno = errsave;
! if (srv < 0 && errno != EINTR) {
! #ifdef LINUX
! if (errno == EFAULT) {
! log_unixerr("select", "(listen) fatal, exiting",
! NULL, server_conf);
! exit(1);
! }
! #endif
log_unixerr("select", "(listen)", NULL, server_conf);
+ }
if (srv <= 0)
continue;
***************
*** 2463,2468 ****
--- 2471,2479 ----
GETUSERMODE();
}
#endif
+ if (ap_setjmp (jmpbuffer)) {
+ exit (0);
+ }
c = sizeof(sa_client);
if ((getpeername(fileno(stdin), &sa_client, &c)) < 0)
Index: apache-1.2-rus/src/http_request.c
diff -c apache-1.2-rus/src/http_request.c:1.5 apache-1.2-rus/src/http_request.c:1.6
*** apache-1.2-rus/src/http_request.c:1.5 Sat Aug 23 17:03:16 1997
--- apache-1.2-rus/src/http_request.c Fri Jan 9 22:25:24 1998
***************
*** 909,917 ****
((r->proto_num == 1001) && !table_get(r->headers_in, "Host"))) {
/* Client sent us a HTTP/1.1 or later request without telling
* us the hostname, either with a full URL or a Host: header.
! * We therefore need to (as per the 1.1 spec) send an error
*/
! log_reason ("client sent HTTP/1.1 request without hostname",
r->uri, r);
die (BAD_REQUEST, r);
return;
--- 909,920 ----
((r->proto_num == 1001) && !table_get(r->headers_in, "Host"))) {
/* Client sent us a HTTP/1.1 or later request without telling
* us the hostname, either with a full URL or a Host: header.
! * We therefore need to (as per the 1.1 spec) send an error.
! * As a special case, HTTP/1.1 mentions twice (S9, S14.23)
! * that a request MUST contain a Host: header, and the server
! * MUST respond with 400 if it doesn't.
*/
! log_reason ("client sent HTTP/1.1 request without hostname (see RFC2068 sections 9 and 14.23)",
r->uri, r);
die (BAD_REQUEST, r);
return;
Index: apache-1.2-rus/src/httpd.h
diff -c apache-1.2-rus/src/httpd.h:1.23 apache-1.2-rus/src/httpd.h:1.25
*** apache-1.2-rus/src/httpd.h:1.23 Thu Jan 1 19:24:17 1998
--- apache-1.2-rus/src/httpd.h Fri Jan 9 19:43:58 1998
***************
*** 256,262 ****
* Example: "Apache/1.1.0 MrWidget/0.1-alpha"
*/
! #define SERVER_BASEVERSION "Apache/1.2.4 rus/PL21.3" /* SEE COMMENTS ABOVE */
#ifdef SERVER_SUBVERSION
#define SERVER_VERSION SERVER_BASEVERSION " " SERVER_SUBVERSION
#else
--- 256,262 ----
* Example: "Apache/1.1.0 MrWidget/0.1-alpha"
*/
! #define SERVER_BASEVERSION "Apache/1.2.5 rus/PL21.4" /* SEE COMMENTS ABOVE */
#ifdef SERVER_SUBVERSION
#define SERVER_VERSION SERVER_BASEVERSION " " SERVER_SUBVERSION
#else
***************
*** 266,272 ****
/* Numeric release version identifier: major minor bugfix betaseq
* Always increases along the same track as the source branch.
*/
! #define APACHE_RELEASE 1020499
#define SERVER_PROTOCOL "HTTP/1.1"
#define SERVER_SUPPORT "http://www.apache.org/"
--- 266,272 ----
/* Numeric release version identifier: major minor bugfix betaseq
* Always increases along the same track as the source branch.
*/
! #define APACHE_RELEASE 1020501
#define SERVER_PROTOCOL "HTTP/1.1"
#define SERVER_SUPPORT "http://www.apache.org/"
Index: apache-1.2-rus/src/mod_charset.c
diff -c apache-1.2-rus/src/mod_charset.c:1.21 apache-1.2-rus/src/mod_charset.c:1.22
*** apache-1.2-rus/src/mod_charset.c:1.21 Thu Jan 1 19:24:19 1998
--- apache-1.2-rus/src/mod_charset.c Fri Jan 9 19:04:56 1998
***************
*** 219,232 ****
cp->charset_exts = make_table(p,20);
cp->portlist = make_array(p,5,sizeof(portlist_t));
cp->charset_default = NULL;
! cp->reject_error = FL_DEFAULT;
! cp->maxprio = FL_DEFAULT;
! cp->matchlang = FL_DEFAULT;
! cp->turnoff = FL_DEFAULT;
! cp->recode_headers = FL_DEFAULT;
! cp->recode_filenames = FL_DEFAULT;
! cp->override_expires = FL_DEFAULT;
! cp->strict_names = FL_DEFAULT;
memset(cp->selection_rules,0,NRULES*sizeof(cp->selection_rules[0]));
return cp;
}
--- 219,228 ----
cp->charset_exts = make_table(p,20);
cp->portlist = make_array(p,5,sizeof(portlist_t));
cp->charset_default = NULL;
! cp->reject_error = cp->maxprio = cp->matchlang = cp->turnoff =
! cp->recode_headers = cp->recode_filenames =
! cp->override_expires = cp->strict_names
! = FL_DEFAULT;
memset(cp->selection_rules,0,NRULES*sizeof(cp->selection_rules[0]));
return cp;
}
***************
*** 294,300 ****
/* ============ table lookup utilities ================= */
! /* ×ÏÚ×ÒÁÝÁÅÔ ËÏÎÆÉÇÕÒÁÃÉÀ, ÎÁÚ×ÁÎÉÅ ËÏÔÏÒÏÊ ÓÏ×ÐÁÄÁÅÔ Ó ÐÅÒ×ÙÍÉ ÓÉÍ×ÏÌÁÍÉ bname */
static charset_table_t*
strncmp_get_chtable(charset_dir_t *s,const char *bname,int strict, char *delim)
--- 290,301 ----
/* ============ table lookup utilities ================= */
! /*
! ×ÏÚ×ÒÁÝÁÅÔ ËÏÎÆÉÇÕÒÁÃÉÀ, ÎÁÚ×ÁÎÉÅ ËÏÔÏÒÏÊ ÓÏ×ÐÁÄÁÅÔ Ó ÐÅÒ×ÙÍÉ
! ÓÉÍ×ÏÌÁÍÉ bname
! åÓÌÉ strict != 0, ÔÏ ÓÌÅÄÕÀÛÉÊ ÓÉÍ×ÏÌ bname ÐÏÓÌÅ match ÄÏÌÖÅÎ ÂÙÔØ
! ÉÌÉ \0, ÉÌÉ ÓÉÍ×ÏÌÏÍ ÉÚ ÓÔÒÏËÉ delim
! */
static charset_table_t*
strncmp_get_chtable(charset_dir_t *s,const char *bname,int strict, char *delim)
***************
*** 328,335 ****
static recode_table_t*
! make_recode_table(pool *p, recode_table_t *table, char *namefrom, char *nameto,
! unsigned char *ctbl,unsigned char *rtbl)
{
table->namefrom = namefrom;
table->nameto = nameto;
--- 329,337 ----
static recode_table_t*
! make_recode_table(pool *p, recode_table_t *table,
! char *namefrom, char *nameto,
! unsigned char *ctbl,unsigned char *rtbl)
{
table->namefrom = namefrom;
table->nameto = nameto;
***************
*** 340,347 ****
}
static recode_table_t*
! new_recode_table(pool *p, char *namefrom,char *nameto, unsigned char *ctbl,
! unsigned char *rtbl)
{
recode_table_t *r = pcalloc(p,sizeof(recode_table_t));
return make_recode_table(p,r,namefrom,nameto,ctbl,rtbl);
--- 342,349 ----
}
static recode_table_t*
! new_recode_table(pool *p, char *namefrom,char *nameto,
! unsigned char *ctbl, unsigned char *rtbl)
{
recode_table_t *r = pcalloc(p,sizeof(recode_table_t));
return make_recode_table(p,r,namefrom,nameto,ctbl,rtbl);
***************
*** 730,748 ****
{ "CharsetRecodeFilenames",add_charset_recode_filenames,NULL,OR_FILEINFO,FLAG,
"Turn On recoding of filenames"},
/* support for soft redirection */
! { "CharsetSoftRedirect", charset_add_redirect, (void*)HTTP_MOVED_TEMPORARILY,
OR_FILEINFO, TAKE23,
"an optional status, then document to be redirected and destination URL" },
! { "CharsetSoftRedirectTemp", charset_add_redirect, (void*)HTTP_MOVED_TEMPORARILY,
! OR_FILEINFO, TAKE2,"a document to be redirected, then the destination URL" },
{ "CharsetSoftRedirectPermanent", charset_add_redirect,
(void*)HTTP_MOVED_PERMANENTLY,
! OR_FILEINFO, TAKE2, "a document to be redirected, then the destination URL" },
{ "CharsetProcessType", add_proctype, NULL,
! OR_FILEINFO, ITERATE, "additional mime-type substring to be processed" },
{ "CharsetBrokenAccept", add_brokaccept, NULL,
! OR_FILEINFO, TAKE2, "user-agent substring then full accept-charset string"},
! { "CharsetOverrideExpires",add_charset_override_expires,NULL,OR_FILEINFO,FLAG,
"Turn On/Off override of Expires: header set by other modules"},
{ "CharsetStrictURIMatch",add_charset_stricturi,NULL,OR_FILEINFO,FLAG,
"Turn On/Off strict hostname/directory match"},
--- 732,757 ----
{ "CharsetRecodeFilenames",add_charset_recode_filenames,NULL,OR_FILEINFO,FLAG,
"Turn On recoding of filenames"},
/* support for soft redirection */
! { "CharsetSoftRedirect", charset_add_redirect,
! (void*)HTTP_MOVED_TEMPORARILY,
OR_FILEINFO, TAKE23,
"an optional status, then document to be redirected and destination URL" },
! { "CharsetSoftRedirectTemp", charset_add_redirect,
! (void*)HTTP_MOVED_TEMPORARILY,
! OR_FILEINFO, TAKE2,
! "a document to be redirected, then the destination URL" },
{ "CharsetSoftRedirectPermanent", charset_add_redirect,
(void*)HTTP_MOVED_PERMANENTLY,
! OR_FILEINFO, TAKE2,
! "a document to be redirected, then the destination URL" },
{ "CharsetProcessType", add_proctype, NULL,
! OR_FILEINFO, ITERATE,
! "additional mime-type substring to be processed" },
{ "CharsetBrokenAccept", add_brokaccept, NULL,
! OR_FILEINFO, TAKE2,
! "user-agent substring then full accept-charset string"},
! { "CharsetOverrideExpires",add_charset_override_expires,NULL,
! OR_FILEINFO,FLAG,
"Turn On/Off override of Expires: header set by other modules"},
{ "CharsetStrictURIMatch",add_charset_stricturi,NULL,OR_FILEINFO,FLAG,
"Turn On/Off strict hostname/directory match"},
***************
*** 1259,1264 ****
--- 1268,1277 ----
main function for selecting charset
*/
+ #if !defined(APACHE_SSL) && !defined(http_method)
+ #define http_method(r) "http"
+ #endif
+
int
find_code_page(request_rec *r)
***************
*** 1267,1273 ****
charset_dir_t *dirconf = get_module_config(r->per_dir_config, &charset_module);
char *cset = NULL,*cset2;
int rc = DECLINED;
! int has_wildcard = 0,i,*l, sc_flags = 0;
table *e = r->subprocess_env;
/* catch proxy requests */
--- 1280,1286 ----
charset_dir_t *dirconf = get_module_config(r->per_dir_config, &charset_module);
char *cset = NULL,*cset2;
int rc = DECLINED;
! int has_wildcard = 0,i,*l, zz_sc_flags = 0;
table *e = r->subprocess_env;
/* catch proxy requests */
***************
*** 1285,1295 ****
{
if (is_HTTP_REDIRECT(status))
{
! redir = pstrcat (r->pool, "http://",
construct_server(r->pool,
r->server->server_hostname,
ntohs(r->connection->
local_addr.sin_port)),
rel_uri, NULL);
table_set (r->headers_out, "Location", redir);
return status;
--- 1298,1316 ----
{
if (is_HTTP_REDIRECT(status))
{
! redir = pstrcat (r->pool, http_method(r),"://",
! #ifndef APACHE_SSL
construct_server(r->pool,
r->server->server_hostname,
ntohs(r->connection->
local_addr.sin_port)),
+ #else
+ construct_server(r->pool,
+ r->server->server_hostname,
+ ntohs(r->connection->
+ local_addr.sin_port),r),
+ #endif
+
rel_uri, NULL);
table_set (r->headers_out, "Location", redir);
return status;
***************
*** 1374,1380 ****
else
{
charset = charset_from_useragent(r,dirconf);
! sc_flags |= SCH_BY_UA; /* User-agent probed, so next request may
be accepted via User-Agent test */
}
}
--- 1395,1401 ----
else
{
charset = charset_from_useragent(r,dirconf);
! zz_sc_flags |= SCH_BY_UA; /* User-agent probed, so next request may
be accepted via User-Agent test */
}
}
***************
*** 1382,1388 ****
if(charset!=NULL)
{
if(l[i]==sHostname || l[i] == sDirprefix || l[i]==sPortnumber)
! sc_flags |= SCH_CAN_CACHE;
break;
}
}
--- 1403,1409 ----
if(charset!=NULL)
{
if(l[i]==sHostname || l[i] == sDirprefix || l[i]==sPortnumber)
! zz_sc_flags |= SCH_CAN_CACHE;
break;
}
}
***************
*** 1390,1401 ****
if(cset_by_accept != NULL)
{
if(charset && !strcasecmp(cset_by_accept->tablename,charset->tablename))
! sc_flags |= SCH_CAN_CACHE;
else
{
/* cannot cache */
! sc_flags &= (~(SCH_CAN_CACHE));
! sc_flags |= SCH_BY_ACCEPT;
}
charset=cset_by_accept;
}
--- 1411,1422 ----
if(cset_by_accept != NULL)
{
if(charset && !strcasecmp(cset_by_accept->tablename,charset->tablename))
! zz_sc_flags |= SCH_CAN_CACHE;
else
{
/* cannot cache */
! zz_sc_flags &= (~(SCH_CAN_CACHE));
! zz_sc_flags |= SCH_BY_ACCEPT;
}
charset=cset_by_accept;
}
***************
*** 1419,1425 ****
if(charset)
{
! set_charset(charset,r,dirconf,sc_flags);
table_set (e, "CHARSET", charset->tablename);
if(r->codep && r->codep->cp_fromname)
table_set (e, "SOURCE_CHARSET",r->codep->cp_fromname);
--- 1440,1446 ----
if(charset)
{
! set_charset(charset,r,dirconf,zz_sc_flags);
table_set (e, "CHARSET", charset->tablename);
if(r->codep && r->codep->cp_fromname)
table_set (e, "SOURCE_CHARSET",r->codep->cp_fromname);
***************
*** 1770,1779 ****
if (r->args) {
rel_uri = pstrcat (r->pool, rel_uri, "?", r->args, NULL);
}
redir = pstrcat (r->pool, "http://",
! construct_server(r->pool, r->server->server_hostname,
ntohs(r->connection->
local_addr.sin_port)),
rel_uri, NULL);
table_set (r->headers_out, "Location", redir);
--- 1791,1809 ----
if (r->args) {
rel_uri = pstrcat (r->pool, rel_uri, "?", r->args, NULL);
}
+
redir = pstrcat (r->pool, "http://",
! #ifndef APACHE_SSL
! construct_server(r->pool,
! r->server->server_hostname,
ntohs(r->connection->
local_addr.sin_port)),
+ #else
+ construct_server(r->pool,
+ r->server->server_hostname,
+ ntohs(r->connection->
+ local_addr.sin_port),r),
+ #endif
rel_uri, NULL);
table_set (r->headers_out, "Location", redir);
***************
*** 1787,1805 ****
/************************************************************/
module charset_module = {
STANDARD_MODULE_STUFF,
! NULL, /* initializer */
! create_charset_dir_conf,/* dir config creater */
merge_charset_dir_conf,
! create_charset_config, /* server config */
merge_charset_config,
! charset_cmds, /* command table */
! charset_handlers, /* handlers */
! translate_charset_redir,/* filename translation */
! NULL, /* check_user_id */
! NULL, /* check auth */
! NULL, /* check access */
! NULL, /* type_checker */
! find_code_page, /* fixups */
! NULL, /* logger */
};
#endif
--- 1817,1835 ----
/************************************************************/
module charset_module = {
STANDARD_MODULE_STUFF,
! NULL, /* initializer */
! create_charset_dir_conf, /* dir config creater */
merge_charset_dir_conf,
! create_charset_config, /* server config */
merge_charset_config,
! charset_cmds, /* command table */
! charset_handlers, /* handlers */
! translate_charset_redir, /* filename translation */
! NULL, /* check_user_id */
! NULL, /* check auth */
! NULL, /* check access */
! NULL, /* type_checker */
! find_code_page, /* fixups */
! NULL, /* logger */
};
#endif
Index: apache-1.2-rus/src/mod_dir.c
diff -c apache-1.2-rus/src/mod_dir.c:1.3 apache-1.2-rus/src/mod_dir.c:1.4
*** apache-1.2-rus/src/mod_dir.c:1.3 Sun Dec 21 22:24:30 1997
--- apache-1.2-rus/src/mod_dir.c Fri Jan 9 19:04:57 1998
***************
*** 809,822 ****
ifile = pstrcat (r->pool, escape_uri(r->pool, r->uri),
"/", NULL);
! #ifndef USE_TRANSFER_TABLES
! table_set (r->headers_out, "Location",
! construct_url(r->pool, ifile, r->server));
! #else
r->server->port=ntohs(r->connection->local_addr.sin_port);
table_set (r->headers_out, "Location",
construct_url(r->pool, ifile, r->server));
- #endif
return HTTP_MOVED_PERMANENTLY;
}
--- 809,820 ----
ifile = pstrcat (r->pool, escape_uri(r->pool, r->uri),
"/", NULL);
! #ifdef USE_TRANSFER_TABLES
r->server->port=ntohs(r->connection->local_addr.sin_port);
+ #endif
+
table_set (r->headers_out, "Location",
construct_url(r->pool, ifile, r->server));
return HTTP_MOVED_PERMANENTLY;
}
Index: apache-1.2-rus/src/mod_imap.c
diff -c apache-1.2-rus/src/mod_imap.c:1.2 apache-1.2-rus/src/mod_imap.c:1.3
*** apache-1.2-rus/src/mod_imap.c:1.2 Sat Aug 23 17:03:21 1997
--- apache-1.2-rus/src/mod_imap.c Fri Jan 9 22:25:28 1998
***************
*** 20,26 ****
*
* 4. The names "Apache Server" and "Apache Group" must not be used to
* endorse or promote products derived from this software without
! * prior written permission.
*
* 5. Redistributions of any form whatsoever must retain the following
* acknowledgment:
--- 20,27 ----
*
* 4. The names "Apache Server" and "Apache Group" must not be used to
* endorse or promote products derived from this software without
! * prior written permission. For written permission, please contact
! * apache@apache.org.
*
* 5. Redistributions of any form whatsoever must retain the following
* acknowledgment:
***************
*** 96,103 ****
#include "util_script.h"
#define IMAP_MAGIC_TYPE "application/x-httpd-imap"
- #define LARGEBUF 500
- #define SMALLBUF 256
#define MAXVERTS 100
#define X 0
#define Y 1
--- 97,102 ----
***************
*** 107,168 ****
#define IMAP_BASE_DEFAULT "map"
#ifdef SUNOS4
! double strtod(); /* SunOS needed this */
#endif
module imap_module;
! typedef struct {
! char *imap_menu;
! char *imap_default;
! char *imap_base;
} imap_conf_rec;
! void *create_imap_dir_config (pool *p, char *dummy) {
! imap_conf_rec *icr =
! (imap_conf_rec *)palloc(p, sizeof(imap_conf_rec));
!
! icr->imap_menu = NULL;
! icr->imap_default = NULL;
! icr->imap_base = NULL;
!
! return icr;
! }
!
! void *merge_imap_dir_configs (pool *p, void *basev, void *addv)
! {
! imap_conf_rec *new=(imap_conf_rec *)pcalloc (p, sizeof(imap_conf_rec));
! imap_conf_rec *base = (imap_conf_rec *)basev;
! imap_conf_rec *add = (imap_conf_rec *)addv;
!
! new->imap_menu = add->imap_menu ? add->imap_menu : base->imap_menu;
! new->imap_default=add->imap_default ? add->imap_default : base->imap_default;
! new->imap_base =add-> imap_base ? add->imap_base : base->imap_base;
!
! return new;
}
! command_rec imap_cmds[] = {
! { "ImapMenu", set_string_slot,
! (void*)XtOffsetOf(imap_conf_rec, imap_menu), OR_INDEXES, TAKE1,
! "the type of menu generated: none, formatted, semiformatted, unformatted"},
! { "ImapDefault", set_string_slot,
! (void*)XtOffsetOf(imap_conf_rec, imap_default), OR_INDEXES, TAKE1,
! "the action taken if no match: error, nocontent, referer, menu, URL" },
! { "ImapBase", set_string_slot,
! (void*)XtOffsetOf(imap_conf_rec, imap_base), OR_INDEXES, TAKE1,
! "the base for all URL's: map, referer, URL (or start of)" },
! { NULL }
};
! int pointinrect(double point[2], double coords[MAXVERTS][2])
{
double max[2], min[2];
if (coords[0][X] > coords[1][X]) {
max[0] = coords[0][X];
min[0] = coords[1][X];
! } else {
max[0] = coords[1][X];
min[0] = coords[0][X];
}
--- 106,170 ----
#define IMAP_BASE_DEFAULT "map"
#ifdef SUNOS4
! double strtod(); /* SunOS needed this */
#endif
module imap_module;
! typedef struct {
! char *imap_menu;
! char *imap_default;
! char *imap_base;
} imap_conf_rec;
! static void *create_imap_dir_config(pool *p, char *dummy)
! {
! imap_conf_rec *icr =
! (imap_conf_rec *) palloc(p, sizeof(imap_conf_rec));
!
! icr->imap_menu = NULL;
! icr->imap_default = NULL;
! icr->imap_base = NULL;
!
! return icr;
! }
!
! static void *merge_imap_dir_configs(pool *p, void *basev, void *addv)
! {
! imap_conf_rec *new = (imap_conf_rec *) pcalloc(p, sizeof(imap_conf_rec));
! imap_conf_rec *base = (imap_conf_rec *) basev;
! imap_conf_rec *add = (imap_conf_rec *) addv;
!
! new->imap_menu = add->imap_menu ? add->imap_menu : base->imap_menu;
! new->imap_default = add->imap_default ? add->imap_default : base->imap_default;
! new->imap_base = add->imap_base ? add->imap_base : base->imap_base;
!
! return new;
}
! static command_rec imap_cmds[] =
! {
! {"ImapMenu", set_string_slot,
! (void *) XtOffsetOf(imap_conf_rec, imap_menu), OR_INDEXES, TAKE1,
! "the type of menu generated: none, formatted, semiformatted, unformatted"},
! {"ImapDefault", set_string_slot,
! (void *) XtOffsetOf(imap_conf_rec, imap_default), OR_INDEXES, TAKE1,
! "the action taken if no match: error, nocontent, referer, menu, URL"},
! {"ImapBase", set_string_slot,
! (void *) XtOffsetOf(imap_conf_rec, imap_base), OR_INDEXES, TAKE1,
! "the base for all URL's: map, referer, URL (or start of)"},
! {NULL}
};
! static int pointinrect(const double point[2], const double coords[MAXVERTS][2])
{
double max[2], min[2];
if (coords[0][X] > coords[1][X]) {
max[0] = coords[0][X];
min[0] = coords[1][X];
! }
! else {
max[0] = coords[1][X];
min[0] = coords[0][X];
}
***************
*** 170,202 ****
if (coords[0][Y] > coords[1][Y]) {
max[1] = coords[0][Y];
min[1] = coords[1][Y];
! } else {
max[1] = coords[1][Y];
min[1] = coords[0][Y];
}
return ((point[X] >= min[0] && point[X] <= max[0]) &&
! (point[Y] >= min[1] && point[Y] <= max[1]));
}
! int pointincircle(double point[2], double coords[MAXVERTS][2])
{
! int radius1, radius2;
radius1 = ((coords[0][Y] - coords[1][Y]) * (coords[0][Y] - coords[1][Y]))
! + ((coords[0][X] - coords[1][X]) * (coords[0][X] - coords[1][X]));
!
radius2 = ((coords[0][Y] - point[Y]) * (coords[0][Y] - point[Y]))
! + ((coords[0][X] - point[X]) * (coords[0][X] - point[X]));
return (radius2 <= radius1);
}
! int pointinpoly(double point[2], double pgon[MAXVERTS][2])
{
int i, numverts, inside_flag, xflag0;
int crossings;
! double *p, *stop;
double tx, ty, y;
for (i = 0; pgon[i][X] != -1 && i < MAXVERTS; i++);
--- 172,206 ----
if (coords[0][Y] > coords[1][Y]) {
max[1] = coords[0][Y];
min[1] = coords[1][Y];
! }
! else {
max[1] = coords[1][Y];
min[1] = coords[0][Y];
}
return ((point[X] >= min[0] && point[X] <= max[0]) &&
! (point[Y] >= min[1] && point[Y] <= max[1]));
}
! static int pointincircle(const double point[2], const double coords[MAXVERTS][2])
{
! double radius1, radius2;
radius1 = ((coords[0][Y] - coords[1][Y]) * (coords[0][Y] - coords[1][Y]))
! + ((coords[0][X] - coords[1][X]) * (coords[0][X] - coords[1][X]));
!
radius2 = ((coords[0][Y] - point[Y]) * (coords[0][Y] - point[Y]))
! + ((coords[0][X] - point[X]) * (coords[0][X] - point[X]));
return (radius2 <= radius1);
}
! static int pointinpoly(const double point[2], const double pgon[MAXVERTS][2])
{
int i, numverts, inside_flag, xflag0;
int crossings;
! double *p;
! const double *stop;
double tx, ty, y;
for (i = 0; pgon[i][X] != -1 && i < MAXVERTS; i++);
***************
*** 211,264 ****
p = (double *) pgon + 1;
if ((y >= ty) != (*p >= ty)) {
! if ((xflag0 = (pgon[numverts - 1][X] >= tx)) == (*(double *) pgon >= tx)) {
! if (xflag0)
! crossings++;
! }
! else {
! crossings += (pgon[numverts - 1][X] - (y - ty) *
! (*(double *) pgon - pgon[numverts - 1][X]) /
! (*p - y)) >= tx;
! }
}
stop = pgon[numverts];
for (y = *p, p += 2; p < stop; y = *p, p += 2) {
-
- if (y >= ty) {
-
- while ((p < stop) && (*p >= ty))
- p += 2;
-
- if (p >= stop)
- break;
- if ((xflag0 = (*(p - 3) >= tx)) == (*(p - 1) >= tx)) {
-
- if (xflag0)
- crossings++;
- }
- else {
- crossings += (*(p - 3) - (*(p - 2) - ty) *
- (*(p - 1) - *(p - 3)) / (*p - *(p - 2))) >= tx;
- }
- }
- else {
- while ((p < stop) && (*p < ty))
- p += 2;
! if (p >= stop)
! break;
! if ((xflag0 = (*(p - 3) >= tx)) == (*(p - 1) >= tx)) {
! if (xflag0)
! crossings++;
! }
! else {
! crossings += (*(p - 3) - (*(p - 2) - ty) *
! (*(p - 1) - *(p - 3)) / (*p - *(p - 2))) >= tx;
! }
! }
}
inside_flag = crossings & 0x01;
--- 215,268 ----
p = (double *) pgon + 1;
if ((y >= ty) != (*p >= ty)) {
! if ((xflag0 = (pgon[numverts - 1][X] >= tx)) == (*(double *) pgon >= tx)) {
! if (xflag0)
! crossings++;
! }
! else {
! crossings += (pgon[numverts - 1][X] - (y - ty) *
! (*(double *) pgon - pgon[numverts - 1][X]) /
! (*p - y)) >= tx;
! }
}
stop = pgon[numverts];
for (y = *p, p += 2; p < stop; y = *p, p += 2) {
! if (y >= ty) {
! while ((p < stop) && (*p >= ty))
! p += 2;
!
! if (p >= stop)
! break;
! if ((xflag0 = (*(p - 3) >= tx)) == (*(p - 1) >= tx)) {
!
! if (xflag0)
! crossings++;
! }
! else {
! crossings += (*(p - 3) - (*(p - 2) - ty) *
! (*(p - 1) - *(p - 3)) / (*p - *(p - 2))) >= tx;
! }
! }
! else {
! while ((p < stop) && (*p < ty))
! p += 2;
!
! if (p >= stop)
! break;
!
! if ((xflag0 = (*(p - 3) >= tx)) == (*(p - 1) >= tx)) {
! if (xflag0)
! crossings++;
! }
! else {
! crossings += (*(p - 3) - (*(p - 2) - ty) *
! (*(p - 1) - *(p - 3)) / (*p - *(p - 2))) >= tx;
! }
! }
}
inside_flag = crossings & 0x01;
***************
*** 266,841 ****
}
! int is_closer(double point[2], double coords[MAXVERTS][2], double *closest)
{
! double dist_squared =((point[X] - coords[0][X]) * (point[X] - coords[0][X]))
! + ((point[Y] - coords[0][Y]) * (point[Y] - coords[0][Y]));
! if (point[X] < 0 || point[Y] < 0 )
! return(0); /* don't mess around with negative coordinates */
! if ( *closest < 0 || dist_squared < *closest ) {
! *closest = dist_squared;
! return(1); /* if this is the first point or is the closest yet
! set 'closest' equal to this distance^2 */
! }
!
! return(0); /* if it's not the first or closest */
}
! double get_x_coord(char *args)
{
! char *endptr; /* we want it non-null */
! double x_coord = -1; /* -1 is returned if no coordinate is given */
! if (args == NULL)
! return(-1); /* in case we aren't passed anything */
! while( *args && !isdigit(*args) && *args != ',')
! args++; /* jump to the first digit, but not past a comma or end */
! x_coord = strtod(args, &endptr);
! if (endptr > args) /* if a conversion was made */
! return(x_coord);
! return(-1); /* else if no conversion was made, or if no args was given */
}
! double get_y_coord(char *args)
{
! char *endptr; /* we want it non-null */
! char *start_of_y = NULL;
! double y_coord = -1; /* -1 is returned on error */
! if (args == NULL)
! return(-1); /* in case we aren't passed anything */
! start_of_y = strchr(args, ','); /* the comma */
! if (start_of_y) {
!
! start_of_y++; /* start looking at the character after the comma */
! while( *start_of_y && !isdigit(*start_of_y))
! start_of_y++; /* jump to the first digit, but not past the end */
! y_coord = strtod(start_of_y, &endptr);
! if (endptr > start_of_y)
! return(y_coord);
! }
!
! return(-1); /* if no conversion was made, or no comma was found in args */
}
-
- int read_quoted(char *string, char *quoted_part)
- {
- char *starting_pos = string;
-
- while ( isspace(*string) )
- string++; /* go along string until non-whitespace */
! if ( *string == '"' ) { /* if that character is a double quote */
! string++; /* step over it */
! while ( *string && *string != '"' ) {
! *quoted_part++ = *string++; /* copy the quoted portion */
! }
! *quoted_part = '\0'; /* end the string with a SNUL */
!
! string++; /* step over the last double quote */
! }
! return(string - starting_pos); /* return the total characters read */
}
/*
! * url needs to point to a string with at least SMALLBUF memory allocated
*/
! void imap_url(request_rec *r, char *base, char *value, char *url)
{
/* translates a value into a URL. */
! int slen, clen;
! char *string_pos = NULL;
! char *directory = NULL;
! char *referer = NULL;
! char my_base[SMALLBUF] = {'\0'};
!
! if ( ! strcasecmp(value, "map" ) || ! strcasecmp(value, "menu") ) {
! if (r->server->port == DEFAULT_PORT ) {
! ap_snprintf(url, SMALLBUF,
! "http://%s%s", r->server->server_hostname, r->uri);
}
! else {
! ap_snprintf(url, SMALLBUF, "http://%s:%d%s", r->server->server_hostname,
! r->server->port, r->uri);
}
! return;
! }
! if ( ! strcasecmp(value, "nocontent") || ! strcasecmp(value, "error") ) {
! strncpy(url, value, SMALLBUF-1);
! url[SMALLBUF-1] = '\0';
! return; /* these are handled elsewhere, so just copy them */
! }
!
! if ( ! strcasecmp(value, "referer" ) ) {
! referer = table_get(r->headers_in, "Referer");
! if ( referer && *referer ) {
! strncpy(url, referer, SMALLBUF-1);
! url[SMALLBUF-1] = '\0';
! return;
}
! else {
! *value = '\0'; /* if 'referer' but no referring page, null the value */
! }
! }
!
! string_pos = value;
! while ( isalpha(*string_pos) )
! string_pos++; /* go along the URL from the map until a non-letter */
! if ( *string_pos == ':' ) {
! strncpy(url, value, SMALLBUF-1); /* if letters and then a colon (like http:) */
! url[SMALLBUF-1] = '\0';
! return; /* it's an absolute URL, so use it! */
! }
!
! if ( ! base || ! *base ) {
! if ( value && *value ) {
! strncpy(url, value, SMALLBUF-1); /* no base: use what is given */
! url[SMALLBUF-1] = '\0';
! }
! else {
! if (r->server->port == DEFAULT_PORT ) {
! ap_snprintf(url, SMALLBUF, "http://%s/", r->server->server_hostname);
! }
! if (r->server->port != DEFAULT_PORT ) {
! ap_snprintf(url, SMALLBUF, "http://%s:%d/",
! r->server->server_hostname, r->server->port);
! } /* no base, no value: pick a simple default */
! }
! return;
! }
!
! strncpy(my_base, base, sizeof(my_base)-1); /* must be a relative URL to be combined with base */
! my_base[sizeof(my_base)-1] = '\0';
! if (strchr(my_base, '/') == NULL && (!strncmp(value, "../", 3) || !strcmp(value, "..")) ) {
! url[0] = '\0';
! log_reason("invalid base directive in map file", r->uri, r);
return;
! }
! string_pos = my_base;
! while (*string_pos) {
! if (*string_pos == '/' && *(string_pos+1) == '/') {
! string_pos += 2; /* if there are two slashes, jump over them */
! continue;
! }
! if (*string_pos == '/') { /* the first single slash */
! if ( value[0] == '/' ) {
! *string_pos = '\0';
! } /* if the URL from the map starts from root, end the
! base URL string at the first single slash */
! else {
! directory = string_pos; /* save the start of the directory portion */
! string_pos = strrchr(string_pos, '/'); /* now reuse string_pos */
! string_pos++; /* step over that last slash */
! *string_pos = '\0';
! } /* but if the map url is relative, leave the
! slash on the base (if there is one) */
! break;
! }
! string_pos++; /* until we get to the end of my_base without finding
! a slash by itself */
! }
!
! while ( ! strncmp(value, "../", 3) || ! strcmp(value, "..") ) {
!
! if (directory && (slen = strlen (directory))) {
!
! /* for each '..', knock a directory off the end
! by ending the string right at the last slash.
! But only consider the directory portion: don't eat
! into the server name. And only try if a directory
! portion was found */
!
! clen = slen - 1;
!
! while ((slen - clen) == 1) {
!
! if ((string_pos = strrchr(directory, '/')))
! *string_pos = '\0';
! clen = strlen (directory);
! if (clen == 0) break;
! }
!
! value += 2; /* jump over the '..' that we found in the value */
! } else if (directory) {
! url[0] = '\0';
! log_reason("invalid directory name in map file", r->uri, r);
! return;
! }
!
! if (! strncmp(value, "/../", 4) || ! strcmp(value, "/..") )
!
! value++; /* step over the '/' if there are more '..' to do.
! this way, we leave the starting '/' on value after
! the last '..', but get rid of it otherwise */
!
! } /* by this point, value does not start with '..' */
!
! if ( value && *value ) {
! ap_snprintf(url, SMALLBUF, "%s%s", my_base, value);
! }
! else {
! ap_snprintf(url, SMALLBUF, "%s", my_base);
! }
! return;
! }
!
! int imap_reply(request_rec *r, char *redirect)
! {
! if ( ! strcasecmp(redirect, "error") ) {
! return SERVER_ERROR; /* they actually requested an error! */
! }
! if ( ! strcasecmp(redirect, "nocontent") ) {
! return HTTP_NO_CONTENT; /* tell the client to keep the page it has */
! }
! if (redirect && *redirect ) {
! table_set(r->headers_out, "Location", redirect);
! return REDIRECT; /* must be a URL, so redirect to it */
! }
! return SERVER_ERROR;
! }
!
! void menu_header(request_rec *r, char *menu)
! {
! r->content_type = "text/html";
! send_http_header(r);
! hard_timeout("send menu", r); /* killed in menu_footer */
!
! rvputs(r, "\nMenu for ", r->uri,
! "\n\n", NULL);
!
! if (!strcasecmp(menu, "formatted")) {
! rvputs(r, "Menu for ", r->uri, "
\n
\n\n", NULL);
! }
!
! return;
! }
!
! void menu_blank(request_rec *r, char *menu)
! {
! if (! strcasecmp(menu, "formatted") ) {
! rputs("\n", r);
! }
! if (! strcasecmp(menu, "semiformatted") ) {
! rputs("
\n", r);
! }
! if (! strcasecmp(menu, "unformatted") ) {
! rputs("\n", r);
! }
! return;
! }
!
! void menu_comment(request_rec *r, char *menu, char *comment)
! {
! if (! strcasecmp(menu, "formatted") ) {
! rputs("\n", r); /* print just a newline if 'formatted' */
! }
! if (! strcasecmp(menu, "semiformatted") && *comment ) {
! rvputs(r, comment, "\n", NULL);
! }
! if (! strcasecmp(menu, "unformatted") && *comment ) {
! rvputs(r, comment, "\n", NULL);
! }
! return; /* comments are ignored in the 'formatted' form */
! }
!
! void menu_default(request_rec *r, char *menu, char *href, char *text)
! {
! if ( ! strcasecmp(href, "error") || ! strcasecmp(href, "nocontent") ) {
! return; /* don't print such lines, these aren'te really href's */
! }
! if ( ! strcasecmp(menu, "formatted" ) ) {
! rvputs(r, "(Default) ", text, "
\n",
! NULL);
! }
! if ( ! strcasecmp(menu, "semiformatted" ) ) {
! rvputs(r, "(Default) ", text, "
\n",
! NULL);
! }
! if ( ! strcasecmp(menu, "unformatted" ) ) {
! rvputs(r, "", text, "", NULL);
! }
! return;
! }
!
! void menu_directive(request_rec *r, char *menu, char *href, char *text)
! {
! if ( ! strcasecmp(href, "error") || ! strcasecmp(href, "nocontent") ) {
! return; /* don't print such lines, as this isn't really an href */
! }
! if ( ! strcasecmp(menu, "formatted" ) ) {
! rvputs(r, " ", text, "
\n",
! NULL);
! }
! if ( ! strcasecmp(menu, "semiformatted" ) ) {
! rvputs(r, " ", text, "
\n",
! NULL);
! }
! if ( ! strcasecmp(menu, "unformatted" ) ) {
! rvputs(r, "", text, "", NULL);
! }
! return;
! }
!
! void menu_footer(request_rec *r)
! {
! rputs("\n\n\n\n", r); /* finish the menu */
! kill_timeout(r);
! }
!
! int imap_handler(request_rec *r)
! {
! char input[LARGEBUF] = {'\0'};
! /* size of input can not be lowered without changing hard-coded
! * checks
*/
! char href_text[SMALLBUF] = {'\0'};
! char base[SMALLBUF] = {'\0'};
! char redirect[SMALLBUF] = {'\0'};
! char directive[SMALLBUF] = {'\0'};
! char value[SMALLBUF] = {'\0'};
! char mapdflt[SMALLBUF] = {'\0'};
! char closest[SMALLBUF] = {'\0'};
! double closest_yet = -1;
!
! double testpoint[2] = { -1,-1 };
! double pointarray[MAXVERTS + 1][2] = { {-1,-1} };
! int vertex = 0;
!
! char *string_pos = NULL;
! int chars_read = 0;
! int showmenu = 0;
!
! imap_conf_rec *icr = get_module_config(r->per_dir_config, &imap_module);
!
! char *imap_menu = icr->imap_menu ?
! icr->imap_menu : IMAP_MENU_DEFAULT;
! char *imap_default = icr->imap_default ?
! icr->imap_default : IMAP_DEFAULT_DEFAULT;
! char *imap_base = icr->imap_base ?
! icr->imap_base : IMAP_BASE_DEFAULT;
!
! FILE *imap = pfopen(r->pool, r->filename, "r");
!
! if ( ! imap )
! return NOT_FOUND;
!
! imap_url(r, NULL, imap_base, base); /* set base according to default */
! imap_url(r, NULL, imap_default, mapdflt); /* and default to global default */
!
! testpoint[X] = get_x_coord(r->args);
! testpoint[Y] = get_y_coord(r->args);
!
! if ((testpoint[X] == -1 || testpoint[Y] == -1) ||
! (testpoint[X] == 0 && testpoint[Y] == 0) ) {
! /* if either is -1 or if both are zero (new Lynx) */
! /* we don't have valid coordinates */
! testpoint[X] = -1;
! testpoint[Y] = -1;
! if ( strncasecmp(imap_menu, "none", 2) )
! showmenu = 1; /* show the menu _unless_ ImapMenu is 'none' or 'no' */
! }
!
! if (showmenu) { /* send start of imagemap menu if we're going to */
! menu_header(r, imap_menu);
! }
!
! while (!cfg_getline(input, LARGEBUF, imap)) {
! string_pos = input; /* always start at the beginning of line */
!
! directive[0] = '\0';
! value[0] = '\0';
! href_text[0] = '\0';
! redirect[0] = '\0';
! chars_read = 0; /* clear these before using */
!
! if ( ! input[0] ) {
! if (showmenu) {
! menu_blank(r, imap_menu);
! }
! continue;
! }
!
! if ( input[0] == '#' ) {
! if (showmenu) {
! menu_comment(r, imap_menu, input + 1);
! }
! continue;
! } /* blank lines and comments are ignored if we aren't printing a menu */
!
!
! if (sscanf(input, "%255s %255s", directive, value) != 2) {
! continue; /* make sure we read two fields */
! }
! /* Now skip what we just read... we can't use ANSIism %n */
! while (!(isspace(*string_pos))) /* past directive */
! string_pos++;
! while (isspace(*string_pos)) /* and whitespace */
! string_pos++;
! while (!(isspace(*string_pos))) /* and value... have to watch it */
! string_pos++; /* can have punctuation and stuff */
!
! if ( ! strncasecmp(directive, "base", 4 ) ) { /* base, base_uri */
! imap_url(r, NULL, value, base);
! continue; /* base is never printed to a menu */
! }
!
! chars_read = read_quoted(string_pos, href_text);
! string_pos += chars_read; /* read the quoted href text if present */
!
! if ( ! strcasecmp(directive, "default" ) ) { /* default */
! imap_url(r, NULL, value, mapdflt);
! if (showmenu) { /* print the default if there's a menu */
! if (! *href_text) { /* if we didn't find a "href text" */
! strncpy(href_text, mapdflt, sizeof(href_text)-1); /* use the href itself as text */
! href_text[sizeof(href_text)-1] = '\0';
}
- imap_url(r, base, mapdflt, redirect);
- menu_default(r, imap_menu, redirect, href_text);
- }
- continue;
- }
-
- vertex = 0;
- while ( vertex < MAXVERTS &&
- sscanf(string_pos, "%lf, %lf",
- &pointarray[vertex][X], &pointarray[vertex][Y]) == 2)
- {
- /* Now skip what we just read... we can't use ANSIism %n */
- while(isspace(*string_pos)) /* past whitespace */
- string_pos++;
- while(isdigit(*string_pos)) /* and the 1st number */
- string_pos++;
- string_pos++; /* skip the ',' */
- while(isspace(*string_pos)) /* past any more whitespace */
- string_pos++;
- while(isdigit(*string_pos)) /* 2nd number */
- string_pos++;
- vertex++;
- } /* so long as there are more vertices to read, and
- we have room, read them in. We start where we left
- off of the last sscanf, not at the beginning.*/
-
- pointarray[vertex][X] = -1; /* signals the end of vertices */
if (showmenu) {
! read_quoted(string_pos, href_text); /* href text could be here instead */
! if (! *href_text) { /* if we didn't find a "href text" */
! strncpy(href_text, value, sizeof(href_text)-1); /* use the href itself in the menu */
! href_text[sizeof(href_text)-1] = '\0';
! }
! imap_url(r, base, value, redirect);
! menu_directive(r, imap_menu, redirect, href_text);
! continue;
! }
! /* note that we don't make it past here if we are making a menu */
!
! if (testpoint[X] == -1 || pointarray[0][X] == -1 )
! continue; /* don't try the following tests if testpoints
! are invalid, or if there are no coordinates */
!
! if ( ! strcasecmp(directive, "poly" ) ) { /* poly */
!
! if (pointinpoly (testpoint, pointarray) ) {
! pfclose(r->pool, imap);
! imap_url(r, base, value, redirect);
! return (imap_reply(r, redirect));
! }
! continue;
! }
!
! if ( ! strcasecmp(directive, "circle" ) ) { /* circle */
!
! if (pointincircle (testpoint, pointarray) ) {
! pfclose(r->pool, imap);
! imap_url(r, base, value, redirect);
! return (imap_reply(r, redirect));
! }
! continue;
! }
!
! if ( ! strcasecmp(directive, "rect" ) ) { /* rect */
!
! if (pointinrect (testpoint, pointarray) ) {
! pfclose(r->pool, imap);
! imap_url(r, base, value, redirect);
! return (imap_reply(r, redirect));
! }
! continue;
! }
!
! if ( ! strcasecmp(directive, "point" ) ) { /* point */
!
! if (is_closer(testpoint, pointarray, &closest_yet) ) {
! strncpy(closest, value, sizeof(closest)-1); /* if the closest point yet save it */
! closest[sizeof(closest)-1] = '\0';
! }
!
! continue;
! } /* move on to next line whether it's closest or not */
!
! } /* nothing matched, so we get another line! */
!
! pfclose(r->pool, imap); /* we are done with the map file, so close it */
!
! if (showmenu) {
! menu_footer(r); /* finish the menu and we are done */
! return OK;
! }
!
! if (*closest) { /* if a 'point' directive has been seen */
! imap_url(r, base, closest, redirect);
! return (imap_reply(r, redirect));
! }
!
! if (*mapdflt ) { /* a default should be defined, even if only 'nocontent'*/
! imap_url(r, base, mapdflt, redirect);
! return(imap_reply(r, redirect));
! }
!
! return SERVER_ERROR; /* If we make it this far, we failed. They lose! */
! }
!
!
! handler_rec imap_handlers[] = {
! { IMAP_MAGIC_TYPE, imap_handler },
! { "imap-file", imap_handler },
! { NULL }
};
! module imap_module = {
! STANDARD_MODULE_STUFF,
! NULL, /* initializer */
! create_imap_dir_config, /* dir config creater */
! merge_imap_dir_configs, /* dir merger --- default is to override */
! NULL, /* server config */
! NULL, /* merge server config */
! imap_cmds, /* command table */
! imap_handlers, /* handlers */
! NULL, /* filename translation */
! NULL, /* check_user_id */
! NULL, /* check auth */
! NULL, /* check access */
! NULL, /* type_checker */
! NULL, /* fixups */
! NULL, /* logger */
! NULL /* header parser */
};
--- 270,876 ----
}
! static int is_closer(const double point[2], const double coords[MAXVERTS][2], double *closest)
{
! double dist_squared = ((point[X] - coords[0][X]) * (point[X] - coords[0][X]))
! + ((point[Y] - coords[0][Y]) * (point[Y] - coords[0][Y]));
!
! if (point[X] < 0 || point[Y] < 0)
! return (0); /* don't mess around with negative coordinates */
! if (*closest < 0 || dist_squared < *closest) {
! *closest = dist_squared;
! return (1); /* if this is the first point or is the closest yet
! set 'closest' equal to this distance^2 */
! }
! return (0); /* if it's not the first or closest */
}
! static double get_x_coord(const char *args)
{
! char *endptr; /* we want it non-null */
! double x_coord = -1; /* -1 is returned if no coordinate is given */
! if (args == NULL)
! return (-1); /* in case we aren't passed anything */
! while (*args && !isdigit(*args) && *args != ',')
! args++; /* jump to the first digit, but not past a comma or end */
! x_coord = strtod(args, &endptr);
! if (endptr > args) /* if a conversion was made */
! return (x_coord);
! return (-1); /* else if no conversion was made, or if no args was given */
}
! static double get_y_coord(const char *args)
{
! char *endptr; /* we want it non-null */
! char *start_of_y = NULL;
! double y_coord = -1; /* -1 is returned on error */
! if (args == NULL)
! return (-1); /* in case we aren't passed anything */
! start_of_y = strchr(args, ','); /* the comma */
! if (start_of_y) {
! start_of_y++; /* start looking at the character after the comma */
! while (*start_of_y && !isdigit(*start_of_y))
! start_of_y++; /* jump to the first digit, but not past the end */
!
! y_coord = strtod(start_of_y, &endptr);
!
! if (endptr > start_of_y)
! return (y_coord);
! }
! return (-1); /* if no conversion was made, or no comma was found in args */
}
! /* See if string has a "quoted part", and if so set *quoted_part to
! * the first character of the quoted part, then hammer a \0 onto the
! * trailing quote, and set *string to point at the first character
! * past the second quote.
! *
! * Otherwise set *quoted_part to NULL, and leave *string alone.
! */
! static void read_quoted(char **string, char **quoted_part)
! {
! char *strp = *string;
! /* assume there's no quoted part */
! *quoted_part = NULL;
! while (isspace(*strp))
! strp++; /* go along string until non-whitespace */
!
! if (*strp == '"') { /* if that character is a double quote */
! strp++; /* step over it */
! *quoted_part = strp; /* note where the quoted part begins */
!
! while (*strp && *strp != '"') {
! ++strp; /* skip the quoted portion */
! }
! *strp = '\0'; /* end the string with a NUL */
! strp++; /* step over the last double quote */
! *string = strp;
! }
}
/*
! * returns the mapped URL or NULL.
*/
! static char *imap_url(request_rec *r, const char *base, const char *value)
{
/* translates a value into a URL. */
! int slen, clen;
! char *string_pos = NULL;
! const char *string_pos_const = NULL;
! char *directory = NULL;
! char *referer = NULL;
! char *my_base;
!
! if (!strcasecmp(value, "map") || !strcasecmp(value, "menu")) {
! return construct_url(r->pool, r->uri, r->server);
! }
!
! if (!strcasecmp(value, "nocontent") || !strcasecmp(value, "error")) {
! return pstrdup(r->pool, value); /* these are handled elsewhere, so just copy them */
! }
!
! if (!strcasecmp(value, "referer")) {
! referer = table_get(r->headers_in, "Referer");
! if (referer && *referer) {
! return pstrdup(r->pool, referer);
! }
! else {
! /* XXX: This used to do *value = '\0'; ... which is totally bogus
! * because it hammers the passed in value, which can be a string constant,
! * or part of a config, or whatever. Total garbage. This works around
! * that without changing the rest of this code much
! */
! value = ""; /* if 'referer' but no referring page, null the value */
! }
! }
!
! string_pos_const = value;
! while (isalpha(*string_pos_const))
! string_pos_const++; /* go along the URL from the map until a non-letter */
! if (*string_pos_const == ':') {
! /* if letters and then a colon (like http:) */
! /* it's an absolute URL, so use it! */
! return pstrdup(r->pool, value);
! }
!
! if (!base || !*base) {
! if (value && *value) {
! return pstrdup(r->pool, value); /* no base: use what is given */
! }
! /* no base, no value: pick a simple default */
! return construct_url(r->pool, "/", r->server);
! }
!
! /* must be a relative URL to be combined with base */
! if (strchr(base, '/') == NULL && (!strncmp(value, "../", 3) || !strcmp(value, ".."))) {
! log_reason("invalid base directive in map file: %s", r->uri, r);
! return NULL;
! }
! my_base = pstrdup(r->pool, base);
! string_pos = my_base;
! while (*string_pos) {
! if (*string_pos == '/' && *(string_pos + 1) == '/') {
! string_pos += 2; /* if there are two slashes, jump over them */
! continue;
! }
! if (*string_pos == '/') { /* the first single slash */
! if (value[0] == '/') {
! *string_pos = '\0';
! } /* if the URL from the map starts from root, end the
! base URL string at the first single slash */
! else {
! directory = string_pos; /* save the start of the directory portion */
!
! string_pos = strrchr(string_pos, '/'); /* now reuse string_pos */
! string_pos++; /* step over that last slash */
! *string_pos = '\0';
! } /* but if the map url is relative, leave the
! slash on the base (if there is one) */
! break;
! }
! string_pos++; /* until we get to the end of my_base without finding
! a slash by itself */
! }
!
! while (!strncmp(value, "../", 3) || !strcmp(value, "..")) {
!
! if (directory && (slen = strlen(directory))) {
!
! /* for each '..', knock a directory off the end
! by ending the string right at the last slash.
! But only consider the directory portion: don't eat
! into the server name. And only try if a directory
! portion was found */
!
! clen = slen - 1;
!
! while ((slen - clen) == 1) {
!
! if ((string_pos = strrchr(directory, '/')))
! *string_pos = '\0';
! clen = strlen(directory);
! if (clen == 0)
! break;
! }
!
! value += 2; /* jump over the '..' that we found in the value */
! }
! else if (directory) {
! log_reason("invalid directory name in map file: %s", r->uri, r);
! return NULL;
! }
!
! if (!strncmp(value, "/../", 4) || !strcmp(value, "/.."))
! value++; /* step over the '/' if there are more '..' to do.
! this way, we leave the starting '/' on value after
! the last '..', but get rid of it otherwise */
!
! } /* by this point, value does not start with '..' */
!
! if (value && *value) {
! return pstrcat(r->pool, my_base, value, NULL);
! }
! return my_base;
! }
!
! static int imap_reply(request_rec *r, char *redirect)
! {
! if (!strcasecmp(redirect, "error")) {
! return SERVER_ERROR; /* they actually requested an error! */
! }
! if (!strcasecmp(redirect, "nocontent")) {
! return HTTP_NO_CONTENT; /* tell the client to keep the page it has */
! }
! if (redirect && *redirect) {
! table_set(r->headers_out, "Location", redirect);
! return REDIRECT; /* must be a URL, so redirect to it */
! }
! return SERVER_ERROR;
! }
!
! static void menu_header(request_rec *r, char *menu)
! {
! r->content_type = "text/html";
! send_http_header(r);
! hard_timeout("send menu", r); /* killed in menu_footer */
!
! rvputs(r, "\nMenu for ", r->uri,
! "\n\n", NULL);
!
! if (!strcasecmp(menu, "formatted")) {
! rvputs(r, "Menu for ", r->uri, "
\n
\n\n", NULL);
}
!
! return;
! }
!
! static void menu_blank(request_rec *r, char *menu)
! {
! if (!strcasecmp(menu, "formatted")) {
! rputs("\n", r);
! }
! if (!strcasecmp(menu, "semiformatted")) {
! rputs("
\n", r);
! }
! if (!strcasecmp(menu, "unformatted")) {
! rputs("\n", r);
! }
! return;
! }
!
! static void menu_comment(request_rec *r, char *menu, char *comment)
! {
! if (!strcasecmp(menu, "formatted")) {
! rputs("\n", r); /* print just a newline if 'formatted' */
! }
! if (!strcasecmp(menu, "semiformatted") && *comment) {
! rvputs(r, comment, "\n", NULL);
! }
! if (!strcasecmp(menu, "unformatted") && *comment) {
! rvputs(r, comment, "\n", NULL);
}
! return; /* comments are ignored in the 'formatted' form */
! }
! static void menu_default(request_rec *r, char *menu, char *href, char *text)
! {
! if (!strcasecmp(href, "error") || !strcasecmp(href, "nocontent")) {
! return; /* don't print such lines, these aren'te really href's */
}
! if (!strcasecmp(menu, "formatted")) {
! rvputs(r, "(Default) ", text, "
\n",
! NULL);
! }
! if (!strcasecmp(menu, "semiformatted")) {
! rvputs(r, "(Default) ", text, "
\n",
! NULL);
! }
! if (!strcasecmp(menu, "unformatted")) {
! rvputs(r, "", text, "", NULL);
! }
return;
! }
!
! static void menu_directive(request_rec *r, char *menu, char *href, char *text)
! {
! if (!strcasecmp(href, "error") || !strcasecmp(href, "nocontent")) {
! return; /* don't print such lines, as this isn't really an href */
! }
! if (!strcasecmp(menu, "formatted")) {
! rvputs(r, " ", text, "
\n",
! NULL);
! }
! if (!strcasecmp(menu, "semiformatted")) {
! rvputs(r, " ", text, "
\n",
! NULL);
! }
! if (!strcasecmp(menu, "unformatted")) {
! rvputs(r, "", text, "", NULL);
! }
! return;
! }
!
! static void menu_footer(request_rec *r)
! {
! rputs("\n\n\n\n", r); /* finish the menu */
! kill_timeout(r);
! }
! static int imap_handler(request_rec *r)
! {
! char input[MAX_STRING_LEN];
! char *directive;
! char *value;
! char *href_text;
! char *base;
! char *redirect;
! char *mapdflt;
! char *closest = NULL;
! double closest_yet = -1;
!
! double testpoint[2];
! double pointarray[MAXVERTS + 1][2];
! int vertex;
!
! char *string_pos;
! int showmenu = 0;
!
! imap_conf_rec *icr = get_module_config(r->per_dir_config, &imap_module);
!
! char *imap_menu = icr->imap_menu ? icr->imap_menu : IMAP_MENU_DEFAULT;
! char *imap_default = icr->imap_default
! ? icr->imap_default : IMAP_DEFAULT_DEFAULT;
! char *imap_base = icr->imap_base ? icr->imap_base : IMAP_BASE_DEFAULT;
!
! FILE *imap;
!
! if (r->method_number != M_GET)
! return DECLINED;
!
! imap = pfopen(r->pool, r->filename, "r");
!
! if (!imap)
! return NOT_FOUND;
!
! base = imap_url(r, NULL, imap_base); /* set base according to default */
! if (!base)
! return HTTP_INTERNAL_SERVER_ERROR;
! mapdflt = imap_url(r, NULL, imap_default); /* and default to global default */
! if (!mapdflt)
! return HTTP_INTERNAL_SERVER_ERROR;
!
! testpoint[X] = get_x_coord(r->args);
! testpoint[Y] = get_y_coord(r->args);
!
! if ((testpoint[X] == -1 || testpoint[Y] == -1) ||
! (testpoint[X] == 0 && testpoint[Y] == 0)) {
! /* if either is -1 or if both are zero (new Lynx) */
! /* we don't have valid coordinates */
! testpoint[X] = -1;
! testpoint[Y] = -1;
! if (strncasecmp(imap_menu, "none", 2))
! showmenu = 1; /* show the menu _unless_ ImapMenu is 'none' or 'no' */
! }
!
! if (showmenu) { /* send start of imagemap menu if we're going to */
! menu_header(r, imap_menu);
! }
!
! while (!cfg_getline(input, sizeof(input), imap)) {
! if (!input[0]) {
! if (showmenu) {
! menu_blank(r, imap_menu);
! }
! continue;
! }
!
! if (input[0] == '#') {
! if (showmenu) {
! menu_comment(r, imap_menu, input + 1);
! }
! continue;
! } /* blank lines and comments are ignored if we aren't printing a menu */
!
! /* find the first two space delimited fields, recall that
! * cfg_getline has removed leading/trailing whitespace and
! * compressed the other whitespace down to one space a piece
! *
! * note that we're tokenizing as we go... if we were to use the
! * getword() class of functions we would end up allocating extra
! * memory for every line of the map file
*/
! string_pos = input;
! if (!*string_pos) /* need at least two fields */
! goto need_2_fields;
!
! directive = string_pos;
! while (*string_pos && *string_pos != ' ') /* past directive */
! ++string_pos;
! if (!*string_pos) /* need at least two fields */
! goto need_2_fields;
! *string_pos++ = '\0';
!
! if (!*string_pos) /* need at least two fields */
! goto need_2_fields;
! value = string_pos;
! while (*string_pos && *string_pos != ' ') /* past value */
! ++string_pos;
! if (*string_pos == ' ') {
! *string_pos++ = '\0';
! }
! else {
! /* end of input, don't advance past it */
! *string_pos = '\0';
}
+ if (!strncasecmp(directive, "base", 4)) { /* base, base_uri */
+ base = imap_url(r, NULL, value);
+ if (!base)
+ goto menu_bail;
+ continue; /* base is never printed to a menu */
+ }
+
+ read_quoted(&string_pos, &href_text);
+
+ if (!strcasecmp(directive, "default")) { /* default */
+ mapdflt = imap_url(r, NULL, value);
+ if (!mapdflt)
+ goto menu_bail;
+ if (showmenu) { /* print the default if there's a menu */
+ redirect = imap_url(r, base, mapdflt);
+ if (!redirect)
+ goto menu_bail;
+ menu_default(r, imap_menu, redirect, href_text ? href_text : mapdflt);
+ }
+ continue;
+ }
+
+ vertex = 0;
+ while (vertex < MAXVERTS &&
+ sscanf(string_pos, "%lf%*[, ]%lf",
+ &pointarray[vertex][X], &pointarray[vertex][Y]) == 2) {
+ /* Now skip what we just read... we can't use ANSIism %n */
+ while (isspace(*string_pos)) /* past whitespace */
+ string_pos++;
+ while (isdigit(*string_pos)) /* and the 1st number */
+ string_pos++;
+ string_pos++; /* skip the ',' */
+ while (isspace(*string_pos)) /* past any more whitespace */
+ string_pos++;
+ while (isdigit(*string_pos)) /* 2nd number */
+ string_pos++;
+ vertex++;
+ } /* so long as there are more vertices to read, and
+ we have room, read them in. We start where we left
+ off of the last sscanf, not at the beginning. */
+
+ pointarray[vertex][X] = -1; /* signals the end of vertices */
+
+ if (showmenu) {
+ if (!href_text) {
+ read_quoted(&string_pos, &href_text); /* href text could be here instead */
+ }
+ redirect = imap_url(r, base, value);
+ if (!redirect)
+ goto menu_bail;
+ menu_directive(r, imap_menu, redirect, href_text ? href_text : value);
+ continue;
+ }
+ /* note that we don't make it past here if we are making a menu */
+
+ if (testpoint[X] == -1 || pointarray[0][X] == -1)
+ continue; /* don't try the following tests if testpoints
+ are invalid, or if there are no coordinates */
+
+ if (!strcasecmp(directive, "poly")) { /* poly */
+
+ if (pointinpoly(testpoint, pointarray)) {
+ pfclose(r->pool, imap);
+ redirect = imap_url(r, base, value);
+ if (!redirect)
+ return HTTP_INTERNAL_SERVER_ERROR;
+ return (imap_reply(r, redirect));
+ }
+ continue;
+ }
+
+ if (!strcasecmp(directive, "circle")) { /* circle */
+
+ if (pointincircle(testpoint, pointarray)) {
+ pfclose(r->pool, imap);
+ redirect = imap_url(r, base, value);
+ if (!redirect)
+ return HTTP_INTERNAL_SERVER_ERROR;
+ return (imap_reply(r, redirect));
+ }
+ continue;
+ }
+
+ if (!strcasecmp(directive, "rect")) { /* rect */
+
+ if (pointinrect(testpoint, pointarray)) {
+ pfclose(r->pool, imap);
+ redirect = imap_url(r, base, value);
+ if (!redirect)
+ return HTTP_INTERNAL_SERVER_ERROR;
+ return (imap_reply(r, redirect));
+ }
+ continue;
+ }
+
+ if (!strcasecmp(directive, "point")) { /* point */
+
+ if (is_closer(testpoint, pointarray, &closest_yet)) {
+ closest = pstrdup(r->pool, value);
+ }
+
+ continue;
+ } /* move on to next line whether it's closest or not */
+
+ } /* nothing matched, so we get another line! */
+
+ pfclose(r->pool, imap); /* we are done with the map file, so close it */
+
+ if (showmenu) {
+ menu_footer(r); /* finish the menu and we are done */
+ return OK;
+ }
+
+ if (closest) { /* if a 'point' directive has been seen */
+ redirect = imap_url(r, base, closest);
+ if (!redirect)
+ return HTTP_INTERNAL_SERVER_ERROR;
+ return (imap_reply(r, redirect));
+ }
+
+ if (mapdflt) { /* a default should be defined, even if only 'nocontent' */
+ redirect = imap_url(r, base, mapdflt);
+ if (!redirect)
+ return HTTP_INTERNAL_SERVER_ERROR;
+ return (imap_reply(r, redirect));
+ }
+
+ return SERVER_ERROR; /* If we make it this far, we failed. They lose! */
+
+ need_2_fields:
+ log_reason("all map file lines require at least two fields", r->uri, r);
+ /* fall through */
+ menu_bail:
+ pfclose(r->pool, imap);
if (showmenu) {
! /* There's not much else we can do ... we've already sent the headers
! * to the client.
! */
! rputs("\n\n[an internal server error occured]\n", r);
! menu_footer(r);
! return OK;
! }
! return HTTP_INTERNAL_SERVER_ERROR;
! }
!
!
! static handler_rec imap_handlers[] =
! {
! {IMAP_MAGIC_TYPE, imap_handler},
! {"imap-file", imap_handler},
! {NULL}
};
! module imap_module =
! {
! STANDARD_MODULE_STUFF,
! NULL, /* initializer */
! create_imap_dir_config, /* dir config creater */
! merge_imap_dir_configs, /* dir merger --- default is to override */
! NULL, /* server config */
! NULL, /* merge server config */
! imap_cmds, /* command table */
! imap_handlers, /* handlers */
! NULL, /* filename translation */
! NULL, /* check_user_id */
! NULL, /* check auth */
! NULL, /* check access */
! NULL, /* type_checker */
! NULL, /* fixups */
! NULL, /* logger */
! NULL /* header parser */
};
Index: apache-1.2-rus/src/mod_include.c
diff -c apache-1.2-rus/src/mod_include.c:1.3 apache-1.2-rus/src/mod_include.c:1.4
*** apache-1.2-rus/src/mod_include.c:1.3 Sat Aug 23 17:03:22 1997
--- apache-1.2-rus/src/mod_include.c Fri Jan 9 22:25:30 1998
***************
*** 20,26 ****
*
* 4. The names "Apache Server" and "Apache Group" must not be used to
* endorse or promote products derived from this software without
! * prior written permission.
*
* 5. Redistributions of any form whatsoever must retain the following
* acknowledgment:
--- 20,27 ----
*
* 4. The names "Apache Server" and "Apache Group" must not be used to
* endorse or promote products derived from this software without
! * prior written permission. For written permission, please contact
! * apache@apache.org.
*
* 5. Redistributions of any form whatsoever must retain the following
* acknowledgment:
***************
*** 91,108 ****
#define STARTING_SEQUENCE ""
#define DEFAULT_ERROR_MSG "[an error occurred while processing this directive]"
! #define DEFAULT_TIME_FORMAT "%A, %d-%b-%y %T %Z"
#define SIZEFMT_BYTES 0
#define SIZEFMT_KMG 1
- static void decodehtml(char *s);
- static char *get_tag(pool *p, FILE *in, char *tag, int tag_len, int dodecode);
- static int get_directive(FILE *in, char *d, pool *p);
/* ------------------------ Environment function -------------------------- */
! void add_include_vars(request_rec *r, char *timefmt)
{
struct passwd *pw;
table *e = r->subprocess_env;
--- 92,111 ----
#define STARTING_SEQUENCE ""
#define DEFAULT_ERROR_MSG "[an error occurred while processing this directive]"
! #define DEFAULT_TIME_FORMAT "%A, %d-%b-%Y %H:%M:%S %Z"
#define SIZEFMT_BYTES 0
#define SIZEFMT_KMG 1
+ static void safe_copy(char *dest, const char *src, size_t max_len)
+ {
+ strncpy(dest, src, max_len - 1);
+ dest[max_len - 1] = '\0';
+ }
/* ------------------------ Environment function -------------------------- */
! static void add_include_vars(request_rec *r, char *timefmt)
{
struct passwd *pw;
table *e = r->subprocess_env;
***************
*** 111,138 ****
table_set(e, "DATE_LOCAL", ht_time(r->pool, date, timefmt, 0));
table_set(e, "DATE_GMT", ht_time(r->pool, date, timefmt, 1));
! table_set(e, "LAST_MODIFIED",ht_time(r->pool,r->finfo.st_mtime,timefmt,0));
table_set(e, "DOCUMENT_URI", r->uri);
table_set(e, "DOCUMENT_PATH_INFO", r->path_info);
pw = getpwuid(r->finfo.st_uid);
if (pw) {
! table_set(e, "USER_NAME", pw->pw_name);
! } else {
! char uid[16];
! ap_snprintf(uid, sizeof(uid), "user#%lu", (unsigned long)r->finfo.st_uid);
! table_set(e, "USER_NAME", uid);
}
! if((t = strrchr(r->filename, '/')))
! table_set (e, "DOCUMENT_NAME", ++t);
! else
! table_set (e, "DOCUMENT_NAME", r->uri);
if (r->args) {
! char *arg_copy = pstrdup (r->pool, r->args);
! unescape_url (arg_copy);
! table_set (e, "QUERY_STRING_UNESCAPED",
! escape_shell_cmd (r->pool, arg_copy));
}
}
--- 114,146 ----
table_set(e, "DATE_LOCAL", ht_time(r->pool, date, timefmt, 0));
table_set(e, "DATE_GMT", ht_time(r->pool, date, timefmt, 1));
! table_set(e, "LAST_MODIFIED",
! ht_time(r->pool, r->finfo.st_mtime, timefmt, 0));
table_set(e, "DOCUMENT_URI", r->uri);
table_set(e, "DOCUMENT_PATH_INFO", r->path_info);
pw = getpwuid(r->finfo.st_uid);
if (pw) {
! table_set(e, "USER_NAME", pw->pw_name);
! }
! else {
! char uid[16];
! ap_snprintf(uid, sizeof(uid), "user#%lu",
! (unsigned long) r->finfo.st_uid);
! table_set(e, "USER_NAME", uid);
}
! if ((t = strrchr(r->filename, '/'))) {
! table_set(e, "DOCUMENT_NAME", ++t);
! }
! else {
! table_set(e, "DOCUMENT_NAME", r->uri);
! }
if (r->args) {
! char *arg_copy = pstrdup(r->pool, r->args);
! unescape_url(arg_copy);
! table_set(e, "QUERY_STRING_UNESCAPED",
! escape_shell_cmd(r->pool, arg_copy));
}
}
***************
*** 148,156 ****
*/
#define PUT_CHAR(c,r) \
{ \
! outbuf[outind++] = c; \
! if (outind == OUTBUFSIZE) { FLUSH_BUF(r) }; \
! }
/* there SHOULD be some error checking on the return value of
* rwrite, however it is unclear what the API for rwrite returning
--- 156,166 ----
*/
#define PUT_CHAR(c,r) \
{ \
! outbuf[outind++] = c; \
! if (outind == OUTBUFSIZE) { \
! FLUSH_BUF(r) \
! }; \
! }
/* there SHOULD be some error checking on the return value of
* rwrite, however it is unclear what the API for rwrite returning
***************
*** 176,214 ****
#define GET_CHAR(f,c,ret,r) \
{ \
int i = getc(f); \
! if(i == EOF) { /* either EOF or error -- needs error handling if latter */ \
! if (ferror(f)) \
! fprintf(stderr, "encountered error in GET_CHAR macro, mod_include.\n"); \
FLUSH_BUF(r); \
! pfclose(r->pool,f); \
return ret; \
} \
c = (char)i; \
}
! int find_string(FILE *in,char *str, request_rec *r, int printing) {
! int x,l=strlen(str),p;
char outbuf[OUTBUFSIZE];
int outind = 0;
char c;
! p=0;
! while(1) {
! GET_CHAR(in,c,1,r);
! if(c == str[p]) {
! if((++p) == l) {
! FLUSH_BUF(r);
return 0;
! }
}
else {
if (printing) {
! for(x=0;xpool, f); \
return ret; \
} \
c = (char)i; \
}
! static int find_string(FILE *in, const char *str, request_rec *r, int printing)
! {
! int x, l = strlen(str), p;
char outbuf[OUTBUFSIZE];
int outind = 0;
char c;
! p = 0;
! while (1) {
! GET_CHAR(in, c, 1, r);
! if (c == str[p]) {
! if ((++p) == l) {
! FLUSH_BUF(r);
return 0;
! }
}
else {
if (printing) {
! for (x = 0; x < p; x++) {
! PUT_CHAR(str[x], r);
}
! PUT_CHAR(c, r);
}
! p = 0;
}
}
}
***************
*** 219,228 ****
#define GET_CHAR(f,c,r,p) \
{ \
int i = getc(f); \
! if(i == EOF) { /* either EOF or error -- needs error handling if latter */ \
! if (ferror(f)) \
! fprintf(stderr, "encountered error in GET_CHAR macro, mod_include.\n"); \
! pfclose(p,f); \
return r; \
} \
c = (char)i; \
--- 232,243 ----
#define GET_CHAR(f,c,r,p) \
{ \
int i = getc(f); \
! if (i == EOF) { /* either EOF or error -- needs error handling if latter */ \
! if (ferror(f)) { \
! fprintf(stderr, "encountered error in GET_CHAR macro, " \
! "mod_include.\n"); \
! } \
! pfclose(p, f); \
return r; \
} \
c = (char)i; \
***************
*** 244,312 ****
/* The following is a shrinking transformation, therefore safe. */
! static void
! decodehtml(char *s)
{
int val, i, j;
! char *p=s;
! char *ents;
! static char *entlist[MAXENTLEN+1]={
! NULL, /* 0 */
! NULL, /* 1 */
! "lt\074gt\076", /* 2 */
! "amp\046ETH\320eth\360", /* 3 */
! "quot\042Auml\304Euml\313Iuml\317Ouml\326Uuml\334auml\344euml\353\
! iuml\357ouml\366uuml\374yuml\377", /* 4 */
! "Acirc\302Aring\305AElig\306Ecirc\312Icirc\316Ocirc\324Ucirc\333\
THORN\336szlig\337acirc\342aring\345aelig\346ecirc\352icirc\356ocirc\364\
! ucirc\373thorn\376", /* 5 */
! "Agrave\300Aacute\301Atilde\303Ccedil\307Egrave\310Eacute\311\
Igrave\314Iacute\315Ntilde\321Ograve\322Oacute\323Otilde\325Oslash\330\
Ugrave\331Uacute\332Yacute\335agrave\340aacute\341atilde\343ccedil\347\
egrave\350eacute\351igrave\354iacute\355ntilde\361ograve\362oacute\363\
! otilde\365oslash\370ugrave\371uacute\372yacute\375" /* 6 */
};
for (; *s != '\0'; s++, p++) {
! if (*s != '&') {
! *p = *s;
! continue;
! }
! /* find end of entity */
! for (i=1; s[i] != ';' && s[i] != '\0'; i++)
! continue;
!
! if (s[i] == '\0') { /* treat as normal data */
! *p = *s;
! continue;
! }
! /* is it numeric ? */
! if (s[1] == '#') {
! for (j=2, val=0; j < i && isdigit(s[j]); j++)
! val = val * 10 + s[j] - '0';
! s += i;
! if (j < i || val <= 8 || (val >= 11 && val <= 31) ||
! (val >= 127 && val <= 160) || val >= 256)
! p--; /* no data to output */
! else
! *p = val;
! } else{
! j = i-1;
! if (i-1 > MAXENTLEN || entlist[i-1] == NULL) { /* wrong length */
! *p = '&';
! continue; /* skip it */
! }
! for (ents=entlist[i-1]; *ents != '\0'; ents += i)
! if (strncmp(s+1, ents, i-1) == 0) break;
! if (*ents == '\0')
! *p = '&'; /* unknown */
! else {
! *p = ((const unsigned char *)ents)[i-1];
! s += i;
! }
! }
}
*p = '\0';
--- 259,337 ----
/* The following is a shrinking transformation, therefore safe. */
! static void decodehtml(char *s)
{
int val, i, j;
! char *p = s;
! const char *ents;
! static const char * const entlist[MAXENTLEN + 1] =
! {
! NULL, /* 0 */
! NULL, /* 1 */
! "lt\074gt\076", /* 2 */
! "amp\046ETH\320eth\360", /* 3 */
! "quot\042Auml\304Euml\313Iuml\317Ouml\326Uuml\334auml\344euml\353\
! iuml\357ouml\366uuml\374yuml\377", /* 4 */
! "Acirc\302Aring\305AElig\306Ecirc\312Icirc\316Ocirc\324Ucirc\333\
THORN\336szlig\337acirc\342aring\345aelig\346ecirc\352icirc\356ocirc\364\
! ucirc\373thorn\376", /* 5 */
! "Agrave\300Aacute\301Atilde\303Ccedil\307Egrave\310Eacute\311\
Igrave\314Iacute\315Ntilde\321Ograve\322Oacute\323Otilde\325Oslash\330\
Ugrave\331Uacute\332Yacute\335agrave\340aacute\341atilde\343ccedil\347\
egrave\350eacute\351igrave\354iacute\355ntilde\361ograve\362oacute\363\
! otilde\365oslash\370ugrave\371uacute\372yacute\375" /* 6 */
};
for (; *s != '\0'; s++, p++) {
! if (*s != '&') {
! *p = *s;
! continue;
! }
! /* find end of entity */
! for (i = 1; s[i] != ';' && s[i] != '\0'; i++) {
! continue;
! }
! if (s[i] == '\0') { /* treat as normal data */
! *p = *s;
! continue;
! }
! /* is it numeric ? */
! if (s[1] == '#') {
! for (j = 2, val = 0; j < i && isdigit(s[j]); j++) {
! val = val * 10 + s[j] - '0';
! }
! s += i;
! if (j < i || val <= 8 || (val >= 11 && val <= 31) ||
! (val >= 127 && val <= 160) || val >= 256) {
! p--; /* no data to output */
! }
! else {
! *p = val;
! }
! }
! else {
! j = i - 1;
! if (i - 1 > MAXENTLEN || entlist[i - 1] == NULL) {
! /* wrong length */
! *p = '&';
! continue; /* skip it */
! }
! for (ents = entlist[i - 1]; *ents != '\0'; ents += i) {
! if (strncmp(s + 1, ents, i - 1) == 0) {
! break;
! }
! }
!
! if (*ents == '\0') {
! *p = '&'; /* unknown */
! }
! else {
! *p = ((const unsigned char *) ents)[i - 1];
! s += i;
! }
! }
}
*p = '\0';
***************
*** 318,414 ****
* the tag value is html decoded if dodecode is non-zero
*/
! static char *
! get_tag(pool *p, FILE *in, char *tag, int tagbuf_len, int dodecode) {
char *t = tag, *tag_val, c, term;
- int n;
! n = 0;
! do { /* skip whitespace */
! GET_CHAR(in,c,NULL,p);
} while (isspace(c));
/* tags can't start with - */
! if(c == '-') {
! GET_CHAR(in,c,NULL,p);
! if(c == '-') {
do {
! GET_CHAR(in,c,NULL,p);
! } while (isspace(c));
! if(c == '>') {
! strncpy(tag,"done", tagbuf_len-1);
! tag[tagbuf_len-1] = '\0';
return tag;
}
}
! return NULL; /* failed */
}
/* find end of tag name */
! while(1) {
! if(++n == tagbuf_len) {
! t[tagbuf_len - 1] = '\0';
return NULL;
}
! if(c == '=' || isspace(c)) break;
! *(t++) = tolower(c);
! GET_CHAR(in,c,NULL,p);
}
*t++ = '\0';
tag_val = t;
! while (isspace(c)) GET_CHAR(in, c, NULL,p); /* space before = */
if (c != '=') {
ungetc(c, in);
return NULL;
}
do {
! GET_CHAR(in,c,NULL,p); /* space after = */
} while (isspace(c));
/* we should allow a 'name' as a value */
!
! if (c != '"' && c != '\'') return NULL;
term = c;
! while(1) {
! GET_CHAR(in,c,NULL,p);
! if(++n == tagbuf_len) {
! t[tagbuf_len - 1] = '\0';
! return NULL;
! }
/* Want to accept \" as a valid character within a string. */
! if (c == '\\') {
! *(t++) = c; /* Add backslash */
! GET_CHAR(in,c,NULL,p);
! if (c == term) /* Only if */
! *(--t) = c; /* Replace backslash ONLY for terminator */
! } else if (c == term) break;
! *(t++) = c;
}
*t = '\0';
! if (dodecode) decodehtml(tag_val);
! return pstrdup (p, tag_val);
}
! static int
! get_directive(FILE *in, char *d, pool *p) {
char c;
/* skip initial whitespace */
! while(1) {
! GET_CHAR(in,c,1,p);
! if(!isspace(c))
break;
}
/* now get directive */
! while(1) {
*d++ = tolower(c);
! GET_CHAR(in,c,1,p);
! if(isspace(c))
break;
}
*d = '\0';
return 0;
--- 343,459 ----
* the tag value is html decoded if dodecode is non-zero
*/
! static char *get_tag(pool *p, FILE *in, char *tag, int tagbuf_len, int dodecode)
! {
char *t = tag, *tag_val, c, term;
! /* makes code below a little less cluttered */
! --tagbuf_len;
! do { /* skip whitespace */
! GET_CHAR(in, c, NULL, p);
} while (isspace(c));
/* tags can't start with - */
! if (c == '-') {
! GET_CHAR(in, c, NULL, p);
! if (c == '-') {
do {
! GET_CHAR(in, c, NULL, p);
! } while (isspace(c));
! if (c == '>') {
! safe_copy(tag, "done", tagbuf_len);
return tag;
}
}
! return NULL; /* failed */
}
/* find end of tag name */
! while (1) {
! if (t - tag == tagbuf_len) {
! *t = '\0';
return NULL;
+ }
+ if (c == '=' || isspace(c)) {
+ break;
}
! *(t++) = tolower(c);
! GET_CHAR(in, c, NULL, p);
}
*t++ = '\0';
tag_val = t;
! while (isspace(c)) {
! GET_CHAR(in, c, NULL, p); /* space before = */
! }
if (c != '=') {
ungetc(c, in);
return NULL;
}
do {
! GET_CHAR(in, c, NULL, p); /* space after = */
} while (isspace(c));
/* we should allow a 'name' as a value */
!
! if (c != '"' && c != '\'') {
! return NULL;
! }
term = c;
! while (1) {
! GET_CHAR(in, c, NULL, p);
! if (t - tag == tagbuf_len) {
! *t = '\0';
! return NULL;
! }
/* Want to accept \" as a valid character within a string. */
! if (c == '\\') {
! *(t++) = c; /* Add backslash */
! GET_CHAR(in, c, NULL, p);
! if (c == term) { /* Only if */
! *(--t) = c; /* Replace backslash ONLY for terminator */
! }
! }
! else if (c == term) {
! break;
! }
! *(t++) = c;
}
*t = '\0';
! if (dodecode) {
! decodehtml(tag_val);
! }
! return pstrdup(p, tag_val);
}
! static int get_directive(FILE *in, char *dest, size_t len, pool *p)
! {
! char *d = dest;
char c;
+ /* make room for nul terminator */
+ --len;
+
/* skip initial whitespace */
! while (1) {
! GET_CHAR(in, c, 1, p);
! if (!isspace(c)) {
break;
+ }
}
/* now get directive */
! while (1) {
! if (d - dest == len) {
! return 1;
! }
*d++ = tolower(c);
! GET_CHAR(in, c, 1, p);
! if (isspace(c)) {
break;
+ }
}
*d = '\0';
return 0;
***************
*** 417,489 ****
/*
* Do variable substitution on strings
*/
! void parse_string(request_rec *r, char *in, char *out, int length,
! int leave_name)
{
char ch;
char *next = out;
! int numchars = 0;
while ((ch = *in++) != '\0') {
! switch(ch) {
! case '\\':
! if(*in == '$')
! *next++=*in++;
! else
! *next++=ch;
! break;
! case '$':
! {
! char var[MAX_STRING_LEN];
! char vtext[MAX_STRING_LEN];
! char *val;
! int braces=0;
! int vlen, vtlen;
! /*
! * Keep the $ and { around because we do no substitution
! * if the variable isn't found
! */
! vlen = vtlen = 0;
! vtext[vtlen++] = ch;
! if (*in == '{') { braces = 1; vtext[vtlen++] = *in++; }
! while (*in != '\0') {
! if (vlen == (MAX_STRING_LEN - 1)) continue;
! if (braces == 1) {
! if (*in == '}') break;
! }
! else if (! (isalpha((int)*in) || (*in == '_') || isdigit((int)*in)) ) break;
! if (vtlen < (MAX_STRING_LEN - 1)) vtext[vtlen++] = *in;
! var[vlen++] = *in++;
! }
! var[vlen] = vtext[vtlen] = '\0';
! if (braces == 1) {
! if (*in != '}') {
! log_printf(r->server, "Invalid variable \"%s%s\"", vtext,in);
! *next = '\0';
! return;
! } else
! in++;
! }
!
! val = (char *)NULL;
! if (var[0] == '\0') {
! val = &vtext[0];
! } else {
! val = table_get (r->subprocess_env, &var[0]);
! if (!val && leave_name)
! val = &vtext[0];
! }
! while ((val != (char *)NULL) && (*val != '\0')) {
! *next++ = *val++;
! if (++numchars == (length -1)) break;
}
break;
! }
! default:
*next++ = ch;
break;
}
- if (++numchars == (length -1)) break;
}
*next = '\0';
return;
--- 462,556 ----
/*
* Do variable substitution on strings
*/
! static void parse_string(request_rec *r, const char *in, char *out,
! size_t length, int leave_name)
{
char ch;
char *next = out;
! char *end_out;
!
! /* leave room for nul terminator */
! end_out = out + length - 1;
while ((ch = *in++) != '\0') {
! switch (ch) {
! case '\\':
! if (next == end_out) {
! /* truncated */
! *next = '\0';
! return;
! }
! if (*in == '$') {
! *next++ = *in++;
! }
! else {
! *next++ = ch;
}
break;
! case '$':
! {
! char var[MAX_STRING_LEN];
! const char *start_of_var_name;
! const char *end_of_var_name; /* end of var name + 1 */
! const char *expansion;
! const char *val;
! size_t l;
!
! /* guess that the expansion won't happen */
! expansion = in - 1;
! if (*in == '{') {
! ++in;
! start_of_var_name = in;
! in = strchr(in, '}');
! if (in == NULL) {
! log_printf(r->server,
! "Missing '}' on variable \"%s\" in %s",
! expansion, r->filename);
! *next = '\0';
! return;
! }
! end_of_var_name = in;
! ++in;
! }
! else {
! start_of_var_name = in;
! while (isalnum(*in) || *in == '_') {
! ++in;
! }
! end_of_var_name = in;
! }
! /* what a pain, too bad there's no table_getn where you can
! * pass a non-nul terminated string */
! l = end_of_var_name - start_of_var_name;
! l = (l > sizeof(var) - 1) ? (sizeof(var) - 1) : l;
! memcpy(var, start_of_var_name, l);
! var[l] = '\0';
!
! val = table_get(r->subprocess_env, var);
! if (val) {
! expansion = val;
! l = strlen(expansion);
! }
! else if (leave_name) {
! l = in - expansion;
! }
! else {
! break; /* no expansion to be done */
! }
! l = (l > end_out - next) ? (end_out - next) : l;
! memcpy(next, expansion, l);
! next += l;
! break;
! }
! default:
! if (next == end_out) {
! /* truncated */
! *next = '\0';
! return;
! }
*next++ = ch;
break;
}
}
*next = '\0';
return;
***************
*** 491,512 ****
/* --------------------------- Action handlers ---------------------------- */
! int include_cgi(char *s, request_rec *r)
{
! request_rec *rr = sub_req_lookup_uri (s, r);
!
! if (rr->status != 200) return -1;
!
/* No hardwired path info or query allowed */
!
! if ((rr->path_info && rr->path_info[0]) || rr->args) return -1;
! if (rr->finfo.st_mode == 0) return -1;
/* Script gets parameters of the *document*, for back compatibility */
!
! rr->path_info = r->path_info; /* painful to get right; see mod_cgi.c */
rr->args = r->args;
!
/* Force sub_req to be treated as a CGI request, even if ordinary
* typing rules would have called it something else.
*/
--- 558,586 ----
/* --------------------------- Action handlers ---------------------------- */
! static int include_cgi(char *s, request_rec *r)
{
! request_rec *rr = sub_req_lookup_uri(s, r);
! int rr_status;
!
! if (rr->status != HTTP_OK) {
! return -1;
! }
!
/* No hardwired path info or query allowed */
!
! if ((rr->path_info && rr->path_info[0]) || rr->args) {
! return -1;
! }
! if (rr->finfo.st_mode == 0) {
! return -1;
! }
/* Script gets parameters of the *document*, for back compatibility */
!
! rr->path_info = r->path_info; /* hard to get right; see mod_cgi.c */
rr->args = r->args;
!
/* Force sub_req to be treated as a CGI request, even if ordinary
* typing rules would have called it something else.
*/
***************
*** 514,589 ****
rr->content_type = CGI_MAGIC_TYPE;
/* Run it. */
!
! if (run_sub_req (rr) == REDIRECT) {
! char *location = table_get (rr->headers_out, "Location");
location = escape_html(rr->pool, location);
! rvputs(r,"", location, "", NULL);
}
!
! destroy_sub_req (rr);
chdir_file(r->filename);
!
return 0;
}
! int handle_include(FILE *in, request_rec *r, char *error, int noexec) {
char tag[MAX_STRING_LEN];
char parsed_string[MAX_STRING_LEN];
char *tag_val;
! while(1) {
! if(!(tag_val = get_tag(r->pool, in, tag, MAX_STRING_LEN, 1)))
return 1;
! if(!strcmp(tag,"file") || !strcmp (tag, "virtual")) {
! request_rec *rr=NULL;
! char *error_fmt = NULL;
!
! parse_string(r, tag_val, parsed_string, MAX_STRING_LEN, 0);
! if (tag[0] == 'f')
! { /* be safe; only files in this directory or below allowed */
! char tmp[MAX_STRING_LEN+2];
! ap_snprintf(tmp, sizeof(tmp), "/%s/", parsed_string);
! if (parsed_string[0] == '/' || strstr(tmp, "/../") != NULL)
! error_fmt = "unable to include file \"%s\" in parsed file %s";
! else
! rr = sub_req_lookup_file (parsed_string, r);
! } else
! rr = sub_req_lookup_uri (parsed_string, r);
!
! if (!error_fmt && rr->status != 200)
! error_fmt = "unable to include \"%s\" in parsed file %s";
!
! if (!error_fmt && noexec && rr->content_type
! && (strncmp (rr->content_type, "text/", 5)))
! error_fmt =
! "unable to include potential exec \"%s\" in parsed file %s";
! if (error_fmt == NULL)
! {
request_rec *p;
! for (p=r; p != NULL; p=p->main)
! if (strcmp(p->filename, rr->filename) == 0) break;
! if (p != NULL)
! error_fmt = "Recursive include of \"%s\" in parsed file %s";
! }
!
! if (!error_fmt && run_sub_req (rr))
! error_fmt = "unable to include \"%s\" in parsed file %s";
! chdir_file(r->filename);
!
if (error_fmt) {
log_printf(r->server, error_fmt, tag_val, r->filename);
rputs(error, r);
! }
! if (rr != NULL) destroy_sub_req (rr);
! }
! else if(!strcmp(tag,"done"))
return 0;
else {
! log_printf(r->server, "unknown parameter \"%s\" to tag include in %s",
! tag, r->filename);
rputs(error, r);
}
}
--- 588,704 ----
rr->content_type = CGI_MAGIC_TYPE;
/* Run it. */
!
! rr_status = run_sub_req(rr);
! if (is_HTTP_REDIRECT(rr_status)) {
! char *location = table_get(rr->headers_out, "Location");
location = escape_html(rr->pool, location);
! rvputs(r, "", location, "", NULL);
}
!
! destroy_sub_req(rr);
chdir_file(r->filename);
!
return 0;
}
! /* ensure that path is relative, and does not contain ".." elements
! * ensentially ensure that it does not match the regex:
! * (^/|(^|/)\.\.(/|$))
! * XXX: this needs os abstraction... consider c:..\foo in win32
! */
! static int is_only_below(const char *path)
! {
! if (path[0] == '/') {
! return 0;
! }
! if (path[0] == '.' && path[1] == '.'
! && (path[2] == '\0' || path[2] == '/')) {
! return 0;
! }
! while (*path) {
! if (*path == '/' && path[1] == '.' && path[2] == '.'
! && (path[3] == '\0' || path[3] == '/')) {
! return 0;
! }
! ++path;
! }
! return 1;
! }
!
! static int handle_include(FILE *in, request_rec *r, const char *error, int noexec)
! {
char tag[MAX_STRING_LEN];
char parsed_string[MAX_STRING_LEN];
char *tag_val;
! while (1) {
! if (!(tag_val = get_tag(r->pool, in, tag, sizeof(tag), 1))) {
return 1;
! }
! if (!strcmp(tag, "file") || !strcmp(tag, "virtual")) {
! request_rec *rr = NULL;
! char *error_fmt = NULL;
!
! parse_string(r, tag_val, parsed_string, sizeof(parsed_string), 0);
! if (tag[0] == 'f') {
! /* be safe; only files in this directory or below allowed */
! if (!is_only_below(parsed_string)) {
! error_fmt = "unable to include file \"%s\" "
! "in parsed file %s";
! }
! else {
! rr = sub_req_lookup_file(parsed_string, r);
! }
! }
! else {
! rr = sub_req_lookup_uri(parsed_string, r);
! }
!
! if (!error_fmt && rr->status != HTTP_OK) {
! error_fmt = "unable to include \"%s\" in parsed file %s";
! }
!
! if (!error_fmt && noexec && rr->content_type
! && (strncmp(rr->content_type, "text/", 5))) {
! error_fmt = "unable to include potential exec \"%s\" "
! "in parsed file %s";
! }
! if (error_fmt == NULL) {
request_rec *p;
! for (p = r; p != NULL; p = p->main) {
! if (strcmp(p->filename, rr->filename) == 0) {
! break;
! }
! }
! if (p != NULL) {
! error_fmt = "Recursive include of \"%s\" "
! "in parsed file %s";
! }
! }
!
! if (!error_fmt && run_sub_req(rr)) {
! error_fmt = "unable to include \"%s\" in parsed file %s";
! }
! chdir_file(r->filename);
!
if (error_fmt) {
log_printf(r->server, error_fmt, tag_val, r->filename);
rputs(error, r);
! }
! if (rr != NULL) {
! destroy_sub_req(rr);
! }
! }
! else if (!strcmp(tag, "done")) {
return 0;
+ }
else {
! log_printf(r->server,
! "unknown parameter \"%s\" to tag include in %s",
! tag, r->filename);
rputs(error, r);
}
}
***************
*** 594,763 ****
char *s;
} include_cmd_arg;
! void include_cmd_child (void *arg)
{
! request_rec *r = ((include_cmd_arg *)arg)->r;
! char *s = ((include_cmd_arg *)arg)->s;
table *env = r->subprocess_env;
! #ifdef DEBUG_INCLUDE_CMD
! FILE *dbg = fopen ("/dev/tty", "w");
! #endif
! char err_string [MAX_STRING_LEN];
! #ifdef DEBUG_INCLUDE_CMD
#ifdef __EMX__
/* under OS/2 /dev/tty is referenced as con */
! FILE *dbg = fopen ("con", "w");
#else
! fprintf (dbg, "Attempting to include command '%s'\n", s);
! #endif
! #endif
! if (r->path_info && r->path_info[0] != '\0')
! {
! request_rec *pa_req;
! table_set (env, "PATH_INFO", escape_shell_cmd (r->pool, r->path_info));
!
! pa_req = sub_req_lookup_uri(escape_uri(r->pool, r->path_info), r);
! if (pa_req->filename)
! table_set(env, "PATH_TRANSLATED",
! pstrcat(r->pool, pa_req->filename, pa_req->path_info,
! NULL));
}
if (r->args) {
! char *arg_copy = pstrdup (r->pool, r->args);
! table_set (env, "QUERY_STRING", r->args);
! unescape_url (arg_copy);
! table_set (env, "QUERY_STRING_UNESCAPED",
! escape_shell_cmd (r->pool, arg_copy));
! }
!
! error_log2stderr (r->server);
!
! #ifdef DEBUG_INCLUDE_CMD
! fprintf (dbg, "Attempting to exec '%s'\n", s);
! #endif
cleanup_for_exec();
/* set shellcmd flag to pass arg to SHELL_PATH */
! call_exec(r, s, create_environment (r->pool, env), 1);
!
/* Oh, drat. We're still here. The log file descriptors are closed,
* so we have to whimper a complaint onto stderr...
*/
!
! #ifdef DEBUG_INCLUDE_CMD
! fprintf (dbg, "Exec failed\n");
! #endif
ap_snprintf(err_string, sizeof(err_string),
! "httpd: exec of %s failed, reason: %s (errno = %d)\n",
! SHELL_PATH, strerror(errno), errno);
! write (2, err_string, strlen(err_string));
exit(0);
}
! int include_cmd(char *s, request_rec *r) {
include_cmd_arg arg;
FILE *f;
! arg.r = r; arg.s = s;
! if (!spawn_child (r->pool, include_cmd_child, &arg,
! kill_after_timeout, NULL, &f))
return -1;
!
! send_fd(f,r);
! pfclose(r->pool, f); /* will wait for zombie when
! * r->pool is cleared
! */
return 0;
}
! int handle_exec(FILE *in, request_rec *r, char *error)
{
char tag[MAX_STRING_LEN];
char *tag_val;
char *file = r->filename;
char parsed_string[MAX_STRING_LEN];
! while(1) {
! if(!(tag_val = get_tag (r->pool, in, tag, MAX_STRING_LEN, 1)))
return 1;
! if(!strcmp(tag,"cmd")) {
! parse_string(r, tag_val, parsed_string, MAX_STRING_LEN, 1);
! if(include_cmd(parsed_string, r) == -1) {
! log_printf(r->server, "execution failure for parameter \"%s\" to tag exec in file %s",
! tag, r->filename);
rputs(error, r);
}
/* just in case some stooge changed directories */
chdir_file(r->filename);
! }
! else if(!strcmp(tag,"cgi")) {
! parse_string(r, tag_val, parsed_string, MAX_STRING_LEN, 0);
! if(include_cgi(parsed_string, r) == -1) {
! log_printf(r->server, "invalid CGI ref \"%s\" in %s",tag_val,file);
rputs(error, r);
}
/* grumble groan */
chdir_file(r->filename);
}
! else if(!strcmp(tag,"done"))
return 0;
else {
! log_printf(r->server, "unknown parameter \"%s\" to tag exec in %s",
! tag, file);
rputs(error, r);
}
}
}
! int handle_echo (FILE *in, request_rec *r, char *error) {
char tag[MAX_STRING_LEN];
char *tag_val;
! while(1) {
! if(!(tag_val = get_tag (r->pool, in, tag, MAX_STRING_LEN, 1)))
return 1;
! if(!strcmp(tag,"var")) {
! char *val = table_get (r->subprocess_env, tag_val);
! if (val) rputs(val, r);
! else rputs("(none)", r);
! } else if(!strcmp(tag,"done"))
return 0;
else {
! log_printf(r->server, "unknown parameter \"%s\" to tag echo in %s",
! tag, r->filename);
rputs(error, r);
}
}
}
#ifdef USE_PERL_SSI
! int handle_perl (FILE *in, request_rec *r, char *error) {
char tag[MAX_STRING_LEN];
char *tag_val;
SV *sub = Nullsv;
! AV *av = newAV();
! if (!(allow_options (r) & OPT_INCLUDES)) {
log_printf(r->server,
! "httpd: #perl SSI disallowed by IncludesNoExec in %s", r->filename);
! return DECLINED;
}
! while(1) {
! if(!(tag_val = get_tag (r->pool, in, tag, MAX_STRING_LEN, 1)))
! break;
! if(strnEQ(tag, "sub", 3))
! sub = newSVpv(tag_val,0);
! else if(strnEQ(tag, "arg", 3))
! av_push(av, newSVpv(tag_val,0));
! else if(strnEQ(tag,"done", 4))
! break;
}
perl_stdout2client(r);
perl_call_handler(sub, r, av);
--- 709,902 ----
char *s;
} include_cmd_arg;
! static void include_cmd_child(void *arg)
{
! request_rec *r = ((include_cmd_arg *) arg)->r;
! char *s = ((include_cmd_arg *) arg)->s;
table *env = r->subprocess_env;
! #ifdef DEBUG_INCLUDE_CMD
! FILE *dbg = fopen("/dev/tty", "w");
! #endif
! char err_string[MAX_STRING_LEN];
! #ifdef DEBUG_INCLUDE_CMD
#ifdef __EMX__
/* under OS/2 /dev/tty is referenced as con */
! FILE *dbg = fopen("con", "w");
#else
! fprintf(dbg, "Attempting to include command '%s'\n", s);
! #endif
! #endif
! if (r->path_info && r->path_info[0] != '\0') {
! request_rec *pa_req;
!
! table_set(env, "PATH_INFO", escape_shell_cmd(r->pool, r->path_info));
! pa_req = sub_req_lookup_uri(escape_uri(r->pool, r->path_info), r);
! if (pa_req->filename) {
! table_set(env, "PATH_TRANSLATED",
! pstrcat(r->pool, pa_req->filename, pa_req->path_info,
! NULL));
! }
}
if (r->args) {
! char *arg_copy = pstrdup(r->pool, r->args);
!
! table_set(env, "QUERY_STRING", r->args);
! unescape_url(arg_copy);
! table_set(env, "QUERY_STRING_UNESCAPED",
! escape_shell_cmd(r->pool, arg_copy));
! }
! error_log2stderr(r->server);
!
! #ifdef DEBUG_INCLUDE_CMD
! fprintf(dbg, "Attempting to exec '%s'\n", s);
! #endif
cleanup_for_exec();
/* set shellcmd flag to pass arg to SHELL_PATH */
! call_exec(r, s, create_environment(r->pool, env), 1);
/* Oh, drat. We're still here. The log file descriptors are closed,
* so we have to whimper a complaint onto stderr...
*/
!
! #ifdef DEBUG_INCLUDE_CMD
! fprintf(dbg, "Exec failed\n");
! #endif
ap_snprintf(err_string, sizeof(err_string),
! "httpd: exec of %s failed, reason: %s (errno = %d)\n",
! SHELL_PATH, strerror(errno), errno);
! write(STDERR_FILENO, err_string, strlen(err_string));
exit(0);
}
! static int include_cmd(char *s, request_rec *r)
! {
include_cmd_arg arg;
FILE *f;
! arg.r = r;
! arg.s = s;
! if (!spawn_child(r->pool, include_cmd_child, &arg,
! kill_after_timeout, NULL, &f)) {
return -1;
! }
!
! send_fd(f, r);
! pfclose(r->pool, f); /* will wait for zombie when
! * r->pool is cleared
! */
return 0;
}
! static int handle_exec(FILE *in, request_rec *r, const char *error)
{
char tag[MAX_STRING_LEN];
char *tag_val;
char *file = r->filename;
char parsed_string[MAX_STRING_LEN];
! while (1) {
! if (!(tag_val = get_tag(r->pool, in, tag, sizeof(tag), 1))) {
return 1;
! }
! if (!strcmp(tag, "cmd")) {
! parse_string(r, tag_val, parsed_string, sizeof(parsed_string), 1);
! if (include_cmd(parsed_string, r) == -1) {
! log_printf(r->server,
! "execution failure for parameter \"%s\" "
! "to tag exec in file %s",
! tag, r->filename);
rputs(error, r);
}
/* just in case some stooge changed directories */
chdir_file(r->filename);
! }
! else if (!strcmp(tag, "cgi")) {
! parse_string(r, tag_val, parsed_string, sizeof(parsed_string), 0);
! if (include_cgi(parsed_string, r) == -1) {
! log_printf(r->server,
! "invalid CGI ref \"%s\" in %s", tag_val, file);
rputs(error, r);
}
/* grumble groan */
chdir_file(r->filename);
}
! else if (!strcmp(tag, "done")) {
return 0;
+ }
else {
! log_printf(r->server,
! "unknown parameter \"%s\" to tag exec in %s",
! tag, file);
rputs(error, r);
}
}
}
! static int handle_echo(FILE *in, request_rec *r, const char *error)
! {
char tag[MAX_STRING_LEN];
char *tag_val;
! while (1) {
! if (!(tag_val = get_tag(r->pool, in, tag, sizeof(tag), 1))) {
return 1;
! }
! if (!strcmp(tag, "var")) {
! char *val = table_get(r->subprocess_env, tag_val);
! if (val) {
! rputs(val, r);
! }
! else {
! rputs("(none)", r);
! }
! }
! else if (!strcmp(tag, "done")) {
return 0;
+ }
else {
! log_printf(r->server,
! "unknown parameter \"%s\" to tag echo in %s",
! tag, r->filename);
rputs(error, r);
}
}
}
+
#ifdef USE_PERL_SSI
! static int handle_perl(FILE *in, request_rec *r, const char *error)
! {
char tag[MAX_STRING_LEN];
char *tag_val;
SV *sub = Nullsv;
! AV *av = newAV();
! if (!(allow_options(r) & OPT_INCLUDES)) {
log_printf(r->server,
! "httpd: #perl SSI disallowed by IncludesNoExec in %s",
! r->filename);
! return DECLINED;
}
! while (1) {
! if (!(tag_val = get_tag(r->pool, in, tag, sizeof(tag), 1))) {
! break;
! }
! if (strnEQ(tag, "sub", 3)) {
! sub = newSVpv(tag_val, 0);
! }
! else if (strnEQ(tag, "arg", 3)) {
! av_push(av, newSVpv(tag_val, 0));
! }
! else if (strnEQ(tag, "done", 4)) {
! break;
! }
}
perl_stdout2client(r);
perl_call_handler(sub, r, av);
***************
*** 768,891 ****
/* error and tf must point to a string with room for at
* least MAX_STRING_LEN characters
*/
! int handle_config(FILE *in, request_rec *r, char *error, char *tf,
! int *sizefmt) {
char tag[MAX_STRING_LEN];
char *tag_val;
char parsed_string[MAX_STRING_LEN];
table *env = r->subprocess_env;
! while(1) {
! if(!(tag_val = get_tag(r->pool, in, tag, MAX_STRING_LEN, 0)))
return 1;
! if(!strcmp(tag,"errmsg")) {
! parse_string(r, tag_val, parsed_string, MAX_STRING_LEN, 0);
! strncpy(error,parsed_string,MAX_STRING_LEN-1);
! error[MAX_STRING_LEN-1] = '\0';
! } else if(!strcmp(tag,"timefmt")) {
! time_t date = r->request_time;
! parse_string(r, tag_val, parsed_string, MAX_STRING_LEN, 0);
! strncpy(tf,parsed_string,MAX_STRING_LEN-1);
! tf[MAX_STRING_LEN-1] = '\0';
! table_set (env, "DATE_LOCAL", ht_time(r->pool,date,tf,0));
! table_set (env, "DATE_GMT", ht_time(r->pool,date,tf,1));
! table_set (env, "LAST_MODIFIED", ht_time(r->pool,r->finfo.st_mtime,tf,0));
! }
! else if(!strcmp(tag,"sizefmt")) {
! parse_string(r, tag_val, parsed_string, MAX_STRING_LEN, 0);
! decodehtml(parsed_string);
! if(!strcmp(parsed_string,"bytes"))
*sizefmt = SIZEFMT_BYTES;
! else if(!strcmp(parsed_string,"abbrev"))
*sizefmt = SIZEFMT_KMG;
! }
! else if(!strcmp(tag,"done"))
return 0;
else {
! log_printf(r->server,"unknown parameter \"%s\" to tag config in %s",
! tag, r->filename);
rputs(error, r);
}
}
}
-
! int find_file(request_rec *r, char *directive, char *tag,
! char *tag_val, struct stat *finfo, char *error)
{
- char *dir = "./";
char *to_send;
! if(!strcmp(tag,"file")) {
! getparents(tag_val); /* get rid of any nasties */
! to_send = make_full_path (r->pool, dir, tag_val);
! if(stat(to_send,finfo) == -1) {
log_printf(r->server,
! "unable to get information about \"%s\" in parsed file %s",
! to_send, r->filename);
rputs(error, r);
return -1;
}
return 0;
}
! else if(!strcmp(tag,"virtual")) {
! request_rec *rr = sub_req_lookup_uri (tag_val, r);
!
! if (rr->status == 200 && rr->finfo.st_mode != 0) {
! memcpy ((char*)finfo, (const char *)&rr->finfo, sizeof (struct stat));
! destroy_sub_req (rr);
! return 0;
! } else {
log_printf(r->server,
! "unable to get information about \"%s\" in parsed file %s",
! tag_val, r->filename);
rputs(error, r);
! destroy_sub_req (rr);
return -1;
}
}
else {
! log_printf(r->server,"unknown parameter \"%s\" to tag %s in %s",
! tag, directive, r->filename);
rputs(error, r);
return -1;
}
}
! int handle_fsize(FILE *in, request_rec *r, char *error, int sizefmt)
{
char tag[MAX_STRING_LEN];
char *tag_val;
struct stat finfo;
char parsed_string[MAX_STRING_LEN];
! while(1) {
! if(!(tag_val = get_tag(r->pool, in, tag, MAX_STRING_LEN, 1)))
return 1;
! else if(!strcmp(tag,"done"))
return 0;
else {
! parse_string(r, tag_val, parsed_string, MAX_STRING_LEN, 0);
! if(!find_file(r,"fsize",tag,parsed_string,&finfo,error)) {
! if(sizefmt == SIZEFMT_KMG) {
send_size(finfo.st_size, r);
}
else {
! int l,x;
#if defined(BSD) && BSD > 199305
! /* ap_snprintf can't handle %qd */
! sprintf(tag,"%qd", finfo.st_size);
#else
! ap_snprintf(tag, sizeof(tag), "%ld",finfo.st_size);
#endif
! l = strlen(tag); /* grrr */
! for(x=0;xsubprocess_env;
! while (1) {
! if (!(tag_val = get_tag(r->pool, in, tag, sizeof(tag), 0))) {
return 1;
! }
! if (!strcmp(tag, "errmsg")) {
! parse_string(r, tag_val, error, MAX_STRING_LEN, 0);
! }
! else if (!strcmp(tag, "timefmt")) {
! time_t date = r->request_time;
!
! parse_string(r, tag_val, tf, MAX_STRING_LEN, 0);
! table_set(env, "DATE_LOCAL", ht_time(r->pool, date, tf, 0));
! table_set(env, "DATE_GMT", ht_time(r->pool, date, tf, 1));
! table_set(env, "LAST_MODIFIED",
! ht_time(r->pool, r->finfo.st_mtime, tf, 0));
! }
! else if (!strcmp(tag, "sizefmt")) {
! parse_string(r, tag_val, parsed_string, sizeof(parsed_string), 0);
! decodehtml(parsed_string);
! if (!strcmp(parsed_string, "bytes")) {
*sizefmt = SIZEFMT_BYTES;
! }
! else if (!strcmp(parsed_string, "abbrev")) {
*sizefmt = SIZEFMT_KMG;
! }
! }
! else if (!strcmp(tag, "done")) {
return 0;
+ }
else {
! log_printf(r->server,
! "unknown parameter \"%s\" to tag config in %s",
! tag, r->filename);
rputs(error, r);
}
}
}
! static int find_file(request_rec *r, const char *directive, const char *tag,
! char *tag_val, struct stat *finfo, const char *error)
{
char *to_send;
! if (!strcmp(tag, "file")) {
! getparents(tag_val); /* get rid of any nasties */
! to_send = make_full_path(r->pool, "./", tag_val);
! if (stat(to_send, finfo) == -1) {
log_printf(r->server,
! "unable to get information about \"%s\" "
! "in parsed file %s",
! to_send, r->filename);
rputs(error, r);
return -1;
}
return 0;
}
! else if (!strcmp(tag, "virtual")) {
! request_rec *rr = sub_req_lookup_uri(tag_val, r);
!
! if (rr->status == HTTP_OK && rr->finfo.st_mode != 0) {
! memcpy((char *) finfo, (const char *) &rr->finfo,
! sizeof(struct stat));
! destroy_sub_req(rr);
! return 0;
! }
! else {
log_printf(r->server,
! "unable to get information about \"%s\" "
! "in parsed file %s",
! tag_val, r->filename);
rputs(error, r);
! destroy_sub_req(rr);
return -1;
}
}
else {
! log_printf(r->server,
! "unknown parameter \"%s\" to tag %s in %s",
! tag, directive, r->filename);
rputs(error, r);
return -1;
}
}
! static int handle_fsize(FILE *in, request_rec *r, const char *error, int sizefmt)
{
char tag[MAX_STRING_LEN];
char *tag_val;
struct stat finfo;
char parsed_string[MAX_STRING_LEN];
! while (1) {
! if (!(tag_val = get_tag(r->pool, in, tag, sizeof(tag), 1))) {
return 1;
! }
! else if (!strcmp(tag, "done")) {
return 0;
+ }
else {
! parse_string(r, tag_val, parsed_string, sizeof(parsed_string), 0);
! if (!find_file(r, "fsize", tag, parsed_string, &finfo, error)) {
! if (sizefmt == SIZEFMT_KMG) {
send_size(finfo.st_size, r);
}
else {
! int l, x;
#if defined(BSD) && BSD > 199305
! /* ap_snprintf can't handle %qd */
! sprintf(tag, "%qd", finfo.st_size);
#else
! ap_snprintf(tag, sizeof(tag), "%ld", finfo.st_size);
#endif
! l = strlen(tag); /* grrr */
! for (x = 0; x < l; x++) {
! if (x && (!((l - x) % 3))) {
rputc(',', r);
}
! rputc(tag[x], r);
}
}
}
***************
*** 893,1028 ****
}
}
! int handle_flastmod(FILE *in, request_rec *r, char *error, char *tf)
{
char tag[MAX_STRING_LEN];
char *tag_val;
struct stat finfo;
char parsed_string[MAX_STRING_LEN];
! while(1) {
! if(!(tag_val = get_tag(r->pool, in, tag, MAX_STRING_LEN, 1)))
return 1;
! else if(!strcmp(tag,"done"))
return 0;
else {
! parse_string(r, tag_val, parsed_string, MAX_STRING_LEN, 0);
! if(!find_file(r,"flastmod",tag,parsed_string,&finfo,error))
rputs(ht_time(r->pool, finfo.st_mtime, tf, 0), r);
}
}
! }
! int re_check(request_rec *r, char *string, char *rexp)
{
regex_t *compiled;
int regex_error;
! compiled = pregcomp (r->pool, rexp, REG_EXTENDED|REG_NOSUB);
if (compiled == NULL) {
log_printf(r->server, "unable to compile pattern \"%s\"", rexp);
return -1;
}
! regex_error = regexec(compiled, string, 0, (regmatch_t *)NULL, 0);
! pregfree (r->pool, compiled);
! return(!regex_error);
}
! enum token_type { token_string,
token_and, token_or, token_not, token_eq, token_ne,
! token_rbrace, token_lbrace, token_group
};
struct token {
enum token_type type;
char value[MAX_STRING_LEN];
};
! char *get_ptoken(request_rec *r, char *string, struct token *token) {
char ch;
! int next=0;
! int qs=0;
/* Skip leading white space */
! if (string == (char *)NULL) return (char *)NULL;
! while ((ch = *string++))
! if (!isspace(ch)) break;
! if (ch == '\0') return (char *)NULL;
! switch(ch) {
! case '(':
token->type = token_lbrace;
! return(string);
! case ')':
token->type = token_rbrace;
! return(string);
! case '=':
token->type = token_eq;
! return(string);
! case '!':
if (*string == '=') {
token->type = token_ne;
! return(string+1);
! } else {
token->type = token_not;
! return(string);
}
! case '\'':
token->type = token_string;
qs = 1;
break;
! case '|':
if (*string == '|') {
token->type = token_or;
! return(string+1);
}
! case '&':
if (*string == '&') {
token->type = token_and;
! return(string+1);
}
! default:
token->type = token_string;
break;
}
/* We should only be here if we are in a string */
! if (!qs) token->value[next++] = ch;
/*
* Yes I know that goto's are BAD. But, c doesn't allow me to
* exit a loop from a switch statement. Yes, I could use a flag,
* but that is (IMHO) even less readable/maintainable than the goto.
! */
/*
* I used the ++string throughout this section so that string
* ends up pointing to the next token and I can just return it
! */
for (ch = *string; ch != '\0'; ch = *++string) {
if (ch == '\\') {
! if ((ch = *++string) == '\0') goto TOKEN_DONE;
token->value[next++] = ch;
continue;
}
if (!qs) {
! if (isspace(ch)) goto TOKEN_DONE;
! switch(ch) {
! case '(': goto TOKEN_DONE;
! case ')': goto TOKEN_DONE;
! case '=': goto TOKEN_DONE;
! case '!': goto TOKEN_DONE;
! case '|': if (*(string+1) == '|') goto TOKEN_DONE;
! case '&': if (*(string+1) == '&') goto TOKEN_DONE;
}
token->value[next++] = ch;
! } else {
! if (ch == '\'') { qs=0; ++string; goto TOKEN_DONE; }
token->value[next++] = ch;
}
}
! TOKEN_DONE:
/* If qs is still set, I have an unmatched ' */
! if (qs) { rputs("\nUnmatched '\n", r); next=0; }
token->value[next] = '\0';
! return(string);
}
--- 1042,1245 ----
}
}
! static int handle_flastmod(FILE *in, request_rec *r, const char *error, const char *tf)
{
char tag[MAX_STRING_LEN];
char *tag_val;
struct stat finfo;
char parsed_string[MAX_STRING_LEN];
! while (1) {
! if (!(tag_val = get_tag(r->pool, in, tag, sizeof(tag), 1))) {
return 1;
! }
! else if (!strcmp(tag, "done")) {
return 0;
+ }
else {
! parse_string(r, tag_val, parsed_string, sizeof(parsed_string), 0);
! if (!find_file(r, "flastmod", tag, parsed_string, &finfo, error)) {
rputs(ht_time(r->pool, finfo.st_mtime, tf, 0), r);
+ }
}
}
! }
! static int re_check(request_rec *r, char *string, char *rexp)
{
regex_t *compiled;
int regex_error;
! compiled = pregcomp(r->pool, rexp, REG_EXTENDED | REG_NOSUB);
if (compiled == NULL) {
log_printf(r->server, "unable to compile pattern \"%s\"", rexp);
return -1;
}
! regex_error = regexec(compiled, string, 0, (regmatch_t *) NULL, 0);
! pregfree(r->pool, compiled);
! return (!regex_error);
}
! enum token_type {
! token_string,
token_and, token_or, token_not, token_eq, token_ne,
! token_rbrace, token_lbrace, token_group,
! token_ge, token_le, token_gt, token_lt
};
struct token {
enum token_type type;
char value[MAX_STRING_LEN];
};
! /* there is an implicit assumption here that string is at most MAX_STRING_LEN-1
! * characters long...
! */
! static const char *get_ptoken(request_rec *r, const char *string, struct token *token)
! {
char ch;
! int next = 0;
! int qs = 0;
/* Skip leading white space */
! if (string == (char *) NULL) {
! return (char *) NULL;
! }
! while ((ch = *string++)) {
! if (!isspace(ch)) {
! break;
! }
! }
! if (ch == '\0') {
! return (char *) NULL;
! }
! token->type = token_string; /* the default type */
! switch (ch) {
! case '(':
token->type = token_lbrace;
! return (string);
! case ')':
token->type = token_rbrace;
! return (string);
! case '=':
token->type = token_eq;
! return (string);
! case '!':
if (*string == '=') {
token->type = token_ne;
! return (string + 1);
! }
! else {
token->type = token_not;
! return (string);
}
! case '\'':
token->type = token_string;
qs = 1;
break;
! case '|':
if (*string == '|') {
token->type = token_or;
! return (string + 1);
}
! break;
! case '&':
if (*string == '&') {
token->type = token_and;
! return (string + 1);
! }
! break;
! case '>':
! if (*string == '=') {
! token->type = token_ge;
! return (string + 1);
! }
! else {
! token->type = token_gt;
! return (string);
! }
! case '<':
! if (*string == '=') {
! token->type = token_le;
! return (string + 1);
! }
! else {
! token->type = token_lt;
! return (string);
}
! default:
token->type = token_string;
break;
}
/* We should only be here if we are in a string */
! if (!qs) {
! token->value[next++] = ch;
! }
/*
* Yes I know that goto's are BAD. But, c doesn't allow me to
* exit a loop from a switch statement. Yes, I could use a flag,
* but that is (IMHO) even less readable/maintainable than the goto.
! */
/*
* I used the ++string throughout this section so that string
* ends up pointing to the next token and I can just return it
! */
for (ch = *string; ch != '\0'; ch = *++string) {
if (ch == '\\') {
! if ((ch = *++string) == '\0') {
! goto TOKEN_DONE;
! }
token->value[next++] = ch;
continue;
}
if (!qs) {
! if (isspace(ch)) {
! goto TOKEN_DONE;
! }
! switch (ch) {
! case '(':
! goto TOKEN_DONE;
! case ')':
! goto TOKEN_DONE;
! case '=':
! goto TOKEN_DONE;
! case '!':
! goto TOKEN_DONE;
! case '|':
! if (*(string + 1) == '|') {
! goto TOKEN_DONE;
! }
! break;
! case '&':
! if (*(string + 1) == '&') {
! goto TOKEN_DONE;
! }
! break;
! case '<':
! goto TOKEN_DONE;
! case '>':
! goto TOKEN_DONE;
}
token->value[next++] = ch;
! }
! else {
! if (ch == '\'') {
! qs = 0;
! ++string;
! goto TOKEN_DONE;
! }
token->value[next++] = ch;
}
}
! TOKEN_DONE:
/* If qs is still set, I have an unmatched ' */
! if (qs) {
! rputs("\nUnmatched '\n", r);
! next = 0;
! }
token->value[next] = '\0';
! return (string);
}
***************
*** 1032,1144 ****
* I absolutely want to make sure that I clean up the memory in all
* cases. And, without rewriting this completely, the easiest way
* is to just branch to the return code which cleans it up.
*/
! int parse_expr(request_rec *r, char *expr, char *error)
{
struct parse_node {
struct parse_node *left, *right, *parent;
struct token token;
int value, done;
! } *root, *current, *new;
! char *parse;
char buffer[MAX_STRING_LEN];
! struct pool *expr_pool;
int retval = 0;
! if ((parse = expr) == (char *)NULL) return(0);
! root = current = (struct parse_node*)NULL;
! if ((expr_pool = make_sub_pool(r->pool)) == (struct pool *)NULL) {
! log_printf(r->server, "out of memory processing file %s", r->filename);
! rputs(error, r);
! return(0);
}
/* Create Parse Tree */
while (1) {
! new = (struct parse_node*)palloc(expr_pool, sizeof (struct parse_node));
! if (new == (struct parse_node*)NULL) {
! log_printf(r->server,"out of memory processing file %s", r->filename);
! rputs(error, r);
! goto RETURN;
! }
! new->parent = new->left = new->right = (struct parse_node*)NULL;
new->done = 0;
! if ((parse = get_ptoken(r, parse, &new->token)) == (char *)NULL)
break;
! switch(new->token.type) {
! case token_string:
#ifdef DEBUG_INCLUDE
! rvputs(r," Token: string (", new->token.value, ")\n", NULL);
#endif
! if (current == (struct parse_node*)NULL) {
root = current = new;
break;
}
! switch(current->token.type) {
! case token_string:
! if (current->token.value[0] != '\0')
! strncat(current->token.value, " ",
! MAX_STRING_LEN-strlen(current->token.value)-1);
! strncat(current->token.value, new->token.value,
! MAX_STRING_LEN-strlen(current->token.value)-1);
break;
! case token_eq:
! case token_ne:
! case token_and:
! case token_or:
! case token_lbrace:
! case token_not:
new->parent = current;
current = current->right = new;
break;
! default:
log_printf(r->server,
! "Invalid expression \"%s\" in file %s", expr, r->filename);
rputs(error, r);
goto RETURN;
}
break;
! case token_and:
! case token_or:
#ifdef DEBUG_INCLUDE
! rputs (" Token: and/or\n", r);
#endif
! if (current == (struct parse_node*)NULL) {
log_printf(r->server,
! "Invalid expression \"%s\" in file %s", expr, r->filename);
rputs(error, r);
goto RETURN;
}
/* Percolate upwards */
! while (current != (struct parse_node *)NULL) {
! switch(current->token.type) {
! case token_string:
! case token_group:
! case token_not:
! case token_eq:
! case token_ne:
! case token_and:
! case token_or:
current = current->parent;
continue;
! case token_lbrace:
break;
! default:
log_printf(r->server,
! "Invalid expression \"%s\" in file %s", expr, r->filename);
rputs(error, r);
goto RETURN;
}
break;
}
! if (current == (struct parse_node*)NULL) {
new->left = root;
new->left->parent = new;
! new->parent = (struct parse_node*)NULL;
root = new;
! } else {
new->left = current->right;
current->right = new;
new->parent = current;
--- 1249,1373 ----
* I absolutely want to make sure that I clean up the memory in all
* cases. And, without rewriting this completely, the easiest way
* is to just branch to the return code which cleans it up.
+ */
+ /* there is an implicit assumption here that expr is at most MAX_STRING_LEN-1
+ * characters long...
*/
! static int parse_expr(request_rec *r, const char *expr, const char *error)
{
struct parse_node {
struct parse_node *left, *right, *parent;
struct token token;
int value, done;
! } *root, *current, *new;
! const char *parse;
char buffer[MAX_STRING_LEN];
! pool *expr_pool;
int retval = 0;
! if ((parse = expr) == (char *) NULL) {
! return (0);
}
+ root = current = (struct parse_node *) NULL;
+ expr_pool = make_sub_pool(r->pool);
/* Create Parse Tree */
while (1) {
! new = (struct parse_node *) palloc(expr_pool,
! sizeof(struct parse_node));
! new->parent = new->left = new->right = (struct parse_node *) NULL;
new->done = 0;
! if ((parse = get_ptoken(r, parse, &new->token)) == (char *) NULL) {
break;
! }
! switch (new->token.type) {
! case token_string:
#ifdef DEBUG_INCLUDE
! rvputs(r, " Token: string (", new->token.value, ")\n", NULL);
#endif
! if (current == (struct parse_node *) NULL) {
root = current = new;
break;
}
! switch (current->token.type) {
! case token_string:
! if (current->token.value[0] != '\0') {
! strncat(current->token.value, " ",
! MAX_STRING_LEN - strlen(current->token.value) - 1);
! }
! strncat(current->token.value, new->token.value,
! MAX_STRING_LEN - strlen(current->token.value) - 1);
! current->token.value[sizeof(current->token.value) - 1] = '\0';
break;
! case token_eq:
! case token_ne:
! case token_and:
! case token_or:
! case token_lbrace:
! case token_not:
! case token_ge:
! case token_gt:
! case token_le:
! case token_lt:
new->parent = current;
current = current->right = new;
break;
! default:
log_printf(r->server,
! "Invalid expression \"%s\" in file %s",
! expr, r->filename);
rputs(error, r);
goto RETURN;
}
break;
! case token_and:
! case token_or:
#ifdef DEBUG_INCLUDE
! rputs(" Token: and/or\n", r);
#endif
! if (current == (struct parse_node *) NULL) {
log_printf(r->server,
! "Invalid expression \"%s\" in file %s",
! expr, r->filename);
rputs(error, r);
goto RETURN;
}
/* Percolate upwards */
! while (current != (struct parse_node *) NULL) {
! switch (current->token.type) {
! case token_string:
! case token_group:
! case token_not:
! case token_eq:
! case token_ne:
! case token_and:
! case token_or:
! case token_ge:
! case token_gt:
! case token_le:
! case token_lt:
current = current->parent;
continue;
! case token_lbrace:
break;
! default:
log_printf(r->server,
! "Invalid expression \"%s\" in file %s",
! expr, r->filename);
rputs(error, r);
goto RETURN;
}
break;
}
! if (current == (struct parse_node *) NULL) {
new->left = root;
new->left->parent = new;
! new->parent = (struct parse_node *) NULL;
root = new;
! }
! else {
new->left = current->right;
current->right = new;
new->parent = current;
***************
*** 1146,1183 ****
current = new;
break;
! case token_not:
#ifdef DEBUG_INCLUDE
! rputs(" Token: not\n", r);
#endif
! if (current == (struct parse_node*)NULL) {
root = current = new;
break;
}
/* Percolate upwards */
! while (current != (struct parse_node *)NULL) {
! switch(current->token.type) {
! case token_not:
! case token_eq:
! case token_ne:
! case token_and:
! case token_or:
! case token_lbrace:
break;
! default:
log_printf(r->server,
! "Invalid expression \"%s\" in file %s", expr, r->filename);
rputs(error, r);
goto RETURN;
}
break;
}
! if (current == (struct parse_node*)NULL) {
new->left = root;
new->left->parent = new;
! new->parent = (struct parse_node*)NULL;
root = new;
! } else {
new->left = current->right;
current->right = new;
new->parent = current;
--- 1375,1418 ----
current = new;
break;
! case token_not:
#ifdef DEBUG_INCLUDE
! rputs(" Token: not\n", r);
#endif
! if (current == (struct parse_node *) NULL) {
root = current = new;
break;
}
/* Percolate upwards */
! while (current != (struct parse_node *) NULL) {
! switch (current->token.type) {
! case token_not:
! case token_eq:
! case token_ne:
! case token_and:
! case token_or:
! case token_lbrace:
! case token_ge:
! case token_gt:
! case token_le:
! case token_lt:
break;
! default:
log_printf(r->server,
! "Invalid expression \"%s\" in file %s",
! expr, r->filename);
rputs(error, r);
goto RETURN;
}
break;
}
! if (current == (struct parse_node *) NULL) {
new->left = root;
new->left->parent = new;
! new->parent = (struct parse_node *) NULL;
root = new;
! }
! else {
new->left = current->right;
current->right = new;
new->parent = current;
***************
*** 1185,1230 ****
current = new;
break;
! case token_eq:
! case token_ne:
#ifdef DEBUG_INCLUDE
! rputs(" Token: eq/ne\n", r);
#endif
! if (current == (struct parse_node*)NULL) {
log_printf(r->server,
! "Invalid expression \"%s\" in file %s", expr, r->filename);
rputs(error, r);
goto RETURN;
}
/* Percolate upwards */
! while (current != (struct parse_node *)NULL) {
! switch(current->token.type) {
! case token_string:
! case token_group:
current = current->parent;
continue;
! case token_lbrace:
! case token_and:
! case token_or:
break;
! case token_not:
! case token_eq:
! case token_ne:
! default:
! log_printf(r->server,
! "Invalid expression \"%s\" in file %s",
! expr, r->filename);
rputs(error, r);
goto RETURN;
}
break;
}
! if (current == (struct parse_node*)NULL) {
new->left = root;
new->left->parent = new;
! new->parent = (struct parse_node*)NULL;
root = new;
! } else {
new->left = current->right;
current->right = new;
new->parent = current;
--- 1420,1475 ----
current = new;
break;
! case token_eq:
! case token_ne:
! case token_ge:
! case token_gt:
! case token_le:
! case token_lt:
#ifdef DEBUG_INCLUDE
! rputs(" Token: eq/ne/ge/gt/le/lt\n", r);
#endif
! if (current == (struct parse_node *) NULL) {
log_printf(r->server,
! "Invalid expression \"%s\" in file %s",
! expr, r->filename);
rputs(error, r);
goto RETURN;
}
/* Percolate upwards */
! while (current != (struct parse_node *) NULL) {
! switch (current->token.type) {
! case token_string:
! case token_group:
current = current->parent;
continue;
! case token_lbrace:
! case token_and:
! case token_or:
break;
! case token_not:
! case token_eq:
! case token_ne:
! case token_ge:
! case token_gt:
! case token_le:
! case token_lt:
! default:
! log_printf(r->server,
! "Invalid expression \"%s\" in file %s",
! expr, r->filename);
rputs(error, r);
goto RETURN;
}
break;
}
! if (current == (struct parse_node *) NULL) {
new->left = root;
new->left->parent = new;
! new->parent = (struct parse_node *) NULL;
root = new;
! }
! else {
new->left = current->right;
current->right = new;
new->parent = current;
***************
*** 1232,1651 ****
current = new;
break;
! case token_rbrace:
#ifdef DEBUG_INCLUDE
! rputs(" Token: rbrace\n", r);
#endif
! while (current != (struct parse_node*)NULL) {
if (current->token.type == token_lbrace) {
current->token.type = token_group;
break;
}
current = current->parent;
}
! if (current == (struct parse_node*)NULL) {
! log_printf(r->server,"Unmatched ')' in %s", expr, r->filename);
rputs(error, r);
goto RETURN;
}
break;
! case token_lbrace:
#ifdef DEBUG_INCLUDE
! rputs(" Token: lbrace\n", r);
#endif
! if (current == (struct parse_node*)NULL) {
root = current = new;
break;
}
/* Percolate upwards */
! while (current != (struct parse_node *)NULL) {
! switch(current->token.type) {
! case token_not:
! case token_eq:
! case token_ne:
! case token_and:
! case token_or:
! case token_lbrace:
break;
! case token_string:
! case token_group:
! default:
log_printf(r->server,
! "Invalid expression \"%s\" in file %s",
! expr, r->filename);
rputs(error, r);
goto RETURN;
}
break;
}
! if (current == (struct parse_node*)NULL) {
new->left = root;
new->left->parent = new;
! new->parent = (struct parse_node*)NULL;
root = new;
! } else {
new->left = current->right;
current->right = new;
new->parent = current;
}
current = new;
break;
! default:
! break;
}
}
/* Evaluate Parse Tree */
current = root;
! while (current != (struct parse_node *)NULL) {
! switch(current->token.type) {
! case token_string:
! #ifdef DEBUG_INCLUDE
! rputs(" Evaluate string\n", r);
! #endif
! parse_string(r, current->token.value, buffer, MAX_STRING_LEN, 0);
! strncpy(current->token.value, buffer, MAX_STRING_LEN-1);
! current->token.value[MAX_STRING_LEN-1] = '\0';
current->value = (current->token.value[0] != '\0');
current->done = 1;
current = current->parent;
break;
! case token_and:
! case token_or:
#ifdef DEBUG_INCLUDE
! rputs(" Evaluate and/or\n", r);
#endif
! if (current->left == (struct parse_node*)NULL ||
! current->right == (struct parse_node*)NULL) {
! log_printf(r->server,
! "Invalid expression \"%s\" in file %s", expr, r->filename);
rputs(error, r);
goto RETURN;
}
if (!current->left->done) {
! switch(current->left->token.type) {
! case token_string:
parse_string(r, current->left->token.value,
! buffer, MAX_STRING_LEN, 0);
! strncpy(current->left->token.value, buffer,
! MAX_STRING_LEN-1);
! current->left->token.value[MAX_STRING_LEN-1] = '\0';
current->left->done = 1;
break;
! default:
current = current->left;
continue;
}
}
if (!current->right->done) {
! switch(current->right->token.type) {
! case token_string:
parse_string(r, current->right->token.value,
! buffer, MAX_STRING_LEN, 0);
! strncpy(current->right->token.value, buffer,
! MAX_STRING_LEN-1);
! current->right->token.value[MAX_STRING_LEN-1] = '\0';
current->right->done = 1;
break;
! default:
current = current->right;
continue;
}
}
#ifdef DEBUG_INCLUDE
! rvputs(r," Left: ", current->left->value ? "1" : "0", "\n", NULL);
! rvputs(r," Right: ", current->right->value ? "1" : "0", "\n", NULL);
#endif
! if (current->token.type == token_and)
! current->value =
! current->left->value && current->right->value;
! else
! current->value =
! current->left->value || current->right->value;
#ifdef DEBUG_INCLUDE
! rvputs(r," Returning ", current->value ? "1" : "0", "\n", NULL);
#endif
current->done = 1;
current = current->parent;
break;
! case token_eq:
! case token_ne:
#ifdef DEBUG_INCLUDE
! rputs(" Evaluate eq/ne\n", r);
#endif
! if ((current->left == (struct parse_node*)NULL) ||
! (current->right == (struct parse_node*)NULL) ||
! (current->left->token.type != token_string) ||
! (current->right->token.type != token_string)) {
! log_printf(r->server,
! "Invalid expression \"%s\" in file %s", expr, r->filename);
rputs(error, r);
goto RETURN;
}
parse_string(r, current->left->token.value,
! buffer, MAX_STRING_LEN, 0);
! strncpy(current->left->token.value, buffer, MAX_STRING_LEN-1);
! current->left->token.value[MAX_STRING_LEN-1] = '\0';
parse_string(r, current->right->token.value,
! buffer, MAX_STRING_LEN, 0);
! strncpy(current->right->token.value, buffer, MAX_STRING_LEN-1);
! current->right->token.value[MAX_STRING_LEN-1] = '\0';
if (current->right->token.value[0] == '/') {
int len;
len = strlen(current->right->token.value);
! if (current->right->token.value[len-1] == '/') {
! current->right->token.value[len-1] = '\0';
! } else {
! log_printf(r->server,"Invalid rexp \"%s\" in file %s",
! current->right->token.value, r->filename);
rputs(error, r);
goto RETURN;
}
#ifdef DEBUG_INCLUDE
! rvputs(r," Re Compare (", current->left->token.value,
! ") with /", ¤t->right->token.value[1], "/\n", NULL);
#endif
current->value =
re_check(r, current->left->token.value,
! ¤t->right->token.value[1]);
! } else {
#ifdef DEBUG_INCLUDE
! rvputs(r," Compare (", current->left->token.value,
! ") with (", current->right->token.value, ")\n", NULL);
#endif
current->value =
! (strcmp(current->left->token.value,
! current->right->token.value) == 0);
}
! if (current->token.type == token_ne)
current->value = !current->value;
#ifdef DEBUG_INCLUDE
! rvputs(r," Returning ", current->value ? "1" : "0", "\n", NULL);
#endif
current->done = 1;
current = current->parent;
break;
! case token_not:
! if (current->right != (struct parse_node *)NULL) {
if (!current->right->done) {
current = current->right;
continue;
}
current->value = !current->right->value;
! } else {
current->value = 0;
}
#ifdef DEBUG_INCLUDE
! rvputs(r," Evaluate !: ", current->value ? "1" : "0", "\n", NULL);
#endif
current->done = 1;
current = current->parent;
break;
! case token_group:
! if (current->right != (struct parse_node *)NULL) {
if (!current->right->done) {
current = current->right;
continue;
}
current->value = current->right->value;
! } else {
current->value = 1;
}
#ifdef DEBUG_INCLUDE
! rvputs(r," Evaluate (): ", current->value ? "1" : "0", "\n", NULL);
#endif
current->done = 1;
current = current->parent;
break;
! case token_lbrace:
! log_printf(r->server,"Unmatched '(' in %s in file %s",
! expr, r->filename);
rputs(error, r);
goto RETURN;
! case token_rbrace:
! log_printf(r->server,"Unmatched ')' in %s in file %s\n",
! expr, r->filename);
rputs(error, r);
goto RETURN;
! default:
! log_printf(r->server,"bad token type");
rputs(error, r);
goto RETURN;
}
}
! retval = (root == (struct parse_node *)NULL) ? 0 : root->value;
! RETURN:
destroy_pool(expr_pool);
return (retval);
! }
! int handle_if(FILE *in, request_rec *r, char *error,
! int *conditional_status, int *printing)
{
char tag[MAX_STRING_LEN];
! char *tag_val = '\0';
! char *expr = '\0';
! while(1) {
! tag_val = get_tag(r->pool, in, tag, MAX_STRING_LEN, 0);
! if(*tag == '\0')
return 1;
! else if(!strcmp(tag,"done")) {
*printing = *conditional_status = parse_expr(r, expr, error);
#ifdef DEBUG_INCLUDE
! rvputs(r,"**** if conditional_status=\"", *conditional_status ? "1" : "0", "\"\n", NULL);
#endif
return 0;
! } else if(!strcmp(tag,"expr")) {
! expr = tag_val;
#ifdef DEBUG_INCLUDE
! rvputs(r,"**** if expr=\"", expr, "\"\n", NULL);
#endif
! } else {
! log_printf(r->server,"unknown parameter \"%s\" to tag if in %s",
! tag, r->filename);
rputs(error, r);
}
}
! }
! int handle_elif(FILE *in, request_rec *r, char *error,
! int *conditional_status, int *printing)
{
char tag[MAX_STRING_LEN];
! char *tag_val = '\0';
! char *expr = '\0';
! while(1) {
! tag_val = get_tag(r->pool, in, tag, MAX_STRING_LEN, 0);
! if(*tag == '\0')
return 1;
! else if(!strcmp(tag,"done")) {
#ifdef DEBUG_INCLUDE
! rvputs(r,"**** elif conditional_status=\"", *conditional_status ? "1" : "0", "\"\n", NULL);
#endif
if (*conditional_status) {
*printing = 0;
! return(0);
}
*printing = *conditional_status = parse_expr(r, expr, error);
#ifdef DEBUG_INCLUDE
! rvputs(r,"**** elif conditional_status=\"", *conditional_status ? "1" : "0", "\"\n", NULL);
#endif
return 0;
! } else if(!strcmp(tag,"expr")) {
! expr = tag_val;
#ifdef DEBUG_INCLUDE
! rvputs(r,"**** if expr=\"", expr, "\"\n", NULL);
#endif
! } else {
! log_printf(r->server,"unknown parameter \"%s\" to tag if in %s",
! tag, r->filename);
rputs(error, r);
}
}
}
! int handle_else(FILE *in, request_rec *r, char *error,
! int *conditional_status, int *printing)
{
char tag[MAX_STRING_LEN];
char *tag_val;
! if(!(tag_val = get_tag(r->pool, in, tag, MAX_STRING_LEN, 1)))
return 1;
! else if(!strcmp(tag,"done")) {
#ifdef DEBUG_INCLUDE
! rvputs(r,"**** else conditional_status=\"", *conditional_status ? "1" : "0", "\"\n", NULL);
#endif
*printing = !(*conditional_status);
*conditional_status = 1;
return 0;
! } else {
! log_printf(r->server, "else directive does not take tags");
! if (*printing) rputs(error, r);
return -1;
}
! }
! int handle_endif(FILE *in, request_rec *r, char *error,
! int *conditional_status, int *printing)
{
char tag[MAX_STRING_LEN];
char *tag_val;
! if(!(tag_val = get_tag(r->pool, in, tag, MAX_STRING_LEN, 1))) {
return 1;
! } else if(!strcmp(tag,"done")) {
#ifdef DEBUG_INCLUDE
! rvputs(r,"**** endif conditional_status=\"", *conditional_status ? "1" : "0", "\"\n", NULL);
#endif
*printing = 1;
*conditional_status = 1;
return 0;
! } else {
! log_printf(r->server, "endif directive does not take tags");
rputs(error, r);
return -1;
}
! }
! int handle_set(FILE *in, request_rec *r, char *error)
{
char tag[MAX_STRING_LEN];
char parsed_string[MAX_STRING_LEN];
char *tag_val;
char *var;
! var = (char *)NULL;
while (1) {
! if(!(tag_val = get_tag(r->pool, in, tag, MAX_STRING_LEN, 1)))
return 1;
! else if(!strcmp(tag,"done"))
return 0;
! else if (!strcmp(tag,"var")) {
var = tag_val;
! } else if (!strcmp(tag,"value")) {
! if (var == (char *)NULL) {
log_printf(r->server,
! "variable must precede value in set directive");
rputs(error, r);
return -1;
! }
! parse_string(r, tag_val, parsed_string, MAX_STRING_LEN, 0);
! table_set (r->subprocess_env, var, parsed_string);
}
}
! }
! int handle_printenv(FILE *in, request_rec *r, char *error)
{
char tag[MAX_STRING_LEN];
char *tag_val;
table_entry *elts = (table_entry *) r->subprocess_env->elts;
int i;
! if(!(tag_val = get_tag(r->pool, in, tag, MAX_STRING_LEN, 1)))
return 1;
! else if(!strcmp(tag,"done")) {
! for (i = 0; i < r->subprocess_env->nelts; ++i)
! rvputs(r, elts[i].key, "=", elts[i].val, "\n", NULL);
! return 0;
! } else {
! log_printf(r->server, "printenv directive does not take tags");
rputs(error, r);
return -1;
}
! }
--- 1477,2012 ----
current = new;
break;
! case token_rbrace:
#ifdef DEBUG_INCLUDE
! rputs(" Token: rbrace\n", r);
#endif
! while (current != (struct parse_node *) NULL) {
if (current->token.type == token_lbrace) {
current->token.type = token_group;
break;
}
current = current->parent;
}
! if (current == (struct parse_node *) NULL) {
! log_printf(r->server, "Unmatched ')' in \"%s\" in file %s",
! expr, r->filename);
rputs(error, r);
goto RETURN;
}
break;
! case token_lbrace:
#ifdef DEBUG_INCLUDE
! rputs(" Token: lbrace\n", r);
#endif
! if (current == (struct parse_node *) NULL) {
root = current = new;
break;
}
/* Percolate upwards */
! while (current != (struct parse_node *) NULL) {
! switch (current->token.type) {
! case token_not:
! case token_eq:
! case token_ne:
! case token_and:
! case token_or:
! case token_lbrace:
! case token_ge:
! case token_gt:
! case token_le:
! case token_lt:
break;
! case token_string:
! case token_group:
! default:
log_printf(r->server,
! "Invalid expression \"%s\" in file %s",
! expr, r->filename);
rputs(error, r);
goto RETURN;
}
break;
}
! if (current == (struct parse_node *) NULL) {
new->left = root;
new->left->parent = new;
! new->parent = (struct parse_node *) NULL;
root = new;
! }
! else {
new->left = current->right;
current->right = new;
new->parent = current;
}
current = new;
break;
! default:
! break;
}
}
/* Evaluate Parse Tree */
current = root;
! while (current != (struct parse_node *) NULL) {
! switch (current->token.type) {
! case token_string:
! #ifdef DEBUG_INCLUDE
! rputs(" Evaluate string\n", r);
! #endif
! parse_string(r, current->token.value, buffer, sizeof(buffer), 0);
! safe_copy(current->token.value, buffer, sizeof(current->token.value));
current->value = (current->token.value[0] != '\0');
current->done = 1;
current = current->parent;
break;
! case token_and:
! case token_or:
#ifdef DEBUG_INCLUDE
! rputs(" Evaluate and/or\n", r);
#endif
! if (current->left == (struct parse_node *) NULL ||
! current->right == (struct parse_node *) NULL) {
! log_printf(r->server, "Invalid expression \"%s\" in file %s",
! expr, r->filename);
rputs(error, r);
goto RETURN;
}
if (!current->left->done) {
! switch (current->left->token.type) {
! case token_string:
parse_string(r, current->left->token.value,
! buffer, sizeof(buffer), 0);
! safe_copy(current->left->token.value, buffer,
! sizeof(current->left->token.value));
! current->left->value = (current->left->token.value[0] != '\0');
current->left->done = 1;
break;
! default:
current = current->left;
continue;
}
}
if (!current->right->done) {
! switch (current->right->token.type) {
! case token_string:
parse_string(r, current->right->token.value,
! buffer, sizeof(buffer), 0);
! safe_copy(current->right->token.value, buffer,
! sizeof(current->right->token.value));
! current->right->value = (current->right->token.value[0] != '\0');
current->right->done = 1;
break;
! default:
current = current->right;
continue;
}
}
#ifdef DEBUG_INCLUDE
! rvputs(r, " Left: ", current->left->value ? "1" : "0",
! "\n", NULL);
! rvputs(r, " Right: ", current->right->value ? "1" : "0",
! "\n", NULL);
#endif
! if (current->token.type == token_and) {
! current->value = current->left->value && current->right->value;
! }
! else {
! current->value = current->left->value || current->right->value;
! }
#ifdef DEBUG_INCLUDE
! rvputs(r, " Returning ", current->value ? "1" : "0",
! "\n", NULL);
#endif
current->done = 1;
current = current->parent;
break;
! case token_eq:
! case token_ne:
#ifdef DEBUG_INCLUDE
! rputs(" Evaluate eq/ne\n", r);
#endif
! if ((current->left == (struct parse_node *) NULL) ||
! (current->right == (struct parse_node *) NULL) ||
! (current->left->token.type != token_string) ||
! (current->right->token.type != token_string)) {
! log_printf(r->server, "Invalid expression \"%s\" in file %s",
! expr, r->filename);
rputs(error, r);
goto RETURN;
}
parse_string(r, current->left->token.value,
! buffer, sizeof(buffer), 0);
! safe_copy(current->left->token.value, buffer,
! sizeof(current->left->token.value));
parse_string(r, current->right->token.value,
! buffer, sizeof(buffer), 0);
! safe_copy(current->right->token.value, buffer,
! sizeof(current->right->token.value));
if (current->right->token.value[0] == '/') {
int len;
len = strlen(current->right->token.value);
! if (current->right->token.value[len - 1] == '/') {
! current->right->token.value[len - 1] = '\0';
! }
! else {
! log_printf(r->server, "Invalid rexp \"%s\" in file %s",
! current->right->token.value, r->filename);
rputs(error, r);
goto RETURN;
}
#ifdef DEBUG_INCLUDE
! rvputs(r, " Re Compare (", current->left->token.value,
! ") with /", ¤t->right->token.value[1], "/\n", NULL);
#endif
current->value =
re_check(r, current->left->token.value,
! ¤t->right->token.value[1]);
! }
! else {
#ifdef DEBUG_INCLUDE
! rvputs(r, " Compare (", current->left->token.value,
! ") with (", current->right->token.value, ")\n", NULL);
#endif
current->value =
! (strcmp(current->left->token.value,
! current->right->token.value) == 0);
}
! if (current->token.type == token_ne) {
current->value = !current->value;
+ }
#ifdef DEBUG_INCLUDE
! rvputs(r, " Returning ", current->value ? "1" : "0",
! "\n", NULL);
#endif
current->done = 1;
current = current->parent;
break;
+ case token_ge:
+ case token_gt:
+ case token_le:
+ case token_lt:
+ #ifdef DEBUG_INCLUDE
+ rputs(" Evaluate ge/gt/le/lt\n", r);
+ #endif
+ if ((current->left == (struct parse_node *) NULL) ||
+ (current->right == (struct parse_node *) NULL) ||
+ (current->left->token.type != token_string) ||
+ (current->right->token.type != token_string)) {
+ log_printf(r->server, "Invalid expression \"%s\" in file %s",
+ expr, r->filename);
+ rputs(error, r);
+ goto RETURN;
+ }
+ parse_string(r, current->left->token.value,
+ buffer, sizeof(buffer), 0);
+ safe_copy(current->left->token.value, buffer,
+ sizeof(current->left->token.value));
+ parse_string(r, current->right->token.value,
+ buffer, sizeof(buffer), 0);
+ safe_copy(current->right->token.value, buffer,
+ sizeof(current->right->token.value));
+ #ifdef DEBUG_INCLUDE
+ rvputs(r, " Compare (", current->left->token.value,
+ ") with (", current->right->token.value, ")\n", NULL);
+ #endif
+ current->value =
+ strcmp(current->left->token.value,
+ current->right->token.value);
+ if (current->token.type == token_ge) {
+ current->value = current->value >= 0;
+ }
+ else if (current->token.type == token_gt) {
+ current->value = current->value > 0;
+ }
+ else if (current->token.type == token_le) {
+ current->value = current->value <= 0;
+ }
+ else if (current->token.type == token_lt) {
+ current->value = current->value < 0;
+ }
+ else {
+ current->value = 0; /* Don't return -1 if unknown token */
+ }
+ #ifdef DEBUG_INCLUDE
+ rvputs(r, " Returning ", current->value ? "1" : "0",
+ "\n", NULL);
+ #endif
+ current->done = 1;
+ current = current->parent;
+ break;
! case token_not:
! if (current->right != (struct parse_node *) NULL) {
if (!current->right->done) {
current = current->right;
continue;
}
current->value = !current->right->value;
! }
! else {
current->value = 0;
}
#ifdef DEBUG_INCLUDE
! rvputs(r, " Evaluate !: ", current->value ? "1" : "0",
! "\n", NULL);
#endif
current->done = 1;
current = current->parent;
break;
! case token_group:
! if (current->right != (struct parse_node *) NULL) {
if (!current->right->done) {
current = current->right;
continue;
}
current->value = current->right->value;
! }
! else {
current->value = 1;
}
#ifdef DEBUG_INCLUDE
! rvputs(r, " Evaluate (): ", current->value ? "1" : "0",
! "\n", NULL);
#endif
current->done = 1;
current = current->parent;
break;
! case token_lbrace:
! log_printf(r->server, "Unmatched '(' in \"%s\" in file %s",
! expr, r->filename);
rputs(error, r);
goto RETURN;
! case token_rbrace:
! log_printf(r->server, "Unmatched ')' in \"%s\" in file %s\n",
! expr, r->filename);
rputs(error, r);
goto RETURN;
! default:
! log_printf(r->server, "bad token type");
rputs(error, r);
goto RETURN;
}
}
! retval = (root == (struct parse_node *) NULL) ? 0 : root->value;
! RETURN:
destroy_pool(expr_pool);
return (retval);
! }
! static int handle_if(FILE *in, request_rec *r, const char *error,
! int *conditional_status, int *printing)
{
char tag[MAX_STRING_LEN];
! char *tag_val;
! char *expr;
! expr = NULL;
! while (1) {
! tag_val = get_tag(r->pool, in, tag, sizeof(tag), 0);
! if (*tag == '\0') {
return 1;
! }
! else if (!strcmp(tag, "done")) {
! if (expr == NULL) {
! log_printf(r->server, "missing expr in if statement: %s",
! r->filename);
! rputs(error, r);
! return 1;
! }
*printing = *conditional_status = parse_expr(r, expr, error);
#ifdef DEBUG_INCLUDE
! rvputs(r, "**** if conditional_status=\"",
! *conditional_status ? "1" : "0", "\"\n", NULL);
#endif
return 0;
! }
! else if (!strcmp(tag, "expr")) {
! expr = tag_val;
#ifdef DEBUG_INCLUDE
! rvputs(r, "**** if expr=\"", expr, "\"\n", NULL);
#endif
! }
! else {
! log_printf(r->server, "unknown parameter \"%s\" to tag if in %s",
! tag, r->filename);
rputs(error, r);
}
}
! }
! static int handle_elif(FILE *in, request_rec *r, const char *error,
! int *conditional_status, int *printing)
{
char tag[MAX_STRING_LEN];
! char *tag_val;
! char *expr;
! expr = NULL;
! while (1) {
! tag_val = get_tag(r->pool, in, tag, sizeof(tag), 0);
! if (*tag == '\0') {
return 1;
! }
! else if (!strcmp(tag, "done")) {
#ifdef DEBUG_INCLUDE
! rvputs(r, "**** elif conditional_status=\"",
! *conditional_status ? "1" : "0", "\"\n", NULL);
#endif
if (*conditional_status) {
*printing = 0;
! return (0);
}
+ if (expr == NULL) {
+ log_printf(r->server, "missing expr in elif statement: %s",
+ r->filename);
+ rputs(error, r);
+ return 1;
+ }
*printing = *conditional_status = parse_expr(r, expr, error);
#ifdef DEBUG_INCLUDE
! rvputs(r, "**** elif conditional_status=\"",
! *conditional_status ? "1" : "0", "\"\n", NULL);
#endif
return 0;
! }
! else if (!strcmp(tag, "expr")) {
! expr = tag_val;
#ifdef DEBUG_INCLUDE
! rvputs(r, "**** if expr=\"", expr, "\"\n", NULL);
#endif
! }
! else {
! log_printf(r->server, "unknown parameter \"%s\" to tag if in %s",
! tag, r->filename);
rputs(error, r);
}
}
}
! static int handle_else(FILE *in, request_rec *r, const char *error,
! int *conditional_status, int *printing)
{
char tag[MAX_STRING_LEN];
char *tag_val;
! if (!(tag_val = get_tag(r->pool, in, tag, sizeof(tag), 1))) {
return 1;
! }
! else if (!strcmp(tag, "done")) {
#ifdef DEBUG_INCLUDE
! rvputs(r, "**** else conditional_status=\"",
! *conditional_status ? "1" : "0", "\"\n", NULL);
#endif
*printing = !(*conditional_status);
*conditional_status = 1;
return 0;
! }
! else {
! log_printf(r->server, "else directive does not take tags in %s",
! r->filename);
! if (*printing) {
! rputs(error, r);
! }
return -1;
}
! }
! static int handle_endif(FILE *in, request_rec *r, const char *error,
! int *conditional_status, int *printing)
{
char tag[MAX_STRING_LEN];
char *tag_val;
! if (!(tag_val = get_tag(r->pool, in, tag, sizeof(tag), 1))) {
return 1;
! }
! else if (!strcmp(tag, "done")) {
#ifdef DEBUG_INCLUDE
! rvputs(r, "**** endif conditional_status=\"",
! *conditional_status ? "1" : "0", "\"\n", NULL);
#endif
*printing = 1;
*conditional_status = 1;
return 0;
! }
! else {
! log_printf(r->server, "endif directive does not take tags in %s",
! r->filename);
rputs(error, r);
return -1;
}
! }
! static int handle_set(FILE *in, request_rec *r, const char *error)
{
char tag[MAX_STRING_LEN];
char parsed_string[MAX_STRING_LEN];
char *tag_val;
char *var;
! var = (char *) NULL;
while (1) {
! if (!(tag_val = get_tag(r->pool, in, tag, sizeof(tag), 1))) {
return 1;
! }
! else if (!strcmp(tag, "done")) {
return 0;
! }
! else if (!strcmp(tag, "var")) {
var = tag_val;
! }
! else if (!strcmp(tag, "value")) {
! if (var == (char *) NULL) {
log_printf(r->server,
! "variable must precede value in set directive in %s",
! r->filename);
rputs(error, r);
return -1;
! }
! parse_string(r, tag_val, parsed_string, sizeof(parsed_string), 0);
! table_set(r->subprocess_env, var, parsed_string);
! }
! else {
! log_printf(r->server, "Invalid tag for set directive in %s",
! r->filename);
! rputs(error, r);
! return -1;
}
}
! }
! static int handle_printenv(FILE *in, request_rec *r, const char *error)
{
char tag[MAX_STRING_LEN];
char *tag_val;
table_entry *elts = (table_entry *) r->subprocess_env->elts;
int i;
! if (!(tag_val = get_tag(r->pool, in, tag, sizeof(tag), 1))) {
return 1;
! }
! else if (!strcmp(tag, "done")) {
! for (i = 0; i < r->subprocess_env->nelts; ++i) {
! rvputs(r, elts[i].key, "=", elts[i].val, "\n", NULL);
! }
! return 0;
! }
! else {
! log_printf(r->server, "printenv directive does not take tags in %s",
! r->filename);
rputs(error, r);
return -1;
}
! }
***************
*** 1653,1757 ****
/* This is a stub which parses a file descriptor. */
! void send_parsed_content(FILE *f, request_rec *r)
{
char directive[MAX_STRING_LEN], error[MAX_STRING_LEN];
char timefmt[MAX_STRING_LEN];
! int noexec = allow_options (r) & OPT_INCNOEXEC;
int ret, sizefmt;
int if_nesting;
int printing;
int conditional_status;
! strncpy(error,DEFAULT_ERROR_MSG, sizeof(error)-1);
! error[sizeof(error)-1] = '\0';
! strncpy(timefmt,DEFAULT_TIME_FORMAT, sizeof(timefmt)-1);
! timefmt[sizeof(timefmt)-1] = '\0';
sizefmt = SIZEFMT_KMG;
/* Turn printing on */
printing = conditional_status = 1;
if_nesting = 0;
! chdir_file (r->filename);
! if (r->args) { /* add QUERY stuff to env cause it ain't yet */
! char *arg_copy = pstrdup (r->pool, r->args);
!
! table_set (r->subprocess_env, "QUERY_STRING", r->args);
! unescape_url (arg_copy);
! table_set (r->subprocess_env, "QUERY_STRING_UNESCAPED",
! escape_shell_cmd (r->pool, arg_copy));
}
! while(1) {
! if(!find_string(f,STARTING_SEQUENCE,r,printing)) {
! if(get_directive(f,directive,r->pool))
return;
! if(!strcmp(directive,"if")) {
if (!printing) {
if_nesting++;
! } else {
! ret=handle_if(f, r, error, &conditional_status, &printing);
if_nesting = 0;
}
continue;
! } else if(!strcmp(directive,"else")) {
! if (!if_nesting)
! ret=handle_else(f, r, error, &conditional_status, &printing);
continue;
! } else if(!strcmp(directive,"elif")) {
! if (!if_nesting)
! ret = handle_elif(f, r, error, &conditional_status, &printing);
continue;
! } else if(!strcmp(directive,"endif")) {
if (!if_nesting) {
! ret = handle_endif(f, r, error, &conditional_status, &printing);
! } else {
if_nesting--;
}
continue;
! }
! if (!printing) continue;
! if(!strcmp(directive,"exec")) {
! if(noexec) {
! log_printf(r->server,"httpd: exec used but not allowed in %s",
! r->filename);
! if (printing) rputs(error, r);
! ret = find_string(f,ENDING_SEQUENCE,r,0);
! } else
! ret=handle_exec(f, r, error);
! } else if(!strcmp(directive,"config"))
! ret=handle_config(f, r, error, timefmt, &sizefmt);
! else if(!strcmp(directive,"set"))
! ret=handle_set(f, r, error);
! else if(!strcmp(directive,"include"))
! ret=handle_include(f, r, error, noexec);
! else if(!strcmp(directive,"echo"))
! ret=handle_echo(f, r, error);
! else if(!strcmp(directive,"fsize"))
! ret=handle_fsize(f, r, error, sizefmt);
! else if(!strcmp(directive,"flastmod"))
! ret=handle_flastmod(f, r, error, timefmt);
! else if(!strcmp(directive,"printenv"))
! ret=handle_printenv(f, r, error);
#ifdef USE_PERL_SSI
! else if(!strcmp(directive,"perl"))
! ret=handle_perl(f, r, error);
#endif
else {
! log_printf(r->server,
! "httpd: unknown directive \"%s\" in parsed doc %s",
! directive,r->filename);
! if (printing) rputs(error, r);
! ret=find_string(f,ENDING_SEQUENCE,r,0);
}
! if(ret) {
! log_printf(r->server,"httpd: premature EOF in parsed file %s",
! r->filename);
return;
}
! } else
return;
}
}
--- 2014,2152 ----
/* This is a stub which parses a file descriptor. */
! static void send_parsed_content(FILE *f, request_rec *r)
{
char directive[MAX_STRING_LEN], error[MAX_STRING_LEN];
char timefmt[MAX_STRING_LEN];
! int noexec = allow_options(r) & OPT_INCNOEXEC;
int ret, sizefmt;
int if_nesting;
int printing;
int conditional_status;
! safe_copy(error, DEFAULT_ERROR_MSG, sizeof(error));
! safe_copy(timefmt, DEFAULT_TIME_FORMAT, sizeof(timefmt));
sizefmt = SIZEFMT_KMG;
/* Turn printing on */
printing = conditional_status = 1;
if_nesting = 0;
! chdir_file(r->filename);
! if (r->args) { /* add QUERY stuff to env cause it ain't yet */
! char *arg_copy = pstrdup(r->pool, r->args);
!
! table_set(r->subprocess_env, "QUERY_STRING", r->args);
! unescape_url(arg_copy);
! table_set(r->subprocess_env, "QUERY_STRING_UNESCAPED",
! escape_shell_cmd(r->pool, arg_copy));
}
! while (1) {
! if (!find_string(f, STARTING_SEQUENCE, r, printing)) {
! if (get_directive(f, directive, sizeof(directive), r->pool)) {
! log_printf(r->server,
! "mod_include: error reading directive in %s",
! r->filename);
! rputs(error, r);
return;
! }
! if (!strcmp(directive, "if")) {
if (!printing) {
if_nesting++;
! }
! else {
! ret = handle_if(f, r, error, &conditional_status,
! &printing);
if_nesting = 0;
}
continue;
! }
! else if (!strcmp(directive, "else")) {
! if (!if_nesting) {
! ret = handle_else(f, r, error, &conditional_status,
! &printing);
! }
continue;
! }
! else if (!strcmp(directive, "elif")) {
! if (!if_nesting) {
! ret = handle_elif(f, r, error, &conditional_status,
! &printing);
! }
continue;
! }
! else if (!strcmp(directive, "endif")) {
if (!if_nesting) {
! ret = handle_endif(f, r, error, &conditional_status,
! &printing);
! }
! else {
if_nesting--;
}
continue;
! }
! if (!printing) {
! continue;
! }
! if (!strcmp(directive, "exec")) {
! if (noexec) {
! log_printf(r->server,
! "httpd: exec used but not allowed in %s",
! r->filename);
! if (printing) {
! rputs(error, r);
! }
! ret = find_string(f, ENDING_SEQUENCE, r, 0);
! }
! else {
! ret = handle_exec(f, r, error);
! }
! }
! else if (!strcmp(directive, "config")) {
! ret = handle_config(f, r, error, timefmt, &sizefmt);
! }
! else if (!strcmp(directive, "set")) {
! ret = handle_set(f, r, error);
! }
! else if (!strcmp(directive, "include")) {
! ret = handle_include(f, r, error, noexec);
! }
! else if (!strcmp(directive, "echo")) {
! ret = handle_echo(f, r, error);
! }
! else if (!strcmp(directive, "fsize")) {
! ret = handle_fsize(f, r, error, sizefmt);
! }
! else if (!strcmp(directive, "flastmod")) {
! ret = handle_flastmod(f, r, error, timefmt);
! }
! else if (!strcmp(directive, "printenv")) {
! ret = handle_printenv(f, r, error);
! }
#ifdef USE_PERL_SSI
! else if (!strcmp(directive, "perl")) {
! ret = handle_perl(f, r, error);
! }
#endif
else {
! log_printf(r->server, "httpd: unknown directive \"%s\" "
! "in parsed doc %s",
! directive, r->filename);
! if (printing) {
! rputs(error, r);
! }
! ret = find_string(f, ENDING_SEQUENCE, r, 0);
}
! if (ret) {
! log_printf(r->server, "httpd: premature EOF in parsed file %s",
! r->filename);
return;
}
! }
! else {
return;
+ }
}
}
***************
*** 1762,1813 ****
*/
module includes_module;
! enum xbithack { xbithack_off, xbithack_on, xbithack_full };
! #ifdef XBITHACK
#define DEFAULT_XBITHACK xbithack_full
#else
#define DEFAULT_XBITHACK xbithack_off
#endif
! void *create_includes_dir_config (pool *p, char *dummy)
{
! enum xbithack *result = (enum xbithack*)palloc(p, sizeof (enum xbithack));
*result = DEFAULT_XBITHACK;
return result;
}
! const char *set_xbithack (cmd_parms *cmd, void *xbp, char *arg)
{
! enum xbithack *state = (enum xbithack *)xbp;
! if (!strcasecmp (arg, "off")) *state = xbithack_off;
! else if (!strcasecmp (arg, "on")) *state = xbithack_on;
! else if (!strcasecmp (arg, "full")) *state = xbithack_full;
! else return "XBitHack must be set to Off, On, or Full";
! return NULL;
}
! int send_parsed_file(request_rec *r)
{
FILE *f;
enum xbithack *state =
! (enum xbithack *)get_module_config(r->per_dir_config,&includes_module);
int errstatus;
! if (!(allow_options (r) & OPT_INCLUDES)) return DECLINED;
! if (r->method_number != M_GET) return DECLINED;
if (r->finfo.st_mode == 0) {
! log_reason("File does not exist",
! r->path_info ? pstrcat(r->pool, r->filename, r->path_info, NULL)
! : r->filename, r);
! return NOT_FOUND;
}
! if(!(f=pfopen(r->pool, r->filename, "r"))) {
! log_reason("file permissions deny server access", r->filename, r);
! return FORBIDDEN;
}
if (*state == xbithack_full
--- 2157,2224 ----
*/
module includes_module;
! enum xbithack {
! xbithack_off, xbithack_on, xbithack_full
! };
! #ifdef XBITHACK
#define DEFAULT_XBITHACK xbithack_full
#else
#define DEFAULT_XBITHACK xbithack_off
#endif
! static void *create_includes_dir_config(pool *p, char *dummy)
{
! enum xbithack *result = (enum xbithack *) palloc(p, sizeof(enum xbithack));
*result = DEFAULT_XBITHACK;
return result;
}
! static const char *set_xbithack(cmd_parms *cmd, void *xbp, char *arg)
{
! enum xbithack *state = (enum xbithack *) xbp;
! if (!strcasecmp(arg, "off")) {
! *state = xbithack_off;
! }
! else if (!strcasecmp(arg, "on")) {
! *state = xbithack_on;
! }
! else if (!strcasecmp(arg, "full")) {
! *state = xbithack_full;
! }
! else {
! return "XBitHack must be set to Off, On, or Full";
! }
! return NULL;
}
! static int send_parsed_file(request_rec *r)
{
FILE *f;
enum xbithack *state =
! (enum xbithack *) get_module_config(r->per_dir_config, &includes_module);
int errstatus;
! if (!(allow_options(r) & OPT_INCLUDES)) {
! return DECLINED;
! }
! if (r->method_number != M_GET) {
! return DECLINED;
! }
if (r->finfo.st_mode == 0) {
! log_printf(r->server, "File does not exist: %s",
! (r->path_info
! ? pstrcat(r->pool, r->filename, r->path_info, NULL)
! : r->filename));
! return HTTP_NOT_FOUND;
}
! if (!(f = pfopen(r->pool, r->filename, "r"))) {
! log_printf(r->server,
! "file permissions deny server access: %s", r->filename);
! return HTTP_FORBIDDEN;
}
if (*state == xbithack_full
***************
*** 1821,1904 ****
send_http_header(r);
if (r->header_only) {
! pfclose (r->pool, f);
! return OK;
}
!
if (r->main) {
! /* Kludge --- for nested includes, we want to keep the
! * subprocess environment of the base document (for compatibility);
! * that means torquing our own last_modified date as well so that
! * the LAST_MODIFIED variable gets reset to the proper value if
! * the nested document resets
! */
! r->subprocess_env = r->main->subprocess_env;
! r->finfo.st_mtime= r->main->finfo.st_mtime;
! } else {
! add_common_vars (r);
! add_cgi_vars(r);
! add_include_vars (r, DEFAULT_TIME_FORMAT);
}
hard_timeout("send SSI", r);
! send_parsed_content (f, r);
!
! kill_timeout (r);
return OK;
}
! int send_shtml_file (request_rec *r)
{
r->content_type = "text/html";
return send_parsed_file(r);
}
! int xbithack_handler (request_rec *r)
{
- enum xbithack *state;
-
#ifdef __EMX__
/* OS/2 dosen't currently support the xbithack. This is being worked on. */
return DECLINED;
#else
! if (!(r->finfo.st_mode & S_IXUSR)) return DECLINED;
! state = (enum xbithack *)get_module_config(r->per_dir_config,
! &includes_module);
!
! if (*state == xbithack_off) return DECLINED;
! return send_parsed_file (r);
#endif
}
! command_rec includes_cmds[] = {
! { "XBitHack", set_xbithack, NULL, OR_OPTIONS, TAKE1, "Off, On, or Full" },
! { NULL }
};
! handler_rec includes_handlers[] = {
! { INCLUDES_MAGIC_TYPE, send_shtml_file },
! { INCLUDES_MAGIC_TYPE3, send_shtml_file },
! { "server-parsed", send_parsed_file },
! { "text/html", xbithack_handler },
! { NULL }
};
! module includes_module = {
! STANDARD_MODULE_STUFF,
! NULL, /* initializer */
! create_includes_dir_config, /* dir config creater */
! NULL, /* dir merger --- default is to override */
! NULL, /* server config */
! NULL, /* merge server config */
! includes_cmds, /* command table */
! includes_handlers, /* handlers */
! NULL, /* filename translation */
! NULL, /* check_user_id */
! NULL, /* check auth */
! NULL, /* check access */
! NULL, /* type_checker */
! NULL, /* fixups */
! NULL, /* logger */
! NULL /* header parser */
};
--- 2232,2323 ----
send_http_header(r);
if (r->header_only) {
! pfclose(r->pool, f);
! return OK;
}
!
if (r->main) {
! /* Kludge --- for nested includes, we want to keep the
! * subprocess environment of the base document (for compatibility);
! * that means torquing our own last_modified date as well so that
! * the LAST_MODIFIED variable gets reset to the proper value if
! * the nested document resets
! */
! r->subprocess_env = r->main->subprocess_env;
! r->finfo.st_mtime = r->main->finfo.st_mtime;
! }
! else {
! add_common_vars(r);
! add_cgi_vars(r);
! add_include_vars(r, DEFAULT_TIME_FORMAT);
}
hard_timeout("send SSI", r);
! send_parsed_content(f, r);
!
! kill_timeout(r);
return OK;
}
! static int send_shtml_file(request_rec *r)
{
r->content_type = "text/html";
return send_parsed_file(r);
}
! static int xbithack_handler(request_rec *r)
{
#ifdef __EMX__
/* OS/2 dosen't currently support the xbithack. This is being worked on. */
return DECLINED;
#else
! enum xbithack *state;
!
! if (!(r->finfo.st_mode & S_IXUSR)) {
! return DECLINED;
! }
!
! state = (enum xbithack *) get_module_config(r->per_dir_config,
! &includes_module);
! if (*state == xbithack_off) {
! return DECLINED;
! }
! return send_parsed_file(r);
#endif
}
! static command_rec includes_cmds[] =
! {
! {"XBitHack", set_xbithack, NULL, OR_OPTIONS, TAKE1, "Off, On, or Full"},
! {NULL}
};
! static handler_rec includes_handlers[] =
! {
! {INCLUDES_MAGIC_TYPE, send_shtml_file},
! {INCLUDES_MAGIC_TYPE3, send_shtml_file},
! {"server-parsed", send_parsed_file},
! {"text/html", xbithack_handler},
! {NULL}
};
! module includes_module =
! {
! STANDARD_MODULE_STUFF,
! NULL, /* initializer */
! create_includes_dir_config, /* dir config creater */
! NULL, /* dir merger --- default is to override */
! NULL, /* server config */
! NULL, /* merge server config */
! includes_cmds, /* command table */
! includes_handlers, /* handlers */
! NULL, /* filename translation */
! NULL, /* check_user_id */
! NULL, /* check auth */
! NULL, /* check access */
! NULL, /* type_checker */
! NULL, /* fixups */
! NULL, /* logger */
! NULL /* header parser */
};
Index: apache-1.2-rus/src/mod_negotiation.c
diff -c apache-1.2-rus/src/mod_negotiation.c:1.3 apache-1.2-rus/src/mod_negotiation.c:1.4
*** apache-1.2-rus/src/mod_negotiation.c:1.3 Sat Aug 23 17:03:25 1997
--- apache-1.2-rus/src/mod_negotiation.c Fri Jan 9 22:25:32 1998
***************
*** 623,630 ****
{
char *cp = header;
! while (*cp && *cp != ':')
! *cp++ = tolower(*cp);
if (!*cp) {
log_reason ("Syntax error in type map --- no ':'", r->filename, r);
--- 623,631 ----
{
char *cp = header;
! for ( ; *cp && *cp != ':' ; ++cp) {
! *cp = tolower(*cp);
! }
if (!*cp) {
log_reason ("Syntax error in type map --- no ':'", r->filename, r);
Index: apache-1.2-rus/src/mod_userdir.c
diff -c apache-1.2-rus/src/mod_userdir.c:1.1.1.1 apache-1.2-rus/src/mod_userdir.c:1.2
*** apache-1.2-rus/src/mod_userdir.c:1.1.1.1 Wed Jun 18 00:20:11 1997
--- apache-1.2-rus/src/mod_userdir.c Fri Jan 9 22:25:34 1998
***************
*** 114,119 ****
--- 114,120 ----
char *name = r->uri;
const char *w, *dname, *redirect;
char *x = NULL;
+ struct stat statbuf;
if (userdirs == NULL || !strcasecmp(userdirs, "disabled") ||
(name[0] != '/') || (name[1] != '~')) {
***************
*** 182,189 ****
in the hope that some handler might handle it. This can be used, for
example, to run a CGI script for the user.
*/
! if (filename && (!*userdirs || stat(filename, &r->finfo) != -1)) {
r->filename = pstrcat(r->pool, filename, dname, NULL);
return OK;
}
}
--- 183,191 ----
in the hope that some handler might handle it. This can be used, for
example, to run a CGI script for the user.
*/
! if (filename && (!*userdirs || stat(filename, &statbuf) != -1)) {
r->filename = pstrcat(r->pool, filename, dname, NULL);
+ r->finfo = statbuf;
return OK;
}
}
Index: apache-1.2-rus/src/util.c
diff -c apache-1.2-rus/src/util.c:1.2 apache-1.2-rus/src/util.c:1.3
*** apache-1.2-rus/src/util.c:1.2 Mon Jul 7 16:40:33 1997
--- apache-1.2-rus/src/util.c Fri Jan 9 22:25:35 1998
***************
*** 83,88 ****
--- 83,89 ----
/* check return code? */
strftime(ts,MAX_STRING_LEN,fmt,tms);
+ ts[MAX_STRING_LEN - 1] = '\0';
return pstrdup (p, ts);
}
***************
*** 328,341 ****
}
}
! void no2slash(char *name) {
! register int x,y;
! for(x=0; name[x];)
! if(x && (name[x-1] == '/') && (name[x] == '/'))
! for(y=x+1;name[y-1];y++)
! name[y-1] = name[y];
! else x++;
}
char *make_dirstr(pool *p, const char *s, int n) {
--- 329,350 ----
}
}
! void no2slash(char *name)
! {
! char *d, *s;
! s = d = name;
! while (*s) {
! if ((*d++ = *s) == '/') {
! do {
! ++s;
! } while (*s == '/');
! }
! else {
! ++s;
! }
! }
! *d = '\0';
}
char *make_dirstr(pool *p, const char *s, int n) {
***************
*** 561,566 ****
--- 570,580 ----
if(c == EOF)
return 1;
+ if(n < 2) {
+ /* too small, assume caller is crazy */
+ return 1;
+ }
+
while(1) {
if((c == '\t') || (c == ' ')) {
s[i++] = ' ';
***************
*** 570,576 ****
if(c == CR) {
c = getc(f);
}
! if(c == EOF || c == 0x4 || c == LF || i == (n-1)) {
/* blast trailing whitespace */
while(i && (s[i-1] == ' ')) --i;
s[i] = '\0';
--- 584,590 ----
if(c == CR) {
c = getc(f);
}
! if(c == EOF || c == 0x4 || c == LF || i >= (n-2)) {
/* blast trailing whitespace */
while(i && (s[i-1] == ' ')) --i;
s[i] = '\0';
Index: apache-1.2-rus/src/modules/proxy/proxy_cache.c
diff -c apache-1.2-rus/src/modules/proxy/proxy_cache.c:1.2 apache-1.2-rus/src/modules/proxy/proxy_cache.c:1.3
*** apache-1.2-rus/src/modules/proxy/proxy_cache.c:1.2 Sat Aug 23 17:03:36 1997
--- apache-1.2-rus/src/modules/proxy/proxy_cache.c Fri Jan 9 22:25:37 1998
***************
*** 84,89 ****
--- 84,90 ----
static unsigned long int curblocks;
static time_t now, expire;
static char *filename;
+ static int filenamelen;
static int sub_garbage_coll(request_rec *r,array_header *files,
const char *cachedir,const char *cachesubdir);
***************
*** 111,119 ****
block_alarms(); /* avoid SIGALRM on big cache cleanup */
! filename = palloc(r->pool, strlen(cachedir) + HASH_LEN + 2);
! strcpy(filename, cachedir);
! strcat(filename, "/.time");
if (stat(filename, &buf) == -1) /* does not exist */
{
if (errno != ENOENT)
--- 112,121 ----
block_alarms(); /* avoid SIGALRM on big cache cleanup */
! filenamelen = strlen(cachedir) + HASH_LEN + 2;
! filename = palloc(r->pool, filenamelen);
! ap_snprintf(filename, filenamelen, "%s/.time", cachedir);
!
if (stat(filename, &buf) == -1) /* does not exist */
{
if (errno != ENOENT)
***************
*** 161,167 ****
for (i=0; i < files->nelts; i++)
{
fent = elts[i];
! sprintf(filename, "%s%s", cachedir, fent->file);
Explain3("GC Unlinking %s (expiry %ld, now %ld)",filename,fent->expire,now);
#if TESTING
fprintf(stderr,"Would unlink %s\n",filename);
--- 163,169 ----
for (i=0; i < files->nelts; i++)
{
fent = elts[i];
! ap_snprintf(filename, filenamelen, "%s%s", cachedir, fent->file);
Explain3("GC Unlinking %s (expiry %ld, now %ld)",filename,fent->expire,now);
#if TESTING
fprintf(stderr,"Would unlink %s\n",filename);
***************
*** 216,222 ****
while ((ent = readdir(dir)) != NULL)
{
if (ent->d_name[0] == '.') continue;
! sprintf(filename, "%s%s", cachedir, ent->d_name);
Explain1("GC Examining file %s",filename);
/* is it a temporary file? */
if (strncmp(ent->d_name, "tmp", 3) == 0)
--- 218,224 ----
while ((ent = readdir(dir)) != NULL)
{
if (ent->d_name[0] == '.') continue;
! ap_snprintf(filename, filenamelen, "%s%s", cachedir, ent->d_name);
Explain1("GC Examining file %s",filename);
/* is it a temporary file? */
if (strncmp(ent->d_name, "tmp", 3) == 0)
***************
*** 315,322 ****
fent = palloc(r->pool, sizeof(struct gc_ent));
fent->len = buf.st_size;
fent->expire = expire;
! strcpy(fent->file,cachesubdir);
! strcat(fent->file, ent->d_name);
*(struct gc_ent **)push_array(files) = fent;
/* accumulate in blocks, to cope with directories > 4Gb */
--- 317,324 ----
fent = palloc(r->pool, sizeof(struct gc_ent));
fent->len = buf.st_size;
fent->expire = expire;
! ap_snprintf(fent->file, sizeof(fent->file), "%s%s", cachesubdir,
! ent->d_name);
*(struct gc_ent **)push_array(files) = fent;
/* accumulate in blocks, to cope with directories > 4Gb */
Index: apache-1.2-rus/src/modules/proxy/proxy_ftp.c
diff -c apache-1.2-rus/src/modules/proxy/proxy_ftp.c:1.2 apache-1.2-rus/src/modules/proxy/proxy_ftp.c:1.3
*** apache-1.2-rus/src/modules/proxy/proxy_ftp.c:1.2 Sat Aug 23 17:03:38 1997
--- apache-1.2-rus/src/modules/proxy/proxy_ftp.c Fri Jan 9 22:25:39 1998
***************
*** 286,293 ****
buf[sizeof(buf)-1] = '\0';
n=strlen(buf);
}
! else if(buf[0]=='d' || buf[0]=='-' || buf[0]=='l' || isdigit(buf[0]))
! {
if(isdigit(buf[0])) { /* handle DOS dir */
searchptr = strchr(buf, '<');
if(searchptr != NULL)
--- 286,293 ----
buf[sizeof(buf)-1] = '\0';
n=strlen(buf);
}
! else if (strrchr(buf, ' ') && (buf[0]=='d' || buf[0]=='-' ||
! buf[0]=='l' || isdigit(buf[0])) ) {
if(isdigit(buf[0])) { /* handle DOS dir */
searchptr = strchr(buf, '<');
if(searchptr != NULL)
Index: apache-1.2-rus/src/modules/proxy/proxy_util.c
diff -c apache-1.2-rus/src/modules/proxy/proxy_util.c:1.1.1.1 apache-1.2-rus/src/modules/proxy/proxy_util.c:1.2
*** apache-1.2-rus/src/modules/proxy/proxy_util.c:1.1.1.1 Wed Jun 18 00:20:13 1997
--- apache-1.2-rus/src/modules/proxy/proxy_util.c Fri Jan 9 22:25:42 1998
***************
*** 296,303 ****
for (mon=0; mon < 12; mon++) if (strcmp(month, months[mon]) == 0) break;
if (mon == 12) return x;
! if (strlen(x) < 31) x = palloc(p, 31);
! ap_snprintf(x, strlen(x)+1, "%s, %.2d %s %d %.2d:%.2d:%.2d GMT", wday[wk], mday,
months[mon], year, hour, min, sec);
return x;
}
--- 296,306 ----
for (mon=0; mon < 12; mon++) if (strcmp(month, months[mon]) == 0) break;
if (mon == 12) return x;
! if (strlen(x)+1 < 30) {
! x = palloc(p, 30);
! }
! /* format: "Wed, 17 Dec 1997 00:53:40 GMT" (29 chars data) */
! ap_snprintf(x, 30, "%s, %.2d %s %d %.2d:%.2d:%.2d GMT", wday[wk], mday,
months[mon], year, hour, min, sec);
return x;
}
Index: apache-1.2-rus/support/logresolve.c
diff -c apache-1.2-rus/support/logresolve.c:1.1.1.1 apache-1.2-rus/support/logresolve.c:1.2
*** apache-1.2-rus/support/logresolve.c:1.1.1.1 Wed Jun 18 00:20:29 1997
--- apache-1.2-rus/support/logresolve.c Fri Jan 9 22:25:44 1998
***************
*** 202,208 ****
} else
cachehits++;
! strcpy(string, (*current)->hostname);
}
/*
--- 202,210 ----
} else
cachehits++;
! /* size of string == MAXDNAME +1 */
! strncpy(string, (*current)->hostname, MAXDNAME);
! string[MAXDNAME] = '\0';
}
/*
Index: apache-1.2-rus/support/suexec.c
diff -c apache-1.2-rus/support/suexec.c:1.2 apache-1.2-rus/support/suexec.c:1.3
*** apache-1.2-rus/support/suexec.c:1.2 Mon Jul 7 16:43:28 1997
--- apache-1.2-rus/support/suexec.c Fri Jan 9 22:25:46 1998
***************
*** 138,143 ****
--- 138,144 ----
static void err_output(const char *fmt, va_list ap)
{
+ #ifdef LOG_EXEC
time_t timevar;
struct tm *lt;
***************
*** 157,162 ****
--- 158,164 ----
vfprintf(log, fmt, ap);
fflush(log);
+ #endif /* LOG_EXEC */
return;
}