Index: apache-1.2-rus/CHANGES diff -c apache-1.2-rus/CHANGES:1.1.1.1 apache-1.2-rus/CHANGES:1.2 *** apache-1.2-rus/CHANGES:1.1.1.1 Wed Jun 18 00:20:06 1997 --- apache-1.2-rus/CHANGES Fri Jan 9 22:23:01 1998 *************** *** 117,123 **** Apache 1.2. Some of the changes visible to users: - Improved FTP proxy supporting PASV mode - - NoProxy directive for excluding sites to proxy - CONNECT mode ports are configurable from a list - NoCache * directive for disabling proxy caching - Numerous bug fixes --- 117,122 ---- Index: apache-1.2-rus/conf/httpd.conf-dist diff -c apache-1.2-rus/conf/httpd.conf-dist:1.13 apache-1.2-rus/conf/httpd.conf-dist:1.15 *** apache-1.2-rus/conf/httpd.conf-dist:1.13 Thu Jan 1 19:24:15 1998 --- apache-1.2-rus/conf/httpd.conf-dist Fri Jan 9 22:23:06 1998 *************** *** 129,135 **** CharsetAgent ibm866 DosLynx # Agents that can't understand MIME ! CharsetBadAgent arena Lynx/2.0 Lynx/2.1 Lynx/2.2 Lynx/2.3 Lynx/2.4 "MSIE 2.0;" # Uncomment this if server must reject queries with illegal charset #CharsetErrReject on --- 129,135 ---- CharsetAgent ibm866 DosLynx # Agents that can't understand MIME ! CharsetBadAgent arena Lynx/2.0 Lynx/2.1 Lynx/2.2 Lynx/2.3 Lynx/2.4 "MSIE 2.0;" Lynx2/OS/2 # Uncomment this if server must reject queries with illegal charset #CharsetErrReject on *************** *** 279,285 **** # alias flag, or through kernel patches like VIF. # Any httpd.conf or srm.conf directive may go into a VirtualHost command. ! # See alto the BindAddress entry. # #ServerAdmin webmaster@host.some_domain.com --- 279,285 ---- # alias flag, or through kernel patches like VIF. # Any httpd.conf or srm.conf directive may go into a VirtualHost command. ! # See also the BindAddress entry. # #ServerAdmin webmaster@host.some_domain.com Index: apache-1.2-rus/htdocs/manual/bind.html diff -c apache-1.2-rus/htdocs/manual/bind.html:1.1.1.1 apache-1.2-rus/htdocs/manual/bind.html:1.2 *** apache-1.2-rus/htdocs/manual/bind.html:1.1.1.1 Wed Jun 18 00:20:16 1997 --- apache-1.2-rus/htdocs/manual/bind.html Fri Jan 9 22:23:08 1998 *************** *** 13,18 **** --- 13,21 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Setting which addresses and ports Apache uses

*************** *** 107,112 **** --- 110,118 ---- <VirtualHost> section.
+

+ Apache HTTP Server Version 1.2 +

Index Index: apache-1.2-rus/htdocs/manual/cgi_path.html diff -c apache-1.2-rus/htdocs/manual/cgi_path.html:1.1.1.1 apache-1.2-rus/htdocs/manual/cgi_path.html:1.2 *** apache-1.2-rus/htdocs/manual/cgi_path.html:1.1.1.1 Wed Jun 18 00:20:16 1997 --- apache-1.2-rus/htdocs/manual/cgi_path.html Fri Jan 9 22:23:10 1998 *************** *** 13,18 **** --- 13,21 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

PATH_INFO Changes in the CGI Environment

*************** *** 91,96 **** --- 94,102 ---- CGI/1.1 specification, including all versions of Apache.


+

+ Apache HTTP Server Version 1.2 +

Index Index: apache-1.2-rus/htdocs/manual/content-negotiation.html diff -c apache-1.2-rus/htdocs/manual/content-negotiation.html:1.1.1.1 apache-1.2-rus/htdocs/manual/content-negotiation.html:1.2 *** apache-1.2-rus/htdocs/manual/content-negotiation.html:1.1.1.1 Wed Jun 18 00:20:16 1997 --- apache-1.2-rus/htdocs/manual/content-negotiation.html Fri Jan 9 22:23:11 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Content Negotiation

*************** *** 425,430 **** --- 428,436 ---- clients.
+

+ Apache HTTP Server Version 1.2 +

Index Index: apache-1.2-rus/htdocs/manual/custom-error.html diff -c apache-1.2-rus/htdocs/manual/custom-error.html:1.2 apache-1.2-rus/htdocs/manual/custom-error.html:1.3 *** apache-1.2-rus/htdocs/manual/custom-error.html:1.2 Mon Jul 7 16:44:35 1997 --- apache-1.2-rus/htdocs/manual/custom-error.html Fri Jan 9 22:23:12 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Custom error responses

*************** *** 152,157 **** --- 155,163 ----
+

+ Apache HTTP Server Version 1.2 +

Index Index: apache-1.2-rus/htdocs/manual/dns-caveats.html diff -c apache-1.2-rus/htdocs/manual/dns-caveats.html:1.1.1.1 apache-1.2-rus/htdocs/manual/dns-caveats.html:1.2 *** apache-1.2-rus/htdocs/manual/dns-caveats.html:1.1.1.1 Wed Jun 18 00:20:16 1997 --- apache-1.2-rus/htdocs/manual/dns-caveats.html Fri Jan 9 22:23:14 1998 *************** *** 13,18 **** --- 13,21 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Issues Regarding DNS and Apache

*************** *** 199,204 **** --- 202,210 ---- critical webservers.
+

+ Apache HTTP Server Version 1.2 +

Index Index: apache-1.2-rus/htdocs/manual/env.html diff -c apache-1.2-rus/htdocs/manual/env.html:1.1.1.1 apache-1.2-rus/htdocs/manual/env.html:1.2 *** apache-1.2-rus/htdocs/manual/env.html:1.1.1.1 Wed Jun 18 00:20:16 1997 --- apache-1.2-rus/htdocs/manual/env.html Fri Jan 9 22:23:16 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Special Purpose Environment Variables

*************** *** 40,45 **** --- 43,51 ---- them.
+

+ Apache HTTP Server Version 1.2 +

Index Index: apache-1.2-rus/htdocs/manual/footer.html diff -c apache-1.2-rus/htdocs/manual/footer.html:1.1.1.1 apache-1.2-rus/htdocs/manual/footer.html:1.2 *** apache-1.2-rus/htdocs/manual/footer.html:1.1.1.1 Wed Jun 18 00:20:16 1997 --- apache-1.2-rus/htdocs/manual/footer.html Fri Jan 9 22:23:17 1998 *************** *** 1,3 **** --- 1,6 ----
+

+ Apache HTTP Server Version 1.2 +

Index Index: apache-1.2-rus/htdocs/manual/handler.html diff -c apache-1.2-rus/htdocs/manual/handler.html:1.1.1.1 apache-1.2-rus/htdocs/manual/handler.html:1.2 *** apache-1.2-rus/htdocs/manual/handler.html:1.1.1.1 Wed Jun 18 00:20:16 1997 --- apache-1.2-rus/htdocs/manual/handler.html Fri Jan 9 22:23:18 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Apache's Handler Use

*************** *** 139,144 **** --- 142,150 ---- type name-space.


+

+ Apache HTTP Server Version 1.2 +

Index Index: apache-1.2-rus/htdocs/manual/header.html diff -c apache-1.2-rus/htdocs/manual/header.html:1.1.1.1 apache-1.2-rus/htdocs/manual/header.html:1.2 *** apache-1.2-rus/htdocs/manual/header.html:1.1.1.1 Wed Jun 18 00:20:16 1997 --- apache-1.2-rus/htdocs/manual/header.html Fri Jan 9 22:23:21 1998 *************** *** 1,3 **** --- 1,6 ----
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Index: apache-1.2-rus/htdocs/manual/host.html diff -c apache-1.2-rus/htdocs/manual/host.html:1.1.1.1 apache-1.2-rus/htdocs/manual/host.html:1.2 *** apache-1.2-rus/htdocs/manual/host.html:1.1.1.1 Wed Jun 18 00:20:16 1997 --- apache-1.2-rus/htdocs/manual/host.html Fri Jan 9 22:23:24 1998 *************** *** 13,18 **** --- 13,21 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Apache non-IP Virtual Hosts

*************** *** 171,176 **** --- 174,182 ---- pages.


+

+ Apache HTTP Server Version 1.2 +

Index Index: apache-1.2-rus/htdocs/manual/index.html diff -c apache-1.2-rus/htdocs/manual/index.html:1.1.1.1 apache-1.2-rus/htdocs/manual/index.html:1.2 *** apache-1.2-rus/htdocs/manual/index.html:1.1.1.1 Wed Jun 18 00:20:16 1997 --- apache-1.2-rus/htdocs/manual/index.html Fri Jan 9 22:23:25 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Apache User's Guide

*************** *** 65,70 **** --- 68,76 ----
+

+ Apache HTTP Server Version 1.2 +

Index Index: apache-1.2-rus/htdocs/manual/install.html diff -c apache-1.2-rus/htdocs/manual/install.html:1.1.1.1 apache-1.2-rus/htdocs/manual/install.html:1.2 *** apache-1.2-rus/htdocs/manual/install.html:1.1.1.1 Wed Jun 18 00:20:17 1997 --- apache-1.2-rus/htdocs/manual/install.html Fri Jan 9 22:23:26 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

*************** *** 248,253 **** --- 251,259 ----
+

+ Apache HTTP Server Version 1.2 +

Index Index: apache-1.2-rus/htdocs/manual/install_1_1.html diff -c apache-1.2-rus/htdocs/manual/install_1_1.html:1.1.1.1 apache-1.2-rus/htdocs/manual/install_1_1.html:1.2 *** apache-1.2-rus/htdocs/manual/install_1_1.html:1.1.1.1 Wed Jun 18 00:20:17 1997 --- apache-1.2-rus/htdocs/manual/install_1_1.html Fri Jan 9 22:23:28 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Compiling and Installing Apache

*************** *** 111,116 **** --- 114,122 ---- httpd.conf.
+

+ Apache HTTP Server Version 1.2 +

Index Index: apache-1.2-rus/htdocs/manual/invoking.html diff -c apache-1.2-rus/htdocs/manual/invoking.html:1.1.1.1 apache-1.2-rus/htdocs/manual/invoking.html:1.2 *** apache-1.2-rus/htdocs/manual/invoking.html:1.1.1.1 Wed Jun 18 00:20:17 1997 --- apache-1.2-rus/htdocs/manual/invoking.html Fri Jan 9 22:23:29 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Starting Apache

*************** *** 123,128 **** --- 126,134 ---- hosts.
+

+ Apache HTTP Server Version 1.2 +

Index Index: apache-1.2-rus/htdocs/manual/keepalive.html diff -c apache-1.2-rus/htdocs/manual/keepalive.html:1.1.1.1 apache-1.2-rus/htdocs/manual/keepalive.html:1.2 *** apache-1.2-rus/htdocs/manual/keepalive.html:1.1.1.1 Wed Jun 18 00:20:17 1997 --- apache-1.2-rus/htdocs/manual/keepalive.html Fri Jan 9 22:23:31 1998 *************** *** 13,18 **** --- 13,21 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Apache Keep-Alive Support

*************** *** 77,82 **** --- 80,88 ---- to the end user, it is something the web-master may want to keep in mind.


+

+ Apache HTTP Server Version 1.2 +

Index Index: apache-1.2-rus/htdocs/manual/location.html diff -c apache-1.2-rus/htdocs/manual/location.html:1.1.1.1 apache-1.2-rus/htdocs/manual/location.html:1.2 *** apache-1.2-rus/htdocs/manual/location.html:1.1.1.1 Wed Jun 18 00:20:17 1997 --- apache-1.2-rus/htdocs/manual/location.html Fri Jan 9 22:23:32 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Access Control by URL

*************** *** 57,62 **** --- 60,68 ----
+

+ Apache HTTP Server Version 1.2 +

Index Index: apache-1.2-rus/htdocs/manual/man-template.html diff -c apache-1.2-rus/htdocs/manual/man-template.html:1.1.1.1 apache-1.2-rus/htdocs/manual/man-template.html:1.2 *** apache-1.2-rus/htdocs/manual/man-template.html:1.1.1.1 Wed Jun 18 00:20:17 1997 --- apache-1.2-rus/htdocs/manual/man-template.html Fri Jan 9 22:23:33 1998 *************** *** 16,21 **** --- 16,24 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Module mod_foobar

*************** *** 67,72 **** --- 70,78 ---- The ADirective directive does something.
+

+ Apache HTTP Server Version 1.2 +

Index Index: apache-1.2-rus/htdocs/manual/multilogs.html diff -c apache-1.2-rus/htdocs/manual/multilogs.html:1.1.1.1 apache-1.2-rus/htdocs/manual/multilogs.html:1.2 *** apache-1.2-rus/htdocs/manual/multilogs.html:1.1.1.1 Wed Jun 18 00:20:17 1997 --- apache-1.2-rus/htdocs/manual/multilogs.html Fri Jan 9 22:23:35 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Multiple Log Files

*************** *** 121,126 **** --- 124,132 ---- log format), and not in logs/access_log or logs/referer.
+

+ Apache HTTP Server Version 1.2 +

Index Index: apache-1.2-rus/htdocs/manual/new_features_1_0.html diff -c apache-1.2-rus/htdocs/manual/new_features_1_0.html:1.1.1.1 apache-1.2-rus/htdocs/manual/new_features_1_0.html:1.2 *** apache-1.2-rus/htdocs/manual/new_features_1_0.html:1.1.1.1 Wed Jun 18 00:20:17 1997 --- apache-1.2-rus/htdocs/manual/new_features_1_0.html Fri Jan 9 22:23:36 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Overview of new features

*************** *** 123,128 **** --- 126,134 ----
+

+ Apache HTTP Server Version 1.2 +

Index Index: apache-1.2-rus/htdocs/manual/new_features_1_1.html diff -c apache-1.2-rus/htdocs/manual/new_features_1_1.html:1.1.1.1 apache-1.2-rus/htdocs/manual/new_features_1_1.html:1.2 *** apache-1.2-rus/htdocs/manual/new_features_1_1.html:1.1.1.1 Wed Jun 18 00:20:17 1997 --- apache-1.2-rus/htdocs/manual/new_features_1_1.html Fri Jan 9 22:23:38 1998 *************** *** 13,18 **** --- 13,21 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Overview of new features

*************** *** 211,216 **** --- 214,222 ----

Apache now includes support for OS/2, thanks to Softlink Services.


+

+ Apache HTTP Server Version 1.2 +

Index Index: apache-1.2-rus/htdocs/manual/new_features_1_2.html diff -c apache-1.2-rus/htdocs/manual/new_features_1_2.html:1.2 apache-1.2-rus/htdocs/manual/new_features_1_2.html:1.3 *** apache-1.2-rus/htdocs/manual/new_features_1_2.html:1.2 Mon Jul 7 16:44:36 1997 --- apache-1.2-rus/htdocs/manual/new_features_1_2.html Fri Jan 9 22:23:39 1998 *************** *** 13,18 **** --- 13,21 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Overview of new features

*************** *** 206,211 **** --- 209,217 ----
+

+ Apache HTTP Server Version 1.2 +

Index Index: apache-1.2-rus/htdocs/manual/process-model.html diff -c apache-1.2-rus/htdocs/manual/process-model.html:1.2 apache-1.2-rus/htdocs/manual/process-model.html:1.3 *** apache-1.2-rus/htdocs/manual/process-model.html:1.2 Mon Jul 7 16:44:37 1997 --- apache-1.2-rus/htdocs/manual/process-model.html Fri Jan 9 22:23:40 1998 *************** *** 13,18 **** --- 13,21 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Server Pool Management

*************** *** 66,71 **** --- 69,77 ----
+

+ Apache HTTP Server Version 1.2 +

Index Index: apache-1.2-rus/htdocs/manual/stopping.html diff -c apache-1.2-rus/htdocs/manual/stopping.html:1.1.1.1 apache-1.2-rus/htdocs/manual/stopping.html:1.2 *** apache-1.2-rus/htdocs/manual/stopping.html:1.1.1.1 Wed Jun 18 00:20:17 1997 --- apache-1.2-rus/htdocs/manual/stopping.html Fri Jan 9 22:23:42 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Stopping and Restarting Apache

*************** *** 165,170 **** --- 168,176 ---- empty documents.
+

+ Apache HTTP Server Version 1.2 +

Index Index: apache-1.2-rus/htdocs/manual/suexec.html diff -c apache-1.2-rus/htdocs/manual/suexec.html:1.2 apache-1.2-rus/htdocs/manual/suexec.html:1.3 *** apache-1.2-rus/htdocs/manual/suexec.html:1.2 Mon Jul 7 16:44:37 1997 --- apache-1.2-rus/htdocs/manual/suexec.html Fri Jan 9 22:23:43 1998 *************** *** 13,18 **** --- 13,21 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

*************** *** 505,510 **** --- 508,516 ----


+

+ Apache HTTP Server Version 1.2 +

Index Index: apache-1.2-rus/htdocs/manual/unixware.html diff -c apache-1.2-rus/htdocs/manual/unixware.html:1.1.1.1 apache-1.2-rus/htdocs/manual/unixware.html:1.2 *** apache-1.2-rus/htdocs/manual/unixware.html:1.1.1.1 Wed Jun 18 00:20:18 1997 --- apache-1.2-rus/htdocs/manual/unixware.html Fri Jan 9 22:23:45 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

*************** *** 60,65 **** --- 63,71 ---- <rvaughn@aad.com> for additional info for UnixWare builds.


+

+ Apache HTTP Server Version 1.2 +

Index Index: apache-1.2-rus/htdocs/manual/vhosts-in-depth.html diff -c apache-1.2-rus/htdocs/manual/vhosts-in-depth.html:1.2 apache-1.2-rus/htdocs/manual/vhosts-in-depth.html:1.3 *** apache-1.2-rus/htdocs/manual/vhosts-in-depth.html:1.2 Mon Jul 7 16:44:38 1997 --- apache-1.2-rus/htdocs/manual/vhosts-in-depth.html Fri Jan 9 22:23:47 1998 *************** *** 13,18 **** --- 13,21 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

An In-Depth Discussion of VirtualHost Matching

*************** *** 385,390 **** --- 388,396 ----
+

+ Apache HTTP Server Version 1.2 +

Index Index: apache-1.2-rus/htdocs/manual/virtual-host.html diff -c apache-1.2-rus/htdocs/manual/virtual-host.html:1.2 apache-1.2-rus/htdocs/manual/virtual-host.html:1.3 *** apache-1.2-rus/htdocs/manual/virtual-host.html:1.2 Mon Jul 7 16:44:40 1997 --- apache-1.2-rus/htdocs/manual/virtual-host.html Fri Jan 9 22:23:48 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Virtual Host Support

*************** *** 203,208 **** --- 206,214 ---- The latter will probably manifest itself in a later version of Apache.
+

+ Apache HTTP Server Version 1.2 +

Index Index: apache-1.2-rus/htdocs/manual/misc/API.html diff -c apache-1.2-rus/htdocs/manual/misc/API.html:1.1.1.1 apache-1.2-rus/htdocs/manual/misc/API.html:1.2 *** apache-1.2-rus/htdocs/manual/misc/API.html:1.1.1.1 Wed Jun 18 00:20:21 1997 --- apache-1.2-rus/htdocs/manual/misc/API.html Fri Jan 9 22:23:50 1998 *************** *** 12,17 **** --- 12,20 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Apache API notes

*************** *** 1004,1009 **** --- 1007,1015 ---- }
+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/misc/FAQ.html diff -c apache-1.2-rus/htdocs/manual/misc/FAQ.html:1.4 apache-1.2-rus/htdocs/manual/misc/FAQ.html:1.5 *** apache-1.2-rus/htdocs/manual/misc/FAQ.html:1.4 Sat Aug 23 16:57:39 1997 --- apache-1.2-rus/htdocs/manual/misc/FAQ.html Fri Jan 9 22:23:52 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Apache Server Frequently Asked Questions

*************** *** 2057,2062 **** --- 2060,2068 ----
+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/misc/client_block_api.html diff -c apache-1.2-rus/htdocs/manual/misc/client_block_api.html:1.1.1.1 apache-1.2-rus/htdocs/manual/misc/client_block_api.html:1.2 *** apache-1.2-rus/htdocs/manual/misc/client_block_api.html:1.1.1.1 Wed Jun 18 00:20:21 1997 --- apache-1.2-rus/htdocs/manual/misc/client_block_api.html Fri Jan 9 22:23:53 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Reading Client Input in Apache 1.2

*************** *** 85,90 **** --- 88,96 ---- guidelines.


+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/misc/compat_notes.html diff -c apache-1.2-rus/htdocs/manual/misc/compat_notes.html:1.3 apache-1.2-rus/htdocs/manual/misc/compat_notes.html:1.4 *** apache-1.2-rus/htdocs/manual/misc/compat_notes.html:1.3 Sat Aug 23 16:57:41 1997 --- apache-1.2-rus/htdocs/manual/misc/compat_notes.html Fri Jan 9 22:23:55 1998 *************** *** 12,17 **** --- 12,20 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Compatibility Notes with NCSA's Server

*************** *** 89,102 **** If you are using the same srm.conf from an old distribution, make sure you add the new AddIcon, AddIconByType, and DefaultIcon directives. --- 92,105 ---- If you are using the same srm.conf from an old distribution, make sure you add the new AddIcon, AddIconByType, and DefaultIcon directives. *************** *** 135,140 **** --- 138,146 ---- More to come when we notice them....
+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/misc/descriptors.html diff -c apache-1.2-rus/htdocs/manual/misc/descriptors.html:1.2 apache-1.2-rus/htdocs/manual/misc/descriptors.html:1.3 *** apache-1.2-rus/htdocs/manual/misc/descriptors.html:1.2 Sat Aug 23 16:57:42 1997 --- apache-1.2-rus/htdocs/manual/misc/descriptors.html Fri Jan 9 22:23:57 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Descriptors and Apache

*************** *** 154,159 **** --- 157,165 ---- we can investigate.
+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/misc/fin_wait_2.html diff -c apache-1.2-rus/htdocs/manual/misc/fin_wait_2.html:1.2 apache-1.2-rus/htdocs/manual/misc/fin_wait_2.html:1.3 *** apache-1.2-rus/htdocs/manual/misc/fin_wait_2.html:1.2 Mon Jul 7 16:44:44 1997 --- apache-1.2-rus/htdocs/manual/misc/fin_wait_2.html Fri Jan 9 22:23:58 1998 *************** *** 16,21 **** --- 16,24 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

*************** *** 326,331 **** --- 329,337 ---- problem -- it only moves it to a different and much harder one to detect.
+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/misc/footer.html diff -c apache-1.2-rus/htdocs/manual/misc/footer.html:1.1.1.1 apache-1.2-rus/htdocs/manual/misc/footer.html:1.2 *** apache-1.2-rus/htdocs/manual/misc/footer.html:1.1.1.1 Wed Jun 18 00:20:21 1997 --- apache-1.2-rus/htdocs/manual/misc/footer.html Fri Jan 9 22:23:59 1998 *************** *** 1,4 **** --- 1,7 ----
+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/misc/header.html diff -c apache-1.2-rus/htdocs/manual/misc/header.html:1.1.1.1 apache-1.2-rus/htdocs/manual/misc/header.html:1.2 *** apache-1.2-rus/htdocs/manual/misc/header.html:1.1.1.1 Wed Jun 18 00:20:21 1997 --- apache-1.2-rus/htdocs/manual/misc/header.html Fri Jan 9 22:24:01 1998 *************** *** 1,3 **** --- 1,6 ----
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Index: apache-1.2-rus/htdocs/manual/misc/howto.html diff -c apache-1.2-rus/htdocs/manual/misc/howto.html:1.1.1.1 apache-1.2-rus/htdocs/manual/misc/howto.html:1.2 *** apache-1.2-rus/htdocs/manual/misc/howto.html:1.1.1.1 Wed Jun 18 00:20:21 1997 --- apache-1.2-rus/htdocs/manual/misc/howto.html Fri Jan 9 22:24:02 1998 *************** *** 16,21 **** --- 16,24 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Apache HOWTO documentation

*************** *** 146,151 **** --- 149,157 ---- to the robot information pages provided by Martijn Koster for the syntax.


+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/misc/index.html diff -c apache-1.2-rus/htdocs/manual/misc/index.html:1.2 apache-1.2-rus/htdocs/manual/misc/index.html:1.3 *** apache-1.2-rus/htdocs/manual/misc/index.html:1.2 Mon Jul 7 16:44:45 1997 --- apache-1.2-rus/htdocs/manual/misc/index.html Fri Jan 9 22:24:04 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Apache Miscellaneous Documentation

*************** *** 118,123 **** --- 121,129 ----
+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/misc/known_bugs.html diff -c apache-1.2-rus/htdocs/manual/misc/known_bugs.html:1.3 apache-1.2-rus/htdocs/manual/misc/known_bugs.html:1.4 *** apache-1.2-rus/htdocs/manual/misc/known_bugs.html:1.3 Sat Aug 23 16:57:43 1997 --- apache-1.2-rus/htdocs/manual/misc/known_bugs.html Fri Jan 9 22:24:05 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Known Bugs in Apache

*************** *** 156,161 **** --- 159,167 ----
+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/misc/known_client_problems.html diff -c apache-1.2-rus/htdocs/manual/misc/known_client_problems.html:1.1.3.1 apache-1.2-rus/htdocs/manual/misc/known_client_problems.html:removed *** apache-1.2-rus/htdocs/manual/misc/known_client_problems.html:1.1.3.1 Sat Aug 23 16:46:10 1997 --- apache-1.2-rus/htdocs/manual/misc/known_client_problems.html Fri Jan 9 19:55:11 1998 *************** *** 1,207 **** - - - - Apache HTTP Server Project - - - - -
- [APACHE DOCUMENTATION] -
- -

Known Problems in Clients

- -

Over time the Apache Group has discovered or been notified of problems - with various clients which we have had to work around. This document - describes these problems and the workarounds available. It's not arranged - in any particular order. Some familiarity with the standards is assumed, - but not necessary. - -

For brevity, Navigator will refer to Netscape's Navigator - product, and MSIE will refer to Microsoft's Internet Explorer - product. All trademarks and copyrights belong to their respective - companies. We welcome input from the various client authors to correct - inconsistencies in this paper, or to provide us with exact version - numbers where things are broken/fixed. - -

For reference, - RFC1945 - defines HTTP/1.0, and - RFC2068 - defines HTTP/1.1. Apache as of version 1.2 is an HTTP/1.1 server (with an - optional HTTP/1.0 proxy). - -

Various of these workarounds are triggered by environment variables. - The admin typically controls which are set, and for which clients, by using - mod_browser. Unless otherwise - noted all of these workarounds exist in versions 1.2 and later. - -

Trailing CRLF on POSTs

- -

This is a legacy issue. The CERN webserver required POST - data to have an extra CRLF following it. Thus many - clients send an extra CRLF that - is not included in the Content-Length of the request. - Apache works around this problem by eating any empty lines which - appear before a request. - -

Broken keepalive

- -

Various clients have had broken implementations of keepalive - (persistent connections). In particular the Windows versions of - Navigator 2.0 get very confused when the server times out an - idle connection. The workaround is present in the default config files: -

- BrowserMatch Mozilla/2 nokeepalive -
- Note that this matches some earlier versions of MSIE, which began the - practice of calling themselves Mozilla in their user-agent - strings just like Navigator. - -

MSIE 4.0b2, which claims to support HTTP/1.1, does not properly - support keepalive when it is used on 301 or 302 (redirect) - responses. Unfortunately Apache's nokeepalive code - prior to 1.2.2 would not work with HTTP/1.1 clients. You must apply - this - patch to version 1.2.1. Then add this to your config: -

- BrowserMatch "MSIE 4\.0b2;" nokeepalive -
- -

Incorrect interpretation of HTTP/1.1 in response

- -

To quote from section 3.1 of RFC1945: -

- HTTP uses a "." numbering scheme to indicate versions - of the protocol. The protocol versioning policy is intended to allow - the sender to indicate the format of a message and its capacity for - understanding further HTTP communication, rather than the features - obtained via that communication. -
- Since Apache is an HTTP/1.1 server, it indicates so as part of its - response. Many client authors mistakenly treat this part of the response - as an indication of the protocol that the response is in, and then refuse - to accept the response. - -

The first major indication of this problem was with AOL's proxy servers. - When Apache 1.2 went into beta it was the first wide-spread HTTP/1.1 - server. After some discussion, AOL fixed their proxies. In - anticipation of similar problems, the force-response-1.0 - environment variable was added to Apache. When present Apache will - indicate "HTTP/1.0" in response to an HTTP/1.0 client, - but will not in any other way change the response. - -

The pre-1.1 Java Development Kit (JDK) that is used in many clients - (including Navigator 3.x and MSIE 3.x) exhibits this problem. As do some - of the early pre-releases of the 1.1 JDK. We think it is fixed in the - 1.1 JDK release. In any event the workaround: -

- BrowserMatch Java1.0 force-response-1.0
- BrowserMatch JDK/1.0 force-response-1.0 -
- -

RealPlayer 4.0 from Progressive Networks also exhibits this problem. - However they have fixed it in version 4.01 of the player, but version - 4.01 uses the same User-Agent as version 4.0. The - workaround is still: -

- BrowserMatch "RealPlayer 4.0" force-response-1.0 -
- -

Requests use HTTP/1.1 but responses must be in HTTP/1.0

- -

MSIE 4.0b2 has this problem. Its Java VM makes requests in HTTP/1.1 - format but the responses must be in HTTP/1.0 format (in particular, it - does not understand chunked responses). The workaround - is to fool Apache into believing the request came in HTTP/1.0 format. -

- BrowserMatch "MSIE 4\.0b2;" downgrade-1.0 force-response-1.0 -
- This workaround is available in 1.2.2, and in a - patch - against 1.2.1. - -

Boundary problems with header parsing

- -

All versions of Navigator from 2.0 through 4.0b2 (and possibly later) - have a problem if the trailing CRLF of the response header starts at - the 256th or 257th byte of the response. A BrowserMatch for this would - match on nearly every hit, so the workaround is enabled automatically - on all responses. The workaround is to detect when this condition would - occur in a response and add extra padding to the header to push the - trailing CRLF past the 257th byte of the response. - -

Multipart responses and Quoted Boundary Strings

- -

On multipart responses some clients will not accept quotes (") - around the boundary string. The MIME standard recommends that - such quotes be used. But the clients were probably written based - on one of the examples in RFC2068, which does not include quotes. - Apache does not include quotes on its boundary strings to workaround - this problem. - -

Byterange requests

- -

A byterange request is used when the client wishes to retrieve a - portion of an object, not necessarily the entire object. There - was a very old draft which included these byteranges in the URL. - Old clients such as Navigator 2.0b1 and MSIE 3.0 for the MAC - exhibit this behaviour, and - it will appear in the servers' access logs as (failed) attempts to - retrieve a URL with a trailing ";xxx-yyy". Apache does not attempt - to implement this at all. - -

A subsequent draft of this standard defines a header - Request-Range, and a response type - multipart/x-byteranges. The HTTP/1.1 standard includes - this draft with a few fixes, and it defines the header - Range and type multipart/byteranges. - -

Navigator (versions 2 and 3) sends both Range and - Request-Range headers (with the same value), but does not - accept a multipart/byteranges response. The response must - be multipart/x-byteranges. As a workaround, if Apache - receives a Request-Range header it considers it "higher - priority" than a Range header and in response uses - multipart/x-byteranges. - -

The Adobe Acrobat Reader plugin makes extensive use of byteranges and - prior to version 3.01 supports only the multipart/x-byterange - response. Unfortunately there is no clue that it is the plugin - making the request. If the plugin is used with Navigator, the above - workaround works fine. But if the plugin is used with MSIE 3 (on - Windows) the workaround won't work because MSIE 3 doesn't give the - Range-Request clue that Navigator does. To workaround this, - Apache special cases "MSIE 3" in the User-Agent and serves - multipart/x-byteranges. Note that the necessity for this - with MSIE 3 is actually due to the Acrobat plugin, not due to the browser. - -

Netscape Communicator appears to not issue the non-standard - Request-Range header. When an Acrobat plugin prior to - version 3.01 is used with it, it will not properly understand byteranges. - The user must upgrade their Acrobat reader to 3.01. - -

Set-Cookie header is unmergeable

- -

The HTTP specifications say that it is legal to merge headers with - duplicate names into one (separated by semicolon). Some browsers - that support Cookies don't like merged headers and prefer that each - Set-Cookie header is sent separately. When parsing the - headers returned by a CGI, Apache will explicitly avoid merging any - Set-Cookie headers. - -


- - Index - Home - - - - --- 0 ---- Index: apache-1.2-rus/htdocs/manual/misc/nopgp.html diff -c apache-1.2-rus/htdocs/manual/misc/nopgp.html:1.2 apache-1.2-rus/htdocs/manual/misc/nopgp.html:1.3 *** apache-1.2-rus/htdocs/manual/misc/nopgp.html:1.2 Mon Jul 7 16:44:47 1997 --- apache-1.2-rus/htdocs/manual/misc/nopgp.html Fri Jan 9 22:24:08 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Why We Took PEM Out of Apache

*************** *** 87,92 **** --- 90,98 ---- Brian, brian@hyperreal.com
+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/misc/perf-bsd44.html diff -c apache-1.2-rus/htdocs/manual/misc/perf-bsd44.html:1.2 apache-1.2-rus/htdocs/manual/misc/perf-bsd44.html:1.3 *** apache-1.2-rus/htdocs/manual/misc/perf-bsd44.html:1.2 Mon Jul 7 16:44:48 1997 --- apache-1.2-rus/htdocs/manual/misc/perf-bsd44.html Fri Jan 9 22:24:09 1998 *************** *** 15,20 **** --- 15,23 ----
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

*************** *** 235,240 **** --- 238,246 ---- href="mailto:brian@organic.com">brian@organic.com
+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/misc/perf-dec.html diff -c apache-1.2-rus/htdocs/manual/misc/perf-dec.html:1.1.1.1 apache-1.2-rus/htdocs/manual/misc/perf-dec.html:1.2 *** apache-1.2-rus/htdocs/manual/misc/perf-dec.html:1.1.1.1 Wed Jun 18 00:20:21 1997 --- apache-1.2-rus/htdocs/manual/misc/perf-dec.html Fri Jan 9 22:24:11 1998 *************** *** 13,18 **** --- 13,21 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Performance Tuning Tips for Digital Unix

*************** *** 278,283 **** --- 281,289 ----
+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/misc/perf.html diff -c apache-1.2-rus/htdocs/manual/misc/perf.html:1.3 apache-1.2-rus/htdocs/manual/misc/perf.html:1.4 *** apache-1.2-rus/htdocs/manual/misc/perf.html:1.3 Sat Aug 23 16:57:43 1997 --- apache-1.2-rus/htdocs/manual/misc/perf.html Fri Jan 9 22:24:12 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Hints on Running a High-Performance Web Server

*************** *** 131,136 **** --- 134,142 ---- href="mailto:brian@organic.com">brian@organic.com
+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/misc/security_tips.html diff -c apache-1.2-rus/htdocs/manual/misc/security_tips.html:1.2 apache-1.2-rus/htdocs/manual/misc/security_tips.html:1.3 *** apache-1.2-rus/htdocs/manual/misc/security_tips.html:1.2 Mon Jul 7 16:44:49 1997 --- apache-1.2-rus/htdocs/manual/misc/security_tips.html Fri Jan 9 22:24:14 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Security Tips for Server Configuration

*************** *** 184,189 **** --- 187,195 ----

+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/misc/vif-info.html diff -c apache-1.2-rus/htdocs/manual/misc/vif-info.html:1.2 apache-1.2-rus/htdocs/manual/misc/vif-info.html:1.3 *** apache-1.2-rus/htdocs/manual/misc/vif-info.html:1.2 Mon Jul 7 16:44:50 1997 --- apache-1.2-rus/htdocs/manual/misc/vif-info.html Fri Jan 9 22:24:15 1998 *************** *** 12,17 **** --- 12,20 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Configuring Multiple IP Addresses

*************** *** 398,403 **** --- 401,409 ----


+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/misc/windoz_keepalive.html diff -c apache-1.2-rus/htdocs/manual/misc/windoz_keepalive.html:1.1.1.1 apache-1.2-rus/htdocs/manual/misc/windoz_keepalive.html:1.2 *** apache-1.2-rus/htdocs/manual/misc/windoz_keepalive.html:1.1.1.1 Wed Jun 18 00:20:21 1997 --- apache-1.2-rus/htdocs/manual/misc/windoz_keepalive.html Fri Jan 9 22:24:17 1998 *************** *** 13,18 **** --- 13,21 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

HTTP/1.1 KeepAlive problems with Netscape 3.0

*************** *** 50,55 **** --- 53,61 ---- http://www.nueva.pvt.k12.ca.us/~akosut/ http://www.apache.org/
+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/mod/core.html diff -c apache-1.2-rus/htdocs/manual/mod/core.html:1.2 apache-1.2-rus/htdocs/manual/mod/core.html:1.3 *** apache-1.2-rus/htdocs/manual/mod/core.html:1.2 Mon Jul 7 16:44:51 1997 --- apache-1.2-rus/htdocs/manual/mod/core.html Fri Jan 9 22:24:18 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

*************** *** 1447,1452 **** --- 1450,1458 ----


+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/mod/directives.html diff -c apache-1.2-rus/htdocs/manual/mod/directives.html:1.2 apache-1.2-rus/htdocs/manual/mod/directives.html:1.3 *** apache-1.2-rus/htdocs/manual/mod/directives.html:1.2 Mon Jul 7 16:44:53 1997 --- apache-1.2-rus/htdocs/manual/mod/directives.html Fri Jan 9 22:24:20 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Apache directives

*************** *** 176,181 **** --- 179,187 ----
+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/mod/footer.html diff -c apache-1.2-rus/htdocs/manual/mod/footer.html:1.1.1.1 apache-1.2-rus/htdocs/manual/mod/footer.html:1.2 *** apache-1.2-rus/htdocs/manual/mod/footer.html:1.1.1.1 Wed Jun 18 00:20:18 1997 --- apache-1.2-rus/htdocs/manual/mod/footer.html Fri Jan 9 22:24:22 1998 *************** *** 1,4 **** --- 1,7 ----
+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/mod/header.html diff -c apache-1.2-rus/htdocs/manual/mod/header.html:1.1.1.1 apache-1.2-rus/htdocs/manual/mod/header.html:1.2 *** apache-1.2-rus/htdocs/manual/mod/header.html:1.1.1.1 Wed Jun 18 00:20:18 1997 --- apache-1.2-rus/htdocs/manual/mod/header.html Fri Jan 9 22:24:23 1998 *************** *** 1,3 **** --- 1,6 ----
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Index: apache-1.2-rus/htdocs/manual/mod/index.html diff -c apache-1.2-rus/htdocs/manual/mod/index.html:1.1.1.1 apache-1.2-rus/htdocs/manual/mod/index.html:1.2 *** apache-1.2-rus/htdocs/manual/mod/index.html:1.1.1.1 Wed Jun 18 00:20:18 1997 --- apache-1.2-rus/htdocs/manual/mod/index.html Fri Jan 9 22:24:24 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Apache modules

*************** *** 102,107 **** --- 105,113 ----
+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/mod/mod_access.html diff -c apache-1.2-rus/htdocs/manual/mod/mod_access.html:1.1.1.1 apache-1.2-rus/htdocs/manual/mod/mod_access.html:1.2 *** apache-1.2-rus/htdocs/manual/mod/mod_access.html:1.1.1.1 Wed Jun 18 00:20:18 1997 --- apache-1.2-rus/htdocs/manual/mod/mod_access.html Fri Jan 9 22:24:26 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

*************** *** 174,179 **** --- 177,185 ---- denied access.
+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/mod/mod_actions.html diff -c apache-1.2-rus/htdocs/manual/mod/mod_actions.html:1.1.1.1 apache-1.2-rus/htdocs/manual/mod/mod_actions.html:1.2 *** apache-1.2-rus/htdocs/manual/mod/mod_actions.html:1.1.1.1 Wed Jun 18 00:20:18 1997 --- apache-1.2-rus/htdocs/manual/mod/mod_actions.html Fri Jan 9 22:24:27 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Module mod_actions

*************** *** 83,88 **** --- 86,94 ----
+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/mod/mod_alias.html diff -c apache-1.2-rus/htdocs/manual/mod/mod_alias.html:1.1.1.1 apache-1.2-rus/htdocs/manual/mod/mod_alias.html:1.2 *** apache-1.2-rus/htdocs/manual/mod/mod_alias.html:1.1.1.1 Wed Jun 18 00:20:18 1997 --- apache-1.2-rus/htdocs/manual/mod/mod_alias.html Fri Jan 9 22:24:29 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

*************** *** 144,149 **** --- 147,155 ---- run the script /web/cgi-bin/foo.


+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/mod/mod_asis.html diff -c apache-1.2-rus/htdocs/manual/mod/mod_asis.html:1.1.1.1 apache-1.2-rus/htdocs/manual/mod/mod_asis.html:1.2 *** apache-1.2-rus/htdocs/manual/mod/mod_asis.html:1.1.1.1 Wed Jun 18 00:20:18 1997 --- apache-1.2-rus/htdocs/manual/mod/mod_asis.html Fri Jan 9 22:24:30 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

*************** *** 67,72 **** --- 70,78 ----


+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/mod/mod_auth.html diff -c apache-1.2-rus/htdocs/manual/mod/mod_auth.html:1.1.1.1 apache-1.2-rus/htdocs/manual/mod/mod_auth.html:1.2 *** apache-1.2-rus/htdocs/manual/mod/mod_auth.html:1.1.1.1 Wed Jun 18 00:20:18 1997 --- apache-1.2-rus/htdocs/manual/mod/mod_auth.html Fri Jan 9 22:24:32 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

*************** *** 143,148 **** --- 146,154 ---- AuthGroupFile.


+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/mod/mod_auth_anon.html diff -c apache-1.2-rus/htdocs/manual/mod/mod_auth_anon.html:1.2 apache-1.2-rus/htdocs/manual/mod/mod_auth_anon.html:1.3 *** apache-1.2-rus/htdocs/manual/mod/mod_auth_anon.html:1.2 Mon Jul 7 16:44:54 1997 --- apache-1.2-rus/htdocs/manual/mod/mod_auth_anon.html Fri Jan 9 22:24:33 1998 *************** *** 13,18 **** --- 13,21 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Module mod_auth_anon

*************** *** 247,252 **** --- 250,258 ----


+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/mod/mod_auth_db.html diff -c apache-1.2-rus/htdocs/manual/mod/mod_auth_db.html:1.1.1.1 apache-1.2-rus/htdocs/manual/mod/mod_auth_db.html:1.2 *** apache-1.2-rus/htdocs/manual/mod/mod_auth_db.html:1.1.1.1 Wed Jun 18 00:20:19 1997 --- apache-1.2-rus/htdocs/manual/mod/mod_auth_db.html Fri Jan 9 22:24:35 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Module mod_auth_db

*************** *** 158,163 **** --- 161,169 ---- AuthDBGroupFile.


+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/mod/mod_auth_dbm.html diff -c apache-1.2-rus/htdocs/manual/mod/mod_auth_dbm.html:1.1.1.1 apache-1.2-rus/htdocs/manual/mod/mod_auth_dbm.html:1.2 *** apache-1.2-rus/htdocs/manual/mod/mod_auth_dbm.html:1.1.1.1 Wed Jun 18 00:20:19 1997 --- apache-1.2-rus/htdocs/manual/mod/mod_auth_dbm.html Fri Jan 9 22:24:36 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

*************** *** 160,165 **** --- 163,171 ---- AuthDBMGroupFile.


+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/mod/mod_auth_msql.html diff -c apache-1.2-rus/htdocs/manual/mod/mod_auth_msql.html:1.2 apache-1.2-rus/htdocs/manual/mod/mod_auth_msql.html:1.3 *** apache-1.2-rus/htdocs/manual/mod/mod_auth_msql.html:1.2 Mon Jul 7 16:44:55 1997 --- apache-1.2-rus/htdocs/manual/mod/mod_auth_msql.html Fri Jan 9 22:24:38 1998 *************** *** 13,18 **** --- 13,21 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Module mod_auth_msql

*************** *** 473,478 **** --- 476,484 ---- README file.
+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/mod/mod_browser.html diff -c apache-1.2-rus/htdocs/manual/mod/mod_browser.html:1.2 apache-1.2-rus/htdocs/manual/mod/mod_browser.html:1.3 *** apache-1.2-rus/htdocs/manual/mod/mod_browser.html:1.2 Sat Aug 23 16:59:49 1997 --- apache-1.2-rus/htdocs/manual/mod/mod_browser.html Fri Jan 9 22:24:39 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Module mod_browser

*************** *** 84,89 **** --- 87,95 ----


+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/mod/mod_cern_meta.html diff -c apache-1.2-rus/htdocs/manual/mod/mod_cern_meta.html:1.2 apache-1.2-rus/htdocs/manual/mod/mod_cern_meta.html:1.3 *** apache-1.2-rus/htdocs/manual/mod/mod_cern_meta.html:1.2 Sat Aug 23 16:59:50 1997 --- apache-1.2-rus/htdocs/manual/mod/mod_cern_meta.html Fri Jan 9 22:24:40 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Module mod_cern_meta

*************** *** 79,84 **** --- 82,90 ----


+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/mod/mod_cgi.html diff -c apache-1.2-rus/htdocs/manual/mod/mod_cgi.html:1.1.1.1 apache-1.2-rus/htdocs/manual/mod/mod_cgi.html:1.2 *** apache-1.2-rus/htdocs/manual/mod/mod_cgi.html:1.1.1.1 Wed Jun 18 00:20:19 1997 --- apache-1.2-rus/htdocs/manual/mod/mod_cgi.html Fri Jan 9 22:24:42 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

*************** *** 172,177 **** --- 175,183 ---- but this can be changed with this directive.
+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/mod/mod_cookies.html diff -c apache-1.2-rus/htdocs/manual/mod/mod_cookies.html:1.1.1.1 apache-1.2-rus/htdocs/manual/mod/mod_cookies.html:1.2 *** apache-1.2-rus/htdocs/manual/mod/mod_cookies.html:1.1.1.1 Wed Jun 18 00:20:19 1997 --- apache-1.2-rus/htdocs/manual/mod/mod_cookies.html Fri Jan 9 22:24:43 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Module mod_cookies

*************** *** 41,46 **** --- 44,52 ----


+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/mod/mod_digest.html diff -c apache-1.2-rus/htdocs/manual/mod/mod_digest.html:1.1.1.1 apache-1.2-rus/htdocs/manual/mod/mod_digest.html:1.2 *** apache-1.2-rus/htdocs/manual/mod/mod_digest.html:1.1.1.1 Wed Jun 18 00:20:19 1997 --- apache-1.2-rus/htdocs/manual/mod/mod_digest.html Fri Jan 9 22:24:45 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Module mod_digest

*************** *** 63,68 **** --- 66,74 ---- ideal.


+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/mod/mod_dir.html diff -c apache-1.2-rus/htdocs/manual/mod/mod_dir.html:1.1.1.1 apache-1.2-rus/htdocs/manual/mod/mod_dir.html:1.2 *** apache-1.2-rus/htdocs/manual/mod/mod_dir.html:1.1.1.1 Wed Jun 18 00:20:19 1997 --- apache-1.2-rus/htdocs/manual/mod/mod_dir.html Fri Jan 9 22:24:46 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Module mod_dir

*************** *** 365,370 **** --- 368,376 ----
+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/mod/mod_dld.html diff -c apache-1.2-rus/htdocs/manual/mod/mod_dld.html:1.1.1.1 apache-1.2-rus/htdocs/manual/mod/mod_dld.html:1.2 *** apache-1.2-rus/htdocs/manual/mod/mod_dld.html:1.1.1.1 Wed Jun 18 00:20:19 1997 --- apache-1.2-rus/htdocs/manual/mod/mod_dld.html Fri Jan 9 22:24:47 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Module mod_dld

*************** *** 78,83 **** --- 81,89 ----
+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/mod/mod_env.html diff -c apache-1.2-rus/htdocs/manual/mod/mod_env.html:1.2 apache-1.2-rus/htdocs/manual/mod/mod_env.html:1.3 *** apache-1.2-rus/htdocs/manual/mod/mod_env.html:1.2 Sat Aug 23 16:59:51 1997 --- apache-1.2-rus/htdocs/manual/mod/mod_env.html Fri Jan 9 22:24:49 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Module mod_env

*************** *** 90,95 **** --- 93,101 ----


+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/mod/mod_example.html diff -c apache-1.2-rus/htdocs/manual/mod/mod_example.html:1.1.1.1 apache-1.2-rus/htdocs/manual/mod/mod_example.html:1.2 *** apache-1.2-rus/htdocs/manual/mod/mod_example.html:1.1.1.1 Wed Jun 18 00:20:19 1997 --- apache-1.2-rus/htdocs/manual/mod/mod_example.html Fri Jan 9 22:24:50 1998 *************** *** 13,18 **** --- 13,21 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Module mod_example

*************** *** 139,144 **** --- 142,150 ---- what order they were called to service the document request.


+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/mod/mod_expires.html diff -c apache-1.2-rus/htdocs/manual/mod/mod_expires.html:1.1.1.1 apache-1.2-rus/htdocs/manual/mod/mod_expires.html:1.2 *** apache-1.2-rus/htdocs/manual/mod/mod_expires.html:1.1.1.1 Wed Jun 18 00:20:19 1997 --- apache-1.2-rus/htdocs/manual/mod/mod_expires.html Fri Jan 9 22:24:52 1998 *************** *** 13,18 **** --- 13,21 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Module mod_expires

*************** *** 184,189 **** --- 187,195 ---- the syntax of the argument.


+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/mod/mod_headers.html diff -c apache-1.2-rus/htdocs/manual/mod/mod_headers.html:1.2 apache-1.2-rus/htdocs/manual/mod/mod_headers.html:1.3 *** apache-1.2-rus/htdocs/manual/mod/mod_headers.html:1.2 Sat Aug 23 16:59:51 1997 --- apache-1.2-rus/htdocs/manual/mod/mod_headers.html Fri Jan 9 22:24:53 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Module mod_headers

*************** *** 103,108 **** --- 106,114 ----


+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/mod/mod_imap.html diff -c apache-1.2-rus/htdocs/manual/mod/mod_imap.html:1.1.1.1 apache-1.2-rus/htdocs/manual/mod/mod_imap.html:1.2 *** apache-1.2-rus/htdocs/manual/mod/mod_imap.html:1.1.1.1 Wed Jun 18 00:20:19 1997 --- apache-1.2-rus/htdocs/manual/mod/mod_imap.html Fri Jan 9 22:24:54 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Module mod_imap

*************** *** 281,286 **** --- 284,292 ----


+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/mod/mod_include.html diff -c apache-1.2-rus/htdocs/manual/mod/mod_include.html:1.2 apache-1.2-rus/htdocs/manual/mod/mod_include.html:1.3 *** apache-1.2-rus/htdocs/manual/mod/mod_include.html:1.2 Mon Jul 7 16:44:56 1997 --- apache-1.2-rus/htdocs/manual/mod/mod_include.html Fri Jan 9 22:24:56 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Module mod_include

*************** *** 384,389 **** --- 387,395 ----


+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/mod/mod_info.html diff -c apache-1.2-rus/htdocs/manual/mod/mod_info.html:1.1.1.1 apache-1.2-rus/htdocs/manual/mod/mod_info.html:1.2 *** apache-1.2-rus/htdocs/manual/mod/mod_info.html:1.1.1.1 Wed Jun 18 00:20:19 1997 --- apache-1.2-rus/htdocs/manual/mod/mod_info.html Fri Jan 9 22:24:57 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Module mod_info

*************** *** 72,77 **** --- 75,83 ----
+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/mod/mod_log_agent.html diff -c apache-1.2-rus/htdocs/manual/mod/mod_log_agent.html:1.1.1.1 apache-1.2-rus/htdocs/manual/mod/mod_log_agent.html:1.2 *** apache-1.2-rus/htdocs/manual/mod/mod_log_agent.html:1.1.1.1 Wed Jun 18 00:20:20 1997 --- apache-1.2-rus/htdocs/manual/mod/mod_log_agent.html Fri Jan 9 22:24:59 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Module mod_log_agent

*************** *** 59,64 **** --- 62,70 ---- This directive is provided for compatibility with NCSA 1.4.


+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/mod/mod_log_common.html diff -c apache-1.2-rus/htdocs/manual/mod/mod_log_common.html:1.1.1.1 apache-1.2-rus/htdocs/manual/mod/mod_log_common.html:1.2 *** apache-1.2-rus/htdocs/manual/mod/mod_log_common.html:1.1.1.1 Wed Jun 18 00:20:20 1997 --- apache-1.2-rus/htdocs/manual/mod/mod_log_common.html Fri Jan 9 22:25:00 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Module mod_log_common

*************** *** 99,104 **** --- 102,110 ---- that starts the server.


+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/mod/mod_log_config.html diff -c apache-1.2-rus/htdocs/manual/mod/mod_log_config.html:1.1.1.1 apache-1.2-rus/htdocs/manual/mod/mod_log_config.html:1.2 *** apache-1.2-rus/htdocs/manual/mod/mod_log_config.html:1.1.1.1 Wed Jun 18 00:20:20 1997 --- apache-1.2-rus/htdocs/manual/mod/mod_log_config.html Fri Jan 9 22:25:02 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Module mod_log_config

*************** *** 260,265 **** --- 263,271 ----
+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/mod/mod_log_referer.html diff -c apache-1.2-rus/htdocs/manual/mod/mod_log_referer.html:1.1.1.1 apache-1.2-rus/htdocs/manual/mod/mod_log_referer.html:1.2 *** apache-1.2-rus/htdocs/manual/mod/mod_log_referer.html:1.1.1.1 Wed Jun 18 00:20:20 1997 --- apache-1.2-rus/htdocs/manual/mod/mod_log_referer.html Fri Jan 9 22:25:03 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Module mod_log_referer

*************** *** 86,91 **** --- 89,97 ---- This directive is provided for compatibility with NCSA 1.4.


+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/mod/mod_mime.html diff -c apache-1.2-rus/htdocs/manual/mod/mod_mime.html:1.2 apache-1.2-rus/htdocs/manual/mod/mod_mime.html:1.3 *** apache-1.2-rus/htdocs/manual/mod/mod_mime.html:1.2 Mon Jul 7 16:44:57 1997 --- apache-1.2-rus/htdocs/manual/mod/mod_mime.html Fri Jan 9 22:25:04 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Module mod_mime

*************** *** 232,237 **** --- 235,243 ---- character (`#') are ignored.


+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/mod/mod_negotiation.html diff -c apache-1.2-rus/htdocs/manual/mod/mod_negotiation.html:1.1.1.1 apache-1.2-rus/htdocs/manual/mod/mod_negotiation.html:1.2 *** apache-1.2-rus/htdocs/manual/mod/mod_negotiation.html:1.1.1.1 Wed Jun 18 00:20:20 1997 --- apache-1.2-rus/htdocs/manual/mod/mod_negotiation.html Fri Jan 9 22:25:06 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Module mod_negotiation

*************** *** 145,150 **** --- 148,156 ---- HTTP/1.1 requests will mean this directive has no effect.
+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/mod/mod_proxy.html diff -c apache-1.2-rus/htdocs/manual/mod/mod_proxy.html:1.3 apache-1.2-rus/htdocs/manual/mod/mod_proxy.html:1.4 *** apache-1.2-rus/htdocs/manual/mod/mod_proxy.html:1.3 Sat Aug 23 16:59:52 1997 --- apache-1.2-rus/htdocs/manual/mod/mod_proxy.html Fri Jan 9 22:25:07 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Module mod_proxy

*************** *** 364,369 **** --- 367,375 ---- configuration.


+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/mod/mod_rewrite.html diff -c apache-1.2-rus/htdocs/manual/mod/mod_rewrite.html:1.3 apache-1.2-rus/htdocs/manual/mod/mod_rewrite.html:1.4 *** apache-1.2-rus/htdocs/manual/mod/mod_rewrite.html:1.3 Sat Aug 23 16:59:53 1997 --- apache-1.2-rus/htdocs/manual/mod/mod_rewrite.html Fri Jan 9 22:25:09 1998 *************** *** 17,22 **** --- 17,25 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

*************** *** 1216,1221 **** --- 1219,1227 ----
+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/mod/mod_status.html diff -c apache-1.2-rus/htdocs/manual/mod/mod_status.html:1.2 apache-1.2-rus/htdocs/manual/mod/mod_status.html:1.3 *** apache-1.2-rus/htdocs/manual/mod/mod_status.html:1.2 Mon Jul 7 16:45:00 1997 --- apache-1.2-rus/htdocs/manual/mod/mod_status.html Fri Jan 9 22:25:11 1998 *************** *** 12,17 **** --- 12,20 ----
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Module mod_status

*************** *** 106,111 **** --- 109,117 ----
+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/mod/mod_userdir.html diff -c apache-1.2-rus/htdocs/manual/mod/mod_userdir.html:1.2 apache-1.2-rus/htdocs/manual/mod/mod_userdir.html:1.3 *** apache-1.2-rus/htdocs/manual/mod/mod_userdir.html:1.2 Mon Jul 7 16:45:01 1997 --- apache-1.2-rus/htdocs/manual/mod/mod_userdir.html Fri Jan 9 22:25:12 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Module mod_userdir

*************** *** 74,79 **** --- 77,85 ----


+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/htdocs/manual/mod/mod_usertrack.html diff -c apache-1.2-rus/htdocs/manual/mod/mod_usertrack.html:1.1.1.1 apache-1.2-rus/htdocs/manual/mod/mod_usertrack.html:1.2 *** apache-1.2-rus/htdocs/manual/mod/mod_usertrack.html:1.1.1.1 Wed Jun 18 00:20:20 1997 --- apache-1.2-rus/htdocs/manual/mod/mod_usertrack.html Fri Jan 9 22:25:13 1998 *************** *** 14,19 **** --- 14,22 ---- >
[APACHE DOCUMENTATION] +

+ Apache HTTP Server Version 1.2 +

Module mod_usertrack

*************** *** 86,91 **** --- 89,97 ----
+

+ Apache HTTP Server Version 1.2 +

Index Home Index: apache-1.2-rus/src/CHANGES diff -c apache-1.2-rus/src/CHANGES:1.3 apache-1.2-rus/src/CHANGES:1.4 *** apache-1.2-rus/src/CHANGES:1.3 Sat Aug 23 17:03:04 1997 --- apache-1.2-rus/src/CHANGES Fri Jan 9 22:25:16 1998 *************** *** 1,3 **** --- 1,72 ---- + Changes with Apache 1.2.5 + + *) SECURITY: Fix a possible buffer overflow in logresolve. This is + only an issue on systems without a MAXDNAME define or where + the resolver returns domain names longer than MAXDNAME. [Marc Slemko] + + *) Fix an improper length in an ap_snprintf call in proxy_date_canon(). + [Marc Slemko] + + *) Fix core dump in the ftp proxy when reading incorrectly formatted + directory listings. [Marc Slemko] + + *) SECURITY: Fix possible minor buffer overflow in the proxy cache. + [Marc Slemko] + + *) SECURITY: Eliminate possible buffer overflow in cfg_getline, which + is used to read various types of files such as htaccess and + htpasswd files. [Marc Slemko] + + *) SECURITY: Ensure that the buffer returned by ht_time is always + properly null terminated. [Marc Slemko] + + *) SECURITY: General mod_include cleanup, including fixing several + possible buffer overflows and a possible infinite loop. This cleanup + was done against 1.3 code and then backported to 1.2, the result + is a large difference (due to indentation cleanup in 1.3 code). + Users interested in seeing a smaller set of relevant differences + should consider comparing against src/modules/standard/mod_include.c + from the 1.3b3 release. Non-indentation changes to mod_include + between 1.2 and 1.3 were minimal. [Dean Gaudet, Marc Slemko] + + *) SECURITY: Numerous changes to mod_imap in a general cleanup + including fixing a possible buffer overflow. This cleanup also + was done with 1.3 code as a basis, see the the previous note + about mod_include. [Dean Gaudet] + + *) SECURITY: If a htaccess file can not be read due to bad + permissions, deny access to the directory with a HTTP_FORBIDDEN. + The previous behavior was to ignore the htaccess file if it could not + be read. This change may make some setups with unreadable + htaccess files stop working. PR#817 [Marc Slemko] + + *) SECURITY: no2slash() was O(n^2) in the length of the input. + Make it O(n). This inefficiency could be used to mount a denial + of service attack against the Apache server. Thanks to + Michal Zalewski for reporting + this. [Dean Gaudet] + + *) mod_include used uninitialized data for some uses of && and ||. + [Brian Slesinsky ] PR#1139 + + *) mod_imap should decline all non-GET methods. + [Jay Bloodworth ] + + *) suexec.c wouldn't build without -DLOG_EXEC. [Jason A. Dour] + + *) mod_userdir was modifying r->finfo in cases where it wasn't setting + r->filename. Since those two are meant to be in sync with each other + this is a bug. ["Paul B. Henson" ] + + *) mod_include did not properly handle all possible redirects from sub- + requests. [Ken Coar] + + *) Inetd mode (which is buggy) uses timeouts without having setup the + jmpbuffer. [Dean Gaudet] PR#1064 + + *) Work around problem under Linux where a child will start looping + reporting a select error over and over. + [Rick Franchuk ] 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; }