1
0
mirror of https://github.com/apache/httpd.git synced 2025-08-08 15:02:10 +03:00

Apache 1.3.9 baseline for the Apache 2.0 repository.

Obtained from: Apache 1.3.9 (minus unused files), tag APACHE_1_3_9
Submitted by: Apache Group


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@83750 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Roy T. Fielding
1999-08-24 06:46:03 +00:00
parent ef31f58424
commit 6f96ad5227
118 changed files with 38277 additions and 0 deletions

210
docs/man/ab.8 Normal file
View File

@@ -0,0 +1,210 @@
.TH ab 1 "March 1998"
.\" $Id: ab.8,v 1.1 1999/08/24 06:45:53 fielding Exp $
.\" Copyright (c) 1998-1999 The Apache Group. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\"
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\"
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in
.\" the documentation and/or other materials provided with the
.\" distribution.
.\"
.\" 3. All advertising materials mentioning features or use of this
.\" software must display the following acknowledgment:
.\" "This product includes software developed by the Apache Group
.\" for use in the Apache HTTP server project (http://www.apache.org/)."
.\"
.\" 4. The names "Apache Server" and "Apache Group" must not be used to
.\" endorse or promote products derived from this software without
.\" prior written permission.
.\"
.\" 5. Products derived from this software may not be called "Apache"
.\" nor may "Apache" appear in their names without prior written
.\" permission of the Apache Group.
.\"
.\" 6. Redistributions of any form whatsoever must retain the following
.\" acknowledgment:
.\" "This product includes software developed by the Apache Group
.\" for use in the Apache HTTP server project (http://www.apache.org/)."
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
.\" OF THE POSSIBILITY OF SUCH DAMAGE.
.\" ====================================================================
.\"
.\" This software consists of voluntary contributions made by many
.\" individuals on behalf of the Apache Group and was originally based
.\" on public domain software written at the National Center for
.\" Supercomputing Applications, University of Illinois, Urbana-Champaign.
.\" For more information on the Apache Group and the Apache HTTP server
.\" project, please see <http://www.apache.org/>.
.SH NAME
ab \- Apache HTTP server benchmarking tool
.SH SYNOPSIS
.B ab
[
.B \-k
] [
.BI \-n " requests"
] [
.BI \-t " timelimit"
] [
.BI \-c " concurrency"
] [
.BI \-p " POST file"
] [
.BI \-A " Authenticate username:password"
] [
.BI \-P " Proxy Authenticate username:password"
] [
.BI \-H " Custom header"
] [
.BI \-C " Cookie name=value"
] [
.BI \-T " content-type"
] [
.BI \-v " verbosity"
]
] [
.BI \-w " output HTML"
]
] [
.BI \-x " <table> attributes"
]
] [
.BI \-y " <tr> attributes"
]
] [
.BI \-z " <td> attributes"
]
.I [http://]hostname[:port]/path
.B ab
[
.B \-V
] [
.B \-h
]
.PP
.SH DESCRIPTION
.B ab
is a tool for benchmarking your Apache HyperText Transfer Protocol (HTTP)
server. It is designed to give you an impression on how performant is your
current Apache installation. This especially shows you how much requests per
time your Apache installation is capable to serve.
.PP
.SH OPTIONS
.TP 12
.B \-k
Enable the HTTP KeepAlive feature, i.e. perform multiple requests within one
HTTP session instead. Default is no KeepAlive.
.TP 12
.BI \-n " requests"
Number of requests to perform for the benchmarking session. The default is to
just perform one single request which usually leads to not very representative
benchmarking results.
.TP 12
.BI \-t " timelimit"
Seconds to max. spend for benchmarking. This implies
a
.B \-n
.B 50000
internally. Use this to benchmark the server within a fixed total amount of
time. Per default there is no timelimit.
.TP 12
.BI \-c " concurrency"
Number of multiple requests per time to perform.
Default is one request per time.
.TP 12
.BI \-p " POST file"
File containing data to POST.
.TP 12
.BI \-A " Authorization username:password"
Supply BASIC Authentification credentials to the server. The username
and password are separated by a single ':' and send on the wire uuencoded.
The string is send regardless of wether the server needs it; (i.e. has
send an 401. Authentifcation needed).
.TP 12
.BI \-p " Proxy-Authorization username:password"
Supply BASIC Authentification credentials to a proxy en-route. The username
and password are separated by a single ':' and send on the wire uuencoded.
The string is send regardless of wether the proxy needs it; (i.e. has
send an 407 Proxy authentifcation needed).
.TP 12
.BI \-C " Cookie name=value"
Add a 'Cookie:' line to the request. The argument is typically in the form
of a 'name=value' pair. This field is repeatable.
.TP 12
.BI \-p " Header string"
Postfix extra headers to the request. The argument is typically in the form
of a valid header line; containing a colon separated field value pair. (i.e.
'Accept-Encoding: zip/zop;8bit').
.TP 12
.BI \-T " content-type"
Content-type header to use for POST data.
.TP 12
.B \-v
Set verbosity level - 4 and above prints information on headers, 3 and
above prints response codes (404, 200, etc.), 2 and above prints
warnings and info.
.TP 12
.BI \-w
Print out results in HTML tables. Default table is two columns wide,
with a white background.
.TP 12
.BI \-x " attributes"
String to use as attributes for <table>. Attributes are inserted
<table
.B here
>
.TP 12
.BI \-y " attributes"
String to use as attributes for <tr>.
.TP 12
.BI \-z " attributes"
String to use as attributes for <td>.
.TP 12
.B \-V
Display version number and exit.
.TP 12
.B \-h
Display usage information.
.PD
.SH BUGS
There are various statically declared buffers of fixed length. Combined
with the lazy parsing of the command line arguments, the response headers
from the server and other external inputs this might bite you.
.P
It does not implement HTTP/1.x fully; only accepts some 'expected' forms
of responses. The rather heavy use of
.BR strstr(3)
shows up top in profile,
which might indicate a performance problem; i.e. you would measure the
.BR ab
performance rather than the server's.
.SH SEE ALSO
.BR httpd(8)
.

133
docs/man/apachectl.8 Normal file
View File

@@ -0,0 +1,133 @@
.TH apachectl 1 "September 1997"
.\" Copyright (c) 1997-1999 The Apache Group. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\"
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\"
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in
.\" the documentation and/or other materials provided with the
.\" distribution.
.\"
.\" 3. All advertising materials mentioning features or use of this
.\" software must display the following acknowledgment:
.\" "This product includes software developed by the Apache Group
.\" for use in the Apache HTTP server project (http://www.apache.org/)."
.\"
.\" 4. The names "Apache Server" and "Apache Group" must not be used to
.\" endorse or promote products derived from this software without
.\" prior written permission.
.\"
.\" 5. Products derived from this software may not be called "Apache"
.\" nor may "Apache" appear in their names without prior written
.\" permission of the Apache Group.
.\"
.\" 6. Redistributions of any form whatsoever must retain the following
.\" acknowledgment:
.\" "This product includes software developed by the Apache Group
.\" for use in the Apache HTTP server project (http://www.apache.org/)."
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
.\" OF THE POSSIBILITY OF SUCH DAMAGE.
.\" ====================================================================
.\"
.\" This software consists of voluntary contributions made by many
.\" individuals on behalf of the Apache Group and was originally based
.\" on public domain software written at the National Center for
.\" Supercomputing Applications, University of Illinois, Urbana-Champaign.
.\" For more information on the Apache Group and the Apache HTTP server
.\" project, please see <http://www.apache.org/>.
.SH NAME
apachectl \- Apache HTTP server control interface
.SH SYNOPSIS
.B apachectl
\fIcommand\fP [...]
.SH DESCRIPTION
.B apachectl
is a front end to the Apache HyperText Transfer Protocol (HTTP)
server. It is designed to help the administrator control the
functioning of the Apache
.B httpd
daemon.
.PP
.B NOTE:
If your Apache installation uses non-standard paths, you will need to
edit the
.B apachectl
script to set the appropriate paths to your PID file and your
.B httpd
binary. See the comments in the script for details.
.PP
The
.B apachectl
script returns a 0 exit value on success, and >0 if an error
occurs. For more details, view the comments in the script.
.PP
Full documentation for Apache is available at
.B http://www.apache.org/
.
.SH OPTIONS
The \fIcommand\fP can be any one or more of the following options:
.TP 12
.BI start
Start the Apache daemon. Gives an error if it is already running.
.TP
.BI stop
Stops the Apache daemon.
.TP
.BI restart
Restarts the Apache daemon by sending it a SIGHUP. If the daemon
is not running, it is started.
This command automatically checks the configuration files via
.BI configtest
before initiating the restart to make sure Apache doesn't die.
.TP
.BI fullstatus
Displays a full status report from
.B mod_status.
For this to work, you need to have mod_status enabled on your server
and a text-based browser such as \fIlynx\fP available on your system. The
URL used to access the status report can be set by editing the
.B STATUSURL
variable in the script.
.TP
.BI status
Displays a brief status report. Similar to the fullstatus option,
except that the list of requests currently being served is omitted.
.TP
.BI graceful
Gracefully restarts the Apache daemon by sending it a SIGUSR1. If
the daemon is not running, it is started. This differs from a
normal restart in that currently open connections are not aborted.
A side effect is that old log files will not be closed immediately.
This means that if used in a log rotation script, a substantial delay may be
necessary to ensure that the old log files are closed before processing them.
This command automatically checks the configuration files via
.BI configtest
before initiating the restart to make sure Apache doesn't die.
.TP
.BI configtest
Run a configuration file syntax test. It parses the configuration
files and either reports
.B "Syntax Ok"
or detailed information about the particular syntax error.
.TP
.BI help
Displays a short help message.
.SH SEE ALSO
.BR httpd(8)
.

459
docs/man/apxs.8 Normal file
View File

@@ -0,0 +1,459 @@
.TH apxs 8 "April 1998"
.\" Copyright (c) 1998-1999 The Apache Group. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\"
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\"
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in
.\" the documentation and/or other materials provided with the
.\" distribution.
.\"
.\" 3. All advertising materials mentioning features or use of this
.\" software must display the following acknowledgment:
.\" "This product includes software developed by the Apache Group
.\" for use in the Apache HTTP server project (http://www.apache.org/)."
.\"
.\" 4. The names "Apache Server" and "Apache Group" must not be used to
.\" endorse or promote products derived from this software without
.\" prior written permission.
.\"
.\" 5. Products derived from this software may not be called "Apache"
.\" nor may "Apache" appear in their names without prior written
.\" permission of the Apache Group.
.\"
.\" 6. Redistributions of any form whatsoever must retain the following
.\" acknowledgment:
.\" "This product includes software developed by the Apache Group
.\" for use in the Apache HTTP server project (http://www.apache.org/)."
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
.\" OF THE POSSIBILITY OF SUCH DAMAGE.
.\" ====================================================================
.\"
.\" This software consists of voluntary contributions made by many
.\" individuals on behalf of the Apache Group and was originally based
.\" on public domain software written at the National Center for
.\" Supercomputing Applications, University of Illinois, Urbana-Champaign.
.\" For more information on the Apache Group and the Apache HTTP server
.\" project, please see <http://www.apache.org/>.
.SH NAME
apxs \- APache eXtenSion tool
.SH SYNOPSIS
.B apxs
.B \-g
[
.BI \-S " name=value
]
.BI \-n " modname"
.B apxs
.B \-q
[
.BI \-S " name=value
]
.IR query " ..."
.B apxs
.B \-c
[
.BI \-S " name=value
]
[
.BI \-o " dsofile"
]
[
.BI \-I " incdir"
]
[
.BI \-D " name=value"
]
[
.BI \-L " libdir"
]
[
.BI \-l " libname"
]
[
.BI \-Wc, "compiler-flags"
]
[
.BI \-Wl, "linker-flags"
]
.IR files " ..."
.B apxs
.B \-i
[
.BI \-S " name=value
]
[
.BI \-n " modname"
]
[
.B \-a
]
[
.B \-A
]
.IR dsofile " ..."
.B apxs
.B \-e
[
.BI \-S " name=value
]
[
.BI \-n " modname"
]
[
.B \-a
]
[
.B \-A
]
.IR dsofile " ..."
.PP
.SH DESCRIPTION
.B apxs
is a tool for building and installing extension modules for the Apache
HyperText Transfer Protocol (HTTP) server. This is achieved by building a
dynamic shared object (DSO) from one or more source or object
.I files
which then can be loaded into
the Apache server under runtime via the
.B LoadModule
directive from
.BR mod_so.
So to use this extension mechanism your platform has
to support the DSO feature and your
Apache
.B httpd
binary has to be built with the
.B mod_so
module.
The
.B apxs
tool automatically complains if this is not the case.
You can check this yourself by manually running the command
.nf
$ httpd -l
.fi
The module
.B mod_so
should be part of the displayed list.
If these requirements are fulfilled you can easily extend
your Apache server's functionality by installing your own
modules with the DSO mechanism by the help of this
.B apxs
tool:
.nf
$ apxs -i -a -c mod_foo.c
gcc -fpic -DSHARED_MODULE -I/path/to/apache/include -c mod_foo.c
ld -Bshareable -o mod_foo.so mod_foo.o
cp mod_foo.so /path/to/apache/libexec/mod_foo.so
chmod 755 /path/to/apache/libexec/mod_foo.so
[activating module `foo' in /path/to/apache/etc/httpd.conf]
$ apachectl restart
/path/to/apache/sbin/apachectl restart: httpd not running, trying to start
[Tue Mar 31 11:27:55 1998] [debug] mod_so.c(303): loaded module foo_module
/path/to/apache/sbin/apachectl restart: httpd started
$ _
.fi
The arguments
.I files
can be any C source file (.c), a object file (.o) or
even a library archive (.a). The
.B apxs
tool automatically recognizes these extensions and automtaically used the C
source files for compilation while just using the object and archive files for
the linking phase. But when using such pre-compiled objects make sure they are
compiled for position independend code (PIC) to be able to use them for a
dynamically loaded shared object.
For instance with GCC you always just have to use
.BR -fpic .
For other
C compilers consult its manual
page or at watch for the flags
.B apxs
uses to compile the object files.
For more details about DSO support in Apache read the documentation
of
.B mod_so
or perhaps even read the
.B src/modules/standard/mod_so.c
source file.
.PP
.SH OPTIONS
Common options:
.TP 12
.BI \-n " modname"
This explicitly sets the module name for the
.B \-i
(install)
and
.B \-g
(template generation) option. Use this to explicitly specify the module name.
For option
.B \-g
this is required, for option
.B \-i
the
.B apxs
tool tries to determine the name from the source or (as a fallback) at least
by guessing it from the filename.
.PP
Query options:
.TP 12
.B \-q
Performs a query for
.BR apxs 's
knowledge about certain settings. The
.I query
parameters can be one or more of the following strings:
.nf
CC TARGET
CFLAGS SBINDIR
CFLAGS_SHLIB INCLUDEDIR
LD_SHLIB LIBEXECDIR
LDFLAGS_SHLIB SYSCONFDIR
LIBS_SHLIB
.fi
Use this for manually determining settings. For instance use
.nf
INC=-I`apxs -q INCLUDEDIR`
.fi
inside your own Makefiles if you need manual access
to Apache's C header files.
.PP
Configuration options:
.TP 12
.BI \-S " name=value"
This option changes the apxs settings described above.
.PP
Template Generation options:
.TP 12
.B \-g
This generates a subdirectory
.I name
(see option
.BR \-n ")"
and there two files: A sample module source file named
.BI mod_ name.c
which can be used as a template for creating your own modules or
as a quick start for playing with the APXS mechanism.
And a corresponding
.B Makefile
for even easier build and installing of this module.
.PP
DSO compilation options:
.TP 12
.B \-c
This indicates the compilation operation. It first compiles the C source
files (.c) of
.I files
into corresponding object files (.o) and then builds a dynamically shared object in
.I dsofile
by linking these object files plus the remaining
object files (.o and .a) of
.I files
If no
.B \-o
option is specified
the output file is guessed from the first filename in
.I files
and thus usually defaults to
.BI mod_ name.so
.TP 12
.BI \-o " dsofile"
Explicitly specifies the filename of the created dynamically shared object. If
not specified and the name cannot be guessed from the
.I files
list, the fallback name
.B mod_unknown.so
is used.
.TP 12
.BI \-D " name=value"
This option is directly passed through to the compilation command(s).
Use this to add your own defines to the build process.
.TP 12
.BI \-I " incdir"
This option is directly passed through to the compilation command(s).
Use this to add your own include directories to search to the build process.
.TP 12
.BI \-L " libdir"
This option is directly passed through to the linker command.
Use this to add your own library directories to search to the build process.
.TP 12
.BI \-l " libname"
This option is directly passed through to the linker command.
Use this to add your own libraries to search to the build process.
.TP 12
.BI \-Wc, "compiler-flags"
This option passes
.I compiler-flags
as additional flags to the compiler command.
Use this to add local compiler-specific options.
.TP 12
.BI \-Wl, "linker-flags"
This option passes
.I linker-flags
as additional flags to the linker command.
Use this to add local linker-specific options.
.PP
DSO installation and configuration options:
.TP 12
.B \-i
This indicates the installation operation and installs one or more
dynamically shared objects into the
server's
.I libexec
directory.
.TP 12
.B \-a
This activates the module by automatically adding a corresponding
.B LoadModule
line to Apache's
.B httpd.conf
configuration file, or by enabling it if it already exists.
.TP 12
.B \-A
Same as option
.B \-a
but the created
.B LoadModule
directive is prefixed with a hash sign (#), i.e. the module is
just prepared for later activation but initially disabled.
.TP 12
.B \-e
This indicates the editing operation, which can be used with the
.B \-a
and
.B \-A
options similarly to the
.B \-i
operation to edit Apache's
.B httpd.conf
configuration file without attempting to install the module.
.PD
.SH EXAMPLES
Assume you have an Apache module named mod_foo.c available which should extend
Apache's server functionality. To accomplish this you first have to compile
the C source into a shared object suitable for loading into the Apache server
under runtime via the following command:
.nf
$ apxs -c mod_foo.c
gcc -fpic -DSHARED_MODULE -I/path/to/apache/include -c mod_foo.c
ld -Bshareable -o mod_foo.so mod_foo.o
$ _
.fi
Then you have to update the Apache configuration by making sure a
.B LoadModule
directive is present to load this shared object. To simplify this
step
.B apxs
provides an automatic way to install the shared object in its
"libexec" directory and updating the
.B httpd.conf
file accordingly. This can be achieved by running:
.nf
$ apxs -i -a mod_foo.c
cp mod_foo.so /path/to/apache/libexec/mod_foo.so
chmod 755 /path/to/apache/libexec/mod_foo.so
[activating module `foo' in /path/to/apache/etc/httpd.conf]
$ _
.fi
This way a line named
.nf
LoadModule foo_module libexec/mod_foo.so
.fi
is added to the configuration file if still not present.
If you want to have this this disabled per default use the
.B \-A
option, i.e.
.nf
$ apxs -i -A mod_foo.c
.fi
For a quick test of the APXS mechanism you can create a sample Apache module
template plus a corresponding Makefile via:
.nf
$ apxs -g -n foo
Creating [DIR] foo
Creating [FILE] foo/Makefile
Creating [FILE] foo/mod_foo.c
$ _
.fi
Then you can immediately compile this sample module into a shared object and
load it into the Apache server:
.nf
$ cd foo
$ make all reload
apxs -c mod_foo.c
gcc -fpic -DSHARED_MODULE -I/path/to/apache/include -c mod_foo.c
ld -Bshareable -o mod_foo.so mod_foo.o
apxs -i -a -n "foo" mod_foo.so
cp mod_foo.so /path/to/apache/libexec/mod_foo.so
chmod 755 /path/to/apache/libexec/mod_foo.so
[activating module `foo' in /path/to/apache/etc/httpd.conf]
apachectl restart
/path/to/apache/sbin/apachectl restart: httpd not running, trying to start
[Tue Mar 31 11:27:55 1998] [debug] mod_so.c(303): loaded module foo_module
/path/to/apache/sbin/apachectl restart: httpd started
$ _
.fi
You can even use
.B apxs
to compile complex modules outside the Apache source tree, like PHP3:
.nf
$ cd php3
$ ./configure --with-shared-apache=../apache-1.3
$ apxs -c -o libphp3.so mod_php3.c libmodphp3-so.a
gcc -fpic -DSHARED_MODULE -I/tmp/apache/include -c mod_php3.c
ld -Bshareable -o libphp3.so mod_php3.o libmodphp3-so.a
$ _
.fi
because
.B apxs
automatically recognized C source files and object files. Only C source files
are compiled while remaining object files are used for the linking phase.
.PD
.SH SEE ALSO
.BR apachectl(1),
.BR httpd(8).
.

171
docs/man/dbmmanage.1 Normal file
View File

@@ -0,0 +1,171 @@
.TH dbmmanage 1 "March 1998"
.\" Copyright (c) 1998-1999 The Apache Group. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\"
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\"
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in
.\" the documentation and/or other materials provided with the
.\" distribution.
.\"
.\" 3. All advertising materials mentioning features or use of this
.\" software must display the following acknowledgment:
.\" "This product includes software developed by the Apache Group
.\" for use in the Apache HTTP server project (http://www.apache.org/)."
.\"
.\" 4. The names "Apache Server" and "Apache Group" must not be used to
.\" endorse or promote products derived from this software without
.\" prior written permission.
.\"
.\" 5. Products derived from this software may not be called "Apache"
.\" nor may "Apache" appear in their names without prior written
.\" permission of the Apache Group.
.\"
.\" 6. Redistributions of any form whatsoever must retain the following
.\" acknowledgment:
.\" "This product includes software developed by the Apache Group
.\" for use in the Apache HTTP server project (http://www.apache.org/)."
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
.\" OF THE POSSIBILITY OF SUCH DAMAGE.
.\" ====================================================================
.\"
.\" This software consists of voluntary contributions made by many
.\" individuals on behalf of the Apache Group and was originally based
.\" on public domain software written at the National Center for
.\" Supercomputing Applications, University of Illinois, Urbana-Champaign.
.\" For more information on the Apache Group and the Apache HTTP server
.\" project, please see <http://www.apache.org/>.
.SH NAME
dbmmanage \- Create and update user authentication files in DBM format
.SH SYNOPSIS
.B dbmmanage
.I filename
[
.I command
] [
.I username
[
.I encpasswd
] ]
.PP
.SH DESCRIPTION
.B dbmmanage
is used to create and update the DBM format files used to store
usernames and password for basic authentication of HTTP users.
Resources available from the
.B httpd
Apache web server can be restricted to just the users listed
in the files created by
.B dbmmanage.
This program can only be used
when the usernames are stored in a DBM file. To use a
flat-file database see
\fBhtpasswd\fP.
.PP
This manual page only lists the command line arguments. For details of
the directives necessary to configure user authentication in
.B httpd
see
the Apache manual, which is part of the Apache distribution or can be
found at http://www.apache.org/.
.SH OPTIONS
.IP \fB\fIfilename\fP
The filename of the DBM format file. Usually without the
extension .db, .pag, or .dir.
.IP \fB\fIcommand\fP
This selects the operation to perform:
.TP 12
.B add
Adds an entry for \fIusername\fP to \fIfilename\fP using the encrypted
password \fIencpassword\fP.
.TP 12
.B adduser
Asks for a password and then adds an entry for \fIusername\fP to
\fIfilename\fP .
.TP 12
.B check
Asks for a password and then checks if
\fIusername\fP is in \fIfilename\fP and if it's password matches
the specified one.
.TP 12
.B delete
Deletes the \fIusername\fP entry from \fIfilename\fP.
.TP 12
.B import
Reads username:password entries (one per line) from STDIN and adds them to
\fIfilename\fP. The passwords already has to be crypted.
.TP 12
.B update
Same as the "adduser" command, except that it makes sure \fIusername\fP
already exists in \fIfilename\fP.
.TP 12
.B view
Just displays the complete contents of the DBM file.
.IP \fB\fIusername\fP
The user for which the update operation is performed.
.PD
.SH BUGS
.PP
One should be aware that there are a number of different DBM file
formats in existance, and with all likelihood, libraries for more than
one format may exist on your system. The three primary examples are
NDBM, the GNU project's GDBM, and Berkeley DB 2. Unfortunately, all
these libraries use different file formats, and you must make sure
that the file format used by
.I filename
is the same format that
.B dbmmanage
expects to see.
.B dbmmanage
currently has no way of determining what type of DBM file it is
looking at. If used against the wrong format,
.dbmmanage
will simply return nothing, or may create a different DBM file with a
different name, or at worst, it may corrupt the DBM file if you were
attempting to write to it.
.PP
.B dbmmanage
has a list of DBM format preferences, defined by the
.B @AnyDBM::ISA
array near the beginning of the program. Since we prefer the Berkeley
DB 2 file format, the order in which
.B dbmmanage
will look for system libraries is Berkeley DB 2, then NDBM, and then
GDBM. The first library found will be the library
.B dbmmanage
will attempt to use for all DBM file transactions. This ordering is
slightly different than the standard
.B @AnyDBM::ISA
ordering in perl, as well as the ordering used by the simple dbmopen()
call in Perl, so if you use any other utilities to manage your DBM
files, they must also follow this preference ordering. Similar care
must be taken if using programs in other languages, like C, to
access these files.
.PP
Apache's
.B mod_auth_db.c
module corresponds to Berkeley DB 2 library, while
.B mod_auth_dbm.c
corresponds to the NDBM library. Also, one can usually use the
.B file
program supplied with most Unix systems to see what format a DBM file is in.
.PD
.SH SEE ALSO
.BR httpd(8)
.

97
docs/man/htdigest.1 Normal file
View File

@@ -0,0 +1,97 @@
.TH htdigest 1 "March 1998"
.\" Copyright (c) 1997-1999 The Apache Group. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\"
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\"
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in
.\" the documentation and/or other materials provided with the
.\" distribution.
.\"
.\" 3. All advertising materials mentioning features or use of this
.\" software must display the following acknowledgment:
.\" "This product includes software developed by the Apache Group
.\" for use in the Apache HTTP server project (http://www.apache.org/)."
.\"
.\" 4. The names "Apache Server" and "Apache Group" must not be used to
.\" endorse or promote products derived from this software without
.\" prior written permission. For written permission, please contact
.\" apache@apache.org.
.\"
.\" 5. Products derived from this software may not be called "Apache"
.\" nor may "Apache" appear in their names without prior written
.\" permission of the Apache Group.
.\"
.\" 6. Redistributions of any form whatsoever must retain the following
.\" acknowledgment:
.\" "This product includes software developed by the Apache Group
.\" for use in the Apache HTTP server project (http://www.apache.org/)."
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
.\" OF THE POSSIBILITY OF SUCH DAMAGE.
.\" ====================================================================
.\"
.\" This software consists of voluntary contributions made by many
.\" individuals on behalf of the Apache Group and was originally based
.\" on public domain software written at the National Center for
.\" Supercomputing Applications, University of Illinois, Urbana-Champaign.
.\" For more information on the Apache Group and the Apache HTTP server
.\" project, please see <http://www.apache.org/>.
.SH NAME
htdigest \- Create and update user authentication files
.SH SYNOPSIS
.B htdigest
[
.B \-c
]
.I passwdfile
.I realm
.I username
.SH DESCRIPTION
.B htdigest
is used to create and update the flat-files used to store
usernames, realm and password for digest authentication of HTTP users.
Resources available from the
.B httpd
Apache web server can be restricted to just the users listed
in the files created by
.B htdigest.
.PP
This manual page only lists the command line arguments. For details of
the directives necessary to configure digest authentication in
.B httpd
see
the Apache manual, which is part of the Apache distribution or can be
found at http://www.apache.org/.
.SH OPTIONS
.IP \-c
Create the \fIpasswdfile\fP. If \fIpasswdfile\fP already exists, it
is deleted first.
.IP \fB\fIpasswdfile\fP
Name of the file to contain the username, realm and password. If \-c
is given, this file is created if it does not already exist,
or deleted and recreated if it does exist.
.IP \fB\fIrealm\fP
The realm name to which the user name belongs to.
.IP \fB\fIusername\fP
The user name to create or update in \fBpasswdfile\fP. If
\fIusername\fP does not exist is this file, an entry is added. If it
does exist, the password is changed.
.SH SEE ALSO
.BR httpd(8)
.

213
docs/man/htpasswd.1 Normal file
View File

@@ -0,0 +1,213 @@
.TH htpasswd 1 "February 1997"
.\" Copyright (c) 1997-1999 The Apache Group. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\"
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\"
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in
.\" the documentation and/or other materials provided with the
.\" distribution.
.\"
.\" 3. All advertising materials mentioning features or use of this
.\" software must display the following acknowledgment:
.\" "This product includes software developed by the Apache Group
.\" for use in the Apache HTTP server project (http://www.apache.org/)."
.\"
.\" 4. The names "Apache Server" and "Apache Group" must not be used to
.\" endorse or promote products derived from this software without
.\" prior written permission. For written permission, please contact
.\" apache@apache.org.
.\"
.\" 5. Products derived from this software may not be called "Apache"
.\" nor may "Apache" appear in their names without prior written
.\" permission of the Apache Group.
.\"
.\" 6. Redistributions of any form whatsoever must retain the following
.\" acknowledgment:
.\" "This product includes software developed by the Apache Group
.\" for use in the Apache HTTP server project (http://www.apache.org/)."
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
.\" OF THE POSSIBILITY OF SUCH DAMAGE.
.\" ====================================================================
.\"
.\" This software consists of voluntary contributions made by many
.\" individuals on behalf of the Apache Group and was originally based
.\" on public domain software written at the National Center for
.\" Supercomputing Applications, University of Illinois, Urbana-Champaign.
.\" For more information on the Apache Group and the Apache HTTP server
.\" project, please see <http://www.apache.org/>.
.SH NAME
htpasswd \- Create and update user authentication files
.SH SYNOPSIS
.B htpasswd
[
.B \-c
]
[
.B \-m
]
.I passwdfile
.I username
.br
.B htpasswd
.B \-b
[
.B \-c
]
[
.B \-m
.B \-d
.B \-p
.B \-s
]
.I passwdfile
.I username
.I password
.SH DESCRIPTION
.B htpasswd
is used to create and update the flat-files used to store
usernames and password for basic authentication of HTTP users.
If
.B htpasswd
cannot access a file, such as not being able to write to the output
file or not being able to read the file in order to update it,
it returns an error status and makes no changes.
.PP
Resources available from the
.B httpd
Apache web server can be restricted to just the users listed
in the files created by
.B htpasswd.
This program can only be used
when the usernames are stored in a flat-file. To use a
DBM database see
\fBdbmmanage\fP.
.PP
.B htpasswd
encrypts passwords using either a version of MD5 modified for Apache,
or the system's \fIcrypt()\fP routine. Files managed by
.B htpasswd
may contain both types of passwords; some user records may have
MD5-encrypted passwords while others in the same file may have passwords
encrypted with \fIcrypt()\fP.
.PP
This manual page only lists the command line arguments. For details of
the directives necessary to configure user authentication in
.B httpd
see
the Apache manual, which is part of the Apache distribution or can be
found at <URL:http://www.apache.org/>.
.SH OPTIONS
.IP \-b
Use batch mode; \fIi.e.\fP, get the password from the command line
rather than prompting for it. \fBThis option should be used with
extreme care, since the password is clearly visible on the command
line.\fP
.IP \-c
Create the \fIpasswdfile\fP. If \fIpasswdfile\fP already exists, it
is rewritten and truncated.
.IP \-m
Use MD5 encryption for passwords. On Windows and TPF, this is the default.
.IP \-d
Use crypt() encryption for passwords. The default on all platforms but
Windows and TPF. Though possibly supported by
.B htpasswd
onm all platforms, it is not supported by the
.B httpd
server on Windows and TPF.
.IP \-s
Use SHA encryption for passwords. Faciliates migration from/to Netscape
servers using the LDAP Directory Interchange Format (ldif).
.IP \-p
Use plaintext passwords. Though
.B htpasswd
will support creation on all platofrms, the
.B httpd
deamon will only accept plain text passwords on Windows and TPF.
.IP \fB\fIpasswdfile\fP
Name of the file to contain the user name and password. If \-c
is given, this file is created if it does not already exist,
or rewritten and truncated if it does exist.
.IP \fB\fIusername\fP
The username to create or update in \fBpasswdfile\fP. If
\fIusername\fP does not exist in this file, an entry is added. If it
does exist, the password is changed.
.IP \fB\fIpassword\fP
The plaintext password to be encrypted and stored in the file. Only used
with the \fI-b\fP flag.
.SH EXIT STATUS
.B htpasswd
returns a zero status ("true") if the username and password have
been successfully added or updated in the \fIpasswdfile\fP.
.B htpasswd
returns 1 if it encounters some problem accessing files, 2 if there
was a syntax problem with the command line, 3 if the password was
entered interactively and the verification entry didn't match, 4 if
its operation was interrupted, 5 if a value is too long (username,
filename, password, or final computed record), and 6 if the username
contains illegal characters (see the \fBRESTRICTIONS\fP section).
.SH EXAMPLES
\fBhtpasswd /usr/local/etc/apache/.htpasswd-users jsmith\fP
.IP
Adds or modifies the password for user \fIjsmith\fP.
The user is prompted for the password. If executed
on a Windows system, the password will be encrypted using the
modified Apache MD5 algorithm; otherwise, the system's
\fIcrypt()\fP routine will be used. If the file does not
exist,
.B htpasswd
will do nothing except return an error.
.LP
\fBhtpasswd -c /home/doe/public_html/.htpasswd jane\fP
.IP
Creates a new file and stores a record in it for user \fIjane\fP.
The user is prompted for the password.
If the file exists and cannot be read, or cannot be written,
it is not altered and
.B htpasswd
will display a message and return an error status.
.LP
\fBhtpasswd -mb /usr/web/.htpasswd-all jones Pwd4Steve\fP
.IP
Encrypts the password from the command line (\fIPwd4Steve\fP) using
the MD5 algorithm, and stores it in the specified file.
.LP
.SH SECURITY CONSIDERATIONS
Web password files such as those managed by
.B htpasswd
should \fBnot\fP be within the Web server's URI space -- that is,
they should not be fetchable with a browser.
.PP
The use of the \fI-b\fP option is discouraged, since when it is
used the unencrypted password appears on the command line.
.SH RESTRICTIONS
On the Windows and MPE platforms, passwords encrypted with
.B htpasswd
are limited to no more than 255 characters in length. Longer
passwords will be truncated to 255 characters.
.PP
The MD5 algorithm used by
.B htpasswd
is specific to the Apache software; passwords encrypted using it will not be
usable with other Web servers.
.PP
Usernames are limited to 255 bytes and may not include the character ':'.
.SH SEE ALSO
.BR httpd(8)
and the scripts in support/SHA1 which come with the distribution.

211
docs/man/httpd.8 Normal file
View File

@@ -0,0 +1,211 @@
.TH httpd 8 "February 1997"
.\" Copyright (c) 1995-1997 David Robinson. All rights reserved.
.\" Copyright (c) 1997-1999 The Apache Group. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\"
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\"
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in
.\" the documentation and/or other materials provided with the
.\" distribution.
.\"
.\" 3. All advertising materials mentioning features or use of this
.\" software must display the following acknowledgment:
.\" "This product includes software developed by the Apache Group
.\" for use in the Apache HTTP server project (http://www.apache.org/)."
.\"
.\" 4. The names "Apache Server" and "Apache Group" must not be used to
.\" endorse or promote products derived from this software without
.\" prior written permission. For written permission, please contact
.\" apache@apache.org.
.\"
.\" 5. Products derived from this software may not be called "Apache"
.\" nor may "Apache" appear in their names without prior written
.\" permission of the Apache Group.
.\"
.\" 6. Redistributions of any form whatsoever must retain the following
.\" acknowledgment:
.\" "This product includes software developed by the Apache Group
.\" for use in the Apache HTTP server project (http://www.apache.org/)."
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
.\" OF THE POSSIBILITY OF SUCH DAMAGE.
.\" ====================================================================
.\"
.\" This software consists of voluntary contributions made by many
.\" individuals on behalf of the Apache Group and was originally based
.\" on public domain software written at the National Center for
.\" Supercomputing Applications, University of Illinois, Urbana-Champaign.
.\" For more information on the Apache Group and the Apache HTTP server
.\" project, please see <http://www.apache.org/>.
.SH NAME
httpd \- Apache hypertext transfer protocol server
.SH SYNOPSIS
.B httpd
[
.B \-X
] [
.BI \-R " libexecdir"
] [
.BI \-d " serverroot"
] [
.BI \-f " config"
] [
.BI \-C " directive"
] [
.BI \-c " directive"
] [
.BI \-D " parameter"
]
.B httpd
[
.B \-h
]
[
.B \-l
]
[
.B \-L
]
[
.B \-v
]
[
.B \-V
]
[
.B \-S
]
[
.B \-t
]
[
.B \-T
]
.SH DESCRIPTION
.B httpd
is the Apache HyperText Transfer Protocol (HTTP) server program. It is
designed to be run as a standalone daemon process. When used like this
it will create a pool of child processes to handle requests. To stop
it, send a TERM signal to the initial (parent) process. The PID of
this process is written to a file as given in the configuration file.
Alternatively
.B httpd
may be invoked by the Internet daemon inetd(8) each
time a connection to the HTTP service is made.
.PP
This manual page only lists the command line arguments. For details
of the directives necessary to configure
.B httpd
see the Apache manual,
which is part of the Apache distribution or can be found at
http://www.apache.org/. Paths in this manual may not reflect those
compiled into
.B httpd.
.SH OPTIONS
.TP 12
.BI \-R " libexecdir"
This option is only available if Apache was built with
the
.I SHARED_CORE
rule enabled which forces the Apache core code to be
placed into a dynamic shared object (DSO) file. This file
is searched in a hardcoded path under ServerRoot per default. Use this
option if you want to override it.
.TP 12
.BI \-d " serverroot"
Set the initial value for the ServerRoot directive to \fIserverroot\fP. This
can be overridden by the ServerRoot command in the configuration file. The
default is \fB/usr/local/apache\fP.
.TP
.BI \-f " config"
Execute the commands in the file \fIconfig\fP on startup. If \fIconfig\fP
does not begin with a /, then it is taken to be a path relative to
the ServerRoot. The default is \fBconf/httpd.conf\fP.
.TP
.BI \-C " directive"
Process the configuration \fIdirective\fP before reading config files.
.TP
.BI \-c " directive"
Process the configuration \fIdirective\fP after reading config files.
.TP
.BI \-D " parameter"
Sets a configuration \fIparameter\fP which can be used with
<IfDefine>...</IfDefine> sections in the configuration files
to conditionally skip or process commands.
.TP
.B \-h
Output a short summary of available command line options.
.TP
.B \-l
Output a list of modules compiled into the server.
.TP
.B \-L
Output a list of directives together with expected arguments and
places where the directive is valid.
.TP
.B \-S
Show the settings as parsed from the config file (currently only shows the
virtualhost settings).
.TP
.B \-t
Run syntax tests for configuration files only. The program immediately exits
after these syntax parsing with either a return code of 0 (Syntax OK) or
return code not equal to 0 (Syntax Error).
.TP
.B \-T
Same as option
.B \-t
but does not check the configured document roots.
.TP
.B \-X
Run in single-process mode, for internal debugging purposes only; the daemon
does not detach from the terminal or fork any children. Do NOT use this mode
to provide ordinary web service.
.TP
.B \-v
Print the version of
.B httpd
, and then exit.
.TP
.B \-V
Print the version and build parameters of
.B httpd
, and then exit.
.SH FILES
.PD 0
.B /usr/local/apache/conf/httpd.conf
.br
.B /usr/local/apache/conf/srm.conf
.br
.B /usr/local/apache/conf/access.conf
.br
.B /usr/local/apache/conf/mime.types
.br
.B /usr/local/apache/conf/magic
.br
.B /usr/local/apache/logs/error_log
.br
.B /usr/local/apache/logs/access_log
.br
.B /usr/local/apache/logs/httpd.pid
.PD
.SH SEE ALSO
.BR inetd (8).

87
docs/man/logresolve.8 Normal file
View File

@@ -0,0 +1,87 @@
.TH logresolve 8 "March 1998"
.\" Copyright (c) 1998-1999 The Apache Group. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\"
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\"
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in
.\" the documentation and/or other materials provided with the
.\" distribution.
.\"
.\" 3. All advertising materials mentioning features or use of this
.\" software must display the following acknowledgment:
.\" "This product includes software developed by the Apache Group
.\" for use in the Apache HTTP server project (http://www.apache.org/)."
.\"
.\" 4. The names "Apache Server" and "Apache Group" must not be used to
.\" endorse or promote products derived from this software without
.\" prior written permission.
.\"
.\" 5. Products derived from this software may not be called "Apache"
.\" nor may "Apache" appear in their names without prior written
.\" permission of the Apache Group.
.\"
.\" 6. Redistributions of any form whatsoever must retain the following
.\" acknowledgment:
.\" "This product includes software developed by the Apache Group
.\" for use in the Apache HTTP server project (http://www.apache.org/)."
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
.\" OF THE POSSIBILITY OF SUCH DAMAGE.
.\" ====================================================================
.\"
.\" This software consists of voluntary contributions made by many
.\" individuals on behalf of the Apache Group and was originally based
.\" on public domain software written at the National Center for
.\" Supercomputing Applications, University of Illinois, Urbana-Champaign.
.\" For more information on the Apache Group and the Apache HTTP server
.\" project, please see <http://www.apache.org/>.
.SH NAME
logresolve \- resolve hostnames for IP-adresses in Apache logfiles
.SH SYNOPSIS
.B logresolve
[
.BI \-s " filename"
] [
.B \-c
] <
.I access_log
>
.I access_log.new
.PP
.SH DESCRIPTION
.B logresolve
is a post-processing program to resolve IP-adresses in Apache's access
logfiles. To minimize impact on your nameserver, logresolve has its very own
internal hash-table cache. This means that each IP number will only be looked
up the first time it is found in the log file.
.SH OPTIONS
.TP 12
.BI \-s " filename"
Specifies a filename to record statistics.
.TP 12
.B \-c
This causes
.B logresolve
to apply some DNS checks: after finding the hostname from the IP address, it
looks up the IP addresses for the hostname and checks that one of these
matches the original address.
.PD
.SH SEE ALSO
.BR httpd(8)
.

83
docs/man/rotatelogs.8 Normal file
View File

@@ -0,0 +1,83 @@
.TH rotatelogs 8 "March 1998"
.\" Copyright (c) 1998-1999 The Apache Group. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\"
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\"
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in
.\" the documentation and/or other materials provided with the
.\" distribution.
.\"
.\" 3. All advertising materials mentioning features or use of this
.\" software must display the following acknowledgment:
.\" "This product includes software developed by the Apache Group
.\" for use in the Apache HTTP server project (http://www.apache.org/)."
.\"
.\" 4. The names "Apache Server" and "Apache Group" must not be used to
.\" endorse or promote products derived from this software without
.\" prior written permission.
.\"
.\" 5. Products derived from this software may not be called "Apache"
.\" nor may "Apache" appear in their names without prior written
.\" permission of the Apache Group.
.\"
.\" 6. Redistributions of any form whatsoever must retain the following
.\" acknowledgment:
.\" "This product includes software developed by the Apache Group
.\" for use in the Apache HTTP server project (http://www.apache.org/)."
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
.\" OF THE POSSIBILITY OF SUCH DAMAGE.
.\" ====================================================================
.\"
.\" This software consists of voluntary contributions made by many
.\" individuals on behalf of the Apache Group and was originally based
.\" on public domain software written at the National Center for
.\" Supercomputing Applications, University of Illinois, Urbana-Champaign.
.\" For more information on the Apache Group and the Apache HTTP server
.\" project, please see <http://www.apache.org/>.
.SH NAME
rotatelogs \- rotate Apache logs without having to kill the server
.SH SYNOPSIS
.B rotatelogs
.I logfile
.I rotationtime
.PP
.SH DESCRIPTION
.B rotatelogs
is a simple program for use in conjunction with Apache's piped logfile
feature which can be used like this:
.fi
TransferLog "|rotatelogs /path/to/logs/access_log 86400"
.mf
This creates the files /path/to/logs/access_log.nnnn where nnnn is the system
time at which the log nominally starts (this time will always be a multiple of
the rotation time, so you can synchronize cron scripts with it). At the end
of each rotation time (here after 24 hours) a new log is started.
.SH OPTIONS
.IP \fB\fIlogfile\fP
The path plus basename of the logfile. The suffix .nnnn is automatically
added.
.IP \fB\fIrotationtime\fP
The rotation time in seconds.
.PD
.SH SEE ALSO
.BR httpd(8)
.

70
docs/man/suexec.8 Normal file
View File

@@ -0,0 +1,70 @@
.TH suexec 8 "March 1998"
.\" Copyright (c) 1998-1999 The Apache Group. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\"
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\"
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in
.\" the documentation and/or other materials provided with the
.\" distribution.
.\"
.\" 3. All advertising materials mentioning features or use of this
.\" software must display the following acknowledgment:
.\" "This product includes software developed by the Apache Group
.\" for use in the Apache HTTP server project (http://www.apache.org/)."
.\"
.\" 4. The names "Apache Server" and "Apache Group" must not be used to
.\" endorse or promote products derived from this software without
.\" prior written permission.
.\"
.\" 5. Products derived from this software may not be called "Apache"
.\" nor may "Apache" appear in their names without prior written
.\" permission of the Apache Group.
.\"
.\" 6. Redistributions of any form whatsoever must retain the following
.\" acknowledgment:
.\" "This product includes software developed by the Apache Group
.\" for use in the Apache HTTP server project (http://www.apache.org/)."
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
.\" OF THE POSSIBILITY OF SUCH DAMAGE.
.\" ====================================================================
.\"
.\" This software consists of voluntary contributions made by many
.\" individuals on behalf of the Apache Group and was originally based
.\" on public domain software written at the National Center for
.\" Supercomputing Applications, University of Illinois, Urbana-Champaign.
.\" For more information on the Apache Group and the Apache HTTP server
.\" project, please see <http://www.apache.org/>.
.SH NAME
suexec \- Switch User For Exec
.SH SYNOPSIS
No synopsis for usage, because this program
is used internally by Apache only.
.PP
.SH DESCRIPTION
.B suexec
is the "wrapper" support program for the suEXEC behaviour for Apache.
It is run from within Apache automatically to switch the user when
an external program has to be run under a different user. For more
information about suEXEC see the document `Apache suEXEC Support'
under http://www.apache.org/docs/suexec.html .
.PD
.SH SEE ALSO
.BR httpd(8)
.

54
modules/aaa/.indent.pro vendored Normal file
View File

@@ -0,0 +1,54 @@
-i4 -npsl -di0 -br -nce -d0 -cli0 -npcs -nfc1
-TBUFF
-TFILE
-TTRANS
-TUINT4
-T_trans
-Tallow_options_t
-Tapache_sfio
-Tarray_header
-Tbool_int
-Tbuf_area
-Tbuff_struct
-Tbuffy
-Tcmd_how
-Tcmd_parms
-Tcommand_rec
-Tcommand_struct
-Tconn_rec
-Tcore_dir_config
-Tcore_server_config
-Tdir_maker_func
-Tevent
-Tglobals_s
-Thandler_func
-Thandler_rec
-Tjoblist_s
-Tlisten_rec
-Tmerger_func
-Tmode_t
-Tmodule
-Tmodule_struct
-Tmutex
-Tn_long
-Tother_child_rec
-Toverrides_t
-Tparent_score
-Tpid_t
-Tpiped_log
-Tpool
-Trequest_rec
-Trequire_line
-Trlim_t
-Tscoreboard
-Tsemaphore
-Tserver_addr_rec
-Tserver_rec
-Tserver_rec_chain
-Tshort_score
-Ttable
-Ttable_entry
-Tthread
-Tu_wide_int
-Tvtime_t
-Twide_int

View File

@@ -0,0 +1,113 @@
# Microsoft Developer Studio Project File - Name="ApacheModuleAuthAnon" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 5.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=ApacheModuleAuthAnon - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "ApacheModuleAuthAnon.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "ApacheModuleAuthAnon.mak"\
CFG="ApacheModuleAuthAnon - Win32 Release"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "ApacheModuleAuthAnon - Win32 Release" (based on\
"Win32 (x86) Dynamic-Link Library")
!MESSAGE "ApacheModuleAuthAnon - Win32 Debug" (based on\
"Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "ApacheModuleAuthAnon - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir ".\Release"
# PROP BASE Intermediate_Dir ".\Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir ".\ApacheModuleAuthAnonR"
# PROP Intermediate_Dir ".\ApacheModuleAuthAnonR"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "SHARED_MODULE" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x809 /d "NDEBUG"
# ADD RSC /l 0x809 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
# ADD LINK32 ..\..\CoreR\ApacheCore.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib /nologo /subsystem:windows /dll /machine:I386
!ELSEIF "$(CFG)" == "ApacheModuleAuthAnon - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir ".\Debug"
# PROP BASE Intermediate_Dir ".\Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir ".\ApacheModuleAuthAnonD"
# PROP Intermediate_Dir ".\ApacheModuleAuthAnonD"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "SHARED_MODULE" /YX /FD /c
# ADD BASE MTL /nologo /D "_DEBUG" /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x809 /d "_DEBUG"
# ADD RSC /l 0x809 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386
# ADD LINK32 ..\..\CoreD\ApacheCore.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib /nologo /subsystem:windows /dll /debug /machine:I386
!ENDIF
# Begin Target
# Name "ApacheModuleAuthAnon - Win32 Release"
# Name "ApacheModuleAuthAnon - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
# Begin Source File
SOURCE=..\..\modules\standard\mod_auth_anon.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
# Begin Source File
SOURCE=.\readdir.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

View File

@@ -0,0 +1,569 @@
/* ====================================================================
* Copyright (c) 1995-1999 The Apache Group. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* 4. The names "Apache Server" and "Apache Group" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Group and was originally based
* on public domain software written at the National Center for
* Supercomputing Applications, University of Illinois, Urbana-Champaign.
* For more information on the Apache Group and the Apache HTTP server
* project, please see <http://www.apache.org/>.
*
*/
/*
* mod_isapi.c - Internet Server Application (ISA) module for Apache
* by Alexei Kosut <akosut@apache.org>
*
* This module implements Microsoft's ISAPI, allowing Apache (when running
* under Windows) to load Internet Server Applications (ISAPI extensions).
* It implements all of the ISAPI 2.0 specification, except for the
* "Microsoft-only" extensions dealing with asynchronous I/O. All ISAPI
* extensions that use only synchronous I/O and are compatible with the
* ISAPI 2.0 specification should work (most ISAPI 1.0 extensions should
* function as well).
*
* To load, simply place the ISA in a location in the document tree.
* Then add an "AddHandler isapi-isa dll" into your config file.
* You should now be able to load ISAPI DLLs just be reffering to their
* URLs. Make sure the ExecCGI option is active in the directory
* the ISA is in.
*/
#include "httpd.h"
#include "http_config.h"
#include "http_core.h"
#include "http_protocol.h"
#include "http_request.h"
#include "http_log.h"
#include "util_script.h"
/* We use the exact same header file as the original */
#include <HttpExt.h>
/* Seems IIS does not enforce the requirement for \r\n termination on HSE_REQ_SEND_RESPONSE_HEADER,
define this to conform */
#define RELAX_HEADER_RULE
module isapi_module;
/* Our "Connection ID" structure */
typedef struct {
LPEXTENSION_CONTROL_BLOCK ecb;
request_rec *r;
int status;
} isapi_cid;
/* Declare the ISAPI functions */
BOOL WINAPI GetServerVariable (HCONN hConn, LPSTR lpszVariableName,
LPVOID lpvBuffer, LPDWORD lpdwSizeofBuffer);
BOOL WINAPI WriteClient (HCONN ConnID, LPVOID Buffer, LPDWORD lpwdwBytes,
DWORD dwReserved);
BOOL WINAPI ReadClient (HCONN ConnID, LPVOID lpvBuffer, LPDWORD lpdwSize);
BOOL WINAPI ServerSupportFunction (HCONN hConn, DWORD dwHSERequest,
LPVOID lpvBuffer, LPDWORD lpdwSize,
LPDWORD lpdwDataType);
/*
The optimiser blows it totally here. What happens is that autos are addressed relative to the
stack pointer, which, of course, moves around. The optimiser seems to lose track of it somewhere
between setting isapi_entry and calling through it. We work around the problem by forcing it to
use frame pointers.
*/
#pragma optimize("y",off)
int isapi_handler (request_rec *r) {
LPEXTENSION_CONTROL_BLOCK ecb =
ap_pcalloc(r->pool, sizeof(struct _EXTENSION_CONTROL_BLOCK));
HSE_VERSION_INFO *pVer = ap_pcalloc(r->pool, sizeof(HSE_VERSION_INFO));
HINSTANCE isapi_handle;
BOOL (*isapi_version)(HSE_VERSION_INFO *); /* entry point 1 */
DWORD (*isapi_entry)(LPEXTENSION_CONTROL_BLOCK); /* entry point 2 */
BOOL (*isapi_term)(DWORD); /* optional entry point 3 */
isapi_cid *cid = ap_pcalloc(r->pool, sizeof(isapi_cid));
table *e = r->subprocess_env;
int retval;
/* Use similar restrictions as CGIs */
if (!(ap_allow_options(r) & OPT_EXECCGI))
return FORBIDDEN;
if (r->finfo.st_mode == 0)
return NOT_FOUND;
if (S_ISDIR(r->finfo.st_mode))
return FORBIDDEN;
/* Load the module */
if (!(isapi_handle = LoadLibraryEx(r->filename, NULL,
LOAD_WITH_ALTERED_SEARCH_PATH))) {
ap_log_rerror(APLOG_MARK, APLOG_ALERT, r,
"Could not load DLL: %s", r->filename);
return SERVER_ERROR;
}
if (!(isapi_version =
(void *)(GetProcAddress(isapi_handle, "GetExtensionVersion")))) {
ap_log_rerror(APLOG_MARK, APLOG_ALERT, r,
"DLL could not load GetExtensionVersion(): %s", r->filename);
FreeLibrary(isapi_handle);
return SERVER_ERROR;
}
if (!(isapi_entry =
(void *)(GetProcAddress(isapi_handle, "HttpExtensionProc")))) {
ap_log_rerror(APLOG_MARK, APLOG_ALERT, r,
"DLL could not load HttpExtensionProc(): %s", r->filename);
FreeLibrary(isapi_handle);
return SERVER_ERROR;
}
isapi_term = (void *)(GetProcAddress(isapi_handle, "TerminateExtension"));
/* Run GetExtensionVersion() */
if ((*isapi_version)(pVer) != TRUE) {
ap_log_rerror(APLOG_MARK, APLOG_ALERT, r,
"ISAPI GetExtensionVersion() failed: %s", r->filename);
FreeLibrary(isapi_handle);
return SERVER_ERROR;
}
/* Set up variables */
ap_add_common_vars(r);
ap_add_cgi_vars(r);
/* Set up connection ID */
ecb->ConnID = (HCONN)cid;
cid->ecb = ecb;
cid->r = r;
cid->status = 0;
ecb->cbSize = sizeof(struct _EXTENSION_CONTROL_BLOCK);
ecb->dwVersion = MAKELONG(0, 2);
ecb->dwHttpStatusCode = 0;
strcpy(ecb->lpszLogData, "");
ecb->lpszMethod = r->method;
ecb->lpszQueryString = ap_table_get(e, "QUERY_STRING");
ecb->lpszPathInfo = ap_table_get(e, "PATH_INFO");
ecb->lpszPathTranslated = ap_table_get(e, "PATH_TRANSLATED");
ecb->lpszContentType = ap_table_get(e, "CONTENT_TYPE");
/* Set up client input */
if ((retval = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR))) {
if (isapi_term) (*isapi_term)(HSE_TERM_MUST_UNLOAD);
FreeLibrary(isapi_handle);
return retval;
}
if (ap_should_client_block(r)) {
/* Unlike IIS, which limits this to 48k, we read the whole
* sucker in. I suppose this could be bad for memory if someone
* uploaded the complete works of Shakespeare. Well, WebSite
* does the same thing.
*/
long to_read = atol(ap_table_get(e, "CONTENT_LENGTH"));
long read;
/* Actually, let's cap it at 48k, until we figure out what
* to do with this... we don't want a Content-Length: 1000000000
* taking out the machine.
*/
if (to_read > 49152) {
if (isapi_term) (*isapi_term)(HSE_TERM_MUST_UNLOAD);
FreeLibrary(isapi_handle);
return HTTP_REQUEST_ENTITY_TOO_LARGE;
}
ecb->lpbData = ap_pcalloc(r->pool, 1 + to_read);
if ((read = ap_get_client_block(r, ecb->lpbData, to_read)) < 0) {
if (isapi_term) (*isapi_term)(HSE_TERM_MUST_UNLOAD);
FreeLibrary(isapi_handle);
return SERVER_ERROR;
}
/* Although its not to spec, IIS seems to null-terminate
* its lpdData string. So we will too. To make sure
* cbAvailable matches cbTotalBytes, we'll up the latter
* and equalize them.
*/
ecb->cbAvailable = ecb->cbTotalBytes = read + 1;
ecb->lpbData[read] = '\0';
}
else {
ecb->cbTotalBytes = 0;
ecb->cbAvailable = 0;
ecb->lpbData = NULL;
}
/* Set up the callbacks */
ecb->GetServerVariable = &GetServerVariable;
ecb->WriteClient = &WriteClient;
ecb->ReadClient = &ReadClient;
ecb->ServerSupportFunction = &ServerSupportFunction;
/* All right... try and load the sucker */
retval = (*isapi_entry)(ecb);
/* Set the status (for logging) */
if (ecb->dwHttpStatusCode)
r->status = ecb->dwHttpStatusCode;
/* Check for a log message - and log it */
if (ecb->lpszLogData && strcmp(ecb->lpszLogData, ""))
ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
"%s: %s", ecb->lpszLogData, r->filename);
/* All done with the DLL... get rid of it */
if (isapi_term) (*isapi_term)(HSE_TERM_MUST_UNLOAD);
FreeLibrary(isapi_handle);
switch(retval) {
case HSE_STATUS_SUCCESS:
case HSE_STATUS_SUCCESS_AND_KEEP_CONN:
/* Ignore the keepalive stuff; Apache handles it just fine without
* the ISA's "advice".
*/
if (cid->status) /* We have a special status to return */
return cid->status;
return OK;
case HSE_STATUS_PENDING: /* We don't support this */
ap_log_rerror(APLOG_MARK, APLOG_WARNING, r,
"ISAPI asynchronous I/O not supported: %s", r->filename);
case HSE_STATUS_ERROR:
default:
return SERVER_ERROR;
}
}
#pragma optimize("",on)
BOOL WINAPI GetServerVariable (HCONN hConn, LPSTR lpszVariableName,
LPVOID lpvBuffer, LPDWORD lpdwSizeofBuffer) {
request_rec *r = ((isapi_cid *)hConn)->r;
table *e = r->subprocess_env;
const char *result;
/* Mostly, we just grab it from the environment, but there are
* a couple of special cases
*/
if (!strcasecmp(lpszVariableName, "UNMAPPED_REMOTE_USER")) {
/* We don't support NT users, so this is always the same as
* REMOTE_USER
*/
result = ap_table_get(e, "REMOTE_USER");
}
else if (!strcasecmp(lpszVariableName, "SERVER_PORT_SECURE")) {
/* Apache doesn't support secure requests inherently, so
* we have no way of knowing. We'll be conservative, and say
* all requests are insecure.
*/
result = "0";
}
else if (!strcasecmp(lpszVariableName, "URL")) {
result = r->uri;
}
else {
result = ap_table_get(e, lpszVariableName);
}
if (result) {
if (strlen(result) > *lpdwSizeofBuffer) {
*lpdwSizeofBuffer = strlen(result);
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return FALSE;
}
strncpy(lpvBuffer, result, *lpdwSizeofBuffer);
return TRUE;
}
/* Didn't find it */
SetLastError(ERROR_INVALID_INDEX);
return FALSE;
}
BOOL WINAPI WriteClient (HCONN ConnID, LPVOID Buffer, LPDWORD lpwdwBytes,
DWORD dwReserved) {
request_rec *r = ((isapi_cid *)ConnID)->r;
int writ; /* written, actually, but why shouldn't I make up words? */
/* We only support synchronous writing */
if (dwReserved && dwReserved != HSE_IO_SYNC) {
ap_log_rerror(APLOG_MARK, APLOG_WARNING, r,
"ISAPI asynchronous I/O not supported: %s", r->filename);
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if ((writ = ap_rwrite(Buffer, *lpwdwBytes, r)) == EOF) {
SetLastError(ERROR); /* XXX: Find the right error code */
return FALSE;
}
*lpwdwBytes = writ;
return TRUE;
}
BOOL WINAPI ReadClient (HCONN ConnID, LPVOID lpvBuffer, LPDWORD lpdwSize) {
/* Doesn't need to do anything; we've read all the data already */
return TRUE;
}
/* XXX: There is an O(n^2) attack possible here. */
BOOL WINAPI ServerSupportFunction (HCONN hConn, DWORD dwHSERequest,
LPVOID lpvBuffer, LPDWORD lpdwSize,
LPDWORD lpdwDataType) {
isapi_cid *cid = (isapi_cid *)hConn;
request_rec *subreq, *r = cid->r;
char *data;
switch (dwHSERequest) {
case HSE_REQ_SEND_URL_REDIRECT_RESP:
/* Set the status to be returned when the HttpExtensionProc()
* is done.
*/
ap_table_set (r->headers_out, "Location", lpvBuffer);
cid->status = cid->r->status = cid->ecb->dwHttpStatusCode = REDIRECT;
return TRUE;
case HSE_REQ_SEND_URL:
/* Read any additional input */
if (r->remaining > 0) {
char argsbuffer[HUGE_STRING_LEN];
while (ap_get_client_block(r, argsbuffer, HUGE_STRING_LEN));
}
/* Reset the method to GET */
r->method = ap_pstrdup(r->pool, "GET");
r->method_number = M_GET;
/* Don't let anyone think there's still data */
ap_table_unset(r->headers_in, "Content-Length");
ap_internal_redirect((char *)lpvBuffer, r);
return TRUE;
case HSE_REQ_SEND_RESPONSE_HEADER:
r->status_line = lpvBuffer ? lpvBuffer : ap_pstrdup(r->pool, "200 OK");
sscanf(r->status_line, "%d", &r->status);
cid->ecb->dwHttpStatusCode = r->status;
/* Now fill in the HTTP headers, and the rest of it. Ick.
* lpdwDataType contains a string that has headers (in MIME
* format), a blank like, then (possibly) data. We need
* to parse it.
*
* Easy case first:
*/
if (!lpdwDataType) {
ap_send_http_header(r);
return TRUE;
}
/* Make a copy - don't disturb the original */
data = ap_pstrdup(r->pool, (char *)lpdwDataType);
/* We *should* break before this while loop ends */
while (*data) {
char *value, *lf = strchr(data, '\n');
int p;
#ifdef RELAX_HEADER_RULE
if (lf)
*lf = '\0';
#else
if (!lf) { /* Huh? Invalid data, I think */
ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
"ISA sent invalid headers: %s", r->filename);
SetLastError(ERROR); /* XXX: Find right error */
return FALSE;
}
/* Get rid of \n and \r */
*lf = '\0';
#endif
p = strlen(data);
if (p > 0 && data[p-1] == '\r') data[p-1] = '\0';
/* End of headers */
if (*data == '\0') {
#ifdef RELAX_HEADER_RULE
if (lf)
#endif
data = lf + 1; /* Reset data */
break;
}
if (!(value = strchr(data, ':'))) {
SetLastError(ERROR); /* XXX: Find right error */
ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
"ISA sent invalid headers", r->filename);
return FALSE;
}
*value++ = '\0';
while (*value && ap_isspace(*value)) ++value;
/* Check all the special-case headers. Similar to what
* ap_scan_script_header_err() does (see that function for
* more detail)
*/
if (!strcasecmp(data, "Content-Type")) {
char *tmp;
/* Nuke trailing whitespace */
char *endp = value + strlen(value) - 1;
while (endp > value && ap_isspace(*endp)) *endp-- = '\0';
tmp = ap_pstrdup (r->pool, value);
ap_str_tolower(tmp);
r->content_type = tmp;
}
else if (!strcasecmp(data, "Content-Length")) {
ap_table_set(r->headers_out, data, value);
}
else if (!strcasecmp(data, "Transfer-Encoding")) {
ap_table_set(r->headers_out, data, value);
}
else if (!strcasecmp(data, "Set-Cookie")) {
ap_table_add(r->err_headers_out, data, value);
}
else {
ap_table_merge(r->err_headers_out, data, value);
}
/* Reset data */
#ifdef RELAX_HEADER_RULE
if (!lf) {
data += p;
break;
}
#endif
data = lf + 1;
}
/* All the headers should be set now */
ap_send_http_header(r);
/* Any data left should now be sent directly */
ap_rputs(data, r);
return TRUE;
case HSE_REQ_MAP_URL_TO_PATH:
/* Map a URL to a filename */
subreq = ap_sub_req_lookup_uri(ap_pstrndup(r->pool, (char *)lpvBuffer,
*lpdwSize), r);
GetFullPathName(subreq->filename, *lpdwSize - 1, (char *)lpvBuffer, NULL);
/* IIS puts a trailing slash on directories, Apache doesn't */
if (S_ISDIR (subreq->finfo.st_mode)) {
int l = strlen((char *)lpvBuffer);
((char *)lpvBuffer)[l] = '\\';
((char *)lpvBuffer)[l + 1] = '\0';
}
return TRUE;
case HSE_REQ_DONE_WITH_SESSION:
/* Do nothing... since we don't support async I/O, they'll
* return from HttpExtensionProc soon
*/
return TRUE;
/* We don't support all this async I/O, Microsoft-specific stuff */
case HSE_REQ_IO_COMPLETION:
case HSE_REQ_TRANSMIT_FILE:
ap_log_rerror(APLOG_MARK, APLOG_WARNING, r,
"ISAPI asynchronous I/O not supported: %s", r->filename);
default:
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
}
handler_rec isapi_handlers[] = {
{ "isapi-isa", isapi_handler },
{ NULL}
};
module isapi_module = {
STANDARD_MODULE_STUFF,
NULL, /* initializer */
NULL, /* create per-dir config */
NULL, /* merge per-dir config */
NULL, /* server config */
NULL, /* merge server config */
NULL, /* command table */
isapi_handlers, /* handlers */
NULL, /* filename translation */
NULL, /* check_user_id */
NULL, /* check auth */
NULL, /* check access */
NULL, /* type_checker */
NULL, /* logger */
NULL /* header parser */
};

54
modules/cache/.indent.pro vendored Normal file
View File

@@ -0,0 +1,54 @@
-i4 -npsl -di0 -br -nce -d0 -cli0 -npcs -nfc1
-TBUFF
-TFILE
-TTRANS
-TUINT4
-T_trans
-Tallow_options_t
-Tapache_sfio
-Tarray_header
-Tbool_int
-Tbuf_area
-Tbuff_struct
-Tbuffy
-Tcmd_how
-Tcmd_parms
-Tcommand_rec
-Tcommand_struct
-Tconn_rec
-Tcore_dir_config
-Tcore_server_config
-Tdir_maker_func
-Tevent
-Tglobals_s
-Thandler_func
-Thandler_rec
-Tjoblist_s
-Tlisten_rec
-Tmerger_func
-Tmode_t
-Tmodule
-Tmodule_struct
-Tmutex
-Tn_long
-Tother_child_rec
-Toverrides_t
-Tparent_score
-Tpid_t
-Tpiped_log
-Tpool
-Trequest_rec
-Trequire_line
-Trlim_t
-Tscoreboard
-Tsemaphore
-Tserver_addr_rec
-Tserver_rec
-Tserver_rec_chain
-Tshort_score
-Ttable
-Ttable_entry
-Tthread
-Tu_wide_int
-Tvtime_t
-Twide_int

54
modules/echo/.indent.pro vendored Normal file
View File

@@ -0,0 +1,54 @@
-i4 -npsl -di0 -br -nce -d0 -cli0 -npcs -nfc1
-TBUFF
-TFILE
-TTRANS
-TUINT4
-T_trans
-Tallow_options_t
-Tapache_sfio
-Tarray_header
-Tbool_int
-Tbuf_area
-Tbuff_struct
-Tbuffy
-Tcmd_how
-Tcmd_parms
-Tcommand_rec
-Tcommand_struct
-Tconn_rec
-Tcore_dir_config
-Tcore_server_config
-Tdir_maker_func
-Tevent
-Tglobals_s
-Thandler_func
-Thandler_rec
-Tjoblist_s
-Tlisten_rec
-Tmerger_func
-Tmode_t
-Tmodule
-Tmodule_struct
-Tmutex
-Tn_long
-Tother_child_rec
-Toverrides_t
-Tparent_score
-Tpid_t
-Tpiped_log
-Tpool
-Trequest_rec
-Trequire_line
-Trlim_t
-Tscoreboard
-Tsemaphore
-Tserver_addr_rec
-Tserver_rec
-Tserver_rec_chain
-Tshort_score
-Ttable
-Ttable_entry
-Tthread
-Tu_wide_int
-Tvtime_t
-Twide_int

54
modules/experimental/.indent.pro vendored Normal file
View File

@@ -0,0 +1,54 @@
-i4 -npsl -di0 -br -nce -d0 -cli0 -npcs -nfc1
-TBUFF
-TFILE
-TTRANS
-TUINT4
-T_trans
-Tallow_options_t
-Tapache_sfio
-Tarray_header
-Tbool_int
-Tbuf_area
-Tbuff_struct
-Tbuffy
-Tcmd_how
-Tcmd_parms
-Tcommand_rec
-Tcommand_struct
-Tconn_rec
-Tcore_dir_config
-Tcore_server_config
-Tdir_maker_func
-Tevent
-Tglobals_s
-Thandler_func
-Thandler_rec
-Tjoblist_s
-Tlisten_rec
-Tmerger_func
-Tmode_t
-Tmodule
-Tmodule_struct
-Tmutex
-Tn_long
-Tother_child_rec
-Toverrides_t
-Tparent_score
-Tpid_t
-Tpiped_log
-Tpool
-Trequest_rec
-Trequire_line
-Trlim_t
-Tscoreboard
-Tsemaphore
-Tserver_addr_rec
-Tserver_rec
-Tserver_rec_chain
-Tshort_score
-Ttable
-Ttable_entry
-Tthread
-Tu_wide_int
-Tvtime_t
-Twide_int

54
modules/filters/.indent.pro vendored Normal file
View File

@@ -0,0 +1,54 @@
-i4 -npsl -di0 -br -nce -d0 -cli0 -npcs -nfc1
-TBUFF
-TFILE
-TTRANS
-TUINT4
-T_trans
-Tallow_options_t
-Tapache_sfio
-Tarray_header
-Tbool_int
-Tbuf_area
-Tbuff_struct
-Tbuffy
-Tcmd_how
-Tcmd_parms
-Tcommand_rec
-Tcommand_struct
-Tconn_rec
-Tcore_dir_config
-Tcore_server_config
-Tdir_maker_func
-Tevent
-Tglobals_s
-Thandler_func
-Thandler_rec
-Tjoblist_s
-Tlisten_rec
-Tmerger_func
-Tmode_t
-Tmodule
-Tmodule_struct
-Tmutex
-Tn_long
-Tother_child_rec
-Toverrides_t
-Tparent_score
-Tpid_t
-Tpiped_log
-Tpool
-Trequest_rec
-Trequire_line
-Trlim_t
-Tscoreboard
-Tsemaphore
-Tserver_addr_rec
-Tserver_rec
-Tserver_rec_chain
-Tshort_score
-Ttable
-Ttable_entry
-Tthread
-Tu_wide_int
-Tvtime_t
-Twide_int

54
modules/generators/.indent.pro vendored Normal file
View File

@@ -0,0 +1,54 @@
-i4 -npsl -di0 -br -nce -d0 -cli0 -npcs -nfc1
-TBUFF
-TFILE
-TTRANS
-TUINT4
-T_trans
-Tallow_options_t
-Tapache_sfio
-Tarray_header
-Tbool_int
-Tbuf_area
-Tbuff_struct
-Tbuffy
-Tcmd_how
-Tcmd_parms
-Tcommand_rec
-Tcommand_struct
-Tconn_rec
-Tcore_dir_config
-Tcore_server_config
-Tdir_maker_func
-Tevent
-Tglobals_s
-Thandler_func
-Thandler_rec
-Tjoblist_s
-Tlisten_rec
-Tmerger_func
-Tmode_t
-Tmodule
-Tmodule_struct
-Tmutex
-Tn_long
-Tother_child_rec
-Toverrides_t
-Tparent_score
-Tpid_t
-Tpiped_log
-Tpool
-Trequest_rec
-Trequire_line
-Trlim_t
-Tscoreboard
-Tsemaphore
-Tserver_addr_rec
-Tserver_rec
-Tserver_rec_chain
-Tshort_score
-Ttable
-Ttable_entry
-Tthread
-Tu_wide_int
-Tvtime_t
-Twide_int

View File

@@ -0,0 +1,112 @@
# Microsoft Developer Studio Project File - Name="ApacheModuleInfo" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 5.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=ApacheModuleInfo - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "ApacheModuleInfo.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "ApacheModuleInfo.mak" CFG="ApacheModuleInfo - Win32 Release"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "ApacheModuleInfo - Win32 Release" (based on\
"Win32 (x86) Dynamic-Link Library")
!MESSAGE "ApacheModuleInfo - Win32 Debug" (based on\
"Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "ApacheModuleInfo - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir ".\Release"
# PROP BASE Intermediate_Dir ".\Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir ".\ApacheModuleInfoR"
# PROP Intermediate_Dir ".\ApacheModuleInfoR"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "SHARED_MODULE" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x809 /d "NDEBUG"
# ADD RSC /l 0x809 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
# ADD LINK32 ..\..\CoreR\ApacheCore.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib /nologo /subsystem:windows /dll /machine:I386
!ELSEIF "$(CFG)" == "ApacheModuleInfo - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir ".\Debug"
# PROP BASE Intermediate_Dir ".\Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir ".\ApacheModuleInfoD"
# PROP Intermediate_Dir ".\ApacheModuleInfoD"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "SHARED_MODULE" /YX /FD /c
# ADD BASE MTL /nologo /D "_DEBUG" /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x809 /d "_DEBUG"
# ADD RSC /l 0x809 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386
# ADD LINK32 ..\..\CoreD\ApacheCore.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib /nologo /subsystem:windows /dll /debug /machine:I386
!ENDIF
# Begin Target
# Name "ApacheModuleInfo - Win32 Release"
# Name "ApacheModuleInfo - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
# Begin Source File
SOURCE=..\..\modules\standard\mod_info.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
# Begin Source File
SOURCE=.\readdir.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

View File

@@ -0,0 +1,113 @@
# Microsoft Developer Studio Project File - Name="ApacheModuleStatus" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 5.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=ApacheModuleStatus - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "ApacheModuleStatus.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "ApacheModuleStatus.mak"\
CFG="ApacheModuleStatus - Win32 Release"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "ApacheModuleStatus - Win32 Release" (based on\
"Win32 (x86) Dynamic-Link Library")
!MESSAGE "ApacheModuleStatus - Win32 Debug" (based on\
"Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "ApacheModuleStatus - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir ".\Release"
# PROP BASE Intermediate_Dir ".\Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir ".\ApacheModuleStatusR"
# PROP Intermediate_Dir ".\ApacheModuleStatusR"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "SHARED_MODULE" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x809 /d "NDEBUG"
# ADD RSC /l 0x809 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
# ADD LINK32 ..\..\CoreR\ApacheCore.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib /nologo /subsystem:windows /dll /machine:I386
!ELSEIF "$(CFG)" == "ApacheModuleStatus - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir ".\Debug"
# PROP BASE Intermediate_Dir ".\Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir ".\ApacheModuleStatusD"
# PROP Intermediate_Dir ".\ApacheModuleStatusD"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "SHARED_MODULE" /YX /FD /c
# ADD BASE MTL /nologo /D "_DEBUG" /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x809 /d "_DEBUG"
# ADD RSC /l 0x809 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386
# ADD LINK32 ..\..\CoreD\ApacheCore.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib /nologo /subsystem:windows /dll /debug /machine:I386
!ENDIF
# Begin Target
# Name "ApacheModuleStatus - Win32 Release"
# Name "ApacheModuleStatus - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
# Begin Source File
SOURCE=..\..\modules\standard\mod_status.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
# Begin Source File
SOURCE=.\readdir.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

54
modules/http/.indent.pro vendored Normal file
View File

@@ -0,0 +1,54 @@
-i4 -npsl -di0 -br -nce -d0 -cli0 -npcs -nfc1
-TBUFF
-TFILE
-TTRANS
-TUINT4
-T_trans
-Tallow_options_t
-Tapache_sfio
-Tarray_header
-Tbool_int
-Tbuf_area
-Tbuff_struct
-Tbuffy
-Tcmd_how
-Tcmd_parms
-Tcommand_rec
-Tcommand_struct
-Tconn_rec
-Tcore_dir_config
-Tcore_server_config
-Tdir_maker_func
-Tevent
-Tglobals_s
-Thandler_func
-Thandler_rec
-Tjoblist_s
-Tlisten_rec
-Tmerger_func
-Tmode_t
-Tmodule
-Tmodule_struct
-Tmutex
-Tn_long
-Tother_child_rec
-Toverrides_t
-Tparent_score
-Tpid_t
-Tpiped_log
-Tpool
-Trequest_rec
-Trequire_line
-Trlim_t
-Tscoreboard
-Tsemaphore
-Tserver_addr_rec
-Tserver_rec
-Tserver_rec_chain
-Tshort_score
-Ttable
-Ttable_entry
-Tthread
-Tu_wide_int
-Tvtime_t
-Twide_int

3214
modules/http/http_core.c Normal file

File diff suppressed because it is too large Load Diff

2763
modules/http/http_protocol.c Normal file

File diff suppressed because it is too large Load Diff

1374
modules/http/http_request.c Normal file

File diff suppressed because it is too large Load Diff

54
modules/loggers/.indent.pro vendored Normal file
View File

@@ -0,0 +1,54 @@
-i4 -npsl -di0 -br -nce -d0 -cli0 -npcs -nfc1
-TBUFF
-TFILE
-TTRANS
-TUINT4
-T_trans
-Tallow_options_t
-Tapache_sfio
-Tarray_header
-Tbool_int
-Tbuf_area
-Tbuff_struct
-Tbuffy
-Tcmd_how
-Tcmd_parms
-Tcommand_rec
-Tcommand_struct
-Tconn_rec
-Tcore_dir_config
-Tcore_server_config
-Tdir_maker_func
-Tevent
-Tglobals_s
-Thandler_func
-Thandler_rec
-Tjoblist_s
-Tlisten_rec
-Tmerger_func
-Tmode_t
-Tmodule
-Tmodule_struct
-Tmutex
-Tn_long
-Tother_child_rec
-Toverrides_t
-Tparent_score
-Tpid_t
-Tpiped_log
-Tpool
-Trequest_rec
-Trequire_line
-Trlim_t
-Tscoreboard
-Tsemaphore
-Tserver_addr_rec
-Tserver_rec
-Tserver_rec_chain
-Tshort_score
-Ttable
-Ttable_entry
-Tthread
-Tu_wide_int
-Tvtime_t
-Twide_int

54
modules/mappers/.indent.pro vendored Normal file
View File

@@ -0,0 +1,54 @@
-i4 -npsl -di0 -br -nce -d0 -cli0 -npcs -nfc1
-TBUFF
-TFILE
-TTRANS
-TUINT4
-T_trans
-Tallow_options_t
-Tapache_sfio
-Tarray_header
-Tbool_int
-Tbuf_area
-Tbuff_struct
-Tbuffy
-Tcmd_how
-Tcmd_parms
-Tcommand_rec
-Tcommand_struct
-Tconn_rec
-Tcore_dir_config
-Tcore_server_config
-Tdir_maker_func
-Tevent
-Tglobals_s
-Thandler_func
-Thandler_rec
-Tjoblist_s
-Tlisten_rec
-Tmerger_func
-Tmode_t
-Tmodule
-Tmodule_struct
-Tmutex
-Tn_long
-Tother_child_rec
-Toverrides_t
-Tparent_score
-Tpid_t
-Tpiped_log
-Tpool
-Trequest_rec
-Trequire_line
-Trlim_t
-Tscoreboard
-Tsemaphore
-Tserver_addr_rec
-Tserver_rec
-Tserver_rec_chain
-Tshort_score
-Ttable
-Ttable_entry
-Tthread
-Tu_wide_int
-Tvtime_t
-Twide_int

View File

@@ -0,0 +1,117 @@
# Microsoft Developer Studio Project File - Name="ApacheModuleRewrite" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 5.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=ApacheModuleRewrite - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "ApacheModuleRewrite.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "ApacheModuleRewrite.mak"\
CFG="ApacheModuleRewrite - Win32 Release"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "ApacheModuleRewrite - Win32 Release" (based on\
"Win32 (x86) Dynamic-Link Library")
!MESSAGE "ApacheModuleRewrite - Win32 Debug" (based on\
"Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "ApacheModuleRewrite - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir ".\Release"
# PROP BASE Intermediate_Dir ".\Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir ".\ApacheModuleRewriteR"
# PROP Intermediate_Dir ".\ApacheModuleRewriteR"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "NO_DBM_REWRITEMAP" /D "SHARED_MODULE" /D "WIN32_LEAN_AND_MEAN" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x809 /d "NDEBUG"
# ADD RSC /l 0x809 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
# ADD LINK32 ..\..\CoreR\ApacheCore.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ws2_32.lib /nologo /subsystem:windows /dll /machine:I386
!ELSEIF "$(CFG)" == "ApacheModuleRewrite - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir ".\Debug"
# PROP BASE Intermediate_Dir ".\Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir ".\ApacheModuleRewriteD"
# PROP Intermediate_Dir ".\ApacheModuleRewriteD"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "NO_DBM_REWRITEMAP" /D "SHARED_MODULE" /D "WIN32_LEAN_AND_MEAN" /YX /FD /c
# ADD BASE MTL /nologo /D "_DEBUG" /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x809 /d "_DEBUG"
# ADD RSC /l 0x809 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386
# ADD LINK32 ..\..\CoreD\ApacheCore.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ws2_32.lib /nologo /subsystem:windows /dll /debug /machine:I386
!ENDIF
# Begin Target
# Name "ApacheModuleRewrite - Win32 Release"
# Name "ApacheModuleRewrite - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
# Begin Source File
SOURCE=..\..\modules\standard\mod_rewrite.c
# End Source File
# Begin Source File
SOURCE=.\passwd.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
# Begin Source File
SOURCE=.\readdir.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

View File

@@ -0,0 +1,113 @@
# Microsoft Developer Studio Project File - Name="ApacheModuleSpeling" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 5.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=ApacheModuleSpeling - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "ApacheModuleSpeling.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "ApacheModuleSpeling.mak"\
CFG="ApacheModuleSpeling - Win32 Release"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "ApacheModuleSpeling - Win32 Release" (based on\
"Win32 (x86) Dynamic-Link Library")
!MESSAGE "ApacheModuleSpeling - Win32 Debug" (based on\
"Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "ApacheModuleSpeling - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir ".\Release"
# PROP BASE Intermediate_Dir ".\Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir ".\ApacheModuleSpelingR"
# PROP Intermediate_Dir ".\ApacheModuleSpelingR"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "SHARED_MODULE" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x809 /d "NDEBUG"
# ADD RSC /l 0x809 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
# ADD LINK32 ..\..\CoreR\ApacheCore.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib /nologo /subsystem:windows /dll /machine:I386
!ELSEIF "$(CFG)" == "ApacheModuleSpeling - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir ".\Debug"
# PROP BASE Intermediate_Dir ".\Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir ".\ApacheModuleSpelingD"
# PROP Intermediate_Dir ".\ApacheModuleSpelingD"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "SHARED_MODULE" /YX /FD /c
# ADD BASE MTL /nologo /D "_DEBUG" /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x809 /d "_DEBUG"
# ADD RSC /l 0x809 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386
# ADD LINK32 ..\..\CoreD\ApacheCore.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib /nologo /subsystem:windows /dll /debug /machine:I386
!ENDIF
# Begin Target
# Name "ApacheModuleSpeling - Win32 Release"
# Name "ApacheModuleSpeling - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
# Begin Source File
SOURCE=..\..\modules\standard\mod_speling.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
# Begin Source File
SOURCE=.\readdir.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

54
modules/metadata/.indent.pro vendored Normal file
View File

@@ -0,0 +1,54 @@
-i4 -npsl -di0 -br -nce -d0 -cli0 -npcs -nfc1
-TBUFF
-TFILE
-TTRANS
-TUINT4
-T_trans
-Tallow_options_t
-Tapache_sfio
-Tarray_header
-Tbool_int
-Tbuf_area
-Tbuff_struct
-Tbuffy
-Tcmd_how
-Tcmd_parms
-Tcommand_rec
-Tcommand_struct
-Tconn_rec
-Tcore_dir_config
-Tcore_server_config
-Tdir_maker_func
-Tevent
-Tglobals_s
-Thandler_func
-Thandler_rec
-Tjoblist_s
-Tlisten_rec
-Tmerger_func
-Tmode_t
-Tmodule
-Tmodule_struct
-Tmutex
-Tn_long
-Tother_child_rec
-Toverrides_t
-Tparent_score
-Tpid_t
-Tpiped_log
-Tpool
-Trequest_rec
-Trequire_line
-Trlim_t
-Tscoreboard
-Tsemaphore
-Tserver_addr_rec
-Tserver_rec
-Tserver_rec_chain
-Tshort_score
-Ttable
-Ttable_entry
-Tthread
-Tu_wide_int
-Tvtime_t
-Twide_int

View File

@@ -0,0 +1,113 @@
# Microsoft Developer Studio Project File - Name="ApacheModuleCERNMeta" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 5.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=ApacheModuleCERNMeta - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "ApacheModuleCERNMeta.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "ApacheModuleCERNMeta.mak"\
CFG="ApacheModuleCERNMeta - Win32 Release"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "ApacheModuleCERNMeta - Win32 Release" (based on\
"Win32 (x86) Dynamic-Link Library")
!MESSAGE "ApacheModuleCERNMeta - Win32 Debug" (based on\
"Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "ApacheModuleCERNMeta - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir ".\Release"
# PROP BASE Intermediate_Dir ".\Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir ".\ApacheModuleCERNMetaR"
# PROP Intermediate_Dir ".\ApacheModuleCERNMetaR"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "SHARED_MODULE" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x809 /d "NDEBUG"
# ADD RSC /l 0x809 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
# ADD LINK32 ..\..\CoreR\ApacheCore.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib /nologo /subsystem:windows /dll /machine:I386
!ELSEIF "$(CFG)" == "ApacheModuleCERNMeta - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir ".\Debug"
# PROP BASE Intermediate_Dir ".\Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir ".\ApacheModuleCERNMetaD"
# PROP Intermediate_Dir ".\ApacheModuleCERNMetaD"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "SHARED_MODULE" /YX /FD /c
# ADD BASE MTL /nologo /D "_DEBUG" /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x809 /d "_DEBUG"
# ADD RSC /l 0x809 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386
# ADD LINK32 ..\..\CoreD\ApacheCore.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib /nologo /subsystem:windows /dll /debug /machine:I386
!ENDIF
# Begin Target
# Name "ApacheModuleCERNMeta - Win32 Release"
# Name "ApacheModuleCERNMeta - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
# Begin Source File
SOURCE=..\..\modules\standard\mod_cern_meta.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
# Begin Source File
SOURCE=.\readdir.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

View File

@@ -0,0 +1,113 @@
# Microsoft Developer Studio Project File - Name="ApacheModuleExpires" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 5.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=ApacheModuleExpires - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "ApacheModuleExpires.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "ApacheModuleExpires.mak"\
CFG="ApacheModuleExpires - Win32 Release"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "ApacheModuleExpires - Win32 Release" (based on\
"Win32 (x86) Dynamic-Link Library")
!MESSAGE "ApacheModuleExpires - Win32 Debug" (based on\
"Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "ApacheModuleExpires - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir ".\Release"
# PROP BASE Intermediate_Dir ".\Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir ".\ApacheModuleExpiresR"
# PROP Intermediate_Dir ".\ApacheModuleExpiresR"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "SHARED_MODULE" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x809 /d "NDEBUG"
# ADD RSC /l 0x809 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
# ADD LINK32 ..\..\CoreR\ApacheCore.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib /nologo /subsystem:windows /dll /machine:I386
!ELSEIF "$(CFG)" == "ApacheModuleExpires - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir ".\Debug"
# PROP BASE Intermediate_Dir ".\Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir ".\ApacheModuleExpiresD"
# PROP Intermediate_Dir ".\ApacheModuleExpiresD"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "SHARED_MODULE" /YX /FD /c
# ADD BASE MTL /nologo /D "_DEBUG" /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x809 /d "_DEBUG"
# ADD RSC /l 0x809 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386
# ADD LINK32 ..\..\CoreD\ApacheCore.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib /nologo /subsystem:windows /dll /debug /machine:I386
!ENDIF
# Begin Target
# Name "ApacheModuleExpires - Win32 Release"
# Name "ApacheModuleExpires - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
# Begin Source File
SOURCE=..\..\modules\standard\mod_expires.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
# Begin Source File
SOURCE=.\readdir.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

View File

@@ -0,0 +1,113 @@
# Microsoft Developer Studio Project File - Name="ApacheModuleHeaders" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 5.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=ApacheModuleHeaders - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "ApacheModuleHeaders.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "ApacheModuleHeaders.mak"\
CFG="ApacheModuleHeaders - Win32 Release"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "ApacheModuleHeaders - Win32 Release" (based on\
"Win32 (x86) Dynamic-Link Library")
!MESSAGE "ApacheModuleHeaders - Win32 Debug" (based on\
"Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "ApacheModuleHeaders - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir ".\Release"
# PROP BASE Intermediate_Dir ".\Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir ".\ApacheModuleHeadersR"
# PROP Intermediate_Dir ".\ApacheModuleHeadersR"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "SHARED_MODULE" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x809 /d "NDEBUG"
# ADD RSC /l 0x809 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
# ADD LINK32 ..\..\CoreR\ApacheCore.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib /nologo /subsystem:windows /dll /machine:I386
!ELSEIF "$(CFG)" == "ApacheModuleHeaders - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir ".\Debug"
# PROP BASE Intermediate_Dir ".\Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir ".\ApacheModuleHeadersD"
# PROP Intermediate_Dir ".\ApacheModuleHeadersD"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "SHARED_MODULE" /YX /FD /c
# ADD BASE MTL /nologo /D "_DEBUG" /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x809 /d "_DEBUG"
# ADD RSC /l 0x809 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386
# ADD LINK32 ..\..\CoreD\ApacheCore.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib /nologo /subsystem:windows /dll /debug /machine:I386
!ENDIF
# Begin Target
# Name "ApacheModuleHeaders - Win32 Release"
# Name "ApacheModuleHeaders - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
# Begin Source File
SOURCE=..\..\modules\standard\mod_headers.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
# Begin Source File
SOURCE=.\readdir.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

View File

@@ -0,0 +1,113 @@
# Microsoft Developer Studio Project File - Name="ApacheModuleUserTrack" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 5.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=ApacheModuleUserTrack - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "ApacheModuleUserTrack.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "ApacheModuleUserTrack.mak"\
CFG="ApacheModuleUserTrack - Win32 Release"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "ApacheModuleUserTrack - Win32 Release" (based on\
"Win32 (x86) Dynamic-Link Library")
!MESSAGE "ApacheModuleUserTrack - Win32 Debug" (based on\
"Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "ApacheModuleUserTrack - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir ".\Release"
# PROP BASE Intermediate_Dir ".\Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir ".\ApacheModuleUserTrackR"
# PROP Intermediate_Dir ".\ApacheModuleUserTrackR"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "SHARED_MODULE" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x809 /d "NDEBUG"
# ADD RSC /l 0x809 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
# ADD LINK32 ..\..\CoreR\ApacheCore.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib /nologo /subsystem:windows /dll /machine:I386
!ELSEIF "$(CFG)" == "ApacheModuleUserTrack - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir ".\Debug"
# PROP BASE Intermediate_Dir ".\Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir ".\ApacheModuleUserTrackD"
# PROP Intermediate_Dir ".\ApacheModuleUserTrackD"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "SHARED_MODULE" /YX /FD /c
# ADD BASE MTL /nologo /D "_DEBUG" /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x809 /d "_DEBUG"
# ADD RSC /l 0x809 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386
# ADD LINK32 ..\..\CoreD\ApacheCore.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib /nologo /subsystem:windows /dll /debug /machine:I386
!ENDIF
# Begin Target
# Name "ApacheModuleUserTrack - Win32 Release"
# Name "ApacheModuleUserTrack - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
# Begin Source File
SOURCE=..\..\modules\standard\mod_usertrack.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
# Begin Source File
SOURCE=.\readdir.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

54
modules/ssl/.indent.pro vendored Normal file
View File

@@ -0,0 +1,54 @@
-i4 -npsl -di0 -br -nce -d0 -cli0 -npcs -nfc1
-TBUFF
-TFILE
-TTRANS
-TUINT4
-T_trans
-Tallow_options_t
-Tapache_sfio
-Tarray_header
-Tbool_int
-Tbuf_area
-Tbuff_struct
-Tbuffy
-Tcmd_how
-Tcmd_parms
-Tcommand_rec
-Tcommand_struct
-Tconn_rec
-Tcore_dir_config
-Tcore_server_config
-Tdir_maker_func
-Tevent
-Tglobals_s
-Thandler_func
-Thandler_rec
-Tjoblist_s
-Tlisten_rec
-Tmerger_func
-Tmode_t
-Tmodule
-Tmodule_struct
-Tmutex
-Tn_long
-Tother_child_rec
-Toverrides_t
-Tparent_score
-Tpid_t
-Tpiped_log
-Tpool
-Trequest_rec
-Trequire_line
-Trlim_t
-Tscoreboard
-Tsemaphore
-Tserver_addr_rec
-Tserver_rec
-Tserver_rec_chain
-Tshort_score
-Ttable
-Ttable_entry
-Tthread
-Tu_wide_int
-Tvtime_t
-Twide_int

54
os/.indent.pro vendored Normal file
View File

@@ -0,0 +1,54 @@
-i4 -npsl -di0 -br -nce -d0 -cli0 -npcs -nfc1
-TBUFF
-TFILE
-TTRANS
-TUINT4
-T_trans
-Tallow_options_t
-Tapache_sfio
-Tarray_header
-Tbool_int
-Tbuf_area
-Tbuff_struct
-Tbuffy
-Tcmd_how
-Tcmd_parms
-Tcommand_rec
-Tcommand_struct
-Tconn_rec
-Tcore_dir_config
-Tcore_server_config
-Tdir_maker_func
-Tevent
-Tglobals_s
-Thandler_func
-Thandler_rec
-Tjoblist_s
-Tlisten_rec
-Tmerger_func
-Tmode_t
-Tmodule
-Tmodule_struct
-Tmutex
-Tn_long
-Tother_child_rec
-Toverrides_t
-Tparent_score
-Tpid_t
-Tpiped_log
-Tpool
-Trequest_rec
-Trequire_line
-Trlim_t
-Tscoreboard
-Tsemaphore
-Tserver_addr_rec
-Tserver_rec
-Tserver_rec_chain
-Tshort_score
-Ttable
-Ttable_entry
-Tthread
-Tu_wide_int
-Tvtime_t
-Twide_int

1
os/bs2000/.cvsignore Normal file
View File

@@ -0,0 +1 @@
Makefile

297
os/bs2000/bs2login.c Normal file
View File

@@ -0,0 +1,297 @@
/* ====================================================================
* Copyright (c) 1995-1999 The Apache Group. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* 4. The names "Apache Server" and "Apache Group" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Group and was originally based
* on public domain software written at the National Center for
* Supercomputing Applications, University of Illinois, Urbana-Champaign.
* For more information on the Apache Group and the Apache HTTP server
* project, please see <http://www.apache.org/>.
*
*/
#ifdef _OSD_POSIX
#include "httpd.h"
#include "http_config.h"
#include "http_log.h"
#include <ctype.h>
#include <sys/utsname.h>
#define ACCT_LEN 8
#define USER_LEN 8
static const char *bs2000_account = NULL;
typedef enum
{
bs2_unknown, /* not initialized yet. */
bs2_noFORK, /* no fork() because -X flag was specified */
bs2_FORK, /* only fork() because uid != 0 */
bs2_FORK_RINI, /* prior to A17, regular fork() and _rini() was used. */
bs2_RFORK_RINI, /* for A17, use of _rfork() and _rini() was required */
bs2_UFORK /* As of A18, the new ufork() is used. */
} bs2_ForkType;
static bs2_ForkType forktype = bs2_unknown;
static void ap_pad(char *dest, size_t size, char ch)
{
int i = strlen(dest); /* Leave space for trailing '\0' */
while (i < size-1)
dest[i++] = ch;
dest[size-1] = '\0'; /* Guarantee for trailing '\0' */
}
static void ap_str_toupper(char *str)
{
while (*str) {
*str = ap_toupper(*str);
++str;
}
}
/* Determine the method for forking off a child in such a way as to
* set both the POSIX and BS2000 user id's to the unprivileged user.
*/
static bs2_ForkType os_forktype(void)
{
struct utsname os_version;
/* have we checked the OS version before? If yes return the previous
* result - the OS release isn't going to change suddenly!
*/
if (forktype != bs2_unknown) {
return forktype;
}
/* If the user is unprivileged, use the normal fork() only. */
if (getuid() != 0) {
return forktype = bs2_FORK;
}
if (uname(&os_version) < 0)
{
ap_log_error(APLOG_MARK, APLOG_ALERT, NULL,
"uname() failed - aborting.");
exit(APEXIT_CHILDFATAL);
}
/*
* Old BS2000/OSD versions (before XPG4 SPEC1170) don't work with Apache.
* Anyway, simply return a fork().
*/
if (strcmp(os_version.release, "01.0A") == 0 ||
strcmp(os_version.release, "02.0A") == 0 ||
strcmp(os_version.release, "02.1A") == 0)
{
ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, NULL,
"Error: unsupported OS version. "
"You may encounter problems.");
forktype = bs2_FORK;
}
/* The following versions are special:
* OS versions before A17 needs regular fork() and _rini().
* A17 requires _rfork() and _rini(),
* and later versions need ufork().
*/
else if (strcmp(os_version.release, "01.1A") == 0 ||
strcmp(os_version.release, "03.0A") == 0 ||
strcmp(os_version.release, "03.1A") == 0 ||
strcmp(os_version.release, "04.0A") == 0)
{
if (strcmp (os_version.version, "A18") >= 0)
forktype = bs2_UFORK;
else if (strcmp (os_version.version, "A17") < 0)
forktype = bs2_FORK_RINI;
else
forktype = bs2_RFORK_RINI;
}
/* All later OS versions will hopefully use ufork() only ;-) */
else
forktype = bs2_UFORK;
return forktype;
}
/* This routine is called by http_core for the BS2000Account directive */
/* It stores the account name for later use */
const char *os_set_account(pool *p, const char *account)
{
char account_temp[ACCT_LEN+1];
ap_cpystrn(account_temp, account, sizeof account_temp);
/* Make account all upper case */
ap_str_toupper(account_temp);
/* Pad to length 8 */
ap_pad(account_temp, sizeof account_temp, ' ');
bs2000_account = ap_pstrdup(p, account_temp);
return NULL;
}
/* This routine complements the setuid() call: it causes the BS2000 job
* environment to be switched to the target user's user id.
* That is important if CGI scripts try to execute native BS2000 commands.
*/
int os_init_job_environment(server_rec *server, const char *user_name, int one_process)
{
_rini_struct inittask;
char username[USER_LEN+1];
int save_errno;
bs2_ForkType type = os_forktype();
/* We can be sure that no change to uid==0 is possible because of
* the checks in http_core.c:set_user()
*/
/* The _rini() function works only after a prior _rfork().
* In the case of one_process, it would fail.
*/
if (one_process) {
type = forktype = bs2_noFORK;
ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, server,
"The debug mode of Apache should only "
"be started by an unprivileged user!");
return 0;
}
/* If no _rini() is required, then return quickly. */
if (type != bs2_RFORK_RINI && type != bs2_FORK_RINI)
return 0;
/* An Account is required for _rini() */
if (bs2000_account == NULL)
{
ap_log_error(APLOG_MARK, APLOG_ALERT|APLOG_NOERRNO, server,
"No BS2000Account configured - cannot switch to User %s",
user_name);
exit(APEXIT_CHILDFATAL);
}
ap_cpystrn(username, user_name, sizeof username);
/* Make user name all upper case */
ap_str_toupper(username);
/* Pad to length 8 */
ap_pad(username, sizeof username, ' ');
inittask.username = username;
inittask.account = bs2000_account;
inittask.processor_name = " ";
/* Switch to the new logon user (setuid() and setgid() are done later) */
/* Only the super user can switch identities. */
if (_rini(&inittask) != 0) {
ap_log_error(APLOG_MARK, APLOG_ALERT, server,
"_rini: BS2000 auth failed for user \"%s\" acct \"%s\"",
inittask.username, inittask.account);
exit(APEXIT_CHILDFATAL);
}
return 0;
}
/* BS2000 requires a "special" version of fork() before a setuid()/_rini() call */
pid_t os_fork(const char *user)
{
pid_t pid;
char username[USER_LEN+1];
switch (os_forktype()) {
case bs2_FORK:
case bs2_FORK_RINI:
pid = fork();
break;
case bs2_RFORK_RINI:
pid = _rfork();
break;
case bs2_UFORK:
ap_cpystrn(username, user, sizeof username);
/* Make user name all upper case - for some versions of ufork() */
ap_str_toupper(username);
pid = ufork(username);
if (pid == -1 && errno == EPERM) {
ap_log_error(APLOG_MARK, APLOG_EMERG,
NULL, "ufork: Possible mis-configuration "
"for user %s - Aborting.", user);
exit(1);
}
break;
default:
pid = 0;
break;
}
return pid;
}
#else /* _OSD_POSIX */
void bs2login_is_not_here()
{
}
#endif /* _OSD_POSIX */

252
os/bs2000/ebcdic.c Normal file
View File

@@ -0,0 +1,252 @@
/* ====================================================================
* Copyright (c) 1998-1999 The Apache Group. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* 4. The names "Apache Server" and "Apache Group" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Group and was originally based
* on public domain software written at the National Center for
* Supercomputing Applications, University of Illinois, Urbana-Champaign.
* For more information on the Apache Group and the Apache HTTP server
* project, please see <http://www.apache.org/>.
*
*/
#ifdef CHARSET_EBCDIC
#include "ap_config.h"
#include "ebcdic.h"
/*
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 AG, Germany.
Within the POSIX subsystem, the same character set was chosen as in
"native BS2000", namely EBCDIC.
EBCDIC Table. (Yes, in EBCDIC, the letters 'a'..'z' are not contiguous!)
This table is bijective, i.e. there are no ambigous or duplicate characters
00 00 01 02 03 85 09 86 7f 87 8d 8e 0b 0c 0d 0e 0f *................*
10 10 11 12 13 8f 0a 08 97 18 19 9c 9d 1c 1d 1e 1f *................*
20 80 81 82 83 84 92 17 1b 88 89 8a 8b 8c 05 06 07 *................*
30 90 91 16 93 94 95 96 04 98 99 9a 9b 14 15 9e 1a *................*
40 20 a0 e2 e4 e0 e1 e3 e5 e7 f1 60 2e 3c 28 2b 7c * .........`.<(+|*
50 26 e9 ea eb e8 ed ee ef ec df 21 24 2a 29 3b 9f *&.........!$*);.*
60 2d 2f c2 c4 c0 c1 c3 c5 c7 d1 5e 2c 25 5f 3e 3f *-/........^,%_>?*
70 f8 c9 ca cb c8 cd ce cf cc a8 3a 23 40 27 3d 22 *..........:#@'="*
80 d8 61 62 63 64 65 66 67 68 69 ab bb f0 fd fe b1 *.abcdefghi......*
90 b0 6a 6b 6c 6d 6e 6f 70 71 72 aa ba e6 b8 c6 a4 *.jklmnopqr......*
a0 b5 af 73 74 75 76 77 78 79 7a a1 bf d0 dd de ae *..stuvwxyz......*
b0 a2 a3 a5 b7 a9 a7 b6 bc bd be ac 5b 5c 5d b4 d7 *...........[\]..*
c0 f9 41 42 43 44 45 46 47 48 49 ad f4 f6 f2 f3 f5 *.ABCDEFGHI......*
d0 a6 4a 4b 4c 4d 4e 4f 50 51 52 b9 fb fc db fa ff *.JKLMNOPQR......*
e0 d9 f7 53 54 55 56 57 58 59 5a b2 d4 d6 d2 d3 d5 *..STUVWXYZ......*
f0 30 31 32 33 34 35 36 37 38 39 b3 7b dc 7d da 7e *0123456789.{.}.~*
*/
/* The bijective ebcdic-to-ascii table: */
const unsigned char os_toascii_strictly[256] = {
/*00*/ 0x00, 0x01, 0x02, 0x03, 0x85, 0x09, 0x86, 0x7f,
0x87, 0x8d, 0x8e, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /*................*/
/*10*/ 0x10, 0x11, 0x12, 0x13, 0x8f, 0x0a, 0x08, 0x97,
0x18, 0x19, 0x9c, 0x9d, 0x1c, 0x1d, 0x1e, 0x1f, /*................*/
/*20*/ 0x80, 0x81, 0x82, 0x83, 0x84, 0x92, 0x17, 0x1b,
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x05, 0x06, 0x07, /*................*/
/*30*/ 0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04,
0x98, 0x99, 0x9a, 0x9b, 0x14, 0x15, 0x9e, 0x1a, /*................*/
/*40*/ 0x20, 0xa0, 0xe2, 0xe4, 0xe0, 0xe1, 0xe3, 0xe5,
0xe7, 0xf1, 0x60, 0x2e, 0x3c, 0x28, 0x2b, 0x7c, /* .........`.<(+|*/
/*50*/ 0x26, 0xe9, 0xea, 0xeb, 0xe8, 0xed, 0xee, 0xef,
0xec, 0xdf, 0x21, 0x24, 0x2a, 0x29, 0x3b, 0x9f, /*&.........!$*);.*/
/*60*/ 0x2d, 0x2f, 0xc2, 0xc4, 0xc0, 0xc1, 0xc3, 0xc5,
0xc7, 0xd1, 0x5e, 0x2c, 0x25, 0x5f, 0x3e, 0x3f, /*-/........^,%_>?*/
/*70*/ 0xf8, 0xc9, 0xca, 0xcb, 0xc8, 0xcd, 0xce, 0xcf,
0xcc, 0xa8, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22, /*..........:#@'="*/
/*80*/ 0xd8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0x68, 0x69, 0xab, 0xbb, 0xf0, 0xfd, 0xfe, 0xb1, /*.abcdefghi......*/
/*90*/ 0xb0, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
0x71, 0x72, 0xaa, 0xba, 0xe6, 0xb8, 0xc6, 0xa4, /*.jklmnopqr......*/
/*a0*/ 0xb5, 0xaf, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
0x79, 0x7a, 0xa1, 0xbf, 0xd0, 0xdd, 0xde, 0xae, /*..stuvwxyz......*/
/*b0*/ 0xa2, 0xa3, 0xa5, 0xb7, 0xa9, 0xa7, 0xb6, 0xbc,
0xbd, 0xbe, 0xac, 0x5b, 0x5c, 0x5d, 0xb4, 0xd7, /*...........[\]..*/
/*c0*/ 0xf9, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0xad, 0xf4, 0xf6, 0xf2, 0xf3, 0xf5, /*.ABCDEFGHI......*/
/*d0*/ 0xa6, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
0x51, 0x52, 0xb9, 0xfb, 0xfc, 0xdb, 0xfa, 0xff, /*.JKLMNOPQR......*/
/*e0*/ 0xd9, 0xf7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
0x59, 0x5a, 0xb2, 0xd4, 0xd6, 0xd2, 0xd3, 0xd5, /*..STUVWXYZ......*/
/*f0*/ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0xb3, 0x7b, 0xdc, 0x7d, 0xda, 0x7e /*0123456789.{.}.~*/
};
/* This table is (almost) identical to the previous one. The only difference
* is the fact that it maps every EBCDIC *except 0x0A* to its ASCII
* equivalent. The reason for this table is simple: Throughout the
* server, protocol strings are used in the form
* "Content-Type: text/plain\015\012". Now all the characters in the string
* are stored as EBCDIC, only the semantics of \012 is completely
* different from LF (look it up in the table above). \015 happens to be
* mapped to \015 anyway, so there's no special case for it.
*
* In THIS table, EBCDIC-\012 is mapped to ASCII-\012.
* This table is therefore used wherever an EBCDIC to ASCII conversion is
* needed in the server.
*/
/* ebcdic-to-ascii with \012 mapped to ASCII-\n */
const unsigned char os_toascii[256] = {
/*00*/ 0x00, 0x01, 0x02, 0x03, 0x85, 0x09, 0x86, 0x7f,
0x87, 0x8d, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /*................*/
/*10*/ 0x10, 0x11, 0x12, 0x13, 0x8f, 0x0a, 0x08, 0x97,
0x18, 0x19, 0x9c, 0x9d, 0x1c, 0x1d, 0x1e, 0x1f, /*................*/
/*20*/ 0x80, 0x81, 0x82, 0x83, 0x84, 0x92, 0x17, 0x1b,
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x05, 0x06, 0x07, /*................*/
/*30*/ 0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04,
0x98, 0x99, 0x9a, 0x9b, 0x14, 0x15, 0x9e, 0x1a, /*................*/
/*40*/ 0x20, 0xa0, 0xe2, 0xe4, 0xe0, 0xe1, 0xe3, 0xe5,
0xe7, 0xf1, 0x60, 0x2e, 0x3c, 0x28, 0x2b, 0x7c, /* .........`.<(+|*/
/*50*/ 0x26, 0xe9, 0xea, 0xeb, 0xe8, 0xed, 0xee, 0xef,
0xec, 0xdf, 0x21, 0x24, 0x2a, 0x29, 0x3b, 0x9f, /*&.........!$*);.*/
/*60*/ 0x2d, 0x2f, 0xc2, 0xc4, 0xc0, 0xc1, 0xc3, 0xc5,
0xc7, 0xd1, 0x5e, 0x2c, 0x25, 0x5f, 0x3e, 0x3f, /*-/........^,%_>?*/
/*70*/ 0xf8, 0xc9, 0xca, 0xcb, 0xc8, 0xcd, 0xce, 0xcf,
0xcc, 0xa8, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22, /*..........:#@'="*/
/*80*/ 0xd8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0x68, 0x69, 0xab, 0xbb, 0xf0, 0xfd, 0xfe, 0xb1, /*.abcdefghi......*/
/*90*/ 0xb0, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
0x71, 0x72, 0xaa, 0xba, 0xe6, 0xb8, 0xc6, 0xa4, /*.jklmnopqr......*/
/*a0*/ 0xb5, 0xaf, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
0x79, 0x7a, 0xa1, 0xbf, 0xd0, 0xdd, 0xde, 0xae, /*..stuvwxyz......*/
/*b0*/ 0xa2, 0xa3, 0xa5, 0xb7, 0xa9, 0xa7, 0xb6, 0xbc,
0xbd, 0xbe, 0xac, 0x5b, 0x5c, 0x5d, 0xb4, 0xd7, /*...........[\]..*/
/*c0*/ 0xf9, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0xad, 0xf4, 0xf6, 0xf2, 0xf3, 0xf5, /*.ABCDEFGHI......*/
/*d0*/ 0xa6, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
0x51, 0x52, 0xb9, 0xfb, 0xfc, 0xdb, 0xfa, 0xff, /*.JKLMNOPQR......*/
/*e0*/ 0xd9, 0xf7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
0x59, 0x5a, 0xb2, 0xd4, 0xd6, 0xd2, 0xd3, 0xd5, /*..STUVWXYZ......*/
/*f0*/ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0xb3, 0x7b, 0xdc, 0x7d, 0xda, 0x7e /*0123456789.{.}.~*/
};
/* The ascii-to-ebcdic table:
00 00 01 02 03 37 2d 2e 2f 16 05 15 0b 0c 0d 0e 0f *................*
10 10 11 12 13 3c 3d 32 26 18 19 3f 27 1c 1d 1e 1f *................*
20 40 5a 7f 7b 5b 6c 50 7d 4d 5d 5c 4e 6b 60 4b 61 * !"#$%&'()*+,-./
30 f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 7a 5e 4c 7e 6e 6f *0123456789:;<=>?*
40 7c c1 c2 c3 c4 c5 c6 c7 c8 c9 d1 d2 d3 d4 d5 d6 *@ABCDEFGHIJKLMNO*
50 d7 d8 d9 e2 e3 e4 e5 e6 e7 e8 e9 bb bc bd 6a 6d *PQRSTUVWXYZ[\]^_*
60 4a 81 82 83 84 85 86 87 88 89 91 92 93 94 95 96 *`abcdefghijklmno*
70 97 98 99 a2 a3 a4 a5 a6 a7 a8 a9 fb 4f fd ff 07 *pqrstuvwxyz{|}~.*
80 20 21 22 23 24 04 06 08 28 29 2a 2b 2c 09 0a 14 *................*
90 30 31 25 33 34 35 36 17 38 39 3a 3b 1a 1b 3e 5f *................*
a0 41 aa b0 b1 9f b2 d0 b5 79 b4 9a 8a ba ca af a1 *................*
b0 90 8f ea fa be a0 b6 b3 9d da 9b 8b b7 b8 b9 ab *................*
c0 64 65 62 66 63 67 9e 68 74 71 72 73 78 75 76 77 *................*
d0 ac 69 ed ee eb ef ec bf 80 e0 fe dd fc ad ae 59 *................*
e0 44 45 42 46 43 47 9c 48 54 51 52 53 58 55 56 57 *................*
f0 8c 49 cd ce cb cf cc e1 70 c0 de db dc 8d 8e df *................*
*/
const unsigned char os_toebcdic[256] = {
/*00*/ 0x00, 0x01, 0x02, 0x03, 0x37, 0x2d, 0x2e, 0x2f,
0x16, 0x05, 0x15, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /*................*/
/*10*/ 0x10, 0x11, 0x12, 0x13, 0x3c, 0x3d, 0x32, 0x26,
0x18, 0x19, 0x3f, 0x27, 0x1c, 0x1d, 0x1e, 0x1f, /*................*/
/*20*/ 0x40, 0x5a, 0x7f, 0x7b, 0x5b, 0x6c, 0x50, 0x7d,
0x4d, 0x5d, 0x5c, 0x4e, 0x6b, 0x60, 0x4b, 0x61, /* !"#$%&'()*+,-./ */
/*30*/ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9, 0x7a, 0x5e, 0x4c, 0x7e, 0x6e, 0x6f, /*0123456789:;<=>?*/
/*40*/ 0x7c, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
0xc8, 0xc9, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, /*@ABCDEFGHIJKLMNO*/
/*50*/ 0xd7, 0xd8, 0xd9, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6,
0xe7, 0xe8, 0xe9, 0xbb, 0xbc, 0xbd, 0x6a, 0x6d, /*PQRSTUVWXYZ[\]^_*/
/*60*/ 0x4a, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, /*`abcdefghijklmno*/
/*70*/ 0x97, 0x98, 0x99, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6,
0xa7, 0xa8, 0xa9, 0xfb, 0x4f, 0xfd, 0xff, 0x07, /*pqrstuvwxyz{|}~.*/
/*80*/ 0x20, 0x21, 0x22, 0x23, 0x24, 0x04, 0x06, 0x08,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x09, 0x0a, 0x14, /*................*/
/*90*/ 0x30, 0x31, 0x25, 0x33, 0x34, 0x35, 0x36, 0x17,
0x38, 0x39, 0x3a, 0x3b, 0x1a, 0x1b, 0x3e, 0x5f, /*................*/
/*a0*/ 0x41, 0xaa, 0xb0, 0xb1, 0x9f, 0xb2, 0xd0, 0xb5,
0x79, 0xb4, 0x9a, 0x8a, 0xba, 0xca, 0xaf, 0xa1, /*................*/
/*b0*/ 0x90, 0x8f, 0xea, 0xfa, 0xbe, 0xa0, 0xb6, 0xb3,
0x9d, 0xda, 0x9b, 0x8b, 0xb7, 0xb8, 0xb9, 0xab, /*................*/
/*c0*/ 0x64, 0x65, 0x62, 0x66, 0x63, 0x67, 0x9e, 0x68,
0x74, 0x71, 0x72, 0x73, 0x78, 0x75, 0x76, 0x77, /*................*/
/*d0*/ 0xac, 0x69, 0xed, 0xee, 0xeb, 0xef, 0xec, 0xbf,
0x80, 0xe0, 0xfe, 0xdd, 0xfc, 0xad, 0xae, 0x59, /*................*/
/*e0*/ 0x44, 0x45, 0x42, 0x46, 0x43, 0x47, 0x9c, 0x48,
0x54, 0x51, 0x52, 0x53, 0x58, 0x55, 0x56, 0x57, /*................*/
/*f0*/ 0x8c, 0x49, 0xcd, 0xce, 0xcb, 0xcf, 0xcc, 0xe1,
0x70, 0xc0, 0xde, 0xdb, 0xdc, 0x8d, 0x8e, 0xdf /*................*/
};
/* Translate a memory block from EBCDIC (host charset) to ASCII (net charset)
* dest and srce may be identical, or separate memory blocks, but
* should not overlap.
*/
void
ebcdic2ascii(unsigned char *dest, const unsigned char *srce, size_t count)
{
while (count-- != 0) {
*dest++ = os_toascii[*srce++];
}
}
void
ebcdic2ascii_strictly(unsigned char *dest, const unsigned char *srce, size_t count)
{
while (count-- != 0) {
*dest++ = os_toascii_strictly[*srce++];
}
}
void
ascii2ebcdic(unsigned char *dest, const unsigned char *srce, size_t count)
{
while (count-- != 0) {
*dest++ = os_toebcdic[*srce++];
}
}
#endif /*CHARSET_EBCDIC*/

8
os/bs2000/ebcdic.h Normal file
View File

@@ -0,0 +1,8 @@
#include <sys/types.h>
extern const unsigned char os_toascii[256];
extern const unsigned char os_toebcdic[256];
void ebcdic2ascii(unsigned char *dest, const unsigned char *srce, size_t count);
void ebcdic2ascii_strictly(unsigned char *dest, const unsigned char *srce, size_t count);
void ascii2ebcdic(unsigned char *dest, const unsigned char *srce, size_t count);

31
os/bs2000/os-inline.c Normal file
View File

@@ -0,0 +1,31 @@
/*
* This file contains functions which can be inlined if the compiler
* has an "inline" modifier. Because of this, this file is both a
* header file and a compilable module.
*
* Only inlineable functions should be defined in here. They must all
* include the INLINE modifier.
*
* If the compiler supports inline, this file will be #included as a
* header file from os.h to create all the inline function
* definitions. INLINE will be defined to whatever is required on
* function definitions to make them inline declarations.
*
* If the compiler does not support inline, this file will be compiled
* as a normal C file into libos.a (along with os.c). In this case
* INLINE will _not_ be set so we can use this to test if we are
* compiling this source file.
*/
#ifndef INLINE
#define INLINE
/* Anything required only when compiling */
#include "ap_config.h"
#endif
INLINE int ap_os_is_path_absolute(const char *file)
{
return (file && file[0] == '/' ? 1 : 0);
}

103
os/bs2000/os.c Normal file
View File

@@ -0,0 +1,103 @@
/* ====================================================================
* Copyright (c) 1998-1999 The Apache Group. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* 4. The names "Apache Server" and "Apache Group" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Group and was originally based
* on public domain software written at the National Center for
* Supercomputing Applications, University of Illinois, Urbana-Champaign.
* For more information on the Apache Group and the Apache HTTP server
* project, please see <http://www.apache.org/>.
*
*/
/*
* This file will include OS specific functions which are not inlineable.
* Any inlineable functions should be defined in os-inline.c instead.
*/
#include "httpd.h"
#include "http_core.h"
#include "os.h"
/* Check the Content-Type to decide if conversion is needed */
int ap_checkconv(struct request_rec *r)
{
int convert_to_ascii;
const char *type;
/* To make serving of "raw ASCII text" files easy (they serve faster
* since they don't have to be converted from EBCDIC), a new
* "magic" type prefix was invented: text/x-ascii-{plain,html,...}
* If we detect one of these content types here, we simply correct
* the type to the real text/{plain,html,...} type. Otherwise, we
* set a flag that translation is required later on.
*/
type = (r->content_type == NULL) ? ap_default_type(r) : r->content_type;
/* If no content type is set then treat it as (ebcdic) text/plain */
convert_to_ascii = (type == NULL);
/* Conversion is applied to text/ files only, if ever. */
if (type && (strncasecmp(type, "text/", 5) == 0 ||
strncasecmp(type, "message/", 8) == 0)) {
if (strncasecmp(type, ASCIITEXT_MAGIC_TYPE_PREFIX,
sizeof(ASCIITEXT_MAGIC_TYPE_PREFIX)-1) == 0)
r->content_type = ap_pstrcat(r->pool, "text/",
type+sizeof(ASCIITEXT_MAGIC_TYPE_PREFIX)-1,
NULL);
else
/* translate EBCDIC to ASCII */
convert_to_ascii = 1;
}
/* Enable conversion if it's a text document */
ap_bsetflag(r->connection->client, B_EBCDIC2ASCII, convert_to_ascii);
return convert_to_ascii;
}

51
os/bs2000/os.h Normal file
View File

@@ -0,0 +1,51 @@
#ifndef APACHE_OS_H
#define APACHE_OS_H
#define PLATFORM "BS2000"
/*
* This file in included in all Apache source code. It contains definitions
* of facilities available on _this_ operating system (HAVE_* macros),
* and prototypes of OS specific functions defined in os.c or os-inline.c
*/
#if !defined(INLINE) && defined(USE_GNU_INLINE)
/* Compiler supports inline, so include the inlineable functions as
* part of the header
*/
#define INLINE extern ap_inline
INLINE int ap_os_is_path_absolute(const char *file);
#include "os-inline.c"
#endif
#ifndef INLINE
/* Compiler does not support inline, so prototype the inlineable functions
* as normal
*/
extern int ap_os_is_path_absolute(const char *file);
#endif
/* Other ap_os_ routines not used by this platform */
#define ap_os_is_filename_valid(f) (1)
#define ap_os_kill(pid, sig) kill(pid, sig)
#if !defined(_POSIX_SOURCE) && !defined(_XOPEN_SOURCE)
typedef struct {
char *username;
char *account;
char *processor_name;
} _rini_struct;
extern int _rini(_rini_struct *);
#endif /* !defined(_POSIX_SOURCE) && !defined(_XOPEN_SOURCE) */
/* Sorry if this is ugly, but the include order doesn't allow me
* to use request_rec here... */
struct request_rec;
extern int ap_checkconv(struct request_rec *r);
extern pid_t os_fork(const char *user);
#endif /*! APACHE_OS_H*/

1
os/os2/.cvsignore Normal file
View File

@@ -0,0 +1 @@
Makefile

34
os/os2/os-inline.c Normal file
View File

@@ -0,0 +1,34 @@
/*
* This file contains functions which can be inlined if the compiler
* has an "inline" modifier. Because of this, this file is both a
* header file and a compilable module.
*
* Only inlineable functions should be defined in here. They must all
* include the INLINE modifier.
*
* If the compiler supports inline, this file will be #included as a
* header file from os.h to create all the inline function
* definitions. INLINE will be defined to whatever is required on
* function definitions to make them inline declarations.
*
* If the compiler does not support inline, this file will be compiled
* as a normal C file into libos.a (along with os.c). In this case
* INLINE will _not_ be set so we can use this to test if we are
* compiling this source file.
*/
#ifndef INLINE
#define INLINE
/* Anything required only when compiling */
#include "ap_config.h"
#endif
INLINE int ap_os_is_path_absolute(const char *file)
{
/* For now, just do the same check that http_request.c and mod_alias.c
* do.
*/
return file && (file[0] == '/' || file[1] == ':');
}

52
os/os2/os.h Normal file
View File

@@ -0,0 +1,52 @@
#ifndef APACHE_OS_H
#define APACHE_OS_H
#define PLATFORM "OS/2"
#define HAVE_CANONICAL_FILENAME
#define HAVE_DRIVE_LETTERS
/*
* This file in included in all Apache source code. It contains definitions
* of facilities available on _this_ operating system (HAVE_* macros),
* and prototypes of OS specific functions defined in os.c or os-inline.c
*/
#if defined(__GNUC__) && !defined(INLINE)
/* Compiler supports inline, so include the inlineable functions as
* part of the header
*/
#define INLINE extern __inline__
INLINE int ap_os_is_path_absolute(const char *file);
#include "os-inline.c"
#endif
#ifndef INLINE
/* Compiler does not support inline, so prototype the inlineable functions
* as normal
*/
extern int ap_os_is_path_absolute(const char *file);
#endif
/* FIXME: the following should be implemented on this platform */
#define ap_os_is_filename_valid(f) (1)
/* Use a specialized kill() function */
int ap_os_kill(int pid, int sig);
/* Maps an OS error code to an error message */
char *ap_os_error_message(int err);
/* OS/2 doesn't have symlinks so S_ISLNK is always false */
#define S_ISLNK(m) 0
/* Dynamic loading functions */
#define ap_os_dso_handle_t unsigned long
void ap_os_dso_init(void);
ap_os_dso_handle_t ap_os_dso_load(const char *);
void ap_os_dso_unload(ap_os_dso_handle_t);
void * ap_os_dso_sym(ap_os_dso_handle_t, const char *);
const char *ap_os_dso_error(void);
#endif /* ! APACHE_OS_H */

96
os/os2/util_os2.c Normal file
View File

@@ -0,0 +1,96 @@
#define INCL_DOS
#define INCL_DOSERRORS
#include <os2.h>
#include "httpd.h"
#include "http_log.h"
API_EXPORT(char *)ap_os_canonical_filename(pool *pPool, const char *szFile)
{
char buf[HUGE_STRING_LEN];
char buf2[HUGE_STRING_LEN];
int rc, len;
char *pos;
/* Remove trailing slash unless it's a root directory */
strcpy(buf, szFile);
len = strlen(buf);
if (len > 3 && buf[len-1] == '/')
buf[--len] = 0;
rc = DosQueryPathInfo(buf, FIL_QUERYFULLNAME, buf2, HUGE_STRING_LEN);
if (rc) {
if ( rc != ERROR_INVALID_NAME ) {
ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, NULL, "OS/2 error %d for file %s", rc, szFile);
return ap_pstrdup(pPool, "");
} else {
return ap_pstrdup(pPool, szFile);
}
}
strlwr(buf2);
/* Switch backslashes to forward */
for (pos=buf2; *pos; pos++)
if (*pos == '\\')
*pos = '/';
return ap_pstrdup(pPool, buf2);
}
int ap_os_kill(pid_t pid, int sig)
{
/* SIGTERM's don't work too well in OS/2 (only affects other EMX programs).
CGIs may not be, esp. REXX scripts, so use a native call instead */
int rc;
if ( sig == SIGTERM ) {
rc = DosSendSignalException( pid, XCPT_SIGNAL_BREAK );
if ( rc ) {
errno = ESRCH;
rc = -1;
}
} else {
rc = kill(pid, sig);
}
return rc;
}
char *ap_os_error_message(int err)
{
static char result[200];
char message[HUGE_STRING_LEN];
ULONG len;
char *pos;
int c;
if (DosGetMessage(NULL, 0, message, HUGE_STRING_LEN, err, "OSO001.MSG", &len) == 0) {
len--;
message[len] = 0;
pos = result;
if (len >= sizeof(result))
len = sizeof(result-1);
for (c=0; c<len; c++) {
while (isspace(message[c]) && isspace(message[c+1])) /* skip multiple whitespace */
c++;
*(pos++) = isspace(message[c]) ? ' ' : message[c];
}
*pos = 0;
} else {
sprintf(result, "OS/2 error %d", err);
}
return result;
}

7
os/tpf/TPFExport Normal file
View File

@@ -0,0 +1,7 @@
#!/bin/sh
echo " Setting TPF/c89 environment variables"
export _C89_CCMODE=1
# replace the following with the location of your TPF include files
export _C89_INCDIRS="/u/tpf41/currentmaint/include /u/tpf41/currentmaint/include/oco"
export TPF=YES
echo "Done"

221
os/tpf/ebcdic.c Normal file
View File

@@ -0,0 +1,221 @@
/* ====================================================================
* Copyright (c) 1998-1999 The Apache Group. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* 4. The names "Apache Server" and "Apache Group" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Group and was originally based
* on public domain software written at the National Center for
* Supercomputing Applications, University of Illinois, Urbana-Champaign.
* For more information on the Apache Group and the Apache HTTP server
* project, please see <http://www.apache.org/>.
*
*/
#ifdef CHARSET_EBCDIC
#include "ap_config.h"
#include "ebcdic.h"
/*
This code does basic character mapping for IBM's TPF operating system.
It is a modified version of <Martin.Kraemer@Mch.SNI.De>'s code for
the BS2000 (apache/src/os/bs2000/ebcdic.c).
*/
/*
Bijective EBCDIC (character set IBM-1047) to US-ASCII table:
This table is bijective - there are no ambigous or duplicate characters.
*/
const unsigned char os_toascii_strictly[256] = {
0x00, 0x01, 0x02, 0x03, 0x85, 0x09, 0x86, 0x7f, /* 00-0f: */
0x87, 0x8d, 0x8e, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* ................ */
0x10, 0x11, 0x12, 0x13, 0x8f, 0x0a, 0x08, 0x97, /* 10-1f: */
0x18, 0x19, 0x9c, 0x9d, 0x1c, 0x1d, 0x1e, 0x1f, /* ................ */
0x80, 0x81, 0x82, 0x83, 0x84, 0x92, 0x17, 0x1b, /* 20-2f: */
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x05, 0x06, 0x07, /* ................ */
0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04, /* 30-3f: */
0x98, 0x99, 0x9a, 0x9b, 0x14, 0x15, 0x9e, 0x1a, /* ................ */
0x20, 0xa0, 0xe2, 0xe4, 0xe0, 0xe1, 0xe3, 0xe5, /* 40-4f: */
0xe7, 0xf1, 0xa2, 0x2e, 0x3c, 0x28, 0x2b, 0x7c, /* ...........<(+| */
0x26, 0xe9, 0xea, 0xeb, 0xe8, 0xed, 0xee, 0xef, /* 50-5f: */
0xec, 0xdf, 0x21, 0x24, 0x2a, 0x29, 0x3b, 0x5e, /* &.........!$*);^ */
0x2d, 0x2f, 0xc2, 0xc4, 0xc0, 0xc1, 0xc3, 0xc5, /* 60-6f: */
0xc7, 0xd1, 0xa6, 0x2c, 0x25, 0x5f, 0x3e, 0x3f, /* -/.........,%_>? */
0xf8, 0xc9, 0xca, 0xcb, 0xc8, 0xcd, 0xce, 0xcf, /* 70-7f: */
0xcc, 0x60, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22, /* .........`:#@'=" */
0xd8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 80-8f: */
0x68, 0x69, 0xab, 0xbb, 0xf0, 0xfd, 0xfe, 0xb1, /* .abcdefghi...... */
0xb0, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, /* 90-9f: */
0x71, 0x72, 0xaa, 0xba, 0xe6, 0xb8, 0xc6, 0xa4, /* .jklmnopqr...... */
0xb5, 0x7e, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, /* a0-af: */
0x79, 0x7a, 0xa1, 0xbf, 0xd0, 0x5b, 0xde, 0xae, /* .~stuvwxyz...[.. */
0xac, 0xa3, 0xa5, 0xb7, 0xa9, 0xa7, 0xb6, 0xbc, /* b0-bf: */
0xbd, 0xbe, 0xdd, 0xa8, 0xaf, 0x5d, 0xb4, 0xd7, /* .............].. */
0x7b, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* c0-cf: */
0x48, 0x49, 0xad, 0xf4, 0xf6, 0xf2, 0xf3, 0xf5, /* {ABCDEFGHI...... */
0x7d, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, /* d0-df: */
0x51, 0x52, 0xb9, 0xfb, 0xfc, 0xf9, 0xfa, 0xff, /* }JKLMNOPQR...... */
0x5c, 0xf7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, /* e0-ef: */
0x59, 0x5a, 0xb2, 0xd4, 0xd6, 0xd2, 0xd3, 0xd5, /* \.STUVWXYZ...... */
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* f0-ff: */
0x38, 0x39, 0xb3, 0xdb, 0xdc, 0xd9, 0xda, 0x9f /* 0123456789...... */
};
/*
Server EBCDIC (character set IBM-1047) to US-ASCII table:
This table is a copy of the os_toascii_strictly bijective table above.
The only change is that hex 0a (\012 octal) is mapped to hex 0a
(ASCII's line feed) instead of hex 8e. This is done because throughout
Apache, protocol string definitions hardcode the linefeed as \012 (octal):
"Content-Type: text/plain\015\012". Without this kludge all protocol
string definitions would need to be changed from ...\012 to ...\025.
*/
const unsigned char os_toascii[256] = {
0x00, 0x01, 0x02, 0x03, 0x85, 0x09, 0x86, 0x7f, /* 00-0f: */
0x87, 0x8d, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* ................ */
0x10, 0x11, 0x12, 0x13, 0x8f, 0x0a, 0x08, 0x97, /* 10-1f: */
0x18, 0x19, 0x9c, 0x9d, 0x1c, 0x1d, 0x1e, 0x1f, /* ................ */
0x80, 0x81, 0x82, 0x83, 0x84, 0x92, 0x17, 0x1b, /* 20-2f: */
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x05, 0x06, 0x07, /* ................ */
0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04, /* 30-3f: */
0x98, 0x99, 0x9a, 0x9b, 0x14, 0x15, 0x9e, 0x1a, /* ................ */
0x20, 0xa0, 0xe2, 0xe4, 0xe0, 0xe1, 0xe3, 0xe5, /* 40-4f: */
0xe7, 0xf1, 0xa2, 0x2e, 0x3c, 0x28, 0x2b, 0x7c, /* ...........<(+| */
0x26, 0xe9, 0xea, 0xeb, 0xe8, 0xed, 0xee, 0xef, /* 50-5f: */
0xec, 0xdf, 0x21, 0x24, 0x2a, 0x29, 0x3b, 0x5e, /* &.........!$*);^ */
0x2d, 0x2f, 0xc2, 0xc4, 0xc0, 0xc1, 0xc3, 0xc5, /* 60-6f: */
0xc7, 0xd1, 0xa6, 0x2c, 0x25, 0x5f, 0x3e, 0x3f, /* -/.........,%_>? */
0xf8, 0xc9, 0xca, 0xcb, 0xc8, 0xcd, 0xce, 0xcf, /* 70-7f: */
0xcc, 0x60, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22, /* .........`:#@'=" */
0xd8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 80-8f: */
0x68, 0x69, 0xab, 0xbb, 0xf0, 0xfd, 0xfe, 0xb1, /* .abcdefghi...... */
0xb0, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, /* 90-9f: */
0x71, 0x72, 0xaa, 0xba, 0xe6, 0xb8, 0xc6, 0xa4, /* .jklmnopqr...... */
0xb5, 0x7e, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, /* a0-af: */
0x79, 0x7a, 0xa1, 0xbf, 0xd0, 0x5b, 0xde, 0xae, /* .~stuvwxyz...[.. */
0xac, 0xa3, 0xa5, 0xb7, 0xa9, 0xa7, 0xb6, 0xbc, /* b0-bf: */
0xbd, 0xbe, 0xdd, 0xa8, 0xaf, 0x5d, 0xb4, 0xd7, /* .............].. */
0x7b, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* c0-cf: */
0x48, 0x49, 0xad, 0xf4, 0xf6, 0xf2, 0xf3, 0xf5, /* {ABCDEFGHI...... */
0x7d, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, /* d0-df: */
0x51, 0x52, 0xb9, 0xfb, 0xfc, 0xf9, 0xfa, 0xff, /* }JKLMNOPQR...... */
0x5c, 0xf7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, /* e0-ef: */
0x59, 0x5a, 0xb2, 0xd4, 0xd6, 0xd2, 0xd3, 0xd5, /* \.STUVWXYZ...... */
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* f0-ff: */
0x38, 0x39, 0xb3, 0xdb, 0xdc, 0xd9, 0xda, 0x9f /* 0123456789...... */
};
/*
The US-ASCII to EBCDIC (character set IBM-1047) table:
This table is bijective (no ambiguous or duplicate characters)
*/
const unsigned char os_toebcdic[256] = {
0x00, 0x01, 0x02, 0x03, 0x37, 0x2d, 0x2e, 0x2f, /* 00-0f: */
0x16, 0x05, 0x15, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* ................ */
0x10, 0x11, 0x12, 0x13, 0x3c, 0x3d, 0x32, 0x26, /* 10-1f: */
0x18, 0x19, 0x3f, 0x27, 0x1c, 0x1d, 0x1e, 0x1f, /* ................ */
0x40, 0x5a, 0x7f, 0x7b, 0x5b, 0x6c, 0x50, 0x7d, /* 20-2f: */
0x4d, 0x5d, 0x5c, 0x4e, 0x6b, 0x60, 0x4b, 0x61, /* !"#$%&'()*+,-./ */
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 30-3f: */
0xf8, 0xf9, 0x7a, 0x5e, 0x4c, 0x7e, 0x6e, 0x6f, /* 0123456789:;<=>? */
0x7c, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 40-4f: */
0xc8, 0xc9, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, /* @ABCDEFGHIJKLMNO */
0xd7, 0xd8, 0xd9, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, /* 50-5f: */
0xe7, 0xe8, 0xe9, 0xad, 0xe0, 0xbd, 0x5f, 0x6d, /* PQRSTUVWXYZ[\]^_ */
0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 60-6f: */
0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, /* `abcdefghijklmno */
0x97, 0x98, 0x99, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, /* 70-7f: */
0xa7, 0xa8, 0xa9, 0xc0, 0x4f, 0xd0, 0xa1, 0x07, /* pqrstuvwxyz{|}~. */
0x20, 0x21, 0x22, 0x23, 0x24, 0x04, 0x06, 0x08, /* 80-8f: */
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x09, 0x0a, 0x14, /* ................ */
0x30, 0x31, 0x25, 0x33, 0x34, 0x35, 0x36, 0x17, /* 90-9f: */
0x38, 0x39, 0x3a, 0x3b, 0x1a, 0x1b, 0x3e, 0xff, /* ................ */
0x41, 0xaa, 0x4a, 0xb1, 0x9f, 0xb2, 0x6a, 0xb5, /* a0-af: */
0xbb, 0xb4, 0x9a, 0x8a, 0xb0, 0xca, 0xaf, 0xbc, /* ................ */
0x90, 0x8f, 0xea, 0xfa, 0xbe, 0xa0, 0xb6, 0xb3, /* b0-bf: */
0x9d, 0xda, 0x9b, 0x8b, 0xb7, 0xb8, 0xb9, 0xab, /* ................ */
0x64, 0x65, 0x62, 0x66, 0x63, 0x67, 0x9e, 0x68, /* c0-cf: */
0x74, 0x71, 0x72, 0x73, 0x78, 0x75, 0x76, 0x77, /* ................ */
0xac, 0x69, 0xed, 0xee, 0xeb, 0xef, 0xec, 0xbf, /* d0-df: */
0x80, 0xfd, 0xfe, 0xfb, 0xfc, 0xba, 0xae, 0x59, /* ................ */
0x44, 0x45, 0x42, 0x46, 0x43, 0x47, 0x9c, 0x48, /* e0-ef: */
0x54, 0x51, 0x52, 0x53, 0x58, 0x55, 0x56, 0x57, /* ................ */
0x8c, 0x49, 0xcd, 0xce, 0xcb, 0xcf, 0xcc, 0xe1, /* f0-ff: */
0x70, 0xdd, 0xde, 0xdb, 0xdc, 0x8d, 0x8e, 0xdf /* ................ */
};
/* Translate a memory block from EBCDIC (host charset) to ASCII (net charset)
* dest and srce may be identical, or separate memory blocks, but
* should not overlap.
*/
void
ebcdic2ascii(void *dest, const void *srce, size_t count)
{
unsigned char *udest = dest;
const unsigned char *usrce = srce;
while (count-- != 0) {
*udest++ = os_toascii[*usrce++];
}
}
void
ebcdic2ascii_strictly(unsigned char *dest, const unsigned char *srce, size_t count)
{
while (count-- != 0) {
*dest++ = os_toascii_strictly[*srce++];
}
}
void
ascii2ebcdic(void *dest, const void *srce, size_t count)
{
unsigned char *udest = dest;
const unsigned char *usrce = srce;
while (count-- != 0) {
*udest++ = os_toebcdic[*usrce++];
}
}
#endif /*CHARSET_EBCDIC*/

8
os/tpf/ebcdic.h Normal file
View File

@@ -0,0 +1,8 @@
#include <sys/types.h>
extern const unsigned char os_toascii[256];
extern const unsigned char os_toebcdic[256];
void ebcdic2ascii(void *dest, const void *srce, size_t count);
void ebcdic2ascii_strictly(unsigned char *dest, const unsigned char *srce, size_t count);
void ascii2ebcdic(void *dest, const void *srce, size_t count);

31
os/tpf/os-inline.c Normal file
View File

@@ -0,0 +1,31 @@
/*
* This file contains functions which can be inlined if the compiler
* has an "inline" modifier. Because of this, this file is both a
* header file and a compilable module.
*
* Only inlineable functions should be defined in here. They must all
* include the INLINE modifier.
*
* If the compiler supports inline, this file will be #included as a
* header file from os.h to create all the inline function
* definitions. INLINE will be defined to whatever is required on
* function definitions to make them inline declarations.
*
* If the compiler does not support inline, this file will be compiled
* as a normal C file into libos.a (along with os.c). In this case
* INLINE will _not_ be set so we can use this to test if we are
* compiling this source file.
*/
#ifndef INLINE
#define INLINE
/* Anything required only when compiling */
#include "ap_config.h"
#endif
INLINE int ap_os_is_path_absolute(const char *file)
{
return (file && file[0] == '/' ? 1 : 0);
}

414
os/tpf/os.c Normal file
View File

@@ -0,0 +1,414 @@
/* ====================================================================
* Copyright (c) 1998-1999 The Apache Group. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* 4. The names "Apache Server" and "Apache Group" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Group and was originally based
* on public domain software written at the National Center for
* Supercomputing Applications, University of Illinois, Urbana-Champaign.
* For more information on the Apache Group and the Apache HTTP server
* project, please see <http://www.apache.org/>.
*
*/
/*
* This file will include OS specific functions which are not inlineable.
* Any inlineable functions should be defined in os-inline.c instead.
*/
#include "httpd.h"
#include "http_core.h"
#include "os.h"
#include "scoreboard.h"
#include "http_log.h"
#include "http_conf_globals.h"
static FILE *sock_fp;
/* Check the Content-Type to decide if conversion is needed */
int ap_checkconv(struct request_rec *r)
{
int convert_to_ascii;
const char *type;
/* To make serving of "raw ASCII text" files easy (they serve faster
* since they don't have to be converted from EBCDIC), a new
* "magic" type prefix was invented: text/x-ascii-{plain,html,...}
* If we detect one of these content types here, we simply correct
* the type to the real text/{plain,html,...} type. Otherwise, we
* set a flag that translation is required later on.
*/
type = (r->content_type == NULL) ? ap_default_type(r) : r->content_type;
/* If no content type is set then treat it as (ebcdic) text/plain */
convert_to_ascii = (type == NULL);
/* Conversion is applied to text/ files only, if ever. */
if (type && (strncasecmp(type, "text/", 5) == 0 ||
strncasecmp(type, "message/", 8) == 0)) {
if (strncasecmp(type, ASCIITEXT_MAGIC_TYPE_PREFIX,
sizeof(ASCIITEXT_MAGIC_TYPE_PREFIX)-1) == 0){
r->content_type = ap_pstrcat(r->pool, "text/",
type+sizeof(ASCIITEXT_MAGIC_TYPE_PREFIX)-1, NULL);
if (r->method_number == M_PUT)
ap_bsetflag(r->connection->client, B_ASCII2EBCDIC, 0);
}
else
/* translate EBCDIC to ASCII */
convert_to_ascii = 1;
}
else{
if (r->method_number == M_PUT)
ap_bsetflag(r->connection->client, B_ASCII2EBCDIC, 0);
/* don't translate non-text files to EBCDIC */
}
/* Enable conversion if it's a text document */
ap_bsetflag(r->connection->client, B_EBCDIC2ASCII, convert_to_ascii);
return convert_to_ascii;
}
int tpf_select(int maxfds, fd_set *reads, fd_set *writes, fd_set *excepts, struct timeval *tv)
{
/* We're going to force our way through select. We're only interested reads and TPF allows
2billion+ socket descriptors for we don't want an fd_set that big. Just assume that maxfds-1
contains the socket descriptor we're interested in. If it's 0, leave it alone. */
int sockets[1];
int no_reads = 0;
int no_writes = 0;
int no_excepts = 0;
int timeout = 0;
int rv;
if(maxfds) {
if(tv)
timeout = tv->tv_sec * 1000 + tv->tv_usec;
sockets[0] = maxfds-1;
no_reads++;
}
else
sockets[0] = 0;
ap_check_signals();
rv = select(sockets, no_reads, no_writes, no_excepts, timeout);
ap_check_signals();
return rv;
}
int tpf_accept(int sockfd, struct sockaddr *peer, int *paddrlen)
{
int socks[1];
int rv;
ap_check_signals();
socks[0] = sockfd;
rv = select(socks, 1, 0, 0, 1000);
errno = sock_errno();
if(rv>0) {
ap_check_signals();
rv = accept(sockfd, peer, paddrlen);
errno = sock_errno();
}
return rv;
}
/* the getpass function is not usable on TPF */
char *getpass(const char* prompt)
{
errno = EIO;
return((char *)NULL);
}
#ifndef __PIPE_
int pipe(int fildes[2])
{
errno = ENOSYS;
return(-1);
}
#endif
/* fork and exec functions are not defined on
TPF due to the implementation of tpf_fork() */
pid_t fork(void)
{
errno = ENOSYS;
return(-1);
}
int execl(const char *path, const char *arg0, ...)
{
errno = ENOSYS;
return(-1);
}
int execle(const char *path, const char *arg0, ...)
{
errno = ENOSYS;
return(-1);
}
int execve(const char *path, char *const argv[], char *const envp[])
{
errno = ENOSYS;
return(-1);
}
int execvp(const char *file, char *const argv[])
{
errno = ENOSYS;
return(-1);
}
int ap_tpf_spawn_child(pool *p, int (*func) (void *, child_info *),
void *data, enum kill_conditions kill_how,
int *pipe_in, int *pipe_out, int *pipe_err,
int out_fds[], int in_fds[], int err_fds[])
{
int i, temp_out, temp_in, temp_err, save_errno, pid, result=0;
int fd_flags_out, fd_flags_in, fd_flags_err;
struct tpf_fork_input fork_input;
TPF_FORK_CHILD *cld = (TPF_FORK_CHILD *) data;
array_header *env_arr = ap_table_elts ((array_header *) cld->subprocess_env);
table_entry *elts = (table_entry *) env_arr->elts;
if (func) {
if (result=func(data, NULL)) {
return 0; /* error from child function */
}
}
if (pipe_out) {
fd_flags_out = fcntl(out_fds[0], F_GETFD);
fcntl(out_fds[0], F_SETFD, FD_CLOEXEC);
temp_out = dup(STDOUT_FILENO);
fcntl(temp_out, F_SETFD, FD_CLOEXEC);
dup2(out_fds[1], STDOUT_FILENO);
}
if (pipe_in) {
fd_flags_in = fcntl(in_fds[1], F_GETFD);
fcntl(in_fds[1], F_SETFD, FD_CLOEXEC);
temp_in = dup(STDIN_FILENO);
fcntl(temp_in, F_SETFD, FD_CLOEXEC);
dup2(in_fds[0], STDIN_FILENO);
}
if (pipe_err) {
fd_flags_err = fcntl(err_fds[0], F_GETFD);
fcntl(err_fds[0], F_SETFD, FD_CLOEXEC);
temp_err = dup(STDERR_FILENO);
fcntl(temp_err, F_SETFD, FD_CLOEXEC);
dup2(err_fds[1], STDERR_FILENO);
}
if (cld->subprocess_env) {
for (i = 0; i < env_arr->nelts; ++i) {
if (!elts[i].key)
continue;
setenv (elts[i].key, elts[i].val, 1);
}
}
fork_input.program = (const char*) cld->filename;
fork_input.prog_type = cld->prog_type;
fork_input.istream = TPF_FORK_IS_BALANCE;
fork_input.ebw_data_length = 0;
fork_input.ebw_data = NULL;
fork_input.parm_data = NULL;
if ((pid = tpf_fork(&fork_input)) < 0) {
save_errno = errno;
if (pipe_out) {
close(out_fds[0]);
}
if (pipe_in) {
close(in_fds[1]);
}
if (pipe_err) {
close(err_fds[0]);
}
errno = save_errno;
pid = 0;
}
if (cld->subprocess_env) {
for (i = 0; i < env_arr->nelts; ++i) {
if (!elts[i].key)
continue;
unsetenv (elts[i].key);
}
}
if (pipe_out) {
close(out_fds[1]);
dup2(temp_out, STDOUT_FILENO);
close(temp_out);
fcntl(out_fds[0], F_SETFD, fd_flags_out);
}
if (pipe_in) {
close(in_fds[0]);
dup2(temp_in, STDIN_FILENO);
close(temp_in);
fcntl(in_fds[1], F_SETFD, fd_flags_in);
}
if (pipe_err) {
close(err_fds[1]);
dup2(temp_err, STDERR_FILENO);
close(temp_err);
fcntl(err_fds[0], F_SETFD, fd_flags_err);
}
if (pid) {
ap_note_subprocess(p, pid, kill_how);
if (pipe_out) {
*pipe_out = out_fds[0];
}
if (pipe_in) {
*pipe_in = in_fds[1];
}
if (pipe_err) {
*pipe_err = err_fds[0];
}
}
return pid;
}
pid_t os_fork(server_rec *s, int slot)
{
struct tpf_fork_input fork_input;
APACHE_TPF_INPUT input_parms;
int count;
listen_rec *lr;
fflush(stdin);
if (dup2(fileno(sock_fp), STDIN_FILENO) == -1)
ap_log_error(APLOG_MARK, APLOG_CRIT, s,
"unable to replace stdin with sock device driver");
fflush(stdout);
if (dup2(fileno(sock_fp), STDOUT_FILENO) == -1)
ap_log_error(APLOG_MARK, APLOG_CRIT, s,
"unable to replace stdout with sock device driver");
input_parms.generation = ap_my_generation;
#ifdef SCOREBOARD_FILE
input_parms.scoreboard_fd = scoreboard_fd;
#else /* must be USE_TPF_SCOREBOARD or USE_SHMGET_SCOREBOARD */
input_parms.scoreboard_heap = ap_scoreboard_image;
#endif
lr = ap_listeners;
count = 0;
do {
input_parms.listeners[count] = lr->fd;
lr = lr->next;
count++;
} while(lr != ap_listeners);
input_parms.slot = slot;
input_parms.restart_time = ap_restart_time;
fork_input.ebw_data = &input_parms;
fork_input.program = ap_server_argv0;
fork_input.prog_type = TPF_FORK_NAME;
fork_input.istream = TPF_FORK_IS_BALANCE;
fork_input.ebw_data_length = sizeof(input_parms);
fork_input.parm_data = "-x";
return tpf_fork(&fork_input);
}
int os_check_server(char *server) {
#ifndef USE_TPF_DAEMON
int rv;
int *current_acn;
if((rv = inetd_getServerStatus(server)) == INETD_SERVER_STATUS_INACTIVE)
return 1;
else {
current_acn = (int *)cinfc_fast(CINFC_CMMACNUM);
if(ecbp2()->ce2acn != *current_acn)
return 1;
}
#endif
return 0;
}
void os_note_additional_cleanups(pool *p, int sd) {
char sockfilename[50];
/* write the socket to file so that TPF socket device driver will close socket in case
we happen to abend. */
sprintf(sockfilename, "/dev/tpf.socket.file/%.8X", sd);
sock_fp = fopen(sockfilename, "r+");
ap_note_cleanups_for_file(p, sock_fp); /* arrange to close on exec or restart */
fcntl(sd,F_SETFD,FD_CLOEXEC);
}
void os_tpf_child(APACHE_TPF_INPUT *input_parms) {
tpf_child = 1;
ap_my_generation = input_parms->generation;
ap_restart_time = input_parms->restart_time;
}

108
os/tpf/os.h Normal file
View File

@@ -0,0 +1,108 @@
#ifndef APACHE_OS_H
#define APACHE_OS_H
#define PLATFORM "TPF"
#ifdef errno
#undef errno
#endif
/*
* This file in included in all Apache source code. It contains definitions
* of facilities available on _this_ operating system (HAVE_* macros),
* and prototypes of OS specific functions defined in os.c or os-inline.c
*/
#include "ap_config.h"
#if !defined(INLINE) && defined(USE_GNU_INLINE)
/* Compiler supports inline, so include the inlineable functions as
* part of the header
*/
#define INLINE extern ap_inline
#include "os-inline.c"
#endif
#ifndef INLINE
/* Compiler does not support inline, so prototype the inlineable functions
* as normal
*/
extern int ap_os_is_path_absolute(const char *f);
#endif
/* Other ap_os_ routines not used by this platform */
#define ap_os_is_filename_valid(f) (1)
#define ap_os_kill(pid, sig) kill(pid, sig)
/* Sorry if this is ugly, but the include order doesn't allow me
* to use request_rec here... */
struct request_rec;
extern int ap_checkconv(struct request_rec *r);
#include <strings.h>
#ifndef __strings_h
#define FD_SETSIZE 2048
typedef long fd_mask;
#define NBBY 8 /* number of bits in a byte */
#define NFDBITS (sizeof(fd_mask) * NBBY)
#define howmany(x, y) (((x)+((y)-1))/(y))
typedef struct fd_set {
fd_mask fds_bits [howmany(FD_SETSIZE, NFDBITS)];
} fd_set;
#define FD_CLR(n, p)((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
#define FD_ISSET(n, p)((p)->fds_bits[(n)/NFDBITS] & (1 <<((n) % NFDBITS)))
#define FD_ZERO(p) memset((char *)(p), 0, sizeof(*(p)))
#endif
#ifdef FD_SET
#undef FD_SET
#define FD_SET(n, p) (0)
#endif
#define RESOURCE_KEY ((void*) 0xC1C2C1C3)
/* TPF doesn't have, or need, tzset (it is used in mod_expires.c) */
#define tzset()
#include <i$netd.h>
struct apache_input {
INETD_SERVER_INPUT inetd_server;
void *scoreboard_heap; /* scoreboard system heap address */
int scoreboard_fd; /* scoreboard file descriptor */
int slot; /* child number */
int generation; /* server generation number */
int listeners[10];
time_t restart_time;
};
typedef struct apache_input APACHE_TPF_INPUT;
typedef struct tpf_fork_child {
char *filename;
enum { FORK_NAME = 1, FORK_FILE = 2 } prog_type;
void *subprocess_env;
}TPF_FORK_CHILD;
int tpf_accept(int sockfd, struct sockaddr *peer, int *paddrlen);
extern int tpf_child;
struct server_rec;
pid_t os_fork(struct server_rec *s, int slot);
int os_check_server(char *server);
char *getpass(const char *prompt);
extern char *ap_server_argv0;
extern int scoreboard_fd;
#include <signal.h>
#ifndef SIGPIPE
#define SIGPIPE 14
#endif
#ifdef NSIG
#undef NSIG
#endif
#endif /*! APACHE_OS_H*/

121
os/tpf/samples/linkdll.jcl Normal file
View File

@@ -0,0 +1,121 @@
//APACH JOB MSGLEVEL=(1,1),CLASS=A,MSGCLASS=A
/*ROUTE PRINT XXXXXX.XXXXXX
/*ROUTE PUNCH XXXXXX.XXXXXX
/*NOTIFY XXXXXX.XXXXXX
//CCLE JCLLIB ORDER=(SYS1.CBC.SCBCPRC,SYS1.CEE.SCEEPROC)
//PRELINK EXEC EDCPL,COND.LKED=(0,NE),
// PPARM='OMVS,DLLNAME(pppp)',
// LREGSIZ='2048K',
// LPARM='AMODE=31,RMODE=ANY,LIST,XREF'
//PLKED.SYSLIB DD DISP=SHR,DSN=FSE0000.DEVP.STUB.OB
// DD DISP=SHR,DSN=FSE0000.DEVP.CLIB.OB
// DD DISP=SHR,DSN=ACP.CLIB.RLSE46.WEB
// DD DISP=SHR,DSN=ACP.STUB.RLSE46.WEB
// DD DISP=SHR,DSN=ACP.CLIB.RLSE40
// DD DISP=SHR,DSN=ACP.STUB.RLSE40
//PLKED.SYSDEFSD DD DSN=APA0000.DEVP.IMPORTS.DSD(ppppvv),DISP=SHR
//PLKED.DSD DD DSN=APA0000.DEVP.IMPORTS.DSD,DISP=SHR
//PLKED.OBJLIB DD DISP=SHR,DSN=FSE0000.DEVP.TEST.OB
// DD DISP=SHR,DSN=ACP.OBJ.RLSE46.WEB
// DD DISP=SHR,DSN=ACP.OBJ.INTG98.NBS
// DD DISP=SHR,DSN=ACP.MAIN.SYST.OBBSS
// DD DISP=SHR,DSN=ACP.DF.MAIN.SYST.OBBSS
// DD DISP=SHR,DSN=ACP.OBJ.RLSE40.BSS
//PLKED.OBJ1 DD PATH='/usr/local/apache/src/ap/ap_cpystrn.o'
//PLKED.OBJ2 DD PATH='/usr/local/apache/src/ap/ap_execve.o'
//PLKED.OBJ3 DD PATH='/usr/local/apache/src/ap/ap_signal.o'
//PLKED.OBJ4 DD PATH='/usr/local/apache/src/ap/ap_slack.o'
//PLKED.OBJ5 DD PATH='/usr/local/apache/src/ap/ap_snprintf.o'
//PLKED.OBJ6 DD PATH='/usr/local/apache/src/ap/ap_strings.o'
//PLKED.OBJ7 DD PATH='/usr/local/apache/src/os/tpf/ebcdic.o'
//PLKED.OBJ8 DD PATH='/usr/local/apache/src/os/tpf/os.o'
//PLKED.OBJ9 DD PATH='/usr/local/apache/src/os/tpf/os-inline.o'
//PLKED.OBJ10 DD PATH='/usr/local/apache/src/regex/regcomp.o'
//PLKED.OBJ11 DD PATH='/usr/local/apache/src/regex/regerror.o'
//PLKED.OBJ12 DD PATH='/usr/local/apache/src/regex/regexec.o'
//PLKED.OBJ13 DD PATH='/usr/local/apache/src/regex/regfree.o'
//PLKED.OBJ14 DD PATH='/usr/local/apache/src/main/alloc.o'
//PLKED.OBJ15 DD PATH='/usr/local/apache/src/main/buff.o'
//PLKED.OBJ16 DD PATH='/usr/local/apache/src/main/fnmatch.o'
//PLKED.OBJ17 DD PATH='/usr/local/apache/src/main/http_config.o'
//PLKED.OBJ18 DD PATH='/usr/local/apache/src/main/http_core.o'
//PLKED.OBJ19 DD PATH='/usr/local/apache/src/main/http_log.o'
//PLKED.OBJ20 DD PATH='/usr/local/apache/src/main/http_main.o'
//PLKED.OBJ21 DD PATH='/usr/local/apache/src/main/http_protocol.o'
//PLKED.OBJ22 DD PATH='/usr/local/apache/src/main/http_request.o'
//PLKED.OBJ23 DD PATH='/usr/local/apache/src/main/http_vhost.o'
//PLKED.OBJ24 DD PATH='/usr/local/apache/src/main/md5c.o'
//PLKED.OBJ25 DD PATH='/usr/local/apache/src/main/rfc1413.o'
//PLKED.OBJ26 DD PATH='/usr/local/apache/src/main/util.o'
//PLKED.OBJ27 DD PATH='/usr/local/apache/src/main/util_date.o'
//PLKED.OBJ28 DD PATH='/usr/local/apache/src/main/util_md5.o'
//PLKED.OBJ29 DD PATH='/usr/local/apache/src/main/util_script.o'
//PLKED.OBJ30 DD PATH='/usr/local/apache/src/main/util_uri.o'
//PLKED.OBJ31 DD PATH='/usr/local/apache/src/modules.o'
//PLKED.OBJ32 DD PATH='/usr/local/apache/src/buildmark.o'
//PLKED.OBJ33 DD PATH='/usr/local/apache/src/modules/standard/mod_auto\
// index.o'
//PLKED.OBJ34 DD PATH='/usr/local/apache/src/modules/standard/mod_dir.\
// o'
//PLKED.OBJ35 DD PATH='/usr/local/apache/src/modules/standard/mod_mime\
// .o'
//PLKED.OBJ36 DD PATH='/usr/local/apache/src/modules/standard/mod_sete\
// nvif.o'
//PLKED.OBJ37 DD PATH='/usr/local/apache/src/modules/standard/mod_alia\
// s.o'
//PLKED.OBJ38 DD PATH='/usr/local/apache/src/modules/standard/mod_acce\
// ss.o'
//PLKED.OBJ39 DD PATH='/usr/local/apache/src/modules/standard/mod_user\
// dir.o'
//PLKED.OBJ40 DD PATH='/usr/local/apache/src/modules/standard/mod_spel\
// ing.o'
//PLKED.OBJ41 DD PATH='/usr/local/apache/src/modules/standard/mod_nego\
// tiation.o'
//PLKED.SYSIN DD *
ORDER @@DLMHDR
INCLUDE OBJLIB(CSTRTD40)
INCLUDE OBJ1
INCLUDE OBJ2
INCLUDE OBJ3
INCLUDE OBJ4
INCLUDE OBJ5
INCLUDE OBJ6
INCLUDE OBJ7
INCLUDE OBJ8
INCLUDE OBJ9
INCLUDE OBJ10
INCLUDE OBJ11
INCLUDE OBJ12
INCLUDE OBJ13
INCLUDE OBJ14
INCLUDE OBJ15
INCLUDE OBJ16
INCLUDE OBJ17
INCLUDE OBJ18
INCLUDE OBJ19
INCLUDE OBJ20
INCLUDE OBJ21
INCLUDE OBJ22
INCLUDE OBJ23
INCLUDE OBJ24
INCLUDE OBJ25
INCLUDE OBJ26
INCLUDE OBJ27
INCLUDE OBJ28
INCLUDE OBJ29
INCLUDE OBJ30
INCLUDE OBJ31
INCLUDE OBJ32
INCLUDE OBJ33
INCLUDE OBJ34
INCLUDE OBJ35
INCLUDE OBJ36
INCLUDE OBJ37
INCLUDE OBJ38
INCLUDE OBJ39
INCLUDE OBJ40
INCLUDE OBJ41
/*
//*** WARNING *** NEVER change .LK to .OB in SYSLMOD!!!
//LKED.SYSLMOD DD DISP=OLD,DSN=xxxxxx.xxxx(ppppvv)
//

View File

@@ -0,0 +1,58 @@
//OLDRWEB JOB MSGLEVEL=1,CLASS=A,MSGCLASS=S
//JOBCAT DD DSN=ICFCAT.ESAWK2,DISP=SHR
/*ROUTE PRINT xxxxxx.xxxxxxx
/*ROUTE PUNCH xxxxxx.xxxxxxx
//TLDR EXEC PGM=TPFLDRCA,REGION=8M,
// PARM='OLDR,SYS=ACP,CLMSIZE=8000000'
//STEPLIB DD DSN=ACP.LINK.RLSE46.WEB,DISP=SHR
// DD DSN=ACP.LINK.RLSE40.BSS,DISP=SHR
// DD DSN=VIS0000.DEVP.TEST.LK,DISP=SHR
// DD DSN=SYS1.CEE.SCEERUN,DISP=SHR
//SALTB DD DSN=ACP.SALTBL.RLSE46.WEB,DISP=SHR
// DD DSN=ACP.SALTBL.INTG46.WEB,DISP=SHR
//OBJLIB DD DSN=FSE0000.DEVP.TEST.OB,DISP=SHR
// DD DSN=APA0000.DEVP.TEST.OB,DISP=SHR
// DD DSN=ACP.DRVE.TEST.OB,DISP=SHR
// DD DSN=ACP.OBJ.RLSE46.WEB,DISP=SHR
// DD DSN=ACP.OBJ.INTG36.DRV,DISP=SHR
// DD DSN=ACP.OBJ.INTG46.WEB,DISP=SHR
// DD DSN=ACP.OBJ.INTG40.BSS,DISP=SHR
//LOADMOD DD DSN=FSE0000.DEVP.TEST.LK,DISP=SHR
// DD DSN=APA0000.DEVP.TEST.LK,DISP=SHR
// DD DSN=CWEISS.LINK,DISP=SHR
// DD DSN=ACP.DRVE.TEST.LK,DISP=SHR
// DD DSN=ACP.LINK.RLSE46.WEB,DISP=SHR
// DD DSN=ACP.LINK.INTG98.NBS,DISP=SHR
// DD DSN=ACP.LINK.INTG46.WEB,DISP=SHR
// DD DSN=ACP.LINK.INTG36.DRV,DISP=SHR
// DD DSN=ACP.LINK.INTG40.BSS,DISP=SHR
//LOADSUM DD DSN=&&LOADSUM,DISP=(NEW,PASS),UNIT=SYSDA,
// LRECL=133,SPACE=(TRK,(10,10)),RECFM=FBA
//CPRTEMP DD UNIT=SYSDA,
// DSN=&&CPRTEMP,SPACE=(TRK,(100,20)),
// DCB=(RECFM=FB,BLKSIZE=4095,LRECL=4095),
// DISP=(NEW,DELETE)
//PROGTEMP DD UNIT=SYSDA,
// DSN=&&PRTEMP,SPACE=(TRK,(100,20)),
// DCB=(RECFM=FB,BLKSIZE=4095,LRECL=4095),
// DISP=(NEW,DELETE)
//OUTPUT DD DSN=&&VRDROUT,DISP=(NEW,PASS),UNIT=SYSDA,
// DCB=(RECFM=F,BLKSIZE=4095,LRECL=4095)
//SYSUDUMP DD DUMMY
//SYSABEND DD DUMMY
//SYSOUT DD SYSOUT=A
//SYSPRINT DD SYSOUT=A
//PRINTER DD SYSOUT=A
//CEEDUMP DD SYSOUT=A
//SYSIN DD *
SYSID=BSS
PATVERS=NONE
SALVERS=40
LOADER LOADSET lllllll
LOADER CALL PROG ppppvv
/*
//TRANSMIT EXEC PGM=IKJEFT01,
// PARM='TRANSMIT xxxxxx.xxxxxx DDNAME(SYSTSIN) NOLOG NONOTIFY SEQ'
//SYSTSIN DD UNIT=SYSDA,
// DSN=&&VRDROUT,DISP=(OLD,DELETE)
//SYSTSPRT DD DUMMY

1
os/unix/.cvsignore Normal file
View File

@@ -0,0 +1 @@
Makefile

31
os/unix/os-inline.c Normal file
View File

@@ -0,0 +1,31 @@
/*
* This file contains functions which can be inlined if the compiler
* has an "inline" modifier. Because of this, this file is both a
* header file and a compilable module.
*
* Only inlineable functions should be defined in here. They must all
* include the INLINE modifier.
*
* If the compiler supports inline, this file will be #included as a
* header file from os.h to create all the inline function
* definitions. INLINE will be defined to whatever is required on
* function definitions to make them inline declarations.
*
* If the compiler does not support inline, this file will be compiled
* as a normal C file into libos.a (along with os.c). In this case
* INLINE will _not_ be set so we can use this to test if we are
* compiling this source file.
*/
#ifndef INLINE
#define INLINE
/* Anything required only when compiling */
#include "ap_config.h"
#endif
INLINE int ap_os_is_path_absolute(const char *file)
{
return file[0] == '/';
}

147
os/unix/os.h Normal file
View File

@@ -0,0 +1,147 @@
/* ====================================================================
* Copyright (c) 1998-1999 The Apache Group. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* 4. The names "Apache Server" and "Apache Group" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Group and was originally based
* on public domain software written at the National Center for
* Supercomputing Applications, University of Illinois, Urbana-Champaign.
* For more information on the Apache Group and the Apache HTTP server
* project, please see <http://www.apache.org/>.
*
*/
#ifndef APACHE_OS_H
#define APACHE_OS_H
#include "ap_config.h"
#ifndef PLATFORM
#define PLATFORM "Unix"
#endif
/*
* This file in included in all Apache source code. It contains definitions
* of facilities available on _this_ operating system (HAVE_* macros),
* and prototypes of OS specific functions defined in os.c or os-inline.c
*/
#if !defined(INLINE) && defined(USE_GNU_INLINE)
/* Compiler supports inline, so include the inlineable functions as
* part of the header
*/
#define INLINE extern ap_inline
INLINE int ap_os_is_path_absolute(const char *file);
#include "os-inline.c"
#else
/* Compiler does not support inline, so prototype the inlineable functions
* as normal
*/
extern int ap_os_is_path_absolute(const char *file);
#endif
/* Other ap_os_ routines not used by this platform */
#define ap_os_is_filename_valid(f) (1)
#define ap_os_kill(pid, sig) kill(pid, sig)
/*
* Abstraction layer for loading
* Apache modules under run-time via
* dynamic shared object (DSO) mechanism
*/
#ifdef HAVE_DL_H
#include <dl.h>
#endif
/*
* Do not use native AIX DSO support
*/
#ifdef AIX
#undef HAVE_DLFCN_H
#endif
#ifdef HAVE_DLFCN_H
#include <dlfcn.h>
#else
void *dlopen(const char *, int);
int dlclose(void *);
void *dlsym(void *, const char *);
const char *dlerror(void);
#endif
/* probably on an older system that doesn't support RTLD_NOW or RTLD_LAZY.
* The below define is a lie since we are really doing RTLD_LAZY since the
* system doesn't support RTLD_NOW.
*/
#ifndef RTLD_NOW
#define RTLD_NOW 1
#endif
#ifndef RTLD_GLOBAL
#define RTLD_GLOBAL 0
#endif
#if (defined(__FreeBSD__) ||\
defined(__OpenBSD__) ||\
defined(__NetBSD__) ) && !defined(__ELF__)
#define DLSYM_NEEDS_UNDERSCORE
#endif
#define ap_os_dso_handle_t void *
void ap_os_dso_init(void);
void * ap_os_dso_load(const char *);
void ap_os_dso_unload(void *);
void * ap_os_dso_sym(void *, const char *);
const char *ap_os_dso_error(void);
#endif /* !APACHE_OS_H */

27
os/win32/.cvsignore Normal file
View File

@@ -0,0 +1,27 @@
*.mdp
*.ncb
*.opt
*.plg
*.dsw
ApacheModuleAuthAnonD
ApacheModuleAuthAnonR
ApacheModuleCERNMetaD
ApacheModuleCERNMetaR
ApacheModuleDigestD
ApacheModuleDigestR
ApacheModuleExpiresD
ApacheModuleExpiresR
ApacheModuleHeadersD
ApacheModuleHeadersR
ApacheModuleInfoD
ApacheModuleInfoR
ApacheModuleRewriteD
ApacheModuleRewriteR
ApacheModuleSpelingD
ApacheModuleSpelingR
ApacheModuleStatusD
ApacheModuleStatusR
ApacheModuleUserTrackD
ApacheModuleUserTrackR
ApacheOSR
ApacheOSD

View File

@@ -0,0 +1,59 @@
#include <fstream.h>
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void MakeMake(const char *szModule,const char *szSource)
{
ifstream ifs("Module.mak.tmpl",ios::nocreate);
assert(ifs.good());
char buf[1024];
sprintf(buf,"%s.mak",szModule);
ofstream ofs(buf,ios::trunc);
for( ; ; )
{
ifs.getline(buf,sizeof buf);
if(ifs.eof())
break;
for(char *s=buf ; *s ; )
{
char *p=strchr(s,'%');
if(!p)
{
ofs << s << '\n';
break;
}
if(!strncmp(p,"%Module%",8))
{
ofs.write(s,p-s);
ofs << szModule;
s=p+8;
}
else if(!strncmp(p,"%Source%",8))
{
ofs.write(s,p-s);
ofs << szSource;
s=p+8;
}
else
{
ofs.write(s,p-s+1);
s=p+1;
}
}
}
}
void main(int argc,char **argv)
{
if(argc < 2 || (argc%2) != 1)
{
cerr << argv[0] << " [<module name> <source file>]+\n";
exit(1);
}
for(int n=1 ; n < argc ; n+=2)
MakeMake(argv[n],argv[n+1]);
}

230
os/win32/Module.mak.tmpl Normal file
View File

@@ -0,0 +1,230 @@
# Microsoft Developer Studio Generated NMAKE File, Format Version 4.20
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
!IF "$(CFG)" == ""
CFG=%Module% - Win32 Debug
!MESSAGE No configuration specified. Defaulting to %Module% - Win32\
Debug.
!ENDIF
!IF "$(CFG)" != "%Module% - Win32 Release" && "$(CFG)" !=\
"%Module% - Win32 Debug"
!MESSAGE Invalid configuration "$(CFG)" specified.
!MESSAGE You can specify a configuration when running NMAKE on this makefile
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "%Module%.mak"\
CFG="%Module% - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "%Module% - Win32 Release" (based on\
"Win32 (x86) Dynamic-Link Library")
!MESSAGE "%Module% - Win32 Debug" (based on\
"Win32 (x86) Dynamic-Link Library")
!MESSAGE
!ERROR An invalid configuration is specified.
!ENDIF
!IF "$(OS)" == "Windows_NT"
NULL=
!ELSE
NULL=nul
!ENDIF
################################################################################
# Begin Project
# PROP Target_Last_Scanned "%Module% - Win32 Debug"
MTL=mktyplib.exe
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "%Module% - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "%Module%R"
# PROP Intermediate_Dir "%Module%R"
# PROP Target_Dir ""
OUTDIR=.\%Module%R
INTDIR=.\%Module%R
ALL : "$(OUTDIR)\%Module%.dll"
CLEAN :
-@erase "$(INTDIR)\%Source%.obj"
-@erase "$(OUTDIR)\%Module%.dll"
-@erase "$(OUTDIR)\%Module%.exp"
-@erase "$(OUTDIR)\%Module%.lib"
"$(OUTDIR)" :
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\regex" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
CPP_PROJ=/nologo /MD /W3 /GX /O2 /I "..\regex" /D "WIN32" /D "NDEBUG" /D\
"_WINDOWS" /Fp"$(INTDIR)/%Module%.pch" /YX /Fo"$(INTDIR)/" /c
CPP_OBJS=.\%Module%R/
CPP_SBRS=.\.
# ADD BASE MTL /nologo /D "NDEBUG" /win32
# ADD MTL /nologo /D "NDEBUG" /win32
MTL_PROJ=/nologo /D "NDEBUG" /win32
# ADD BASE RSC /l 0x809 /d "NDEBUG"
# ADD RSC /l 0x809 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
BSC32_FLAGS=/nologo /o"$(OUTDIR)/%Module%.bsc"
BSC32_SBRS= \
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
# ADD LINK32 ..\CoreR\ApacheCore.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
LINK32_FLAGS=..\CoreR\ApacheCore.lib kernel32.lib user32.lib gdi32.lib\
winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib\
uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll\
/incremental:no /pdb:"$(OUTDIR)/%Module%.pdb" /machine:I386\
/out:"$(OUTDIR)/%Module%.dll"\
/implib:"$(OUTDIR)/%Module%.lib"
LINK32_OBJS= \
"$(INTDIR)\%Source%.obj"
"$(OUTDIR)\%Module%.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<<
!ELSEIF "$(CFG)" == "%Module% - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "%Module%D"
# PROP Intermediate_Dir "%Module%D"
# PROP Target_Dir ""
OUTDIR=.\%Module%D
INTDIR=.\%Module%D
ALL : "$(OUTDIR)\%Module%.dll"
CLEAN :
-@erase "$(INTDIR)\%Source%.obj"
-@erase "$(INTDIR)\vc40.idb"
-@erase "$(INTDIR)\vc40.pdb"
-@erase "$(OUTDIR)\%Module%.dll"
-@erase "$(OUTDIR)\%Module%.exp"
-@erase "$(OUTDIR)\%Module%.ilk"
-@erase "$(OUTDIR)\%Module%.lib"
-@erase "$(OUTDIR)\%Module%.pdb"
"$(OUTDIR)" :
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\regex" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
CPP_PROJ=/nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\regex" /D "WIN32" /D "_DEBUG"\
/D "_WINDOWS" /Fp"$(INTDIR)/%Module%.pch" /YX /Fo"$(INTDIR)/"\
/Fd"$(INTDIR)/" /c
CPP_OBJS=.\%Module%D/
CPP_SBRS=.\.
# ADD BASE MTL /nologo /D "_DEBUG" /win32
# ADD MTL /nologo /D "_DEBUG" /win32
MTL_PROJ=/nologo /D "_DEBUG" /win32
# ADD BASE RSC /l 0x809 /d "_DEBUG"
# ADD RSC /l 0x809 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
BSC32_FLAGS=/nologo /o"$(OUTDIR)/%Module%.bsc"
BSC32_SBRS= \
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386
# ADD LINK32 ..\CoreD\ApacheCore.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386
LINK32_FLAGS=..\CoreD\ApacheCore.lib kernel32.lib user32.lib gdi32.lib\
winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib\
uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll\
/incremental:yes /pdb:"$(OUTDIR)/%Module%.pdb" /debug /machine:I386\
/out:"$(OUTDIR)/%Module%.dll"\
/implib:"$(OUTDIR)/%Module%.lib"
LINK32_OBJS= \
"$(INTDIR)\%Source%.obj"
"$(OUTDIR)\%Module%.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<<
!ENDIF
.c{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
.cpp{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
.cxx{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
.c{$(CPP_SBRS)}.sbr:
$(CPP) $(CPP_PROJ) $<
.cpp{$(CPP_SBRS)}.sbr:
$(CPP) $(CPP_PROJ) $<
.cxx{$(CPP_SBRS)}.sbr:
$(CPP) $(CPP_PROJ) $<
################################################################################
# Begin Target
# Name "%Module% - Win32 Release"
# Name "%Module% - Win32 Debug"
!IF "$(CFG)" == "%Module% - Win32 Release"
!ELSEIF "$(CFG)" == "%Module% - Win32 Debug"
!ENDIF
################################################################################
# Begin Source File
SOURCE=\work\apache\src\%Source%.c
DEP_CPP_MOD_A=\
"..\alloc.h"\
"..\buff.h"\
"..\conf.h"\
"..\http_config.h"\
"..\http_core.h"\
"..\http_log.h"\
"..\http_request.h"\
"..\httpd.h"\
"..\regex\regex.h"\
"..\ap_mmn.h"\
".\readdir.h"\
{$(INCLUDE)}"\sys\stat.h"\
{$(INCLUDE)}"\sys\types.h"\
NODEP_CPP_MOD_A=\
"..\sfio.h"\
"$(INTDIR)\%Source%.obj" : $(SOURCE) $(DEP_CPP_MOD_A) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
# End Source File
# End Target
# End Project
################################################################################

569
os/win32/mod_isapi.c Normal file
View File

@@ -0,0 +1,569 @@
/* ====================================================================
* Copyright (c) 1995-1999 The Apache Group. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* 4. The names "Apache Server" and "Apache Group" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Group and was originally based
* on public domain software written at the National Center for
* Supercomputing Applications, University of Illinois, Urbana-Champaign.
* For more information on the Apache Group and the Apache HTTP server
* project, please see <http://www.apache.org/>.
*
*/
/*
* mod_isapi.c - Internet Server Application (ISA) module for Apache
* by Alexei Kosut <akosut@apache.org>
*
* This module implements Microsoft's ISAPI, allowing Apache (when running
* under Windows) to load Internet Server Applications (ISAPI extensions).
* It implements all of the ISAPI 2.0 specification, except for the
* "Microsoft-only" extensions dealing with asynchronous I/O. All ISAPI
* extensions that use only synchronous I/O and are compatible with the
* ISAPI 2.0 specification should work (most ISAPI 1.0 extensions should
* function as well).
*
* To load, simply place the ISA in a location in the document tree.
* Then add an "AddHandler isapi-isa dll" into your config file.
* You should now be able to load ISAPI DLLs just be reffering to their
* URLs. Make sure the ExecCGI option is active in the directory
* the ISA is in.
*/
#include "httpd.h"
#include "http_config.h"
#include "http_core.h"
#include "http_protocol.h"
#include "http_request.h"
#include "http_log.h"
#include "util_script.h"
/* We use the exact same header file as the original */
#include <HttpExt.h>
/* Seems IIS does not enforce the requirement for \r\n termination on HSE_REQ_SEND_RESPONSE_HEADER,
define this to conform */
#define RELAX_HEADER_RULE
module isapi_module;
/* Our "Connection ID" structure */
typedef struct {
LPEXTENSION_CONTROL_BLOCK ecb;
request_rec *r;
int status;
} isapi_cid;
/* Declare the ISAPI functions */
BOOL WINAPI GetServerVariable (HCONN hConn, LPSTR lpszVariableName,
LPVOID lpvBuffer, LPDWORD lpdwSizeofBuffer);
BOOL WINAPI WriteClient (HCONN ConnID, LPVOID Buffer, LPDWORD lpwdwBytes,
DWORD dwReserved);
BOOL WINAPI ReadClient (HCONN ConnID, LPVOID lpvBuffer, LPDWORD lpdwSize);
BOOL WINAPI ServerSupportFunction (HCONN hConn, DWORD dwHSERequest,
LPVOID lpvBuffer, LPDWORD lpdwSize,
LPDWORD lpdwDataType);
/*
The optimiser blows it totally here. What happens is that autos are addressed relative to the
stack pointer, which, of course, moves around. The optimiser seems to lose track of it somewhere
between setting isapi_entry and calling through it. We work around the problem by forcing it to
use frame pointers.
*/
#pragma optimize("y",off)
int isapi_handler (request_rec *r) {
LPEXTENSION_CONTROL_BLOCK ecb =
ap_pcalloc(r->pool, sizeof(struct _EXTENSION_CONTROL_BLOCK));
HSE_VERSION_INFO *pVer = ap_pcalloc(r->pool, sizeof(HSE_VERSION_INFO));
HINSTANCE isapi_handle;
BOOL (*isapi_version)(HSE_VERSION_INFO *); /* entry point 1 */
DWORD (*isapi_entry)(LPEXTENSION_CONTROL_BLOCK); /* entry point 2 */
BOOL (*isapi_term)(DWORD); /* optional entry point 3 */
isapi_cid *cid = ap_pcalloc(r->pool, sizeof(isapi_cid));
table *e = r->subprocess_env;
int retval;
/* Use similar restrictions as CGIs */
if (!(ap_allow_options(r) & OPT_EXECCGI))
return FORBIDDEN;
if (r->finfo.st_mode == 0)
return NOT_FOUND;
if (S_ISDIR(r->finfo.st_mode))
return FORBIDDEN;
/* Load the module */
if (!(isapi_handle = LoadLibraryEx(r->filename, NULL,
LOAD_WITH_ALTERED_SEARCH_PATH))) {
ap_log_rerror(APLOG_MARK, APLOG_ALERT, r,
"Could not load DLL: %s", r->filename);
return SERVER_ERROR;
}
if (!(isapi_version =
(void *)(GetProcAddress(isapi_handle, "GetExtensionVersion")))) {
ap_log_rerror(APLOG_MARK, APLOG_ALERT, r,
"DLL could not load GetExtensionVersion(): %s", r->filename);
FreeLibrary(isapi_handle);
return SERVER_ERROR;
}
if (!(isapi_entry =
(void *)(GetProcAddress(isapi_handle, "HttpExtensionProc")))) {
ap_log_rerror(APLOG_MARK, APLOG_ALERT, r,
"DLL could not load HttpExtensionProc(): %s", r->filename);
FreeLibrary(isapi_handle);
return SERVER_ERROR;
}
isapi_term = (void *)(GetProcAddress(isapi_handle, "TerminateExtension"));
/* Run GetExtensionVersion() */
if ((*isapi_version)(pVer) != TRUE) {
ap_log_rerror(APLOG_MARK, APLOG_ALERT, r,
"ISAPI GetExtensionVersion() failed: %s", r->filename);
FreeLibrary(isapi_handle);
return SERVER_ERROR;
}
/* Set up variables */
ap_add_common_vars(r);
ap_add_cgi_vars(r);
/* Set up connection ID */
ecb->ConnID = (HCONN)cid;
cid->ecb = ecb;
cid->r = r;
cid->status = 0;
ecb->cbSize = sizeof(struct _EXTENSION_CONTROL_BLOCK);
ecb->dwVersion = MAKELONG(0, 2);
ecb->dwHttpStatusCode = 0;
strcpy(ecb->lpszLogData, "");
ecb->lpszMethod = r->method;
ecb->lpszQueryString = ap_table_get(e, "QUERY_STRING");
ecb->lpszPathInfo = ap_table_get(e, "PATH_INFO");
ecb->lpszPathTranslated = ap_table_get(e, "PATH_TRANSLATED");
ecb->lpszContentType = ap_table_get(e, "CONTENT_TYPE");
/* Set up client input */
if ((retval = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR))) {
if (isapi_term) (*isapi_term)(HSE_TERM_MUST_UNLOAD);
FreeLibrary(isapi_handle);
return retval;
}
if (ap_should_client_block(r)) {
/* Unlike IIS, which limits this to 48k, we read the whole
* sucker in. I suppose this could be bad for memory if someone
* uploaded the complete works of Shakespeare. Well, WebSite
* does the same thing.
*/
long to_read = atol(ap_table_get(e, "CONTENT_LENGTH"));
long read;
/* Actually, let's cap it at 48k, until we figure out what
* to do with this... we don't want a Content-Length: 1000000000
* taking out the machine.
*/
if (to_read > 49152) {
if (isapi_term) (*isapi_term)(HSE_TERM_MUST_UNLOAD);
FreeLibrary(isapi_handle);
return HTTP_REQUEST_ENTITY_TOO_LARGE;
}
ecb->lpbData = ap_pcalloc(r->pool, 1 + to_read);
if ((read = ap_get_client_block(r, ecb->lpbData, to_read)) < 0) {
if (isapi_term) (*isapi_term)(HSE_TERM_MUST_UNLOAD);
FreeLibrary(isapi_handle);
return SERVER_ERROR;
}
/* Although its not to spec, IIS seems to null-terminate
* its lpdData string. So we will too. To make sure
* cbAvailable matches cbTotalBytes, we'll up the latter
* and equalize them.
*/
ecb->cbAvailable = ecb->cbTotalBytes = read + 1;
ecb->lpbData[read] = '\0';
}
else {
ecb->cbTotalBytes = 0;
ecb->cbAvailable = 0;
ecb->lpbData = NULL;
}
/* Set up the callbacks */
ecb->GetServerVariable = &GetServerVariable;
ecb->WriteClient = &WriteClient;
ecb->ReadClient = &ReadClient;
ecb->ServerSupportFunction = &ServerSupportFunction;
/* All right... try and load the sucker */
retval = (*isapi_entry)(ecb);
/* Set the status (for logging) */
if (ecb->dwHttpStatusCode)
r->status = ecb->dwHttpStatusCode;
/* Check for a log message - and log it */
if (ecb->lpszLogData && strcmp(ecb->lpszLogData, ""))
ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
"%s: %s", ecb->lpszLogData, r->filename);
/* All done with the DLL... get rid of it */
if (isapi_term) (*isapi_term)(HSE_TERM_MUST_UNLOAD);
FreeLibrary(isapi_handle);
switch(retval) {
case HSE_STATUS_SUCCESS:
case HSE_STATUS_SUCCESS_AND_KEEP_CONN:
/* Ignore the keepalive stuff; Apache handles it just fine without
* the ISA's "advice".
*/
if (cid->status) /* We have a special status to return */
return cid->status;
return OK;
case HSE_STATUS_PENDING: /* We don't support this */
ap_log_rerror(APLOG_MARK, APLOG_WARNING, r,
"ISAPI asynchronous I/O not supported: %s", r->filename);
case HSE_STATUS_ERROR:
default:
return SERVER_ERROR;
}
}
#pragma optimize("",on)
BOOL WINAPI GetServerVariable (HCONN hConn, LPSTR lpszVariableName,
LPVOID lpvBuffer, LPDWORD lpdwSizeofBuffer) {
request_rec *r = ((isapi_cid *)hConn)->r;
table *e = r->subprocess_env;
const char *result;
/* Mostly, we just grab it from the environment, but there are
* a couple of special cases
*/
if (!strcasecmp(lpszVariableName, "UNMAPPED_REMOTE_USER")) {
/* We don't support NT users, so this is always the same as
* REMOTE_USER
*/
result = ap_table_get(e, "REMOTE_USER");
}
else if (!strcasecmp(lpszVariableName, "SERVER_PORT_SECURE")) {
/* Apache doesn't support secure requests inherently, so
* we have no way of knowing. We'll be conservative, and say
* all requests are insecure.
*/
result = "0";
}
else if (!strcasecmp(lpszVariableName, "URL")) {
result = r->uri;
}
else {
result = ap_table_get(e, lpszVariableName);
}
if (result) {
if (strlen(result) > *lpdwSizeofBuffer) {
*lpdwSizeofBuffer = strlen(result);
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return FALSE;
}
strncpy(lpvBuffer, result, *lpdwSizeofBuffer);
return TRUE;
}
/* Didn't find it */
SetLastError(ERROR_INVALID_INDEX);
return FALSE;
}
BOOL WINAPI WriteClient (HCONN ConnID, LPVOID Buffer, LPDWORD lpwdwBytes,
DWORD dwReserved) {
request_rec *r = ((isapi_cid *)ConnID)->r;
int writ; /* written, actually, but why shouldn't I make up words? */
/* We only support synchronous writing */
if (dwReserved && dwReserved != HSE_IO_SYNC) {
ap_log_rerror(APLOG_MARK, APLOG_WARNING, r,
"ISAPI asynchronous I/O not supported: %s", r->filename);
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if ((writ = ap_rwrite(Buffer, *lpwdwBytes, r)) == EOF) {
SetLastError(ERROR); /* XXX: Find the right error code */
return FALSE;
}
*lpwdwBytes = writ;
return TRUE;
}
BOOL WINAPI ReadClient (HCONN ConnID, LPVOID lpvBuffer, LPDWORD lpdwSize) {
/* Doesn't need to do anything; we've read all the data already */
return TRUE;
}
/* XXX: There is an O(n^2) attack possible here. */
BOOL WINAPI ServerSupportFunction (HCONN hConn, DWORD dwHSERequest,
LPVOID lpvBuffer, LPDWORD lpdwSize,
LPDWORD lpdwDataType) {
isapi_cid *cid = (isapi_cid *)hConn;
request_rec *subreq, *r = cid->r;
char *data;
switch (dwHSERequest) {
case HSE_REQ_SEND_URL_REDIRECT_RESP:
/* Set the status to be returned when the HttpExtensionProc()
* is done.
*/
ap_table_set (r->headers_out, "Location", lpvBuffer);
cid->status = cid->r->status = cid->ecb->dwHttpStatusCode = REDIRECT;
return TRUE;
case HSE_REQ_SEND_URL:
/* Read any additional input */
if (r->remaining > 0) {
char argsbuffer[HUGE_STRING_LEN];
while (ap_get_client_block(r, argsbuffer, HUGE_STRING_LEN));
}
/* Reset the method to GET */
r->method = ap_pstrdup(r->pool, "GET");
r->method_number = M_GET;
/* Don't let anyone think there's still data */
ap_table_unset(r->headers_in, "Content-Length");
ap_internal_redirect((char *)lpvBuffer, r);
return TRUE;
case HSE_REQ_SEND_RESPONSE_HEADER:
r->status_line = lpvBuffer ? lpvBuffer : ap_pstrdup(r->pool, "200 OK");
sscanf(r->status_line, "%d", &r->status);
cid->ecb->dwHttpStatusCode = r->status;
/* Now fill in the HTTP headers, and the rest of it. Ick.
* lpdwDataType contains a string that has headers (in MIME
* format), a blank like, then (possibly) data. We need
* to parse it.
*
* Easy case first:
*/
if (!lpdwDataType) {
ap_send_http_header(r);
return TRUE;
}
/* Make a copy - don't disturb the original */
data = ap_pstrdup(r->pool, (char *)lpdwDataType);
/* We *should* break before this while loop ends */
while (*data) {
char *value, *lf = strchr(data, '\n');
int p;
#ifdef RELAX_HEADER_RULE
if (lf)
*lf = '\0';
#else
if (!lf) { /* Huh? Invalid data, I think */
ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
"ISA sent invalid headers: %s", r->filename);
SetLastError(ERROR); /* XXX: Find right error */
return FALSE;
}
/* Get rid of \n and \r */
*lf = '\0';
#endif
p = strlen(data);
if (p > 0 && data[p-1] == '\r') data[p-1] = '\0';
/* End of headers */
if (*data == '\0') {
#ifdef RELAX_HEADER_RULE
if (lf)
#endif
data = lf + 1; /* Reset data */
break;
}
if (!(value = strchr(data, ':'))) {
SetLastError(ERROR); /* XXX: Find right error */
ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
"ISA sent invalid headers", r->filename);
return FALSE;
}
*value++ = '\0';
while (*value && ap_isspace(*value)) ++value;
/* Check all the special-case headers. Similar to what
* ap_scan_script_header_err() does (see that function for
* more detail)
*/
if (!strcasecmp(data, "Content-Type")) {
char *tmp;
/* Nuke trailing whitespace */
char *endp = value + strlen(value) - 1;
while (endp > value && ap_isspace(*endp)) *endp-- = '\0';
tmp = ap_pstrdup (r->pool, value);
ap_str_tolower(tmp);
r->content_type = tmp;
}
else if (!strcasecmp(data, "Content-Length")) {
ap_table_set(r->headers_out, data, value);
}
else if (!strcasecmp(data, "Transfer-Encoding")) {
ap_table_set(r->headers_out, data, value);
}
else if (!strcasecmp(data, "Set-Cookie")) {
ap_table_add(r->err_headers_out, data, value);
}
else {
ap_table_merge(r->err_headers_out, data, value);
}
/* Reset data */
#ifdef RELAX_HEADER_RULE
if (!lf) {
data += p;
break;
}
#endif
data = lf + 1;
}
/* All the headers should be set now */
ap_send_http_header(r);
/* Any data left should now be sent directly */
ap_rputs(data, r);
return TRUE;
case HSE_REQ_MAP_URL_TO_PATH:
/* Map a URL to a filename */
subreq = ap_sub_req_lookup_uri(ap_pstrndup(r->pool, (char *)lpvBuffer,
*lpdwSize), r);
GetFullPathName(subreq->filename, *lpdwSize - 1, (char *)lpvBuffer, NULL);
/* IIS puts a trailing slash on directories, Apache doesn't */
if (S_ISDIR (subreq->finfo.st_mode)) {
int l = strlen((char *)lpvBuffer);
((char *)lpvBuffer)[l] = '\\';
((char *)lpvBuffer)[l + 1] = '\0';
}
return TRUE;
case HSE_REQ_DONE_WITH_SESSION:
/* Do nothing... since we don't support async I/O, they'll
* return from HttpExtensionProc soon
*/
return TRUE;
/* We don't support all this async I/O, Microsoft-specific stuff */
case HSE_REQ_IO_COMPLETION:
case HSE_REQ_TRANSMIT_FILE:
ap_log_rerror(APLOG_MARK, APLOG_WARNING, r,
"ISAPI asynchronous I/O not supported: %s", r->filename);
default:
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
}
handler_rec isapi_handlers[] = {
{ "isapi-isa", isapi_handler },
{ NULL}
};
module isapi_module = {
STANDARD_MODULE_STUFF,
NULL, /* initializer */
NULL, /* create per-dir config */
NULL, /* merge per-dir config */
NULL, /* server config */
NULL, /* merge server config */
NULL, /* command table */
isapi_handlers, /* handlers */
NULL, /* filename translation */
NULL, /* check_user_id */
NULL, /* check auth */
NULL, /* check access */
NULL, /* type_checker */
NULL, /* logger */
NULL /* header parser */
};

72
os/win32/modules.c Normal file
View File

@@ -0,0 +1,72 @@
/* modules.c --- major modules compiled into Apache for Win32.
* Only insert an entry for a module if it must be compiled into
* the core server
*/
#include "httpd.h"
#include "http_config.h"
extern module core_module;
extern module so_module;
extern module mime_module;
extern module access_module;
extern module auth_module;
extern module negotiation_module;
extern module includes_module;
extern module autoindex_module;
extern module dir_module;
extern module cgi_module;
extern module userdir_module;
extern module alias_module;
extern module env_module;
extern module config_log_module;
extern module asis_module;
extern module imap_module;
extern module action_module;
extern module setenvif_module;
extern module isapi_module;
module *ap_prelinked_modules[] = {
&core_module,
&so_module,
&mime_module,
&access_module,
&auth_module,
&negotiation_module,
&includes_module,
&autoindex_module,
&dir_module,
&cgi_module,
&userdir_module,
&alias_module,
&env_module,
&config_log_module,
&asis_module,
&imap_module,
&action_module,
&setenvif_module,
&isapi_module,
NULL
};
module *ap_preloaded_modules[] = {
&core_module,
&so_module,
&mime_module,
&access_module,
&auth_module,
&negotiation_module,
&includes_module,
&autoindex_module,
&dir_module,
&cgi_module,
&userdir_module,
&alias_module,
&env_module,
&config_log_module,
&asis_module,
&imap_module,
&action_module,
&setenvif_module,
&isapi_module,
NULL
};

126
os/win32/os.h Normal file
View File

@@ -0,0 +1,126 @@
#ifndef APACHE_OS_H
#define APACHE_OS_H
#define PLATFORM "Win32"
/*
* This file in included in all Apache source code. It contains definitions
* of facilities available on _this_ operating system (HAVE_* macros),
* and prototypes of OS specific functions defined in os.c
*/
/* temporarily replace crypt */
/* char *crypt(const char *pw, const char *salt); */
#define crypt(buf,salt) (buf)
/* Although DIR_TYPE is dirent (see nt/readdir.h) we need direct.h for
chdir() */
#include <direct.h>
#define STATUS
/*#define WIN32_LEAN_AND_MEAN Now defined in project files */
#ifndef STRICT
#define STRICT
#endif
#define CASE_BLIND_FILESYSTEM
#define NO_WRITEV
#define NO_SETSID
#define NO_USE_SIGACTION
#define NO_TIMES
#define NO_GETTIMEOFDAY
//#define NEED_PROCESS_H although we do, this is specially handled in ap_config.h
#define USE_LONGJMP
#define HAVE_MMAP
#define USE_MMAP_SCOREBOARD
#define MULTITHREAD
#define HAVE_CANONICAL_FILENAME
#define HAVE_DRIVE_LETTERS
typedef int uid_t;
typedef int gid_t;
typedef int pid_t;
typedef int mode_t;
typedef char * caddr_t;
/*
Define export types. API_EXPORT_NONSTD is a nasty hack to avoid having to declare
every configuration function as __stdcall.
*/
#ifdef SHARED_MODULE
# define API_VAR_EXPORT __declspec(dllimport)
# define API_EXPORT(type) __declspec(dllimport) type __stdcall
# define API_EXPORT_NONSTD(type) __declspec(dllimport) type
#else
# define API_VAR_EXPORT __declspec(dllexport)
# define API_EXPORT(type) __declspec(dllexport) type __stdcall
# define API_EXPORT_NONSTD(type) __declspec(dllexport) type
#endif
#define MODULE_VAR_EXPORT __declspec(dllexport)
#define strcasecmp(s1, s2) stricmp(s1, s2)
#define strncasecmp(s1, s2, n) strnicmp(s1, s2, n)
#define lstat(x, y) stat(x, y)
#define S_ISLNK(m) (0)
#define S_ISREG(m) ((m & _S_IFREG) == _S_IFREG)
#ifndef S_ISDIR
#define S_ISDIR(m) (((m) & S_IFDIR) == S_IFDIR)
#endif
#ifndef S_ISREG
#define S_ISREG(m) (((m)&(S_IFREG)) == (S_IFREG))
#endif
#define STDIN_FILENO 0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
#define JMP_BUF jmp_buf
#define sleep(t) Sleep(t*1000)
#define O_CREAT _O_CREAT
#define O_RDWR _O_RDWR
#define SIGPIPE 17
/* Seems Windows is not a subgenius */
#define NO_SLACK
#include <stddef.h>
#define NO_OTHER_CHILD
#define NO_RELIABLE_PIPED_LOGS
__inline int ap_os_is_path_absolute(const char *file)
{
/* For now, just do the same check that http_request.c and mod_alias.c
* do.
*/
return file[0] == '/' || file[1] == ':';
}
#define stat(f,ps) os_stat(f,ps)
API_EXPORT(int) os_stat(const char *szPath,struct stat *pStat);
API_EXPORT(int) os_strftime(char *s, size_t max, const char *format, const struct tm *tm);
#define _spawnv(mode,cmdname,argv) os_spawnv(mode,cmdname,argv)
#define spawnv(mode,cmdname,argv) os_spawnv(mode,cmdname,argv)
API_EXPORT(int) os_spawnv(int mode,const char *cmdname,const char *const *argv);
#define _spawnve(mode,cmdname,argv,envp) os_spawnve(mode,cmdname,argv,envp)
#define spawnve(mode,cmdname,argv,envp) os_spawnve(mode,cmdname,argv,envp)
API_EXPORT(int) os_spawnve(int mode,const char *cmdname,const char *const *argv,const char *const *envp);
#define _spawnle os_spawnle
#define spawnle os_spawnle
API_EXPORT(int) os_spawnle(int mode,const char *cmdname,...);
/* OS-dependent filename routines in util_win32.c */
API_EXPORT(int) ap_os_is_filename_valid(const char *file);
/* Abstractions for dealing with shared object files (DLLs on Win32).
* These are used by mod_so.c
*/
#define ap_os_dso_handle_t HINSTANCE
#define ap_os_dso_init()
#define ap_os_dso_load(l) LoadLibraryEx(l, NULL, LOAD_WITH_ALTERED_SEARCH_PATH)
#define ap_os_dso_unload(l) FreeLibrary(l)
#define ap_os_dso_sym(h,s) GetProcAddress(h,s)
#define ap_os_dso_error() "" /* for now */
/* Other ap_os_ routines not used by this platform */
#define ap_os_kill(pid, sig) kill(pid, sig)
#endif /* ! APACHE_OS_H */

677
os/win32/util_win32.c Normal file
View File

@@ -0,0 +1,677 @@
#include <windows.h>
#include <sys/stat.h>
#include <stdarg.h>
#include <time.h>
#include <stdlib.h>
#include "httpd.h"
#include "http_log.h"
/* Returns TRUE if the input string is a string
* of one or more '.' characters.
*/
static BOOL OnlyDots(char *pString)
{
char *c;
if (*pString == '\0')
return FALSE;
for (c = pString;*c;c++)
if (*c != '.')
return FALSE;
return TRUE;
}
/* Accepts as input a pathname, and tries to match it to an
* existing path and return the pathname in the case that
* is present on the existing path. This routine also
* converts alias names to long names.
*/
API_EXPORT(char *) ap_os_systemcase_filename(pool *pPool,
const char *szFile)
{
char buf[HUGE_STRING_LEN];
char *pInputName;
char *p, *q;
BOOL bDone = FALSE;
BOOL bFileExists = TRUE;
HANDLE hFind;
WIN32_FIND_DATA wfd;
if (!szFile || strlen(szFile) == 0 || strlen(szFile) >= sizeof(buf))
return ap_pstrdup(pPool, "");
buf[0] = '\0';
pInputName = ap_pstrdup(pPool, szFile);
/* First convert all slashes to \ so Win32 calls work OK */
for (p = pInputName; *p; p++) {
if (*p == '/')
*p = '\\';
}
p = pInputName;
/* If there is drive information, copy it over. */
if (pInputName[1] == ':') {
buf[0] = tolower(*p++);
buf[1] = *p++;
buf[2] = '\0';
/* If all we have is a drive letter, then we are done */
if (strlen(pInputName) == 2)
bDone = TRUE;
}
q = p;
if (*p == '\\') {
p++;
if (*p == '\\') /* Possible UNC name */
{
p++;
/* Get past the machine name. FindFirstFile */
/* will not find a machine name only */
p = strchr(p, '\\');
if (p)
{
p++;
/* Get past the share name. FindFirstFile */
/* will not find a \\machine\share name only */
p = strchr(p, '\\');
if (p) {
strncat(buf,q,p-q);
q = p;
p++;
}
}
if (!p)
p = q;
}
}
p = strchr(p, '\\');
while (!bDone) {
if (p)
*p = '\0';
if (strchr(q, '*') || strchr(q, '?'))
bFileExists = FALSE;
/* If the path exists so far, call FindFirstFile
* again. However, if this portion of the path contains
* only '.' charaters, skip the call to FindFirstFile
* since it will convert '.' and '..' to actual names.
* Note: in the call to OnlyDots, we may have to skip
* a leading slash.
*/
if (bFileExists && !OnlyDots((*q == '.' ? q : q+1))) {
hFind = FindFirstFile(pInputName, &wfd);
if (hFind == INVALID_HANDLE_VALUE) {
bFileExists = FALSE;
}
else {
FindClose(hFind);
if (*q == '\\')
strcat(buf,"\\");
strcat(buf, wfd.cFileName);
}
}
if (!bFileExists || OnlyDots((*q == '.' ? q : q+1))) {
strcat(buf, q);
}
if (p) {
q = p;
*p++ = '\\';
p = strchr(p, '\\');
}
else {
bDone = TRUE;
}
}
/* First convert all slashes to / so server code handles it ok */
for (p = buf; *p; p++) {
if (*p == '\\')
*p = '/';
}
return ap_pstrdup(pPool, buf);
}
/* Perform canonicalization with the exception that the
* input case is preserved.
*/
API_EXPORT(char *) ap_os_case_canonical_filename(pool *pPool,
const char *szFile)
{
char *pNewStr;
char *s;
char *p;
char *q;
if (szFile == NULL || strlen(szFile) == 0)
return ap_pstrdup(pPool, "");
pNewStr = ap_pstrdup(pPool, szFile);
/* Change all '\' characters to '/' characters.
* While doing this, remove any trailing '.'.
* Also, blow away any directories with 3 or
* more '.'
*/
for (p = pNewStr,s = pNewStr; *s; s++,p++) {
if (*s == '\\' || *s == '/') {
q = p;
while (p > pNewStr && *(p-1) == '.')
p--;
if (p == pNewStr && q-p <= 2 && *p == '.')
p = q;
else if (p > pNewStr && p < q && *(p-1) == '/') {
if (q-p > 2)
p--;
else
p = q;
}
*p = '/';
}
else {
*p = *s;
}
}
*p = '\0';
/* Blow away any final trailing '.' since on Win32
* foo.bat == foo.bat. == foo.bat... etc.
* Also blow away any trailing spaces since
* "filename" == "filename "
*/
q = p;
while (p > pNewStr && (*(p-1) == '.' || *(p-1) == ' '))
p--;
if ((p > pNewStr) ||
(p == pNewStr && q-p > 2))
*p = '\0';
/* One more security issue to deal with. Win32 allows
* you to create long filenames. However, alias filenames
* are always created so that the filename will
* conform to 8.3 rules. According to the Microsoft
* Developer's network CD (1/98)
* "Automatically generated aliases are composed of the
* first six characters of the filename plus ~n
* (where n is a number) and the first three characters
* after the last period."
* Here, we attempt to detect and decode these names.
*/
p = strchr(pNewStr, '~');
if (p != NULL) {
char *pConvertedName, *pQstr, *pPstr;
char buf[HUGE_STRING_LEN];
/* We potentially have a short name. Call
* ap_os_systemcase_filename to examine the filesystem
* and possibly extract the long name.
*/
pConvertedName = ap_os_systemcase_filename(pPool, pNewStr);
/* Since we want to preserve the incoming case as much
* as we can, compare for differences in the string and
* only substitute in the path names that changed.
*/
if (stricmp(pNewStr, pConvertedName)) {
buf[0] = '\0';
q = pQstr = pConvertedName;
p = pPstr = pNewStr;
do {
q = strchr(q,'/');
p = strchr(p,'/');
if (p != NULL) {
*q = '\0';
*p = '\0';
}
if (stricmp(pQstr, pPstr))
strcat(buf, pQstr); /* Converted name */
else
strcat(buf, pPstr); /* Original name */
if (p != NULL) {
pQstr = q;
pPstr = p;
*q++ = '/';
*p++ = '/';
}
} while (p != NULL);
pNewStr = ap_pstrdup(pPool, buf);
}
}
return pNewStr;
}
/* Perform complete canonicalization.
*/
API_EXPORT(char *) ap_os_canonical_filename(pool *pPool, const char *szFile)
{
char *pNewName;
pNewName = ap_os_case_canonical_filename(pPool, szFile);
strlwr(pNewName);
return pNewName;
}
/* Win95 doesn't like trailing /s. NT and Unix don't mind. This works
* around the problem.
* Errr... except if it is UNC and we are referring to the root of
* the UNC, we MUST have a trailing \ and we can't use /s. Jeez.
* Not sure if this refers to all UNCs or just roots,
* but I'm going to fix it for all cases for now. (Ben)
*/
#undef stat
API_EXPORT(int) os_stat(const char *szPath, struct stat *pStat)
{
int n;
if (strlen(szPath) == 0) {
return -1;
}
if (szPath[0] == '/' && szPath[1] == '/') {
char buf[_MAX_PATH];
char *s;
int nSlashes = 0;
ap_assert(strlen(szPath) < _MAX_PATH);
strcpy(buf, szPath);
for (s = buf; *s; ++s) {
if (*s == '/') {
*s = '\\';
++nSlashes;
}
}
/* then we need to add one more to get \\machine\share\ */
if (nSlashes == 3) {
*s++ = '\\';
}
*s = '\0';
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] == '/') &&
!(n == 3 && szPath[1] == ':')) {
char buf[_MAX_PATH];
ap_assert(n < _MAX_PATH);
strcpy(buf, szPath);
buf[n - 1] = '\0';
return stat(buf, pStat);
}
return stat(szPath, pStat);
}
/* Fix two really crap problems with Win32 spawn[lv]e*:
*
* 1. Win32 doesn't deal with spaces in argv.
* 2. Win95 doesn't like / in cmdname.
*/
#undef _spawnv
API_EXPORT(int) os_spawnv(int mode, const char *cmdname,
const char *const *argv)
{
int n;
char **aszArgs;
const char *szArg;
char *szCmd;
char *s;
szCmd = _alloca(strlen(cmdname)+1);
strcpy(szCmd, cmdname);
for (s = szCmd; *s; ++s) {
if (*s == '/') {
*s = '\\';
}
}
for (n = 0; argv[n]; ++n)
;
aszArgs = _alloca((n + 1) * sizeof(const char *));
for (n = 0; szArg = argv[n]; ++n) {
if (strchr(szArg, ' ')) {
int l = strlen(szArg);
aszArgs[n] = _alloca(l + 2 + 1);
aszArgs[n][0] = '"';
strcpy(&aszArgs[n][1], szArg);
aszArgs[n][l + 1] = '"';
aszArgs[n][l + 2] = '\0';
}
else {
aszArgs[n] = (char *)szArg;
}
}
aszArgs[n] = NULL;
return _spawnv(mode, szCmd, aszArgs);
}
#undef _spawnve
API_EXPORT(int) os_spawnve(int mode, const char *cmdname,
const char *const *argv, const char *const *envp)
{
int n;
char **aszArgs;
const char *szArg;
char *szCmd;
char *s;
szCmd = _alloca(strlen(cmdname)+1);
strcpy(szCmd, cmdname);
for (s = szCmd; *s; ++s) {
if (*s == '/') {
*s = '\\';
}
}
for (n = 0; argv[n]; ++n)
;
aszArgs = _alloca((n + 1)*sizeof(const char *));
for (n = 0; szArg = argv[n]; ++n){
if (strchr(szArg, ' ')) {
int l = strlen(szArg);
aszArgs[n] = _alloca(l + 2 + 1);
aszArgs[n][0] = '"';
strcpy(&aszArgs[n][1], szArg);
aszArgs[n][l + 1] = '"';
aszArgs[n][l + 2] = '\0';
}
else {
aszArgs[n] = (char *)szArg;
}
}
aszArgs[n] = NULL;
return _spawnve(mode, szCmd, aszArgs, envp);
}
API_EXPORT(int) os_spawnle(int mode, const char *cmdname, ...)
{
int n;
va_list vlist;
char **aszArgs;
const char *szArg;
const char *const *aszEnv;
char *szCmd;
char *s;
szCmd = _alloca(strlen(cmdname)+1);
strcpy(szCmd, cmdname);
for (s = szCmd; *s; ++s) {
if (*s == '/') {
*s = '\\';
}
}
va_start(vlist, cmdname);
for (n = 0; va_arg(vlist, const char *); ++n)
;
va_end(vlist);
aszArgs = _alloca((n + 1) * sizeof(const char *));
va_start(vlist, cmdname);
for (n = 0; szArg = va_arg(vlist, const char *); ++n) {
if (strchr(szArg, ' ')) {
int l = strlen(szArg);
aszArgs[n] = _alloca(l + 2 + 1);
aszArgs[n][0] = '"';
strcpy(&aszArgs[n][1], szArg);
aszArgs[n][l + 1] = '"';
aszArgs[n][l + 2] = '\0';
}
else {
aszArgs[n] = (char *)szArg;
}
}
aszArgs[n] = NULL;
aszEnv = va_arg(vlist, const char *const *);
va_end(vlist);
return _spawnve(mode, szCmd, aszArgs, aszEnv);
}
#undef strftime
/* Partial replacement for strftime. This adds certain expandos to the
* Windows version
*/
API_EXPORT(int) os_strftime(char *s, size_t max, const char *format,
const struct tm *tm) {
/* If the new format string is bigger than max, the result string probably
* won't fit anyway. When %-expandos are added, made sure the padding below
* is enough.
*/
char *new_format = (char *) _alloca(max + 11);
size_t i, j, format_length = strlen(format);
int return_value;
int length_written;
for (i = 0, j = 0; (i < format_length && j < max);) {
if (format[i] != '%') {
new_format[j++] = format[i++];
continue;
}
switch (format[i+1]) {
case 'D':
/* Is this locale dependent? Shouldn't be...
Also note the year 2000 exposure here */
memcpy(new_format + j, "%m/%d/%y", 8);
i += 2;
j += 8;
break;
case 'r':
memcpy(new_format + j, "%I:%M:%S %p", 11);
i += 2;
j += 11;
break;
case 'T':
memcpy(new_format + j, "%H:%M:%S", 8);
i += 2;
j += 8;
break;
case 'e':
length_written = ap_snprintf(new_format + j, max - j, "%2d",
tm->tm_mday);
j = (length_written == -1) ? max : (j + length_written);
i += 2;
break;
default:
/* We know we can advance two characters forward here. */
new_format[j++] = format[i++];
new_format[j++] = format[i++];
}
}
if (j >= max) {
*s = '\0'; /* Defensive programming, okay since output is undefined */
return_value = 0;
} else {
new_format[j] = '\0';
return_value = strftime(s, max, new_format, tm);
}
return return_value;
}
/*
* ap_os_is_filename_valid is given a filename, and returns 0 if the filename
* is not valid for use on this system. On Windows, this means it fails any
* of the tests below. Otherwise returns 1.
*
* Test for filename validity on Win32. This is of tests come in part from
* the MSDN article at "Technical Articles, Windows Platform, Base Services,
* Guidelines, Making Room for Long Filenames" although the information
* in MSDN about filename testing is incomplete or conflicting. There is a
* similar set of tests in "Technical Articles, Windows Platform, Base Services,
* Guidelines, Moving Unix Applications to Windows NT".
*
* The tests are:
*
* 1) total path length greater than MAX_PATH
*
* 2) anything using the octets 0-31 or characters " < > | :
* (these are reserved for Windows use in filenames. In addition
* each file system has its own additional characters that are
* invalid. See KB article Q100108 for more details).
*
* 3) anything ending in "." (no matter how many)
* (filename doc, doc. and doc... all refer to the same file)
*
* 4) any segment in which the basename (before first period) matches
* one of the DOS device names
* (the list comes from KB article Q100108 although some people
* reports that additional names such as "COM5" are also special
* devices).
*
* If the path fails ANY of these tests, the result must be to deny access.
*/
API_EXPORT(int) ap_os_is_filename_valid(const char *file)
{
const char *segstart;
unsigned int seglength;
const char *pos;
static const char * const invalid_characters = "?\"<>*|:";
static const char * const invalid_filenames[] = {
"CON", "AUX", "COM1", "COM2", "COM3",
"COM4", "LPT1", "LPT2", "LPT3", "PRN", "NUL", NULL
};
/* Test 1 */
if (strlen(file) > MAX_PATH) {
/* Path too long for Windows. Note that this test is not valid
* if the path starts with //?/ or \\?\. */
return 0;
}
pos = file;
/* Skip any leading non-path components. This can be either a
* drive letter such as C:, or a UNC path such as \\SERVER\SHARE\.
* We continue and check the rest of the path based on the rules above.
* This means we could eliminate valid filenames from servers which
* are not running NT (such as Samba).
*/
if (pos[0] && pos[1] == ':') {
/* Skip leading drive letter */
pos += 2;
}
else {
if ((pos[0] == '\\' || pos[0] == '/') &&
(pos[1] == '\\' || pos[1] == '/')) {
/* Is a UNC, so skip the server name and share name */
pos += 2;
while (*pos && *pos != '/' && *pos != '\\')
pos++;
if (!*pos) {
/* No share name */
return 0;
}
pos++; /* Move to start of share name */
while (*pos && *pos != '/' && *pos != '\\')
pos++;
if (!*pos) {
/* No path information */
return 0;
}
}
}
while (*pos) {
unsigned int idx;
unsigned int baselength;
while (*pos == '/' || *pos == '\\') {
pos++;
}
if (*pos == '\0') {
break;
}
segstart = pos; /* start of segment */
while (*pos && *pos != '/' && *pos != '\\') {
pos++;
}
seglength = pos - segstart;
/*
* Now we have a segment of the path, starting at position "segstart"
* and length "seglength"
*/
/* Test 2 */
for (idx = 0; idx < seglength; idx++) {
if ((segstart[idx] > 0 && segstart[idx] < 32) ||
strchr(invalid_characters, segstart[idx])) {
return 0;
}
}
/* Test 3 */
if (segstart[seglength-1] == '.') {
return 0;
}
/* Test 4 */
for (baselength = 0; baselength < seglength; baselength++) {
if (segstart[baselength] == '.') {
break;
}
}
/* baselength is the number of characters in the base path of
* the segment (which could be the same as the whole segment length,
* if it does not include any dot characters). */
if (baselength == 3 || baselength == 4) {
for (idx = 0; invalid_filenames[idx]; idx++) {
if (strlen(invalid_filenames[idx]) == baselength &&
!strnicmp(invalid_filenames[idx], segstart, baselength)) {
return 0;
}
}
}
}
return 1;
}

13
server/.cvsignore Normal file
View File

@@ -0,0 +1,13 @@
Makefile
uri_delims.h
gen_uri_delims
test_char.h
gen_test_char
gen_uri_delims_R
gen_test_char_R
gen_uri_delims_D
gen_uri_delims.ilk
gen_uri_delims.pdb
gen_test_char_D
gen_test_char.ilk
gen_test_char.pdb

54
server/.indent.pro vendored Normal file
View File

@@ -0,0 +1,54 @@
-i4 -npsl -di0 -br -nce -d0 -cli0 -npcs -nfc1
-TBUFF
-TFILE
-TTRANS
-TUINT4
-T_trans
-Tallow_options_t
-Tapache_sfio
-Tarray_header
-Tbool_int
-Tbuf_area
-Tbuff_struct
-Tbuffy
-Tcmd_how
-Tcmd_parms
-Tcommand_rec
-Tcommand_struct
-Tconn_rec
-Tcore_dir_config
-Tcore_server_config
-Tdir_maker_func
-Tevent
-Tglobals_s
-Thandler_func
-Thandler_rec
-Tjoblist_s
-Tlisten_rec
-Tmerger_func
-Tmode_t
-Tmodule
-Tmodule_struct
-Tmutex
-Tn_long
-Tother_child_rec
-Toverrides_t
-Tparent_score
-Tpid_t
-Tpiped_log
-Tpool
-Trequest_rec
-Trequire_line
-Trlim_t
-Tscoreboard
-Tsemaphore
-Tserver_addr_rec
-Tserver_rec
-Tserver_rec_chain
-Tshort_score
-Ttable
-Ttable_entry
-Tthread
-Tu_wide_int
-Tvtime_t
-Twide_int

1641
server/config.c Normal file

File diff suppressed because it is too large Load Diff

62
server/gen_test_char.c Normal file
View File

@@ -0,0 +1,62 @@
/* we need some of the portability definitions... for strchr */
#include "httpd.h"
/* A bunch of functions in util.c scan strings looking for certain characters.
* To make that more efficient we encode a lookup table.
*/
#define T_ESCAPE_SHELL_CMD (0x01)
#define T_ESCAPE_PATH_SEGMENT (0x02)
#define T_OS_ESCAPE_PATH (0x04)
#define T_HTTP_TOKEN_STOP (0x08)
int main(int argc, char *argv[])
{
unsigned c;
unsigned char flags;
printf(
"/* this file is automatically generated by gen_test_char, do not edit */\n"
"#define T_ESCAPE_SHELL_CMD (%u)\n"
"#define T_ESCAPE_PATH_SEGMENT (%u)\n"
"#define T_OS_ESCAPE_PATH (%u)\n"
"#define T_HTTP_TOKEN_STOP (%u)\n"
"\n"
"static const unsigned char test_char_table[256] = {\n"
" 0,",
T_ESCAPE_SHELL_CMD,
T_ESCAPE_PATH_SEGMENT,
T_OS_ESCAPE_PATH,
T_HTTP_TOKEN_STOP);
/* we explicitly dealt with NUL above
* in case some strchr() do bogosity with it */
for (c = 1; c < 256; ++c) {
flags = 0;
if (c % 20 == 0)
printf("\n ");
/* escape_shell_cmd */
if (strchr("&;`'\"|*?~<>^()[]{}$\\\n", c)) {
flags |= T_ESCAPE_SHELL_CMD;
}
if (!ap_isalnum(c) && !strchr("$-_.+!*'(),:@&=~", c)) {
flags |= T_ESCAPE_PATH_SEGMENT;
}
if (!ap_isalnum(c) && !strchr("$-_.+!*'(),:@&=/~", c)) {
flags |= T_OS_ESCAPE_PATH;
}
/* these are the "tspecials" from RFC2068 */
if (ap_iscntrl(c) || strchr(" \t()<>@,;:\\/[]?={}", c)) {
flags |= T_HTTP_TOKEN_STOP;
}
printf("%u%c", flags, (c < 255) ? ',' : ' ');
}
printf("\n};\n");
return 0;
}

105
server/gen_test_char.dsp Normal file
View File

@@ -0,0 +1,105 @@
# Microsoft Developer Studio Project File - Name="gen_test_char" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 5.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=gen_test_char - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "gen_test_char.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "gen_test_char.mak" CFG="gen_test_char - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "gen_test_char - Win32 Release" (based on\
"Win32 (x86) Console Application")
!MESSAGE "gen_test_char - Win32 Debug" (based on\
"Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "gen_test_char - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "gen_test"
# PROP BASE Intermediate_Dir "gen_test"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir ""
# PROP Intermediate_Dir "gen_test_char_R"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /I "..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x809 /d "NDEBUG"
# ADD RSC /l 0x809 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib /nologo /subsystem:console /machine:I386
# Begin Special Build Tool
SOURCE=$(InputPath)
PostBuild_Desc=Create test_char.h
PostBuild_Cmds=.\gen_test_char > test_char.h
# End Special Build Tool
!ELSEIF "$(CFG)" == "gen_test_char - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "gen_tes0"
# PROP BASE Intermediate_Dir "gen_tes0"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir ""
# PROP Intermediate_Dir "gen_test_char_D"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x809 /d "_DEBUG"
# ADD RSC /l 0x809 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# Begin Special Build Tool
SOURCE=$(InputPath)
PostBuild_Desc=Create test_char.h
PostBuild_Cmds=.\gen_test_char > test_char.h
# End Special Build Tool
!ENDIF
# Begin Target
# Name "gen_test_char - Win32 Release"
# Name "gen_test_char - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\gen_test_char.c
# End Source File
# End Group
# End Target
# End Project

31
server/gen_uri_delims.c Normal file
View File

@@ -0,0 +1,31 @@
#include <stdio.h>
/* generate a table of 256 values, where certain characters are
* marked "interesting"... for the uri parsing process.
*/
int main(int argc, char *argv[])
{
int i;
char *value;
printf("/* this file is automatically generated by "
"gen_uri_delims, do not edit */\n");
printf("static const unsigned char uri_delims[256] = {");
for (i = 0; i < 256; ++i) {
if (i % 20 == 0)
printf("\n ");
switch (i) {
case ':': value = "T_COLON"; break;
case '/': value = "T_SLASH"; break;
case '?': value = "T_QUESTION"; break;
case '#': value = "T_HASH"; break;
case '\0': value = "T_NUL"; break;
default: value = "0"; break;
}
printf("%s%c", value, (i < 255) ? ',' : ' ');
}
printf("\n};\n");
return 0;
}

105
server/gen_uri_delims.dsp Normal file
View File

@@ -0,0 +1,105 @@
# Microsoft Developer Studio Project File - Name="gen_uri_delims" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 5.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=gen_uri_delims - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "gen_uri_delims.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "gen_uri_delims.mak" CFG="gen_uri_delims - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "gen_uri_delims - Win32 Release" (based on\
"Win32 (x86) Console Application")
!MESSAGE "gen_uri_delims - Win32 Debug" (based on\
"Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "gen_uri_delims - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir ""
# PROP Intermediate_Dir "gen_uri_delims_R"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x809 /d "NDEBUG"
# ADD RSC /l 0x809 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib /nologo /subsystem:console /machine:I386
# Begin Special Build Tool
SOURCE=$(InputPath)
PostBuild_Desc=Create uri_delims.h
PostBuild_Cmds=.\gen_uri_delims > uri_delims.h
# End Special Build Tool
!ELSEIF "$(CFG)" == "gen_uri_delims - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir ""
# PROP Intermediate_Dir "gen_uri_delims_D"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x809 /d "_DEBUG"
# ADD RSC /l 0x809 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# Begin Special Build Tool
SOURCE=$(InputPath)
PostBuild_Desc=Create uri_delims.h
PostBuild_Cmds=.\gen_uri_delims > uri_delims.h
# End Special Build Tool
!ENDIF
# Begin Target
# Name "gen_uri_delims - Win32 Release"
# Name "gen_uri_delims - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\gen_uri_delims.c
# End Source File
# End Group
# End Target
# End Project

777
server/log.c Normal file
View File

@@ -0,0 +1,777 @@
/* ====================================================================
* Copyright (c) 1995-1999 The Apache Group. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* 4. The names "Apache Server" and "Apache Group" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Group and was originally based
* on public domain software written at the National Center for
* Supercomputing Applications, University of Illinois, Urbana-Champaign.
* For more information on the Apache Group and the Apache HTTP server
* project, please see <http://www.apache.org/>.
*
*/
/*
* http_log.c: Dealing with the logs and errors
*
* Rob McCool
*
*/
#define CORE_PRIVATE
#include "httpd.h"
#include "http_conf_globals.h"
#include "http_config.h"
#include "http_core.h"
#include "http_log.h"
#include "http_main.h"
#include <stdarg.h>
typedef struct {
char *t_name;
int t_val;
} TRANS;
#ifdef HAVE_SYSLOG
static const TRANS facilities[] = {
{"auth", LOG_AUTH},
#ifdef LOG_AUTHPRIV
{"authpriv",LOG_AUTHPRIV},
#endif
#ifdef LOG_CRON
{"cron", LOG_CRON},
#endif
#ifdef LOG_DAEMON
{"daemon", LOG_DAEMON},
#endif
#ifdef LOG_FTP
{"ftp", LOG_FTP},
#endif
#ifdef LOG_KERN
{"kern", LOG_KERN},
#endif
#ifdef LOG_LPR
{"lpr", LOG_LPR},
#endif
#ifdef LOG_MAIL
{"mail", LOG_MAIL},
#endif
#ifdef LOG_NEWS
{"news", LOG_NEWS},
#endif
#ifdef LOG_SYSLOG
{"syslog", LOG_SYSLOG},
#endif
#ifdef LOG_USER
{"user", LOG_USER},
#endif
#ifdef LOG_UUCP
{"uucp", LOG_UUCP},
#endif
#ifdef LOG_LOCAL0
{"local0", LOG_LOCAL0},
#endif
#ifdef LOG_LOCAL1
{"local1", LOG_LOCAL1},
#endif
#ifdef LOG_LOCAL2
{"local2", LOG_LOCAL2},
#endif
#ifdef LOG_LOCAL3
{"local3", LOG_LOCAL3},
#endif
#ifdef LOG_LOCAL4
{"local4", LOG_LOCAL4},
#endif
#ifdef LOG_LOCAL5
{"local5", LOG_LOCAL5},
#endif
#ifdef LOG_LOCAL6
{"local6", LOG_LOCAL6},
#endif
#ifdef LOG_LOCAL7
{"local7", LOG_LOCAL7},
#endif
{NULL, -1},
};
#endif
static const TRANS priorities[] = {
{"emerg", APLOG_EMERG},
{"alert", APLOG_ALERT},
{"crit", APLOG_CRIT},
{"error", APLOG_ERR},
{"warn", APLOG_WARNING},
{"notice", APLOG_NOTICE},
{"info", APLOG_INFO},
{"debug", APLOG_DEBUG},
{NULL, -1},
};
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
* be common for other foo-loggers to want this sort of thing...
*/
int child_pid = 0;
ap_cleanup_for_exec();
#ifdef SIGHUP
/* No concept of a child process on Win32 */
signal(SIGHUP, SIG_IGN);
#endif /* ndef SIGHUP */
#if defined(WIN32)
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 '/' and spawn the child rather than exec as
* we haven't forked */
child_pid = spawnl(P_NOWAIT, SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL);
return(child_pid);
#else
execl(SHELL_PATH, SHELL_PATH, "-c", (char *)cmd, NULL);
#endif
exit(1);
/* NOT REACHED */
return(child_pid);
}
static void open_error_log(server_rec *s, pool *p)
{
char *fname;
if (*s->error_fname == '|') {
FILE *dummy;
#ifdef TPF
TPF_FORK_CHILD cld;
cld.filename = s->error_fname+1;
cld.subprocess_env = NULL;
cld.prog_type = FORK_NAME;
if (!ap_spawn_child(p, NULL, &cld,
kill_after_timeout, &dummy, NULL, NULL)) {
#else
if (!ap_spawn_child(p, error_log_child, (void *)(s->error_fname+1),
kill_after_timeout, &dummy, NULL, NULL)) {
#endif /* TPF */
perror("ap_spawn_child");
fprintf(stderr, "Couldn't fork child for ErrorLog process\n");
exit(1);
}
s->error_log = dummy;
}
#ifdef HAVE_SYSLOG
else if (!strncasecmp(s->error_fname, "syslog", 6)) {
if ((fname = strchr(s->error_fname, ':'))) {
const TRANS *fac;
fname++;
for (fac = facilities; fac->t_name; fac++) {
if (!strcasecmp(fname, fac->t_name)) {
openlog(ap_server_argv0, LOG_NDELAY|LOG_CONS|LOG_PID,
fac->t_val);
s->error_log = NULL;
return;
}
}
}
else
openlog(ap_server_argv0, LOG_NDELAY|LOG_CONS|LOG_PID, LOG_LOCAL7);
s->error_log = NULL;
}
#endif
else {
fname = ap_server_root_relative(p, s->error_fname);
if (!(s->error_log = ap_pfopen(p, fname, "a"))) {
perror("fopen");
fprintf(stderr, "%s: could not open error log file %s.\n",
ap_server_argv0, fname);
exit(1);
}
}
}
void ap_open_logs(server_rec *s_main, pool *p)
{
server_rec *virt, *q;
int replace_stderr;
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), STDERR_FILENO) == -1) {
ap_log_error(APLOG_MARK, APLOG_CRIT, s_main,
"unable to replace stderr with error_log");
} else {
replace_stderr = 0;
}
}
/* note that stderr may still need to be replaced with something
* because it points to the old error log, or back to the tty
* of the submitter.
*/
if (replace_stderr && freopen("/dev/null", "w", stderr) == NULL) {
ap_log_error(APLOG_MARK, APLOG_CRIT, s_main,
"unable to replace stderr with /dev/null");
}
for (virt = s_main->next; virt; virt = virt->next) {
if (virt->error_fname)
{
for (q=s_main; q != virt; q = q->next)
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;
}
else
virt->error_log = s_main->error_log;
}
}
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,
const server_rec *s, const request_rec *r,
const char *fmt, va_list args)
{
char errstr[MAX_STRING_LEN];
size_t len;
int save_errno = errno;
FILE *logf;
if (s == NULL) {
/*
* If we are doing stderr logging (startup), don't log messages that are
* above the default server log level unless it is a startup/shutdown
* notice
*/
if (((level & APLOG_LEVELMASK) != APLOG_NOTICE) &&
((level & APLOG_LEVELMASK) > DEFAULT_LOGLEVEL))
return;
logf = stderr;
}
else if (s->error_log) {
/*
* If we are doing normal logging, don't log messages that are
* above the server log level unless it is a startup/shutdown notice
*/
if (((level & APLOG_LEVELMASK) != APLOG_NOTICE) &&
((level & APLOG_LEVELMASK) > s->loglevel))
return;
logf = s->error_log;
}
#ifdef TPF
else if (tpf_child) {
/*
* If we are doing normal logging, don't log messages that are
* above the server log level unless it is a startup/shutdown notice
*/
if (((level & APLOG_LEVELMASK) != APLOG_NOTICE) &&
((level & APLOG_LEVELMASK) > s->loglevel))
return;
logf = stderr;
}
#endif /* TPF */
else {
/*
* If we are doing syslog logging, don't log messages that are
* above the server log level (including a startup/shutdown notice)
*/
if ((level & APLOG_LEVELMASK) > s->loglevel)
return;
logf = NULL;
}
if (logf) {
len = ap_snprintf(errstr, sizeof(errstr), "[%s] ", ap_get_time());
} else {
len = 0;
}
len += ap_snprintf(errstr + len, sizeof(errstr) - len,
"[%s] ", priorities[level & APLOG_LEVELMASK].t_name);
#ifndef TPF
if (file && (level & APLOG_LEVELMASK) == APLOG_DEBUG) {
#ifdef _OSD_POSIX
char tmp[256];
char *e = strrchr(file, '/');
/* In OSD/POSIX, the compiler returns for __FILE__
* a string like: __FILE__="*POSIX(/usr/include/stdio.h)"
* (it even returns an absolute path for sources in
* the current directory). Here we try to strip this
* down to the basename.
*/
if (e != NULL && e[1] != '\0') {
ap_snprintf(tmp, sizeof(tmp), "%s", &e[1]);
e = &tmp[strlen(tmp)-1];
if (*e == ')')
*e = '\0';
file = tmp;
}
#endif /*_OSD_POSIX*/
len += ap_snprintf(errstr + len, sizeof(errstr) - len,
"%s(%d): ", file, line);
}
#endif /* TPF */
if (r) {
/* XXX: TODO: add a method of selecting whether logged client
* addresses are in dotted quad or resolved form... dotted
* quad is the most secure, which is why I'm implementing it
* first. -djg
*/
len += ap_snprintf(errstr + len, sizeof(errstr) - len,
"[client %s] ", r->connection->remote_ip);
}
if (!(level & APLOG_NOERRNO)
&& (save_errno != 0)
#ifdef WIN32
&& !(level & APLOG_WIN32ERROR)
#endif
) {
len += ap_snprintf(errstr + len, sizeof(errstr) - len,
"(%d)%s: ", save_errno, strerror(save_errno));
}
#ifdef WIN32
if (level & APLOG_WIN32ERROR) {
int nChars;
int nErrorCode;
nErrorCode = GetLastError();
len += ap_snprintf(errstr + len, sizeof(errstr) - len,
"(%d)", nErrorCode);
nChars = FormatMessage(
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
nErrorCode,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) errstr + len,
sizeof(errstr) - len,
NULL
);
len += nChars;
if (nChars == 0) {
/* Um, error occurred, but we can't recurse to log it again
* (and it would probably only fail anyway), so lets just
* log the numeric value.
*/
nErrorCode = GetLastError();
len += ap_snprintf(errstr + len, sizeof(errstr) - len,
"(FormatMessage failed with code %d): ",
nErrorCode);
}
else {
/* FormatMessage put the message in the buffer, but it may
* have appended a newline (\r\n). So remove it and use
* ": " instead like the Unix errors. The error may also
* end with a . before the return - if so, trash it.
*/
if (len > 1 && errstr[len-2] == '\r' && errstr[len-1] == '\n') {
if (len > 2 && errstr[len-3] == '.')
len--;
errstr[len-2] = ':';
errstr[len-1] = ' ';
}
}
}
#endif
len += ap_vsnprintf(errstr + len, sizeof(errstr) - len, fmt, args);
/* NULL if we are logging to syslog */
if (logf) {
fputs(errstr, logf);
fputc('\n', logf);
fflush(logf);
}
#ifdef HAVE_SYSLOG
else {
syslog(level & APLOG_LEVELMASK, "%s", errstr);
}
#endif
}
API_EXPORT(void) ap_log_error(const char *file, int line, int level,
const server_rec *s, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
log_error_core(file, line, level, s, NULL, fmt, args);
va_end(args);
}
API_EXPORT(void) ap_log_rerror(const char *file, int line, int level,
const request_rec *r, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
log_error_core(file, line, level, r->server, r, fmt, args);
/*
* 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.
*/
va_end(args);
va_start(args,fmt);
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)
{
FILE *pid_file;
struct stat finfo;
static pid_t saved_pid = -1;
pid_t mypid;
if (!fname)
return;
fname = ap_server_root_relative(p, fname);
mypid = getpid();
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.
*
* XXX: Could just write first time through too, although
* that may screw up scripts written to do something
* based on the last modification time of the pid file.
*/
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, NULL,
ap_psprintf(p,
"pid file %s overwritten -- Unclean shutdown of previous Apache run?",
fname)
);
}
if(!(pid_file = fopen(fname, "w"))) {
perror("fopen");
fprintf(stderr, "%s: could not log pid to file %s\n",
ap_server_argv0, fname);
exit(1);
}
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)
{
ap_log_error(APLOG_MARK, APLOG_ERR, s, "%s", err);
}
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, ...)
{
va_list args;
va_start(args, fmt);
log_error_core(APLOG_MARK, APLOG_ERR, s, NULL, fmt, args);
va_end(args);
}
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",
file,
ap_get_remote_host(r->connection, r->per_dir_config, REMOTE_NAME),
reason);
}
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);
#ifndef WIN32
/* unix assert does an abort leading to a core dump */
abort();
#else
exit(1);
#endif
}
/* piped log support */
#ifndef NO_RELIABLE_PIPED_LOGS
/* forward declaration */
static void piped_log_maintenance(int reason, void *data, ap_wait_t status);
static int piped_log_spawn(piped_log *pl)
{
int pid;
ap_block_alarms();
pid = fork();
if (pid == 0) {
/* XXX: this needs porting to OS2 and WIN32 */
/* XXX: need to check what open fds the logger is actually passed,
* XXX: and CGIs for that matter ... cleanup_for_exec *should*
* 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,
"piped_log_spawn: unable to exec %s -c '%s': %s\n",
SHELL_PATH, pl->program, strerror (errno));
exit(1);
}
if (pid == -1) {
fprintf(stderr,
"piped_log_spawn: unable to fork(): %s\n", strerror (errno));
ap_unblock_alarms();
return -1;
}
ap_unblock_alarms();
pl->pid = pid;
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)
{
piped_log *pl = data;
switch (reason) {
case OC_REASON_DEATH:
case OC_REASON_LOST:
pl->pid = -1;
ap_unregister_other_child(pl);
if (pl->program == NULL) {
/* during a restart */
break;
}
if (piped_log_spawn(pl) == -1) {
/* what can we do? This could be the error log we're having
* problems opening up... */
fprintf(stderr,
"piped_log_maintenance: unable to respawn '%s': %s\n",
pl->program, strerror(errno));
}
break;
case OC_REASON_UNWRITABLE:
if (pl->pid != -1) {
kill(pl->pid, SIGTERM);
}
break;
case OC_REASON_RESTART:
pl->program = NULL;
if (pl->pid != -1) {
kill(pl->pid, SIGTERM);
}
break;
case OC_REASON_UNREGISTER:
break;
}
}
static void piped_log_cleanup(void *data)
{
piped_log *pl = data;
if (pl->pid != -1) {
kill(pl->pid, SIGTERM);
}
ap_unregister_other_child(pl);
close(pl->fds[0]);
close(pl->fds[1]);
}
static void piped_log_cleanup_for_exec(void *data)
{
piped_log *pl = data;
close(pl->fds[0]);
close(pl->fds[1]);
}
API_EXPORT(piped_log *) ap_open_piped_log(pool *p, const char *program)
{
piped_log *pl;
pl = ap_palloc(p, sizeof (*pl));
pl->p = p;
pl->program = ap_pstrdup(p, program);
pl->pid = -1;
ap_block_alarms ();
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) {
int save_errno = errno;
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();
return 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();
}
#else
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
* be common for other foo-loggers to want this sort of thing...
*/
int child_pid = 1;
ap_cleanup_for_exec();
#ifdef SIGHUP
signal(SIGHUP, SIG_IGN);
#endif
#if defined(WIN32)
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 '/' and spawn the child rather than exec as
* we haven't forked */
child_pid = spawnl(P_NOWAIT, SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL);
return(child_pid);
#else
execl (SHELL_PATH, SHELL_PATH, "-c", (char *)cmd, NULL);
#endif
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)
{
piped_log *pl;
FILE *dummy;
#ifdef TPF
TPF_FORK_CHILD cld;
cld.filename = (char *)program;
cld.subprocess_env = NULL;
cld.prog_type = FORK_NAME;
if (!ap_spawn_child (p, NULL, &cld,
kill_after_timeout, &dummy, NULL, NULL)){
#else
if (!ap_spawn_child(p, piped_log_child, (void *)program,
kill_after_timeout, &dummy, NULL, NULL)) {
#endif /* TPF */
perror("ap_spawn_child");
fprintf(stderr, "Couldn't fork child for piped log process\n");
exit (1);
}
pl = ap_palloc(p, sizeof (*pl));
pl->p = p;
pl->write_f = dummy;
return pl;
}
API_EXPORT(void) ap_close_piped_log(piped_log *pl)
{
ap_pfclose(pl->p, pl->write_f);
}
#endif

6669
server/main.c Normal file

File diff suppressed because it is too large Load Diff

471
server/mpm/winnt/registry.c Normal file
View File

@@ -0,0 +1,471 @@
/*
* Functions to handle interacting with the Win32 registry
*/
/*
* Apache registry key structure
*
* Apache's registry information is stored in the HKEY_LOCAL_MACHINE
* key, under
*
* HKLM\SOFTWARE\Apache Group\Apache\version
*
* These keys are defined in this file. The definition of the "version" part
* will need updating each time Apache moves from beta to non-beta or from a
* release to a development or beta version.
*/
/* To allow for multiple services, store the configuration file's full path
* under each service entry:
*
* HKLM\System\CurrentControlSet\Services\[service name]\Parameters\ConfPath
*
* The default configuration path (for console apache) is still stored:
*
* HKLM\Software\[Vendor]\[Software]\[Version]\ServerRoot
*/
#include <windows.h>
#include <stdio.h>
#include "httpd.h"
#include "http_log.h"
/* Define where the Apache values are stored in the registry. In general
* VERSION will be the same across all beta releases for a particular
* major release, but will change when the final release is made.
*/
#define VENDOR "Apache Group"
#define SOFTWARE "Apache"
#define VERSION "1.3.9"
#define REGKEY "SOFTWARE\\" VENDOR "\\" SOFTWARE "\\" VERSION
#define SERVICEKEYPRE "System\\CurrentControlSet\\Services\\"
#define SERVICEKEYPOST "\\Parameters"
/*
* The Windows API registry key functions don't set the last error
* value (the windows equivalent of errno). So we need to set it
* with SetLastError() before calling the aplog_error() function.
* Because this is common, let's have a macro.
*/
#define do_error(rv,fmt,arg) do { \
SetLastError(rv); \
ap_log_error(APLOG_MARK, APLOG_WIN32ERROR|APLOG_ERR, NULL, fmt,arg); \
} while (0);
/*
* Get the data for registry key value. This is a generic function that
* can either get a value into a caller-supplied buffer, or it can
* allocate space for the value from the pass-in pool. It will normally
* be used by other functions within this file to get specific key values
* (e.g. registry_get_server_root()). This function returns a number of
* different error statuses, allowing the caller to differentiate
* between a key or value not existing and other kinds of errors. Depending
* on the type of data being obtained the caller can then either ignore
* the key-not-existing error, or treat it as a real error.
*
* If ppValue is NULL, allocate space for the value and return it in
* *pValue. The return value is the number of bytes in the value.
* The first argument is the pool to use to allocate space for the value.
*
* If pValue is not NULL, assume it is a buffer of nSizeValue bytes,
* and write the value into the buffer. The return value is the number
* of bytes in the value (so if the return value is greater than
* the supplied nSizeValue, the caller knows that *pValue is truncated).
* The pool argument is ignored.
*
* The return value is the number of bytes in the successfully retreived
* key if everything worked, or:
*
* -1 the key does not exists
* -2 if out of memory during the function
* -3 if the buffer specified by *pValue/nSizeValue was not large enough
* for the value.
* -4 if an error occurred
*
* If the return value is negative a message will be logged to the error
* log (aplog_error) function. If the return value is -2, -3 or -4 the message
* will be logged at priority "error", while if the return value is -1 the
* message will be logged at priority "warning".
*/
static int ap_registry_get_key_int(pool *p, char *key, char *name, char *pBuffer, int nSizeBuffer, char **ppValue)
{
long rv;
HKEY hKey;
char *pValue;
int nSize;
int retval;
rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
key,
0,
KEY_READ,
&hKey);
if (rv == ERROR_FILE_NOT_FOUND) {
ap_log_error(APLOG_MARK,APLOG_WARNING|APLOG_NOERRNO,NULL,
"Registry does not contain key %s",key);
return -1;
}
if (rv != ERROR_SUCCESS) {
do_error(rv, "RegOpenKeyEx HKLM\\%s",key);
return -4;
}
if (pBuffer == NULL) {
/* Find the size required for the data by passing NULL as the buffer
* pointer. On return nSize will contain the size required for the
* buffer if the return value is ERROR_SUCCESS.
*/
rv = RegQueryValueEx(hKey,
name, /* key name */
NULL, /* reserved */
NULL, /* type */
NULL, /* for value */
&nSize); /* for size of "value" */
if (rv != ERROR_SUCCESS) {
do_error(rv, "RegQueryValueEx(key %s)", key);
return -1;
}
pValue = ap_palloc(p, nSize);
*ppValue = pValue;
if (!pValue) {
/* Eek, out of memory, probably not worth trying to carry on,
* but let's give it a go
*/
ap_log_error(APLOG_MARK,APLOG_ERR|APLOG_NOERRNO,NULL,
"Error getting registry key: out of memory");
return -2;
}
}
else {
/* Get the value into the existing buffer of length nSizeBuffer */
pValue = pBuffer;
nSize = nSizeBuffer;
}
rv = RegQueryValueEx(hKey,
name, /* key name */
NULL, /* reserved */
NULL, /* type */
pValue, /* for value */
&nSize); /* for size of "value" */
retval = 0; /* Return value */
if (rv == ERROR_FILE_NOT_FOUND) {
ap_log_error(APLOG_MARK,APLOG_WARNING|APLOG_NOERRNO,NULL,
"Registry does not contain value %s\\%s", key, name);
retval = -1;
}
else if (rv == ERROR_MORE_DATA) {
/* This should only happen if we got passed a pre-existing buffer
* (pBuffer, nSizeBuffer). But I suppose it could also happen if we
* allocate a buffer if another process changed the length of the
* value since we found out its length above. Umm.
*/
ap_log_error(APLOG_MARK,APLOG_ERR|APLOG_NOERRNO,NULL,
"Error getting registry value %s: buffer not big enough", key);
retval = -3;
}
else if (rv != ERROR_SUCCESS) {
do_error(rv, "RegQueryValueEx(key %s)", key);
retval = -4;
}
rv = RegCloseKey(hKey);
if (rv != ERROR_SUCCESS) {
do_error(rv, "RegCloseKey HKLM\\%s", key);
if (retval == 0) {
/* Keep error status from RegQueryValueEx, if any */
retval = -4;
}
}
return retval < 0 ? retval : nSize;
}
/*
* Get the server root from the registry into 'dir' which is
* size bytes long. Returns 0 if the server root was found
* or if the serverroot key does not exist (in which case
* dir will contain an empty string), or -1 if there was
* an error getting the key.
*/
int ap_registry_get_server_root(pool *p, char *dir, int size)
{
int rv;
rv = ap_registry_get_key_int(p, REGKEY, "ServerRoot", dir, size, NULL);
if (rv < 0) {
dir[0] = '\0';
}
return (rv < -1) ? -1 : 0;
}
char *ap_get_service_key(char *service_name)
{
char *key = malloc(strlen(SERVICEKEYPRE) +
strlen(service_name) +
strlen(SERVICEKEYPOST) + 1);
sprintf(key,"%s%s%s", SERVICEKEYPRE, service_name, SERVICEKEYPOST);
return(key);
}
int ap_registry_get_service_conf(pool *p, char *dir, int size, char *service_name)
{
int rv;
char *key = ap_get_service_key(service_name);
rv = ap_registry_get_key_int(p, key, "ConfPath", dir, size, NULL);
if (rv < 0) {
dir[0] = '\0';
}
free(key);
return (rv < -1) ? -1 : 0;
}
/**********************************************************************
* The rest of this file deals with storing keys or values in the registry
*/
char *ap_registry_parse_key(int index, char *key)
{
char *head = key, *skey;
int i;
if(!key)
return(NULL);
for(i = 0; i <= index; i++)
{
if(key && key[0] == '\\')
key++;
if (!key)
return(NULL);
head = key;
key = strchr(head, '\\');
}
if(!key)
return(strdup(head));
*key = '\0';
skey = strdup(head);
*key = '\\';
return(skey);
}
/*
* ap_registry_create_apache_key() creates the Apache registry key
* (HLKM\SOFTWARE\Apache Group\Apache\version, as defined at the start
* of this file), if it does not already exist. It will be called by
* ap_registry_store_key_int() if it cannot open this key. This
* function is intended to be called by ap_registry_store_key_int() if
* the Apache key does not exist when it comes to store a data item.
*
* Returns 0 on success or -1 on error. If -1 is returned, the error will
* already have been logged.
*/
static int ap_registry_create_key(char *longkey)
{
int index;
HKEY hKey;
HKEY hKeyNext;
int retval;
int rv;
char *key;
hKey = HKEY_LOCAL_MACHINE;
index = 0;
retval = 0;
/* Walk the tree, creating at each stage if necessary */
while (key=ap_registry_parse_key(index,longkey)) {
int result;
rv = RegCreateKeyEx(hKey,
key, /* subkey */
0, /* reserved */
NULL, /* class */
REG_OPTION_NON_VOLATILE,
KEY_WRITE,
NULL,
&hKeyNext,
&result);
if (rv != ERROR_SUCCESS) {
do_error(rv, "RegCreateKeyEx(%s)", longkey);
retval = -4;
}
/* Close the old key */
rv = RegCloseKey(hKey);
if (rv != ERROR_SUCCESS) {
do_error(rv, "RegCloseKey", NULL);
if (retval == 0) {
/* Keep error status from RegCreateKeyEx, if any */
retval = -4;
}
}
if (retval) {
break;
}
free(key);
hKey = hKeyNext;
index++;
}
if (!key) {
/* Close the final key we opened, if we walked the entire
* tree
*/
rv = RegCloseKey(hKey);
if (rv != ERROR_SUCCESS) {
do_error(rv, "RegCloseKey", NULL);
if (retval == 0) {
/* Keep error status from RegCreateKeyEx, if any */
retval = -4;
}
}
}
else
free(key);
return retval;
}
/*
* ap_registry_store_key_int() stores a value name and value under the
* Apache registry key. If the Apache key does not exist it is created
* first. This function is intended to be called from a wrapper function
* in this file to set particular data values, such as
* ap_registry_set_server_root() below.
*
* Returns 0 if the value name and data was stored successfully, or
* returns -1 if the Apache key does not exist (since we try to create
* this key, this should never happen), or -4 if any other error occurred
* (these values are consistent with ap_registry_get_key_int()).
* If the return value is negative then the error will already have been
* logged via aplog_error().
*/
static int ap_registry_store_key_int(char *key, char *name, DWORD type, void *value, int value_size)
{
long rv;
HKEY hKey;
int retval;
rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
key,
0,
KEY_WRITE,
&hKey);
if (rv == ERROR_FILE_NOT_FOUND) {
/* Key could not be opened -- try to create it
*/
if (ap_registry_create_key(key) < 0) {
/* Creation failed (error already reported) */
return -4;
}
/* Now it has been created we should be able to open it
*/
rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
key,
0,
KEY_WRITE,
&hKey);
if (rv == ERROR_FILE_NOT_FOUND) {
ap_log_error(APLOG_MARK,APLOG_WARNING|APLOG_NOERRNO,NULL,
"Registry does not contain key %s after creation",key);
return -1;
}
}
if (rv != ERROR_SUCCESS) {
do_error(rv, "RegOpenKeyEx HKLM\\%s", key);
return -4;
}
/* Now set the value and data */
rv = RegSetValueEx(hKey,
name, /* value key name */
0, /* reserved */
type, /* type */
value, /* value data */
(DWORD)value_size); /* for size of "value" */
retval = 0; /* Return value */
if (rv != ERROR_SUCCESS) {
do_error(rv, "RegQueryValueEx(key %s)", key);
retval = -4;
}
else {
ap_log_error(APLOG_MARK,APLOG_INFO|APLOG_NOERRNO,NULL,
"Registry stored HKLM\\" REGKEY "\\%s value %s", key,
type == REG_SZ ? value : "(not displayable)");
}
/* Make sure we close the key even if there was an error storing
* the data
*/
rv = RegCloseKey(hKey);
if (rv != ERROR_SUCCESS) {
do_error(rv, "RegCloseKey HKLM\\%s", key);
if (retval == 0) {
/* Keep error status from RegQueryValueEx, if any */
retval = -4;
}
}
return retval;
}
/*
* Sets the service confpath value within the registry. Returns 0 on success
* or -1 on error. If -1 is return the error will already have been
* logged via aplog_error().
*/
int ap_registry_set_service_conf(char *conf, char *service_name)
{
int rv;
char *key = ap_get_service_key(service_name);
rv = ap_registry_store_key_int(key, "ConfPath", REG_SZ, conf, strlen(conf)+1);
free(key);
return rv < 0 ? -1: 0;
}
/*
* Sets the serverroot value within the registry. Returns 0 on success
* or -1 on error. If -1 is return the error will already have been
* logged via aplog_error().
*/
int ap_registry_set_server_root(char *dir)
{
int rv;
rv = ap_registry_store_key_int(REGKEY, "ServerRoot", REG_SZ, dir, strlen(dir)+1);
return rv < 0 ? -1 : 0;
}

431
server/mpm/winnt/service.c Normal file
View File

@@ -0,0 +1,431 @@
#ifdef WIN32
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <process.h>
#include <direct.h>
#include "httpd.h"
#include "http_conf_globals.h"
#include "http_log.h"
#include "http_main.h"
#include "multithread.h"
#include "service.h"
#include "registry.h"
static struct
{
int (*main_fn)(int, char **);
event *stop_event;
int connected;
SERVICE_STATUS_HANDLE hServiceStatus;
char *name;
int exit_status;
SERVICE_STATUS ssStatus;
FILE *logFile;
} globdat;
static void WINAPI service_main_fn(DWORD, LPTSTR *);
static void WINAPI service_ctrl(DWORD ctrlCode);
static int ReportStatusToSCMgr(int currentState, int exitCode, int waitHint);
static int ap_start_service(SC_HANDLE);
static int ap_stop_service(SC_HANDLE);
int service_main(int (*main_fn)(int, char **), int argc, char **argv )
{
SERVICE_TABLE_ENTRY dispatchTable[] =
{
{ "", service_main_fn },
{ NULL, NULL }
};
globdat.main_fn = main_fn;
globdat.stop_event = create_event(0, 0, "apache-signal");
globdat.connected = 1;
if(!StartServiceCtrlDispatcher(dispatchTable))
{
/* This is a genuine failure of the SCM. */
ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL,
"Error starting service control dispatcher");
return(globdat.exit_status);
}
else
{
return(globdat.exit_status);
}
}
void service_cd()
{
/* change to the drive with the executable */
char buf[300];
GetModuleFileName(NULL, buf, 300);
buf[2] = 0;
chdir(buf);
}
void __stdcall service_main_fn(DWORD argc, LPTSTR *argv)
{
ap_server_argv0 = globdat.name = argv[0];
if(!(globdat.hServiceStatus = RegisterServiceCtrlHandler( globdat.name, service_ctrl)))
{
ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL,
"Failure registering service handler");
return;
}
ReportStatusToSCMgr(
SERVICE_START_PENDING, // service state
NO_ERROR, // exit code
3000); // wait hint
service_cd();
if( service_init() )
/* Arguments are ok except for \! */
globdat.exit_status = (*globdat.main_fn)( argc, argv );
ReportStatusToSCMgr(SERVICE_STOPPED, NO_ERROR, 0);
return;
}
void service_set_status(int status)
{
ReportStatusToSCMgr(status, NO_ERROR, 3000);
}
//
// FUNCTION: service_ctrl
//
// PURPOSE: This function is called by the SCM whenever
// ControlService() is called on this service.
//
// PARAMETERS:
// dwCtrlCode - type of control requested
//
// RETURN VALUE:
// none
//
// COMMENTS:
//
VOID WINAPI service_ctrl(DWORD dwCtrlCode)
{
int state;
state = globdat.ssStatus.dwCurrentState;
switch(dwCtrlCode)
{
// Stop the service.
//
case SERVICE_CONTROL_STOP:
state = SERVICE_STOP_PENDING;
ap_start_shutdown();
break;
// Update the service status.
//
case SERVICE_CONTROL_INTERROGATE:
break;
// invalid control code
//
default:
break;
}
ReportStatusToSCMgr(state, NO_ERROR, 0);
}
int ReportStatusToSCMgr(int currentState, int exitCode, int waitHint)
{
static int firstTime = 1;
static int checkPoint = 1;
int rv;
if(firstTime)
{
firstTime = 0;
globdat.ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
globdat.ssStatus.dwServiceSpecificExitCode = 0;
globdat.ssStatus.dwCheckPoint = 1;
}
if(globdat.connected)
{
if (currentState == SERVICE_START_PENDING)
globdat.ssStatus.dwControlsAccepted = 0;
else
globdat.ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
globdat.ssStatus.dwCurrentState = currentState;
globdat.ssStatus.dwWin32ExitCode = exitCode;
if(waitHint)
globdat.ssStatus.dwWaitHint = waitHint;
if ( ( currentState == SERVICE_RUNNING ) ||
( currentState == SERVICE_STOPPED ) )
{
globdat.ssStatus.dwWaitHint = 0;
globdat.ssStatus.dwCheckPoint = 0;
}
else
globdat.ssStatus.dwCheckPoint = ++checkPoint;
rv = SetServiceStatus(globdat.hServiceStatus, &globdat.ssStatus);
}
return(1);
}
void InstallService(char *service_name, char *conf)
{
SC_HANDLE schService;
SC_HANDLE schSCManager;
TCHAR szPath[512];
TCHAR szQuotedPath[512];
printf("Installing the %s service to use %s\n", service_name, conf);
if (GetModuleFileName( NULL, szPath, 512 ) == 0)
{
ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL,
"GetModuleFileName failed");
return;
}
ap_snprintf(szQuotedPath, 512, "\"%s\"", szPath);
schSCManager = OpenSCManager(
NULL, // machine (NULL == local)
NULL, // database (NULL == default)
SC_MANAGER_ALL_ACCESS // access required
);
if (!schSCManager) {
ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL,
"OpenSCManager failed");
}
else {
schService = CreateService(
schSCManager, // SCManager database
service_name, // name of service
service_name, // name to display
SERVICE_ALL_ACCESS, // desired access
SERVICE_WIN32_OWN_PROCESS, // service type
SERVICE_AUTO_START, // start type
SERVICE_ERROR_NORMAL, // error control type
szQuotedPath, // service's binary
NULL, // no load ordering group
NULL, // no tag identifier
NULL, // dependencies
NULL, // LocalSystem account
NULL); // no password
if (schService) {
CloseServiceHandle(schService);
/* Now store the server_root in the registry */
if(!ap_registry_set_service_conf(conf, service_name))
printf("The %s service has been installed successfully.\n", service_name );
}
else {
ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL,
"CreateService failed");
}
CloseServiceHandle(schSCManager);
}
}
void RemoveService(char *service_name)
{
SC_HANDLE schService;
SC_HANDLE schSCManager;
printf("Removing the %s service\n", service_name);
schSCManager = OpenSCManager(
NULL, // machine (NULL == local)
NULL, // database (NULL == default)
SC_MANAGER_ALL_ACCESS // access required
);
if (!schSCManager) {
ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL,
"OpenSCManager failed");
}
else {
schService = OpenService(schSCManager, service_name, SERVICE_ALL_ACCESS);
if (schService == NULL) {
/* Could not open the service */
ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL,
"OpenService failed");
}
else {
/* try to stop the service */
ap_stop_service(schService);
// now remove the service
if (DeleteService(schService) == 0)
ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL,
"DeleteService failed");
else
printf("The %s service has been removed successfully.\n", service_name );
CloseServiceHandle(schService);
}
/* SCM removes registry parameters */
CloseServiceHandle(schSCManager);
}
}
/* A hack to determine if we're running as a service without waiting for
* the SCM to fail; if AllocConsole succeeds, we're a service.
*/
BOOL isProcessService() {
if( !AllocConsole() )
return FALSE;
FreeConsole();
return TRUE;
}
/* Determine is service_name is a valid service
*/
BOOL isValidService(char *service_name) {
SC_HANDLE schSCM, schSVC;
int Err;
if (!(schSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS))) {
ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL,
"OpenSCManager failed");
return FALSE;
}
if ((schSVC = OpenService(schSCM, service_name, SERVICE_ALL_ACCESS))) {
CloseServiceHandle(schSVC);
CloseServiceHandle(schSCM);
return TRUE;
}
Err = GetLastError();
if (Err != ERROR_SERVICE_DOES_NOT_EXIST && Err != ERROR_INVALID_NAME)
ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL,
"OpenService failed");
return FALSE;
}
int send_signal_to_service(char *service_name, char *sig) {
SC_HANDLE schService;
SC_HANDLE schSCManager;
int success = FALSE;
enum { start, restart, stop, unknown } action;
static char *param[] = { "start", "restart", "shutdown" };
static char *participle[] = { "starting", "restarting", "stopping" };
static char *past[] = { "started", "restarted", "stopped" };
for (action = start; action < unknown; action++)
if (!strcasecmp(sig, param[action]))
break;
if (action == unknown) {
printf("signal must be start, restart, or shutdown\n");
return FALSE;
}
schSCManager = OpenSCManager(
NULL, // machine (NULL == local)
NULL, // database (NULL == default)
SC_MANAGER_ALL_ACCESS // access required
);
if (!schSCManager) {
ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL,
"OpenSCManager failed");
}
else {
schService = OpenService(schSCManager, service_name, SERVICE_ALL_ACCESS);
if (schService == NULL) {
/* Could not open the service */
ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL,
"OpenService failed");
}
else {
if (!QueryServiceStatus(schService, &globdat.ssStatus))
ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL,
"QueryService failed");
else {
if (globdat.ssStatus.dwCurrentState == SERVICE_STOPPED && action == stop)
printf("The %s service is not started.\n", service_name);
else if (globdat.ssStatus.dwCurrentState == SERVICE_RUNNING && action == start)
printf("The %s service has already been started.\n", service_name);
else {
printf("The %s service is %s.\n", service_name, participle[action]);
if (action == stop || action == restart)
success = ap_stop_service(schService);
if (action == start || action == restart)
success = ap_start_service(schService);
if( success )
printf("The %s service has %s.\n", service_name, past[action]);
else
printf("Failed to %s the %s service.\n", sig, service_name );
}
CloseServiceHandle(schService);
}
}
/* SCM removes registry parameters */
CloseServiceHandle(schSCManager);
}
return success;
}
int ap_stop_service(SC_HANDLE schService)
{
if (ControlService(schService, SERVICE_CONTROL_STOP, &globdat.ssStatus)) {
Sleep(1000);
while (QueryServiceStatus(schService, &globdat.ssStatus)) {
if (globdat.ssStatus.dwCurrentState == SERVICE_STOP_PENDING)
Sleep(1000);
else
break;
}
}
if (QueryServiceStatus(schService, &globdat.ssStatus))
if (globdat.ssStatus.dwCurrentState == SERVICE_STOPPED)
return TRUE;
return FALSE;
}
int ap_start_service(SC_HANDLE schService) {
if (StartService(schService, 0, NULL)) {
Sleep(1000);
while(QueryServiceStatus(schService, &globdat.ssStatus)) {
if(globdat.ssStatus.dwCurrentState == SERVICE_START_PENDING)
Sleep(1000);
else
break;
}
}
if (QueryServiceStatus(schService, &globdat.ssStatus))
if (globdat.ssStatus.dwCurrentState == SERVICE_RUNNING)
return TRUE;
return FALSE;
}
#endif /* WIN32 */

248
server/rfc1413.c Normal file
View File

@@ -0,0 +1,248 @@
/* ====================================================================
* Copyright (c) 1995-1999 The Apache Group. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* 4. The names "Apache Server" and "Apache Group" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Group and was originally based
* on public domain software written at the National Center for
* Supercomputing Applications, University of Illinois, Urbana-Champaign.
* For more information on the Apache Group and the Apache HTTP server
* project, please see <http://www.apache.org/>.
*
*/
/*
* rfc1413() speaks a common subset of the RFC 1413, AUTH, TAP and IDENT
* protocols. The code queries an RFC 1413 etc. compatible daemon on a remote
* host to look up the owner of a connection. The information should not be
* used for authentication purposes. This routine intercepts alarm signals.
*
* Diagnostics are reported through syslog(3).
*
* Author: Wietse Venema, Eindhoven University of Technology,
* The Netherlands.
*/
/* Some small additions for Apache --- ditch the "sccsid" var if
* compiling with gcc (it *has* changed), include ap_config.h for the
* prototypes it defines on at least one system (SunlOSs) which has
* them missing from the standard header files, and one minor change
* below (extra parens around assign "if (foo = bar) ..." to shut up
* gcc -Wall).
*/
/* Rewritten by David Robinson */
#include "httpd.h" /* for server_rec, conn_rec, ap_longjmp, etc. */
#include "http_log.h" /* for aplog_error */
#include "rfc1413.h"
#include "http_main.h" /* set_callback_and_alarm */
/* Local stuff. */
/* Semi-well-known port */
#define RFC1413_PORT 113
/* maximum allowed length of userid */
#define RFC1413_USERLEN 512
/* rough limit on the amount of data we accept. */
#define RFC1413_MAXDATA 1000
#ifndef RFC1413_TIMEOUT
#define RFC1413_TIMEOUT 30
#endif
#define ANY_PORT 0 /* Any old port will do */
#define FROM_UNKNOWN "unknown"
int ap_rfc1413_timeout = RFC1413_TIMEOUT; /* Global so it can be changed */
static JMP_BUF timebuf;
/* bind_connect - bind both ends of a socket */
/* Ambarish fix this. Very broken */
static int get_rfc1413(int sock, const struct sockaddr_in *our_sin,
const struct sockaddr_in *rmt_sin,
char user[RFC1413_USERLEN+1], server_rec *srv)
{
struct sockaddr_in rmt_query_sin, our_query_sin;
unsigned int rmt_port, our_port;
int i;
char *cp;
char buffer[RFC1413_MAXDATA + 1];
int buflen;
/*
* Bind the local and remote ends of the query socket to the same
* IP addresses as the connection under investigation. We go
* through all this trouble because the local or remote system
* might have more than one network address. The RFC1413 etc.
* client sends only port numbers; the server takes the IP
* addresses from the query socket.
*/
our_query_sin = *our_sin;
our_query_sin.sin_port = htons(ANY_PORT);
rmt_query_sin = *rmt_sin;
rmt_query_sin.sin_port = htons(RFC1413_PORT);
if (bind(sock, (struct sockaddr *) &our_query_sin,
sizeof(struct sockaddr_in)) < 0) {
ap_log_error(APLOG_MARK, APLOG_CRIT, srv,
"bind: rfc1413: Error binding to local port");
return -1;
}
/*
* errors from connect usually imply the remote machine doesn't support
* the service
*/
if (connect(sock, (struct sockaddr *) &rmt_query_sin,
sizeof(struct sockaddr_in)) < 0)
return -1;
/* send the data */
buflen = ap_snprintf(buffer, sizeof(buffer), "%u,%u\r\n", ntohs(rmt_sin->sin_port),
ntohs(our_sin->sin_port));
/* send query to server. Handle short write. */
#ifdef CHARSET_EBCDIC
ebcdic2ascii(&buffer, &buffer, buflen);
#endif
i = 0;
while(i < strlen(buffer)) {
int j;
j = write(sock, buffer+i, (strlen(buffer+i)));
if (j < 0 && errno != EINTR) {
ap_log_error(APLOG_MARK, APLOG_CRIT, srv,
"write: rfc1413: error sending request");
return -1;
}
else if (j > 0) {
i+=j;
}
}
/*
* Read response from server. - the response should be newline
* terminated according to rfc - make sure it doesn't stomp it's
* way out of the buffer.
*/
i = 0;
memset(buffer, '\0', sizeof(buffer));
/*
* Note that the strchr function below checks for 10 instead of '\n'
* this allows it to work on both ASCII and EBCDIC machines.
*/
while((cp = strchr(buffer, '\012')) == NULL && i < sizeof(buffer) - 1) {
int j;
j = read(sock, buffer+i, (sizeof(buffer) - 1) - i);
if (j < 0 && errno != EINTR) {
ap_log_error(APLOG_MARK, APLOG_CRIT, srv,
"read: rfc1413: error reading response");
return -1;
}
else if (j > 0) {
i+=j;
}
}
/* RFC1413_USERLEN = 512 */
#ifdef CHARSET_EBCDIC
ascii2ebcdic(&buffer, &buffer, (size_t)i);
#endif
if (sscanf(buffer, "%u , %u : USERID :%*[^:]:%512s", &rmt_port, &our_port,
user) != 3 || ntohs(rmt_sin->sin_port) != rmt_port
|| ntohs(our_sin->sin_port) != our_port)
return -1;
/*
* Strip trailing carriage return. It is part of the
* protocol, not part of the data.
*/
if ((cp = strchr(user, '\r')))
*cp = '\0';
return 0;
}
/* ident_timeout - handle timeouts */
static void ident_timeout(int sig)
{
ap_longjmp(timebuf, sig);
}
/* rfc1413 - return remote user name, given socket structures */
char *ap_rfc1413(conn_rec *conn, server_rec *srv)
{
static char user[RFC1413_USERLEN + 1]; /* XXX */
static char *result;
static int sock;
result = FROM_UNKNOWN;
sock = ap_psocket(conn->pool, AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock < 0) {
ap_log_error(APLOG_MARK, APLOG_CRIT, srv,
"socket: rfc1413: error creating socket");
conn->remote_logname = result;
}
/*
* Set up a timer so we won't get stuck while waiting for the server.
*/
if (ap_setjmp(timebuf) == 0) {
ap_set_callback_and_alarm(ident_timeout, ap_rfc1413_timeout);
if (get_rfc1413(sock, &conn->local_addr, &conn->remote_addr, user, srv) >= 0)
result = user;
}
ap_set_callback_and_alarm(NULL, 0);
ap_pclosesocket(conn->pool, sock);
conn->remote_logname = result;
return conn->remote_logname;
}

2145
server/util.c Normal file

File diff suppressed because it is too large Load Diff

321
server/util_date.c Normal file
View File

@@ -0,0 +1,321 @@
/* ====================================================================
* Copyright (c) 1996-1999 The Apache Group. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* 4. The names "Apache Server" and "Apache Group" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Group and was originally based
* on public domain software written at the National Center for
* Supercomputing Applications, University of Illinois, Urbana-Champaign.
* For more information on the Apache Group and the Apache HTTP server
* project, please see <http://www.apache.org/>.
*
*/
/*
* util_date.c: date parsing utility routines
* These routines are (hopefully) platform-independent.
*
* 27 Oct 1996 Roy Fielding
* Extracted (with many modifications) from mod_proxy.c and
* tested with over 50,000 randomly chosen valid date strings
* and several hundred variations of invalid date strings.
*
*/
#include "ap_config.h"
#include "util_date.h"
#include <ctype.h>
#include <string.h>
/*
* Compare a string to a mask
* Mask characters (arbitrary maximum is 256 characters, just in case):
* @ - uppercase letter
* $ - lowercase letter
* & - hex digit
* # - digit
* ~ - digit or space
* * - swallow remaining characters
* <x> - exact match for any other character
*/
API_EXPORT(int) ap_checkmask(const char *data, const char *mask)
{
int i;
char d;
for (i = 0; i < 256; i++) {
d = data[i];
switch (mask[i]) {
case '\0':
return (d == '\0');
case '*':
return 1;
case '@':
if (!ap_isupper(d))
return 0;
break;
case '$':
if (!ap_islower(d))
return 0;
break;
case '#':
if (!ap_isdigit(d))
return 0;
break;
case '&':
if (!ap_isxdigit(d))
return 0;
break;
case '~':
if ((d != ' ') && !ap_isdigit(d))
return 0;
break;
default:
if (mask[i] != d)
return 0;
break;
}
}
return 0; /* We only get here if mask is corrupted (exceeds 256) */
}
/*
* tm2sec converts a GMT tm structure into the number of seconds since
* 1st January 1970 UT. Note that we ignore tm_wday, tm_yday, and tm_dst.
*
* The return value is always a valid time_t value -- (time_t)0 is returned
* if the input date is outside that capable of being represented by time(),
* i.e., before Thu, 01 Jan 1970 00:00:00 for all systems and
* beyond 2038 for 32bit systems.
*
* This routine is intended to be very fast, much faster than mktime().
*/
API_EXPORT(time_t) ap_tm2sec(const struct tm * t)
{
int year;
time_t days;
static const int dayoffset[12] =
{306, 337, 0, 31, 61, 92, 122, 153, 184, 214, 245, 275};
year = t->tm_year;
if (year < 70 || ((sizeof(time_t) <= 4) && (year >= 138)))
return BAD_DATE;
/* shift new year to 1st March in order to make leap year calc easy */
if (t->tm_mon < 2)
year--;
/* Find number of days since 1st March 1900 (in the Gregorian calendar). */
days = year * 365 + year / 4 - year / 100 + (year / 100 + 3) / 4;
days += dayoffset[t->tm_mon] + t->tm_mday - 1;
days -= 25508; /* 1 jan 1970 is 25508 days since 1 mar 1900 */
days = ((days * 24 + t->tm_hour) * 60 + t->tm_min) * 60 + t->tm_sec;
if (days < 0)
return BAD_DATE; /* must have overflowed */
else
return days; /* must be a valid time */
}
/*
* Parses an HTTP date in one of three standard forms:
*
* Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123
* Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036
* Sun Nov 6 08:49:37 1994 ; ANSI C's asctime() format
*
* and returns the time_t number of seconds since 1 Jan 1970 GMT, or
* 0 if this would be out of range or if the date is invalid.
*
* The restricted HTTP syntax is
*
* HTTP-date = rfc1123-date | rfc850-date | asctime-date
*
* rfc1123-date = wkday "," SP date1 SP time SP "GMT"
* rfc850-date = weekday "," SP date2 SP time SP "GMT"
* asctime-date = wkday SP date3 SP time SP 4DIGIT
*
* date1 = 2DIGIT SP month SP 4DIGIT
* ; day month year (e.g., 02 Jun 1982)
* date2 = 2DIGIT "-" month "-" 2DIGIT
* ; day-month-year (e.g., 02-Jun-82)
* date3 = month SP ( 2DIGIT | ( SP 1DIGIT ))
* ; month day (e.g., Jun 2)
*
* time = 2DIGIT ":" 2DIGIT ":" 2DIGIT
* ; 00:00:00 - 23:59:59
*
* wkday = "Mon" | "Tue" | "Wed"
* | "Thu" | "Fri" | "Sat" | "Sun"
*
* weekday = "Monday" | "Tuesday" | "Wednesday"
* | "Thursday" | "Friday" | "Saturday" | "Sunday"
*
* month = "Jan" | "Feb" | "Mar" | "Apr"
* | "May" | "Jun" | "Jul" | "Aug"
* | "Sep" | "Oct" | "Nov" | "Dec"
*
* However, for the sake of robustness (and Netscapeness), we ignore the
* weekday and anything after the time field (including the timezone).
*
* This routine is intended to be very fast; 10x faster than using sscanf.
*
* Originally from Andrew Daviel <andrew@vancouver-webpages.com>, 29 Jul 96
* but many changes since then.
*
*/
API_EXPORT(time_t) ap_parseHTTPdate(const char *date)
{
struct tm ds;
int mint, mon;
const char *monstr, *timstr;
static const int months[12] =
{
('J' << 16) | ('a' << 8) | 'n', ('F' << 16) | ('e' << 8) | 'b',
('M' << 16) | ('a' << 8) | 'r', ('A' << 16) | ('p' << 8) | 'r',
('M' << 16) | ('a' << 8) | 'y', ('J' << 16) | ('u' << 8) | 'n',
('J' << 16) | ('u' << 8) | 'l', ('A' << 16) | ('u' << 8) | 'g',
('S' << 16) | ('e' << 8) | 'p', ('O' << 16) | ('c' << 8) | 't',
('N' << 16) | ('o' << 8) | 'v', ('D' << 16) | ('e' << 8) | 'c'};
if (!date)
return BAD_DATE;
while (*date && ap_isspace(*date)) /* Find first non-whitespace char */
++date;
if (*date == '\0')
return BAD_DATE;
if ((date = strchr(date, ' ')) == NULL) /* Find space after weekday */
return BAD_DATE;
++date; /* Now pointing to first char after space, which should be */
/* start of the actual date information for all 3 formats. */
if (ap_checkmask(date, "## @$$ #### ##:##:## *")) { /* RFC 1123 format */
ds.tm_year = ((date[7] - '0') * 10 + (date[8] - '0') - 19) * 100;
if (ds.tm_year < 0)
return BAD_DATE;
ds.tm_year += ((date[9] - '0') * 10) + (date[10] - '0');
ds.tm_mday = ((date[0] - '0') * 10) + (date[1] - '0');
monstr = date + 3;
timstr = date + 12;
}
else if (ap_checkmask(date, "##-@$$-## ##:##:## *")) { /* RFC 850 format */
ds.tm_year = ((date[7] - '0') * 10) + (date[8] - '0');
if (ds.tm_year < 70)
ds.tm_year += 100;
ds.tm_mday = ((date[0] - '0') * 10) + (date[1] - '0');
monstr = date + 3;
timstr = date + 10;
}
else if (ap_checkmask(date, "@$$ ~# ##:##:## ####*")) { /* asctime format */
ds.tm_year = ((date[16] - '0') * 10 + (date[17] - '0') - 19) * 100;
if (ds.tm_year < 0)
return BAD_DATE;
ds.tm_year += ((date[18] - '0') * 10) + (date[19] - '0');
if (date[4] == ' ')
ds.tm_mday = 0;
else
ds.tm_mday = (date[4] - '0') * 10;
ds.tm_mday += (date[5] - '0');
monstr = date;
timstr = date + 7;
}
else
return BAD_DATE;
if (ds.tm_mday <= 0 || ds.tm_mday > 31)
return BAD_DATE;
ds.tm_hour = ((timstr[0] - '0') * 10) + (timstr[1] - '0');
ds.tm_min = ((timstr[3] - '0') * 10) + (timstr[4] - '0');
ds.tm_sec = ((timstr[6] - '0') * 10) + (timstr[7] - '0');
if ((ds.tm_hour > 23) || (ds.tm_min > 59) || (ds.tm_sec > 61))
return BAD_DATE;
mint = (monstr[0] << 16) | (monstr[1] << 8) | monstr[2];
for (mon = 0; mon < 12; mon++)
if (mint == months[mon])
break;
if (mon == 12)
return BAD_DATE;
if ((ds.tm_mday == 31) && (mon == 3 || mon == 5 || mon == 8 || mon == 10))
return BAD_DATE;
/* February gets special check for leapyear */
if ((mon == 1) &&
((ds.tm_mday > 29)
|| ((ds.tm_mday == 29)
&& ((ds.tm_year & 3)
|| (((ds.tm_year % 100) == 0)
&& (((ds.tm_year % 400) != 100)))))))
return BAD_DATE;
ds.tm_mon = mon;
return ap_tm2sec(&ds);
}

229
server/util_md5.c Normal file
View File

@@ -0,0 +1,229 @@
/* ====================================================================
* Copyright (c) 1995-1999 The Apache Group. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* 4. The names "Apache Server" and "Apache Group" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Group and was originally based
* on public domain software written at the National Center for
* Supercomputing Applications, University of Illinois, Urbana-Champaign.
* For more information on the Apache Group and the Apache HTTP server
* project, please see <http://www.apache.org/>.
*
*/
/************************************************************************
* NCSA HTTPd Server
* Software Development Group
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* 605 E. Springfield, Champaign, IL 61820
* httpd@ncsa.uiuc.edu
*
* Copyright (C) 1995, Board of Trustees of the University of Illinois
*
************************************************************************
*
* md5.c: NCSA HTTPd code which uses the md5c.c RSA Code
*
* Original Code Copyright (C) 1994, Jeff Hostetler, Spyglass, Inc.
* Portions of Content-MD5 code Copyright (C) 1993, 1994 by Carnegie Mellon
* University (see Copyright below).
* Portions of Content-MD5 code Copyright (C) 1991 Bell Communications
* Research, Inc. (Bellcore) (see Copyright below).
* Portions extracted from mpack, John G. Myers - jgm+@cmu.edu
* Content-MD5 Code contributed by Martin Hamilton (martin@net.lut.ac.uk)
*
*/
/* md5.c --Module Interface to MD5. */
/* Jeff Hostetler, Spyglass, Inc., 1994. */
#include "httpd.h"
#include "util_md5.h"
API_EXPORT(char *) ap_md5_binary(pool *p, const unsigned char *buf, int length)
{
const char *hex = "0123456789abcdef";
AP_MD5_CTX my_md5;
unsigned char hash[16];
char *r, result[33];
int i;
/*
* Take the MD5 hash of the string argument.
*/
ap_MD5Init(&my_md5);
ap_MD5Update(&my_md5, buf, (unsigned int)length);
ap_MD5Final(hash, &my_md5);
for (i = 0, r = result; i < 16; i++) {
*r++ = hex[hash[i] >> 4];
*r++ = hex[hash[i] & 0xF];
}
*r = '\0';
return ap_pstrdup(p, result);
}
API_EXPORT(char *) ap_md5(pool *p, const unsigned char *string)
{
return ap_md5_binary(p, string, (int) strlen((char *)string));
}
/* these portions extracted from mpack, John G. Myers - jgm+@cmu.edu */
/* (C) Copyright 1993,1994 by Carnegie Mellon University
* All Rights Reserved.
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
* appear in supporting documentation, and that the name of Carnegie
* Mellon University not be used in advertising or publicity
* pertaining to distribution of the software without specific,
* written prior permission. Carnegie Mellon University makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied
* warranty.
*
* CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
/*
* Copyright (c) 1991 Bell Communications Research, Inc. (Bellcore)
*
* Permission to use, copy, modify, and distribute this material
* for any purpose and without fee is hereby granted, provided
* that the above copyright notice and this permission notice
* appear in all copies, and that the name of Bellcore not be
* used in advertising or publicity pertaining to this
* material without the specific, prior written permission
* of an authorized representative of Bellcore. BELLCORE
* MAKES NO REPRESENTATIONS ABOUT THE ACCURACY OR SUITABILITY
* OF THIS MATERIAL FOR ANY PURPOSE. IT IS PROVIDED "AS IS",
* WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
*/
static char basis_64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
API_EXPORT(char *) ap_md5contextTo64(pool *a, AP_MD5_CTX * context)
{
unsigned char digest[18];
char *encodedDigest;
int i;
char *p;
encodedDigest = (char *) ap_pcalloc(a, 25 * sizeof(char));
ap_MD5Final(digest, context);
digest[sizeof(digest) - 1] = digest[sizeof(digest) - 2] = 0;
p = encodedDigest;
for (i = 0; i < sizeof(digest); i += 3) {
*p++ = basis_64[digest[i] >> 2];
*p++ = basis_64[((digest[i] & 0x3) << 4) | ((int) (digest[i + 1] & 0xF0) >> 4)];
*p++ = basis_64[((digest[i + 1] & 0xF) << 2) | ((int) (digest[i + 2] & 0xC0) >> 6)];
*p++ = basis_64[digest[i + 2] & 0x3F];
}
*p-- = '\0';
*p-- = '=';
*p-- = '=';
return encodedDigest;
}
#ifdef CHARSET_EBCDIC
API_EXPORT(char *) ap_md5digest(pool *p, FILE *infile, int convert)
{
AP_MD5_CTX context;
unsigned char buf[1000];
long length = 0;
int nbytes;
ap_MD5Init(&context);
while ((nbytes = fread(buf, 1, sizeof(buf), infile))) {
length += nbytes;
if (!convert) {
ascii2ebcdic(buf, buf, nbytes);
}
ap_MD5Update(&context, buf, nbytes);
}
rewind(infile);
return ap_md5contextTo64(p, &context);
}
#else
API_EXPORT(char *) ap_md5digest(pool *p, FILE *infile)
{
AP_MD5_CTX context;
unsigned char buf[1000];
long length = 0;
unsigned int nbytes;
ap_MD5Init(&context);
while ((nbytes = fread(buf, 1, sizeof(buf), infile))) {
length += nbytes;
ap_MD5Update(&context, buf, nbytes);
}
rewind(infile);
return ap_md5contextTo64(p, &context);
}
#endif /* CHARSET_EBCDIC */

1138
server/util_script.c Normal file

File diff suppressed because it is too large Load Diff

599
server/util_uri.c Normal file
View File

@@ -0,0 +1,599 @@
/* ====================================================================
* Copyright (c) 1998-1999 The Apache Group. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* 4. The names "Apache Server" and "Apache Group" must not be used to
* endorse or promote products derived from this software without
* prior written permission.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Group and was originally based
* on public domain software written at the National Center for
* Supercomputing Applications, University of Illinois, Urbana-Champaign.
* For more information on the Apache Group and the Apache HTTP server
* project, please see <http://www.apache.org/>.
*
*/
/*
* util_uri.c: URI related utility things
*
*/
#include "httpd.h"
#include "http_log.h"
#include "http_conf_globals.h" /* for user_id & group_id */
#include "util_uri.h"
/* Some WWW schemes and their default ports; this is basically /etc/services */
/* This will become global when the protocol abstraction comes */
/* As the schemes are searched by a linear search, */
/* they are sorted by their expected frequency */
static schemes_t schemes[] =
{
{"http", DEFAULT_HTTP_PORT},
{"ftp", DEFAULT_FTP_PORT},
{"https", DEFAULT_HTTPS_PORT},
{"gopher", DEFAULT_GOPHER_PORT},
{"wais", DEFAULT_WAIS_PORT},
{"nntp", DEFAULT_NNTP_PORT},
{"snews", DEFAULT_SNEWS_PORT},
{"prospero", DEFAULT_PROSPERO_PORT},
{ NULL, 0xFFFF } /* unknown port */
};
API_EXPORT(unsigned short) ap_default_port_for_scheme(const char *scheme_str)
{
schemes_t *scheme;
for (scheme = schemes; scheme->name != NULL; ++scheme)
if (strcasecmp(scheme_str, scheme->name) == 0)
return scheme->default_port;
return 0;
}
API_EXPORT(unsigned short) ap_default_port_for_request(const request_rec *r)
{
return (r->parsed_uri.scheme)
? ap_default_port_for_scheme(r->parsed_uri.scheme)
: 0;
}
/* Create a copy of a "struct hostent" record; it was presumably returned
* from a call to gethostbyname() and lives in static storage.
* By creating a copy we can tuck it away for later use.
*/
API_EXPORT(struct hostent *) ap_pduphostent(pool *p, const struct hostent *hp)
{
struct hostent *newent;
char **ptrs;
char **aliases;
struct in_addr *addrs;
int i = 0, j = 0;
if (hp == NULL)
return NULL;
/* Count number of alias entries */
if (hp->h_aliases != NULL)
for (; hp->h_aliases[j] != NULL; ++j)
continue;
/* Count number of in_addr entries */
if (hp->h_addr_list != NULL)
for (; hp->h_addr_list[i] != NULL; ++i)
continue;
/* Allocate hostent structure, alias ptrs, addr ptrs, addrs */
newent = (struct hostent *) ap_palloc(p, sizeof(*hp));
aliases = (char **) ap_palloc(p, (j+1) * sizeof(char*));
ptrs = (char **) ap_palloc(p, (i+1) * sizeof(char*));
addrs = (struct in_addr *) ap_palloc(p, (i+1) * sizeof(struct in_addr));
*newent = *hp;
newent->h_name = ap_pstrdup(p, hp->h_name);
newent->h_aliases = aliases;
newent->h_addr_list = (char**) ptrs;
/* Copy Alias Names: */
for (j = 0; hp->h_aliases[j] != NULL; ++j) {
aliases[j] = ap_pstrdup(p, hp->h_aliases[j]);
}
aliases[j] = NULL;
/* Copy address entries */
for (i = 0; hp->h_addr_list[i] != NULL; ++i) {
ptrs[i] = (char*) &addrs[i];
addrs[i] = *(struct in_addr *) hp->h_addr_list[i];
}
ptrs[i] = NULL;
return newent;
}
/* pgethostbyname(): resolve hostname, if successful return an ALLOCATED
* COPY OF the hostent structure, intended to be stored and used later.
* (gethostbyname() uses static storage that would be overwritten on each call)
*/
API_EXPORT(struct hostent *) ap_pgethostbyname(pool *p, const char *hostname)
{
struct hostent *hp = gethostbyname(hostname);
return (hp == NULL) ? NULL : ap_pduphostent(p, hp);
}
/* Unparse a uri_components structure to an URI string.
* Optionally suppress the password for security reasons.
*/
API_EXPORT(char *) ap_unparse_uri_components(pool *p, const uri_components *uptr, unsigned flags)
{
char *ret = "";
/* If suppressing the site part, omit both user name & scheme://hostname */
if (!(flags & UNP_OMITSITEPART)) {
/* Construct a "user:password@" string, honoring the passed UNP_ flags: */
if (uptr->user||uptr->password)
ret = ap_pstrcat (p,
(uptr->user && !(flags & UNP_OMITUSER)) ? uptr->user : "",
(uptr->password && !(flags & UNP_OMITPASSWORD)) ? ":" : "",
(uptr->password && !(flags & UNP_OMITPASSWORD))
? ((flags & UNP_REVEALPASSWORD) ? uptr->password : "XXXXXXXX")
: "",
"@", NULL);
/* Construct scheme://site string */
if (uptr->hostname) {
int is_default_port;
is_default_port =
(uptr->port_str == NULL ||
uptr->port == 0 ||
uptr->port == ap_default_port_for_scheme(uptr->scheme));
ret = ap_pstrcat (p,
uptr->scheme, "://", ret,
uptr->hostname ? uptr->hostname : "",
is_default_port ? "" : ":",
is_default_port ? "" : uptr->port_str,
NULL);
}
}
/* Should we suppress all path info? */
if (!(flags & UNP_OMITPATHINFO)) {
/* Append path, query and fragment strings: */
ret = ap_pstrcat (p,
ret,
uptr->path ? uptr->path : "",
(uptr->query && !(flags & UNP_OMITQUERY)) ? "?" : "",
(uptr->query && !(flags & UNP_OMITQUERY)) ? uptr->query : "",
(uptr->fragment && !(flags & UNP_OMITQUERY)) ? "#" : NULL,
(uptr->fragment && !(flags & UNP_OMITQUERY)) ? uptr->fragment : NULL,
NULL);
}
return ret;
}
/* The regex version of parse_uri_components has the advantage that it is
* relatively easy to understand and extend. But it has the disadvantage
* that the regexes are complex enough that regex libraries really
* don't do a great job with them performancewise.
*
* The default is a hand coded scanner that is two orders of magnitude
* faster.
*/
#ifdef UTIL_URI_REGEX
static regex_t re_uri;
static regex_t re_hostpart;
void ap_util_uri_init(void)
{
int ret;
const char *re_str;
/* This is a modified version of the regex that appeared in
* draft-fielding-uri-syntax-01. It doesnt allow the uri to contain a
* scheme but no hostinfo or vice versa.
*
* draft-fielding-uri-syntax-01.txt, section 4.4 tells us:
*
* Although the BNF defines what is allowed in each component, it is
* ambiguous in terms of differentiating between a site component and
* a path component that begins with two slash characters.
*
* RFC2068 disambiguates this for the Request-URI, which may only ever be
* the "abs_path" portion of the URI. So a request "GET //foo/bar
* HTTP/1.1" is really referring to the path //foo/bar, not the host foo,
* path /bar. Nowhere in RFC2068 is it possible to have a scheme but no
* hostinfo or a hostinfo but no scheme. (Unless you're proxying a
* protocol other than HTTP, but this parsing engine probably won't work
* for other protocols.)
*
* 12 3 4 5 6 7 8 */
re_str = "^(([^:/?#]+)://([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?$";
/* ^scheme--^ ^site---^ ^path--^ ^query^ ^frag */
if ((ret = regcomp(&re_uri, re_str, REG_EXTENDED)) != 0) {
char line[1024];
/* Make a readable error message */
ret = regerror(ret, &re_uri, line, sizeof line);
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, NULL,
"Internal error: regcomp(\"%s\") returned non-zero (%s) - "
"possibly due to broken regex lib! "
"Did you define WANTHSREGEX=yes?",
re_str, line);
exit(1);
}
/* This is a sub-RE which will break down the hostinfo part,
* i.e., user, password, hostname and port.
* $ 12 3 4 5 6 7 */
re_str = "^(([^:]*)(:(.*))?@)?([^@:]*)(:([0-9]*))?$";
/* ^^user^ :pw ^host^ ^:[port]^ */
if ((ret = regcomp(&re_hostpart, re_str, REG_EXTENDED)) != 0) {
char line[1024];
/* Make a readable error message */
ret = regerror(ret, &re_hostpart, line, sizeof line);
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, NULL,
"Internal error: regcomp(\"%s\") returned non-zero (%s) - "
"possibly due to broken regex lib! "
"Did you define WANTHSREGEX=yes?",
re_str, line);
exit(1);
}
}
/* parse_uri_components():
* Parse a given URI, fill in all supplied fields of a uri_components
* structure. This eliminates the necessity of extracting host, port,
* path, query info repeatedly in the modules.
* Side effects:
* - fills in fields of uri_components *uptr
* - none on any of the r->* fields
*/
API_EXPORT(int) ap_parse_uri_components(pool *p, const char *uri, uri_components *uptr)
{
int ret;
regmatch_t match[10]; /* This must have at least as much elements
* as there are braces in the re_strings */
ap_assert (uptr != NULL);
/* Initialize the structure. parse_uri() and parse_uri_components()
* can be called more than once per request.
*/
memset (uptr, '\0', sizeof(*uptr));
uptr->is_initialized = 1;
ret = ap_regexec(&re_uri, uri, re_uri.re_nsub + 1, match, 0);
if (ret != 0) {
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, NULL,
"ap_regexec() could not parse uri (\"%s\")",
uri);
return HTTP_BAD_REQUEST;
}
if (match[2].rm_so != match[2].rm_eo)
uptr->scheme = ap_pstrndup (p, uri+match[2].rm_so, match[2].rm_eo - match[2].rm_so);
/* empty hostinfo is valid, that's why we test $1 but use $3 */
if (match[1].rm_so != match[1].rm_eo)
uptr->hostinfo = ap_pstrndup (p, uri+match[3].rm_so, match[3].rm_eo - match[3].rm_so);
if (match[4].rm_so != match[4].rm_eo)
uptr->path = ap_pstrndup (p, uri+match[4].rm_so, match[4].rm_eo - match[4].rm_so);
/* empty query string is valid, that's why we test $5 but use $6 */
if (match[5].rm_so != match[5].rm_eo)
uptr->query = ap_pstrndup (p, uri+match[6].rm_so, match[6].rm_eo - match[6].rm_so);
/* empty fragment is valid, test $7 use $8 */
if (match[7].rm_so != match[7].rm_eo)
uptr->fragment = ap_pstrndup (p, uri+match[8].rm_so, match[8].rm_eo - match[8].rm_so);
if (uptr->hostinfo) {
/* Parse the hostinfo part to extract user, password, host, and port */
ret = ap_regexec(&re_hostpart, uptr->hostinfo, re_hostpart.re_nsub + 1, match, 0);
if (ret != 0) {
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, NULL,
"ap_regexec() could not parse (\"%s\") as host part",
uptr->hostinfo);
return HTTP_BAD_REQUEST;
}
/* $ 12 3 4 5 6 7 */
/* "^(([^:]*)(:(.*))?@)?([^@:]*)(:([0-9]*))?$" */
/* ^^user^ :pw ^host^ ^:[port]^ */
/* empty user is valid, that's why we test $1 but use $2 */
if (match[1].rm_so != match[1].rm_eo)
uptr->user = ap_pstrndup (p, uptr->hostinfo+match[2].rm_so, match[2].rm_eo - match[2].rm_so);
/* empty password is valid, test $3 but use $4 */
if (match[3].rm_so != match[3].rm_eo)
uptr->password = ap_pstrndup (p, uptr->hostinfo+match[4].rm_so, match[4].rm_eo - match[4].rm_so);
/* empty hostname is valid, and implied by the existence of hostinfo */
uptr->hostname = ap_pstrndup (p, uptr->hostinfo+match[5].rm_so, match[5].rm_eo - match[5].rm_so);
if (match[6].rm_so != match[6].rm_eo) {
/* Note that the port string can be empty.
* If it is, we use the default port associated with the scheme
*/
uptr->port_str = ap_pstrndup (p, uptr->hostinfo+match[7].rm_so, match[7].rm_eo - match[7].rm_so);
if (uptr->port_str[0] != '\0') {
char *endstr;
int port;
port = strtol(uptr->port_str, &endstr, 10);
uptr->port = port;
if (*endstr != '\0') {
/* Invalid characters after ':' found */
return HTTP_BAD_REQUEST;
}
}
else {
uptr->port = uptr->scheme ? ap_default_port_for_scheme(uptr->scheme) : DEFAULT_HTTP_PORT;
}
}
}
if (ret == 0)
ret = HTTP_OK;
return ret;
}
#else
/* Here is the hand-optimized parse_uri_components(). There are some wild
* tricks we could pull in assembly language that we don't pull here... like we
* can do word-at-time scans for delimiter characters using the same technique
* that fast memchr()s use. But that would be way non-portable. -djg
*/
/* We have a table that we can index by character and it tells us if the
* character is one of the interesting delimiters. Note that we even get
* compares for NUL for free -- it's just another delimiter.
*/
#define T_COLON 0x01 /* ':' */
#define T_SLASH 0x02 /* '/' */
#define T_QUESTION 0x04 /* '?' */
#define T_HASH 0x08 /* '#' */
#define T_NUL 0x80 /* '\0' */
/* the uri_delims.h file is autogenerated by gen_uri_delims.c */
#include "uri_delims.h"
/* it works like this:
if (uri_delims[ch] & NOTEND_foobar) {
then we're not at a delimiter for foobar
}
*/
/* Note that we optimize the scheme scanning here, we cheat and let the
* compiler know that it doesn't have to do the & masking.
*/
#define NOTEND_SCHEME (0xff)
#define NOTEND_HOSTINFO (T_SLASH | T_QUESTION | T_HASH | T_NUL)
#define NOTEND_PATH (T_QUESTION | T_HASH | T_NUL)
void ap_util_uri_init(void)
{
/* nothing to do */
}
/* parse_uri_components():
* Parse a given URI, fill in all supplied fields of a uri_components
* structure. This eliminates the necessity of extracting host, port,
* path, query info repeatedly in the modules.
* Side effects:
* - fills in fields of uri_components *uptr
* - none on any of the r->* fields
*/
API_EXPORT(int) ap_parse_uri_components(pool *p, const char *uri, uri_components *uptr)
{
const char *s;
const char *s1;
const char *hostinfo;
char *endstr;
int port;
/* Initialize the structure. parse_uri() and parse_uri_components()
* can be called more than once per request.
*/
memset (uptr, '\0', sizeof(*uptr));
uptr->is_initialized = 1;
/* We assume the processor has a branch predictor like most --
* it assumes forward branches are untaken and backwards are taken. That's
* the reason for the gotos. -djg
*/
if (uri[0] == '/') {
deal_with_path:
/* we expect uri to point to first character of path ... remember
* that the path could be empty -- http://foobar?query for example
*/
s = uri;
while ((uri_delims[*(unsigned char *)s] & NOTEND_PATH) == 0) {
++s;
}
if (s != uri) {
uptr->path = ap_pstrndup(p, uri, s - uri);
}
if (*s == 0) {
return HTTP_OK;
}
if (*s == '?') {
++s;
s1 = strchr(s, '#');
if (s1) {
uptr->fragment = ap_pstrdup(p, s1 + 1);
uptr->query = ap_pstrndup(p, s, s1 - s);
}
else {
uptr->query = ap_pstrdup(p, s);
}
return HTTP_OK;
}
/* otherwise it's a fragment */
uptr->fragment = ap_pstrdup(p, s + 1);
return HTTP_OK;
}
/* find the scheme: */
s = uri;
while ((uri_delims[*(unsigned char *)s] & NOTEND_SCHEME) == 0) {
++s;
}
/* scheme must be non-empty and followed by :// */
if (s == uri || s[0] != ':' || s[1] != '/' || s[2] != '/') {
goto deal_with_path; /* backwards predicted taken! */
}
uptr->scheme = ap_pstrndup(p, uri, s - uri);
s += 3;
hostinfo = s;
while ((uri_delims[*(unsigned char *)s] & NOTEND_HOSTINFO) == 0) {
++s;
}
uri = s; /* whatever follows hostinfo is start of uri */
uptr->hostinfo = ap_pstrndup(p, hostinfo, uri - hostinfo);
/* If there's a username:password@host:port, the @ we want is the last @...
* too bad there's no memrchr()... For the C purists, note that hostinfo
* is definately not the first character of the original uri so therefore
* &hostinfo[-1] < &hostinfo[0] ... and this loop is valid C.
*/
do {
--s;
} while (s >= hostinfo && *s != '@');
if (s < hostinfo) {
/* again we want the common case to be fall through */
deal_with_host:
/* We expect hostinfo to point to the first character of
* the hostname. If there's a port it is the first colon.
*/
s = memchr(hostinfo, ':', uri - hostinfo);
if (s == NULL) {
/* we expect the common case to have no port */
uptr->hostname = ap_pstrndup(p, hostinfo, uri - hostinfo);
goto deal_with_path;
}
uptr->hostname = ap_pstrndup(p, hostinfo, s - hostinfo);
++s;
uptr->port_str = ap_pstrndup(p, s, uri - s);
if (uri != s) {
port = strtol(uptr->port_str, &endstr, 10);
uptr->port = port;
if (*endstr == '\0') {
goto deal_with_path;
}
/* Invalid characters after ':' found */
return HTTP_BAD_REQUEST;
}
uptr->port = ap_default_port_for_scheme(uptr->scheme);
goto deal_with_path;
}
/* first colon delimits username:password */
s1 = memchr(hostinfo, ':', s - hostinfo);
if (s1) {
uptr->user = ap_pstrndup(p, hostinfo, s1 - hostinfo);
++s1;
uptr->password = ap_pstrndup(p, s1, s - s1);
}
else {
uptr->user = ap_pstrndup(p, hostinfo, s - hostinfo);
}
hostinfo = s + 1;
goto deal_with_host;
}
/* Special case for CONNECT parsing: it comes with the hostinfo part only */
/* See the INTERNET-DRAFT document "Tunneling SSL Through a WWW Proxy"
* currently at http://www.mcom.com/newsref/std/tunneling_ssl.html
* for the format of the "CONNECT host:port HTTP/1.0" request
*/
API_EXPORT(int) ap_parse_hostinfo_components(pool *p, const char *hostinfo, uri_components *uptr)
{
const char *s;
char *endstr;
/* Initialize the structure. parse_uri() and parse_uri_components()
* can be called more than once per request.
*/
memset (uptr, '\0', sizeof(*uptr));
uptr->is_initialized = 1;
uptr->hostinfo = ap_pstrdup(p, hostinfo);
/* We expect hostinfo to point to the first character of
* the hostname. There must be a port, separated by a colon
*/
s = strchr(hostinfo, ':');
if (s == NULL) {
return HTTP_BAD_REQUEST;
}
uptr->hostname = ap_pstrndup(p, hostinfo, s - hostinfo);
++s;
uptr->port_str = ap_pstrdup(p, s);
if (*s != '\0') {
uptr->port = strtol(uptr->port_str, &endstr, 10);
if (*endstr == '\0') {
return HTTP_OK;
}
/* Invalid characters after ':' found */
}
return HTTP_BAD_REQUEST;
}
#endif

917
server/vhost.c Normal file
View File

@@ -0,0 +1,917 @@
/* ====================================================================
* Copyright (c) 1995-1999 The Apache Group. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* 4. The names "Apache Server" and "Apache Group" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Group and was originally based
* on public domain software written at the National Center for
* Supercomputing Applications, University of Illinois, Urbana-Champaign.
* For more information on the Apache Group and the Apache HTTP server
* project, please see <http://www.apache.org/>.
*
*/
/*
* http_vhost.c: functions pertaining to virtual host addresses
* (configuration and run-time)
*/
#define CORE_PRIVATE
#include "httpd.h"
#include "http_config.h"
#include "http_conf_globals.h"
#include "http_log.h"
#include "http_vhost.h"
#include "http_protocol.h"
/*
* After all the definitions there's an explanation of how it's all put
* together.
*/
/* meta-list of name-vhosts. Each server_rec can be in possibly multiple
* lists of name-vhosts.
*/
typedef struct name_chain name_chain;
struct name_chain {
name_chain *next;
server_addr_rec *sar; /* the record causing it to be in
* this chain (needed for port comparisons) */
server_rec *server; /* the server to use on a match */
};
/* meta-list of ip addresses. Each server_rec can be in possibly multiple
* hash chains since it can have multiple ips.
*/
typedef struct ipaddr_chain ipaddr_chain;
struct ipaddr_chain {
ipaddr_chain *next;
server_addr_rec *sar; /* the record causing it to be in
* this chain (need for both ip addr and port
* comparisons) */
server_rec *server; /* the server to use if this matches */
name_chain *names; /* if non-NULL then a list of name-vhosts
* sharing this address */
};
/* This defines the size of the hash table used for hashing ip addresses
* of virtual hosts. It must be a power of two.
*/
#ifndef IPHASH_TABLE_SIZE
#define IPHASH_TABLE_SIZE 256
#endif
/* A (n) bucket hash table, each entry has a pointer to a server rec and
* a pointer to the other entries in that bucket. Each individual address,
* even for virtualhosts with multiple addresses, has an entry in this hash
* table. There are extra buckets for _default_, and name-vhost entries.
*
* Note that after config time this is constant, so it is thread-safe.
*/
static ipaddr_chain *iphash_table[IPHASH_TABLE_SIZE];
/* dump out statistics about the hash function */
/* #define IPHASH_STATISTICS */
/* list of the _default_ servers */
static ipaddr_chain *default_list;
/* list of the NameVirtualHost addresses */
static server_addr_rec *name_vhost_list;
static server_addr_rec **name_vhost_list_tail;
/*
* How it's used:
*
* The ip address determines which chain in iphash_table is interesting, then
* a comparison is done down that chain to find the first ipaddr_chain whose
* sar matches the address:port pair.
*
* If that ipaddr_chain has names == NULL then you're done, it's an ip-vhost.
*
* Otherwise it's a name-vhost list, and the default is the server in the
* ipaddr_chain record. We tuck away the ipaddr_chain record in the
* conn_rec field vhost_lookup_data. Later on after the headers we get a
* second chance, and we use the name_chain to figure out what name-vhost
* matches the headers.
*
* If there was no ip address match in the iphash_table then do a lookup
* in the default_list.
*
* How it's put together ... well you should be able to figure that out
* from how it's used. Or something like that.
*/
/* called at the beginning of the config */
void ap_init_vhost_config(pool *p)
{
memset(iphash_table, 0, sizeof(iphash_table));
default_list = NULL;
name_vhost_list = NULL;
name_vhost_list_tail = &name_vhost_list;
}
/*
* Parses a host of the form <address>[:port]
* paddr is used to create a list in the order of input
* **paddr is the ->next pointer of the last entry (or s->addrs)
* *paddr is the variable used to keep track of **paddr between calls
* port is the default port to assume
*/
static const char *get_addresses(pool *p, char *w, server_addr_rec ***paddr,
unsigned port)
{
struct hostent *hep;
unsigned long my_addr;
server_addr_rec *sar;
char *t;
int i, is_an_ip_addr;
if (*w == 0)
return NULL;
t = strchr(w, ':');
if (t) {
if (strcmp(t + 1, "*") == 0) {
port = 0;
}
else if ((i = atoi(t + 1))) {
port = i;
}
else {
return ":port must be numeric";
}
*t = 0;
}
is_an_ip_addr = 0;
if (strcmp(w, "*") == 0) {
my_addr = htonl(INADDR_ANY);
is_an_ip_addr = 1;
}
else if (strcasecmp(w, "_default_") == 0
|| strcmp(w, "255.255.255.255") == 0) {
my_addr = DEFAULT_VHOST_ADDR;
is_an_ip_addr = 1;
}
else if ((my_addr = ap_inet_addr(w)) != INADDR_NONE) {
is_an_ip_addr = 1;
}
if (is_an_ip_addr) {
sar = ap_pcalloc(p, sizeof(server_addr_rec));
**paddr = sar;
*paddr = &sar->next;
sar->host_addr.s_addr = my_addr;
sar->host_port = port;
sar->virthost = ap_pstrdup(p, w);
if (t != NULL)
*t = ':';
return NULL;
}
hep = gethostbyname(w);
if ((!hep) || (hep->h_addrtype != AF_INET || !hep->h_addr_list[0])) {
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, NULL,
"Cannot resolve host name %s --- ignoring!", w);
if (t != NULL)
*t = ':';
return NULL;
}
for (i = 0; hep->h_addr_list[i]; ++i) {
sar = ap_pcalloc(p, sizeof(server_addr_rec));
**paddr = sar;
*paddr = &sar->next;
sar->host_addr = *(struct in_addr *) hep->h_addr_list[i];
sar->host_port = port;
sar->virthost = ap_pstrdup(p, w);
}
if (t != NULL)
*t = ':';
return NULL;
}
/* parse the <VirtualHost> addresses */
const char *ap_parse_vhost_addrs(pool *p, const char *hostname, server_rec *s)
{
server_addr_rec **addrs;
const char *err;
/* start the list of addreses */
addrs = &s->addrs;
while (hostname[0]) {
err = get_addresses(p, ap_getword_conf(p, &hostname), &addrs, s->port);
if (err) {
*addrs = NULL;
return err;
}
}
/* terminate the list */
*addrs = NULL;
if (s->addrs) {
if (s->addrs->host_port) {
/* override the default port which is inherited from main_server */
s->port = s->addrs->host_port;
}
}
return NULL;
}
const char *ap_set_name_virtual_host (cmd_parms *cmd, void *dummy, char *arg)
{
/* use whatever port the main server has at this point */
return get_addresses(cmd->pool, arg, &name_vhost_list_tail,
cmd->server->port);
}
/* hash table statistics, keep this in here for the beta period so
* we can find out if the hash function is ok
*/
#ifdef IPHASH_STATISTICS
static int iphash_compare(const void *a, const void *b)
{
return (*(const int *) b - *(const int *) a);
}
static void dump_iphash_statistics(server_rec *main_s)
{
unsigned count[IPHASH_TABLE_SIZE];
int i;
ipaddr_chain *src;
unsigned total;
char buf[HUGE_STRING_LEN];
char *p;
total = 0;
for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
count[i] = 0;
for (src = iphash_table[i]; src; src = src->next) {
++count[i];
if (i < IPHASH_TABLE_SIZE) {
/* don't count the slop buckets in the total */
++total;
}
}
}
qsort(count, IPHASH_TABLE_SIZE, sizeof(count[0]), iphash_compare);
p = buf + ap_snprintf(buf, sizeof(buf),
"iphash: total hashed = %u, avg chain = %u, "
"chain lengths (count x len):",
total, total / IPHASH_TABLE_SIZE);
total = 1;
for (i = 1; i < IPHASH_TABLE_SIZE; ++i) {
if (count[i - 1] != count[i]) {
p += ap_snprintf(p, sizeof(buf) - (p - buf), " %ux%u",
total, count[i - 1]);
total = 1;
}
else {
++total;
}
}
p += ap_snprintf(p, sizeof(buf) - (p - buf), " %ux%u",
total, count[IPHASH_TABLE_SIZE - 1]);
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, main_s, buf);
}
#endif
/* This hashing function is designed to get good distribution in the cases
* where the server is handling entire "networks" of servers. i.e. a
* whack of /24s. This is probably the most common configuration for
* ISPs with large virtual servers.
*
* NOTE: This function is symmetric (i.e. collapses all 4 octets
* into one), so machine byte order (big/little endianness) does not matter.
*
* Hash function provided by David Hankins.
*/
static ap_inline unsigned hash_inaddr(unsigned key)
{
key ^= (key >> 16);
return ((key >> 8) ^ key) % IPHASH_TABLE_SIZE;
}
static ipaddr_chain *new_ipaddr_chain(pool *p,
server_rec *s, server_addr_rec *sar)
{
ipaddr_chain *new;
new = ap_palloc(p, sizeof(*new));
new->names = NULL;
new->server = s;
new->sar = sar;
new->next = NULL;
return new;
}
static name_chain *new_name_chain(pool *p, server_rec *s, server_addr_rec *sar)
{
name_chain *new;
new = ap_palloc(p, sizeof(*new));
new->server = s;
new->sar = sar;
new->next = NULL;
return new;
}
static ap_inline ipaddr_chain *find_ipaddr(struct in_addr *server_ip,
unsigned port)
{
unsigned bucket;
ipaddr_chain *trav;
unsigned addr;
/* scan the hash table for an exact match first */
addr = server_ip->s_addr;
bucket = hash_inaddr(addr);
for (trav = iphash_table[bucket]; trav; trav = trav->next) {
server_addr_rec *sar = trav->sar;
if ((sar->host_addr.s_addr == addr)
&& (sar->host_port == 0 || sar->host_port == port
|| port == 0)) {
return trav;
}
}
return NULL;
}
static ipaddr_chain *find_default_server(unsigned port)
{
server_addr_rec *sar;
ipaddr_chain *trav;
for (trav = default_list; trav; trav = trav->next) {
sar = trav->sar;
if (sar->host_port == 0 || sar->host_port == port) {
/* match! */
return trav;
}
}
return NULL;
}
static void dump_vhost_config(FILE *f)
{
int i;
ipaddr_chain *ic;
name_chain *nc;
char buf[MAX_STRING_LEN];
fprintf(f, "VirtualHost configuration:\n");
for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
for (ic = iphash_table[i]; ic; ic = ic->next) {
if (ic->sar->host_port == 0) {
ap_snprintf(buf, sizeof(buf), "%pA:*", &ic->sar->host_addr);
}
else {
ap_snprintf(buf, sizeof(buf), "%pA:%u", &ic->sar->host_addr,
ic->sar->host_port);
}
if (ic->names == NULL) {
fprintf(f, "%-22s %s (%s:%u)\n", buf,
ic->server->server_hostname, ic->server->defn_name,
ic->server->defn_line_number);
continue;
}
fprintf(f, "%-22s is a NameVirtualHost\n"
"%22s default server %s (%s:%u)\n",
buf, "", ic->server->server_hostname,
ic->server->defn_name, ic->server->defn_line_number);
for (nc = ic->names; nc; nc = nc->next) {
if (nc->sar->host_port) {
fprintf(f, "%22s port %u ", "", nc->sar->host_port);
}
else {
fprintf(f, "%22s port * ", "");
}
fprintf(f, "namevhost %s (%s:%u)\n",
nc->server->server_hostname,
nc->server->defn_name,
nc->server->defn_line_number);
}
}
}
if (default_list) {
fprintf(f, "_default_ servers:\n");
for (ic = default_list; ic; ic = ic->next) {
if (ic->sar->host_port == 0) {
fprintf(f, "port * ");
}
else {
fprintf(f, "port %u ", ic->sar->host_port);
}
fprintf(f, "server %s (%s:%u)\n",
ic->server->server_hostname, ic->server->defn_name,
ic->server->defn_line_number);
}
}
}
/* compile the tables and such we need to do the run-time vhost lookups */
void ap_fini_vhost_config(pool *p, server_rec *main_s)
{
server_addr_rec *sar;
int has_default_vhost_addr;
server_rec *s;
int i;
ipaddr_chain **iphash_table_tail[IPHASH_TABLE_SIZE];
/* terminate the name_vhost list */
*name_vhost_list_tail = NULL;
/* Main host first */
s = main_s;
if (!s->server_hostname) {
s->server_hostname = ap_get_local_host(p);
}
/* initialize the tails */
for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
iphash_table_tail[i] = &iphash_table[i];
}
/* The first things to go into the hash table are the NameVirtualHosts
* Since name_vhost_list is in the same order that the directives
* occured in the config file, we'll copy it in that order.
*/
for (sar = name_vhost_list; sar; sar = sar->next) {
unsigned bucket = hash_inaddr(sar->host_addr.s_addr);
ipaddr_chain *new = new_ipaddr_chain(p, NULL, sar);
*iphash_table_tail[bucket] = new;
iphash_table_tail[bucket] = &new->next;
/* Notice that what we've done is insert an ipaddr_chain with
* both server and names NULL. Remember that.
*/
}
/* The next things to go into the hash table are the virtual hosts
* themselves. They're listed off of main_s->next in the reverse
* order they occured in the config file, so we insert them at
* the iphash_table_tail but don't advance the tail.
*/
for (s = main_s->next; s; s = s->next) {
has_default_vhost_addr = 0;
for (sar = s->addrs; sar; sar = sar->next) {
ipaddr_chain *ic;
if (sar->host_addr.s_addr == DEFAULT_VHOST_ADDR
|| sar->host_addr.s_addr == INADDR_ANY) {
/* add it to default bucket for each appropriate sar
* since we need to do a port test
*/
ipaddr_chain *other;
other = find_default_server(sar->host_port);
if (other && other->sar->host_port != 0) {
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, main_s,
"_default_ VirtualHost overlap on port %u,"
" the first has precedence", sar->host_port);
}
has_default_vhost_addr = 1;
ic = new_ipaddr_chain(p, s, sar);
ic->next = default_list;
default_list = ic;
}
else {
/* see if it matches something we've already got */
ic = find_ipaddr(&sar->host_addr, sar->host_port);
/* the first time we encounter a NameVirtualHost address
* ic->server will be NULL, on subsequent encounters
* ic->names will be non-NULL.
*/
if (ic && (ic->names || ic->server == NULL)) {
name_chain *nc = new_name_chain(p, s, sar);
nc->next = ic->names;
ic->names = nc;
ic->server = s;
if (sar->host_port != ic->sar->host_port) {
/* one of the two is a * port, the other isn't */
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, main_s,
"VirtualHost %s:%u -- mixing * "
"ports and non-* ports with "
"a NameVirtualHost address is not supported,"
" proceeding with undefined results",
sar->virthost, sar->host_port);
}
}
else if (ic) {
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, main_s,
"VirtualHost %s:%u overlaps with "
"VirtualHost %s:%u, the first has precedence, "
"perhaps you need a NameVirtualHost directive",
sar->virthost, sar->host_port,
ic->sar->virthost, ic->sar->host_port);
ic->sar = sar;
ic->server = s;
}
else {
unsigned bucket = hash_inaddr(sar->host_addr.s_addr);
ic = new_ipaddr_chain(p, s, sar);
ic->next = *iphash_table_tail[bucket];
*iphash_table_tail[bucket] = ic;
}
}
}
/* Ok now we want to set up a server_hostname if the user was
* silly enough to forget one.
* XXX: This is silly we should just crash and burn.
*/
if (!s->server_hostname) {
if (has_default_vhost_addr) {
s->server_hostname = main_s->server_hostname;
}
else if (!s->addrs) {
/* what else can we do? at this point this vhost has
no configured name, probably because they used
DNS in the VirtualHost statement. It's disabled
anyhow by the host matching code. -djg */
s->server_hostname =
ap_pstrdup(p, "bogus_host_without_forward_dns");
}
else {
struct hostent *h;
if ((h = gethostbyaddr((char *) &(s->addrs->host_addr),
sizeof(struct in_addr), AF_INET))) {
s->server_hostname = ap_pstrdup(p, (char *) h->h_name);
}
else {
/* again, what can we do? They didn't specify a
ServerName, and their DNS isn't working. -djg */
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, main_s,
"Failed to resolve server name "
"for %s (check DNS) -- or specify an explicit "
"ServerName",
inet_ntoa(s->addrs->host_addr));
s->server_hostname =
ap_pstrdup(p, "bogus_host_without_reverse_dns");
}
}
}
}
/* now go through and delete any NameVirtualHosts that didn't have any
* hosts associated with them. Lamers.
*/
for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
ipaddr_chain **pic = &iphash_table[i];
while (*pic) {
ipaddr_chain *ic = *pic;
if (ic->server == NULL) {
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, main_s,
"NameVirtualHost %s:%u has no VirtualHosts",
ic->sar->virthost, ic->sar->host_port);
*pic = ic->next;
}
else if (ic->names == NULL) {
/* if server != NULL and names == NULL then we're done
* looking at NameVirtualHosts
*/
break;
}
else {
pic = &ic->next;
}
}
}
#ifdef IPHASH_STATISTICS
dump_iphash_statistics(main_s);
#endif
if (ap_dump_settings) {
dump_vhost_config(stderr);
}
}
/*****************************************************************************
* run-time vhost matching functions
*/
/* Remove :port and optionally a single trailing . from the hostname, this
* canonicalizes it somewhat.
*/
static void fix_hostname(request_rec *r)
{
const char *hostname = r->hostname;
char *host = ap_getword(r->pool, &hostname, ':'); /* get rid of port */
size_t l;
/* trim a trailing . */
l = strlen(host);
if (l > 0 && host[l-1] == '.') {
host[l-1] = '\0';
}
r->hostname = host;
}
/* return 1 if host matches ServerName or ServerAliases */
static int matches_aliases(server_rec *s, const char *host)
{
int i;
array_header *names;
/* match ServerName */
if (!strcasecmp(host, s->server_hostname)) {
return 1;
}
/* search all the aliases from ServerAlias directive */
names = s->names;
if (names) {
char **name = (char **) names->elts;
for (i = 0; i < names->nelts; ++i) {
if(!name[i]) continue;
if (!strcasecmp(host, name[i]))
return 1;
}
}
names = s->wild_names;
if (names) {
char **name = (char **) names->elts;
for (i = 0; i < names->nelts; ++i) {
if(!name[i]) continue;
if (!ap_strcasecmp_match(host, name[i]))
return 1;
}
}
return 0;
}
/* Suppose a request came in on the same socket as this r, and included
* a header "Host: host:port", would it map to r->server? It's more
* than just that though. When we do the normal matches for each request
* we don't even bother considering Host: etc on non-namevirtualhosts,
* we just call it a match. But here we require the host:port to match
* the ServerName and/or ServerAliases.
*/
API_EXPORT(int) ap_matches_request_vhost(request_rec *r, const char *host,
unsigned port)
{
server_rec *s;
server_addr_rec *sar;
s = r->server;
/* search all the <VirtualHost> values */
/* XXX: If this is a NameVirtualHost then we may not be doing the Right Thing
* consider:
*
* NameVirtualHost 10.1.1.1
* <VirtualHost 10.1.1.1>
* ServerName v1
* </VirtualHost>
* <VirtualHost 10.1.1.1>
* ServerName v2
* </VirtualHost>
*
* Suppose r->server is v2, and we're asked to match "10.1.1.1". We'll say
* "yup it's v2", when really it isn't... if a request came in for 10.1.1.1
* it would really go to v1.
*/
for (sar = s->addrs; sar; sar = sar->next) {
if ((sar->host_port == 0 || port == sar->host_port)
&& !strcasecmp(host, sar->virthost)) {
return 1;
}
}
/* the Port has to match now, because the rest don't have ports associated
* with them. */
if (port != s->port) {
return 0;
}
return matches_aliases(s, host);
}
static void check_hostalias(request_rec *r)
{
/*
* Even if the request has a Host: header containing a port we ignore
* that port. We always use the physical port of the socket. There
* are a few reasons for this:
*
* - the default of 80 or 443 for SSL is easier to handle this way
* - there is less of a possibility of a security problem
* - it simplifies the data structure
* - the client may have no idea that a proxy somewhere along the way
* translated the request to another ip:port
* - except for the addresses from the VirtualHost line, none of the other
* names we'll match have ports associated with them
*/
const char *host = r->hostname;
unsigned port = ntohs(r->connection->local_addr.sin_port);
server_rec *s;
server_rec *last_s;
name_chain *src;
last_s = NULL;
/* Recall that the name_chain is a list of server_addr_recs, some of
* whose ports may not match. Also each server may appear more than
* once in the chain -- specifically, it will appear once for each
* address from its VirtualHost line which matched. We only want to
* do the full ServerName/ServerAlias comparisons once for each
* server, fortunately we know that all the VirtualHost addresses for
* a single server are adjacent to each other.
*/
for (src = r->connection->vhost_lookup_data; src; src = src->next) {
server_addr_rec *sar;
/* We only consider addresses on the name_chain which have a matching
* port
*/
sar = src->sar;
if (sar->host_port != 0 && port != sar->host_port) {
continue;
}
s = src->server;
/* does it match the virthost from the sar? */
if (!strcasecmp(host, sar->virthost)) {
goto found;
}
if (s == last_s) {
/* we've already done ServerName and ServerAlias checks for this
* vhost
*/
continue;
}
last_s = s;
if (matches_aliases(s, host)) {
goto found;
}
}
return;
found:
/* s is the first matching server, we're done */
r->server = r->connection->server = s;
}
static void check_serverpath(request_rec *r)
{
server_rec *s;
server_rec *last_s;
name_chain *src;
unsigned port = ntohs(r->connection->local_addr.sin_port);
/*
* This is in conjunction with the ServerPath code in http_core, so we
* get the right host attached to a non- Host-sending request.
*
* See the comment in check_hostalias about how each vhost can be
* listed multiple times.
*/
last_s = NULL;
for (src = r->connection->vhost_lookup_data; src; src = src->next) {
/* We only consider addresses on the name_chain which have a matching
* port
*/
if (src->sar->host_port != 0 && port != src->sar->host_port) {
continue;
}
s = src->server;
if (s == last_s) {
continue;
}
last_s = s;
if (s->path && !strncmp(r->uri, s->path, s->pathlen) &&
(s->path[s->pathlen - 1] == '/' ||
r->uri[s->pathlen] == '/' ||
r->uri[s->pathlen] == '\0')) {
r->server = r->connection->server = s;
return;
}
}
}
void ap_update_vhost_from_headers(request_rec *r)
{
/* must set this for HTTP/1.1 support */
if (r->hostname || (r->hostname = ap_table_get(r->headers_in, "Host"))) {
fix_hostname(r);
}
/* check if we tucked away a name_chain */
if (r->connection->vhost_lookup_data) {
if (r->hostname)
check_hostalias(r);
else
check_serverpath(r);
}
}
/* Called for a new connection which has a known local_addr. Note that the
* new connection is assumed to have conn->server == main server.
*/
void ap_update_vhost_given_ip(conn_rec *conn)
{
ipaddr_chain *trav;
unsigned port = ntohs(conn->local_addr.sin_port);
/* scan the hash table for an exact match first */
trav = find_ipaddr(&conn->local_addr.sin_addr, port);
if (trav) {
/* save the name_chain for later in case this is a name-vhost */
conn->vhost_lookup_data = trav->names;
conn->server = trav->server;
return;
}
/* There's certainly no name-vhosts with this address, they would have
* been matched above.
*/
conn->vhost_lookup_data = NULL;
/* maybe there's a default server matching this port */
trav = find_default_server(port);
if (trav) {
conn->server = trav->server;
}
/* otherwise we're stuck with just the main server */
}

1
srclib/.cvsignore Normal file
View File

@@ -0,0 +1 @@
Makefile

11
support/.cvsignore Normal file
View File

@@ -0,0 +1,11 @@
Makefile
rotatelogs
htpasswd
htdigest
unescape
inc2shtml
httpd_monitor
suexec
logresolve
ab
apxs

54
support/.indent.pro vendored Normal file
View File

@@ -0,0 +1,54 @@
-i4 -npsl -di0 -br -nce -d0 -cli0 -npcs -nfc1
-TBUFF
-TFILE
-TTRANS
-TUINT4
-T_trans
-Tallow_options_t
-Tapache_sfio
-Tarray_header
-Tbool_int
-Tbuf_area
-Tbuff_struct
-Tbuffy
-Tcmd_how
-Tcmd_parms
-Tcommand_rec
-Tcommand_struct
-Tconn_rec
-Tcore_dir_config
-Tcore_server_config
-Tdir_maker_func
-Tevent
-Tglobals_s
-Thandler_func
-Thandler_rec
-Tjoblist_s
-Tlisten_rec
-Tmerger_func
-Tmode_t
-Tmodule
-Tmodule_struct
-Tmutex
-Tn_long
-Tother_child_rec
-Toverrides_t
-Tparent_score
-Tpid_t
-Tpiped_log
-Tpool
-Trequest_rec
-Trequire_line
-Trlim_t
-Tscoreboard
-Tsemaphore
-Tserver_addr_rec
-Tserver_rec
-Tserver_rec_chain
-Tshort_score
-Ttable
-Ttable_entry
-Tthread
-Tu_wide_int
-Tvtime_t
-Twide_int

62
support/README Normal file
View File

@@ -0,0 +1,62 @@
Support files:
ab
ABuse your server with this benchmarker. Rudimentary
command line testing tool.
apachectl
Apache run-time Control script. To facilitate the
administrator and/or your rc.d scripts to control the
functioning of the Apache httpd daemon.
apxs
APache eXtenSion tool. Eases building and installing
DSO style modules.
dbmmanage
Create and update user authentication files in the faster
DBM format used by mod_auth_db.
htdigest
Create and update user authentication files used in
DIGEST authentification. See mod_auth_digest.
htpasswd
Create and update user authentication files used in
BASIC authentification. I.e. the htpasswd files.
See mod_auth.
httpd.8
General apache man page.
log_server_status
This script is designed to be run at a frequent interval by something
like cron. It connects to the server and downloads the status
information. It reformats the information to a single line and logs
it to a file.
logresolve
resolve hostnames for IP-adresses in Apache logfiles
phf_abuse_log.cgi
This script can be used to detect people trying to abuse an ancient
and long plugged security hole which existed in a CGI script distributed
with Apache 1.0.3 and earlier versions.
rotatelogs
rotate Apache logs without having to kill the server.
split-logfile
This script will take a combined virtual hosts access
log file and break its contents into separate files.
suexec
Switch User For Exec. Used internally by apache,
see the document `Apache suEXEC Support'
under http://www.apache.org/docs/suexec.html .
SHA1
This directory includes some utilities to allow Apache 1.3.6 to
recognize passwords in SHA1 format, as used by Netscape web
servers. It is not installed by default.

34
support/SHA1/README.sha1 Normal file
View File

@@ -0,0 +1,34 @@
This directory includes some utilities to allow Apache 1.3.6 to
recognize passwords in SHA1 format, as used by Netscape web servers.
From Netscape's admin interface, export the password database to an
ldif file and then use convert.pl in this distribution to generate
apache style password files.
Note: SHA1 support is useful for migration purposes, but is less
secure than Apache's password format, since Apache's (MD5)
password format uses a random eight character salt to generate
one of many possible hashes for the same password. Netscape
uses plain SHA1 without a salt, so the same password
will always generate the same hash, making it easier
to break since the search space is smaller.
This code was contributed by Clinton Wong <clintdw@netcom.com>.
README.sha1
this file
convert-sha1.pl
takes an ldif dump from Netscape's web server on
standard in, outputs apache htpasswd format on standard out.
Usage: convert.pl < ldif > passwords
htpasswd-sha1.pl
perl script to generate entries in apache htpasswd format.
Usage: htpasswd-sha1.pl some_user some_password
ldif-sha1.example
sample ldif dump with one sha1 password and one crypt password.

View File

@@ -0,0 +1,36 @@
#!/usr/bin/perl -w
use strict;
# This is public domain code. Do whatever you want with it.
# It was originally included in Clinton Wong's Apache 1.3.6 SHA1/ldif
# patch distribution as sample code for converting accounts from
# ldif format (as used by Netscape web servers) to Apache password format.
my $uid='';
my $passwd='';
while (my $line = <>) {
chomp $line;
if ( $line =~ /uid:\s*(.+)/) { $uid = $1 }
if ( $line =~ /userpassword:\s*(\{\w+\}.+)/) {
$passwd = $1;
$passwd =~ s/^\{crypt\}//i; # Apache stores crypt without a magic string
}
if (length($line)==0) {
if (length $uid and length $passwd) {
print $uid, ':', $passwd, "\n";
} # output if we have something to print
$uid = '';
$passwd = '';
} # if newline
} # while something to read
# handle last entry if there isn't a newline before EOF
if (length $uid and length $passwd) {
print $uid, ':', $passwd, "\n";
}

View File

@@ -0,0 +1,22 @@
#!/usr/bin/perl -w
use strict;
#
# Utility which takes a username and password
# on the command line and generates a username
# sha1-encrytped password on the stdout.
#
# Typical useage:
# ./htpasswd-sha1.pl dirkx MySecret >> sha1-passwd
#
# This is public domain code. Do whatever you want with it.
# It was originally included in Clinton Wong's Apache 1.3.6 SHA1/ldif
# patch distribution as sample code for generating entries for
# Apache password files using SHA1.
use MIME::Base64; # http://www.cpan.org/modules/by-module/MIME/
use Digest::SHA1; # http://www.cpan.org/modules/by-module/MD5/
if ($#ARGV!=1) { die "Usage $0: user password\n" }
print $ARGV[0], ':{SHA}', encode_base64( Digest::SHA1::sha1($ARGV[1]) );

View File

@@ -0,0 +1,19 @@
dn: cn=someuser
cn: someuser
sn: someuser
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
uid: someuser
userpassword: {SHA}GvF+c3IdvgxAARuC7Uuxp9vjzik=
dn: cn=anotheruser
cn: anotheruser
sn: anotheruser
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
uid: anotheruser
userpassword: {crypt}eFnp.4sz5XnH6

1100
support/ab.c Normal file

File diff suppressed because it is too large Load Diff

655
support/apxs.in Normal file
View File

@@ -0,0 +1,655 @@
#!/usr/local/bin/perl
## ====================================================================
## Copyright (c) 1998-1999 The Apache Group. All rights reserved.
##
## Redistribution and use in source and binary forms, with or without
## modification, are permitted provided that the following conditions
## are met:
##
## 1. Redistributions of source code must retain the above copyright
## notice, this list of conditions and the following disclaimer.
##
## 2. Redistributions in binary form must reproduce the above copyright
## notice, this list of conditions and the following disclaimer in
## the documentation and/or other materials provided with the
## distribution.
##
## 3. All advertising materials mentioning features or use of this
## software must display the following acknowledgment:
## "This product includes software developed by the Apache Group
## for use in the Apache HTTP server project (http://www.apache.org/)."
##
## 4. The names "Apache Server" and "Apache Group" must not be used to
## endorse or promote products derived from this software without
## prior written permission. For written permission, please contact
## apache@apache.org.
##
## 5. Products derived from this software may not be called "Apache"
## nor may "Apache" appear in their names without prior written
## permission of the Apache Group.
##
## 6. Redistributions of any form whatsoever must retain the following
## acknowledgment:
## "This product includes software developed by the Apache Group
## for use in the Apache HTTP server project (http://www.apache.org/)."
##
## THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
## EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
## ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
## NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
## LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
## HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
## STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
## OF THE POSSIBILITY OF SUCH DAMAGE.
## ====================================================================
##
## This software consists of voluntary contributions made by many
## individuals on behalf of the Apache Group and was originally based
## on public domain software written at the National Center for
## Supercomputing Applications, University of Illinois, Urbana-Champaign.
## For more information on the Apache Group and the Apache HTTP server
## project, please see <http://www.apache.org/>.
##
##
## apxs -- APache eXtenSion tool
## Written by Ralf S. Engelschall <rse@apache.org>
##
require 5.003;
use strict;
package apxs;
##
## Configuration
##
my $CFG_TARGET = '@TARGET@'; # substituted via Makefile.tmpl
my $CFG_CC = '@CC@'; # substituted via Makefile.tmpl
my $CFG_CFLAGS = '@CFLAGS@'; # substituted via Makefile.tmpl
my $CFG_CFLAGS_SHLIB = '@CFLAGS_SHLIB@'; # substituted via Makefile.tmpl
my $CFG_LD_SHLIB = '@LD_SHLIB@'; # substituted via Makefile.tmpl
my $CFG_LDFLAGS_SHLIB = '@LDFLAGS_MOD_SHLIB@'; # substituted via Makefile.tmpl
my $CFG_LIBS_SHLIB = '@LIBS_SHLIB@'; # substituted via Makefile.tmpl
my $CFG_PREFIX = '@prefix@'; # substituted via APACI install
my $CFG_SBINDIR = '@sbindir@'; # substituted via APACI install
my $CFG_INCLUDEDIR = '@includedir@'; # substituted via APACI install
my $CFG_LIBEXECDIR = '@libexecdir@'; # substituted via APACI install
my $CFG_SYSCONFDIR = '@sysconfdir@'; # substituted via APACI install
##
## Cleanup the above stuff
##
$CFG_CFLAGS =~ s|^\s+||;
$CFG_CFLAGS =~ s|\s+$||;
$CFG_CFLAGS =~ s|\s+`.+apaci`||;
##
## Initial shared object support check
##
if (not -x "$CFG_SBINDIR/$CFG_TARGET") {
print STDERR "apxs:Error: $CFG_SBINDIR/$CFG_TARGET not found or not executable\n";
exit(1);
}
if (not grep(/mod_so/, `$CFG_SBINDIR/$CFG_TARGET -l`)) {
print STDERR "apxs:Error: Sorry, no shared object support for Apache\n";
print STDERR "apxs:Error: available under your platform. Make sure\n";
print STDERR "apxs:Error: the Apache module mod_so is compiled into\n";
print STDERR "apxs:Error: your server binary `$CFG_SBINDIR/$CFG_TARGET'.\n";
exit(1);
}
##
## parse argument line
##
# defaults for parameters
my $opt_n = '';
my $opt_g = '';
my $opt_c = 0;
my $opt_o = '';
my @opt_D = ();
my @opt_I = ();
my @opt_L = ();
my @opt_l = ();
my @opt_W = ();
my @opt_S = ();
my $opt_e = 0;
my $opt_i = 0;
my $opt_a = 0;
my $opt_A = 0;
my $opt_q = 0;
# this subroutine is derived from Perl's getopts.pl with the enhancement of
# the "+" metacharater at the format string to allow a list to be build by
# subsequent occurance of the same option.
sub Getopts {
my ($argumentative, @ARGV) = @_;
my (@args, $first, $rest, $pos);
my ($errs) = 0;
local ($_);
local ($[) = 0;
@args = split( / */, $argumentative);
while(@ARGV && ($_ = $ARGV[0]) =~ /^-(.)(.*)/) {
($first, $rest) = ($1,$2);
if ($_ =~ m|^--$|) {
shift(@ARGV);
last;
}
$pos = index($argumentative,$first);
if($pos >= $[) {
if($args[$pos+1] eq ':') {
shift(@ARGV);
if($rest eq '') {
unless (@ARGV) {
print STDERR "apxs:Error: Incomplete option: $first (needs an argument)\n";
++$errs;
}
$rest = shift(@ARGV);
}
eval "\$opt_$first = \$rest;";
}
elsif ($args[$pos+1] eq '+') {
shift(@ARGV);
if($rest eq '') {
unless (@ARGV) {
print STDERR "apxs:Error: Incomplete option: $first (needs an argument)\n";
++$errs;
}
$rest = shift(@ARGV);
}
eval "push(\@opt_$first, \$rest);";
}
else {
eval "\$opt_$first = 1";
if($rest eq '') {
shift(@ARGV);
}
else {
$ARGV[0] = "-$rest";
}
}
}
else {
print STDERR "apxs:Error: Unknown option: $first\n";
++$errs;
if($rest ne '') {
$ARGV[0] = "-$rest";
}
else {
shift(@ARGV);
}
}
}
return ($errs == 0, @ARGV);
}
sub usage {
print STDERR "Usage: apxs -g [-S <var>=<val>] -n <modname>\n";
print STDERR " apxs -q [-S <var>=<val>] <query> ...\n";
print STDERR " apxs -c [-S <var>=<val>] [-o <dsofile>] [-D <name>[=<value>]]\n";
print STDERR " [-I <incdir>] [-L <libdir>] [-l <libname>] [-Wc,<flags>]\n";
print STDERR " [-Wl,<flags>] <files> ...\n";
print STDERR " apxs -i [-S <var>=<val>] [-a] [-A] [-n <modname>] <dsofile> ...\n";
print STDERR " apxs -e [-S <var>=<val>] [-a] [-A] [-n <modname>] <dsofile> ...\n";
exit(1);
}
# option handling
my $rc;
($rc, @ARGV) = &Getopts("qn:gco:I+D+L+l+W+S+eiaA", @ARGV);
&usage if ($rc == 0);
&usage if ($#ARGV == -1 and not $opt_g);
&usage if (not $opt_q and not ($opt_g and $opt_n) and not $opt_i and not $opt_c and not $opt_e);
# argument handling
my @args = @ARGV;
my $name = 'unknown';
$name = $opt_n if ($opt_n ne '');
if (@opt_S) {
my ($opt_S);
foreach $opt_S (@opt_S) {
if ($opt_S =~ m/^([^=]+)=(.*)$/) {
my ($var) = $1;
my ($val) = $2;
my $oldval = eval "\$CFG_$var";
unless ($var and $oldval) {
print STDERR "apxs:Error: no config variable $var\n";
&usage;
}
eval "\$CFG_${var}=\"${val}\"";
} else {
print STDERR "apxs:Error: malformatted -S option\n";
&usage;
}
}
}
##
## Operation
##
# helper function for executing a list of
# system command with return code checks
sub execute_cmds {
my (@cmds) = @_;
my ($cmd, $rc);
foreach $cmd (@cmds) {
print STDERR "$cmd\n";
$rc = system("$cmd");
if ($rc != 0) {
printf(STDERR "apxs:Break: Command failed with rc=%d\n", $rc << 8);
exit(1);
}
}
}
if ($opt_g) {
##
## SAMPLE MODULE SOURCE GENERATION
##
if (-d $name) {
print STDERR "apxs:Error: Directory `$name' already exists. Remove first\n";
exit(1);
}
my $data = join('', <DATA>);
$data =~ s|%NAME%|$name|sg;
$data =~ s|%TARGET%|$CFG_TARGET|sg;
my ($mkf, $src) = ($data =~ m|^(.+)-=#=-\n(.+)|s);
print STDERR "Creating [DIR] $name\n";
system("mkdir $name");
print STDERR "Creating [FILE] $name/Makefile\n";
open(FP, ">${name}/Makefile") || die;
print FP $mkf;
close(FP);
print STDERR "Creating [FILE] $name/mod_$name.c\n";
open(FP, ">${name}/mod_${name}.c") || die;
print FP $src;
close(FP);
exit(0);
}
if ($opt_q) {
##
## QUERY INFORMATION
##
my $result = '';
my $arg;
foreach $arg (@args) {
my $ok = 0;
my $name;
foreach $name (qw(
TARGET CC CFLAGS CFLAGS_SHLIB LD_SHLIB LDFLAGS_SHLIB LIBS_SHLIB
PREFIX SBINDIR INCLUDEDIR LIBEXECDIR SYSCONFDIR
)) {
if ($arg eq $name or $arg eq lc($name)) {
my $val = eval "\$CFG_$name";
$result .= "${val}::";
$ok = 1;
}
}
if (not $ok) {
printf(STDERR "apxs:Error: Invalid query string `%s'\n", $arg);
exit(1);
}
}
$result =~ s|::$||;
$result =~ s|::| |;
print $result;
}
if ($opt_c) {
##
## SHARED OBJECT COMPILATION
##
# split files into sources and objects
my @srcs = ();
my @objs = ();
my $f;
foreach $f (@args) {
if ($f =~ m|\.c$|) {
push(@srcs, $f);
}
else {
push(@objs, $f);
}
}
# determine output file
my $dso_file;
if ($opt_o eq '') {
if ($#srcs > -1) {
$dso_file = $srcs[0];
$dso_file =~ s|\.[^.]+$|.so|;
}
elsif ($#objs > -1) {
$dso_file = $objs[0];
$dso_file =~ s|\.[^.]+$|.so|;
}
else {
$dso_file = "mod_unknown.so";
}
}
else {
$dso_file = $opt_o;
}
# create compilation commands
my @cmds = ();
my $opt = '';
my ($opt_Wc, $opt_I, $opt_D);
foreach $opt_Wc (@opt_W) {
$opt .= "$1 " if ($opt_Wc =~ m|^\s*c,(.*)$|);
}
foreach $opt_I (@opt_I) {
$opt .= "-I$opt_I ";
}
foreach $opt_D (@opt_D) {
$opt .= "-D$opt_D ";
}
my $cflags = "$CFG_CFLAGS $CFG_CFLAGS_SHLIB";
my $s;
foreach $s (@srcs) {
my $o = $s;
$o =~ s|\.c$|.o|;
push(@cmds, "$CFG_CC $cflags -I$CFG_INCLUDEDIR $opt -c $s");
unshift(@objs, $o);
}
# create link command
my $cmd = "$CFG_LD_SHLIB $CFG_LDFLAGS_SHLIB -o $dso_file";
my $o;
foreach $o (@objs) {
$cmd .= " $o";
}
$opt = '';
my ($opt_Wl, $opt_L, $opt_l);
foreach $opt_Wl (@opt_W) {
if($CFG_LD_SHLIB ne "gcc") {
$opt .= " $1" if ($opt_Wl =~ m|^\s*l,(.*)$|);
} else {
$opt .= " -W$opt_Wl";
}
}
foreach $opt_L (@opt_L) {
$opt .= " -L$opt_L";
}
foreach $opt_l (@opt_l) {
$opt .= " -l$opt_l";
}
$cmd .= $opt;
$cmd .= " $CFG_LIBS_SHLIB";
push(@cmds, $cmd);
# execute the commands
&execute_cmds(@cmds);
# allow one-step compilation and installation
if ($opt_i or $opt_e) {
@args = ( $dso_file );
}
}
if ($opt_i or $opt_e) {
##
## SHARED OBJECT INSTALLATION
##
# determine installation commands
# and corresponding LoadModule/AddModule directives
my @lmd = ();
my @amd = ();
my @cmds = ();
my $f;
foreach $f (@args) {
if ($f !~ m|\.so$|) {
print STDERR "apxs:Error: file $f is not a shared object\n";
exit(1);
}
my $t = $f;
$t =~ s|^.+/([^/]+)$|$1|;
if ($opt_i) {
push(@cmds, "cp $f $CFG_LIBEXECDIR/$t");
push(@cmds, "chmod 755 $CFG_LIBEXECDIR/$t");
}
# determine module symbolname and filename
my $filename = '';
if ($name eq 'unknown') {
$name = '';
my $base = $f;
$base =~ s|\.[^.]+$||;
if (-f "$base.c") {
open(FP, "<$base.c");
my $content = join('', <FP>);
close(FP);
if ($content =~ m|.*module\s+(?:MODULE_VAR_EXPORT\s+)?([a-zA-Z0-9_]+)_module\s*=\s*.*|s) {
$name = "$1";
$filename = "$base.c";
$filename =~ s|^[^/]+/||;
}
}
if ($name eq '') {
if ($base =~ m|.*mod_([a-zA-Z0-9_]+)\..+|) {
$name = "$1";
$filename = $base;
$filename =~ s|^[^/]+/||;
}
}
if ($name eq '') {
print "apxs:Error: Sorry, cannot determine bootstrap symbol name\n";
print "apxs:Error: Please specify one with option `-n'\n";
exit(1);
}
}
if ($filename eq '') {
$filename = "mod_${name}.c";
}
my $dir = $CFG_LIBEXECDIR;
$dir =~ s|^$CFG_PREFIX/?||;
$dir =~ s|(.)$|$1/|;
push(@lmd, sprintf("LoadModule %-18s %s", "${name}_module", "$dir$t"));
push(@amd, sprintf("AddModule %s", $filename));
}
# execute the commands
&execute_cmds(@cmds);
# activate module via LoadModule/AddModule directive
if ($opt_a or $opt_A) {
if (not -f "$CFG_SYSCONFDIR/$CFG_TARGET.conf") {
print "apxs:Error: Config file $CFG_SYSCONFDIR/$CFG_TARGET.conf not found\n";
exit(1);
}
open(FP, "<$CFG_SYSCONFDIR/$CFG_TARGET.conf") || die;
my $content = join('', <FP>);
close(FP);
if ($content !~ m|\n#?\s*LoadModule\s+|) {
print STDERR "apxs:Error: Activation failed for custom $CFG_SYSCONFDIR/$CFG_TARGET.conf file.\n";
print STDERR "apxs:Error: At least one `LoadModule' directive already has to exist.\n";
exit(1);
}
my $lmd;
my $c = '';
$c = '#' if ($opt_A);
foreach $lmd (@lmd) {
my $what = $opt_A ? "preparing" : "activating";
if ($content !~ m|\n#?\s*$lmd|) {
$content =~ s|^(.*\n#?\s*LoadModule\s+[^\n]+\n)|$1$c$lmd\n|sg;
} else {
$content =~ s|^(.*\n)#?\s*$lmd[^\n]*\n|$1$c$lmd\n|sg;
}
$lmd =~ m|LoadModule\s+(.+?)_module.*|;
print STDERR "[$what module `$1' in $CFG_SYSCONFDIR/$CFG_TARGET.conf]\n";
}
my $amd;
foreach $amd (@amd) {
if ($content !~ m|\n#?\s*$amd|) {
$content =~ s|^(.*\n#?\s*AddModule\s+[^\n]+\n)|$1$c$amd\n|sg;
} else {
$content =~ s|^(.*\n)#?\s*$amd[^\n]*\n|$1$c$amd\n|sg;
}
}
if (@lmd or @amd) {
open(FP, ">$CFG_SYSCONFDIR/$CFG_TARGET.conf.new") || die;
print FP $content;
close(FP);
system("cp $CFG_SYSCONFDIR/$CFG_TARGET.conf $CFG_SYSCONFDIR/$CFG_TARGET.conf.bak && " .
"cp $CFG_SYSCONFDIR/$CFG_TARGET.conf.new $CFG_SYSCONFDIR/$CFG_TARGET.conf && " .
"rm $CFG_SYSCONFDIR/$CFG_TARGET.conf.new");
}
}
}
##EOF##
__DATA__
##
## Makefile -- Build procedure for sample %NAME% Apache module
## Autogenerated via ``apxs -n %NAME% -g''.
##
# the used tools
APXS=apxs
APACHECTL=apachectl
# additional defines, includes and libraries
#DEF=-Dmy_define=my_value
#INC=-Imy/include/dir
#LIB=-Lmy/lib/dir -lmylib
# the default target
all: mod_%NAME%.so
# compile the shared object file
mod_%NAME%.so: mod_%NAME%.c
$(APXS) -c $(DEF) $(INC) $(LIB) mod_%NAME%.c
# install the shared object file into Apache
install: all
$(APXS) -i -a -n '%NAME%' mod_%NAME%.so
# cleanup
clean:
-rm -f mod_%NAME%.o mod_%NAME%.so
# simple test
test: reload
lynx -mime_header http://localhost/%NAME%
# install and activate shared object by reloading Apache to
# force a reload of the shared object file
reload: install restart
# the general Apache start/restart/stop
# procedures
start:
$(APACHECTL) start
restart:
$(APACHECTL) restart
stop:
$(APACHECTL) stop
-=#=-
/*
** mod_%NAME%.c -- Apache sample %NAME% module
** [Autogenerated via ``apxs -n %NAME% -g'']
**
** To play with this sample module first compile it into a
** DSO file and install it into Apache's libexec directory
** by running:
**
** $ apxs -c -i mod_%NAME%.c
**
** Then activate it in Apache's %TARGET%.conf file for instance
** for the URL /%NAME% in as follows:
**
** # %TARGET%.conf
** LoadModule %NAME%_module libexec/mod_%NAME%.so
** <Location /%NAME%>
** SetHandler %NAME%
** </Location>
**
** Then after restarting Apache via
**
** $ apachectl restart
**
** you immediately can request the URL /%NAME and watch for the
** output of this module. This can be achieved for instance via:
**
** $ lynx -mime_header http://localhost/%NAME%
**
** The output should be similar to the following one:
**
** HTTP/1.1 200 OK
** Date: Tue, 31 Mar 1998 14:42:22 GMT
** Server: Apache/1.3.4 (Unix)
** Connection: close
** Content-Type: text/html
**
** The sample page from mod_%NAME%.c
*/
#include "httpd.h"
#include "http_config.h"
#include "http_protocol.h"
#include "ap_config.h"
/* The sample content handler */
static int %NAME%_handler(request_rec *r)
{
r->content_type = "text/html";
ap_send_http_header(r);
if (!r->header_only)
ap_rputs("The sample page from mod_%NAME%.c\n", r);
return OK;
}
/* Dispatch list of content handlers */
static const handler_rec %NAME%_handlers[] = {
{ "%NAME%", %NAME%_handler },
{ NULL, NULL }
};
/* Dispatch list for API hooks */
module MODULE_VAR_EXPORT %NAME%_module = {
STANDARD_MODULE_STUFF,
NULL, /* module initializer */
NULL, /* create per-dir config structures */
NULL, /* merge per-dir config structures */
NULL, /* create per-server config structures */
NULL, /* merge per-server config structures */
NULL, /* table of config file commands */
%NAME%_handlers, /* [#8] MIME-typed-dispatched handlers */
NULL, /* [#1] URI to filename translation */
NULL, /* [#4] validate user id from request */
NULL, /* [#5] check if the user is ok _here_ */
NULL, /* [#3] check access by host address */
NULL, /* [#6] determine MIME type */
NULL, /* [#7] pre-run fixups */
NULL, /* [#9] log a transaction */
NULL, /* [#2] header parser */
NULL, /* child_init */
NULL, /* child_exit */
NULL /* [#0] post read-request */
};

189
support/dbmmanage Normal file
View File

@@ -0,0 +1,189 @@
#!/usr/local/bin/perl
# ====================================================================
# Copyright (c) 1995-1999 The Apache Group. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. All advertising materials mentioning features or use of this
# software must display the following acknowledgment:
# "This product includes software developed by the Apache Group
# for use in the Apache HTTP server project (http://www.apache.org/)."
#
# 4. The names "Apache Server" and "Apache Group" must not be used to
# endorse or promote products derived from this software without
# prior written permission. For written permission, please contact
# apache@apache.org.
#
# 5. Products derived from this software may not be called "Apache"
# nor may "Apache" appear in their names without prior written
# permission of the Apache Group.
#
# 6. Redistributions of any form whatsoever must retain the following
# acknowledgment:
# "This product includes software developed by the Apache Group
# for use in the Apache HTTP server project (http://www.apache.org/)."
#
# THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
# ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
# OF THE POSSIBILITY OF SUCH DAMAGE.
# ====================================================================
#
# This software consists of voluntary contributions made by many
# individuals on behalf of the Apache Group and was originally based
# on public domain software written at the National Center for
# Supercomputing Applications, University of Illinois, Urbana-Champaign.
# For more information on the Apache Group and the Apache HTTP server
# project, please see <http://www.apache.org/>.
#for more functionality see the HTTPD::UserAdmin module:
# http://www.perl.com/CPAN/modules/by-module/HTTPD/HTTPD-Tools-x.xx.tar.gz
#
# usage: dbmmanage <DBMfile> <command> <key> <value>
package dbmmanage;
# -ldb -lndbm -lgdbm
BEGIN { @AnyDBM_File::ISA = qw(DB_File NDBM_File GDBM_File) }
use strict;
use Fcntl;
use AnyDBM_File ();
my($file,$command,$key,$crypted_pwd) = @ARGV;
usage() unless $file and $command and defined &{$dbmc::{$command}};
# if your osname is in $newstyle_salt, then use new style salt (starts with '_' and contains
# four bytes of iteration count and four bytes of salt). Otherwise, just use
# the traditional two-byte salt.
# see the man page on your system to decide if you have a newer crypt() lib.
# I believe that 4.4BSD derived systems do (at least BSD/OS 2.0 does).
# The new style crypt() allows up to 20 characters of the password to be
# significant rather than only 8.
my $newstyle_salt = join '|', qw{bsdos}; #others?
# remove extension if any
my $chop = join '|', qw{db.? pag dir};
$file =~ s/\.($chop)$//;
my $is_update = $command eq "update";
my $Is_Win32 = $^O eq "MSWin32";
my %DB = ();
my @range = ();
my($mode, $flags) = $command =~
/^(?:view|check)$/ ? (0644, O_RDONLY) : (0644, O_RDWR|O_CREAT);
tie %DB, "AnyDBM_File", $file, $flags, $mode || die "Can't tie $file: $!";
dbmc->$command();
untie %DB;
sub usage {
my $cmds = join "|", sort keys %dbmc::;
die "usage: $0 filename [$cmds] [username]\n";
}
my $x;
sub genseed {
my $psf;
for (qw(-xlwwa -le)) {
`ps $_ 2>/dev/null`;
$psf = $_, last unless $?;
}
srand (time ^ $$ ^ unpack("%L*", `ps $psf | gzip -f`));
@range = (qw(. /), '0'..'9','a'..'z','A'..'Z');
$x = int scalar @range;
}
sub randchar {
join '', map $range[rand $x], 1..shift||1;
}
sub salt {
my $newstyle = $^O =~ /(?:$newstyle_salt)/;
genseed() unless @range;
return $newstyle ?
join '', "_", randchar, "a..", randchar(4) :
randchar(2);
}
sub getpass {
my $prompt = shift || "Enter password:";
unless($Is_Win32) {
open STDIN, "/dev/tty" or warn "couldn't open /dev/tty $!\n";
system "stty -echo;";
}
my($c,$pwd);
print STDERR $prompt;
while (($c = getc(STDIN)) ne '' and $c ne "\n" and $c ne "\r") {
$pwd .= $c;
}
system "stty echo" unless $Is_Win32;
print STDERR "\n";
die "Can't use empty password!\n" unless length $pwd;
return $pwd;
}
sub dbmc::update {
die "Sorry, user `$key' doesn't exist!\n" unless $DB{$key};
dbmc->adduser;
}
sub dbmc::add {
die "Can't use empty password!\n" unless $crypted_pwd;
unless($is_update) {
die "Sorry, user `$key' already exists!\n" if $DB{$key};
}
$DB{$key} = $crypted_pwd;
my $action = $is_update ? "updated" : "added";
print "User $key $action with password encrypted to $DB{$key}\n";
}
sub dbmc::adduser {
my $value = getpass "New password:";
die "They don't match, sorry.\n" unless getpass("Re-type new password:") eq $value;
$crypted_pwd = crypt $value, caller->salt;
dbmc->add;
}
sub dbmc::delete {
die "Sorry, user `$key' doesn't exist!\n" unless $DB{$key};
delete $DB{$key}, print "`$key' deleted\n";
}
sub dbmc::view {
print $key ? "$key:$DB{$key}\n" : map { "$_:$DB{$_}\n" if $DB{$_} } keys %DB;
}
sub dbmc::check {
die "Sorry, user `$key' doesn't exist!\n" unless $DB{$key};
print crypt(getpass(), $DB{$key}) eq $DB{$key} ? "password ok\n" : "password mismatch\n";
}
sub dbmc::import {
while(defined($_ = <STDIN>) and chomp) {
($key,$crypted_pwd) = split /:/, $_, 2;
dbmc->add;
}
}

271
support/htdigest.c Normal file
View File

@@ -0,0 +1,271 @@
/* ====================================================================
* Copyright (c) 1995-1999 The Apache Group. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* 4. The names "Apache Server" and "Apache Group" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Group and was originally based
* on public domain software written at the National Center for
* Supercomputing Applications, University of Illinois, Urbana-Champaign.
* For more information on the Apache Group and the Apache HTTP server
* project, please see <http://www.apache.org/>.
*
*/
/******************************************************************************
******************************************************************************
* NOTE! This program is not safe as a setuid executable! Do not make it
* setuid!
******************************************************************************
*****************************************************************************/
/*
* htdigest.c: simple program for manipulating digest passwd file for Apache
*
* by Alexei Kosut, based on htpasswd.c, by Rob McCool
*/
#include "ap_config.h"
#include <sys/types.h>
#include "ap.h"
#include "ap_md5.h"
#if defined(MPE) || defined(QNX) || defined(WIN32) || defined(__TANDEM)
#include <signal.h>
#else
#include <sys/signal.h>
#endif
#ifdef WIN32
#include <conio.h>
#define unlink _unlink
#endif
#ifdef CHARSET_EBCDIC
#define LF '\n'
#define CR '\r'
#else
#define LF 10
#define CR 13
#endif /* CHARSET_EBCDIC */
#define MAX_STRING_LEN 256
char *tn;
static void getword(char *word, char *line, char stop)
{
int x = 0, y;
for (x = 0; ((line[x]) && (line[x] != stop)); x++)
word[x] = line[x];
word[x] = '\0';
if (line[x])
++x;
y = 0;
while ((line[y++] = line[x++]));
}
static int getline(char *s, int n, FILE *f)
{
register int i = 0;
while (1) {
s[i] = (char) fgetc(f);
if (s[i] == CR)
s[i] = fgetc(f);
if ((s[i] == 0x4) || (s[i] == LF) || (i == (n - 1))) {
s[i] = '\0';
return (feof(f) ? 1 : 0);
}
++i;
}
}
static void putline(FILE *f, char *l)
{
int x;
for (x = 0; l[x]; x++)
fputc(l[x], f);
fputc('\n', f);
}
static void add_password(char *user, char *realm, FILE *f)
{
char *pw;
AP_MD5_CTX context;
unsigned char digest[16];
char string[MAX_STRING_LEN];
char pwin[MAX_STRING_LEN];
char pwv[MAX_STRING_LEN];
unsigned int i;
if (ap_getpass("New password: ", pwin, sizeof(pwin)) != 0) {
fprintf(stderr, "password too long");
exit(5);
}
ap_getpass("Re-type new password: ", pwv, sizeof(pwv));
if (strcmp(pwin, pwv) != 0) {
fprintf(stderr, "They don't match, sorry.\n");
if (tn) {
unlink(tn);
}
exit(1);
}
pw = pwin;
fprintf(f, "%s:%s:", user, realm);
/* Do MD5 stuff */
sprintf(string, "%s:%s:%s", user, realm, pw);
ap_MD5Init(&context);
ap_MD5Update(&context, (unsigned char *) string, strlen(string));
ap_MD5Final(digest, &context);
for (i = 0; i < 16; i++)
fprintf(f, "%02x", digest[i]);
fprintf(f, "\n");
}
static void usage(void)
{
fprintf(stderr, "Usage: htdigest [-c] passwordfile realm username\n");
fprintf(stderr, "The -c flag creates a new file.\n");
exit(1);
}
static void interrupted(void)
{
fprintf(stderr, "Interrupted.\n");
if (tn)
unlink(tn);
exit(1);
}
int main(int argc, char *argv[])
{
FILE *tfp, *f;
char user[MAX_STRING_LEN];
char realm[MAX_STRING_LEN];
char line[MAX_STRING_LEN];
char l[MAX_STRING_LEN];
char w[MAX_STRING_LEN];
char x[MAX_STRING_LEN];
char command[MAX_STRING_LEN];
int found;
tn = NULL;
signal(SIGINT, (void (*)(int)) interrupted);
if (argc == 5) {
if (strcmp(argv[1], "-c"))
usage();
if (!(tfp = fopen(argv[2], "w"))) {
fprintf(stderr, "Could not open passwd file %s for writing.\n",
argv[2]);
perror("fopen");
exit(1);
}
printf("Adding password for %s in realm %s.\n", argv[4], argv[3]);
add_password(argv[4], argv[3], tfp);
fclose(tfp);
exit(0);
}
else if (argc != 4)
usage();
tn = tmpnam(NULL);
if (!(tfp = fopen(tn, "w"))) {
fprintf(stderr, "Could not open temp file.\n");
exit(1);
}
if (!(f = fopen(argv[1], "r"))) {
fprintf(stderr,
"Could not open passwd file %s for reading.\n", argv[1]);
fprintf(stderr, "Use -c option to create new one.\n");
exit(1);
}
strcpy(user, argv[3]);
strcpy(realm, argv[2]);
found = 0;
while (!(getline(line, MAX_STRING_LEN, f))) {
if (found || (line[0] == '#') || (!line[0])) {
putline(tfp, line);
continue;
}
strcpy(l, line);
getword(w, l, ':');
getword(x, l, ':');
if (strcmp(user, w) || strcmp(realm, x)) {
putline(tfp, line);
continue;
}
else {
printf("Changing password for user %s in realm %s\n", user, realm);
add_password(user, realm, tfp);
found = 1;
}
}
if (!found) {
printf("Adding user %s in realm %s\n", user, realm);
add_password(user, realm, tfp);
}
fclose(f);
fclose(tfp);
#if defined(OS2) || defined(WIN32)
sprintf(command, "copy \"%s\" \"%s\"", tn, argv[1]);
#else
sprintf(command, "cp %s %s", tn, argv[1]);
#endif
system(command);
unlink(tn);
return 0;
}

577
support/htpasswd.c Normal file
View File

@@ -0,0 +1,577 @@
/* ====================================================================
* Copyright (c) 1995-1999 The Apache Group. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* 4. The names "Apache Server" and "Apache Group" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Group and was originally based
* on public domain software written at the National Center for
* Supercomputing Applications, University of Illinois, Urbana-Champaign.
* For more information on the Apache Group and the Apache HTTP server
* project, please see <http://www.apache.org/>.
*
*/
/******************************************************************************
******************************************************************************
* NOTE! This program is not safe as a setuid executable! Do not make it
* setuid!
******************************************************************************
*****************************************************************************/
/*
* htpasswd.c: simple program for manipulating password file for
* the Apache HTTP server
*
* Originally by Rob McCool
*
* Exit values:
* 0: Success
* 1: Failure; file access/permission problem
* 2: Failure; command line syntax problem (usage message issued)
* 3: Failure; password verification failure
* 4: Failure; operation interrupted (such as with CTRL/C)
* 5: Failure; buffer would overflow (username, filename, or computed
* record too long)
* 6: Failure; username contains illegal or reserved characters
*/
#include "ap_config.h"
#include <sys/types.h>
#include <signal.h>
#include <errno.h>
#include "ap.h"
#include "ap_md5.h"
#include "ap_sha1.h"
#ifdef WIN32
#include <conio.h>
#include "../os/win32/getopt.h"
#define unlink _unlink
#endif
#ifndef CHARSET_EBCDIC
#define LF 10
#define CR 13
#else /*CHARSET_EBCDIC*/
#define LF '\n'
#define CR '\r'
#endif /*CHARSET_EBCDIC*/
#define MAX_STRING_LEN 256
#define ALG_PLAIN 0
#define ALG_CRYPT 1
#define ALG_APMD5 2
#define ALG_APSHA 3
#define ERR_FILEPERM 1
#define ERR_SYNTAX 2
#define ERR_PWMISMATCH 3
#define ERR_INTERRUPTED 4
#define ERR_OVERFLOW 5
#define ERR_BADUSER 6
/*
* This needs to be declared statically so the signal handler can
* access it.
*/
static char *tempfilename;
/*
* Get a line of input from the user, not including any terminating
* newline.
*/
static int getline(char *s, int n, FILE *f)
{
register int i = 0;
while (1) {
s[i] = (char) fgetc(f);
if (s[i] == CR) {
s[i] = fgetc(f);
}
if ((s[i] == 0x4) || (s[i] == LF) || (i == (n - 1))) {
s[i] = '\0';
return (feof(f) ? 1 : 0);
}
++i;
}
}
static void putline(FILE *f, char *l)
{
int x;
for (x = 0; l[x]; x++) {
fputc(l[x], f);
}
fputc('\n', f);
}
/*
* Make a password record from the given information. A zero return
* indicates success; failure means that the output buffer contains an
* error message instead.
*/
static int mkrecord(char *user, char *record, size_t rlen, char *passwd,
int alg)
{
char *pw;
char cpw[120];
char pwin[MAX_STRING_LEN];
char pwv[MAX_STRING_LEN];
char salt[9];
if (passwd != NULL) {
pw = passwd;
}
else {
if (ap_getpass("New password: ", pwin, sizeof(pwin)) != 0) {
ap_snprintf(record, (rlen - 1), "password too long (>%d)",
sizeof(pwin) - 1);
return ERR_OVERFLOW;
}
ap_getpass("Re-type new password: ", pwv, sizeof(pwv));
if (strcmp(pwin, pwv) != 0) {
ap_cpystrn(record, "password verification error", (rlen - 1));
return ERR_PWMISMATCH;
}
pw = pwin;
memset(pwv, '\0', sizeof(pwin));
}
switch (alg) {
case ALG_APSHA:
/* XXX cpw >= 28 + strlen(sha1) chars - fixed len SHA */
ap_sha1_base64(pw,strlen(pw),cpw);
break;
case ALG_APMD5:
(void) srand((int) time((time_t *) NULL));
ap_to64(&salt[0], rand(), 8);
salt[8] = '\0';
ap_MD5Encode((const unsigned char *)pw, (const unsigned char *)salt,
cpw, sizeof(cpw));
break;
case ALG_PLAIN:
/* XXX this len limitation is not in sync with any HTTPd len. */
ap_cpystrn(cpw,pw,sizeof(cpw));
break;
case ALG_CRYPT:
default:
(void) srand((int) time((time_t *) NULL));
ap_to64(&salt[0], rand(), 8);
salt[8] = '\0';
ap_cpystrn(cpw, (char *)crypt(pw, salt), sizeof(cpw) - 1);
break;
}
memset(pw, '\0', strlen(pw));
/*
* Check to see if the buffer is large enough to hold the username,
* hash, and delimiters.
*/
if ((strlen(user) + 1 + strlen(cpw)) > (rlen - 1)) {
ap_cpystrn(record, "resultant record too long", (rlen - 1));
return ERR_OVERFLOW;
}
strcpy(record, user);
strcat(record, ":");
strcat(record, cpw);
return 0;
}
static int usage(void)
{
fprintf(stderr, "Usage:\n");
fprintf(stderr, "\thtpasswd [-cmdps] passwordfile username\n");
fprintf(stderr, "\thtpasswd -b[cmdps] passwordfile username password\n\n");
fprintf(stderr, " -c Create a new file.\n");
fprintf(stderr, " -m Force MD5 encryption of the password"
#if defined(WIN32) || defined(TPF)
" (default)"
#endif
".\n");
fprintf(stderr, " -d Force CRYPT encryption of the password"
#if (!(defined(WIN32) || defined(TPF)))
" (default)"
#endif
".\n");
fprintf(stderr, " -p Do not encrypt the password (plaintext).\n");
fprintf(stderr, " -s Force SHA encryption of the password.\n");
fprintf(stderr, " -b Use the password from the command line rather "
"than prompting for it.\n");
fprintf(stderr,
"On Windows and TPF systems the '-m' flag is used by default.\n");
fprintf(stderr,
"On all other systems, the '-p' flag will probably not work.\n");
return ERR_SYNTAX;
}
static void interrupted(void)
{
fprintf(stderr, "Interrupted.\n");
if (tempfilename != NULL) {
unlink(tempfilename);
}
exit(ERR_INTERRUPTED);
}
/*
* Check to see if the specified file can be opened for the given
* access.
*/
static int accessible(char *fname, char *mode)
{
FILE *s;
s = fopen(fname, mode);
if (s == NULL) {
return 0;
}
fclose(s);
return 1;
}
/*
* Return true if a file is readable.
*/
static int readable(char *fname)
{
return accessible(fname, "r");
}
/*
* Return true if the specified file can be opened for write access.
*/
static int writable(char *fname)
{
return accessible(fname, "a");
}
/*
* Return true if the named file exists, regardless of permissions.
*/
static int exists(char *fname)
{
#ifdef WIN32
struct _stat sbuf;
#else
struct stat sbuf;
#endif
int check;
#ifdef WIN32
check = _stat(fname, &sbuf);
#else
check = stat(fname, &sbuf);
#endif
return ((check == -1) && (errno == ENOENT)) ? 0 : 1;
}
/*
* Copy from the current position of one file to the current position
* of another.
*/
static void copy_file(FILE *target, FILE *source)
{
static char line[MAX_STRING_LEN];
while (fgets(line, sizeof(line), source) != NULL) {
fputs(line, target);
}
}
/*
* Let's do it. We end up doing a lot of file opening and closing,
* but what do we care? This application isn't run constantly.
*/
int main(int argc, char *argv[])
{
FILE *ftemp = NULL;
FILE *fpw = NULL;
char user[MAX_STRING_LEN];
char password[MAX_STRING_LEN];
char record[MAX_STRING_LEN];
char line[MAX_STRING_LEN];
char pwfilename[MAX_STRING_LEN];
char *arg;
int found = 0;
int alg = ALG_CRYPT;
int newfile = 0;
int noninteractive = 0;
int i;
int args_left = 2;
tempfilename = NULL;
signal(SIGINT, (void (*)(int)) interrupted);
/*
* Preliminary check to make sure they provided at least
* three arguments, we'll do better argument checking as
* we parse the command line.
*/
if (argc < 3) {
return usage();
}
/*
* Go through the argument list and pick out any options. They
* have to precede any other arguments.
*/
for (i = 1; i < argc; i++) {
arg = argv[i];
if (*arg != '-') {
break;
}
while (*++arg != '\0') {
if (*arg == 'c') {
newfile++;
}
else if (*arg == 'm') {
alg = ALG_APMD5;
}
else if (*arg == 's') {
alg = ALG_APSHA;
}
else if (*arg == 'p') {
alg = ALG_PLAIN;
}
else if (*arg == 'd') {
alg = ALG_CRYPT;
}
else if (*arg == 'b') {
noninteractive++;
args_left++;
}
else {
return usage();
}
}
}
/*
* Make sure we still have exactly the right number of arguments left
* (the filename, the username, and possibly the password if -b was
* specified).
*/
if ((argc - i) != args_left) {
return usage();
}
if (strlen(argv[i]) > (sizeof(pwfilename) - 1)) {
fprintf(stderr, "%s: filename too long\n", argv[0]);
return ERR_OVERFLOW;
}
strcpy(pwfilename, argv[i]);
if (strlen(argv[i + 1]) > (sizeof(user) - 1)) {
fprintf(stderr, "%s: username too long (>%d)\n", argv[0],
sizeof(user) - 1);
return ERR_OVERFLOW;
}
strcpy(user, argv[i + 1]);
if ((arg = strchr(user, ':')) != NULL) {
fprintf(stderr, "%s: username contains illegal character '%c'\n",
argv[0], *arg);
return ERR_BADUSER;
}
if (noninteractive) {
if (strlen(argv[i + 2]) > (sizeof(password) - 1)) {
fprintf(stderr, "%s: password too long (>%d)\n", argv[0],
sizeof(password) - 1);
return ERR_OVERFLOW;
}
strcpy(password, argv[i + 2]);
}
#ifdef WIN32
if (alg == ALG_CRYPT) {
alg = ALG_APMD5;
fprintf(stderr, "Automatically using MD5 format on Windows.\n");
}
#endif
#if (!(defined(WIN32) || defined(TPF)))
if (alg == ALG_PLAIN) {
fprintf(stderr,"Warning: storing passwords as plain text might "
"just not work on this platform.\n");
}
#endif
/*
* Verify that the file exists if -c was omitted. We give a special
* message if it doesn't.
*/
if ((! newfile) && (! exists(pwfilename))) {
fprintf(stderr, "%s: cannot modify file %s; use '-c' to create it\n",
argv[0], pwfilename);
perror("fopen");
exit(ERR_FILEPERM);
}
/*
* Verify that we can read the existing file in the case of an update
* to it (rather than creation of a new one).
*/
if ((! newfile) && (! readable(pwfilename))) {
fprintf(stderr, "%s: cannot open file %s for read access\n",
argv[0], pwfilename);
perror("fopen");
exit(ERR_FILEPERM);
}
/*
* Now check to see if we can preserve an existing file in case
* of password verification errors on a -c operation.
*/
if (newfile && exists(pwfilename) && (! readable(pwfilename))) {
fprintf(stderr, "%s: cannot open file %s for read access\n"
"%s: existing auth data would be lost on password mismatch",
argv[0], pwfilename, argv[0]);
perror("fopen");
exit(ERR_FILEPERM);
}
/*
* Now verify that the file is writable!
*/
if (! writable(pwfilename)) {
fprintf(stderr, "%s: cannot open file %s for write access\n",
argv[0], pwfilename);
perror("fopen");
exit(ERR_FILEPERM);
}
/*
* All the file access checks have been made. Time to go to work;
* try to create the record for the username in question. If that
* fails, there's no need to waste any time on file manipulations.
* Any error message text is returned in the record buffer, since
* the mkrecord() routine doesn't have access to argv[].
*/
i = mkrecord(user, record, sizeof(record) - 1,
noninteractive ? password : NULL,
alg);
if (i != 0) {
fprintf(stderr, "%s: %s\n", argv[0], record);
exit(i);
}
/*
* We can access the files the right way, and we have a record
* to add or update. Let's do it..
*/
tempfilename = tmpnam(NULL);
ftemp = fopen(tempfilename, "w+");
if (ftemp == NULL) {
fprintf(stderr, "%s: unable to create temporary file\n", argv[0]);
perror("fopen");
exit(ERR_FILEPERM);
}
/*
* If we're not creating a new file, copy records from the existing
* one to the temporary file until we find the specified user.
*/
if (! newfile) {
char scratch[MAX_STRING_LEN];
fpw = fopen(pwfilename, "r");
while (! (getline(line, sizeof(line), fpw))) {
char *colon;
if ((line[0] == '#') || (line[0] == '\0')) {
putline(ftemp, line);
continue;
}
strcpy(scratch, line);
/*
* See if this is our user.
*/
colon = strchr(scratch, ':');
if (colon != NULL) {
*colon = '\0';
}
if (strcmp(user, scratch) != 0) {
putline(ftemp, line);
continue;
}
found++;
break;
}
}
if (found) {
fprintf(stderr, "Updating ");
}
else {
fprintf(stderr, "Adding ");
}
fprintf(stderr, "password for user %s\n", user);
/*
* Now add the user record we created.
*/
putline(ftemp, record);
/*
* If we're updating an existing file, there may be additional
* records beyond the one we're updating, so copy them.
*/
if (! newfile) {
copy_file(ftemp, fpw);
fclose(fpw);
}
/*
* The temporary file now contains the information that should be
* in the actual password file. Close the open files, re-open them
* in the appropriate mode, and copy them file to the real one.
*/
fclose(ftemp);
fpw = fopen(pwfilename, "w+");
ftemp = fopen(tempfilename, "r");
copy_file(fpw, ftemp);
fclose(fpw);
fclose(ftemp);
unlink(tempfilename);
return 0;
}

412
support/httpd.exp Normal file
View File

@@ -0,0 +1,412 @@
#!
ap_MD5Encode
ap_MD5Final
ap_MD5Init
ap_MD5Update
ap_SHA1Final
ap_SHA1Init
ap_SHA1Update_binary
ap_SHA1Update
ap_add_cgi_vars
ap_add_common_vars
ap_add_module
ap_add_named_module
ap_add_per_dir_conf
ap_add_per_url_conf
ap_add_version_component
ap_allow_options
ap_allow_overrides
ap_append_arrays
ap_array_cat
ap_array_pstrcat
ap_auth_name
ap_auth_type
ap_base64encode
ap_base64encode_binary
ap_base64encode_len
ap_base64decode
ap_base64decode_binary
ap_base64decode_len
ap_basic_http_header
ap_bclose
ap_bcreate
ap_bfilbuf
ap_bfileno
ap_bflsbuf
ap_bflush
ap_bgetopt
ap_bgets
ap_bhalfduplex
ap_bind_address
ap_block_alarms
ap_blookc
ap_bnonblock
ap_bonerror
ap_bprintf
ap_bpushfd
ap_bputs
ap_bread
ap_bsetflag
ap_bsetopt
ap_bskiplf
ap_bspawn_child
ap_bvputs
ap_bwrite
ap_bytes_in_free_blocks
ap_bytes_in_pool
ap_call_exec
ap_can_exec
ap_cfg_closefile
ap_cfg_getc
ap_cfg_getline
ap_chdir_file
ap_check_access
ap_check_auth
ap_check_cmd_context
ap_check_user_id
ap_checkmask
ap_child_exit_modules
ap_child_init_modules
ap_child_terminate
ap_cleanup_for_exec
ap_clear_module_list
ap_clear_pool
ap_clear_table
ap_close_piped_log
ap_construct_server
ap_construct_url
ap_content_type_tolower
ap_copy_array
ap_copy_array_hdr
ap_copy_table
ap_core_reorder_directories
ap_coredump_dir
ap_count_dirs
ap_cpystrn
ap_create_environment
ap_create_per_dir_config
ap_create_request_config
ap_daemons_limit
ap_daemons_max_free
ap_daemons_min_free
ap_daemons_to_start
ap_day_snames
ap_default_port_for_request
ap_default_port_for_scheme
ap_default_type
ap_destroy_pool
ap_destroy_sub_req
ap_die
ap_discard_request_body
ap_document_root
ap_dummy_mutex
ap_each_byterange
ap_error_log2stderr
ap_escape_html
ap_escape_path_segment
ap_escape_quotes
ap_escape_shell_cmd
ap_excess_requests_per_child
ap_exists_config_define
ap_exists_scoreboard_image
ap_extended_status
ap_field_noparam
ap_finalize_request_protocol
ap_finalize_sub_req_protocol
ap_find_command
ap_find_command_in_modules
ap_find_last_token
ap_find_linked_module
ap_find_list_item
ap_find_module_name
ap_find_path_info
ap_find_token
ap_find_types
ap_fini_vhost_config
ap_fnmatch
ap_force_library_loading
ap_get_basic_auth_pw
ap_get_client_block
ap_get_gmtoff
ap_get_list_item
ap_get_local_host
ap_get_remote_host
ap_get_remote_logname
ap_get_server_built
ap_get_server_name
ap_get_server_port
ap_get_server_version
ap_get_time
ap_get_token
ap_get_virthost_addr
ap_getparents
ap_getword
ap_getword_conf
ap_getword_conf_nc
ap_getword_nc
ap_getword_nulls
ap_getword_nulls_nc
ap_getword_white
ap_getword_white_nc
ap_gm_timestr_822
ap_gname2id
ap_group_id
ap_handle_command
ap_hard_timeout
ap_header_parse
ap_ht_time
ap_ind
ap_index_of_response
ap_init_alloc
ap_init_modules
ap_init_vhost_config
ap_init_virtual_host
ap_internal_redirect
ap_internal_redirect_handler
ap_invoke_handler
ap_is_directory
ap_is_fnmatch
ap_is_initial_req
ap_is_matchexp
ap_is_url
ap_keepalive_timeout
ap_kill_cleanup
ap_kill_cleanups_for_fd
ap_kill_cleanups_for_socket
ap_kill_timeout
ap_limit_section
ap_listenbacklog
ap_listeners
ap_lock_fname
ap_log_assert
ap_log_error
ap_log_error_old
ap_log_pid
ap_log_printf
ap_log_reason
ap_log_rerror
ap_log_transaction
ap_log_unixerr
ap_make_array
ap_make_dirstr
ap_make_dirstr_parent
ap_make_dirstr_prefix
ap_make_etag
ap_make_full_path
ap_make_sub_pool
ap_make_table
ap_matches_request_vhost
ap_max_requests_per_child
ap_md5
ap_md5contextTo64
ap_md5digest
ap_meets_conditions
ap_merge_per_dir_configs
ap_method_number_of
ap_month_snames
ap_my_generation
ap_no2slash
ap_note_auth_failure
ap_note_basic_auth_failure
ap_note_cleanups_for_fd
ap_note_cleanups_for_file
ap_note_cleanups_for_socket
ap_note_digest_auth_failure
ap_note_subprocess
ap_null_cleanup
ap_open_logs
ap_open_piped_log
ap_os_escape_path
ap_os_is_path_absolute
ap_overlay_tables
ap_overlap_tables
ap_palloc
ap_parseHTTPdate
ap_parse_hostinfo_components
ap_parse_htaccess
ap_parse_uri
ap_parse_uri_components
ap_parse_vhost_addrs
ap_pbase64decode
ap_pbase64encode
ap_pcalloc
ap_pcfg_open_custom
ap_pcfg_openfile
ap_pclosedir
ap_pclosef
ap_pclosesocket
ap_pduphostent
ap_pfclose
ap_pfdopen
ap_pfopen
ap_pgethostbyname
ap_pid_fname
ap_popendir
ap_popenf
ap_pregcomp
ap_pregfree
ap_pregsub
ap_prelinked_modules
ap_preloaded_modules
ap_process_request
ap_process_resource_config
ap_psignature
ap_psocket
ap_psprintf
ap_pstrcat
ap_pstrdup
ap_pstrndup
ap_push_array
ap_pvsprintf
ap_rationalize_mtime
ap_read_config
ap_read_request
ap_regerror
ap_regexec
ap_register_cleanup
ap_register_other_child
ap_remove_module
ap_requires
ap_reset_timeout
ap_response_code_string
ap_restart_time
ap_rfc1413
ap_rfc1413_timeout
ap_rflush
ap_rind
ap_rprintf
ap_rputc
ap_rputs
ap_run_cleanup
ap_run_fixups
ap_run_post_read_request
ap_run_sub_req
ap_rvputs
ap_rwrite
ap_satisfies
ap_scan_script_header_err
ap_scan_script_header_err_buff
ap_scoreboard_fname
ap_scoreboard_image
ap_send_error_response
ap_send_fb
ap_send_fb_length
ap_send_fd
ap_send_fd_length
ap_send_header_field
ap_send_http_header
ap_send_http_options
ap_send_http_trace
ap_send_mmap
ap_send_size
ap_server_argv0
ap_server_config_defines
ap_server_confname
ap_server_post_read_config
ap_server_pre_read_config
ap_server_root
ap_server_root_relative
ap_set_byterange
ap_set_callback_and_alarm
ap_set_content_length
ap_set_etag
ap_set_file_slot
ap_set_flag_slot
ap_set_keepalive
ap_set_last_modified
ap_set_name_virtual_host
ap_set_string_slot
ap_set_string_slot_lower
ap_set_sub_req_protocol
ap_setup_client_block
ap_setup_prelinked_modules
ap_sha1_base64
ap_should_client_block
ap_show_directives
ap_show_modules
ap_signal
ap_single_module_configure
ap_size_list_item
ap_slack
ap_snprintf
ap_soft_timeout
ap_some_auth_required
ap_spawn_child
ap_srm_command_loop
ap_standalone
ap_start_restart
ap_start_shutdown
ap_str_tolower
ap_strcasecmp_match
ap_strcmp_match
ap_sub_req_lookup_file
ap_sub_req_lookup_uri
ap_sub_req_method_uri
ap_suexec_enabled
ap_sync_scoreboard_image
ap_table_add
ap_table_addn
ap_table_do
ap_table_get
ap_table_merge
ap_table_mergen
ap_table_set
ap_table_setn
ap_table_unset
ap_threads_per_child
ap_tm2sec
ap_translate_name
ap_uname2id
ap_unblock_alarms
ap_unescape_url
ap_unparse_uri_components
ap_unregister_other_child
ap_update_child_status
ap_update_mtime
ap_update_vhost_from_headers
ap_update_vhost_given_ip
ap_user_id
ap_user_name
ap_util_init
ap_util_uri_init
ap_uudecode
ap_validate_password
ap_vbprintf
ap_vformatter
ap_vsnprintf
core_module
top_module
XML_DefaultCurrent
XML_ErrorString
XML_ExternalEntityParserCreate
XML_GetBase
XML_GetBuffer
XML_GetCurrentByteCount
XML_GetCurrentByteIndex
XML_GetCurrentColumnNumber
XML_GetCurrentLineNumber
XML_GetErrorCode
XML_GetSpecifiedAttributeCount
XML_Parse
XML_ParseBuffer
XML_ParserCreate
XML_ParserCreateNS
XML_ParserFree
XML_SetBase
XML_SetCdataSectionHandler
XML_SetCharacterDataHandler
XML_SetCommentHandler
XML_SetDefaultHandler
XML_SetDefaultHandlerExpand
XML_SetElementHandler
XML_SetEncoding
XML_SetExternalEntityRefHandler
XML_SetExternalEntityRefHandlerArg
XML_SetNamespaceDeclHandler
XML_SetNotStandaloneHandler
XML_SetNotationDeclHandler
XML_SetProcessingInstructionHandler
XML_SetUnknownEncodingHandler
XML_SetUnparsedEntityDeclHandler
XML_SetUserData
XML_UseParserAsHandlerArg

118
support/log_server_status Normal file
View File

@@ -0,0 +1,118 @@
#!/usr/local/bin/perl
# ====================================================================
# Copyright (c) 1995-1999 The Apache Group. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. All advertising materials mentioning features or use of this
# software must display the following acknowledgment:
# "This product includes software developed by the Apache Group
# for use in the Apache HTTP server project (http://www.apache.org/)."
#
# 4. The names "Apache Server" and "Apache Group" must not be used to
# endorse or promote products derived from this software without
# prior written permission. For written permission, please contact
# apache@apache.org.
#
# 5. Products derived from this software may not be called "Apache"
# nor may "Apache" appear in their names without prior written
# permission of the Apache Group.
#
# 6. Redistributions of any form whatsoever must retain the following
# acknowledgment:
# "This product includes software developed by the Apache Group
# for use in the Apache HTTP server project (http://www.apache.org/)."
#
# THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
# ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
# OF THE POSSIBILITY OF SUCH DAMAGE.
# ====================================================================
#
# This software consists of voluntary contributions made by many
# individuals on behalf of the Apache Group and was originally based
# on public domain software written at the National Center for
# Supercomputing Applications, University of Illinois, Urbana-Champaign.
# For more information on the Apache Group and the Apache HTTP server
# project, please see <http://www.apache.org/>.
# Log Server Status
# Mark J Cox, UK Web Ltd 1996, mark@ukweb.com
#
# This script is designed to be run at a frequent interval by something
# like cron. It connects to the server and downloads the status
# information. It reformats the information to a single line and logs
# it to a file. Make sure the directory $wherelog is writable by the
# user who runs this script.
#
require 'sys/socket.ph';
$wherelog = "/var/log/graph/"; # Logs will be like "/var/log/graph/19960312"
$server = "localhost"; # Name of server, could be "www.foo.com"
$port = "80"; # Port on server
$request = "/status/?auto"; # Request to send
sub tcp_connect
{
local($host,$port) =@_;
$sockaddr='S n a4 x8';
chop($hostname=`hostname`);
$port=(getservbyname($port, 'tcp'))[2] unless $port =~ /^\d+$/;
$me=pack($sockaddr,&AF_INET,0,(gethostbyname($hostname))[4]);
$them=pack($sockaddr,&AF_INET,$port,(gethostbyname($host))[4]);
socket(S,&PF_INET,&SOCK_STREAM,(getprotobyname('tcp'))[2]) ||
die "socket: $!";
bind(S,$me) || return "bind: $!";
connect(S,$them) || return "connect: $!";
select(S);
$| = 1;
select(stdout);
return "";
}
### Main
{
$year=`date +%y`;
chomp($year);
$year += ($year < 70) ? 2000 : 1900;
$date = $year . `date +%m%d:%H%M%S`;
chomp($date);
($day,$time)=split(/:/,$date);
$res=&tcp_connect($server,$port);
open(OUT,">>$wherelog$day");
if ($res) {
print OUT "$time:-1:-1:-1:-1:$res\n";
exit 1;
}
print S "GET $request\n";
while (<S>) {
$requests=$1 if ( m|^BusyServers:\ (\S+)|);
$idle=$1 if ( m|^IdleServers:\ (\S+)|);
$number=$1 if ( m|sses:\ (\S+)|);
$cpu=$1 if (m|^CPULoad:\ (\S+)|);
}
print OUT "$time:$requests:$idle:$number:$cpu\n";
}

345
support/logresolve.c Normal file
View File

@@ -0,0 +1,345 @@
/*
* logresolve 1.1
*
* Tom Rathborne - tomr@uunet.ca - http://www.uunet.ca/~tomr/
* UUNET Canada, April 16, 1995
*
* Rewritten by David Robinson. (drtr@ast.cam.ac.uk)
*
* Usage: logresolve [-s filename] [-c] < access_log > new_log
*
* Arguments:
* -s filename name of a file to record statistics
* -c check the DNS for a matching A record for the host.
*
* Notes:
*
* To generate meaningful statistics from an HTTPD log file, it's good
* to have the domain name of each machine that accessed your site, but
* doing this on the fly can slow HTTPD down.
*
* Compiling NCSA HTTPD with the -DMINIMAL_DNS flag turns IP#->hostname
* resolution off. Before running your stats program, just run your log
* file through this program (logresolve) and all of your IP numbers will
* be resolved into hostnames (where possible).
*
* logresolve takes an HTTPD access log (in the COMMON log file format,
* or any other format that has the IP number/domain name as the first
* field for that matter), and outputs the same file with all of the
* domain names looked up. Where no domain name can be found, the IP
* number is left in.
*
* To minimize impact on your nameserver, logresolve has its very own
* internal hash-table cache. This means that each IP number will only
* be looked up the first time it is found in the log file.
*
* The -c option causes logresolve to apply the same check as httpd
* compiled with -DMAXIMUM_DNS; after finding the hostname from the IP
* address, it looks up the IP addresses for the hostname and checks
* that one of these matches the original address.
*/
#include "ap_config.h"
#include <sys/types.h>
#include <ctype.h>
#ifndef MPE
#include <arpa/inet.h>
#endif
static void cgethost(struct in_addr ipnum, char *string, int check);
static int getline(char *s, int n);
static void stats(FILE *output);
/* maximum line length */
#define MAXLINE 1024
/* maximum length of a domain name */
#ifndef MAXDNAME
#define MAXDNAME 256
#endif
/* number of buckets in cache hash table */
#define BUCKETS 256
#if defined(NEED_STRDUP)
char *strdup (const char *str)
{
char *dup;
if (!(dup = (char *) malloc(strlen(str) + 1)))
return NULL;
dup = strcpy(dup, str);
return dup;
}
#endif
/*
* struct nsrec - record of nameservice for cache linked list
*
* ipnum - IP number hostname - hostname noname - nonzero if IP number has no
* hostname, i.e. hostname=IP number
*/
struct nsrec {
struct in_addr ipnum;
char *hostname;
int noname;
struct nsrec *next;
} *nscache[BUCKETS];
/*
* statistics - obvious
*/
#ifndef h_errno
extern int h_errno; /* some machines don't have this in their headers */
#endif
/* largeste value for h_errno */
#define MAX_ERR (NO_ADDRESS)
#define UNKNOWN_ERR (MAX_ERR+1)
#define NO_REVERSE (MAX_ERR+2)
static int cachehits = 0;
static int cachesize = 0;
static int entries = 0;
static int resolves = 0;
static int withname = 0;
static int errors[MAX_ERR + 3];
/*
* cgethost - gets hostname by IP address, caching, and adding unresolvable
* IP numbers with their IP number as hostname, setting noname flag
*/
static void cgethost (struct in_addr ipnum, char *string, int check)
{
struct nsrec **current, *new;
struct hostent *hostdata;
char *name;
current = &nscache[((ipnum.s_addr + (ipnum.s_addr >> 8) +
(ipnum.s_addr >> 16) + (ipnum.s_addr >> 24)) % BUCKETS)];
while (*current != NULL && ipnum.s_addr != (*current)->ipnum.s_addr)
current = &(*current)->next;
if (*current == NULL) {
cachesize++;
new = (struct nsrec *) malloc(sizeof(struct nsrec));
if (new == NULL) {
perror("malloc");
fprintf(stderr, "Insufficient memory\n");
exit(1);
}
*current = new;
new->next = NULL;
new->ipnum = ipnum;
hostdata = gethostbyaddr((const char *) &ipnum, sizeof(struct in_addr),
AF_INET);
if (hostdata == NULL) {
if (h_errno > MAX_ERR)
errors[UNKNOWN_ERR]++;
else
errors[h_errno]++;
new->noname = h_errno;
name = strdup(inet_ntoa(ipnum));
}
else {
new->noname = 0;
name = strdup(hostdata->h_name);
if (check) {
if (name == NULL) {
perror("strdup");
fprintf(stderr, "Insufficient memory\n");
exit(1);
}
hostdata = gethostbyname(name);
if (hostdata != NULL) {
char **hptr;
for (hptr = hostdata->h_addr_list; *hptr != NULL; hptr++)
if (((struct in_addr *) (*hptr))->s_addr == ipnum.s_addr)
break;
if (*hptr == NULL)
hostdata = NULL;
}
if (hostdata == NULL) {
fprintf(stderr, "Bad host: %s != %s\n", name,
inet_ntoa(ipnum));
new->noname = NO_REVERSE;
free(name);
name = strdup(inet_ntoa(ipnum));
errors[NO_REVERSE]++;
}
}
}
new->hostname = name;
if (new->hostname == NULL) {
perror("strdup");
fprintf(stderr, "Insufficient memory\n");
exit(1);
}
}
else
cachehits++;
/* size of string == MAXDNAME +1 */
strncpy(string, (*current)->hostname, MAXDNAME);
string[MAXDNAME] = '\0';
}
/*
* prints various statistics to output
*/
static void stats (FILE *output)
{
int i;
char *ipstring;
struct nsrec *current;
char *errstring[MAX_ERR + 3];
for (i = 0; i < MAX_ERR + 3; i++)
errstring[i] = "Unknown error";
errstring[HOST_NOT_FOUND] = "Host not found";
errstring[TRY_AGAIN] = "Try again";
errstring[NO_RECOVERY] = "Non recoverable error";
errstring[NO_DATA] = "No data record";
errstring[NO_ADDRESS] = "No address";
errstring[NO_REVERSE] = "No reverse entry";
fprintf(output, "logresolve Statistics:\n");
fprintf(output, "Entries: %d\n", entries);
fprintf(output, " With name : %d\n", withname);
fprintf(output, " Resolves : %d\n", resolves);
if (errors[HOST_NOT_FOUND])
fprintf(output, " - Not found : %d\n", errors[HOST_NOT_FOUND]);
if (errors[TRY_AGAIN])
fprintf(output, " - Try again : %d\n", errors[TRY_AGAIN]);
if (errors[NO_DATA])
fprintf(output, " - No data : %d\n", errors[NO_DATA]);
if (errors[NO_ADDRESS])
fprintf(output, " - No address: %d\n", errors[NO_ADDRESS]);
if (errors[NO_REVERSE])
fprintf(output, " - No reverse: %d\n", errors[NO_REVERSE]);
fprintf(output, "Cache hits : %d\n", cachehits);
fprintf(output, "Cache size : %d\n", cachesize);
fprintf(output, "Cache buckets : IP number * hostname\n");
for (i = 0; i < BUCKETS; i++)
for (current = nscache[i]; current != NULL; current = current->next) {
ipstring = inet_ntoa(current->ipnum);
if (current->noname == 0)
fprintf(output, " %3d %15s - %s\n", i, ipstring,
current->hostname);
else {
if (current->noname > MAX_ERR + 2)
fprintf(output, " %3d %15s : Unknown error\n", i,
ipstring);
else
fprintf(output, " %3d %15s : %s\n", i, ipstring,
errstring[current->noname]);
}
}
}
/*
* gets a line from stdin
*/
static int getline (char *s, int n)
{
char *cp;
if (!fgets(s, n, stdin))
return (0);
cp = strchr(s, '\n');
if (cp)
*cp = '\0';
return (1);
}
int main (int argc, char *argv[])
{
struct in_addr ipnum;
char *bar, hoststring[MAXDNAME + 1], line[MAXLINE], *statfile;
int i, check;
check = 0;
statfile = NULL;
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-c") == 0)
check = 1;
else if (strcmp(argv[i], "-s") == 0) {
if (i == argc - 1) {
fprintf(stderr, "logresolve: missing filename to -s\n");
exit(1);
}
i++;
statfile = argv[i];
}
else {
fprintf(stderr, "Usage: logresolve [-s statfile] [-c] < input > output\n");
exit(0);
}
}
for (i = 0; i < BUCKETS; i++)
nscache[i] = NULL;
for (i = 0; i < MAX_ERR + 2; i++)
errors[i] = 0;
while (getline(line, MAXLINE)) {
if (line[0] == '\0')
continue;
entries++;
if (!isdigit(line[0])) { /* short cut */
puts(line);
withname++;
continue;
}
bar = strchr(line, ' ');
if (bar != NULL)
*bar = '\0';
ipnum.s_addr = inet_addr(line);
if (ipnum.s_addr == 0xffffffffu) {
if (bar != NULL)
*bar = ' ';
puts(line);
withname++;
continue;
}
resolves++;
cgethost(ipnum, hoststring, check);
if (bar != NULL)
printf("%s %s\n", hoststring, bar + 1);
else
puts(hoststring);
}
if (statfile != NULL) {
FILE *fp;
fp = fopen(statfile, "w");
if (fp == NULL) {
fprintf(stderr, "logresolve: could not open statistics file '%s'\n"
,statfile);
exit(1);
}
stats(fp);
fclose(fp);
}
return (0);
}

264
support/logresolve.pl Normal file
View File

@@ -0,0 +1,264 @@
#!/usr/local/bin/perl
# ====================================================================
# Copyright (c) 1995-1999 The Apache Group. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. All advertising materials mentioning features or use of this
# software must display the following acknowledgment:
# "This product includes software developed by the Apache Group
# for use in the Apache HTTP server project (http://www.apache.org/)."
#
# 4. The names "Apache Server" and "Apache Group" must not be used to
# endorse or promote products derived from this software without
# prior written permission. For written permission, please contact
# apache@apache.org.
#
# 5. Products derived from this software may not be called "Apache"
# nor may "Apache" appear in their names without prior written
# permission of the Apache Group.
#
# 6. Redistributions of any form whatsoever must retain the following
# acknowledgment:
# "This product includes software developed by the Apache Group
# for use in the Apache HTTP server project (http://www.apache.org/)."
#
# THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
# ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
# OF THE POSSIBILITY OF SUCH DAMAGE.
# ====================================================================
#
# This software consists of voluntary contributions made by many
# individuals on behalf of the Apache Group and was originally based
# on public domain software written at the National Center for
# Supercomputing Applications, University of Illinois, Urbana-Champaign.
# For more information on the Apache Group and the Apache HTTP server
# project, please see <http://www.apache.org/>.
# logresolve.pl
#
# v 1.2 by robh @ imdb.com
#
# usage: logresolve.pl <infile >outfile
#
# input = Apache/NCSA/.. logfile with IP numbers at start of lines
# output = same logfile with IP addresses resolved to hostnames where
# name lookups succeeded.
#
# this differs from the C based 'logresolve' in that this script
# spawns a number ($CHILDREN) of subprocesses to resolve addresses
# concurrently and sets a short timeout ($TIMEOUT) for each lookup in
# order to keep things moving quickly.
#
# the parent process handles caching of IP->hostnames using a Perl hash
# it also avoids sending the same IP to multiple child processes to be
# resolved multiple times concurrently.
#
# Depending on the settings of $CHILDREN and $TIMEOUT you should see
# significant reductions in the overall time taken to resolve your
# logfiles. With $CHILDREN=40 and $TIMEOUT=5 I've seen 200,000 - 300,000
# logfile lines processed per hour compared to ~45,000 per hour
# with 'logresolve'.
#
# I haven't yet seen any noticable reduction in the percentage of IPs
# that fail to get resolved. Your mileage will no doubt vary. 5s is long
# enough to wait IMO.
#
# Known to work with FreeBSD 2.2
# Known to have problems with Solaris
#
# 980417 - use 'sockaddr_un' for bind/connect to make the script work
# with linux. Fix from Luuk de Boer <luuk_de_boer@pi.net>
require 5.004;
$|=1;
use FileHandle;
use Socket;
use strict;
no strict 'refs';
use vars qw($PROTOCOL);
$PROTOCOL = 0;
my $CHILDREN = 40;
my $TIMEOUT = 5;
my $filename;
my %hash = ();
my $parent = $$;
my @children = ();
for (my $child = 1; $child <=$CHILDREN; $child++) {
my $f = fork();
if (!$f) {
$filename = "./.socket.$parent.$child";
if (-e $filename) { unlink($filename) || warn "$filename .. $!\n";}
&child($child);
exit(0);
}
push(@children, $f);
}
&parent;
&cleanup;
## remove all temporary files before shutting down
sub cleanup {
# die kiddies, die
kill(15, @children);
for (my $child = 1; $child <=$CHILDREN; $child++) {
if (-e "./.socket.$parent.$child") {
unlink("./.socket.$parent.$child")
|| warn ".socket.$parent.$child $!";
}
}
}
sub parent {
# Trap some possible signals to trigger temp file cleanup
$SIG{'KILL'} = $SIG{'INT'} = $SIG{'PIPE'} = \&cleanup;
my %CHILDSOCK;
my $filename;
## fork child processes. Each child will create a socket connection
## to this parent and use an unique temp filename to do so.
for (my $child = 1; $child <=$CHILDREN; $child++) {
$CHILDSOCK{$child}= FileHandle->new;
if (!socket($CHILDSOCK{$child}, AF_UNIX, SOCK_STREAM, $PROTOCOL)) {
warn "parent socket to child failed $!";
}
$filename = "./.socket.$parent.$child";
my $response;
do {
$response = connect($CHILDSOCK{$child}, sockaddr_un($filename));
if ($response != 1) {
sleep(1);
}
} while ($response != 1);
$CHILDSOCK{$child}->autoflush;
}
## All child processes should now be ready or at worst warming up
my (@buffer, $child, $ip, $rest, $hostname, $response);
## read the logfile lines from STDIN
while(<STDIN>) {
@buffer = (); # empty the logfile line buffer array.
$child = 1; # children are numbered 1..N, start with #1
# while we have a child to talk to and data to give it..
do {
push(@buffer, $_); # buffer the line
($ip, $rest) = split(/ /, $_, 2); # separate IP form rest
unless ($hash{$ip}) { # resolve if unseen IP
$CHILDSOCK{$child}->print("$ip\n"); # pass IP to next child
$hash{$ip} = $ip; # don't look it up again.
$child++;
}
} while (($child < ($CHILDREN-1)) and ($_ = <STDIN>));
## now poll each child for a response
while (--$child > 0) {
$response = $CHILDSOCK{$child}->getline;
chomp($response);
# child sends us back both the IP and HOSTNAME, no need for us
# to remember what child received any given IP, and no worries
# what order we talk to the children
($ip, $hostname) = split(/\|/, $response, 2);
$hash{$ip} = $hostname;
}
# resolve all the logfiles lines held in the log buffer array..
for (my $line = 0; $line <=$#buffer; $line++) {
# get next buffered line
($ip, $rest) = split(/ /, $buffer[$line], 2);
# separate IP from rest and replace with cached hostname
printf STDOUT ("%s %s", $hash{$ip}, $rest);
}
}
}
########################################
sub child {
# arg = numeric ID - how the parent refers to me
my $me = shift;
# add trap for alarm signals.
$SIG{'ALRM'} = sub { die "alarmed"; };
# create a socket to communicate with parent
socket(INBOUND, AF_UNIX, SOCK_STREAM, $PROTOCOL)
|| die "Error with Socket: !$\n";
$filename = "./.socket.$parent.$me";
bind(INBOUND, sockaddr_un($filename))
|| die "Error Binding $filename: $!\n";
listen(INBOUND, 5) || die "Error Listening: $!\n";
my ($ip, $send_back);
my $talk = FileHandle->new;
# accept a connection from the parent process. We only ever have
# have one connection where we exchange 1 line of info with the
# parent.. 1 line in (IP address), 1 line out (IP + hostname).
accept($talk, INBOUND) || die "Error Accepting: $!\n";
# disable I/O buffering just in case
$talk->autoflush;
# while the parent keeps sending data, we keep responding..
while(($ip = $talk->getline)) {
chomp($ip);
# resolve the IP if time permits and send back what we found..
$send_back = sprintf("%s|%s", $ip, &nslookup($ip));
$talk->print($send_back."\n");
}
}
# perform a time restricted hostname lookup.
sub nslookup {
# get the IP as an arg
my $ip = shift;
my $hostname = undef;
# do the hostname lookup inside an eval. The eval will use the
# already configured SIGnal handler and drop out of the {} block
# regardless of whether the alarm occured or not.
eval {
alarm($TIMEOUT);
$hostname = gethostbyaddr(gethostbyname($ip), AF_INET);
alarm(0);
};
if ($@ =~ /alarm/) {
# useful for debugging perhaps..
# print "alarming, isn't it? ($ip)";
}
# return the hostname or the IP address itself if there is no hostname
$hostname ne "" ? $hostname : $ip;
}

21
support/phf_abuse_log.cgi Normal file
View File

@@ -0,0 +1,21 @@
#!/usr/local/bin/perl
# This script can be used to detect people trying to abuse the security hole which
# existed in A CGI script direstributed with Apache 1.0.3 and earlier versions.
# You can redirect them to here using the "<Location /cgi-bin/phf*>" suggestion in
# httpd.conf.
#
# The format logged to is "[date] remote_addr remote_host [date] referrer user_agent".
$LOG = "/var/log/phf_log";
require "ctime.pl";
$when = &ctime(time);
$when =~ s/\n//go;
$ENV{HTTP_USER_AGENT} .= " via $ENV{HTTP_VIA}" if($ENV{HTTP_VIA});
open(LOG, ">>$LOG") || die "boo hoo, phf_log $!";
print LOG "[$when] $ENV{REMOTE_ADDR} $ENV{REMOTE_HOST} $ENV{$HTTP_REFERER} $ENV{HTTP_USER_AGENT}\n";
close(LOG);
print "Content-type: text/html\r\n\r\n<BLINK>Smile, you're on Candid Camera.</BLINK>\n";

Some files were not shown because too many files have changed in this diff Show More