diff options
author | 1998-10-11 19:44:59 +0000 | |
---|---|---|
committer | 1998-10-11 19:44:59 +0000 | |
commit | 0ad52bed66a21e2d9cde06cdbb2fa8563982553b (patch) | |
tree | 436beee31e9b2153b6be177e3461de7701b82945 | |
parent | typo: Thuner != Thunder; spotted by theo. (diff) | |
download | wireguard-openbsd-0ad52bed66a21e2d9cde06cdbb2fa8563982553b.tar.xz wireguard-openbsd-0ad52bed66a21e2d9cde06cdbb2fa8563982553b.zip |
Apache 1.3.3 merge + proxy_segv fix
49 files changed, 1438 insertions, 617 deletions
diff --git a/usr.sbin/httpd/ABOUT_APACHE b/usr.sbin/httpd/ABOUT_APACHE index 950c10df9a5..8f54e59e8de 100644 --- a/usr.sbin/httpd/ABOUT_APACHE +++ b/usr.sbin/httpd/ABOUT_APACHE @@ -3,7 +3,7 @@ http://www.apache.org/ - July 1998 + September 1998 The Apache Project is a collaborative software development effort aimed at creating a robust, commercial-grade, featureful, and freely-available @@ -67,10 +67,10 @@ NCSA's httpd as the #1 server on the Internet. ============================================================================ -Current Apache Group in alphabetical order as of 14 July 1998: +Current Apache Group in alphabetical order as of 23 September 1998: Brian Behlendorf Organic Online, California - Ken Coar MeepZor Consulting, New England, USA + Ken Coar IBM Corporation, Research Triangle Park, NC, USA Mark J. Cox C2Net Europe, UK Lars Eilebrecht Kreuztal, Germany Ralf S. Engelschall Munich, Germany. @@ -87,6 +87,7 @@ Current Apache Group in alphabetical order as of 14 July 1998: Sameer Parekh C2Net, California Marc Slemko Canada Cliff Skolnick Freelance, California + Bill Stoddard IBM Corp., Research Triangle Park, NC Paul Sutton C2Net Europe, UK Randy Terbush Zyzzyva ISP, Nebraska Dirk-Willem van Gulik Freelance Consultant, Italy diff --git a/usr.sbin/httpd/Announcement b/usr.sbin/httpd/Announcement index cfbc34f504a..9382397d10c 100644 --- a/usr.sbin/httpd/Announcement +++ b/usr.sbin/httpd/Announcement @@ -1,22 +1,32 @@ -Apache 1.3.2 Released +Apache 1.3.3 Released ===================== The Apache Group is pleased to announce the release of version -1.3.2 of the Apache HTTP server. - -The changes in this release consist of Unix portability fixes, -DoS issues, and assorted other minor features or fixes. Users -should review the CHANGES file and decide on their upgrade plans; -We consider Apache 1.3.2 to be the most stable version of Apache -available. - -Apache 1.3.2 is available for download from +1.3.3 of the Apache HTTP server. + +This new Apache version is a bugfix release, primarily to fix a +serious problem with server error reporting introduced in 1.3.2. +This affected the functionality of most custom ErrorDocuments and +of some modules that depend on special error output (e.g., mod_speling). +A side-effect bug that resulted in incorrect error reporting of +nonexistent .htaccess files has also been fixed. + +Additional changes in this release consist of new supported platforms, +Win32 and Unix portability fixes, ErrorDocument environment enhancements, +improved protocol behavior to match the HTTP/1.1 revised specification, +and assorted other features or fixes. Users should review the CHANGES file +and decide on their upgrade plans. We consider Apache 1.3.3 to be the +most stable version of Apache available and we strongly recommend that +users of older versions, especially of the 1.1.x and 1.2.x family, upgrade +as soon as possible. + +Apache 1.3.3 is available for download from http://www.apache.org/dist/ -Please see the CHANGES file in the same directory for a full list -of changes. The distribution is also available via any of the -mirrors listed at +Please see the CHANGES_1.3 file in the same directory for a full +list of changes. The distribution is also available via any of +the mirrors listed at http://www.apache.org/mirrors/ @@ -26,10 +36,10 @@ For an overview of new features in 1.3 please see In general, Apache 1.3 offers several substantial improvements over version 1.2, including better performance, reliability and a -wider-range of supported platforms, including Windows 95 and NT +wider range of supported platforms, including Windows 95 and NT (which both fall under the "Win32" label). -Apache is the most popular web-server in the known universe; over +Apache is the most popular web server in the known universe; over half of the servers on the Internet are running Apache or one of its variants. @@ -40,6 +50,5 @@ levels and should still be considered to be of beta quality. Any Win32 stability or security problems do not impact, in any way, Apache on other platforms. With the continued donation of time and resources by individuals and companies, we hope that the Win32 -version of Apache will grow stronger through the 1.3.x release -cycle. +version of Apache will grow stronger through the 1.3.x release cycle. diff --git a/usr.sbin/httpd/INSTALL b/usr.sbin/httpd/INSTALL index 75d492877f9..1fc381e8844 100644 --- a/usr.sbin/httpd/INSTALL +++ b/usr.sbin/httpd/INSTALL @@ -271,7 +271,7 @@ (-) mod_speling ...... Correction of misspelled URLs Directory Handling (+) mod_dir .......... Directory and directory default file handling - (+) mod_auto_index ... Automated directory index file generation + (+) mod_autoindex .... Automated directory index file generation Access Control (+) mod_access ....... Access Control (user, host, network) (+) mod_auth ......... HTTP Basic Authentication (user, passwd) @@ -435,8 +435,11 @@ $ PREFIX/sbin/apachectl start and then you should be able to request your first document via URL - http://localhost/. Then stop the server again by running: - + http://localhost/ (when you built and installed Apache as root or at + least used the --without-confadjust option) or http://localhost:8080/ + (when you built and installed Apache as a regular user). Then stop the + server again by running: + $ PREFIX/sbin/apachectl stop 7. Customizing the package @@ -449,7 +452,7 @@ $ vi PREFIX/etc/access.conf $ vi PREFIX/etc/srm.conf - Have a look at the Apache manual under http://localhost/manual/ or + Have a look at the Apache manual under htdocs/manual/ or http://www.apache.org/docs/ for a complete reference of available configuration directives. diff --git a/usr.sbin/httpd/README.NT b/usr.sbin/httpd/README.NT index e7f7c7438e0..db2a23e6733 100644 --- a/usr.sbin/httpd/README.NT +++ b/usr.sbin/httpd/README.NT @@ -31,10 +31,6 @@ platform such as Solaris, FreeBSD, or Linux. Apache on Win32 should still be considered beta quality code. It does not meet the normal standards of stability and security that Unix releases do. -There is also a much greater chance of security holes being present in the -Win32 version of Apache, due to the frequent discrepancies between the public -documentation for the various Windows system calls and file system types -and the reality of what is included in Windows system software. Installation or Compilation Instructions ---------------------------------------- diff --git a/usr.sbin/httpd/README.configure b/usr.sbin/httpd/README.configure index 87eeb113347..e8d0ddc2271 100644 --- a/usr.sbin/httpd/README.configure +++ b/usr.sbin/httpd/README.configure @@ -13,7 +13,7 @@ The basic goal is to provide the following commonly known and expected procedure for out-of-the-box building and installing a package like Apache: - $ gunzip <apache-1.3.X.tar.gz | tar xvf - + $ gunzip <apache_1.3.X.tar.gz | tar xvf - $ ./configure --prefix=PREFIX [...] $ make $ make install @@ -224,7 +224,7 @@ [optionally you now have the chance to prepare or add more third-party modules to the Apache source tree] - $ cd ../apache-1.3.X + $ cd ../apache_1.3.X $ ./configure --prefix=/path/to/apache \ --activate-module=src/modules/perl/libperl.a \ [--enable-shared=perl] @@ -242,17 +242,17 @@ $ gunzip <apache_1.3.X.tar.gz | tar xvf - $ gunzip <php-3.0.tar.gz | tar xvf - - $ cd apache-1.3.X + $ cd apache_1.3.X $ ./configure --prefix=/path/to/apache $ cd ../php-3.0 - $ ./configure --with-apache=../apache-1.3.X + $ ./configure --with-apache=../apache_1.3.X $ make $ make install [optionally you now have the chance to prepare or add more third-party modules to the Apache source tree] - $ cd ../apache-1.3.X + $ cd ../apache_1.3.X $ ./configure --prefix=/path/to/apache \ --activate-module=src/modules/php3/libphp3.a $ make @@ -262,17 +262,17 @@ $ gunzip <apache_1.3.X.tar.gz | tar xvf - $ gunzip <php-3.0.tar.gz | tar xvf - - $ cd apache-1.3.X + $ cd apache_1.3.X $ ./configure --prefix=/path/to/apache $ cd ../php-3.0 - $ ./configure --with-shared-apache=../apache-1.3.X + $ ./configure --with-shared-apache=../apache_1.3.X $ make $ make install [optionally you now have the chance to prepare or add more third-party modules to the Apache source tree] - $ cd ../apache-1.3.X + $ cd ../apache_1.3.X $ ./configure --prefix=/path/to/apache \ --activate-module=src/modules/php3/libphp3.a \ --enable-shared=php3 diff --git a/usr.sbin/httpd/conf/access.conf-dist b/usr.sbin/httpd/conf/access.conf-dist index dd9d0a92189..c965cdb7569 100644 --- a/usr.sbin/httpd/conf/access.conf-dist +++ b/usr.sbin/httpd/conf/access.conf-dist @@ -25,7 +25,7 @@ AllowOverride None # This should be changed to whatever you set DocumentRoot to. -<Directory @@ServerRoot@@/htdocs> +<Directory "@@ServerRoot@@/htdocs"> # This may also be "None", "All", or any combination of "Indexes", # "Includes", "FollowSymLinks", "ExecCGI", or "MultiViews". @@ -51,7 +51,7 @@ allow from all # @@ServerRoot@@/cgi-bin should be changed to whatever your ScriptAliased # CGI directory exists, if you have that configured. -<Directory @@ServerRoot@@/cgi-bin> +<Directory "@@ServerRoot@@/cgi-bin"> AllowOverride None Options None </Directory> diff --git a/usr.sbin/httpd/conf/highperformance.conf-dist b/usr.sbin/httpd/conf/highperformance.conf-dist index 4c03fba5287..fb7c72563ba 100644 --- a/usr.sbin/httpd/conf/highperformance.conf-dist +++ b/usr.sbin/httpd/conf/highperformance.conf-dist @@ -43,7 +43,7 @@ ErrorLog logs/error_log </Directory> # If this was a real internet server you'd probably want to uncomment this: -#<Directory @@ServerRoot@@/htdocs> +#<Directory "@@ServerRoot@@/htdocs"> # order allow,deny # allow from all #</Directory> diff --git a/usr.sbin/httpd/conf/httpd.conf-dist b/usr.sbin/httpd/conf/httpd.conf-dist index 0b2e35d7962..264d9f0b52f 100644 --- a/usr.sbin/httpd/conf/httpd.conf-dist +++ b/usr.sbin/httpd/conf/httpd.conf-dist @@ -63,7 +63,7 @@ ServerAdmin you@your.address # mounted filesystem then please read the LockFile documentation, # you will save yourself a lot of trouble. -ServerRoot @@ServerRoot@@ +ServerRoot "@@ServerRoot@@" # BindAddress: You can support virtual hosts with this option. This option # is used to tell the server which IP address to listen to. It can either diff --git a/usr.sbin/httpd/conf/mime.types b/usr.sbin/httpd/conf/mime.types index 8c0d636154d..6408d6a8eea 100644 --- a/usr.sbin/httpd/conf/mime.types +++ b/usr.sbin/httpd/conf/mime.types @@ -26,6 +26,7 @@ application/powerpoint ppt application/remote-printing application/rtf rtf application/slate +application/smil smi smil sml application/wita application/wordperfect5.1 application/x-bcpio bcpio diff --git a/usr.sbin/httpd/conf/srm.conf-dist b/usr.sbin/httpd/conf/srm.conf-dist index ddefc2e1461..d71d148b987 100644 --- a/usr.sbin/httpd/conf/srm.conf-dist +++ b/usr.sbin/httpd/conf/srm.conf-dist @@ -12,7 +12,7 @@ # documents. By default, all requests are taken from this directory, but # symbolic links and aliases may be used to point to other locations. -DocumentRoot @@ServerRoot@@/htdocs +DocumentRoot "@@ServerRoot@@/htdocs" # UserDir: The name of the directory which is appended onto a user's home # directory if a ~user request is recieved. @@ -152,12 +152,12 @@ LanguagePriority en fr de # require it to be present in the URL. So "/icons" isn't aliased in this # example. -Alias /icons/ @@ServerRoot@@/icons/ +Alias /icons/ "@@ServerRoot@@/icons/" # ScriptAlias: This controls which directories contain server scripts. # Format: ScriptAlias fakename realname -#ScriptAlias /cgi-bin/ @@ServerRoot@@/cgi-bin/ +#ScriptAlias /cgi-bin/ "@@ServerRoot@@/cgi-bin/" # If you want to use server side includes, or CGI outside # ScriptAliased directories, uncomment the following lines. diff --git a/usr.sbin/httpd/htdocs/manual/ebcdic.html b/usr.sbin/httpd/htdocs/manual/ebcdic.html index 3ce6116c0ff..a8ce553d44e 100644 --- a/usr.sbin/httpd/htdocs/manual/ebcdic.html +++ b/usr.sbin/httpd/htdocs/manual/ebcdic.html @@ -25,8 +25,8 @@ Version 1.3 of the Apache HTTP Server is the first version which includes a port to a (non-ASCII) mainframe machine which uses the EBCDIC character set as its native codeset.<BR> - (It is the SIEMENS NIXDORF family of mainframes running the - <A HREF="http://www.sni.de/servers/bs2osd/osdbc_us.htm">BS2000/OSD + (It is the SIEMENS family of mainframes running the + <A HREF="http://www.siemens.de/servers/bs2osd/osdbc_us.htm">BS2000/OSD operating system</A>. This mainframe OS nowadays features a SVR4-derived POSIX subsystem). </P> @@ -107,9 +107,9 @@ indicate which part of the HTTP protocol has to be converted and which part doesn't <EM>etc.</EM> <DT><CODE><STRONG>#ifdef _OSD_POSIX</STRONG></CODE> - <DD>Code which is needed for the BS2000 SIEMENS NIXDORF + <DD>Code which is needed for the SIEMENS BS2000/OSD mainframe platform only. This deals with include file - differences and socket implementations topics which are + differences and socket implementation topics which are only required on the BS2000/OSD platform. </DL> </LI><BR> @@ -403,7 +403,7 @@ <TR> <TD ALIGN=LEFT>mod_mime_magic - <TD ALIGN=CENTER>- + <TD ALIGN=CENTER>? <TD>not ported yet </TR> @@ -479,7 +479,7 @@ <TR> <TD ALIGN=LEFT><A HREF="http://www.php.net/">mod_php3</A> <TD ALIGN=CENTER>+ - <TD>mod_php3 runs fine, with LDAP and GD libraries + <TD>mod_php3 runs fine, with LDAP and GD and FreeType libraries </TR> <TR> diff --git a/usr.sbin/httpd/htdocs/manual/misc/FAQ.html b/usr.sbin/httpd/htdocs/manual/misc/FAQ.html index 2a4db4bcfe6..767a5759eb0 100644 --- a/usr.sbin/httpd/htdocs/manual/misc/FAQ.html +++ b/usr.sbin/httpd/htdocs/manual/misc/FAQ.html @@ -20,7 +20,7 @@ <H1 ALIGN="CENTER">Apache Server Frequently Asked Questions</H1> <P> - $Revision: 1.1.1.2 $ ($Date: 1998/10/01 17:20:10 $) + $Revision: 1.2 $ ($Date: 1998/10/11 19:45:05 $) </P> <P> The latest version of this FAQ is always available from the main @@ -302,6 +302,14 @@ </LI> <LI><A HREF="#submit_patch">How do I submit a patch to the Apache Group?</A> </LI> + <LI><A HREF="#aixccbug">Why am I getting "<SAMP>Expected </Directory> + but saw </Directory></SAMP>" when I try to start Apache?</A> + </LI> + <LI><A HREF="#domination">Why has Apache stolen my favourite site's + Internet address?</A> + </LI> + <LI><A HREF="#apspam">Why am I getting spam mail from the Apache site?</A> + </LI> </OL> </LI> </UL> @@ -2283,30 +2291,35 @@ let you apply certain attributes against collections of files or resources in very flexible ways - for example, all .gif and .jpg files under any "images" directory could be written as /.*\/images\/.*[jpg|gif]/. - - <P>The best overview around is probably the one which comes with + </P> + <P> + The best overview around is probably the one which comes with Perl. We implement a simple subset of Perl's regexp support, but it's still a good way to learn what they mean. You can start by - going to the <A - HREF="http://www.perl.com/CPAN-local/doc/manual/html/pod/perlre.html#Version_8_Regular_Expresions">CPAN - page on regular expressions</A>, and branching out from there. - + going to the + <A + HREF="http://www.perl.com/CPAN-local/doc/manual/html/pod/perlre.html#Version_8_Regular_Expresions" + >CPAN page on regular expressions</A>, and branching out from there. + </P> <HR> </LI> <LI><A NAME="broken-gcc"><STRONG>I'm using gcc and I get some compilation errors, what is wrong?</STRONG></A> - <P> GCC parses your system header files and produces a modified subset which + <P> + GCC parses your system header files and produces a modified subset which it uses for compiling. This behaviour ties GCC tightly to the version of your operating system. So, for example, if you were running IRIX 5.3 when you built GCC and then upgrade to IRIX 6.2 later, you will have to rebuild GCC. Similarly for Solaris 2.4, 2.5, or 2.5.1 when you upgrade to 2.6. Sometimes you can type "gcc -v" and it will tell you the version of the operating system it was built against. + </P> <P> If you fail to do this, then it is very likely that Apache will fail to build. One of the most common errors is with <CODE>readv</CODE>, <CODE>writev</CODE>, or <CODE>uio.h</CODE>. This is <STRONG>not</STRONG> a bug with Apache. You will need to re-install GCC. + </P> <HR> </LI> <LI><A NAME="htaccess-work"> @@ -2319,33 +2332,86 @@ it covers the directory you are trying to use the .htaccess file in. This is normally accomplished by ensuring it is inside the proper <A HREF="../mod/core.html#directory">Directory</A> container. + </P> <HR> </LI> <LI><A NAME="submit_patch"> <STRONG>How do I submit a patch to the Apache Group?</STRONG></A> <P> - The Apache Group encourages patches from outside developers. There are 2 main "types" - of patches: small bugfixes and general improvements. Bugfixes should be sent to the + The Apache Group encourages patches from outside developers. There are 2 + main "types" + of patches: small bugfixes and general improvements. Bugfixes should be + submitting using the Apache <A HREF="http://www.apache.org/bug_report.html">bug report page</A>. - Improvements, modifications and additions should follow these instructions. + Improvements, modifications, and additions should follow the instructions + below. + </P> <P> In general, the first course of action is to be a member of the - <CODE>new-httpd@apache.org</CODE> mailing list. This indicates to the Group that - you are closely following the latest Apache developments. Your patch file should be - generated using either '<CODE>diff -c</CODE>' or '<CODE>diff -u</CODE>' against the - latest CVS tree. To submit your patch, send Email to <CODE>new-httpd@apache.org</CODE> - with a <CODE>Subject:</CODE> line that starts with <CODE>[PATCH]</CODE> and + <SAMP>new-httpd@apache.org</SAMP> mailing list. This indicates to the Group + that + you are closely following the latest Apache developments. Your patch file + should be + generated using either '<CODE>diff -c</CODE>' or + '<CODE>diff -u</CODE>' against the + latest CVS tree. To submit your patch, send email to + <SAMP>new-httpd@apache.org</SAMP> + with a <SAMP>Subject:</SAMP> line that starts with <SAMP>[PATCH]</SAMP> and includes a general description of the patch. In the body of the message, the - patch should be clearly described and then included at the end of the message. - If the patch-file is long, you can note a URL to the file instead of the file - itself. Use of MIME enclosures/attachments should be avoided. + patch should be clearly described and then included at the end of the + message. + If the patch-file is long, you can note a URL to the file instead of the + file itself. Use of MIME enclosures/attachments should be avoided. + </P> <P> - Be prepared to respond to any questions about your patches and possibly defend + Be prepared to respond to any questions about your patches and possibly + defend your code. If your patch results in a lot of discussion, you may be asked to submit an updated patch that incorporate all changes and suggestions. + </P> + <HR> + </LI> + <LI><A NAME="aixccbug"><STRONG>Why am I getting "<SAMP>Expected + </Directory> but saw </Directory></SAMP>" when + I try to start Apache?</STRONG></A> + <P> + This is a known problem with certain versions of the AIX C compiler. + IBM are working on a solution, and the issue is being tracked by + <A HREF="http://bugs.apache.org/index/full/2312">problem report #2312</A>. + </P> + <HR> + </LI> + <LI><A NAME="domination"><STRONG>Why has Apache stolen my favourite site's + Internet address?</STRONG></A> + <P> + The simple answer is: "It hasn't." This misconception is usually + caused by the site in question having migrated to the Apache Web + server software, but not having migrated the site's content yet. When + Apache is installed, the default page that gets installed tells the + Webmaster the installation was successful. The expectation is that + this default page will be replaced with the site's real content. + If it doesn't, complain to the Webmaster, not to the Apache project -- + we just make the software and aren't responsible for what people + do (or don't do) with it. + </P> + <HR> + </LI> + <LI><A NAME="apspam"><STRONG>Why am I getting spam mail from the + Apache site?</STRONG></A> + <P> + The short answer is: "You aren't." Usually when someone thinks the + Apache site is originating spam, it's because they've traced the + spam to a Web site, and the Web site says it's using Apache. See the + <A HREF="#domination">previous FAQ entry</A> for more details on this + phenomenon. + </P> + <P> + No marketing spam originates from the Apache site. The only mail + that comes from the site goes only to addresses that have been + <EM>requested</EM> to receive the mail. + </P> <HR> </LI> - <!-- Don't forget to add HR tags at the end of each list item.. --> </OL> diff --git a/usr.sbin/httpd/htdocs/manual/mod/core.html b/usr.sbin/httpd/htdocs/manual/mod/core.html index 26c397b0f5d..f8734d1d9d7 100644 --- a/usr.sbin/httpd/htdocs/manual/mod/core.html +++ b/usr.sbin/httpd/htdocs/manual/mod/core.html @@ -818,7 +818,7 @@ responses.</A><P><HR> <A HREF="directive-dict.html#Syntax" REL="Help" -><STRONG>Syntax:</STRONG></A> ErrorLog <EM>filename</EM>|<CODE>syslog</CODE> +><STRONG>Syntax:</STRONG></A> ErrorLog ><EM>filename</EM>|<CODE>syslog[:facility]</CODE> <BR> <A HREF="directive-dict.html#Default" @@ -841,7 +841,10 @@ spawn to handle the error log. <P><STRONG>Apache 1.3 and above:</STRONG> Using <CODE>syslog</CODE> instead of a filename enables logging via syslogd(8) -if the system supports it. +if the system supports it. The default is to use syslog facility +<CODE>local7</CODE>, but you can override this by using the +<CODE>syslog:</CODE><EM>facility</EM> syntax where <EM>facility</EM> can be +one of the names usually documented in syslog(1). <P> SECURITY: See the diff --git a/usr.sbin/httpd/htdocs/manual/mod/mod_autoindex.html b/usr.sbin/httpd/htdocs/manual/mod/mod_autoindex.html index aacc963d3af..f4091df25da 100644 --- a/usr.sbin/httpd/htdocs/manual/mod/mod_autoindex.html +++ b/usr.sbin/httpd/htdocs/manual/mod/mod_autoindex.html @@ -476,7 +476,16 @@ IndexIgnore README .htaccess *~ <A HREF="directive-dict.html#Syntax" REL="Help" -><STRONG>Syntax:</STRONG></A> IndexOptions <EM>option option ...</EM><BR> +><STRONG>Syntax:</STRONG></A> IndexOptions <EM>option option ...</EM> + (Apache 1.3.2 and earlier) +<BR> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> IndexOptions <EM>[+|-]option [+|-]option + ...</EM> + (Apache 1.3.3 and later) +<BR> <A HREF="directive-dict.html#Context" REL="Help" @@ -493,12 +502,20 @@ IndexIgnore README .htaccess *~ <A HREF="directive-dict.html#Module" REL="Help" -><STRONG>Module:</STRONG></A> mod_autoindex<P> +><STRONG>Module:</STRONG></A> mod_autoindex +<BR> +<A + HREF="directive-dict.html#Compatibility" + REL="Help" +><STRONG>Compatibility:</STRONG></A> '+/-' syntax and merging of multiple + <SAMP>IndexOptions</SAMP> directives is only available with + Apache 1.3.3 and later +<P> The IndexOptions directive specifies the behavior of the directory indexing. <EM>Option</EM> can be one of <DL> -<DT>FancyIndexing +<DT><A NAME="indexoptions:fancyindexing">FancyIndexing</A> <DD><!--%plaintext <?INDEX {\tt FancyIndexing} index option> --> This turns on fancy indexing of directories. <BLOCKQUOTE> @@ -511,7 +528,7 @@ This turns on fancy indexing of directories. is combined with any <SAMP>IndexOptions</SAMP> directive already specified for the current scope.</STRONG> </BLOCKQUOTE> -<DT>IconHeight[=pixels] (<EM>Apache 1.3 and later</EM>) +<DT><A NAME="indexoptions:iconheight">IconHeight[=pixels] (<EM>Apache 1.3 and later</EM>)</A> <DD> <!--%plaintext <?INDEX {\tt IconHeight} index option> --> Presence of this option, when used with IconWidth, will cause the server @@ -521,12 +538,12 @@ precalculate the page layout without having to wait until all the images have been loaded. If no value is given for the option, it defaults to the standard height of the icons supplied with the Apache software. -<DT>IconsAreLinks +<DT><A NAME="indexoptions:iconsarelinks">IconsAreLinks</A> <DD> <!--%plaintext <?INDEX {\tt IconsAreLinks} index option> --> This makes the icons part of the anchor for the filename, for fancy indexing. -<DT>IconWidth[=pixels] (<EM>Apache 1.3 and later</EM>) +<DT><A NAME="indexoptions:iconwidth">IconWidth[=pixels] (<EM>Apache 1.3 and later</EM>)</A> <DD> <!--%plaintext <?INDEX {\tt IconWidth} index option> --> Presence of this option, when used with IconHeight, will cause the server @@ -536,19 +553,19 @@ precalculate the page layout without having to wait until all the images have been loaded. If no value is given for the option, it defaults to the standard width of the icons supplied with the Apache software. -<DT>NameLength=[<EM>n</EM> | *] (<EM>Apache 1.3.2 and later</EM>) +<DT><A NAME="indexoptions:namewidth">NameWidth=[<EM>n</EM> | *] (<EM>Apache 1.3.2 and later</EM>)</A> <DD> -The NameLength keyword allows you to specify the width of the +The NameWidth keyword allows you to specify the width of the filename column in bytes. If the keyword value is '<SAMP>*</SAMP>', then the column is automatically sized to the length of the longest filename in the display. -<DT>ScanHTMLTitles +<DT><A NAME="indexoptions:scanhtmltitles">ScanHTMLTitles</A> <DD><!--%plaintext <?INDEX {\tt ScanHTMLTitles} index option> --> This enables the extraction of the title from HTML documents for fancy indexing. If the file does not have a description given by <A HREF="#adddescription">AddDescription</A> then httpd will read the document for the value of the TITLE tag. This is CPU and disk intensive. -<DT>SuppressColumnSorting +<DT><A NAME="indexoptions:suppresscolumnsorting">SuppressColumnSorting</A> <DD> <!--%plaintext <?INDEX {\tt SuppressColumnSorting} index option> --> If specified, Apache will not make the column headings in a FancyIndexed @@ -556,11 +573,11 @@ directory listing into links for sorting. The default behaviour is for them to be links; selecting the column heading will sort the directory listing by the values in that column. <STRONG>Only available in Apache 1.3 and later.</STRONG> -<DT>SuppressDescription +<DT><A NAME="indexoptions:suppressdescription">SuppressDescription</A> <DD> <!--%plaintext <?INDEX {\tt SuppressDescription} index option> --> This will suppress the file description in fancy indexing listings. -<DT>SuppressHTMLPreamble +<DT><A NAME="indexoptions:suppresshtmlpreamble">SuppressHTMLPreamble</A> <DD> <!--%plaintext <?INDEX {\tt SuppressHTMLPreamble} index option> --> If the directory actually contains a file specified by the @@ -573,17 +590,25 @@ cetera</EM>). The SuppressHTMLPreamble option disables this behaviour, causing the module to start the display with the header file contents. The header file must contain appropriate HTML instructions in this case. If there is no header file, the preamble is generated as usual. -<DT>SuppressLastModified +<DT><A NAME="indexoptions:suppresslastmodified">SuppressLastModified</A> <DD> <!--%plaintext <?INDEX {\tt SuppressLastModified} index option> --> This will suppress the display of the last modification date, in fancy indexing listings. -<DT>SuppressSize +<DT><A NAME="indexoptions:suppresssize">SuppressSize</A> <DD> <!--%plaintext <?INDEX {\tt SuppressSize} index option> --> This will suppress the file size in fancy indexing listings. </DL> -This default is that no options are enabled. If multiple IndexOptions +<P> +There are some noticeable differences in the behaviour of this +directive in recent (post-1.3.0) versions of Apache. +</P> +<DL> +<DT>Apache 1.3.2 and earlier:</DT> +<DD> +<P> +The default is that no options are enabled. If multiple IndexOptions could apply to a directory, then the most specific one is taken complete; the options are not merged. For example: <BLOCKQUOTE><CODE> @@ -595,7 +620,52 @@ IndexOptions ScanHTMLTitles <BR> </Directory> </CODE></BLOCKQUOTE> then only <CODE>ScanHTMLTitles</CODE> will be set for the /web/docs/spec -directory.<P><HR> +directory. +</P> +</DD> +<DT>Apache 1.3.3 and later:</DT> +<DD> +<P> +Apache 1.3.3 introduced some significant changes in the handling of +<SAMP>IndexOptions</SAMP> directives. In particular, +</P> +<UL> + <LI>Multiple <SAMP>IndexOptions</SAMP> directives for a single + directory are now merged together. The result of the example above + will now be the equivalent of + <CODE>IndexOptions FancyIndexing ScanHTMLTitles</CODE>. + </LI> + <LI>The addition of the incremental syntax (<EM>i.e.</EM>, prefixing + keywords with '+' or '-'). + </LI> +</UL> +<P> +Whenever a '+' or '-' prefixed keyword is encountered, it is applied +to the current <SAMP>IndexOptions</SAMP> settings (which may have been +inherited from an upper-level directory). However, whenever an unprefixed +keyword is processed, it clears all inherited options and any incremental +settings encountered so far. Consider the following example: +</P> +<BLOCKQUOTE><CODE>IndexOptions +ScanHTMLTitles -IconsAreLinks FancyIndexing +<BR> +IndexOptions +SuppressSize +<BR> +</CODE></BLOCKQUOTE> +<P> +The net effect is equivalent to +<CODE>IndexOptions FancyIndexing +SuppressSize</CODE>, because +the unprefixed <CODE>FancyIndexing</CODE> discarded the incremental +keywords before it, but allowed them to start accumulating again +afterward. +</P> +<P> +To unconditionally set the <CODE>IndexOptions</CODE> for a +particular directory, clearing the inherited settings, specify +keywords without either '+' or '-' prefixes. +</P> +</DD> +</DL> +<HR> <H2><A NAME="readmename">ReadmeName</A></H2> <!--%plaintext <?INDEX {\tt ReadmeName} directive> --> diff --git a/usr.sbin/httpd/htdocs/manual/new_features_1_3.html b/usr.sbin/httpd/htdocs/manual/new_features_1_3.html index 8e955ceefc2..0963caa9d90 100644 --- a/usr.sbin/httpd/htdocs/manual/new_features_1_3.html +++ b/usr.sbin/httpd/htdocs/manual/new_features_1_3.html @@ -288,18 +288,37 @@ MIME-typing</A></STRONG> HREF="mod/mod_autoindex.html#indexoptions">IndexOptions</A> keyword. - <LI><A HREF="mod/mod_autoindex.html#indexoptions"> + <LI><A HREF="mod/mod_autoindex.html#indexoptions:suppresshtmlpreamble"> <CODE><STRONG>SuppressHTMLPreamble</STRONG></CODE></A> can be used if your README.html file includes its own HTML header. - <LI><STRONG><CODE>IconHeight</CODE> and <CODE>IconWidth</CODE></STRONG> let - you set - height and width attributes to the <CODE><IMG></CODE> tag in - directory listings. + <LI>The <A HREF="mod/mod_autoindex.html#indexoptions"> + <CODE><STRONG>IndexOptions</STRONG></CODE></A> directive now allows + the use of incremental prefixes (+/- to add/remove the respective + keyword feature, as was already possible for the + <A HREF="mod/core.html#options">Options</A> directive) to its + keyword arguments. Multiple IndexOptions directives applying + to the same directory will now be merged. + + <LI><A HREF="mod/mod_autoindex.html#indexoptions:iconheight" + ><STRONG><CODE>IconHeight</CODE></STRONG></A> and + <A HREF="mod/mod_autoindex.html#indexoptions:iconwidth" + ><STRONG><CODE>IconWidth</CODE></STRONG></A> + let you set height and width attributes to the + <CODE><IMG></CODE> tag in directory listings. + + <LI>The new <A HREF="mod/mod_autoindex.html#indexoptions:namewidth" + ><STRONG><CODE>NameWidth</CODE></STRONG></A> keyword to the + <A HREF="mod/mod_autoindex.html#indexoptions">IndexOptions</A> + directive lets you set the number of columns for + <A HREF="mod/mod_autoindex.html#indexoptions:fancyindexing">"fancy" + directory listings</A>. If set to an '*' asterisk, the name width + will be adjusted automatically. <LI>The <A HREF="mod/mod_autoindex.html#fancyindexing" ><SAMP>FancyIndexing</SAMP></A> directive now correctly has - the same impact as <SAMP>IndexOptions FancyIndexing</SAMP> + the same impact as + <A HREF="mod/mod_autoindex.html#indexoptions:fancyindexing"><SAMP>IndexOptions FancyIndexing</SAMP></A> without replacing the effect of any existing <SAMP>IndexOptions</SAMP> directive. @@ -517,9 +536,9 @@ MIME-typing</A></STRONG> running BS2000/OSD</A></STRONG> <DD>As a premiere, this version of Apache comes with a beta version of a port to a mainframe machine which uses the EBCDIC character set - as its native codeset (It is the SIEMENS NIXDORF family of - mainframes running the BS2000/OSD operating system on a IBM/390 - compatible processor This mainframe OS nowadays features a + as its native codeset (It is the SIEMENS family of mainframes + running the BS2000/OSD operating system on a IBM/390 + compatible processor. This mainframe OS nowadays features a SVR4-like POSIX subsystem). <DT><STRONG><A HREF="mod/core.html#accessfilename"><CODE>AccessFileName</CODE> diff --git a/usr.sbin/httpd/htdocs/manual/windows.html b/usr.sbin/httpd/htdocs/manual/windows.html index 385be7cead4..8ddc4aad3e4 100644 --- a/usr.sbin/httpd/htdocs/manual/windows.html +++ b/usr.sbin/httpd/htdocs/manual/windows.html @@ -23,7 +23,7 @@ <H1 ALIGN="CENTER">Using Apache With Microsoft Windows</H1> <P>This document explains how to install, configure and run - Apache 1.3 under Microsoft Windows. Please note that at + Apache 1.3b6 and later under Microsoft Windows. Please note that at this time, Windows support is entirely experimental, and is recommended only for experienced users. The Apache Group does not guarantee that this software will work as documented, or even at @@ -53,6 +53,7 @@ to help with development, or to track down bugs), see the section on <LI><A HREF="#run">Running Apache for Windows</A> <LI><A HREF="#use">Using Apache for Windows</A> <LI><A HREF="#cmdline">Running Apache for Windows from the Command Line</A> + <LI><A HREF="#signal">Signalling Apache when running</A> <LI><A HREF="#comp">Compiling Apache for Windows</A> </UL> @@ -189,8 +190,8 @@ with To run Apache from a console window, select the "Apache Server" option from the Start menu. This will open a console window and start Apache running inside it. The window will remain active until you stop -Apache. To stop Apache running, press Control-C within the console -window. +Apache. To stop Apache running, see <A HREF="#signal>Signalling Apache +when Running</SAMP>. <P> @@ -362,6 +363,35 @@ and to remove the Apache service, use </PRE> +<H2><A NAME="signal">Signalling Apache when running</A></H2> + +On Windows 95 Apache runs as a console application. You can tell a +running Apache to stop by opening another console window and running + +<PRE> + apache -k shutdown +</PRE> + +This should be used instead of pressing Control-C in the running +Apache console window, because it lets Apache end any current +transactions and cleanup gracefully. + +<P> + +You can also tell Apache to restart. This makes it re-read the +configuration files. Any transactions in progress are allowed to +complete without interruption. To restart Apache, run + +<PRE> + apache -k restart +</PRE> + +Note for people familiar with the Unix version of Apache: these +commands provide a Windows equivalent to <CODE>kill -TERM +<i>pid</i></CODE> and <CODE>kill -USR1 <i>pid</i></CODE>. The command +line option used, <CODE>-k</CODE>, was chosen as a reminder of the +"kill" command used on Unix. + <H2><A NAME="comp">Compiling Apache for Windows</A></H2> <P>Compiling Apache requires Microsoft Visual C++ 5.0 to be properly diff --git a/usr.sbin/httpd/src/CHANGES b/usr.sbin/httpd/src/CHANGES index 03bfe02f369..2d9899db077 100644 --- a/usr.sbin/httpd/src/CHANGES +++ b/usr.sbin/httpd/src/CHANGES @@ -1,3 +1,121 @@ +Changes with Apache 1.3.3 + + *) Added a complete implementation of the Expect header field as + specified in rev-05 of HTTP/1.1. Disabled the 100 Continue + response when we already know the final status, which is mighty + useful for PUT responses that result in 302 or 401. [Roy Fielding] + + *) Remove extra trailing whitespace from the getline results as part + of the protocol processing, which is extra nice because it works + between continuation lines, is almost no cost in the normal case + of no extra whitespace, and saves memory. [Roy Fielding] + + *) Added new HTTP status codes and default response bodies from the + revised HTTP/1.1 (307, 416, 417), WebDAV (102, 207, 422, 423), and + HTTP Extension Framework (510) specifications. Did not add the + WebDAV 424 and 425 codes because they are bogus. We don't use any + of these codes yet, but they are now available to 3rd-party modules. + [Roy Fielding] + + *) Fix a possible race condition between timed-out requests and the + ap_bhalfduplex select that might result in an infinite loop on + platforms that do not validate the descriptor. [Roy Fielding] + + *) WIN32: Add "-k shutdown" and "-k restart" options to signal a + running Apache server [Paul Sutton] + + *) Fix mod_autoindex bug where directories got a size of "0k" instead + of "-". [Martin Plechsmid <plechsmi@karlin.mff.cuni.cz>, Marc Slemko] + PR#3130 + + *) PORT: DRS 6000 machine. [Paul Debleecker <pdebleecker@jetair.be>] + + *) Add the server signature text (from the core ServerSignature directive) + to the list of envariables available to scripts, SSI, and the like. + [Ken Coar] + + *) PORT: Fix sys/resource.h handling for SCO 3.x platform. + [M. Laak <maert@proinv.ee>] PR#3108 + + *) Fallback from sysconf-based to plain HZ-based `ticks per second' + calculation in mod_status for all systems which don't have POSIX + sysconf() (like UTS 2.1) and not only for the NEXT platform. + [Dave Dykstra <dwd@bell-labs.com>] PR#3055 + + *) Fix `require ...' directive parsing in mod_auth, mod_auth_dbm and + mod_auth_db by using ap_getword_white() (which uses ap_isspace()) + instead of ap_getword(..., ' ') (which parses only according to spaces + but not tabs). [James Morris <jmorris@intercode.com.au>, + Ralf S. Engelschall] PR#3105 + + *) Fix the SERVER_NAME variable under sub-request situations (where + `UseCanonicalName off' is used) like CGI's called from SSI pages or + RewriteCond variables by adopting r->hostname to sub-requests. + [James Grinter <jrg@blodwen.demon.co.uk>] PR#3111 + + *) Fix stderr redirection under syslog-based error logging situation. + [Youichirou Koga <y-koga@jp.FreeBSD.org>] PR#3095 + + *) Document `ErrorLog syslog:facility' variant of error logging. + [Youichirou Koga <y-koga@jp.FreeBSD.org>] PR#3096 + + *) Fix http://localhost/ hints in top-level INSTALL document. + [Rob Jenson <robjen@spotch.com>, Ralf S. Engelschall] PR#3088 + + *) Quote paths in default configuration files. [Wilfredo Sanchez] + + *) PORT: Remove extra HAVE_SYS_RESOURCE_H define for RHAPSODY since + it is now taken care of properly by the header file tests. + [Wilfredo Sanchez <wsanchez@apple.com>] + + *) Fix problem with scripts and filehandle inheritance on Win32. + [Ken Parzygnat <kparz@raleigh.ibm.com>] PR#2884, 2910 + + *) Win32 name canonicalisation could end up using the server's + working directory to fill in some blanks. [Ken Parzygnat + <kparz@raleigh.ibm.com>] PR#3001 + + *) Correct invalid assumption by ap_sub_req_lookup_file() that all + absolute paths begin with "/" -- because they don't on Win32. + [Ken Parzygnat <kparz@raleigh.ibm.com>] PR#2976, 3074 + + *) Add [REDIRECT_]VARIANTS environment variable to mod_speling + so that ErrorDocument 300 processors can reformat the list + if desired. [Ken Coar] PR#2859 + + *) Add +/- incremental prefixes to IndexOptions keywords, and + enable merging of multiple IndexOptions directives. [Ken Coar] + + *) PORT: Allow GuessOS to recognize Unixware 7.0.1 [Steve Cameron + <steve.cameron@compaq.com>] + + *) Reconstructed the loop through multiple htaccess file names so + that missing files are not confused with unreadable files. + [Roy Fielding] + + *) The ap_pfopen and ap_pfdopen routines were failing to protect the + errno on an error, which leads to one error being mistaken for + another when reading non-existent .htaccess files. + [Jim Jagielski] + + *) OS/2: The new header tests get things right, need to update + ap_config.h. [Brian Havard] + + *) The Perl %ENV hash will now be setup by default when using the + mod_include `perl' command [Doug MacEachern] + + *) PORT: Add Pyramid DC/OSx support to configuration mechanism. + [Earle Ake <akee@wpdiss1.wpafb.af.mil>] + + *) PORT: Fix sys/resource.h handling for Amdahl's UTS 2.1 + [Dave Dykstra <dwd@bell-labs.com>] PR#3054 + + *) Correct comment in mod_log_config.c about its internals. + [Elf Sternberg <elf@halcyon.com>] + + *) Avoid possible line overflow in Configure: Use an awkfile to + handle the creation of modules.c [Jim Jagielski] + Changes with Apache 1.3.2 *) Fix bug in ap_remove_module(), which caused problems for dso's @@ -2129,7 +2247,7 @@ Changes with Apache 1.3b4 [robinton@amtrash.comlink.de (Soeren Ziehe), Martin Kraemer] *) PORT: Apache now compiles & runs on an EBCDIC mainframe - (the Siemens Nixdorf BS2000-OSD family) in the POSIX subsystem + (the Siemens BS2000/OSD family) in the POSIX subsystem [Martin Kraemer] *) PORT: Fix problem killing children when terminating. Allow ^C diff --git a/usr.sbin/httpd/src/Configure b/usr.sbin/httpd/src/Configure index a8822c7dcfe..e961d076187 100644 --- a/usr.sbin/httpd/src/Configure +++ b/usr.sbin/httpd/src/Configure @@ -618,6 +618,12 @@ case "$PLAT" in DEF_WANTHSREGEX=yes LIBS="$LIBS -lsocket -lnsl -lc" ;; + pyramid-pyramid-svr4) + OS='SVR4' + CFLAGS="$CFLAGS -DSVR4 -DNO_LONG_DOUBLE" + DEF_WANTHSREGEX=yes + LIBS="$LIBS -lsocket -lnsl -lc" + ;; DS/90\ 7000-*-sysv4*) OS='UXP/DS' CFLAGS="$CFLAGS -DUXPDS" @@ -708,6 +714,12 @@ case "$PLAT" in DEF_WANTHSREGEX=yes LIBS="$LIBS -lsocket -lnsl -lc -L/usr/ucblib -lucb" ;; + drs6000*) + OS='DRS6000' + CFLAGS="$CFLAGS -DSVR4" + DEF_WANTHSREGEX=yes + LIBS="$LIBS -lsocket -lnsl -lc -L/usr/ucblib -lucb" + ;; *) # default: Catch systems we don't know about OS='Unknown and unsupported OS' echo Sorry, but we cannot grok \"$PLAT\" @@ -1499,7 +1511,7 @@ if [ "x$using_shlib" = "x1" ] ; then # select the special subtarget for shared core generation SUBTARGET=target_shared # determine additional suffixes for libhttpd.so - V=1 R=3 P=2 + V=1 R=3 P=3 if [ ".$SHLIB_SUFFIX_DEPTH" = .0 ]; then SHLIB_SUFFIX_LIST="" fi @@ -1540,7 +1552,7 @@ fi #################################################################### ## Now create modules.c ## -cat $tmpfile | sed 's/_module//' | awk >modules.c ' +$CAT > $awkfile <<'EOFM' BEGIN { modules[n++] = "core" pmodules[pn++] = "core" @@ -1588,7 +1600,9 @@ cat $tmpfile | sed 's/_module//' | awk >modules.c ' print " NULL" print "};" print "" - }' + } +EOFM +$CAT $tmpfile | sed 's/_module//' | awk -f $awkfile > modules.c #################################################################### ## figure out which module dir require use to autocreate a Makefile. diff --git a/usr.sbin/httpd/src/README.EBCDIC b/usr.sbin/httpd/src/README.EBCDIC index 749ddc66765..e3361adadf3 100644 --- a/usr.sbin/httpd/src/README.EBCDIC +++ b/usr.sbin/httpd/src/README.EBCDIC @@ -2,8 +2,8 @@ This version of Apache comes with a first-cut (working, but not fully tested) port to a mainframe machine which uses the EBCDIC -character set as its native codeset (It is the SIEMENS NIXDORF -family of mainframes running the BS2000 operating system. This +character set as its native codeset (It is the SIEMENS family +of mainframes running the BS2000 operating system. This mainframe OS nowadays features a SVR4-like POSIX subsystem). The port was started initially to @@ -22,7 +22,7 @@ decisions of the port to this machine. #ifdef CHARSET_EBCDIC Code which is needed for any EBCDIC based machine #ifdef _OSD_POSIX Code which is needed for the BS2000 - SIEMENS NIXDORF mainframe platform only. + SIEMENS mainframe platform only. * The possibility to translate between ASCII and EBCDIC at the socket level (on BS2000 POSIX, there is a socket option which @@ -88,56 +88,6 @@ decisions of the port to this machine. An example for the latter case is the wwwcount program which we ported as well. -What works: -- In the following list, - + means: works, tested - - means: doesn't work for some reason - ? means: compiled-in, but untested - - http_core.c + - mod_access.c + - mod_actions.c ? - mod_alias.c + - mod_asis.c ? - mod_auth.c + - mod_auth_anon.c + - mod_auth_db.c ? with own libdb.a - mod_auth_dbm.c ? with own libdb.a - mod_autoindex.c + - mod_cern_meta.c ? - mod_cgi.c + - mod_digest.c - / MD5 not ported yet - mod_dir.c + - mod_env.c + - mod_example.c - / not tried yet - mod_expires.c + - mod_headers.c + - mod_imap.c + - mod_include.c + - mod_info.c + - mod_log_agent.c + - mod_log_config.c + - mod_log_referer.c + - mod_mime.c + - mod_mime_magic.c - / not tried yet - mod_negotiation.c + - mod_proxy.c + - mod_rewrite.c ? / untested - mod_setenvif.c + - mod_so.c - / no shared libs - mod_speling.c + - mod_status.c + - mod_unique_id.c + - mod_userdir.c + - mod_usertrack.c ? / untested - -Additional (third-party) modules: See: - mod_jserv.c - / JAVA still being ported http://java.apache.org/ - mod_php.c - / not ported yet http://www.php.net/ - mod_put.c ? / untested http://hpwww.ec-lyon.fr/~vincent/apache/mod_put.html - mod_session.c ? / untested ftp://hachiman.vidya.com/pub/apache/mod_session.tar.gz - - Notes: To use the mod_auth_db functionality, you will need a working libdb.a. On the system where I did the port none was available, so I ported the @@ -145,4 +95,6 @@ standard db-1.85.14 with little problems. Note however that you will need a working perl5 as well if you want to use Apache's dbmmanage script to maintain db user databases. - Martin Kraemer, 31-Mar-1998 +See also the ebcdic.html document which is part of the apache documentation. + + Martin Kraemer, 1-Oct-1998 diff --git a/usr.sbin/httpd/src/helpers/GuessOS b/usr.sbin/httpd/src/helpers/GuessOS index 5901305312d..096df4fd965 100644 --- a/usr.sbin/httpd/src/helpers/GuessOS +++ b/usr.sbin/httpd/src/helpers/GuessOS @@ -53,9 +53,11 @@ if [ "x$XREL" != "x" ]; then echo "whatever-whatever-unixware1"; exit 0 ;; 5) - if [ "x$VERSION" = "x7" ]; then - echo "${MACHINE}-whatever-unixware7"; exit 0 - fi + case "$VERSION" in + 7*) + echo "${MACHINE}-whatever-unixware7"; exit 0 + ;; + esac ;; esac fi @@ -246,6 +248,13 @@ case "${SYSTEM}:${RELEASE}:${VERSION}:${MACHINE}" in echo "whatever-unisys-sysv4"; exit 0; ;; + *:*:dcosx:NILE*) + echo "pyramid-pyramid-svr4"; exit 0; + ;; + + *:*:*:"DRS 6000") + echo "drs6000-whatever-whatever"; exit 0; + ;; esac # diff --git a/usr.sbin/httpd/src/include/ap_config.h b/usr.sbin/httpd/src/include/ap_config.h index e12639e81ab..60e35665ab6 100644 --- a/usr.sbin/httpd/src/include/ap_config.h +++ b/usr.sbin/httpd/src/include/ap_config.h @@ -372,7 +372,6 @@ typedef int pid_t; #define USE_MMAP_SCOREBOARD #define MAP_TMPFILE #define HAVE_RESOURCE -#define HAVE_SYS_RESOURCE_H /* apaci should catch this but doesn't */ #define HAVE_SNPRINTF #define JMP_BUF jmp_buf #define USE_LONGJMP @@ -466,6 +465,7 @@ typedef int rlim_t; #define NO_WRITEV #include <sys/time.h> #define HAVE_SYSLOG 1 +#undef HAVE_SYS_RESOURCE_H #elif defined(SCO5) @@ -615,6 +615,7 @@ extern char *crypt(); #define WEXITSTATUS(status) (int)((status).w_retcode) #define WTERMSIG(status) (int)((status).w_termsig) #define strftime(buf,bufsize,fmt,tm) ascftime(buf,fmt,tm) +#undef HAVE_SYS_RESOURCE_H /* exists but does not provide *rlimit funcs */ #include <sys/types.h> #include <sys/time.h> @@ -645,6 +646,7 @@ extern char *crypt(); typedef quad_t rlim_t; #endif #define USE_FLOCK_SERIALIZED_ACCEPT +#define SINGLE_LISTEN_UNSERIALIZED_ACCEPT #define HAVE_SYSLOG 1 #define SYS_SIGLIST sys_siglist @@ -706,8 +708,6 @@ typedef int rlim_t; #define NEED_STRNCASECMP #define NO_SETSID #define NO_TIMES -/* ap_config_auto.h gets this wrong, force sys/select.h to be included */ -#define HAVE_SYS_SELECT_H #define CASE_BLIND_FILESYSTEM /* Add some drive name support */ #define chdir _chdir2 diff --git a/usr.sbin/httpd/src/include/ap_mmn.h b/usr.sbin/httpd/src/include/ap_mmn.h index 718dcd21136..5ad482c319d 100644 --- a/usr.sbin/httpd/src/include/ap_mmn.h +++ b/usr.sbin/httpd/src/include/ap_mmn.h @@ -159,6 +159,9 @@ * 4. compat.h -> ap_compat.h * 5. apctype.h -> ap_ctype.h * 19980806 (1.3.2-dev) - add ap_log_rerror() + * - add ap_scan_script_header_err_core() + * - add ap_uuencode() + * - add ap_custom_response() * 19980811 (1.3.2-dev) - added limit_req_line, limit_req_fieldsize, and * limit_req_fields to server_rec. * added limit_req_body to core_dir_config and diff --git a/usr.sbin/httpd/src/include/httpd.h b/usr.sbin/httpd/src/include/httpd.h index 0323072bf0a..d93a896a2db 100644 --- a/usr.sbin/httpd/src/include/httpd.h +++ b/usr.sbin/httpd/src/include/httpd.h @@ -410,7 +410,7 @@ extern "C" { * Example: "Apache/1.1.0 MrWidget/0.1-alpha" */ -#define SERVER_BASEVERSION "Apache/1.3.2" /* SEE COMMENTS ABOVE */ +#define SERVER_BASEVERSION "Apache/1.3.3" /* SEE COMMENTS ABOVE */ #define SERVER_VERSION SERVER_BASEVERSION enum server_token_type { SrvTk_MIN, /* eg: Apache/1.3.0 */ @@ -427,7 +427,7 @@ API_EXPORT(const char *) ap_get_server_built(void); * For a final release, 'betaseq' should be set to '99'. * For example, Apache 1.4.2 should be '1040299' */ -#define APACHE_RELEASE 1030299 +#define APACHE_RELEASE 1030399 #define SERVER_PROTOCOL "HTTP/1.1" #ifndef SERVER_SUPPORT @@ -443,10 +443,15 @@ API_EXPORT(const char *) ap_get_server_built(void); /* ----------------------- HTTP Status Codes ------------------------- */ -#define RESPONSE_CODES 38 +/* The size of the static array in http_protocol.c for storing + * all of the potential response status-lines (a sparse table). + * A future version should dynamically generate the table at startup. + */ +#define RESPONSE_CODES 54 #define HTTP_CONTINUE 100 #define HTTP_SWITCHING_PROTOCOLS 101 +#define HTTP_PROCESSING 102 #define HTTP_OK 200 #define HTTP_CREATED 201 #define HTTP_ACCEPTED 202 @@ -454,12 +459,14 @@ API_EXPORT(const char *) ap_get_server_built(void); #define HTTP_NO_CONTENT 204 #define HTTP_RESET_CONTENT 205 #define HTTP_PARTIAL_CONTENT 206 +#define HTTP_MULTI_STATUS 207 #define HTTP_MULTIPLE_CHOICES 300 #define HTTP_MOVED_PERMANENTLY 301 #define HTTP_MOVED_TEMPORARILY 302 #define HTTP_SEE_OTHER 303 #define HTTP_NOT_MODIFIED 304 #define HTTP_USE_PROXY 305 +#define HTTP_TEMPORARY_REDIRECT 307 #define HTTP_BAD_REQUEST 400 #define HTTP_UNAUTHORIZED 401 #define HTTP_PAYMENT_REQUIRED 402 @@ -476,6 +483,10 @@ API_EXPORT(const char *) ap_get_server_built(void); #define HTTP_REQUEST_ENTITY_TOO_LARGE 413 #define HTTP_REQUEST_URI_TOO_LARGE 414 #define HTTP_UNSUPPORTED_MEDIA_TYPE 415 +#define HTTP_RANGE_NOT_SATISFIABLE 416 +#define HTTP_EXPECTATION_FAILED 417 +#define HTTP_UNPROCESSABLE_ENTITY 422 +#define HTTP_LOCKED 423 #define HTTP_INTERNAL_SERVER_ERROR 500 #define HTTP_NOT_IMPLEMENTED 501 #define HTTP_BAD_GATEWAY 502 @@ -483,6 +494,7 @@ API_EXPORT(const char *) ap_get_server_built(void); #define HTTP_GATEWAY_TIME_OUT 504 #define HTTP_VERSION_NOT_SUPPORTED 505 #define HTTP_VARIANT_ALSO_VARIES 506 +#define HTTP_NOT_EXTENDED 510 #define DOCUMENT_FOLLOWS HTTP_OK #define PARTIAL_CONTENT HTTP_PARTIAL_CONTENT @@ -740,6 +752,13 @@ struct request_rec { * that way, a sub request's list can (temporarily) point to a parent's list */ const struct htaccess_result *htaccess; + +/* Things placed at the end of the record to avoid breaking binary + * compatibility. It would be nice to remember to reorder the entire + * record to improve 64bit alignment the next time we need to break + * binary compatibility for some other reason. + */ + unsigned expecting_100; /* is client waiting for a 100 response? */ }; diff --git a/usr.sbin/httpd/src/main/alloc.c b/usr.sbin/httpd/src/main/alloc.c index 67b4c224b67..e85a85aa3d2 100644 --- a/usr.sbin/httpd/src/main/alloc.c +++ b/usr.sbin/httpd/src/main/alloc.c @@ -1744,6 +1744,7 @@ API_EXPORT(FILE *) ap_pfopen(pool *a, const char *name, const char *mode) FILE *fd = NULL; int baseFlag, desc; int modeFlags = 0; + int saved_errno; #ifdef WIN32 modeFlags = _S_IREAD | _S_IWRITE; @@ -1766,22 +1767,26 @@ API_EXPORT(FILE *) ap_pfopen(pool *a, const char *name, const char *mode) else { fd = fopen(name, mode); } - + saved_errno = errno; if (fd != NULL) ap_note_cleanups_for_file(a, fd); ap_unblock_alarms(); + errno = saved_errno; return fd; } API_EXPORT(FILE *) ap_pfdopen(pool *a, int fd, const char *mode) { FILE *f; + int saved_errno; ap_block_alarms(); f = ap_fdopen(fd, mode); + saved_errno = errno; if (f != NULL) ap_note_cleanups_for_file(a, f); ap_unblock_alarms(); + errno = saved_errno; return f; } @@ -2217,6 +2222,10 @@ API_EXPORT(int) ap_bspawn_child(pool *p, int (*func) (void *, child_info *), voi HANDLE hPipeInputWrite = NULL; HANDLE hPipeErrorRead = NULL; HANDLE hPipeErrorWrite = NULL; + HANDLE hPipeInputWriteDup = NULL; + HANDLE hPipeOutputReadDup = NULL; + HANDLE hPipeErrorReadDup = NULL; + HANDLE hCurrentProcess; int pid = 0; child_info info; @@ -2255,6 +2264,57 @@ API_EXPORT(int) ap_bspawn_child(pool *p, int (*func) (void *, child_info *), voi } return 0; } + /* + * When the pipe handles are created, the security descriptor + * indicates that the handle can be inherited. However, we do not + * want the server side handles to the pipe to be inherited by the + * child CGI process. If the child CGI does inherit the server + * side handles, then the child may be left around if the server + * closes its handles (e.g. if the http connection is aborted), + * because the child will have a valid copy of handles to both + * sides of the pipes, and no I/O error will occur. Microsoft + * recommends using DuplicateHandle to turn off the inherit bit + * under NT and Win95. + */ + hCurrentProcess = GetCurrentProcess(); + if ((pipe_in && !DuplicateHandle(hCurrentProcess, hPipeInputWrite, + hCurrentProcess, + &hPipeInputWriteDup, 0, FALSE, + DUPLICATE_SAME_ACCESS)) + || (pipe_out && !DuplicateHandle(hCurrentProcess, hPipeOutputRead, + hCurrentProcess, &hPipeOutputReadDup, + 0, FALSE, DUPLICATE_SAME_ACCESS)) + || (pipe_err && !DuplicateHandle(hCurrentProcess, hPipeErrorRead, + hCurrentProcess, &hPipeErrorReadDup, + 0, FALSE, DUPLICATE_SAME_ACCESS))) { + if (pipe_in) { + CloseHandle(hPipeInputRead); + CloseHandle(hPipeInputWrite); + } + if (pipe_out) { + CloseHandle(hPipeOutputRead); + CloseHandle(hPipeOutputWrite); + } + if (pipe_err) { + CloseHandle(hPipeErrorRead); + CloseHandle(hPipeErrorWrite); + } + return 0; + } + else { + if (pipe_in) { + CloseHandle(hPipeInputWrite); + hPipeInputWrite = hPipeInputWriteDup; + } + if (pipe_out) { + CloseHandle(hPipeOutputRead); + hPipeOutputRead = hPipeOutputReadDup; + } + if (pipe_err) { + CloseHandle(hPipeErrorRead); + hPipeErrorRead = hPipeErrorReadDup; + } + } /* The script writes stdout to this pipe handle */ info.hPipeOutputWrite = hPipeOutputWrite; diff --git a/usr.sbin/httpd/src/main/buff.c b/usr.sbin/httpd/src/main/buff.c index 0501b1a7377..a8cb2515160 100644 --- a/usr.sbin/httpd/src/main/buff.c +++ b/usr.sbin/httpd/src/main/buff.c @@ -562,14 +562,22 @@ static int saferead(BUFF *fb, char *buf, int nbyte) #endif -/* note we assume the caller has ensured that fb->fd_in <= FD_SETSIZE */ +/* Test the descriptor and flush the output buffer if it looks like + * we will block on the next read. + * + * Note we assume the caller has ensured that fb->fd_in <= FD_SETSIZE + */ API_EXPORT(void) ap_bhalfduplex(BUFF *fb) { int rv; fd_set fds; struct timeval tv; - if (fb->incnt > 0 || fb->outcnt == 0) { + /* We don't need to do anything if the connection has been closed + * or there is something readable in the incoming buffer + * or there is nothing flushable in the output buffer. + */ + if (fb == NULL || fb->fd_in < 0 || fb->incnt > 0 || fb->outcnt == 0) { return; } /* test for a block */ @@ -579,7 +587,8 @@ API_EXPORT(void) ap_bhalfduplex(BUFF *fb) tv.tv_sec = 0; tv.tv_usec = 0; rv = ap_select(fb->fd_in + 1, &fds, NULL, NULL, &tv); - } while (rv < 0 && errno == EINTR); + } while (rv < 0 && errno == EINTR && !(fb->flags & B_EOUT)); + /* treat any error as if it would block as well */ if (rv != 1) { ap_bflush(fb); diff --git a/usr.sbin/httpd/src/main/http_config.c b/usr.sbin/httpd/src/main/http_config.c index 307e9044d1e..50f865712b1 100644 --- a/usr.sbin/httpd/src/main/http_config.c +++ b/usr.sbin/httpd/src/main/http_config.c @@ -1206,7 +1206,7 @@ int ap_parse_htaccess(void **result, request_rec *r, int override, char *filename = NULL; const struct htaccess_result *cache; struct htaccess_result *new; - void *dc; + void *dc = NULL; /* firstly, search cache */ for (cache = r->htaccess; cache != NULL; cache = cache->next) @@ -1224,41 +1224,39 @@ int ap_parse_htaccess(void **result, request_rec *r, int override, parms.path = ap_pstrdup(r->pool, d); /* loop through the access names and find the first one */ - while (!f && access_name[0]) { - char *w = ap_getword_conf(r->pool, &access_name); - filename = ap_make_full_path(r->pool, d, w); - f = ap_pcfg_openfile(r->pool, filename); - } - if (f) { - dc = ap_create_per_dir_config(r->pool); - parms.config_file = f; + while (access_name[0]) { + filename = ap_make_full_path(r->pool, d, + ap_getword_conf(r->pool, &access_name)); - errmsg = ap_srm_command_loop(&parms, dc); + if ((f = ap_pcfg_openfile(r->pool, filename)) != NULL) { - ap_cfg_closefile(f); + dc = ap_create_per_dir_config(r->pool); - if (errmsg) { - ap_log_rerror(APLOG_MARK, APLOG_ALERT|APLOG_NOERRNO, r, "%s: %s", - filename, errmsg); - ap_table_setn(r->notes, "error-notes", errmsg); - return HTTP_INTERNAL_SERVER_ERROR; - } + parms.config_file = f; - *result = dc; - } - else { - if (errno == ENOENT || errno == ENOTDIR) - dc = NULL; - else { - ap_log_rerror(APLOG_MARK, APLOG_CRIT, r, - "%s pcfg_openfile: unable to check htaccess file, ensure it is readable", - filename); - ap_table_setn(r->notes, "error-notes", - "Server unable to read htaccess file, denying " - "access to be safe"); - return HTTP_FORBIDDEN; - } + errmsg = ap_srm_command_loop(&parms, dc); + + ap_cfg_closefile(f); + + if (errmsg) { + ap_log_rerror(APLOG_MARK, APLOG_ALERT|APLOG_NOERRNO, r, + "%s: %s", filename, errmsg); + return HTTP_INTERNAL_SERVER_ERROR; + } + *result = dc; + break; + } + else if (errno != ENOENT && errno != ENOTDIR) { + ap_log_rerror(APLOG_MARK, APLOG_CRIT, r, + "%s pcfg_openfile: unable to check htaccess file, " + "ensure it is readable", + filename); + ap_table_setn(r->notes, "error-notes", + "Server unable to read htaccess file, denying " + "access to be safe"); + return HTTP_FORBIDDEN; + } } /* cache it */ diff --git a/usr.sbin/httpd/src/main/http_core.c b/usr.sbin/httpd/src/main/http_core.c index de5a7e04aab..320f907e6f1 100644 --- a/usr.sbin/httpd/src/main/http_core.c +++ b/usr.sbin/httpd/src/main/http_core.c @@ -2670,8 +2670,20 @@ static int core_translate(request_rec *r) (r->uri + r->server->pathlen), NULL); } else { - r->filename = ap_pstrcat(r->pool, conf->ap_document_root, r->uri, - NULL); + /* + * Make sure that we do not mess up the translation by adding two + * /'s in a row. This happens under windows when the document + * root ends with a / + */ + if ((conf->ap_document_root[strlen(conf->ap_document_root)-1] == '/') + && (*(r->uri) == '/')) { + r->filename = ap_pstrcat(r->pool, conf->ap_document_root, r->uri+1, + NULL); + } + else { + r->filename = ap_pstrcat(r->pool, conf->ap_document_root, r->uri, + NULL); + } } return OK; @@ -2743,7 +2755,6 @@ static int default_handler(request_rec *r) emsg = ap_pstrcat(r->pool, emsg, r->filename, r->path_info, NULL); } ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, r, emsg); - ap_table_setn(r->notes, "error-notes", emsg); return HTTP_NOT_FOUND; } if (r->method_number != M_GET) { diff --git a/usr.sbin/httpd/src/main/http_log.c b/usr.sbin/httpd/src/main/http_log.c index 094bbfc5746..3c380862563 100644 --- a/usr.sbin/httpd/src/main/http_log.c +++ b/usr.sbin/httpd/src/main/http_log.c @@ -154,7 +154,7 @@ static const TRANS priorities[] = { {NULL, -1}, }; -static int error_log_child (void *cmd, child_info *pinfo) +static int error_log_child(void *cmd, child_info *pinfo) { /* Child process code for 'ErrorLog "|..."'; * may want a common framework for this, since I expect it will @@ -165,23 +165,23 @@ static int error_log_child (void *cmd, child_info *pinfo) ap_cleanup_for_exec(); #ifdef SIGHUP /* No concept of a child process on Win32 */ - signal (SIGHUP, SIG_IGN); + signal(SIGHUP, SIG_IGN); #endif /* ndef SIGHUP */ #if defined(WIN32) - child_pid = spawnl (_P_NOWAIT, SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL); + child_pid = spawnl(_P_NOWAIT, SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL); return(child_pid); #elif defined(OS2) /* For OS/2 we need to use a '/' */ - execl (SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL); + execl(SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL); #else - execl (SHELL_PATH, SHELL_PATH, "-c", (char *)cmd, NULL); + execl(SHELL_PATH, SHELL_PATH, "-c", (char *)cmd, NULL); #endif - exit (1); + exit(1); /* NOT REACHED */ return(child_pid); } -static void open_error_log (server_rec *s, pool *p) +static void open_error_log(server_rec *s, pool *p) { char *fname; @@ -190,9 +190,9 @@ static void open_error_log (server_rec *s, pool *p) if (!ap_spawn_child(p, error_log_child, (void *)(s->error_fname+1), kill_after_timeout, &dummy, NULL, NULL)) { - perror ("ap_spawn_child"); - fprintf (stderr, "Couldn't fork child for ErrorLog process\n"); - exit (1); + perror("ap_spawn_child"); + fprintf(stderr, "Couldn't fork child for ErrorLog process\n"); + exit(1); } s->error_log = dummy; @@ -219,8 +219,8 @@ static void open_error_log (server_rec *s, pool *p) } #endif else { - fname = ap_server_root_relative (p, s->error_fname); - if(!(s->error_log = ap_pfopen(p, fname, "a"))) { + fname = ap_server_root_relative(p, s->error_fname); + if (!(s->error_log = ap_pfopen(p, fname, "a"))) { perror("fopen"); fprintf(stderr,"httpd: could not open error log file %s.\n", fname); exit(1); @@ -228,18 +228,18 @@ static void open_error_log (server_rec *s, pool *p) } } -void ap_open_logs (server_rec *s_main, pool *p) +void ap_open_logs(server_rec *s_main, pool *p) { server_rec *virt, *q; int replace_stderr; - open_error_log (s_main, p); + open_error_log(s_main, p); replace_stderr = 1; if (s_main->error_log) { /* replace stderr with this new log */ fflush(stderr); - if (dup2(fileno(s_main->error_log), 2) == -1) { + if (dup2(fileno(s_main->error_log), STDERR_FILENO) == -1) { ap_log_error(APLOG_MARK, APLOG_CRIT, s_main, "unable to replace stderr with error_log"); } else { @@ -262,20 +262,23 @@ void ap_open_logs (server_rec *s_main, pool *p) if (q->error_fname != NULL && strcmp(q->error_fname, virt->error_fname) == 0) break; - if (q == virt) open_error_log (virt, p); - else virt->error_log = q->error_log; + if (q == virt) + open_error_log(virt, p); + else + virt->error_log = q->error_log; } else virt->error_log = s_main->error_log; } } -API_EXPORT(void) ap_error_log2stderr (server_rec *s) { - if(fileno(s->error_log) != STDERR_FILENO) - dup2(fileno(s->error_log),STDERR_FILENO); +API_EXPORT(void) ap_error_log2stderr(server_rec *s) { + if ( s->error_log != NULL + && fileno(s->error_log) != STDERR_FILENO) + dup2(fileno(s->error_log), STDERR_FILENO); } -static void log_error_core (const char *file, int line, int level, +static void log_error_core(const char *file, int line, int level, const server_rec *s, const request_rec *r, const char *fmt, va_list args) { @@ -423,7 +426,7 @@ static void log_error_core (const char *file, int line, int level, #endif } -API_EXPORT(void) ap_log_error (const char *file, int line, int level, +API_EXPORT(void) ap_log_error(const char *file, int line, int level, const server_rec *s, const char *fmt, ...) { va_list args; @@ -440,27 +443,35 @@ API_EXPORT(void) ap_log_rerror(const char *file, int line, int level, va_start(args, fmt); log_error_core(file, line, level, r->server, r, fmt, args); - if (ap_table_get(r->notes, "error-notes") == NULL) { - char errstr[MAX_STRING_LEN]; - - ap_vsnprintf(errstr, sizeof(errstr), fmt, args); - ap_table_set(r->notes, "error-notes", errstr); + /* + * IF the error level is 'warning' or more severe, + * AND there isn't already error text associated with this request, + * THEN make the message text available to ErrorDocument and + * other error processors. This can be disabled by stuffing + * something, even an empty string, into the "error-notes" cell + * before calling this routine. + */ + if (((level & APLOG_LEVELMASK) <= APLOG_WARNING) + && (ap_table_get(r->notes, "error-notes") == NULL)) { + ap_table_setn(r->notes, "error-notes", + ap_pvsprintf(r->pool, fmt, args)); } va_end(args); } -void ap_log_pid (pool *p, char *fname) +void ap_log_pid(pool *p, char *fname) { FILE *pid_file; struct stat finfo; static pid_t saved_pid = -1; pid_t mypid; - if (!fname) return; + if (!fname) + return; - fname = ap_server_root_relative (p, fname); + fname = ap_server_root_relative(p, fname); mypid = getpid(); - if (mypid != saved_pid && stat(fname,&finfo) == 0) { + if (mypid != saved_pid && stat(fname, &finfo) == 0) { /* USR1 and HUP call this on each restart. * Only warn on first time through for this pid. * @@ -475,28 +486,28 @@ void ap_log_pid (pool *p, char *fname) ); } - if(!(pid_file = fopen(fname,"w"))) { + if(!(pid_file = fopen(fname, "w"))) { perror("fopen"); - fprintf(stderr,"httpd: could not log pid to file %s\n", fname); + fprintf(stderr, "httpd: could not log pid to file %s\n", fname); exit(1); } - fprintf(pid_file,"%ld\n",(long)mypid); + fprintf(pid_file, "%ld\n", (long)mypid); fclose(pid_file); saved_pid = mypid; } -API_EXPORT(void) ap_log_error_old (const char *err, server_rec *s) +API_EXPORT(void) ap_log_error_old(const char *err, server_rec *s) { ap_log_error(APLOG_MARK, APLOG_ERR, s, "%s", err); } -API_EXPORT(void) ap_log_unixerr (const char *routine, const char *file, +API_EXPORT(void) ap_log_unixerr(const char *routine, const char *file, const char *msg, server_rec *s) { ap_log_error(file, 0, APLOG_ERR, s, "%s", msg); } -API_EXPORT(void) ap_log_printf (const server_rec *s, const char *fmt, ...) +API_EXPORT(void) ap_log_printf(const server_rec *s, const char *fmt, ...) { va_list args; @@ -505,7 +516,7 @@ API_EXPORT(void) ap_log_printf (const server_rec *s, const char *fmt, ...) va_end(args); } -API_EXPORT(void) ap_log_reason (const char *reason, const char *file, request_rec *r) +API_EXPORT(void) ap_log_reason(const char *reason, const char *file, request_rec *r) { ap_log_error(APLOG_MARK, APLOG_ERR, r->server, "access to %s failed for %s, reason: %s", @@ -514,7 +525,7 @@ API_EXPORT(void) ap_log_reason (const char *reason, const char *file, request_re reason); } -API_EXPORT(void) ap_log_assert (const char *szExp, const char *szFile, int nLine) +API_EXPORT(void) ap_log_assert(const char *szExp, const char *szFile, int nLine) { fprintf(stderr, "[%s] file %s, line %d, assertion \"%s\" failed\n", ap_get_time(), szFile, nLine, szExp); @@ -530,9 +541,9 @@ API_EXPORT(void) ap_log_assert (const char *szExp, const char *szFile, int nLine #ifndef NO_RELIABLE_PIPED_LOGS /* forward declaration */ -static void piped_log_maintenance (int reason, void *data, ap_wait_t status); +static void piped_log_maintenance(int reason, void *data, ap_wait_t status); -static int piped_log_spawn (piped_log *pl) +static int piped_log_spawn(piped_log *pl) { int pid; @@ -545,32 +556,32 @@ static int piped_log_spawn (piped_log *pl) * XXX: close all the relevant stuff, but hey, it could be broken. */ RAISE_SIGSTOP(PIPED_LOG_SPAWN); /* we're now in the child */ - close (STDIN_FILENO); - dup2 (pl->fds[0], STDIN_FILENO); - - ap_cleanup_for_exec (); - signal (SIGCHLD, SIG_DFL); /* for HPUX */ - signal (SIGHUP, SIG_IGN); - execl (SHELL_PATH, SHELL_PATH, "-c", pl->program, NULL); - fprintf (stderr, + close(STDIN_FILENO); + dup2(pl->fds[0], STDIN_FILENO); + + ap_cleanup_for_exec(); + signal(SIGCHLD, SIG_DFL); /* for HPUX */ + signal(SIGHUP, SIG_IGN); + execl(SHELL_PATH, SHELL_PATH, "-c", pl->program, NULL); + fprintf(stderr, "piped_log_spawn: unable to exec %s -c '%s': %s\n", SHELL_PATH, pl->program, strerror (errno)); - exit (1); + exit(1); } if (pid == -1) { - fprintf (stderr, + fprintf(stderr, "piped_log_spawn: unable to fork(): %s\n", strerror (errno)); - ap_unblock_alarms (); + ap_unblock_alarms(); return -1; } ap_unblock_alarms(); pl->pid = pid; - ap_register_other_child (pid, piped_log_maintenance, pl, pl->fds[1]); + ap_register_other_child(pid, piped_log_maintenance, pl, pl->fds[1]); return 0; } -static void piped_log_maintenance (int reason, void *data, ap_wait_t status) +static void piped_log_maintenance(int reason, void *data, ap_wait_t status) { piped_log *pl = data; @@ -578,30 +589,30 @@ static void piped_log_maintenance (int reason, void *data, ap_wait_t status) case OC_REASON_DEATH: case OC_REASON_LOST: pl->pid = -1; - ap_unregister_other_child (pl); + ap_unregister_other_child(pl); if (pl->program == NULL) { /* during a restart */ break; } - if (piped_log_spawn (pl) == -1) { + if (piped_log_spawn(pl) == -1) { /* what can we do? This could be the error log we're having * problems opening up... */ - fprintf (stderr, + fprintf(stderr, "piped_log_maintenance: unable to respawn '%s': %s\n", - pl->program, strerror (errno)); + pl->program, strerror(errno)); } break; case OC_REASON_UNWRITABLE: if (pl->pid != -1) { - kill (pl->pid, SIGTERM); + kill(pl->pid, SIGTERM); } break; case OC_REASON_RESTART: pl->program = NULL; if (pl->pid != -1) { - kill (pl->pid, SIGTERM); + kill(pl->pid, SIGTERM); } break; @@ -611,67 +622,67 @@ static void piped_log_maintenance (int reason, void *data, ap_wait_t status) } -static void piped_log_cleanup (void *data) +static void piped_log_cleanup(void *data) { piped_log *pl = data; if (pl->pid != -1) { - kill (pl->pid, SIGTERM); + kill(pl->pid, SIGTERM); } - ap_unregister_other_child (pl); - close (pl->fds[0]); - close (pl->fds[1]); + ap_unregister_other_child(pl); + close(pl->fds[0]); + close(pl->fds[1]); } -static void piped_log_cleanup_for_exec (void *data) +static void piped_log_cleanup_for_exec(void *data) { piped_log *pl = data; - close (pl->fds[0]); - close (pl->fds[1]); + close(pl->fds[0]); + close(pl->fds[1]); } -API_EXPORT(piped_log *) ap_open_piped_log (pool *p, const char *program) +API_EXPORT(piped_log *) ap_open_piped_log(pool *p, const char *program) { piped_log *pl; - pl = ap_palloc (p, sizeof (*pl)); + pl = ap_palloc(p, sizeof (*pl)); pl->p = p; - pl->program = ap_pstrdup (p, program); + pl->program = ap_pstrdup(p, program); pl->pid = -1; ap_block_alarms (); - if (pipe (pl->fds) == -1) { + if (pipe(pl->fds) == -1) { int save_errno = errno; ap_unblock_alarms(); errno = save_errno; return NULL; } - ap_register_cleanup (p, pl, piped_log_cleanup, piped_log_cleanup_for_exec); - if (piped_log_spawn (pl) == -1) { + ap_register_cleanup(p, pl, piped_log_cleanup, piped_log_cleanup_for_exec); + if (piped_log_spawn(pl) == -1) { int save_errno = errno; - ap_kill_cleanup (p, pl, piped_log_cleanup); - close (pl->fds[0]); - close (pl->fds[1]); - ap_unblock_alarms (); + ap_kill_cleanup(p, pl, piped_log_cleanup); + close(pl->fds[0]); + close(pl->fds[1]); + ap_unblock_alarms(); errno = save_errno; return NULL; } - ap_unblock_alarms (); + ap_unblock_alarms(); return pl; } -API_EXPORT(void) ap_close_piped_log (piped_log *pl) +API_EXPORT(void) ap_close_piped_log(piped_log *pl) { - ap_block_alarms (); - piped_log_cleanup (pl); - ap_kill_cleanup (pl->p, pl, piped_log_cleanup); - ap_unblock_alarms (); + ap_block_alarms(); + piped_log_cleanup(pl); + ap_kill_cleanup(pl->p, pl, piped_log_cleanup); + ap_unblock_alarms(); } #else -static int piped_log_child (void *cmd, child_info *pinfo) +static int piped_log_child(void *cmd, child_info *pinfo) { /* Child process code for 'TransferLog "|..."'; * may want a common framework for this, since I expect it will @@ -681,10 +692,10 @@ static int piped_log_child (void *cmd, child_info *pinfo) ap_cleanup_for_exec(); #ifdef SIGHUP - signal (SIGHUP, SIG_IGN); + signal(SIGHUP, SIG_IGN); #endif #if defined(WIN32) - child_pid = spawnl (_P_NOWAIT, SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL); + child_pid = spawnl(_P_NOWAIT, SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL); return(child_pid); #elif defined(OS2) /* For OS/2 we need to use a '/' */ @@ -692,24 +703,24 @@ static int piped_log_child (void *cmd, child_info *pinfo) #else execl (SHELL_PATH, SHELL_PATH, "-c", (char *)cmd, NULL); #endif - perror ("exec"); - fprintf (stderr, "Exec of shell for logging failed!!!\n"); + perror("exec"); + fprintf(stderr, "Exec of shell for logging failed!!!\n"); return(child_pid); } -API_EXPORT(piped_log *) ap_open_piped_log (pool *p, const char *program) +API_EXPORT(piped_log *) ap_open_piped_log(pool *p, const char *program) { piped_log *pl; FILE *dummy; if (!ap_spawn_child(p, piped_log_child, (void *)program, kill_after_timeout, &dummy, NULL, NULL)) { - perror ("ap_spawn_child"); - fprintf (stderr, "Couldn't fork child for piped log process\n"); + perror("ap_spawn_child"); + fprintf(stderr, "Couldn't fork child for piped log process\n"); exit (1); } - pl = ap_palloc (p, sizeof (*pl)); + pl = ap_palloc(p, sizeof (*pl)); pl->p = p; pl->write_f = dummy; @@ -717,8 +728,8 @@ API_EXPORT(piped_log *) ap_open_piped_log (pool *p, const char *program) } -API_EXPORT(void) ap_close_piped_log (piped_log *pl) +API_EXPORT(void) ap_close_piped_log(piped_log *pl) { - ap_pfclose (pl->p, pl->write_f); + ap_pfclose(pl->p, pl->write_f); } #endif diff --git a/usr.sbin/httpd/src/main/http_main.c b/usr.sbin/httpd/src/main/http_main.c index 2b6833f1542..defbca0b5bf 100644 --- a/usr.sbin/httpd/src/main/http_main.c +++ b/usr.sbin/httpd/src/main/http_main.c @@ -999,6 +999,10 @@ static void usage(char *bin) fprintf(stderr, " -l : list compiled-in modules\n"); fprintf(stderr, " -S : show parsed settings (currently only vhost settings)\n"); fprintf(stderr, " -t : run syntax test for configuration files only\n"); +#ifdef WIN32 + fprintf(stderr, " -k shutdown : tell running Apache to shutdown\n"); + fprintf(stderr, " -k restart : tell running Apache to do a graceful restart\n"); +#endif exit(1); } @@ -2542,17 +2546,41 @@ static int volatile generation; #ifdef WIN32 /* - * signal_parent() tells the parent process to wake up and do something. - * Once woken it will look at shutdown_pending and restart_pending to decide - * what to do. If neither variable is set, it will do a shutdown. This function - * if called by start_shutdown() or start_restart() in the parent's process - * space, so that the variables get set. However it can also be called - * by child processes to force the parent to exit in an emergency. + * Signalling Apache on NT. + * + * Under Unix, Apache can be told to shutdown or restart by sending various + * signals (HUP, USR, TERM). On NT we don't have easy access to signals, so + * we use "events" instead. The parent apache process goes into a loop + * where it waits forever for a set of events. Two of those events are + * called + * + * apPID_shutdown + * apPID_restart + * + * (where PID is the PID of the apache parent process). When one of these + * is signalled, the Apache parent performs the appropriate action. The events + * can become signalled through internal Apache methods (e.g. if the child + * finds a fatal error and needs to kill its parent), via the service + * control manager (the control thread will signal the shutdown event when + * requested to stop the Apache service), from the -k Apache command line, + * or from any external program which finds the Apache PID from the + * httpd.pid file. + * + * The signal_parent() function, below, is used to signal one of these events. + * It can be called by any child or parent process, since it does not + * rely on global variables. + * + * On entry, type gives the event to signal. 0 means shutdown, 1 means + * graceful restart. */ -static void signal_parent(void) +static void signal_parent(int type) { HANDLE e; + char *signal_name; + extern char signal_shutdown_name[]; + extern char signal_restart_name[]; + /* after updating the shutdown_pending or restart flags, we need * to wake up the parent process so it can see the changes. The * parent will normally be waiting for either a child process @@ -2564,21 +2592,28 @@ static void signal_parent(void) return; } - APD1("*** SIGNAL_PARENT SET ***"); + switch(type) { + case 0: signal_name = signal_shutdown_name; break; + case 1: signal_name = signal_restart_name; break; + default: return; + } - e = OpenEvent(EVENT_ALL_ACCESS, FALSE, "apache-signal"); + APD2("signal_parent signalling event \"%s\"", signal_name); + + e = OpenEvent(EVENT_ALL_ACCESS, FALSE, signal_name); if (!e) { - /* Um, problem, can't signal the main loop, which means we can't + /* Um, problem, can't signal the parent, which means we can't * signal ourselves to die. Ignore for now... */ ap_log_error(APLOG_MARK, APLOG_EMERG|APLOG_WIN32ERROR, server_conf, - "OpenEvent on apache-signal event"); + "OpenEvent on %s event", signal_name); return; } if (SetEvent(e) == 0) { /* Same problem as above */ ap_log_error(APLOG_MARK, APLOG_EMERG|APLOG_WIN32ERROR, server_conf, - "SetEvent on apache-signal event"); + "SetEvent on %s event", signal_name); + CloseHandle(e); return; } CloseHandle(e); @@ -2586,24 +2621,19 @@ static void signal_parent(void) #endif /* - * start_shutdown() and start_restart(), below, are a first stab at + * ap_start_shutdown() and ap_start_restart(), below, are a first stab at * functions to initiate shutdown or restart without relying on signals. * Previously this was initiated in sig_term() and restart() signal handlers, * but we want to be able to start a shutdown/restart from other sources -- * e.g. on Win32, from the service manager. Now the service manager can - * call start_shutdown() or start_restart() as appropiate. - * - * These should only be called from the parent process itself, since the - * parent process will use the shutdown_pending and restart_pending variables - * to determine whether to shutdown or restart. The child process should - * call signal_parent() directly to tell the parent to die -- this will - * cause neither of those variable to be set, which the parent will - * assume means something serious is wrong (which it will be, for the - * child to force an exit) and so do an exit anyway. + * call ap_start_shutdown() or ap_start_restart() as appropiate. Note that + * these functions can also be called by the child processes, since global + * variables are no longer used to pass on the required action to the parent. */ void ap_start_shutdown(void) { +#ifndef WIN32 if (shutdown_pending == 1) { /* Um, is this _probably_ not an error, if the user has * tried to do a shutdown twice quickly, so we won't @@ -2612,24 +2642,23 @@ void ap_start_shutdown(void) return; } shutdown_pending = 1; - -#ifdef WIN32 - signal_parent(); /* get the parent process to wake up */ +#else + signal_parent(0); /* get the parent process to wake up */ #endif } /* do a graceful restart if graceful == 1 */ void ap_start_restart(int graceful) { +#ifndef WIN32 if (restart_pending == 1) { /* Probably not an error - don't bother reporting it */ return; } restart_pending = 1; is_graceful = graceful; - -#ifdef WIN32 - signal_parent(); /* get the parent process to wake up */ +#else + signal_parent(1); /* get the parent process to wake up */ #endif /* WIN32 */ } @@ -4633,11 +4662,13 @@ int REALMAIN(int argc, char *argv[]) * * Signalling between the parent and working process uses a Win32 * event. Each child has a unique name for the event, which is - * passed to it with the -c argument when the child is spawned. The + * passed to it with the -Z argument when the child is spawned. The * parent sets (signals) this event to tell the child to die. * At present all children do a graceful die - they finish all * current jobs _and_ empty the listen queue before they exit. - * A non-graceful die would need a second event. + * A non-graceful die would need a second event. The -Z argument in + * the child is also used to create the shutdown and restart events, + * since the prefix (apPID) contains the parent process PID. * * The code below starts with functions at the lowest level - * worker threads, and works up to the top level - the main() @@ -5001,17 +5032,37 @@ extern void main_control_server(void *); /* in hellop.c */ event *exit_event; mutex *start_mutex; +#define MAX_SIGNAL_NAME 30 /* Long enough for apPID_shutdown, where PID is an int */ +char signal_name_prefix[MAX_SIGNAL_NAME]; +char signal_restart_name[MAX_SIGNAL_NAME]; +char signal_shutdown_name[MAX_SIGNAL_NAME]; + #define MAX_SELECT_ERRORS 100 +/* + * Initialise the signal names, in the global variables signal_name_prefix, + * signal_restart_name and signal_shutdown_name. + */ + +void setup_signal_names(char *prefix) +{ + ap_snprintf(signal_name_prefix, sizeof(signal_name_prefix), prefix); + ap_snprintf(signal_shutdown_name, sizeof(signal_shutdown_name), + "%s_shutdown", signal_name_prefix); + ap_snprintf(signal_restart_name, sizeof(signal_restart_name), + "%s_restart", signal_name_prefix); + + APD2("signal prefix %s", signal_name_prefix); +} + +/* + * worker_main() is main loop for the child process. The loop in + * this function becomes the controlling thread for the actually working + * threads (which run in a loop in child_sub_main()). + */ + void worker_main(void) { - /* - * I am writing this stuff specifically for NT. - * have pulled out a lot of the restart and - * graceful restart stuff, because that is only - * useful on Unix (not sure it even makes sense - * in a multi-threaded env. - */ int nthreads; fd_set main_fds; int srv; @@ -5059,7 +5110,13 @@ void worker_main(void) reinit_scoreboard(pconf); - //ap_acquire_mutex(start_mutex); + /* + * Wait until we have permission to start accepting connections. + * start_mutex is used to ensure that only one child ever + * goes into the listen/accept loop at once. Also wait on exit_event, + * in case we (this child) is told to die before we get a chance to + * serve any requests. + */ hObjects[0] = (HANDLE)start_mutex; hObjects[1] = (HANDLE)exit_event; rv = WaitForMultipleObjects(2, hObjects, FALSE, INFINITE); @@ -5085,7 +5142,7 @@ void worker_main(void) ap_log_error(APLOG_MARK, APLOG_CRIT|APLOG_NOERRNO, NULL, "No sockets were created for listening"); - signal_parent(); /* tell parent to die */ + signal_parent(0); /* tell parent to die */ ap_destroy_pool(pchild); cleanup_scoreboard(); @@ -5114,15 +5171,11 @@ void worker_main(void) /* spawn off the threads */ child_handles = (thread *) alloca(nthreads * sizeof(int)); - { - int i; - - for (i = 0; i < nthreads; i++) { - child_handles[i] = create_thread((void (*)(void *)) child_main, (void *) i); - } - if (nthreads > max_daemons_limit) { - max_daemons_limit = nthreads; - } + for (i = 0; i < nthreads; i++) { + child_handles[i] = create_thread((void (*)(void *)) child_main, (void *) i); + } + if (nthreads > max_daemons_limit) { + max_daemons_limit = nthreads; } while (1) { @@ -5288,22 +5341,21 @@ void worker_main(void) clean_parent_exit(0); } /* standalone_main */ -/* Spawn a child Apache process. The child process has the command - * line arguments from argc and argv[], plus a -Z argument giving the - * name of an event. The child should open and poll or wait on this - * event. When it is signalled, the child should die. prefix is a - * prefix string for the event name. +/* + * Spawn a child Apache process. The child process has the command line arguments from + * argc and argv[], plus a -Z argument giving the name of an event. The child should + * open and poll or wait on this event. When it is signalled, the child should die. + * prefix is a prefix string for the event name. * - * The child_num argument on entry contains a serial number for this - * child (used to create a unique event name). On exit, this number - * will have been incremented by one, ready for the next call. + * The child_num argument on entry contains a serial number for this child (used to create + * a unique event name). On exit, this number will have been incremented by one, ready + * for the next call. * * On exit, the value pointed to be *ev will contain the event created * to signal the new child process. * - * The return value is the handle to the child process if successful, - * else -1. If -1 is returned the error will already have been logged - * by ap_log_error(). + * The return value is the handle to the child process if successful, else -1. If -1 is + * returned the error will already have been logged by ap_log_error(). */ int create_event_and_spawn(int argc, char **argv, event **ev, int *child_num, char *prefix) @@ -5311,8 +5363,15 @@ int create_event_and_spawn(int argc, char **argv, event **ev, int *child_num, ch char buf[40], mod[200]; int i, rv; char **pass_argv = (char **) alloca(sizeof(char *) * (argc + 3)); - - ap_snprintf(buf, sizeof(buf), "%s_%d", prefix, ++(*child_num)); + + /* We need an event to tell the child process to kill itself when + * the parent is doing a shutdown/restart. This will be named + * apPID_CN where PID is the parent Apache process PID and + * N is a unique child serial number. prefix contains + * the "apPID" part. The child will get the name of this + * event as its -Z command line argument. + */ + ap_snprintf(buf, sizeof(buf), "%s_C%d", prefix, ++(*child_num)); _flushall(); *ev = CreateEvent(NULL, TRUE, FALSE, buf); if (!*ev) { @@ -5409,10 +5468,11 @@ int master_main(int argc, char **argv) int *child; int child_num = 0; int rv, cld; - char buf[100]; + char signal_prefix_string[100]; int i; time_t tmstart; - HANDLE signal_event; /* used to signal shutdown/restart to parent */ + HANDLE signal_shutdown_event; /* used to signal shutdown to parent */ + HANDLE signal_restart_event; /* used to signal a restart to parent */ HANDLE process_handles[MAX_PROCESSES]; HANDLE process_kill_events[MAX_PROCESSES]; int current_live_processes = 0; /* number of child process we know about */ @@ -5425,22 +5485,34 @@ int master_main(int argc, char **argv) is_graceful = 0; ++generation; - signal_event = OpenEvent(EVENT_ALL_ACCESS, FALSE, "apache-signal"); - if (!signal_event) { + ap_snprintf(signal_prefix_string, sizeof(signal_prefix_string), + "ap%d", getpid()); + setup_signal_names(signal_prefix_string); + + signal_shutdown_event = CreateEvent(NULL, TRUE, FALSE, signal_shutdown_name); + if (!signal_shutdown_event) { + ap_log_error(APLOG_MARK, APLOG_EMERG|APLOG_WIN32ERROR, server_conf, + "Cannot create shutdown event %s", signal_shutdown_name); + exit(1); + } + APD2("master_main: created event %s", signal_shutdown_name); + signal_restart_event = CreateEvent(NULL, TRUE, FALSE, signal_restart_name); + if (!signal_restart_event) { + CloseHandle(signal_shutdown_event); ap_log_error(APLOG_MARK, APLOG_EMERG|APLOG_WIN32ERROR, server_conf, - "Cannot open apache-signal event"); + "Cannot create restart event %s", signal_restart_name); exit(1); } + APD2("master_main: created event %s", signal_restart_name); - sprintf(buf, "Apache%d", getpid()); - start_mutex = ap_create_mutex(buf); + start_mutex = ap_create_mutex(signal_prefix_string); ev = (event **) alloca(sizeof(event *) * nchild); child = (int *) alloca(sizeof(int) * (nchild+1)); while (processes_to_create--) { service_set_status(SERVICE_START_PENDING); if (create_process(process_handles, process_kill_events, - ¤t_live_processes, &child_num, buf, argc, argv) < 0) { + ¤t_live_processes, &child_num, signal_prefix_string, argc, argv) < 0) { goto die_now; } } @@ -5461,8 +5533,6 @@ int master_main(int argc, char **argv) ap_set_version(); ap_init_modules(pconf, server_conf); version_locked++; - if (!is_graceful) - reinit_scoreboard(pconf); restart_pending = shutdown_pending = 0; @@ -5478,15 +5548,17 @@ int master_main(int argc, char **argv) ap_log_error(APLOG_MARK,APLOG_ERR|APLOG_NOERRNO, server_conf, "master_main: no child processes alive! creating one"); if (create_process(process_handles, process_kill_events, - ¤t_live_processes, &child_num, buf, argc, argv) < 0) { + ¤t_live_processes, &child_num, signal_prefix_string, + argc, argv) < 0) { goto die_now; } if (processes_to_create) { processes_to_create--; } } - process_handles[current_live_processes] = signal_event; - rv = WaitForMultipleObjects(current_live_processes+1, (HANDLE *)process_handles, + process_handles[current_live_processes] = signal_shutdown_event; + process_handles[current_live_processes+1] = signal_restart_event; + rv = WaitForMultipleObjects(current_live_processes+2, (HANDLE *)process_handles, FALSE, INFINITE); if (rv == WAIT_FAILED) { /* Something serious is wrong */ @@ -5495,13 +5567,35 @@ int master_main(int argc, char **argv) shutdown_pending = 1; break; } - ap_assert(rv != WAIT_TIMEOUT); + if (rv == WAIT_TIMEOUT) { + /* Hey, this cannot happen */ + ap_log_error(APLOG_MARK, APLOG_ERR, server_conf, + "WaitForMultipeObjects with INFINITE wait exited with WAIT_TIMEOUT"); + shutdown_pending = 1; + } + cld = rv - WAIT_OBJECT_0; APD4("main process: wait finished, cld=%d handle %d (max=%d)", cld, process_handles[cld], current_live_processes); if (cld == current_live_processes) { - /* stop_event is signalled, we should exit now */ - if (ResetEvent(signal_event) == 0) - APD1("main process: *** ERROR: ResetEvent(stop_event) failed ***"); + /* shutdown event signalled, we should exit now */ + if (ResetEvent(signal_shutdown_event) == 0) { + ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, server_conf, + "ResetEvent(signal_shutdown_event)"); + /* Continue -- since we are doing a shutdown anyway */ + } + shutdown_pending = 1; + APD3("main process: stop_event signalled: shutdown_pending=%d, restart_pending=%d", + shutdown_pending, restart_pending); + break; + } + if (cld == current_live_processes+1) { + /* restart event signalled, we should exit now */ + if (ResetEvent(signal_restart_event) == 0) { + ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, server_conf, + "ResetEvent(signal_restart_event)"); + /* Continue -- hopefully the restart will fix the problem */ + } + restart_pending = 1; APD3("main process: stop_event signalled: shutdown_pending=%d, restart_pending=%d", shutdown_pending, restart_pending); break; @@ -5510,7 +5604,8 @@ int master_main(int argc, char **argv) cleanup_process(process_handles, process_kill_events, cld, ¤t_live_processes); APD2("main_process: child in slot %d died", rv); if (processes_to_create) { - create_process(process_handles, process_kill_events, ¤t_live_processes, &child_num, buf, argc, argv); + create_process(process_handles, process_kill_events, ¤t_live_processes, + &child_num, signal_prefix_string, argc, argv); processes_to_create--; } } @@ -5527,7 +5622,6 @@ int master_main(int argc, char **argv) ap_log_error(APLOG_MARK,APLOG_WIN32ERROR, server_conf, "SetEvent for child process in slot #%d", i); } - break; } if (restart_pending) { @@ -5539,7 +5633,8 @@ int master_main(int argc, char **argv) for (i = 0; i < nchild; ++i) { if (current_live_processes >= MAX_PROCESSES) break; - create_process(process_handles, process_kill_events, ¤t_live_processes, &child_num, buf, argc, argv); + create_process(process_handles, process_kill_events, ¤t_live_processes, + &child_num, signal_prefix_string, argc, argv); processes_to_create--; } for (i = 0; i < children_to_kill; i++) { @@ -5559,7 +5654,8 @@ int master_main(int argc, char **argv) APD2("*** main process shutdown, processes=%d ***", current_live_processes); die_now: - CloseHandle(signal_event); + CloseHandle(signal_restart_event); + CloseHandle(signal_shutdown_event); tmstart = time(NULL); while (current_live_processes && ((tmstart+60) > time(NULL))) { @@ -5579,7 +5675,6 @@ die_now: "forcing termination of child #%d (handle %d)", i, process_handles[i]); TerminateProcess((HANDLE) process_handles[i], 1); } - service_set_status(SERVICE_STOPPED); /* cleanup pid file on normal shutdown */ { @@ -5597,9 +5692,61 @@ die_now: } ap_destroy_mutex(start_mutex); + + service_set_status(SERVICE_STOPPED); return (0); } +/* + * Send signal to a running Apache. On entry signal should contain + * either "shutdown" or "restart" + */ + +void send_signal(pool *p, char *signal) +{ + char prefix[20]; + FILE *fp; + int nread; + char *fname; + int end; + + fname = ap_server_root_relative (p, ap_pid_fname); + + fp = fopen(fname, "r"); + if (!fp) { + printf("Cannot read apache PID file %s\n", fname); + return; + } + prefix[0] = 'a'; + prefix[1] = 'p'; + + nread = fread(prefix+2, 1, sizeof(prefix)-3, fp); + if (nread == 0) { + fclose(fp); + printf("PID file %s was empty\n", fname); + return; + } + fclose(fp); + + /* Terminate the prefix string */ + end = 2 + nread - 1; + while (end > 0 && (prefix[end] == '\r' || prefix[end] == '\n')) + end--; + prefix[end + 1] = '\0'; + + setup_signal_names(prefix); + + if (!strcasecmp(signal, "shutdown")) + ap_start_shutdown(); + else if (!strcasecmp(signal, "restart")) + ap_start_restart(1); + else + printf("Unknown signal name \"%s\". Use either shutdown or restart.\n", + signal); + + return; +} + #ifdef WIN32 __declspec(dllexport) int apache_main(int argc, char *argv[]) @@ -5613,6 +5760,7 @@ int REALMAIN(int argc, char *argv[]) int run_as_service = 1; int install = 0; int configtestonly = 0; + char *signal_to_send = NULL; common_init(); @@ -5637,7 +5785,7 @@ int REALMAIN(int argc, char *argv[]) ap_setup_prelinked_modules(); - while ((c = getopt(argc, argv, "D:C:c:Xd:f:vVhlZ:iusSt")) != -1) { + while ((c = getopt(argc, argv, "D:C:c:Xd:f:vVhlZ:iusStk:")) != -1) { char **new; switch (c) { case 'c': @@ -5659,7 +5807,9 @@ int REALMAIN(int argc, char *argv[]) cp = strchr(optarg, '_'); ap_assert(cp); *cp = 0; - start_mutex = ap_open_mutex(optarg); + setup_signal_names(optarg); + start_mutex = ap_open_mutex(signal_name_prefix); + ap_assert(start_mutex); child = 1; break; case 'i': @@ -5674,6 +5824,9 @@ int REALMAIN(int argc, char *argv[]) case 'S': ap_dump_settings = 1; break; + case 'k': + signal_to_send = optarg; + break; #endif /* WIN32 */ case 'd': ap_cpystrn(ap_server_root, ap_os_canonical_filename(pconf, optarg), sizeof(ap_server_root)); @@ -5718,7 +5871,12 @@ int REALMAIN(int argc, char *argv[]) exit(0); } - if (!child) { + if (signal_to_send) { + send_signal(pconf, signal_to_send); + exit(0); + } + + if (!child && !ap_dump_settings && !install) { ap_log_pid(pconf, ap_pid_fname); } ap_set_version(); diff --git a/usr.sbin/httpd/src/main/http_protocol.c b/usr.sbin/httpd/src/main/http_protocol.c index 98f58517ea8..e28df5c4636 100644 --- a/usr.sbin/httpd/src/main/http_protocol.c +++ b/usr.sbin/httpd/src/main/http_protocol.c @@ -551,6 +551,17 @@ static int getline(char *s, int n, BUFF *in, int fold) total += retval; /* and how long s has become */ if (*pos == '\n') { /* Did we get a full line of input? */ + /* + * Trim any extra trailing spaces or tabs except for the first + * space or tab at the beginning of a blank string. This makes + * it much easier to check field values for exact matches, and + * saves memory as well. Terminate string at end of line. + */ + while (pos > (s + 1) && (*(pos - 1) == ' ' || *(pos - 1) == '\t')) { + --pos; /* trim extra trailing spaces or tabs */ + --total; /* but not one at the beginning of line */ + ++n; + } *pos = '\0'; --total; ++n; @@ -767,8 +778,6 @@ static void get_mime_headers(request_rec *r) while (*value == ' ' || *value == '\t') ++value; /* Skip to start of value */ - /* XXX: should strip trailing whitespace as well */ - ap_table_addn(tmp_headers, copy, value); } @@ -778,8 +787,9 @@ static void get_mime_headers(request_rec *r) request_rec *ap_read_request(conn_rec *conn) { request_rec *r; - int access_status; pool *p; + const char *expect; + int access_status; p = ap_make_sub_pool(conn->pool); r = ap_pcalloc(p, sizeof(request_rec)); @@ -846,6 +856,23 @@ request_rec *ap_read_request(conn_rec *conn) } else { ap_kill_timeout(r); + + if (r->header_only) { + /* + * Client asked for headers only with HTTP/0.9, which doesn't send + * headers! Have to dink things just to make sure the error message + * comes through... + */ + ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r, + "client sent invalid HTTP/0.9 request: HEAD %s", + r->uri); + r->header_only = 0; + r->status = HTTP_BAD_REQUEST; + ap_send_error_response(r, 0); + ap_bflush(r->connection->client); + ap_log_transaction(r); + return r; + } } r->status = HTTP_OK; /* Until further notice. */ @@ -860,6 +887,49 @@ request_rec *ap_read_request(conn_rec *conn) conn->keptalive = 0; /* We now have a request to play with */ + if ((!r->hostname && (r->proto_num >= HTTP_VERSION(1,1))) || + ((r->proto_num == HTTP_VERSION(1,1)) && + !ap_table_get(r->headers_in, "Host"))) { + /* + * Client sent us an 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. + */ + r->status = HTTP_BAD_REQUEST; + ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r, + "client sent HTTP/1.1 request without hostname " + "(see RFC2068 section 9, and 14.23): %s", r->uri); + ap_send_error_response(r, 0); + ap_bflush(r->connection->client); + ap_log_transaction(r); + return r; + } + if (((expect = ap_table_get(r->headers_in, "Expect")) != NULL) && + (expect[0] != '\0')) { + /* + * The Expect header field was added to HTTP/1.1 after RFC 2068 + * as a means to signal when a 100 response is desired and, + * unfortunately, to signal a poor man's mandatory extension that + * the server must understand or return 417 Expectation Failed. + */ + if (strcasecmp(expect, "100-continue") == 0) { + r->expecting_100 = 1; + } + else { + r->status = HTTP_EXPECTATION_FAILED; + ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, r, + "client sent an unrecognized expectation value of " + "Expect: %s", expect); + ap_send_error_response(r, 0); + ap_bflush(r->connection->client); + (void) ap_discard_request_body(r); + ap_log_transaction(r); + return r; + } + } + if ((access_status = ap_run_post_read_request(r))) { ap_die(access_status, r); ap_log_transaction(r); @@ -895,6 +965,7 @@ void ap_set_sub_req_protocol(request_rec *rnew, const request_rec *r) rnew->err_headers_out = ap_make_table(rnew->pool, 5); rnew->notes = ap_make_table(rnew->pool, 5); + rnew->expecting_100 = r->expecting_100; rnew->read_length = r->read_length; rnew->read_body = REQUEST_NO_BODY; @@ -988,7 +1059,8 @@ API_EXPORT(int) ap_get_basic_auth_pw(request_rec *r, const char **pw) static char *status_lines[] = { "100 Continue", "101 Switching Protocols", -#define LEVEL_200 2 + "102 Processing", +#define LEVEL_200 3 "200 OK", "201 Created", "202 Accepted", @@ -996,14 +1068,17 @@ static char *status_lines[] = { "204 No Content", "205 Reset Content", "206 Partial Content", -#define LEVEL_300 9 + "207 Multi-Status", +#define LEVEL_300 11 "300 Multiple Choices", "301 Moved Permanently", - "302 Moved Temporarily", + "302 Found", "303 See Other", "304 Not Modified", "305 Use Proxy", -#define LEVEL_400 15 + "306 unused", + "307 Temporary Redirect", +#define LEVEL_400 19 "400 Bad Request", "401 Authorization Required", "402 Payment Required", @@ -1020,14 +1095,26 @@ static char *status_lines[] = { "413 Request Entity Too Large", "414 Request-URI Too Large", "415 Unsupported Media Type", -#define LEVEL_500 31 + "416 Requested Range Not Satisfiable", + "417 Expectation Failed", + "418 unused", + "419 unused", + "420 unused", + "421 unused", + "422 Unprocessable Entity", + "423 Locked", +#define LEVEL_500 43 "500 Internal Server Error", "501 Method Not Implemented", "502 Bad Gateway", "503 Service Temporarily Unavailable", "504 Gateway Time-out", "505 HTTP Version Not Supported", - "506 Variant Also Varies" + "506 Variant Also Negotiates" + "507 unused", + "508 unused", + "509 unused", + "510 Not Extended", }; /* The index is found by its offset from the x00 code of each level. @@ -1441,7 +1528,7 @@ API_EXPORT(int) ap_should_client_block(request_rec *r) if (r->read_length || (!r->read_chunked && (r->remaining <= 0))) return 0; - if (r->proto_num >= HTTP_VERSION(1,1)) { + if (r->expecting_100 && r->proto_num >= HTTP_VERSION(1,1)) { /* sending 100 Continue interim response */ ap_bvputs(r->connection->client, SERVER_PROTOCOL, " ", status_lines[0], "\015\012\015\012", @@ -1653,6 +1740,11 @@ API_EXPORT(int) ap_discard_request_body(request_rec *r) if ((rv = ap_setup_client_block(r, REQUEST_CHUNKED_PASS))) return rv; + /* If we are discarding the request body, then we must already know + * the final status code, therefore disable the sending of 100 continue. + */ + r->expecting_100 = 0; + if (ap_should_client_block(r)) { char dumpbuf[HUGE_STRING_LEN]; @@ -2127,132 +2219,177 @@ void ap_send_error_response(request_rec *r, int recursive_error) "</TITLE>\n</HEAD><BODY>\n<H1>", h1, "</H1>\n", NULL); - if ((error_notes = ap_table_get(r->notes, "error-notes"))) { - ap_bputs(error_notes, fd); - } - else - switch (status) { - case REDIRECT: - case MOVED: - ap_bvputs(fd, "The document has moved <A HREF=\"", - ap_escape_html(r->pool, location), "\">here</A>.<P>\n", NULL); - break; - case HTTP_SEE_OTHER: - ap_bvputs(fd, "The answer to your request is located <A HREF=\"", - ap_escape_html(r->pool, location), "\">here</A>.<P>\n", NULL); - break; - case HTTP_USE_PROXY: - ap_bvputs(fd, "This resource is only accessible through the proxy\n", - ap_escape_html(r->pool, location), "<BR>\nYou will need to ", - "configure your client to use that proxy.<P>\n", NULL); - break; - case HTTP_PROXY_AUTHENTICATION_REQUIRED: - case AUTH_REQUIRED: - ap_bputs("This server could not verify that you\n", fd); - ap_bputs("are authorized to access the document you\n", fd); - ap_bputs("requested. Either you supplied the wrong\n", fd); - ap_bputs("credentials (e.g., bad password), or your\n", fd); - ap_bputs("browser doesn't understand how to supply\n", fd); - ap_bputs("the credentials required.<P>\n", fd); - break; - case BAD_REQUEST: - ap_bputs("Your browser sent a request that\n", fd); - ap_bputs("this server could not understand.<P>\n", fd); - break; - case HTTP_FORBIDDEN: - ap_bvputs(fd, "You don't have permission to access ", - ap_escape_html(r->pool, r->uri), "\non this server.<P>\n", - NULL); - break; - case NOT_FOUND: - ap_bvputs(fd, "The requested URL ", ap_escape_html(r->pool, r->uri), - " was not found on this server.<P>\n", NULL); - break; - case METHOD_NOT_ALLOWED: - ap_bvputs(fd, "The requested method ", r->method, " is not allowed " - "for the URL ", ap_escape_html(r->pool, r->uri), - ".<P>\n", NULL); - break; - case NOT_ACCEPTABLE: - ap_bvputs(fd, - "An appropriate representation of the requested resource ", - ap_escape_html(r->pool, r->uri), - " could not be found on this server.<P>\n", NULL); - /* fall through */ - case MULTIPLE_CHOICES: - { - const char *list; - if ((list = ap_table_get(r->notes, "variant-list"))) - ap_bputs(list, fd); - } - break; - case LENGTH_REQUIRED: - ap_bvputs(fd, "A request of the requested method ", r->method, - " requires a valid Content-length.<P>\n", NULL); - break; - case PRECONDITION_FAILED: - ap_bvputs(fd, "The precondition on the request for the URL ", - ap_escape_html(r->pool, r->uri), " evaluated to false.<P>\n", - NULL); - break; - case NOT_IMPLEMENTED: - ap_bvputs(fd, ap_escape_html(r->pool, r->method), " to ", - ap_escape_html(r->pool, r->uri), " not supported.<P>\n", NULL); - break; - case BAD_GATEWAY: - ap_bputs("The proxy server received an invalid\015\012", fd); - ap_bputs("response from an upstream server.<P>\015\012", fd); - break; - case VARIANT_ALSO_VARIES: - ap_bvputs(fd, "A variant for the requested entity ", - ap_escape_html(r->pool, r->uri), " is itself a ", - "transparently negotiable resource.<P>\n", NULL); - break; - case HTTP_REQUEST_TIME_OUT: - ap_bputs("I'm tired of waiting for your request.\n", fd); - break; - case HTTP_GONE: - ap_bvputs(fd, "The requested resource<BR>", - ap_escape_html(r->pool, r->uri), - "<BR>\nis no longer available on this server ", - "and there is no forwarding address.\n", - "Please remove all references to this resource.\n", NULL); - break; - case HTTP_REQUEST_ENTITY_TOO_LARGE: - ap_bvputs(fd, "The requested resource<BR>", - ap_escape_html(r->pool, r->uri), "<BR>\n", - "does not allow request data with ", r->method, - " requests, or the amount of data provided in\n", - "the request exceeds the capacity limit.\n", NULL); - break; - case HTTP_REQUEST_URI_TOO_LARGE: - ap_bputs("The requested URL's length exceeds the capacity\n", fd); - ap_bputs("limit for this server.\n", fd); - break; - case HTTP_UNSUPPORTED_MEDIA_TYPE: - ap_bputs("The supplied request data is not in a format\n", fd); - ap_bputs("acceptable for processing by this resource.\n", fd); - break; - case HTTP_SERVICE_UNAVAILABLE: - ap_bputs("The server is temporarily unable to service your\n", fd); - ap_bputs("request due to maintenance downtime or capacity\n", fd); - ap_bputs("problems. Please try again later.\n", fd); - break; - case HTTP_GATEWAY_TIME_OUT: - ap_bputs("The proxy server did not receive a timely response\n", fd); - ap_bputs("from the upstream server.<P>\n", fd); - break; - default: /* HTTP_INTERNAL_SERVER_ERROR */ - ap_bputs("The server encountered an internal error or\n", fd); - ap_bputs("misconfiguration and was unable to complete\n", fd); - ap_bputs("your request.<P>\n", fd); - ap_bputs("Please contact the server administrator,\n ", fd); - ap_bputs(ap_escape_html(r->pool, r->server->server_admin), fd); - ap_bputs(" and inform them of the time the error occurred,\n", fd); - ap_bputs("and anything you might have done that may have\n", fd); - ap_bputs("caused the error.<P>\n", fd); - break; - } + switch (status) { + case HTTP_MOVED_PERMANENTLY: + case HTTP_MOVED_TEMPORARILY: + case HTTP_TEMPORARY_REDIRECT: + ap_bvputs(fd, "The document has moved <A HREF=\"", + ap_escape_html(r->pool, location), "\">here</A>.<P>\n", + NULL); + break; + case HTTP_SEE_OTHER: + ap_bvputs(fd, "The answer to your request is located <A HREF=\"", + ap_escape_html(r->pool, location), "\">here</A>.<P>\n", + NULL); + break; + case HTTP_USE_PROXY: + ap_bvputs(fd, "This resource is only accessible " + "through the proxy\n", + ap_escape_html(r->pool, location), + "<BR>\nYou will need to ", + "configure your client to use that proxy.<P>\n", NULL); + break; + case HTTP_PROXY_AUTHENTICATION_REQUIRED: + case AUTH_REQUIRED: + ap_bputs("This server could not verify that you\n", fd); + ap_bputs("are authorized to access the document you\n", fd); + ap_bputs("requested. Either you supplied the wrong\n", fd); + ap_bputs("credentials (e.g., bad password), or your\n", fd); + ap_bputs("browser doesn't understand how to supply\n", fd); + ap_bputs("the credentials required.<P>\n", fd); + break; + case BAD_REQUEST: + ap_bputs("Your browser sent a request that\n", fd); + ap_bputs("this server could not understand.<P>\n", fd); + if ((error_notes = ap_table_get(r->notes, "error-notes")) != NULL) { + ap_bvputs(fd, error_notes, "<P>\n", NULL); + } + break; + case HTTP_FORBIDDEN: + ap_bvputs(fd, "You don't have permission to access ", + ap_escape_html(r->pool, r->uri), + "\non this server.<P>\n", NULL); + break; + case NOT_FOUND: + ap_bvputs(fd, "The requested URL ", + ap_escape_html(r->pool, r->uri), + " was not found on this server.<P>\n", NULL); + break; + case METHOD_NOT_ALLOWED: + ap_bvputs(fd, "The requested method ", r->method, + " is not allowed " + "for the URL ", ap_escape_html(r->pool, r->uri), + ".<P>\n", NULL); + break; + case NOT_ACCEPTABLE: + ap_bvputs(fd, + "An appropriate representation of the " + "requested resource ", + ap_escape_html(r->pool, r->uri), + " could not be found on this server.<P>\n", NULL); + /* fall through */ + case MULTIPLE_CHOICES: + { + const char *list; + if ((list = ap_table_get(r->notes, "variant-list"))) + ap_bputs(list, fd); + } + break; + case LENGTH_REQUIRED: + ap_bvputs(fd, "A request of the requested method ", r->method, + " requires a valid Content-length.<P>\n", NULL); + if ((error_notes = ap_table_get(r->notes, "error-notes")) != NULL) { + ap_bvputs(fd, error_notes, "<P>\n", NULL); + } + break; + case PRECONDITION_FAILED: + ap_bvputs(fd, "The precondition on the request for the URL ", + ap_escape_html(r->pool, r->uri), + " evaluated to false.<P>\n", NULL); + break; + case NOT_IMPLEMENTED: + ap_bvputs(fd, ap_escape_html(r->pool, r->method), " to ", + ap_escape_html(r->pool, r->uri), + " not supported.<P>\n", NULL); + break; + case BAD_GATEWAY: + ap_bputs("The proxy server received an invalid\015\012", fd); + ap_bputs("response from an upstream server.<P>\015\012", fd); + break; + case VARIANT_ALSO_VARIES: + ap_bvputs(fd, "A variant for the requested entity ", + ap_escape_html(r->pool, r->uri), " is itself a ", + "transparently negotiable resource.<P>\n", NULL); + break; + case HTTP_REQUEST_TIME_OUT: + ap_bputs("I'm tired of waiting for your request.\n", fd); + break; + case HTTP_GONE: + ap_bvputs(fd, "The requested resource<BR>", + ap_escape_html(r->pool, r->uri), + "<BR>\nis no longer available on this server ", + "and there is no forwarding address.\n", + "Please remove all references to this resource.\n", + NULL); + break; + case HTTP_REQUEST_ENTITY_TOO_LARGE: + ap_bvputs(fd, "The requested resource<BR>", + ap_escape_html(r->pool, r->uri), "<BR>\n", + "does not allow request data with ", r->method, + " requests, or the amount of data provided in\n", + "the request exceeds the capacity limit.\n", NULL); + break; + case HTTP_REQUEST_URI_TOO_LARGE: + ap_bputs("The requested URL's length exceeds the capacity\n" + "limit for this server.<P>\n", fd); + if ((error_notes = ap_table_get(r->notes, "error-notes")) != NULL) { + ap_bvputs(fd, error_notes, "<P>\n", NULL); + } + break; + case HTTP_UNSUPPORTED_MEDIA_TYPE: + ap_bputs("The supplied request data is not in a format\n" + "acceptable for processing by this resource.\n", fd); + break; + case HTTP_RANGE_NOT_SATISFIABLE: + ap_bputs("None of the range-specifier values in the Range\n" + "request-header field overlap the current extent\n" + "of the selected resource.\n", fd); + break; + case HTTP_EXPECTATION_FAILED: + ap_bvputs(fd, "The expectation given in the Expect request-header" + "\nfield could not be met by this server.<P>\n" + "The client sent<PRE>\n Expect: ", + ap_table_get(r->headers_in, "Expect"), "\n</PRE>\n" + "but we only allow the 100-continue expectation.\n", + NULL); + break; + case HTTP_UNPROCESSABLE_ENTITY: + ap_bputs("The server understands the media type of the\n" + "request entity, but was unable to process the\n" + "contained instructions.\n", fd); + break; + case HTTP_LOCKED: + ap_bputs("The requested resource is currently locked.\n" + "The lock must be released or proper identification\n" + "given before the method can be applied.\n", fd); + break; + case HTTP_SERVICE_UNAVAILABLE: + ap_bputs("The server is temporarily unable to service your\n" + "request due to maintenance downtime or capacity\n" + "problems. Please try again later.\n", fd); + break; + case HTTP_GATEWAY_TIME_OUT: + ap_bputs("The proxy server did not receive a timely response\n" + "from the upstream server.\n", fd); + break; + case HTTP_NOT_EXTENDED: + ap_bputs("A mandatory extension policy in the request is not\n" + "accepted by the server for this resource.\n", fd); + break; + default: /* HTTP_INTERNAL_SERVER_ERROR */ + ap_bvputs(fd, "The server encountered an internal error or\n" + "misconfiguration and was unable to complete\n" + "your request.<P>\n" + "Please contact the server administrator,\n ", + ap_escape_html(r->pool, r->server->server_admin), + " and inform them of the time the error occurred,\n" + "and anything you might have done that may have\n" + "caused the error.<P>\n", NULL); + if ((error_notes = ap_table_get(r->notes, "error-notes")) != NULL) { + ap_bvputs(fd, error_notes, "<P>\n", NULL); + } + break; + } if (recursive_error) { ap_bvputs(fd, "<P>Additionally, a ", diff --git a/usr.sbin/httpd/src/main/http_request.c b/usr.sbin/httpd/src/main/http_request.c index 62918edc2ea..918dc9226bf 100644 --- a/usr.sbin/httpd/src/main/http_request.c +++ b/usr.sbin/httpd/src/main/http_request.c @@ -188,8 +188,10 @@ static int get_path_info(request_rec *r) } #ifdef WIN32 - /* If the path is x:/, then convert it to x:/., coz that's what stat needs to work properly */ - if(strlen(path) == 3 && path[1] == ':') { + /* If the path is x:/, then convert it to x:/., coz that's what stat + * needs to work properly + */ + if (strlen(path) == 3 && path[1] == ':') { strcpy(buf,path); buf[3]='.'; buf[4]='\0'; @@ -674,6 +676,7 @@ API_EXPORT(request_rec *) ap_sub_req_lookup_uri(const char *new_file, char *udir; rnew = make_sub_request(r); + rnew->hostname = r->hostname; rnew->request_time = r->request_time; rnew->connection = r->connection; rnew->server = r->server; @@ -751,6 +754,7 @@ API_EXPORT(request_rec *) ap_sub_req_lookup_file(const char *new_file, char *fdir; rnew = make_sub_request(r); + rnew->hostname = r->hostname; rnew->request_time = r->request_time; rnew->connection = r->connection; rnew->server = r->server; @@ -826,7 +830,14 @@ API_EXPORT(request_rec *) ap_sub_req_lookup_file(const char *new_file, * file may not have a uri associated with it -djg */ rnew->uri = "INTERNALLY GENERATED file-relative req"; +#ifdef WIN32 + rnew->filename = ((new_file[0] == '/' + || (ap_isalpha(new_file[0]) + && new_file[1] == ':' + && new_file[2] == '/')) ? +#else rnew->filename = ((new_file[0] == '/') ? +#endif ap_pstrdup(rnew->pool, new_file) : ap_make_full_path(rnew->pool, fdir, new_file)); rnew->per_dir_config = r->server->lookup_defaults; @@ -1013,39 +1024,6 @@ static void process_request_internal(request_rec *r) { int access_status; - /* - * Kluge to be reading the assbackwards field outside of protocol.c, but - * we've got to check for this sort of nonsense somewhere... - */ - - if (r->assbackwards && r->header_only) { - /* - * Client asked for headers only with HTTP/0.9, which doesn't send - * headers! Have to dink things even to make sure the error message - * comes through... - */ - ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r, - "client sent illegal HTTP/0.9 request: %s", r->uri); - r->header_only = 0; - ap_die(BAD_REQUEST, r); - return; - } - - if ((!r->hostname && (r->proto_num >= HTTP_VERSION(1,1))) || - ((r->proto_num == HTTP_VERSION(1,1)) && !ap_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. - */ - ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r, - "client sent HTTP/1.1 request without hostname (see RFC2068 section 9, and 14.23): %s", r->uri); - ap_die(BAD_REQUEST, r); - return; - } - /* Ignore embedded %2F's in path for proxy requests */ if (!r->proxyreq && r->parsed_uri.path) { access_status = ap_unescape_url(r->parsed_uri.path); diff --git a/usr.sbin/httpd/src/main/util.c b/usr.sbin/httpd/src/main/util.c index 6ea60371380..eee03233261 100644 --- a/usr.sbin/httpd/src/main/util.c +++ b/usr.sbin/httpd/src/main/util.c @@ -738,6 +738,7 @@ API_EXPORT(configfile_t *) ap_pcfg_openfile(pool *p, const char *name) poolfile_t *new_pfile; FILE *file; struct stat stbuf; + int saved_errno; if (name == NULL) { ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, NULL, @@ -747,9 +748,11 @@ API_EXPORT(configfile_t *) ap_pcfg_openfile(pool *p, const char *name) file = ap_pfopen(p, name, "r"); #ifdef DEBUG + saved_errno = errno; ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, NULL, "Opening config file %s (%s)", name, (file == NULL) ? strerror(errno) : "successful"); + errno = saved_errno; #endif if (file == NULL) return NULL; @@ -761,10 +764,12 @@ API_EXPORT(configfile_t *) ap_pcfg_openfile(pool *p, const char *name) #else strcmp(name, "/dev/null") != 0) { #endif + saved_errno = errno; ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, NULL, "Access to file %s denied by server: not a regular file", name); ap_pfclose(p, file); + errno = saved_errno; return NULL; } diff --git a/usr.sbin/httpd/src/main/util_script.c b/usr.sbin/httpd/src/main/util_script.c index 270d377867f..9ee38bf8edd 100644 --- a/usr.sbin/httpd/src/main/util_script.c +++ b/usr.sbin/httpd/src/main/util_script.c @@ -262,6 +262,7 @@ API_EXPORT(void) ap_add_common_vars(request_rec *r) #endif ap_table_addn(e, "PATH", env_path); + ap_table_setn(e, "SERVER_SIGNATURE", ap_psignature("", r)); ap_table_addn(e, "SERVER_SOFTWARE", ap_get_server_version()); ap_table_addn(e, "SERVER_NAME", ap_get_server_name(r)); ap_table_addn(e, "SERVER_PORT", @@ -458,8 +459,6 @@ API_EXPORT(int) ap_scan_script_header_err_core(request_rec *r, char *buffer, ap_kill_timeout(r); ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r, "Premature end of script headers: %s", r->filename); - ap_table_setn(r->notes, "error-notes", - "Premature end of script headers"); return HTTP_INTERNAL_SERVER_ERROR; } @@ -543,8 +542,6 @@ API_EXPORT(int) ap_scan_script_header_err_core(request_rec *r, char *buffer, ap_kill_timeout(r); ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r, "%s: %s", malformed, r->filename); - ap_table_setn(r->notes, "error-notes", - ap_pstrdup(r->pool, malformed)); return HTTP_INTERNAL_SERVER_ERROR; } diff --git a/usr.sbin/httpd/src/modules/proxy/proxy_util.c b/usr.sbin/httpd/src/modules/proxy/proxy_util.c index c917d7645fc..a2dfd0e8ed7 100644 --- a/usr.sbin/httpd/src/modules/proxy/proxy_util.c +++ b/usr.sbin/httpd/src/modules/proxy/proxy_util.c @@ -581,7 +581,7 @@ long int ap_proxy_send_fb(BUFF *f, request_rec *r, cache_req *c) ap_reset_timeout(r); if (w <= 0) { - if (c != NULL) { + if (c != NULL && c->fp != NULL) { /* when a send failure occurs, we need to decide * whether to continue loading and caching the * document, or to abort the whole thing diff --git a/usr.sbin/httpd/src/modules/standard/mod_auth.c b/usr.sbin/httpd/src/modules/standard/mod_auth.c index c4ca529cf63..605ef9cfa65 100644 --- a/usr.sbin/httpd/src/modules/standard/mod_auth.c +++ b/usr.sbin/httpd/src/modules/standard/mod_auth.c @@ -264,7 +264,7 @@ static int check_user_access(request_rec *r) method_restricted = 1; t = reqs[x].requirement; - w = ap_getword(r->pool, &t, ' '); + w = ap_getword_white(r->pool, &t); if (!strcmp(w, "valid-user")) return OK; if (!strcmp(w, "user")) { diff --git a/usr.sbin/httpd/src/modules/standard/mod_auth_db.c b/usr.sbin/httpd/src/modules/standard/mod_auth_db.c index 26a994b7367..a4b5da96ce5 100644 --- a/usr.sbin/httpd/src/modules/standard/mod_auth_db.c +++ b/usr.sbin/httpd/src/modules/standard/mod_auth_db.c @@ -281,7 +281,7 @@ static int db_check_auth(request_rec *r) continue; t = reqs[x].requirement; - w = ap_getword(r->pool, &t, ' '); + w = ap_getword_white(r->pool, &t); if (!strcmp(w, "group") && sec->auth_dbgrpfile) { const char *orig_groups, *groups; @@ -298,7 +298,7 @@ static int db_check_auth(request_rec *r) } orig_groups = groups; while (t[0]) { - w = ap_getword(r->pool, &t, ' '); + w = ap_getword_white(r->pool, &t); groups = orig_groups; while (groups[0]) { v = ap_getword(r->pool, &groups, ','); diff --git a/usr.sbin/httpd/src/modules/standard/mod_auth_dbm.c b/usr.sbin/httpd/src/modules/standard/mod_auth_dbm.c index b280513f232..d4a72b23977 100644 --- a/usr.sbin/httpd/src/modules/standard/mod_auth_dbm.c +++ b/usr.sbin/httpd/src/modules/standard/mod_auth_dbm.c @@ -266,7 +266,7 @@ static int dbm_check_auth(request_rec *r) continue; t = reqs[x].requirement; - w = ap_getword(r->pool, &t, ' '); + w = ap_getword_white(r->pool, &t); if (!strcmp(w, "group") && sec->auth_dbmgrpfile) { const char *orig_groups, *groups; @@ -283,7 +283,7 @@ static int dbm_check_auth(request_rec *r) } orig_groups = groups; while (t[0]) { - w = ap_getword(r->pool, &t, ' '); + w = ap_getword_white(r->pool, &t); groups = orig_groups; while (groups[0]) { v = ap_getword(r->pool, &groups, ','); diff --git a/usr.sbin/httpd/src/modules/standard/mod_autoindex.c b/usr.sbin/httpd/src/modules/standard/mod_autoindex.c index 691b78d09b2..18f35cecce3 100644 --- a/usr.sbin/httpd/src/modules/standard/mod_autoindex.c +++ b/usr.sbin/httpd/src/modules/standard/mod_autoindex.c @@ -93,6 +93,7 @@ module MODULE_VAR_EXPORT autoindex_module; #define SUPPRESS_DESC 32 #define SUPPRESS_PREAMBLE 64 #define SUPPRESS_COLSORT 128 +#define NO_OPTIONS 256 #define K_PAD 1 #define K_NOPAD 0 @@ -130,6 +131,8 @@ typedef struct autoindex_config_struct { char *default_icon; int opts; + int incremented_opts; + int decremented_opts; int name_width; int name_adjust; int icon_width; @@ -293,7 +296,11 @@ static const char *fancy_indexing(cmd_parms *cmd, void *d, int arg) cfg = (autoindex_config_rec *) d; curopts = cfg->opts; - newopts = (arg ? (curopts | FANCY_INDEXING) : (curopts & !FANCY_INDEXING)); + if (curopts & NO_OPTIONS) { + return "FancyIndexing directive conflicts with existing " + "IndexOptions None"; + } + newopts = (arg ? (curopts | FANCY_INDEXING) : (curopts & ~FANCY_INDEXING)); cfg->opts = newopts; return NULL; } @@ -301,51 +308,97 @@ static const char *fancy_indexing(cmd_parms *cmd, void *d, int arg) static const char *add_opts(cmd_parms *cmd, void *d, const char *optstr) { char *w; - int opts = 0; + int opts; + int opts_add; + int opts_remove; + char action; autoindex_config_rec *d_cfg = (autoindex_config_rec *) d; + opts = d_cfg->opts; + opts_add = d_cfg->incremented_opts; + opts_remove = d_cfg->decremented_opts; while (optstr[0]) { + int option = 0; + w = ap_getword_conf(cmd->pool, &optstr); + if ((*w == '+') || (*w == '-')) { + action = *(w++); + } + else { + action = '\0'; + } if (!strcasecmp(w, "FancyIndexing")) { - opts |= FANCY_INDEXING; + option = FANCY_INDEXING; } else if (!strcasecmp(w, "IconsAreLinks")) { - opts |= ICONS_ARE_LINKS; + option = ICONS_ARE_LINKS; } else if (!strcasecmp(w, "ScanHTMLTitles")) { - opts |= SCAN_HTML_TITLES; + option = SCAN_HTML_TITLES; } else if (!strcasecmp(w, "SuppressLastModified")) { - opts |= SUPPRESS_LAST_MOD; + option = SUPPRESS_LAST_MOD; } else if (!strcasecmp(w, "SuppressSize")) { - opts |= SUPPRESS_SIZE; + option = SUPPRESS_SIZE; } else if (!strcasecmp(w, "SuppressDescription")) { - opts |= SUPPRESS_DESC; + option = SUPPRESS_DESC; } else if (!strcasecmp(w, "SuppressHTMLPreamble")) { - opts |= SUPPRESS_PREAMBLE; + option = SUPPRESS_PREAMBLE; } else if (!strcasecmp(w, "SuppressColumnSorting")) { - opts |= SUPPRESS_COLSORT; + option = SUPPRESS_COLSORT; } else if (!strcasecmp(w, "None")) { - opts = 0; + if (action != '\0') { + return "Cannot combine '+' or '-' with 'None' keyword"; + } + opts = NO_OPTIONS; + opts_add = 0; + opts_remove = 0; } else if (!strcasecmp(w, "IconWidth")) { - d_cfg->icon_width = DEFAULT_ICON_WIDTH; + if (action != '-') { + d_cfg->icon_width = DEFAULT_ICON_WIDTH; + } + else { + d_cfg->icon_width = 0; + } } else if (!strncasecmp(w, "IconWidth=", 10)) { + if (action != '\0') { + return "Cannot combine '+' or '-' with IconWidth=n"; + } d_cfg->icon_width = atoi(&w[10]); } else if (!strcasecmp(w, "IconHeight")) { - d_cfg->icon_height = DEFAULT_ICON_HEIGHT; + if (action != '-') { + d_cfg->icon_height = DEFAULT_ICON_HEIGHT; + } + else { + d_cfg->icon_height = 0; + } } else if (!strncasecmp(w, "IconHeight=", 11)) { + if (action != '\0') { + return "Cannot combine '+' or '-' with IconHeight=n"; + } d_cfg->icon_height = atoi(&w[11]); } + else if (!strcasecmp(w, "NameWidth")) { + if (action != '-') { + return "NameWidth with no value may only appear as " + "'-NameWidth'"; + } + d_cfg->name_width = DEFAULT_NAME_WIDTH; + d_cfg->name_adjust = 0; + } else if (!strncasecmp(w, "NameWidth=", 10)) { + if (action != '\0') { + return "Cannot combine '+' or '-' with NameWidth=n"; + } if (w[10] == '*') { d_cfg->name_adjust = 1; } @@ -361,7 +414,25 @@ static const char *add_opts(cmd_parms *cmd, void *d, const char *optstr) else { return "Invalid directory indexing option"; } + if (action == '\0') { + opts |= option; + opts_add = 0; + opts_remove = 0; + } + else if (action == '+') { + opts_add |= option; + opts_remove &= ~option; + } + else { + opts_remove |= option; + opts_add &= ~option; + } + } + if ((opts & NO_OPTIONS) && (opts & ~NO_OPTIONS)) { + return "Cannot combine other IndexOptions keywords with 'None'"; } + d_cfg->incremented_opts = opts_add; + d_cfg->decremented_opts = opts_remove; d_cfg->opts = opts; return NULL; } @@ -414,6 +485,8 @@ static void *create_autoindex_config(pool *p, char *dummy) new->hdr_list = ap_make_array(p, 4, sizeof(struct item)); new->rdme_list = ap_make_array(p, 4, sizeof(struct item)); new->opts = 0; + new->incremented_opts = 0; + new->decremented_opts = 0; return (void *) new; } @@ -436,7 +509,48 @@ static void *merge_autoindex_configs(pool *p, void *basev, void *addv) new->desc_list = ap_append_arrays(p, add->desc_list, base->desc_list); new->icon_list = ap_append_arrays(p, add->icon_list, base->icon_list); new->rdme_list = ap_append_arrays(p, add->rdme_list, base->rdme_list); - new->opts = add->opts; + if (add->opts & NO_OPTIONS) { + /* + * If the current directory says 'no options' then we also + * clear any incremental mods from being inheritable further down. + */ + new->opts = NO_OPTIONS; + new->incremented_opts = 0; + new->decremented_opts = 0; + } + else { + /* + * If there were any non-incremental options selected for + * this directory, they dominate and we don't inherit *anything.* + * Contrariwise, we *do* inherit if the only settings here are + * incremental ones. + */ + if (add->opts == 0) { + new->incremented_opts = (base->incremented_opts + | add->incremented_opts) + & ~add->decremented_opts; + new->decremented_opts = (base->decremented_opts + | add->decremented_opts); + /* + * We may have incremental settings, so make sure we don't + * inadvertently inherit an IndexOptions None from above. + */ + new->opts = (base->opts & ~NO_OPTIONS); + } + else { + /* + * There are local non-incremental settings, which clear + * all inheritance from above. They *are* the new base settings. + */ + new->opts = add->opts;; + } + /* + * We're guaranteed that there'll be no overlap between + * the add-options and the remove-options. + */ + new->opts |= new->incremented_opts; + new->opts &= ~new->decremented_opts; + } new->name_width = add->name_width; new->name_adjust = add->name_adjust; @@ -455,7 +569,7 @@ struct ent { char *icon; char *alt; char *desc; - size_t size; + off_t size; time_t lm; struct ent *next; int ascending; @@ -745,7 +859,7 @@ static struct ent *make_autoindex_entry(char *name, int autoindex_opts, p = (struct ent *) ap_pcalloc(r->pool, sizeof(struct ent)); p->name = ap_pstrdup(r->pool, name); - p->size = 0; + p->size = -1; p->icon = NULL; p->alt = NULL; p->desc = NULL; @@ -765,7 +879,7 @@ static struct ent *make_autoindex_entry(char *name, int autoindex_opts, if (!(p->alt = find_alt(d, rr, 1))) { p->alt = "DIR"; } - p->size = 0; + p->size = -1; p->name = ap_pstrcat(r->pool, name, "/", NULL); } else { diff --git a/usr.sbin/httpd/src/modules/standard/mod_cgi.c b/usr.sbin/httpd/src/modules/standard/mod_cgi.c index fd5906c4ec2..70f7956228f 100644 --- a/usr.sbin/httpd/src/modules/standard/mod_cgi.c +++ b/usr.sbin/httpd/src/modules/standard/mod_cgi.c @@ -433,7 +433,6 @@ static int cgi_handler(request_rec *r) &script_out, &script_in, &script_err)) { ap_log_rerror(APLOG_MARK, APLOG_ERR, r, "couldn't spawn child process: %s", r->filename); - ap_table_setn(r->notes, "error-notes", "Couldn't spawn child process"); return HTTP_INTERNAL_SERVER_ERROR; } diff --git a/usr.sbin/httpd/src/modules/standard/mod_digest.c b/usr.sbin/httpd/src/modules/standard/mod_digest.c index 08e52f4ecfe..f44e7e3edea 100644 --- a/usr.sbin/httpd/src/modules/standard/mod_digest.c +++ b/usr.sbin/httpd/src/modules/standard/mod_digest.c @@ -159,7 +159,7 @@ static int get_digest_rec(request_rec *r, digest_header_rec * response) return AUTH_REQUIRED; } - if (strcasecmp(scheme=ap_getword(r->pool, &auth_line, ' '), "Digest")) { + if (strcasecmp(scheme = ap_getword_white(r->pool, &auth_line), "Digest")) { /* Client tried to authenticate using wrong auth scheme */ ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r->server, "client used wrong authentication scheme: %s for %s", @@ -345,7 +345,7 @@ static int digest_check_auth(request_rec *r) method_restricted = 1; t = reqs[x].requirement; - w = ap_getword(r->pool, &t, ' '); + w = ap_getword_white(r->pool, &t); if (!strcmp(w, "valid-user")) return OK; else if (!strcmp(w, "user")) { diff --git a/usr.sbin/httpd/src/modules/standard/mod_include.c b/usr.sbin/httpd/src/modules/standard/mod_include.c index 612759ed6e9..3acc0c6f696 100644 --- a/usr.sbin/httpd/src/modules/standard/mod_include.c +++ b/usr.sbin/httpd/src/modules/standard/mod_include.c @@ -946,6 +946,7 @@ static int handle_perl(FILE *in, request_rec *r, const char *error) } } perl_stdout2client(r); + perl_setup_env(r); perl_call_handler(sub, r, av); return OK; } diff --git a/usr.sbin/httpd/src/modules/standard/mod_log_config.c b/usr.sbin/httpd/src/modules/standard/mod_log_config.c index 1fa8f498589..da6d2bcb458 100644 --- a/usr.sbin/httpd/src/modules/standard/mod_log_config.c +++ b/usr.sbin/httpd/src/modules/standard/mod_log_config.c @@ -202,10 +202,9 @@ static mode_t xfer_mode = (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); * multi_log_state is our per-(virtual)-server configuration. We store * an array of the logs we are going to use, each of type config_log_state. * If a default log format is given by LogFormat, store in default_format - * (backward compat. with mod_log_config). We also store a pointer to - * the logs specified for the main server for virtual servers, so that - * if this vhost has now logs defined, we can use the main server's - * logs instead. + * (backward compat. with mod_log_config). We also store for each virtual + * server a pointer to the logs specified for the main server, so that if this + * vhost has no logs defined, we can use the main server's logs instead. * * So, for the main server, config_logs contains a list of the log files * and server_config_logs in empty. For a vhost, server_config_logs diff --git a/usr.sbin/httpd/src/modules/standard/mod_speling.c b/usr.sbin/httpd/src/modules/standard/mod_speling.c index 53f8c1da34d..7d1b976d639 100644 --- a/usr.sbin/httpd/src/modules/standard/mod_speling.c +++ b/usr.sbin/httpd/src/modules/standard/mod_speling.c @@ -453,18 +453,21 @@ static int check_speling(request_rec *r) t = ""; for (i = 0; i < candidates->nelts; ++i) { + char *vuri; + const char *reason; + reason = sp_reason_str[(int) (variant[i].quality)]; /* The format isn't very neat... */ - t = ap_pstrcat(p, t, "<li><a href=\"", url, - variant[i].name, r->path_info, - r->parsed_uri.query ? "?" : "", - r->parsed_uri.query ? r->parsed_uri.query : "", - "\">", variant[i].name, r->path_info, - r->parsed_uri.query ? "?" : "", - r->parsed_uri.query ? r->parsed_uri.query : "", - "</a> (", - sp_reason_str[(int) (variant[i].quality)], - ")\n", NULL); + vuri = ap_pstrcat(p, url, variant[i].name, r->path_info, + (r->parsed_uri.query != NULL) ? "?" : "", + (r->parsed_uri.query != NULL) + ? r->parsed_uri.query : "", + NULL); + ap_table_mergen(r->subprocess_env, "VARIANTS", + ap_pstrcat(p, "\"", vuri, "\";\"", + reason, "\"", NULL)); + t = ap_pstrcat(p, t, "<li><a href=\"", vuri, + "\">", vuri, "</a> (", reason, ")\n", NULL); /* * when we have printed the "close matches" and there are diff --git a/usr.sbin/httpd/src/modules/standard/mod_status.c b/usr.sbin/httpd/src/modules/standard/mod_status.c index 2c24df1ff51..31e9aa41abb 100644 --- a/usr.sbin/httpd/src/modules/standard/mod_status.c +++ b/usr.sbin/httpd/src/modules/standard/mod_status.c @@ -240,10 +240,12 @@ static int status_handler(request_rec *r) unsigned long bcount = 0; unsigned long kbcount = 0; long req_time; -#if defined(NEXT) - float tick = HZ; -#elif !defined(NO_TIMES) +#ifndef NO_TIMES +#ifdef _SC_CLK_TCK float tick = sysconf(_SC_CLK_TCK); +#else + float tick = HZ; +#endif #endif int short_report = 0; int no_table_report = 0; diff --git a/usr.sbin/httpd/src/os/bs2000/bs2login.c b/usr.sbin/httpd/src/os/bs2000/bs2login.c index 361c59d92f7..afba7fd928b 100644 --- a/usr.sbin/httpd/src/os/bs2000/bs2login.c +++ b/usr.sbin/httpd/src/os/bs2000/bs2login.c @@ -67,9 +67,6 @@ static const char *bs2000_account = NULL; /* It stores the account name for later use */ const char *os_set_account(pool *p, const char *account) { - if (bs2000_account != NULL && strcasecmp(bs2000_account, account) != 0) - return "BS2000Account: can be defined only once."; - bs2000_account = ap_pstrdup(p, account); return NULL; } diff --git a/usr.sbin/httpd/src/os/bs2000/ebcdic.c b/usr.sbin/httpd/src/os/bs2000/ebcdic.c index d8c650c0ebc..4a268488de8 100644 --- a/usr.sbin/httpd/src/os/bs2000/ebcdic.c +++ b/usr.sbin/httpd/src/os/bs2000/ebcdic.c @@ -62,8 +62,7 @@ /* Initial Port for Apache-1.3 by <Martin.Kraemer@Mch.SNI.De> -"BS2000 OSD" is a POSIX on a main frame. -It is made by Siemens Nixdorf AG, Germany. +"BS2000 OSD" is a POSIX on a main frame. It is made by Siemens AG, Germany. Within the POSIX subsystem, the same character set was chosen as in "native BS2000", namely EBCDIC. diff --git a/usr.sbin/httpd/src/os/win32/registry.c b/usr.sbin/httpd/src/os/win32/registry.c index 64aa72982a6..665f8ee67e7 100644 --- a/usr.sbin/httpd/src/os/win32/registry.c +++ b/usr.sbin/httpd/src/os/win32/registry.c @@ -28,7 +28,7 @@ #define VENDOR "Apache Group" #define SOFTWARE "Apache" -#define VERSION "1.3.2" +#define VERSION "1.3.3" #define REGKEY "SOFTWARE\\" VENDOR "\\" SOFTWARE "\\" VERSION diff --git a/usr.sbin/httpd/src/os/win32/util_win32.c b/usr.sbin/httpd/src/os/win32/util_win32.c index 47d8f7af9b5..3aac08767ce 100644 --- a/usr.sbin/httpd/src/os/win32/util_win32.c +++ b/usr.sbin/httpd/src/os/win32/util_win32.c @@ -23,7 +23,18 @@ static BOOL sub_canonical_filename(char *szCanon, unsigned nCanon, for (nSlashes = 0; s > szFile && s[-1] == '\\'; ++nSlashes, --s) ; - n = GetFullPathName(szFile, sizeof buf, buf, &szFilePart); + if (strlen(szFile)==2 && szFile[1]==':') { + /* + * If the file name is x:, do not call GetFullPathName + * because it will use the current path of the executable + */ + strcpy(buf,szFile); + n = strlen(buf); + szFilePart = buf + n; + } + else { + n = GetFullPathName(szFile, sizeof buf, buf, &szFilePart); + } ap_assert(n); ap_assert(n < sizeof buf); @@ -36,6 +47,8 @@ static BOOL sub_canonical_filename(char *szCanon, unsigned nCanon, * is no '\' in szInFile, it must just be a file name, so it should be * valid to use the name from GetFullPathName. Be sure to adjust the * 's' variable so the rest of the code functions normally. + * Note it is possible to get here when szFile == 'x:', but that is OK + * because we will bail out of this routine early. */ if (!s) { szFile = buf; @@ -180,9 +193,21 @@ API_EXPORT(char *) ap_os_canonical_filename(pool *pPool, const char *szFile) buf[0] = ap_tolower(buf[0]); - ap_assert(strlen(buf)+nSlashes < sizeof buf); - while (nSlashes--) { - strcat(buf, "/"); + if (nSlashes) { + /* + * If there were additional trailing slashes, add them back on. + * Be sure not to add more than were originally there though, + * by checking to see if sub_canonical_filename added one; + * this could happen in cases where the file name is 'd:/' + */ + ap_assert(strlen(buf)+nSlashes < sizeof buf); + + if (nSlashes && buf[strlen(buf)-1] == '/') + nSlashes--; + + while (nSlashes--) { + strcat(buf, "/"); + } } return ap_pstrdup(pPool, buf); @@ -233,8 +258,13 @@ API_EXPORT(int) os_stat(const char *szPath, struct stat *pStat) return stat(buf, pStat); } + /* + * Below removes the trailing /, however, do not remove + * it in the case of 'x:/' or stat will fail + */ n = strlen(szPath); - if (szPath[n - 1] == '\\' || szPath[n - 1] == '/') { + if ((szPath[n - 1] == '\\' || szPath[n - 1] == '/') && + !(n == 3 && szPath[1] == ':')) { char buf[_MAX_PATH]; ap_assert(n < _MAX_PATH); diff --git a/usr.sbin/httpd/src/support/dbmmanage b/usr.sbin/httpd/src/support/dbmmanage index 824cda540d6..042c686497e 100644 --- a/usr.sbin/httpd/src/support/dbmmanage +++ b/usr.sbin/httpd/src/support/dbmmanage @@ -89,9 +89,9 @@ my $Is_Win32 = $^O eq "MSWin32"; my %DB = (); my @range = (); my($mode, $flags) = $command =~ - /^(?:view|check)$/ ? (undef, O_RDONLY) : (0644, O_RDWR|O_CREAT); + /^(?:view|check)$/ ? (0644, O_RDONLY) : (0644, O_RDWR|O_CREAT); -tie %DB, "AnyDBM_File", $file, $flags, $mode; +tie %DB, "AnyDBM_File", $file, $flags, $mode || die "Can't tie $file: $!"; dbmc->$command(); untie %DB; |