summaryrefslogtreecommitdiff
path: root/usr.sbin/httpd
diff options
context:
space:
mode:
authorBob Beck <beck@cvs.openbsd.org>1998-10-01 17:25:55 +0000
committerBob Beck <beck@cvs.openbsd.org>1998-10-01 17:25:55 +0000
commit7a676a0ec6f795fb90ee4e61331a193516dc7f9d (patch)
tree3432bf197181bc72107d241251c7e25ee4db6060 /usr.sbin/httpd
parent44becabb19680fe2222a8dbb4374ec6ca8ffa42e (diff)
unused files, thanks to apache souce tree transmogrification..
Diffstat (limited to 'usr.sbin/httpd')
-rw-r--r--usr.sbin/httpd/CHANGES128
-rw-r--r--usr.sbin/httpd/Makefile116
-rw-r--r--usr.sbin/httpd/htdocs/manual/TODO4
-rw-r--r--usr.sbin/httpd/htdocs/manual/host.html185
-rw-r--r--usr.sbin/httpd/htdocs/manual/install_1_1.html124
-rw-r--r--usr.sbin/httpd/htdocs/manual/misc/known_bugs.html171
-rw-r--r--usr.sbin/httpd/htdocs/manual/mod/mod_auth_msql.html488
-rw-r--r--usr.sbin/httpd/htdocs/manual/vhosts-in-depth.html398
-rw-r--r--usr.sbin/httpd/htdocs/manual/virtual-host.html216
-rw-r--r--usr.sbin/httpd/src/.indent.pro1
-rw-r--r--usr.sbin/httpd/src/alloc.c1142
-rw-r--r--usr.sbin/httpd/src/alloc.h252
-rw-r--r--usr.sbin/httpd/src/buff.c1011
-rw-r--r--usr.sbin/httpd/src/buff.h139
-rw-r--r--usr.sbin/httpd/src/conf.h763
-rw-r--r--usr.sbin/httpd/src/explain.c14
-rw-r--r--usr.sbin/httpd/src/explain.h23
-rw-r--r--usr.sbin/httpd/src/http_bprintf.c602
-rw-r--r--usr.sbin/httpd/src/http_conf_globals.h86
-rw-r--r--usr.sbin/httpd/src/http_config.c1213
-rw-r--r--usr.sbin/httpd/src/http_config.h298
-rw-r--r--usr.sbin/httpd/src/http_core.c1413
-rw-r--r--usr.sbin/httpd/src/http_core.h205
-rw-r--r--usr.sbin/httpd/src/http_log.c197
-rw-r--r--usr.sbin/httpd/src/http_log.h62
-rw-r--r--usr.sbin/httpd/src/http_main.c2620
-rw-r--r--usr.sbin/httpd/src/http_main.h99
-rw-r--r--usr.sbin/httpd/src/http_protocol.c2047
-rw-r--r--usr.sbin/httpd/src/http_protocol.h191
-rw-r--r--usr.sbin/httpd/src/http_request.c1152
-rw-r--r--usr.sbin/httpd/src/http_request.h92
-rw-r--r--usr.sbin/httpd/src/httpd.h766
-rw-r--r--usr.sbin/httpd/src/md5.h99
-rw-r--r--usr.sbin/httpd/src/md5c.c354
-rw-r--r--usr.sbin/httpd/src/mod_access.c283
-rw-r--r--usr.sbin/httpd/src/mod_actions.c219
-rw-r--r--usr.sbin/httpd/src/mod_alias.c329
-rw-r--r--usr.sbin/httpd/src/mod_asis.c131
-rw-r--r--usr.sbin/httpd/src/mod_auth.c298
-rw-r--r--usr.sbin/httpd/src/mod_auth_anon.c299
-rw-r--r--usr.sbin/httpd/src/mod_auth_db.c303
-rw-r--r--usr.sbin/httpd/src/mod_auth_dbm.c291
-rw-r--r--usr.sbin/httpd/src/mod_auth_msql.c996
-rw-r--r--usr.sbin/httpd/src/mod_browser.c189
-rw-r--r--usr.sbin/httpd/src/mod_cern_meta.c325
-rw-r--r--usr.sbin/httpd/src/mod_cgi.c575
-rw-r--r--usr.sbin/httpd/src/mod_digest.c363
-rw-r--r--usr.sbin/httpd/src/mod_dir.c911
-rw-r--r--usr.sbin/httpd/src/mod_dld.c190
-rw-r--r--usr.sbin/httpd/src/mod_env.c261
-rw-r--r--usr.sbin/httpd/src/mod_expires.c477
-rw-r--r--usr.sbin/httpd/src/mod_headers.c253
-rw-r--r--usr.sbin/httpd/src/mod_imap.c877
-rw-r--r--usr.sbin/httpd/src/mod_include.c2329
-rw-r--r--usr.sbin/httpd/src/mod_info.c455
-rw-r--r--usr.sbin/httpd/src/mod_log_agent.c198
-rw-r--r--usr.sbin/httpd/src/mod_log_config.c787
-rw-r--r--usr.sbin/httpd/src/mod_log_referer.c235
-rw-r--r--usr.sbin/httpd/src/mod_mime.c324
-rw-r--r--usr.sbin/httpd/src/mod_negotiation.c2052
-rw-r--r--usr.sbin/httpd/src/mod_rewrite.c3335
-rw-r--r--usr.sbin/httpd/src/mod_rewrite.h400
-rw-r--r--usr.sbin/httpd/src/mod_status.c643
-rw-r--r--usr.sbin/httpd/src/mod_userdir.c214
-rw-r--r--usr.sbin/httpd/src/mod_usertrack.c328
-rw-r--r--usr.sbin/httpd/src/modules/example/Makefile107
-rw-r--r--usr.sbin/httpd/src/modules/proxy/Makefile89
-rw-r--r--usr.sbin/httpd/src/regex/Makefile133
-rw-r--r--usr.sbin/httpd/src/regex/regex.h73
-rw-r--r--usr.sbin/httpd/src/rfc1413.c239
-rw-r--r--usr.sbin/httpd/src/rfc1413.h53
-rw-r--r--usr.sbin/httpd/src/scoreboard.h110
-rw-r--r--usr.sbin/httpd/src/util.c1369
-rw-r--r--usr.sbin/httpd/src/util_date.c296
-rw-r--r--usr.sbin/httpd/src/util_date.h63
-rw-r--r--usr.sbin/httpd/src/util_md5.c192
-rw-r--r--usr.sbin/httpd/src/util_md5.h58
-rw-r--r--usr.sbin/httpd/src/util_script.c641
-rw-r--r--usr.sbin/httpd/src/util_script.h69
-rw-r--r--usr.sbin/httpd/src/util_snprintf.c949
80 files changed, 0 insertions, 39982 deletions
diff --git a/usr.sbin/httpd/CHANGES b/usr.sbin/httpd/CHANGES
deleted file mode 100644
index 4f36295a07b..00000000000
--- a/usr.sbin/httpd/CHANGES
+++ /dev/null
@@ -1,128 +0,0 @@
- OVERVIEW OF NEW FEATURES IN APACHE 1.2
-
-New features with this release, as extensions of the Apache functionality
-For more information, see the documentation included with this release
-(htdocs/manual/) or http://www.apache.org/docs/
-
-In addition to a number of bug fixes and internal performance
-enhancements, Apache 1.2 has the following specific new user
-features:
-
-
- *) HTTP/1.1 Compliance
- Aside from the optional proxy module (which operates as HTTP/1.0),
- Apache is conditionally compliant with the HTTP/1.1 proposed standard,
- as approved by the IESG and the IETF HTTP working group.
- HTTP/1.1 provides a much-improved protocol, and should allow for
- greater performance and efficiency when transferring files. Apache
- does, however, still work great with HTTP/1.0 browsers. We are very
- close to being unconditionally compliant; if you note any deviance
- from the proposed standard, please report it as a bug.
-
- *) eXtended Server Side Includes (XSSI)
- A new set of server-side include directives allows the user to
- better create WWW pages. This includes number of powerful new
- features, such as the ability to set variables and use conditional
- HTML.
-
- *) File-based and Regex-enabled Directive Sections
- The new <Files> section allows directives to be enabled based on
- full filename, not just directory and URL. In addition, <Files>
- sections can appear in .htaccess files. <Files>, along with
- <Directory> and <Location>, can also now be based on regular
- expressions, not just simple prefix matching.
-
- *) Browser-based Environment Variables
- Environment variables can now be set based on the User-Agent
- string of the browser. Combined with XSSI, this allows you to
- write browser-based conditional HTML documents.
-
- *) SetUID CGI Execution
- Apache now supports the execution of CGI scripts as users other
- than the server user. A number of security checks are built in to
- try and make this as safe as possible.
-
- *) URL Rewriting Module
- The optional mod_rewrite module is now included. This module can
- provide powerful URL mapping, using regular expressions. There's
- nothing this module can't do!
-
- *) Enhanced, Configurable Logging
- The optional mod_log_config included with earlier versions of
- Apache is now standard, and has been enhanced to allow logging of
- much more detail about the transaction, and can be used to open
- more than one log at once (each of which can have a different log
- format).
-
- *) User Tracking (Cookies) Revisions
- The mod_cookies included with previous versions of Apache has been
- renamed mod_usertrack, to more accurately reflect its function
- (some people inadvertently thought it enabled cookie support in
- Apache, which is not true - Apache supports the use of cookies
- directly). It is also now possible to disable the generation of
- cookies, even when the cookie module is compiled in. Also, an
- expiry time can be set on the cookies.
-
- *) Multiple IPs in <VirtualHost>
- The <VirtualHost> directive can now take more than one IP address
- or hostname. This lets a single vhost handles requests for
- multiple IPs or hostnames.
-
- *) CGI Debugging Environment
- ScriptLog allows you to now set up a log that records all input
- and output to failed CGI scripts. This includes environment
- variables, input headers, POST data, output, and more. This makes
- CGI scripts much easier to debug.
-
- *) Resource Limits for CGI Scripts
- New directives allow the limiting of resources used by CGI scripts
- (e.g. max CPU time). This is helpful in preventing 'runaway' CGI
- processes.
-
- *) Redirect Directive Can Return Alternate Status
- The Redirect directive can return permanent or temporary redirects,
- "Gone" or "See Other" HTTP status. For NCSA-compatibility,
- RedirectTemp and RedirectPermanent are also implemented.
-
- *) Graceful Restarts
- Apache can re-read the config files and re-open log files without
- terminating transactions in progress.
-
- *) Simplified Compilation
- The process of configuring Apache for compilation has been
- simplified.
-
- *) Add or Remove Options
- The Options directive can now add or remove options from those
- currently in force, rather than always replacing them.
-
- *) Command-line Help
- The -h command-line option now lists all the available directives.
-
- *) Optional Headers Module to Set or Remove HTTP Headers
- The optional mod_headers module can be used to set custom headers
- in the HTTP response. It can append to existing headers, replace
- them, or remove headers from the response.
-
- *) Conditional Config Directives
- A new <IfModule> section allows directives to be enabled only if a
- given module is loaded into the server.
-
- *) Authorization Directives Now Use NCSA-style Syntax
- The AuthUserFile, AuthGroupFile and AuthDigestFile commands now
- have a syntax compatible with the NCSA server.
-
- *) Optional Proxy Module
- An improved FTP, HTTP, and CONNECT mode SSL proxy is included with
- Apache 1.2. Some of the changes visible to users:
-
- - Improved FTP proxy supporting PASV mode
- - CONNECT mode ports are configurable from a list
- - NoCache * directive for disabling proxy caching
- - Numerous bug fixes
-
- *) Optional Example Module
- An example module that demonstrates many of the aspects of the
- API is now included with Apache as of version 1.2. It can be
- used as a base for those who wish to write their own Apache
- modules.
diff --git a/usr.sbin/httpd/Makefile b/usr.sbin/httpd/Makefile
deleted file mode 100644
index 0cb40323986..00000000000
--- a/usr.sbin/httpd/Makefile
+++ /dev/null
@@ -1,116 +0,0 @@
-MAN = httpd.8
-SUBDIR+=src
-WWWROOT=/var/www
-CONFFILES= \
- conf/srm.conf-dist conf/access.conf-dist conf/httpd.conf-dist \
- conf/mime.types conf/access.conf conf/httpd.conf conf/srm.conf
-HTDOCS= \
- htdocs/apache_pb.gif htdocs/index.html htdocs/openbsdpower.gif
-CGIFILES= \
- cgi-bin/printenv cgi-bin/test-cgi
-MANUALFILES= \
- manual/images/home.gif manual/images/index.gif \
- manual/images/sub.gif manual/misc/API.html \
- manual/misc/known_bugs.html manual/misc/FAQ.html \
- manual/misc/known_client_problems.html \
- manual/misc/client_block_api.html manual/misc/nopgp.html \
- manual/misc/compat_notes.html manual/misc/perf-bsd44.html \
- manual/misc/descriptors.html manual/misc/perf-dec.html \
- manual/misc/fin_wait_2.html manual/misc/perf.html \
- manual/misc/footer.html manual/misc/security_tips.html \
- manual/misc/header.html manual/misc/vif-info.html \
- manual/misc/howto.html manual/misc/windoz_keepalive.html \
- manual/LICENSE manual/host.html manual/multilogs.html \
- manual/TODO manual/new_features_1_0.html \
- manual/bind.html manual/index.html \
- manual/new_features_1_1.html manual/cgi_path.html \
- manual/install.html manual/new_features_1_2.html \
- manual/content-negotiation.html manual/install_1_1.html \
- manual/process-model.html manual/custom-error.html \
- manual/invoking.html manual/stopping.html \
- manual/dns-caveats.html manual/keepalive.html \
- manual/suexec.html manual/env.html manual/location.html \
- manual/unixware.html manual/footer.html \
- manual/man-template.html manual/vhosts-in-depth.html \
- manual/handler.html manual/virtual-host.html \
- manual/header.html manual/mod/core.html \
- manual/mod/mod_auth_msql.html manual/mod/mod_include.html \
- manual/mod/directives.html manual/mod/mod_browser.html \
- manual/mod/mod_info.html manual/mod/footer.html \
- manual/mod/mod_cern_meta.html manual/mod/mod_log_agent.html \
- manual/mod/header.html manual/mod/mod_cgi.html \
- manual/mod/mod_log_common.html manual/mod/index.html \
- manual/mod/mod_cookies.html manual/mod/mod_log_config.html \
- manual/mod/mod_access.html manual/mod/mod_digest.html \
- manual/mod/mod_log_referer.html manual/mod/mod_actions.html \
- manual/mod/mod_dir.html manual/mod/mod_mime.html \
- manual/mod/mod_alias.html manual/mod/mod_dld.html \
- manual/mod/mod_negotiation.html manual/mod/mod_asis.html \
- manual/mod/mod_env.html manual/mod/mod_proxy.html \
- manual/mod/mod_auth.html manual/mod/mod_example.html \
- manual/mod/mod_rewrite.html manual/mod/mod_auth_anon.html \
- manual/mod/mod_expires.html manual/mod/mod_status.html \
- manual/mod/mod_auth_db.html manual/mod/mod_headers.html \
- manual/mod/mod_userdir.html manual/mod/mod_auth_dbm.html \
- manual/mod/mod_imap.html manual/mod/mod_usertrack.html
-ICONFILES= \
- icons/README icons/c.gif icons/hand.right.gif icons/pie2.gif \
- icons/sphere1.gif icons/a.gif icons/comp.blue.gif \
- icons/hand.up.gif icons/pie3.gif icons/sphere2.gif \
- icons/alert.black.gif icons/comp.gray.gif icons/icon.sheet.gif \
- icons/pie4.gif icons/tar.gif icons/alert.red.gif \
- icons/compressed.gif icons/image1.gif icons/pie5.gif \
- icons/tex.gif icons/apache_pb.gif icons/continued.gif \
- icons/image2.gif icons/pie6.gif icons/text.gif icons/back.gif \
- icons/dir.gif icons/image3.gif icons/pie7.gif \
- icons/transfer.gif icons/ball.gray.gif icons/down.gif \
- icons/index.gif icons/pie8.gif icons/unknown.gif \
- icons/ball.red.gif icons/dvi.gif icons/layout.gif \
- icons/portal.gif icons/up.gif icons/binary.gif icons/f.gif \
- icons/left.gif icons/ps.gif icons/uu.gif icons/binhex.gif \
- icons/folder.gif icons/link.gif icons/quill.gif \
- icons/uuencoded.gif icons/blank.gif icons/folder.open.gif \
- icons/movie.gif icons/right.gif icons/world1.gif \
- icons/bomb.gif icons/folder.sec.gif icons/p.gif \
- icons/screw1.gif icons/world2.gif icons/box1.gif \
- icons/forward.gif icons/patch.gif icons/screw2.gif \
- icons/box2.gif icons/generic.gif icons/pdf.gif \
- icons/script.gif icons/broken.gif icons/generic.red.gif \
- icons/pie0.gif icons/sound1.gif icons/burst.gif \
- icons/generic.sec.gif icons/pie1.gif icons/sound2.gif
-
-distribution:
- @-for i in ${CONFFILES}; do \
- j=`dirname $$i`; \
- echo "Installing ${DESTDIR}${WWWROOT}/$$i"; \
- ${INSTALL} ${INSTALL_COPY} -g ${BINGRP} -m 444 \
- ${.CURDIR}/$$i ${DESTDIR}${WWWROOT}/$$j/; \
- done
- @-for i in ${HTDOCS}; do \
- j=`dirname $$i`; \
- echo "Installing ${DESTDIR}${WWWROOT}/$$i"; \
- ${INSTALL} ${INSTALL_COPY} -g ${BINGRP} -m 444 \
- ${.CURDIR}/$$i ${DESTDIR}${WWWROOT}/$$j/; \
- done
- @-for i in ${MANUALFILES}; do \
- j=`dirname $$i`; \
- echo "Installing ${DESTDIR}${WWWROOT}/$$i"; \
- ${INSTALL} ${INSTALL_COPY} -g ${BINGRP} -m 444 \
- ${.CURDIR}/htdocs/$$i ${DESTDIR}${WWWROOT}/htdocs/$$j/; \
- done
- @-for i in ${CGIFILES}; do \
- j=`dirname $$i`; \
- echo "Installing ${DESTDIR}${WWWROOT}/$$i"; \
- ${INSTALL} ${INSTALL_COPY} -g ${BINGRP} -m 000 \
- ${.CURDIR}/$$i ${DESTDIR}${WWWROOT}/$$j/; \
- done
- @-for i in ${ICONFILES}; do \
- j=`dirname $$i`; \
- echo "Installing ${DESTDIR}${WWWROOT}/$$i"; \
- ${INSTALL} ${INSTALL_COPY} -g ${BINGRP} -m 444 \
- ${.CURDIR}/$$i ${DESTDIR}${WWWROOT}/$$j/; \
- done
-
-.include<bsd.obj.mk>
-.include<bsd.subdir.mk>
-.include<bsd.man.mk>
diff --git a/usr.sbin/httpd/htdocs/manual/TODO b/usr.sbin/httpd/htdocs/manual/TODO
deleted file mode 100644
index 975ac8e68ea..00000000000
--- a/usr.sbin/httpd/htdocs/manual/TODO
+++ /dev/null
@@ -1,4 +0,0 @@
-Documentation changes/enhancements needed:
-
-- Documentation for mod_expires
-- Documentation for Satisfy
diff --git a/usr.sbin/httpd/htdocs/manual/host.html b/usr.sbin/httpd/htdocs/manual/host.html
deleted file mode 100644
index 74639a5b5fb..00000000000
--- a/usr.sbin/httpd/htdocs/manual/host.html
+++ /dev/null
@@ -1,185 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
-<html><head>
-<title>Apache non-IP Virtual Hosts</title>
-</head>
-
-<!-- Background white, links blue (unvisited), navy (visited), red (active) -->
-<BODY
- BGCOLOR="#FFFFFF"
- TEXT="#000000"
- LINK="#0000FF"
- VLINK="#000080"
- ALINK="#FF0000"
->
-<DIV ALIGN="CENTER">
- <IMG SRC="images/sub.gif" ALT="[APACHE DOCUMENTATION]">
- <H3>
- Apache HTTP Server Version 1.2
- </H3>
-</DIV>
-
-<h1 ALIGN="CENTER">Apache non-IP Virtual Hosts</h1>
-
-<strong>See Also:</strong>
-<a href="virtual-host.html">Virtual Host Support</a>
-
-<hr>
-
-<h2>What is a Virtual Host</h2>
-
-<p>The "Virtual Host" refers to the practice of maintaining more than
-one server on one machine, as differentiated by their apparent
-hostname. For example, it is often desirable for companies sharing a
-web server to have their own domains, with web servers accessible as
-<code>www.company1.com</code> and <code>www.company2.com</code>,
-without requiring the user to know any extra path information.</p>
-
-<p>Apache was one of the first servers to support virtual hosts right
-out of the box, but since the base <code>HTTP</code> (HyperText
-Transport Protocol) standard does not allow any method for the server
-to determine the hostname it is being addressed as, Apache's virtual
-host support has required a separate IP address for each
-server. Documentation on using this approach (which still works very
-well) <a href="virtual-host.html">is available</a>.
-
-<p>While the approach described above works, with the available IP
-address space growing smaller, and the number of domains increasing,
-it is not the most elegant solution, and is hard to implement on some
-machines. The <code>HTTP/1.1</code> protocol contains a method for the
-server to identify what name it is being addressed as. Apache 1.1 and
-later support this approach as well as the traditional
-IP-address-per-hostname method.</p>
-
-<p>The benefits of using the new virtual host support is a practically
-unlimited number of servers, ease of configuration and use, and
-requires no additional hardware or software. The main disadvantage is
-that the user's browser must support this part of the protocol. The
-latest versions of many browsers (including Netscape Navigator 2.0 and
-later) do, but many browsers, especially older ones, do not. This can
-cause problems, although a possible solution is addressed below.</p>
-
-<h2>Using non-IP Virtual Hosts</h2>
-
-<p>Using the new virtual hosts is quite easy, and superficially looks
-like the old method. You simply add to one of the Apache configuration
-files (most likely <code>httpd.conf</code> or <code>srm.conf</code>)
-code similar to the following:</p>
-<pre>
- &lt;VirtualHost www.apache.org&gt;
- ServerName www.apache.org
- DocumentRoot /usr/web/apache
- &lt;/VirtualHost&gt;
-</pre>
-
-<p>Of course, any additional directives can (and should) be placed
-into the <code>&lt;VirtualHost&gt;</code> section. To make this work,
-all that is needed is to make sure that the <code>www.apache.org</code>
-DNS entry points to the same IP address as the main
-server. Optionally, you could simply use that IP address in the
-&lt;VirtualHost&gt; entry.</p>
-
-<p>Additionally, many servers may wish to be accessible by more than
-one name. For example, the Apache server might want to be accessible
-as <code>apache.org</code>, or <code>ftp.apache.org</code>, assuming
-the IP addresses pointed to the same server. In fact, one might want it
-so that all addresses at <code>apache.org</code> were picked up by the
-server. This is possible with the <code>ServerAlias</code>
-directive, placed inside the &lt;VirtualHost&gt; section. For
-example:</p>
-
-<pre>
- ServerAlias apache.org *.apache.org
-</pre>
-
-<p>Note that you can use <code>*</code> and <code>?</code> as wild-card
-characters.</p>
-
-<p>You also might need ServerAlias if you are serving local users who
-do not always include the domain name. For example, if local users are
-familiar with typing "www" or "www.physics" then you will need to add
-<code>ServerAlias www www.physics</code>. It isn't possible for the
-server to know what domain the client uses for their name resolution
-because the client doesn't provide that information in the request.</p>
-
-<h2>Security Considerations</h2>
-
-Apache allows all virtual hosts to be made accessible via the
-<code>Host:</code> header through all IP interfaces, even those which
-are configured to use different IP interfaces. For example, if the
-configuration for <code>www.foo.com</code> contained a virtual host
-section for <code>www.bar.com</code>, and <code>www.bar.com</code> was
-a separate IP interface, such that
-non-<code>Host:</code>-header-supporting browsers can use it, as
-before with Apache 1.0. If a request is made to
-<code>www.foo.com</code> and the request includes the header
-<code>Host: www.bar.com</code>, a page from <code>www.bar.com</code>
-will be sent.
-
-<P>
-
-This is a security concern if you are controlling access to a
-particular server based on IP-layer controls, such as from within a
-firewall or router. Let's say <code>www.bar.com</code> in the above
-example was instead an intra-net server called
-<code>private.foo.com</code>, and the router used by foo.com only let
-internal users access <code>private.foo.com</code>. Obviously,
-<code>Host:</code> header functionality now allows someone who has
-access to <code>www.foo.com</code> to get
-<code>private.foo.com</code>, if they send a <code>Host:
-private.foo.com</code> header. It is important to note that this
-condition exists only if you only implement this policy at the IP
-layer - all security controls used by Apache (i.e., <A
-HREF="mod/mod_access.html">allow, deny from,</A> etc.) are consistently
-respected.
-
-<h2>Compatibility with Older Browsers</h2>
-
-<p>As mentioned earlier, a majority of browsers do not send the
-required data for the new virtual hosts to work properly. These
-browsers will always be sent to the main server's pages. There is a
-workaround, albeit a slightly cumbersome one:</p>
-
-<p>To continue the <code>www.apache.org</code> example (Note: Apache's
-web server does not actually function in this manner), we might use the
-new <code>ServerPath</code> directive in the <code>www.apache.org</code> virtual host,
-for example:
-
-<pre>
- ServerPath /apache
-</pre>
-<p>What does this mean? It means that a request for any file beginning
-with "<code>/apache</code>" will be looked for in the Apache
-docs. This means that the pages can be accessed as
-<code>http://www.apache.org/apache/</code> for all browsers, although
-new browsers can also access it as
-<code>http://www.apache.org/</code>.</p>
-
-<p>In order to make this work, put a link on your main server's page
-to <code>http://www.apache.org/apache/</code> (Note: Do not use
-<code>http://www.apache.org/</code> - this would create an endless
-loop). Then, in the virtual host's pages, be sure to use either purely
-relative links (e.g. "<code>file.html</code>" or
-"<code>../icons/image.gif</code>" or links containing the prefacing
-<code>/apache/</code>
-(e.g. "<code>http://www.apache.org/apache/file.html</code>" or
-"<code>/apache/docs/1.1/index.html</code>").</p>
-
-<p>This requires a bit of
-discipline, but adherence to these guidelines will, for the most part,
-ensure that your pages will work with all browsers, new and old. When
-a new browser contacts <code>http://www.apache.org/</code>, they will
-be directly taken to the Apache pages. Older browsers will be able to
-click on the link from the main server, go to
-<code>http://www.apache.org/apache/</code>, and then access the
-pages.</p>
-
-<HR>
-<H3 ALIGN="CENTER">
- Apache HTTP Server Version 1.2
-</H3>
-
-<A HREF="./"><IMG SRC="images/index.gif" ALT="Index"></A>
-
-</BODY>
-</HTML>
-
diff --git a/usr.sbin/httpd/htdocs/manual/install_1_1.html b/usr.sbin/httpd/htdocs/manual/install_1_1.html
deleted file mode 100644
index f5f0f4d376c..00000000000
--- a/usr.sbin/httpd/htdocs/manual/install_1_1.html
+++ /dev/null
@@ -1,124 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
-<HTML>
-<HEAD>
-<TITLE>Compiling and Installing Apache</TITLE>
-</HEAD>
-
-<!-- Background white, links blue (unvisited), navy (visited), red (active) -->
-<BODY
- BGCOLOR="#FFFFFF"
- TEXT="#000000"
- LINK="#0000FF"
- VLINK="#000080"
- ALINK="#FF0000"
->
-<DIV ALIGN="CENTER">
- <IMG SRC="images/sub.gif" ALT="[APACHE DOCUMENTATION]">
- <H3>
- Apache HTTP Server Version 1.2
- </H3>
-</DIV>
-
-<h1 ALIGN="CENTER">Compiling and Installing Apache</h1>
-<h2>Downloading Apache</h2>
-<p>Information on the latest version of Apache can be found on the Apache
-web server at http://www.apache.org/. This will list the current release,
-any more recent beta-test release, together with details of mirror
-web and anonymous ftp sites.</p>
-
-UnixWare users will want to consult <A HREF="unixware.html">build notes</A>
-for various UnixWare versions before compiling.
-
-<h2>Compiling Apache</h2>
-This release of Apache supports the notion of `optional modules'.
-However, the server has to know which modules are compiled into it, in
-order for those modules to be effective; this requires generation of a
-short bit of code (`<code>modules.c</code>') which simply has a list of them.
-<p>
-If you are satisfied with our standard module set, and expect to
-continue to be satisfied with it, then you can just edit the stock
-<code>Makefile</code> and compile as you have been doing previously. If you
-would
-like to select optional modules, however, you need to run the
-configuration script.
-<p>
-To do this:
-<ol>
-<li>Edit the file `<code>Configuration</code>'. This contains the per-machine
-config settings of the Makefile, and also an additional section at
-the bottom which lists the modules which have been compiled in, and
-also names the files containing them. You will need to:
-<ol>
-<li> Select a compiler and compilation options as appropriate to
-your machine.
-<li> Uncomment lines corresponding to those optional modules you wish
-to include (among the Module lines at the bottom of the file)
-or add new lines corresponding to custom modules you have written.
-<p>
-Note that DBM auth has to be explicitly configured in, if you want
-it; just uncomment the corresponding line.
-</ol>
-<li> Run the `Configure' script:
-<blockquote><code>
-% Configure<br>
-Using 'Configuration' as config file<br>
-%</code></blockquote>
-
-This generates new versions of the Makefile and of modules.c. If
-you want to maintain multiple configurations, you can say, e.g.,
-<blockquote><code>
-% Configure -file Configuration.ai<br>
-Using alternate config file Configuration.ai<br>
-%</code></blockquote>
-
-<li>Type `make'.
-<p>
-The modules we place in the Apache distribution are the ones we have
-tested and are used regularly by various members of the Apache
-development group. Additional modules contributed by members or third
-parties with specific needs or functions are available at
-<A HREF="http://www.apache.org/dist/contrib/modules/">&lt;URL:http://www.apache.org/dist/contrib/modules/&gt;</A>. There are instructions on that page for
-linking these modules into the core Apache code.
-</ol>
-
-<h2>Installing Apache</h2>
-After compilation, you will have a binary called `httpd' in the
-<code>src/</code> directory. A binary distribution of Apache will supply this
-file.
-<p>
-The next step is to edit the configuration files for the server. In
-the subdirectory called `conf' you should find distribution versions
-of the three configuration files: <code>srm.conf-dist</code>,
-<code>access.conf-dist</code> and <code>httpd.conf-dist</code>. Copy them to
-<code>srm.conf</code>, <code>access.conf</code> and <code>httpd.conf</code>
-respectively.
-<p>
-First edit <code>httpd.conf</code>. This sets up general attributes about the
-server; the port number, the user it runs as, etc. Next edit the
-<code>srm.conf</code> file; this sets up the root of the document tree,
-special functions like server-parsed HTML or internal imagemap parsing, etc.
-Finally, edit the <code>access.conf</code> file to at least set the base cases
-of access.
-<p>
-Finally, make a call to httpd, with a -f to the full path to the
-httpd.conf file. I.e., the common case:
-<blockquote><code>
- /usr/local/etc/apache/src/httpd -f /usr/local/etc/apache/conf/httpd.conf
-</code></blockquote>
-The server should be now running.
-<p>
-By default the <code>srm.conf</code> and <code>access.conf</code> files are
-located by name; to specifically call them by other names, use the
-<A HREF="mod/core.html#accessconfig">AccessConfig</A> and
-<A HREF="mod/core.html#resourceconfig">ResourceConfig</A> directives in
-<code>httpd.conf</code>.
-
-<HR>
-<H3 ALIGN="CENTER">
- Apache HTTP Server Version 1.2
-</H3>
-
-<A HREF="./"><IMG SRC="images/index.gif" ALT="Index"></A>
-
-</BODY>
-</HTML>
diff --git a/usr.sbin/httpd/htdocs/manual/misc/known_bugs.html b/usr.sbin/httpd/htdocs/manual/misc/known_bugs.html
deleted file mode 100644
index 95bb37c705d..00000000000
--- a/usr.sbin/httpd/htdocs/manual/misc/known_bugs.html
+++ /dev/null
@@ -1,171 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
-<HTML>
-<HEAD>
-<TITLE>Apache HTTP Server Project</TITLE>
-</HEAD>
-
-<!-- Background white, links blue (unvisited), navy (visited), red (active) -->
-<BODY
- BGCOLOR="#FFFFFF"
- TEXT="#000000"
- LINK="#0000FF"
- VLINK="#000080"
- ALINK="#FF0000"
->
-<DIV ALIGN="CENTER">
- <IMG SRC="../images/sub.gif" ALT="[APACHE DOCUMENTATION]">
- <H3>
- Apache HTTP Server Version 1.2
- </H3>
-</DIV>
-
-<H1 ALIGN="CENTER">Known Bugs in Apache</H1>
-
-The most up-to-date resource for bug tracking and information is the
-<A HREF="http://www.apache.org/bugdb.cgi">Apache bug database</A>.
-Significant bugs at release time will also be noted there.
-If you are running a 1.2 beta release or version 1.1.3 or earlier
-and thing you have found a bug, please upgrade to 1.2. Many bugs
-in early versions have been fixed in 1.2.
-
-<P>See Also: <A HREF="compat_notes.html">Compatibility notes</A></P>
-<HR>
-
-<H2>Apache 1.2 Bugs</H2>
-
-<OL>
- <LI><b>Exists in 1.2.1 only.</b>
- On Solaris 2.x the server will stop running after receiving a
- SIGHUP. Four workarounds exist (choose one):<p>
- <ul>
- <li>Retrieve <a href="http://www.apache.org/dist/patches/apply_to_1.2.1/solaris_hup.patch">this patch</a>.
- <code>cd</code> to your <code>apache_1.2.1</code> directory, and
- type <code>patch -s -p1 < /path/to/patchfile</code>. Then rebuild
- Apache.<p>
- <li>Use SIGUSR1 instead of SIGHUP, see <a href="../stopping.html">
- Stopping and Restarting Apache</a> for more details.<p>
- <li>Add <code>-DNO_SLACK</code> to
- <code>EXTRA_CFLAGS</code> in
- your <code>Configuration</code> file, re-run <code>Configure</code>
- and rebuild your server. This disables the
- <a href="descriptors.html">descriptor slack workaround</a><p>
- <li>(Least preferable) Use Apache 1.2.0 instead of 1.2.1.<p>
- </ul>
- This problem will be tracked as
- <a href="http://www.apache.org/bugdb.cgi/full/832">PR#832</a>.<p>
- </li>
-
- <LI>(Exists in 1.2.0 and in 1.2.1 after either of the
- <code>NO_SLACK</code> or patch provided by the previous bug are applied.)
- Solaris 2.5.1 (and probably other versions of Solaris) appear to have
- a race condition completely unrelated to all the others. It is possible
- during a SIGHUP that the server will fail to start because it will not
- be able to re-open its sockets. To our knowledge this has only shown
- up during testing when we pummel the server with as many SIGHUP requests
- per second as we can. This appears unrelated to the similar sounding bug
- described in <a href="http://www.apache.org/bugdb.cgi/full/832">PR#832</a>.
- <p>
-
- <LI><a name="listenbug">On some architectures</A>
- if your configuration uses multiple
- <a href="../mod/core.html#listen">Listen</a> directives then it is possible
- that the server will starve one of the sockets while serving hits on
- another. The work-around is to add
- <code>-DUSE_FLOCK_SERIALIZED_ACCEPT</code> to the
- <code>EXTRA_CFLAGS</code> line in your Configuration and rebuild.
- (If you encounter problems with that, you can also try
- <code>-DUSE_FCNTL_SERIALIZED_ACCEPT</code>.)
- This affects any architecture that doesn't use one of the
- <code>USE_xxxxx_SERIALIZED_ACCEPT</code> definitions, see the
- source file <code>conf.h</code> for your architecture.
- This will be tracked as
- <a href="http://www.apache.org/bugdb.cgi/full/467">PR#467</a>.
- <P></LI>
-
- <LI><b>Fixed in 1.2.1.</b>
- <a name="cnegbug">Apache's</A> <A HREF="../content-negotiation.html">Content
- Negotiation</A> should pick the smallest variant if there
- are several that are equally acceptable. A bug in 1.2 means it no
- longer does this unless all the variants have character sets.
- This <A HREF="../../dist/contrib/patches/1.2/conneg-bug.patch">patch</A>
- fixes this problem. It also fixes the problem which makes Apache
- pick the last equally acceptable variant instead of the first.
- This will be tracked as
- <a href="http://www.apache.org/bugdb.cgi/full/94">PR#94</a>.
- <P></LI>
-
- <LI>
- The PATH_INFO part of a request URI cannot include the sequence
- <CODE>%2f</CODE>. This will be tracked as
- <A HREF="http://www.apache.org/bugdb.cgi/full/543">PR#543</A>.
- <P></LI>
-
- <LI>Users of early 1.2 betas reported problems with many
- connections stuck in the FIN_WAIT_2 state due to server
- timeouts. Several changes were made during the beta testing of 1.2
- to reduce this problem as much as possible, although you may still
- see sockets in FIN_WAIT_2 state due to network or operating system
- issues outside the control of Apache. See our <A
- HREF="fin_wait_2.html">FIN_WAIT_2</A> page for more details.
-
- <P>SunOS4 has a kernel bug in the allocation of memory for the mbuf table.
- When it fills up, the result is a Panic the next time any routine tries
- to set something in an imaginary mbuf beyond the range of the table.
- Due to buggy browser behavior and the lack of a FIN_WAIT_2 timeout
- on SunOS4, "KeepAlive Off" is necessary to avoid filling up the mbuf
- table on busy sites.
- <P></LI>
-
- <LI>Compilation fails on SCO3 when using gcc instead of cc, complaining
- with "<CODE>gcc: noinline: No such file or directory</CODE>". Fix
- is given in <a href="http://www.apache.org/bugdb.cgi/full/695">PR#695</A>.
- <P></LI>
-
- <LI>If compilation fails complaining about "unknown symbol __inet_ntoa()"
- then you have probably installed version 8 of bind. You will need to
- explicitly link with the bind library by adding <CODE>-lbind</CODE>
- to <CODE>EXTRA_LDFLAGS</CODE> in <CODE>Configuration</CODE>. See
- <A HREF="http://www.apache.org/bugdb.cgi/full/616">PR#616</A>
- and the
- <A HREF="FAQ.html#bind8.1">Apache FAQ</A>.
- <P></LI>
-
- <LI>The message "<CODE>created shared memory segment #730499</CODE>"
- in error_log is not an error and should be ignored. See
- <a href="http://www.apache.org/bugdb.cgi/full/696">PR#696</A>.
- <P></LI>
-
- <LI>
- Compiling on Solaris 2 with SunSoft's C compiler gives the warning
- <CODE>"mod_include.c", line 1123: warning: end-of-loop code not
- reached</CODE>. This is a bogus warning and can be ignored.
- See <A HREF="http://www.apache.org/bugdb.cgi/full/681">PR#681</A>.
- <P></LI>
-
- <LI><a href="descriptors.html"><b>Workaround available in 1.2.1.</b></a>
- There appears to be a problem on BSDI 2.1 with large numbers of
- virtual hosts. This appears similar to a file-descriptor limit
- but BSDI should not have this problem. This will be tracked as
- <A HREF="http://www.apache.org/bugdb.cgi/full/611">PR#611</A>.
- See also the <A HREF="FAQ.html#fdlim">Apache FAQ</A>.
- <P></LI>
-
- <LI><a href="descriptors.html"><b>Workaround available in 1.2.1.</b></a>
- Solaris 2 has problems with large numbers of virtual hosts. This is
- because of an operating system limit of 256 file pointers, not due
- to Apache. See also the <A HREF="FAQ.html#fdlim">Apache FAQ</A>.
- <P></LI>
-
-</OL>
-
-<HR>
-<H3 ALIGN="CENTER">
- Apache HTTP Server Version 1.2
-</H3>
-
-<A HREF="./"><IMG SRC="../images/index.gif" ALT="Index"></A>
-<A HREF="../"><IMG SRC="../images/home.gif" ALT="Home"></A>
-
-</BODY>
-</HTML>
-
diff --git a/usr.sbin/httpd/htdocs/manual/mod/mod_auth_msql.html b/usr.sbin/httpd/htdocs/manual/mod/mod_auth_msql.html
deleted file mode 100644
index 9e85f5d2cdd..00000000000
--- a/usr.sbin/httpd/htdocs/manual/mod/mod_auth_msql.html
+++ /dev/null
@@ -1,488 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
-<html>
-<head>
-<title>Module mod_auth_msql</title>
-</head>
-<!-- Background white, links blue (unvisited), navy (visited), red (active) -->
-<BODY
- BGCOLOR="#FFFFFF"
- TEXT="#000000"
- LINK="#0000FF"
- VLINK="#000080"
- ALINK="#FF0000"
->
-<DIV ALIGN="CENTER">
- <IMG SRC="../images/sub.gif" ALT="[APACHE DOCUMENTATION]">
- <H3>
- Apache HTTP Server Version 1.2
- </H3>
-</DIV>
-
-<H1 ALIGN="CENTER">Module mod_auth_msql</H1>
-
-This module is contained in the <code>mod_auth_msql.c</code> file and
-is compiled in by default. It allows access control using the public
-domain mSQL database <code><a
-href="ftp://ftp.bond.edu.au/pub/Minerva/msql">ftp://ftp.bond.edu.au/pub/Minerva/msql</a></code>,
-a fast but limited SQL engine which can be contacted over an internal
-Unix domain protocol as well as over normal TCP/IP socket
-communication. It is only available in Apache 1.1 and later. <p>
-
-<a href="#FullDescription">Full description</a> /
-<a href="#Example">Example</a> /
-<a href="#CompileTimeOptions">Compile time options</a> /
-<a href="#RevisionHistory">RevisionHistory</a> /
-<a href="#Person">Person to blame</a> /
-<a href="#Sourcecode">Sourcecode</a>
-<p>
-
-<hr><h2><a name="FullDescription">Full description of all tokens</a></h2>
-<dl>
-
-<code><dt>
-Auth_MSQLhost &lt; FQHN | IP Address | localhost &gt
-</dt></code><dd>
- Hostname of the machine running the mSQL demon. The effective uid
- of the server should be allowed access. If not given, or if it is
- the magic name <code>localhost</code>, it is passed to the mSQL library as a null
- pointer. This effectively forces it to use /dev/msql rather than the
- (slower) socket communication.
-</dd>
-
-<code><dt>
-Auth_MSQLdatabase &lt; mSQL database name &gt
-</dt></code><dd>
- Name of the database in which the following table(s) are contained (Quick check: use the
- mSQL command <code>relshow [&lt;hostname&gt dbase]</code> to verify the spelling of the
- database name).
-</dd>
-
-<code><dt>
-Auth_MSQLpwd_table &lt; mSQL table name &gt
-</dt></code><dd>
- Contains at least the fields with the username
- and the (encrypted) password. Each uid should only occur once in this table and
- for performance reasons should be a primary key.
- Normally this table is compulsory, but it is
- possible to use a fall-through to other methods
- and use the mSQL module for group control only.
- See the <a href="#Authoritative"><code>Auth_MSQL_Authoritative</code></a>
- directive below.
-</dd>
-
-<code><dt>
-Auth_MSQLgrp_table &lt; mSQL table name in the above database &gt
-</dt></code><dd>
- Contains at least the fields with the
- username and the groupname. A user which
- is in multiple groups has therefore
- multiple entries. There might be some performance
- problems associated with this and one
- might consider to have separate tables for each
- group (rather than all groups in one table) if
- your directory structure allows for it.
- One only need to specify this table when doing
- group control.
-</dd>
-
-<code><dt>
-Auth_MSQLuid_field &lt; mSQL field name &gt
-</dt></code><dd>
- Name of the field containing the username in the <code>
- Auth_MSQLpwd_table</code> and optionally in the <code>
- Auth_MSQLgrp_table</code> tables.
-</dd>
-
-<code><dt>
-Auth_MSQLpwd_field &lt; mSQL field name &gt
-</dt></code><dd>
- Fieldname for the passwords in the <code>
- Auth_MSQLpwd_table</code> table.
-</dd>
-
-<code><dt>
-Auth_MSQLgrp_field &lt; mSQL field name &gt
-</dt></code><dd>
- Fieldname for the groupname<br>
- Only the fields used need to be specified. When this
- module is compiled with the
- <a href="#VITEK"><code>BACKWARD_VITEK</code></a> option then
- the uid and pwd field names default to 'user' and 'password'.
- However you are strongly encouraged to always specify these values
- explicitly given the security issues involved.
-</dd>
-
-<code><dt>
-Auth_MSQL_nopasswd &lt; on | off &gt
-</dt></code><dd>
- Skip password comparison if passwd field is
- empty, i.e. allow any password. This is 'off'
- by default to ensure that an empty field
- in the mSQL table does not allow people in by
- default with a random password.
-</dd>
-
-<code><dt>
-<a name="Authoritative">Auth_MSQL_Authoritative &lt; on | off &gt</a>
-</dt></code><dd>
- Default is 'on'. When set 'on', there is no
- fall-through to other authorization methods. So if a
- user is not in the mSQL dbase table (and perhaps
- not in the right group) or has the password wrong, then
- he or she is denied access. When this directive is set to
- 'off', control is passed on to any other authorization
- modules, such as the basic auth module with the htpasswd
- file or the Unix-(g)dbm modules. The default is 'on'
- to avoid nasty 'fall-through' surprises. Be sure you
- know what you are doing when you decide to switch it off.
-</dd>
-
-<code><dt>
-Auth_MSQL_EncryptedPasswords &lt; on | off &gt
-</dt></code><dd>
- Default is 'on'. When set on, the values in the
- pwd_field are assumed to be crypt-ed using *your*
- machines 'crypt()' function and the incoming password
- is 'crypt'ed before comparison. When this function is
- 'off', the comparison is done directly with the plaintext
- entered password. (Yes, http-basic-auth does send the
- password as plaintext over the wire :-( ). The default
- is a sensible 'on', and I personally think that it is
- a *very-bad-idea* to change this. However a multi
- vendor or international environment (which sometimes
- leads to different crypts functions) might force you to.
-</dd>
-</dl>
-
-
-<hr><h2><a name="Example">Example</a></h2>
-
-An example mSQL table could be created with the following commands:
-<pre>
- % msqladmin create www <br>
- % msql www <br>
- -&gt; create table user_records ( <br>
- -&gt; User_id char(32) primary key, <br>
- -&gt; Cpasswd char(32), <br>
- -&gt; Xgroup char(32) <br>
- -&gt; ) \g <br>
- query OK <br>
- -&gt; \q <br>
- % <br>
-</pre><br>
-
-The <code>User_id</code> can be as long as desired. However some of the
-popular web browsers truncate names at or stop the user from entering
-names longer than 32 characters. Furthermore the 'crypt' function
-on your platform might impose further limits. Also use of
-the <code>require users uid [uid..]</code> directive in the
-<code>access.conf</code> file where the uid's are separated by
-spaces can possibly prohibit the use of spaces in your usernames.
-Also, please note the <a href="#MAX_FIELD_LEN"><code>MAX_FIELD_LEN</code></a>
-directive somewhere below.
-<p>
-To use the above, the following example could be in your
-<code>access.conf</code> file. Also there is a more elaborate description
-below this example.
-<p>
-
-<code>&lt;directory /web/docs/private&gt;</code>
-<p>
-
-<dl>
-<dt><code>
-Auth_MSQLhost localhost<br>
-</code></dt>
- <blockquote>or</blockquote>
-<dt><code>
-Auth_MSQLhost datab.machine.your.org
-</code></dt><dd>
- If this directive is omitted or set to <code>localhost</code>,
- it is assumed that Apache and the mSQL
- database run on the same (physical) machine and the faster
- /dev/msql communication channel will be used. Otherwise,
- it is the machine to contact by TCP/IP. Consult the mSQL
- documentation for more information.
-</dd>
-<p>
-
-<dt><code>
-Auth_MSQLdatabase www
-</code></dt><dd>
- The name of the database on the above machine,
- which contains *both* the tables for group and
- for user/passwords. Currently it is not possible
- to have these split over two databases. Make
- sure that the <code>msql.acl</code> (access control file) of
- mSQL does indeed allow the effective uid of the
- web server read access to this database. Check the
- httpd.conf file for this uid.
-</dd>
-
-<code><dt>
-Auth_MSQLpwd_table user_records
-</dt></code><dd>
- This is the table which contain the uid/password combination
- is specified.
-</dd>
-
-<code><dt>
-Auth_MSQLuid_field User_id <br>
-Auth_MSQLpwd_field Cpasswd
-</dt></code><dd>
- These two directive specify the field names in the <code>user_record</code>
- table. If this module is compiled with the <a href="#VITEK"><code>BACKWARD_VITEK</code></a>
- compatibility switch, the defaults <code>user</code> and <code>password</code> are
- assumed if you do not specify them. Currently the user_id field
- *MUST* be a primary key or one must ensure that each user only
- occurs <b>once</b> in the table. If a uid occurs twice access is
- denied by default; but see the <code><a href="#ONLY_ONCE">ONLY_ONCE</a></code>
- compiler directive for more information.
-</dd>
-
-<code><dt>
-Auth_MSQLgrp_table user_records <br>
-Auth_MSQLgrp_field Xgroup <br>
-</dt></code><dd>
- Optionally one can also specify a table which contains the
- user/group combinations. This can be the same table which
- also contains the username/password combinations. However
- if a user belongs to two or more groups, one will have to
- use a different table with multiple entries.
-</dd>
-
-<code><dt>
-Auth_MSQL_nopasswd off <br>
-Auth_MSQL_Authoritative on <br>
-Auth_MSQL_EncryptedPasswords on <br>
-</dt></code><dd>
- These three optional fields (all set to the sensible defaults,
- so you really do not have to enter them) are described in more
- detail below. If you choose to set these to any other values then
- the above, be very sure you understand the security implications and
- do verify that Apache does what you expect it to do.
-</dd>
-
-<code><dt>
-AuthName example mSQL realm <br>
-AuthType basic
-</dt></code>
-<dd>
- Normal Apache/NCSA tokens for access control
- <p>
- <code>&lt;limit get post head&gt</code><br>
- <code>order deny,allow </code><br>
- <code>allow from all </code><br>
- <p>
- <code>require valid-user </code><br>
- <ul><li><code>valid-user</code>; allow in any user which has a valid uid/passwd
- pair in the above pwd_table.
- </ul>
- or<br>
- <code>require user smith jones </code><br>
- <ul><li>Limit access to users who have a valid uid/passwd pair in the
- above pwd_table *and* whose uid is 'smith' or 'jones'. Do note that
- the uid's are separated by 'spaces' for historic (NCSA) reasons.
- So allowing uids with spaces might cause problems.
- </ul>
- <code>require group has_paid</code><br>
- <ul><li>Optionally also ensure that the uid has the value 'has_paid' in
- the group field in the group table.
- </ul>
- <code>&lt;limit&gt </code><br>
-</dd>
-</dl>
-
-
-<hr><h2><a name="CompileTimeOptions">Compile Time Options</a></h2>
-
-<dl>
-<dt><code>
-<a name="ONLY_ONCE">#define ONLY_ONCE 1</a>
-</code></dt><dd>
- If the mSQL table containing the uid/passwd combination does
- not have the uid field as a primary key, it is possible for the
- uid to occur more than once in the table with possibly different
- passwords. When this module is compiled with the <code>ONLY_ONCE</code>
- directive set, access is denied if the uid occurs more than once in the
- uid/passwd table. If you choose not to set it, the software takes
- the first pair returned and ignores any further pairs. The SQL
- statement used for this is<br>
- <p><code>"select password form pwd_table where user='UID'"</code><p>
- this might lead to unpredictable results. For this reason as well
- as for performance reasons you are strongly advised to make the
- uid field a primary key. Use at your own peril :-)
-</dd>
-
-<dt><code>
-<a name="KEEP_MSQL_CONNECTION_OPEN">#define KEEP_MSQL_CONNECTION_OPEN</a>
-</code></dt><dd>
- Normally the (TCP/IP) connection with the database is opened and
- closed for each SQL query. When the Apache web-server and the database
- are on the same machine, and /dev/msql is used this does not
- cause a serious overhead. However when your platform does not
- support this (see the mSQL documentation) or when the web server
- and the database are on different machines the overhead can be
- considerable. When the above directive is set defined the server leaves
- the connection open, i.e. no call to <code>msqlClose()</code>.
- If an error occurs an attempt is made to reopen the connection for
- the next http request.
- <p>
- This has a number of very serious drawbacks
- <ul><li> It costs 2 already rare file-descriptors for each child.
- <li> It costs msql-connections, typically one per child. The (compiled in)
- number of connections mSQL can handle is low, typically 6 or 12.
- which might prohibit access to the mSQL database for later
- processes.
- <li> When a child dies, it might not free that connection properly
- or quick enough.
- <li> When errors start to occur, connection/file-descriptor resources
- might become exhausted very quickly.
- </ul>
- <p>
- In short, use this at your own peril and only in a highly controlled and
- monitored environment.
-</dd>
-
-<dt><code>
-<a name="VITEK">
-#define BACKWARD_VITEK<br></a>
-#define VITEK_uid_name "user"<br>
-#define VITEK_gid_name "passwd"
-</code></dt><dd>
- A second mSQL auth module for Apache has also been developed by Vivek Khera
- &lt<a href="mailto:khera@kciLink.com"><code>khera@kciLink.com</code></a>&gt
- and was subsequently distributed with some early versions of Apache. It
- can be obtained from
- <code><a href="ftp://ftp.kcilink.com/pub/">ftp://ftp.kcilink.com/pub/mod_auth_msql.c*</a></code>.
- Older 'vitek' versions had the field/table names compiled in. Newer
- versions, v.1.11 have more <code>access.conf</code> configuration
- options. However these where chosen not to be in line the 'ewse'
- version of this module. Also, the 'vitek' module does not give group
- control or 'empty' password control.
- <p>
- To get things slightly more in line this version (0.9) should
- be backward compatible with the 'vitek' module by:
- <ul><li> Adding support for the <code>Auth_MSQL_EncryptedPasswords</code> on/off functionality
- <li> Adding support for the different spelling of the 4 configuration
- tokens for user-table-name, user/password-field-name and dbase-name.
- <li> Setting some field names to a default which used to be hard
- coded in in older 'vitek' modules.
- </ul>
- <p>
- If this troubles you, remove the 'BACKWARD_VITEK' define.
-</dd>
-
-<dt><code>
-<a name="MAX_FIELD_LEN">
-#define MAX_FIELD_LEN (64)<br>
-#define MAX_QUERY_LEN (32+24+MAX_FIELD_LEN*2+3*MSQL_FIELD_NAME_LEN+1*MSQL_TABLE_NAME_LEN)<br></a>
-</code></dt><dd>
- In order to avoid using the very large <code>HUGE_STRING_LENGTH</code>, the above two compile
- time directives are supplies. The <code>MAX_FIELD_LEN</code> contains the maximum number of
- characters in your user, password and group fields. The maximum query length is derived
- from those values.
- <p>
- We only do the following two queries:
- <ul><li>For the user/passwd combination
- <p><code>"select PWDFIELD from PWDTABLE where USERFIELD='UID'"</code><br>
- <li>Optionally for the user/group combination:
- <p><code>"select GROUPFIELD from GROUPTABLE where USERFIELD='UID' and GROUPFIELD='GID'"</code><br>
- </ul>
- <p>
- This leads to the above limit for the query string. We are ignoring escaping a wee bit here
- assuming not more than 24 escapes.)
-</dd>
-</dl>
-
-
-<hr><h2><a name="RevisionHistory">Revision History</a></h2>
-
-This version: 23 Nov 1995, 24 Feb 1996, 16 May 1996.
-
-<dl>
-
-<dt>Version 0.0<br></dt>
- <dd>First release
- </dd>
-<dt>Version 0.1<br></dt>
- <dd>Update to Apache 1.00
- </dd>
-<dt>Version 0.2<br></dt>
- <dd>Added lines which got missing God knows when
- and which did the valid-user authentication no good at all !
- </dd>
-<dt>Version 0.3<br></dt>
- <dd>Added '<code>Auth_MSQL_nopasswd</code>' option
- </dd>
-<dt>Version 0.4<br></dt>
- <dd>Cleaned out the error messages mess.
- </dd>
-<dt>Version 0.6<br></dt>
- <dd>Inconsistency with gid/grp in comment/token/source
- Make sure you really use '<code>Auth_MSQLgrp_field</code>'
- as indicated above.
- </dd>
-<dt>Version 0.7<br></dt>
- <dd><code>*host</code> to <code>host</code> fixed. Credits
- go to Rob Stout, &lt;stout@lava.et.tudelft.nl&gt; for
- spotting this one.
- </dd>
-<dt>Version 0.8<br></dt>
- <dd>Authoritative directive added. See above.
- </dd>
-<dt>Version 0.9<br></dt>
- <dd><code>palloc</code> return code check(s), should be
- backward compatible with 1.11 version of Vivek Khera
- &lt;khera@kciLink.com&gt; msql
- module, fixed broken err msg in group control, changed
- command table messages to make more sense when displayed
- in that new module management tool. Added
- <code>Auth_MSQL_EncryptedPasswords</code> on/off functionality.
- msqlClose() statements added upon error. Support for
- persistent connections with the mSQL database (riscy).
- Escaping of ' and \. Replaced some
- <code>MAX_STRING_LENGTH</code> claims.
- </dd>
-</dl>
-
-
-<hr><h2><a name="Person">Contact/person to blame</a></h2>
-
-This module was written for the
-<a href="http://ewse.ceo.org">European Wide Service Exchange</a> by
-&lt<a href="mailto:Dirk.vanGulik@jrc.it"><code>Dirk.vanGulik@jrc.it</code></a>&gt.
-Feel free to contact me if you have any problems, ice-creams or bugs. This
-documentation, courtesy of Nick Himba, <a href="mailto:himba@cs.utwente.nl">
-<code>&lt;himba@cs.utwente.nl&gt;</code></a>.
-<p>
-
-
-<hr><h2><a NAME="Sourcecode">Sourcecode</a></h2>
-
-The source code can be found at <a href="http://www.apache.org"><code>
-http://www.apache.org</code></a>. A snapshot of a development version
-usually resides at <a href="http://me-www.jrc.it/~dirkx/mod_auth_msql.c"><code>
-http://me-www.jrc.it/~dirkx/mod_auth_msql.c</code></a>. Please make sure
-that you always quote the version you use when filing a bug report.
-<p>
-Furthermore a test/demonstration suite (which assumes that you have
-both mSQL and Apache compiled and installed) is available at the contrib
-section of <a href="ftp://ftp.apache.org/apache/dist/contrib"><code>
-ftp://ftp.apache.org/apache/dist/contrib</code></a> or
-<a href="http://me-www.jrc.it/~dirkx/apache-msql-demo.tar.gz"><code>
-http://me-www.jrc.it/~dirkx/apache-msql-demo.tar.gz</code></a> and
-its <a href="http://me-www.jrc.it/~dirkx/apache-msql-demo"><code>
-README</code></a> file.
-
-<HR>
-<H3 ALIGN="CENTER">
- Apache HTTP Server Version 1.2
-</H3>
-
-<A HREF="./"><IMG SRC="../images/index.gif" ALT="Index"></A>
-<A HREF="../"><IMG SRC="../images/home.gif" ALT="Home"></A>
-
-</body>
-</html>
-
diff --git a/usr.sbin/httpd/htdocs/manual/vhosts-in-depth.html b/usr.sbin/httpd/htdocs/manual/vhosts-in-depth.html
deleted file mode 100644
index 0f87f775ed6..00000000000
--- a/usr.sbin/httpd/htdocs/manual/vhosts-in-depth.html
+++ /dev/null
@@ -1,398 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
-<html><head>
-<title>An In-Depth Discussion of VirtualHost Matching</title>
-</head>
-
-<!-- Background white, links blue (unvisited), navy (visited), red (active) -->
-<BODY
- BGCOLOR="#FFFFFF"
- TEXT="#000000"
- LINK="#0000FF"
- VLINK="#000080"
- ALINK="#FF0000"
->
-<DIV ALIGN="CENTER">
- <IMG SRC="images/sub.gif" ALT="[APACHE DOCUMENTATION]">
- <H3>
- Apache HTTP Server Version 1.2
- </H3>
-</DIV>
-
-<h1 ALIGN="CENTER">An In-Depth Discussion of VirtualHost Matching</h1>
-
-<p>This is a very rough document that was probably out of date the moment
-it was written. It attempts to explain exactly what the code does when
-deciding what virtual host to serve a hit from. It's provided on the
-assumption that something is better than nothing. The server version
-under discussion is Apache 1.2.
-
-<p>If you just want to &quot;make it work&quot; without understanding
-how, there's a <a href="#whatworks">What Works</a> section at the bottom.
-
-<h3>Config File Parsing</h3>
-
-<p>There is a main_server which consists of all the definitions appearing
-outside of <CODE>VirtualHost</CODE> sections. There are virtual servers,
-called <EM>vhosts</EM>, which are defined by
-<A
- HREF="mod/core.html#virtualhost"
-><SAMP>VirtualHost</SAMP></A>
-sections.
-
-<p>The directives
-<A
- HREF="mod/core.html#port"
-><SAMP>Port</SAMP></A>,
-<A
- HREF="mod/core.html#servername"
-><SAMP>ServerName</SAMP></A>,
-<A
- HREF="mod/core.html#serverpath"
-><SAMP>ServerPath</SAMP></A>,
-and
-<A
- HREF="mod/core.html#serveralias"
-><SAMP>ServerAlias</SAMP></A>
-can appear anywhere within the definition of
-a server. However, each appearance overrides the previous appearance
-(within that server).
-
-<p>The default value of the <code>Port</code> field for main_server
-is 80. The main_server has no default <code>ServerName</code>,
-<code>ServerPath</code>, or <code>ServerAlias</code>.
-
-<p>In the absence of any
-<A
- HREF="mod/core.html#listen"
-><SAMP>Listen</SAMP></A>
-directives, the (final if there
-are multiple) <code>Port</code> directive in the main_server indicates
-which port httpd will listen on.
-
-<p> The <code>Port</code> and <code>ServerName</code> directives for
-any server main or virtual are used when generating URLs such as during
-redirects.
-
-<p> Each address appearing in the <code>VirtualHost</code> directive
-can have an optional port. If the port is unspecified it defaults to
-the value of the main_server's most recent <code>Port</code> statement.
-The special port <SAMP>*</SAMP> indicates a wildcard that matches any port.
-Collectively the entire set of addresses (including multiple
-<SAMP>A</SAMP> record
-results from DNS lookups) are called the vhost's <EM>address set</EM>.
-
-<p> The magic <code>_default_</code> address has significance during
-the matching algorithm. It essentially matches any unspecified address.
-
-<p> After parsing the <code>VirtualHost</code> directive, the vhost server
-is given a default <code>Port</code> equal to the port assigned to the
-first name in its <code>VirtualHost</code> directive. The complete
-list of names in the <code>VirtualHost</code> directive are treated
-just like a <code>ServerAlias</code> (but are not overridden by any
-<code>ServerAlias</code> statement). Note that subsequent <code>Port</code>
-statements for this vhost will not affect the ports assigned in the
-address set.
-
-<p>
-All vhosts are stored in a list which is in the reverse order that
-they appeared in the config file. For example, if the config file is:
-
-<blockquote><pre>
- &lt;VirtualHost A&gt;
- ...
- &lt;/VirtualHost&gt;
-
- &lt;VirtualHost B&gt;
- ...
- &lt;/VirtualHost&gt;
-
- &lt;VirtualHost C&gt;
- ...
- &lt;/VirtualHost&gt;
-</pre></blockquote>
-
-Then the list will be ordered: main_server, C, B, A. Keep this in mind.
-
-<p>
-After parsing has completed, the list of servers is scanned, and various
-merges and default values are set. In particular:
-
-<ol>
-<li>If a vhost has no
- <A
- HREF="mod/core.html#serveradmin"
- ><code>ServerAdmin</code></A>,
- <A
- HREF="mod/core.html#resourceconfig"
- ><code>ResourceConfig</code></A>,
- <A
- HREF="mod/core.html#accessconfig"
- ><code>AccessConfig</code></A>,
- <A
- HREF="mod/core.html#timeout"
- ><code>Timeout</code></A>,
- <A
- HREF="mod/core.html#keepalivetimeout"
- ><code>KeepAliveTimeout</code></A>,
- <A
- HREF="mod/core.html#keepalive"
- ><code>KeepAlive</code></A>,
- <A
- HREF="mod/core.html#maxkeepaliverequests"
- ><code>MaxKeepAliveRequests</code></A>,
- or
- <A
- HREF="mod/core.html#sendbuffersize"
- ><code>SendBufferSize</code></A>
- directive then the respective value is
- inherited from the main_server. (That is, inherited from whatever
- the final setting of that value is in the main_server.)
-
-<li>The &quot;lookup defaults&quot; that define the default directory
- permissions
- for a vhost are merged with those of the main server. This includes
- any per-directory configuration information for any module.
-
-<li>The per-server configs for each module from the main_server are
- merged into the vhost server.
-</ol>
-
-Essentially, the main_server is treated as &quot;defaults&quot; or a
-&quot;base&quot; on
-which to build each vhost. But the positioning of these main_server
-definitions in the config file is largely irrelevant -- the entire
-config of the main_server has been parsed when this final merging occurs.
-So even if a main_server definition appears after a vhost definition
-it might affect the vhost definition.
-
-<p> If the main_server has no <code>ServerName</code> at this point,
-then the hostname of the machine that httpd is running on is used
-instead. We will call the <EM>main_server address set</EM> those IP
-addresses returned by a DNS lookup on the <code>ServerName</code> of
-the main_server.
-
-<p> Now a pass is made through the vhosts to fill in any missing
-<code>ServerName</code> fields and to classify the vhost as either
-an <EM>IP-based</EM> vhost or a <EM>name-based</EM> vhost. A vhost is
-considered a name-based vhost if any of its address set overlaps the
-main_server (the port associated with each address must match the
-main_server's <code>Port</code>). Otherwise it is considered an IP-based
-vhost.
-
-<p> For any undefined <code>ServerName</code> fields, a name-based vhost
-defaults to the address given first in the <code>VirtualHost</code>
-statement defining the vhost. Any vhost that includes the magic
-<SAMP>_default_</SAMP> wildcard is given the same <code>ServerName</code> as
-the main_server. Otherwise the vhost (which is necessarily an IP-based
-vhost) is given a <code>ServerName</code> based on the result of a reverse
-DNS lookup on the first address given in the <code>VirtualHost</code>
-statement.
-
-<p>
-
-<h3>Vhost Matching</h3>
-
-<p>
-The server determines which vhost to use for a request as follows:
-
-<p> <code>find_virtual_server</code>: When the connection is first made
-by the client, the local IP address (the IP address to which the client
-connected) is looked up in the server list. A vhost is matched if it
-is an IP-based vhost, the IP address matches and the port matches
-(taking into account wildcards).
-
-<p> If no vhosts are matched then the last occurrence, if it appears,
-of a <SAMP>_default_</SAMP> address (which if you recall the ordering of the
-server list mentioned above means that this would be the first occurrence
-of <SAMP>_default_</SAMP> in the config file) is matched.
-
-<p> In any event, if nothing above has matched, then the main_server is
-matched.
-
-<p> The vhost resulting from the above search is stored with data
-about the connection. We'll call this the <EM>connection vhost</EM>.
-The connection vhost is constant over all requests in a particular TCP/IP
-session -- that is, over all requests in a KeepAlive/persistent session.
-
-<p> For each request made on the connection the following sequence of
-events further determines the actual vhost that will be used to serve
-the request.
-
-<p> <code>check_fulluri</code>: If the requestURI is an absoluteURI, that
-is it includes <code>http://hostname/</code>, then an attempt is made to
-determine if the hostname's address (and optional port) match that of
-the connection vhost. If it does then the hostname portion of the URI
-is saved as the <EM>request_hostname</EM>. If it does not match, then the
-URI remains untouched. <STRONG>Note</STRONG>: to achieve this address
-comparison,
-the hostname supplied goes through a DNS lookup unless it matches the
-<code>ServerName</code> or the local IP address of the client's socket.
-
-<p> <code>parse_uri</code>: If the URI begins with a protocol
-(<EM>i.e.</EM>, <code>http:</code>, <code>ftp:</code>) then the request is
-considered a proxy request. Note that even though we may have stripped
-an <code>http://hostname/</code> in the previous step, this could still
-be a proxy request.
-
-<p> <code>read_request</code>: If the request does not have a hostname
-from the earlier step, then any <code>Host:</code> header sent by the
-client is used as the request hostname.
-
-<p> <code>check_hostalias</code>: If the request now has a hostname,
-then an attempt is made to match for this hostname. The first step
-of this match is to compare any port, if one was given in the request,
-against the <code>Port</code> field of the connection vhost. If there's
-a mismatch then the vhost used for the request is the connection vhost.
-(This is a bug, see observations.)
-
-<p>
-If the port matches, then httpd scans the list of vhosts starting with
-the next server <STRONG>after</STRONG> the connection vhost. This scan does not
-stop if there are any matches, it goes through all possible vhosts,
-and in the end uses the last match it found. The comparisons performed
-are as follows:
-
-<ul>
-<li>Compare the request hostname:port with the vhost
- <code>ServerName</code> and <code>Port</code>.
-
-<li>Compare the request hostname against any and all addresses given in
- the <code>VirtualHost</code> directive for this vhost.
-
-<li>Compare the request hostname against the <code>ServerAlias</code>
- given for the vhost.
-</ul>
-
-<p>
-<code>check_serverpath</code>: If the request has no hostname
-(back up a few paragraphs) then a scan similar to the one
-in <code>check_hostalias</code> is performed to match any
-<code>ServerPath</code> directives given in the vhosts. Note that the
-<STRONG>last match</STRONG> is used regardless (again consider the ordering of
-the virtual hosts).
-
-<h3>Observations</h3>
-
-<ul>
-
-<li>It is difficult to define an IP-based vhost for the machine's
- &quot;main IP address&quot;. You essentially have to create a bogus
- <code>ServerName</code> for the main_server that does not match the
- machine's IPs.
-
-<li>During the scans in both <code>check_hostalias</code> and
- <code>check_serverpath</code> no check is made that the vhost being
- scanned is actually a name-based vhost. This means, for example, that
- it's possible to match an IP-based vhost through another address. But
- because the scan starts in the vhost list at the first vhost that
- matched the local IP address of the connection, not all IP-based vhosts
- can be matched.
-
- <p>Consider the config file above with three vhosts A, B, C. Suppose
- that B is a named-based vhost, and A and C are IP-based vhosts. If
- a request comes in on B or C's address containing a header
- &quot;<SAMP>Host: A</SAMP>&quot; then
- it will be served from A's config. If a request comes in on A's
- address then it will always be served from A's config regardless of
- any Host: header.
- </p>
-
-<li>Unless you have a <SAMP>_default_</SAMP> vhost,
- it doesn't matter if you mix name-based vhosts in amongst IP-based
- vhosts. During the <code>find_virtual_server</code> phase above no
- named-based vhost will be matched, so the main_server will remain the
- connection vhost. Then scans will cover all vhosts in the vhost list.
-
- <p>If you do have a <SAMP>_default_</SAMP> vhost, then you cannot place
- named-based vhosts after it in the config. This is because on any
- connection to the main server IPs the connection vhost will always be
- the <SAMP>_default_</SAMP> vhost since none of the name-based are
- considered during <code>find_virtual_server</code>.
- </p>
-
-<li>You should never specify DNS names in <code>VirtualHost</code>
- directives because it will force your server to rely on DNS to boot.
- Furthermore it poses a security threat if you do not control the
- DNS for all the domains listed.
- <a href="dns-caveats.html">
- There's more information
- available on this and the next two topics</a>.</p>
-
-<li><code>ServerName</code> should always be set for each vhost. Otherwise
- A DNS lookup is required for each vhost.</p>
-
-<li>A DNS lookup is always required for the main_server's
- <code>ServerName</code> (or to generate that if it isn't specified
- in the config).</p>
-
-<li>If a <code>ServerPath</code> directive exists which is a prefix of
- another <code>ServerPath</code> directive that appears later in
- the configuration file, then the former will always be matched
- and the latter will never be matched. (That is assuming that no
- Host header was available to disambiguate the two.)</p>
-
-<li>If a vhost that would otherwise be a name-vhost includes a
- <code>Port</code> statement that doesn't match the main_server
- <code>Port</code> then it will be considered an IP-based vhost.
- Then <code>find_virtual_server</code> will match it (because
- the ports associated with each address in the address set default
- to the port of the main_server) as the connection vhost. Then
- <code>check_hostalias</code> will refuse to check any other name-based
- vhost because of the port mismatch. The result is that the vhost
- will steal all hits going to the main_server address.</p>
-
-<li>If two IP-based vhosts have an address in common, the vhost appearing
- later in the file is always matched. Such a thing might happen
- inadvertently. If the config has name-based vhosts and for some reason
- the main_server <code>ServerName</code> resolves to the wrong address
- then all the name-based vhosts will be parsed as ip-based vhosts.
- Then the last of them will steal all the hits.</P>
-
-<li>The last name-based vhost in the config is always matched for any hit
- which doesn't match one of the other name-based vhosts.</p>
-
-</ul>
-
-<h3><a name="whatworks">What Works</a></h3>
-
-<p>In addition to the tips on the <a href="dns-caveats.html#tips">DNS
-Issues</a> page, here are some further tips:
-
-<ul>
-
-<li>Place all main_server definitions before any VirtualHost definitions.
-(This is to aid the readability of the configuration -- the post-config
-merging process makes it non-obvious that definitions mixed in around
-virtualhosts might affect all virtualhosts.)
-<p>
-
-<li>Arrange your VirtualHosts such
-that all name-based virtual hosts come first, followed by IP-based
-virtual hosts, followed by any <SAMP>_default_</SAMP> virtual host
-<p>
-
-<li>Avoid <code>ServerPaths</code> which are prefixes of other
-<code>ServerPaths</code>. If you cannot avoid this then you have to
-ensure that the longer (more specific) prefix vhost appears earlier in
-the configuration file than the shorter (less specific) prefix
-(<EM>i.e.</EM>, &quot;ServerPath /abc&quot; should appear after
-&quot;ServerPath /abcdef&quot;).
-<p>
-
-<li>Do not use <i>port-based</i> vhosts in the same server as
-name-based vhosts. A loose definition for port-based is a vhost which
-is determined by the port on the server (<em>i.e.</em> one server with
-ports 8000, 8080, and 80 all of which have different configurations).
-<p>
-
-</ul>
-
-<HR>
-<H3 ALIGN="CENTER">
- Apache HTTP Server Version 1.2
-</H3>
-
-<A HREF="./"><IMG SRC="images/index.gif" ALT="Index"></A>
-
-</BODY>
-</HTML>
diff --git a/usr.sbin/httpd/htdocs/manual/virtual-host.html b/usr.sbin/httpd/htdocs/manual/virtual-host.html
deleted file mode 100644
index d21ac708fd8..00000000000
--- a/usr.sbin/httpd/htdocs/manual/virtual-host.html
+++ /dev/null
@@ -1,216 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
-<html>
-<head>
-<title>Apache Server Virtual Host Support</title>
-</head>
-
-<!-- Background white, links blue (unvisited), navy (visited), red (active) -->
-<BODY
- BGCOLOR="#FFFFFF"
- TEXT="#000000"
- LINK="#0000FF"
- VLINK="#000080"
- ALINK="#FF0000"
->
-<DIV ALIGN="CENTER">
- <IMG SRC="images/sub.gif" ALT="[APACHE DOCUMENTATION]">
- <H3>
- Apache HTTP Server Version 1.2
- </H3>
-</DIV>
-
-<h1 ALIGN="CENTER">Virtual Host Support</h1>
-
-<strong>See Also:</strong>
-<a href="host.html">Non-IP based virtual hosts</a>
-
-<h2>What are virtual hosts?</h2>
-This is the ability of a single machine to be a web server for multiple
-domains. For example, an Internet service provider might have a machine
-called <code>www.serve.com</code> which provides Web space for several
-organizations including, say, <em>smallco</em> and <em>baygroup</em>.
-Ordinarily, these groups would be given parts of the Web tree on www.serve.com.
-So smallco's home page would have the URL
-<blockquote>
-http://www.serve.com/smallco/
-</blockquote>
-and baygroup's home page would have the URL
-<blockquote>
-http://www.serve.com/baygroup/
-</blockquote>
-<p>
-For esthetic reasons, however, both organizations would rather their home
-pages appeared under their own names rather than that of the service
-provider's; but they do not want to set up their own Internet links and
-servers.
-<p>
-Virtual hosts are the solution to this problem. smallco and baygroup would
-have their own Internet name registrations, <code>www.smallco.com</code> and
-<code>www.baygroup.org</code> respectively. These hostnames would both
-correspond to the service provider's machine (www.serve.com). Thus
-smallco's home page would now have the URL
-<blockquote>
-http://www.smallco.com/
-</blockquote>
-and baygroup's home page would would have the URL
-<blockquote>
-http://www.baygroup.org/
-</blockquote>
-
-<h2>System requirements</h2>
-Due to limitations in the HTTP/1.0 protocol, the web server <strong>must have a
-different IP address for each virtual host</strong>. This can be achieved
-by the machine having several physical network connections, or by use
-of a <a href="misc/vif-info.html">virtual interface</a> on some operating systems.
-
-<h2>How to set up Apache</h2>
-There are two ways of configuring apache to support multiple hosts.
-Either by running a separate httpd daemon for each hostname, or by running a
-single daemon which supports all the virtual hosts.
-<p>
-Use multiple daemons when:
-<ul>
-<li>The different virtual hosts need very different httpd configurations, such
- as different values for: <A HREF="mod/core.html#servertype">ServerType</A>,
- <A HREF="mod/core.html#user">User</A>,
- <A HREF="mod/core.html#group">Group</A>,
- <A HREF="mod/mod_mime.html#typesconfig">TypesConfig</A> or
- <A HREF="mod/core.html#serverroot">ServerRoot</A>.
-<li>The machine does not process a very high request rate.
-</ul>
-Use a single daemon when:
-<ul>
-<li>Sharing of the httpd configuration between virtual hosts is acceptable.
-<li>The machine services a large number of requests, and so the performance
- loss in running separate daemons may be significant.
-</ul>
-
-<h2>Setting up multiple daemons</h2>
-Create a separate httpd installation for each virtual host.
-For each installation, use the
-<A HREF="mod/core.html#bindaddress">BindAddress</A> directive in the configuration
-file to select which IP address (or virtual host) that daemon services.
-e.g.
-<blockquote><code>BindAddress www.smallco.com</code></blockquote>
-This hostname can also be given as an IP address.
-
-<h2>Setting up a single daemon</h2>
-For this case, a single httpd will service requests for all the virtual hosts.
-The <A HREF="mod/core.html#virtualhost">VirtualHost</A> directive in the
- configuration file is used to set the values of
-<A HREF="mod/core.html#serveradmin">ServerAdmin</A>,
-<A HREF="mod/core.html#servername">ServerName</A>,
-<A HREF="mod/core.html#documentroot">DocumentRoot</A>,
-<A HREF="mod/core.html#errorlog">ErrorLog</A> and
-<A HREF="mod/mod_log_common.html#transferlog">TransferLog</A> configuration
-directives to different values for each virtual host.
-e.g.
-<blockquote><code>
-&lt;VirtualHost www.smallco.com&gt;<br>
-ServerAdmin webmaster@mail.smallco.com<br>
-DocumentRoot /groups/smallco/www<br>
-ServerName www.smallco.com<br>
-ErrorLog /groups/smallco/logs/error_log<br>
-TransferLog /groups/smallco/logs/access_log<br>
-&lt;/VirtualHost&gt;<br>
-<br>
-&lt;VirtualHost www.baygroup.org&gt;<br>
-ServerAdmin webmaster@mail.baygroup.org<br>
-DocumentRoot /groups/baygroup/www<br>
-ServerName www.baygroup.org<br>
-ErrorLog /groups/baygroup/logs/error_log<br>
-TransferLog /groups/baygroup/logs/access_log<br>
-&lt;/VirtualHost&gt;<br>
-</code></blockquote>
-
-This VirtualHost hostnames can also be given as IP addresses.
-
-<P>
-
-Almost <strong>ANY</strong> configuration directive can be put
-in the VirtualHost directive, with the exception of
-<A HREF="mod/core.html#servertype">ServerType</A>,
-<A HREF="mod/core.html#user">User</A>,
-<A HREF="mod/core.html#group">Group</A>,
-<A HREF="mod/core.html#startservers">StartServers</A>,
-<A HREF="mod/core.html#maxspareservers">MaxSpareServers</A>,
-<A HREF="mod/core.html#minspareservers">MinSpareServers</A>,
-<A HREF="mod/core.html#maxrequestsperchild">MaxRequestsPerChild</A>,
-<A HREF="mod/core.html#bindaddress">BindAddress</A>,
-<A HREF="mod/core.html#pidfile">PidFile</A>,
-<A HREF="mod/mod_mime.html#typesconfig">TypesConfig</A>, and
-<A HREF="mod/core.html#serverroot">ServerRoot</A>.
-
-<P>
-
-<EM>SECURITY:</EM> When specifying where to write log files, be aware
-of some security risks which are present if anyone other than the
-user that starts Apache has write access to the directory where they
-are written. See the <A HREF="misc/security_tips.html">security
-tips</A> document for details.
-
-<P>
-
-<H2>File Handle/Resource Limits:</H2>
-When using a large number of Virtual Hosts, Apache may run out of available
-file descriptors if each Virtual Host specifies different log files.
-The total number of file descriptors used by Apache is one for each distinct
-error log file, one for every other log file directive, plus 10-20 for
-internal use. Unix operating systems limit the number of file descriptors that
-may be used by a process; the limit is typically 64, and may usually be
-increased up to a large hard-limit.
-<p>
-Although Apache attempts to increase the limit as required, this
-may not work if:
-<ol>
-<li>Your system does not provide the setrlimit() system call.
-<li>The setrlimit(RLIMIT_NOFILE) call does not function on your system
- (such as Solaris 2.3)
-<li>The number of file descriptors required exceeds the hard limit.
-<li>Your system imposes other limits on file descriptors, such as a limit
-on stdio streams only using file descriptors below 256. (Solaris 2)
-</ol>
-
-In the event of problems you can:
-<ul>
-<li>Reduce the number of log files; don't specify log files in the VirtualHost
-sections, but only log to the main log files.
-<li>If you system falls into 1 or 2 (above), then increase the file descriptor
-limit before starting Apache, using a script like
-<blockquote><code>
-#!/bin/sh <br>
-ulimit -S -n 100 <br>
-exec httpd</code></blockquote>
-</ul>
-
-The have been reports that Apache may start running out of resources allocated
-for the root process. This will exhibit itself as errors in the error log like
-"unable to fork". There are two ways you can bump this up:
-
-<OL>
-<LI>Have a <code>csh</code> script wrapper around httpd which sets the
-"rlimit" to some large number, like 512.
-<LI>Edit http_main.c to add calls to setrlimit() from main(), along the lines of
-<PRE>
- struct rlimit rlp;
-
- rlp.rlim_cur = rlp.rlim_max = 512;
- if (setrlimit(RLIMIT_NPROC, &rlp)) {
- fprintf(stderr, "setrlimit(RLIMIT_NPROC) failed.\n");
- exit(1);
- }
-</PRE>
-(thanks to "Aaron Gifford &lt;agifford@InfoWest.COM&gt;" for the patch)
-</OL>
-
-The latter will probably manifest itself in a later version of Apache.
-
-<HR>
-<H3 ALIGN="CENTER">
- Apache HTTP Server Version 1.2
-</H3>
-
-<A HREF="./"><IMG SRC="images/index.gif" ALT="Index"></A>
-
-</body></html>
-
diff --git a/usr.sbin/httpd/src/.indent.pro b/usr.sbin/httpd/src/.indent.pro
deleted file mode 100644
index 77b65f3d6a7..00000000000
--- a/usr.sbin/httpd/src/.indent.pro
+++ /dev/null
@@ -1 +0,0 @@
--i4 -npsl -di0 -br -nce -d0 -cli0 -npcs
diff --git a/usr.sbin/httpd/src/alloc.c b/usr.sbin/httpd/src/alloc.c
deleted file mode 100644
index d002a6f8f8c..00000000000
--- a/usr.sbin/httpd/src/alloc.c
+++ /dev/null
@@ -1,1142 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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/>.
- *
- */
-
-
-/*
- * Resource allocation code... the code here is responsible for making
- * sure that nothing leaks.
- *
- * rst --- 4/95 --- 6/95
- */
-
-#include "httpd.h"
-
-#include <stdarg.h>
-
-/*****************************************************************
- *
- * Managing free storage blocks...
- */
-
-union align
-{
- /* Types which are likely to have the longest RELEVANT alignment
- * restrictions...
- */
-
- char *cp;
- void (*f)();
- long l;
- FILE *fp;
- double d;
-};
-
-#define CLICK_SZ (sizeof(union align))
-
-union block_hdr
-{
- union align a;
-
- /* Actual header... */
-
- struct {
- char *endp;
- union block_hdr *next;
- char *first_avail;
- } h;
-};
-
-union block_hdr *block_freelist = NULL;
-
-
-
-/* Get a completely new block from the system pool. Note that we rely on
-malloc() to provide aligned memory. */
-
-union block_hdr *malloc_block (int size)
-{
- union block_hdr *blok =
- (union block_hdr *)malloc(size + sizeof(union block_hdr));
-
- if (blok == NULL) {
- fprintf (stderr, "Ouch! malloc failed in malloc_block()\n");
- exit (1);
- }
- blok->h.next = NULL;
- blok->h.first_avail = (char *)(blok + 1);
- blok->h.endp = size + blok->h.first_avail;
-
- return blok;
-}
-
-
-
-void chk_on_blk_list (union block_hdr *blok, union block_hdr *free_blk)
-{
- /* Debugging code. Left in for the moment. */
-
- while (free_blk) {
- if (free_blk == blok) {
- fprintf (stderr, "Ouch! Freeing free block\n");
- exit (1);
- }
- free_blk = free_blk->h.next;
- }
-}
-
-/* Free a chain of blocks --- must be called with alarms blocked. */
-
-void free_blocks (union block_hdr *blok)
-{
- /* First, put new blocks at the head of the free list ---
- * we'll eventually bash the 'next' pointer of the last block
- * in the chain to point to the free blocks we already had.
- */
-
- union block_hdr *old_free_list = block_freelist;
-
- if (blok == NULL) return; /* Sanity check --- freeing empty pool? */
-
- block_freelist = blok;
-
- /*
- * Next, adjust first_avail pointers of each block --- have to do it
- * sooner or later, and it simplifies the search in new_block to do it
- * now.
- */
-
- while (blok->h.next != NULL) {
- chk_on_blk_list (blok, old_free_list);
- blok->h.first_avail = (char *)(blok + 1);
- blok = blok->h.next;
- }
-
- chk_on_blk_list (blok, old_free_list);
- blok->h.first_avail = (char *)(blok + 1);
-
- /* Finally, reset next pointer to get the old free blocks back */
-
- blok->h.next = old_free_list;
-}
-
-
-
-
-/* Get a new block, from our own free list if possible, from the system
- * if necessary. Must be called with alarms blocked.
- */
-
-union block_hdr *new_block (int min_size)
-{
- union block_hdr **lastptr = &block_freelist;
- union block_hdr *blok = block_freelist;
-
- /* First, see if we have anything of the required size
- * on the free list...
- */
-
- while (blok != NULL) {
- if (min_size + BLOCK_MINFREE <= blok->h.endp - blok->h.first_avail) {
- *lastptr = blok->h.next;
- blok->h.next = NULL;
- return blok;
- }
- else {
- lastptr = &blok->h.next;
- blok = blok->h.next;
- }
- }
-
- /* Nope. */
-
- min_size += BLOCK_MINFREE;
- return malloc_block((min_size > BLOCK_MINALLOC) ? min_size : BLOCK_MINALLOC);
-}
-
-
-
-/* Accounting */
-
-long bytes_in_block_list (union block_hdr *blok)
-{
- long size = 0;
-
- while (blok) {
- size += blok->h.endp - (char *)(blok + 1);
- blok = blok->h.next;
- }
-
- return size;
-}
-
-
-/*****************************************************************
- *
- * Pool internals and management...
- * NB that subprocesses are not handled by the generic cleanup code,
- * basically because we don't want cleanups for multiple subprocesses
- * to result in multiple three-second pauses.
- */
-
-struct process_chain;
-struct cleanup;
-
-static void run_cleanups (struct cleanup *);
-static void free_proc_chain (struct process_chain *);
-
-struct pool {
- union block_hdr *first;
- union block_hdr *last;
- struct cleanup *cleanups;
- struct process_chain *subprocesses;
- struct pool *sub_pools;
- struct pool *sub_next;
- struct pool *sub_prev;
- struct pool *parent;
- char *free_first_avail;
-};
-
-pool *permanent_pool;
-
-/* Each pool structure is allocated in the start of its own first block,
- * so we need to know how many bytes that is (once properly aligned...).
- * This also means that when a pool's sub-pool is destroyed, the storage
- * associated with it is *completely* gone, so we have to make sure it
- * gets taken off the parent's sub-pool list...
- */
-
-#define POOL_HDR_CLICKS (1 + ((sizeof(struct pool) - 1) / CLICK_SZ))
-#define POOL_HDR_BYTES (POOL_HDR_CLICKS * CLICK_SZ)
-
-struct pool *make_sub_pool (struct pool *p)
-{
- union block_hdr *blok;
- pool *new_pool;
-
- block_alarms();
-
- blok = new_block (0);
- new_pool = (pool *)blok->h.first_avail;
- blok->h.first_avail += POOL_HDR_BYTES;
-
- memset ((char *)new_pool, '\0', sizeof (struct pool));
- new_pool->free_first_avail = blok->h.first_avail;
- new_pool->first = new_pool->last = blok;
-
- if (p) {
- new_pool->parent = p;
- new_pool->sub_next = p->sub_pools;
- if (new_pool->sub_next) new_pool->sub_next->sub_prev = new_pool;
- p->sub_pools = new_pool;
- }
-
- unblock_alarms();
-
- return new_pool;
-}
-
-void init_alloc() { permanent_pool = make_sub_pool (NULL); }
-
-void clear_pool (struct pool *a)
-{
- block_alarms();
-
- while (a->sub_pools)
- destroy_pool (a->sub_pools);
-
- a->sub_pools = NULL;
-
- run_cleanups (a->cleanups); a->cleanups = NULL;
- free_proc_chain (a->subprocesses); a->subprocesses = NULL;
- free_blocks (a->first->h.next); a->first->h.next = NULL;
-
- a->last = a->first;
- a->first->h.first_avail = a->free_first_avail;
-
- unblock_alarms();
-}
-
-void destroy_pool (pool *a)
-{
- block_alarms();
- clear_pool (a);
-
- if (a->parent) {
- if (a->parent->sub_pools == a) a->parent->sub_pools = a->sub_next;
- if (a->sub_prev) a->sub_prev->sub_next = a->sub_next;
- if (a->sub_next) a->sub_next->sub_prev = a->sub_prev;
- }
-
- free_blocks (a->first);
- unblock_alarms();
-}
-
-long bytes_in_pool (pool *p) { return bytes_in_block_list (p->first); }
-long bytes_in_free_blocks () { return bytes_in_block_list (block_freelist); }
-
-/*****************************************************************
- *
- * Allocating stuff...
- */
-
-
-void *palloc (struct pool *a, int reqsize)
-{
- /* Round up requested size to an even number of alignment units (core clicks)
- */
-
- int nclicks = 1 + ((reqsize - 1) / CLICK_SZ);
- int size = nclicks * CLICK_SZ;
-
- /* First, see if we have space in the block most recently
- * allocated to this pool
- */
-
- union block_hdr *blok = a->last;
- char *first_avail = blok->h.first_avail;
- char *new_first_avail;
-
- if(reqsize <= 0)
- return NULL;
-
- new_first_avail = first_avail + size;
-
- if (new_first_avail <= blok->h.endp) {
- blok->h.first_avail = new_first_avail;
- return (void *)first_avail;
- }
-
- /* Nope --- get a new one that's guaranteed to be big enough */
-
- block_alarms();
- blok = new_block (size);
- a->last->h.next = blok;
- a->last = blok;
- unblock_alarms();
-
- first_avail = blok->h.first_avail;
- blok->h.first_avail += size;
-
- return (void *)first_avail;
-}
-
-void *pcalloc(struct pool *a, int size)
-{
- void *res = palloc (a, size);
- memset (res, '\0', size);
- return res;
-}
-
-char *pstrdup(struct pool *a, const char *s)
-{
- char *res;
- if (s == NULL) return NULL;
- res = palloc (a, strlen(s) + 1);
- strcpy (res, s);
- return res;
-}
-
-char *pstrndup(struct pool *a, const char *s, int n)
-{
- char *res;
- if (s == NULL) return NULL;
- res = palloc (a, n + 1);
- strncpy (res, s, n);
- res[n] = '\0';
- return res;
-}
-
-char *pstrcat(pool *a, ...)
-{
- char *cp, *argp, *res;
-
- /* Pass one --- find length of required string */
-
- int len = 0;
- va_list adummy;
-
- va_start (adummy, a);
-
- while ((cp = va_arg (adummy, char *)) != NULL)
- len += strlen(cp);
-
- va_end (adummy);
-
- /* Allocate the required string */
-
- res = (char *)palloc(a, len + 1);
- cp = res;
-
- /* Pass two --- copy the argument strings into the result space */
-
- va_start (adummy, a);
-
- while ((argp = va_arg (adummy, char *)) != NULL) {
- strcpy (cp, argp);
- cp += strlen(argp);
- }
-
- va_end (adummy);
-
- /* Return the result string */
-
- return res;
-}
-
-
-/*****************************************************************
- *
- * The 'array' functions...
- */
-
-array_header *make_array (pool *p, int nelts, int elt_size)
-{
- array_header *res = (array_header *)palloc(p, sizeof(array_header));
-
- if (nelts < 1) nelts = 1; /* Assure sanity if someone asks for
- * array of zero elts.
- */
-
- res->elts = pcalloc (p, nelts * elt_size);
-
- res->pool = p;
- res->elt_size = elt_size;
- res->nelts = 0; /* No active elements yet... */
- res->nalloc = nelts; /* ...but this many allocated */
-
- return res;
-}
-
-void *push_array (array_header *arr)
-{
- if (arr->nelts == arr->nalloc) {
- int new_size = (arr->nalloc <= 0) ? 1 : arr->nalloc * 2;
- char *new_data;
-
- new_data = pcalloc (arr->pool, arr->elt_size * new_size);
-
- memcpy (new_data, arr->elts, arr->nalloc * arr->elt_size);
- arr->elts = new_data;
- arr->nalloc = new_size;
- }
-
- ++arr->nelts;
- return arr->elts + (arr->elt_size * (arr->nelts - 1));
-}
-
-void array_cat (array_header *dst, const array_header *src)
-{
- int elt_size = dst->elt_size;
-
- if (dst->nelts + src->nelts > dst->nalloc) {
- int new_size = (dst->nalloc <= 0) ? 1 : dst->nalloc * 2;
- char *new_data;
-
- while (dst->nelts + src->nelts > new_size)
- new_size *= 2;
-
- new_data = pcalloc (dst->pool, elt_size * new_size);
- memcpy (new_data, dst->elts, dst->nalloc * elt_size);
-
- dst->elts = new_data;
- dst->nalloc = new_size;
- }
-
- memcpy (dst->elts + dst->nelts * elt_size, src->elts, elt_size * src->nelts);
- dst->nelts += src->nelts;
-}
-
-array_header *copy_array (pool *p, const array_header *arr)
-{
- array_header *res = make_array (p, arr->nalloc, arr->elt_size);
-
- memcpy (res->elts, arr->elts, arr->elt_size * arr->nelts);
- res->nelts = arr->nelts;
- return res;
-}
-
-/* This cute function copies the array header *only*, but arranges
- * for the data section to be copied on the first push or arraycat.
- * It's useful when the elements of the array being copied are
- * read only, but new stuff *might* get added on the end; we have the
- * overhead of the full copy only where it is really needed.
- */
-
-array_header *copy_array_hdr (pool *p, const array_header *arr)
-{
- array_header *res = (array_header *)palloc(p, sizeof(array_header));
-
- res->elts = arr->elts;
-
- res->pool = p;
- res->elt_size = arr->elt_size;
- res->nelts = arr->nelts;
- res->nalloc = arr->nelts; /* Force overflow on push */
-
- return res;
-}
-
-/* The above is used here to avoid consing multiple new array bodies... */
-
-array_header *append_arrays (pool *p,
- const array_header *first,
- const array_header *second)
-{
- array_header *res = copy_array_hdr (p, first);
-
- array_cat (res, second);
- return res;
-}
-
-
-/*****************************************************************
- *
- * The "table" functions.
- */
-
-table *make_table (pool *p, int nelts) {
- return make_array (p, nelts, sizeof (table_entry));
-}
-
-table *copy_table (pool *p, const table *t) {
- return copy_array (p, t);
-}
-
-void clear_table (table *t)
-{
- t->nelts = 0;
-}
-
-array_header *table_elts (table *t) { return t; }
-
-char *table_get (const table *t, const char *key)
-{
- table_entry *elts = (table_entry *)t->elts;
- int i;
-
- if (key == NULL) return NULL;
-
- for (i = 0; i < t->nelts; ++i)
- if (!strcasecmp (elts[i].key, key))
- return elts[i].val;
-
- return NULL;
-}
-
-void table_set (table *t, const char *key, const char *val)
-{
- register int i, j, k;
- table_entry *elts = (table_entry *)t->elts;
- int done = 0;
-
- for (i = 0; i < t->nelts;) {
- if (!strcasecmp (elts[i].key, key)) {
- if (!done) {
- elts[i].val = pstrdup(t->pool, val);
- done = 1;
- ++i;
- }
- else { /* delete an extraneous element */
- for (j = i, k = i + 1; k < t->nelts; ++j, ++k) {
- elts[j].key = elts[k].key;
- elts[j].val = elts[k].val;
- }
- --t->nelts;
- }
- }
- else {
- ++i;
- }
- }
-
- if (!done) {
- elts = (table_entry *)push_array(t);
- elts->key = pstrdup (t->pool, key);
- elts->val = pstrdup (t->pool, val);
- }
-}
-
-void table_unset( table *t, const char *key )
-{
- register int i, j, k;
- table_entry *elts = (table_entry *)t->elts;
-
- for (i = 0; i < t->nelts;) {
- if (!strcasecmp (elts[i].key, key)) {
-
- /* found an element to skip over
- * there are any number of ways to remove an element from
- * a contiguous block of memory. I've chosen one that
- * doesn't do a memcpy/bcopy/array_delete, *shrug*...
- */
- for (j = i, k = i + 1; k < t->nelts; ++j, ++k) {
- elts[j].key = elts[k].key;
- elts[j].val = elts[k].val;
- }
- --t->nelts;
- }
- else {
- ++i;
- }
- }
-}
-
-void table_merge (table *t, const char *key, const char *val)
-{
- table_entry *elts = (table_entry *)t->elts;
- int i;
-
- for (i = 0; i < t->nelts; ++i)
- if (!strcasecmp (elts[i].key, key)) {
- elts[i].val = pstrcat (t->pool, elts[i].val, ", ", val, NULL);
- return;
- }
-
- elts = (table_entry *)push_array(t);
- elts->key = pstrdup (t->pool, key);
- elts->val = pstrdup (t->pool, val);
-}
-
-void table_add (table *t, const char *key, const char *val)
-{
- table_entry *elts = (table_entry *)t->elts;
-
- elts = (table_entry *)push_array(t);
- elts->key = pstrdup (t->pool, key);
- elts->val = pstrdup (t->pool, val);
-}
-
-table* overlay_tables (pool *p, const table *overlay, const table *base)
-{
- return append_arrays (p, overlay, base);
-}
-
-/* And now for something completely abstract ...
- *
- * For each key value given as a vararg:
- * run the function pointed to as
- * int comp(void *r, char *key, char *value);
- * on each valid key-value pair in the table t that matches the vararg key,
- * or once for every valid key-value pair if the vararg list is empty,
- * until the function returns false (0) or we finish the table.
- *
- * Note that we restart the traversal for each vararg, which means that
- * duplicate varargs will result in multiple executions of the function
- * for each matching key. Note also that if the vararg list is empty,
- * only one traversal will be made and will cut short if comp returns 0.
- *
- * Note that the table_get and table_merge functions assume that each key in
- * the table is unique (i.e., no multiple entries with the same key). This
- * function does not make that assumption, since it (unfortunately) isn't
- * true for some of Apache's tables.
- *
- * Note that rec is simply passed-on to the comp function, so that the
- * caller can pass additional info for the task.
- */
-void table_do (int (*comp)(void *, const char *, const char *), void *rec,
- const table *t, ...)
-{
- va_list vp;
- char *argp;
- table_entry *elts = (table_entry *)t->elts;
- int rv, i;
-
- va_start(vp, t);
-
- argp = va_arg(vp, char *);
-
- do {
- for (rv = 1, i = 0; rv && (i < t->nelts); ++i) {
- if (elts[i].key && (!argp || !strcasecmp(elts[i].key, argp))) {
- rv = (*comp)(rec, elts[i].key, elts[i].val);
- }
- }
- } while (argp && ((argp = va_arg(vp, char *)) != NULL));
-
- va_end(vp);
-}
-
-/*****************************************************************
- *
- * Managing generic cleanups.
- */
-
-struct cleanup {
- void *data;
- void (*plain_cleanup)(void *);
- void (*child_cleanup)(void *);
- struct cleanup *next;
-};
-
-void register_cleanup (pool *p, void *data, void (*plain_cleanup)(void *),
- void (*child_cleanup)(void *))
-{
- struct cleanup *c = (struct cleanup *)palloc(p, sizeof (struct cleanup));
- c->data = data;
- c->plain_cleanup = plain_cleanup;
- c->child_cleanup = child_cleanup;
- c->next = p->cleanups;
- p->cleanups = c;
-}
-
-void kill_cleanup (pool *p, void *data, void (*cleanup)(void *))
-{
- struct cleanup *c = p->cleanups;
- struct cleanup **lastp = &p->cleanups;
-
- while (c) {
- if (c->data == data && c->plain_cleanup == cleanup) {
- *lastp = c->next;
- break;
- }
-
- lastp = &c->next;
- c = c->next;
- }
-}
-
-void run_cleanup (pool *p, void *data, void (*cleanup)(void *))
-{
- block_alarms(); /* Run cleanup only once! */
- (*cleanup)(data);
- kill_cleanup (p, data, cleanup);
- unblock_alarms();
-}
-
-static void run_cleanups (struct cleanup *c)
-{
- while (c) {
- (*c->plain_cleanup)(c->data);
- c = c->next;
- }
-}
-
-static void run_child_cleanups (struct cleanup *c)
-{
- while (c) {
- (*c->child_cleanup)(c->data);
- c = c->next;
- }
-}
-
-static void cleanup_pool_for_exec (pool *p)
-{
- run_child_cleanups (p->cleanups);
- p->cleanups = NULL;
-
- for (p = p->sub_pools; p; p = p->sub_next)
- cleanup_pool_for_exec (p);
-}
-
-void cleanup_for_exec()
-{
- block_alarms();
- cleanup_pool_for_exec (permanent_pool);
- unblock_alarms();
-}
-
-/*****************************************************************
- *
- * Files and file descriptors; these are just an application of the
- * generic cleanup interface.
- */
-
-static void fd_cleanup (void *fdv) { close ((int)fdv); }
-
-void note_cleanups_for_fd (pool *p, int fd) {
- register_cleanup (p, (void *)fd, fd_cleanup, fd_cleanup);
-}
-
-void kill_cleanups_for_fd(pool *p,int fd)
- {
- kill_cleanup(p,(void *)fd,fd_cleanup);
- }
-
-int popenf(pool *a, const char *name, int flg, int mode)
-{
- int fd;
- int save_errno;
-
- block_alarms();
- fd = open(name, flg, mode);
- save_errno = errno;
- if (fd >= 0) {
- fd = ap_slack (fd, AP_SLACK_HIGH);
- note_cleanups_for_fd (a, fd);
- }
- unblock_alarms();
- errno = save_errno;
- return fd;
-}
-
-int pclosef(pool *a, int fd)
-{
- int res;
- int save_errno;
-
- block_alarms();
- res = close(fd);
- save_errno = errno;
- kill_cleanup(a, (void *)fd, fd_cleanup);
- unblock_alarms();
- errno = save_errno;
- return res;
-}
-
-/* Note that we have separate plain_ and child_ cleanups for FILE *s,
- * since fclose() would flush I/O buffers, which is extremely undesirable;
- * we just close the descriptor.
- */
-
-static void file_cleanup (void *fpv) { fclose ((FILE *)fpv); }
-static void file_child_cleanup (void *fpv) { close (fileno ((FILE *)fpv)); }
-
-void note_cleanups_for_file (pool *p, FILE *fp) {
- register_cleanup (p, (void *)fp, file_cleanup, file_child_cleanup);
-}
-
-FILE *pfopen(pool *a, const char *name, const char *mode)
-{
- FILE *fd = NULL;
- int baseFlag, desc;
-
- block_alarms();
-
- if (*mode == 'a') {
- /* Work around faulty implementations of fopen */
- baseFlag = (*(mode+1) == '+') ? O_RDWR : O_WRONLY;
- desc = open(name, baseFlag | O_APPEND | O_CREAT,
- S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
- if (desc >= 0) {
- desc = ap_slack(desc, AP_SLACK_LOW);
- fd = fdopen(desc, mode);
- }
- } else {
- fd = fopen(name, mode);
- }
-
- if (fd != NULL) note_cleanups_for_file (a, fd);
- unblock_alarms();
- return fd;
-}
-
-FILE *pfdopen(pool *a,int fd, const char *mode)
-{
- FILE *f;
-
- block_alarms();
- f=fdopen(fd,mode);
- if(f != NULL)
- note_cleanups_for_file(a,f);
- unblock_alarms();
- return f;
-}
-
-
-int pfclose(pool *a, FILE *fd)
-{
- int res;
-
- block_alarms();
- res = fclose(fd);
- kill_cleanup(a, (void *)fd, file_cleanup);
- unblock_alarms();
- return res;
-}
-
-/*
- * Here's a pool-based interface to POSIX regex's regcomp().
- * Note that we return regex_t instead of being passed one.
- * The reason is that if you use an already-used regex_t structure,
- * the memory that you've already allocated gets forgotten, and
- * regfree() doesn't clear it. So we don't allow it.
- */
-
-static void regex_cleanup (void *preg) { regfree ((regex_t *)preg); }
-
-regex_t *pregcomp(pool *p, const char *pattern, int cflags) {
- regex_t *preg = palloc(p, sizeof(regex_t));
-
- if (regcomp(preg, pattern, cflags))
- return NULL;
-
- register_cleanup (p, (void *)preg, regex_cleanup, regex_cleanup);
-
- return preg;
-}
-
-
-void pregfree(pool *p, regex_t *reg)
-{
- block_alarms();
- regfree (reg);
- kill_cleanup (p, (void *)reg, regex_cleanup);
- unblock_alarms();
-}
-
-/*****************************************************************
- *
- * More grotty system stuff... subprocesses. Frump. These don't use
- * the generic cleanup interface because I don't want multiple
- * subprocesses to result in multiple three-second pauses; the
- * subprocesses have to be "freed" all at once. If someone comes
- * along with another resource they want to allocate which has the
- * same property, we might want to fold support for that into the
- * generic interface, but for now, it's a special case
- */
-
-struct process_chain {
- pid_t pid;
- enum kill_conditions kill_how;
- struct process_chain *next;
-};
-
-void note_subprocess (pool *a, int pid, enum kill_conditions how)
-{
- struct process_chain *new =
- (struct process_chain *)palloc(a, sizeof(struct process_chain));
-
- new->pid = pid;
- new->kill_how = how;
- new->next = a->subprocesses;
- a->subprocesses = new;
-}
-
-int spawn_child_err (pool *p, void (*func)(void *), void *data,
- enum kill_conditions kill_how,
- FILE **pipe_in, FILE **pipe_out, FILE **pipe_err)
-{
- int pid;
- int in_fds[2];
- int out_fds[2];
- int err_fds[2];
- int save_errno;
-
- block_alarms();
-
- if (pipe_in && pipe (in_fds) < 0)
- {
- save_errno = errno;
- unblock_alarms();
- errno = save_errno;
- return 0;
- }
-
- if (pipe_out && pipe (out_fds) < 0) {
- save_errno = errno;
- if (pipe_in) {
- close (in_fds[0]); close (in_fds[1]);
- }
- unblock_alarms();
- errno = save_errno;
- return 0;
- }
-
- if (pipe_err && pipe (err_fds) < 0) {
- save_errno = errno;
- if (pipe_in) {
- close (in_fds[0]); close (in_fds[1]);
- }
- if (pipe_out) {
- close (out_fds[0]); close (out_fds[1]);
- }
- unblock_alarms();
- errno = save_errno;
- return 0;
- }
-
- if ((pid = fork()) < 0) {
- save_errno = errno;
- if (pipe_in) {
- close (in_fds[0]); close (in_fds[1]);
- }
- if (pipe_out) {
- close (out_fds[0]); close (out_fds[1]);
- }
- if (pipe_err) {
- close (err_fds[0]); close (err_fds[1]);
- }
- unblock_alarms();
- errno = save_errno;
- return 0;
- }
-
- if (!pid) {
- /* Child process */
-
- if (pipe_out) {
- close (out_fds[0]);
- dup2 (out_fds[1], STDOUT_FILENO);
- close (out_fds[1]);
- }
-
- if (pipe_in) {
- close (in_fds[1]);
- dup2 (in_fds[0], STDIN_FILENO);
- close (in_fds[0]);
- }
-
- if (pipe_err) {
- close (err_fds[0]);
- dup2 (err_fds[1], STDERR_FILENO);
- close (err_fds[1]);
- }
-
- /* HP-UX SIGCHLD fix goes here, if someone will remind me what it is... */
- signal (SIGCHLD, SIG_DFL); /* Was that it? */
-
- func (data);
- exit (0); /* Should never get here... */
- }
-
- /* Parent process */
-
- note_subprocess (p, pid, kill_how);
-
- if (pipe_out) {
- close (out_fds[1]);
-#ifdef __EMX__
- /* Need binary mode set for OS/2. */
- *pipe_out = fdopen (out_fds[0], "rb");
-#else
- *pipe_out = fdopen (out_fds[0], "r");
-#endif
-
- if (*pipe_out) note_cleanups_for_file (p, *pipe_out);
- }
-
- if (pipe_in) {
- close (in_fds[0]);
-#ifdef __EMX__
- /* Need binary mode set for OS/2 */
- *pipe_in = fdopen (in_fds[1], "wb");
-#else
- *pipe_in = fdopen (in_fds[1], "w");
-#endif
-
- if (*pipe_in) note_cleanups_for_file (p, *pipe_in);
- }
-
- if (pipe_err) {
- close (err_fds[1]);
-#ifdef __EMX__
- /* Need binary mode set for OS/2. */
- *pipe_err = fdopen (err_fds[0], "rb");
-#else
- *pipe_err = fdopen (err_fds[0], "r");
-#endif
-
- if (*pipe_err) note_cleanups_for_file (p, *pipe_err);
- }
-
- unblock_alarms();
- return pid;
-}
-
-static void free_proc_chain (struct process_chain *procs)
-{
- /* Dispose of the subprocesses we've spawned off in the course of
- * whatever it was we're cleaning up now. This may involve killing
- * some of them off...
- */
-
- struct process_chain *p;
- int need_timeout = 0;
- int status;
-
- if (procs == NULL) return; /* No work. Whew! */
-
- /* First, check to see if we need to do the SIGTERM, sleep, SIGKILL
- * dance with any of the processes we're cleaning up. If we've got
- * any kill-on-sight subprocesses, ditch them now as well, so they
- * don't waste any more cycles doing whatever it is that they shouldn't
- * be doing anymore.
- */
-
-#ifndef NEED_WAITPID
- /* Pick up all defunct processes */
- for (p = procs; p; p = p->next) {
- if (waitpid (p->pid, (int *) 0, WNOHANG) > 0) {
- p->kill_how = kill_never;
- }
- }
-#endif
-
- for (p = procs; p; p = p->next) {
- if (p->kill_how == kill_after_timeout) {
- /* Subprocess may be dead already. Only need the timeout if not. */
- if (kill (p->pid, SIGTERM) != -1)
- need_timeout = 1;
- } else if (p->kill_how == kill_always) {
- kill (p->pid, SIGKILL);
- }
- }
-
- /* Sleep only if we have to... */
-
- if (need_timeout) sleep (3);
-
- /* OK, the scripts we just timed out for have had a chance to clean up
- * --- now, just get rid of them, and also clean up the system accounting
- * goop...
- */
-
- for (p = procs; p; p = p->next){
-
- if (p->kill_how == kill_after_timeout)
- kill (p->pid, SIGKILL);
-
- if (p->kill_how != kill_never)
- waitpid (p->pid, &status, 0);
- }
-}
-
diff --git a/usr.sbin/httpd/src/alloc.h b/usr.sbin/httpd/src/alloc.h
deleted file mode 100644
index 858bf2cb549..00000000000
--- a/usr.sbin/httpd/src/alloc.h
+++ /dev/null
@@ -1,252 +0,0 @@
-
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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/>.
- *
- */
-
-/*
- * Resource allocation routines...
- *
- * designed so that we don't have to keep track of EVERYTHING so that
- * it can be explicitly freed later (a fundamentally unsound strategy ---
- * particularly in the presence of die()).
- *
- * Instead, we maintain pools, and allocate items (both memory and I/O
- * handlers) from the pools --- currently there are two, one for per
- * transaction info, and one for config info. When a transaction is over,
- * we can delete everything in the per-transaction pool without fear, and
- * without thinking too hard about it either.
- *
- * rst
- */
-
-/* Arenas for configuration info and transaction info
- * --- actual layout of the pool structure is private to
- * alloc.c.
- */
-
-typedef struct pool pool;
-
-extern pool *permanent_pool;
-void init_alloc(); /* Set up everything */
-pool *make_sub_pool (pool *); /* All pools are subpools of permanent_pool */
-void destroy_pool (pool *);
-
-/* Clearing out EVERYTHING in an pool... destroys any sub-pools */
-
-void clear_pool (struct pool *);
-
-/* Preparing for exec() --- close files, etc., but *don't* flush I/O
- * buffers, *don't* wait for subprocesses, and *don't* free any memory.
- */
-
-void cleanup_for_exec ();
-
-/* routines to allocate memory from an pool... */
-
-void *palloc(struct pool *, int nbytes);
-void *pcalloc(struct pool *, int nbytes);
-extern char *pstrdup(struct pool *, const char *s);
-extern char *pstrndup(struct pool *, const char *s, int n);
-char *pstrcat(struct pool *, ...); /* all '...' must be char* */
-
-/* array and alist management... keeping lists of things.
- * Common enough to want common support code ...
- */
-
-typedef struct {
- pool *pool;
- int elt_size;
- int nelts;
- int nalloc;
- char *elts;
-} array_header;
-
-array_header *make_array (pool *p, int nelts, int elt_size);
-void *push_array (array_header *);
-void array_cat (array_header *dst, const array_header *src);
-array_header *append_arrays (pool *, const array_header *,
- const array_header *);
-
-/* copy_array copies the *entire* array. copy_array_hdr just copies
- * the header, and arranges for the elements to be copied if (and only
- * if) the code subsequently does a push or arraycat.
- */
-
-array_header *copy_array (pool *p, const array_header *src);
-array_header *copy_array_hdr (pool *p, const array_header *src);
-
-
-/* Tables. Implemented alist style, for now, though we try to keep
- * it so that imposing a hash table structure on top in the future
- * wouldn't be *too* hard...
- *
- * Note that key comparisons for these are case-insensitive, largely
- * because that's what's appropriate and convenient everywhere they're
- * currently being used...
- */
-
-typedef array_header table;
-
-typedef struct {
- char *key; /* maybe NULL in future;
- * check when iterating thru table_elts
- */
- char *val;
-} table_entry;
-
-table *make_table (pool *p, int nelts);
-table *copy_table (pool *p, const table *);
-void clear_table (table *);
-char *table_get (const table *, const char *);
-void table_set (table *, const char *name, const char *val);
-void table_merge (table *, const char *name, const char *more_val);
-void table_unset (table *, const char *key);
-void table_add (table *, const char *name, const char *val);
-void table_do (int (*comp)(void *, const char *, const char *), void *rec,
- const table *t, ...);
-
-table *overlay_tables (pool *p, const table *overlay, const table *base);
-
-array_header *table_elts (table *);
-
-#define is_empty_table(t) (((t) == NULL)||((t)->nelts == 0))
-
-/* routines to remember allocation of other sorts of things...
- * generic interface first. Note that we want to have two separate
- * cleanup functions in the general case, one for exec() preparation,
- * to keep CGI scripts and the like from inheriting access to things
- * they shouldn't be able to touch, and one for actually cleaning up,
- * when the actual server process wants to get rid of the thing,
- * whatever it is.
- *
- * kill_cleanup disarms a cleanup, presumably because the resource in
- * question has been closed, freed, or whatever, and it's scarce
- * enough to want to reclaim (e.g., descriptors). It arranges for the
- * resource not to be cleaned up a second time (it might have been
- * reallocated). run_cleanup does the same, but runs it first.
- *
- * Cleanups are identified for purposes of finding & running them off by the
- * plain_cleanup and data, which should presumably be unique.
- *
- * NB any code which invokes register_cleanup or kill_cleanup directly
- * is a critical section which should be guarded by block_alarms() and
- * unblock_alarms() below...
- */
-
-void register_cleanup (pool *p, void *data,
- void (*plain_cleanup)(void *),
- void (*child_cleanup)(void *));
-
-void kill_cleanup (pool *p, void *data, void (*plain_cleanup)(void *));
-void run_cleanup (pool *p, void *data, void (*cleanup)(void *));
-
-/* The time between when a resource is actually allocated, and when it
- * its cleanup is registered is a critical section, during which the
- * resource could leak if we got interrupted or timed out. So, anything
- * which registers cleanups should bracket resource allocation and the
- * cleanup registry with these. (This is done internally by run_cleanup).
- *
- * NB they are actually implemented in http_main.c, since they are bound
- * up with timeout handling in general...
- */
-
-extern void block_alarms();
-extern void unblock_alarms();
-
-/* Common cases which want utility support..
- * the note_cleanups_for_foo routines are for
- */
-
-FILE *pfopen(struct pool *, const char *name, const char *fmode);
-FILE *pfdopen(struct pool *, int fd, const char *fmode);
-int popenf(struct pool *, const char *name, int flg, int mode);
-
-void note_cleanups_for_file (pool *, FILE *);
-void note_cleanups_for_fd (pool *, int);
-void kill_cleanups_for_fd (pool *p, int fd);
-
-regex_t *pregcomp (pool *p, const char *pattern, int cflags);
-void pregfree (pool *p, regex_t *reg);
-
-/* routines to note closes... file descriptors are constrained enough
- * on some systems that we want to support this.
- */
-
-int pfclose(struct pool *, FILE *);
-int pclosef(struct pool *, int fd);
-
-/* ... even child processes (which we may want to wait for,
- * or to kill outright, on unexpected termination).
- *
- * spawn_child is a utility routine which handles an awful lot of
- * the rigamarole associated with spawning a child --- it arranges
- * for pipes to the child's stdin and stdout, if desired (if not,
- * set the associated args to NULL). It takes as args a function
- * to call in the child, and an argument to be passed to the function.
- */
-
-enum kill_conditions { kill_never, kill_always, kill_after_timeout, just_wait};
-
-int spawn_child_err (pool *, void (*)(void *), void *,
- enum kill_conditions, FILE **pipe_in, FILE **pipe_out,
- FILE **pipe_err);
-#define spawn_child(p,f,v,k,in,out) spawn_child_err(p,f,v,k,in,out,NULL)
-
-/* magic numbers --- min free bytes to consider a free pool block useable,
- * and the min amount to allocate if we have to go to malloc() */
-
-#define BLOCK_MINFREE 4096
-#define BLOCK_MINALLOC 8192
-
-/* Finally, some accounting */
-
-long bytes_in_pool(pool *p);
-long bytes_in_free_blocks();
diff --git a/usr.sbin/httpd/src/buff.c b/usr.sbin/httpd/src/buff.c
deleted file mode 100644
index 48872043359..00000000000
--- a/usr.sbin/httpd/src/buff.c
+++ /dev/null
@@ -1,1011 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1996,1997 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. 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/>.
- *
- */
-
-#include "conf.h"
-#include "alloc.h"
-#include "buff.h"
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#ifndef NO_UNISTD_H
-#include <unistd.h>
-#endif
-#ifndef NO_WRITEV
-#include <sys/types.h>
-#include <sys/uio.h>
-#endif
-
-#ifdef HAVE_BSTRING_H
-#include <bstring.h> /* for IRIX, FD_SET calls bzero() */
-#endif
-
-#define DEFAULT_BUFSIZE (4096)
-/* This must be enough to represent (DEFAULT_BUFSIZE - 3) in hex,
- * plus two extra characters.
- */
-#define CHUNK_HEADER_SIZE (5)
-
-/*
- * Buffered I/O routines.
- * These are a replacement for the stdio routines.
- * Advantages:
- * Known semantics for handling of file-descriptors (on close etc.)
- * No problems reading and writing simultanously to the same descriptor
- * No limits on the number of open file handles.
- * Only uses memory resources; no need to ensure the close routine
- * is called.
- * Extra code could be inserted between the buffered and un-buffered routines.
- * Timeouts could be handled by using select or poll before read or write.
- * Extra error handling could be introduced; e.g.
- * keep an address to which we should longjump(), or
- * keep a stack of routines to call on error.
- */
-
-/* Notes:
- * On reading EOF, EOF will set in the flags and no further Input will
- * be done.
- *
- * On an error except for EAGAIN, ERROR will be set in the flags and no
- * futher I/O will be done
- */
-
-static void
-doerror(BUFF *fb, int err)
-{
- int errsave = errno; /* Save errno to prevent overwriting it below */
-
- if (err == B_RD)
- fb->flags |= B_RDERR;
- else
- fb->flags |= B_WRERR;
- if (fb->error != NULL) (*fb->error)(fb, err, fb->error_data);
-
- errno = errsave;
-}
-
-/* Buffering routines */
-/*
- * Create a new buffered stream
- */
-BUFF *
-bcreate(pool *p, int flags)
-{
- BUFF *fb;
-
- fb = palloc(p, sizeof(BUFF));
- fb->pool=p;
- fb->bufsiz = DEFAULT_BUFSIZE;
- fb->flags = flags & B_RDWR;
-
- if (flags & B_RD) fb->inbase = palloc(p, fb->bufsiz);
- else fb->inbase = NULL;
-
- /* overallocate so that we can put a chunk trailer of CRLF into this
- * buffer */
- if (flags & B_WR) fb->outbase = palloc(p, fb->bufsiz + 2);
- else fb->outbase = NULL;
-
- fb->inptr = fb->inbase;
-
- fb->incnt = 0;
- fb->outcnt = 0;
- fb->outchunk = -1;
- fb->error = NULL;
- fb->bytes_sent = 0L;
-
- fb->fd = -1;
- fb->fd_in = -1;
-
- return fb;
-}
-
-/*
- * Push some I/O file descriptors onto the stream
- */
-void
-bpushfd(BUFF *fb, int fd_in, int fd_out)
-{
- fb->fd = fd_out;
- fb->fd_in = fd_in;
-}
-
-int
-bsetopt(BUFF *fb, int optname, const void *optval)
-{
- if (optname == BO_BYTECT)
- {
- fb->bytes_sent = *(const long int *)optval - (long int)fb->outcnt;;
- return 0;
- } else
- {
- errno = EINVAL;
- return -1;
- }
-}
-
-int
-bgetopt(BUFF *fb, int optname, void *optval)
-{
- if (optname == BO_BYTECT)
- {
- long int bs=fb->bytes_sent + fb->outcnt;
- if (bs < 0L) bs = 0L;
- *(long int *)optval = bs;
- return 0;
- } else
- {
- errno = EINVAL;
- return -1;
- }
-}
-
-
-static int bflush_core(BUFF *fb);
-
-/*
- * Start chunked encoding.
- *
- * Note that in order for bputc() to be an efficient macro we have to
- * guarantee that start_chunk() has always been called on the buffer before we
- * leave any routine in this file. Said another way, if a routine here uses
- * end_chunk() and writes something on the wire, then it has to call
- * start_chunk() or set an error condition before returning.
- */
-static void
-start_chunk( BUFF *fb )
-{
- if (fb->outchunk != -1) {
- /* already chunking */
- return;
- }
- if (!(fb->flags & B_WR) || (fb->flags & (B_WRERR|B_EOUT))) {
- /* unbuffered writes */
- return;
- }
-
- /* we need at least the header_len + at least 1 data byte
- * remember that we've overallocated fb->outbase so that we can always
- * fit the two byte CRLF trailer
- */
- if( fb->bufsiz - fb->outcnt < CHUNK_HEADER_SIZE + 1 ) {
- bflush_core(fb);
- }
- /* assume there's enough space now */
- fb->outchunk = fb->outcnt;
- fb->outcnt += CHUNK_HEADER_SIZE;
-}
-
-
-/*
- * end a chunk -- tweak the chunk_header from start_chunk, and add a trailer
- */
-static void
-end_chunk( BUFF *fb )
-{
- int i;
- char *strp;
-
- if( fb->outchunk == -1 ) {
- /* not chunking */
- return;
- }
-
- if( fb->outchunk + CHUNK_HEADER_SIZE == fb->outcnt ) {
- /* nothing was written into this chunk, and we can't write a 0 size
- * chunk because that signifies EOF, so just erase it
- */
- fb->outcnt = fb->outchunk;
- fb->outchunk = -1;
- return;
- }
-
- /* we know this will fit because of how we wrote it in start_chunk() */
- i = ap_snprintf( (char *)&fb->outbase[fb->outchunk],
- CHUNK_HEADER_SIZE,
- "%x", fb->outcnt - fb->outchunk - CHUNK_HEADER_SIZE );
-
- /* we may have to tack some trailing spaces onto the number we just wrote
- * in case it was smaller than our estimated size. We've also written
- * a \0 into the buffer with ap_snprintf so we might have to put a
- * \r back in.
- */
- strp = &fb->outbase[fb->outchunk + i];
- while (i < CHUNK_HEADER_SIZE - 2) {
- *strp++ = ' ';
- ++i;
- }
- *strp++ = '\015';
- *strp = '\012';
-
- /* tack on the trailing CRLF, we've reserved room for this */
- fb->outbase[fb->outcnt++] = '\015';
- fb->outbase[fb->outcnt++] = '\012';
-
- fb->outchunk = -1;
-}
-
-
-/*
- * Set a flag on (1) or off (0).
- */
-int bsetflag(BUFF *fb, int flag, int value)
-{
- if (value) {
- fb->flags |= flag;
- if( flag & B_CHUNK ) {
- start_chunk(fb);
- }
- } else {
- fb->flags &= ~flag;
- if( flag & B_CHUNK ) {
- end_chunk(fb);
- }
- }
- return value;
-}
-
-
-/*
- * This is called instead of read() everywhere in here. It implements
- * the B_SAFEREAD functionality -- which is to force a flush() if a read()
- * would block. It also deals with the EINTR errno result from read().
- * return code is like read() except EINTR is eliminated.
- */
-static int
-saferead( BUFF *fb, void *buf, int nbyte )
-{
- int rv;
-
- if( fb->flags & B_SAFEREAD ) {
- fd_set fds;
- struct timeval tv;
-
- /* test for a block */
- do {
- FD_ZERO( &fds );
- FD_SET( fb->fd_in, &fds );
- tv.tv_sec = 0;
- tv.tv_usec = 0;
-#ifdef SELECT_NEEDS_CAST
- rv = select( fb->fd_in + 1, (int *)&fds, NULL, NULL, &tv );
-#else
- rv = select( fb->fd_in + 1, &fds, NULL, NULL, &tv );
-#endif
- } while( rv < 0 && errno == EINTR );
- /* treat any error as if it would block as well */
- if( rv != 1 ) {
- bflush(fb);
- }
- }
- do {
- rv = read( fb->fd_in, buf, nbyte );
- } while (rv == -1 && errno == EINTR && !(fb->flags & B_EOUT));
- return( rv );
-}
-
-
-/*
- * Read up to nbyte bytes into buf.
- * If fewer than byte bytes are currently available, then return those.
- * Returns 0 for EOF, -1 for error.
- */
-int
-bread(BUFF *fb, void *buf, int nbyte)
-{
- int i, nrd;
-
- if (fb->flags & B_RDERR) return -1;
- if (nbyte == 0) return 0;
-
- if (!(fb->flags & B_RD))
- {
-/* Unbuffered reading */
- i = saferead( fb, buf, nbyte );
- if (i == -1 && errno != EAGAIN) doerror(fb, B_RD);
- return i;
- }
-
- nrd = fb->incnt;
-/* can we fill the buffer */
- if (nrd >= nbyte)
- {
- memcpy(buf, fb->inptr, nbyte);
- fb->incnt = nrd - nbyte;
- fb->inptr += nbyte;
- return nbyte;
- }
-
- if (nrd > 0)
- {
- memcpy(buf, fb->inptr, nrd);
- nbyte -= nrd;
- buf = nrd + (char *)buf;
- fb->incnt = 0;
- }
- if (fb->flags & B_EOF) return nrd;
-
-/* do a single read */
- if (nbyte >= fb->bufsiz)
- {
-/* read directly into buffer */
- i = saferead( fb, buf, nbyte );
- if (i == -1)
- {
- if (nrd == 0)
- {
- if (errno != EAGAIN) doerror(fb, B_RD);
- return -1;
- }
- else return nrd;
- } else if (i == 0) fb->flags |= B_EOF;
- } else
- {
-/* read into hold buffer, then memcpy */
- fb->inptr = fb->inbase;
- i = saferead( fb, fb->inptr, fb->bufsiz );
- if (i == -1)
- {
- if (nrd == 0)
- {
- if (errno != EAGAIN) doerror(fb, B_RD);
- return -1;
- }
- else return nrd;
- } else if (i == 0) fb->flags |= B_EOF;
- fb->incnt = i;
- if (i > nbyte) i = nbyte;
- memcpy(buf, fb->inptr, i);
- fb->incnt -= i;
- fb->inptr += i;
- }
- return nrd + i;
-}
-
-
-/*
- * Reads from the stream into the array pointed to by buff, until
- * a (CR)LF sequence is read, or end-of-file condition is encountered
- * or until n-1 bytes have been stored in buff. If a CRLF sequence is
- * read, it is replaced by a newline character. The string is then
- * terminated with a null character.
- *
- * Returns the number of bytes stored in buff, or zero on end of
- * transmission, or -1 on an error.
- *
- * Notes:
- * If null characters are exepected in the data stream, then
- * buff should not be treated as a null terminated C string; instead
- * the returned count should be used to determine the length of the
- * string.
- * CR characters in the byte stream not immediately followed by a LF
- * will be preserved.
- */
-int
-bgets(char *buff, int n, BUFF *fb)
-{
- int i, ch, ct;
-
-/* Can't do bgets on an unbuffered stream */
- if (!(fb->flags & B_RD))
- {
- errno = EINVAL;
- return -1;
- }
- if (fb->flags & B_RDERR) return -1;
-
- ct = 0;
- i = 0;
- for (;;)
- {
- if (i == fb->incnt)
- {
-/* no characters left */
- fb->inptr = fb->inbase;
- fb->incnt = 0;
- if (fb->flags & B_EOF) break;
- i = saferead( fb, fb->inptr, fb->bufsiz );
- if (i == -1)
- {
- buff[ct] = '\0';
- if (ct == 0)
- {
- if (errno != EAGAIN) doerror(fb, B_RD);
- return -1;
- }
- else return ct;
- }
- fb->incnt = i;
- if (i == 0)
- {
- fb->flags |= B_EOF;
- break; /* EOF */
- }
- i = 0;
- continue; /* restart with the new data */
- }
-
- ch = fb->inptr[i++];
- if (ch == '\012') /* got LF */
- {
- if (ct == 0) buff[ct++] = '\n';
-/* if just preceeded by CR, replace CR with LF */
- else if (buff[ct-1] == '\015') buff[ct-1] = '\n';
- else if (ct < n-1) buff[ct++] = '\n';
- else i--; /* no room for LF */
- break;
- }
- if (ct == n-1)
- {
- i--; /* push back ch */
- break;
- }
-
- buff[ct++] = ch;
- }
- fb->incnt -= i;
- fb->inptr += i;
-
- buff[ct] = '\0';
- return ct;
-}
-
-/*
- * Looks at the stream fb and places the first character into buff
- * without removing it from the stream buffer.
- *
- * Returns 1 on success, zero on end of transmission, or -1 on an error.
- *
- */
-int blookc(char *buff, BUFF *fb)
-{
- int i;
-
- *buff = '\0';
-
- if (!(fb->flags & B_RD)) { /* Can't do blookc on an unbuffered stream */
- errno = EINVAL;
- return -1;
- }
- if (fb->flags & B_RDERR) return -1;
-
- if (fb->incnt == 0) { /* no characters left in stream buffer */
- fb->inptr = fb->inbase;
- if (fb->flags & B_EOF)
- return 0;
-
- i = saferead( fb, fb->inptr, fb->bufsiz );
-
- if (i == -1) {
- if (errno != EAGAIN)
- doerror(fb, B_RD);
- return -1;
- }
- if (i == 0) {
- fb->flags |= B_EOF;
- return 0; /* EOF */
- }
- else fb->incnt = i;
- }
-
- *buff = fb->inptr[0];
- return 1;
-}
-
-/*
- * Skip data until a linefeed character is read
- * Returns 1 on success, 0 if no LF found, or -1 on error
- */
-int
-bskiplf(BUFF *fb)
-{
- unsigned char *x;
- int i;
-
-/* Can't do bskiplf on an unbuffered stream */
- if (!(fb->flags & B_RD))
- {
- errno = EINVAL;
- return -1;
- }
- if (fb->flags & B_RDERR) return -1;
-
- for (;;)
- {
- x = (unsigned char *)memchr(fb->inptr, '\012', fb->incnt);
- if (x != NULL)
- {
- x++;
- fb->incnt -= x - fb->inptr;
- fb->inptr = x;
- return 1;
- }
-
- fb->inptr = fb->inbase;
- fb->incnt = 0;
- if (fb->flags & B_EOF) return 0;
- i = saferead( fb, fb->inptr, fb->bufsiz );
- if (i == 0) fb->flags |= B_EOF;
- if (i == -1 && errno != EAGAIN) doerror(fb, B_RD);
- if (i == 0 || i == -1) return i;
- fb->incnt = i;
- }
-}
-
-/*
- * Emtpy the buffer after putting a single character in it
- */
-int
-bflsbuf(int c, BUFF *fb)
-{
- char ss[1];
-
- ss[0] = c;
- return bwrite(fb, ss, 1);
-}
-
-/*
- * Fill the buffer and read a character from it
- */
-int
-bfilbuf(BUFF *fb)
-{
- int i;
- char buf[1];
-
- i = bread(fb, buf, 1);
- if (i == 0) errno = 0; /* no error; EOF */
- if (i != 1) return EOF;
- else return buf[0];
-}
-
-
-/*
- * When doing chunked encodings we really have to write everything in the
- * chunk before proceeding onto anything else. This routine either writes
- * nbytes and returns 0 or returns -1 indicating a failure.
- *
- * This is *seriously broken* if used on a non-blocking fd. It will poll.
- */
-static int
-write_it_all(BUFF *fb, const void *buf, int nbyte)
-{
- int i;
-
- if (fb->flags & (B_WRERR|B_EOUT))
- return -1;
-
- while (nbyte > 0) {
- i = write(fb->fd, buf, nbyte);
- if (i < 0) {
- if (errno != EAGAIN && errno != EINTR) {
- doerror (fb, B_WR);
- return -1;
- }
- }
- else {
- nbyte -= i;
- buf = i + (const char *)buf;
- }
- if (fb->flags & B_EOUT)
- return -1;
- }
- return 0;
-}
-
-
-/*
- * A hook to write() that deals with chunking. This is really a protocol-
- * level issue, but we deal with it here because it's simpler; this is
- * an interim solution pending a complete rewrite of all this stuff in
- * 2.0, using something like sfio stacked disciplines or BSD's funopen().
- */
-static int
-bcwrite(BUFF *fb, const void *buf, int nbyte)
-{
- char chunksize[16]; /* Big enough for practically anything */
- int rv;
-#ifndef NO_WRITEV
- struct iovec vec[3];
- int i;
-#endif
-
- if (fb->flags & (B_WRERR|B_EOUT))
- return -1;
-
- if (!(fb->flags & B_CHUNK)) {
- do rv = write(fb->fd, buf, nbyte);
- while (rv == -1 && errno == EINTR && !(fb->flags & B_EOUT));
- if (rv == -1) {
- if (errno != EAGAIN) {
- doerror (fb, B_WR);
- }
- return -1;
- } else if (rv == 0) {
- errno = EAGAIN;
- }
- return rv;
- }
-
-#ifdef NO_WRITEV
- /* without writev() this has poor performance, too bad */
-
- ap_snprintf(chunksize, sizeof(chunksize), "%x\015\012", nbyte);
- if (write_it_all(fb, chunksize, strlen(chunksize)) == -1)
- return -1;
- if (write_it_all(fb, buf, nbyte) == -1)
- return -1;
- if (write_it_all(fb, "\015\012", 2) == -1)
- return -1;
- return nbyte;
-#else
-
-#define NVEC (sizeof(vec)/sizeof(vec[0]))
-
- vec[0].iov_base = chunksize;
- vec[0].iov_len = ap_snprintf(chunksize, sizeof(chunksize), "%x\015\012",
- nbyte);
- vec[1].iov_base = (void *)buf; /* cast is to avoid const warning */
- vec[1].iov_len = nbyte;
- vec[2].iov_base = "\r\n";
- vec[2].iov_len = 2;
- /* while it's nice an easy to build the vector and crud, it's painful
- * to deal with a partial writev()
- */
- for( i = 0; i < NVEC; ) {
- do {
- rv = writev( fb->fd, &vec[i], NVEC - i );
- } while ((rv <= 0)
- && !(fb->flags & B_EOUT)
- && (errno == EINTR || errno == EAGAIN || rv == 0));
- if (rv == -1) {
- doerror (fb, B_WR);
- return -1;
- }
- /* recalculate vec to deal with partial writes */
- while (rv > 0) {
- if( rv <= vec[i].iov_len ) {
- vec[i].iov_base = (char *)vec[i].iov_base + rv;
- vec[i].iov_len -= rv;
- rv = 0;
- if( vec[i].iov_len == 0 ) {
- ++i;
- }
- } else {
- rv -= vec[i].iov_len;
- ++i;
- }
- }
- if (fb->flags & B_EOUT)
- return -1;
- }
- /* if we got here, we wrote it all */
- return nbyte;
-#undef NVEC
-#endif
-}
-
-
-/*
- * Write nbyte bytes.
- * Only returns fewer than nbyte if an error ocurred.
- * Returns -1 if no bytes were written before the error ocurred.
- * It is worth noting that if an error occurs, the buffer is in an unknown
- * state.
- */
-int
-bwrite(BUFF *fb, const void *buf, int nbyte)
-{
- int i, nwr, useable_bufsiz;
-
- if (fb->flags & (B_WRERR|B_EOUT)) return -1;
- if (nbyte == 0) return 0;
-
- if (!(fb->flags & B_WR))
- {
-/* unbuffered write -- have to use bcwrite since we aren't taking care
- * of chunking any other way */
- i = bcwrite(fb, buf, nbyte);
- if (i <= 0) {
- return -1;
- }
- fb->bytes_sent += i;
- if (fb->flags & B_EOUT)
- return -1;
- else
- return i;
- }
-
-/*
- * Whilst there is data in the buffer, keep on adding to it and writing it
- * out
- */
- nwr = 0;
- while (fb->outcnt > 0)
- {
-/* can we accept some data? */
- i = fb->bufsiz - fb->outcnt;
- if (i > 0)
- {
- if (i > nbyte) i = nbyte;
- memcpy(fb->outbase + fb->outcnt, buf, i);
- fb->outcnt += i;
- nbyte -= i;
- buf = i + (const char *)buf;
- nwr += i;
- if (nbyte == 0) return nwr; /* return if none left */
- }
-
-/* the buffer must be full */
- if (fb->flags & B_CHUNK) {
- end_chunk(fb);
- /* it is just too painful to try to re-cram the buffer while
- * chunking
- */
- if (write_it_all(fb, fb->outbase, fb->outcnt) == -1) {
- /* we cannot continue after a chunked error */
- return -1;
- }
- fb->bytes_sent += fb->outcnt;
- fb->outcnt = 0;
- break;
- }
- do {
- i = write(fb->fd, fb->outbase, fb->outcnt);
- } while (i == -1 && errno == EINTR && !(fb->flags & B_EOUT));
- if (i <= 0) {
- if (i == 0) /* return of 0 means non-blocking */
- errno = EAGAIN;
- if (nwr == 0) {
- if (errno != EAGAIN) doerror(fb, B_WR);
- return -1;
- }
- else return nwr;
- }
- fb->bytes_sent += i;
-
- /* deal with a partial write */
- if (i < fb->outcnt)
- {
- int j, n=fb->outcnt;
- unsigned char *x=fb->outbase;
- for (j=i; j < n; j++) x[j-i] = x[j];
- fb->outcnt -= i;
- }
- else
- fb->outcnt = 0;
-
- if (fb->flags & B_EOUT)
- return -1;
- }
-/* we have emptied the file buffer. Now try to write the data from the
- * original buffer until there is less than bufsiz left. Note that we
- * use bcwrite() to do this for us, it will do the chunking so that
- * we don't have to dink around building a chunk in our own buffer.
- * Remember we may not be able to use the entire buffer if we're
- * chunking.
- */
- useable_bufsiz = fb->bufsiz;
- if (fb->flags & B_CHUNK) useable_bufsiz -= CHUNK_HEADER_SIZE;
- while (nbyte >= useable_bufsiz)
- {
- i = bcwrite(fb, buf, nbyte);
- if (i <= 0) {
- if (nwr == 0) {
- return -1;
- }
- else return nwr;
- }
- fb->bytes_sent += i;
-
- buf = i + (const char *)buf;
- nwr += i;
- nbyte -= i;
-
- if (fb->flags & B_EOUT)
- return -1;
- }
-/* copy what's left to the file buffer */
- fb->outcnt = 0;
- if( fb->flags & B_CHUNK ) start_chunk( fb );
- if (nbyte > 0) memcpy(fb->outbase + fb->outcnt, buf, nbyte);
- fb->outcnt += nbyte;
- nwr += nbyte;
- return nwr;
-}
-
-static int bflush_core(BUFF *fb)
-{
- int i;
-
- while (fb->outcnt > 0)
- {
- do {
- i = write(fb->fd, fb->outbase, fb->outcnt);
- } while ((i <= 0)
- && !(fb->flags & B_EOUT)
- && (errno == EINTR || errno == EAGAIN || i == 0));
-
- if (i == 0) {
- errno = EAGAIN;
- return -1; /* return of 0 means B_EOUT and non-blocking */
- }
- else if (i < 0) {
- if (errno != EAGAIN) doerror(fb, B_WR);
- return -1;
- }
- fb->bytes_sent += i;
-
- /*
- * We should have written all the data, but if the fd was in a
- * strange (non-blocking) mode, then we might not have done so.
- */
- if (i < fb->outcnt)
- {
- int j, n=fb->outcnt;
- unsigned char *x=fb->outbase;
- for (j=i; j < n; j++) x[j-i] = x[j];
- }
- fb->outcnt -= i;
-
- /* If a soft timeout occurs while flushing, the handler should
- * have set the buffer flag B_EOUT.
- */
- if (fb->flags & B_EOUT)
- return -1;
- }
-
- return 0;
-}
-
-/*
- * Flushes the buffered stream.
- * Returns 0 on success or -1 on error
- */
-int bflush(BUFF *fb)
-{
- int ret;
-
- if (!(fb->flags & B_WR) || (fb->flags & B_EOUT)) return 0;
-
- if (fb->flags & B_WRERR) return -1;
-
- if (fb->flags & B_CHUNK) end_chunk(fb);
-
- ret = bflush_core(fb);
-
- if (ret == 0 && (fb->flags & B_CHUNK)) {
- start_chunk(fb);
- }
-
- return ret;
-}
-
-/*
- * Flushes and closes the file, even if an error occurred.
- * Discards an data that was not read, or not written by bflush()
- * Sets the EOF flag to indicate no futher data can be read,
- * and the EOUT flag to indicate no further data can be written.
- */
-int
-bclose(BUFF *fb)
-{
- int rc1, rc2, rc3;
-
- if (fb->flags & B_WR) rc1 = bflush(fb);
- else rc1 = 0;
- rc2 = close(fb->fd);
- if (fb->fd_in != fb->fd) rc3 = close(fb->fd_in);
- else rc3 = 0;
-
- fb->inptr = fb->inbase;
- fb->incnt = 0;
- fb->outcnt = 0;
-
- fb->flags |= B_EOF | B_EOUT;
- fb->fd = -1;
- fb->fd_in = -1;
-
- if (rc1 != 0) return rc1;
- else if (rc2 != 0) return rc2;
- else return rc3;
-}
-
-/*
- * returns the number of bytes written or -1 on error
- */
-int
-bputs(const char *x, BUFF *fb)
-{
- int i, j=strlen(x);
- i = bwrite(fb, x, j);
- if (i != j) return -1;
- else return j;
-}
-
-/*
- * returns the number of bytes written or -1 on error
- */
-int
-bvputs(BUFF *fb, ...)
-{
- int i, j, k;
- va_list v;
- const char *x;
-
- va_start(v, fb);
- for (k=0;;)
- {
- x = va_arg(v, const char *);
- if (x == NULL) break;
- j = strlen(x);
- i = bwrite(fb, x, j);
- if (i != j)
- {
- va_end(v);
- return -1;
- }
- k += i;
- }
-
- va_end(v);
-
- return k;
-}
-
-void
-bonerror(BUFF *fb, void (*error)(BUFF *, int, void *), void *data)
-{
- fb->error = error;
- fb->error_data = data;
-}
diff --git a/usr.sbin/httpd/src/buff.h b/usr.sbin/httpd/src/buff.h
deleted file mode 100644
index aa1926723d3..00000000000
--- a/usr.sbin/httpd/src/buff.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1996,1997 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. 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/>.
- *
- */
-
-#include <stdarg.h>
-
-/* Reading is buffered */
-#define B_RD (1)
-/* Writing is buffered */
-#define B_WR (2)
-#define B_RDWR (3)
-/* At end of file, or closed stream; no further input allowed */
-#define B_EOF (4)
-/* No further output possible */
-#define B_EOUT (8)
-/* A read error has occurred */
-#define B_RDERR (16)
-/* A write error has occurred */
-#define B_WRERR (32)
-#ifdef B_ERROR /* in SVR4: sometimes defined in /usr/include/sys/buf.h */
-#undef B_ERROR /* avoid "warning: `B_ERROR' redefined" */
-#endif
-#define B_ERROR (48)
-/* Use chunked writing */
-#define B_CHUNK (64)
-/* bflush() if a read would block */
-#define B_SAFEREAD (128)
-
-typedef struct buff_struct BUFF;
-
-struct buff_struct
-{
- int flags; /* flags */
- unsigned char *inptr; /* pointer to next location to read */
- int incnt; /* number of bytes left to read from input buffer;
- * always 0 if had a read error */
- int outchunk; /* location of chunk header when chunking */
- int outcnt; /* number of byte put in output buffer */
- unsigned char *inbase;
- unsigned char *outbase;
- int bufsiz;
- void (*error)(BUFF *fb, int op, void *data);
- void *error_data;
- long int bytes_sent; /* number of bytes actually written */
-
- pool *pool;
-
-/* could also put pointers to the basic I/O routines here */
- int fd; /* the file descriptor */
- int fd_in; /* input file descriptor, if different */
-};
-
-/* Options to bset/getopt */
-#define BO_BYTECT (1)
-
-/* Stream creation and modification */
-extern BUFF *bcreate(pool *p, int flags);
-extern void bpushfd(BUFF *fb, int fd_in, int fd_out);
-extern int bsetopt(BUFF *fb, int optname, const void *optval);
-extern int bgetopt(BUFF *fb, int optname, void *optval);
-extern int bsetflag(BUFF *fb, int flag, int value);
-extern int bclose(BUFF *fb);
-
-#define bgetflag(fb, flag) ((fb)->flags & (flag))
-
-/* Error handling */
-extern void bonerror(BUFF *fb, void (*error)(BUFF *, int, void *),
- void *data);
-
-/* I/O */
-extern int bread(BUFF *fb, void *buf, int nbyte);
-extern int bgets(char *s, int n, BUFF *fb);
-extern int blookc(char *buff, BUFF *fb);
-extern int bskiplf(BUFF *fb);
-extern int bwrite(BUFF *fb, const void *buf, int nbyte);
-extern int bflush(BUFF *fb);
-extern int bputs(const char *x, BUFF *fb);
-extern int bvputs(BUFF *fb, ...);
-extern int bprintf(BUFF *fb,const char *fmt,...);
-extern int vbprintf(BUFF *fb,const char *fmt,va_list vlist);
-
-/* Internal routines */
-extern int bflsbuf(int c, BUFF *fb);
-extern int bfilbuf(BUFF *fb);
-
-#define bgetc(fb) ( ((fb)->incnt == 0) ? bfilbuf(fb) : \
- ((fb)->incnt--, *((fb)->inptr++)) )
-
-#define bputc(c, fb) ((((fb)->flags & (B_EOUT|B_WRERR|B_WR)) != B_WR || \
- (fb)->outcnt == (fb)->bufsiz) ? bflsbuf(c, (fb)) : \
- ((fb)->outbase[(fb)->outcnt++] = (c), 0))
diff --git a/usr.sbin/httpd/src/conf.h b/usr.sbin/httpd/src/conf.h
deleted file mode 100644
index 03c90748dfe..00000000000
--- a/usr.sbin/httpd/src/conf.h
+++ /dev/null
@@ -1,763 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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/>.
- *
- */
-
-/*
- * conf.h: system-dependant #defines and includes...
- * See PORTING for a listing of what they mean
- */
-
-#if !defined(QNX) && !defined(MPE)
-#include <sys/param.h>
-#endif
-
-/* Define one of these according to your system. */
-#if defined(MPE)
-#include <sys/times.h>
-#define JMP_BUF sigjmp_buf
-#define NO_SETSID
-#define NO_KILLPG
-#define NO_WRITEV
-#define NEED_INITGROUPS
-#define NEED_STRCASECMP
-#define NEED_STRDUP
-#define NEED_STRNCASECMP
-extern void GETPRIVMODE();
-extern void GETUSERMODE();
-extern char *inet_ntoa();
-#define NO_SLACK
-
-#elif defined(SUNOS4)
-#define HAVE_GMTOFF
-#define HAVE_SYS_RESOURCE_H
-#undef NO_KILLPG
-#undef NO_SETSID
-char *crypt(const char *pw, const char *salt);
-char *mktemp(char *template);
-#define JMP_BUF sigjmp_buf
-#define HAVE_MMAP
-#include <sys/time.h>
-#define NEED_STRERROR
-typedef int rlim_t;
-#define memmove(a,b,c) bcopy(b,a,c)
-#define NO_LINGCLOSE
-#define USE_FLOCK_SERIALIZED_ACCEPT
-
-#elif defined(SOLARIS2)
-#undef HAVE_GMTOFF
-#define NO_KILLPG
-#undef NO_SETSID
-#define HAVE_SYS_RESOURCE_H
-#define bzero(a,b) memset(a,0,b)
-#define JMP_BUF sigjmp_buf
-#define USE_FCNTL_SERIALIZED_ACCEPT
-#define HAVE_MMAP
-#define HAVE_CRYPT_H
-int gethostname(char *name, int namelen);
-
-#elif defined(IRIX)
-#undef HAVE_GMTOFF
-/* IRIX has killpg, but it's only in _BSD_COMPAT, so don't use it in case
- * there's some weird conflict with non-BSD signals */
-#define NO_KILLPG
-#undef NO_SETSID
-#define JMP_BUF sigjmp_buf
-#define USE_FCNTL_SERIALIZED_ACCEPT
-#define HAVE_SHMGET
-#define HAVE_CRYPT_H
-#define NO_LONG_DOUBLE
-#define HAVE_BSTRING_H
-#define NO_LINGCLOSE
-
-#elif defined(HIUX)
-#define HAVE_SYS_RESOURCE_H
-#undef HAVE_GMTOFF
-#define NO_KILLPG
-#undef NO_SETSID
-#ifndef _HIUX_SOURCE
-#define _HIUX_SOURCE
-#endif
-#define JMP_BUF sigjmp_buf
-#define HAVE_SHMGET
-#define SELECT_NEEDS_CAST
-
-#elif defined(HPUX) || defined(HPUX10)
-#define HAVE_SYS_RESOURCE_H
-#undef HAVE_GMTOFF
-#define NO_KILLPG
-#undef NO_SETSID
-#ifndef _HPUX_SOURCE
-#define _HPUX_SOURCE
-#endif
-#define JMP_BUF sigjmp_buf
-#define HAVE_SHMGET
-#ifndef HPUX10
-#define SELECT_NEEDS_CAST
-typedef int rlim_t;
-#endif
-
-#elif defined(AIX)
-#undef HAVE_GMTOFF
-#undef NO_KILLPG
-#undef NO_SETSID
-#define HAVE_SYS_SELECT_H
-#define JMP_BUF sigjmp_buf
-#ifndef __ps2__
-#define HAVE_MMAP
-#define DEFAULT_GROUP "nobody"
-#endif
-#define DEFAULT_USER "nobody"
-#ifdef NEED_RLIM_T
-typedef int rlim_t;
-#endif
-
-#elif defined(ULTRIX)
-#define HAVE_GMTOFF
-#undef NO_KILLPG
-#undef NO_SETSID
-#define ULTRIX_BRAIN_DEATH
-#define NEED_STRDUP
-/* If you have Ultrix 4.3, and are using cc, const is broken */
-#ifndef __ultrix__ /* Hack to check for pre-Ultrix 4.4 cc */
-#define const /* Not implemented */
-#endif
-#define JMP_BUF sigjmp_buf
-
-#elif defined(OSF1)
-#define HAVE_GMTOFF
-#undef NO_KILLPG
-#undef NO_SETSID
-#define JMP_BUF sigjmp_buf
-#define HAVE_MMAP
-#define HAVE_CRYPT_H
-#define NO_LONG_DOUBLE
-
-#elif defined(PARAGON)
-#define HAVE_GMTOFF
-#undef NO_KILLPG
-#undef NO_SETSID
-#define JMP_BUF sigjmp_buf
-#define HAVE_MMAP
-#define HAVE_CRYPT_H
-#define NO_LONG_DOUBLE
-typedef int rlim_t;
-
-#elif defined(SEQUENT)
-#define HAVE_GMTOFF
-#undef NO_KILLPG
-#define NO_SETSID
-#define NEED_STRDUP
-#define tolower(c) (isupper(c) ? tolower(c) : c)
-
-#elif defined(NEXT)
-typedef unsigned short mode_t;
-#define HAVE_GMTOFF
-#undef NO_KILLPG
-#define NO_SETSID
-#define NEED_STRDUP
-#define NO_LINGCLOSE
-#define NO_UNISTD_H
-#undef _POSIX_SOURCE
-#ifndef FD_CLOEXEC
-#define FD_CLOEXEC 1
-#endif
-#ifndef S_ISDIR
-#define S_ISDIR(m) (((m)&(S_IFMT)) == (S_IFDIR))
-#endif
-#ifndef S_ISREG
-#define S_ISREG(m) (((m)&(S_IFMT)) == (S_IFREG))
-#endif
-#ifndef S_IXUSR
-#define S_IXUSR 00100
-#endif
-#ifndef S_IRGRP
-#define S_IRGRP 00040
-#endif
-#ifndef S_IXGRP
-#define S_IXGRP 00010
-#endif
-#ifndef S_IROTH
-#define S_IROTH 00004
-#endif
-#ifndef S_IXOTH
-#define S_IXOTH 00001
-#endif
-#ifndef S_IRUSR
-#define S_IRUSR S_IREAD
-#endif
-#ifndef S_IWUSR
-#define S_IWUSR S_IWRITE
-#endif
-#ifndef S_IWGRP
-#define S_IWGRP 000020
-#endif
-#ifndef S_IWOTH
-#define S_IWOTH 000002
-#ifndef rlim_t
-typedef int rlim_t;
-#endif
-typedef u_long n_long;
-#endif
-
-#define STDIN_FILENO 0
-#define STDOUT_FILENO 1
-#define STDERR_FILENO 2
-#define waitpid(a,b,c) wait4((a) == -1 ? 0 : (a),(union wait *)(b),c,NULL)
-typedef int pid_t;
-#define JMP_BUF jmp_buf
-#define USE_LONGJMP
-#define NO_USE_SIGACTION
-
-#elif defined(LINUX)
-#if LINUX > 1
-#define HAVE_SHMGET
-#define HAVE_SYS_RESOURCE_H
-typedef int rlim_t;
-#endif
-#define USE_FCNTL_SERIALIZED_ACCEPT
-#undef HAVE_GMTOFF
-#undef NO_KILLPG
-#undef NO_SETSID
-#undef NEED_STRDUP
-#define JMP_BUF sigjmp_buf
-#include <sys/time.h>
-
-#elif defined(SCO)
-#undef HAVE_GMTOFF
-#undef NO_KILLPG
-#undef NO_SETSID
-#define NEED_INITGROUPS
-#define NO_WRITEV
-#define JMP_BUF sigjmp_buf
-#define SIGURG SIGUSR1 /* but note, this signal will be sent to a process group if enabled (for OOB data). It is not currently enabled. */
-#include <sys/time.h>
-
-#elif defined(SCO5)
-
-#define JMP_BUF sigjmp_buf
-#define SIGURG SIGUSR1
-#define HAVE_SYS_SELECT_H
-#define USE_FCNTL_SERIALIZED_ACCEPT
-#define HAVE_MMAP
-#define HAVE_SYS_RESOURCE_H
-#define SecureWare
-
-/* Although SCO 5 defines these in <strings.h> (note the "s") they don't have
-consts. Sigh. */
-extern int strcasecmp(const char *,const char *);
-extern int strncasecmp(const char *,const char *,unsigned);
-
-#elif defined(AUX)
-/* These are to let -Wall compile more cleanly */
-extern int strcasecmp(const char *, const char *);
-extern int strncasecmp(const char *,const char *,unsigned);
-extern int set42sig(), getopt(), getpeername(), bzero();
-extern int listen(), bind(), socket(), getsockname();
-extern int accept(), gethostname(), connect(), lstat();
-extern int select(), killpg(), shutdown();
-extern int initgroups(), setsockopt();
-extern char *shmat();
-extern int shmctl();
-extern int shmget();
-extern char *sbrk();
-extern char *crypt();
-#include <sys/time.h>
-#undef HAVE_GMTOFF
-#undef NO_KILLPG
-#undef NO_SETSID
-#define NEED_STRDUP
-#define JMP_BUF sigjmp_buf
-/* fcntl() locking is expensive with NFS */
-#define USE_FLOCK_SERIALIZED_ACCEPT
-#define HAVE_SHMGET
-/*
- * NOTE: If when you run Apache under A/UX and you get a warning
- * that httpd couldn't move break, then the below value for
- * MOVEBREAK (64megs) is too large for your setup. Try reducing
- * to 0x2000000 which is still PLENTY of space. I doubt if
- * even on heavy systems sbrk() would be called at all...
- */
-#define MOVEBREAK 0x4000000
-#define NO_LINGCLOSE
-#define NO_SLACK
-
-#elif defined(SVR4)
-#define NO_KILLPG
-#undef NO_SETSID
-#undef NEED_STRDUP
-#define NEED_STRCASECMP
-#define NEED_STRNCASECMP
-#define bzero(a,b) memset(a,0,b)
-#define JMP_BUF sigjmp_buf
-/* A lot of SVR4 systems need this */
-#define USE_FCNTL_SERIALIZED_ACCEPT
-
-#elif defined(UW)
-#define NO_LINGCLOSE
-#define NO_KILLPG
-#undef NO_SETSID
-#undef NEED_STRDUP
-#define NEED_STRCASECMP
-#define NEED_STRNCASECMP
-#define bzero(a,b) memset(a,0,b)
-#define JMP_BUF sigjmp_buf
-#define HAVE_RESOURCE
-#define HAVE_MMAP
-#define HAVE_SHMGET
-#define HAVE_CRYPT_H
-#define HAVE_SYS_SELECT_H
-#define HAVE_SYS_RESOURCE_H
-#include <sys/time.h>
-#define _POSIX_SOURCE
-
-#elif defined(DGUX)
-#define NO_KILLPG
-#undef NO_SETSID
-#undef NEED_STRDUP
-#define NEED_STRCASECMP
-#define NEED_STRNCASECMP
-#define bzero(a,b) memset(a,0,b)
-#define JMP_BUF sigjmp_buf
-/* A lot of SVR4 systems need this */
-#define USE_FCNTL_SERIALIZED_ACCEPT
-
-#elif defined(__NetBSD__) || defined(__OpenBSD__)
-#define HAVE_SYS_RESOURCE_H
-#define HAVE_GMTOFF
-#undef NO_KILLPG
-#undef NO_SETSID
-#define JMP_BUF sigjmp_buf
-#define DEFAULT_USER "nobody"
-#define DEFAULT_GROUP "nogroup"
-#define HAVE_MMAP
-#define USE_FLOCK_SERIALIZED_ACCEPT
-
-
-#elif defined(UTS21)
-#undef HAVE_GMTOFF
-#undef NO_KILLPG
-#define NO_SETSID
-#define NEED_WAITPID
-#define STDIN_FILENO 0
-#define STDOUT_FILENO 1
-#define STDERR_FILENO 2
-#define strftime(buf,bufsize,fmt,tm) ascftime(buf,fmt,tm)
-#include <sys/types.h>
-
-#elif defined(APOLLO)
-#undef HAVE_GMTOFF
-#undef NO_KILLPG
-#undef NO_SETSID
-
-#elif defined(__FreeBSD__) || defined(__bsdi__)
-#if defined(__FreeBSD__)
-#include <osreldate.h>
-#endif
-#define HAVE_SYS_RESOURCE_H
-#define HAVE_GMTOFF
-#undef NO_KILLPG
-#undef NO_SETSID
-#define JMP_BUF sigjmp_buf
-#define HAVE_MMAP
-#define DEFAULT_USER "nobody"
-#define DEFAULT_GROUP "nogroup"
-#if defined(__bsdi__) || \
-(defined(__FreeBSD_version) && (__FreeBSD_version < 220000))
-typedef quad_t rlim_t;
-#endif
-#define USE_FLOCK_SERIALIZED_ACCEPT
-
-#elif defined(QNX)
-#ifndef crypt
-char *crypt(const char *pw, const char *salt);
-#endif
-#ifndef initgroups
-int initgroups (char *, int);
-#endif
-#ifndef strncasecmp
-#define strncasecmp strnicmp
-#endif
-#undef NO_KILLPG
-#undef NO_SETSID
-#define NEED_INITGROUPS
-#define NEED_SELECT_H
-#define NEED_PROCESS_H
-#define HAVE_SYS_SELECT_H
-#include <unix.h>
-#define JMP_BUF sigjmp_buf
-
-#elif defined(LYNXOS)
-#undef NO_KILLPG
-#undef NO_SETSID
-#define NEED_STRCASECMP
-#define NEED_STRNCASECMP
-#define NEED_INITGROUPS
-#define JMP_BUF jmp_buf
-
-#elif defined(UXPDS)
-#undef NEED_STRCASECMP
-#undef NEED_STRNCASECMP
-#undef NEED_STRDUP
-#undef HAVE_GMTOFF
-#define NO_KILLPG
-#undef NO_SETSID
-#define HAVE_RESOURCE 1
-#define bzero(a,b) memset(a,0,b)
-#define JMP_BUF sigjmp_buf
-#define USE_FCNTL_SERIALIZED_ACCEPT
-#define HAVE_MMAP
-#define HAVE_CRYPT_H
-
-#elif defined(__EMX__)
-/* Defines required for EMX OS/2 port. */
-#define JMP_BUF sigjmp_buf
-#define NO_KILLPG
-#define NEED_STRCASECMP
-#define NEED_STRNCASECMP
-#define NO_SETSID
-/* Add some drive name support */
-#define chdir _chdir2
-#include <sys/time.h>
-#define MAXSOCKETS 4096
-#define HAVE_MMAP
-
-#elif defined(__MACHTEN__)
-typedef int rlim_t;
-#define JMP_BUF sigjmp_buf
-#undef NO_KILLPG
-#define NO_SETSID
-#define HAVE_GMTOFF
-#ifndef __MACHTEN_PPC__
-#ifndef __MACHTEN_68K__
-#define __MACHTEN_68K__
-#endif
-#define USE_FLOCK_SERIALIZED_ACCEPT
-#define NO_USE_SIGACTION
-#define USE_LONGJMP
-#undef NEED_STRDUP
-#else
-#define HAVE_SHMGET
-#define USE_FCNTL_SERIALIZED_ACCEPT
-#endif
-
-/* Convex OS v11 */
-#elif defined(CONVEXOS11)
-#undef HAVE_GMTOFF
-#undef NO_KILLPG
-#undef NO_SETSID
-#undef NEED_STRDUP
-#define HAVE_MMAP
-
-#define NO_TIMEZONE
-#include <stdio.h>
-#include <sys/types.h>
-#define JMP_BUF jmp_buf
-typedef int rlim_t;
-
-#elif defined(ISC)
-#include <net/errno.h>
-#define NO_KILLPG
-#undef NO_SETSID
-#define HAVE_SHMGET
-#define SIGURG SIGUSR1
-#define JMP_BUF sigjmp_buf
-#define USE_FCNTL_SERIALIZED_ACCEPT
-
-/* Unknown system - Edit these to match */
-#else
-#ifdef BSD
-#define HAVE_GMTOFF
-#else
-#undef HAVE_GMTOFF
-#endif
-/* NO_KILLPG is set on systems that don't have killpg */
-#undef NO_KILLPG
-/* NO_SETSID is set on systems that don't have setsid */
-#undef NO_SETSID
-/* NEED_STRDUP is set on stupid systems that don't have strdup. */
-#undef NEED_STRDUP
-#endif
-
-/* Do we have sys/resource.h; assume that BSD does. */
-#ifndef HAVE_SYS_RESOURCE_H
-#ifdef BSD
-#define HAVE_SYS_RESOURCE_H
-#endif
-#endif /* HAVE_SYS_RESOURCE_H */
-
-/*
- * The particular directory style your system supports. If you have dirent.h
- * in /usr/include (POSIX) or /usr/include/sys (SYSV), #include
- * that file and define DIR_TYPE to be dirent. Otherwise, if you have
- * /usr/include/sys/dir.h, define DIR_TYPE to be direct and include that
- * file. If you have neither, I'm confused.
- */
-
-#include <sys/types.h>
-#include <stdarg.h>
-/*
- * We use snprintf() to avoid overflows, but we include
- * our own version (ap_snprintf). Allow for people to use their
- * snprintf() if they want
- */
-#ifdef HAVE_SNPRINTF
-#define ap_snprintf snprintf
-#define ap_vsnprintf vsnprintf
-#else
-int ap_snprintf(char *buf, size_t len, const char *format,...);
-int ap_vsnprintf(char *buf, size_t len, const char *format, va_list ap);
-#endif
-
-#if !defined(NEXT)
-#include <dirent.h>
-#define DIR_TYPE dirent
-#else
-#include <sys/dir.h>
-#define DIR_TYPE direct
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#ifndef MPE
-#include <sys/file.h>
-#endif
-#include <sys/socket.h>
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
-#include <ctype.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <sys/ioctl.h>
-#ifndef MPE
-#include <arpa/inet.h> /* for inet_ntoa */
-#endif
-#include <time.h> /* for ctime */
-#include <signal.h>
-#include <errno.h>
-#include <sys/wait.h>
-#include <pwd.h>
-#include <grp.h>
-#include <fcntl.h>
-#include <limits.h>
-#if !defined(QNX) && !defined(CONVEXOS11) && !defined(NEXT)
-#include <memory.h>
-#endif
-#ifdef NEED_PROCESS_H
-#include <process.h>
-#endif
-
-#include <regex.h>
-
-#ifdef HAVE_SYS_RESOURCE_H
-#include <sys/resource.h>
-#ifdef SUNOS4
-int getrlimit( int, struct rlimit *);
-int setrlimit( int, struct rlimit *);
-#endif
-#endif
-#ifdef HAVE_MMAP
-#ifndef __EMX__
-/* This file is not needed for OS/2 */
-#include <sys/mman.h>
-#endif
-#endif
-#if !defined(MAP_ANON) && defined(MAP_ANONYMOUS)
-#define MAP_ANON MAP_ANONYMOUS
-#endif
-
-#if defined(HAVE_MMAP) && defined(NO_MMAP)
-#undef HAVE_MMAP
-#endif
-
-#ifndef LOGNAME_MAX
-#define LOGNAME_MAX 25
-#endif
-
-#ifndef NEXT
-#include <unistd.h>
-#endif
-
-#ifdef ultrix
-#define ULTRIX_BRAIN_DEATH
-#endif
-
-#ifndef S_ISLNK
-#ifndef __EMX__
-/* Don't define this for OS/2 */
-#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
-#endif
-#endif
-
-#ifndef INADDR_NONE
-#define INADDR_NONE ((unsigned long) -1)
-#endif
-
-/*
- * Replace signal function with sigaction equivalent
- */
-#ifndef NO_USE_SIGACTION
-typedef void Sigfunc(int);
-
-#if defined(SIG_IGN) && !defined(SIG_ERR)
-#define SIG_ERR ((Sigfunc *)-1)
-#endif
-
-/*
- * For some strange reason, QNX defines signal to signal. Eliminate it.
- */
-#ifdef signal
-#undef signal
-#endif
-#define signal(s,f) ap_signal(s,f)
-Sigfunc *signal(int signo, Sigfunc *func);
-#endif
-
-#include <setjmp.h>
-
-#if defined(USE_LONGJMP)
-#define ap_longjmp(x, y) longjmp((x), (y))
-#define ap_setjmp(x) setjmp(x)
-#else
-#define ap_longjmp(x, y) siglongjmp((x), (y))
-#define ap_setjmp(x) sigsetjmp((x), 1)
-#endif
-
-/* Finding offsets of elements within structures.
- * Taken from the X code... they've sweated portability of this stuff
- * so we don't have to. Sigh...
- */
-
-#if defined(CRAY) || defined(__arm)
-#if __STDC__
-#define XtOffset(p_type,field) _Offsetof(p_type,field)
-#else
-#ifdef CRAY2
-#define XtOffset(p_type,field) \
- (sizeof(int)*((unsigned int)&(((p_type)NULL)->field)))
-
-#else /* !CRAY2 */
-
-#define XtOffset(p_type,field) ((unsigned int)&(((p_type)NULL)->field))
-
-#endif /* !CRAY2 */
-#endif /* __STDC__ */
-#else /* ! (CRAY || __arm) */
-
-#define XtOffset(p_type,field) \
- ((long) (((char *) (&(((p_type)NULL)->field))) - ((char *) NULL)))
-
-#endif /* !CRAY */
-
-#ifdef offsetof
-#define XtOffsetOf(s_type,field) offsetof(s_type,field)
-#else
-#define XtOffsetOf(s_type,field) XtOffset(s_type*,field)
-#endif
-
-#ifdef SUNOS_LIB_PROTOTYPES
-/* Prototypes needed to get a clean compile with gcc -Wall.
- * Believe it or not, these do have to be declared, at least on SunOS,
- * because they aren't mentioned in the relevant system headers.
- * Sun Quality Software. Gotta love it.
- */
-
-int getopt (int, char **, char *);
-
-int strcasecmp (char *, char *);
-int strncasecmp (char *, char *, int);
-int toupper(int);
-int tolower(int);
-
-int printf (char *, ...);
-int fprintf (FILE *, char *, ...);
-int fputs (char *, FILE *);
-int fread (char *, int, int, FILE *);
-int fwrite (char *, int, int, FILE *);
-int fflush (FILE *);
-int fclose (FILE *);
-int ungetc (int, FILE *);
-int _filbuf (FILE *); /* !!! */
-int _flsbuf (unsigned char, FILE *); /* !!! */
-int sscanf (char *, char *, ...);
-void setbuf (FILE *, char *);
-void perror (char *);
-
-time_t time (time_t *);
-int strftime (char *, int, char *, struct tm *);
-
-int initgroups (char *, int);
-int wait3 (int *, int, void*); /* Close enough for us... */
-int lstat (const char *, struct stat *);
-int stat (const char *, struct stat *);
-int flock (int, int);
-#ifndef NO_KILLPG
-int killpg(int, int);
-#endif
-int socket (int, int, int);
-int setsockopt (int, int, int, const char*, int);
-int listen (int, int);
-int bind (int, struct sockaddr *, int);
-int connect (int, struct sockaddr *, int);
-int accept (int, struct sockaddr *, int *);
-int shutdown (int, int);
-
-int getsockname (int s, struct sockaddr *name, int *namelen);
-int getpeername (int s, struct sockaddr *name, int *namelen);
-int gethostname (char *name, int namelen);
-void syslog (int, char *, ...);
-char *mktemp (char *);
-
-long vfprintf (FILE *, char *, va_list);
-
-#endif
diff --git a/usr.sbin/httpd/src/explain.c b/usr.sbin/httpd/src/explain.c
deleted file mode 100644
index 6490c940522..00000000000
--- a/usr.sbin/httpd/src/explain.c
+++ /dev/null
@@ -1,14 +0,0 @@
-#include <stdio.h>
-#include <stdarg.h>
-#include "explain.h"
-
-void _Explain(const char *szFile,int nLine,const char *szFmt,...)
- {
- va_list vlist;
-
- fprintf(stderr,"%s(%d): ",szFile,nLine);
- va_start(vlist,szFmt);
- vfprintf(stderr,szFmt,vlist);
- va_end(vlist);
- fputc('\n',stderr);
- }
diff --git a/usr.sbin/httpd/src/explain.h b/usr.sbin/httpd/src/explain.h
deleted file mode 100644
index 5912502585e..00000000000
--- a/usr.sbin/httpd/src/explain.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef EXPLAIN
-#define DEF_Explain
-#define Explain0(f)
-#define Explain1(f,a1)
-#define Explain2(f,a1,a2)
-#define Explain3(f,a1,a2,a3)
-#define Explain4(f,a1,a2,a3,a4)
-#define Explain5(f,a1,a2,a3,a4,a5)
-#define Explain6(f,a1,a2,a3,a4,a5,a6)
-#else
-#define DEF_Explain static const char *__ExplainFile=__FILE__;
-void _Explain(const char *szFile,int nLine,const char *szFmt,...);
-#define Explain0(f) _Explain(__ExplainFile,__LINE__,f)
-#define Explain1(f,a1) _Explain(__ExplainFile,__LINE__,f,a1)
-#define Explain2(f,a1,a2) _Explain(__ExplainFile,__LINE__,f,a1,a2)
-#define Explain3(f,a1,a2,a3) _Explain(__ExplainFile,__LINE__,f,a1,a2,a3)
-#define Explain4(f,a1,a2,a3,a4) _Explain(__ExplainFile,__LINE__,f,a1,a2,a3,a4)
-#define Explain5(f,a1,a2,a3,a4,a5) \
- _Explain(__ExplainFile,__LINE__,f,a1,a2,a3,a4,a5)
-#define Explain6(f,a1,a2,a3,a4,a5,a6) \
- _Explain(__ExplainFile,__LINE__,f,a1,a2,a3,a4,a5,a6)
-
-#endif
diff --git a/usr.sbin/httpd/src/http_bprintf.c b/usr.sbin/httpd/src/http_bprintf.c
deleted file mode 100644
index 3035b759ccf..00000000000
--- a/usr.sbin/httpd/src/http_bprintf.c
+++ /dev/null
@@ -1,602 +0,0 @@
-/*
- * printf() style routines stolen from FastCGI
- * Copyright (c) 1996 Open Market, Inc.
- */
-
-/*
- * Modified to work with Apache buffering routines by Ben Laurie
- * <ben@algroup.co.uk>.
- *
- * Modifications Copyright (C) 1996 Ben Laurie.
- *
- * History:
- * 18 May 1996 Initial revision [Ben Laurie]
- *
- */
-
-#include <assert.h>
-#include <math.h>
-#include "conf.h"
-#include "alloc.h"
-#include "buff.h"
-
-#if !defined(max)
-#define max(a,b) (a > b ? a : b)
-#endif
-
-#ifdef NO_LONG_DOUBLE
-#define LONG_DOUBLE double
-#else
-#define LONG_DOUBLE long double
-#endif
-
-#define FALSE 0
-#define TRUE 1
-
-#define PRINTF_BUFFLEN 100
- /*
- * More than sufficient space for all unmodified conversions
- * except %s and %f.
- */
-#define FMT_BUFFLEN 25
- /*
- * Max size of a format specifier is 1 + 5 + 7 + 7 + 2 + 1 + slop
- */
-#define NULL_STRING "(null)"
- /*
- * String displayed if given a NULL pointer.
- */
-
-/*
- * Copy n characters from *srcPtr to *destPtr, then increment
- * both *srcPtr and *destPtr by n.
- */
-static void CopyAndAdvance(char **destPtr, const char **srcPtr, int n)
- {
- char *dest = *destPtr;
- const char *src = *srcPtr;
- int i;
-
- for (i = 0; i < n; i++)
- *dest++ = *src++;
- *destPtr = dest;
- *srcPtr = src;
- }
-
-int vbprintf(BUFF *bp, const char *format, va_list arg)
- {
- const char *f,*fStop,*percentPtr,*p;
- char *fmtBuffPtr, *buffPtr;
- int op, performedOp, sizeModifier, buffLen, specifierLength;
- int fastPath, n, buffReqd, minWidth, precision, exp;
- int buffCount = 0;
- int auxBuffLen = 0;
- char *auxBuffPtr = NULL;
- int streamCount = 0;
- char fmtBuff[FMT_BUFFLEN];
- char buff[PRINTF_BUFFLEN];
-
- int intArg;
- short shortArg;
- long longArg;
- unsigned unsignedArg;
- unsigned long uLongArg;
- unsigned short uShortArg;
- char *charPtrArg = NULL;
- void *voidPtrArg;
- int *intPtrArg;
- long *longPtrArg;
- short *shortPtrArg;
- double doubleArg = 0.0;
- LONG_DOUBLE lDoubleArg = 0.0;
-
- fmtBuff[0] = '%';
- f=format;
- fStop = f + strlen(f);
- while (f != fStop)
- {
- percentPtr = memchr(f, '%', fStop - f);
- if(percentPtr == NULL) percentPtr = fStop;
- if(percentPtr != f)
- {
- if(bwrite(bp,f,percentPtr - f) < 0)
- goto ErrorReturn;
- streamCount += percentPtr - f;
- f = percentPtr;
- if(f == fStop)
- break;
- }
- fastPath = TRUE;
- /*
- * The following loop always executes either once or twice.
- */
- for (;;)
- {
- if(fastPath)
- {
- /*
- * Fast path: Scan optimistically, hoping that no flags,
- * minimum field width, or precision are specified.
- * Use the preallocated buffer, which is large enough
- * for all fast path cases. If the conversion specifier
- * is really more complex, run the loop a second time
- * using the slow path.
- * Note that fast path execution of %s bypasses the buffer
- * and %f is not attempted on the fast path due to
- * its large buffering requirements.
- */
- op = percentPtr[1];
- switch(op)
- {
- case 'l':
- case 'L':
- case 'h':
- sizeModifier = op;
- op = percentPtr[2];
- fmtBuff[1] = sizeModifier;
- fmtBuff[2] = op;
- fmtBuff[3] = '\0';
- specifierLength = 3;
- break;
- default:
- sizeModifier = ' ';
- fmtBuff[1] = op;
- fmtBuff[2] = '\0';
- specifierLength = 2;
- break;
- }
- buffPtr = buff;
- buffLen = PRINTF_BUFFLEN;
- }
- else
- {
- /*
- * Slow path: Scan the conversion specifier and construct
- * a new format string, compute an upper bound on the
- * amount of buffering that sprintf will require,
- * and allocate a larger buffer if necessary.
- */
- p = percentPtr + 1;
- fmtBuffPtr = &fmtBuff[1];
- /*
- * Scan flags
- */
- n = strspn(p, "-0+ #");
- if(n > 5)
- goto ErrorReturn;
- CopyAndAdvance(&fmtBuffPtr, &p, n);
-
- /* Optimiser bug in SCO 5 - p is not advanced here under -O2.
- * -K noinline fixes it. Ben.
- */
-
- /*
- * Scan minimum field width
- */
- n = strspn(p, "0123456789");
- if(n == 0)
- {
- if(*p == '*')
- {
- minWidth = va_arg(arg, int);
- if(abs(minWidth) > 999999) goto ErrorReturn;
- /*
- * The following use of strlen rather than the
- * value returned from sprintf is because SUNOS4
- * returns a char * instead of an int count.
- */
- sprintf(fmtBuffPtr, "%d", minWidth);
- fmtBuffPtr += strlen(fmtBuffPtr);
- p++;
- }
- else
- minWidth = 0;
- }
- else if(n <= 6)
- {
- minWidth = strtol(p, NULL, 10);
- CopyAndAdvance(&fmtBuffPtr, &p, n);
- }
- else
- goto ErrorReturn;
- /*
- * Scan precision
- */
- if(*p == '.')
- {
- p++;
- n = strspn(p, "0123456789");
- if(n == 0)
- {
- if(*p == '*')
- {
- precision = va_arg(arg, int);
- if(precision < 0) precision = 0;
- if(precision > 999999) goto ErrorReturn;
- /*
- * The following use of strlen rather than the
- * value returned from sprintf is because SUNOS4
- * returns a char * instead of an int count.
- */
- sprintf(fmtBuffPtr, ".%d", precision);
- fmtBuffPtr += strlen(fmtBuffPtr);
- p++;
- }
- else
- precision = 0;
- }
- else if(n <= 6)
- {
- precision = strtol(p, NULL, 10);
- *fmtBuffPtr++='.';
- CopyAndAdvance(&fmtBuffPtr, &p, n);
- }
- else
- goto ErrorReturn;
- }
- else
- precision = -1;
- /*
- * Scan size modifier and conversion operation
- */
- switch(*p)
- {
- case 'l':
- case 'L':
- case 'h':
- sizeModifier = *p;
- CopyAndAdvance(&fmtBuffPtr, &p, 1);
- break;
-
- default:
- sizeModifier = ' ';
- break;
- }
- op = *p;
- CopyAndAdvance(&fmtBuffPtr, &p, 1);
- assert(fmtBuffPtr - fmtBuff < FMT_BUFFLEN);
- *fmtBuffPtr = '\0';
- /*
- bwrite(bp,"[",1);
- bwrite(bp,fmtBuff,strlen(fmtBuff));
- bwrite(bp,"]",1);
- */
- specifierLength = p - percentPtr;
- /*
- * Bound the required buffer size. For s and f
- * conversions this requires examining the argument.
- */
- switch(op)
- {
- case 'd':
- case 'i':
- case 'u':
- case 'o':
- case 'x':
- case 'X':
- case 'c':
- case 'p':
- buffReqd = max(precision, 46);
- break;
-
- case 's':
- charPtrArg = va_arg(arg, char *);
- if (charPtrArg == NULL) {
- charPtrArg = NULL_STRING;
- };
- if(precision == -1)
- buffReqd = strlen(charPtrArg);
- else
- {
- p = memchr(charPtrArg, '\0', precision);
- if (p == NULL)
- buffReqd = precision;
- else
- buffReqd = p - charPtrArg;
- }
- break;
-
- case 'f':
- switch(sizeModifier)
- {
- case ' ':
- doubleArg = va_arg(arg, double);
- frexp(doubleArg, &exp);
- break;
-
- case 'L':
- lDoubleArg = va_arg(arg, LONG_DOUBLE);
- frexp(lDoubleArg, &exp);
- break;
-
- default:
- goto ErrorReturn;
- }
- if(precision == -1)
- precision = 6;
- buffReqd = precision + 3 + ((exp > 0) ? exp/3 : 0);
- break;
-
- case 'e':
- case 'E':
- case 'g':
- case 'G':
- if(precision == -1)
- precision = 6;
- buffReqd = precision + 8;
- break;
-
- case 'n':
- case '%':
- default:
- goto ErrorReturn;
- }
- buffReqd = max(buffReqd + 10, minWidth);
- /*
- * Allocate the buffer
- */
- if(buffReqd <= PRINTF_BUFFLEN)
- {
- buffPtr = buff;
- buffLen = PRINTF_BUFFLEN;
- }
- else
- {
- if(auxBuffPtr == NULL || buffReqd > auxBuffLen)
- {
- if(auxBuffPtr != NULL) free(auxBuffPtr);
- auxBuffPtr = malloc(buffReqd);
- auxBuffLen = buffReqd;
- if(auxBuffPtr == NULL)
- goto ErrorReturn;
- }
- buffPtr = auxBuffPtr;
- buffLen = auxBuffLen;
- }
- }
- /*
- * This giant switch statement requires the following variables
- * to be set up: op, sizeModifier, arg, buffPtr, fmtBuff.
- * When fastPath == FALSE and op == 's' or 'f', the argument
- * has been read into charPtrArg, doubleArg, or lDoubleArg.
- * The statement produces the boolean performedOp, TRUE iff
- * the op/sizeModifier were executed and argument consumed;
- * if performedOp, the characters written into buffPtr[]
- * and the character count buffCount (== EOF meaning error).
- *
- * The switch cases are arranged in the same order as in the
- * description of fprintf in section 15.11 of Harbison and Steele.
- */
- performedOp = TRUE;
- switch(op)
- {
- case 'd':
- case 'i':
- switch(sizeModifier)
- {
- case ' ':
- intArg = va_arg(arg, int);
- sprintf(buffPtr, fmtBuff, intArg);
- buffCount = strlen(buffPtr);
- break;
-
- case 'l':
- longArg = va_arg(arg, long);
- sprintf(buffPtr, fmtBuff, longArg);
- buffCount = strlen(buffPtr);
- break;
-
- case 'h':
- shortArg = va_arg(arg, short);
- sprintf(buffPtr, fmtBuff, shortArg);
- buffCount = strlen(buffPtr);
- break;
-
- default:
- goto ErrorReturn;
- }
- break;
-
- case 'u':
- case 'o':
- case 'x':
- case 'X':
- switch(sizeModifier)
- {
- case ' ':
- unsignedArg = va_arg(arg, unsigned);
- sprintf(buffPtr, fmtBuff, unsignedArg);
- buffCount = strlen(buffPtr);
- break;
-
- case 'l':
- uLongArg = va_arg(arg, unsigned long);
- sprintf(buffPtr, fmtBuff, uLongArg);
- buffCount = strlen(buffPtr);
- break;
-
- case 'h':
- uShortArg = va_arg(arg, unsigned short);
- sprintf(buffPtr, fmtBuff, uShortArg);
- buffCount = strlen(buffPtr);
- break;
-
- default:
- goto ErrorReturn;
- }
- break;
-
- case 'c':
- switch(sizeModifier)
- {
- case ' ':
- intArg = va_arg(arg, int);
- sprintf(buffPtr, fmtBuff, intArg);
- buffCount = strlen(buffPtr);
- break;
-
- case 'l':
- /*
- * XXX: Allowed by ISO C Amendment 1, but
- * many platforms don't yet support wint_t
- */
- goto ErrorReturn;
-
- default:
- goto ErrorReturn;
- }
- break;
-
- case 's':
- switch(sizeModifier)
- {
- case ' ':
- if(fastPath)
- {
- buffPtr = va_arg(arg, char *);
- if (buffPtr == NULL) {
- buffPtr = NULL_STRING;
- };
- buffCount = strlen(buffPtr);
- buffLen = buffCount + 1;
- }
- else
- {
- sprintf(buffPtr, fmtBuff, charPtrArg);
- buffCount = strlen(buffPtr);
- }
- break;
-
- case 'l':
- /*
- * XXX: Don't know how to convert a sequence
- * of wide characters into a byte stream, or
- * even how to predict the buffering required.
- */
- goto ErrorReturn;
-
- default:
- goto ErrorReturn;
- }
- break;
-
- case 'p':
- if(sizeModifier != ' ')
- goto ErrorReturn;
- voidPtrArg = va_arg(arg, void *);
- sprintf(buffPtr, fmtBuff, voidPtrArg);
- buffCount = strlen(buffPtr);
- break;
-
- case 'n':
- switch(sizeModifier)
- {
- case ' ':
- intPtrArg = va_arg(arg, int *);
- *intPtrArg = streamCount;
- break;
-
- case 'l':
- longPtrArg = va_arg(arg, long *);
- *longPtrArg = streamCount;
- break;
-
- case 'h':
- shortPtrArg = va_arg(arg, short *);
- *shortPtrArg = streamCount;
- break;
-
- default:
- goto ErrorReturn;
- }
- buffCount = 0;
- break;
-
- case 'f':
- if(fastPath)
- {
- performedOp = FALSE;
- break;
- }
-
- switch(sizeModifier)
- {
- case ' ':
- sprintf(buffPtr, fmtBuff, doubleArg);
- buffCount = strlen(buffPtr);
- break;
-
- case 'L':
- sprintf(buffPtr, fmtBuff, lDoubleArg);
- buffCount = strlen(buffPtr);
- break;
-
- default:
- goto ErrorReturn;
- }
- break;
- /* FIXME: Used to flow through here? Should it? Ben */
-
- case 'e':
- case 'E':
- case 'g':
- case 'G':
- switch(sizeModifier)
- {
- case ' ':
- doubleArg = va_arg(arg, double);
- sprintf(buffPtr, fmtBuff, doubleArg);
- buffCount = strlen(buffPtr);
- break;
-
- case 'L':
- lDoubleArg = va_arg(arg, LONG_DOUBLE);
- sprintf(buffPtr, fmtBuff, lDoubleArg);
- buffCount = strlen(buffPtr);
- break;
-
- default:
- goto ErrorReturn;
- }
- break;
-
- case '%':
- if(sizeModifier != ' ')
- goto ErrorReturn;
- buff[0] = '%';
- buffCount = 1;
- break;
-
- case '\0':
- goto ErrorReturn;
-
- default:
- performedOp = FALSE;
- break;
- } /* switch(op) */
-
- if(performedOp)
- break;
- if(!fastPath)
- goto ErrorReturn;
- fastPath = FALSE;
- } /* for (;;) */
- assert(buffCount < buffLen);
- if(buffCount > 0)
- {
- if(bwrite(bp,buffPtr,buffCount) < 0)
- goto ErrorReturn;
- streamCount += buffCount;
- }
- else if(buffCount < 0)
- goto ErrorReturn;
- f += specifierLength;
- } /* while(f != fStop) */
- goto NormalReturn;
-ErrorReturn:
- streamCount = -1;
-NormalReturn:
- if(auxBuffPtr != NULL)
- free(auxBuffPtr);
- return streamCount;
- }
diff --git a/usr.sbin/httpd/src/http_conf_globals.h b/usr.sbin/httpd/src/http_conf_globals.h
deleted file mode 100644
index 3a60e7db77b..00000000000
--- a/usr.sbin/httpd/src/http_conf_globals.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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/>.
- *
- */
-
-/*
- * Process config --- what the process ITSELF is doing
- */
-
-extern int standalone;
-extern uid_t user_id;
-extern char *user_name;
-extern gid_t group_id;
-#ifdef MULTIPLE_GROUPS
-extern gid_t group_id_list[NGROUPS_MAX];
-#endif
-extern int max_requests_per_child;
-extern struct in_addr bind_address;
-extern listen_rec *listeners;
-extern int daemons_to_start;
-extern int daemons_min_free;
-extern int daemons_max_free;
-extern int daemons_limit;
-extern int suexec_enabled;
-
-extern char *pid_fname;
-extern char *scoreboard_fname;
-extern char *lock_fname;
-extern char *server_argv0;
-
-/* Trying to allocate these in the config pool gets us into some *nasty*
- * chicken-and-egg problems in http_main.c --- where do you stick them
- * when pconf gets cleared? Better to just allocate a little space
- * statically...
- */
-
-extern char server_root[MAX_STRING_LEN];
-extern char server_confname[MAX_STRING_LEN];
-
diff --git a/usr.sbin/httpd/src/http_config.c b/usr.sbin/httpd/src/http_config.c
deleted file mode 100644
index d39af86994c..00000000000
--- a/usr.sbin/httpd/src/http_config.c
+++ /dev/null
@@ -1,1213 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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_config.c: once was auxillary functions for reading httpd's config
- * file and converting filenames into a namespace
- *
- * Rob McCool
- *
- * Wall-to-wall rewrite for Apache... commands which are part of the
- * server core can now be found next door in "http_core.c". Now contains
- * general command loop, and functions which do bookkeeping for the new
- * Apache config stuff (modules and configuration vectors).
- *
- * rst
- *
- */
-
-#define CORE_PRIVATE
-
-#include "httpd.h"
-#include "http_config.h"
-#include "http_core.h"
-#include "http_log.h" /* for errors in parse_htaccess */
-#include "http_request.h" /* for default_handler (see invoke_handler) */
-#include "http_conf_globals.h" /* Sigh... */
-#include "explain.h"
-
-DEF_Explain
-
-/****************************************************************
- *
- * We begin with the functions which deal with the linked list
- * of modules which control just about all of the server operation.
- */
-
-/* num_modules is the number of currently active modules. */
-static int num_modules = 0;
-/* total_modules is the number of modules linked in. */
-static int total_modules = 0;
-module *top_module = NULL;
-
-typedef int (*handler)(request_rec *);
-typedef void *(*maker)(pool *);
-typedef void *(*dir_maker)(pool *, char *);
-typedef void *(*merger)(pool *, void *, void *);
-
-/* Dealing with config vectors. These are associated with per-directory,
- * per-server, and per-request configuration, and have a void* pointer for
- * each modules. The nature of the structure pointed to is private to the
- * module in question... the core doesn't (and can't) know. However, there
- * are defined interfaces which allow it to create instances of its private
- * per-directory and per-server structures, and to merge the per-directory
- * structures of a directory and its subdirectory (producing a new one in
- * which the defaults applying to the base directory have been properly
- * overridden).
- */
-
-void *
-get_module_config (void *conf_vector, module *m)
-{
- void **confv = (void**)conf_vector;
- return confv[m->module_index];
-}
-
-void
-set_module_config (void *conf_vector, module *m, void *val)
-{
- void **confv = (void**)conf_vector;
- confv[m->module_index] = val;
-}
-
-void *
-create_empty_config (pool *p)
-{
- void **conf_vector = (void **)pcalloc(p, sizeof(void*) * total_modules);
- return (void *)conf_vector;
-}
-
-void *
-create_default_per_dir_config (pool *p)
-{
- void **conf_vector = (void **)pcalloc(p, sizeof(void*) * (total_modules+DYNAMIC_MODULE_LIMIT));
- module *modp;
-
- for (modp = top_module; modp; modp = modp->next) {
- dir_maker df = modp->create_dir_config;
-
- if (df) conf_vector[modp->module_index] = (*df)(p, NULL);
- }
-
- return (void*)conf_vector;
-}
-
-void *
-merge_per_dir_configs (pool *p, void *base, void *new)
-{
- void **conf_vector = (void **)pcalloc(p, sizeof(void*) * total_modules);
- void **base_vector = (void **) base;
- void **new_vector = (void **) new;
- module *modp;
-
- for (modp = top_module; modp; modp = modp->next) {
- merger df = modp->merge_dir_config;
- int i = modp->module_index;
-
- if (df && new_vector[i])
- conf_vector[i] = (*df)(p, base_vector[i], new_vector[i]);
- else
- conf_vector[i] = new_vector[i]? new_vector[i] : base_vector[i];
- }
-
- return (void*)conf_vector;
-}
-
-void *
-create_server_config (pool *p, server_rec *s)
-{
- void **conf_vector = (void **)pcalloc(p, sizeof(void*) * (total_modules+DYNAMIC_MODULE_LIMIT));
- module *modp;
-
- for (modp = top_module; modp; modp = modp->next) {
- if (modp->create_server_config)
- conf_vector[modp->module_index]=(*modp->create_server_config)(p,s);
- }
-
- return (void*)conf_vector;
-}
-
-void merge_server_configs (pool *p, void *base, void *virt)
-{
- /* Can reuse the 'virt' vector for the spine of it, since we don't
- * have to deal with the moral equivalent of .htaccess files here...
- */
-
- void **base_vector = (void **)base;
- void **virt_vector = (void **)virt;
- module *modp;
-
- for (modp = top_module; modp; modp = modp->next) {
- merger df = modp->merge_server_config;
- int i = modp->module_index;
-
- if (!virt_vector[i])
- virt_vector[i] = base_vector[i];
- else if (df)
- virt_vector[i] = (*df)(p, base_vector[i], virt_vector[i]);
- }
-}
-
-void *create_connection_config (pool *p) {
- return create_empty_config (p);
-}
-
-void *create_request_config (pool *p) {
- return create_empty_config (p);
-}
-
-void *create_per_dir_config (pool *p) {
- return create_empty_config (p);
-}
-
-#ifdef EXPLAIN
-
-struct
- {
- int offset;
- char *method;
- } aMethods[]=
- {
-#define m(meth) { XtOffsetOf(module,meth),#meth }
- m(translate_handler),
- m(check_user_id),
- m(auth_checker),
- m(type_checker),
- m(fixer_upper),
- m(logger),
- { -1,"?" },
-#undef m
- };
-
-char *ShowMethod(module *modp,int offset)
- {
- int n;
- static char buf[200];
-
- for(n=0 ; aMethods[n].offset >= 0 ; ++n)
- if(aMethods[n].offset == offset)
- break;
- ap_snprintf(buf, sizeof(buf), "%s:%s",modp->name,aMethods[n].method);
- return buf;
- }
-#else
-#define ShowMethod(modp,offset)
-#endif
-
-/****************************************************************
- *
- * Dispatch through the modules to find handlers for various phases
- * of request handling. These are invoked by http_request.c to actually
- * do the dirty work of slogging through the module structures.
- */
-
-int
-run_method (request_rec *r, int offset, int run_all)
-{
- module *modp;
- for (modp = top_module; modp; modp = modp->next) {
- handler mod_handler = *(handler *)(offset + (char *)(modp));
-
- if (mod_handler) {
- int result;
-
- Explain1("Run %s",ShowMethod(modp,offset));
- result = (*mod_handler)(r);
-
- Explain2("%s returned %d",ShowMethod(modp,offset),result);
- if (result != DECLINED && (!run_all || result != OK))
- return result;
- }
- }
-
- return run_all ? OK : DECLINED;
-}
-
-int translate_name(request_rec *r) {
- return run_method (r, XtOffsetOf (module, translate_handler), 0);
-}
-
-int check_access(request_rec *r) {
- return run_method (r, XtOffsetOf (module, access_checker), 1);
-}
-
-int find_types (request_rec *r) {
- return run_method (r, XtOffsetOf (module, type_checker), 0);
-}
-
-int run_fixups (request_rec *r) {
- return run_method (r, XtOffsetOf (module, fixer_upper), 1);
-}
-
-int log_transaction (request_rec *r) {
- return run_method (r, XtOffsetOf (module, logger), 1);
-}
-
-int header_parse (request_rec *r) {
- return run_method (r, XtOffsetOf (module, header_parser), 1);
-}
-
-/* Auth stuff --- anything that defines one of these will presumably
- * want to define something for the other. Note that check_auth is
- * separate from check_access to make catching some config errors easier.
- */
-
-int check_user_id (request_rec *r) {
- return run_method (r, XtOffsetOf (module, check_user_id), 0);
-}
-
-int check_auth (request_rec *r) {
- return run_method (r, XtOffsetOf (module, auth_checker), 0);
-}
-
-int invoke_handler (request_rec *r)
-{
- module *modp;
- handler_rec *handp;
- char *content_type = r->content_type ? r->content_type : default_type (r);
- char *handler, *p;
-
- if ((p = strchr(content_type, ';')) != NULL) { /* MIME type arguments */
- while (p > content_type && p[-1] == ' ') --p; /* strip trailing spaces */
- content_type = pstrndup(r->pool, content_type, p - content_type);
- }
- handler = r->handler ? r->handler : content_type;
-
- /* Pass one --- direct matches */
-
- for (modp = top_module; modp; modp = modp->next)
- {
- if (!modp->handlers) continue;
-
- for (handp = modp->handlers; handp->content_type; ++handp) {
- if (!strcasecmp (handler, handp->content_type)) {
- int result = (*handp->handler)(r);
-
- if (result != DECLINED) return result;
- }
- }
- }
-
- /* Pass two --- wildcard matches */
-
- for (modp = top_module; modp; modp = modp->next)
- {
- if (!modp->handlers) continue;
-
- for (handp = modp->handlers; handp->content_type; ++handp) {
- char *starp = strchr (handp->content_type, '*');
- int len;
-
- if (!starp) continue;
-
- len = starp - handp->content_type;
-
- if (!len || !strncasecmp (handler, handp->content_type, len))
- {
- int result = (*handp->handler)(r);
-
- if (result != DECLINED) return result;
- }
- }
- }
-
- return NOT_IMPLEMENTED;
-}
-
-/* One-time setup for precompiled modules --- NOT to be done on restart */
-
-void add_module (module *m)
-{
- /* This could be called from an AddModule httpd.conf command,
- * after the file has been linked and the module structure within it
- * teased out...
- */
-
- /* At some point, we may want to offer back-compatibility for
- * loading modules that are for older versions of Apache. For now,
- * though, we don't.
- */
-
- if (m->version != MODULE_MAGIC_NUMBER) {
- fprintf(stderr, "httpd: module \"%s\" is not compatible with this "
- "version of Apache.\n", m->name);
- fprintf(stderr, "Please contact the author for the correct version.\n");
- exit(1);
- }
-
- if (m->next == NULL) {
- m->next = top_module;
- top_module = m;
- }
- if (m->module_index == -1) {
- m->module_index = num_modules++;
- }
-}
-
-void setup_prelinked_modules ()
-{
- extern module *prelinked_modules[], *preloaded_modules[];
- module **m;
-
- /* First, set all module indices, and init total_modules. */
- total_modules = 0;
- for (m = preloaded_modules; *m; ++m, ++total_modules) {
- (*m)->module_index = total_modules;
- }
-
- for (m = prelinked_modules; *m; ++m) {
- add_module (*m);
- }
-}
-
-const char *find_module_name (module *m)
-{
- return m->name;
-}
-
-module *find_linked_module (const char *name)
-{
- module *modp;
-
- for (modp = top_module; modp; modp = modp->next) {
- if (strcmp(modp->name, name) == 0)
- return modp;
- }
- return NULL;
-}
-
-/* Add a named module. Returns 1 if module found, 0 otherwise. */
-int add_named_module (const char *name)
-{
- extern module *preloaded_modules[];
- module *modp;
- int i = 0;
-
- for (modp = preloaded_modules[i]; modp; modp = preloaded_modules[++i]) {
- if (strcmp(modp->name, name) == 0) {
- /* Only add modules that are not already enabled. */
- if (modp->next == NULL) {
- add_module(modp);
- }
- return 1;
- }
- }
-
- return 0;
-}
-
-/* Clear the internal list of modules, in preparation for starting over. */
-void clear_module_list ()
-{
- module **m = &top_module;
- module **next_m;
-
- while (*m) {
- next_m = &((*m)->next);
- *m = NULL;
- m = next_m;
- }
-
- num_modules = 0;
-
- /* This is required; so we add it always. */
- add_named_module ("http_core.c");
-}
-
-/*****************************************************************
- *
- * Resource, access, and .htaccess config files now parsed by a common
- * command loop.
- *
- * Let's begin with the basics; parsing the line and
- * invoking the function...
- */
-
-const char *invoke_cmd(const command_rec *cmd, cmd_parms *parms, void *mconfig,
- const char *args)
-{
- char *w, *w2, *w3;
- const char *errmsg;
-
- if ((parms->override & cmd->req_override) == 0)
- return pstrcat (parms->pool, cmd->name, " not allowed here", NULL);
-
- parms->info = cmd->cmd_data;
- parms->cmd = cmd;
-
- switch (cmd->args_how) {
- case RAW_ARGS:
- return (*cmd->func) (parms, mconfig, args);
-
- case NO_ARGS:
- if (*args != 0)
- return pstrcat (parms->pool, cmd->name, " takes no arguments",
- NULL);
-
- return (*cmd->func) (parms, mconfig);
-
- case TAKE1:
- w = getword_conf (parms->pool, &args);
-
- if (*w == '\0' || *args != 0)
- return pstrcat (parms->pool, cmd->name, " takes one argument",
- cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
-
- return (*cmd->func) (parms, mconfig, w);
-
- case TAKE2:
-
- w = getword_conf (parms->pool, &args);
- w2 = getword_conf (parms->pool, &args);
-
- if (*w == '\0' || *w2 == '\0' || *args != 0)
- return pstrcat (parms->pool, cmd->name, " takes two arguments",
- cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
-
- return (*cmd->func) (parms, mconfig, w, w2);
-
- case TAKE12:
-
- w = getword_conf (parms->pool, &args);
- w2 = getword_conf (parms->pool, &args);
-
- if (*w == '\0' || *args != 0)
- return pstrcat (parms->pool, cmd->name, " takes 1-2 arguments",
- cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
-
- return (*cmd->func) (parms, mconfig, w, *w2 ? w2 : NULL);
-
- case TAKE3:
-
- w = getword_conf (parms->pool, &args);
- w2 = getword_conf (parms->pool, &args);
- w3 = getword_conf (parms->pool, &args);
-
- if (*w == '\0' || *w2 == '\0' || *w3 == '\0' || *args != 0)
- return pstrcat (parms->pool, cmd->name, " takes three arguments",
- cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
-
- return (*cmd->func) (parms, mconfig, w, w2, w3);
-
- case TAKE23:
-
- w = getword_conf (parms->pool, &args);
- w2 = getword_conf (parms->pool, &args);
- w3 = *args ? getword_conf (parms->pool, &args) : NULL;
-
- if (*w == '\0' || *w2 == '\0' || *args != 0)
- return pstrcat (parms->pool, cmd->name, " takes two or three arguments",
- cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
-
- return (*cmd->func) (parms, mconfig, w, w2, w3);
-
- case TAKE123:
-
- w = getword_conf (parms->pool, &args);
- w2 = *args ? getword_conf (parms->pool, &args) : NULL;
- w3 = *args ? getword_conf (parms->pool, &args) : NULL;
-
- if (*w == '\0' || *args != 0)
- return pstrcat (parms->pool, cmd->name, " takes one, two or three arguments",
- cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
-
- return (*cmd->func) (parms, mconfig, w, w2, w3);
-
- case TAKE13:
-
- w = getword_conf (parms->pool, &args);
- w2 = *args ? getword_conf (parms->pool, &args) : NULL;
- w3 = *args ? getword_conf (parms->pool, &args) : NULL;
-
- if (*w == '\0' || (*w2 && !w3) || *args != 0)
- return pstrcat (parms->pool, cmd->name, " takes one or three arguments",
- cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
-
- return (*cmd->func) (parms, mconfig, w, w2, w3);
-
- case ITERATE:
-
- while (*(w = getword_conf (parms->pool, &args)) != '\0')
- if ((errmsg = (*cmd->func) (parms, mconfig, w)))
- return errmsg;
-
- return NULL;
-
- case ITERATE2:
-
- w = getword_conf (parms->pool, &args);
-
- if (*w == '\0' || *args == 0)
- return pstrcat(parms->pool, cmd->name,
- " requires at least two arguments",
- cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
-
-
- while (*(w2 = getword_conf (parms->pool, &args)) != '\0')
- if ((errmsg = (*cmd->func) (parms, mconfig, w, w2)))
- return errmsg;
-
- return NULL;
-
- case FLAG:
-
- w = getword_conf (parms->pool, &args);
-
- if (*w == '\0' || (strcasecmp(w, "on") && strcasecmp (w, "off")))
- return pstrcat (parms->pool, cmd->name, " must be On or Off",
- NULL);
-
- return (*cmd->func) (parms, mconfig, strcasecmp (w, "off") != 0);
-
- default:
-
- return pstrcat (parms->pool, cmd->name,
- " is improperly configured internally (server bug)",
- NULL);
- }
-}
-
-const command_rec *find_command (const char *name, const command_rec *cmds)
-{
- while (cmds->name)
- if (!strcasecmp (name, cmds->name))
- return cmds;
- else
- ++cmds;
-
- return NULL;
-}
-
-const command_rec *find_command_in_modules (const char *cmd_name, module **mod)
-{
- const command_rec *cmdp;
- module *modp;
-
- for (modp = *mod; modp; modp = modp->next)
- if (modp->cmds && (cmdp = find_command (cmd_name, modp->cmds))) {
- *mod = modp;
- return cmdp;
- }
-
- return NULL;
-}
-
-const char *handle_command (cmd_parms *parms, void *config, const char *l)
-{
- const char *args, *cmd_name, *retval;
- const command_rec *cmd;
- module *mod = top_module;
-
- ++parms->config_line;
- if((l[0] == '#') || (!l[0])) return NULL;
-
- args = l;
- cmd_name = getword_conf (parms->temp_pool, &args);
- if (*cmd_name == '\0') return NULL;
-
- do {
- if (!(cmd = find_command_in_modules (cmd_name, &mod))) {
- return pstrcat (parms->pool, "Invalid command ", cmd_name, NULL);
- }
- else {
- void *mconfig = get_module_config (config, mod);
- void *sconfig =
- get_module_config (parms->server->module_config, mod);
-
- if (!mconfig && mod->create_dir_config) {
- mconfig = (*mod->create_dir_config) (parms->pool, parms->path);
- set_module_config (config, mod, mconfig);
- }
-
- if (!sconfig && mod->create_server_config) {
- sconfig =
- (*mod->create_server_config)(parms->pool, parms->server);
- set_module_config (parms->server->module_config, mod, sconfig);
- }
-
- retval = invoke_cmd (cmd, parms, mconfig, args);
- mod = mod->next; /* Next time around, skip this one */
- }
- } while (retval && !strcmp(retval, DECLINE_CMD));
-
- return retval;
-}
-
-const char *srm_command_loop (cmd_parms *parms, void *config)
-{
- char l[MAX_STRING_LEN];
-
- while (!(cfg_getline (l, MAX_STRING_LEN, parms->infile))) {
- const char *errmsg = handle_command (parms, config, l);
- if (errmsg) return errmsg;
- }
-
- return NULL;
-}
-
-/*
- * Generic command functions...
- */
-
-const char *set_string_slot (cmd_parms *cmd, char *struct_ptr, char *arg)
-{
- /* This one's pretty generic... */
-
- int offset = (int)cmd->info;
- *(char **)(struct_ptr + offset) = pstrdup (cmd->pool, arg);
- return NULL;
-}
-
-const char *set_flag_slot (cmd_parms *cmd, char *struct_ptr, int arg)
-{
- /* This one's pretty generic too... */
-
- int offset = (int)cmd->info;
- *(int *)(struct_ptr + offset) = arg ? 1 : 0;
- return NULL;
-}
-
-/*****************************************************************
- *
- * Reading whole config files...
- */
-
-cmd_parms default_parms = { NULL, 0, -1, NULL, 0, NULL, NULL, NULL, NULL };
-
-char *server_root_relative (pool *p, char *file)
-{
-#ifdef __EMX__
- /* Add support for OS/2 drive names */
- if ((file[0] == '/') || (file[1] == ':')) return file;
-#else
- if (file[0] == '/') return file;
-#endif
- return make_full_path (p, server_root, file);
-}
-
-void process_resource_config(server_rec *s, char *fname, pool *p, pool *ptemp)
-{
- FILE *cfg;
- const char *errmsg;
- cmd_parms parms;
- struct stat finfo;
-
- fname = server_root_relative (p, fname);
-
- if (!(strcmp(fname, server_root_relative(p, RESOURCE_CONFIG_FILE))) ||
- !(strcmp(fname, server_root_relative(p, ACCESS_CONFIG_FILE)))) {
- if (stat(fname, &finfo) == -1)
- return;
- }
-
- /* GCC's initialization extensions are soooo nice here... */
-
- parms = default_parms;
- parms.config_file = fname;
- parms.pool = p;
- parms.temp_pool = ptemp;
- parms.server = s;
- parms.override = (RSRC_CONF|OR_ALL)&~(OR_AUTHCFG|OR_LIMIT);
-
- if(!(cfg = fopen(fname, "r"))) {
- perror("fopen");
- fprintf(stderr,"httpd: could not open document config file %s\n",
- fname);
- exit(1);
- }
-
- parms.infile = cfg;
-
- errmsg = srm_command_loop (&parms, s->lookup_defaults);
-
- if (errmsg) {
- fprintf (stderr, "Syntax error on line %d of %s:\n",
- parms.config_line, fname);
- fprintf (stderr, "%s\n", errmsg);
- exit(1);
- }
-
- fclose(cfg);
-}
-
-
-int parse_htaccess(void **result, request_rec *r, int override,
- char *d, char *filename)
-{
- FILE *f;
- cmd_parms parms;
- const char *errmsg;
- const struct htaccess_result *cache;
- struct htaccess_result *new;
- void *dc;
-
-/* firstly, search cache */
- for (cache=r->htaccess; cache != NULL; cache=cache->next)
- if (cache->override == override && strcmp(cache->dir, d) == 0)
- {
- if (cache->htaccess != NULL) *result = cache->htaccess;
- return OK;
- }
-
- parms = default_parms;
- parms.override = override;
- parms.pool = r->pool;
- parms.temp_pool = r->pool;
- parms.server = r->server;
- parms.path = d;
-
- if((f=pfopen(r->pool, filename, "r"))) {
- dc = create_per_dir_config (r->pool);
-
- parms.infile = f;
- parms.config_file = filename;
-
- errmsg = srm_command_loop (&parms, dc);
-
- pfclose(r->pool, f);
-
- if (errmsg) {
- log_reason (errmsg, filename, r);
- return SERVER_ERROR;
- }
-
- *result = dc;
- } else {
- if (errno == ENOENT || errno == ENOTDIR)
- dc = NULL;
- else {
- log_unixerr("pfopen", filename,
- "unable to check htaccess file, ensure it is readable",
- r->server);
- return HTTP_FORBIDDEN;
- }
- }
-
-/* cache it */
- new = palloc(r->pool, sizeof(struct htaccess_result));
- new->dir = pstrdup(r->pool, d);
- new->override = override;
- new->htaccess = dc;
-/* add to head of list */
- new->next = r->htaccess;
- r->htaccess = new;
-
- return OK;
-}
-
-/*****************************************************************
- *
- * Virtual host stuff; note that the commands that invoke this stuff
- * are with the command table in http_core.c.
- */
-
-/*
- * 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 void 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;
-
- t = strchr(w, ':');
- if (t) {
- if( strcmp(t+1,"*") == 0 ) {
- port = 0;
- } else if( (i = atoi(t+1)) ) {
- port = i;
- } else {
- fprintf( stderr, "Port must be numeric\n" );
- }
- *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(
-#ifdef DGUX
- ( my_addr = inet_network(w) )
-#else
- ( my_addr = inet_addr(w) )
-#endif
- != INADDR_NONE ) {
- is_an_ip_addr = 1;
- }
- if( is_an_ip_addr ) {
- sar = pcalloc( p, sizeof( server_addr_rec ) );
- **paddr = sar;
- *paddr = &sar->next;
- sar->host_addr.s_addr = my_addr;
- sar->host_port = port;
- sar->virthost = pstrdup(p, w);
- if (t != NULL) *t = ':';
- return;
- }
-
- hep = gethostbyname(w);
-
- if ((!hep) || (hep->h_addrtype != AF_INET || !hep->h_addr_list[0])) {
- fprintf (stderr, "Cannot resolve host name %s --- ignoring!\n", w);
- if (t != NULL) *t = ':';
- return;
- }
-
- for( i = 0; hep->h_addr_list[i]; ++i ) {
- sar = 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 = pstrdup(p, w);
- }
-
- if (t != NULL) *t = ':';
-}
-
-server_rec *init_virtual_host (pool *p, const char *hostname,
- server_rec *main_server)
-{
- server_rec *s = (server_rec *)pcalloc (p, sizeof (server_rec));
- server_addr_rec **addrs;
-
-#ifdef RLIMIT_NOFILE
- struct rlimit limits;
-
- getrlimit ( RLIMIT_NOFILE, &limits );
- if ( limits.rlim_cur < limits.rlim_max ) {
- limits.rlim_cur += 2;
- if ( setrlimit ( RLIMIT_NOFILE, &limits ) < 0 ) {
- perror ("setrlimit(RLIMIT_NOFILE)");
- fprintf (stderr, "Cannot exceed hard limit for open files");
- }
- }
-#endif
-
- s->server_admin = NULL;
- s->server_hostname = NULL;
- s->error_fname = NULL;
- s->srm_confname = NULL;
- s->access_confname = NULL;
- s->timeout = 0;
- s->keep_alive_timeout = 0;
- s->keep_alive = -1;
- s->keep_alive_max = -1;
- s->error_log = main_server->error_log;
- /* start the list of addreses */
- addrs = &s->addrs;
- while( hostname[0] ) {
- get_addresses( p, getword_conf( p, &hostname ), &addrs,
- main_server->port );
- }
- /* terminate the list */
- *addrs = NULL;
- if( s->addrs ) {
- if (s->addrs->host_port) {
- s->port = s->addrs->host_port; /* set them the same, by default */
- } else {
- /* otherwise we get a port of 0 on redirects */
- s->port = main_server->port;
- }
- }
- s->next = NULL;
-
- s->is_virtual = 1;
- s->names = NULL;
-
- s->module_config = create_empty_config (p);
- s->lookup_defaults = create_per_dir_config (p);
-
- s->server_uid = user_id;
- s->server_gid = group_id;
-
- return s;
-}
-
-int is_virtual_server (server_rec *s)
-{
- return s->is_virtual;
-}
-
-void fixup_virtual_hosts (pool *p, server_rec *main_server)
-{
- server_rec *virt;
-
- for (virt = main_server->next; virt; virt = virt->next) {
- merge_server_configs (p, main_server->module_config,
- virt->module_config);
-
- virt->lookup_defaults =
- merge_per_dir_configs (p, main_server->lookup_defaults,
- virt->lookup_defaults);
-
- if (virt->server_admin == NULL)
- virt->server_admin = main_server->server_admin;
-
- if (virt->srm_confname == NULL)
- virt->srm_confname = main_server->srm_confname;
-
- if (virt->access_confname == NULL)
- virt->access_confname = main_server->access_confname;
-
- if (virt->timeout == 0)
- virt->timeout = main_server->timeout;
-
- if (virt->keep_alive_timeout == 0)
- virt->keep_alive_timeout = main_server->keep_alive_timeout;
-
- if (virt->keep_alive == -1)
- virt->keep_alive = main_server->keep_alive;
-
- if (virt->keep_alive_max == -1)
- virt->keep_alive_max = main_server->keep_alive_max;
-
- if (virt->send_buffer_size == 0)
- virt->send_buffer_size = main_server->send_buffer_size;
- }
-}
-
-/*****************************************************************
- *
- * Getting *everything* configured...
- */
-
-void init_config_globals (pool *p)
-{
- /* ServerRoot, server_confname set in httpd.c */
-
- standalone = 1;
- user_name = DEFAULT_USER;
- user_id = uname2id(DEFAULT_USER);
- group_id = gname2id(DEFAULT_GROUP);
- daemons_to_start = DEFAULT_START_DAEMON;
- daemons_min_free = DEFAULT_MIN_FREE_DAEMON;
- daemons_max_free = DEFAULT_MAX_FREE_DAEMON;
- daemons_limit = HARD_SERVER_LIMIT;
- pid_fname = DEFAULT_PIDLOG;
- scoreboard_fname = DEFAULT_SCOREBOARD;
- lock_fname = DEFAULT_LOCKFILE;
- max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD;
- bind_address.s_addr = htonl(INADDR_ANY);
- listeners = NULL;
-}
-
-server_rec *init_server_config(pool *p)
-{
- server_rec *s = (server_rec *)pcalloc (p, sizeof (server_rec));
-
- s->port = DEFAULT_PORT;
- s->server_admin = DEFAULT_ADMIN;
- s->server_hostname = NULL;
- s->error_fname = DEFAULT_ERRORLOG;
- s->error_log = stderr;
- s->srm_confname = RESOURCE_CONFIG_FILE;
- s->access_confname = ACCESS_CONFIG_FILE;
- s->timeout = DEFAULT_TIMEOUT;
- s->keep_alive_timeout = DEFAULT_KEEPALIVE_TIMEOUT;
- s->keep_alive_max = DEFAULT_KEEPALIVE;
- s->keep_alive = 1;
- s->next = NULL;
- s->addrs = pcalloc(p, sizeof (server_addr_rec));
- s->addrs->host_addr.s_addr = htonl (INADDR_ANY); /* NOT virtual host;
- * don't match any real network
- * interface.
- */
- s->addrs->host_port = 0; /* matches any port */
-
- s->module_config = create_server_config (p, s);
- s->lookup_defaults = create_default_per_dir_config (p);
-
- return s;
-}
-
-server_rec *read_config(pool *p, pool *ptemp, char *confname)
-{
- server_rec *s = init_server_config(p);
-
- init_config_globals(p);
-
- /* All server-wide config files now have the SAME syntax... */
-
- process_resource_config (s, confname, p, ptemp);
- process_resource_config (s, s->srm_confname, p, ptemp);
- process_resource_config (s, s->access_confname, p, ptemp);
-
- fixup_virtual_hosts (p, s);
-
- return s;
-}
-
-
-void init_modules(pool *p, server_rec *s)
-{
- module *m;
-
- for (m = top_module; m; m = m->next)
- if (m->init)
- (*m->init) (s, p);
-}
-
-
-/********************************************************************
- * Configuration directives are restricted in terms of where they may
- * appear in the main configuration files and/or .htaccess files according
- * to the bitmask req_override in the command_rec structure.
- * If any of the overrides set in req_override are also allowed in the
- * context in which the command is read, then the command is allowed.
- * The context is determined as follows:
- *
- * inside *.conf --> override = (RSRC_CONF|OR_ALL)&~(OR_AUTHCFG|OR_LIMIT);
- * within <Directory> or <Location> --> override = OR_ALL|ACCESS_CONF;
- * within .htaccess --> override = AllowOverride for current directory;
- *
- * the result is, well, a rather confusing set of possibilities for when
- * a particular directive is allowed to be used. This procedure prints
- * in English where the given (pc) directive can be used.
- */
-void show_overrides(command_rec *pc, module *pm)
-{
- int n = 0;
-
- printf("\tAllowed in *.conf ");
- if ((pc->req_override & (OR_OPTIONS|OR_FILEINFO|OR_INDEXES)) ||
- ((pc->req_override & RSRC_CONF) &&
- ((pc->req_override & (ACCESS_CONF|OR_AUTHCFG|OR_LIMIT)))))
- printf("anywhere");
- else if (pc->req_override & RSRC_CONF)
- printf("only outside <Directory> or <Location>");
- else
- printf("only inside <Directory> or <Location>");
-
- /* Warn if the directive is allowed inside <Directory> or .htaccess
- * but module doesn't support per-dir configuration */
-
- if ((pc->req_override & (OR_ALL|ACCESS_CONF)) && !pm->create_dir_config)
- printf(" [no per-dir config]");
-
- if (pc->req_override & OR_ALL) {
- printf(" and in .htaccess\n\twhen AllowOverride");
-
- if ((pc->req_override & OR_ALL) == OR_ALL)
- printf(" isn't None");
- else {
- printf(" includes ");
-
- if (pc->req_override & OR_AUTHCFG) {
- if (n++) printf(" or ");
- printf("AuthConfig");
- }
- if (pc->req_override & OR_LIMIT) {
- if (n++) printf(" or ");
- printf("Limit");
- }
- if (pc->req_override & OR_OPTIONS) {
- if (n++) printf(" or ");
- printf("Options");
- }
- if (pc->req_override & OR_FILEINFO) {
- if (n++) printf(" or ");
- printf("FileInfo");
- }
- if (pc->req_override & OR_INDEXES) {
- if (n++) printf(" or ");
- printf("Indexes");
- }
- }
- }
- printf("\n");
-}
-
-/* Show the preloaded configuration directives, the help string explaining
- * the directive arguments, in what module they are handled, and in
- * what parts of the configuration they are allowed. Used for httpd -h.
- */
-void show_directives()
-{
- extern module *preloaded_modules[];
- command_rec *pc;
- int n;
-
- for (n = 0; preloaded_modules[n]; ++n)
- for (pc = preloaded_modules[n]->cmds; pc && pc->name; ++pc) {
- printf("%s\n", pc->name);
- if (pc->errmsg)
- printf("\t%s\n", pc->errmsg);
- printf("\t%s\n", preloaded_modules[n]->name);
- show_overrides(pc, preloaded_modules[n]);
- }
-}
-
-/* Show the preloaded module names. Used for httpd -l. */
-void show_modules()
-{
- extern module *preloaded_modules[];
- int n;
-
- printf ("Compiled-in modules:\n");
- for (n = 0; preloaded_modules[n]; ++n)
- printf (" %s\n", preloaded_modules[n]->name);
-}
-
diff --git a/usr.sbin/httpd/src/http_config.h b/usr.sbin/httpd/src/http_config.h
deleted file mode 100644
index 02d041854d3..00000000000
--- a/usr.sbin/httpd/src/http_config.h
+++ /dev/null
@@ -1,298 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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/>.
- *
- */
-
-/*
- * The central data structures around here...
- */
-
-/* Command dispatch structures... */
-
-enum cmd_how {
- RAW_ARGS, /* cmd_func parses command line itself */
- TAKE1, /* one argument only */
- TAKE2, /* two arguments only */
- ITERATE, /* one argument, occuring multiple times
- * (e.g., IndexIgnore)
- */
- ITERATE2, /* two arguments, 2nd occurs multiple times
- * (e.g., AddIcon)
- */
- FLAG, /* One of 'On' or 'Off' */
- NO_ARGS, /* No args at all, e.g. </Directory> */
- TAKE12, /* one or two arguments */
- TAKE3, /* three arguments only */
- TAKE23, /* two or three arguments */
- TAKE123, /* one, two or three arguments */
- TAKE13 /* one or three arguments */
-};
-
-typedef struct command_struct {
- char *name; /* Name of this command */
- const char *(*func)(); /* Function invoked */
- void *cmd_data; /* Extra data, for functions which
- * implement multiple commands...
- */
- int req_override; /* What overrides need to be allowed to
- * enable this command.
- */
- enum cmd_how args_how; /* What the command expects as arguments */
-
- char *errmsg; /* 'usage' message, in case of syntax errors */
-} command_rec;
-
-/* The allowed locations for a configuration directive are the union of
- * those indicated by each set bit in the req_override mask.
- *
- * (req_override & RSRC_CONF) => *.conf outside <Directory> or <Location>
- * (req_override & ACCESS_CONF) => *.conf inside <Directory> or <Location>
- * (req_override & OR_AUTHCFG) => *.conf inside <Directory> or <Location>
- * and .htaccess when AllowOverride AuthConfig
- * (req_override & OR_LIMIT) => *.conf inside <Directory> or <Location>
- * and .htaccess when AllowOverride Limit
- * (req_override & OR_OPTIONS) => *.conf anywhere
- * and .htaccess when AllowOverride Options
- * (req_override & OR_FILEINFO) => *.conf anywhere
- * and .htaccess when AllowOverride FileInfo
- * (req_override & OR_INDEXES) => *.conf anywhere
- * and .htaccess when AllowOverride Indexes
- */
-#define OR_NONE 0
-#define OR_LIMIT 1
-#define OR_OPTIONS 2
-#define OR_FILEINFO 4
-#define OR_AUTHCFG 8
-#define OR_INDEXES 16
-#define OR_UNSET 32
-#define ACCESS_CONF 64
-#define RSRC_CONF 128
-#define OR_ALL (OR_LIMIT|OR_OPTIONS|OR_FILEINFO|OR_AUTHCFG|OR_INDEXES)
-
-/* This can be returned by a function if they don't wish to handle
- * a command. Make it something not likely someone will actually use
- * as an error code.
- */
-
-#define DECLINE_CMD "\a\b"
-
-/*
- * This structure is passed to a command which is being invoked,
- * to carry a large variety of miscellaneous data which is all of
- * use to *somebody*...
- */
-
-typedef struct {
- void *info; /* Argument to command from cmd_table */
- int override; /* Which allow-override bits are set */
- int limited; /* Which methods are <Limit>ed */
-
- char *config_file; /* Filename cmd read from */
- int config_line; /* Line cmd read from */
- FILE *infile; /* fd for more lines (not currently used) */
-
- pool *pool; /* Pool to allocate new storage in */
- pool *temp_pool; /* Pool for scratch memory; persists during
- * configuration, but wiped before the first
- * request is served...
- */
- server_rec *server; /* Server_rec being configured for */
- char *path; /* If configuring for a directory,
- * pathname of that directory.
- */
- const command_rec *cmd; /* configuration command */
-} cmd_parms;
-
-/* This structure records the existence of handlers in a module... */
-
-typedef struct {
- char *content_type;
- int (*handler) (request_rec *);
-} handler_rec;
-
-/*
- * Module structures. Just about everything is dispatched through
- * these, directly or indirectly (through the command and handler
- * tables).
- */
-
-typedef struct module_struct {
- int version; /* API version, *not* module version;
- * check that module is compatible with this
- * version of the server.
- */
- int module_index; /* Index to this modules structures in
- * config vectors.
- */
-
- const char *name;
-
- struct module_struct *next;
-
-#ifdef ULTRIX_BRAIN_DEATH
- void (*init)();
- void *(*create_dir_config)();
- void *(*merge_dir_config)();
- void *(*create_server_config)();
- void *(*merge_server_config)();
-#else
- void (*init)(server_rec *, pool *);
- void *(*create_dir_config)(pool *p, char *dir);
- void *(*merge_dir_config)(pool *p, void *base_conf, void *new_conf);
- void *(*create_server_config)(pool *p, server_rec *s);
- void *(*merge_server_config)(pool *p, void *base_conf, void *new_conf);
-#endif
-
- command_rec *cmds;
- handler_rec *handlers;
-
- /* Hooks for getting into the middle of server ops...
- *
- * translate_handler --- translate URI to filename
- * access_checker --- check access by host address, etc. All of these
- * run; if all decline, that's still OK.
- * check_user_id --- get and validate user id from the HTTP request
- * auth_checker --- see if the user (from check_user_id) is OK *here*.
- * If all of *these* decline, the request is rejected
- * (as a SERVER_ERROR, since the module which was
- * supposed to handle this was configured wrong).
- * type_checker --- Determine MIME type of the requested entity;
- * sets content_type, _encoding and _language fields.
- * logger --- log a transaction. Not supported yet out of sheer
- * laziness on my part.
- */
-
- int (*translate_handler)(request_rec *);
- int (*check_user_id)(request_rec *);
- int (*auth_checker)(request_rec *);
- int (*access_checker)(request_rec *);
- int (*type_checker)(request_rec *);
- int (*fixer_upper)(request_rec *);
- int (*logger)(request_rec *);
- int (*header_parser)(request_rec *);
-} module;
-
-/* Initializer for the first few module slots, which are only
- * really set up once we start running. Note that the first word
- * is a version check; this should allow us to deal with changes to
- * the API (the server can detect an old-format module, and either
- * handle it back-compatibly, or at least signal an error).
- */
-
-#define MODULE_MAGIC_NUMBER 19970622
-#define STANDARD_MODULE_STUFF MODULE_MAGIC_NUMBER, -1, __FILE__, NULL
-
-/* Generic accessors for other modules to get at their own module-specific
- * data
- */
-
-void *get_module_config (void *conf_vector, module *m);
-void set_module_config (void *conf_vector, module *m, void *val);
-
-/* Generic command handling function... */
-
-const char *set_string_slot (cmd_parms *, char *, char *);
-const char *set_flag_slot (cmd_parms *, char *, int);
-
-/* For modules which need to read config files, open logs, etc. ...
- * this returns the fname argument if it begins with '/'; otherwise
- * it relativizes it wrt server_root.
- */
-
-char *server_root_relative (pool *p, char *fname);
-
-/* Finally, the hook for dynamically loading modules in... */
-
-void add_module (module *m);
-int add_named_module (const char *name);
-void clear_module_list ();
-const char *find_module_name (module *m);
-module *find_linked_module (const char *name);
-
-#ifdef CORE_PRIVATE
-
-/* For http_main.c... */
-
-server_rec *read_config (pool *conf_pool, pool *temp_pool, char *config_name);
-void init_modules(pool *p, server_rec *s);
-void setup_prelinked_modules();
-void show_directives();
-void show_modules();
-
-/* For http_request.c... */
-
-void *create_request_config (pool *p);
-void *create_per_dir_config (pool *p);
-void *merge_per_dir_configs (pool *p, void *base, void *new);
-
-/* For http_core.c... (<Directory> command and virtual hosts) */
-
-int parse_htaccess(void **result, request_rec *r, int override,
- char *path, char *file);
-const char *srm_command_loop (cmd_parms *parms, void *config);
-
-server_rec *init_virtual_host (pool *p, const char *hostname, server_rec *main_server);
-int is_virtual_server (server_rec *);
-void process_resource_config(server_rec *s, char *fname, pool *p, pool *ptemp);
-
-/* Module-method dispatchers, also for http_request.c */
-
-int translate_name (request_rec *);
-int directory_walk (request_rec *); /* check symlinks, get per-dir config */
-int check_access (request_rec *); /* check access on non-auth basis */
-int check_user_id (request_rec *); /* obtain valid username from client auth */
-int check_auth (request_rec *); /* check (validated) user is authorized here */
-int find_types (request_rec *); /* identify MIME type */
-int run_fixups (request_rec *); /* poke around for other metainfo, etc.... */
-int invoke_handler (request_rec *);
-int log_transaction (request_rec *r);
-int header_parse (request_rec *);
-
-#endif
diff --git a/usr.sbin/httpd/src/http_core.c b/usr.sbin/httpd/src/http_core.c
deleted file mode 100644
index ce44d64eea2..00000000000
--- a/usr.sbin/httpd/src/http_core.c
+++ /dev/null
@@ -1,1413 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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/>.
- *
- */
-
-#define CORE_PRIVATE
-#include "httpd.h"
-#include "http_config.h"
-#include "http_core.h"
-#include "http_protocol.h" /* For index_of_response(). Grump. */
-#include "http_conf_globals.h"
-
-#include "http_main.h" /* For the default_handler below... */
-#include "http_log.h"
-#include "rfc1413.h"
-#include "util_md5.h"
-#include "scoreboard.h"
-
-/* Server core module... This module provides support for really basic
- * server operations, including options and commands which control the
- * operation of other modules. Consider this the bureaucracy module.
- *
- * The core module also defines handlers, etc., do handle just enough
- * to allow a server with the core module ONLY to actually serve documents
- * (though it slaps DefaultType on all of 'em); this was useful in testing,
- * but may not be worth preserving.
- *
- * This file could almost be mod_core.c, except for the stuff which affects
- * the http_conf_globals.
- */
-
-void *create_core_dir_config (pool *a, char *dir)
-{
- core_dir_config *conf =
- (core_dir_config *)pcalloc(a, sizeof(core_dir_config));
-
- if (!dir || dir[strlen(dir) - 1] == '/') conf->d = dir;
- else if (strncmp(dir,"proxy:",6)==0) conf->d = pstrdup (a, dir);
- else conf->d = pstrcat (a, dir, "/", NULL);
- conf->d_is_matchexp = conf->d ? is_matchexp( conf->d ) : 0;
-
-
- conf->opts = dir ? OPT_UNSET : OPT_ALL;
- conf->opts_add = conf->opts_remove = OPT_NONE;
- conf->override = dir ? OR_UNSET : OR_ALL;
-
- conf->content_md5 = 2;
-
- conf->hostname_lookups = 2;/* binary, but will use 2 as an "unset = on" */
- conf->do_rfc1413 = DEFAULT_RFC1413 | 2; /* set bit 1 to indicate default */
- conf->satisfy = SATISFY_NOSPEC;
-
-#ifdef RLIMIT_CPU
- conf->limit_cpu = NULL;
-#endif
-#if defined(RLIMIT_DATA) || defined(RLIMIT_VMEM)
- conf->limit_mem = NULL;
-#endif
-#ifdef RLIMIT_NPROC
- conf->limit_nproc = NULL;
-#endif
-
- conf->sec = make_array (a, 2, sizeof(void *));
-
- return (void *)conf;
-}
-
-void *merge_core_dir_configs (pool *a, void *basev, void *newv)
-{
- core_dir_config *base = (core_dir_config *)basev;
- core_dir_config *new = (core_dir_config *)newv;
- core_dir_config *conf =
- (core_dir_config *)pcalloc (a, sizeof(core_dir_config));
- int i;
-
- memcpy ((char *)conf, (const char *)base, sizeof(core_dir_config));
- if( base->response_code_strings ) {
- conf->response_code_strings = palloc(a,
- sizeof(*conf->response_code_strings) * RESPONSE_CODES );
- memcpy( conf->response_code_strings, base->response_code_strings,
- sizeof(*conf->response_code_strings) * RESPONSE_CODES );
- }
-
- conf->d = new->d;
- conf->d_is_matchexp = new->d_is_matchexp;
- conf->r = new->r;
-
- if (new->opts != OPT_UNSET) conf->opts = new->opts;
- if (new->opts_add) conf->opts |= new->opts_add;
- if (new->opts_remove) conf->opts &= ~(new->opts_remove);
-
- if (new->override != OR_UNSET) conf->override = new->override;
- if (new->default_type) conf->default_type = new->default_type;
-
- if (new->auth_type) conf->auth_type = new->auth_type;
- if (new->auth_name) conf->auth_name = new->auth_name;
- if (new->requires) conf->requires = new->requires;
-
- if( new->response_code_strings ) {
- if( conf->response_code_strings == NULL ) {
- conf->response_code_strings = palloc(a,
- sizeof(*conf->response_code_strings) * RESPONSE_CODES );
- memcpy( conf->response_code_strings, new->response_code_strings,
- sizeof(*conf->response_code_strings) * RESPONSE_CODES );
- } else {
- for (i = 0; i < RESPONSE_CODES; ++i)
- if (new->response_code_strings[i] != NULL)
- conf->response_code_strings[i] = new->response_code_strings[i];
- }
- }
- if (new->hostname_lookups != 2)
- conf->hostname_lookups = new->hostname_lookups;
- if ((new->do_rfc1413 & 2) == 0) conf->do_rfc1413 = new->do_rfc1413;
- if ((new->content_md5 & 2) == 0) conf->content_md5 = new->content_md5;
-
-#ifdef RLIMIT_CPU
- if (new->limit_cpu) conf->limit_cpu = new->limit_cpu;
-#endif
-#if defined(RLIMIT_DATA) || defined(RLIMIT_VMEM)
- if (new->limit_mem) conf->limit_mem = new->limit_mem;
-#endif
-#ifdef RLIMIT_NPROC
- if (new->limit_nproc) conf->limit_nproc = new->limit_nproc;
-#endif
-
- conf->sec = append_arrays (a, base->sec, new->sec);
-
- if (new->satisfy != SATISFY_NOSPEC) conf->satisfy = new->satisfy;
- return (void*)conf;
-}
-
-void *create_core_server_config (pool *a, server_rec *s)
-{
- core_server_config *conf =
- (core_server_config *)pcalloc(a, sizeof(core_server_config));
- int is_virtual = s->is_virtual;
-
- conf->access_name = is_virtual ? NULL : DEFAULT_ACCESS_FNAME;
- conf->document_root = is_virtual ? NULL : DOCUMENT_LOCATION;
- conf->sec = make_array (a, 40, sizeof(void *));
- conf->sec_url = make_array (a, 40, sizeof(void *));
-
- return (void *)conf;
-}
-
-void *merge_core_server_configs (pool *p, void *basev, void *virtv)
-{
- core_server_config *base = (core_server_config *)basev;
- core_server_config *virt = (core_server_config *)virtv;
- core_server_config *conf =
- (core_server_config *)pcalloc(p, sizeof(core_server_config));
-
- *conf = *virt;
- if (!conf->access_name) conf->access_name = base->access_name;
- if (!conf->document_root) conf->document_root = base->document_root;
- conf->sec = append_arrays (p, base->sec, virt->sec);
- conf->sec_url = append_arrays (p, base->sec_url, virt->sec_url);
-
- return conf;
-}
-
-/* Add per-directory configuration entry (for <directory> section);
- * these are part of the core server config.
- */
-
-void add_per_dir_conf (server_rec *s, void *dir_config)
-{
- core_server_config *sconf = get_module_config (s->module_config,
- &core_module);
- void **new_space = (void **) push_array (sconf->sec);
-
- *new_space = dir_config;
-}
-
-void add_per_url_conf (server_rec *s, void *url_config)
-{
- core_server_config *sconf = get_module_config (s->module_config,
- &core_module);
- void **new_space = (void **) push_array (sconf->sec_url);
-
- *new_space = url_config;
-}
-
-void add_file_conf (core_dir_config *conf, void *url_config)
-{
- void **new_space = (void **) push_array (conf->sec);
-
- *new_space = url_config;
-}
-
-/*****************************************************************
- *
- * There are some elements of the core config structures in which
- * other modules have a legitimate interest (this is ugly, but necessary
- * to preserve NCSA back-compatibility). So, we have a bunch of accessors
- * here...
- */
-
-int allow_options (request_rec *r)
-{
- core_dir_config *conf =
- (core_dir_config *)get_module_config(r->per_dir_config, &core_module);
-
- return conf->opts;
-}
-
-int allow_overrides (request_rec *r)
-{
- core_dir_config *conf =
- (core_dir_config *)get_module_config(r->per_dir_config, &core_module);
-
- return conf->override;
-}
-
-char *auth_type (request_rec *r)
-{
- core_dir_config *conf =
- (core_dir_config *)get_module_config(r->per_dir_config, &core_module);
-
- return conf->auth_type;
-}
-
-char *auth_name (request_rec *r)
-{
- core_dir_config *conf =
- (core_dir_config *)get_module_config(r->per_dir_config, &core_module);
-
- return conf->auth_name;
-}
-
-char *default_type (request_rec *r)
-{
- core_dir_config *conf =
- (core_dir_config *)get_module_config(r->per_dir_config, &core_module);
-
- return conf->default_type ? conf->default_type : DEFAULT_TYPE;
-}
-
-char *document_root (request_rec *r) /* Don't use this!!! */
-{
- core_server_config *conf =
- (core_server_config *)get_module_config(r->server->module_config,
- &core_module);
-
- return conf->document_root;
-}
-
-array_header *requires (request_rec *r)
-{
- core_dir_config *conf =
- (core_dir_config *)get_module_config(r->per_dir_config, &core_module);
-
- return conf->requires;
-}
-
-int satisfies (request_rec *r)
-{
- core_dir_config *conf =
- (core_dir_config *)get_module_config(r->per_dir_config, &core_module);
-
- return conf->satisfy;
-}
-
-/* Should probably just get rid of this... the only code that cares is
- * part of the core anyway (and in fact, it isn't publicised to other
- * modules).
- */
-
-char *response_code_string (request_rec *r, int error_index)
-{
- core_dir_config *conf =
- (core_dir_config *)get_module_config(r->per_dir_config, &core_module);
-
- if( conf->response_code_strings == NULL ) {
- return NULL;
- }
- return conf->response_code_strings[error_index];
-}
-
-const char *
-get_remote_host(conn_rec *conn, void *dir_config, int type)
-{
- struct in_addr *iaddr;
- struct hostent *hptr;
-#ifdef MAXIMUM_DNS
- char **haddr;
-#endif
- core_dir_config *dir_conf = NULL;
-
-/* If we haven't checked the host name, and we want to */
- if (dir_config)
- dir_conf = (core_dir_config *)get_module_config(dir_config, &core_module);
-
- if ((!dir_conf) || (type != REMOTE_NOLOOKUP && conn->remote_host == NULL && dir_conf->hostname_lookups))
- {
-#ifdef STATUS
- int old_stat = update_child_status(conn->child_num,
- SERVER_BUSY_DNS,
- (request_rec*)NULL);
-#endif /* STATUS */
- iaddr = &(conn->remote_addr.sin_addr);
- hptr = gethostbyaddr((char *)iaddr, sizeof(struct in_addr), AF_INET);
- if (hptr != NULL)
- {
- conn->remote_host = pstrdup(conn->pool, (void *)hptr->h_name);
- str_tolower (conn->remote_host);
-
-#ifdef MAXIMUM_DNS
- /* Grrr. Check THAT name to make sure it's really the name of the addr. */
- /* Code from Harald Hanche-Olsen <hanche@imf.unit.no> */
-
- hptr = gethostbyname(conn->remote_host);
- if (hptr)
- {
- for(haddr=hptr->h_addr_list; *haddr; haddr++)
- if(((struct in_addr *)(*haddr))->s_addr == iaddr->s_addr)
- break;
- }
- if((!hptr) || (!(*haddr)))
- conn->remote_host = NULL;
-#endif
- }
-/* if failed, set it to the NULL string to indicate error */
- if (conn->remote_host == NULL) conn->remote_host = "";
-#ifdef STATUS
- (void)update_child_status(conn->child_num,old_stat,(request_rec*)NULL);
-#endif /* STATUS */
- }
-
-/*
- * Return the desired information; either the remote DNS name, if found,
- * or either NULL (if the hostname was requested) or the IP address
- * (if any identifier was requested).
- */
- if (conn->remote_host != NULL && conn->remote_host[0] != '\0')
- return conn->remote_host;
- else
- {
- if (type == REMOTE_HOST) return NULL;
- else return conn->remote_ip;
- }
-}
-
-const char *
-get_remote_logname(request_rec *r)
-{
- core_dir_config *dir_conf;
-
- if (r->connection->remote_logname != NULL)
- return r->connection->remote_logname;
-
-/* If we haven't checked the identity, and we want to */
- dir_conf = (core_dir_config *)
- get_module_config(r->per_dir_config, &core_module);
-
- if (dir_conf->do_rfc1413 & 1)
- return rfc1413(r->connection, r->server);
- else
- return NULL;
-}
-
-/*****************************************************************
- *
- * Commands... this module handles almost all of the NCSA httpd.conf
- * commands, but most of the old srm.conf is in the the modules.
- */
-
-const char *set_access_name (cmd_parms *cmd, void *dummy, char *arg)
-{
- void *sconf = cmd->server->module_config;
- core_server_config *conf = get_module_config (sconf, &core_module);
-
- conf->access_name = arg;
- return NULL;
-}
-
-const char *set_document_root (cmd_parms *cmd, void *dummy, char *arg)
-{
- void *sconf = cmd->server->module_config;
- core_server_config *conf = get_module_config (sconf, &core_module);
-
- if (!is_directory (arg))
- if (cmd->server->is_virtual)
- fprintf (stderr, "Warning: DocumentRoot [%s] does not exist\n", arg);
- else
- return "DocumentRoot must be a directory";
-
- conf->document_root = arg;
- return NULL;
-}
-
-const char *set_error_document (cmd_parms *cmd, core_dir_config *conf,
- char *line)
-{
- int error_number, index_number, idx500;
- char *w;
-
- /* 1st parameter should be a 3 digit number, which we recognize;
- * convert it into an array index
- */
-
- w = getword_conf_nc (cmd->pool, &line);
- error_number = atoi(w);
-
- idx500 = index_of_response(HTTP_INTERNAL_SERVER_ERROR);
-
- if (error_number == HTTP_INTERNAL_SERVER_ERROR)
- index_number = idx500;
- else if ((index_number = index_of_response(error_number)) == idx500)
- return pstrcat(cmd->pool, "Unsupported HTTP response code ", w, NULL);
-
- /* Store it... */
-
- if( conf->response_code_strings == NULL ) {
- conf->response_code_strings = pcalloc(cmd->pool,
- sizeof(*conf->response_code_strings) * RESPONSE_CODES );
- }
- conf->response_code_strings[index_number] = pstrdup (cmd->pool, line);
-
- return NULL;
-}
-
-/* access.conf commands...
- *
- * The *only* thing that can appear in access.conf at top level is a
- * <Directory> section. NB we need to have a way to cut the srm_command_loop
- * invoked by dirsection (i.e., <Directory>) short when </Directory> is seen.
- * We do that by returning an error, which dirsection itself recognizes and
- * discards as harmless. Cheesy, but it works.
- */
-
-const char *set_override (cmd_parms *cmd, core_dir_config *d, const char *l)
-{
- char *w;
-
- d->override = OR_NONE;
- while(l[0]) {
- w = getword_conf (cmd->pool, &l);
- if(!strcasecmp(w,"Limit"))
- d->override |= OR_LIMIT;
- else if(!strcasecmp(w,"Options"))
- d->override |= OR_OPTIONS;
- else if(!strcasecmp(w,"FileInfo"))
- d->override |= OR_FILEINFO;
- else if(!strcasecmp(w,"AuthConfig"))
- d->override |= OR_AUTHCFG;
- else if(!strcasecmp(w,"Indexes"))
- d->override |= OR_INDEXES;
- else if(!strcasecmp(w,"None"))
- d->override = OR_NONE;
- else if(!strcasecmp(w,"All"))
- d->override = OR_ALL;
- else
- return pstrcat (cmd->pool, "Illegal override option ", w, NULL);
- }
-
- return NULL;
-}
-
-const char *set_options (cmd_parms *cmd, core_dir_config *d, const char *l)
-{
- char opt;
- int first = 1;
- char action;
-
- while(l[0]) {
- char *w = getword_conf(cmd->pool, &l);
- action = '\0';
-
- if (*w == '+' || *w == '-')
- action = *(w++);
- else if (first) {
- d->opts = OPT_NONE;
- first = 0;
- }
-
- if(!strcasecmp(w,"Indexes"))
- opt = OPT_INDEXES;
- else if(!strcasecmp(w,"Includes"))
- opt = OPT_INCLUDES;
- else if(!strcasecmp(w,"IncludesNOEXEC"))
- opt = (OPT_INCLUDES | OPT_INCNOEXEC);
- else if(!strcasecmp(w,"FollowSymLinks"))
- opt = OPT_SYM_LINKS;
- else if(!strcasecmp(w,"SymLinksIfOwnerMatch"))
- opt = OPT_SYM_OWNER;
- else if(!strcasecmp(w,"execCGI"))
- opt = OPT_EXECCGI;
- else if (!strcasecmp(w,"MultiViews"))
- opt = OPT_MULTI;
- else if (!strcasecmp(w,"RunScripts")) /* AI backcompat. Yuck */
- opt = OPT_MULTI|OPT_EXECCGI;
- else if(!strcasecmp(w,"None"))
- opt = OPT_NONE;
- else if(!strcasecmp(w,"All"))
- opt = OPT_ALL;
- else
- return pstrcat (cmd->pool, "Illegal option ", w, NULL);
-
- if (action == '-')
- d->opts_remove |= opt;
- else if (action == '+')
- d->opts_add |= opt;
- else
- d->opts |= opt;
- }
-
- return NULL;
-}
-
-const char *satisfy (cmd_parms *cmd, core_dir_config *c, char *arg)
-{
- if(!strcasecmp(arg,"all"))
- c->satisfy = SATISFY_ALL;
- else if(!strcasecmp(arg,"any"))
- c->satisfy = SATISFY_ANY;
- else
- return "Satisfy either 'any' or 'all'.";
- return NULL;
-}
-
-const char *require (cmd_parms *cmd, core_dir_config *c, char *arg)
-{
- require_line *r;
-
- if (!c->requires)
- c->requires = make_array (cmd->pool, 2, sizeof(require_line));
-
- r = (require_line *)push_array (c->requires);
- r->requirement = pstrdup (cmd->pool, arg);
- r->method_mask = cmd->limited;
- return NULL;
-}
-
-const char *limit (cmd_parms *cmd, void *dummy, const char *arg)
-{
- const char *limited_methods = getword(cmd->pool,&arg,'>');
- int limited = 0;
-
- if (cmd->limited > 0) return "Can't nest <Limit> sections";
-
- while(limited_methods[0]) {
- char *method = getword_conf (cmd->pool, &limited_methods);
- if(!strcasecmp(method,"GET")) limited |= (1 << M_GET);
- else if(!strcasecmp(method,"PUT")) limited |= (1 << M_PUT);
- else if(!strcasecmp(method,"POST")) limited |= (1 << M_POST);
- else if(!strcasecmp(method,"DELETE")) limited |= (1 << M_DELETE);
- else if(!strcasecmp(method,"CONNECT")) limited |= (1 << M_CONNECT);
- else if(!strcasecmp(method,"OPTIONS")) limited |= (1 << M_OPTIONS);
- else return "unknown method in <Limit>";
- }
-
- cmd->limited = limited;
- return NULL;
-}
-
-const char *endlimit (cmd_parms *cmd, void *dummy, void *dummy2)
-{
- if (cmd->limited == -1) return "</Limit> unexpected";
-
- cmd->limited = -1;
- return NULL;
-}
-
-static const char end_dir_magic[] = "</Directory> outside of any <Directory> section";
-
-const char *end_dirsection (cmd_parms *cmd, void *dummy) {
- return end_dir_magic;
-}
-
-const char *dirsection (cmd_parms *cmd, void *dummy, const char *arg)
-{
- const char *errmsg;
- char *endp = strrchr (arg, '>');
- int old_overrides = cmd->override;
- char *old_path = cmd->path;
- core_dir_config *conf;
- void *new_dir_conf = create_per_dir_config (cmd->pool);
- regex_t *r = NULL;
-
- if (endp) *endp = '\0';
-
- if (cmd->path) return "<Directory> sections don't nest";
- if (cmd->limited != -1) return "Can't have <Directory> within <Limit>";
-
- cmd->path = getword_conf (cmd->pool, &arg);
-#ifdef __EMX__
- /* Fix OS/2 HPFS filename case problem. */
- cmd->path = strlwr(cmd->path);
-#endif
- cmd->override = OR_ALL|ACCESS_CONF;
-
- if (!strcmp(cmd->path, "~")) {
- cmd->path = getword_conf (cmd->pool, &arg);
- r = pregcomp(cmd->pool, cmd->path, REG_EXTENDED);
- }
-
- errmsg = srm_command_loop (cmd, new_dir_conf);
- if (errmsg != end_dir_magic) return errmsg;
-
- conf = (core_dir_config *)get_module_config(new_dir_conf, &core_module);
- conf->r = r;
-
- add_per_dir_conf (cmd->server, new_dir_conf);
-
- cmd->path = old_path;
- cmd->override = old_overrides;
-
- return NULL;
-}
-
-static const char end_url_magic[] = "</Location> outside of any <Location> section";
-
-const char *end_urlsection (cmd_parms *cmd, void *dummy) {
- return end_url_magic;
-}
-
-const char *urlsection (cmd_parms *cmd, void *dummy, const char *arg)
-{
- const char *errmsg;
- char *endp = strrchr (arg, '>');
- int old_overrides = cmd->override;
- char *old_path = cmd->path;
- core_dir_config *conf;
- regex_t *r = NULL;
-
- void *new_url_conf = create_per_dir_config (cmd->pool);
-
- if (endp) *endp = '\0';
-
- if (cmd->path) return "<Location> sections don't nest";
- if (cmd->limited != -1) return "Can't have <Location> within <Limit>";
-
- cmd->path = getword_conf (cmd->pool, &arg);
- cmd->override = OR_ALL|ACCESS_CONF;
-
- if (!strcmp(cmd->path, "~")) {
- cmd->path = getword_conf (cmd->pool, &arg);
- r = pregcomp(cmd->pool, cmd->path, REG_EXTENDED);
- }
-
- errmsg = srm_command_loop (cmd, new_url_conf);
- if (errmsg != end_url_magic) return errmsg;
-
- conf = (core_dir_config *)get_module_config(new_url_conf, &core_module);
- conf->d = pstrdup(cmd->pool, cmd->path); /* No mangling, please */
- conf->d_is_matchexp = is_matchexp( conf->d );
- conf->r = r;
-
- add_per_url_conf (cmd->server, new_url_conf);
-
- cmd->path = old_path;
- cmd->override = old_overrides;
-
- return NULL;
-}
-
-static char *end_file_magic = "</Files> outside of any <Files> section";
-
-const char *end_filesection (cmd_parms *cmd, void *dummy) {
- return end_file_magic;
-}
-
-const char *filesection (cmd_parms *cmd, core_dir_config *c, const char *arg)
-{
- const char *errmsg;
- char *endp = strrchr (arg, '>');
- int old_overrides = cmd->override;
- char *old_path = cmd->path;
- core_dir_config *conf;
- regex_t *r = NULL;
-
- void *new_file_conf = create_per_dir_config (cmd->pool);
-
- if (endp) *endp = '\0';
-
- if (cmd->limited != -1) return "Can't have <Files> within <Limit>";
-
- cmd->path = getword_conf (cmd->pool, &arg);
- /* Only if not an .htaccess file */
- if (cmd->path)
- cmd->override = OR_ALL|ACCESS_CONF;
-
- if (!strcmp(cmd->path, "~")) {
- cmd->path = getword_conf (cmd->pool, &arg);
- if (old_path && cmd->path[0] != '/' && cmd->path[0] != '^')
- cmd->path = pstrcat(cmd->pool, "^", old_path, cmd->path, NULL);
- r = pregcomp(cmd->pool, cmd->path, REG_EXTENDED);
- }
- else if (old_path && cmd->path[0] != '/')
- cmd->path = pstrcat(cmd->pool, old_path, cmd->path, NULL);
-
- errmsg = srm_command_loop (cmd, new_file_conf);
- if (errmsg != end_file_magic) return errmsg;
-
- conf = (core_dir_config *)get_module_config(new_file_conf, &core_module);
- conf->d = pstrdup(cmd->pool, cmd->path);
- conf->d_is_matchexp = is_matchexp( conf->d );
- conf->r = r;
-
- add_file_conf (c, new_file_conf);
-
- cmd->path = old_path;
- cmd->override = old_overrides;
-
- return NULL;
-}
-
-const char *end_ifmod (cmd_parms *cmd, void *dummy) {
- return NULL;
-}
-
-const char *start_ifmod (cmd_parms *cmd, void *dummy, char *arg)
-{
- char *endp = strrchr (arg, '>');
- char l[MAX_STRING_LEN];
- int not = (arg[0] == '!');
- module *found;
- int nest = 1;
-
- if (endp) *endp = '\0';
- if (not) arg++;
-
- found = find_linked_module(arg);
-
- if ((!not && found) || (not && !found))
- return NULL;
-
- while (nest && !(cfg_getline (l, MAX_STRING_LEN, cmd->infile))) {
- if (!strncasecmp(l, "<IfModule", 9))
- nest++;
- if (!strcasecmp(l, "</IfModule>"))
- nest--;
- }
-
- return NULL;
-}
-
-/* httpd.conf commands... beginning with the <VirtualHost> business */
-
-const char end_virthost_magic[] = "</Virtualhost> out of place";
-
-const char *end_virtualhost_section (cmd_parms *cmd, void *dummy)
-{
- return end_virthost_magic;
-}
-
-const char *virtualhost_section (cmd_parms *cmd, void *dummy, char *arg)
-{
- server_rec *main_server = cmd->server, *s;
- const char *errmsg;
- char *endp = strrchr (arg, '>');
- pool *p = cmd->pool, *ptemp = cmd->temp_pool;
-
- if (endp) *endp = '\0';
-
- /* FIXME: There's another feature waiting to happen here -- since you
- can now put multiple addresses/names on a single <VirtualHost>
- you might want to use it to group common definitions and then
- define other "subhosts" with their individual differences. But
- personally I'd rather just do it with a macro preprocessor. -djg */
- if (main_server->is_virtual)
- return "<VirtualHost> doesn't nest!";
-
- s = init_virtual_host (p, arg, main_server);
- s->next = main_server->next;
- main_server->next = s;
-
- cmd->server = s;
- errmsg = srm_command_loop (cmd, s->lookup_defaults);
- cmd->server = main_server;
-
- if (s->srm_confname)
- process_resource_config (s, s->srm_confname, p, ptemp);
-
- if (s->access_confname)
- process_resource_config (s, s->access_confname, p, ptemp);
-
- if (errmsg == end_virthost_magic) return NULL;
- return errmsg;
-}
-
-const char *add_module_command (cmd_parms *cmd, void *dummy, char *arg)
-{
- if (add_named_module (arg))
- return NULL;
- return "required module not found";
-}
-
-const char *clear_module_list_command (cmd_parms *cmd, void *dummy)
-{
- clear_module_list ();
- return NULL;
-}
-
-const char *set_server_string_slot (cmd_parms *cmd, void *dummy, char *arg)
-{
- /* This one's pretty generic... */
-
- int offset = (int)cmd->info;
- char *struct_ptr = (char *)cmd->server;
-
- *(char **)(struct_ptr + offset) = pstrdup (cmd->pool, arg);
- return NULL;
-}
-
-const char *server_type (cmd_parms *cmd, void *dummy, char *arg)
-{
- if (!strcasecmp (arg, "inetd")) standalone = 0;
- else if (!strcasecmp (arg, "standalone")) standalone = 1;
- else return "ServerType must be either 'inetd' or 'standalone'";
-
- return NULL;
-}
-
-const char *server_port (cmd_parms *cmd, void *dummy, char *arg) {
- cmd->server->port = atoi (arg);
- return NULL;
-}
-
-const char *set_send_buffer_size (cmd_parms *cmd, void *dummy, char *arg) {
- int s = atoi (arg);
- if (s < 512 && s != 0) {
- return "SendBufferSize must be >= 512 bytes, or 0 for system default.";
- }
- cmd->server->send_buffer_size = s;
- return NULL;
-}
-
-const char *set_user (cmd_parms *cmd, void *dummy, char *arg)
-{
- if (!cmd->server->is_virtual) {
- user_name = pstrdup (cmd->pool, arg);
- cmd->server->server_uid = user_id = uname2id(arg);
- }
- else {
- if (suexec_enabled)
- cmd->server->server_uid = uname2id(arg);
- else {
- cmd->server->server_uid = user_id;
- fprintf(stderr,
- "Warning: User directive in <VirtualHost> "
- "requires SUEXEC wrapper.\n");
- }
- }
-#if !defined (BIG_SECURITY_HOLE)
- if (cmd->server->server_uid == 0) {
- fprintf (stderr,
-"Error:\tApache has not been designed to serve pages while running\n"
-"\tas root. There are known race conditions that will allow any\n"
-"\tlocal user to read any file on the system. Should you still\n"
-"\tdesire to serve pages as root then add -DBIG_SECURITY_HOLE to\n"
-"\tthe EXTRA_CFLAGS line in your src/Configuration file and rebuild\n"
-"\tthe server. It is strongly suggested that you instead modify the\n"
-"\tUser directive in your httpd.conf file to list a non-root user.\n");
- exit (1);
- }
-#endif
-
- return NULL;
-}
-
-const char *set_group (cmd_parms *cmd, void *dummy, char *arg)
-{
- if (!cmd->server->is_virtual)
- cmd->server->server_gid = group_id = gname2id(arg);
- else {
- if (suexec_enabled)
- cmd->server->server_gid = gname2id(arg);
- else {
- cmd->server->server_gid = group_id;
- fprintf(stderr,
- "Warning: Group directive in <VirtualHost> requires SUEXEC wrapper.\n");
- }
- }
-
- return NULL;
-}
-
-const char *set_server_root (cmd_parms *cmd, void *dummy, char *arg) {
- if (!is_directory (arg)) return "ServerRoot must be a valid directory";
- strncpy (server_root, arg, sizeof(server_root)-1);
- server_root[sizeof(server_root)-1] = '\0';
- return NULL;
-}
-
-const char *set_timeout (cmd_parms *cmd, void *dummy, char *arg) {
- cmd->server->timeout = atoi (arg);
- return NULL;
-}
-
-const char *set_keep_alive_timeout (cmd_parms *cmd, void *dummy, char *arg) {
- cmd->server->keep_alive_timeout = atoi (arg);
- return NULL;
-}
-
-const char *set_keep_alive (cmd_parms *cmd, void *dummy, char *arg) {
- /* We've changed it to On/Off, but used to use numbers
- * so we accept anything but "Off" or "0" as "On"
- */
- if (!strcasecmp(arg, "off") || !strcmp(arg, "0"))
- cmd->server->keep_alive = 0;
- else
- cmd->server->keep_alive = 1;
- return NULL;
-}
-
-const char *set_keep_alive_max (cmd_parms *cmd, void *dummy, char *arg) {
- cmd->server->keep_alive_max = atoi (arg);
- return NULL;
-}
-
-const char *set_pidfile (cmd_parms *cmd, void *dummy, char *arg) {
- pid_fname = pstrdup (cmd->pool, arg);
- return NULL;
-}
-
-const char *set_scoreboard (cmd_parms *cmd, void *dummy, char *arg) {
- scoreboard_fname = pstrdup (cmd->pool, arg);
- return NULL;
-}
-
-const char *set_lockfile (cmd_parms *cmd, void *dummy, char *arg) {
- lock_fname = pstrdup (cmd->pool, arg);
- return NULL;
-}
-
-const char *set_idcheck (cmd_parms *cmd, core_dir_config *d, int arg) {
- d->do_rfc1413 = arg;
- return NULL;
-}
-
-const char *set_hostname_lookups (cmd_parms *cmd, core_dir_config *d, int arg)
-{
- d->hostname_lookups = arg;
- return NULL;
-}
-
-const char *set_serverpath (cmd_parms *cmd, void *dummy, char *arg) {
- cmd->server->path = pstrdup (cmd->pool, arg);
- cmd->server->pathlen = strlen (arg);
- return NULL;
-}
-
-const char *set_content_md5 (cmd_parms *cmd, core_dir_config *d, int arg) {
- d->content_md5 = arg;
- return NULL;
-}
-
-const char *set_daemons_to_start (cmd_parms *cmd, void *dummy, char *arg) {
- daemons_to_start = atoi (arg);
- return NULL;
-}
-
-const char *set_min_free_servers (cmd_parms *cmd, void *dummy, char *arg) {
- daemons_min_free = atoi (arg);
- if (daemons_min_free <= 0) {
- fprintf(stderr, "WARNING: detected MinSpareServers set to non-positive.\n");
- fprintf(stderr, "Resetting to 1 to avoid almost certain Apache failure.\n");
- fprintf(stderr, "Please read the documentation.\n");
- daemons_min_free = 1;
- }
-
- return NULL;
-}
-
-const char *set_max_free_servers (cmd_parms *cmd, void *dummy, char *arg) {
- daemons_max_free = atoi (arg);
- return NULL;
-}
-
-const char *set_server_limit (cmd_parms *cmd, void *dummy, char *arg) {
- daemons_limit = atoi (arg);
- if (daemons_limit > HARD_SERVER_LIMIT) {
- fprintf(stderr, "WARNING: MaxClients of %d exceeds compile time limit "
- "of %d servers,\n", daemons_limit, HARD_SERVER_LIMIT);
- fprintf(stderr, " lowering MaxClients to %d. To increase, please "
- "see the\n", HARD_SERVER_LIMIT);
- fprintf(stderr, " HARD_SERVER_LIMIT define in src/httpd.h.\n");
- daemons_limit = HARD_SERVER_LIMIT;
- } else if (daemons_limit < 1) {
- fprintf (stderr, "WARNING: Require MaxClients > 0, setting to 1\n");
- daemons_limit = 1;
- }
- return NULL;
-}
-
-const char *set_max_requests (cmd_parms *cmd, void *dummy, char *arg) {
- max_requests_per_child = atoi (arg);
- return NULL;
-}
-
-#if defined(RLIMIT_CPU) || defined(RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined(RLIMIT_NPROC)
-static void set_rlimit(cmd_parms *cmd, struct rlimit **plimit, const char *arg,
- const char * arg2, int type)
-{
- char *str;
- struct rlimit *limit;
- /* If your platform doesn't define rlim_t then typedef it in conf.h */
- rlim_t cur = 0;
- rlim_t max = 0;
-
- *plimit=(struct rlimit *)pcalloc(cmd->pool,sizeof **plimit);
- limit=*plimit;
- if ((getrlimit(type, limit)) != 0)
- {
- *plimit = NULL;
- log_unixerr("getrlimit",cmd->cmd->name,"failed",cmd->server);
- return;
- }
-
- if ((str = getword_conf(cmd->pool, &arg)))
- if (!strcasecmp(str, "max"))
- cur = limit->rlim_max;
- else
- cur = atol(str);
- else {
- log_printf(cmd->server, "Invalid parameters for %s", cmd->cmd->name);
- return;
- }
-
- if (arg2 && (str = getword_conf(cmd->pool, &arg2)))
- max = atol(str);
-
- /* if we aren't running as root, cannot increase max */
- if (geteuid()) {
- limit->rlim_cur = cur;
- if (max)
- log_printf(cmd->server, "Must be uid 0 to raise maximum %s",
- cmd->cmd->name);
- }
- else {
- if (cur)
- limit->rlim_cur = cur;
- if (max)
- limit->rlim_max = max;
- }
-}
-#endif
-
-#if !defined (RLIMIT_CPU) || !(defined (RLIMIT_DATA) || defined (RLIMIT_VMEM)) || !defined (RLIMIT_NPROC)
-static const char *no_set_limit (cmd_parms *cmd, core_dir_config *conf,
- char *arg, char *arg2)
-{
- log_printf(cmd->server, "%s not supported on this platform",
- cmd->cmd->name);
- return NULL;
-}
-#endif
-
-#ifdef RLIMIT_CPU
-const char *set_limit_cpu (cmd_parms *cmd, core_dir_config *conf, char *arg, char *arg2)
-{
- set_rlimit(cmd,&conf->limit_cpu,arg,arg2,RLIMIT_CPU);
- return NULL;
-}
-#endif
-
-#if defined (RLIMIT_DATA) || defined (RLIMIT_VMEM)
-const char *set_limit_mem (cmd_parms *cmd, core_dir_config *conf, char *arg, char * arg2)
-{
-#ifdef RLIMIT_DATA
- set_rlimit(cmd,&conf->limit_mem,arg,arg2,RLIMIT_DATA);
-#else
- set_rlimit(cmd,&conf->limit_mem,arg,arg2,RLIMIT_VMEM);
-#endif
- return NULL;
-}
-#endif
-
-#ifdef RLIMIT_NPROC
-const char *set_limit_nproc (cmd_parms *cmd, core_dir_config *conf, char *arg, char * arg2)
-{
- set_rlimit(cmd,&conf->limit_nproc,arg,arg2,RLIMIT_NPROC);
- return NULL;
-}
-#endif
-
-const char *set_bind_address (cmd_parms *cmd, void *dummy, char *arg) {
- bind_address.s_addr = get_virthost_addr (arg, NULL);
- return NULL;
-}
-
-const char *set_listener(cmd_parms *cmd, void *dummy, char *ips)
-{
- listen_rec *new;
- char *ports;
- unsigned port;
-
- if (cmd->server->is_virtual) return "Listen not allowed in <VirtualHost>";
- ports=strchr(ips, ':');
- if (ports != NULL)
- {
- if (ports == ips) return "Missing IP address";
- else if (ports[0] == '\0')
- return "Address must end in :<port-number>";
- *(ports++) = '\0';
- } else
- ports = ips;
-
- new=pcalloc(cmd->pool, sizeof(listen_rec));
- new->local_addr.sin_family = AF_INET;
- if (ports == ips) /* no address */
- new->local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
- else
- new->local_addr.sin_addr.s_addr = get_virthost_addr(ips, NULL);
- port=atoi(ports);
- if(!port)
- return "Port must be numeric";
- new->local_addr.sin_port = htons(port);
- new->fd = -1;
- new->used = 0;
- new->next = listeners;
- listeners = new;
- return NULL;
-}
-
-/* Note --- ErrorDocument will now work from .htaccess files.
- * The AllowOverride of Fileinfo allows webmasters to turn it off
- */
-
-command_rec core_cmds[] = {
-
-/* Old access config file commands */
-
-{ "<Directory", dirsection, NULL, RSRC_CONF, RAW_ARGS, "Container for directives affecting resources located in the specified directories" },
-{ "</Directory>", end_dirsection, NULL, ACCESS_CONF, NO_ARGS, NULL },
-{ "<Location", urlsection, NULL, RSRC_CONF, RAW_ARGS, "Container for directives affecting resources accessed through the specified URL paths" },
-{ "</Location>", end_urlsection, NULL, ACCESS_CONF, NO_ARGS, NULL },
-{ "<VirtualHost", virtualhost_section, NULL, RSRC_CONF, RAW_ARGS, "Container to map directives to a particular virtual host" },
-{ "</VirtualHost>", end_virtualhost_section, NULL, RSRC_CONF, NO_ARGS, NULL },
-{ "<Files", filesection, NULL, OR_ALL, RAW_ARGS, "Container for directives affecting files matching specified patterns" },
-{ "</Files>", end_filesection, NULL, OR_ALL, NO_ARGS, NULL },
-{ "<Limit", limit, NULL, OR_ALL, RAW_ARGS, "Container for authentication directives when accessed using specified HTTP methods" },
-{ "</Limit>", endlimit, NULL, OR_ALL, RAW_ARGS, NULL },
-{ "<IfModule", start_ifmod, NULL, OR_ALL, RAW_ARGS, "Container for directives based on existance of specified modules" },
-{ "</IfModule>", end_ifmod, NULL, OR_ALL, NO_ARGS, NULL },
-{ "AuthType", set_string_slot, (void*)XtOffsetOf(core_dir_config, auth_type),
- OR_AUTHCFG, TAKE1, "An HTTP authorization type (e.g., \"Basic\")" },
-{ "AuthName", set_string_slot, (void*)XtOffsetOf(core_dir_config, auth_name),
- OR_AUTHCFG, RAW_ARGS, "The authentication realm (e.g. \"Members Only\")" },
-{ "Require", require, NULL, OR_AUTHCFG, RAW_ARGS, "Selects which authenticated users or groups may access a protected space" },
-{ "Satisfy", satisfy, NULL, OR_AUTHCFG, TAKE1,
- "access policy if both allow and require used ('all' or 'any')" },
-
-/* Old resource config file commands */
-
-{ "AccessFileName", set_access_name, NULL, RSRC_CONF, TAKE1, "Name of per-directory config files (default: .htaccess)" },
-{ "DocumentRoot", set_document_root, NULL, RSRC_CONF, TAKE1, "Root directory of the document tree" },
-{ "ErrorDocument", set_error_document, NULL, OR_FILEINFO, RAW_ARGS, "Change responses for HTTP errors" },
-{ "AllowOverride", set_override, NULL, ACCESS_CONF, RAW_ARGS, "Controls what groups of directives can be configured by per-directory config files" },
-{ "Options", set_options, NULL, OR_OPTIONS, RAW_ARGS, "Set a number of attributes for a given directory" },
-{ "DefaultType", set_string_slot,
- (void*)XtOffsetOf (core_dir_config, default_type),
- OR_FILEINFO, TAKE1, "the default MIME type for untypable files" },
-
-/* Old server config file commands */
-
-{ "ServerType", server_type, NULL, RSRC_CONF, TAKE1,"'inetd' or 'standalone'"},
-{ "Port", server_port, NULL, RSRC_CONF, TAKE1, "A TCP port number"},
-{ "HostnameLookups", set_hostname_lookups, NULL, ACCESS_CONF|RSRC_CONF, FLAG, "\"on\" to enable or \"off\" to disable reverse DNS lookups" },
-{ "User", set_user, NULL, RSRC_CONF, TAKE1, "Effective user id for this server"},
-{ "Group", set_group, NULL, RSRC_CONF, TAKE1, "Effective group id for this server"},
-{ "ServerAdmin", set_server_string_slot,
- (void *)XtOffsetOf (server_rec, server_admin), RSRC_CONF, TAKE1,
- "The email address of the server administrator" },
-{ "ServerName", set_server_string_slot,
- (void *)XtOffsetOf (server_rec, server_hostname), RSRC_CONF, TAKE1,
- "The hostname of the server" },
-{ "ServerRoot", set_server_root, NULL, RSRC_CONF, TAKE1, "Common directory of server-related files (logs, confs, etc)" },
-{ "ErrorLog", set_server_string_slot,
- (void *)XtOffsetOf (server_rec, error_fname), RSRC_CONF, TAKE1,
- "The filename of the error log" },
-{ "PidFile", set_pidfile, NULL, RSRC_CONF, TAKE1,
- "A file for logging the server process ID"},
-{ "ScoreBoardFile", set_scoreboard, NULL, RSRC_CONF, TAKE1,
- "A file for Apache to maintain runtime process management information"},
-{ "LockFile", set_lockfile, NULL, RSRC_CONF, TAKE1,
- "The lockfile used when Apache needs to lock the accept() call"},
-{ "AccessConfig", set_server_string_slot,
- (void *)XtOffsetOf (server_rec, access_confname), RSRC_CONF, TAKE1,
- "The filename of the access config file" },
-{ "ResourceConfig", set_server_string_slot,
- (void *)XtOffsetOf (server_rec, srm_confname), RSRC_CONF, TAKE1,
- "The filename of the resource config file" },
-{ "ServerAlias", set_server_string_slot,
- (void *)XtOffsetOf (server_rec, names), RSRC_CONF, RAW_ARGS,
- "A name or names alternately used to access the server" },
-{ "ServerPath", set_serverpath, NULL, RSRC_CONF, TAKE1,
- "The pathname the server can be reached at" },
-{ "Timeout", set_timeout, NULL, RSRC_CONF, TAKE1, "Timeout duration (sec)"},
-{ "KeepAliveTimeout", set_keep_alive_timeout, NULL, RSRC_CONF, TAKE1, "Keep-Alive timeout duration (sec)"},
-{ "MaxKeepAliveRequests", set_keep_alive_max, NULL, RSRC_CONF, TAKE1, "Maximum number of Keep-Alive requests per connection, or 0 for infinite" },
-{ "KeepAlive", set_keep_alive, NULL, RSRC_CONF, TAKE1, "Whether persistent connections should be On or Off" },
-{ "IdentityCheck", set_idcheck, NULL, RSRC_CONF|ACCESS_CONF, FLAG, "Enable identd (RFC 1413) user lookups - SLOW" },
-{ "ContentDigest", set_content_md5, NULL, RSRC_CONF|ACCESS_CONF|OR_AUTHCFG, FLAG, "whether or not to send a Content-MD5 header with each request" },
-{ "StartServers", set_daemons_to_start, NULL, RSRC_CONF, TAKE1, "Number of child processes launched at server startup" },
-{ "MinSpareServers", set_min_free_servers, NULL, RSRC_CONF, TAKE1, "Minimum number of idle children, to handle request spikes" },
-{ "MaxSpareServers", set_max_free_servers, NULL, RSRC_CONF, TAKE1, "Maximum number of idle children" },
-{ "MaxServers", set_max_free_servers, NULL, RSRC_CONF, TAKE1, "Deprecated equivalent to MaxSpareServers" },
-{ "ServersSafetyLimit", set_server_limit, NULL, RSRC_CONF, TAKE1, "Deprecated equivalent to MaxClients" },
-{ "MaxClients", set_server_limit, NULL, RSRC_CONF, TAKE1, "Maximum number of children alive at the same time" },
-{ "MaxRequestsPerChild", set_max_requests, NULL, RSRC_CONF, TAKE1, "Maximum number of requests a particular child serves before dying." },
-{ "RLimitCPU",
-#ifdef RLIMIT_CPU
- set_limit_cpu, (void*)XtOffsetOf(core_dir_config, limit_cpu),
-#else
- no_set_limit, NULL,
-#endif
- OR_ALL, TAKE12, "soft/hard limits for max CPU usage in seconds" },
-{ "RLimitMEM",
-#if defined (RLIMIT_DATA) || defined (RLIMIT_VMEM)
- set_limit_mem, (void*)XtOffsetOf(core_dir_config, limit_mem),
-#else
- no_set_limit, NULL,
-#endif
- OR_ALL, TAKE12, "soft/hard limits for max memory usage per process" },
-{ "RLimitNPROC",
-#ifdef RLIMIT_NPROC
- set_limit_nproc, (void*)XtOffsetOf(core_dir_config, limit_nproc),
-#else
- no_set_limit, NULL,
-#endif
- OR_ALL, TAKE12, "soft/hard limits for max number of processes per uid" },
-{ "BindAddress", set_bind_address, NULL, RSRC_CONF, TAKE1,
- "'*', a numeric IP address, or the name of a host with a unique IP address"},
-{ "Listen", set_listener, NULL, RSRC_CONF, TAKE1,
- "a port number or a numeric IP address and a port number"},
-{ "SendBufferSize", set_send_buffer_size, NULL, RSRC_CONF, TAKE1, "send buffer size in bytes"},
-{ "AddModule", add_module_command, NULL, RSRC_CONF, ITERATE,
- "the name of a module" },
-{ "ClearModuleList", clear_module_list_command, NULL, RSRC_CONF, NO_ARGS, NULL },
-{ NULL },
-};
-
-/*****************************************************************
- *
- * Core handlers for various phases of server operation...
- */
-
-int core_translate (request_rec *r)
-{
- void *sconf = r->server->module_config;
- core_server_config *conf = get_module_config (sconf, &core_module);
-
- if (r->proxyreq) return HTTP_FORBIDDEN;
- if ((r->uri[0] != '/') && strcmp(r->uri, "*")) {
- log_printf(r->server, "Invalid URI in request %s", r->the_request);
- return BAD_REQUEST;
- }
-
- if (r->server->path &&
- !strncmp(r->uri, r->server->path, r->server->pathlen) &&
- (r->server->path[r->server->pathlen - 1] == '/' ||
- r->uri[r->server->pathlen] == '/' ||
- r->uri[r->server->pathlen] == '\0'))
- r->filename = pstrcat (r->pool, conf->document_root,
- (r->uri + r->server->pathlen), NULL);
- else
- r->filename = pstrcat (r->pool, conf->document_root, r->uri, NULL);
-
- return OK;
-}
-
-int do_nothing (request_rec *r) { return OK; }
-
-/*
- * Default handler for MIME types without other handlers. Only GET
- * and OPTIONS at this point... anyone who wants to write a generic
- * handler for PUT or POST is free to do so, but it seems unwise to provide
- * any defaults yet... So, for now, we assume that this will always be
- * the last handler called and return 405 or 501.
- */
-
-int default_handler (request_rec *r)
-{
- core_dir_config *d =
- (core_dir_config *)get_module_config(r->per_dir_config, &core_module);
- int rangestatus, errstatus;
- FILE *f;
-
- /* This handler has no use for a request body (yet), but we still
- * need to read and discard it if the client sent one.
- */
- if ((errstatus = discard_request_body(r)) != OK)
- return errstatus;
-
- r->allowed |= (1 << M_GET) | (1 << M_OPTIONS);
-
- if (r->method_number == M_INVALID) {
- log_printf(r->server, "Invalid method in request %s", r->the_request);
- return NOT_IMPLEMENTED;
- }
- if (r->method_number == M_OPTIONS) return send_http_options(r);
- if (r->method_number == M_PUT) return METHOD_NOT_ALLOWED;
-
- if (r->finfo.st_mode == 0 || (r->path_info && *r->path_info)) {
- log_reason("File does not exist",
- r->path_info ? pstrcat(r->pool, r->filename, r->path_info, NULL)
- : r->filename, r);
- return NOT_FOUND;
- }
- if (r->method_number != M_GET) return METHOD_NOT_ALLOWED;
-
-#ifdef __EMX__
- /* Need binary mode for OS/2 */
- f = pfopen (r->pool, r->filename, "rb");
-#else
- f = pfopen (r->pool, r->filename, "r");
-#endif
-
- if (f == NULL) {
- log_reason("file permissions deny server access", r->filename, r);
- return FORBIDDEN;
- }
-
- if ((errstatus = set_last_modified (r, r->finfo.st_mtime))
- || (errstatus = set_content_length (r, r->finfo.st_size)))
- return errstatus;
-
- if (d->content_md5 & 1) {
- table_set (r->headers_out, "Content-MD5", md5digest(r->pool, f));
- }
-
- rangestatus = set_byterange(r);
- send_http_header (r);
-
- if (!r->header_only) {
- if (!rangestatus)
- send_fd (f, r);
- else {
- long offset, length;
- while (each_byterange(r, &offset, &length)) {
- fseek(f, offset, SEEK_SET);
- send_fd_length(f, r, length);
- }
- }
- }
-
- pfclose(r->pool, f);
- return OK;
-}
-
-handler_rec core_handlers[] = {
-{ "*/*", default_handler },
-{ NULL }
-};
-
-module core_module = {
- STANDARD_MODULE_STUFF,
- NULL, /* initializer */
- create_core_dir_config, /* create per-directory config structure */
- merge_core_dir_configs, /* merge per-directory config structures */
- create_core_server_config, /* create per-server config structure */
- merge_core_server_configs, /* merge per-server config structures */
- core_cmds, /* command table */
- core_handlers, /* handlers */
- core_translate, /* translate_handler */
- NULL, /* check_user_id */
- NULL, /* check auth */
- do_nothing, /* check access */
- do_nothing, /* type_checker */
- NULL, /* pre-run fixups */
- NULL, /* logger */
- NULL /* header parser */
-};
diff --git a/usr.sbin/httpd/src/http_core.h b/usr.sbin/httpd/src/http_core.h
deleted file mode 100644
index 8454b81ad11..00000000000
--- a/usr.sbin/httpd/src/http_core.h
+++ /dev/null
@@ -1,205 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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/>.
- *
- */
-
-/*****************************************************************
- *
- * The most basic server code is encapsulated in a single module
- * known as the core, which is just *barely* functional enough to
- * serve documents, though not terribly well.
- *
- * Largely for NCSA back-compatibility reasons, the core needs to
- * make pieces of its config structures available to other modules.
- * The accessors are declared here, along with the interpretation
- * of one of them (allow_options).
- */
-
-#define OPT_NONE 0
-#define OPT_INDEXES 1
-#define OPT_INCLUDES 2
-#define OPT_SYM_LINKS 4
-#define OPT_EXECCGI 8
-#define OPT_UNSET 16
-#define OPT_INCNOEXEC 32
-#define OPT_SYM_OWNER 64
-#define OPT_MULTI 128
-#define OPT_ALL (OPT_INDEXES|OPT_INCLUDES|OPT_SYM_LINKS|OPT_EXECCGI)
-
-/* options for get_remote_host() */
-#define REMOTE_HOST (0)
-#define REMOTE_NAME (1)
-#define REMOTE_NOLOOKUP (2)
-
-#define SATISFY_ALL 0
-#define SATISFY_ANY 1
-#define SATISFY_NOSPEC 2
-
-int allow_options (request_rec *);
-int allow_overrides (request_rec *);
-char *default_type (request_rec *);
-char *document_root (request_rec *); /* Don't use this! If your request went
- * through a Userdir, or something like
- * that, it'll screw you. But it's
- * back-compatible...
- */
-extern const char *get_remote_host(conn_rec *conn, void *dir_config, int type);
-extern const char *get_remote_logname(request_rec *r);
-
-/* Authentication stuff. This is one of the places where compatibility
- * with the old config files *really* hurts; they don't discriminate at
- * all between different authentication schemes, meaning that we need
- * to maintain common state for all of them in the core, and make it
- * available to the other modules through interfaces.
- */
-
-typedef struct {
- int method_mask;
- char *requirement;
-} require_line;
-
-char *auth_type (request_rec *);
-char *auth_name (request_rec *);
-int satisfies (request_rec *r);
-array_header *requires (request_rec *);
-
-#ifdef CORE_PRIVATE
-
-/*
- * Core is also unlike other modules in being implemented in more than
- * one file... so, data structures are declared here, even though most of
- * the code that cares really is in http_core.c. Also, anothre accessor.
- */
-
-char *response_code_string (request_rec *r, int error_index);
-
-extern module core_module;
-
-/* Per-directory configuration */
-
-typedef char allow_options_t;
-typedef char overrides_t;
-
-typedef struct {
- char *d;
- /* since is_matchexp(conf->d) was being called so frequently in
- * directory_walk() and its relatives, this field was created and
- * is set to the result of that call.
- */
- int d_is_matchexp;
-
- allow_options_t opts;
- allow_options_t opts_add;
- allow_options_t opts_remove;
- overrides_t override;
-
- /* MIME typing --- the core doesn't do anything at all with this,
- * but it does know what to slap on a request for a document which
- * goes untyped by other mechanisms before it slips out the door...
- */
-
- char *default_type;
-
- /* Authentication stuff. Groan... */
-
- int satisfy;
- char *auth_type;
- char *auth_name;
- array_header *requires;
-
- int content_md5;
-
- /* Custom response config. These can contain text or a URL to redirect to.
- * if response_code_strings is NULL then there are none in the config,
- * if it's not null then it's allocated to sizeof(char*)*RESPONSE_CODES.
- * This lets us do quick merges in merge_core_dir_configs().
- */
-
- char **response_code_strings;
-
- /* Hostname resolution etc */
- int hostname_lookups;
- int do_rfc1413; /* See if client is advertising a username? */
-
- /* System Resource Control */
-#ifdef RLIMIT_CPU
- struct rlimit *limit_cpu;
-#endif
-#if defined (RLIMIT_DATA) || defined (RLIMIT_VMEM)
- struct rlimit *limit_mem;
-#endif
-#ifdef RLIMIT_NPROC
- struct rlimit *limit_nproc;
-#endif
-
- /* Access control */
- array_header *sec;
- regex_t *r;
-
-} core_dir_config;
-
-/* Per-server core configuration */
-
-typedef struct {
-
- /* Name translations --- we want the core to be able to do *something*
- * so it's at least a minimally functional web server on its own (and
- * can be tested that way). But let's keep it to the bare minimum:
- */
- char *document_root;
-
- /* Access control */
-
- char *access_name;
- array_header *sec;
- array_header *sec_url;
-} core_server_config;
-
-#endif
diff --git a/usr.sbin/httpd/src/http_log.c b/usr.sbin/httpd/src/http_log.c
deleted file mode 100644
index 896c0a8dc59..00000000000
--- a/usr.sbin/httpd/src/http_log.c
+++ /dev/null
@@ -1,197 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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
- *
- */
-
-
-#include "httpd.h"
-#include "http_config.h"
-#include "http_core.h"
-#include "http_log.h"
-
-#include <stdarg.h>
-
-void error_log_child (void *cmd)
-{
- /* 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...
- */
-
- cleanup_for_exec();
- signal (SIGHUP, SIG_IGN);
-#ifdef __EMX__
- /* For OS/2 we need to use a '/' */
- execl (SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL);
-#else
- execl (SHELL_PATH, SHELL_PATH, "-c", (char *)cmd, NULL);
-#endif
- exit (1);
-}
-
-void open_error_log(server_rec *s, pool *p)
-{
- char *fname;
-
- fname = server_root_relative (p, s->error_fname);
-
- if (*s->error_fname == '|') {
- FILE *dummy;
-
- if (!spawn_child (p, error_log_child, (void *)(s->error_fname+1),
- kill_after_timeout, &dummy, NULL)) {
- perror ("spawn_child");
- fprintf (stderr, "Couldn't fork child for ErrorLog process\n");
- exit (1);
- }
-
- s->error_log = dummy;
- } else {
- if(!(s->error_log = pfopen(p, fname, "a"))) {
- perror("fopen");
- fprintf(stderr,"httpd: could not open error log file %s.\n", fname);
- exit(1);
- }
- }
-}
-
-void open_logs (server_rec *s_main, pool *p)
-{
- server_rec *virt, *q;
-
- open_error_log (s_main, p);
-
- 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;
- }
-}
-
-void error_log2stderr(server_rec *s) {
- if(fileno(s->error_log) != STDERR_FILENO)
- dup2(fileno(s->error_log),STDERR_FILENO);
-}
-
-void log_pid(pool *p, char *pid_fname) {
- FILE *pid_file;
-
- if (!pid_fname) return;
- pid_fname = server_root_relative (p, pid_fname);
- if(!(pid_file = fopen(pid_fname,"w"))) {
- perror("fopen");
- fprintf(stderr,"httpd: could not log pid to file %s\n", pid_fname);
- exit(1);
- }
- fprintf(pid_file,"%ld\n",(long)getpid());
- fclose(pid_file);
-}
-
-void log_error(char *err, server_rec *s) {
- fprintf(s->error_log, "[%s] %s\n",get_time(),err);
- fflush(s->error_log);
-}
-
-void
-log_unixerr(const char *routine, const char *file, const char *msg,
- server_rec *s)
-{
- const char *p, *q;
-
- p = strerror(errno);
- q = get_time();
-
- if (file != NULL)
- fprintf(s->error_log, "[%s] %s: %s: %s\n", q, routine, file, p);
- else
- fprintf(s->error_log, "[%s] %s: %s\n", q, routine, p);
- if (msg != NULL) fprintf(s->error_log, "[%s] - %s\n", q, msg);
-
- fflush(s->error_log);
-}
-
-void
-log_printf(const server_rec *s, const char *fmt, ...)
-{
- va_list args;
-
- fprintf(s->error_log, "[%s] ", get_time());
- va_start (args, fmt);
- vfprintf (s->error_log, fmt, args);
- va_end (args);
-
- fputc('\n', s->error_log);
- fflush(s->error_log);
-}
-
-void log_reason(const char *reason, const char *file, request_rec *r) {
- fprintf (r->server->error_log,
- "[%s] access to %s failed for %s, reason: %s\n",
- get_time(), file,
- get_remote_host(r->connection, r->per_dir_config, REMOTE_NAME),
- reason);
- fflush (r->server->error_log);
-}
-
diff --git a/usr.sbin/httpd/src/http_log.h b/usr.sbin/httpd/src/http_log.h
deleted file mode 100644
index e30324db61d..00000000000
--- a/usr.sbin/httpd/src/http_log.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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/>.
- *
- */
-
-void open_logs (server_rec *, pool *p);
-void error_log2stderr (server_rec *);
-
-void log_pid (pool *p, char *pid_fname);
-void log_error(char *err, server_rec *s);
-extern void log_unixerr(const char *routine, const char *file,
- const char *msg, server_rec *s);
-void log_printf(const server_rec *s, const char *fmt, ...);
-void log_reason(const char *reason, const char *fname, request_rec *r);
-
diff --git a/usr.sbin/httpd/src/http_main.c b/usr.sbin/httpd/src/http_main.c
deleted file mode 100644
index e553a2d3636..00000000000
--- a/usr.sbin/httpd/src/http_main.c
+++ /dev/null
@@ -1,2620 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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/>.
- *
- */
-
-/*
- * httpd.c: simple http daemon for answering WWW file requests
- *
- *
- * 03-21-93 Rob McCool wrote original code (up to NCSA HTTPd 1.3)
- *
- * 03-06-95 blong
- * changed server number for child-alone processes to 0 and changed name
- * of processes
- *
- * 03-10-95 blong
- * Added numerous speed hacks proposed by Robert S. Thau (rst@ai.mit.edu)
- * including set group before fork, and call gettime before to fork
- * to set up libraries.
- *
- * 04-14-95 rst / rh
- * Brandon's code snarfed from NCSA 1.4, but tinkered to work with the
- * Apache server, and also to have child processes do accept() directly.
- *
- * April-July '95 rst
- * Extensive rework for Apache.
- */
-
-#define CORE_PRIVATE
-
-#include "httpd.h"
-#include "http_main.h"
-#include "http_log.h"
-#include "http_config.h" /* for read_config */
-#include "http_protocol.h" /* for read_request */
-#include "http_request.h" /* for process_request */
-#include "http_conf_globals.h"
-#include "http_core.h" /* for get_remote_host */
-#include "scoreboard.h"
-#include <assert.h>
-#include <sys/stat.h>
-#ifdef HAVE_SHMGET
-#include <sys/types.h>
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#endif
-#ifdef SecureWare
-#include <sys/security.h>
-#include <sys/audit.h>
-#include <prot.h>
-#endif
-#include <netinet/tcp.h>
-
-#ifdef HAVE_BSTRING_H
-#include <bstring.h> /* for IRIX, FD_SET calls bzero() */
-#endif
-
-#include "explain.h"
-
-#if !defined(max)
-#define max(a,b) (a > b ? a : b)
-#endif
-
-#ifdef __EMX__
- /* Add MMAP style functionality to OS/2 */
- #ifdef HAVE_MMAP
- #define INCL_DOSMEMMGR
- #include <os2.h>
- #include <umalloc.h>
- #include <stdio.h>
- caddr_t create_shared_heap (const char *, size_t);
- caddr_t get_shared_heap (const char *);
- #endif
-#endif
-
-
-DEF_Explain
-
-/*
- * Actual definitions of config globals... here because this is
- * for the most part the only code that acts on 'em. (Hmmm... mod_main.c?)
- */
-
-int standalone;
-uid_t user_id;
-char *user_name;
-gid_t group_id;
-#ifdef MULTIPLE_GROUPS
-gid_t group_id_list[NGROUPS_MAX];
-#endif
-int max_requests_per_child;
-char *pid_fname;
-char *scoreboard_fname;
-char *lock_fname;
-char *server_argv0;
-struct in_addr bind_address;
-listen_rec *listeners;
-int daemons_to_start;
-int daemons_min_free;
-int daemons_max_free;
-int daemons_limit;
-time_t restart_time;
-int suexec_enabled = 0;
-
-char server_root[MAX_STRING_LEN];
-char server_confname[MAX_STRING_LEN];
-
-/* *Non*-shared http_main globals... */
-
-server_rec *server_conf;
-JMP_BUF jmpbuffer;
-int sd;
-static fd_set listenfds;
-static int listenmaxfd;
-pid_t pgrp;
-
-/* one_process --- debugging mode variable; can be set from the command line
- * with the -X flag. If set, this gets you the child_main loop running
- * in the process which originally started up (no detach, no make_child),
- * which is a pretty nice debugging environment. (You'll get a SIGHUP
- * early in standalone_main; just continue through. This is the server
- * trying to kill off any child processes which it might have lying
- * around --- Apache doesn't keep track of their pids, it just sends
- * SIGHUP to the process group, ignoring it in the root process.
- * Continue through and you'll be fine.).
- */
-
-int one_process = 0;
-
-/* small utility macros to make things easier to read */
-
-#ifdef NO_KILLPG
-#define ap_killpg(x, y) (kill (-(x), (y)))
-#else
-#define ap_killpg(x, y) (killpg ((x), (y)))
-#endif
-
-#if defined(USE_FCNTL_SERIALIZED_ACCEPT) || defined(USE_FLOCK_SERIALIZED_ACCEPT)
-static void expand_lock_fname(pool *p)
-{
- char buf[20];
-
- ap_snprintf( buf, sizeof(buf), ".%u", getpid() );
- lock_fname = pstrcat (p, server_root_relative (p, lock_fname), buf, NULL);
-}
-#endif
-
-#if defined(USE_FCNTL_SERIALIZED_ACCEPT)
-static struct flock lock_it;
-static struct flock unlock_it;
-
-static int lock_fd=-1;
-
-/*
- * Initialize mutex lock.
- * Must be safe to call this on a restart.
- */
-void
-accept_mutex_init(pool *p)
-{
-
- lock_it.l_whence = SEEK_SET; /* from current point */
- lock_it.l_start = 0; /* -"- */
- lock_it.l_len = 0; /* until end of file */
- lock_it.l_type = F_WRLCK; /* set exclusive/write lock */
- lock_it.l_pid = 0; /* pid not actually interesting */
- unlock_it.l_whence = SEEK_SET; /* from current point */
- unlock_it.l_start = 0; /* -"- */
- unlock_it.l_len = 0; /* until end of file */
- unlock_it.l_type = F_UNLCK; /* set exclusive/write lock */
- unlock_it.l_pid = 0; /* pid not actually interesting */
-
- expand_lock_fname (p);
- lock_fd = popenf(p, lock_fname, O_CREAT | O_WRONLY | O_EXCL, 0644);
- if (lock_fd == -1)
- {
- perror ("open");
- fprintf (stderr, "Cannot open lock file: %s\n", lock_fname);
- exit (1);
- }
- unlink(lock_fname);
-}
-
-void accept_mutex_on()
-{
- int ret;
-
- while ((ret = fcntl(lock_fd, F_SETLKW, &lock_it)) < 0 && errno == EINTR)
- continue;
-
- if (ret < 0) {
- log_unixerr("fcntl", "F_SETLKW", "Error getting accept lock. Exiting!"
- "Perhaps you need to use the LockFile directive to place "
- "your lock file on a local disk!", server_conf);
- exit(1);
- }
-}
-
-void accept_mutex_off()
-{
- if (fcntl (lock_fd, F_SETLKW, &unlock_it) < 0)
- {
- log_unixerr("fcntl", "F_SETLKW", "Error freeing accept lock. Exiting!"
- "Perhaps you need to use the LockFile directive to place "
- "your lock file on a local disk!", server_conf);
- exit(1);
- }
-}
-#elif defined(USE_FLOCK_SERIALIZED_ACCEPT)
-
-static int lock_fd=-1;
-
-/*
- * Initialize mutex lock.
- * Must be safe to call this on a restart.
- */
-void
-accept_mutex_init(pool *p)
-{
-
- expand_lock_fname (p);
- lock_fd = popenf(p, lock_fname, O_CREAT | O_WRONLY | O_EXCL, 0644);
- if (lock_fd == -1)
- {
- perror ("open");
- fprintf (stderr, "Cannot open lock file: %s\n", lock_fname);
- exit (1);
- }
- unlink(lock_fname);
-}
-
-void accept_mutex_on()
-{
- int ret;
-
- while ((ret = flock(lock_fd, LOCK_EX)) < 0 && errno == EINTR)
- continue;
-
- if (ret < 0) {
- log_unixerr("flock", "LOCK_EX", "Error getting accept lock. Exiting!",
- server_conf);
- exit(1);
- }
-}
-
-void accept_mutex_off()
-{
- if (flock (lock_fd, LOCK_UN) < 0)
- {
- log_unixerr("flock", "LOCK_UN", "Error freeing accept lock. Exiting!",
- server_conf);
- exit(1);
- }
-}
-#else
-/* Default --- no serialization. Other methods *could* go here,
- * as #elifs...
- */
-#define accept_mutex_init(x)
-#define accept_mutex_on()
-#define accept_mutex_off()
-#endif
-
-void usage(char *bin)
-{
- fprintf(stderr,"Usage: %s [-d directory] [-f file] [-v] [-h] [-l]\n",bin);
- fprintf(stderr,"-d directory : specify an alternate initial ServerRoot\n");
- fprintf(stderr,"-f file : specify an alternate ServerConfigFile\n");
- fprintf(stderr,"-v : show version number\n");
- fprintf(stderr,"-h : list directives\n");
- fprintf(stderr,"-l : list modules\n");
- exit(1);
-}
-
-/*****************************************************************
- *
- * Timeout handling. DISTINCTLY not thread-safe, but all this stuff
- * has to change for threads anyway. Note that this code allows only
- * one timeout in progress at a time...
- */
-
-static conn_rec *current_conn;
-static request_rec *timeout_req;
-static char *timeout_name = NULL;
-static int alarms_blocked = 0;
-static int alarm_pending = 0;
-
-#ifndef NO_USE_SIGACTION
-/*
- * Replace standard signal() with the more reliable sigaction equivalent
- * from W. Richard Stevens' "Advanced Programming in the UNIX Environment"
- * (the version that does not automatically restart system calls).
- */
-Sigfunc *signal(int signo, Sigfunc *func)
-{
- struct sigaction act, oact;
-
- act.sa_handler = func;
- sigemptyset(&act.sa_mask);
- act.sa_flags = 0;
-#ifdef SA_INTERRUPT /* SunOS */
- act.sa_flags |= SA_INTERRUPT;
-#endif
- if (sigaction(signo, &act, &oact) < 0)
- return SIG_ERR;
- return oact.sa_handler;
-}
-#endif
-
-void timeout(int sig) /* Also called on SIGPIPE */
-{
- char errstr[MAX_STRING_LEN];
- void *dirconf;
-
- signal(SIGPIPE, SIG_IGN); /* Block SIGPIPE */
- if (alarms_blocked) {
- alarm_pending = 1;
- return;
- }
-
- if (!current_conn) {
- ap_longjmp (jmpbuffer, 1);
- }
-
- if (timeout_req != NULL) dirconf = timeout_req->per_dir_config;
- else dirconf = current_conn->server->lookup_defaults;
- if (sig == SIGPIPE) {
- ap_snprintf(errstr, sizeof(errstr), "%s lost connection to client %s",
- timeout_name ? timeout_name : "request",
- get_remote_host(current_conn, dirconf, REMOTE_NAME));
- } else {
- ap_snprintf(errstr, sizeof(errstr), "%s timed out for %s",
- timeout_name ? timeout_name : "request",
- get_remote_host(current_conn, dirconf, REMOTE_NAME));
- }
-
- if (!current_conn->keptalive)
- log_error(errstr, current_conn->server);
-
- if (timeout_req) {
- /* Someone has asked for this transaction to just be aborted
- * if it times out...
- */
-
- request_rec *log_req = timeout_req;
-
- while (log_req->main || log_req->prev) {
- /* Get back to original request... */
- if (log_req->main) log_req = log_req->main;
- else log_req = log_req->prev;
- }
-
- if (!current_conn->keptalive)
- log_transaction(log_req);
-
- bsetflag(timeout_req->connection->client, B_EOUT, 1);
- bclose(timeout_req->connection->client);
-
- if (!standalone) exit(0);
-
- ap_longjmp (jmpbuffer, 1);
- }
- else { /* abort the connection */
- bsetflag(current_conn->client, B_EOUT, 1);
- current_conn->aborted = 1;
- }
-}
-
-/*
- * These two called from alloc.c to protect its critical sections...
- * Note that they can nest (as when destroying the sub_pools of a pool
- * which is itself being cleared); we have to support that here.
- */
-
-void block_alarms() {
- ++alarms_blocked;
-}
-
-void unblock_alarms() {
- --alarms_blocked;
- if (alarms_blocked == 0 && alarm_pending) {
- alarm_pending = 0;
- timeout(0);
- }
-}
-
-void keepalive_timeout (char *name, request_rec *r)
-{
- timeout_req = r;
- timeout_name = name;
-
- signal(SIGALRM, timeout);
- if (r->connection->keptalive)
- alarm (r->server->keep_alive_timeout);
- else
- alarm (r->server->timeout);
-}
-
-void hard_timeout (char *name, request_rec *r)
-{
- timeout_req = r;
- timeout_name = name;
-
- signal(SIGALRM, timeout);
- alarm (r->server->timeout);
-}
-
-void soft_timeout (char *name, request_rec *r)
-{
- timeout_name = name;
-
- signal(SIGALRM, timeout);
- alarm (r->server->timeout);
-}
-
-void kill_timeout (request_rec *dummy) {
- alarm (0);
- timeout_req = NULL;
- timeout_name = NULL;
-}
-
-/* reset_timeout (request_rec *) resets the timeout in effect,
- * as long as it hasn't expired already.
- */
-
-void reset_timeout (request_rec *r) {
- int i;
-
- if (timeout_name) { /* timeout has been set */
- i = alarm(r->server->timeout);
- if (i == 0) /* timeout already expired, so set it back to 0 */
- alarm(0);
- }
-}
-
-/*
- * More machine-dependent networking gooo... on some systems,
- * you've got to be *really* sure that all the packets are acknowledged
- * before closing the connection, since the client will not be able
- * to see the last response if their TCP buffer is flushed by a RST
- * packet from us, which is what the server's TCP stack will send
- * if it receives any request data after closing the connection.
- *
- * In an ideal world, this function would be accomplished by simply
- * setting the socket option SO_LINGER and handling it within the
- * server's TCP stack while the process continues on to the next request.
- * Unfortunately, it seems that most (if not all) operating systems
- * block the server process on close() when SO_LINGER is used.
- * For those that don't, see USE_SO_LINGER below. For the rest,
- * we have created a home-brew lingering_close.
- *
- * Many operating systems tend to block, puke, or otherwise mishandle
- * calls to shutdown only half of the connection. You should define
- * NO_LINGCLOSE in conf.h if such is the case for your system.
- */
-#ifndef MAX_SECS_TO_LINGER
-#define MAX_SECS_TO_LINGER 30
-#endif
-
-#ifdef USE_SO_LINGER
-#define NO_LINGCLOSE /* The two lingering options are exclusive */
-
-static void sock_enable_linger (int s)
-{
- struct linger li;
-
- li.l_onoff = 1;
- li.l_linger = MAX_SECS_TO_LINGER;
-
- if (setsockopt(s, SOL_SOCKET, SO_LINGER,
- (char *)&li, sizeof(struct linger)) < 0) {
- log_unixerr("setsockopt", "(SO_LINGER)", NULL, server_conf);
- /* not a fatal error */
- }
-}
-
-#else
-#define sock_enable_linger(s) /* NOOP */
-#endif /* USE_SO_LINGER */
-
-#ifndef NO_LINGCLOSE
-
-/* Special version of timeout for lingering_close */
-
-static void lingerout(sig)
-int sig;
-{
- if (alarms_blocked) {
- alarm_pending = 1;
- return;
- }
-
- if (!current_conn) {
- ap_longjmp (jmpbuffer, 1);
- }
- bsetflag(current_conn->client, B_EOUT, 1);
- current_conn->aborted = 1;
-}
-
-static void linger_timeout ()
-{
- timeout_name = "lingering close";
-
- signal(SIGALRM, lingerout);
- alarm(MAX_SECS_TO_LINGER);
-}
-
-/* Since many clients will abort a connection instead of closing it,
- * attempting to log an error message from this routine will only
- * confuse the webmaster. There doesn't seem to be any portable way to
- * distinguish between a dropped connection and something that might be
- * worth logging.
- */
-static void lingering_close (request_rec *r)
-{
- int dummybuf[512];
- struct timeval tv;
- fd_set lfds, fds_read, fds_err;
- int select_rv = 0, read_rv = 0;
- int lsd;
-
- /* Prevent a slow-drip client from holding us here indefinitely */
-
- linger_timeout();
-
- /* Send any leftover data to the client, but never try to again */
-
- if (bflush(r->connection->client) == -1) {
- kill_timeout(r);
- bclose(r->connection->client);
- return;
- }
- bsetflag(r->connection->client, B_EOUT, 1);
-
- /* Close our half of the connection --- send the client a FIN */
-
- lsd = r->connection->client->fd;
-
- if ((shutdown(lsd, 1) != 0) || r->connection->aborted) {
- kill_timeout(r);
- bclose(r->connection->client);
- return;
- }
-
- /* Set up to wait for readable data on socket... */
-
- FD_ZERO(&lfds);
- FD_SET(lsd, &lfds);
-
- /* Wait for readable data or error condition on socket;
- * slurp up any data that arrives... We exit when we go for
- * an interval of tv length without getting any more data, get an
- * error from select(), get an exception on lsd, get an error or EOF
- * on a read, or the timer expires.
- */
-
- do {
- /* We use a 2 second timeout because current (Feb 97) browsers
- * fail to close a connection after the server closes it. Thus,
- * to avoid keeping the child busy, we are only lingering long enough
- * for a client that is actively sending data on a connection.
- * This should be sufficient unless the connection is massively
- * losing packets, in which case we might have missed the RST anyway.
- * These parameters are reset on each pass, since they might be
- * changed by select.
- */
- tv.tv_sec = 2;
- tv.tv_usec = 0;
- read_rv = 0;
- fds_read = lfds;
- fds_err = lfds;
-
-#ifdef SELECT_NEEDS_CAST
- select_rv = select(lsd+1, (int*)&fds_read, NULL, (int*)&fds_err, &tv);
-#else
- select_rv = select(lsd+1, &fds_read, NULL, &fds_err, &tv);
-#endif
- } while ((select_rv > 0) && /* Something to see on socket */
- !FD_ISSET(lsd, &fds_err) && /* that isn't an error condition */
- FD_ISSET(lsd, &fds_read) && /* and is worth trying to read */
- ((read_rv = read(lsd, dummybuf, sizeof dummybuf)) > 0));
-
- /* Should now have seen final ack. Safe to finally kill socket */
-
- bclose(r->connection->client);
-
- kill_timeout(r);
-}
-#endif /* ndef NO_LINGCLOSE */
-
-/*****************************************************************
- *
- * Dealing with the scoreboard... a lot of these variables are global
- * only to avoid getting clobbered by the longjmp() that happens when
- * a hard timeout expires...
- *
- * We begin with routines which deal with the file itself...
- */
-
-#if defined(HAVE_MMAP)
-static scoreboard *scoreboard_image=NULL;
-
-static void setup_shared_mem(void)
-{
- caddr_t m;
-
-#ifdef __EMX__
- char errstr[MAX_STRING_LEN];
- int rc;
-
- m = (caddr_t)create_shared_heap("\\SHAREMEM\\SCOREBOARD", HARD_SERVER_LIMIT*sizeof(short_score));
- if(m == 0) {
- fprintf(stderr, "httpd: Could not create OS/2 Shared memory pool.\n");
- exit(1);
- }
-
- rc = _uopen((Heap_t)m);
- if(rc != 0) {
- fprintf(stderr, "httpd: Could not uopen() newly created OS/2 Shared memory pool.\n");
- }
-
-#elif defined(MAP_ANON) || defined(MAP_FILE)
-/* BSD style */
-#ifdef CONVEXOS11
- /*
- * 9-Aug-97 - Jeff Venters (venters@convex.hp.com)
- * ConvexOS maps address space as follows:
- * 0x00000000 - 0x7fffffff : Kernel
- * 0x80000000 - 0xffffffff : User
- * Start mmapped area 1GB above start of text.
- *
- * Also, the length requires a pointer as the actual length is
- * returned (rounded up to a page boundary).
- */
- {
- unsigned len = SCOREBOARD_SIZE;
-
- m = mmap((caddr_t)0xC0000000, &len,
- PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, NOFD, 0);
- }
-#else
- m = mmap((caddr_t)0, SCOREBOARD_SIZE,
- PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0);
-#endif
- if (m == (caddr_t)-1)
- {
- perror("mmap");
- fprintf(stderr, "httpd: Could not mmap memory\n");
- exit(1);
- }
-#else
-/* Sun style */
- int fd;
-
- fd = open("/dev/zero", O_RDWR);
- if (fd == -1)
- {
- perror("open");
- fprintf(stderr, "httpd: Could not open /dev/zero\n");
- exit(1);
- }
- m = mmap((caddr_t)0, SCOREBOARD_SIZE,
- PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
- if (m == (caddr_t)-1)
- {
- perror("mmap");
- fprintf(stderr, "httpd: Could not mmap /dev/zero\n");
- exit(1);
- }
- close(fd);
-#endif
- scoreboard_image = (scoreboard *)m;
- scoreboard_image->global.exit_generation=0;
-}
-
-#elif defined(HAVE_SHMGET)
-static scoreboard *scoreboard_image=NULL;
-static key_t shmkey = IPC_PRIVATE;
-static int shmid = -1;
-
-static void setup_shared_mem(void)
-{
- char errstr[MAX_STRING_LEN];
- struct shmid_ds shmbuf;
-#ifdef MOVEBREAK
- char *obrk;
-#endif
-
- if ((shmid = shmget(shmkey, SCOREBOARD_SIZE, IPC_CREAT|SHM_R|SHM_W)) == -1)
- {
-#ifdef LINUX
- if (errno == ENOSYS) {
- fprintf(stderr,
- "httpd: Your kernel was built without CONFIG_SYSVIPC\n"
- "httpd: please consult the Apache FAQ for details\n");
- }
-#endif
- perror("shmget");
- fprintf(stderr, "httpd: Could not call shmget\n");
- exit(1);
- }
-
- ap_snprintf(errstr, sizeof(errstr), "created shared memory segment #%d", shmid);
- log_error(errstr, server_conf);
-
-#ifdef MOVEBREAK
- /*
- * Some SysV systems place the shared segment WAY too close
- * to the dynamic memory break point (sbrk(0)). This severely
- * limits the use of malloc/sbrk in the program since sbrk will
- * refuse to move past that point.
- *
- * To get around this, we move the break point "way up there",
- * attach the segment and then move break back down. Ugly
- */
- if ((obrk=sbrk(MOVEBREAK)) == (char *)-1)
- {
- perror("sbrk");
- fprintf(stderr, "httpd: Could not move break\n");
- }
-#endif
-
-#define BADSHMAT ((scoreboard *)(-1))
- if ((scoreboard_image = (scoreboard *)shmat(shmid, 0, 0)) == BADSHMAT)
- {
- perror("shmat");
- fprintf(stderr, "httpd: Could not call shmat\n");
- /*
- * We exit below, after we try to remove the segment
- */
- }
- else /* only worry about permissions if we attached the segment */
- {
- if (shmctl(shmid, IPC_STAT, &shmbuf) != 0) {
- perror("shmctl");
- fprintf(stderr, "httpd: Could not stat segment #%d\n", shmid);
- }
- else
- {
- shmbuf.shm_perm.uid = user_id;
- shmbuf.shm_perm.gid = group_id;
- if (shmctl(shmid, IPC_SET, &shmbuf) != 0) {
- perror("shmctl");
- fprintf(stderr, "httpd: Could not set segment #%d\n", shmid);
- }
- }
- }
- /*
- * We must avoid leaving segments in the kernel's
- * (small) tables.
- */
- if (shmctl(shmid, IPC_RMID, NULL) != 0) {
- perror("shmctl");
- fprintf(stderr, "httpd: Could not delete segment #%d\n", shmid);
- ap_snprintf(errstr, sizeof(errstr), "could not remove shared memory segment #%d", shmid);
- log_unixerr("shmctl","IPC_RMID",errstr, server_conf);
- }
- if (scoreboard_image == BADSHMAT) /* now bailout */
- exit(1);
-
-#ifdef MOVEBREAK
- if (obrk == (char *)-1)
- return; /* nothing else to do */
- if (sbrk(-(MOVEBREAK)) == (char *)-1)
- {
- perror("sbrk");
- fprintf(stderr, "httpd: Could not move break back\n");
- }
-#endif
- scoreboard_image->global.exit_generation=0;
-}
-
-#else
-#define SCOREBOARD_FILE
-static scoreboard _scoreboard_image;
-static scoreboard *scoreboard_image=&_scoreboard_image;
-static int scoreboard_fd;
-
-/* XXX: things are seriously screwed if we ever have to do a partial
- * read or write ... we could get a corrupted scoreboard
- */
-static int force_write (int fd, char *buffer, int bufsz)
-{
- int rv, orig_sz = bufsz;
-
- do {
- rv = write (fd, buffer, bufsz);
- if (rv > 0) {
- buffer += rv;
- bufsz -= rv;
- }
- } while ((rv > 0 && bufsz > 0) || (rv == -1 && errno == EINTR));
-
- return rv < 0? rv : orig_sz - bufsz;
-}
-
-static int force_read (int fd, char *buffer, int bufsz)
-{
- int rv, orig_sz = bufsz;
-
- do {
- rv = read (fd, buffer, bufsz);
- if (rv > 0) {
- buffer += rv;
- bufsz -= rv;
- }
- } while ((rv > 0 && bufsz > 0) || (rv == -1 && errno == EINTR));
-
- return rv < 0? rv : orig_sz - bufsz;
-}
-#endif
-
-/* Called by parent process */
-void reinit_scoreboard (pool *p)
-{
- int exit_gen=0;
- if(scoreboard_image)
- exit_gen=scoreboard_image->global.exit_generation;
-
-#ifndef SCOREBOARD_FILE
- if (scoreboard_image == NULL)
- {
- setup_shared_mem();
- }
- memset(scoreboard_image, 0, SCOREBOARD_SIZE);
- scoreboard_image->global.exit_generation=exit_gen;
-#else
- scoreboard_fname = server_root_relative (p, scoreboard_fname);
-
-#ifdef __EMX__
- /* OS/2 needs binary mode set. */
- scoreboard_fd = popenf(p, scoreboard_fname, O_CREAT|O_BINARY|O_RDWR, 0644);
-#else
- scoreboard_fd = popenf(p, scoreboard_fname, O_CREAT|O_RDWR, 0644);
-#endif
- if (scoreboard_fd == -1)
- {
- perror (scoreboard_fname);
- fprintf (stderr, "Cannot open scoreboard file:\n");
- exit (1);
- }
-
- memset ((char*)scoreboard_image, 0, sizeof(*scoreboard_image));
- scoreboard_image->global.exit_generation=exit_gen;
- force_write (scoreboard_fd, (char*)scoreboard_image,
- sizeof(*scoreboard_image));
-#endif
-}
-
-/* called by child */
-void reopen_scoreboard (pool *p)
-{
-#ifdef SCOREBOARD_FILE
- if (scoreboard_fd != -1) pclosef (p, scoreboard_fd);
-
-#ifdef __EMX__
- /* OS/2 needs binary mode set. */
- scoreboard_fd = popenf(p, scoreboard_fname, O_CREAT|O_BINARY|O_RDWR, 0666);
-#else
- scoreboard_fd = popenf(p, scoreboard_fname, O_CREAT|O_RDWR, 0666);
-#endif
- if (scoreboard_fd == -1)
- {
- perror (scoreboard_fname);
- fprintf (stderr, "Cannot open scoreboard file:\n");
- exit (1);
- }
-#else
-#ifdef __EMX__
-#ifdef HAVE_MMAP
- caddr_t m;
- int rc;
-
- m = (caddr_t)get_shared_heap("\\SHAREMEM\\SCOREBOARD");
- if(m == 0) {
- fprintf(stderr, "httpd: Could not find existing OS/2 Shared memory pool.\n");
- exit(1);
- }
-
- rc = _uopen((Heap_t)m);
- scoreboard_image = (scoreboard *)m;
-#endif
-#endif
-#endif
-}
-
-void cleanup_scoreboard ()
-{
-#ifdef SCOREBOARD_FILE
- unlink (scoreboard_fname);
-#endif
-}
-
-/* Routines called to deal with the scoreboard image
- * --- note that we do *not* need write locks, since update_child_status
- * only updates a *single* record in place, and only one process writes to
- * a given scoreboard slot at a time (either the child process owning that
- * slot, or the parent, noting that the child has died).
- *
- * As a final note --- setting the score entry to getpid() is always safe,
- * since when the parent is writing an entry, it's only noting SERVER_DEAD
- * anyway.
- */
-
-void sync_scoreboard_image ()
-{
-#ifdef SCOREBOARD_FILE
- lseek (scoreboard_fd, 0L, 0);
- force_read (scoreboard_fd, (char*)scoreboard_image,
- sizeof(*scoreboard_image));
-#endif
-}
-
-int exists_scoreboard_image ()
-{
- return (scoreboard_image ? 1 : 0);
-}
-
-int update_child_status (int child_num, int status, request_rec *r)
-{
- int old_status;
- short_score new_score_rec;
-
- if (child_num < 0)
- return -1;
-
- sync_scoreboard_image();
- new_score_rec = scoreboard_image->servers[child_num];
- new_score_rec.pid = getpid();
- old_status = new_score_rec.status;
- new_score_rec.status = status;
-
-#if defined(STATUS)
- new_score_rec.last_used=time(NULL);
- if (status == SERVER_READY || status == SERVER_DEAD) {
- /*
- * Reset individual counters
- */
- if (status == SERVER_DEAD) {
- new_score_rec.my_access_count = 0L;
- new_score_rec.my_bytes_served = 0L;
- }
- new_score_rec.conn_count = (unsigned short)0;
- new_score_rec.conn_bytes = (unsigned long)0;
- }
- if (r) {
- int slot_size;
- conn_rec *c = r->connection;
- slot_size = sizeof(new_score_rec.client) - 1;
- strncpy(new_score_rec.client, get_remote_host(c, r->per_dir_config,
- REMOTE_NOLOOKUP), slot_size);
- new_score_rec.client[slot_size] = '\0';
- slot_size = sizeof(new_score_rec.request) - 1;
- strncpy(new_score_rec.request, (r->the_request ? r->the_request :
- "NULL"), slot_size);
- new_score_rec.request[slot_size] = '\0';
- slot_size = sizeof(new_score_rec.vhost) - 1;
- strncpy(new_score_rec.vhost,r->server->server_hostname, slot_size);
- new_score_rec.vhost[slot_size] = '\0';
- }
-#endif
-
-#ifndef SCOREBOARD_FILE
- memcpy(&scoreboard_image->servers[child_num], &new_score_rec, sizeof new_score_rec);
-#else
- lseek (scoreboard_fd, (long)child_num * sizeof(short_score), 0);
- force_write (scoreboard_fd, (char*)&new_score_rec, sizeof(short_score));
-#endif
-
- return old_status;
-}
-
-void update_scoreboard_global()
- {
-#ifdef SCOREBOARD_FILE
- lseek(scoreboard_fd,
- (char *)&scoreboard_image->global-(char *)scoreboard_image,0);
- force_write(scoreboard_fd,(char *)&scoreboard_image->global,
- sizeof scoreboard_image->global);
-#endif
- }
-
-int get_child_status (int child_num)
-{
- if (child_num<0 || child_num>=HARD_SERVER_LIMIT)
- return -1;
- else
- return scoreboard_image->servers[child_num].status;
-}
-
-int count_busy_servers ()
-{
- int i;
- int res = 0;
-
- for (i = 0; i < HARD_SERVER_LIMIT; ++i)
- if (scoreboard_image->servers[i].status == SERVER_BUSY_READ ||
- scoreboard_image->servers[i].status == SERVER_BUSY_WRITE ||
- scoreboard_image->servers[i].status == SERVER_BUSY_KEEPALIVE ||
- scoreboard_image->servers[i].status == SERVER_BUSY_LOG ||
- scoreboard_image->servers[i].status == SERVER_BUSY_DNS)
- ++res;
- return res;
-}
-
-int count_live_servers()
- {
- int i;
- int res = 0;
-
- for (i = 0; i < HARD_SERVER_LIMIT; ++i)
- if (scoreboard_image->servers[i].status != SERVER_DEAD)
- ++res;
- return res;
- }
-
-short_score get_scoreboard_info(int i)
-{
- return (scoreboard_image->servers[i]);
-}
-
-#if defined(STATUS)
-static void increment_counts (int child_num, request_rec *r)
-{
- long int bs=0;
- short_score new_score_rec;
-
- sync_scoreboard_image();
- new_score_rec = scoreboard_image->servers[child_num];
- if (r->sent_bodyct)
- bgetopt(r->connection->client, BO_BYTECT, &bs);
-
- new_score_rec.access_count ++;
- new_score_rec.my_access_count ++;
- new_score_rec.conn_count ++;
- new_score_rec.bytes_served += (unsigned long)bs;
- new_score_rec.my_bytes_served += (unsigned long)bs;
- new_score_rec.conn_bytes += (unsigned long)bs;
-
- times(&new_score_rec.times);
-
-
-#ifndef SCOREBOARD_FILE
- memcpy(&scoreboard_image->servers[child_num], &new_score_rec, sizeof(short_score));
-#else
- lseek (scoreboard_fd, (long)child_num * sizeof(short_score), 0);
- force_write (scoreboard_fd, (char*)&new_score_rec, sizeof(short_score));
-#endif
-}
-#endif
-
-int count_idle_servers ()
-{
- int i;
- int res = 0;
-
- for (i = 0; i < HARD_SERVER_LIMIT; ++i)
- if (scoreboard_image->servers[i].status == SERVER_READY)
- ++res;
-
- return res;
-}
-
-int find_free_child_num ()
-{
- int i;
-
- for (i = 0; i < HARD_SERVER_LIMIT; ++i)
- if (scoreboard_image->servers[i].status == SERVER_DEAD)
- return i;
-
- return -1;
-}
-
-int find_child_by_pid (int pid)
-{
- int i;
-
- for (i = 0; i < HARD_SERVER_LIMIT; ++i)
- if (scoreboard_image->servers[i].pid == pid)
- return i;
-
- return -1;
-}
-
-void reclaim_child_processes ()
-{
- int i, status;
- int my_pid = getpid();
-
- sync_scoreboard_image();
- for (i = 0; i < HARD_SERVER_LIMIT; ++i) {
- int pid = scoreboard_image->servers[i].pid;
-
- if (pid != my_pid && pid != 0) {
- int waitret = 0,
- tries = 1;
-
- while (waitret == 0 && tries <= 4) {
- long int waittime = 4096; /* in usecs */
- struct timeval tv;
-
- /* don't want to hold up progress any more than
- * necessary, so keep checking to see if the child
- * has exited with an exponential backoff.
- * Currently set for a maximum wait of a bit over
- * four seconds.
- */
- while (((waitret = waitpid(pid, &status, WNOHANG)) == 0) &&
- waittime < 3000000) {
- tv.tv_sec = waittime / 1000000;
- tv.tv_usec = waittime % 1000000;
- waittime = waittime * 2;
- select(0, NULL, NULL, NULL, &tv);
- }
- if (waitret == 0) {
- switch (tries) {
- case 1:
- /* perhaps it missed the SIGHUP, lets try again */
- log_printf(server_conf, "child process %d did not exit, sending another SIGHUP", pid);
- kill(pid, SIGHUP);
- break;
- case 2:
- /* ok, now it's being annoying */
- log_printf(server_conf, "child process %d still did not exit, sending a SIGTERM", pid);
- kill(pid, SIGTERM);
- break;
- case 3:
- /* die child scum */
- log_printf(server_conf, "child process %d still did not exit, sending a SIGKILL", pid);
- kill(pid, SIGKILL);
- break;
- case 4:
- /* gave it our best shot, but alas... If this really
- * is a child we are trying to kill and it really hasn't
- * exited, we will likely fail to bind to the port
- * after the restart.
- */
- log_printf(server_conf, "could not make child process %d exit, attempting to continue anyway", pid);
- break;
- }
- }
- tries++;
- }
- }
- }
-}
-
-#if defined(BROKEN_WAIT) || defined(NEED_WAITPID)
-/*
-Some systems appear to fail to deliver dead children to wait() at times.
-This sorts them out. In fact, this may have been caused by a race condition
-in wait_or_timeout(). But this routine is still useful for systems with no
-waitpid().
-*/
-int reap_children ()
-{
- int status, n;
- int ret = 0;
-
- for (n = 0; n < HARD_SERVER_LIMIT; ++n) {
- if (scoreboard_image->servers[n].status != SERVER_DEAD
- && waitpid (scoreboard_image->servers[n].pid, &status, WNOHANG)
- == -1
- && errno == ECHILD) {
- sync_scoreboard_image ();
- update_child_status (n, SERVER_DEAD, NULL);
- ret = 1;
- }
- }
- return ret;
-}
-#endif
-
-/* Finally, this routine is used by the caretaker process to wait for
- * a while...
- */
-
-static int wait_or_timeout ()
-{
-#ifndef NEED_WAITPID
- int ret;
-
- ret = waitpid (-1, NULL, WNOHANG);
- if (ret == -1 && errno == EINTR) {
- return -1;
- }
- if (ret <= 0) {
- sleep (1);
- return -1;
- }
- return ret;
-#else
- if (!reap_children ()) {
- sleep(1);
- }
- return -1;
-#endif
-}
-
-
-void sig_term() {
- log_error("httpd: caught SIGTERM, shutting down", server_conf);
- cleanup_scoreboard();
- ap_killpg (pgrp, SIGKILL);
- close(sd);
- exit(1);
-}
-
-void bus_error(void) {
- char emsg[256];
-
- ap_snprintf
- (
- emsg,
- sizeof(emsg) - 1,
- "httpd: caught SIGBUS, attempting to dump core in %s",
- server_root
- );
- log_error(emsg, server_conf);
- chdir(server_root);
- abort();
- exit(1);
-}
-
-void seg_fault() {
- char emsg[256];
-
- ap_snprintf
- (
- emsg,
- sizeof(emsg) - 1,
- "httpd: caught SIGSEGV, attempting to dump core in %s",
- server_root
- );
- log_error(emsg, server_conf);
- chdir(server_root);
- abort();
- exit(1);
-}
-
-void just_die() /* SIGHUP to child process??? */
-{
- exit (0);
-}
-
-static int deferred_die;
-
-static void deferred_die_handler ()
-{
- deferred_die = 1;
-}
-
-/* volatile just in case */
-static volatile int restart_pending;
-static volatile int is_graceful;
-static volatile int generation;
-
-static void restart (int sig)
-{
- is_graceful = (sig == SIGUSR1);
- restart_pending = 1;
-}
-
-
-void set_signals()
-{
-#ifndef NO_USE_SIGACTION
- struct sigaction sa;
-
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
-
- if (!one_process) {
- sa.sa_handler = (void (*)())seg_fault;
- if (sigaction (SIGSEGV, &sa, NULL) < 0)
- log_unixerr ("sigaction(SIGSEGV)", NULL, NULL, server_conf);
- sa.sa_handler = (void (*)())bus_error;
- if (sigaction (SIGBUS, &sa, NULL) < 0)
- log_unixerr ("sigaction(SIGBUS)", NULL, NULL, server_conf);
- }
- sa.sa_handler = (void (*)())sig_term;
- if (sigaction (SIGTERM, &sa, NULL) < 0)
- log_unixerr ("sigaction(SIGTERM)", NULL, NULL, server_conf);
-
- /* wait_or_timeout uses sleep() which could deliver a SIGALRM just as we're
- * trying to process the restart requests. That's not good. restart
- * cleans out the SIGALRM handler, but this totally avoids the race
- * condition between when the restart request is made and when the handler
- * is invoked.
- *
- * We also don't want to ignore HUPs and USR1 while we're busy processing
- * one.
- */
- sigaddset (&sa.sa_mask, SIGALRM);
- sigaddset (&sa.sa_mask, SIGHUP);
- sigaddset (&sa.sa_mask, SIGUSR1);
- sa.sa_handler = (void (*)())restart;
- if (sigaction (SIGHUP, &sa, NULL) < 0)
- log_unixerr ("sigaction(SIGHUP)", NULL, NULL, server_conf);
- if (sigaction (SIGUSR1, &sa, NULL) < 0)
- log_unixerr ("sigaction(SIGUSR1)", NULL, NULL, server_conf);
-#else
- if(!one_process) {
- signal (SIGSEGV, (void (*)())seg_fault);
- signal (SIGBUS, (void (*)())bus_error);
- }
-
- signal (SIGTERM, (void (*)())sig_term);
- signal (SIGHUP, (void (*)())restart);
- signal (SIGUSR1, (void (*)())restart);
-#endif
-}
-
-
-/*****************************************************************
- * Here follows a long bunch of generic server bookkeeping stuff...
- */
-
-void detach()
-{
- int x;
-
- chdir("/");
-#ifndef MPE
-/* Don't detach for MPE because child processes can't survive the death of
- the parent. */
- if((x = fork()) > 0)
- exit(0);
- else if(x == -1) {
- perror("fork");
- fprintf(stderr,"httpd: unable to fork new process\n");
- exit(1);
- }
-#endif
-#ifndef NO_SETSID
- if((pgrp=setsid()) == -1) {
- perror("setsid");
- fprintf(stderr,"httpd: setsid failed\n");
- exit(1);
- }
-#elif defined(NEXT)
- if(setpgrp(0,getpid()) == -1 || (pgrp = getpgrp(0)) == -1) {
- perror("setpgrp");
- fprintf(stderr,"httpd: setpgrp or getpgrp failed\n");
- exit(1);
- }
-#elif defined(__EMX__)
- /* OS/2 doesn't support process group IDs */
- pgrp=getpid();
-#elif defined(MPE)
- /* MPE uses negative pid for process group */
- pgrp=-getpid();
-#else
- if((pgrp=setpgrp(getpid(),0)) == -1) {
- perror("setpgrp");
- fprintf(stderr,"httpd: setpgrp failed\n");
- exit(1);
- }
-#endif
-}
-
-/* Reset group privileges, after rereading the config files
- * (our uid may have changed, and if so, we want the new perms).
- *
- * Don't reset the uid yet --- we do that only in the child process,
- * so as not to lose any root privs. But we can set the group stuff
- * now, once, as opposed to once per each new child.
- *
- * Note that we use the username as set in the config files, rather than
- * the lookup of to uid --- the same uid may have multiple passwd entries,
- * with different sets of groups for each.
- */
-
-static void set_group_privs()
-{
- if(!geteuid()) {
- char *name;
-
- /* Get username if passed as a uid */
-
- if (user_name[0] == '#') {
- struct passwd* ent;
- uid_t uid=atoi(&user_name[1]);
-
- if ((ent = getpwuid(uid)) == NULL) {
- log_unixerr("getpwuid",NULL,"couldn't determine user name from uid", server_conf);
- exit(1);
- }
-
- name = ent->pw_name;
- } else name = user_name;
-
-#ifndef __EMX__
- /* OS/2 dosen't support groups. */
-
- /* Reset `groups' attributes. */
-
- if (initgroups(name, group_id) == -1) {
- log_unixerr("initgroups", NULL, "unable to set groups", server_conf);
- exit (1);
- }
-#ifdef MULTIPLE_GROUPS
- if (getgroups(NGROUPS_MAX, group_id_list) == -1) {
- log_unixerr("getgroups", NULL, "unable to get group list", server_conf);
- exit (1);
- }
-#endif
- if (setgid(group_id) == -1) {
- log_unixerr("setgid", NULL, "unable to set group id", server_conf);
- exit (1);
- }
-#endif
- }
-}
-
-/* check to see if we have the 'suexec' setuid wrapper installed */
-int init_suexec ()
-{
- struct stat wrapper;
-
- if ((stat(SUEXEC_BIN, &wrapper)) != 0)
- return (suexec_enabled);
-
- if ((wrapper.st_mode & S_ISUID) && wrapper.st_uid == 0) {
- suexec_enabled = 1;
- fprintf(stderr, "Configuring Apache for use with suexec wrapper.\n");
- }
-
- return (suexec_enabled);
-}
-
-/*****************************************************************
- * Connection structures and accounting...
- * Should these be global? Only to this file, at least...
- */
-
-pool *pconf; /* Pool for config stuff */
-pool *ptrans; /* Pool for per-transaction stuff */
-
-static server_rec *find_virtual_server (struct in_addr server_ip,
- unsigned port, server_rec *server)
-{
- server_rec *virt;
- server_addr_rec *sar;
- server_rec *def;
-
- def = server;
- for (virt = server->next; virt; virt = virt->next) {
- for (sar = virt->addrs; sar; sar = sar->next) {
- if ((virt->is_virtual == 1) && /* VirtualHost */
- (sar->host_addr.s_addr == htonl(INADDR_ANY) ||
- sar->host_addr.s_addr == server_ip.s_addr) &&
- (sar->host_port == 0 || sar->host_port == port)) {
- return virt;
- } else if ( sar->host_addr.s_addr == DEFAULT_VHOST_ADDR
- && (sar->host_port == 0 || sar->host_port == port)) {
- /* this is so that you can build a server that is the
- "default" for any interface which isn't explicitly
- specified. So that you can implement "deny anything
- which isn't expressly permitted" -djg */
- def = virt;
- }
- }
- }
-
- return def;
-}
-
-void default_server_hostnames(server_rec *s)
-{
- struct hostent *h;
- struct in_addr *main_addr;
- int num_addr;
- char *def_hostname;
- int n;
- server_addr_rec *sar;
- int has_default_vhost_addr;
- unsigned mainport = s->port;
- int from_local=0;
-
- /* Main host first */
-
- if (!s->server_hostname) {
- s->server_hostname = get_local_host(pconf);
- from_local = 1;
- }
-
- def_hostname = s->server_hostname;
- h = gethostbyname(def_hostname);
- if( h == NULL ) {
- fprintf(stderr,"httpd: cannot determine the IP address of ");
- if (from_local) {
- fprintf(stderr,"the local host (%s). Use ServerName to set it manually.\n",
- s->server_hostname ? s->server_hostname : "<NULL>");
- } else {
- fprintf(stderr,"the specified ServerName (%s).\n",
- s->server_hostname ? s->server_hostname : "<NULL>");
- };
- exit(1);
- }
- /* we need to use gethostbyaddr below... and since it shares a static
- area with gethostbyname it'd clobber the value we just got. So
- we need to make a copy. -djg */
- for (num_addr = 0; h->h_addr_list[num_addr] != NULL; num_addr++) {
- /* nop */
- }
- main_addr = palloc( pconf, sizeof( *main_addr ) * num_addr );
- for (n = 0; n < num_addr; n++) {
- main_addr[n] = *(struct in_addr *)h->h_addr_list[n];
- }
-
- /* Then virtual hosts */
-
- for (s = s->next; s; s = s->next) {
- /* Check to see if we might be a HTTP/1.1 virtual host - same IP */
- has_default_vhost_addr = 0;
- for (n = 0; n < num_addr; n++) {
- for(sar = s->addrs; sar; sar = sar->next) {
- if (sar->host_addr.s_addr == main_addr[n].s_addr &&
- s->port == mainport)
- s->is_virtual = 2;
- if( sar->host_addr.s_addr == DEFAULT_VHOST_ADDR ) {
- has_default_vhost_addr = 1;
- }
- }
- }
-
- /* FIXME: some of this decision doesn't make a lot of sense in
- the presence of multiple addresses on the <VirtualHost>
- directive. It should issue warnings here perhaps. -djg */
- if (!s->server_hostname) {
- if (s->is_virtual == 2) {
- if (s->addrs) {
- s->server_hostname = s->addrs->virthost;
- } else {
- /* 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 = "bogus_host_without_forward_dns";
- }
- } else if (has_default_vhost_addr) {
- s->server_hostname = def_hostname;
- } else {
- if (s->addrs
- && (h = gethostbyaddr ((char *)&(s->addrs->host_addr),
- sizeof (struct in_addr), AF_INET))) {
- s->server_hostname = pstrdup (pconf, (char *)h->h_name);
- } else {
- /* again, what can we do? They didn't specify a
- ServerName, and their DNS isn't working. -djg */
- if (s->addrs) {
- fprintf(stderr, "Failed to resolve server name "
- "for %s (check DNS)\n",
- inet_ntoa(s->addrs->host_addr));
- }
- s->server_hostname = "bogus_host_without_reverse_dns";
- }
- }
- }
- }
-}
-
-conn_rec *new_connection (pool *p, server_rec *server, BUFF *inout,
- const struct sockaddr_in *remaddr,
- const struct sockaddr_in *saddr,
- int child_num)
-{
- conn_rec *conn = (conn_rec *)pcalloc (p, sizeof(conn_rec));
-
- /* Got a connection structure, so initialize what fields we can
- * (the rest are zeroed out by pcalloc).
- */
-
- conn->child_num = child_num;
-
- conn->pool = p;
- conn->local_addr = *saddr;
- conn->server = find_virtual_server(saddr->sin_addr, ntohs(saddr->sin_port),
- server);
- conn->base_server = conn->server;
- conn->client = inout;
-
- conn->remote_addr = *remaddr;
- conn->remote_ip = pstrdup (conn->pool,
- inet_ntoa(conn->remote_addr.sin_addr));
-
- return conn;
-}
-
-#if defined(TCP_NODELAY) && !defined(MPE)
-static void sock_disable_nagle (int s)
-{
- /* The Nagle algorithm says that we should delay sending partial
- * packets in hopes of getting more data. We don't want to do
- * this; we are not telnet. There are bad interactions between
- * persistent connections and Nagle's algorithm that have very severe
- * performance penalties. (Failing to disable Nagle is not much of a
- * problem with simple HTTP.)
- *
- * In spite of these problems, failure here is not a shooting offense.
- */
- int just_say_no = 1;
-
- if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&just_say_no,
- sizeof(int)) < 0) {
- log_unixerr("setsockopt", "(TCP_NODELAY)", NULL, server_conf);
- }
-}
-#else
-#define sock_disable_nagle(s) /* NOOP */
-#endif
-
-/*****************************************************************
- * Child process main loop.
- * The following vars are static to avoid getting clobbered by longjmp();
- * they are really private to child_main.
- */
-
-static int srv;
-static int csd;
-static int dupped_csd;
-static int requests_this_child;
-static int child_num;
-static fd_set main_fds;
-
-void child_main(int child_num_arg)
-{
-#if defined(UW)
- size_t clen;
-#else
- int clen;
-#endif
- struct sockaddr sa_server;
- struct sockaddr sa_client;
-
- csd = -1;
- dupped_csd = -1;
- child_num = child_num_arg;
- requests_this_child = 0;
-
- reopen_scoreboard(pconf);
- (void)update_child_status(child_num, SERVER_READY, (request_rec*)NULL);
-
-#ifdef MPE
- /* Only try to switch if we're running as MANAGER.SYS */
- if (geteuid() == 1 && user_id > 1) {
- GETPRIVMODE();
- if (setuid(user_id) == -1) {
- GETUSERMODE();
-#else
- /* Only try to switch if we're running as root */
- if (!geteuid() && setuid(user_id) == -1) {
-#endif
- log_unixerr("setuid", NULL, "unable to change uid", server_conf);
- exit (1);
- }
-#ifdef MPE
- GETUSERMODE();
- }
-#endif
-
- /*
- * Setup the jump buffers so that we can return here after
- * a signal or a timeout (yeah, I know, same thing).
- */
- ap_setjmp (jmpbuffer);
-#ifndef __EMX__
-#ifdef SIGURG
- signal(SIGURG, timeout);
-#endif
-#endif
-
- while (1) {
- int errsave;
- BUFF *conn_io;
- request_rec *r;
-
- /* Prepare to receive a SIGUSR1 due to graceful restart so that
- * we can exit cleanly. Since we're between connections right
- * now it's the right time to exit, but we might be blocked in a
- * system call when the graceful restart request is made. */
- signal (SIGUSR1, (void (*)())just_die);
-
- /*
- * (Re)initialize this child to a pre-connection state.
- */
-
- alarm(0); /* Cancel any outstanding alarms. */
- timeout_req = NULL; /* No request in progress */
- current_conn = NULL;
- signal(SIGPIPE, timeout);
-
- clear_pool (ptrans);
-
- sync_scoreboard_image();
- if (scoreboard_image->global.exit_generation >= generation)
- exit(0);
-
- if ((count_idle_servers() >= daemons_max_free)
- || (max_requests_per_child > 0
- && ++requests_this_child >= max_requests_per_child))
- {
- exit(0);
- }
-
- (void)update_child_status(child_num, SERVER_READY, (request_rec*)NULL);
-
- if (listeners == NULL) {
- FD_ZERO(&listenfds);
- FD_SET(sd, &listenfds);
- listenmaxfd = sd;
- }
-
- /*
- * Wait for an acceptable connection to arrive.
- */
-
- accept_mutex_on(); /* Lock around "accept", if necessary */
-
- for (;;) {
- memcpy(&main_fds, &listenfds, sizeof(fd_set));
-#ifdef SELECT_NEEDS_CAST
- srv = select(listenmaxfd+1, (int*)&main_fds, NULL, NULL, NULL);
-#else
- srv = select(listenmaxfd+1, &main_fds, NULL, NULL, NULL);
-#endif
- errsave = errno;
-
- sync_scoreboard_image();
- if (scoreboard_image->global.exit_generation >= generation)
- exit(0);
-
- errno = errsave;
- if (srv < 0 && errno != EINTR) {
- /* Single Unix documents select as returning errnos
- * EBADF, EINTR, and EINVAL... and in none of those
- * cases does it make sense to continue. In fact
- * on Linux 2.0.x we seem to end up with EFAULT
- * occasionally, and we'd loop forever due to it.
- */
- log_unixerr("select", "(listen)", NULL, server_conf);
- exit(1);
- }
-
- if (srv <= 0)
- continue;
-
- if (listeners != NULL) {
- for (sd = listenmaxfd; sd >= 0; sd--)
- if (FD_ISSET(sd, &main_fds)) break;
- if (sd < 0)
- continue;
- }
-
- /* if we accept() something we don't want to die, so we have to
- * defer the exit
- */
- deferred_die = 0;
- signal (SIGUSR1, (void (*)())deferred_die_handler);
- for (;;) {
- clen = sizeof(sa_client);
- csd = accept(sd, &sa_client, &clen);
- if (csd >= 0 || errno != EINTR) break;
- if (deferred_die) {
- /* we didn't get a socket, and we were told to die */
- exit (0);
- }
- }
-
- if (csd >= 0)
- break; /* We have a socket ready for reading */
- else {
- /* Our old behaviour here was to continue after accept()
- * errors. But this leads us into lots of troubles
- * because most of the errors are quite fatal. For
- * example, EMFILE can be caused by slow descriptor
- * leaks (say in a 3rd party module, or libc). It's
- * foolish for us to continue after an EMFILE. We also
- * seem to tickle kernel bugs on some platforms which
- * lead to never-ending loops here. So it seems best
- * to just exit in most cases.
- */
- switch (errno) {
-#ifdef EPROTO
- /* EPROTO on certain older kernels really means
- * ECONNABORTED, so we need to ignore it for them.
- * See discussion in new-httpd archives nh.9701
- * search for EPROTO.
- *
- * Also see nh.9603, search for EPROTO:
- * There is potentially a bug in Solaris 2.x x<6,
- * and other boxes that implement tcp sockets in
- * userland (i.e. on top of STREAMS). On these
- * systems, EPROTO can actually result in a fatal
- * loop. See PR#981 for example. It's hard to
- * handle both uses of EPROTO.
- */
- case EPROTO:
-#endif
-#ifdef ECONNABORTED
- case ECONNABORTED:
-#endif
- /* Linux generates the rest of these, other tcp
- * stacks (i.e. bsd) tend to hide them behind
- * getsockopt() interfaces. They occur when
- * the net goes sour or the client disconnects
- * after the three-way handshake has been done
- * in the kernel but before userland has picked
- * up the socket.
- */
-#ifdef ECONNRESET
- case ECONNRESET:
-#endif
-#ifdef ETIMEDOUT
- case ETIMEDOUT:
-#endif
-#ifdef EHOSTUNREACH
- case EHOSTUNREACH:
-#endif
-#ifdef ENETUNREACH
- case ENETUNREACH:
-#endif
- break;
-
- default:
- log_unixerr("accept", "(client socket)", NULL, server_conf);
- exit(1);
- }
- }
-
- /* go around again, safe to die */
- signal (SIGUSR1, (void (*)())just_die);
- if (deferred_die) {
- /* ok maybe not, see ya later */
- exit (0);
- }
- }
-
- accept_mutex_off(); /* unlock after "accept" */
-
- /* We've got a socket, let's at least process one request off the
- * socket before we accept a graceful restart request.
- */
- signal (SIGUSR1, SIG_IGN);
-
- note_cleanups_for_fd(ptrans,csd);
-
- /*
- * We now have a connection, so set it up with the appropriate
- * socket options, file descriptors, and read/write buffers.
- */
-
- clen = sizeof(sa_server);
- if (getsockname(csd, &sa_server, &clen) < 0) {
- log_unixerr("getsockname", NULL, NULL, server_conf);
- continue;
- }
-
- sock_disable_nagle(csd);
-
- (void)update_child_status(child_num, SERVER_BUSY_READ,
- (request_rec*)NULL);
-
- conn_io = bcreate(ptrans, B_RDWR);
- dupped_csd = csd;
-#if defined(NEED_DUPPED_CSD)
- if ((dupped_csd = dup(csd)) < 0) {
- log_unixerr("dup", NULL, "couldn't duplicate csd", server_conf);
- dupped_csd = csd; /* Oh well... */
- }
- note_cleanups_for_fd(ptrans,dupped_csd);
-#endif
- bpushfd(conn_io, csd, dupped_csd);
-
- current_conn = new_connection (ptrans, server_conf, conn_io,
- (struct sockaddr_in *)&sa_client,
- (struct sockaddr_in *)&sa_server,
- child_num);
-
- /*
- * Read and process each request found on our connection
- * until no requests are left or we decide to close.
- */
-
- while ((r = read_request(current_conn)) != NULL) {
-
- /* ok we've read the request... it's a little too late
- * to do a graceful restart, so ignore them for now.
- */
- signal (SIGUSR1, SIG_IGN);
-
- (void)update_child_status(child_num, SERVER_BUSY_WRITE, r);
-
- process_request(r);
-#if defined(STATUS)
- increment_counts(child_num, r);
-#endif
- if (!current_conn->keepalive || current_conn->aborted)
- break;
-
- destroy_pool(r->pool);
- (void)update_child_status(child_num, SERVER_BUSY_KEEPALIVE,
- (request_rec*)NULL);
-
- sync_scoreboard_image();
- if (scoreboard_image->global.exit_generation >= generation) {
- bclose(conn_io);
- exit(0);
- }
-
- /* In case we get a graceful restart while we're blocked
- * waiting for the request.
- *
- * XXX: This isn't perfect, we might actually read the
- * request and then just die without saying anything to
- * the client. This can be fixed by using deferred_die
- * but you have to teach buff.c about it so that it can handle
- * the EINTR properly.
- *
- * In practice though browsers (have to) expect keepalive
- * connections to close before receiving a response because
- * of network latencies and server timeouts.
- */
- signal (SIGUSR1, (void (*)())just_die);
- }
-
- /*
- * Close the connection, being careful to send out whatever is still
- * in our buffers. If possible, try to avoid a hard close until the
- * client has ACKed our FIN and/or has stopped sending us data.
- */
-
-#ifdef NO_LINGCLOSE
- bclose(conn_io); /* just close it */
-#else
- if (r && r->connection
- && !r->connection->aborted
- && r->connection->client
- && (r->connection->client->fd >= 0)) {
-
- lingering_close(r);
- }
- else {
- bsetflag(conn_io, B_EOUT, 1);
- bclose(conn_io);
- }
-#endif
- }
-}
-
-int make_child(server_rec *server_conf, int child_num)
-{
- int pid;
-
- if (one_process) {
- signal (SIGHUP, (void (*)())just_die);
- signal (SIGTERM, (void (*)())just_die);
- child_main (child_num);
- }
-
- Explain1 ("Starting new child in slot %d", child_num);
- (void)update_child_status (child_num, SERVER_STARTING, (request_rec *)NULL);
-
- if ((pid = fork()) == -1) {
- log_unixerr("fork", NULL, "Unable to fork new process", server_conf);
-
- /* fork didn't succeed. Fix the scoreboard or else
- * it will say SERVER_STARTING forever and ever
- */
- (void)update_child_status (child_num, SERVER_DEAD, (request_rec*)NULL);
-
- /* In case system resources are maxxed out, we don't want
- Apache running away with the CPU trying to fork over and
- over and over again. */
- sleep(10);
-
- return -1;
- }
-
- if (!pid) {
- /* Disable the restart signal handlers and enable the just_die stuff.
- * Note that since restart() just notes that a restart has been
- * requested there's no race condition here.
- */
- signal (SIGHUP, (void (*)())just_die);
- signal (SIGUSR1, (void (*)())just_die);
- signal (SIGTERM, (void (*)())just_die);
- child_main (child_num);
- }
-
- /* If the parent proceeds with a restart before the child has written
- * their pid into the scoreboard we'll end up "forgetting" about the
- * child. So we write the child pid into the scoreboard now. (This
- * is safe, because the child is going to be writing the same value
- * to the same word.)
- * XXX: this needs to be sync'd to disk in the non shared memory stuff
- */
- scoreboard_image->servers[child_num].pid = pid;
-
- return 0;
-}
-
-static int make_sock(pool *pconf, const struct sockaddr_in *server)
-{
- int s;
- int one = 1;
-
- if ((s = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) == -1) {
- log_unixerr("socket", NULL, "Failed to get a socket, exiting child",
- server_conf);
- exit(1);
- }
-
- /* Solaris (probably versions 2.4, 2.5, and 2.5.1 with various levels
- * of tcp patches) has some really weird bugs where if you dup the
- * socket now it breaks things across SIGHUP restarts. It'll either
- * be unable to bind, or it won't respond.
- */
-#ifndef SOLARIS2
- s = ap_slack(s, AP_SLACK_HIGH);
-
- note_cleanups_for_fd(pconf, s); /* arrange to close on exec or restart */
-#endif
-
-#ifndef MPE
-/* MPE does not support SO_REUSEADDR and SO_KEEPALIVE */
- if (setsockopt(s, SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(int)) < 0) {
- log_unixerr("setsockopt", "(SO_REUSEADDR)", NULL, server_conf);
- exit(1);
- }
- one = 1;
- if (setsockopt(s, SOL_SOCKET,SO_KEEPALIVE,(char *)&one,sizeof(int)) < 0) {
- log_unixerr("setsockopt", "(SO_KEEPALIVE)", NULL, server_conf);
- exit(1);
- }
-#endif
-
- sock_disable_nagle(s);
- sock_enable_linger(s);
-
- /*
- * To send data over high bandwidth-delay connections at full
- * speed we must force the TCP window to open wide enough to keep the
- * pipe full. The default window size on many systems
- * is only 4kB. Cross-country WAN connections of 100ms
- * at 1Mb/s are not impossible for well connected sites.
- * If we assume 100ms cross-country latency,
- * a 4kB buffer limits throughput to 40kB/s.
- *
- * To avoid this problem I've added the SendBufferSize directive
- * to allow the web master to configure send buffer size.
- *
- * The trade-off of larger buffers is that more kernel memory
- * is consumed. YMMV, know your customers and your network!
- *
- * -John Heidemann <johnh@isi.edu> 25-Oct-96
- *
- * If no size is specified, use the kernel default.
- */
- if (server_conf->send_buffer_size) {
- if (setsockopt(s, SOL_SOCKET, SO_SNDBUF,
- (char *)&server_conf->send_buffer_size, sizeof(int)) < 0) {
- log_unixerr("setsockopt", "(SO_SNDBUF)",
- "Failed to set SendBufferSize, using default",
- server_conf);
- /* not a fatal error */
- }
- }
-
-#ifdef MPE
-/* MPE requires CAP=PM and GETPRIVMODE to bind to ports less than 1024 */
- if (ntohs(server->sin_port) < 1024) GETPRIVMODE();
-#endif
- if(bind(s, (struct sockaddr *)server,sizeof(struct sockaddr_in)) == -1)
- {
- perror("bind");
-#ifdef MPE
- if (ntohs(server->sin_port) < 1024) GETUSERMODE();
-#endif
- if (server->sin_addr.s_addr != htonl(INADDR_ANY))
- fprintf(stderr,"httpd: could not bind to address %s port %d\n",
- inet_ntoa(server->sin_addr), ntohs(server->sin_port));
- else
- fprintf(stderr,"httpd: could not bind to port %d\n",
- ntohs(server->sin_port));
- exit(1);
- }
-#ifdef MPE
- if (ntohs(server->sin_port) < 1024) GETUSERMODE();
-#endif
- listen(s, 512);
-
-#ifdef SOLARIS2
- s = ap_slack(s, AP_SLACK_HIGH);
-
- note_cleanups_for_fd(pconf, s); /* arrange to close on exec or restart */
-#endif
- return s;
-}
-
-static listen_rec *old_listeners;
-
-static void copy_listeners(pool *p)
- {
- listen_rec *lr;
-
- assert(old_listeners == NULL);
- for(lr=listeners ; lr ; lr=lr->next)
- {
- listen_rec *nr=malloc(sizeof *nr);
- if (nr == NULL) {
- fprintf (stderr, "Ouch! malloc failed in copy_listeners()\n");
- exit (1);
- }
- *nr=*lr;
- kill_cleanups_for_fd(p,nr->fd);
- nr->next=old_listeners;
- assert(!nr->used);
- old_listeners=nr;
- }
- }
-
-static int find_listener(listen_rec *lr)
- {
- listen_rec *or;
-
- for(or=old_listeners ; or ; or=or->next)
- if(!memcmp(&or->local_addr,&lr->local_addr,sizeof or->local_addr))
- {
- or->used=1;
- return or->fd;
- }
- return -1;
- }
-
-static void close_unused_listeners()
- {
- listen_rec *or,*next;
-
- for(or=old_listeners ; or ; or=next)
- {
- next=or->next;
- if(!or->used)
- close(or->fd);
- free(or);
- }
- old_listeners=NULL;
- }
-
-/*****************************************************************
- * Executive routines.
- */
-
-void standalone_main(int argc, char **argv)
-{
- struct sockaddr_in sa_server;
- int saved_sd;
- int remaining_children_to_start;
-
- standalone = 1;
- sd = listenmaxfd = -1;
-
- is_graceful = 0;
- ++generation;
-
- if (!one_process) detach ();
-
- do {
- copy_listeners(pconf);
- saved_sd = sd;
- if (!is_graceful) {
- restart_time = time(NULL);
- }
-#ifdef SCOREBOARD_FILE
- else {
- kill_cleanups_for_fd (pconf, scoreboard_fd);
- }
-#endif
- clear_pool (pconf);
- ptrans = make_sub_pool (pconf);
-
- server_conf = read_config (pconf, ptrans, server_confname);
-
- if (listeners == NULL) {
- if (!is_graceful) {
- memset ((char *)&sa_server, 0, sizeof (sa_server));
- sa_server.sin_family = AF_INET;
- sa_server.sin_addr = bind_address;
- sa_server.sin_port = htons (server_conf->port);
- sd = make_sock (pconf, &sa_server);
- }
- else {
- sd = saved_sd;
- note_cleanups_for_fd(pconf, sd);
- }
- }
- else {
- listen_rec *lr;
- int fd;
-
- listenmaxfd = -1;
- FD_ZERO (&listenfds);
- for (lr = listeners; lr != NULL; lr = lr->next)
- {
- fd = find_listener (lr);
- if (fd < 0) {
- fd = make_sock (pconf, &lr->local_addr);
- }
- FD_SET (fd, &listenfds);
- if (fd > listenmaxfd) listenmaxfd = fd;
- lr->fd = fd;
- }
- close_unused_listeners ();
- sd = -1;
- }
-
- init_modules (pconf, server_conf);
- open_logs (server_conf, pconf);
- set_group_privs ();
- accept_mutex_init (pconf);
- if (!is_graceful) {
- reinit_scoreboard(pconf);
- }
-#ifdef SCOREBOARD_FILE
- else {
- scoreboard_fname = server_root_relative (pconf, scoreboard_fname);
- note_cleanups_for_fd (pconf, scoreboard_fd);
- }
-#endif
-
- default_server_hostnames (server_conf);
-
- set_signals ();
- log_pid (pconf, pid_fname);
-
- if (daemons_max_free < daemons_min_free + 1) /* Don't thrash... */
- daemons_max_free = daemons_min_free + 1;
-
- /* If we're doing a graceful_restart then we're going to see a lot
- * of children exiting immediately when we get into the main loop
- * below (because we just sent them SIGUSR1). This happens pretty
- * rapidly... and for each one that exits we'll start a new one until
- * we reach at least daemons_min_free. But we may be permitted to
- * start more than that, so we'll just keep track of how many we're
- * supposed to start up without the 1 second penalty between each fork.
- */
- remaining_children_to_start = daemons_to_start;
- if( remaining_children_to_start > daemons_limit ) {
- remaining_children_to_start = daemons_limit;
- }
- if (!is_graceful) {
- while (remaining_children_to_start) {
- --remaining_children_to_start;
- make_child (server_conf, remaining_children_to_start);
- }
- }
-
- log_error ("Server configured -- resuming normal operations",
- server_conf);
- restart_pending = 0;
-
- while (!restart_pending) {
- int child_slot;
- int pid = wait_or_timeout ();
-
- /* XXX: if it takes longer than 1 second for all our children
- * to start up and get into IDLE state then we may spawn an
- * extra child
- */
- if (pid >= 0) {
- /* Child died... note that it's gone in the scoreboard. */
- sync_scoreboard_image ();
- child_slot = find_child_by_pid (pid);
- Explain2 ("Reaping child %d slot %d", pid, child_slot);
- if (child_slot >= 0) {
- (void)update_child_status (child_slot, SERVER_DEAD,
- (request_rec *)NULL);
- } else if (is_graceful) {
- /* Great, we've probably just lost a slot in the
- * scoreboard. Somehow we don't know about this
- * child.
- */
- log_printf (server_conf,
- "long lost child came home! (pid %d)", pid );
- }
- } else if (remaining_children_to_start) {
- /* we hit a 1 second timeout in which none of the previous
- * generation of children needed to be reaped... so assume
- * they're all done, and pick up the slack if any is left.
- */
- while (remaining_children_to_start > 0) {
- child_slot = find_free_child_num ();
- if (child_slot < 0 || child_slot >= daemons_limit) {
- remaining_children_to_start = 0;
- break;
- }
- if (make_child (server_conf, child_slot) < 0) {
- remaining_children_to_start = 0;
- break;
- }
- --remaining_children_to_start;
- }
- /* In any event we really shouldn't do the code below because
- * few of the servers we just started are in the IDLE state
- * yet, so we'd mistakenly create an extra server.
- */
- continue;
- }
-
- sync_scoreboard_image ();
- if ((remaining_children_to_start
- || (count_idle_servers () < daemons_min_free))
- && (child_slot = find_free_child_num ()) >= 0
- && child_slot < daemons_limit) {
- make_child (server_conf, child_slot);
- }
- if (remaining_children_to_start) {
- --remaining_children_to_start;
- }
- }
-
- /* we've been told to restart */
- signal (SIGHUP, SIG_IGN);
- signal (SIGUSR1, SIG_IGN);
-
- if (one_process) {
- /* not worth thinking about */
- exit (0);
- }
-
- if (is_graceful) {
-#ifndef SCOREBOARD_FILE
- int i;
-#endif
-
- /* USE WITH CAUTION: Graceful restarts are not known to work
- * in various configurations on the architectures we support. */
- scoreboard_image->global.exit_generation = generation;
- update_scoreboard_global ();
-
- log_error ("SIGUSR1 received. Doing graceful restart",server_conf);
- kill_cleanups_for_fd (pconf, sd);
- /* kill off the idle ones */
- if (ap_killpg(pgrp, SIGUSR1) < 0) {
- log_unixerr ("killpg SIGUSR1", NULL, NULL, server_conf);
- }
-#ifndef SCOREBOARD_FILE
- /* This is mostly for debugging... so that we know what is still
- * gracefully dealing with existing request. But we can't really
- * do it if we're in a SCOREBOARD_FILE because it'll cause
- * corruption too easily.
- */
- sync_scoreboard_image();
- for (i = 0; i < daemons_limit; ++i ) {
- if (scoreboard_image->servers[i].status != SERVER_DEAD) {
- scoreboard_image->servers[i].status = SERVER_GRACEFUL;
- }
- }
-#endif
- }
- else {
- /* Kill 'em off */
- if (ap_killpg (pgrp, SIGHUP) < 0) {
- log_unixerr ("killpg SIGHUP", NULL, NULL, server_conf);
- }
- reclaim_child_processes(); /* Not when just starting up */
- log_error ("SIGHUP received. Attempting to restart", server_conf);
- }
- ++generation;
-
- } while (restart_pending);
-
-} /* standalone_main */
-
-extern char *optarg;
-extern int optind;
-
-int
-main(int argc, char *argv[])
-{
- int c;
-
-#ifdef AUX
- (void)set42sig();
-#endif
-
-#ifdef SecureWare
- if(set_auth_parameters(argc,argv) < 0)
- perror("set_auth_parameters");
- if(getluid() < 0)
- if(setluid(getuid()) < 0)
- perror("setluid");
- if(setreuid(0, 0) < 0)
- perror("setreuid");
-#endif
-
- init_alloc();
- pconf = permanent_pool;
- ptrans = make_sub_pool(pconf);
-
- server_argv0 = argv[0];
- strncpy (server_root, HTTPD_ROOT, sizeof(server_root)-1);
- server_root[sizeof(server_root)-1] = '\0';
- strncpy (server_confname, SERVER_CONFIG_FILE, sizeof(server_root)-1);
- server_confname[sizeof(server_confname)-1] = '\0';
-
- while((c = getopt(argc,argv,"Xd:f:vhl")) != -1) {
- switch(c) {
- case 'd':
- strncpy (server_root, optarg, sizeof(server_root)-1);
- server_root[sizeof(server_root)-1] = '\0';
- break;
- case 'f':
- strncpy (server_confname, optarg, sizeof(server_confname)-1);
- server_confname[sizeof(server_confname)-1] = '\0';
- break;
- case 'v':
- printf("Server version %s.\n",SERVER_VERSION);
- exit(0);
- case 'h':
- show_directives();
- exit(0);
- case 'l':
- show_modules();
- exit(0);
- case 'X':
- ++one_process; /* Weird debugging mode. */
- break;
- case '?':
- usage(argv[0]);
- }
- }
-
-#ifdef __EMX__
- printf("%s \n",SERVER_VERSION);
- printf("OS/2 port by Garey Smiley <garey@slink.com> \n");
-#endif
-
- setup_prelinked_modules();
-
- suexec_enabled = init_suexec();
- server_conf = read_config (pconf, ptrans, server_confname);
- init_modules (pconf, server_conf);
-
- if(standalone) {
- clear_pool (pconf); /* standalone_main rereads... */
- standalone_main(argc, argv);
- }
- else {
- conn_rec *conn;
- request_rec *r;
- struct sockaddr sa_server, sa_client;
- BUFF *cio;
-
- open_logs(server_conf, pconf);
- set_group_privs();
- default_server_hostnames (server_conf);
-
-#ifdef MPE
- /* Only try to switch if we're running as MANAGER.SYS */
- if (geteuid() == 1 && user_id > 1) {
- GETPRIVMODE();
- if (setuid(user_id) == -1) {
- GETUSERMODE();
-#else
- /* Only try to switch if we're running as root */
- if(!geteuid() && setuid(user_id) == -1) {
-#endif
- log_unixerr("setuid", NULL, "unable to change uid", server_conf);
- exit (1);
- }
-#ifdef MPE
- GETUSERMODE();
- }
-#endif
- if (ap_setjmp (jmpbuffer)) {
- exit (0);
- }
-
- c = sizeof(sa_client);
- if ((getpeername(fileno(stdin), &sa_client, &c)) < 0)
- {
-/* get peername will fail if the input isn't a socket */
- perror("getpeername");
- memset(&sa_client, '\0', sizeof(sa_client));
- }
-
- c = sizeof(sa_server);
- if(getsockname(fileno(stdin), &sa_server, &c) < 0) {
- perror("getsockname");
- fprintf(stderr, "Error getting local address\n");
- exit(1);
- }
- server_conf->port =ntohs(((struct sockaddr_in *)&sa_server)->sin_port);
- cio = bcreate(ptrans, B_RDWR);
-#ifdef MPE
-/* HP MPE 5.5 inetd only passes the incoming socket as stdin (fd 0), whereas
- HPUX inetd passes the incoming socket as stdin (fd 0) and stdout (fd 1).
- Go figure. SR 5003355016 has been submitted to request that the existing
- functionality be documented, and then to enhance the functionality to be
- like HPUX. */
-
- cio->fd = fileno(stdin);
-#else
- cio->fd = fileno(stdout);
-#endif
- cio->fd_in = fileno(stdin);
- conn = new_connection (ptrans, server_conf, cio,
- (struct sockaddr_in *)&sa_client,
- (struct sockaddr_in *)&sa_server,-1);
- r = read_request (conn);
- if (r) process_request (r); /* else premature EOF (ignore) */
-
- while (r && conn->keepalive && !conn->aborted) {
- destroy_pool(r->pool);
- r = read_request (conn);
- if (r) process_request (r);
- }
-
- bclose(cio);
- }
- exit (0);
-}
-
-#ifdef __EMX__
-#ifdef HAVE_MMAP
-/* The next two routines are used to access shared memory under OS/2. */
-/* This requires EMX v09c to be installed. */
-
-caddr_t create_shared_heap (const char *name, size_t size)
-{
- ULONG rc;
- void *mem;
- Heap_t h;
-
- rc = DosAllocSharedMem (&mem, name, size,
- PAG_COMMIT | PAG_READ | PAG_WRITE);
- if (rc != 0)
- return NULL;
- h = _ucreate (mem, size, !_BLOCK_CLEAN, _HEAP_REGULAR | _HEAP_SHARED,
- NULL, NULL);
- if (h == NULL)
- DosFreeMem (mem);
- return (caddr_t)h;
-}
-
-caddr_t get_shared_heap (const char *Name)
-{
-
- PVOID BaseAddress; /* Pointer to the base address of
- the shared memory object */
- ULONG AttributeFlags; /* Flags describing characteristics
- of the shared memory object */
- APIRET rc; /* Return code */
-
- /* Request read and write access to */
- /* the shared memory object */
- AttributeFlags = PAG_WRITE | PAG_READ;
-
- rc = DosGetNamedSharedMem(&BaseAddress, Name, AttributeFlags);
-
- if(rc != 0) {
- printf("DosGetNamedSharedMem error: return code = %ld", rc);
- return 0;
- }
-
- return BaseAddress;
-}
-#endif
-#endif
-
diff --git a/usr.sbin/httpd/src/http_main.h b/usr.sbin/httpd/src/http_main.h
deleted file mode 100644
index 7d3c2f5a789..00000000000
--- a/usr.sbin/httpd/src/http_main.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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/>.
- *
- */
-
-/*
- * Routines in http_main.c which other code --- in particular modules ---
- * may want to call. Right now, that's limited to timeout handling.
- * There are two functions which modules can call to trigger a timeout
- * (with the per-virtual-server timeout duration); these are hard_timeout
- * and soft_timeout.
- *
- * The difference between the two is what happens when the timeout
- * expires (or earlier than that, if the client connection aborts) ---
- * a soft_timeout just puts the connection to the client in an
- * "aborted" state, which will cause http_protocol.c to stop trying to
- * talk to the client, but otherwise allows the code to continue normally.
- * hard_timeout(), by contrast, logs the request, and then aborts it
- * completely --- longjmp()ing out to the accept() loop in http_main.
- * Any resources tied into the request's resource pool will be cleaned up;
- * everything that isn't will leak.
- *
- * soft_timeout() is recommended as a general rule, because it gives your
- * code a chance to clean up. However, hard_timeout() may be the most
- * convenient way of dealing with timeouts waiting for some external
- * resource other than the client, if you can live with the restrictions.
- *
- * (When a hard timeout is in scope, critical sections can be guarded
- * with block_alarms() and unblock_alarms() --- these are declared in
- * alloc.c because they are most often used in conjunction with
- * routines to allocate something or other, to make sure that the
- * cleanup does get registered before any alarm is allowed to happen
- * which might require it to be cleaned up; they * are, however,
- * implemented in http_main.c).
- *
- * kill_timeout() will disarm either variety of timeout.
- *
- * reset_timeout() resets the timeout in progress.
- */
-
-void hard_timeout (char *, request_rec *);
-void keepalive_timeout (char *, request_rec *);
-void soft_timeout (char *, request_rec *);
-void kill_timeout (request_rec *);
-void reset_timeout (request_rec *);
-
-void sync_scoreboard_image ();
-int update_child_status (int child_num, int status, request_rec *r);
-int get_child_status (int child_num);
-int count_busy_servers ();
-int count_idle_servers ();
-
diff --git a/usr.sbin/httpd/src/http_protocol.c b/usr.sbin/httpd/src/http_protocol.c
deleted file mode 100644
index f34097260c1..00000000000
--- a/usr.sbin/httpd/src/http_protocol.c
+++ /dev/null
@@ -1,2047 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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_protocol.c --- routines which directly communicate with the client.
- *
- * Code originally by Rob McCool; much redone by Robert S. Thau
- * and the Apache Group.
- */
-
-#define CORE_PRIVATE
-#include "httpd.h"
-#include "http_config.h"
-#include "http_core.h"
-#include "http_protocol.h"
-#include "http_main.h"
-#include "http_log.h" /* For errors detected in basic auth
- * common support code...
- */
-#include "util_date.h" /* For parseHTTPdate and BAD_DATE */
-#include <stdarg.h>
-
-#define SET_BYTES_SENT(r) \
- do { if (r->sent_bodyct) \
- bgetopt (r->connection->client, BO_BYTECT, &r->bytes_sent); \
- } while (0)
-
-
-static int parse_byterange (char *range, long clength, long *start, long *end)
-{
- char *dash = strchr(range, '-');
-
- if (!dash)
- return 0;
-
- if ((dash == range)) {
- /* In the form "-5" */
- *start = clength - atol(dash + 1);
- *end = clength - 1;
- }
- else {
- *dash = '\0';
- dash++;
- *start = atol(range);
- if (*dash)
- *end = atol(dash);
- else /* "5-" */
- *end = clength -1;
- }
-
- if (*start > *end)
- return 0;
-
- if (*end >= clength)
- *end = clength - 1;
-
- return 1;
-}
-
-static int internal_byterange(int, long*, request_rec*, char**, long*, long*);
-
-int set_byterange (request_rec *r)
-{
- char *range, *if_range, *match;
- char ts[MAX_STRING_LEN];
- long range_start, range_end;
-
- if (!r->clength || r->assbackwards) return 0;
-
- /* Check for Range request-header (HTTP/1.1) or Request-Range for
- * backwards-compatibility with second-draft Luotonen/Franks
- * byte-ranges (e.g. Netscape Navigator 2-3).
- *
- * We support this form, with Request-Range, and (farther down) we
- * send multipart/x-byteranges instead of multipart/byteranges for
- * Request-Range based requests to work around a bug in Netscape
- * Navigator 2-3 and MSIE 3.
- */
-
- if (!(range = table_get(r->headers_in, "Range")))
- range = table_get(r->headers_in, "Request-Range");
-
- if (!range || strncasecmp(range, "bytes=", 6)) {
- table_set (r->headers_out, "Accept-Ranges", "bytes");
- return 0;
- }
-
- /* Check the If-Range header for Etag or Date */
-
- if ((if_range = table_get(r->headers_in, "If-Range"))) {
- if (if_range[0] == '"') {
- if (!(match = table_get(r->headers_out, "Etag")) ||
- (strcasecmp(if_range, match) != 0))
- return 0;
- }
- else if (!(match = table_get(r->headers_out, "Last-Modified")) ||
- (strcasecmp(if_range, match) != 0))
- return 0;
- }
-
- if (!strchr(range, ',')) {
- /* A single range */
- if (!parse_byterange(pstrdup(r->pool, range + 6), r->clength,
- &range_start, &range_end))
- return 0;
-
- r->byterange = 1;
-
- ap_snprintf(ts, sizeof(ts), "bytes %ld-%ld/%ld",
- range_start, range_end, r->clength);
- table_set(r->headers_out, "Content-Range", ts);
- ap_snprintf(ts, sizeof(ts), "%ld", range_end - range_start + 1);
- table_set(r->headers_out, "Content-Length", ts);
- }
- else {
- /* a multiple range */
- char boundary[33]; /* Long enough */
- char *r_range = pstrdup(r->pool, range + 6);
- long tlength = 0;
-
- r->byterange = 2;
- ap_snprintf(boundary, sizeof(boundary), "%lx%lx",
- r->request_time, (long)getpid());
- r->boundary = pstrdup(r->pool, boundary);
- while (internal_byterange(0, &tlength, r, &r_range, NULL, NULL));
- ap_snprintf(ts, sizeof(ts), "%ld", tlength);
- table_set(r->headers_out, "Content-Length", ts);
- }
-
- r->status = PARTIAL_CONTENT;
- r->range = range + 6;
-
- return 1;
-}
-
-int each_byterange (request_rec *r, long *offset, long *length)
-{
- return internal_byterange(1, NULL, r, &r->range, offset, length);
-}
-
-/* If this function is called with realreq=1, it will spit out
- * the correct headers for a byterange chunk, and set offset and
- * length to the positions they should be.
- *
- * If it is called with realreq=0, it will add to tlength the length
- * it *would* have used with realreq=1.
- *
- * Either case will return 1 if it should be called again, and 0
- * when done.
- *
- */
-
-static int internal_byterange(int realreq, long *tlength, request_rec *r,
- char **r_range, long *offset, long *length)
-{
- long range_start, range_end;
- char *range;
-
- if (!**r_range) {
- if (r->byterange > 1) {
- if (realreq)
- rvputs(r, "\015\012--", r->boundary, "--\015\012", NULL);
- else
- *tlength += 4 + strlen(r->boundary) + 4;
- }
- return 0;
- }
-
- range = getword_nc(r->pool, r_range, ',');
- if (!parse_byterange(range, r->clength, &range_start, &range_end))
- /* Skip this one */
- return internal_byterange(realreq, tlength, r, r_range, offset,
- length);
-
- if (r->byterange > 1) {
- char *ct = r->content_type ? r->content_type : default_type(r);
- char ts[MAX_STRING_LEN];
-
- ap_snprintf(ts, sizeof(ts), "%ld-%ld/%ld", range_start, range_end, r->clength);
- if (realreq)
- rvputs(r, "\015\012--", r->boundary, "\015\012Content-type: ",
- ct, "\015\012Content-range: bytes ", ts, "\015\012\015\012",
- NULL);
- else
- *tlength += 4 + strlen(r->boundary) + 16 + strlen(ct) + 23 +
- strlen(ts) + 4;
- }
-
- if (realreq) {
- *offset = range_start;
- *length = range_end - range_start + 1;
- }
- else {
- *tlength += range_end - range_start + 1;
- }
- return 1;
-}
-
-int set_content_length (request_rec *r, long clength)
-{
- char ts[MAX_STRING_LEN];
-
- r->clength = clength;
-
- ap_snprintf (ts, sizeof(ts), "%ld", clength);
- table_set (r->headers_out, "Content-Length", ts);
-
- return 0;
-}
-
-int set_keepalive(request_rec *r)
-{
- int ka_sent = 0;
- int wimpy = find_token(r->pool,
- table_get(r->headers_out, "Connection"), "close");
- char *conn = table_get(r->headers_in, "Connection");
-
- /* The following convoluted conditional determines whether or not
- * the current connection should remain persistent after this response
- * (a.k.a. HTTP Keep-Alive) and whether or not the output message
- * body should use the HTTP/1.1 chunked transfer-coding. In English,
- *
- * IF we have not marked this connection as errored;
- * and the response body has a defined length due to the status code
- * being 304 or 204, the request method being HEAD, already
- * having defined Content-Length or Transfer-Encoding: chunked, or
- * the request version being HTTP/1.1 and thus capable of being set
- * as chunked [we know the (r->chunked = 1) side-effect is ugly];
- * and the server configuration enables keep-alive;
- * and the server configuration has a reasonable inter-request timeout;
- * and there is no maximum # requests or the max hasn't been reached;
- * and the response status does not require a close;
- * and the response generator has not already indicated close;
- * and the client did not request non-persistence (Connection: close);
- * and we haven't been configured to ignore the buggy twit
- * or they're a buggy twit coming through a HTTP/1.1 proxy
- * and the client is requesting an HTTP/1.0-style keep-alive
- * or the client claims to be HTTP/1.1 compliant (perhaps a proxy);
- * THEN we can be persistent, which requires more headers be output.
- *
- * Note that the condition evaluation order is extremely important.
- */
- if ((r->connection->keepalive != -1) &&
- ((r->status == HTTP_NOT_MODIFIED) ||
- (r->status == HTTP_NO_CONTENT) ||
- r->header_only ||
- table_get(r->headers_out, "Content-Length") ||
- find_last_token(r->pool,
- table_get(r->headers_out, "Transfer-Encoding"),
- "chunked") ||
- ((r->proto_num >= 1001) && (r->chunked = 1))) &&
- r->server->keep_alive &&
- (r->server->keep_alive_timeout > 0) &&
- ((r->server->keep_alive_max == 0) ||
- (r->server->keep_alive_max > r->connection->keepalives)) &&
- !status_drops_connection(r->status) &&
- !wimpy &&
- !find_token(r->pool, conn, "close") &&
- (!table_get(r->subprocess_env, "nokeepalive") ||
- table_get(r->headers_in, "Via")) &&
- ((ka_sent = find_token(r->pool, conn, "keep-alive")) ||
- (r->proto_num >= 1001))
- ) {
- char header[256];
- int left = r->server->keep_alive_max - r->connection->keepalives;
-
- r->connection->keepalive = 1;
- r->connection->keepalives++;
-
- /* If they sent a Keep-Alive token, send one back */
- if (ka_sent) {
- if (r->server->keep_alive_max)
- ap_snprintf(header, sizeof(header), "timeout=%d, max=%d",
- r->server->keep_alive_timeout, left);
- else
- ap_snprintf(header, sizeof(header), "timeout=%d",
- r->server->keep_alive_timeout);
- table_set(r->headers_out, "Keep-Alive", header);
- table_merge(r->headers_out, "Connection", "Keep-Alive");
- }
-
- return 1;
- }
-
- /* Otherwise, we need to indicate that we will be closing this
- * connection immediately after the current response.
- *
- * We only really need to send "close" to HTTP/1.1 clients, but we
- * always send it anyway, because a broken proxy may identify itself
- * as HTTP/1.0, but pass our request along with our HTTP/1.1 tag
- * to a HTTP/1.1 client. Better safe than sorry.
- */
- if (!wimpy)
- table_merge(r->headers_out, "Connection", "close");
-
- r->connection->keepalive = 0;
-
- return 0;
-}
-
-int set_last_modified(request_rec *r, time_t mtime)
-{
- char *etag, weak_etag[MAX_STRING_LEN];
- char *if_match, *if_modified_since, *if_unmodified, *if_nonematch;
- time_t now = time(NULL);
-
- if (now < 0)
- now = r->request_time;
-
- table_set(r->headers_out, "Last-Modified",
- gm_timestr_822(r->pool, (mtime > now) ? now : mtime));
-
- /* Make an ETag header out of various pieces of information. We use
- * the last-modified date and, if we have a real file, the
- * length and inode number - note that this doesn't have to match
- * the content-length (i.e. includes), it just has to be unique
- * for the file.
- *
- * If the request was made within a second of the last-modified date,
- * we send a weak tag instead of a strong one, since it could
- * be modified again later in the second, and the validation
- * would be incorrect.
- */
-
- if (r->finfo.st_mode != 0)
- ap_snprintf(weak_etag, sizeof(weak_etag), "W/\"%lx-%lx-%lx\"",
- (unsigned long)r->finfo.st_ino,
- (unsigned long)r->finfo.st_size, (unsigned long)mtime);
- else
- ap_snprintf(weak_etag, sizeof(weak_etag), "W/\"%lx\"",
- (unsigned long)mtime);
-
- etag = weak_etag + ((r->request_time - mtime > 1) ? 2 : 0);
- table_set(r->headers_out, "ETag", etag);
-
- /* Check for conditional requests --- note that we only want to do
- * this if we are successful so far and we are not processing a
- * subrequest or an ErrorDocument.
- *
- * The order of the checks is important, since etag checks are supposed
- * to be more accurate than checks relative to the modification time.
- */
-
- if (!is_HTTP_SUCCESS(r->status) || r->no_local_copy)
- return OK;
-
- /* If an If-Match request-header field was given and
- * if our ETag does not match any of the entity tags in that field
- * and the field value is not "*" (meaning match anything), then
- * respond with a status of 412 (Precondition Failed).
- */
-
- if ((if_match = table_get(r->headers_in, "If-Match")) != NULL) {
- if ((if_match[0] != '*') && !find_token(r->pool, if_match, etag))
- return HTTP_PRECONDITION_FAILED;
- }
-
- /* Else if a valid If-Unmodified-Since request-header field was given
- * and the requested resource has been modified since the time
- * specified in this field, then the server MUST
- * respond with a status of 412 (Precondition Failed).
- */
-
- else if ((if_unmodified = table_get(r->headers_in, "If-Unmodified-Since"))
- != NULL) {
- time_t ius = parseHTTPdate(if_unmodified);
-
- if ((ius != BAD_DATE) && (mtime > ius))
- return HTTP_PRECONDITION_FAILED;
- }
-
- /* If an If-None-Match request-header field was given and
- * if our ETag matches any of the entity tags in that field or
- * if the field value is "*" (meaning match anything), then
- * if the request method was GET or HEAD, the server SHOULD
- * respond with a 304 (Not Modified) response.
- * For all other request methods, the server MUST
- * respond with a status of 412 (Precondition Failed).
- */
-
- if ((if_nonematch = table_get(r->headers_in, "If-None-Match")) != NULL) {
- if ((if_nonematch[0] == '*') || find_token(r->pool,if_nonematch,etag))
- return (r->method_number == M_GET) ? HTTP_NOT_MODIFIED
- : HTTP_PRECONDITION_FAILED;
- }
-
- /* Else if a valid If-Modified-Since request-header field was given
- * and it is a GET or HEAD request
- * and the requested resource has not been modified since the time
- * specified in this field, then the server MUST
- * respond with a status of 304 (Not Modified).
- * A date later than the server's current request time is invalid.
- */
-
- else if ((r->method_number == M_GET) && ((if_modified_since =
- table_get(r->headers_in, "If-Modified-Since")) != NULL)) {
- time_t ims = parseHTTPdate(if_modified_since);
-
- if ((ims >= mtime) && (ims <= r->request_time))
- return HTTP_NOT_MODIFIED;
- }
-
- return OK;
-}
-
-/* Get a line of protocol input, including any continuation lines
- * caused by MIME folding (or broken clients) if fold != 0, and place it
- * in the buffer s, of size n bytes, without the ending newline.
- *
- * Returns -1 on error, or the length of s.
- *
- * Note: Because bgets uses 1 char for newline and 1 char for NUL,
- * the most we can get is (n - 2) actual characters if it
- * was ended by a newline, or (n - 1) characters if the line
- * length exceeded (n - 1). So, if the result == (n - 1),
- * then the actual input line exceeded the buffer length,
- * and it would be a good idea for the caller to puke 400 or 414.
- */
-static int getline(char *s, int n, BUFF *in, int fold)
-{
- char *pos, next;
- int retval;
- int total = 0;
-
- pos = s;
-
- do {
- retval = bgets(pos, n, in); /* retval == -1 if error, 0 if EOF */
-
- if (retval <= 0)
- return ((retval < 0) && (total == 0)) ? -1 : total;
-
- /* retval is the number of characters read, not including NUL */
-
- n -= retval; /* Keep track of how much of s is full */
- pos += (retval-1); /* and where s ends */
- total += retval; /* and how long s has become */
-
- if (*pos == '\n') { /* Did we get a full line of input? */
- *pos = '\0';
- --total; ++n;
- }
- else return total; /* if not, input line exceeded buffer size */
-
- /* Continue appending if line folding is desired and
- * the last line was not empty and we have room in the buffer and
- * the next line begins with a continuation character.
- */
- } while (fold && (retval != 1) && (n > 1) &&
- (blookc(&next, in) == 1) &&
- ((next == ' ') || (next == '\t')));
-
- return total;
-}
-
-void parse_uri (request_rec *r, const char *uri)
-{
- const char *s;
-
-#ifdef __EMX__
- /* Variable for OS/2 fix below. */
- int loop;
-#endif
-
-/* A proxy request contains a ':' early on, but not as first character */
- for (s=uri; s != '\0'; s++)
- if (!isalnum(*s) && *s != '+' && *s != '-' && *s != '.') break;
-
- if (*s == ':' && s != uri)
- {
- r->proxyreq = 1;
- r->uri = pstrdup(r->pool, uri);
- r->args = NULL;
- }
- else if (r->method && !strcmp(r->method, "TRACE")) {
- r->proxyreq = 0;
- r->uri = pstrdup(r->pool, uri);
- r->args = NULL;
- }
- else {
- r->proxyreq = 0;
- r->uri = getword (r->pool, &uri, '?');
-
-#ifdef __EMX__
- /* Handle path translations for OS/2 and plug security hole. */
- /* This will prevent "http://www.wherever.com/..\..\/" from
- returning a directory for the root drive. */
- for (loop = 0; loop <= strlen(r->uri); ++loop) {
- if (r->uri[loop] == '\\')
- r->uri[loop] = '/';
- };
-
- /* Fix OS/2 HPFS filename case problem. */
- r->uri = strlwr(r->uri);
-#endif
-
- if (*uri) r->args= pstrdup(r->pool, uri);
- else r->args = NULL;
- }
-}
-
-const char *check_fulluri (request_rec *r, const char *uri)
-{
- char *name, *host;
- int i;
- unsigned port;
- server_addr_rec * sar;
-
- /* This routine parses full URLs, if they match the server */
- if (strncasecmp(uri, "http://", 7)) return uri;
- name = pstrdup(r->pool, uri + 7);
-
- /* Find the hostname, assuming a valid request */
- i = ind(name, '/');
- name[i] = '\0';
-
- /* Find the port */
- host = getword_nc(r->pool, &name, ':');
- if (*name) port = atoi(name);
- else port = 80;
-
- /* Make sure ports patch */
- if (port != r->server->port) {
- for (sar = r->server->addrs; sar; sar = sar->next) {
- if( (sar->host_port == 0) || (port == sar->host_port) )
- break;
- }
- if (!sar) return uri;
- }
-
- /* Save it for later use */
- r->hostname = pstrdup(r->pool, host);
- r->hostlen = 7 + i;
-
- /* The easy cases first */
- if (!strcasecmp(host, r->server->server_hostname)) {
- return (uri + r->hostlen);
- }
- else if (!strcmp(host, inet_ntoa(r->connection->local_addr.sin_addr))) {
- return (uri + r->hostlen);
- }
-
- /* Now things get a bit trickier - check the IP address(es) of the host */
- /* they gave, see if it matches ours. */
- else {
- struct hostent *hp;
- int n;
-
- if ((hp = gethostbyname(host))) {
- for (n = 0; hp->h_addr_list[n] != NULL; n++) {
- if (r->connection->local_addr.sin_addr.s_addr ==
- (((struct in_addr *)(hp->h_addr_list[n]))->s_addr)) {
- return (uri + r->hostlen);
- }
- }
- }
- }
-
- return uri;
-}
-
-int read_request_line (request_rec *r)
-{
- char l[HUGE_STRING_LEN];
- const char *ll = l, *uri;
- conn_rec *conn = r->connection;
- int major = 1, minor = 0; /* Assume HTTP/1.0 if non-"HTTP" protocol*/
- int len;
-
- /* Read past empty lines until we get a real request line,
- * a read error, the connection closes (EOF), or we timeout.
- *
- * We skip empty lines because browsers have to tack a CRLF on to the end
- * of POSTs to support old CERN webservers. But note that we may not
- * have flushed any previous response completely to the client yet.
- * We delay the flush as long as possible so that we can improve
- * performance for clients that are pipelining requests. If a request
- * is pipelined then we won't block during the (implicit) read() below.
- * If the requests aren't pipelined, then the client is still waiting
- * for the final buffer flush from us, and we will block in the implicit
- * read(). B_SAFEREAD ensures that the BUFF layer flushes if it will
- * have to block during a read.
- */
- bsetflag( conn->client, B_SAFEREAD, 1 );
- while ((len = getline(l, HUGE_STRING_LEN, conn->client, 0)) <= 0) {
- if ((len < 0) || bgetflag(conn->client, B_EOF)) {
- bsetflag( conn->client, B_SAFEREAD, 0 );
- return 0;
- }
- }
- /* we've probably got something to do, ignore graceful restart requests */
- signal (SIGUSR1, SIG_IGN);
- bsetflag( conn->client, B_SAFEREAD, 0 );
- if (len == (HUGE_STRING_LEN - 1)) {
- log_printf(r->server, "request failed for %s, reason: URI too long",
- get_remote_host(r->connection, r->per_dir_config, REMOTE_NAME));
- r->status = HTTP_REQUEST_URI_TOO_LARGE;
- return 0;
- }
-
- r->request_time = time(NULL);
- r->the_request = pstrdup (r->pool, l);
- r->method = getword_white(r->pool, &ll);
- uri = getword_white(r->pool, &ll);
- uri = check_fulluri(r, uri);
- parse_uri (r, uri);
-
- r->assbackwards = (ll[0] == '\0');
- r->protocol = pstrdup (r->pool, ll[0] ? ll : "HTTP/0.9");
- sscanf(r->protocol, "HTTP/%d.%d", &major, &minor);
- r->proto_num = 1000*major + minor;
-
- return 1;
-}
-
-void get_mime_headers (request_rec *r)
-{
- conn_rec *c = r->connection;
- int len;
- char *value;
- char field[MAX_STRING_LEN];
-
- /* Read header lines until we get the empty separator line,
- * a read error, the connection closes (EOF), or we timeout.
- * Should we also check for overflow (len == MAX_STRING_LEN-1)?
- */
- while ((len = getline(field, MAX_STRING_LEN, c->client, 1)) > 0) {
-
- if (!(value = strchr(field,':'))) /* Find the colon separator */
- continue; /* or should puke 400 here */
-
- *value = '\0';
- ++value;
- while (isspace(*value)) ++value; /* Skip to start of value */
-
- table_merge(r->headers_in, field, value);
- }
-}
-
-#define ADDR_MATCHES(addr1,addr2) \
- (addr1.s_addr == addr2.s_addr) || (addr1.s_addr == htonl(INADDR_ANY)) \
- || (addr1.s_addr == DEFAULT_VHOST_ADDR)
-
-static void check_hostalias (request_rec *r)
-{
- const char *hostname=r->hostname;
- char *host = getword(r->pool, &hostname, ':'); /* Get rid of port */
- unsigned port = (*hostname) ? atoi(hostname) : 80;
- server_rec *s = r->server;
- server_addr_rec * sar;
- int l;
-
-/* make sure the client can't spoof the port;
- * have to check all possiblities to see if the server
- * should be listening. */
- if (port != r->server->port) {
- for (sar = s->addrs; sar; sar = sar->next) {
- if ( (port == sar->host_port) || (sar->host_port == 0) )
- break;
- }
- if (!sar) return;
- }
-
- l = strlen(host)-1;
- if ((host[l]) == '.') {
- host[l] = '\0';
- }
-
- r->hostname = host;
-
- for (s = r->server->next; s; s = s->next) {
- const char *names;
- server_addr_rec *sar;
-
- if (s->addrs == NULL) {
- /* this server has been disabled because of DNS screwups during
- configuration */
- continue;
- }
-/* ok, now there are several possibilities, and we're matching the
- * hostname, the port, and r->connection->local_addr. The last is
- * required so as to only respond on an address to which this vhost
- * should actually be listening.
- *
- * Either we can match s->server_name and s->port while matching
- * against the ip address in a record in the s->addrs list *or* we
- * can match s->server_name and a complete record in the s->addrs
- * list *or* we can match the virtual host name and the address and
- * the port of a record in the s->addrs list.
- */
- if (!strcasecmp(host,s->server_hostname)) { /* ServerName matches hostname */
- if (port == s->port) { /* possibly configured by Port */
- for (sar = s->addrs; sar; sar = sar->next) {
- if (ADDR_MATCHES(sar->host_addr,r->connection->local_addr.sin_addr))
- break; /* SN matches, Port matches, and one IP addr matches */
- }
- } else { /* check to see if an addr matches */
- for (sar = s->addrs; sar; sar = sar->next) {
- if (((port == sar->host_port) || (sar->host_port == 0))
- && (ADDR_MATCHES(sar->host_addr,
- r->connection->local_addr.sin_addr)))
- break; /* SN matches, and a addr matches IP & port */
- }
- }
- if (sar) { /* we got a match */
- r->server = r->connection->server = s;
- if (r->hostlen && !strncasecmp(r->uri, "http://", 7)) {
- r->uri += r->hostlen;
- parse_uri(r, r->uri);
- /* we still might want to do something below (ie. set r->proxyreq) */
- }
- }
- } /* ServerName doesn't match */
-
- /* now s->addrs list, include the names, from the VirtualHost directive */
- for (sar = s->addrs; sar; sar = sar->next) {
- if (((sar->host_port==0) || (port==sar->host_port))
- && (ADDR_MATCHES(sar->host_addr,r->connection->local_addr.sin_addr))
- && !strcasecmp(host,sar->virthost)) {
- /* ok, an element in the addrs list matched all three items */
- r->server = r->connection->server = s;
- if (r->hostlen && !strncasecmp(r->uri, "http://", 7)) {
- r->uri += r->hostlen;
- r->proxyreq = 0;
- }
- }
- }
-
- /* search all the aliases from ServerAlias directive
- * ServerAlias acts like a wildcard, so as to help deal with the
- * transition when the DNS for a given host changes.
- */
- names = s->names;
- if (names) {
- while (*names) {
- char *name = getword_conf (r->pool, &names);
-
- if ((is_matchexp(name) && !strcasecmp_match(host, name)) ||
- (!strcasecmp(host, name))) {
- r->server = r->connection->server = s;
- if (r->hostlen && !strncasecmp(r->uri, "http://", 7)) {
- r->uri += r->hostlen;
- r->proxyreq = 0;
- }
- }
- }
- }
- }
-}
-
-void check_serverpath (request_rec *r)
-{
- server_rec *s;
- server_addr_rec * sar = NULL;
- int port = 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.
- */
-
- for (s = r->server->next; s; s = s->next) {
- /* we should check to make sure that this server should be listening
- * at all.
- *
- * this code is duplicated in check_hostalias, but only one of these
- * two functions runs for a given request.
- */
- if (!s->addrs) continue;
-
- if( (port == s->port) ) {
- for(sar = s->addrs; sar; sar = sar->next) {
- if(ADDR_MATCHES(sar->host_addr, r->connection->local_addr.sin_addr))
- break;
- }
- }
- else {
- for(sar = s->addrs; sar; sar = sar->next) {
- if( ( (port == sar->host_port) || (sar->host_port == 0) )
- && ( ADDR_MATCHES(sar->host_addr,
- r->connection->local_addr.sin_addr) ) )
- break;
- }
- }
-
- if (!sar) continue; /* no match */
-
- 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;
- }
-}
-
-request_rec *read_request (conn_rec *conn)
-{
- request_rec *r = (request_rec *)pcalloc (conn->pool, sizeof(request_rec));
-
- r->connection = conn;
- conn->server = conn->base_server;
- r->server = conn->server;
- r->pool = make_sub_pool(conn->pool);
-
- conn->keptalive = conn->keepalive;
- conn->keepalive = 0;
-
- conn->user = NULL;
- conn->auth_type = NULL;
-
- r->headers_in = make_table (r->pool, 50);
- r->subprocess_env = make_table (r->pool, 50);
- r->headers_out = make_table (r->pool, 5);
- r->err_headers_out = make_table (r->pool, 5);
- r->notes = make_table (r->pool, 5);
-
- r->request_config = create_request_config (r->pool);
- r->per_dir_config = r->server->lookup_defaults; /* For now. */
-
- r->sent_bodyct = 0; /* bytect isn't for body */
-
- r->read_length = 0;
- r->read_body = REQUEST_NO_BODY;
-
- r->status = HTTP_REQUEST_TIME_OUT; /* Until we get a request */
-
- /* Get the request... */
-
- keepalive_timeout("read request line", r);
- if (!read_request_line (r)) {
- kill_timeout(r);
- return NULL;
- }
- if (!r->assbackwards) {
- hard_timeout("read request headers", r);
- get_mime_headers (r);
- }
- kill_timeout(r);
-
- r->status = HTTP_OK; /* Until further notice. */
-
- /* handle Host header here, to get virtual server */
-
- if (r->hostname || (r->hostname = table_get(r->headers_in, "Host")))
- check_hostalias(r);
- else
- check_serverpath(r);
-
- /* we may have switched to another server */
- r->per_dir_config = r->server->lookup_defaults;
-
- conn->keptalive = 0; /* We now have a request to play with */
-
- if(!strcmp(r->method, "HEAD")) {
- r->header_only=1;
- r->method_number = M_GET;
- }
- else if(!strcmp(r->method, "GET"))
- r->method_number = M_GET;
- else if(!strcmp(r->method,"POST"))
- r->method_number = M_POST;
- else if(!strcmp(r->method,"PUT"))
- r->method_number = M_PUT;
- else if(!strcmp(r->method,"DELETE"))
- r->method_number = M_DELETE;
- else if(!strcmp(r->method,"CONNECT"))
- r->method_number = M_CONNECT;
- else if(!strcmp(r->method,"OPTIONS"))
- r->method_number = M_OPTIONS;
- else if(!strcmp(r->method,"TRACE"))
- r->method_number = M_TRACE;
- else
- r->method_number = M_INVALID; /* Will eventually croak. */
-
- return r;
-}
-
-/*
- * A couple of other functions which initialize some of the fields of
- * a request structure, as appropriate for adjuncts of one kind or another
- * to a request in progress. Best here, rather than elsewhere, since
- * *someone* has to set the protocol-specific fields...
- */
-
-void set_sub_req_protocol (request_rec *rnew, const request_rec *r)
-{
- rnew->the_request = r->the_request; /* Keep original request-line */
-
- rnew->assbackwards = 1; /* Don't send headers from this. */
- rnew->no_local_copy = 1; /* Don't try to send USE_LOCAL_COPY for a
- * fragment.
- */
- rnew->method = "GET"; rnew->method_number = M_GET;
- rnew->protocol = "INCLUDED";
-
- rnew->status = HTTP_OK;
-
- rnew->headers_in = r->headers_in;
- rnew->subprocess_env = copy_table (rnew->pool, r->subprocess_env);
- rnew->headers_out = make_table (rnew->pool, 5);
- rnew->err_headers_out = make_table (rnew->pool, 5);
- rnew->notes = make_table (rnew->pool, 5);
-
- rnew->read_length = r->read_length;
- rnew->read_body = REQUEST_NO_BODY;
-
- rnew->main = (request_rec *)r;
-}
-
-void finalize_sub_req_protocol (request_rec *sub)
-{
- SET_BYTES_SENT (sub->main);
-}
-
-/* Support for the Basic authentication protocol, and a bit for Digest.
- */
-
-void note_auth_failure(request_rec *r)
-{
- if (!strcasecmp(auth_type(r), "Basic"))
- note_basic_auth_failure(r);
- else if(!strcasecmp(auth_type(r), "Digest"))
- note_digest_auth_failure(r);
-}
-
-void note_basic_auth_failure(request_rec *r)
-{
- if (strcasecmp(auth_type(r), "Basic"))
- note_auth_failure(r);
- else
- table_set (r->err_headers_out, "WWW-Authenticate",
- pstrcat(r->pool, "Basic realm=\"", auth_name(r), "\"", NULL));
-}
-
-void note_digest_auth_failure(request_rec *r)
-{
- char nonce[256];
-
- ap_snprintf(nonce, sizeof(nonce), "%lu", r->request_time);
- table_set (r->err_headers_out, "WWW-Authenticate",
- pstrcat(r->pool, "Digest realm=\"", auth_name(r),
- "\", nonce=\"", nonce, "\"", NULL));
-}
-
-int get_basic_auth_pw (request_rec *r, char **pw)
-{
- const char *auth_line = table_get (r->headers_in, "Authorization");
- char *t;
-
- if(!(t = auth_type(r)) || strcasecmp(t, "Basic"))
- return DECLINED;
-
- if (!auth_name (r)) {
- log_reason ("need AuthName", r->uri, r);
- return SERVER_ERROR;
- }
-
- if(!auth_line) {
- note_basic_auth_failure (r);
- return AUTH_REQUIRED;
- }
-
- if (strcasecmp(getword (r->pool, &auth_line, ' '), "Basic")) {
- /* Client tried to authenticate using wrong auth scheme */
- log_reason ("client used wrong authentication scheme", r->uri, r);
- note_basic_auth_failure (r);
- return AUTH_REQUIRED;
- }
-
- t = uudecode (r->pool, auth_line);
- r->connection->user = getword_nulls_nc (r->connection->pool, &t, ':');
- r->connection->auth_type = "Basic";
-
- *pw = t;
-
- return OK;
-}
-
-/* New Apache routine to map status codes into array indicies
- * e.g. 100 -> 0, 101 -> 1, 200 -> 2 ...
- * The number of status lines must equal the value of RESPONSE_CODES (httpd.h)
- * and must be listed in order.
- */
-
-static char *status_lines[] = {
- "100 Continue",
- "101 Switching Protocols",
-#define LEVEL_200 2
- "200 OK",
- "201 Created",
- "202 Accepted",
- "203 Non-Authoritative Information",
- "204 No Content",
- "205 Reset Content",
- "206 Partial Content",
-#define LEVEL_300 9
- "300 Multiple Choices",
- "301 Moved Permanently",
- "302 Moved Temporarily",
- "303 See Other",
- "304 Not Modified",
- "305 Use Proxy",
-#define LEVEL_400 15
- "400 Bad Request",
- "401 Authorization Required",
- "402 Payment Required",
- "403 Forbidden",
- "404 File Not Found",
- "405 Method Not Allowed",
- "406 Not Acceptable",
- "407 Proxy Authentication Required",
- "408 Request Time-out",
- "409 Conflict",
- "410 Gone",
- "411 Length Required",
- "412 Precondition Failed",
- "413 Request Entity Too Large",
- "414 Request-URI Too Large",
- "415 Unsupported Media Type",
-#define LEVEL_500 31
- "500 Internal Server Error",
- "501 Method Not Implemented",
- "502 Bad Gateway",
- "503 Service Temporarily Unavailable",
- "504 Gateway Time-out",
- "505 HTTP Version Not Supported",
- "506 Variant Also Varies"
-};
-
-/* The index is found by its offset from the x00 code of each level.
- * Although this is fast, it will need to be replaced if some nutcase
- * decides to define a high-numbered code before the lower numbers.
- * If that sad event occurs, replace the code below with a linear search
- * from status_lines[shortcut[i]] to status_lines[shortcut[i+1]-1];
- */
-
-int index_of_response(int status)
-{
- static int shortcut[6] = { 0, LEVEL_200, LEVEL_300, LEVEL_400,
- LEVEL_500, RESPONSE_CODES };
- int i, pos;
-
- if (status < 100) /* Below 100 is illegal for HTTP status */
- return LEVEL_500;
-
- for (i = 0; i < 5; i++) {
- status -= 100;
- if (status < 100) {
- pos = (status + shortcut[i]);
- if (pos < shortcut[i+1])
- return pos;
- else
- return LEVEL_500; /* status unknown (falls in gap) */
- }
- }
- return LEVEL_500; /* 600 or above is also illegal */
-}
-
-/* Send a single HTTP header field to the client. Note that this function
- * is used in calls to table_do(), so their interfaces are co-dependent.
- * In other words, don't change this one without checking table_do in alloc.c.
- * It returns true unless there was a write error of some kind.
- */
-int send_header_field (request_rec *r, const char *fieldname,
- const char *fieldval)
-{
- return (0 < bvputs(r->connection->client,
- fieldname, ": ", fieldval, "\015\012", NULL));
-}
-
-void basic_http_header (request_rec *r)
-{
- char *protocol;
-
- if (r->assbackwards) return;
-
- if (!r->status_line)
- r->status_line = status_lines[index_of_response(r->status)];
-
- /* mod_proxy is only HTTP/1.0, so avoid sending HTTP/1.1 error response;
- * kluge around broken browsers when indicated by force-response-1.0
- */
- if (r->proxyreq
- || (r->proto_num == 1000
- && table_get(r->subprocess_env,"force-response-1.0"))) {
-
- protocol = "HTTP/1.0";
- r->connection->keepalive = -1;
- }
- else
- protocol = SERVER_PROTOCOL;
-
- /* Output the HTTP/1.x Status-Line and the Date and Server fields */
-
- bvputs(r->connection->client,
- protocol, " ", r->status_line, "\015\012", NULL);
-
- send_header_field(r, "Date", gm_timestr_822(r->pool, r->request_time));
- send_header_field(r, "Server", SERVER_VERSION);
-
- table_unset(r->headers_out, "Date"); /* Avoid bogosity */
- table_unset(r->headers_out, "Server");
-}
-
-/* Navigator versions 2.x, 3.x and 4.0 betas up to and including 4.0b2
- * have a header parsing bug. If the terminating \r\n occur starting
- * at the 256th or 257th byte of output then it will not properly parse
- * the headers. Curiously it doesn't exhibit this problem at 512, 513.
- * We are guessing that this is because their initial read of a new request
- * uses a 256 byte buffer, and subsequent reads use a larger buffer.
- * So the problem might exist at different offsets as well.
- *
- * This should also work on keepalive connections assuming they use the
- * same small buffer for the first read of each new request.
- *
- * At any rate, we check the bytes written so far and, if we are about to
- * tickle the bug, we instead insert a bogus padding header. Since the bug
- * manifests as a broken image in Navigator, users blame the server. :(
- * It is more expensive to check the User-Agent than it is to just add the
- * bytes, so we haven't used the BrowserMatch feature here.
- */
-static void terminate_header (BUFF *client)
-{
- long int bs;
-
- bgetopt(client, BO_BYTECT, &bs);
- if (bs >= 255 && bs <= 257)
- bputs("X-Pad: avoid browser bug\015\012", client);
-
- bputs("\015\012", client); /* Send the terminating empty line */
-}
-
-/* Build the Allow field-value from the request handler method mask.
- * Note that we always allow TRACE, since it is handled below.
- */
-static char *make_allow(request_rec *r)
-{
- return 2 + pstrcat(r->pool,
- (r->allowed & (1 << M_GET)) ? ", GET, HEAD" : "",
- (r->allowed & (1 << M_POST)) ? ", POST" : "",
- (r->allowed & (1 << M_PUT)) ? ", PUT" : "",
- (r->allowed & (1 << M_DELETE)) ? ", DELETE" : "",
- (r->allowed & (1 << M_OPTIONS)) ? ", OPTIONS" : "",
- ", TRACE",
- NULL);
-}
-
-int send_http_trace (request_rec *r)
-{
- int rv;
-
- /* Get the original request */
- while (r->prev) r = r->prev;
-
- if ((rv = setup_client_block(r, REQUEST_NO_BODY)))
- return rv;
-
- hard_timeout("send TRACE", r);
-
- r->content_type = "message/http";
- send_http_header(r);
-
- /* Now we recreate the request, and echo it back */
-
- rvputs( r, r->the_request, "\015\012", NULL );
-
- table_do((int (*)(void *, const char *, const char *))send_header_field,
- (void *)r, r->headers_in, NULL);
- bputs("\015\012", r->connection->client);
-
- kill_timeout(r);
- return OK;
-}
-
-int send_http_options(request_rec *r)
-{
- const long int zero = 0L;
-
- if (r->assbackwards) return DECLINED;
-
- hard_timeout("send OPTIONS", r);
-
- basic_http_header(r);
-
- table_set(r->headers_out, "Content-Length", "0");
- table_set(r->headers_out, "Allow", make_allow(r));
- set_keepalive(r);
-
- table_do((int (*)(void *, const char *, const char *))send_header_field,
- (void *)r, r->headers_out, NULL);
-
- terminate_header(r->connection->client);
-
- kill_timeout(r);
- bsetopt(r->connection->client, BO_BYTECT, &zero);
-
- return OK;
-}
-
-/*
- * Here we try to be compatible with clients that want multipart/x-byteranges
- * instead of multipart/byteranges (also see above), as per HTTP/1.1. We
- * look for the Request-Range header (e.g. Netscape 2 and 3) as an indication
- * that the browser supports an older protocol. We also check User-Agent
- * for Microsoft Internet Explorer 3, which needs this as well.
- */
-
-static int use_range_x(request_rec *r) {
- char *ua;
- return (table_get(r->headers_in, "Request-Range") ||
- ((ua = table_get(r->headers_in, "User-Agent"))
- && strstr(ua, "MSIE 3")));
-}
-
-void send_http_header(request_rec *r)
-{
- int i;
- const long int zero = 0L;
-
- if (r->assbackwards) {
- if(!r->main)
- bsetopt(r->connection->client, BO_BYTECT, &zero);
- r->sent_bodyct = 1;
- return;
- }
-
- /* Now that we are ready to send a response, we need to combine the two
- * header field tables into a single table. If we don't do this, our
- * later attempts to set or unset a given fieldname might be bypassed.
- */
- if (!is_empty_table(r->err_headers_out))
- r->headers_out = overlay_tables(r->pool, r->err_headers_out,
- r->headers_out);
-
- hard_timeout("send headers", r);
-
- basic_http_header(r);
-
- set_keepalive(r);
-
- if (r->chunked) {
- table_merge(r->headers_out, "Transfer-Encoding", "chunked");
- table_unset(r->headers_out, "Content-Length");
- }
-
- if (r->byterange > 1)
- table_set(r->headers_out, "Content-Type",
- pstrcat(r->pool, "multipart", use_range_x(r) ? "/x-" : "/",
- "byteranges; boundary=", r->boundary, NULL));
- else if (r->content_type)
- table_set(r->headers_out, "Content-Type", r->content_type);
- else
- table_set(r->headers_out, "Content-Type", default_type(r));
-
- if (r->content_encoding)
- table_set(r->headers_out, "Content-Encoding", r->content_encoding);
-
- if (r->content_languages && r->content_languages->nelts) {
- for (i = 0; i < r->content_languages->nelts; ++i) {
- table_merge(r->headers_out, "Content-Language",
- ((char**)(r->content_languages->elts))[i]);
- }
- }
- else if (r->content_language)
- table_set(r->headers_out, "Content-Language", r->content_language);
-
- /* Control cachability for non-cachable responses if not already set
- * by some other part of the server configuration.
- */
- if (r->no_cache && !table_get(r->headers_out, "Expires"))
- table_add(r->headers_out, "Expires",
- gm_timestr_822(r->pool, r->request_time));
-
- /* Send the entire table of header fields, terminated by an empty line. */
-
- table_do((int (*)(void *, const char *, const char *))send_header_field,
- (void *)r, r->headers_out, NULL);
-
- terminate_header(r->connection->client);
-
- kill_timeout(r);
-
- bsetopt(r->connection->client, BO_BYTECT, &zero);
- r->sent_bodyct = 1; /* Whatever follows is real body stuff... */
-
- /* Set buffer flags for the body */
- if (r->chunked) bsetflag(r->connection->client, B_CHUNK, 1);
-}
-
-void finalize_request_protocol (request_rec *r)
-{
- /* Turn off chunked encoding */
-
- if (r->chunked && !r->connection->aborted) {
- soft_timeout("send ending chunk", r);
- bsetflag(r->connection->client, B_CHUNK, 0);
- bputs("0\015\012", r->connection->client);
- /* If we had footer "headers", we'd send them now */
- bputs("\015\012", r->connection->client);
- kill_timeout(r);
- }
-}
-
-/* Here we deal with getting the request message body from the client.
- * Whether or not the request contains a body is signaled by the presence
- * of a non-zero Content-Length or by a Transfer-Encoding: chunked.
- *
- * Note that this is more complicated than it was in Apache 1.1 and prior
- * versions, because chunked support means that the module does less.
- *
- * The proper procedure is this:
- *
- * 1. Call setup_client_block() near the beginning of the request
- * handler. This will set up all the necessary properties, and will
- * return either OK, or an error code. If the latter, the module should
- * return that error code. The second parameter selects the policy to
- * apply if the request message indicates a body, and how a chunked
- * transfer-coding should be interpreted. Choose one of
- *
- * REQUEST_NO_BODY Send 413 error if message has any body
- * REQUEST_CHUNKED_ERROR Send 411 error if body without Content-Length
- * REQUEST_CHUNKED_DECHUNK If chunked, remove the chunks for me.
- * REQUEST_CHUNKED_PASS Pass the chunks to me without removal.
- *
- * In order to use the last two options, the caller MUST provide a buffer
- * large enough to hold a chunk-size line, including any extensions.
- *
- * 2. When you are ready to read a body (if any), call should_client_block().
- * This will tell the module whether or not to read input. If it is 0,
- * the module should assume that there is no message body to read.
- * This step also sends a 100 Continue response to HTTP/1.1 clients,
- * so should not be called until the module is *definitely* ready to
- * read content. (otherwise, the point of the 100 response is defeated).
- * Never call this function more than once.
- *
- * 3. Finally, call get_client_block in a loop. Pass it a buffer and its size.
- * It will put data into the buffer (not necessarily a full buffer), and
- * return the length of the input block. When it is done reading, it will
- * return 0 if EOF, or -1 if there was an error.
- * If an error occurs on input, we force an end to keepalive.
- */
-
-int setup_client_block (request_rec *r, int read_policy)
-{
- char *tenc = table_get(r->headers_in, "Transfer-Encoding");
- char *lenp = table_get(r->headers_in, "Content-Length");
-
- r->read_body = read_policy;
- r->read_chunked = 0;
- r->remaining = 0;
-
- if (tenc) {
- if (strcasecmp(tenc, "chunked")) {
- log_printf(r->server, "Unknown Transfer-Encoding %s", tenc);
- return HTTP_BAD_REQUEST;
- }
- if (r->read_body == REQUEST_CHUNKED_ERROR) {
- log_reason("chunked Transfer-Encoding forbidden", r->uri, r);
- return (lenp) ? HTTP_BAD_REQUEST : HTTP_LENGTH_REQUIRED;
- }
-
- r->read_chunked = 1;
- }
- else if (lenp) {
- char *pos = lenp;
-
- while (isdigit(*pos) || isspace(*pos)) ++pos;
- if (*pos != '\0') {
- log_printf(r->server, "Invalid Content-Length %s", lenp);
- return HTTP_BAD_REQUEST;
- }
-
- r->remaining = atol(lenp);
- }
-
- if ((r->read_body == REQUEST_NO_BODY) &&
- (r->read_chunked || (r->remaining > 0))) {
- log_printf(r->server, "%s with body is not allowed for %s",
- r->method, r->uri);
- return HTTP_REQUEST_ENTITY_TOO_LARGE;
- }
-
- return OK;
-}
-
-int should_client_block (request_rec *r)
-{
- /* First check if we have already read the request body */
-
- if (r->read_length || (!r->read_chunked && (r->remaining <= 0)))
- return 0;
-
- if (!r->read_chunked && (r->remaining <= 0))
- return 0;
-
- if (r->proto_num >= 1001) { /* sending 100 Continue interim response */
- bvputs(r->connection->client,
- SERVER_PROTOCOL, " ", status_lines[0], "\015\012\015\012", NULL);
- bflush(r->connection->client);
- }
-
- return 1;
-}
-
-static long get_chunk_size (char *b)
-{
- long chunksize = 0;
-
- while (isxdigit(*b)) {
- int xvalue = 0;
-
- if (*b >= '0' && *b <= '9') xvalue = *b - '0';
- else if (*b >= 'A' && *b <= 'F') xvalue = *b - 'A' + 0xa;
- else if (*b >= 'a' && *b <= 'f') xvalue = *b - 'a' + 0xa;
-
- chunksize = (chunksize << 4) | xvalue;
- ++b;
- }
-
- return chunksize;
-}
-
-/* get_client_block is called in a loop to get the request message body.
- * This is quite simple if the client includes a content-length
- * (the normal case), but gets messy if the body is chunked. Note that
- * r->remaining is used to maintain state across calls and that
- * r->read_length is the total number of bytes given to the caller
- * across all invocations. It is messy because we have to be careful not
- * to read past the data provided by the client, since these reads block.
- * Returns 0 on End-of-body, -1 on error or premature chunk end.
- *
- * Reading the chunked encoding requires a buffer size large enough to
- * hold a chunk-size line, including any extensions. For now, we'll leave
- * that to the caller, at least until we can come up with a better solution.
- */
-long get_client_block (request_rec *r, char *buffer, int bufsiz)
-{
- int c;
- long len_read, len_to_read;
- long chunk_start = 0;
-
- if (!r->read_chunked) { /* Content-length read */
- len_to_read = (r->remaining > bufsiz) ? bufsiz : r->remaining;
- len_read = bread(r->connection->client, buffer, len_to_read);
- if (len_read <= 0) {
- if (len_read < 0) r->connection->keepalive = -1;
- return len_read;
- }
- r->read_length += len_read;
- r->remaining -= len_read;
- return len_read;
- }
-
- /* Handle chunked reading
- * Note: we are careful to shorten the input bufsiz so that there
- * will always be enough space for us to add a CRLF (if necessary).
- */
- if (r->read_body == REQUEST_CHUNKED_PASS)
- bufsiz -= 2;
- if (bufsiz <= 0)
- return -1; /* Cannot read chunked with a small buffer */
-
- if (r->remaining == 0) { /* Start of new chunk */
-
- chunk_start = getline(buffer, bufsiz, r->connection->client, 0);
- if ((chunk_start <= 0) || (chunk_start >= (bufsiz - 1))
- || !isxdigit(*buffer)) {
- r->connection->keepalive = -1;
- return -1;
- }
-
- len_to_read = get_chunk_size(buffer);
-
- if (len_to_read == 0) { /* Last chunk indicated, get footers */
- if (r->read_body == REQUEST_CHUNKED_DECHUNK) {
- get_mime_headers(r);
- ap_snprintf(buffer, bufsiz, "%ld", r->read_length);
- table_unset(r->headers_in, "Transfer-Encoding");
- table_set(r->headers_in, "Content-Length", buffer);
- return 0;
- }
- r->remaining = -1; /* Indicate footers in-progress */
- }
- else {
- r->remaining = len_to_read;
- }
- if (r->read_body == REQUEST_CHUNKED_PASS) {
- buffer[chunk_start++] = CR; /* Restore chunk-size line end */
- buffer[chunk_start++] = LF;
- buffer += chunk_start; /* and pass line on to caller */
- bufsiz -= chunk_start;
- } else {
- /* REQUEST_CHUNKED_DECHUNK -- do not include the length of
- * the header in the return value */
- chunk_start = 0;
- }
- }
- /* When REQUEST_CHUNKED_PASS, we are */
- if (r->remaining == -1) { /* reading footers until empty line */
- len_read = chunk_start;
-
- while ((bufsiz > 1) && ((len_read =
- getline(buffer, bufsiz, r->connection->client, 1)) > 0)) {
-
- if (len_read != (bufsiz - 1)) {
- buffer[len_read++] = CR; /* Restore footer line end */
- buffer[len_read++] = LF;
- }
- chunk_start += len_read;
- buffer += len_read;
- bufsiz -= len_read;
- }
- if (len_read < 0) {
- r->connection->keepalive = -1;
- return -1;
- }
-
- if (len_read == 0) { /* Indicates an empty line */
- buffer[0] = CR;
- buffer[1] = LF;
- chunk_start += 2;
- r->remaining = -2;
- }
- r->read_length += chunk_start;
- return chunk_start;
- }
- /* When REQUEST_CHUNKED_PASS, we */
- if (r->remaining == -2) { /* finished footers when last called */
- r->remaining = 0; /* so now we must signal EOF */
- return 0;
- }
-
- /* Otherwise, we are in the midst of reading a chunk of data */
-
- len_to_read = (r->remaining > bufsiz) ? bufsiz : r->remaining;
-
- len_read = bread(r->connection->client, buffer, len_to_read);
- if (len_read <= 0) {
- r->connection->keepalive = -1;
- return -1;
- }
-
- r->remaining -= len_read;
-
- if (r->remaining == 0) { /* End of chunk, get trailing CRLF */
- if ((c = bgetc(r->connection->client)) == CR) {
- c = bgetc(r->connection->client);
- }
- if (c != LF) {
- r->connection->keepalive = -1;
- return -1;
- }
- if (r->read_body == REQUEST_CHUNKED_PASS) {
- buffer[len_read++] = CR;
- buffer[len_read++] = LF;
- }
- }
- r->read_length += (chunk_start + len_read);
-
- return (chunk_start + len_read);
-}
-
-/* In HTTP/1.1, any method can have a body. However, most GET handlers
- * wouldn't know what to do with a request body if they received one.
- * This helper routine tests for and reads any message body in the request,
- * simply discarding whatever it receives. We need to do this because
- * failing to read the request body would cause it to be interpreted
- * as the next request on a persistent connection.
- *
- * Since we return an error status if the request is malformed, this
- * routine should be called at the beginning of a no-body handler, e.g.,
- *
- * if ((retval = discard_request_body(r)) != OK)
- * return retval;
- */
-int discard_request_body(request_rec *r)
-{
- int rv;
-
- if ((rv = setup_client_block(r, REQUEST_CHUNKED_PASS)))
- return rv;
-
- if (should_client_block(r)) {
- char dumpbuf[HUGE_STRING_LEN];
-
- hard_timeout("reading request body", r);
- while ((rv = get_client_block(r, dumpbuf, HUGE_STRING_LEN)) > 0)
- continue;
- kill_timeout(r);
-
- if (rv < 0)
- return HTTP_BAD_REQUEST;
- }
- return OK;
-}
-
-/*
- * Send the body of a response to the client.
- */
-long send_fd(FILE *f, request_rec *r) { return send_fd_length(f, r, -1); }
-
-long send_fd_length(FILE *f, request_rec *r, long length)
-{
- char buf[IOBUFSIZE];
- long total_bytes_sent = 0;
- register int n, w, o, len;
-
- if (length == 0) return 0;
-
- soft_timeout("send body", r);
-
- while (!r->connection->aborted) {
- if ((length > 0) && (total_bytes_sent + IOBUFSIZE) > length)
- len = length - total_bytes_sent;
- else len = IOBUFSIZE;
-
- while ((n= fread(buf, sizeof(char), len, f)) < 1
- && ferror(f) && errno == EINTR && !r->connection->aborted)
- continue;
-
- if (n < 1) {
- break;
- }
- o=0;
-
- while (n && !r->connection->aborted) {
- w = bwrite(r->connection->client, &buf[o], n);
- if (w > 0) {
- reset_timeout(r); /* reset timeout after successful write */
- total_bytes_sent += w;
- n-=w;
- o+=w;
- }
- else if (w < 0) {
- if (r->connection->aborted)
- break;
- else if (errno == EAGAIN)
- continue;
- else {
- log_unixerr("send body lost connection to",
- get_remote_host(r->connection,
- r->per_dir_config, REMOTE_NAME),
- NULL, r->server);
- bsetflag(r->connection->client, B_EOUT, 1);
- r->connection->aborted = 1;
- break;
- }
- }
- }
- }
-
- kill_timeout(r);
- SET_BYTES_SENT(r);
- return total_bytes_sent;
-}
-
-int rputc (int c, request_rec *r)
-{
- if (r->connection->aborted) return EOF;
- bputc(c, r->connection->client);
- SET_BYTES_SENT(r);
- return c;
-}
-
-int rputs(const char *str, request_rec *r)
-{
- if (r->connection->aborted) return EOF;
- SET_BYTES_SENT(r);
- return bputs(str, r->connection->client);
-}
-
-int rwrite(const void *buf, int nbyte, request_rec *r)
-{
- int n;
- if (r->connection->aborted) return EOF;
- n=bwrite(r->connection->client, buf, nbyte);
- SET_BYTES_SENT(r);
- return n;
-}
-
-int rprintf(request_rec *r,const char *fmt,...)
-{
- va_list vlist;
- int n;
-
- if(r->connection->aborted) return EOF;
- va_start(vlist,fmt);
- n=vbprintf(r->connection->client,fmt,vlist);
- va_end(vlist);
- SET_BYTES_SENT(r);
- return n;
-}
-
-int rvputs(request_rec *r, ...)
-{
- va_list args;
- int i, j, k;
- const char *x;
- BUFF *fb=r->connection->client;
-
- if (r->connection->aborted) return EOF;
-
- va_start (args, r);
- for (k=0;;)
- {
- x = va_arg(args, const char *);
- if (x == NULL) break;
- j = strlen(x);
- i = bwrite(fb, x, j);
- if (i != j)
- {
- va_end(args);
- return -1;
- }
- k += i;
- }
- va_end(args);
-
- SET_BYTES_SENT(r);
- return k;
-}
-
-int rflush (request_rec *r) {
- return bflush(r->connection->client);
-}
-
-/* We should have named this send_canned_response, since it is used for any
- * response that can be generated by the server from the request record.
- * This includes all 204 (no content), 3xx (redirect), 4xx (client error),
- * and 5xx (server error) messages that have not been redirected to another
- * handler via the ErrorDocument feature.
- */
-void send_error_response (request_rec *r, int recursive_error)
-{
- BUFF *fd = r->connection->client;
- int status = r->status;
- int idx = index_of_response (status);
- char *custom_response;
- char *location = pstrdup(r->pool, table_get(r->headers_out, "Location"));
-
- /* We need to special-case the handling of 204 and 304 responses,
- * since they have specific HTTP requirements and do not include a
- * message body. Note that being assbackwards here is not an option.
- */
- if (status == HTTP_NOT_MODIFIED) {
- if (!is_empty_table(r->err_headers_out))
- r->headers_out = overlay_tables(r->pool, r->err_headers_out,
- r->headers_out);
- hard_timeout("send 304", r);
-
- basic_http_header(r);
- set_keepalive(r);
-
- table_do((int (*)(void *, const char *, const char *))send_header_field,
- (void *)r, r->headers_out,
- "Connection",
- "Keep-Alive",
- "ETag",
- "Content-Location",
- "Expires",
- "Cache-Control",
- "Vary",
- "Warning",
- "WWW-Authenticate",
- NULL);
-
- terminate_header(r->connection->client);
-
- kill_timeout(r);
- return;
- }
-
- if (status == HTTP_NO_CONTENT) {
- send_http_header(r);
- finalize_request_protocol(r);
- return;
- }
-
- if (!r->assbackwards) {
- table *tmp = r->headers_out;
-
- /* For all HTTP/1.x responses for which we generate the message,
- * we need to avoid inheriting the "normal status" header fields
- * that may have been set by the request handler before the
- * error or redirect, except for Location on external redirects.
- */
- r->headers_out = r->err_headers_out;
- r->err_headers_out = tmp;
- clear_table(r->err_headers_out);
-
- if (location && *location
- && (is_HTTP_REDIRECT(status) || status == HTTP_CREATED))
- table_set(r->headers_out, "Location", location);
-
- r->content_language = NULL;
- r->content_languages = NULL;
- r->content_encoding = NULL;
- r->clength = 0;
- r->content_type = "text/html";
-
- if ((status == METHOD_NOT_ALLOWED) || (status == NOT_IMPLEMENTED))
- table_set(r->headers_out, "Allow", make_allow(r));
-
- send_http_header(r);
-
- if (r->header_only) {
- finalize_request_protocol(r);
- return;
- }
- }
-
- hard_timeout("send error body", r);
-
- if ((custom_response = response_code_string (r, idx))) {
- /*
- * We have a custom response output. This should only be
- * a text-string to write back. But if the ErrorDocument
- * was a local redirect and the requested resource failed
- * for any reason, the custom_response will still hold the
- * redirect URL. We don't really want to output this URL
- * as a text message, so first check the custom response
- * string to ensure that it is a text-string (using the
- * same test used in die(), i.e. does it start with a
- * "). If it doesn't, we've got a recursive error, so find
- * the original error and output that as well.
- */
- if (custom_response[0] == '\"') {
- bputs(custom_response+1, fd);
- kill_timeout(r);
- finalize_request_protocol(r);
- return;
- }
- /* Redirect failed, so get back the original error
- */
- while (r->prev && (r->prev->status != HTTP_OK))
- r = r->prev;
- }
- {
- char *title = status_lines[idx];
- /* folks decided they didn't want the error code in the H1 text */
-
- char *h1 = 4 + status_lines[idx];
-
- bvputs
- (
- fd,
- "<HTML><HEAD>\n<TITLE>",
- title,
- "</TITLE>\n</HEAD><BODY>\n<H1>",
- h1,
- "</H1>\n",
- NULL
- );
-
- switch (status) {
- case REDIRECT:
- case MOVED:
- bvputs(fd, "The document has moved <A HREF=\"",
- escape_html(r->pool, location), "\">here</A>.<P>\n", NULL);
- break;
- case HTTP_SEE_OTHER:
- bvputs(fd, "The answer to your request is located <A HREF=\"",
- escape_html(r->pool, location), "\">here</A>.<P>\n", NULL);
- break;
- case HTTP_USE_PROXY:
- bvputs(fd, "This resource is only accessible through the proxy\n",
- escape_html(r->pool, location), "<BR>\nYou will need to ",
- "configure your client to use that proxy.<P>\n", NULL);
- break;
- case AUTH_REQUIRED:
- bputs("This server could not verify that you\n", fd);
- bputs("are authorized to access the document you\n", fd);
- bputs("requested. Either you supplied the wrong\n", fd);
- bputs("credentials (e.g., bad password), or your\n", fd);
- bputs("browser doesn't understand how to supply\n", fd);
- bputs("the credentials required.<P>\n", fd);
- break;
- case BAD_REQUEST:
- bputs("Your browser sent a request that\n", fd);
- bputs("this server could not understand.<P>\n", fd);
- break;
- case FORBIDDEN:
- bvputs(fd, "You don't have permission to access ",
- escape_html(r->pool, r->uri), "\non this server.<P>\n",
- NULL);
- break;
- case NOT_FOUND:
- bvputs(fd, "The requested URL ", escape_html(r->pool, r->uri),
- " was not found on this server.<P>\n", NULL);
- break;
- case METHOD_NOT_ALLOWED:
- bvputs(fd, "The requested method ", r->method, " is not allowed "
- "for the URL ", escape_html(r->pool, r->uri),
- ".<P>\n", NULL);
- break;
- case NOT_ACCEPTABLE:
- bvputs(fd,
- "An appropriate representation of the requested resource ",
- escape_html(r->pool, r->uri),
- " could not be found on this server.<P>\n", NULL);
- /* fall through */
- case MULTIPLE_CHOICES:
- {
- char *list;
- if ((list = table_get (r->notes, "variant-list")))
- bputs(list, fd);
- }
- break;
- case LENGTH_REQUIRED:
- bvputs(fd, "A request of the requested method ", r->method,
- " requires a valid Content-length.<P>\n", NULL);
- break;
- case PRECONDITION_FAILED:
- bvputs(fd, "The precondition on the request for the URL ",
- escape_html(r->pool, r->uri), " evaluated to false.<P>\n",
- NULL);
- break;
- case NOT_IMPLEMENTED:
- bvputs(fd, escape_html(r->pool, r->method), " to ",
- escape_html(r->pool, r->uri), " not supported.<P>\n", NULL);
- break;
- case BAD_GATEWAY:
- bputs("The proxy server received an invalid\015\012", fd);
- bputs("response from an upstream server.<P>\015\012", fd);
- break;
- case VARIANT_ALSO_VARIES:
- bvputs(fd, "A variant for the requested entity ",
- escape_html(r->pool, r->uri), " is itself a ",
- "transparently negotiable resource.<P>\n", NULL);
- break;
- case HTTP_REQUEST_TIME_OUT:
- bputs("I'm tired of waiting for your request.\n", fd);
- break;
- case HTTP_GONE:
- bvputs(fd, "The requested resource<BR>",
- escape_html(r->pool, r->uri),
- "<BR>\nis no longer available on this server ",
- "and there is no forwarding address.\n",
- "Please remove all references to this resource.\n", NULL);
- break;
- case HTTP_REQUEST_ENTITY_TOO_LARGE:
- bvputs(fd, "The requested resource<BR>",
- escape_html(r->pool, r->uri), "<BR>\n",
- "does not allow request data with ", r->method,
- " requests, or the amount of data provided in\n",
- "the request exceeds the capacity limit.\n", NULL);
- break;
- case HTTP_REQUEST_URI_TOO_LARGE:
- bputs("The requested URL's length exceeds the capacity\n", fd);
- bputs("limit for this server.\n", fd);
- break;
- case HTTP_UNSUPPORTED_MEDIA_TYPE:
- bputs("The supplied request data is not in a format\n", fd);
- bputs("acceptable for processing by this resource.\n", fd);
- break;
- case HTTP_SERVICE_UNAVAILABLE:
- bputs("The server is temporarily unable to service your\n", fd);
- bputs("request due to maintenance downtime or capacity\n", fd);
- bputs("problems. Please try again later.\n", fd);
- break;
- case HTTP_GATEWAY_TIME_OUT:
- bputs("The proxy server did not receive a timely response\n", fd);
- bputs("from the upstream server.<P>\n", fd);
- break;
- default: /* HTTP_INTERNAL_SERVER_ERROR */
- bputs("The server encountered an internal error or\n", fd);
- bputs("misconfiguration and was unable to complete\n", fd);
- bputs("your request.<P>\n", fd);
- bputs("Please contact the server administrator,\n ", fd);
- bputs(escape_html(r->pool, r->server->server_admin), fd);
- bputs(" and inform them of the time the error occurred,\n", fd);
- bputs("and anything you might have done that may have\n", fd);
- bputs("caused the error.<P>\n", fd);
- break;
- }
-
- if (recursive_error) {
- bvputs(fd, "<P>Additionally, a ",
- status_lines[index_of_response(recursive_error)],
- "\nerror was encountered while trying to use an "
- "ErrorDocument to handle the request.\n", NULL);
- }
- bputs("</BODY></HTML>\n", fd);
- }
- kill_timeout(r);
- finalize_request_protocol(r);
-}
-
-/* Finally, this... it's here to support nph- scripts
- * Now what ever are we going to do about them when HTTP-NG packetization
- * comes along?
- */
-
-void client_to_stdout (conn_rec *c)
-{
- bflush(c->client);
- dup2(c->client->fd, STDOUT_FILENO);
-}
diff --git a/usr.sbin/httpd/src/http_protocol.h b/usr.sbin/httpd/src/http_protocol.h
deleted file mode 100644
index db608c253e9..00000000000
--- a/usr.sbin/httpd/src/http_protocol.h
+++ /dev/null
@@ -1,191 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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/>.
- *
- */
-
-/*
- * Prototypes for routines which either talk directly back to the user,
- * or control the ones that eventually do.
- */
-
-/* Read a request and fill in the fields. */
-
-request_rec *read_request (conn_rec *c);
-
-/* Send a single HTTP header field */
-
-int send_header_field (request_rec *r, const char *fieldname,
- const char *fieldval);
-
-/* Send the Status-Line and header fields for HTTP response */
-
-void send_http_header (request_rec *l);
-
-/* Send the response to special method requests */
-
-int send_http_trace (request_rec *r);
-int send_http_options (request_rec *r);
-
-/* Finish up stuff after a request */
-
-void finalize_request_protocol (request_rec *r);
-
-/* Send error back to client... last arg indicates error status in case
- * we get an error in the process of trying to deal with an ErrorDocument
- * to handle some other error. In that case, we print the default report
- * for the first thing that went wrong, and more briefly report on the
- * problem with the ErrorDocument.
- */
-
-void send_error_response (request_rec *r, int recursive_error);
-
-/* Set last modified header line from the lastmod date of the associated file.
- * Also, set content length.
- *
- * May return an error status, typically USE_LOCAL_COPY (that when the
- * permit_cache argument is set to one).
- */
-
-int set_content_length (request_rec *r, long length);
-int set_keepalive (request_rec *r);
-int set_last_modified (request_rec *r, time_t mtime);
-
-/* Other ways to send stuff at the client. All of these keep track
- * of bytes_sent automatically. This indirection is intended to make
- * it a little more painless to slide things like HTTP-NG packetization
- * underneath the main body of the code later. In the meantime, it lets
- * us centralize a bit of accounting (bytes_sent).
- *
- * These also return the number of bytes written by the call.
- * They should only be called with a timeout registered, for obvious reaasons.
- * (Ditto the send_header stuff).
- */
-
-long send_fd(FILE *f, request_rec *r);
-long send_fd_length(FILE *f, request_rec *r, long length);
-
-/* Hmmm... could macrofy these for now, and maybe forever, though the
- * definitions of the macros would get a whole lot hairier.
- */
-
-int rputc (int c, request_rec *r);
-int rputs(const char *str, request_rec *r);
-int rwrite(const void *buf, int nbyte, request_rec *r);
-int rvputs(request_rec *r, ...);
-int rprintf(request_rec *r,const char *fmt,...);
-int rflush(request_rec *r);
-
-/*
- * Index used in custom_responses array for a specific error code
- * (only use outside protocol.c is in getting them configured).
- */
-
-int index_of_response (int status);
-
-/* Reading a block of data from the client connection (e.g., POST arg) */
-
-int setup_client_block (request_rec *r, int read_policy);
-int should_client_block (request_rec *r);
-long get_client_block (request_rec *r, char *buffer, int bufsiz);
-int discard_request_body (request_rec *r);
-
-/* Sending a byterange */
-
-int set_byterange (request_rec *r);
-int each_byterange (request_rec *r, long *offset, long *length);
-
-/* Finally, this charming little number is here to encapsulate the
- * degree to which nph- scripts completely escape from any discipline
- * the protocol code might care to impose (this as opposed to other
- * scripts, which *partially* escape to the extent that they may try
- * to explicitly set the status line).
- */
-
-void client_to_stdout (conn_rec *c);
-
-
-/* Support for the Basic authentication protocol. Note that there's
- * nothing that prevents these from being in mod_auth.c, except that other
- * modules which wanted to provide their own variants on finding users and
- * passwords for Basic auth (a fairly common request) would then require
- * mod_auth to be loaded or they wouldn't work.
- *
- * get_basic_auth_pw returns 0 (OK) if it set the 'pw' argument (and assured
- * a correct value in r->connection->user); otherwise it returns an error
- * code, either SERVER_ERROR if things are really confused, AUTH_REQUIRED
- * if no authentication at all seemed to be in use, or DECLINED if there
- * was authentication but it wasn't Basic (in which case, the caller should
- * presumably decline as well).
- *
- * note_basic_auth_failure arranges for the right stuff to be scribbled on
- * the HTTP return so that the client knows how to authenticate itself the
- * next time. As does note_digest_auth_failure for Digest auth.
- *
- * note_auth_failure does the same thing, but will call the correct one
- * based on the authentication type in use.
- *
- */
-
-void note_auth_failure(request_rec *r);
-void note_basic_auth_failure(request_rec *r);
-void note_digest_auth_failure(request_rec *r);
-int get_basic_auth_pw (request_rec *r, char **pw);
-
-/*
- * Setting up the protocol fields for subsidiary requests...
- * Also, a wrapup function to keep the internal accounting straight.
- */
-
-void set_sub_req_protocol (request_rec *rnew, const request_rec *r);
-void finalize_sub_req_protocol (request_rec *sub_r);
-
-/* This is also useful for putting sub_reqs and internal_redirects together */
-
-void parse_uri (request_rec *r, const char *uri);
diff --git a/usr.sbin/httpd/src/http_request.c b/usr.sbin/httpd/src/http_request.c
deleted file mode 100644
index 0ffa6ee6386..00000000000
--- a/usr.sbin/httpd/src/http_request.c
+++ /dev/null
@@ -1,1152 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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_request.c: functions to get and process requests
- *
- * Rob McCool 3/21/93
- *
- * Thoroughly revamped by rst for Apache. NB this file reads
- * best from the bottom up.
- *
- */
-
-#define CORE_PRIVATE
-#include "httpd.h"
-#include "http_config.h"
-#include "http_request.h"
-#include "http_core.h"
-#include "http_protocol.h"
-#include "http_log.h"
-#include "http_main.h"
-#include "scoreboard.h"
-
-/*****************************************************************
- *
- * Getting and checking directory configuration. Also checks the
- * FollowSymlinks and FollowSymOwner stuff, since this is really the
- * only place that can happen (barring a new mid_dir_walk callout).
- *
- * We can't do it as an access_checker module function which gets
- * called with the final per_dir_config, since we could have a directory
- * with FollowSymLinks disabled, which contains a symlink to another
- * with a .htaccess file which turns FollowSymLinks back on --- and
- * access in such a case must be denied. So, whatever it is that
- * checks FollowSymLinks needs to know the state of the options as
- * they change, all the way down.
- */
-
-
-/*
- * We don't want people able to serve up pipes, or unix sockets, or other
- * scary things. Note that symlink tests are performed later.
- */
-static int check_safe_file(request_rec *r)
-{
- if (r->finfo.st_mode == 0 /* doesn't exist */
- || S_ISDIR (r->finfo.st_mode)
- || S_ISREG (r->finfo.st_mode)
- || S_ISLNK (r->finfo.st_mode)) {
- return OK;
- }
- log_reason("object is not a file, directory or symlink", r->filename, r);
- return HTTP_FORBIDDEN;
-}
-
-
-int check_symlinks (char *d, int opts)
-{
- struct stat lfi, fi;
- char *lastp;
- int res;
-
-#ifdef __EMX__
- /* OS/2 dosen't have symlinks */
- return OK;
-#else
-
- if (opts & OPT_SYM_LINKS) return OK;
-
- /* Strip trailing '/', if any, off what we're checking; trailing
- * slashes make some systems follow symlinks to directories even in
- * lstat(). After we've done the lstat, put it back. Also, don't
- * bother checking '/' at all...
- *
- * Note that we don't have to worry about multiple slashes here
- * because of no2slash() below...
- */
-
- lastp = d + strlen(d) - 1;
- if (lastp == d) return OK; /* Root directory, '/' */
-
- if (*lastp == '/') *lastp = '\0';
- else lastp = NULL;
-
- res = lstat (d, &lfi);
-
- if (lastp) *lastp = '/';
-
- /* Note that we don't reject accesses to nonexistent files (multiviews
- * or the like may cons up a way to run the transaction anyway)...
- */
-
- if (!(res >= 0) || !S_ISLNK(lfi.st_mode)) return OK;
-
- /* OK, it's a symlink. May still be OK with OPT_SYM_OWNER */
-
- if (!(opts & OPT_SYM_OWNER)) return HTTP_FORBIDDEN;
-
- if (stat (d, &fi) < 0) return HTTP_FORBIDDEN;
-
- return (fi.st_uid == lfi.st_uid) ? OK : HTTP_FORBIDDEN;
-
-#endif
-}
-
-/* Dealing with the file system to get PATH_INFO
- */
-
-int get_path_info(request_rec *r)
-{
- char *cp;
- char *path = r->filename;
- char *end = &path[strlen(path)];
- char *last_cp = NULL;
- int rv;
-
- /* Advance over trailing slashes ... NOT part of filename */
-
- for (cp = end; cp > path && cp[-1] == '/'; --cp)
- continue;
-
- while (cp > path) {
-
- /* See if the pathname ending here exists... */
-
- *cp = '\0';
-
- errno = 0;
- rv = stat(path, &r->finfo);
-
- if (cp != end) *cp = '/';
-
- if (!rv) {
-
- /* Aha! Found something. If it was a directory, we will
- * search contents of that directory for a multi_match, so
- * the PATH_INFO argument starts with the component after that.
- */
-
- if (S_ISDIR(r->finfo.st_mode) && last_cp) {
- r->finfo.st_mode = 0; /* No such file... */
- cp = last_cp;
- }
-
- r->path_info = pstrdup (r->pool, cp);
- *cp = '\0';
- return OK;
- }
-#if defined(ENOENT) && defined(ENOTDIR)
- else if (errno == ENOENT || errno == ENOTDIR) {
-#else
-#error ENOENT || ENOTDIR not defined -- check the comment below this line in the source for details
- /*
- * If ENOENT || ENOTDIR is not defined in one of the your OS's
- * include files, Apache does not know how to check to see why
- * the stat() of the index file failed; there are cases where
- * it can fail even though the file exists. This means
- * that it is possible for someone to get a directory
- * listing of a directory even though there is an index
- * (eg. index.html) file in it. If you do not have a
- * problem with this, delete the above #error line and
- * start the compile again. If you need to do this, please
- * submit a bug report from http://www.apache.org/bug_report.html
- * letting us know that you needed to do this. Please be
- * sure to include the operating system you are using.
- */
-
- else {
-#endif
- last_cp = cp;
-
- while (--cp > path && *cp != '/')
- continue;
-
- while (cp > path && cp[-1] == '/')
- --cp;
- }
-#if defined(ENOENT) && defined(ENOTDIR)
- else {
-#if defined(EACCES)
- if (errno != EACCES)
-#endif
- log_printf(r->server,
- "access to %s failed for %s, reason: stat: %s (errno = %d)",
- r->uri, get_remote_host(r->connection, r->per_dir_config,
- REMOTE_NAME), strerror(errno), errno);
-
- return HTTP_FORBIDDEN;
- }
-#endif /* ENOENT && ENOTDIR */
- }
- return OK;
-}
-
-int directory_walk (request_rec *r)
-{
- core_server_config *sconf = get_module_config (r->server->module_config,
- &core_module);
- array_header *sec_array = copy_array (r->pool, sconf->sec);
- void *per_dir_defaults = r->server->lookup_defaults;
-
- core_dir_config **sec = (core_dir_config **)sec_array->elts;
- int num_sec = sec_array->nelts;
- char *test_filename = pstrdup (r->pool, r->filename);
-
- int num_dirs, res;
- int i;
-
- /* Are we dealing with a file? If not, we can (hopefuly) safely assume
- * we have a handler that doesn't require one, but for safety's sake,
- * and so we have something find_types() can get something out of,
- * fake one. But don't run through the directory entries.
- */
-
- if (test_filename == NULL) {
- r->filename = pstrdup(r->pool, r->uri);
- r->finfo.st_mode = 0; /* Not really a file... */
- r->per_dir_config = per_dir_defaults;
-
- return OK;
- }
-
- /* Go down the directory hierarchy. Where we have to check for symlinks,
- * do so. Where a .htaccess file has permission to override anything,
- * try to find one. If either of these things fails, we could poke
- * around, see why, and adjust the lookup_rec accordingly --- this might
- * save us a call to get_path_info (with the attendant stat()s); however,
- * for the moment, that's not worth the trouble.
- */
-
-#ifdef __EMX__
- /* Add OS/2 drive name support */
- if ((test_filename[0] != '/') && (test_filename[1] != ':'))
-#else
- if (test_filename[0] != '/')
-#endif
- {
-/* fake filenames only match Directory sections */
- void *this_conf, *entry_config;
- core_dir_config *entry_core;
- char *entry_dir;
- int j;
-
- for (j = 0; j < num_sec; ++j) {
-
- entry_config = sec[j];
- if (!entry_config) continue;
-
- entry_core =(core_dir_config *)
- get_module_config(entry_config, &core_module);
- entry_dir = entry_core->d;
-
- this_conf = NULL;
- if (entry_core->r) {
- if (!regexec(entry_core->r, test_filename, 0, NULL, 0))
- this_conf = entry_config;
- }
- else if (entry_core->d_is_matchexp) {
- if (!strcmp_match(test_filename, entry_dir))
- this_conf = entry_config;
- }
- else if (!strncmp (test_filename, entry_dir, strlen(entry_dir)))
- this_conf = entry_config;
-
- if (this_conf)
- per_dir_defaults = merge_per_dir_configs (r->pool,
- per_dir_defaults, this_conf);
- }
-
- r->per_dir_config = per_dir_defaults;
-
- return OK;
- }
-
- no2slash (test_filename);
- num_dirs = count_dirs(test_filename);
-
- res = get_path_info (r);
- if (res != OK) {
- return res;
- }
-
- if ((res = check_safe_file(r))) {
- return res;
- }
-
- if (test_filename[strlen(test_filename)-1] == '/')
- --num_dirs;
-
- if (S_ISDIR (r->finfo.st_mode)) {
- ++num_dirs;
- }
-
- for (i = 1; i <= num_dirs; ++i) {
- core_dir_config *core_dir =
- (core_dir_config *)get_module_config(per_dir_defaults, &core_module);
- int overrides_here;
- void *this_conf, *htaccess_conf = NULL;
- char *this_dir = make_dirstr (r->pool, test_filename, i);
- int j;
-
- /* Do symlink checks first, because they are done with the
- * permissions appropriate to the *parent* directory...
- */
-
- if ((res = check_symlinks (this_dir, core_dir->opts)))
- {
- log_reason("Symbolic link not allowed", this_dir, r);
- return res;
- }
-
- /* Begin *this* level by looking for matching <Directory> sections from
- * access.conf.
- */
-
- for (j = 0; j < num_sec; ++j) {
- void *entry_config = sec[j];
- core_dir_config *entry_core;
- char *entry_dir;
-
- if (!entry_config) continue;
-
- entry_core =
- (core_dir_config *)get_module_config(entry_config, &core_module);
- entry_dir = entry_core->d;
-
- this_conf = NULL;
- if (entry_core->r) {
- if (!regexec(entry_core->r, this_dir, 0, NULL,
- (j == num_sec) ? 0 : REG_NOTEOL)) {
- /* Don't try this wildcard again --- if it ends in '*'
- * it'll match again, and subdirectories won't be able to
- * override it...
- */
- sec[j] = NULL;
- this_conf = entry_config;
- }
- }
- else if (entry_core->d_is_matchexp &&
- !strcmp_match(this_dir, entry_dir)) {
- sec[j] = NULL;
- this_conf = entry_config;
- }
- else if (!strcmp (this_dir, entry_dir))
- this_conf = entry_config;
-
- if (this_conf) {
- per_dir_defaults =
- merge_per_dir_configs (r->pool, per_dir_defaults, this_conf);
- core_dir =(core_dir_config *)get_module_config(per_dir_defaults,
- &core_module);
- }
-
- }
-
- overrides_here = core_dir->override;
-
- /* If .htaccess files are enabled, check for one.
- */
-
- if (overrides_here) {
- char *config_name = make_full_path(r->pool, this_dir,
- sconf->access_name);
- res = parse_htaccess (&htaccess_conf, r, overrides_here,
- this_dir, config_name);
- if (res) return res;
- }
-
- if (htaccess_conf)
- per_dir_defaults =
- merge_per_dir_configs (r->pool, per_dir_defaults,
- htaccess_conf);
-
- }
-
- r->per_dir_config = per_dir_defaults;
-
- /* Symlink permissions are determined by the parent. If the request is for
- * a directory then applying the symlink test here would use the
- * permissions of the directory as opposed to its parent. Consider a
- * symlink pointing to a dir with a .htaccess disallowing symlinks. If you
- * access /symlink (or /symlink/) you would get a 403 without this S_ISDIR
- * test. But if you accessed /symlink/index.html, for example, you would
- * *not* get the 403.
- */
- if (!S_ISDIR (r->finfo.st_mode)
- && (res = check_symlinks (r->filename, allow_options(r)))) {
- log_reason("Symbolic link not allowed", r->filename, r);
- return res;
- }
-
- return OK; /* Can only "fail" if access denied
- * by the symlink goop.
- */
-}
-
-int location_walk (request_rec *r)
-{
- core_server_config *sconf = get_module_config (r->server->module_config,
- &core_module);
- array_header *url_array = copy_array (r->pool, sconf->sec_url);
- void *per_dir_defaults = r->per_dir_config;
-
- core_dir_config **url = (core_dir_config **)url_array->elts;
- int len, num_url = url_array->nelts;
- char *test_location = pstrdup (r->pool, r->uri);
-
- /* Collapse multiple slashes, if it's a path URL (we don't want to
- * do anything to <Location http://...> or such).
- */
- if (test_location[0] == '/')
- no2slash (test_location);
-
- /* Go through the location entries, and check for matches. */
-
- if (num_url) {
- void *this_conf, *entry_config;
- core_dir_config *entry_core;
- char *entry_url;
- int j;
-
-/*
- * we apply the directive sections in some order; should really try them
- * with the most general first.
- */
- for (j = 0; j < num_url; ++j) {
-
- entry_config = url[j];
- if (!entry_config) continue;
-
- entry_core =(core_dir_config *)
- get_module_config(entry_config, &core_module);
- entry_url = entry_core->d;
-
- len = strlen(entry_url);
-
- this_conf = NULL;
-
- if (entry_core->r) {
- if (!regexec(entry_core->r, test_location, 0, NULL, 0))
- this_conf = entry_config;
- }
- else if( entry_core->d_is_matchexp ) {
- if (!strcmp_match(test_location, entry_url))
- this_conf = entry_config;
- }
- else if (!strncmp (test_location, entry_url, len) &&
- (entry_url[len - 1] == '/' ||
- test_location[len] == '/' || test_location[len] == '\0'))
- this_conf = entry_config;
-
- if (this_conf)
- per_dir_defaults = merge_per_dir_configs (r->pool,
- per_dir_defaults, this_conf);
- }
-
- r->per_dir_config = per_dir_defaults;
- }
-
- return OK;
-}
-
-int file_walk (request_rec *r)
-{
- core_dir_config *conf = get_module_config(r->per_dir_config, &core_module);
- array_header *file_array = copy_array (r->pool, conf->sec);
- void *per_dir_defaults = r->per_dir_config;
-
- core_dir_config **file = (core_dir_config **)file_array->elts;
- int len, num_files = file_array->nelts;
- char *test_file = pstrdup (r->pool, r->filename);
-
- /* Collapse multiple slashes */
- no2slash (test_file);
-
- /* Go through the file entries, and check for matches. */
-
- if (num_files) {
- void *this_conf, *entry_config;
- core_dir_config *entry_core;
- char *entry_file;
- int j;
-
-/*
- * we apply the directive sections in some order; should really try them
- * with the most general first.
- */
- for (j = 0; j < num_files; ++j) {
-
- entry_config = file[j];
- if (!entry_config) continue;
-
- entry_core =(core_dir_config *)
- get_module_config(entry_config, &core_module);
- entry_file = entry_core->d;
-
- len = strlen(entry_file);
-
- this_conf = NULL;
-
- if (entry_core->r) {
- if (!regexec(entry_core->r, test_file, 0, NULL, 0))
- this_conf = entry_config;
- }
- else if ( entry_core->d_is_matchexp ) {
- if (!strcmp_match(test_file, entry_file))
- this_conf = entry_config;
- }
- else if (!strncmp (test_file, entry_file, len) &&
- (entry_file[len - 1] == '/' ||
- test_file[len] == '/' || test_file[len] == '\0'))
- this_conf = entry_config;
-
- if (this_conf)
- per_dir_defaults = merge_per_dir_configs (r->pool,
- per_dir_defaults, this_conf);
- }
-
- r->per_dir_config = per_dir_defaults;
- }
-
- return OK;
-}
-
-/*****************************************************************
- *
- * The sub_request mechanism.
- *
- * Fns to look up a relative URI from, e.g., a map file or SSI document.
- * These do all access checks, etc., but don't actually run the transaction
- * ... use run_sub_req below for that. Also, be sure to use destroy_sub_req
- * as appropriate if you're likely to be creating more than a few of these.
- * (An early Apache version didn't destroy the sub_reqs used in directory
- * indexing. The result, when indexing a directory with 800-odd files in
- * it, was massively excessive storage allocation).
- *
- * Note more manipulation of protocol-specific vars in the request
- * structure...
- */
-
-request_rec *make_sub_request (const request_rec *r)
-{
- pool *rrp = make_sub_pool (r->pool);
- request_rec *rr = pcalloc (rrp, sizeof (request_rec));
-
- rr->pool = rrp;
- return rr;
-}
-
-
-request_rec *sub_req_lookup_uri (const char *new_file, const request_rec *r)
-{
- request_rec *rnew;
- int res;
- char *udir;
-
- rnew = make_sub_request (r);
- rnew->request_time = r->request_time;
- rnew->connection = r->connection;
- rnew->server = r->server;
- rnew->request_config = create_request_config (rnew->pool);
- rnew->htaccess = r->htaccess; /* copy htaccess cache */
- rnew->per_dir_config=r->server->lookup_defaults;
- set_sub_req_protocol (rnew, r);
-
- if (new_file[0] == '/')
- parse_uri(rnew, new_file);
- else
- {
- udir = make_dirstr (rnew->pool, r->uri, count_dirs (r->uri));
- udir = escape_uri(rnew->pool, udir); /* re-escape it */
- parse_uri (rnew, make_full_path (rnew->pool, udir, new_file));
- }
-
- res = unescape_url (rnew->uri);
- if (res)
- {
- rnew->status = res;
- return rnew;
- }
-
- getparents (rnew->uri);
-
- if ((res = location_walk (rnew))) {
- rnew->status=res;
- return rnew;
- }
-
- res = translate_name(rnew);
- if (res)
- {
- rnew->status = res;
- return rnew;
- }
-
- /* We could be clever at this point, and avoid calling directory_walk, etc.
- * However, we'd need to test that the old and new filenames contain the
- * same directory components, so it would require duplicating the start
- * of translate_name.
- * Instead we rely on the cache of .htaccess results.
- */
- /* NB: directory_walk() clears the per_dir_config, so we don't inherit from
- location_walk() above */
-
- if ((res = directory_walk (rnew))
- || (res = file_walk (rnew))
- || (res = location_walk (rnew))
- || ((satisfies(rnew)==SATISFY_ALL || satisfies(rnew)==SATISFY_NOSPEC)?
- ((res = check_access (rnew))
- || (some_auth_required (rnew) &&
- ((res = check_user_id (rnew)) || (res = check_auth (rnew))))):
- ((res = check_access (rnew))
- && (!some_auth_required (rnew) ||
- ((res = check_user_id (rnew)) || (res = check_auth (rnew)))))
- )
- || (res = find_types (rnew))
- || (res = run_fixups (rnew))
- )
- {
- rnew->status = res;
- }
-
- return rnew;
-}
-
-request_rec *sub_req_lookup_file (const char *new_file, const request_rec *r)
-{
- request_rec *rnew;
- int res;
- char *fdir;
-
- rnew = make_sub_request (r);
- rnew->request_time = r->request_time;
- rnew->connection = r->connection; /* For now... */
- rnew->server = r->server;
- rnew->request_config = create_request_config (rnew->pool);
- rnew->htaccess = r->htaccess; /* copy htaccess cache */
- set_sub_req_protocol (rnew, r);
- fdir = make_dirstr (rnew->pool, r->filename, count_dirs (r->filename));
-
- /* Check for a special case... if there are no '/' characters in new_file
- * at all, then we are looking at a relative lookup in the same directory.
- * That means we won't have to redo directory_walk, and we may not
- * even have to redo access checks.
- */
-
- if (strchr (new_file, '/') == NULL) {
- char *udir = make_dirstr(rnew->pool, r->uri, count_dirs(r->uri));
-
- rnew->uri = make_full_path (rnew->pool, udir, new_file);
- rnew->filename = make_full_path (rnew->pool, fdir, new_file);
- if (stat (rnew->filename, &rnew->finfo) < 0) {
- rnew->finfo.st_mode = 0;
- }
-
- if ((res = check_safe_file(rnew))) {
- rnew->status = res;
- return rnew;
- }
-
- rnew->per_dir_config = r->per_dir_config;
-
- /* no matter what, if it's a subdirectory, we need to re-run
- * directory_walk */
- if (S_ISDIR (rnew->finfo.st_mode)) {
- res = directory_walk (rnew);
- if (!res) {
- res = file_walk (rnew);
- }
- } else {
- if ((res = check_symlinks (rnew->filename, allow_options (rnew)))) {
- log_reason ("Symbolic link not allowed", rnew->filename, rnew);
- rnew->status = res;
- return rnew;
- }
- /* do a file_walk, if it doesn't change the per_dir_config then
- * we know that we don't have to redo all the access checks */
- if ((res = file_walk (rnew))) {
- rnew->status = res;
- return rnew;
- }
- if (rnew->per_dir_config == r->per_dir_config) {
- if ((res = find_types (rnew)) || (res = run_fixups (rnew))) {
- rnew->status = res;
- }
- return rnew;
- }
- }
- } else {
- /* XXX: this should be set properly like it is in the same-dir case
- * but it's actually sometimes to impossible to do it... because the
- * file may not have a uri associated with it -djg */
- rnew->uri = "INTERNALLY GENERATED file-relative req";
- rnew->filename = ((new_file[0] == '/') ?
- pstrdup(rnew->pool,new_file) :
- make_full_path (rnew->pool, fdir, new_file));
- rnew->per_dir_config = r->server->lookup_defaults;
- res = directory_walk (rnew);
- if (!res) {
- res = file_walk (rnew);
- }
- }
-
- if (res
- || ((satisfies(rnew)==SATISFY_ALL || satisfies(rnew)==SATISFY_NOSPEC)?
- ((res = check_access (rnew))
- || (some_auth_required (rnew) &&
- ((res = check_user_id (rnew)) || (res = check_auth (rnew))))):
- ((res = check_access (rnew))
- && (!some_auth_required (rnew) ||
- ((res = check_user_id (rnew)) || (res = check_auth (rnew)))))
- )
- || (res = find_types (rnew))
- || (res = run_fixups (rnew))
- )
- {
- rnew->status = res;
- }
-
- return rnew;
-}
-
-int run_sub_req (request_rec *r)
-{
- int retval = invoke_handler (r);
- finalize_sub_req_protocol (r);
- return retval;
-}
-
-void destroy_sub_req (request_rec *r)
-{
- /* Reclaim the space */
- destroy_pool (r->pool);
-}
-
-/*****************************************************************
- *
- * Mainline request processing...
- */
-
-void die(int type, request_rec *r)
-{
- int error_index = index_of_response (type);
- char *custom_response = response_code_string(r, error_index);
- int recursive_error = 0;
-
- /* The following takes care of Apache redirects to custom response URLs
- * Note that if we are already dealing with the response to some other
- * error condition, we just report on the original error, and give up on
- * any attempt to handle the other thing "intelligently"...
- */
-
- if (r->status != HTTP_OK) {
- recursive_error = type;
-
- while (r->prev && (r->prev->status != HTTP_OK))
- r = r->prev; /* Get back to original error */
-
- type = r->status;
- custom_response = NULL; /* Do NOT retry the custom thing! */
- }
-
- r->status = type;
-
- /*
- * If we want to keep the connection, be sure that the request body
- * (if any) has been read.
- */
- if ((r->status != HTTP_NOT_MODIFIED) && (r->status != HTTP_NO_CONTENT)
- && !status_drops_connection(r->status)
- && r->connection && (r->connection->keepalive != -1)) {
- (void) discard_request_body(r);
- }
-
- /* Two types of custom redirects --- plain text, and URLs.
- * Plain text has a leading '"', so the URL code, here, is triggered
- * on its absence
- */
-
- if (custom_response && custom_response[0] != '"') {
-
- if (is_url(custom_response)) {
- /* The URL isn't local, so lets drop through the rest of
- * this apache code, and continue with the usual REDIRECT
- * handler. But note that the client will ultimately see
- * the wrong status...
- */
- r->status = REDIRECT;
- table_set (r->headers_out, "Location", custom_response);
- } else if ( custom_response[0] == '/') {
- r->no_local_copy = 1; /* Do NOT send USE_LOCAL_COPY for
- * error documents!
- */
- /* This redirect needs to be a GET no matter what the original
- * method was.
- */
- table_set(r->subprocess_env, "REQUEST_METHOD", r->method);
- r->method = pstrdup(r->pool, "GET");
- r->method_number = M_GET;
- internal_redirect (custom_response, r);
- return;
- } else {
- /* Dumb user has given us a bad url to redirect to
- * --- fake up dying with a recursive server error...
- */
- recursive_error = SERVER_ERROR;
- log_reason("Invalid error redirection directive", custom_response,
- r);
- }
- }
-
- send_error_response (r, recursive_error);
-}
-
-static void decl_die (int status, char *phase, request_rec *r)
-{
- if (status == DECLINED) {
- log_reason (pstrcat (r->pool,
- "configuration error: couldn't ",
- phase, NULL),
- r->uri,
- r);
- die (SERVER_ERROR, r);
- }
- else die (status, r);
-}
-
-int some_auth_required (request_rec *r)
-{
- /* Is there a require line configured for the type of *this* req? */
-
- array_header *reqs_arr = requires (r);
- require_line *reqs;
- int i;
-
- if (!reqs_arr) return 0;
-
- reqs = (require_line *)reqs_arr->elts;
-
- for (i = 0; i < reqs_arr->nelts; ++i)
- if (reqs[i].method_mask & (1 << r->method_number))
- return 1;
-
- return 0;
-}
-
-void process_request_internal (request_rec *r)
-{
- int access_status;
-
- /* Kludge to be reading the assbackwards field outside of protocol.c,
- * but we've got to check for this sort of nonsense somewhere...
- */
-
- if (r->assbackwards && r->header_only) {
- /* Client asked for headers only with HTTP/0.9, which doesn't
- * send headers! Have to dink things even to make sure the
- * error message comes through...
- */
- log_reason ("client sent illegal HTTP/0.9 request", r->uri, r);
- r->header_only = 0;
- die (BAD_REQUEST, r);
- return;
- }
-
- if ((!r->hostname && (r->proto_num >= 1001)) ||
- ((r->proto_num == 1001) && !table_get(r->headers_in, "Host"))) {
- /* Client sent us a HTTP/1.1 or later request without telling
- * us the hostname, either with a full URL or a Host: header.
- * We therefore need to (as per the 1.1 spec) send an error.
- * As a special case, HTTP/1.1 mentions twice (S9, S14.23)
- * that a request MUST contain a Host: header, and the server
- * MUST respond with 400 if it doesn't.
- */
- log_reason ("client sent HTTP/1.1 request without hostname (see RFC2068 sections 9 and 14.23)",
- r->uri, r);
- die (BAD_REQUEST, r);
- return;
- }
-
- if (!r->proxyreq)
- {
- /* We don't want TRACE to run through the normal handler set,
- * we handle it specially.
- */
- if (r->method_number == M_TRACE) {
- if ((access_status = send_http_trace(r)))
- die(access_status, r);
- else
- finalize_request_protocol(r);
- return;
- }
-
- access_status = unescape_url(r->uri);
- if (access_status)
- {
- die(access_status, r);
- return;
- }
-
- getparents(r->uri); /* OK --- shrinking transformations... */
- }
-
- if ((access_status = location_walk (r))) {
- die (access_status, r);
- return;
- }
-
- if ((access_status = translate_name (r))) {
- decl_die (access_status, "translate", r);
- return;
- }
-
- if (r->proto_num > 1000 && table_get (r->subprocess_env, "downgrade-1.0")) {
- r->proto_num = 1000;
- }
-
- /* NB: directory_walk() clears the per_dir_config, so we don't inherit from
- location_walk() above */
-
- if ((access_status = directory_walk (r))) {
- die (access_status, r);
- return;
- }
-
- if ((access_status = file_walk (r))) {
- die (access_status, r);
- return;
- }
-
- if ((access_status = location_walk (r))) {
- die (access_status, r);
- return;
- }
-
- if ((access_status = header_parse (r))) {
- die (access_status, r);
- return;
- }
-
- switch (satisfies(r)) {
- case SATISFY_ALL: case SATISFY_NOSPEC:
- if ((access_status = check_access (r)) != 0) {
- decl_die (access_status, "check access", r);
- return;
- }
- if (some_auth_required (r)) {
- if ((access_status = check_user_id (r)) != 0) {
- decl_die (access_status, "check user. No user file?", r);
- return;
- }
- if ((access_status = check_auth (r)) != 0) {
- decl_die (access_status, "check access. No groups file?", r);
- return;
- }
- }
- break;
- case SATISFY_ANY:
- if ((access_status = check_access (r)) != 0) {
- if (!some_auth_required (r)) {
- decl_die (access_status, "check access", r);
- return;
- }
- if ((access_status = check_user_id (r)) != 0) {
- decl_die (access_status, "check user. No user file?", r);
- return;
- }
- if ((access_status = check_auth (r)) != 0) {
- decl_die (access_status, "check access. No groups file?", r);
- return;
- }
- }
- break;
- }
-
- if ((access_status = find_types (r)) != 0) {
- decl_die (access_status, "find types", r);
- return;
- }
-
- if ((access_status = run_fixups (r)) != 0) {
- die (access_status, r);
- return;
- }
-
- if ((access_status = invoke_handler (r)) != 0) {
- die (access_status, r);
- return;
- }
-
- /* Take care of little things that need to happen when we're done */
- finalize_request_protocol (r);
-}
-
-void process_request (request_rec *r)
-{
-#ifdef STATUS
- int old_stat;
-#endif /* STATUS */
- process_request_internal (r);
-#ifdef STATUS
- old_stat = update_child_status (r->connection->child_num, SERVER_BUSY_LOG,
- r);
-#endif /* STATUS */
- log_transaction (r);
-#ifdef STATUS
- (void)update_child_status (r->connection->child_num, old_stat, r);
-#endif /* STATUS */
-}
-
-table *rename_original_env (pool *p, table *t)
-{
- array_header *env_arr = table_elts (t);
- table_entry *elts = (table_entry *)env_arr->elts;
- table *new = make_table (p, env_arr->nelts);
- int i;
-
- for (i = 0; i < env_arr->nelts; ++i) {
- if (!elts[i].key) continue;
- table_set (new, pstrcat (p, "REDIRECT_", elts[i].key, NULL),
- elts[i].val);
- }
-
- return new;
-}
-
-request_rec *internal_internal_redirect (const char *new_uri, request_rec *r)
-{
- request_rec *new = (request_rec *)pcalloc(r->pool, sizeof(request_rec));
- char t[256]; /* Long enough... */
-
- new->connection = r->connection;
- new->server = r->server;
- new->pool = r->pool;
-
- /* A whole lot of this really ought to be shared with protocol.c...
- * another missing cleanup. It's particularly inappropriate to be
- * setting header_only, etc., here.
- */
-
- parse_uri (new, new_uri);
- new->request_config = create_request_config (r->pool);
- new->per_dir_config = r->server->lookup_defaults;
-
- new->prev = r;
- r->next = new;
-
- /* Inherit the rest of the protocol info... */
-
- new->the_request = r->the_request;
-
- new->method = r->method;
- new->method_number = r->method_number;
- new->allowed = r->allowed;
-
- new->status = r->status;
- new->assbackwards = r->assbackwards;
- new->header_only = r->header_only;
- new->protocol = r->protocol;
- new->proto_num = r->proto_num;
- new->hostname = r->hostname;
- new->hostlen = r->hostlen;
- new->request_time = r->request_time;
- new->main = r->main;
-
- new->headers_in = r->headers_in;
- new->headers_out = make_table (r->pool, 5);
- new->err_headers_out = r->err_headers_out;
- new->subprocess_env = rename_original_env (r->pool, r->subprocess_env);
- new->notes = make_table (r->pool, 5);
- new->htaccess = r->htaccess; /* copy .htaccess cache */
-
- new->no_cache = r->no_cache; /* If we've already made up our minds
- * about this, don't change 'em back!
- */
- new->no_local_copy = r->no_local_copy;
-
- new->read_length = r->read_length; /* We can only read it once */
-
- ap_snprintf (t, sizeof(t), "%d", r->status);
- table_set (new->subprocess_env, "REDIRECT_STATUS", pstrdup (r->pool, t));
-
- return new;
-}
-
-void internal_redirect (const char *new_uri, request_rec *r)
-{
- request_rec *new = internal_internal_redirect(new_uri, r);
- process_request_internal (new);
-}
-
-/* This function is designed for things like actions or CGI scripts, when
- * using AddHandler, and you want to preserve the content type across
- * an internal redirect.
- */
-
-void internal_redirect_handler (const char *new_uri, request_rec *r)
-{
- request_rec *new = internal_internal_redirect(new_uri, r);
- if (r->handler)
- new->content_type = r->content_type;
- process_request_internal (new);
-}
diff --git a/usr.sbin/httpd/src/http_request.h b/usr.sbin/httpd/src/http_request.h
deleted file mode 100644
index f20d494cad9..00000000000
--- a/usr.sbin/httpd/src/http_request.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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_request.c is the code which handles the main line of request
- * processing, once a request has been read in (finding the right per-
- * directory configuration, building it if necessary, and calling all
- * the module dispatch functions in the right order).
- *
- * The pieces here which are public to the modules, allow them to learn
- * how the server would handle some other file or URI, or perhaps even
- * direct the server to serve that other file instead of the one the
- * client requested directly.
- *
- * There are two ways to do that. The first is the sub_request mechanism,
- * which handles looking up files and URIs as adjuncts to some other
- * request (e.g., directory entries for multiviews and directory listings);
- * the lookup functions stop short of actually running the request, but
- * (e.g., for includes), a module may call for the request to be run
- * by calling run_sub_req. The space allocated to create sub_reqs can be
- * reclaimed by calling destroy_sub_req --- be sure to copy anything you care
- * about which was allocated in its pool elsewhere before doing this.
- */
-
-request_rec *sub_req_lookup_uri (const char *new_file, const request_rec *r);
-request_rec *sub_req_lookup_file (const char *new_file, const request_rec *r);
-int run_sub_req (request_rec *r);
-void destroy_sub_req (request_rec *r);
-
-/*
- * Then there's the case that you want some other request to be served
- * as the top-level request INSTEAD of what the client requested directly.
- * If so, call this from a handler, and then immediately return OK.
- */
-
-void internal_redirect (const char *new_uri, request_rec *);
-void internal_redirect_handler (const char *new_uri, request_rec *);
-int some_auth_required (request_rec *r);
-
-#ifdef CORE_PRIVATE
-/* Function called by main.c to handle first-level request */
-void process_request (request_rec *);
-int default_handler (request_rec *);
-#endif
diff --git a/usr.sbin/httpd/src/httpd.h b/usr.sbin/httpd/src/httpd.h
deleted file mode 100644
index 33bb73cd645..00000000000
--- a/usr.sbin/httpd/src/httpd.h
+++ /dev/null
@@ -1,766 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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/>.
- *
- */
-
-/*
- * httpd.h: header for simple (ha! not anymore) http daemon
- */
-
-/* Headers in which EVERYONE has an interest... */
-
-#include "conf.h"
-#include "alloc.h"
-#include "buff.h"
-
-/* ----------------------------- config dir ------------------------------ */
-
-/* Define this to be the default server home dir. Anything later in this
- * file with a relative pathname will have this added.
- */
-#ifndef HTTPD_ROOT
-#ifdef __EMX__
-/* Set default for OS/2 file system */
-#define HTTPD_ROOT "/os2httpd"
-#else
-#define HTTPD_ROOT "/var/www"
-#endif
-#endif
-
-#ifndef DOCUMENT_LOCATION
-/* Root of server */
-#ifdef __EMX__
-/* Set default for OS/2 file system */
-#define DOCUMENT_LOCATION "/os2httpd/docs"
-#else
-#define DOCUMENT_LOCATION "/var/www/htdocs"
-#endif
-#endif
-
-/* Max. number of dynamically loaded modules */
-#define DYNAMIC_MODULE_LIMIT 64
-
-/* Default administrator's address */
-#define DEFAULT_ADMIN "[no address given]"
-
-/*
- * --------- You shouldn't have to edit anything below this line ----------
- *
- * Any modifications to any defaults not defined above should be done in the
- * respective config. file.
- *
- */
-
-
-/* -------------- Port number for server running standalone --------------- */
-
-#define DEFAULT_PORT 80
-
-/* --------- Default user name and group name running standalone ---------- */
-/* --- These may be specified as numbers by placing a # before a number --- */
-
-#ifndef DEFAULT_USER
-#define DEFAULT_USER "#-1"
-#endif
-#ifndef DEFAULT_GROUP
-#define DEFAULT_GROUP "#-1"
-#endif
-
-/* The name of the log files */
-#ifndef DEFAULT_XFERLOG
-#ifdef __EMX__
-/* Set default for OS/2 file system */
-#define DEFAULT_XFERLOG "logs/access.log"
-#else
-#define DEFAULT_XFERLOG "logs/access_log"
-#endif
-#endif /* DEFAULT_XFERLOG */
-#ifndef DEFAULT_ERRORLOG
-#ifdef __EMX__
-/* Set default for OS/2 file system */
-#define DEFAULT_ERRORLOG "logs/error.log"
-#else
-#define DEFAULT_ERRORLOG "logs/error_log"
-#endif
-#endif /* DEFAULT_ERRORLOG */
-#ifndef DEFAULT_PIDLOG
-#define DEFAULT_PIDLOG "logs/httpd.pid"
-#endif
-#ifndef DEFAULT_SCOREBOARD
-#define DEFAULT_SCOREBOARD "logs/apache_runtime_status"
-#endif
-#ifndef DEFAULT_LOCKFILE
-#define DEFAULT_LOCKFILE "logs/accept.lock"
-#endif
-
-/* Define this to be what your HTML directory content files are called */
-#define DEFAULT_INDEX "index.html"
-
-/* Define this to 1 if you want fancy indexing, 0 otherwise */
-#define DEFAULT_INDEXING 0
-
-/* Define this to be what type you'd like returned for files with unknown */
-/* suffixes */
-#define DEFAULT_TYPE "text/plain"
-
-/* Define this to be what your per-directory security files are called */
-#ifdef __EMX__
-/* Set default for OS/2 file system */
-#define DEFAULT_ACCESS_FNAME "htaccess"
-#else
-#define DEFAULT_ACCESS_FNAME ".htaccess"
-#endif
-
-/* The name of the server config file */
-#ifndef SERVER_CONFIG_FILE
-#define SERVER_CONFIG_FILE "conf/httpd.conf"
-#endif
-
-#ifndef RESOURCE_CONFIG_FILE
-/* The name of the document config file */
-#define RESOURCE_CONFIG_FILE "conf/srm.conf"
-#endif
-
-#ifndef TYPES_CONFIG_FILE
-/* The name of the MIME types file */
-#define TYPES_CONFIG_FILE "conf/mime.types"
-#endif
-
-#ifndef ACCESS_CONFIG_FILE
-/* The name of the access file */
-#define ACCESS_CONFIG_FILE "conf/access.conf"
-#endif
-
-/* Whether we should enable rfc1413 identity checking */
-#define DEFAULT_RFC1413 0
-/* The default directory in user's home dir */
-#define DEFAULT_USER_DIR "public_html"
-
-/* The default path for CGI scripts if none is currently set */
-#ifndef DEFAULT_PATH
-#define DEFAULT_PATH "/bin:/usr/bin:/usr/ucb:/usr/bsd:/usr/local/bin"
-#endif
-
-/* The path to the Bourne shell, for parsed docs */
-#ifndef SHELL_PATH
-#ifdef __EMX__
-/* Set default for OS/2 file system */
-#define SHELL_PATH "CMD.EXE"
-#else
-#define SHELL_PATH "/bin/sh"
-#endif
-#endif
-
-/* The path to the suExec wrapper, can be overridden in Configuration */
-#ifndef SUEXEC_BIN
-#define SUEXEC_BIN "/usr/local/etc/httpd/sbin/suexec"
-#endif
-
-/* The default string lengths */
-#define MAX_STRING_LEN HUGE_STRING_LEN
-#define HUGE_STRING_LEN 8192
-
-/* The timeout for waiting for messages */
-#define DEFAULT_TIMEOUT 300
-
-/* The timeout for waiting for keepalive timeout until next request */
-#define DEFAULT_KEEPALIVE_TIMEOUT 15
-
-/* The number of requests to entertain per connection */
-#define DEFAULT_KEEPALIVE 100
-
-/* The size of the server's internal read-write buffers */
-#define IOBUFSIZE 8192
-
-/* Number of servers to spawn off by default --- also, if fewer than
- * this free when the caretaker checks, it will spawn more.
- */
-#define DEFAULT_START_DAEMON 5
-
-/* Maximum number of *free* server processes --- more than this, and
- * they will die off.
- */
-
-#define DEFAULT_MAX_FREE_DAEMON 10
-
-/* Minimum --- fewer than this, and more will be created */
-
-#define DEFAULT_MIN_FREE_DAEMON 5
-
-/* Limit on the total --- clients will be locked out if more servers than
- * this are needed. It is intended solely to keep the server from crashing
- * when things get out of hand.
- *
- * We keep a hard maximum number of servers, for two reasons --- first off,
- * in case something goes seriously wrong, we want to stop the fork bomb
- * short of actually crashing the machine we're running on by filling some
- * kernel table. Secondly, it keeps the size of the scoreboard file small
- * enough that we can read the whole thing without worrying too much about
- * the overhead.
- */
-#ifndef HARD_SERVER_LIMIT
-#define HARD_SERVER_LIMIT 256
-#endif
-
-/* Number of requests to try to handle in a single process. If <= 0,
- * the children don't die off. That's the default here, since I'm still
- * interested in finding and stanching leaks.
- */
-
-#define DEFAULT_MAX_REQUESTS_PER_CHILD 0
-
-/* If you have altered Apache and wish to change the SERVER_VERSION
- * identifier below, please keep to the HTTP specification. This states that
- * the identification string should consist of product tokens with an optional
- * slash and version designator. Sub-products which form a significant part
- * of the application can be listed, separated by whitespace, by adding
- * their product tokens to EXTRA_CFLAGS in the Configuration file like so.
- *
- * EXTRA_CFLAGS="-DSERVER_SUBVERSION="MrWidget/0.1-alpha"
- *
- * The tokens are listed in order of their significance for identifying the
- * application.
- *
- * "Product tokens should be short and to the point -- use of them for
- * advertizing or other non-essential information is explicitly forbidden."
- *
- * Example: "Apache/1.1.0 MrWidget/0.1-alpha"
- */
-
-#define SERVER_BASEVERSION "Apache/1.2.6" /* SEE COMMENTS ABOVE */
-#ifdef SERVER_SUBVERSION
-#define SERVER_VERSION SERVER_BASEVERSION " " SERVER_SUBVERSION
-#else
-#define SERVER_VERSION SERVER_BASEVERSION
-#endif
-
-/* Numeric release version identifier: major minor bugfix betaseq
- * Always increases along the same track as the source branch.
- */
-#define APACHE_RELEASE 1020600
-
-#define SERVER_PROTOCOL "HTTP/1.1"
-#define SERVER_SUPPORT "http://www.apache.org/"
-
-#define DECLINED -1 /* Module declines to handle */
-#define OK 0 /* Module has handled this stage. */
-
-
-/* ----------------------- HTTP Status Codes ------------------------- */
-
-#define RESPONSE_CODES 38
-
-#define HTTP_CONTINUE 100
-#define HTTP_SWITCHING_PROTOCOLS 101
-#define HTTP_OK 200
-#define HTTP_CREATED 201
-#define HTTP_ACCEPTED 202
-#define HTTP_NON_AUTHORITATIVE 203
-#define HTTP_NO_CONTENT 204
-#define HTTP_RESET_CONTENT 205
-#define HTTP_PARTIAL_CONTENT 206
-#define HTTP_MULTIPLE_CHOICES 300
-#define HTTP_MOVED_PERMANENTLY 301
-#define HTTP_MOVED_TEMPORARILY 302
-#define HTTP_SEE_OTHER 303
-#define HTTP_NOT_MODIFIED 304
-#define HTTP_USE_PROXY 305
-#define HTTP_BAD_REQUEST 400
-#define HTTP_UNAUTHORIZED 401
-#define HTTP_PAYMENT_REQUIRED 402
-#define HTTP_FORBIDDEN 403
-#define HTTP_NOT_FOUND 404
-#define HTTP_METHOD_NOT_ALLOWED 405
-#define HTTP_NOT_ACCEPTABLE 406
-#define HTTP_PROXY_AUTHENTICATION_REQUIRED 407
-#define HTTP_REQUEST_TIME_OUT 408
-#define HTTP_CONFLICT 409
-#define HTTP_GONE 410
-#define HTTP_LENGTH_REQUIRED 411
-#define HTTP_PRECONDITION_FAILED 412
-#define HTTP_REQUEST_ENTITY_TOO_LARGE 413
-#define HTTP_REQUEST_URI_TOO_LARGE 414
-#define HTTP_UNSUPPORTED_MEDIA_TYPE 415
-#define HTTP_INTERNAL_SERVER_ERROR 500
-#define HTTP_NOT_IMPLEMENTED 501
-#define HTTP_BAD_GATEWAY 502
-#define HTTP_SERVICE_UNAVAILABLE 503
-#define HTTP_GATEWAY_TIME_OUT 504
-#define HTTP_VERSION_NOT_SUPPORTED 505
-#define HTTP_VARIANT_ALSO_VARIES 506
-
-#define DOCUMENT_FOLLOWS HTTP_OK
-#define PARTIAL_CONTENT HTTP_PARTIAL_CONTENT
-#define MULTIPLE_CHOICES HTTP_MULTIPLE_CHOICES
-#define MOVED HTTP_MOVED_PERMANENTLY
-#define REDIRECT HTTP_MOVED_TEMPORARILY
-#define USE_LOCAL_COPY HTTP_NOT_MODIFIED
-#define BAD_REQUEST HTTP_BAD_REQUEST
-#define AUTH_REQUIRED HTTP_UNAUTHORIZED
-#define FORBIDDEN HTTP_FORBIDDEN
-#define NOT_FOUND HTTP_NOT_FOUND
-#define METHOD_NOT_ALLOWED HTTP_METHOD_NOT_ALLOWED
-#define NOT_ACCEPTABLE HTTP_NOT_ACCEPTABLE
-#define LENGTH_REQUIRED HTTP_LENGTH_REQUIRED
-#define PRECONDITION_FAILED HTTP_PRECONDITION_FAILED
-#define SERVER_ERROR HTTP_INTERNAL_SERVER_ERROR
-#define NOT_IMPLEMENTED HTTP_NOT_IMPLEMENTED
-#define BAD_GATEWAY HTTP_BAD_GATEWAY
-#define VARIANT_ALSO_VARIES HTTP_VARIANT_ALSO_VARIES
-
-#define is_HTTP_INFO(x) (((x) >= 100)&&((x) < 200))
-#define is_HTTP_SUCCESS(x) (((x) >= 200)&&((x) < 300))
-#define is_HTTP_REDIRECT(x) (((x) >= 300)&&((x) < 400))
-#define is_HTTP_ERROR(x) (((x) >= 400)&&((x) < 600))
-#define is_HTTP_CLIENT_ERROR(x) (((x) >= 400)&&((x) < 500))
-#define is_HTTP_SERVER_ERROR(x) (((x) >= 500)&&((x) < 600))
-
-#define status_drops_connection(x) (((x) == HTTP_BAD_REQUEST) || \
- ((x) == HTTP_REQUEST_TIME_OUT) || \
- ((x) == HTTP_LENGTH_REQUIRED) || \
- ((x) == HTTP_REQUEST_ENTITY_TOO_LARGE) || \
- ((x) == HTTP_REQUEST_URI_TOO_LARGE) || \
- ((x) == HTTP_INTERNAL_SERVER_ERROR) || \
- ((x) == HTTP_SERVICE_UNAVAILABLE))
-
-
-#define METHODS 8
-#define M_GET 0
-#define M_PUT 1
-#define M_POST 2
-#define M_DELETE 3
-#define M_CONNECT 4
-#define M_OPTIONS 5
-#define M_TRACE 6
-#define M_INVALID 7
-
-#define CGI_MAGIC_TYPE "application/x-httpd-cgi"
-#define INCLUDES_MAGIC_TYPE "text/x-server-parsed-html"
-#define INCLUDES_MAGIC_TYPE3 "text/x-server-parsed-html3"
-#define MAP_FILE_MAGIC_TYPE "application/x-type-map"
-#define ASIS_MAGIC_TYPE "httpd/send-as-is"
-#define DIR_MAGIC_TYPE "httpd/unix-directory"
-#define STATUS_MAGIC_TYPE "application/x-httpd-status"
-
-/* Just in case your linefeed isn't the one the other end is expecting. */
-#define LF 10
-#define CR 13
-
-/* Possible values for request_rec.read_body (set by handling module):
- * REQUEST_NO_BODY Send 413 error if message has any body
- * REQUEST_CHUNKED_ERROR Send 411 error if body without Content-Length
- * REQUEST_CHUNKED_DECHUNK If chunked, remove the chunks for me.
- * REQUEST_CHUNKED_PASS Pass the chunks to me without removal.
- */
-#define REQUEST_NO_BODY 0
-#define REQUEST_CHUNKED_ERROR 1
-#define REQUEST_CHUNKED_DECHUNK 2
-#define REQUEST_CHUNKED_PASS 3
-
-/* Things which may vary per file-lookup WITHIN a request ---
- * e.g., state of MIME config. Basically, the name of an object, info
- * about the object, and any other info we may ahve which may need to
- * change as we go poking around looking for it (e.g., overridden by
- * .htaccess files).
- *
- * Note how the default state of almost all these things is properly
- * zero, so that allocating it with pcalloc does the right thing without
- * a whole lot of hairy initialization... so long as we are willing to
- * make the (fairly) portable assumption that the bit pattern of a NULL
- * pointer is, in fact, zero.
- */
-
-/* This represents the result of calling htaccess; these are cached for
- * each request.
- */
-struct htaccess_result
-{
- char *dir; /* the directory to which this applies */
- int override; /* the overrides allowed for the .htaccess file */
- void *htaccess; /* the configuration directives */
-/* the next one, or NULL if no more; N.B. never change this */
- const struct htaccess_result *next;
-};
-
-
-typedef struct conn_rec conn_rec;
-typedef struct server_rec server_rec;
-typedef struct request_rec request_rec;
-typedef struct listen_rec listen_rec;
-
-struct request_rec {
-
- pool *pool;
- conn_rec *connection;
- server_rec *server;
-
- request_rec *next; /* If we wind up getting redirected,
- * pointer to the request we redirected to.
- */
- request_rec *prev; /* If this is an internal redirect,
- * pointer to where we redirected *from*.
- */
-
- request_rec *main; /* If this is a sub_request (see request.h)
- * pointer back to the main request.
- */
-
- /* Info about the request itself... we begin with stuff that only
- * protocol.c should ever touch...
- */
-
- char *the_request; /* First line of request, so we can log it */
- int assbackwards; /* HTTP/0.9, "simple" request */
- int proxyreq; /* A proxy request */
- int header_only; /* HEAD request, as opposed to GET */
- char *protocol; /* Protocol, as given to us, or HTTP/0.9 */
- int proto_num; /* Number version of protocol; 1.1 = 1001 */
- char *hostname; /* Host, as set by full URI or Host: */
- int hostlen; /* Length of http://host:port in full URI */
-
- time_t request_time; /* When the request started */
-
- char *status_line; /* Status line, if set by script */
- int status; /* In any case */
-
- /* Request method, two ways; also, protocol, etc.. Outside of protocol.c,
- * look, but don't touch.
- */
-
- char *method; /* GET, HEAD, POST, etc. */
- int method_number; /* M_GET, M_POST, etc. */
- int allowed; /* Allowed methods - for 405, OPTIONS, etc */
-
- int sent_bodyct; /* byte count in stream is for body */
- long bytes_sent; /* body byte count, for easy access */
-
- /* HTTP/1.1 connection-level features */
-
- int chunked; /* sending chunked transfer-coding */
- int byterange; /* number of byte ranges */
- char *boundary; /* multipart/byteranges boundary */
- char *range; /* The Range: header */
- long clength; /* The "real" content length */
-
- long remaining; /* bytes left to read */
- long read_length; /* bytes that have been read */
- int read_body; /* how the request body should be read */
- int read_chunked; /* reading chunked transfer-coding */
-
- /* MIME header environments, in and out. Also, an array containing
- * environment variables to be passed to subprocesses, so people can
- * write modules to add to that environment.
- *
- * The difference between headers_out and err_headers_out is that the
- * latter are printed even on error, and persist across internal redirects
- * (so the headers printed for ErrorDocument handlers will have them).
- *
- * The 'notes' table is for notes from one module to another, with no
- * other set purpose in mind...
- */
-
- table *headers_in;
- table *headers_out;
- table *err_headers_out;
- table *subprocess_env;
- table *notes;
-
- char *content_type; /* Break these out --- we dispatch on 'em */
- char *handler; /* What we *really* dispatch on */
-
- char *content_encoding;
- char *content_language; /* for back-compat. only -- do not use */
- array_header *content_languages; /* array of (char*) */
-
- int no_cache;
- int no_local_copy;
-
- /* What object is being requested (either directly, or via include
- * or content-negotiation mapping).
- */
-
- char *uri; /* complete URI for a proxy req, or
- URL path for a non-proxy req */
- char *filename;
- char *path_info;
- char *args; /* QUERY_ARGS, if any */
- struct stat finfo; /* ST_MODE set to zero if no such file */
-
- /* Various other config info which may change with .htaccess files
- * These are config vectors, with one void* pointer for each module
- * (the thing pointed to being the module's business).
- */
-
- void *per_dir_config; /* Options set in config files, etc. */
- void *request_config; /* Notes on *this* request */
-
-/*
- * a linked list of the configuration directives in the .htaccess files
- * accessed by this request.
- * N.B. always add to the head of the list, _never_ to the end.
- * that way, a sub request's list can (temporarily) point to a parent's list
- */
- const struct htaccess_result *htaccess;
-};
-
-
-/* Things which are per connection
- */
-
-struct conn_rec {
-
- pool *pool;
- server_rec *server;
- server_rec *base_server; /* Physical vhost this conn come in on */
-
- /* Information about the connection itself */
-
- int child_num; /* The number of the child handling conn_rec */
- BUFF *client; /* Connetion to the guy */
- int aborted; /* Are we still talking? */
-
- /* Who is the client? */
-
- struct sockaddr_in local_addr; /* local address */
- struct sockaddr_in remote_addr;/* remote address */
- char *remote_ip; /* Client's IP address */
- char *remote_host; /* Client's DNS name, if known.
- * NULL if DNS hasn't been checked,
- * "" if it has and no address was found.
- * N.B. Only access this though
- * get_remote_host() */
- char *remote_logname; /* Only ever set if doing rfc1413 lookups.
- * N.B. Only access this through
- * get_remote_logname() */
- char *user; /* If an authentication check was made,
- * this gets set to the user name. We assume
- * that there's only one user per connection(!)
- */
- char *auth_type; /* Ditto. */
-
- int keepalive; /* Are we using HTTP Keep-Alive? */
- int keptalive; /* Did we use HTTP Keep-Alive? */
- int keepalives; /* How many times have we used it? */
-};
-
-/* Per-vhost config... */
-
-/* The address 255.255.255.255, when used as a virtualhost address,
- * will become the "default" server when the ip doesn't match other vhosts.
- */
-#define DEFAULT_VHOST_ADDR 0xfffffffful
-
-typedef struct server_addr_rec server_addr_rec;
-struct server_addr_rec {
- server_addr_rec *next;
- struct in_addr host_addr; /* The bound address, for this server */
- unsigned short host_port; /* The bound port, for this server */
- char *virthost; /* The name given in <VirtualHost> */
-};
-
-
-struct server_rec {
-
- server_rec *next;
-
- /* Full locations of server config info */
-
- char *srm_confname;
- char *access_confname;
-
- /* Contact information */
-
- char *server_admin;
- char *server_hostname;
- unsigned short port; /* for redirects, etc. */
-
- /* Log files --- note that transfer log is now in the modules... */
-
- char *error_fname;
- FILE *error_log;
-
- /* Module-specific configuration for server, and defaults... */
-
- int is_virtual; /* true if this is the virtual server */
- void *module_config; /* Config vector containing pointers to
- * modules' per-server config structures.
- */
- void *lookup_defaults; /* MIME type info, etc., before we start
- * checking per-directory info.
- */
- /* Transaction handling */
-
- server_addr_rec *addrs;
- int timeout; /* Timeout, in seconds, before we give up */
- int keep_alive_timeout; /* Seconds we'll wait for another request */
- int keep_alive_max; /* Maximum requests per connection */
- int keep_alive; /* Use persistent connections? */
- int send_buffer_size; /* size of TCP send buffer (in bytes) */
-
- char *path; /* Pathname for ServerPath */
- int pathlen; /* Length of path */
-
- char *names; /* Wildcarded names for ServerAlias servers */
-
- uid_t server_uid; /* effective user id when calling exec wrapper */
- gid_t server_gid; /* effective group id when calling exec wrapper */
-};
-
-/* These are more like real hosts than virtual hosts */
-struct listen_rec {
- listen_rec *next;
- struct sockaddr_in local_addr; /* local IP address and port */
- int fd;
- int used; /* Only used during restart */
-/* more stuff here, like which protocol is bound to the port */
-};
-
-/* Prototypes for utilities... util.c.
- */
-
-/* Time */
-extern const char month_snames[12][4];
-
-struct tm *get_gmtoff(int *tz);
-char *get_time();
-char *ht_time (pool *p, time_t t, const char *fmt, int gmt);
-char *gm_timestr_822(pool *p, time_t t);
-
-/* String handling. The *_nc variants allow you to use non-const char **s as
-arguments (unfortunately C won't automatically convert a char ** to a const
-char **) */
-
-char *getword(pool *p, const char **line, char stop);
-char *getword_nc(pool *p, char **line, char stop);
-char *getword_white(pool *p, const char **line);
-char *getword_white_nc(pool *p, char **line);
-char *getword_nulls (pool *p, const char **line, char stop);
-char *getword_nulls_nc (pool *p, char **line, char stop);
-char *getword_conf (pool *p, const char **line);
-char *getword_conf_nc (pool *p, char **line);
-
-char *get_token (pool *p, char **accept_line, int accept_white);
-int find_token (pool *p, const char *line, const char *tok);
-int find_last_token (pool *p, const char *line, const char *tok);
-
-int is_url(const char *u);
-extern int unescape_url(char *url);
-void no2slash(char *name);
-void getparents(char *name);
-char *escape_path_segment(pool *p, const char *s);
-char *os_escape_path(pool *p,const char *path,int partial);
-#define escape_uri(ppool,path) os_escape_path(ppool,path,1)
-extern char *escape_html(pool *p, const char *s);
-char *construct_server(pool *p, const char *hostname, unsigned port);
-char *construct_url (pool *p, const char *path, const server_rec *s);
-char *escape_shell_cmd (pool *p, const char *s);
-
-int count_dirs(const char *path);
-char *make_dirstr(pool *a, const char *s, int n);
-char *make_full_path(pool *a, const char *dir, const char *f);
-
-int is_matchexp(const char *str);
-int strcmp_match(const char *str, const char *exp);
-int strcasecmp_match(const char *str, const char *exp);
-char *uudecode (pool *, const char *);
-
-char *pregsub(pool *p, const char *input, const char *source,
- size_t nmatch, regmatch_t pmatch[]);
-
-void str_tolower (char *);
-int ind (const char *, char); /* Sigh... */
-int rind (const char *, char);
-
-int cfg_getline(char *s, int n, FILE *f);
-
-#ifdef NEED_STRERROR
-char *strerror (int err);
-#endif
-
-/* Misc system hackery */
-
-uid_t uname2id(const char *name);
-gid_t gname2id(const char *name);
-int is_directory(const char *name);
-int can_exec(const struct stat *);
-void chdir_file(const char *file);
-
-char *get_local_host(pool *);
-unsigned long get_virthost_addr (const char *hostname, unsigned short *port);
-
-extern time_t restart_time;
-
-/*
- * Apache tries to keep all of its long term filehandles (such as log files,
- * and sockets) above this number. This is to workaround problems in many
- * third party libraries that are compiled with a small FD_SETSIZE. There
- * should be no reason to lower this, because it's only advisory. If a file
- * can't be allocated above this number then it will remain in the "slack"
- * area.
- *
- * Only the low slack line is used by default. If HIGH_SLACK_LINE is defined
- * then an attempt is also made to keep all non-FILE * files above the high
- * slack line. This is to work around a Solaris C library limitation, where it
- * uses an unsigned char to store the file descriptor.
- */
-#ifndef LOW_SLACK_LINE
-#define LOW_SLACK_LINE 15
-#endif
-/* #define HIGH_SLACK_LINE 255 */
-
-/*
- * The ap_slack() function takes a fd, and tries to move it above the indicated
- * line. It returns an fd which may or may not have moved above the line, and
- * never fails. If the high line was requested and it fails it will also try
- * the low line.
- */
-int ap_slack (int fd, int line);
-#define AP_SLACK_LOW 1
-#define AP_SLACK_HIGH 2
diff --git a/usr.sbin/httpd/src/md5.h b/usr.sbin/httpd/src/md5.h
deleted file mode 100644
index a8ff86c4bd0..00000000000
--- a/usr.sbin/httpd/src/md5.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * This is work is derived from material Copyright RSA Data Security, Inc.
- *
- * The RSA copyright statement and Licence for that original material is
- * included below. This is followed by the Apache copyright statement and
- * licence for the modifications made to that material.
- */
-
-/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
-rights reserved.
-
-License to copy and use this software is granted provided that it
-is identified as the "RSA Data Security, Inc. MD5 Message-Digest
-Algorithm" in all material mentioning or referencing this software
-or this function.
-
-License is also granted to make and use derivative works provided
-that such works are identified as "derived from the RSA Data
-Security, Inc. MD5 Message-Digest Algorithm" in all material
-mentioning or referencing the derived work.
-
-RSA Data Security, Inc. makes no representations concerning either
-the merchantability of this software or the suitability of this
-software for any particular purpose. It is provided "as is"
-without express or implied warranty of any kind.
-
-These notices must be retained in any copies of any part of this
-documentation and/or software.
- */
-
-/* ====================================================================
- * Copyright (c) 1996,1997 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. 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/>.
- *
- */
-
-
-/* MD5.H - header file for MD5C.C */
-
-/* UINT4 defines a four byte word */
-typedef unsigned int UINT4;
-
-/* MD5 context. */
-typedef struct {
- UINT4 state[4]; /* state (ABCD) */
- UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
- unsigned char buffer[64]; /* input buffer */
-} MD5_CTX;
-
-extern void MD5Init(MD5_CTX *context);
-extern void MD5Update(MD5_CTX *context, const unsigned char *input,
- unsigned int inputLen);
-extern void MD5Final(unsigned char digest[16], MD5_CTX *context);
diff --git a/usr.sbin/httpd/src/md5c.c b/usr.sbin/httpd/src/md5c.c
deleted file mode 100644
index fd42bcb456e..00000000000
--- a/usr.sbin/httpd/src/md5c.c
+++ /dev/null
@@ -1,354 +0,0 @@
-/*
- * This is work is derived from material Copyright RSA Data Security, Inc.
- *
- * The RSA copyright statement and Licence for that original material is
- * included below. This is followed by the Apache copyright statement and
- * licence for the modifications made to that material.
- */
-
-/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
- */
-
-/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
-rights reserved.
-
-License to copy and use this software is granted provided that it
-is identified as the "RSA Data Security, Inc. MD5 Message-Digest
-Algorithm" in all material mentioning or referencing this software
-or this function.
-
-License is also granted to make and use derivative works provided
-that such works are identified as "derived from the RSA Data
-Security, Inc. MD5 Message-Digest Algorithm" in all material
-mentioning or referencing the derived work.
-
-RSA Data Security, Inc. makes no representations concerning either
-the merchantability of this software or the suitability of this
-software for any particular purpose. It is provided "as is"
-without express or implied warranty of any kind.
-
-These notices must be retained in any copies of any part of this
-documentation and/or software.
- */
-
-/* ====================================================================
- * Copyright (c) 1996,1997 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. 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/>.
- *
- */
-
-#include <string.h>
-
-#include "md5.h"
-
-/* Constants for MD5Transform routine.
- */
-
-#define S11 7
-#define S12 12
-#define S13 17
-#define S14 22
-#define S21 5
-#define S22 9
-#define S23 14
-#define S24 20
-#define S31 4
-#define S32 11
-#define S33 16
-#define S34 23
-#define S41 6
-#define S42 10
-#define S43 15
-#define S44 21
-
-static void MD5Transform(UINT4 state[4], const unsigned char block[64]);
-static void Encode(unsigned char *output, const UINT4 *input,
- unsigned int len);
-static void Decode(UINT4 *output, const unsigned char *input,
- unsigned int len);
-
-static unsigned char PADDING[64] =
-{
- 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-/* F, G, H and I are basic MD5 functions.
- */
-#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
-#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
-#define H(x, y, z) ((x) ^ (y) ^ (z))
-#define I(x, y, z) ((y) ^ ((x) | (~z)))
-
-/* ROTATE_LEFT rotates x left n bits.
- */
-#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
-
-/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
-Rotation is separate from addition to prevent recomputation.
- */
-#define FF(a, b, c, d, x, s, ac) { \
- (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
- }
-#define GG(a, b, c, d, x, s, ac) { \
- (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
- }
-#define HH(a, b, c, d, x, s, ac) { \
- (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
- }
-#define II(a, b, c, d, x, s, ac) { \
- (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
- }
-
-/* MD5 initialization. Begins an MD5 operation, writing a new context.
- */
-void
-MD5Init(MD5_CTX *context)
-{
- context->count[0] = context->count[1] = 0;
- /* Load magic initialization constants. */
- context->state[0] = 0x67452301;
- context->state[1] = 0xefcdab89;
- context->state[2] = 0x98badcfe;
- context->state[3] = 0x10325476;
-}
-
-/* MD5 block update operation. Continues an MD5 message-digest
- operation, processing another message block, and updating the
- context.
- */
-void
-MD5Update(MD5_CTX *context, const unsigned char *input, unsigned int inputLen)
-{
- unsigned int i, index, partLen;
-
- /* Compute number of bytes mod 64 */
- index = (unsigned int)((context->count[0] >> 3) & 0x3F);
-
- /* Update number of bits */
- if ((context->count[0] += ((UINT4)inputLen << 3)) < ((UINT4)inputLen << 3))
- context->count[1]++;
- context->count[1] += (UINT4)inputLen >> 29;
-
- partLen = 64 - index;
-
- /* Transform as many times as possible. */
- if (inputLen >= partLen)
- {
- memcpy(&context->buffer[index], input, partLen);
- MD5Transform(context->state, context->buffer);
-
- for (i = partLen; i + 63 < inputLen; i += 64)
- MD5Transform(context->state, &input[i]);
-
- index = 0;
- }
- else
- i = 0;
-
- /* Buffer remaining input */
- memcpy(&context->buffer[index], &input[i], inputLen-i);
-}
-
-/* MD5 finalization. Ends an MD5 message-digest operation, writing the
- the message digest and zeroizing the context.
- */
-void
-MD5Final(unsigned char digest[16], MD5_CTX *context)
-{
- unsigned char bits[8];
- unsigned int index, padLen;
-
- /* Save number of bits */
- Encode (bits, context->count, 8);
-
- /* Pad out to 56 mod 64. */
- index = (unsigned int)((context->count[0] >> 3) & 0x3f);
- padLen = (index < 56) ? (56 - index) : (120 - index);
- MD5Update(context, PADDING, padLen);
-
- /* Append length (before padding) */
- MD5Update(context, bits, 8);
-
- /* Store state in digest */
- Encode(digest, context->state, 16);
-
- /* Zeroize sensitive information. */
- memset(context, 0, sizeof (*context));
-}
-
-/* MD5 basic transformation. Transforms state based on block. */
-static void
-MD5Transform(UINT4 state[4], const unsigned char block[64])
-{
- UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
-
- Decode (x, block, 64);
-
- /* Round 1 */
- FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
- FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
- FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
- FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
- FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
- FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
- FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
- FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
- FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
- FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
- FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
- FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
- FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
- FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
- FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
- FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
-
- /* Round 2 */
- GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
- GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
- GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
- GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
- GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
- GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
- GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
- GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
- GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
- GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
- GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
- GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
- GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
- GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
- GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
- GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
-
- /* Round 3 */
- HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
- HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
- HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
- HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
- HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
- HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
- HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
- HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
- HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
- HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
- HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
- HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
- HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
- HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
- HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
- HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
-
- /* Round 4 */
- II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
- II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
- II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
- II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
- II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
- II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
- II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
- II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
- II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
- II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
- II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
- II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
- II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
- II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
- II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
- II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
-
- state[0] += a;
- state[1] += b;
- state[2] += c;
- state[3] += d;
-
- /* Zeroize sensitive information. */
- memset(x, 0, sizeof (x));
-}
-
-/* Encodes input (UINT4) into output (unsigned char). Assumes len is
- a multiple of 4.
- */
-static void
-Encode(unsigned char *output, const UINT4 *input, unsigned int len)
-{
- unsigned int i, j;
- UINT4 k;
-
- for (i = 0, j = 0; j < len; i++, j += 4)
- {
- k = input[i];
- output[j] = (unsigned char)(k & 0xff);
- output[j+1] = (unsigned char)((k >> 8) & 0xff);
- output[j+2] = (unsigned char)((k >> 16) & 0xff);
- output[j+3] = (unsigned char)((k >> 24) & 0xff);
- }
-}
-
-/* Decodes input (unsigned char) into output (UINT4). Assumes len is
- a multiple of 4.
- */
-static void
-Decode(UINT4 *output, const unsigned char *input, unsigned int len)
-{
- unsigned int i, j;
-
- for (i = 0, j = 0; j < len; i++, j += 4)
- output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
- (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
-}
diff --git a/usr.sbin/httpd/src/mod_access.c b/usr.sbin/httpd/src/mod_access.c
deleted file mode 100644
index eb352380123..00000000000
--- a/usr.sbin/httpd/src/mod_access.c
+++ /dev/null
@@ -1,283 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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/>.
- *
- */
-
-/*
- * Security options etc.
- *
- * Module derived from code originally written by Rob McCool
- *
- */
-
-#include "httpd.h"
-#include "http_core.h"
-#include "http_config.h"
-#include "http_log.h"
-#include "http_request.h"
-
-typedef struct {
- char *from;
- int limited;
-} allowdeny;
-
-/* things in the 'order' array */
-#define DENY_THEN_ALLOW 0
-#define ALLOW_THEN_DENY 1
-#define MUTUAL_FAILURE 2
-
-typedef struct {
- int order[METHODS];
- array_header *allows;
- array_header *denys;
-} access_dir_conf;
-
-module access_module;
-
-void *create_access_dir_config (pool *p, char *dummy)
-{
- access_dir_conf *conf =
- (access_dir_conf *)pcalloc(p, sizeof(access_dir_conf));
- int i;
-
- for (i = 0; i < METHODS; ++i) conf->order[i] = DENY_THEN_ALLOW;
- conf->allows = make_array (p, 1, sizeof (allowdeny));
- conf->denys = make_array (p, 1, sizeof (allowdeny));
-
- return (void *)conf;
-}
-
-const char *order (cmd_parms *cmd, void *dv, char *arg)
-{
- access_dir_conf *d = (access_dir_conf *)dv;
- int i, order;
-
- if (!strcasecmp (arg, "allow,deny")) order = ALLOW_THEN_DENY;
- else if (!strcasecmp (arg, "deny,allow")) order = DENY_THEN_ALLOW;
- else if (!strcasecmp (arg, "mutual-failure")) order = MUTUAL_FAILURE;
- else return "unknown order";
-
- for (i = 0; i < METHODS; ++i)
- if (cmd->limited & (1 << i))
- d->order[i] = order;
-
- return NULL;
-}
-
-const char *allow_cmd (cmd_parms *cmd, void *dv, char *from, char *where)
-{
- access_dir_conf *d = (access_dir_conf *)dv;
- allowdeny *a;
-
- if (strcasecmp (from, "from"))
- return "allow and deny must be followed by 'from'";
-
- a = (allowdeny *)push_array (cmd->info ? d->allows : d->denys);
- a->from = pstrdup (cmd->pool, where);
- a->limited = cmd->limited;
- return NULL;
-}
-
-static char its_an_allow;
-
-command_rec access_cmds[] = {
-{ "order", order, NULL, OR_LIMIT, TAKE1,
- "'allow,deny', 'deny,allow', or 'mutual-failure'" },
-{ "allow", allow_cmd, &its_an_allow, OR_LIMIT, ITERATE2,
- "'from' followed by hostnames or IP-address wildcards" },
-{ "deny", allow_cmd, NULL, OR_LIMIT, ITERATE2,
- "'from' followed by hostnames or IP-address wildcards" },
-{NULL}
-};
-
-int in_domain(const char *domain, const char *what) {
- int dl=strlen(domain);
- int wl=strlen(what);
-
- if((wl-dl) >= 0) {
- if (strcasecmp(domain,&what[wl-dl]) != 0) return 0;
-
- /* Make sure we matched an *entire* subdomain --- if the user
- * said 'allow from good.com', we don't want people from nogood.com
- * to be able to get in.
- */
-
- if (wl == dl) return 1; /* matched whole thing */
- else return (domain[0] == '.' || what[wl - dl - 1] == '.');
- } else
- return 0;
-}
-
-int in_ip(char *domain, char *what) {
-
- /* Check a similar screw case to the one checked above ---
- * "allow from 204.26.2" shouldn't let in people from 204.26.23
- */
-
- int l = strlen(domain);
- if (strncmp(domain,what,l) != 0) return 0;
- if (domain[l - 1] == '.') return 1;
- return (what[l] == '\0' || what[l] == '.');
-}
-
-static int is_ip(const char *host)
-{
- while ((*host == '.') || isdigit(*host))
- host++;
- return (*host == '\0');
-}
-
-int find_allowdeny (request_rec *r, array_header *a, int method)
-{
- allowdeny *ap = (allowdeny *)a->elts;
- int mmask = (1 << method);
- int i;
- int gothost = 0;
- const char *remotehost = NULL;
-
- for (i = 0; i < a->nelts; ++i) {
- if (!(mmask & ap[i].limited))
- continue;
-
- if (!strncmp(ap[i].from,"env=",4) && table_get(r->subprocess_env,ap[i].from+4))
- return 1;
-
- if (ap[i].from && !strcmp(ap[i].from, "user-agents")) {
- char * this_agent = table_get(r->headers_in, "User-Agent");
- int j;
-
- if (!this_agent) return 0;
-
- for (j = i+1; j < a->nelts; ++j) {
- if (strstr(this_agent, ap[j].from)) return 1;
- }
- return 0;
- }
-
- if (!strcmp (ap[i].from, "all"))
- return 1;
-
- if (!gothost) {
- remotehost = get_remote_host(r->connection, r->per_dir_config,
- REMOTE_HOST);
-
- if ((remotehost == NULL) || is_ip(remotehost))
- gothost = 1;
- else
- gothost = 2;
- }
-
- if ((gothost == 2) && in_domain(ap[i].from, remotehost))
- return 1;
-
- if (in_ip (ap[i].from, r->connection->remote_ip))
- return 1;
- }
-
- return 0;
-}
-
-int check_dir_access (request_rec *r)
-{
- int method = r->method_number;
- access_dir_conf *a =
- (access_dir_conf *)
- get_module_config (r->per_dir_config, &access_module);
- int ret = OK;
-
- if (a->order[method] == ALLOW_THEN_DENY) {
- ret = FORBIDDEN;
- if (find_allowdeny (r, a->allows, method))
- ret = OK;
- if (find_allowdeny (r, a->denys, method))
- ret = FORBIDDEN;
- } else if (a->order[method] == DENY_THEN_ALLOW) {
- if (find_allowdeny (r, a->denys, method))
- ret = FORBIDDEN;
- if (find_allowdeny (r, a->allows, method))
- ret = OK;
- }
- else {
- if (find_allowdeny(r, a->allows, method)
- && !find_allowdeny(r, a->denys, method))
- ret = OK;
- else
- ret = FORBIDDEN;
- }
-
- if (ret == FORBIDDEN && (
- satisfies(r) != SATISFY_ANY || !some_auth_required(r)
- )) {
- log_reason ("Client denied by server configuration", r->filename, r);
- }
-
- return ret;
-}
-
-
-
-module access_module = {
- STANDARD_MODULE_STUFF,
- NULL, /* initializer */
- create_access_dir_config, /* dir config creater */
- NULL, /* dir merger --- default is to override */
- NULL, /* server config */
- NULL, /* merge server config */
- access_cmds,
- NULL, /* handlers */
- NULL, /* filename translation */
- NULL, /* check_user_id */
- NULL, /* check auth */
- check_dir_access, /* check access */
- NULL, /* type_checker */
- NULL, /* fixups */
- NULL, /* logger */
- NULL /* header parser */
-};
diff --git a/usr.sbin/httpd/src/mod_actions.c b/usr.sbin/httpd/src/mod_actions.c
deleted file mode 100644
index 570147069ed..00000000000
--- a/usr.sbin/httpd/src/mod_actions.c
+++ /dev/null
@@ -1,219 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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_actions.c: executes scripts based on MIME type
- *
- * by Alexei Kosut; based on mod_cgi.c, mod_mime.c and mod_includes.c,
- * adapted by rst from original NCSA code by Rob McCool
- *
- * Usage instructions:
- *
- * Action mime/type /cgi-bin/script
- *
- * will activate /cgi-bin/script when a file of content type mime/type is
- * requested. It sends the URL and file path of the requested document using
- * the standard CGI PATH_INFO and PATH_TRANSLATED environment variables.
- *
- */
-
-#include "httpd.h"
-#include "http_config.h"
-#include "http_request.h"
-#include "http_core.h"
-#include "http_protocol.h"
-#include "http_main.h"
-#include "http_log.h"
-#include "util_script.h"
-
-typedef struct {
- table *action_types; /* Added with Action... */
- char *get; /* Added with Script GET */
- char *post; /* Added with Script POST */
- char *put; /* Added with Script PUT */
- char *delete; /* Added with Script DELETE */
-} action_dir_config;
-
-module action_module;
-
-void *create_action_dir_config (pool *p, char *dummy)
-{
- action_dir_config *new =
- (action_dir_config *) palloc (p, sizeof(action_dir_config));
-
- new->action_types = make_table (p, 4);
- new->get = NULL;
- new->post = NULL;
- new->put = NULL;
- new->delete = NULL;
-
- return new;
-}
-
-void *merge_action_dir_configs (pool *p, void *basev, void *addv)
-{
- action_dir_config *base = (action_dir_config *)basev;
- action_dir_config *add = (action_dir_config *)addv;
- action_dir_config *new =
- (action_dir_config *)palloc (p, sizeof(action_dir_config));
-
- new->action_types = overlay_tables (p, add->action_types,
- base->action_types);
-
- new->get = add->get ? add->get : base->get;
- new->post = add->post ? add->post : base->post;
- new->put = add->put ? add->put : base->put;
- new->delete = add->delete ? add->delete : base->delete;
-
- return new;
-}
-
-const char *add_action(cmd_parms *cmd, action_dir_config *m, char *type,
- char *script)
-{
- table_set (m->action_types, type, script);
- return NULL;
-}
-
-const char *set_script (cmd_parms *cmd, action_dir_config *m, char *method,
- char *script)
-{
- if (!strcmp(method, "GET"))
- m->get = pstrdup(cmd->pool, script);
- else if (!strcmp(method, "POST"))
- m->post = pstrdup(cmd->pool, script);
- else if (!strcmp(method, "PUT"))
- m->put = pstrdup(cmd->pool, script);
- else if (!strcmp(method, "DELETE"))
- m->delete = pstrdup(cmd->pool, script);
- else
- return "Unknown method type for Script";
-
- return NULL;
-}
-
-command_rec action_cmds[] = {
-{ "Action", add_action, NULL, OR_FILEINFO, TAKE2,
- "a media type followed by a script name" },
-{ "Script", set_script, NULL, ACCESS_CONF|RSRC_CONF, TAKE2,
- "a method followed by a script name" },
-{ NULL }
-};
-
-int action_handler (request_rec *r)
-{
- action_dir_config *conf =
- (action_dir_config *)get_module_config(r->per_dir_config,&action_module);
- char *t, *action = r->handler ? r->handler : r->content_type;
- char *script = NULL;
-
- /* Set allowed stuff */
- if (conf->get) r->allowed |= (1 << M_GET);
- if (conf->post) r->allowed |= (1 << M_POST);
- if (conf->put) r->allowed |= (1 << M_PUT);
- if (conf->delete) r->allowed |= (1 << M_DELETE);
-
- /* First, check for the method-handling scripts */
- if ((r->method_number == M_GET) && r->args && conf->get)
- script = conf->get;
- else if ((r->method_number == M_POST) && conf->post)
- script = conf->post;
- else if ((r->method_number == M_PUT) && conf->put)
- script = conf->put;
- else if ((r->method_number == M_DELETE) && conf->delete)
- script = conf->delete;
-
- /* Check for looping, which can happen if the CGI script isn't */
- if (script && r->prev && r->prev->prev)
- return DECLINED;
-
- /* Second, check for actions (which override the method scripts) */
- if ((t = table_get(conf->action_types,
- action ? action : default_type(r)))) {
- script = t;
- if (r->finfo.st_mode == 0) {
- log_reason("File does not exist", r->filename, r);
- return NOT_FOUND;
- }
- }
-
- if (script == NULL)
- return DECLINED;
-
- internal_redirect_handler(pstrcat(r->pool, script, escape_uri(r->pool,
- r->uri), r->args ? "?" : NULL, r->args, NULL), r);
- return OK;
-}
-
-handler_rec action_handlers[] = {
-{ "*/*", action_handler },
-{ NULL }
-};
-
-module action_module = {
- STANDARD_MODULE_STUFF,
- NULL, /* initializer */
- create_action_dir_config, /* dir config creater */
- merge_action_dir_configs, /* dir merger --- default is to override */
- NULL, /* server config */
- NULL, /* merge server config */
- action_cmds, /* command table */
- action_handlers, /* handlers */
- NULL, /* filename translation */
- NULL, /* check_user_id */
- NULL, /* check auth */
- NULL, /* check access */
- NULL, /* type_checker */
- NULL, /* fixups */
- NULL, /* logger */
- NULL /* header parser */
-};
diff --git a/usr.sbin/httpd/src/mod_alias.c b/usr.sbin/httpd/src/mod_alias.c
deleted file mode 100644
index 2d96fd713fd..00000000000
--- a/usr.sbin/httpd/src/mod_alias.c
+++ /dev/null
@@ -1,329 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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_alias.c: Stuff for dealing with directory aliases
- *
- * Original by Rob McCool, rewritten in succession by David Robinson
- * and rst.
- *
- */
-
-#include "httpd.h"
-#include "http_config.h"
-
-typedef struct {
- char *real;
- char *fake;
- char *handler;
- int redir_status; /* 301, 302, 303, 410, etc */
-} alias_entry;
-
-typedef struct {
- array_header *aliases;
- array_header *redirects;
-} alias_server_conf;
-
-typedef struct {
- array_header *redirects;
-} alias_dir_conf;
-module alias_module;
-
-void *create_alias_config (pool *p, server_rec *s)
-{
- alias_server_conf *a =
- (alias_server_conf *)pcalloc (p, sizeof(alias_server_conf));
-
- a->aliases = make_array (p, 20, sizeof(alias_entry));
- a->redirects = make_array (p, 20, sizeof(alias_entry));
- return a;
-}
-
-void *create_alias_dir_config (pool *p, char *d)
-{
- alias_dir_conf *a =
- (alias_dir_conf *)pcalloc (p, sizeof(alias_dir_conf));
- a->redirects = make_array (p, 2, sizeof(alias_entry));
- return a;
-}
-void *merge_alias_config (pool *p, void *basev, void *overridesv)
-{
- alias_server_conf *a =
- (alias_server_conf *)pcalloc (p, sizeof(alias_server_conf));
- alias_server_conf *base = (alias_server_conf *)basev,
- *overrides = (alias_server_conf *)overridesv;
-
- a->aliases = append_arrays (p, overrides->aliases, base->aliases);
- a->redirects = append_arrays (p, overrides->redirects, base->redirects);
- return a;
-}
-
-void *merge_alias_dir_config (pool *p, void *basev, void *overridesv)
-{
- alias_dir_conf *a =
- (alias_dir_conf *)pcalloc (p, sizeof(alias_dir_conf));
- alias_dir_conf *base = (alias_dir_conf *)basev,
- *overrides = (alias_dir_conf *)overridesv;
- a->redirects = append_arrays (p, overrides->redirects, base->redirects);
- return a;
-}
-
-const char *add_alias(cmd_parms *cmd, void *dummy, char *f, char *r)
-{
- server_rec *s = cmd->server;
- alias_server_conf *conf =
- (alias_server_conf *)get_module_config(s->module_config,&alias_module);
- alias_entry *new = push_array (conf->aliases);
-
- /* XX r can NOT be relative to DocumentRoot here... compat bug. */
-
- new->fake = f; new->real = r; new->handler = cmd->info;
- return NULL;
-}
-
-const char *add_redirect(cmd_parms *cmd, alias_dir_conf *dirconf, char *arg1,
- char *arg2, char *arg3)
-{
- alias_entry *new;
- server_rec *s = cmd->server;
- alias_server_conf *serverconf =
- (alias_server_conf *)get_module_config(s->module_config,&alias_module);
- int status = (int)cmd->info;
- char *f = arg2;
- char *url = arg3;
-
- if (!strcasecmp(arg1, "gone"))
- status = HTTP_GONE;
- else if (!strcasecmp(arg1, "permanent"))
- status = HTTP_MOVED_PERMANENTLY;
- else if (!strcasecmp(arg1, "temp"))
- status = HTTP_MOVED_TEMPORARILY;
- else if (!strcasecmp(arg1, "seeother"))
- status = HTTP_SEE_OTHER;
- else if (isdigit(*arg1))
- status = atoi(arg1);
- else {
- f = arg1;
- url = arg2;
- }
-
- if (is_HTTP_REDIRECT(status)) {
- if (!url) return "URL to redirect to is missing";
- if (!is_url (url)) return "Redirect to non-URL";
- }
- else {
- if (url) return "Redirect URL not valid for this status";
- }
-
- if ( cmd->path )
- new = push_array (dirconf->redirects);
- else
- new = push_array (serverconf->redirects);
-
- new->fake = f; new->real = url;
- new->redir_status = status;
- return NULL;
-}
-
-command_rec alias_cmds[] = {
-{ "Alias", add_alias, NULL, RSRC_CONF, TAKE2,
- "a fakename and a realname"},
-{ "ScriptAlias", add_alias, "cgi-script", RSRC_CONF, TAKE2,
- "a fakename and a realname"},
-{ "Redirect", add_redirect, (void*)HTTP_MOVED_TEMPORARILY,
- OR_FILEINFO, TAKE23,
- "an optional status, then document to be redirected and destination URL" },
-{ "RedirectTemp", add_redirect, (void*)HTTP_MOVED_TEMPORARILY,
- OR_FILEINFO, TAKE2,
- "a document to be redirected, then the destination URL" },
-{ "RedirectPermanent", add_redirect, (void*)HTTP_MOVED_PERMANENTLY,
- OR_FILEINFO, TAKE2,
- "a document to be redirected, then the destination URL" },
-{ NULL }
-};
-
-int alias_matches (char *uri, char *alias_fakename)
-{
- char *end_fakename = alias_fakename + strlen (alias_fakename);
- char *aliasp = alias_fakename, *urip = uri;
-
- while (aliasp < end_fakename) {
- if (*aliasp == '/') {
- /* any number of '/' in the alias matches any number in
- * the supplied URI, but there must be at least one...
- */
- if (*urip != '/') return 0;
-
- while (*aliasp == '/') ++ aliasp;
- while (*urip == '/') ++ urip;
- }
- else {
- /* Other characters are compared literally */
- if (*urip++ != *aliasp++) return 0;
- }
- }
-
- /* Check last alias path component matched all the way */
-
- if (aliasp[-1] != '/' && *urip != '\0' && *urip != '/')
- return 0;
-
- /* Return number of characters from URI which matched (may be
- * greater than length of alias, since we may have matched
- * doubled slashes)
- */
-
- return urip - uri;
-}
-
-char *try_alias_list (request_rec *r, array_header *aliases, int doesc, int *status)
-{
- alias_entry *entries = (alias_entry *)aliases->elts;
- int i;
-
- for (i = 0; i < aliases->nelts; ++i) {
- alias_entry *p = &entries[i];
- int l = alias_matches (r->uri, p->fake);
-
- if (l > 0) {
- if (p->handler) { /* Set handler, and leave a note for mod_cgi */
- r->handler = pstrdup(r->pool, p->handler);
- table_set (r->notes, "alias-forced-type", p->handler);
- }
-
- *status = p->redir_status;
-
- if (doesc) {
- char *escurl;
- escurl = os_escape_path(r->pool, r->uri + l, 1);
-
- return pstrcat(r->pool, p->real, escurl, NULL);
- } else
- return pstrcat(r->pool, p->real, r->uri + l, NULL);
- }
- }
-
- return NULL;
-}
-
-int translate_alias_redir(request_rec *r)
-{
- void *sconf = r->server->module_config;
- alias_server_conf *serverconf =
- (alias_server_conf *)get_module_config(sconf, &alias_module);
- char *ret;
- int status;
-
-#ifdef __EMX__
- /* Add support for OS/2 drive names */
- if ((r->uri[0] != '/' && r->uri[0] != '\0') && r->uri[1] != ':')
-#else
- if (r->uri[0] != '/' && r->uri[0] != '\0')
-#endif
- return DECLINED;
-
- if ((ret = try_alias_list (r, serverconf->redirects, 1, &status)) != NULL) {
- if (is_HTTP_REDIRECT(status)) {
- /* include QUERY_STRING if any */
- if (r->args) {
- ret = pstrcat (r->pool, ret, "?", r->args, NULL);
- }
- table_set (r->headers_out, "Location", ret);
- }
- return status;
- }
-
- if ((ret = try_alias_list (r, serverconf->aliases, 0, &status)) != NULL) {
- r->filename = ret;
- return OK;
- }
-
- return DECLINED;
-}
-
-int fixup_redir(request_rec *r)
-{
- void *dconf = r->per_dir_config;
- alias_dir_conf *dirconf =
- (alias_dir_conf *)get_module_config(dconf, &alias_module);
- char *ret;
- int status;
-
- /* It may have changed since last time, so try again */
-
- if ((ret = try_alias_list (r, dirconf->redirects, 1, &status)) != NULL) {
- if (is_HTTP_REDIRECT(status))
- table_set (r->headers_out, "Location", ret);
- return status;
- }
-
- return DECLINED;
-}
-
-module alias_module = {
- STANDARD_MODULE_STUFF,
- NULL, /* initializer */
- create_alias_dir_config, /* dir config creater */
- merge_alias_dir_config, /* dir merger --- default is to override */
- create_alias_config, /* server config */
- merge_alias_config, /* merge server configs */
- alias_cmds, /* command table */
- NULL, /* handlers */
- translate_alias_redir, /* filename translation */
- NULL, /* check_user_id */
- NULL, /* check auth */
- NULL, /* check access */
- NULL, /* type_checker */
- fixup_redir, /* fixups */
- NULL, /* logger */
- NULL /* header parser */
-};
diff --git a/usr.sbin/httpd/src/mod_asis.c b/usr.sbin/httpd/src/mod_asis.c
deleted file mode 100644
index 47bf206d137..00000000000
--- a/usr.sbin/httpd/src/mod_asis.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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/>.
- *
- */
-
-#include "httpd.h"
-#include "http_config.h"
-#include "http_protocol.h"
-#include "http_log.h"
-#include "util_script.h"
-#include "http_main.h"
-#include "http_request.h"
-
-int asis_handler (request_rec *r)
-{
- FILE *f;
- char *location;
-
- r->allowed |= (1 << M_GET);
- if (r->method_number != M_GET) return DECLINED;
- if (r->finfo.st_mode == 0) {
- log_reason("File does not exist", r->filename, r);
- return NOT_FOUND;
- }
-
- f = pfopen (r->pool, r->filename, "r");
-
- if (f == NULL) {
- log_reason("file permissions deny server access", r->filename, r);
- return FORBIDDEN;
- }
-
- scan_script_header (r, f);
- location = table_get (r->headers_out, "Location");
-
- if (location && location[0] == '/' &&
- ((r->status == HTTP_OK) || is_HTTP_REDIRECT(r->status))) {
-
- pfclose(r->pool, f);
-
- /* Internal redirect -- fake-up a pseudo-request */
- r->status = HTTP_OK;
-
- /* This redirect needs to be a GET no matter what the original
- * method was.
- */
- r->method = pstrdup(r->pool, "GET");
- r->method_number = M_GET;
-
- internal_redirect_handler (location, r);
- return OK;
- }
-
- send_http_header (r);
- if (!r->header_only) send_fd (f, r);
-
- pfclose(r->pool, f);
- return OK;
-}
-
-handler_rec asis_handlers[] = {
-{ ASIS_MAGIC_TYPE, asis_handler },
-{ "send-as-is", asis_handler },
-{ NULL }
-};
-
-module asis_module = {
- STANDARD_MODULE_STUFF,
- NULL, /* initializer */
- NULL, /* create per-directory config structure */
- NULL, /* merge per-directory config structures */
- NULL, /* create per-server config structure */
- NULL, /* merge per-server config structures */
- NULL, /* command table */
- asis_handlers, /* handlers */
- NULL, /* translate_handler */
- NULL, /* check_user_id */
- NULL, /* check auth */
- NULL, /* check access */
- NULL, /* type_checker */
- NULL, /* pre-run fixups */
- NULL, /* logger */
- NULL /* header parser */
-};
diff --git a/usr.sbin/httpd/src/mod_auth.c b/usr.sbin/httpd/src/mod_auth.c
deleted file mode 100644
index acacaf07b2f..00000000000
--- a/usr.sbin/httpd/src/mod_auth.c
+++ /dev/null
@@ -1,298 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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_auth: authentication
- *
- * Rob McCool
- *
- * Adapted to Apache by rst.
- *
- * dirkx - Added Authoritative control to allow passing on to lower
- * modules if and only if the user-id is not known to this
- * module. A known user with a faulty or absent password still
- * causes an AuthRequired. The default is 'Authoritative', i.e.
- * no control is passed along.
- */
-
-#include "httpd.h"
-#include "http_config.h"
-#include "http_core.h"
-#include "http_log.h"
-#include "http_protocol.h"
-#if defined(HAVE_CRYPT_H)
-#include <crypt.h>
-#endif
-
-typedef struct auth_config_struct {
- char *auth_pwfile;
- char *auth_grpfile;
- int auth_authoritative;
-} auth_config_rec;
-
-void *create_auth_dir_config (pool *p, char *d)
-{
- auth_config_rec *sec =
- (auth_config_rec *) pcalloc (p, sizeof(auth_config_rec));
- sec->auth_pwfile = NULL; /* just to illustrate the default really */
- sec->auth_grpfile = NULL; /* unless you have a broken HP cc */
- sec->auth_authoritative = 1; /* keep the fortress secure by default */
- return sec;
-}
-
-const char *set_auth_slot (cmd_parms *cmd, void *offset, char *f, char *t)
-{
- if (t && strcmp(t, "standard"))
- return pstrcat(cmd->pool, "Invalid auth file type: ", t, NULL);
-
- return set_string_slot(cmd, offset, f);
-}
-
-command_rec auth_cmds[] = {
-{ "AuthUserFile", set_auth_slot,
- (void*)XtOffsetOf(auth_config_rec,auth_pwfile), OR_AUTHCFG, TAKE12, NULL },
-{ "AuthGroupFile", set_auth_slot,
- (void*)XtOffsetOf(auth_config_rec,auth_grpfile), OR_AUTHCFG, TAKE12, NULL },
-{ "AuthAuthoritative", set_flag_slot,
- (void*)XtOffsetOf(auth_config_rec,auth_authoritative),
- OR_AUTHCFG, FLAG,
- "Set to 'no' to allow access control to be passed along to lower modules if the UserID is not known to this module" },
-{ NULL }
-};
-
-module auth_module;
-
-char *get_pw(request_rec *r, char *user, char *auth_pwfile)
-{
- FILE *f;
- char l[MAX_STRING_LEN];
- const char *rpw, *w;
-
- if(!(f=pfopen(r->pool, auth_pwfile, "r"))) {
- log_reason ("Could not open password file", auth_pwfile, r);
- return NULL;
- }
- while(!(cfg_getline(l,MAX_STRING_LEN,f))) {
- if((l[0] == '#') || (!l[0])) continue;
- rpw = l;
- w = getword(r->pool, &rpw, ':');
-
- if(!strcmp(user,w)) {
- pfclose(r->pool, f);
- return pstrdup (r->pool, rpw);
- }
- }
- pfclose(r->pool, f);
- return NULL;
-}
-
-table *groups_for_user (pool *p, char *user, char *grpfile) {
- FILE *f;
- table *grps = make_table (p, 15);
- pool *sp;
- char l[MAX_STRING_LEN];
- const char *group_name, *ll, *w;
-
- if(!(f=pfopen(p, grpfile, "r")))
- return NULL;
-
- sp = make_sub_pool (p);
-
- while(!(cfg_getline(l,MAX_STRING_LEN,f))) {
- if((l[0] == '#') || (!l[0])) continue;
- ll = l;
- clear_pool (sp);
-
- group_name = getword(sp, &ll, ':');
-
- while(ll[0]) {
- w = getword_conf (sp, &ll);
- if(!strcmp(w,user)) {
- table_set (grps, group_name, "in");
- break;
- }
- }
- }
- pfclose(p, f);
- destroy_pool (sp);
- return grps;
-}
-
-/* These functions return 0 if client is OK, and proper error status
- * if not... either AUTH_REQUIRED, if we made a check, and it failed, or
- * SERVER_ERROR, if things are so totally confused that we couldn't
- * figure out how to tell if the client is authorized or not.
- *
- * If they return DECLINED, and all other modules also decline, that's
- * treated by the server core as a configuration error, logged and
- * reported as such.
- */
-
-/* Determine user ID, and check if it really is that user, for HTTP
- * basic authentication...
- */
-
-int authenticate_basic_user (request_rec *r)
-{
- auth_config_rec *sec =
- (auth_config_rec *)get_module_config (r->per_dir_config, &auth_module);
- conn_rec *c = r->connection;
- char *sent_pw, *real_pw;
- char errstr[MAX_STRING_LEN];
- int res;
-
- if ((res = get_basic_auth_pw (r, &sent_pw))) return res;
-
- if(!sec->auth_pwfile)
- return DECLINED;
-
- if (!(real_pw = get_pw(r, c->user, sec->auth_pwfile))) {
- if (!(sec->auth_authoritative))
- return DECLINED;
- ap_snprintf(errstr, sizeof(errstr), "user %s not found",c->user);
- log_reason (errstr, r->uri, r);
- note_basic_auth_failure (r);
- return AUTH_REQUIRED;
- }
- /* anyone know where the prototype for crypt is? */
- if(strcmp(real_pw,(char *)crypt(sent_pw,real_pw))) {
- ap_snprintf(errstr, sizeof(errstr), "user %s: password mismatch",c->user);
- log_reason (errstr, r->uri, r);
- note_basic_auth_failure (r);
- return AUTH_REQUIRED;
- }
- return OK;
-}
-
-/* Checking ID */
-
-int check_user_access (request_rec *r) {
- auth_config_rec *sec =
- (auth_config_rec *)get_module_config (r->per_dir_config, &auth_module);
- char *user = r->connection->user;
- int m = r->method_number;
- int method_restricted = 0;
- register int x;
- const char *t, *w;
- table *grpstatus;
- array_header *reqs_arr = requires (r);
- require_line *reqs;
-
- /* BUG FIX: tadc, 11-Nov-1995. If there is no "requires" directive,
- * then any user will do.
- */
- if (!reqs_arr)
- return (OK);
- reqs = (require_line *)reqs_arr->elts;
-
- if(sec->auth_grpfile)
- grpstatus = groups_for_user (r->pool, user, sec->auth_grpfile);
- else
- grpstatus = NULL;
-
- for(x=0; x < reqs_arr->nelts; x++) {
-
- if (! (reqs[x].method_mask & (1 << m))) continue;
-
- method_restricted = 1;
-
- t = reqs[x].requirement;
- w = getword(r->pool, &t, ' ');
- if(!strcmp(w,"valid-user"))
- return OK;
- if(!strcmp(w,"user")) {
- while(t[0]) {
- w = getword_conf (r->pool, &t);
- if(!strcmp(user,w))
- return OK;
- }
- }
- else if(!strcmp(w,"group")) {
- if(!grpstatus)
- return DECLINED; /* DBM group? Something else? */
-
- while(t[0]) {
- w = getword_conf(r->pool, &t);
- if(table_get (grpstatus, w))
- return OK;
- }
- }
- }
-
- if (!method_restricted)
- return OK;
-
- if (!(sec -> auth_authoritative))
- return DECLINED;
-
- note_basic_auth_failure (r);
- return AUTH_REQUIRED;
-}
-
-module auth_module = {
- STANDARD_MODULE_STUFF,
- NULL, /* initializer */
- create_auth_dir_config, /* dir config creater */
- NULL, /* dir merger --- default is to override */
- NULL, /* server config */
- NULL, /* merge server config */
- auth_cmds, /* command table */
- NULL, /* handlers */
- NULL, /* filename translation */
- authenticate_basic_user, /* check_user_id */
- check_user_access, /* check auth */
- NULL, /* check access */
- NULL, /* type_checker */
- NULL, /* fixups */
- NULL, /* logger */
- NULL /* header parser */
-};
diff --git a/usr.sbin/httpd/src/mod_auth_anon.c b/usr.sbin/httpd/src/mod_auth_anon.c
deleted file mode 100644
index 2bb90b4d823..00000000000
--- a/usr.sbin/httpd/src/mod_auth_anon.c
+++ /dev/null
@@ -1,299 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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
- * IT'S 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_auth: authentication
- *
- * Rob McCool & Brian Behlendorf.
- *
- * Adapted to Apache by rst.
- *
- * Version 0.5 May 1996
- *
- * Modified by Dirk.vanGulik@jrc.it to
- *
- * Adapted to allow anonymous logins, just like with Anon-FTP, when
- * one gives the magic user name 'anonymous' and ones email address
- * as the password.
- *
- * Just add the following tokes to your <directory> setup:
- *
- * Anonymous magic-user-id [magic-user-id]...
- *
- * Anonymous_MustGiveEmail [ on | off ] default = off
- * Anonymous_LogEmail [ on | off ] default = on
- * Anonymous_VerifyEmail [ on | off ] default = off
- * Anonymous_NoUserId [ on | off ] default = off
- * Anonymous_Authoritative [ on | off ] default = off
- *
- * The magic user id is something like 'anonymous', it is NOT case sensitive.
- *
- * The MustGiveEmail flag can be used to force users to enter something
- * in the password field (like an email address). Default is off.
- *
- * Furthermore the 'NoUserID' flag can be set to allow completely empty
- * usernames in as well; this can be is convenient as a single return
- * in broken GUIs like W95 is often given by the user. The Default is off.
- *
- * Dirk.vanGulik@jrc.it; http://ewse.ceo.org; http://me-www.jrc.it/~dirkx
- *
- */
-
-#include "httpd.h"
-#include "http_config.h"
-#include "http_core.h"
-#include "http_log.h"
-#include "http_protocol.h"
-
-typedef struct auth_anon {
- char *password;
- struct auth_anon * next;
- } auth_anon;
-
-typedef struct {
-
- auth_anon *auth_anon_passwords;
- int auth_anon_nouserid;
- int auth_anon_logemail;
- int auth_anon_verifyemail;
- int auth_anon_mustemail;
- int auth_anon_authoritative;
-
-} anon_auth_config_rec;
-
-void *create_anon_auth_dir_config (pool *p, char *d)
-{
- anon_auth_config_rec * sec = (anon_auth_config_rec *)
- pcalloc (p, sizeof(anon_auth_config_rec));
-
- if (!sec) return NULL; /* no memory... */
-
- /* just to illustrate the defaults really. */
- sec -> auth_anon_passwords =NULL;
-
- sec -> auth_anon_nouserid =0;
- sec -> auth_anon_logemail =1;
- sec -> auth_anon_verifyemail =0;
- sec -> auth_anon_mustemail =1;
- sec -> auth_anon_authoritative =0;
- return sec;
-}
-
-const char *anon_set_passwd_flag (cmd_parms *cmd,
- anon_auth_config_rec *sec, int arg) {
- sec->auth_anon_mustemail=arg;
- return NULL;
-}
-
-const char *anon_set_userid_flag (cmd_parms *cmd,
- anon_auth_config_rec *sec, int arg) {
- sec->auth_anon_nouserid=arg;
- return NULL;
-}
-const char *anon_set_logemail_flag (cmd_parms *cmd,
- anon_auth_config_rec *sec, int arg) {
- sec->auth_anon_logemail=arg;
- return NULL;
-}
-const char *anon_set_verifyemail_flag (cmd_parms *cmd,
- anon_auth_config_rec *sec, int arg) {
- sec->auth_anon_verifyemail=arg;
- return NULL;
-}
-const char *anon_set_authoritative_flag (cmd_parms *cmd,
- anon_auth_config_rec *sec, int arg) {
- sec->auth_anon_authoritative=arg;
- return NULL;
-}
-
-const char *anon_set_string_slots (cmd_parms *cmd,
- anon_auth_config_rec *sec, char *arg) {
-
- auth_anon * first;
-
- if (!(*arg))
- return "Anonymous string cannot be empty, use Anonymous_NoUserId instead";
-
- /* squeeze in a record */
- first = sec->auth_anon_passwords;
-
- if (
- (!(sec->auth_anon_passwords=(auth_anon *) palloc(cmd -> pool, sizeof(auth_anon)))) ||
- (!(sec->auth_anon_passwords->password = pstrdup(cmd -> pool, arg)))
- ) return "Failed to claim memory for an anonymous password...";
-
- /* and repair the next */
- sec->auth_anon_passwords->next = first;
-
- return NULL;
-}
-
-command_rec anon_auth_cmds[] = {
-{ "Anonymous", anon_set_string_slots,
- NULL,OR_AUTHCFG, ITERATE, NULL },
-{ "Anonymous_MustGiveEmail", anon_set_passwd_flag, NULL, OR_AUTHCFG, FLAG,
- "Limited to 'on' or 'off'" },
-{ "Anonymous_NoUserId", anon_set_userid_flag, NULL, OR_AUTHCFG, FLAG,
- "Limited to 'on' or 'off'" },
-{ "Anonymous_VerifyEmail", anon_set_verifyemail_flag, NULL, OR_AUTHCFG, FLAG,
- "Limited to 'on' or 'off'" },
-{ "Anonymous_LogEmail", anon_set_logemail_flag, NULL, OR_AUTHCFG, FLAG,
- "Limited to 'on' or 'off'" },
-{ "Anonymous_Authoritative", anon_set_authoritative_flag, NULL, OR_AUTHCFG, FLAG,
- "Limited to 'on' or 'off'" },
-
-{ NULL }
-};
-
-module anon_auth_module;
-
-int anon_authenticate_basic_user (request_rec *r)
-{
- anon_auth_config_rec *sec =
- (anon_auth_config_rec *)get_module_config (r->per_dir_config,
- &anon_auth_module);
- conn_rec *c = r->connection;
- char *send_pw;
- char errstr[MAX_STRING_LEN];
- int res=DECLINED;
-
-
- if ((res=get_basic_auth_pw (r,&send_pw)))
- return res;
-
- /* Ignore if we are not configured */
- if (!sec->auth_anon_passwords) return DECLINED;
-
- /* Do we allow an empty userID and/or is it the magic one
- */
-
- if ( (!(c->user[0])) && (sec->auth_anon_nouserid) ) {
- res=OK;
- } else {
- auth_anon *p=sec->auth_anon_passwords;
- res=DECLINED;
- while ((res == DECLINED) && (p !=NULL)) {
- if (!(strcasecmp(c->user,p->password)))
- res=OK;
- p=p->next;
- }
- }
- if (
- /* username is OK */
- (res == OK) &&
- /* password been filled out ? */
- ( (!sec->auth_anon_mustemail) || strlen(send_pw) ) &&
- /* does the password look like an email address ? */
- ( (!sec->auth_anon_verifyemail) ||
- ((strpbrk("@",send_pw) != NULL)
- &&
- (strpbrk(".",send_pw) != NULL))
- )
- ) {
- if (sec->auth_anon_logemail && r->prev == NULL && r->main == NULL) {
- ap_snprintf(errstr, sizeof(errstr), "Anonymous: Passwd <%s> Accepted",
- send_pw ? send_pw : "\'none\'");
- log_error (errstr, r->server );
- }
- return OK;
- } else {
- if (sec->auth_anon_authoritative) {
- ap_snprintf(errstr, sizeof(errstr),
- "Anonymous: Authoritative, Passwd <%s> not accepted",
- send_pw ? send_pw : "\'none\'");
- log_error(errstr,r->server);
- return AUTH_REQUIRED;
- }
- /* Drop out the bottom to return DECLINED */
- }
-
-
- return DECLINED;
-}
-
-int check_anon_access (request_rec *r) {
-
-#ifdef NOTYET
- conn_rec *c = r->connection;
- anon_auth_config_rec *sec =
- (anon_auth_config_rec *)get_module_config (r->per_dir_config,
- &anon_auth_module);
-
- if (!sec->auth_anon) return DECLINED;
-
- if ( strcasecmp(r->connection->user,sec->auth_anon ))
- return DECLINED;
-
- return OK;
-#endif
- return DECLINED;
-}
-
-
-module anon_auth_module = {
- STANDARD_MODULE_STUFF,
- NULL, /* initializer */
- create_anon_auth_dir_config, /* dir config creater */
- NULL, /* dir merger ensure strictness */
- NULL, /* server config */
- NULL, /* merge server config */
- anon_auth_cmds, /* command table */
- NULL, /* handlers */
- NULL, /* filename translation */
- anon_authenticate_basic_user,/* check_user_id */
- check_anon_access, /* check auth */
- NULL, /* check access */
- NULL, /* type_checker */
- NULL, /* fixups */
- NULL, /* logger */
- NULL /* header parser */
-};
diff --git a/usr.sbin/httpd/src/mod_auth_db.c b/usr.sbin/httpd/src/mod_auth_db.c
deleted file mode 100644
index 76d21d7ea6c..00000000000
--- a/usr.sbin/httpd/src/mod_auth_db.c
+++ /dev/null
@@ -1,303 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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
- * IT'S 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_auth_db: authentication
- *
- * Original work by Rob McCool & Brian Behlendorf.
- *
- * Adapted to Apache by rst (mod_auth_dbm)
- *
- * Adapted for Berkeley DB by Andrew Cohen
- *
- * mod_auth_db was based on mod_auth_dbm.
- *
- * Warning, this is not a drop in replacement for mod_auth_dbm,
- * for people wanting to switch from dbm to Berkeley DB.
- * It requires the use of AuthDBUserFile and AuthDBGroupFile
- * instead of AuthDBMUserFile AuthDBMGroupFile
- *
- * Also, in the configuration file you need to specify
- * db_auth_module rather than dbm_auth_module
- *
- * On some BSD systems (e.g. FreeBSD and NetBSD) dbm is automatically
- * mapped to Berkeley DB. You can use either mod_auth_dbm or
- * mod_auth_db. The latter makes it more obvious that it's Berkeley.
- *
- * dirkx - Added Authoritative control to allow passing on to lower
- * modules if and only if the user-id is not known to this
- * module. A known user with a faulty or absent password still
- * causes an AuthRequired. The default is 'Authoritative', i.e.
- * no control is passed along.
- */
-
-#include "httpd.h"
-#include "http_config.h"
-#include "http_core.h"
-#include "http_log.h"
-#include "http_protocol.h"
-#include <db.h>
-
-typedef struct {
-
- char *auth_dbpwfile;
- char *auth_dbgrpfile;
- int auth_dbauthoritative;
-} db_auth_config_rec;
-
-void *create_db_auth_dir_config (pool *p, char *d)
-{
- db_auth_config_rec *sec
- = (db_auth_config_rec *)pcalloc (p, sizeof(db_auth_config_rec));
- sec->auth_dbpwfile = NULL;
- sec->auth_dbgrpfile = NULL;
- sec->auth_dbauthoritative=1; /* fortress is secure by default */
- return sec;
-}
-
-const char *set_db_slot (cmd_parms *cmd, void *offset, char *f, char *t)
-{
- if (!t || strcmp(t, "db"))
- return DECLINE_CMD;
-
- return set_string_slot(cmd, offset, f);
-}
-
-command_rec db_auth_cmds[] = {
-{ "AuthDBUserFile", set_string_slot,
- (void*)XtOffsetOf(db_auth_config_rec, auth_dbpwfile),
- OR_AUTHCFG, TAKE1, NULL },
-{ "AuthDBGroupFile", set_string_slot,
- (void*)XtOffsetOf(db_auth_config_rec, auth_dbgrpfile),
- OR_AUTHCFG, TAKE1, NULL },
-{ "AuthUserFile", set_db_slot,
- (void*)XtOffsetOf(db_auth_config_rec, auth_dbpwfile),
- OR_AUTHCFG, TAKE12, NULL },
-{ "AuthGroupFile", set_db_slot,
- (void*)XtOffsetOf(db_auth_config_rec, auth_dbgrpfile),
- OR_AUTHCFG, TAKE12, NULL },
-{ "AuthDBAuthoritative", set_flag_slot,
- (void*)XtOffsetOf(db_auth_config_rec, auth_dbauthoritative),
- OR_AUTHCFG, FLAG,
- "Set to 'no' to allow access control to be passed along to lower modules if the userID is not known to this module" },
-{ NULL }
-};
-
-module db_auth_module;
-
-char *get_db_pw(request_rec *r, char *user, const char *auth_dbpwfile) {
- DB *f;
- DBT d, q;
- char *pw = NULL;
-
- q.data = user;
- q.size = strlen(q.data);
-
- if(!(f=dbopen(auth_dbpwfile,O_RDONLY,0664,DB_HASH,NULL))) {
- log_reason ("could not open db auth file", (char *) auth_dbpwfile, r);
- return NULL;
- }
-
- if (!((f->get)(f,&q,&d,0))) {
- pw = palloc (r->pool, d.size + 1);
- strncpy(pw,d.data,d.size);
- pw[d.size] = '\0'; /* Terminate the string */
- }
-
- (f->close)(f);
- return pw;
-}
-
-/* We do something strange with the group file. If the group file
- * contains any : we assume the format is
- * key=username value=":"groupname [":"anything here is ignored]
- * otherwise we now (0.8.14+) assume that the format is
- * key=username value=groupname
- * The first allows the password and group files to be the same
- * physical DB file; key=username value=password":"groupname[":"anything]
- *
- * mark@telescope.org, 22Sep95
- */
-
-char *get_db_grp(request_rec *r, char *user, const char *auth_dbgrpfile) {
- char *grp_data = get_db_pw (r, user, auth_dbgrpfile);
- char *grp_colon; char *grp_colon2;
-
- if (grp_data == NULL) return NULL;
-
- if ((grp_colon = strchr(grp_data, ':'))!=NULL) {
- grp_colon2 = strchr(++grp_colon, ':');
- if (grp_colon2) *grp_colon2='\0';
- return grp_colon;
- }
- return grp_data;
-}
-
-int db_authenticate_basic_user (request_rec *r)
-{
- db_auth_config_rec *sec =
- (db_auth_config_rec *)get_module_config (r->per_dir_config,
- &db_auth_module);
- conn_rec *c = r->connection;
- char *sent_pw, *real_pw, *colon_pw;
- char errstr[MAX_STRING_LEN];
- int res;
-
- if ((res = get_basic_auth_pw (r, &sent_pw)))
- return res;
-
- if(!sec->auth_dbpwfile)
- return DECLINED;
-
- if(!(real_pw = get_db_pw(r, c->user, sec->auth_dbpwfile))) {
- if (!(sec -> auth_dbauthoritative))
- return DECLINED;
- ap_snprintf(errstr, sizeof(errstr), "DB user %s not found", c->user);
- log_reason (errstr, r->filename, r);
- note_basic_auth_failure (r);
- return AUTH_REQUIRED;
- }
- /* Password is up to first : if exists */
- colon_pw = strchr(real_pw,':');
- if (colon_pw) *colon_pw='\0';
- /* anyone know where the prototype for crypt is? */
- if(strcmp(real_pw,(char *)crypt(sent_pw,real_pw))) {
- ap_snprintf(errstr, sizeof(errstr),
- "user %s: password mismatch",c->user);
- log_reason (errstr, r->uri, r);
- note_basic_auth_failure (r);
- return AUTH_REQUIRED;
- }
- return OK;
-}
-
-/* Checking ID */
-
-int db_check_auth(request_rec *r) {
- db_auth_config_rec *sec =
- (db_auth_config_rec *)get_module_config (r->per_dir_config,
- &db_auth_module);
- char *user = r->connection->user;
- int m = r->method_number;
- char errstr[MAX_STRING_LEN];
-
- array_header *reqs_arr = requires (r);
- require_line *reqs = reqs_arr ? (require_line *)reqs_arr->elts : NULL;
-
- register int x;
- const char *t;
- char *w;
-
- if (!sec->auth_dbgrpfile) return DECLINED;
- if (!reqs_arr) return DECLINED;
-
- for(x=0; x < reqs_arr->nelts; x++) {
-
- if (! (reqs[x].method_mask & (1 << m))) continue;
-
- t = reqs[x].requirement;
- w = getword(r->pool, &t, ' ');
-
- if(!strcmp(w,"group") && sec->auth_dbgrpfile) {
- const char *orig_groups,*groups;
- char *v;
-
- if (!(groups = get_db_grp(r, user, sec->auth_dbgrpfile))) {
- if (!(sec->auth_dbauthoritative))
- return DECLINED;
- ap_snprintf(errstr, sizeof(errstr),
- "user %s not in DB group file %s",
- user, sec->auth_dbgrpfile);
- log_reason (errstr, r->filename, r);
- note_basic_auth_failure (r);
- return AUTH_REQUIRED;
- }
- orig_groups = groups;
- while(t[0]) {
- w = getword(r->pool, &t, ' ');
- groups = orig_groups;
- while(groups[0]) {
- v = getword(r->pool, &groups,',');
- if(!strcmp(v,w))
- return OK;
- }
- }
- ap_snprintf(errstr, sizeof(errstr),
- "user %s not in right group",user);
- log_reason (errstr, r->filename, r);
- note_basic_auth_failure(r);
- return AUTH_REQUIRED;
- }
- }
-
- return DECLINED;
-}
-
-
-module db_auth_module = {
- STANDARD_MODULE_STUFF,
- NULL, /* initializer */
- create_db_auth_dir_config, /* dir config creater */
- NULL, /* dir merger --- default is to override */
- NULL, /* server config */
- NULL, /* merge server config */
- db_auth_cmds, /* command table */
- NULL, /* handlers */
- NULL, /* filename translation */
- db_authenticate_basic_user, /* check_user_id */
- db_check_auth, /* check auth */
- NULL, /* check access */
- NULL, /* type_checker */
- NULL, /* fixups */
- NULL, /* logger */
- NULL /* header parser */
-};
diff --git a/usr.sbin/httpd/src/mod_auth_dbm.c b/usr.sbin/httpd/src/mod_auth_dbm.c
deleted file mode 100644
index d383264e9f6..00000000000
--- a/usr.sbin/httpd/src/mod_auth_dbm.c
+++ /dev/null
@@ -1,291 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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_auth: authentication
- *
- * Rob McCool & Brian Behlendorf.
- *
- * Adapted to Apache by rst.
- *
- * dirkx - Added Authoritative control to allow passing on to lower
- * modules if and only if the user-id is not known to this
- * module. A known user with a faulty or absent password still
- * causes an AuthRequired. The default is 'Authoritative', i.e.
- * no control is passed along.
- */
-
-#include "httpd.h"
-#include "http_config.h"
-#include "http_core.h"
-#include "http_log.h"
-#include "http_protocol.h"
-#include <ndbm.h>
-
-typedef struct {
-
- char *auth_dbmpwfile;
- char *auth_dbmgrpfile;
- int auth_dbmauthoritative;
-
-} dbm_auth_config_rec;
-
-void *create_dbm_auth_dir_config (pool *p, char *d)
-{
- dbm_auth_config_rec *sec
- = (dbm_auth_config_rec *)pcalloc (p, sizeof(dbm_auth_config_rec));
-
- sec->auth_dbmpwfile = NULL;
- sec->auth_dbmgrpfile = NULL;
- sec->auth_dbmauthoritative = 1; /* fortress is secure by default */
-
- return sec;
-}
-
-const char *set_dbm_slot (cmd_parms *cmd, void *offset, char *f, char *t)
-{
- if (!t || strcmp(t, "dbm"))
- return DECLINE_CMD;
-
- return set_string_slot(cmd, offset, f);
-}
-
-command_rec dbm_auth_cmds[] = {
-{ "AuthDBMUserFile", set_string_slot,
- (void*)XtOffsetOf(dbm_auth_config_rec, auth_dbmpwfile),
- OR_AUTHCFG, TAKE1, NULL },
-{ "AuthDBMGroupFile", set_string_slot,
- (void*)XtOffsetOf(dbm_auth_config_rec, auth_dbmgrpfile),
- OR_AUTHCFG, TAKE1, NULL },
-{ "AuthUserFile", set_dbm_slot,
- (void*)XtOffsetOf(dbm_auth_config_rec, auth_dbmpwfile),
- OR_AUTHCFG, TAKE12, NULL },
-{ "AuthGroupFile", set_dbm_slot,
- (void*)XtOffsetOf(dbm_auth_config_rec, auth_dbmgrpfile),
- OR_AUTHCFG, TAKE12, NULL },
-{ "AuthDBMAuthoritative", set_flag_slot,
- (void*)XtOffsetOf(dbm_auth_config_rec, auth_dbmauthoritative),
- OR_AUTHCFG, FLAG, "Set to 'no' to allow access control to be passed along to lower modules, if the UserID is not known in this module" },
-{ NULL }
-};
-
-module dbm_auth_module;
-
-char *get_dbm_pw(request_rec *r, char *user, char *auth_dbmpwfile) {
- DBM *f;
- datum d, q;
- char *pw = NULL;
-
- q.dptr = user;
- q.dsize = strlen(q.dptr);
-
- if(!(f=dbm_open(auth_dbmpwfile,O_RDONLY,0664))) {
- log_reason ("could not open dbm auth file", auth_dbmpwfile, r);
- return NULL;
- }
-
- d = dbm_fetch(f, q);
-
- if (d.dptr) {
- pw = palloc (r->pool, d.dsize + 1);
- strncpy(pw,d.dptr,d.dsize);
- pw[d.dsize] = '\0'; /* Terminate the string */
- }
-
- dbm_close(f);
- return pw;
-}
-
-/* We do something strange with the group file. If the group file
- * contains any : we assume the format is
- * key=username value=":"groupname [":"anything here is ignored]
- * otherwise we now (0.8.14+) assume that the format is
- * key=username value=groupname
- * The first allows the password and group files to be the same
- * physical DBM file; key=username value=password":"groupname[":"anything]
- *
- * mark@telescope.org, 22Sep95
- */
-
-char *get_dbm_grp(request_rec *r, char *user, char *auth_dbmgrpfile) {
- char *grp_data = get_dbm_pw (r, user, auth_dbmgrpfile);
- char *grp_colon; char *grp_colon2;
-
- if (grp_data == NULL) return NULL;
-
- if ((grp_colon = strchr(grp_data, ':'))!=NULL) {
- grp_colon2 = strchr(++grp_colon, ':');
- if (grp_colon2) *grp_colon2='\0';
- return grp_colon;
- }
- return grp_data;
-}
-
-int dbm_authenticate_basic_user (request_rec *r)
-{
- dbm_auth_config_rec *sec =
- (dbm_auth_config_rec *)get_module_config (r->per_dir_config,
- &dbm_auth_module);
- conn_rec *c = r->connection;
- char *sent_pw, *real_pw, *colon_pw;
- char errstr[MAX_STRING_LEN];
- int res;
-
- if ((res = get_basic_auth_pw (r, &sent_pw)))
- return res;
-
- if(!sec->auth_dbmpwfile)
- return DECLINED;
-
- if(!(real_pw = get_dbm_pw(r, c->user, sec->auth_dbmpwfile))) {
- if (!(sec->auth_dbmauthoritative))
- return DECLINED;
- ap_snprintf(errstr, sizeof(errstr), "DBM user %s not found", c->user);
- log_reason (errstr, r->filename, r);
- note_basic_auth_failure (r);
- return AUTH_REQUIRED;
- }
- /* Password is up to first : if exists */
- colon_pw = strchr(real_pw,':');
- if (colon_pw) *colon_pw='\0';
- /* anyone know where the prototype for crypt is? */
- if(strcmp(real_pw,(char *)crypt(sent_pw,real_pw))) {
- ap_snprintf(errstr, sizeof(errstr),
- "user %s: password mismatch",c->user);
- log_reason (errstr, r->uri, r);
- note_basic_auth_failure (r);
- return AUTH_REQUIRED;
- }
- return OK;
-}
-
-/* Checking ID */
-
-int dbm_check_auth(request_rec *r) {
- dbm_auth_config_rec *sec =
- (dbm_auth_config_rec *)get_module_config (r->per_dir_config,
- &dbm_auth_module);
- char *user = r->connection->user;
- int m = r->method_number;
- char errstr[MAX_STRING_LEN];
-
- array_header *reqs_arr = requires (r);
- require_line *reqs = reqs_arr ? (require_line *)reqs_arr->elts : NULL;
-
- register int x;
- const char *t;
- char *w;
-
- if (!sec->auth_dbmgrpfile) return DECLINED;
- if (!reqs_arr) return DECLINED;
-
- for(x=0; x < reqs_arr->nelts; x++) {
-
- if (! (reqs[x].method_mask & (1 << m))) continue;
-
- t = reqs[x].requirement;
- w = getword(r->pool, &t, ' ');
-
- if(!strcmp(w,"group") && sec->auth_dbmgrpfile) {
- const char *orig_groups,*groups;
- char *v;
-
- if (!(groups = get_dbm_grp(r, user, sec->auth_dbmgrpfile))) {
- if (!(sec->auth_dbmauthoritative))
- return DECLINED;
- ap_snprintf(errstr, sizeof(errstr),
- "user %s not in DBM group file %s",
- user, sec->auth_dbmgrpfile);
- log_reason (errstr, r->filename, r);
- note_basic_auth_failure (r);
- return AUTH_REQUIRED;
- }
- orig_groups = groups;
- while(t[0]) {
- w = getword(r->pool, &t, ' ');
- groups = orig_groups;
- while(groups[0]) {
- v = getword(r->pool, &groups,',');
- if(!strcmp(v,w))
- return OK;
- }
- }
- ap_snprintf(errstr, sizeof(errstr),
- "user %s not in right group",user);
- log_reason (errstr, r->filename, r);
- note_basic_auth_failure(r);
- return AUTH_REQUIRED;
- }
- }
-
- return DECLINED;
-}
-
-
-module dbm_auth_module = {
- STANDARD_MODULE_STUFF,
- NULL, /* initializer */
- create_dbm_auth_dir_config, /* dir config creater */
- NULL, /* dir merger --- default is to override */
- NULL, /* server config */
- NULL, /* merge server config */
- dbm_auth_cmds, /* command table */
- NULL, /* handlers */
- NULL, /* filename translation */
- dbm_authenticate_basic_user, /* check_user_id */
- dbm_check_auth, /* check auth */
- NULL, /* check access */
- NULL, /* type_checker */
- NULL, /* fixups */
- NULL, /* logger */
- NULL /* header parser */
-};
diff --git a/usr.sbin/httpd/src/mod_auth_msql.c b/usr.sbin/httpd/src/mod_auth_msql.c
deleted file mode 100644
index dc8064276e8..00000000000
--- a/usr.sbin/httpd/src/mod_auth_msql.c
+++ /dev/null
@@ -1,996 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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
- * IT'S 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_auth_msql: authentication
- *
- * Rob McCool & Brian Behlendorf.
- *
- * Adapted to Apache by rst.
- *
- * Addapted for use with the mSQL database
- * (see ftp:/ftp.bond.edu.au/pub/Minerva/mSQL)
- *
- * Version 1.0 May 1996 - Blame: Dirk.vanGulik@jrc.it.
- *
- * A (sometimes more up to date) version of the documentation
- * can be found at the http://www.apache.org site or at
- * http://me-www.jrc.it/~dirkx/mod_auth_msql.html.
- *
- * Outline:
- *
- * This module allows access control using the public domain
- * mSQL database; a fast but limted SQL engine which can be
- * contacted over an internal unix domain protocol as well as
- * over normal inter-machine tcp/ip socket communication.
- *
- * An example table could be:
- *
- * create table user_records (
- * User_id char(32) primary key,
- * Cpasswd char(32),
- * [ Xgroup char(32) ]
- * ) \g
- *
- * The user_id can be as long as desired; however some of the
- * popular web browsers truncate, or stop the user from entering
- * names longer than 32 characters. Furthermore the 'crypt' function
- * on your platform might impose further limits. Also use of
- * the 'require users uid [uid..]' directive in the access.conf file,
- * where the user ids are separated by spaces can possibly prohibit the
- * use of spaces in your user-names. Also, not the MAX_FIELD_LEN define
- * somewhere below.
- *
- * To use the above, the following example could be in your access.conf
- * file. Also there is a more elaborate description afther this example.
- *
- * <directory /web/docs/private>
- *
- * Auth_MSQLhost localhost
- * or
- * Auth_MSQLhost datab.machine.your.org
- *
- * If this directive is ommited, or set to
- * localhost, the machine on which apache
- * runs is assumed, and the faster /dev/msql
- * communication channel will be used. Otherwise
- * it is the machine to contact by tcp/ip.
- *
- * Auth_MSQLdatabase www
- *
- * The name of the database on the above machine,
- * which contains *both* the tables for group and
- * for user/passwords. Currently it is not possible
- * to have these split over two databases. Make
- * sure that the msql.acl (access control file) of
- * mSQL does indeed allow the effective uid of the
- * web server read access to this database. Check the
- * httpd.conf file for this uid.
- *
- * Auth_MSQLpwd_table user_records
- *
- * Here the table which contain the uid/password combination
- * is specified.
- *
- * Auth_MSQLuid_field User_id
- * Auth_MSQLpwd_field Cpasswd
- *
- * These two directive specify the field names in the 'user_record'
- * table. If this module is compiled with the BACKWARD_VITEK
- * compatibility switch, the defaults 'user' and 'password' are
- * assumed if you do not specify them. Currently the user_id field
- * *MUST* be a primary key or one must ensure that each user only
- * occurs *once* in the table. If a UID occurs twice access is
- * denied by default.
- *
- * Auth_MSQLgrp_table user_records
- * Auth_MSQLgrp_field Xgroup
- *
- * Optionaly one can also specify a table which contains the
- * user/group combinations. This can be the same table which
- * also contains the username/password combinations. However
- * if a user belongs to two or more groups, one will have to
- * use a differt table with multiple entries.
- *
- * Auth_MSQL_nopasswd off
- * Auth_MSQL_Authoritative on
- * Auth_MSQL_EncryptedPasswords on
- *
- * These three optional fields (all set to the sensible defaults,
- * so you really do not have to enter them) are described in more
- * detail below. If you choose to set these to any other values than
- * the above be very sure you understand the security implications and
- * do verify that apache does what you exect it to do.
- *
- * AuthName example mSQL realm
- * AuthType basic
- *
- * Normal apache/ncsa tokens for access control
- *
- * <limit get post head>
- * order deny,allow
- * allow from all
- *
- * require valid-user
- * 'valid-user'; allow in any user which has a valid uid/passwd
- * pair in the above pwd_table.
- * or
- * require user smith jones
- * Limit access to users who have a valid uid/passwd pair in the
- * above pwd_table AND whose uid is 'smith' or 'jones'. Do note that
- * the uid's are separated by 'spaces' for historic (ncsa) reasons.
- * So allowing uids with spaces might cause problems.
- *
- * require group has_paid
- * Optionally also ensure that the uid has the value 'has_paid' in the group
- * field in the group table.
- * </limit>
- * </directory>
- *
- * End of the example
- *
- * - full description of all tokens: -
- *
- * Directives:
- *
- * Auth_MSQLhost Hostname of the machine running
- * the mSQL demon. The effective uid
- * of the server should be allowed
- * access. If not given, or if it is
- * the magic name 'localhost', it is
- * passed to the mSQL libary as a null
- * pointer. This effectively forces it
- * to use /dev/msql rather than the
- * (slower) socket communication.
- *
- * Auth_MSQLdatabase Name of the database in which the following
- * table(s) are contained.
- *
- * Auth_MSQLpwd_table Contains at least the fields with the
- * username and the (encrypted) password. Each
- * uid should only occur once in this table and
- * for performance reasons should be a primary key.
- * Normally this table is compulsory, but it is
- * possible to use a fall-through to other methods
- * and use the mSQL module for group control only;
- * see the Authoritative directive below.
- *
- * Auth_MSQLgrp_table Contains at least the fields with the
- * username and the groupname. A user which
- * is in multiple groups has therefore
- * multiple entries; this might be some per-
- * formance problems associated with this; and one
- * might consider to have separate tables for each
- * group (rather than all groups in one table) if
- * your directory structure allows for it.
- * One only needs to specify this table when doing
- * group control.
- *
- * Auth_MSQLuid_field Name of the field containing the username
- * Auth_MSQLpwd_field Fieldname for the passwords
- * Auth_MSQLgrp_field Fieldname for the groupname
- *
- * Only the fields used need to be specified. When this
- * module is compiled with the BACKWARD_VITEK option the
- * uid and pwd field names default to 'user' and 'password'.
- *
- *
- * Auth_MSQL_nopasswd <on|off>
- * skip password comparison if passwd field is
- * empty; i.e. allow 'any' password. This is off
- * by default; thus to ensure that an empty field
- * in the mSQL table does not allow people in by
- * default with a random password.
- *
- * Auth_MSQL_Authoritative <on|off>
- * default is 'on'. When set on, there is no
- * fall through to other authorization methods. So if a
- * user is not in the mSQL dbase table (and perhaps
- * not in the right group) or has the password wrong, then
- * he or she is denied access. When this directive is set to
- * 'off' control is passed on to any other authorization
- * modules, such as the basic auth module wih the htpasswd
- * file and or the unix-(g)dbm modules.
- * The default is 'ON' to avoid nasty 'fall-through' sur-
- * prizes. Do be sure you know what you decide to switch
- * it off.
- *
- * Auth_MSQL_EncryptedPasswords <on|off>
- * default is on. When set on, the values in the
- * pwd_field are assumed to be crypted using *your*
- * machines 'crypt' function; and the incoming password
- * is 'crypt'ed before comparison. When this function is
- * off, the comparison is done directly with the plaintext
- * entered password. (Yes; http-basic-auth does send the
- * password as plaintext over the wire :-( ). The default
- * is a sensible 'on', and I personally thing that it is
- * a *very-bad-idea* to change this. However a multi
- * vendor or international environment (which sometimes
- * leads to different crypts functions) might force you to.
- *
- * Dirk.vanGulik@jrc.it; http://ewse.ceo.org; http://me-www.jrc.it/~dirkx
- * 23 Nov 1995, 24 Feb 1996, 16 May 1996.
- *
- * Version 0.0 First release
- * 0.1 Update to apache 1.00
- * 0.2 added lines which got missing god knows when
- * and which did the valid-user authentification
- * no good at all !
- * 0.3 Added 'Auth_MSQL_nopasswd' option
- * 0.4 Cleaned out the error messages mess.
- * 0.6 Inconsistency with gid/grp in comment/token/source
- * Make sure you really use 'Auth_MSQLgrp_field' as
- * indicated above.
- * 0.7 *host to host fixed. Credits go to Rob Stout,
- * <stout@lava.et.tudelft.nl> for spotting this one.
- * 0.8 Authoritative directive added. See above.
- * 0.9 palloc return code check(s), should be backward compatible with
- * 1.11 version of Vivek Khera <khera@kciLink.com> msql module,
- * fixed broken err msg in group control, changed command table
- * messages to make more sense when displayed in that new module
- * management tool. Added EncryptedPassword on/off functionality.
- * msqlClose() statements added upon error. Support for persistent
- * connections with the mSQL database (riscy). Escaping of ' and \.
- * Replaced some MAX_STRING_LEN claims.
- * 1.0 removed some error check as they where already done elsehwere
- * NumFields -> NumRows (Thanks Vitek). More stack memory.
- * 1.1 no logging of empty password strings.
- * 1.2 Problem with the Backward vitek which cause it to check
- * even if msql_auth was not configured; Also more carefull
- * with the authoritative stuff; caught by thomas@marvin.calvacom.fr.
- * 1.3 Even more changes to get it right; that BACKWARD thing was a bad
- * idea.
- */
-
-
-#define ONLY_ONCE 1
-/*
- * If the mSQL table containing the uid/passwd combination does
- * not have the uid field as a primary key, it is possible for the
- * uid to occur more than once in the table with possibly different
- * passwords. When this module is compiled with the ONLY_ONCE directive
- * set, access is denied if the uid occures more than once in the
- * uid/passwd table. If you choose not to set it, the software takes
- * the first pair returned and ignores any further pairs. The SQL
- * statement used for this is
- *
- * "select password form pwd_table where user='uid'"
- *
- * this might lead to unpredictable results. For this reason as well
- * as for performance reasons you are strongly adviced to make the
- * uid field a primary key. Use at your own peril :-)
- */
-
-#undef KEEP_MSQL_CONNECTION_OPEN
-/*
- * Normally the (tcp/ip) connection with the database is opened and
- * closed for each SQL query. When the httpd-server and the database
- * are on the same machine, and /dev/msql is used this does not
- * cause a serious overhead. However when your platform does not
- * support this (see the mSQL documentation) or when the web server
- * and the database are on different machines the overhead can be
- * considerable. When the above is set defined the server leaves the
- * connection open; i.e. no call to msqlClose(). If an error occures
- * an attempt is made to re-open the connection for the next http-rq.
- *
- * This has a number of very serious drawbacks
- * - It costs 2 already rare filedescriptors for each child.
- * - It costs msql-connections, typically one per child. The (compiled in)
- * number of connections mSQL can handle is low, typically 6 or 12.
- * which might prohibit access to the mSQL database for later
- * processes.
- * - when a child dies, it might not free that connection properly
- * or quick enough.
- * - When errors start to occur, connection/file-descr resources might
- * become exausted very quickly.
- *
- * In short; use this at your own peril and only in a highly controled and
- * monitored environment
- */
-
-#define BACKWARD_VITEK
-#define VITEX_uid_name "user"
-#define VITEX_gid_name "passwd"
-/* A second mSQL auth module for apache has also been developed by
- * Vivek Khera <khera@kciLink.com> and was subsequently distributed
- * with some early versions of Apache. It can be optained from
- * ftp://ftp.kcilink.com/pub/mod_auth_msql.c*. Older 'vitek' versions had
- * the field/table names compiled in; newer versions, v.1.11 have
- * more access.conf configuration options; however these where
- * choosen not to be in line the 'ewse' version of this module. Also,
- * the 'vitek' module does not give group control or 'empty' password
- * control.
- *
- * To get things slightly more in line this version (0.9) should
- * be backward compatible with the vitek module by:
- *
- * - adding support for the EncryptedPassword on/off functionality
- *
- * - adding support for the different spelling fo the 4 configuration
- * tokens for user-table-name, user/password-field-name and dbase-name.
- *
- * - setting some field names to a default which used to be hard
- * coded in in older vitek modules.
- *
- * If this troubles you; remove the 'BACKWARD_VITEX' define.
- */
-
-/* get some sensible values; rather than that big MAX_STRING_LEN,
- */
-
-/* Max field value length limit; well above the limit of some browsers :-)
- */
-#define MAX_FIELD_LEN (64)
-/* the next two values can be pulled from msql_priv.c, which is *NOT* copied to your
- * /usr/local/include as part of the normal install procedure which comes with
- * mSQL.
- */
-#define MSQL_FIELD_NAME_LEN (19)
-#define MSQL_TABLE_NAME_LEN (19)
-/* We only do the following two queries:
- *
- * - for the user/passwd combination
- * select PWDFIELD from PWDTABEL where USERFIELD='UID'
- *
- * - optionally for the user/group combination:
- * select GROUPFIELD from GROUPTABLE where USERFIELD='UID' and GROUPFIELD='GID'
- *
- * This leads to the following limits: (we are ignoring escaping a wee bit bit here
- * assuming not more than 24 escapes.)
- */
-
-#define MAX_QUERY_LEN (32+24+MAX_FIELD_LEN*2+3*MSQL_FIELD_NAME_LEN+1*MSQL_TABLE_NAME_LEN)
-
-
-#include "httpd.h"
-#include "http_config.h"
-#include "http_core.h"
-#include "http_log.h"
-#include "http_protocol.h"
-#include <msql.h>
-#ifdef HAVE_CRYPT_H
-#include <crypt.h>
-#endif
-
-typedef struct {
-
- char *auth_msql_host;
- char *auth_msql_database;
-
- char *auth_msql_pwd_table;
- char *auth_msql_grp_table;
-
- char *auth_msql_pwd_field;
- char *auth_msql_uname_field;
- char *auth_msql_grp_field;
-
- int auth_msql_nopasswd;
- int auth_msql_authoritative;
- int auth_msql_encrypted;
-
-} msql_auth_config_rec;
-
-void *create_msql_auth_dir_config (pool *p, char *d)
-{
- msql_auth_config_rec * sec= (msql_auth_config_rec *) pcalloc (p, sizeof(msql_auth_config_rec));
-
- sec->auth_msql_host = NULL; /* just to enforce the default 'localhost' behaviour */
-
- /* just in case, to be nice... */
- sec->auth_msql_database = NULL;
- sec->auth_msql_pwd_table = NULL;
- sec->auth_msql_grp_table = NULL;
- sec->auth_msql_pwd_field = NULL;
- sec->auth_msql_uname_field = NULL;
- sec->auth_msql_grp_field = NULL;
-
-
- sec->auth_msql_authoritative = 1; /* set some defaults, just in case... */
- sec->auth_msql_encrypted = 1;
- sec->auth_msql_nopasswd = 0;
-
-#ifdef BACKWARD_VITEK
- /* these are for backward compatibility with the Vivek
- * msql module, as it used to have compile-time defaults.
- */
- sec->auth_msql_uname_field = VITEX_uid_name;
- sec->auth_msql_pwd_field = VITEX_gid_name;
-#endif
-
- return sec;
-}
-
-const char *set_passwd_flag (cmd_parms *cmd, msql_auth_config_rec *sec, int arg) {
- sec->auth_msql_nopasswd=arg;
- return NULL;
-}
-
-const char *set_authoritative_flag (cmd_parms *cmd, msql_auth_config_rec *sec, int arg) {
- sec->auth_msql_authoritative=arg;
- return NULL;
-}
-
-const char *set_crypted_password_flag (cmd_parms *cmd, msql_auth_config_rec *sec , int arg) {
- sec->auth_msql_encrypted = arg;
- return NULL;
-}
-
-const char *msql_set_string_slot (cmd_parms *cmd, char *struct_ptr, char *arg) {
- int offset = (int)cmd->info;
- *(char **)(struct_ptr + offset) = pstrdup (cmd->pool, arg);
- return NULL;
-}
-
-
-command_rec msql_auth_cmds[] = {
-{ "Auth_MSQLhost", msql_set_string_slot,
- (void*)XtOffsetOf(msql_auth_config_rec, auth_msql_host),
- OR_AUTHCFG, TAKE1, "Host on which the mSQL database engine resides (defaults to localhost)" },
-
-{ "Auth_MSQLdatabase", msql_set_string_slot,
- (void*)XtOffsetOf(msql_auth_config_rec, auth_msql_database),
- OR_AUTHCFG, TAKE1, "Name of the mSQL database which contains the password (and possibly the group) tables. " },
-
-{ "Auth_MSQLpwd_table", msql_set_string_slot,
- (void*)XtOffsetOf(msql_auth_config_rec, auth_msql_pwd_table),
- OR_AUTHCFG, TAKE1, "Name of the mSQL table containing the password/user-name combination" },
-
-{ "Auth_MSQLgrp_table", msql_set_string_slot,
- (void*)XtOffsetOf(msql_auth_config_rec, auth_msql_grp_table),
- OR_AUTHCFG, TAKE1, "Name of the mSQL table containing the group-name/user-name combination; can be the same as the password-table." },
-
-{ "Auth_MSQLpwd_field", msql_set_string_slot,
- (void*)XtOffsetOf(msql_auth_config_rec, auth_msql_pwd_field),
- OR_AUTHCFG, TAKE1, "The name of the field in the mSQL password table" },
-
-{ "Auth_MSQLuid_field", msql_set_string_slot,
- (void*)XtOffsetOf(msql_auth_config_rec, auth_msql_uname_field),
- OR_AUTHCFG, TAKE1, "The name of the user-name field in the mSQL password (and possibly group) table(s)." },
-
-{ "Auth_MSQLgrp_field", msql_set_string_slot,
- (void*)XtOffsetOf(msql_auth_config_rec, auth_msql_grp_field),
- OR_AUTHCFG, TAKE1,
- "The name of the group field in the mSQL group table; must be set if you want to use groups." },
-
-{ "Auth_MSQL_nopasswd", set_passwd_flag, NULL, OR_AUTHCFG, FLAG,
- "Enable (on) or disable (off) empty password strings; in which case any user password is accepted." },
-
-{ "Auth_MSQL_Authoritative", set_authoritative_flag, NULL, OR_AUTHCFG, FLAG,
- "When 'on' the mSQL database is taken to be authoritative and access control is not passed along to other db or access modules." },
-
-{ "Auth_MSQL_EncryptedPasswords", set_crypted_password_flag, NULL, OR_AUTHCFG, FLAG,
- "When 'on' the password in the password table are taken to be crypt()ed using your machines crypt() function." },
-
-#ifdef BACKWARD_VITEK
-/* These 'altenative' tokens should ensure backward compatibility
- * with viteks mSQL module. The only difference is the spelling.
- * Note that these tokens do not allow group configuration.
- */
-{ "AuthMSQLHost", set_string_slot,
- (void*)XtOffsetOf(msql_auth_config_rec, auth_msql_host),
- OR_AUTHCFG, TAKE1, "mSQL server hostname" },
-{ "AuthMSQLDB", set_string_slot,
- (void*)XtOffsetOf(msql_auth_config_rec, auth_msql_database),
- OR_AUTHCFG, TAKE1, "mSQL database name" },
-{ "AuthMSQLUserTable", set_string_slot,
- (void*)XtOffsetOf(msql_auth_config_rec, auth_msql_pwd_table),
- OR_AUTHCFG, TAKE1, "mSQL user table name" },
-{ "AuthMSQLGroupTable", set_string_slot,
- (void*)XtOffsetOf(msql_auth_config_rec, auth_msql_grp_table),
- OR_AUTHCFG, TAKE1, "mSQL group table name" },
-{ "AuthMSQLNameField", set_string_slot,
- (void*)XtOffsetOf(msql_auth_config_rec, auth_msql_uname_field),
- OR_AUTHCFG, TAKE1, "mSQL User ID field name within table" },
-{ "AuthMSQLGroupField", set_string_slot,
- (void*)XtOffsetOf(msql_auth_config_rec, auth_msql_grp_field),
- OR_AUTHCFG, TAKE1, "mSQL Group field name within table" },
-{ "AuthMSQLPasswordField", set_string_slot,
- (void*)XtOffsetOf(msql_auth_config_rec, auth_msql_pwd_field),
- OR_AUTHCFG, TAKE1, "mSQL Password field name within table" },
-{ "AuthMSQLCryptedPasswords", set_crypted_password_flag, NULL,
- OR_AUTHCFG, FLAG, "mSQL passwords are stored encrypted if On" },
-
-#endif
-
-{ NULL }
-};
-
-module msql_auth_module;
-
-/* boring little routine which escapes the ' and \ in the
- * SQL query. See the mSQL FAQ for more information :-) on
- * this very popular subject in the msql-mailing list.
- */
-char *msql_escape(char *out, char *in, char *msql_errstr) {
-
- register int i=0,j=0;
-
- do {
- /* do we need to escape */
- if ( (in[i] == '\'') || (in[i] == '\\')) {
-
- /* does this fit ? */
- if (j >= (MAX_FIELD_LEN-1)) {
- ap_snprintf(msql_errstr, MAX_STRING_LEN,
- "Could not escape '%s', longer than %d",in,MAX_FIELD_LEN);
- return NULL;
- };
-
- out[j++] = '\\'; /* insert that escaping slash for good measure */
- };
-
- /* Do things still fit ? */
- if (j >= MAX_FIELD_LEN) return NULL;
-
- } while ( ( out[j++] = in[i++]) != '\0' );
-
- return out;
-}
-
-/* get the password for uname=user, and copy it
- * into r. Assume that user is a string and stored
- * as such in the mSQL database
- */
-char *do_msql_query(request_rec *r, char *query, msql_auth_config_rec *sec, int once , char *msql_errstr) {
-
- static int sock=-1;
- int hit;
- m_result *results;
- m_row currow;
-
- char *result=NULL;
- char *host=sec->auth_msql_host;
-
-#ifndef KEEP_MSQL_CONNECTION_OPEN
- sock=-1;
-#endif
-
- /* force fast access over /dev/msql */
-
- if ((host) && (!(strcasecmp(host,"localhost"))))
- host=NULL;
-
- /* (re) open if nessecary
- */
- if (sock==-1) if ((sock=msqlConnect(host)) == -1) {
- ap_snprintf (msql_errstr, MAX_STRING_LEN,
- "mSQL: Could not connect to Msql DB %s (%s)",
- (sec->auth_msql_host ? sec->auth_msql_host : "\'unset, assuming localhost!\'"),
- msqlErrMsg);
- return NULL;
- }
-
- /* we always do this, as it avoids book-keeping
- * and is quite cheap anyway
- */
- if (msqlSelectDB(sock,sec->auth_msql_database) == -1 ) {
- ap_snprintf (msql_errstr, MAX_STRING_LEN,
- "mSQL: Could not select Msql Table \'%s\' on host \'%s\'(%s)",
- (sec->auth_msql_database ? sec->auth_msql_database : "\'unset!\'"),
- (sec->auth_msql_host ? sec->auth_msql_host : "\'unset, assuming localhost!\'"),
- msqlErrMsg);
- msqlClose(sock);
- sock=-1;
- return NULL;
- }
-
- if (msqlQuery(sock,query) == -1 ) {
- ap_snprintf (msql_errstr, MAX_STRING_LEN,
- "mSQL: Could not Query database '%s' on host '%s' (%s) with query [%s]",
- (sec->auth_msql_database ? sec->auth_msql_database : "\'unset!\'"),
- (sec->auth_msql_host ? sec->auth_msql_host : "\'unset, assuming localhost!\'"),
- msqlErrMsg,
- ( query ? query : "\'unset!\'") );
- msqlClose(sock);
- sock=-1;
- return NULL;
- }
-
- if (!(results=msqlStoreResult())) {
- ap_snprintf (msql_errstr, MAX_STRING_LEN,
- "mSQL: Could not get the results from mSQL database \'%s\' on \'%s\' (%s) with query [%s]",
- (sec->auth_msql_database ? sec->auth_msql_database : "\'unset!\'"),
- (sec->auth_msql_host ? sec->auth_msql_host : "\'unset, assuming localhost!\'"),
- msqlErrMsg,
- ( query ? query : "\'unset!\'") );
- msqlClose(sock);
- sock=-1;
- return NULL;
- };
-
- hit=msqlNumRows(results);
-
- if (( once ) && ( hit >1 )) {
- /* complain if there are to many
- * matches.
- */
- ap_snprintf (msql_errstr, MAX_STRING_LEN,
- "mSQL: More than %d matches (%d) whith query [%s]",
- once,hit,( query ? query : "\'unset!\'") );
- } else
- /* if we have a it, try to get it
- */
- if ( hit ) {
- if ( (currow=msqlFetchRow(results)) != NULL) {
- /* copy the first matching field value */
- if (!(result=palloc(r->pool,strlen(currow[0])+1))) {
- ap_snprintf (msql_errstr, MAX_STRING_LEN,
- "mSQL: Could not get memory for mSQL %s (%s) with [%s]",
- (sec->auth_msql_database ? sec->auth_msql_database : "\'unset!\'"),
- msqlErrMsg,
- ( query ? query : "\'unset!\'") );
- /* do not return right away, to ensure Free/Close.
- */
- } else {
- strcpy(result,currow[0]);
- };
- }
- };
-
- /* ignore errors, functions are voids anyway. */
- msqlFreeResult(results);
-
-#ifndef KEEP_MSQL_CONNECTION_OPEN
- /* close the connection, unless explicitly told not to. Do note that
- * we do not have a decent closing option of child termination due
- * the lack of hooks in the API (or my understanding thereof)
- */
- msqlClose(sock);
- sock=-1;
-#endif
-
- return result;
-}
-
-char *get_msql_pw(request_rec *r, char *user, msql_auth_config_rec *sec ,char *msql_errstr) {
- char query[MAX_QUERY_LEN];
- char esc_user[MAX_FIELD_LEN];
-
- /* do we have enough information to build a query */
- if (
- (!sec->auth_msql_pwd_table) ||
- (!sec->auth_msql_pwd_field) ||
- (!sec->auth_msql_uname_field)
- ) {
- ap_snprintf(msql_errstr, MAX_STRING_LEN,
- "mSQL: Missing parameters for password lookup: %s%s%s",
- (sec->auth_msql_pwd_table ? "" : "Password table "),
- (sec->auth_msql_pwd_field ? "" : "Password field name "),
- (sec->auth_msql_uname_field ? "" : "UserID field name ")
- );
- return NULL;
- };
-
- if (!(msql_escape(esc_user, user, msql_errstr))) {
- ap_snprintf(msql_errstr, MAX_STRING_LEN,
- "mSQL: Could not cope/escape the '%s' user_id value; ",user);
- return NULL;
- };
- ap_snprintf(query, sizeof(query),
- "select %s from %s where %s='%s'",
- sec->auth_msql_pwd_field,
- sec->auth_msql_pwd_table,
- sec->auth_msql_uname_field,
- esc_user
- );
-
- return do_msql_query(r,query,sec,ONLY_ONCE,msql_errstr);
-}
-
-char *get_msql_grp(request_rec *r, char *group,char *user, msql_auth_config_rec *sec, char *msql_errstr) {
- char query[MAX_QUERY_LEN];
-
- char esc_user[MAX_FIELD_LEN];
- char esc_group[MAX_FIELD_LEN];
-
- /* do we have enough information to build a query */
- if (
- (!sec->auth_msql_grp_table) ||
- (!sec->auth_msql_grp_field) ||
- (!sec->auth_msql_uname_field)
- ) {
- ap_snprintf(msql_errstr, MAX_STRING_LEN,
- "mSQL: Missing parameters for group lookup: %s%s%s",
- (sec->auth_msql_grp_table ? "" : "Group table "),
- (sec->auth_msql_grp_field ? "" : "GroupID field name "),
- (sec->auth_msql_uname_field ? "" : "UserID field name ")
- );
- return NULL;
- };
-
- if (!(msql_escape(esc_user, user,msql_errstr))) {
- ap_snprintf(msql_errstr, MAX_STRING_LEN,
- "mSQL: Could not cope/escape the '%s' user_id value",user);
-
- return NULL;
- };
- if (!(msql_escape(esc_group, group,msql_errstr))) {
- ap_snprintf(msql_errstr, MAX_STRING_LEN,
- "mSQL: Could not cope/escape the '%s' group_id value",group);
-
- return NULL;
- };
-
- ap_snprintf(query, sizeof(query),
- "select %s from %s where %s='%s' and %s='%s'",
- sec->auth_msql_grp_field,
- sec->auth_msql_grp_table,
- sec->auth_msql_uname_field,esc_user,
- sec->auth_msql_grp_field, esc_group
- );
-
- return do_msql_query(r,query,sec,0,msql_errstr);
-}
-
-
-int msql_authenticate_basic_user (request_rec *r)
-{
- msql_auth_config_rec *sec =
- (msql_auth_config_rec *)get_module_config (r->per_dir_config,
- &msql_auth_module);
- char msql_errstr[MAX_STRING_LEN];
- /* msql_errstr must be MAX_STRING_LEN in size unless you
- * change size in ap_snprintf() calls
- */
- conn_rec *c = r->connection;
- char *sent_pw, *real_pw;
- int res;
- msql_errstr[0]='\0';
-
- if ((res = get_basic_auth_pw (r, &sent_pw)))
- return res;
-
- /* if mSQL *password* checking is configured in any way, i.e. then
- * handle it, if not decline and leave it to the next in line..
- * We do not check on dbase, group, userid or host name, as it is
- * perfectly possible to only do group control with mSQL and leave
- * user control to the next (dbm) guy in line.
- * We no longer check on the user field name; to avoid problems
- * with Backward VITEK.
- */
- if (!sec->auth_msql_pwd_table) return DECLINED;
-
- if(!(real_pw = get_msql_pw(r, c->user, sec,msql_errstr ))) {
- if ( msql_errstr[0] ) {
- res = SERVER_ERROR;
- } else {
- if (sec->auth_msql_authoritative) {
- /* insist that the user is in the database
- */
- ap_snprintf(msql_errstr, MAX_STRING_LEN,
- "mSQL: Password for user %s not found", c->user);
- note_basic_auth_failure (r);
- res = AUTH_REQUIRED;
- } else {
- /* pass control on to the next authorization module.
- */
- return DECLINED;
- }; /* if authoritative */
- }; /* if no error */
- log_reason (msql_errstr, r->filename, r);
- return res;
- }
-
- /* allow no password, if the flag is set and the password
- * is empty. But be sure to log this.
- */
-
- if ((sec->auth_msql_nopasswd) && (!strlen(real_pw))) {
-/*
- ap_snprintf(msql_errstr, MAX_STRING_LEN,
- "mSQL: user %s: Empty/'any' password accepted",c->user);
- log_reason (msql_errstr, r->uri, r);
- */
- return OK;
- };
-
- /* if the flag is off however, keep that kind of stuff at
- * an arms length.
- */
- if ((!strlen(real_pw)) || (!strlen(sent_pw))) {
- ap_snprintf(msql_errstr, MAX_STRING_LEN,
- "mSQL: user %s: Empty Password(s) Rejected",c->user);
- log_reason (msql_errstr, r->uri, r);
- note_basic_auth_failure (r);
- return AUTH_REQUIRED;
- };
-
- if(sec->auth_msql_encrypted) {
- /* anyone know where the prototype for crypt is?
- *
- * PLEASE NOTE:
- * The crypt function (at least under FreeBSD 2.0.5) returns
- * a ptr to a *static* array (max 120 chars) and does *not*
- * modify the string pointed at by sent_pw !
- */
- sent_pw=(char *)crypt(sent_pw,real_pw);
- };
-
- if (strcmp(real_pw,sent_pw)) {
- ap_snprintf(msql_errstr, MAX_STRING_LEN,
- "mSQL user %s: password mismatch",c->user);
- log_reason (msql_errstr, r->uri, r);
- note_basic_auth_failure (r);
- return AUTH_REQUIRED;
- }
- return OK;
-}
-
-/* Checking ID */
-
-int msql_check_auth (request_rec *r) {
- int user_result=DECLINED,group_result=DECLINED;
-
- msql_auth_config_rec *sec =
- (msql_auth_config_rec *)get_module_config (r->per_dir_config,
- &msql_auth_module);
- char msql_errstr[MAX_STRING_LEN];
- /* msql_errstr must be MAX_STRING_LEN in size unless you
- * change size in ap_snprintf() calls
- */
- char *user = r->connection->user;
- int m = r->method_number;
- array_header *reqs_arr = requires (r);
- require_line *reqs = reqs_arr ? (require_line *)reqs_arr->elts : NULL;
-
- register int x;
- const char *t, *w;
- msql_errstr[0]='\0';
-
- /* If we are not configured, ignore */
- if (!sec->auth_msql_pwd_table) return DECLINED;
-
- if (!reqs_arr) {
- if (sec->auth_msql_authoritative) {
- ap_snprintf(msql_errstr, MAX_STRING_LEN, "user %s denied, no access rules specified (MSQL-Authoritative) ",user);
- log_reason (msql_errstr, r->uri, r);
- note_basic_auth_failure(r);
- return AUTH_REQUIRED;
- };
- return DECLINED;
- };
-
- for(x=0; (x < reqs_arr->nelts) ; x++) {
-
- if (! (reqs[x].method_mask & (1 << m))) continue;
-
- t = reqs[x].requirement;
- w = getword(r->pool, &t, ' ');
-
- if ((user_result != OK) && (!strcmp(w,"user"))) {
- user_result=AUTH_REQUIRED;
- while(t[0]) {
- w = getword_conf (r->pool, &t);
- if (!strcmp(user,w)) {
- user_result= OK;
- break;
- };
- }
- if ((sec->auth_msql_authoritative) && ( user_result != OK)) {
- ap_snprintf(msql_errstr, MAX_STRING_LEN, "User %s not found (MSQL-Auhtorative)",user);
- log_reason (msql_errstr, r->uri, r);
- note_basic_auth_failure(r);
- return AUTH_REQUIRED;
- };
- }
-
- if ( (group_result != OK) &&
- (!strcmp(w,"group")) &&
- (sec->auth_msql_grp_table) &&
- (sec->auth_msql_grp_field)
- ) {
- /* look up the membership for each of the groups in the table
- */
- group_result=AUTH_REQUIRED;
- while ( (t[0]) && (group_result != OK) && (!msql_errstr[0]) ) {
- if (get_msql_grp(r,getword(r->pool, &t, ' '),user,sec,msql_errstr)) {
- group_result= OK;
- break;
- };
- };
-
- if (msql_errstr[0]) {
- log_reason (msql_errstr, r->filename, r);
- return SERVER_ERROR;
- };
-
- if ( (sec->auth_msql_authoritative) && (group_result != OK) ) {
- ap_snprintf(msql_errstr, MAX_STRING_LEN, "user %s not in right groups (MSQL-Authoritative) ",user);
- log_reason (msql_errstr, r->uri, r);
- note_basic_auth_failure(r);
- return AUTH_REQUIRED;
- };
- };
-
- if(!strcmp(w,"valid-user")) {
- user_result= OK;
- };
- }
-
- /* Get serious if we are authoritative, previous
- * returns are only if msql yielded a correct result.
- * This really is not needed.
- */
- if (((group_result == AUTH_REQUIRED) || (user_result == AUTH_REQUIRED)) && (sec->auth_msql_authoritative) ) {
- ap_snprintf(msql_errstr, MAX_STRING_LEN, "mSQL-Authoritative: Access denied on %s %s rule(s) ",
- (group_result == AUTH_REQUIRED) ? "USER" : "",
- (user_result == AUTH_REQUIRED) ? "GROUP" : ""
- );
- log_reason (msql_errstr, r->uri, r);
- return AUTH_REQUIRED;
- };
-
- if ( (user_result == OK) || (group_result == OK))
- return OK;
-
- return DECLINED;
-}
-
-
-module msql_auth_module = {
- STANDARD_MODULE_STUFF,
- NULL, /* initializer */
- create_msql_auth_dir_config, /* dir config creater */
- NULL, /* dir merger --- default is to override */
- NULL, /* server config */
- NULL, /* merge server config */
- msql_auth_cmds, /* command table */
- NULL, /* handlers */
- NULL, /* filename translation */
- msql_authenticate_basic_user,/* check_user_id */
- msql_check_auth, /* check auth */
- NULL, /* check access */
- NULL, /* type_checker */
- NULL, /* pre-run fixups */
- NULL, /* logger */
- NULL /* header parser */
-};
diff --git a/usr.sbin/httpd/src/mod_browser.c b/usr.sbin/httpd/src/mod_browser.c
deleted file mode 100644
index 3779cdec087..00000000000
--- a/usr.sbin/httpd/src/mod_browser.c
+++ /dev/null
@@ -1,189 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1996,1997 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. 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
- * IT'S 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_browser.c
- * Set environment variables based on browser support.
- *
- * Alexei Kosut <akosut@organic.com>
- */
-
-#include "httpd.h"
-#include "http_config.h"
-
-typedef struct {
- char *name;
- regex_t *preg;
- table *features;
-} browser_entry;
-
-typedef struct {
- array_header *browsers;
-} browser_server_config_rec;
-
-module browser_module;
-
-void *create_browser_config (pool *p, server_rec *dummy)
-{
- browser_server_config_rec *new =
- (browser_server_config_rec *) palloc (p, sizeof(browser_server_config_rec));
-
- new->browsers = make_array (p, 20, sizeof(browser_entry));
- return (void *)new;
-}
-
-void *merge_browser_config (pool *p, void *basev, void *overridesv)
-{
- browser_server_config_rec *a =
- pcalloc(p, sizeof(browser_server_config_rec));
- browser_server_config_rec *base = basev, *overrides = overridesv;
-
- a->browsers = append_arrays(p, base->browsers, overrides->browsers);
- return a;
-}
-
-const char *add_browser(cmd_parms *cmd, void *dummy, char *name,
- const char *feature)
-{
- browser_server_config_rec *sconf =
- get_module_config (cmd->server->module_config, &browser_module);
- browser_entry *new, *entries = (browser_entry *)sconf->browsers->elts;
- char *var;
- int i, cflags = (int)cmd->info;
-
- /* First, try to merge into an existing entry */
-
- for (i = 0; i < sconf->browsers->nelts; ++i) {
- browser_entry *b = &entries[i];
- if (!strcmp(b->name, name)) {
- var = getword(cmd->pool, &feature, '=');
- if (*feature) table_set(b->features, var, feature);
- else if (*var == '!') table_set(b->features, var + 1, "!");
- else table_set(b->features, var, "1");
- return NULL;
- }
- }
-
- /* If none was found, create a new entry */
-
- new = push_array(sconf->browsers);
- new->name = name;
- new->preg = pregcomp (cmd->pool, name, REG_EXTENDED|REG_NOSUB|cflags);
- if (new->preg == NULL) {
- return "Browser regex could not be compiled.";
- }
- new->features = make_table(cmd->pool, 5);
-
- var = getword(cmd->pool, &feature, '=');
- if (*feature) table_set(new->features, var, feature);
- else if (*var == '!') table_set(new->features, var + 1, "!");
- else table_set(new->features, var, "1");
-
- return NULL;
-}
-
-command_rec browser_module_cmds[] = {
-{ "BrowserMatch", add_browser, (void*)0,
- RSRC_CONF, ITERATE2, "A browser regex and a list of variables." },
-{ "BrowserMatchNoCase", add_browser, (void*)REG_ICASE,
- RSRC_CONF, ITERATE2, "a browser regex and a list of variables." },
-{ NULL },
-};
-
-static int browser_match(request_rec *r)
-{
- server_rec *s = r->server;
- browser_server_config_rec *sconf = get_module_config (s->module_config,
- &browser_module);
- browser_entry *entries = (browser_entry *)sconf->browsers->elts;
- table_entry *elts;
- char *ua = table_get(r->headers_in, "User-Agent");
- int i, j;
-
- if (!ua) return DECLINED;
-
- for (i = 0; i < sconf->browsers->nelts; ++i) {
- browser_entry *b = &entries[i];
-
- if (!regexec(b->preg, ua, 0, NULL, 0)) {
- elts = (table_entry *)b->features->elts;
-
- for (j = 0; j < b->features->nelts; ++j) {
- if (!strcmp(elts[j].val, "!"))
- table_unset(r->subprocess_env, elts[j].key);
- else
- table_set(r->subprocess_env, elts[j].key, elts[j].val);
- }
- }
- }
-
- return DECLINED;
-}
-
-module browser_module = {
- STANDARD_MODULE_STUFF,
- NULL, /* initializer */
- NULL, /* dir config creater */
- NULL, /* dir merger --- default is to override */
- create_browser_config, /* server config */
- merge_browser_config, /* merge server configs */
- browser_module_cmds, /* command table */
- NULL, /* handlers */
- browser_match, /* filename translation */
- NULL, /* check_user_id */
- NULL, /* check auth */
- NULL, /* check access */
- NULL, /* type_checker */
- NULL, /* fixups */
- NULL, /* logger */
- NULL /* header parser */
-};
diff --git a/usr.sbin/httpd/src/mod_cern_meta.c b/usr.sbin/httpd/src/mod_cern_meta.c
deleted file mode 100644
index d05677c8c25..00000000000
--- a/usr.sbin/httpd/src/mod_cern_meta.c
+++ /dev/null
@@ -1,325 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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
- * IT'S 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_cern_meta.c
- * version 0.0.5
- * status beta
- *
- * Andrew Wilson <Andrew.Wilson@cm.cf.ac.uk> 25.Jan.96
- *
- * Emulate the CERN HTTPD Meta file semantics. Meta files are HTTP
- * headers that can be output in addition to the normal range of
- * headers for each file accessed. They appear rather like the Apache
- * .asis files, and are able to provide a crude way of influencing
- * the Expires: header, as well as providing other curiosities.
- * There are many ways to manage meta information, this one was
- * chosen because there is already a large number of CERN users
- * who can exploit this module. It should be noted that there are probably
- * more sensitive ways of managing the Expires: header specifically.
- *
- * The module obeys the following directives, which can only appear
- * in the server's .conf files and not in any .htaccess file.
- *
- * MetaDir <directory name>
- *
- * specifies the name of the directory in which Apache can find
- * meta information files. The directory is usually a 'hidden'
- * subdirectory of the directory that contains the file being
- * accessed. eg:
- *
- * # .meta files are in the *same* directory as the
- * # file being accessed
- * MetaDir .
- *
- * the default is to look in a '.web' subdirectory. This is the
- * same as for CERN 3.+ webservers and behaviour is the same as
- * for the directive:
- *
- * MetaDir .web
- *
- * MetaSuffix <meta file suffix>
- *
- * specifies the file name suffix for the file containing the
- * meta information. eg:
- *
- * # our meta files are suffixed with '.cern_meta'
- * MetaSuffix .cern_meta
- *
- * the default is to look for files with the suffix '.meta'. This
- * behaviour is the same as for the directive:
- *
- * MetaSuffix .meta
- *
- * When accessing the file
- *
- * DOCUMENT_ROOT/somedir/index.html
- *
- * this module will look for the file
- *
- * DOCUMENT_ROOT/somedir/.web/index.html.meta
- *
- * and will use its contents to generate additional MIME header
- * information.
- *
- * For more information on the CERN Meta file semantics see:
- *
- * http://www.w3.org/hypertext/WWW/Daemon/User/Config/General.html#MetaDir
- *
- * Change-log:
- * 29.Jan.96 pfopen/pfclose instead of fopen/fclose
- * DECLINE when real file not found, we may be checking each
- * of the index.html/index.shtml/index.htm variants and don't
- * need to report missing ones as spurious errors.
- * 31.Jan.96 log_error reports about a malformed .meta file, rather
- * than a script error.
- *
- */
-
-#include "httpd.h"
-#include "http_config.h"
-#include <sys/types.h>
-#include <sys/stat.h>
-#include "util_script.h"
-#include "http_log.h"
-#include "http_request.h"
-
-#define DEFAULT_METADIR ".web"
-#define DEFAULT_METASUFFIX ".meta"
-
-module cern_meta_module;
-
-typedef struct {
- char *metadir;
- char *metasuffix;
-} cern_meta_config;
-
-void *create_cern_meta_config (pool *p, server_rec *dummy)
-{
- cern_meta_config *new =
- (cern_meta_config *) palloc (p, sizeof(cern_meta_config));
-
- new->metadir = DEFAULT_METADIR;
- new->metasuffix = DEFAULT_METASUFFIX;
-
- return new;
-}
-
-const char *set_metadir (cmd_parms *parms, void *dummy, char *arg)
-{
- cern_meta_config *cmc ;
-
- cmc = get_module_config (parms->server->module_config,
- &cern_meta_module);
- cmc->metadir = arg;
- return NULL;
-}
-
-const char *set_metasuffix (cmd_parms *parms, void *dummy, char *arg)
-{
- cern_meta_config *cmc ;
-
- cmc = get_module_config (parms->server->module_config,
- &cern_meta_module);
- cmc->metasuffix = arg;
- return NULL;
-}
-
-command_rec cern_meta_cmds[] = {
-{ "MetaDir", set_metadir, NULL, RSRC_CONF, TAKE1,
- "the name of the directory containing meta files"},
-{ "MetaSuffix", set_metasuffix, NULL, RSRC_CONF, TAKE1,
- "the filename suffix for meta files"},
-{ NULL }
-};
-
-int scan_meta_file(request_rec *r, FILE *f)
-{
- char w[MAX_STRING_LEN];
- char *l;
- int p;
-
- while( fgets(w, MAX_STRING_LEN-1, f) != NULL ) {
-
- /* Delete terminal (CR?)LF */
-
- p = strlen(w);
- if (p > 0 && w[p-1] == '\n')
- {
- if (p > 1 && w[p-2] == '\015') w[p-2] = '\0';
- else w[p-1] = '\0';
- }
-
- if(w[0] == '\0') {
- return OK;
- }
-
- /* if we see a bogus header don't ignore it. Shout and scream */
-
- if(!(l = strchr(w,':'))) {
- log_reason ("malformed header in meta file", r->filename, r);
- return SERVER_ERROR;
- }
-
- *l++ = '\0';
- while (*l && isspace (*l)) ++l;
-
- if(!strcasecmp(w,"Content-type")) {
-
- /* Nuke trailing whitespace */
-
- char *endp = l + strlen(l) - 1;
- while (endp > l && isspace(*endp)) *endp-- = '\0';
-
- r->content_type = pstrdup (r->pool, l);
- }
- else if(!strcasecmp(w,"Status")) {
- sscanf(l, "%d", &r->status);
- r->status_line = pstrdup(r->pool, l);
- }
- else {
- table_set (r->headers_out, w, l);
- }
- }
- return OK;
-}
-
-int add_cern_meta_data(request_rec *r)
-{
- char *metafilename;
- char *last_slash;
- char *real_file;
- char *scrap_book;
- FILE *f;
- cern_meta_config *cmc ;
- int rv;
- request_rec *rr;
-
- cmc = get_module_config (r->server->module_config,
- &cern_meta_module);
-
- /* if ./.web/$1.meta exists then output 'asis' */
-
- if (r->finfo.st_mode == 0) {
- return DECLINED;
- };
-
- /* does uri end in a trailing slash? */
- if ( r->uri[strlen(r->uri) - 1] == '/' ) {
- return DECLINED;
- };
-
- /* what directory is this file in? */
- scrap_book = pstrdup( r->pool, r->filename );
- /* skip leading slash, recovered in later processing */
- scrap_book++;
- last_slash = strrchr( scrap_book, '/' );
- if ( last_slash != NULL ) {
- /* skip over last slash */
- real_file = last_slash;
- real_file++;
- *last_slash = '\0';
- } else {
- /* no last slash, buh?! */
- log_reason("internal error in mod_cern_meta", r->filename, r);
- /* should really barf, but hey, let's be friends... */
- return DECLINED;
- };
-
- metafilename = pstrcat(r->pool, "/", scrap_book, "/", cmc->metadir, "/", real_file, cmc->metasuffix, NULL);
-
- /* XXX: it sucks to require this subrequest to complete, because this
- * means people must leave their meta files accessible to the world.
- * A better solution might be a "safe open" feature of pfopen to avoid
- * pipes, symlinks, and crap like that.
- */
- rr = sub_req_lookup_file (metafilename, r);
- if (rr->status != HTTP_OK) {
- destroy_sub_req (rr);
- return DECLINED;
- }
- destroy_sub_req (rr);
-
- f = pfopen (r->pool, metafilename, "r");
- if (f == NULL) {
- if (errno == ENOENT) {
- return DECLINED;
- }
- log_reason("meta file permissions deny server access", metafilename, r);
- return FORBIDDEN;
- };
-
- /* read the headers in */
- rv = scan_meta_file(r, f);
- pfclose( r->pool, f );
-
- return rv;
-}
-
-module cern_meta_module = {
- STANDARD_MODULE_STUFF,
- NULL, /* initializer */
- NULL, /* dir config creater */
- NULL, /* dir merger --- default is to override */
- create_cern_meta_config, /* server config */
- NULL, /* merge server configs */
- cern_meta_cmds, /* command table */
- NULL, /* handlers */
- NULL, /* filename translation */
- NULL, /* check_user_id */
- NULL, /* check auth */
- NULL, /* check access */
- NULL, /* type_checker */
- add_cern_meta_data, /* fixups */
- NULL, /* logger */
- NULL /* header parser */
-};
diff --git a/usr.sbin/httpd/src/mod_cgi.c b/usr.sbin/httpd/src/mod_cgi.c
deleted file mode 100644
index 6931d128878..00000000000
--- a/usr.sbin/httpd/src/mod_cgi.c
+++ /dev/null
@@ -1,575 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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_script: keeps all script-related ramblings together.
- *
- * Compliant to CGI/1.1 spec
- *
- * Adapted by rst from original NCSA code by Rob McCool
- *
- * Apache adds some new env vars; REDIRECT_URL and REDIRECT_QUERY_STRING for
- * custom error responses, and DOCUMENT_ROOT because we found it useful.
- * It also adds SERVER_ADMIN - useful for scripts to know who to mail when
- * they fail.
- */
-
-#include "httpd.h"
-#include "http_config.h"
-#include "http_request.h"
-#include "http_core.h"
-#include "http_protocol.h"
-#include "http_main.h"
-#include "http_log.h"
-#include "util_script.h"
-#include "http_conf_globals.h"
-
-module cgi_module;
-
-/* KLUDGE --- for back-combatibility, we don't have to check ExecCGI
- * in ScriptAliased directories, which means we need to know if this
- * request came through ScriptAlias or not... so the Alias module
- * leaves a note for us.
- */
-
-int is_scriptaliased (request_rec *r)
-{
- char *t = table_get (r->notes, "alias-forced-type");
- return t && (!strcasecmp (t, "cgi-script"));
-}
-
-/* Configuration stuff */
-
-#define DEFAULT_LOGBYTES 10385760
-#define DEFAULT_BUFBYTES 1024
-
-typedef struct {
- char *logname;
- long logbytes;
- int bufbytes;
-} cgi_server_conf;
-
-void *create_cgi_config (pool *p, server_rec *s)
-{
- cgi_server_conf *c =
- (cgi_server_conf *)pcalloc (p, sizeof(cgi_server_conf));
-
- c->logname = NULL;
- c->logbytes = DEFAULT_LOGBYTES;
- c->bufbytes = DEFAULT_BUFBYTES;
-
- return c;
-}
-
-void *merge_cgi_config (pool *p, void *basev, void *overridesv)
-{
- cgi_server_conf *base = (cgi_server_conf *)basev,
- *overrides = (cgi_server_conf *)overridesv;
-
- return overrides->logname ? overrides : base;
-}
-
-const char *set_scriptlog (cmd_parms *cmd, void *dummy, char *arg) {
- server_rec *s = cmd->server;
- cgi_server_conf *conf =
- (cgi_server_conf *)get_module_config(s->module_config, &cgi_module);
-
- conf->logname = arg;
- return NULL;
-}
-
-const char *set_scriptlog_length (cmd_parms *cmd, void *dummy, char *arg) {
- server_rec *s = cmd->server;
- cgi_server_conf *conf =
- (cgi_server_conf *)get_module_config(s->module_config, &cgi_module);
-
- conf->logbytes = atol (arg);
- return NULL;
-}
-
-const char *set_scriptlog_buffer (cmd_parms *cmd, void *dummy, char *arg) {
- server_rec *s = cmd->server;
- cgi_server_conf *conf =
- (cgi_server_conf *)get_module_config(s->module_config, &cgi_module);
-
- conf->bufbytes = atoi (arg);
- return NULL;
-}
-
-command_rec cgi_cmds[] = {
-{ "ScriptLog", set_scriptlog, NULL, RSRC_CONF, TAKE1,
- "the name of a log for script debugging info"},
-{ "ScriptLogLength", set_scriptlog_length, NULL, RSRC_CONF, TAKE1,
- "the maximum length (in bytes) of the script debug log"},
-{ "ScriptLogBuffer", set_scriptlog_buffer, NULL, RSRC_CONF, TAKE1,
- "the maximum size (in bytes) to record of a POST request"},
-{ NULL}
-};
-
-static int log_scripterror(request_rec *r, cgi_server_conf *conf, int ret,
- char *error)
-{
- FILE *f;
-
- log_reason(error, r->filename, r);
-
- if (!conf->logname ||
- ((stat(server_root_relative(r->pool, conf->logname), &r->finfo) == 0)
- && (r->finfo.st_size > conf->logbytes)) ||
- ((f = pfopen(r->pool, server_root_relative(r->pool, conf->logname),
- "a")) == NULL)) {
- return ret;
- }
-
- /* "%% [Wed Jun 19 10:53:21 1996] GET /cgi-bin/printenv HTTP/1.0" */
- fprintf(f, "%%%% [%s] %s %s%s%s %s\n", get_time(), r->method, r->uri,
- r->args ? "?" : "", r->args ? r->args : "", r->protocol);
- /* "%% 500 /usr/local/etc/httpd/cgi-bin */
- fprintf(f, "%%%% %d %s\n", ret, r->filename);
-
- fprintf(f, "%%error\n%s\n", error);
-
- pfclose(r->pool, f);
- return ret;
-}
-
-static int log_script(request_rec *r, cgi_server_conf *conf, int ret,
- char *dbuf, char *sbuf, FILE *script_in, FILE *script_err)
-{
- table *hdrs_arr = r->headers_in;
- table_entry *hdrs = (table_entry *)hdrs_arr->elts;
- char argsbuffer[HUGE_STRING_LEN];
- FILE *f;
- int i;
-
- if (!conf->logname ||
- ((stat(server_root_relative(r->pool, conf->logname), &r->finfo) == 0)
- && (r->finfo.st_size > conf->logbytes)) ||
- ((f = pfopen(r->pool, server_root_relative(r->pool, conf->logname),
- "a")) == NULL)) {
- /* Soak up script output */
- while (fgets(argsbuffer, MAX_STRING_LEN-1, script_in) != NULL)
- continue;
- while (fgets(argsbuffer, MAX_STRING_LEN-1, script_err) != NULL)
- continue;
- return ret;
- }
-
- /* "%% [Wed Jun 19 10:53:21 1996] GET /cgi-bin/printenv HTTP/1.0" */
- fprintf(f, "%%%% [%s] %s %s%s%s %s\n", get_time(), r->method, r->uri,
- r->args ? "?" : "", r->args ? r->args : "", r->protocol);
- /* "%% 500 /usr/local/etc/httpd/cgi-bin */
- fprintf(f, "%%%% %d %s\n", ret, r->filename);
-
- fputs("%request\n", f);
- for (i = 0; i < hdrs_arr->nelts; ++i) {
- if (!hdrs[i].key) continue;
- fprintf(f, "%s: %s\n", hdrs[i].key, hdrs[i].val);
- }
- if ((r->method_number == M_POST || r->method_number == M_PUT)
- && dbuf && *dbuf) {
- fprintf(f, "\n%s\n", dbuf);
- }
-
- fputs("%response\n", f);
- hdrs_arr = r->err_headers_out;
- hdrs = (table_entry *)hdrs_arr->elts;
-
- for (i = 0; i < hdrs_arr->nelts; ++i) {
- if (!hdrs[i].key) continue;
- fprintf(f, "%s: %s\n", hdrs[i].key, hdrs[i].val);
- }
-
- if (sbuf && *sbuf)
- fprintf(f, "%s\n", sbuf);
-
- *argsbuffer = '\0';
- fgets(argsbuffer, HUGE_STRING_LEN-1, script_in);
- if (*argsbuffer) {
- fputs("%stdout\n", f);
- fputs(argsbuffer, f);
- while (fgets(argsbuffer, HUGE_STRING_LEN-1, script_in) != NULL)
- fputs(argsbuffer, f);
- fputs("\n", f);
- }
-
- *argsbuffer = '\0';
- fgets(argsbuffer, HUGE_STRING_LEN-1, script_err);
- if (*argsbuffer) {
- fputs("%stderr\n", f);
- fputs(argsbuffer, f);
- while (fgets(argsbuffer, HUGE_STRING_LEN-1, script_err) != NULL)
- fputs(argsbuffer, f);
- fputs("\n", f);
- }
-
- pfclose(r->main ? r->main->pool : r->pool, script_in);
- pfclose(r->main ? r->main->pool : r->pool, script_err);
-
- pfclose(r->pool, f);
- return ret;
-}
-
-/****************************************************************
- *
- * Actual CGI handling...
- */
-
-
-struct cgi_child_stuff {
- request_rec *r;
- int nph;
- int debug;
- char *argv0;
-};
-
-void cgi_child (void *child_stuff)
-{
- struct cgi_child_stuff *cld = (struct cgi_child_stuff *)child_stuff;
- request_rec *r = cld->r;
- char *argv0 = cld->argv0;
- int nph = cld->nph;
-
-#ifdef DEBUG_CGI
-#ifdef __EMX__
- /* Under OS/2 need to use device con. */
- FILE *dbg = fopen ("con", "w");
-#else
- FILE *dbg = fopen ("/dev/tty", "w");
-#endif
- int i;
-#endif
-
- char **env;
- char err_string[HUGE_STRING_LEN];
-
-#ifdef DEBUG_CGI
- fprintf (dbg, "Attempting to exec %s as %sCGI child (argv0 = %s)\n",
- r->filename, nph ? "NPH " : "", argv0);
-#endif
-
- add_cgi_vars (r);
- env = create_environment (r->pool, r->subprocess_env);
-
-#ifdef DEBUG_CGI
- fprintf (dbg, "Environment: \n");
- for (i = 0; env[i]; ++i) fprintf (dbg, "'%s'\n", env[i]);
-#endif
-
- chdir_file (r->filename);
- if (!cld->debug)
- error_log2stderr (r->server);
-
-#ifndef __EMX__
- if (nph) client_to_stdout (r->connection);
-#endif
-
- /* Transumute outselves into the script.
- * NB only ISINDEX scripts get decoded arguments.
- */
-
- cleanup_for_exec();
-
- call_exec(r, argv0, env, 0);
-
- /* Uh oh. Still here. Where's the kaboom? There was supposed to be an
- * EARTH-shattering kaboom!
- *
- * Oh, well. Muddle through as best we can...
- *
- * (NB we can't use log_error, or anything like that, because we
- * just closed the file descriptor which r->server->error_log
- * was tied to in cleanup_for_exec(). It's only available on stderr
- * now, so that's what we use).
- */
-
- ap_snprintf(err_string, sizeof(err_string),
- "exec of %s failed, reason: %s (errno = %d)\n",
- r->filename, strerror(errno), errno);
- write(2, err_string, strlen(err_string));
- exit(0);
-}
-
-int cgi_handler (request_rec *r)
-{
- int retval, nph, dbpos = 0;
- char *argv0, *dbuf = NULL;
- FILE *script_out, *script_in, *script_err;
- char argsbuffer[HUGE_STRING_LEN];
- int is_included = !strcmp (r->protocol, "INCLUDED");
- void *sconf = r->server->module_config;
- cgi_server_conf *conf =
- (cgi_server_conf *)get_module_config(sconf, &cgi_module);
-
- struct cgi_child_stuff cld;
- pid_t child_pid;
-
- if (r->method_number == M_OPTIONS) {
- /* 99 out of 100 CGI scripts, this is all they support */
- r->allowed |= (1 << M_GET);
- r->allowed |= (1 << M_POST);
- return DECLINED;
- }
-
- if((argv0 = strrchr(r->filename,'/')) != NULL)
- argv0++;
- else argv0 = r->filename;
-
- nph = !(strncmp(argv0,"nph-",4));
-
- if (!(allow_options (r) & OPT_EXECCGI) && !is_scriptaliased (r))
- return log_scripterror(r, conf, FORBIDDEN,
- "Options ExecCGI is off in this directory");
- if (nph && is_included)
- return log_scripterror(r, conf, FORBIDDEN,
- "attempt to include NPH CGI script");
-
- if (S_ISDIR(r->finfo.st_mode))
- return log_scripterror(r, conf, FORBIDDEN,
- "attempt to invoke directory as script");
-#ifdef __EMX__
- /* Allow for cgi files without the .EXE extension on them under OS/2 */
- if (r->finfo.st_mode == 0) {
- struct stat statbuf;
-
- r->filename = pstrcat (r->pool, r->filename, ".EXE", NULL);
-
- if ((stat(r->filename, &statbuf) != 0) || (!S_ISREG(statbuf.st_mode))) {
- return log_scripterror(r, conf, NOT_FOUND,
- "script not found or unable to stat");
- }
- }
-#else
- if (r->finfo.st_mode == 0)
- return log_scripterror(r, conf, NOT_FOUND,
- "script not found or unable to stat");
-#endif
- if (!suexec_enabled) {
- if (!can_exec(&r->finfo))
- return log_scripterror(r, conf, FORBIDDEN,
- "file permissions deny server execution");
- }
-
- if ((retval = setup_client_block(r, REQUEST_CHUNKED_ERROR)))
- return retval;
-
- add_common_vars (r);
- cld.argv0 = argv0; cld.r = r; cld.nph = nph;
- cld.debug = conf->logname ? 1 : 0;
-
- if (!(child_pid =
- /*
- * we spawn out of r->main if it's there so that we can avoid
- * waiting for free_proc_chain to cleanup in the middle of an
- * SSI request -djg
- */
- spawn_child_err (r->main ? r->main->pool : r->pool, cgi_child,
- (void *)&cld,
- nph ? just_wait : kill_after_timeout,
-#ifdef __EMX__
- &script_out, &script_in, &script_err))) {
-#else
- &script_out, nph ? NULL : &script_in,
- &script_err))) {
-#endif
- log_reason ("couldn't spawn child process", r->filename, r);
- return SERVER_ERROR;
- }
-
- /* Transfer any put/post args, CERN style...
- * Note that if a buggy script fails to read everything we throw
- * at it, or a buggy client sends too much, we get a SIGPIPE, so
- * we have to ignore SIGPIPE while doing this. CERN does the same
- * (and in fact, they pretty nearly guarantee themselves a SIGPIPE
- * on every invocation by chasing the real client data with a
- * spurious newline).
- */
-
- if (should_client_block(r)) {
- void (*handler)();
- int dbsize, len_read;
-
- if (conf->logname) {
- dbuf = pcalloc(r->pool, conf->bufbytes+1);
- dbpos = 0;
- }
-
- hard_timeout ("copy script args", r);
- handler = signal (SIGPIPE, SIG_IGN);
-
- while ((len_read =
- get_client_block(r, argsbuffer, HUGE_STRING_LEN)) > 0)
- {
- if (conf->logname) {
- if ((dbpos + len_read) > conf->bufbytes) {
- dbsize = conf->bufbytes - dbpos;
- }
- else {
- dbsize = len_read;
- }
- memcpy(dbuf + dbpos, argsbuffer, dbsize);
- dbpos += dbsize;
- }
- reset_timeout(r);
- if (fwrite(argsbuffer, sizeof(char), len_read, script_out)
- < (size_t)len_read) {
- /* silly script stopped reading, soak up remaining message */
- while (get_client_block(r, argsbuffer, HUGE_STRING_LEN) > 0)
- ; /* dump it */
- break;
- }
- }
-
- fflush (script_out);
- signal (SIGPIPE, handler);
-
- kill_timeout (r);
- }
-
- pfclose (r->main ? r->main->pool : r->pool, script_out);
-
- /* Handle script return... */
- if (script_in && !nph) {
- char *location, sbuf[MAX_STRING_LEN];
- int ret;
-
- if ((ret = scan_script_header_err(r, script_in, sbuf)))
- return log_script(r, conf, ret, dbuf, sbuf, script_in, script_err);
-
- location = table_get (r->headers_out, "Location");
-
- if (location && location[0] == '/' && r->status == 200) {
-
- /* Soak up all the script output */
- hard_timeout ("read from script", r);
- while (fread(argsbuffer, sizeof(char), HUGE_STRING_LEN, script_in)
- > 0)
- continue;
- while (fread(argsbuffer, sizeof(char), HUGE_STRING_LEN, script_err)
- > 0)
- continue;
- kill_timeout (r);
-
-
- /* This redirect needs to be a GET no matter what the original
- * method was.
- */
- r->method = pstrdup(r->pool, "GET");
- r->method_number = M_GET;
-
- /* We already read the message body (if any), so don't allow
- * the redirected request to think it has one. We can ignore
- * Transfer-Encoding, since we used REQUEST_CHUNKED_ERROR.
- */
- table_unset(r->headers_in, "Content-Length");
-
- internal_redirect_handler (location, r);
- return OK;
- }
- else if (location && r->status == 200) {
- /* XX Note that if a script wants to produce its own Redirect
- * body, it now has to explicitly *say* "Status: 302"
- */
- return REDIRECT;
- }
-
- send_http_header(r);
- if (!r->header_only)
- send_fd(script_in, r);
- pfclose (r->main ? r->main->pool : r->pool, script_in);
-
- /* Soak up stderr */
- soft_timeout("soaking script stderr", r);
- while (!r->connection->aborted &&
- (fread(argsbuffer, sizeof(char), HUGE_STRING_LEN, script_err) > 0))
- continue;
- kill_timeout(r);
- pfclose (r->main ? r->main->pool : r->pool, script_err);
- }
-
- if (nph) {
-#ifdef __EMX__
- while (fgets(argsbuffer, HUGE_STRING_LEN-1, script_in) != NULL) {
- bputs(argsbuffer, r->connection->client);
- }
-#else
- waitpid(child_pid, (int*)0, 0);
-#endif
- }
-
- return OK; /* NOT r->status, even if it has changed. */
-}
-
-handler_rec cgi_handlers[] = {
-{ CGI_MAGIC_TYPE, cgi_handler },
-{ "cgi-script", cgi_handler },
-{ NULL }
-};
-
-module cgi_module = {
- STANDARD_MODULE_STUFF,
- NULL, /* initializer */
- NULL, /* dir config creater */
- NULL, /* dir merger --- default is to override */
- create_cgi_config, /* server config */
- merge_cgi_config, /* merge server config */
- cgi_cmds, /* command table */
- cgi_handlers, /* handlers */
- NULL, /* filename translation */
- NULL, /* check_user_id */
- NULL, /* check auth */
- NULL, /* check access */
- NULL, /* type_checker */
- NULL, /* fixups */
- NULL, /* logger */
- NULL /* header parser */
-};
diff --git a/usr.sbin/httpd/src/mod_digest.c b/usr.sbin/httpd/src/mod_digest.c
deleted file mode 100644
index 814f416d3e2..00000000000
--- a/usr.sbin/httpd/src/mod_digest.c
+++ /dev/null
@@ -1,363 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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_digest: MD5 digest authentication
- *
- * by Alexei Kosut <akosut@nueva.pvt.k12.ca.us>
- * based on mod_auth, by Rob McCool and Robert S. Thau
- *
- */
-
-#include "httpd.h"
-#include "http_config.h"
-#include "http_core.h"
-#include "http_log.h"
-#include "http_protocol.h"
-#include "util_md5.h"
-
-typedef struct digest_config_struct {
- char *pwfile;
-} digest_config_rec;
-
-typedef struct digest_header_struct {
- char *username;
- char *realm;
- char *nonce;
- char *requested_uri;
- char *digest;
-} digest_header_rec;
-
-void *create_digest_dir_config (pool *p, char *d)
-{
- return pcalloc (p, sizeof(digest_config_rec));
-}
-
-const char *set_digest_slot (cmd_parms *cmd, void *offset, char *f, char *t)
-{
- if (t && strcmp(t, "standard"))
- return pstrcat(cmd->pool, "Invalid auth file type: ", t, NULL);
-
- return set_string_slot(cmd, offset, f);
-}
-
-command_rec digest_cmds[] = {
-{ "AuthDigestFile", set_digest_slot,
- (void*)XtOffsetOf(digest_config_rec,pwfile), OR_AUTHCFG, TAKE12, NULL },
-{ NULL }
-};
-
-module digest_module;
-
-char *get_hash(request_rec *r, char *user, char *auth_pwfile)
-{
- FILE *f;
- char l[MAX_STRING_LEN];
- const char *rpw;
- char *w, *x;
-
- if(!(f=pfopen(r->pool, auth_pwfile, "r"))) {
- log_reason ("Could not open password file", auth_pwfile, r);
- return NULL;
- }
- while(!(cfg_getline(l,MAX_STRING_LEN,f))) {
- if((l[0] == '#') || (!l[0])) continue;
- rpw = l;
- w = getword(r->pool, &rpw, ':');
- x = getword(r->pool, &rpw, ':');
-
- if(x && w && !strcmp(user,w) && !strcmp(auth_name(r), x)) {
- pfclose(r->pool, f);
- return pstrdup (r->pool, rpw);
- }
- }
- pfclose(r->pool, f);
- return NULL;
-}
-
-/* Parse the Authorization header, if it exists */
-
-int get_digest_rec(request_rec *r, digest_header_rec *response) {
- const char *auth_line = table_get(r->headers_in, "Authorization");
- int l;
- int s = 0, vk = 0, vv = 0;
- char *t, *key, *value;
-
- if (!(t = auth_type(r)) || strcasecmp(t, "Digest"))
- return DECLINED;
-
- if (!auth_name (r)) {
- log_reason ("need AuthName", r->uri, r);
- return SERVER_ERROR;
- }
-
- if (!auth_line) {
- note_digest_auth_failure (r);
- return AUTH_REQUIRED;
- }
-
- if (strcasecmp(getword (r->pool, &auth_line, ' '), "Digest")) {
- /* Client tried to authenticate using wrong auth scheme */
- log_reason ("client used wrong authentication scheme", r->uri, r);
- note_digest_auth_failure (r);
- return AUTH_REQUIRED;
- }
-
- l = strlen(auth_line);
-
- key=palloc(r->pool,l);
- value=palloc(r->pool,l);
-
- /* There's probably a better way to do this, but for the time being... */
-
-#define D_KEY 0
-#define D_VALUE 1
-#define D_STRING 2
-#define D_EXIT -1
-
- while (s != D_EXIT) {
- switch (s) {
- case D_STRING:
- if (auth_line[0] == '\"') {
- s = D_VALUE;
- }
- else {
- value[vv] = auth_line[0];
- vv++;
- }
- auth_line++;
- break;
-
- case D_VALUE:
- if (isalnum(auth_line[0])) {
- value[vv] = auth_line[0];
- vv++;
- }
- else if (auth_line[0] == '\"') {
- s = D_STRING;
- }
- else {
- value[vv] = '\0';
-
- if (!strcasecmp(key, "username"))
- response->username = pstrdup(r->pool, value);
- else if (!strcasecmp(key, "realm"))
- response->realm = pstrdup(r->pool, value);
- else if (!strcasecmp(key, "nonce"))
- response->nonce = pstrdup(r->pool, value);
- else if (!strcasecmp(key, "uri"))
- response->requested_uri = pstrdup(r->pool, value);
- else if (!strcasecmp(key, "response"))
- response->digest = pstrdup(r->pool, value);
-
- vv = 0;
- s = D_KEY;
- }
- auth_line++;
- break;
-
- case D_KEY:
- if (isalnum(auth_line[0])) {
- key[vk] = auth_line[0];
- vk++;
- }
- else if (auth_line[0] == '=') {
- key[vk] = '\0';
- vk = 0;
- s = D_VALUE;
- }
- auth_line++;
- break;
- }
-
- if (auth_line[-1] == '\0')
- s = D_EXIT;
- }
-
- if (!response->username || !response->realm || !response->nonce ||
- !response->requested_uri || !response->digest) {
- note_digest_auth_failure (r);
- return AUTH_REQUIRED;
- }
-
- r->connection->user = response->username;
- r->connection->auth_type = "Digest";
-
- return OK;
-}
-
-/* The actual MD5 code... whee */
-
-char *find_digest(request_rec *r, digest_header_rec *h, char *a1) {
- return md5(r->pool,
- (unsigned char *)pstrcat(r->pool, a1, ":", h->nonce, ":",
- md5(r->pool,
- (unsigned char *)pstrcat(r->pool,r->method,":",
- h->requested_uri,NULL)),
- NULL));
-}
-
-/* These functions return 0 if client is OK, and proper error status
- * if not... either AUTH_REQUIRED, if we made a check, and it failed, or
- * SERVER_ERROR, if things are so totally confused that we couldn't
- * figure out how to tell if the client is authorized or not.
- *
- * If they return DECLINED, and all other modules also decline, that's
- * treated by the server core as a configuration error, logged and
- * reported as such.
- */
-
-/* Determine user ID, and check if it really is that user, for HTTP
- * basic authentication...
- */
-
-int authenticate_digest_user (request_rec *r)
-{
- digest_config_rec *sec =
- (digest_config_rec *)get_module_config (r->per_dir_config,
- &digest_module);
- digest_header_rec *response = pcalloc (r->pool, sizeof(digest_header_rec));
- conn_rec *c = r->connection;
- char *a1;
- char errstr[MAX_STRING_LEN];
- int res;
-
- if ((res = get_digest_rec (r, response))) return res;
-
- if(!sec->pwfile)
- return DECLINED;
-
- if (!(a1 = get_hash(r, c->user, sec->pwfile))) {
- ap_snprintf(errstr, sizeof(errstr), "user %s not found",c->user);
- log_reason (errstr, r->uri, r);
- note_digest_auth_failure (r);
- return AUTH_REQUIRED;
- }
- /* anyone know where the prototype for crypt is? */
- if(strcmp(response->digest, find_digest(r, response, a1))) {
- ap_snprintf(errstr, sizeof(errstr), "user %s: password mismatch",c->user);
- log_reason (errstr, r->uri, r);
- note_digest_auth_failure (r);
- return AUTH_REQUIRED;
- }
- return OK;
-}
-
-/* Checking ID */
-
-int digest_check_auth (request_rec *r) {
- char *user = r->connection->user;
- int m = r->method_number;
- int method_restricted = 0;
- register int x;
- const char *t;
- char *w;
- array_header *reqs_arr;
- require_line *reqs;
-
- if (!(t = auth_type(r)) || strcasecmp(t, "Digest"))
- return DECLINED;
-
- reqs_arr = requires (r);
- /* If there is no "requires" directive,
- * then any user will do.
- */
- if (!reqs_arr)
- return OK;
- reqs = (require_line *)reqs_arr->elts;
-
- for(x=0; x < reqs_arr->nelts; x++) {
-
- if (! (reqs[x].method_mask & (1 << m))) continue;
-
- method_restricted = 1;
-
- t = reqs[x].requirement;
- w = getword(r->pool, &t, ' ');
- if(!strcmp(w,"valid-user"))
- return OK;
- else if(!strcmp(w,"user")) {
- while(t[0]) {
- w = getword_conf (r->pool, &t);
- if(!strcmp(user,w))
- return OK;
- }
- }
- else
- return DECLINED;
- }
-
- if (!method_restricted)
- return OK;
-
- note_digest_auth_failure(r);
- return AUTH_REQUIRED;
-}
-
-module digest_module = {
- STANDARD_MODULE_STUFF,
- NULL, /* initializer */
- create_digest_dir_config, /* dir config creater */
- NULL, /* dir merger --- default is to override */
- NULL, /* server config */
- NULL, /* merge server config */
- digest_cmds, /* command table */
- NULL, /* handlers */
- NULL, /* filename translation */
- authenticate_digest_user, /* check_user_id */
- digest_check_auth, /* check auth */
- NULL, /* check access */
- NULL, /* type_checker */
- NULL, /* fixups */
- NULL, /* logger */
- NULL /* header parser */
-};
diff --git a/usr.sbin/httpd/src/mod_dir.c b/usr.sbin/httpd/src/mod_dir.c
deleted file mode 100644
index 435b5d3378f..00000000000
--- a/usr.sbin/httpd/src/mod_dir.c
+++ /dev/null
@@ -1,911 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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_dir.c: Handles the on-the-fly html index generation
- *
- * Rob McCool
- * 3/23/93
- *
- * Adapted to Apache by rst.
- */
-
-#include "httpd.h"
-#include "http_config.h"
-#include "http_core.h"
-#include "http_request.h"
-#include "http_protocol.h"
-#include "http_log.h"
-#include "http_main.h"
-#include "util_script.h"
-
-module dir_module;
-
-/****************************************************************
- *
- * Handling configuration directives...
- */
-
-#define FANCY_INDEXING 1 /* Indexing options */
-#define ICONS_ARE_LINKS 2
-#define SCAN_HTML_TITLES 4
-#define SUPPRESS_LAST_MOD 8
-#define SUPPRESS_SIZE 16
-#define SUPPRESS_DESC 32
-
-struct item {
- char *type;
- char *apply_to;
- char *apply_path;
- char *data;
-};
-
-typedef struct dir_config_struct {
-
- char *default_icon;
- char *index_names;
-
- array_header *icon_list, *alt_list, *desc_list, *ign_list;
- array_header *hdr_list, *rdme_list, *opts_list;
-
-} dir_config_rec;
-
-char c_by_encoding, c_by_type, c_by_path;
-
-#define BY_ENCODING &c_by_encoding
-#define BY_TYPE &c_by_type
-#define BY_PATH &c_by_path
-
-void push_item(array_header *arr, char *type, char *to, char *path, char *data)
-{
- struct item *p = (struct item *)push_array(arr);
-
- if (!to) to = "";
- if (!path) path = "";
-
- p->type = type;
- p->data = data ? pstrdup(arr->pool, data): NULL;
- p->apply_path = pstrcat(arr->pool, path, "*", NULL);
-
- if((type == BY_PATH) && (!is_matchexp(to)))
- p->apply_to = pstrcat (arr->pool, "*", to, NULL);
- else if (to)
- p->apply_to = pstrdup (arr->pool, to);
- else
- p->apply_to = NULL;
-}
-
-const char *add_alt(cmd_parms *cmd, void *d, char *alt, char *to)
-{
- if (cmd->info == BY_PATH)
- if(!strcmp(to,"**DIRECTORY**"))
- to = "^^DIRECTORY^^";
-
- push_item(((dir_config_rec *)d)->alt_list, cmd->info, to, cmd->path, alt);
- return NULL;
-}
-
-const char *add_icon(cmd_parms *cmd, void *d, char *icon, char *to)
-{
- char *iconbak = pstrdup (cmd->pool, icon);
-
- if(icon[0] == '(') {
- char *alt = getword_nc (cmd->pool, &iconbak, ',');
- iconbak[strlen(iconbak) - 1] = '\0'; /* Lose closing paren */
- add_alt(cmd, d, &alt[1], to);
- }
- if(cmd->info == BY_PATH)
- if(!strcmp(to,"**DIRECTORY**"))
- to = "^^DIRECTORY^^";
-
- push_item(((dir_config_rec *)d)->icon_list, cmd->info, to, cmd->path,
- iconbak);
- return NULL;
-}
-
-const char *add_desc(cmd_parms *cmd, void *d, char *desc, char *to)
-{
- push_item(((dir_config_rec *)d)->desc_list, cmd->info, to, cmd->path,desc);
- return NULL;
-}
-
-const char *add_ignore(cmd_parms *cmd, void *d, char *ext) {
- push_item(((dir_config_rec *)d)->ign_list, 0, ext, cmd->path, NULL);
- return NULL;
-}
-
-const char *add_header(cmd_parms *cmd, void *d, char *name) {
- if (strchr (name, '/')) {
- return "HeaderName cannot contain a /";
- }
- push_item(((dir_config_rec *)d)->hdr_list, 0, NULL, cmd->path, name);
- return NULL;
-}
-
-const char *add_readme(cmd_parms *cmd, void *d, char *name) {
- if (strchr (name, '/')) {
- return "ReadmeName cannot contain a /";
- }
- push_item(((dir_config_rec *)d)->rdme_list, 0, NULL, cmd->path, name);
- return NULL;
-}
-
-
-const char *add_opts_int(cmd_parms *cmd, void *d, int opts) {
- push_item(((dir_config_rec *)d)->opts_list, (char*)opts, NULL,
- cmd->path, NULL);
- return NULL;
-}
-
-const char *fancy_indexing (cmd_parms *cmd, void *d, int arg)
-{
- return add_opts_int (cmd, d, arg? FANCY_INDEXING : 0);
-}
-
-const char *add_opts(cmd_parms *cmd, void *d, const char *optstr) {
- char *w;
- int opts = 0;
-
- while(optstr[0]) {
- w = getword_conf(cmd->pool, &optstr);
- if(!strcasecmp(w,"FancyIndexing"))
- opts |= FANCY_INDEXING;
- else if(!strcasecmp(w,"IconsAreLinks"))
- opts |= ICONS_ARE_LINKS;
- else if(!strcasecmp(w,"ScanHTMLTitles"))
- opts |= SCAN_HTML_TITLES;
- else if(!strcasecmp(w,"SuppressLastModified"))
- opts |= SUPPRESS_LAST_MOD;
- else if(!strcasecmp(w,"SuppressSize"))
- opts |= SUPPRESS_SIZE;
- else if(!strcasecmp(w,"SuppressDescription"))
- opts |= SUPPRESS_DESC;
- else if(!strcasecmp(w,"None"))
- opts = 0;
- else
- return "Invalid directory indexing option";
- }
- return add_opts_int(cmd, d, opts);
-}
-
-#define DIR_CMD_PERMS OR_INDEXES
-
-command_rec dir_cmds[] = {
-{ "AddIcon", add_icon, BY_PATH, DIR_CMD_PERMS, ITERATE2,
- "an icon URL followed by one or more filenames" },
-{ "AddIconByType", add_icon, BY_TYPE, DIR_CMD_PERMS, ITERATE2,
- "an icon URL followed by one or more MIME types" },
-{ "AddIconByEncoding", add_icon, BY_ENCODING, DIR_CMD_PERMS, ITERATE2,
- "an icon URL followed by one or more content encodings" },
-{ "AddAlt", add_alt, BY_PATH, DIR_CMD_PERMS, ITERATE2,
- "alternate descriptive text followed by one or more filenames" },
-{ "AddAltByType", add_alt, BY_TYPE, DIR_CMD_PERMS, ITERATE2,
- "alternate descriptive text followed by one or more MIME types" },
-{ "AddAltByEncoding", add_alt, BY_ENCODING, DIR_CMD_PERMS, ITERATE2,
- "alternate descriptive text followed by one or more content encodings" },
-{ "IndexOptions", add_opts, NULL, DIR_CMD_PERMS, RAW_ARGS,
- "one or more index options" },
-{ "IndexIgnore", add_ignore, NULL, DIR_CMD_PERMS, ITERATE,
- "one or more file extensions" },
-{ "AddDescription", add_desc, BY_PATH, DIR_CMD_PERMS, ITERATE2,
- "Descriptive text followed by one or more filenames" },
-{ "HeaderName", add_header, NULL, DIR_CMD_PERMS, TAKE1, "a filename" },
-{ "ReadmeName", add_readme, NULL, DIR_CMD_PERMS, TAKE1, "a filename" },
-{ "FancyIndexing", fancy_indexing, NULL, DIR_CMD_PERMS, FLAG, NULL },
-{ "DefaultIcon", set_string_slot,
- (void*)XtOffsetOf(dir_config_rec, default_icon),
- DIR_CMD_PERMS, TAKE1, "an icon URL"},
-{ "DirectoryIndex", set_string_slot,
- (void*)XtOffsetOf(dir_config_rec, index_names),
- DIR_CMD_PERMS, RAW_ARGS, NULL },
-{ NULL }
-};
-
-void *create_dir_config (pool *p, char *dummy)
-{
- dir_config_rec *new =
- (dir_config_rec *) pcalloc (p, sizeof(dir_config_rec));
-
- new->index_names = NULL;
- new->icon_list = make_array (p, 4, sizeof (struct item));
- new->alt_list = make_array (p, 4, sizeof (struct item));
- new->desc_list = make_array (p, 4, sizeof (struct item));
- new->ign_list = make_array (p, 4, sizeof (struct item));
- new->hdr_list = make_array (p, 4, sizeof (struct item));
- new->rdme_list = make_array (p, 4, sizeof (struct item));
- new->opts_list = make_array (p, 4, sizeof (struct item));
-
- return (void *)new;
-}
-
-void *merge_dir_configs (pool *p, void *basev, void *addv)
-{
- dir_config_rec *new=(dir_config_rec*)pcalloc (p, sizeof(dir_config_rec));
- dir_config_rec *base = (dir_config_rec *)basev;
- dir_config_rec *add = (dir_config_rec *)addv;
-
- new->default_icon = add->default_icon?add->default_icon:base->default_icon;
- new->index_names = add->index_names? add->index_names: base->index_names;
-
- new->alt_list = append_arrays (p, add->alt_list, base->alt_list);
- new->ign_list = append_arrays (p, add->ign_list, base->ign_list);
- new->hdr_list = append_arrays (p, add->hdr_list, base->hdr_list);
- new->desc_list = append_arrays (p, add->desc_list, base->desc_list);
- new->icon_list = append_arrays (p, add->icon_list, base->icon_list);
- new->rdme_list = append_arrays (p, add->rdme_list, base->rdme_list);
- new->opts_list = append_arrays (p, add->opts_list, base->opts_list);
-
- return new;
-}
-
-/****************************************************************
- *
- * Looking things up in config entries...
- */
-
-/* Structure used to hold entries when we're actually building an index */
-
-struct ent {
- char *name;
- char *icon;
- char *alt;
- char *desc;
- size_t size;
- time_t lm;
- struct ent *next;
-};
-
-char *find_item(request_rec *r, array_header *list, int path_only) {
- char *content_type = r->content_type;
- char *content_encoding = r->content_encoding;
- char *path = r->filename;
-
- struct item *items = (struct item *)list->elts;
- int i;
-
- for (i = 0; i < list->nelts; ++i) {
- struct item *p = &items[i];
-
- /* Special cased for ^^DIRECTORY^^ and ^^BLANKICON^^ */
- if((path[0] == '^') || (!strcmp_match(path,p->apply_path))) {
- if(!*(p->apply_to))
- return p->data;
- else if(p->type == BY_PATH || path[0] == '^') {
- if(!strcmp_match(path,p->apply_to))
- return p->data;
- } else if(!path_only) {
- if(!content_encoding) {
- if(p->type == BY_TYPE) {
- if(content_type && !strcmp_match(content_type,p->apply_to))
- return p->data;
- }
- } else {
- if(p->type == BY_ENCODING) {
- if(!strcmp_match(content_encoding,p->apply_to))
- return p->data;
- }
- }
- }
- }
- }
- return NULL;
-}
-
-#define find_icon(d,p,t) find_item(p,d->icon_list,t)
-#define find_alt(d,p,t) find_item(p,d->alt_list,t)
-#define find_desc(d,p) find_item(p,d->desc_list,0)
-#define find_header(d,p) find_item(p,d->hdr_list,0)
-#define find_readme(d,p) find_item(p,d->rdme_list,0)
-
-char *find_default_icon (dir_config_rec *d, char *bogus_name)
-{
- request_rec r;
-
- /* Bleah. I tried to clean up find_item, and it lead to this bit
- * of ugliness. Note that the fields initialized are precisely
- * those that find_item looks at...
- */
-
- r.filename = bogus_name;
- r.content_type = r.content_encoding = NULL;
-
- return find_item (&r, d->icon_list, 1);
-}
-
-int ignore_entry(dir_config_rec *d, char *path) {
- array_header *list = d->ign_list;
- struct item *items = (struct item *)list->elts;
- char *tt;
- int i;
-
- if((tt=strrchr(path,'/')) == NULL)
- tt=path;
- else {
- tt++;
- }
-
- for (i = 0; i < list->nelts; ++i) {
- struct item *p = &items[i];
- char *ap;
-
- if((ap=strrchr(p->apply_to,'/')) == NULL)
- ap=p->apply_to;
- else
- ap++;
-
- if(!strcmp_match(path,p->apply_path) && !strcmp_match(tt,ap))
- return 1;
- }
- return 0;
-}
-
-int find_opts(dir_config_rec *d, request_rec *r) {
- char *path = r->filename;
- array_header *list = d->opts_list;
- struct item *items = (struct item *)list->elts;
- int i;
-
- for (i = 0; i < list->nelts; ++i) {
- struct item *p = &items[i];
-
- if(!strcmp_match(path,p->apply_path))
- return (int)p->type;
- }
- return 0;
-}
-
-/*****************************************************************
- *
- * Actually generating output
- */
-
-
-int insert_readme(char *name, char *readme_fname, int rule, request_rec *r) {
- char *fn;
- FILE *f;
- struct stat finfo;
- int plaintext=0;
- request_rec *rr;
-
- /* XXX: this is a load of crap, it needs to do a full sub_req_lookup_uri */
- fn = make_full_path(r->pool, name, readme_fname);
- fn = pstrcat(r->pool, fn, ".html", NULL);
- if(stat(fn,&finfo) == -1) {
- /* A brief fake multiviews search for README.html */
- fn[strlen(fn)-5] = '\0';
- if(stat(fn,&finfo) == -1)
- return 0;
- plaintext=1;
- if(rule) rputs("<HR>\n", r);
- rputs("<PRE>\n", r);
- }
- else if (rule) rputs("<HR>\n", r);
- /* XXX: when the above is rewritten properly, this necessary security
- * check will be redundant. -djg */
- rr = sub_req_lookup_file (fn, r);
- if (rr->status != HTTP_OK) {
- destroy_sub_req (rr);
- return 0;
- }
- destroy_sub_req (rr);
- if(!(f = pfopen(r->pool,fn,"r")))
- return 0;
- if (!plaintext)
- send_fd(f, r);
- else
- {
- char buf[IOBUFSIZE+1];
- int i, n, c, ch;
- while (!feof(f))
- {
- do n = fread(buf, sizeof(char), IOBUFSIZE, f);
- while (n == -1 && ferror(f) && errno == EINTR);
- if (n == -1 || n == 0) break;
- buf[n] = '\0';
- c = 0;
- while (c < n)
- {
- for (i=c; i < n; i++)
- if (buf[i] == '<' || buf[i] == '>' || buf[i] == '&') break;
- ch = buf[i];
- buf[i] = '\0';
- rputs(&buf[c], r);
- if (ch == '<') rputs("&lt;", r);
- else if (ch == '>') rputs("&gt;", r);
- else if (ch == '&') rputs("&amp;", r);
- c = i + 1;
- }
- }
- }
- pfclose(r->pool, f);
- if(plaintext)
- rputs("</PRE>\n", r);
- return 1;
-}
-
-
-char *find_title(request_rec *r) {
- char titlebuf[MAX_STRING_LEN], *find = "<TITLE>";
- FILE *thefile = NULL;
- int x,y,n,p;
-
- if (r->status != HTTP_OK) {
- return NULL;
- }
- if (r->content_type && !strcasecmp(r->content_type,"text/html") && !r->content_encoding) {
- if(!(thefile = pfopen(r->pool, r->filename,"r")))
- return NULL;
- n = fread(titlebuf,sizeof(char),MAX_STRING_LEN - 1,thefile);
- titlebuf[n] = '\0';
- for(x=0,p=0;titlebuf[x];x++) {
- if(toupper(titlebuf[x]) == find[p]) {
- if(!find[++p]) {
- if((p = ind(&titlebuf[++x],'<')) != -1)
- titlebuf[x+p] = '\0';
- /* Scan for line breaks for Tanmoy's secretary */
- for(y=x;titlebuf[y];y++)
- if((titlebuf[y] == CR) || (titlebuf[y] == LF))
- titlebuf[y] = ' ';
- pfclose (r->pool, thefile);
- return pstrdup(r->pool, &titlebuf[x]);
- }
- } else p=0;
- }
- pfclose(r->pool, thefile);
- }
- return NULL;
-}
-
-struct ent *make_dir_entry(char *name, int dir_opts,
- dir_config_rec *d, request_rec *r)
-{
- struct ent *p;
-
- if((name[0] == '.') && (!name[1]))
- return(NULL);
-
- if (ignore_entry(d, make_full_path (r->pool, r->filename, name)))
- return(NULL);
-
- p=(struct ent *)pcalloc(r->pool, sizeof(struct ent));
- p->name = pstrdup (r->pool, name);
- p->size = -1;
- p->icon = NULL;
- p->alt = NULL;
- p->desc = NULL;
- p->lm = -1;
-
- if(dir_opts & FANCY_INDEXING) {
- request_rec *rr = sub_req_lookup_file (name, r);
-
- if (rr->finfo.st_mode != 0) {
- p->lm = rr->finfo.st_mtime;
- if(S_ISDIR(rr->finfo.st_mode)) {
- if(!(p->icon = find_icon(d,rr,1)))
- p->icon = find_default_icon(d,"^^DIRECTORY^^");
- if(!(p->alt = find_alt(d,rr,1)))
- p->alt = "DIR";
- p->size = -1;
- p->name = pstrcat (r->pool, name, "/", NULL);
- }
- else {
- p->icon = find_icon(d, rr, 0);
- p->alt = find_alt(d, rr, 0);
- p->size = rr->finfo.st_size;
- }
- }
-
- p->desc = find_desc(d, rr);
-
- if((!p->desc) && (dir_opts & SCAN_HTML_TITLES))
- p->desc = pstrdup (r->pool, find_title(rr));
-
- destroy_sub_req (rr);
- }
- return(p);
-}
-
-char *terminate_description(dir_config_rec *d, char *desc, int dir_opts) {
- int maxsize = 23;
- register int x;
-
- if(dir_opts & SUPPRESS_LAST_MOD) maxsize += 17;
- if(dir_opts & SUPPRESS_SIZE) maxsize += 7;
-
- for(x=0;desc[x] && maxsize;x++) {
- if(desc[x] == '<') {
- while(desc[x] != '>') {
- if(!desc[x]) {
- maxsize = 0;
- break;
- }
- ++x;
- }
- }
- else --maxsize;
- }
- if(!maxsize) {
- desc[x-1] = '>'; /* Grump. */
- desc[x] = '\0'; /* Double Grump! */
- }
- return desc;
-}
-
-void output_directories(struct ent **ar, int n,
- dir_config_rec *d, request_rec *r, int dir_opts)
-{
- int x, len;
- char *name = r->uri;
- char *tp;
- pool *scratch = make_sub_pool (r->pool);
-
- if(name[0] == '\0') name = "/";
-
- if(dir_opts & FANCY_INDEXING) {
- rputs("<PRE>", r);
- if((tp = find_default_icon(d,"^^BLANKICON^^")))
- rvputs(r, "<IMG SRC=\"", escape_html(scratch, tp),
- "\" ALT=\" \"> ", NULL);
- rputs("Name ", r);
- if(!(dir_opts & SUPPRESS_LAST_MOD))
- rputs("Last modified ", r);
- if(!(dir_opts & SUPPRESS_SIZE))
- rputs("Size ", r);
- if(!(dir_opts & SUPPRESS_DESC))
- rputs("Description", r);
- rputs("\n<HR>\n", r);
- }
- else {
- rputs("<UL>", r);
- }
-
- for(x=0;x<n;x++) {
- char *anchor = NULL, *t = NULL, *t2 = NULL;
-
- clear_pool (scratch);
-
- if((!strcmp(ar[x]->name,"../")) || (!strcmp(ar[x]->name,".."))) {
- char *t = make_full_path (scratch, name, "../");
- getparents(t);
- if(t[0] == '\0') t = "/";
- anchor = pstrcat (scratch, "<A HREF=\"",
- escape_html(scratch, os_escape_path(scratch, t, 0)),
- "\">", NULL);
- t2 = "Parent Directory</A> ";
- }
- else {
- t = ar[x]->name;
- len = strlen(t);
- if(len > 23) {
- t2 = pstrdup(scratch, t);
- t2[21] = '.';
- t2[22] = '.';
- t2[23] = '\0';
- t2 = escape_html(scratch, t2);
- t2 = pstrcat(scratch, t2, "</A>", NULL);
- } else
- {
- char buff[24]=" ";
- t2 = escape_html(scratch, t);
- buff[23-len] = '\0';
- t2 = pstrcat(scratch, t2, "</A>", buff, NULL);
- }
- anchor = pstrcat (scratch, "<A HREF=\"",
- escape_html(scratch, os_escape_path(scratch, t, 0)),
- "\">", NULL);
- }
-
- if(dir_opts & FANCY_INDEXING) {
- if(dir_opts & ICONS_ARE_LINKS)
- rputs(anchor, r);
- if((ar[x]->icon) || d->default_icon) {
- rvputs(r, "<IMG SRC=\"",
- escape_html(scratch, ar[x]->icon ?
- ar[x]->icon : d->default_icon),
- "\" ALT=\"[", (ar[x]->alt ? ar[x]->alt : " "),
- "]\">", NULL);
- }
- if(dir_opts & ICONS_ARE_LINKS)
- rputs("</A>", r);
-
- rvputs(r," ", anchor, t2, NULL);
- if(!(dir_opts & SUPPRESS_LAST_MOD)) {
- if(ar[x]->lm != -1) {
- char time[MAX_STRING_LEN];
- struct tm *ts = localtime(&ar[x]->lm);
- strftime(time,MAX_STRING_LEN,"%d-%b-%y %H:%M ",ts);
- rputs(time, r);
- }
- else {
- rputs(" ", r);
- }
- }
- if(!(dir_opts & SUPPRESS_SIZE)) {
- send_size(ar[x]->size,r);
- rputs(" ", r);
- }
- if(!(dir_opts & SUPPRESS_DESC)) {
- if(ar[x]->desc) {
- rputs(terminate_description(d, ar[x]->desc, dir_opts), r);
- }
- }
- }
- else
- rvputs(r, "<LI> ", anchor," ", t2, NULL);
- rputc('\n', r);
- }
- if(dir_opts & FANCY_INDEXING) {
- rputs("</PRE>", r);
- }
- else {
- rputs("</UL>", r);
- }
-}
-
-
-int dsortf(struct ent **s1,struct ent **s2)
-{
- return(strcmp((*s1)->name,(*s2)->name));
-}
-
-
-int index_directory(request_rec *r, dir_config_rec *dir_conf)
-{
- char *title_name = escape_html(r->pool, r->uri);
- char *title_endp;
- char *name = r->filename;
-
- DIR *d;
- struct DIR_TYPE *dstruct;
- int num_ent=0,x;
- struct ent *head,*p;
- struct ent **ar = NULL;
- char *tmp;
- int dir_opts = find_opts(dir_conf, r);
-
- if(!(d=opendir(name))) {
- log_reason ("Can't open directory for index", r->filename, r);
- return HTTP_FORBIDDEN;
- }
-
- r->content_type = "text/html";
-
- send_http_header(r);
-
- if (r->header_only) {
- closedir (d);
- return 0;
- }
- hard_timeout("send directory", r);
-
- /* Spew HTML preamble */
-
- title_endp = title_name + strlen(title_name) - 1;
-
- while (title_endp > title_name && *title_endp == '/')
- *title_endp-- = '\0';
-
- rvputs
- (
- r,
- "<HTML><HEAD>\n<TITLE>Index of ",
- title_name,
- "</TITLE>\n</HEAD><BODY>\n",
- NULL
- );
-
- if((!(tmp = find_header(dir_conf,r))) || (!(insert_readme(name,tmp,0,r))))
- rvputs(r, "<H1>Index of ", title_name, "</H1>\n", NULL);
-
- /*
- * Since we don't know how many dir. entries there are, put them into a
- * linked list and then arrayificate them so qsort can use them.
- */
- head=NULL;
- while((dstruct=readdir(d))) {
- if((p = make_dir_entry(dstruct->d_name, dir_opts, dir_conf, r))) {
- p->next=head;
- head=p;
- num_ent++;
- }
- }
- if (num_ent > 0) {
- ar=(struct ent **) palloc(r->pool, num_ent*sizeof(struct ent *));
- p=head;
- x=0;
- while(p) {
- ar[x++]=p;
- p = p->next;
- }
-
- qsort((void *)ar,num_ent,sizeof(struct ent *),
-#ifdef ULTRIX_BRAIN_DEATH
- (int (*))dsortf);
-#else
- (int (*)(const void *,const void *))dsortf);
-#endif
- }
- output_directories(ar, num_ent, dir_conf, r, dir_opts);
- closedir(d);
-
- if (dir_opts & FANCY_INDEXING)
- if((tmp = find_readme(dir_conf, r)))
- insert_readme(name,tmp,1,r);
- else {
- rputs("</UL>", r);
- }
-
- rputs ("</BODY></HTML>\n", r);
-
- kill_timeout(r);
- return 0;
-}
-
-/* The formal handler... */
-
-int handle_dir (request_rec *r)
-{
- dir_config_rec *d =
- (dir_config_rec *)get_module_config (r->per_dir_config, &dir_module);
- const char *names_ptr = d->index_names ? d->index_names : DEFAULT_INDEX;
- int allow_opts = allow_options (r);
- int error_notfound = 0;
-
- if (r->uri[0] == '\0' || r->uri[strlen(r->uri)-1] != '/') {
- char* ifile;
- if (r->args != NULL)
- ifile = pstrcat (r->pool, escape_uri(r->pool, r->uri),
- "/", "?", r->args, NULL);
- else
- ifile = pstrcat (r->pool, escape_uri(r->pool, r->uri),
- "/", NULL);
-
- table_set (r->headers_out, "Location",
- construct_url(r->pool, ifile, r->server));
- return HTTP_MOVED_PERMANENTLY;
- }
-
- /* KLUDGE --- make the sub_req lookups happen in the right directory.
- * Fixing this in the sub_req_lookup functions themselves is difficult,
- * and would probably break virtual includes...
- */
-
- r->filename = pstrcat (r->pool, r->filename, "/", NULL);
-
- while (*names_ptr) {
-
- char *name_ptr = getword_conf (r->pool, &names_ptr);
- request_rec *rr = sub_req_lookup_uri (name_ptr, r);
-
- if (rr->status == HTTP_OK && rr->finfo.st_mode != 0) {
- char* new_uri = escape_uri(r->pool, rr->uri);
-
- if (rr->args != NULL)
- new_uri = pstrcat(r->pool, new_uri, "?", rr->args, NULL);
- else if (r->args != NULL)
- new_uri = pstrcat(r->pool, new_uri, "?", r->args, NULL);
-
- destroy_sub_req (rr);
- internal_redirect (new_uri, r);
- return OK;
- }
-
- /* If the request returned a redirect, propagate it to the client */
-
- if (is_HTTP_REDIRECT(rr->status) ||
- (rr->status == HTTP_NOT_ACCEPTABLE && *names_ptr == '\0')) {
-
- error_notfound = rr->status;
- r->notes = overlay_tables(r->pool, r->notes, rr->notes);
- r->headers_out = overlay_tables(r->pool, r->headers_out,
- rr->headers_out);
- r->err_headers_out = overlay_tables(r->pool, r->err_headers_out,
- rr->err_headers_out);
- destroy_sub_req(rr);
- return error_notfound;
- }
-
- /* If the request returned something other than 404 (or 200),
- * it means the module encountered some sort of problem. To be
- * secure, we should return the error, rather than create
- * along a (possibly unsafe) directory index.
- *
- * So we store the error, and if none of the listed files
- * exist, we return the last error response we got, instead
- * of a directory listing.
- */
- if (rr->status && rr->status != HTTP_NOT_FOUND && rr->status != HTTP_OK)
- error_notfound = rr->status;
-
- destroy_sub_req (rr);
- }
-
- if (error_notfound)
- return error_notfound;
-
- r->allowed |= (1 << M_GET);
- if (r->method_number != M_GET) return NOT_IMPLEMENTED;
-
- /* OK, nothing easy. Trot out the heavy artillery... */
-
- if (allow_opts & OPT_INDEXES)
- return index_directory (r, d);
- else {
- log_reason ("Directory index forbidden by rule", r->filename, r);
- return HTTP_FORBIDDEN;
- }
-}
-
-
-handler_rec dir_handlers[] = {
-{ DIR_MAGIC_TYPE, handle_dir },
-{ NULL }
-};
-
-module dir_module = {
- STANDARD_MODULE_STUFF,
- NULL, /* initializer */
- create_dir_config, /* dir config creater */
- merge_dir_configs, /* dir merger --- default is to override */
- NULL, /* server config */
- NULL, /* merge server config */
- dir_cmds, /* command table */
- dir_handlers, /* handlers */
- NULL, /* filename translation */
- NULL, /* check_user_id */
- NULL, /* check auth */
- NULL, /* check access */
- NULL, /* type_checker */
- NULL, /* fixups */
- NULL, /* logger */
- NULL /* header parser */
-};
diff --git a/usr.sbin/httpd/src/mod_dld.c b/usr.sbin/httpd/src/mod_dld.c
deleted file mode 100644
index ac6ff33a7ad..00000000000
--- a/usr.sbin/httpd/src/mod_dld.c
+++ /dev/null
@@ -1,190 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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/>.
- *
- */
-
-/*
- * A first stab at dynamic loading, using the GNU dld library
- * (or at least, an embarassingly old version of it...).
- */
-
-#include "httpd.h"
-#include "http_config.h"
-#include "http_conf_globals.h" /* server_argv0. Sigh... */
-#include <dld.h>
-
-/*
- * The hard part of implementing LoadModule is deciding what to do about
- * rereading the config files. This proof-of-concept implementation takes the
- * cheap way out: we only actually load the modules the first time through.
- */
-
-static int been_there_done_that = 0; /* Loaded the modules yet? */
-static int have_symbol_table = 0;
-
-char *insure_dld_sane()
-{
- int errcode;
- char *bin_name;
-
- if (have_symbol_table) return NULL;
-
- bin_name = dld_find_executable (server_argv0);
-
- if ((errcode = dld_init (bin_name))) {
- dld_perror (server_argv0);
- return "Cannot find server binary (needed for dynamic linking).";
- }
-
- have_symbol_table = 1;
- return NULL;
-}
-
-char *link_file (pool *p, char *filename)
-{
- int errcode;
-
- filename = server_root_relative (p, filename);
- if ((errcode = dld_link (filename))) {
- dld_perror (server_argv0);
- return pstrcat (p, "Cannot load ", filename, " into server", NULL);
- }
- return NULL;
-}
-
-char *load_module (cmd_parms *cmd, void *dummy, char *modname, char *filename)
-{
- char *errname;
- module *modp;
-
- if (been_there_done_that) return NULL;
-
- if ((errname = insure_dld_sane())) return errname;
- if ((errname = link_file (cmd->pool, filename))) return errname;
- if (!(modp = (module *)dld_get_symbol (modname))) {
- return pstrcat (cmd->pool, "Can't find module ", modname,
- " in file ", filename, NULL);
- }
-
- add_module (modp);
-
- /* Alethea Patch (rws,djw2) - need to run configuration functions
- in new modules */
-
- if (modp->create_server_config)
- ((void**)cmd->server->module_config)[modp->module_index]=
- (*modp->create_server_config)(cmd->pool, cmd->server);
-
- if (modp->create_dir_config)
- ((void**)cmd->server->lookup_defaults)[modp->module_index]=
- (*modp->create_dir_config)(cmd->pool, NULL);
-
-
- return NULL;
-}
-
-char *load_file (cmd_parms *cmd, void *dummy, char *filename)
-{
- char *errname;
-
- if (been_there_done_that) return NULL;
-
- if ((errname = insure_dld_sane())) return errname;
- if ((errname = link_file (cmd->pool, filename))) return errname;
- return NULL;
-}
-
-void check_loaded_modules (server_rec *dummy, pool *p)
-{
- if (been_there_done_that) return;
-
- if (dld_undefined_sym_count > 0) {
- /* Screwup. Do the best we can to inform the user, and exit */
- char **bad_syms = dld_list_undefined_sym();
- int i;
-
- fprintf(stderr, "Dynamic linking error --- symbols left undefined.\n");
- fprintf(stderr, "(It may help to relink libraries).\n");
- fprintf(stderr, "Undefined symbols follow:\n");
-
- for (i = 0; i < dld_undefined_sym_count; ++i)
- fprintf (stderr, "%s\n", bad_syms[i]);
-
- exit (1);
- }
-
- been_there_done_that = 1;
-}
-
-command_rec dld_cmds[] = {
-{ "LoadModule", load_module, NULL, RSRC_CONF, TAKE2,
- "a module name, and the name of a file to load it from"},
-{ "LoadFile", load_file, NULL, RSRC_CONF, ITERATE,
- "files or libraries to link into the server at runtime"},
-{ NULL }
-};
-
-module dld_module = {
- STANDARD_MODULE_STUFF,
- check_loaded_modules, /* initializer */
- NULL, /* create per-dir config */
- NULL, /* merge per-dir config */
- NULL, /* server config */
- NULL, /* merge server config */
- dld_cmds, /* command table */
- NULL, /* handlers */
- NULL, /* filename translation */
- NULL, /* check_user_id */
- NULL, /* check auth */
- NULL, /* check access */
- NULL, /* type_checker */
- NULL, /* logger */
- NULL /* header parser */
-};
diff --git a/usr.sbin/httpd/src/mod_env.c b/usr.sbin/httpd/src/mod_env.c
deleted file mode 100644
index 8ae697038da..00000000000
--- a/usr.sbin/httpd/src/mod_env.c
+++ /dev/null
@@ -1,261 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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
- * IT'S 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_env.c
- * version 0.0.5
- * status beta
- * Pass environment variables to CGI/SSI scripts.
- *
- * Andrew Wilson <Andrew.Wilson@cm.cf.ac.uk> 06.Dec.95
- *
- * Change log:
- * 08.Dec.95 Now allows PassEnv directive to appear more than once in
- * conf files.
- * 10.Dec.95 optimisation. getenv() only called at startup and used
- * to build a fast-to-access table. table used to build
- * per-server environment for each request.
- * robustness. better able to handle errors in configuration
- * files:
- * 1) PassEnv directive present, but no environment variable listed
- * 2) PassEnv FOO present, but $FOO not present in environment
- * 3) no PassEnv directive present
- * 23.Dec.95 Now allows SetEnv directive with same semantics as 'sh' setenv:
- * SetEnv Var sets Var to the empty string
- * SetEnv Var Val sets Var to the value Val
- * Values containing whitespace should be quoted, eg:
- * SetEnv Var "this is some text"
- * Environment variables take their value from the last instance
- * of PassEnv / SetEnv to be reached in the configuration file.
- * For example, the sequence:
- * PassEnv FOO
- * SetEnv FOO override
- * Causes FOO to take the value 'override'.
- * 23.Feb.96 Added UnsetEnv directive to allow environment variables
- * to be removed.
- * Virtual hosts now 'inherit' parent server environment which
- * they're able to overwrite with their own directives or
- * selectively ignore with UnsetEnv.
- * *** IMPORTANT - the way that virtual hosts inherit their ***
- * *** environment variables from the default server's ***
- * *** configuration has changed. You should test your ***
- * *** configuration carefully before accepting this ***
- * *** version of the module in a live webserver which used ***
- * *** older versions of the module. ***
- */
-
-#include "httpd.h"
-#include "http_config.h"
-
-typedef struct {
- table *vars;
- char *unsetenv;
- int vars_present;
-} env_server_config_rec;
-
-module env_module;
-
-void *create_env_server_config (pool *p, server_rec *dummy)
-{
- env_server_config_rec *new =
- (env_server_config_rec *) palloc (p, sizeof(env_server_config_rec));
- new->vars = make_table (p, 50);
- new->unsetenv = "";
- new->vars_present = 0;
- return (void *) new;
-}
-
-void *merge_env_server_configs (pool *p, void *basev, void *addv)
-{
- env_server_config_rec *base = (env_server_config_rec *)basev;
- env_server_config_rec *add = (env_server_config_rec *)addv;
- env_server_config_rec *new =
- (env_server_config_rec *)palloc (p, sizeof(env_server_config_rec));
-
- table *new_table;
- table_entry *elts;
-
- int i;
- const char *uenv, *unset;
-
- /*
- * new_table = copy_table( p, base->vars );
- * foreach $element ( @add->vars ) {
- * table_set( new_table, $element.key, $element.val );
- * };
- * foreach $unsetenv ( @UNSETENV ) {
- * table_unset( new_table, $unsetenv );
- * }
- */
-
- new_table = copy_table( p, base->vars );
-
- elts = (table_entry *) add->vars->elts;
-
- for ( i = 0; i < add->vars->nelts; ++i ) {
- table_set( new_table, elts[i].key, elts[i].val );
- }
-
- unset = add->unsetenv;
- uenv = getword_conf( p, &unset );
- while ( uenv[0] != '\0' ) {
- table_unset( new_table, uenv );
- uenv = getword_conf( p, &unset );
- }
-
- new->vars = new_table;
-
- new->vars_present = base->vars_present || add->vars_present;
-
- return new;
-}
-
-const char *add_env_module_vars_passed (cmd_parms *cmd, char *struct_ptr,
- const char *arg)
-{
- env_server_config_rec *sconf =
- get_module_config (cmd->server->module_config, &env_module);
- table *vars = sconf->vars;
- char *env_var;
- char *name_ptr;
-
- while (*arg) {
- name_ptr = getword_conf (cmd->pool, &arg);
- env_var = getenv(name_ptr);
- if ( env_var != NULL ) {
- sconf->vars_present = 1;
- table_set (vars, name_ptr, env_var);
- }
- }
- return NULL;
-}
-
-const char *add_env_module_vars_set (cmd_parms *cmd, char *struct_ptr,
- const char *arg)
-{
- env_server_config_rec *sconf =
- get_module_config (cmd->server->module_config, &env_module);
- table *vars = sconf->vars;
- char *name, *value;
-
- name = getword_conf( cmd->pool, &arg );
- value = getword_conf( cmd->pool, &arg );
-
- /* name is mandatory, value is optional. no value means
- * set the variable to an empty string
- */
-
-
- if ( (*name == '\0') || (*arg != '\0')) {
- return "SetEnv takes one or two arguments. An environment variable name and an optional value to pass to CGI." ;
- }
-
- sconf->vars_present = 1;
- table_set (vars, name, value);
-
- return NULL;
-}
-
-const char *add_env_module_vars_unset (cmd_parms *cmd, char *struct_ptr,
- char *arg)
-{
- env_server_config_rec *sconf =
- get_module_config (cmd->server->module_config, &env_module);
- sconf->unsetenv = sconf->unsetenv ?
- pstrcat( cmd->pool, sconf->unsetenv, " ", arg, NULL ) :
- pstrdup( cmd->pool, arg );
- return NULL;
-}
-
-command_rec env_module_cmds[] = {
-{ "PassEnv", add_env_module_vars_passed, NULL,
- RSRC_CONF, RAW_ARGS, "a list of environment variables to pass to CGI." },
-{ "SetEnv", add_env_module_vars_set, NULL,
- RSRC_CONF, RAW_ARGS, "an environment variable name and a value to pass to CGI." },
-{ "UnsetEnv", add_env_module_vars_unset, NULL,
- RSRC_CONF, RAW_ARGS, "a list of variables to remove from the CGI environment." },
-{ NULL },
-};
-
-int fixup_env_module(request_rec *r)
-{
- table *e = r->subprocess_env;
- server_rec *s = r->server;
- env_server_config_rec *sconf = get_module_config (s->module_config,
- &env_module);
- table *vars = sconf->vars;
-
- if ( !sconf->vars_present ) return DECLINED;
-
- r->subprocess_env = overlay_tables( r->pool, e, vars );
-
- return OK;
-}
-
-module env_module = {
- STANDARD_MODULE_STUFF,
- NULL, /* initializer */
- NULL, /* dir config creater */
- NULL, /* dir merger --- default is to override */
- create_env_server_config, /* server config */
- merge_env_server_configs, /* merge server configs */
- env_module_cmds, /* command table */
- NULL, /* handlers */
- NULL, /* filename translation */
- NULL, /* check_user_id */
- NULL, /* check auth */
- NULL, /* check access */
- NULL, /* type_checker */
- fixup_env_module, /* fixups */
- NULL, /* logger */
- NULL /* header parser */
-};
diff --git a/usr.sbin/httpd/src/mod_expires.c b/usr.sbin/httpd/src/mod_expires.c
deleted file mode 100644
index 226726a0a93..00000000000
--- a/usr.sbin/httpd/src/mod_expires.c
+++ /dev/null
@@ -1,477 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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
- * IT'S 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_expires.c
- * version 0.0.11
- * status beta
- *
- * Andrew Wilson <Andrew.Wilson@cm.cf.ac.uk> 26.Jan.96
- *
- * This module allows you to control the form of the Expires: header
- * that Apache issues for each access. Directives can appear in
- * configuration files or in .htaccess files so expiry semantics can
- * be defined on a per-directory basis.
- *
- * DIRECTIVE SYNTAX
- *
- * Valid directives are:
- *
- * ExpiresActive on | off
- * ExpiresDefault <code><seconds>
- * ExpiresByType type/encoding <code><seconds>
- *
- * Valid values for <code> are:
- *
- * 'M' expires header shows file modification date + <seconds>
- * 'A' expires header shows access time + <seconds>
- *
- * [I'm not sure which of these is best under different
- * circumstances, I guess it's for other people to explore.
- * The effects may be indistinguishable for a number of cases]
- *
- * <seconds> should be an integer value [acceptable to atoi()]
- *
- * There is NO space between the <code> and <seconds>.
- *
- * For example, a directory which contains information which changes
- * frequently might contain:
- *
- * # reports generated by cron every hour. don't let caches
- * # hold onto stale information
- * ExpiresDefault M3600
- *
- * Another example, our html pages can change all the time, the gifs
- * tend not to change often:
- *
- * # pages are hot (1 week), images are cold (1 month)
- * ExpiresByType text/html A604800
- * ExpiresByType image/gif A2592000
- *
- * Expires can be turned on for all URLs on the server by placing the
- * following directive in a conf file:
- *
- * ExpiresActive on
- *
- * ExpiresActive can also appear in .htaccess files, enabling the
- * behaviour to be turned on or off for each chosen directory.
- *
- * # turn off Expires behaviour in this directory
- * # and subdirectories
- * ExpiresActive off
- *
- * Directives defined for a directory are valid in subdirectories
- * unless explicitly overridden by new directives in the subdirectory
- * .htaccess files.
- *
- * ALTERNATIVE DIRECTIVE SYNTAX
- *
- * Directives can also be defined in a more readable syntax of the form:
- *
- * ExpiresDefault "<base> [plus] {<num> <type>}*"
- * ExpiresByType type/encoding "<base> [plus] {<num> <type>}*"
- *
- * where <base> is one of:
- * access
- * now equivalent to 'access'
- * modification
- *
- * where the 'plus' keyword is optional
- *
- * where <num> should be an integer value [acceptable to atoi()]
- *
- * where <type> is one of:
- * years
- * months
- * weeks
- * days
- * hours
- * minutes
- * seconds
- *
- * For example, any of the following directives can be used to make
- * documents expire 1 month after being accessed, by default:
- *
- * ExpiresDefault "access plus 1 month"
- * ExpiresDefault "access plus 4 weeks"
- * ExpiresDefault "access plus 30 days"
- *
- * The expiry time can be fine-tuned by adding several '<num> <type>'
- * clauses:
- *
- * ExpiresByType text/html "access plus 1 month 15 days 2 hours"
- * ExpiresByType image/gif "modification plus 5 hours 3 minutes"
- *
- * ---
- *
- * Change-log:
- * 29.Jan.96 Hardened the add_* functions. Server will now bail out
- * if bad directives are given in the conf files.
- * 02.Feb.96 Returns DECLINED if not 'ExpiresActive on', giving other
- * expires-aware modules a chance to play with the same
- * directives. [Michael Rutman]
- * 03.Feb.96 Call tzset() before localtime(). Trying to get the module
- * to work properly in non GMT timezones.
- * 12.Feb.96 Modified directive syntax to allow more readable commands:
- * ExpiresDefault "now plus 10 days 20 seconds"
- * ExpiresDefault "access plus 30 days"
- * ExpiresDefault "modification plus 1 year 10 months 30 days"
- * 13.Feb.96 Fix call to table_get() with NULL 2nd parameter [Rob Hartill]
- * 19.Feb.96 Call gm_timestr_822() to get time formatted correctly, can't
- * rely on presence of HTTP_TIME_FORMAT in Apache 1.1+.
- * 21.Feb.96 This version (0.0.9) reverses assumptions made in 0.0.8
- * about star/star handlers. Reverting to 0.0.7 behaviour.
- * 08.Jun.96 allows ExpiresDefault to be used with responses that use
- * the DefaultType by not DECLINING, but instead skipping
- * the table_get check and then looking for an ExpiresDefault.
- * [Rob Hartill]
- * 04.Nov.96 'const' definitions added.
- *
- * TODO
- * add support for Cache-Control: max-age=20 from the HTTP/1.1
- * proposal (in this case, a ttl of 20 seconds) [ask roy]
- * add per-file expiry and explicit expiry times - duplicates some
- * of the mod_cern_meta.c functionality. eg:
- * ExpiresExplicit index.html "modification plus 30 days"
- *
- * BUGS
- * Hi, welcome to the internet.
- */
-
-#include <ctype.h>
-#include "httpd.h"
-#include "http_config.h"
-#include "http_log.h"
-
-typedef struct {
- int active;
- char *expiresdefault;
- table *expiresbytype;
-} expires_dir_config;
-
-/* from mod_dir, why is this alias used?
- */
-#define DIR_CMD_PERMS OR_INDEXES
-
-#define ACTIVE_ON 1
-#define ACTIVE_OFF 0
-#define ACTIVE_DONTCARE 2
-
-module expires_module;
-
-void *create_dir_expires_config (pool *p, char *dummy)
-{
- expires_dir_config *new =
- (expires_dir_config *) pcalloc (p, sizeof(expires_dir_config));
- new->active = ACTIVE_DONTCARE;
- new->expiresdefault = "";
- new->expiresbytype = make_table(p, 4);
- return (void *)new;
-}
-
-const char *set_expiresactive (cmd_parms *cmd, expires_dir_config *dir_config, int arg)
-{
- /* if we're here at all it's because someone explicitly
- * set the active flag
- */
- dir_config->active = ACTIVE_ON;
- if ( arg == 0 ) {
- dir_config->active = ACTIVE_OFF;
- };
- return NULL;
-}
-
-/* check_code() parse 'code' and return NULL or an error response
- * string. If we return NULL then real_code contains code converted
- * to the cnnnn format.
- */
-char *check_code( pool *pool, const char *code, char **real_code )
-{
- char *word;
- char base = 'X';
- int modifier = 0;
- int num = 0;
- int factor = 0;
- char foo[MAX_STRING_LEN];
-
- /* 0.0.4 compatibility?
- */
- if ( (code[0] == 'A') || (code[0] == 'M') ) {
- *real_code = pstrdup( pool, code );
- return NULL;
- };
-
- /* <base> [plus] {<num> <type>}*
- */
-
- /* <base>
- */
- word = getword_conf( pool, &code );
- if ( !strncasecmp( word, "now", 1 ) ||
- !strncasecmp( word, "access", 1 ) ) {
- base = 'A';
- } else if ( !strncasecmp( word, "modification", 1 ) ) {
- base = 'M';
- } else {
- return pstrcat( pool, "bad expires code, unrecognised <base> '",
- word, "'", NULL);
- };
-
- /* [plus]
- */
- word = getword_conf( pool, &code );
- if ( !strncasecmp( word, "plus", 1 ) ) {
- word = getword_conf( pool, &code );
- };
-
- /* {<num> <type>}*
- */
- while ( word[0] ) {
- /* <num>
- */
- if (isdigit(word[0])) {
- num = atoi( word );
- } else {
- return pstrcat( pool, "bad expires code, numeric value expected <num> '",
- word, "'", NULL);
- };
-
- /* <type>
- */
- word = getword_conf( pool, &code );
- if ( word[0] ) {
- /* do nothing */
- } else {
- return pstrcat( pool, "bad expires code, missing <type>", NULL);
- };
-
- factor = 0;
- if ( !strncasecmp( word, "years", 1 ) ) {
- factor = 60*60*24*365;
- } else if ( !strncasecmp( word, "months", 2 ) ) {
- factor = 60*60*24*30;
- } else if ( !strncasecmp( word, "weeks", 1 ) ) {
- factor = 60*60*24*7;
- } else if ( !strncasecmp( word, "days", 1 ) ) {
- factor = 60*60*24;
- } else if ( !strncasecmp( word, "hours", 1 ) ) {
- factor = 60*60;
- } else if ( !strncasecmp( word, "minutes", 2 ) ) {
- factor = 60;
- } else if ( !strncasecmp( word, "seconds", 1 ) ) {
- factor = 1;
- } else {
- return pstrcat( pool, "bad expires code, unrecognised <type>",
- "'", word, "'", NULL);
- };
-
- modifier = modifier + factor * num;
-
- /* next <num>
- */
- word = getword_conf( pool, &code );
- };
-
- ap_snprintf(foo, sizeof(foo), "%c%d", base, modifier );
- *real_code = pstrdup( pool, foo );
-
- return NULL;
-}
-
-const char *set_expiresbytype(cmd_parms *cmd, expires_dir_config *dir_config, char *mime, char *code)
-{
- char *response, *real_code;
-
- if ( (response = check_code( cmd->pool, code, &real_code )) == NULL ) {
- table_set (dir_config->expiresbytype, mime, real_code);
- return NULL;
- };
- return pstrcat( cmd->pool,
- "'ExpiresByType ", mime, " ", code, "': ", response, NULL );
-}
-
-const char *set_expiresdefault (cmd_parms *cmd, expires_dir_config *dir_config, char *code)
-{
- char *response, *real_code;
-
- if ( (response = check_code( cmd->pool, code, &real_code )) == NULL ) {
- dir_config->expiresdefault = pstrdup( cmd->pool, real_code );
- return NULL;
- };
- return pstrcat( cmd->pool,
- "'ExpiresDefault ", code, "': ", response, NULL );
-}
-
-command_rec expires_cmds[] = {
-{ "ExpiresActive", set_expiresactive, NULL, DIR_CMD_PERMS, FLAG, NULL},
-{ "ExpiresBytype", set_expiresbytype, NULL, DIR_CMD_PERMS, TAKE2,
- "a mime type followed by an expiry date code"},
-{ "ExpiresDefault", set_expiresdefault, NULL, DIR_CMD_PERMS, TAKE1,
- "an expiry date code"},
-{ NULL }
-};
-
-void *merge_expires_dir_configs (pool *p, void *basev, void *addv)
-{
- expires_dir_config *new= (expires_dir_config*)pcalloc (p, sizeof(expires_dir_config));
- expires_dir_config *base = (expires_dir_config *)basev;
- expires_dir_config *add = (expires_dir_config *)addv;
-
- if ( add->active == ACTIVE_DONTCARE ) {
- new->active = base->active;
- } else {
- new->active = add->active;
- };
-
- if ( add->expiresdefault != '\0' ) {
- new->expiresdefault = add->expiresdefault;
- };
-
- new->expiresbytype = overlay_tables (p, add->expiresbytype,
- base->expiresbytype);
- return new;
-}
-
-int add_expires(request_rec *r)
-{
- expires_dir_config *conf =
- (expires_dir_config *)get_module_config(r->per_dir_config, &expires_module);
- char *code;
- time_t base;
- time_t additional;
- time_t expires;
-
- if ( r->finfo.st_mode == 0 )
- return DECLINED;
-
- /* COMMA bites my ass...
- */
- if ( conf == NULL ) {
- log_reason ("internal error in expires_module; add_expires(), conf == NULL", r->filename, r);
- return SERVER_ERROR;
- };
-
- if ( conf->active != ACTIVE_ON )
- return DECLINED;
-
- /* we perhaps could use the default_type(r) in its place but that
- * may be 2nd guesing the desired configuration... calling table_get
- * with a NULL key will SEGV us
- *
- * I still don't know *why* r->content_type would ever be NULL, this
- * is possibly a result of fixups being called in many different
- * places. Fixups is probably the wrong place to be doing all this
- * work... Bah.
- *
- * Changed as of 08.Jun.96 don't DECLINE, look for an ExpiresDefault.
- */
- if ( r->content_type == NULL )
- code = NULL;
- else
- code = (char *) table_get( conf->expiresbytype, r->content_type );
-
- if ( code == NULL ) {
- /* no expires defined for that type, is there a default? */
- code = conf->expiresdefault;
-
- if ( code[0] == '\0' )
- return OK;
- };
-
- /* we have our code */
-
- switch (code[0]) {
- case 'M':
- base = r->finfo.st_mtime;
- additional = atoi( &code[1] );
- break;
- case 'A':
- /* there's been some discussion and it's possible that
- * 'access time' will be stored in request structure
- */
- base = time( NULL );
- additional = atoi( &code[1] );
- break;
- default:
- /* expecting the add_* routines to be case-hardened this
- * is just a reminder that module is beta
- */
- log_reason ("internal error in expires_module; bad expires code", r->filename, r);
- return SERVER_ERROR;
- };
-
- expires = base + additional;
- tzset(); /* redundant? called implicitly by localtime, at least
- * under FreeBSD
- */
- table_set( r->headers_out, "Expires", gm_timestr_822( r->pool, expires ));
- return OK;
-}
-
-module expires_module = {
- STANDARD_MODULE_STUFF,
- NULL, /* initializer */
- create_dir_expires_config, /* dir config creater */
- merge_expires_dir_configs, /* dir merger --- default is to override */
- NULL, /* server config */
- NULL, /* merge server configs */
- expires_cmds, /* command table */
- NULL, /* handlers */
- NULL, /* filename translation */
- NULL, /* check_user_id */
- NULL, /* check auth */
- NULL, /* check access */
- NULL, /* type_checker */
- add_expires, /* fixups */
- NULL, /* logger */
- NULL /* header parser */
-};
diff --git a/usr.sbin/httpd/src/mod_headers.c b/usr.sbin/httpd/src/mod_headers.c
deleted file mode 100644
index 3976be7ba8a..00000000000
--- a/usr.sbin/httpd/src/mod_headers.c
+++ /dev/null
@@ -1,253 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1996,1997 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. 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_headers.c: Add/append/remove HTTP response headers
- * Written by Paul Sutton, paul@ukweb.com, 1 Oct 1996
- *
- * New directive, Header, can be used to add/replace/remove HTTP headers.
- * Valid in both per-server and per-dir configurations.
- *
- * Syntax is:
- *
- * Header action header value
- *
- * Where action is one of:
- * set - set this header, replacing any old value
- * add - add this header, possible resulting in two or more
- * headers with the same name
- * append - append this text onto any existing header of this same
- * unset - remove this header
- *
- * Where action is unset, the third argument (value) should not be given.
- * The header name can include the colon, or not.
- *
- * The Header directive can only be used where allowed by the FileInfo
- * override.
- *
- * When the request is processed, the header directives are processed in
- * this order: firstly, the main server, then the virtual server handling
- * this request (if any), then any <Directory> sections (working downwards
- * from the root dir), then an <Location> sections (working down from
- * shortest URL component), the any <File> sections. This order is
- * important if any 'set' or 'unset' actions are used. For example,
- * the following two directives have different effect if applied in
- * the reverse order:
- *
- * Header append Author "John P. Doe"
- * Header unset Author
- *
- * Examples:
- *
- * To set the "Author" header, use
- * Header add Author "John P. Doe"
- *
- * To remove a header:
- * Header unset Author
- *
- */
-
-#include "httpd.h"
-#include "http_config.h"
-
-typedef enum {
- hdr_add = 'a', /* add header (could mean multiple hdrs) */
- hdr_set = 's', /* set (replace old value) */
- hdr_append = 'm', /* append (merge into any old value) */
- hdr_unset = 'u' /* unset header */
-} hdr_actions;
-
-typedef struct {
- hdr_actions action;
- char *header;
- char *value;
-} header_entry;
-
-/*
- * headers_conf is our per-module configuration. This is used as both
- * a per-dir and per-server config
- */
-typedef struct {
- array_header *headers;
-} headers_conf;
-
-module headers_module;
-
-void *create_headers_config (pool *p, server_rec *s)
-{
- headers_conf *a =
- (headers_conf *)pcalloc (p, sizeof(headers_conf));
-
- a->headers = make_array (p, 2, sizeof(header_entry));
- return a;
-}
-
-void *create_headers_dir_config (pool *p, char *d)
-{
- return (headers_conf*)create_headers_config(p, NULL);
-}
-
-void *merge_headers_config (pool *p, void *basev, void *overridesv)
-{
- headers_conf *a =
- (headers_conf *)pcalloc (p, sizeof(headers_conf));
- headers_conf *base = (headers_conf *)basev,
- *overrides = (headers_conf *)overridesv;
-
- a->headers = append_arrays(p, base->headers, overrides->headers);
-
- return a;
-}
-
-
-const char *header_cmd(cmd_parms *cmd, headers_conf *dirconf, char *action, char *hdr, char *value)
-{
- header_entry *new;
- server_rec *s = cmd->server;
- headers_conf *serverconf =
- (headers_conf *)get_module_config(s->module_config,&headers_module);
- char *colon;
-
- if ( cmd->path )
- {
- new = (header_entry*)push_array(dirconf->headers);
- }
- else
- {
- new = (header_entry*)push_array(serverconf->headers);
- }
-
- if (!strcasecmp(action, "set")) new->action = hdr_set;
- else if (!strcasecmp(action, "add")) new->action = hdr_add;
- else if (!strcasecmp(action, "append")) new->action = hdr_append;
- else if (!strcasecmp(action, "unset")) new->action = hdr_unset;
- else
- return "first argument must be add, set, append or unset.";
-
- if (new->action == hdr_unset) {
- if (value) return "Header unset takes two arguments";
- }
- else if (!value)
- return "Header requires three arguments";
-
- if ((colon = strchr(hdr, ':')))
- *colon = '\0';
-
- new->header = pstrdup(cmd->pool, hdr);
- new->value = value ? pstrdup(cmd->pool, value) : NULL;
-
- return NULL;
-}
-
-command_rec headers_cmds[] = {
-{ "Header", header_cmd, NULL, OR_FILEINFO, TAKE23,
- "an action, header and value"},
-{ NULL }
-};
-
-void do_headers_fixup(request_rec *r, array_header *headers)
-{
- int i;
-
- for (i = 0; i < headers->nelts; ++i) {
- header_entry *hdr = &((header_entry*)(headers->elts))[i];
- switch (hdr->action) {
- case hdr_add:
- table_add(r->headers_out, hdr->header, hdr->value);
- break;
- case hdr_append:
- table_merge(r->headers_out, hdr->header, hdr->value);
- break;
- case hdr_set:
- table_set(r->headers_out, hdr->header, hdr->value);
- break;
- case hdr_unset:
- table_unset(r->headers_out, hdr->header);
- break;
- }
- }
-
-}
-
-int fixup_headers(request_rec *r)
-{
- void *sconf = r->server->module_config;
- headers_conf *serverconf =
- (headers_conf *)get_module_config(sconf, &headers_module);
- void *dconf = r->per_dir_config;
- headers_conf *dirconf =
- (headers_conf *)get_module_config(dconf, &headers_module);
-
- do_headers_fixup(r, serverconf->headers);
- do_headers_fixup(r, dirconf->headers);
-
- return DECLINED;
-}
-
-module headers_module = {
- STANDARD_MODULE_STUFF,
- NULL, /* initializer */
- create_headers_dir_config, /* dir config creater */
- merge_headers_config, /* dir merger --- default is to override */
- create_headers_config, /* server config */
- merge_headers_config, /* merge server configs */
- headers_cmds, /* command table */
- NULL, /* handlers */
- NULL, /* filename translation */
- NULL, /* check_user_id */
- NULL, /* check auth */
- NULL, /* check access */
- NULL, /* type_checker */
- fixup_headers, /* fixups */
- NULL, /* logger */
- NULL /* header parser */
-};
diff --git a/usr.sbin/httpd/src/mod_imap.c b/usr.sbin/httpd/src/mod_imap.c
deleted file mode 100644
index 3282dfe71f3..00000000000
--- a/usr.sbin/httpd/src/mod_imap.c
+++ /dev/null
@@ -1,877 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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
- * IT'S 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 imagemap module started as a port of the original imagemap.c
- * written by Rob McCool (11/13/93 robm@ncsa.uiuc.edu).
- * This version includes the mapping algorithms found in version 1.3
- * of imagemap.c.
- *
- * Contributors to this code include:
- *
- * Kevin Hughes, kevinh@pulua.hcc.hawaii.edu
- *
- * Eric Haines, erich@eye.com
- * "macmartinized" polygon code copyright 1992 by Eric Haines, erich@eye.com
- *
- * Randy Terbush, randy@zyzzyva.com
- * port to Apache module format, "base_uri" and support for relative URLs
- *
- * James H. Cloos, Jr., cloos@jhcloos.com
- * Added point datatype, using code in NCSA's version 1.8 imagemap.c
- * program, as distributed with version 1.4.1 of their server.
- * The point code is originally added by Craig Milo Rogers, Rogers@ISI.Edu
- *
- * Nathan Kurz, nate@tripod.com
- * Rewrite/reorganization. New handling of default, base and relative URLs.
- * New Configuration directives:
- * ImapMenu {none, formatted, semiformatted, unformatted}
- * ImapDefault {error, nocontent, referer, menu, URL}
- * ImapBase {map, referer, URL}
- * Support for creating non-graphical menu added. (backwards compatible):
- * Old: directive URL [x,y ...]
- * New: directive URL "Menu text" [x,y ...]
- * or: directive URL x,y ... "Menu text"
- * Map format and menu concept courtesy Joshua Bell, jsbell@acs.ucalgary.ca.
- *
- * Mark Cox, mark@ukweb.com, Allow relative URLs even when no base specified
- */
-
-#include "httpd.h"
-#include "http_config.h"
-#include "http_request.h"
-#include "http_core.h"
-#include "http_protocol.h"
-#include "http_main.h"
-#include "http_log.h"
-#include "util_script.h"
-
-#define IMAP_MAGIC_TYPE "application/x-httpd-imap"
-#define MAXVERTS 100
-#define X 0
-#define Y 1
-
-#define IMAP_MENU_DEFAULT "formatted"
-#define IMAP_DEFAULT_DEFAULT "nocontent"
-#define IMAP_BASE_DEFAULT "map"
-
-#ifdef SUNOS4
-double strtod(); /* SunOS needed this */
-#endif
-
-module imap_module;
-
-typedef struct {
- char *imap_menu;
- char *imap_default;
- char *imap_base;
-} imap_conf_rec;
-
-static void *create_imap_dir_config(pool *p, char *dummy)
-{
- imap_conf_rec *icr =
- (imap_conf_rec *) palloc(p, sizeof(imap_conf_rec));
-
- icr->imap_menu = NULL;
- icr->imap_default = NULL;
- icr->imap_base = NULL;
-
- return icr;
-}
-
-static void *merge_imap_dir_configs(pool *p, void *basev, void *addv)
-{
- imap_conf_rec *new = (imap_conf_rec *) pcalloc(p, sizeof(imap_conf_rec));
- imap_conf_rec *base = (imap_conf_rec *) basev;
- imap_conf_rec *add = (imap_conf_rec *) addv;
-
- new->imap_menu = add->imap_menu ? add->imap_menu : base->imap_menu;
- new->imap_default = add->imap_default ? add->imap_default : base->imap_default;
- new->imap_base = add->imap_base ? add->imap_base : base->imap_base;
-
- return new;
-}
-
-
-static command_rec imap_cmds[] =
-{
- {"ImapMenu", set_string_slot,
- (void *) XtOffsetOf(imap_conf_rec, imap_menu), OR_INDEXES, TAKE1,
- "the type of menu generated: none, formatted, semiformatted, unformatted"},
- {"ImapDefault", set_string_slot,
- (void *) XtOffsetOf(imap_conf_rec, imap_default), OR_INDEXES, TAKE1,
- "the action taken if no match: error, nocontent, referer, menu, URL"},
- {"ImapBase", set_string_slot,
- (void *) XtOffsetOf(imap_conf_rec, imap_base), OR_INDEXES, TAKE1,
- "the base for all URL's: map, referer, URL (or start of)"},
- {NULL}
-};
-
-static int pointinrect(const double point[2], double coords[MAXVERTS][2])
-{
- double max[2], min[2];
- if (coords[0][X] > coords[1][X]) {
- max[0] = coords[0][X];
- min[0] = coords[1][X];
- }
- else {
- max[0] = coords[1][X];
- min[0] = coords[0][X];
- }
-
- if (coords[0][Y] > coords[1][Y]) {
- max[1] = coords[0][Y];
- min[1] = coords[1][Y];
- }
- else {
- max[1] = coords[1][Y];
- min[1] = coords[0][Y];
- }
-
- return ((point[X] >= min[0] && point[X] <= max[0]) &&
- (point[Y] >= min[1] && point[Y] <= max[1]));
-}
-
-static int pointincircle(const double point[2], double coords[MAXVERTS][2])
-{
- double radius1, radius2;
-
- radius1 = ((coords[0][Y] - coords[1][Y]) * (coords[0][Y] - coords[1][Y]))
- + ((coords[0][X] - coords[1][X]) * (coords[0][X] - coords[1][X]));
-
- radius2 = ((coords[0][Y] - point[Y]) * (coords[0][Y] - point[Y]))
- + ((coords[0][X] - point[X]) * (coords[0][X] - point[X]));
-
- return (radius2 <= radius1);
-}
-
-static int pointinpoly(const double point[2], double pgon[MAXVERTS][2])
-{
- int i, numverts, inside_flag, xflag0;
- int crossings;
- double *p;
- const double *stop;
- double tx, ty, y;
-
- for (i = 0; pgon[i][X] != -1 && i < MAXVERTS; i++);
-
- numverts = i;
- crossings = 0;
-
- tx = point[X];
- ty = point[Y];
- y = pgon[numverts - 1][Y];
-
- p = (double *) pgon + 1;
- if ((y >= ty) != (*p >= ty)) {
-
- if ((xflag0 = (pgon[numverts - 1][X] >= tx)) == (*(double *) pgon >= tx)) {
- if (xflag0)
- crossings++;
- }
- else {
- crossings += (pgon[numverts - 1][X] - (y - ty) *
- (*(double *) pgon - pgon[numverts - 1][X]) /
- (*p - y)) >= tx;
- }
- }
-
- stop = pgon[numverts];
-
- for (y = *p, p += 2; p < stop; y = *p, p += 2) {
-
- if (y >= ty) {
-
- while ((p < stop) && (*p >= ty))
- p += 2;
-
- if (p >= stop)
- break;
- if ((xflag0 = (*(p - 3) >= tx)) == (*(p - 1) >= tx)) {
-
- if (xflag0)
- crossings++;
- }
- else {
- crossings += (*(p - 3) - (*(p - 2) - ty) *
- (*(p - 1) - *(p - 3)) / (*p - *(p - 2))) >= tx;
- }
- }
- else {
- while ((p < stop) && (*p < ty))
- p += 2;
-
- if (p >= stop)
- break;
-
- if ((xflag0 = (*(p - 3) >= tx)) == (*(p - 1) >= tx)) {
- if (xflag0)
- crossings++;
- }
- else {
- crossings += (*(p - 3) - (*(p - 2) - ty) *
- (*(p - 1) - *(p - 3)) / (*p - *(p - 2))) >= tx;
- }
- }
- }
-
- inside_flag = crossings & 0x01;
- return (inside_flag);
-}
-
-
-static int is_closer(const double point[2], double coords[MAXVERTS][2],
- double *closest)
-{
- double dist_squared = ((point[X] - coords[0][X]) * (point[X] - coords[0][X]))
- + ((point[Y] - coords[0][Y]) * (point[Y] - coords[0][Y]));
-
- if (point[X] < 0 || point[Y] < 0)
- return (0); /* don't mess around with negative coordinates */
-
- if (*closest < 0 || dist_squared < *closest) {
- *closest = dist_squared;
- return (1); /* if this is the first point or is the closest yet
- set 'closest' equal to this distance^2 */
- }
-
- return (0); /* if it's not the first or closest */
-
-}
-
-static double get_x_coord(const char *args)
-{
- char *endptr; /* we want it non-null */
- double x_coord = -1; /* -1 is returned if no coordinate is given */
-
- if (args == NULL)
- return (-1); /* in case we aren't passed anything */
-
- while (*args && !isdigit(*args) && *args != ',')
- args++; /* jump to the first digit, but not past a comma or end */
-
- x_coord = strtod(args, &endptr);
-
- if (endptr > args) /* if a conversion was made */
- return (x_coord);
-
- return (-1); /* else if no conversion was made, or if no args was given */
-}
-
-static double get_y_coord(const char *args)
-{
- char *endptr; /* we want it non-null */
- char *start_of_y = NULL;
- double y_coord = -1; /* -1 is returned on error */
-
- if (args == NULL)
- return (-1); /* in case we aren't passed anything */
-
- start_of_y = strchr(args, ','); /* the comma */
-
- if (start_of_y) {
-
- start_of_y++; /* start looking at the character after the comma */
-
- while (*start_of_y && !isdigit(*start_of_y))
- start_of_y++; /* jump to the first digit, but not past the end */
-
- y_coord = strtod(start_of_y, &endptr);
-
- if (endptr > start_of_y)
- return (y_coord);
- }
-
- return (-1); /* if no conversion was made, or no comma was found in args */
-}
-
-
-/* See if string has a "quoted part", and if so set *quoted_part to
- * the first character of the quoted part, then hammer a \0 onto the
- * trailing quote, and set *string to point at the first character
- * past the second quote.
- *
- * Otherwise set *quoted_part to NULL, and leave *string alone.
- */
-static void read_quoted(char **string, char **quoted_part)
-{
- char *strp = *string;
-
- /* assume there's no quoted part */
- *quoted_part = NULL;
-
- while (isspace(*strp))
- strp++; /* go along string until non-whitespace */
-
- if (*strp == '"') { /* if that character is a double quote */
- strp++; /* step over it */
- *quoted_part = strp; /* note where the quoted part begins */
-
- while (*strp && *strp != '"') {
- ++strp; /* skip the quoted portion */
- }
-
- *strp = '\0'; /* end the string with a NUL */
-
- strp++; /* step over the last double quote */
- *string = strp;
- }
-}
-
-/*
- * returns the mapped URL or NULL.
- */
-static char *imap_url(request_rec *r, const char *base, const char *value)
-{
-/* translates a value into a URL. */
- int slen, clen;
- char *string_pos = NULL;
- const char *string_pos_const = NULL;
- char *directory = NULL;
- char *referer = NULL;
- char *my_base;
-
- if (!strcasecmp(value, "map") || !strcasecmp(value, "menu")) {
- return construct_url(r->pool, r->uri, r->server);
- }
-
- if (!strcasecmp(value, "nocontent") || !strcasecmp(value, "error")) {
- return pstrdup(r->pool, value); /* these are handled elsewhere, so just copy them */
- }
-
- if (!strcasecmp(value, "referer")) {
- referer = table_get(r->headers_in, "Referer");
- if (referer && *referer) {
- return pstrdup(r->pool, referer);
- }
- else {
- /* XXX: This used to do *value = '\0'; ... which is totally bogus
- * because it hammers the passed in value, which can be a string constant,
- * or part of a config, or whatever. Total garbage. This works around
- * that without changing the rest of this code much
- */
- value = ""; /* if 'referer' but no referring page, null the value */
- }
- }
-
- string_pos_const = value;
- while (isalpha(*string_pos_const))
- string_pos_const++; /* go along the URL from the map until a non-letter */
- if (*string_pos_const == ':') {
- /* if letters and then a colon (like http:) */
- /* it's an absolute URL, so use it! */
- return pstrdup(r->pool, value);
- }
-
- if (!base || !*base) {
- if (value && *value) {
- return pstrdup(r->pool, value); /* no base: use what is given */
- }
- /* no base, no value: pick a simple default */
- return construct_url(r->pool, "/", r->server);
- }
-
- /* must be a relative URL to be combined with base */
- if (strchr(base, '/') == NULL && (!strncmp(value, "../", 3) || !strcmp(value, ".."))) {
- log_reason("invalid base directive in map file: %s", r->uri, r);
- return NULL;
- }
- my_base = pstrdup(r->pool, base);
- string_pos = my_base;
- while (*string_pos) {
- if (*string_pos == '/' && *(string_pos + 1) == '/') {
- string_pos += 2; /* if there are two slashes, jump over them */
- continue;
- }
- if (*string_pos == '/') { /* the first single slash */
- if (value[0] == '/') {
- *string_pos = '\0';
- } /* if the URL from the map starts from root, end the
- base URL string at the first single slash */
- else {
- directory = string_pos; /* save the start of the directory portion */
-
- string_pos = strrchr(string_pos, '/'); /* now reuse string_pos */
- string_pos++; /* step over that last slash */
- *string_pos = '\0';
- } /* but if the map url is relative, leave the
- slash on the base (if there is one) */
- break;
- }
- string_pos++; /* until we get to the end of my_base without finding
- a slash by itself */
- }
-
- while (!strncmp(value, "../", 3) || !strcmp(value, "..")) {
-
- if (directory && (slen = strlen(directory))) {
-
- /* for each '..', knock a directory off the end
- by ending the string right at the last slash.
- But only consider the directory portion: don't eat
- into the server name. And only try if a directory
- portion was found */
-
- clen = slen - 1;
-
- while ((slen - clen) == 1) {
-
- if ((string_pos = strrchr(directory, '/')))
- *string_pos = '\0';
- clen = strlen(directory);
- if (clen == 0)
- break;
- }
-
- value += 2; /* jump over the '..' that we found in the value */
- }
- else if (directory) {
- log_reason("invalid directory name in map file: %s", r->uri, r);
- return NULL;
- }
-
- if (!strncmp(value, "/../", 4) || !strcmp(value, "/.."))
- value++; /* step over the '/' if there are more '..' to do.
- this way, we leave the starting '/' on value after
- the last '..', but get rid of it otherwise */
-
- } /* by this point, value does not start with '..' */
-
- if (value && *value) {
- return pstrcat(r->pool, my_base, value, NULL);
- }
- return my_base;
-}
-
-static int imap_reply(request_rec *r, char *redirect)
-{
- if (!strcasecmp(redirect, "error")) {
- return SERVER_ERROR; /* they actually requested an error! */
- }
- if (!strcasecmp(redirect, "nocontent")) {
- return HTTP_NO_CONTENT; /* tell the client to keep the page it has */
- }
- if (redirect && *redirect) {
- table_set(r->headers_out, "Location", redirect);
- return REDIRECT; /* must be a URL, so redirect to it */
- }
- return SERVER_ERROR;
-}
-
-static void menu_header(request_rec *r, char *menu)
-{
- r->content_type = "text/html";
- send_http_header(r);
- hard_timeout("send menu", r); /* killed in menu_footer */
-
- rvputs(r, "<html><head>\n<title>Menu for ", r->uri,
- "</title>\n</head><body>\n", NULL);
-
- if (!strcasecmp(menu, "formatted")) {
- rvputs(r, "<h1>Menu for ", r->uri, "</h1>\n<hr>\n\n", NULL);
- }
-
- return;
-}
-
-static void menu_blank(request_rec *r, char *menu)
-{
- if (!strcasecmp(menu, "formatted")) {
- rputs("\n", r);
- }
- if (!strcasecmp(menu, "semiformatted")) {
- rputs("<br>\n", r);
- }
- if (!strcasecmp(menu, "unformatted")) {
- rputs("\n", r);
- }
- return;
-}
-
-static void menu_comment(request_rec *r, char *menu, char *comment)
-{
- if (!strcasecmp(menu, "formatted")) {
- rputs("\n", r); /* print just a newline if 'formatted' */
- }
- if (!strcasecmp(menu, "semiformatted") && *comment) {
- rvputs(r, comment, "\n", NULL);
- }
- if (!strcasecmp(menu, "unformatted") && *comment) {
- rvputs(r, comment, "\n", NULL);
- }
- return; /* comments are ignored in the 'formatted' form */
-}
-
-static void menu_default(request_rec *r, char *menu, char *href, char *text)
-{
- if (!strcasecmp(href, "error") || !strcasecmp(href, "nocontent")) {
- return; /* don't print such lines, these aren'te really href's */
- }
- if (!strcasecmp(menu, "formatted")) {
- rvputs(r, "<pre>(Default) <a href=\"", href, "\">", text, "</a></pre>\n",
- NULL);
- }
- if (!strcasecmp(menu, "semiformatted")) {
- rvputs(r, "<pre>(Default) <a href=\"", href, "\">", text, "</a></pre>\n",
- NULL);
- }
- if (!strcasecmp(menu, "unformatted")) {
- rvputs(r, "<a href=\"", href, "\">", text, "</a>", NULL);
- }
- return;
-}
-
-static void menu_directive(request_rec *r, char *menu, char *href, char *text)
-{
- if (!strcasecmp(href, "error") || !strcasecmp(href, "nocontent")) {
- return; /* don't print such lines, as this isn't really an href */
- }
- if (!strcasecmp(menu, "formatted")) {
- rvputs(r, "<pre> <a href=\"", href, "\">", text, "</a></pre>\n",
- NULL);
- }
- if (!strcasecmp(menu, "semiformatted")) {
- rvputs(r, "<pre> <a href=\"", href, "\">", text, "</a></pre>\n",
- NULL);
- }
- if (!strcasecmp(menu, "unformatted")) {
- rvputs(r, "<a href=\"", href, "\">", text, "</a>", NULL);
- }
- return;
-}
-
-static void menu_footer(request_rec *r)
-{
- rputs("\n\n</body>\n</html>\n", r); /* finish the menu */
- kill_timeout(r);
-}
-
-static int imap_handler(request_rec *r)
-{
- char input[MAX_STRING_LEN];
- char *directive;
- char *value;
- char *href_text;
- char *base;
- char *redirect;
- char *mapdflt;
- char *closest = NULL;
- double closest_yet = -1;
-
- double testpoint[2];
- double pointarray[MAXVERTS + 1][2];
- int vertex;
-
- char *string_pos;
- int showmenu = 0;
-
- imap_conf_rec *icr = get_module_config(r->per_dir_config, &imap_module);
-
- char *imap_menu = icr->imap_menu ? icr->imap_menu : IMAP_MENU_DEFAULT;
- char *imap_default = icr->imap_default
- ? icr->imap_default : IMAP_DEFAULT_DEFAULT;
- char *imap_base = icr->imap_base ? icr->imap_base : IMAP_BASE_DEFAULT;
-
- FILE *imap;
-
- if (r->method_number != M_GET)
- return DECLINED;
-
- imap = pfopen(r->pool, r->filename, "r");
-
- if (!imap)
- return NOT_FOUND;
-
- base = imap_url(r, NULL, imap_base); /* set base according to default */
- if (!base)
- return HTTP_INTERNAL_SERVER_ERROR;
- mapdflt = imap_url(r, NULL, imap_default); /* and default to global default */
- if (!mapdflt)
- return HTTP_INTERNAL_SERVER_ERROR;
-
- testpoint[X] = get_x_coord(r->args);
- testpoint[Y] = get_y_coord(r->args);
-
- if ((testpoint[X] == -1 || testpoint[Y] == -1) ||
- (testpoint[X] == 0 && testpoint[Y] == 0)) {
- /* if either is -1 or if both are zero (new Lynx) */
- /* we don't have valid coordinates */
- testpoint[X] = -1;
- testpoint[Y] = -1;
- if (strncasecmp(imap_menu, "none", 2))
- showmenu = 1; /* show the menu _unless_ ImapMenu is 'none' or 'no' */
- }
-
- if (showmenu) { /* send start of imagemap menu if we're going to */
- menu_header(r, imap_menu);
- }
-
- while (!cfg_getline(input, sizeof(input), imap)) {
- if (!input[0]) {
- if (showmenu) {
- menu_blank(r, imap_menu);
- }
- continue;
- }
-
- if (input[0] == '#') {
- if (showmenu) {
- menu_comment(r, imap_menu, input + 1);
- }
- continue;
- } /* blank lines and comments are ignored if we aren't printing a menu */
-
- /* find the first two space delimited fields, recall that
- * cfg_getline has removed leading/trailing whitespace and
- * compressed the other whitespace down to one space a piece
- *
- * note that we're tokenizing as we go... if we were to use the
- * getword() class of functions we would end up allocating extra
- * memory for every line of the map file
- */
- string_pos = input;
- if (!*string_pos) /* need at least two fields */
- goto need_2_fields;
-
- directive = string_pos;
- while (*string_pos && *string_pos != ' ') /* past directive */
- ++string_pos;
- if (!*string_pos) /* need at least two fields */
- goto need_2_fields;
- *string_pos++ = '\0';
-
- if (!*string_pos) /* need at least two fields */
- goto need_2_fields;
- value = string_pos;
- while (*string_pos && *string_pos != ' ') /* past value */
- ++string_pos;
- if (*string_pos == ' ') {
- *string_pos++ = '\0';
- }
- else {
- /* end of input, don't advance past it */
- *string_pos = '\0';
- }
-
- if (!strncasecmp(directive, "base", 4)) { /* base, base_uri */
- base = imap_url(r, NULL, value);
- if (!base)
- goto menu_bail;
- continue; /* base is never printed to a menu */
- }
-
- read_quoted(&string_pos, &href_text);
-
- if (!strcasecmp(directive, "default")) { /* default */
- mapdflt = imap_url(r, NULL, value);
- if (!mapdflt)
- goto menu_bail;
- if (showmenu) { /* print the default if there's a menu */
- redirect = imap_url(r, base, mapdflt);
- if (!redirect)
- goto menu_bail;
- menu_default(r, imap_menu, redirect, href_text ? href_text : mapdflt);
- }
- continue;
- }
-
- vertex = 0;
- while (vertex < MAXVERTS &&
- sscanf(string_pos, "%lf%*[, ]%lf",
- &pointarray[vertex][X], &pointarray[vertex][Y]) == 2) {
- /* Now skip what we just read... we can't use ANSIism %n */
- while (isspace(*string_pos)) /* past whitespace */
- string_pos++;
- while (isdigit(*string_pos)) /* and the 1st number */
- string_pos++;
- string_pos++; /* skip the ',' */
- while (isspace(*string_pos)) /* past any more whitespace */
- string_pos++;
- while (isdigit(*string_pos)) /* 2nd number */
- string_pos++;
- vertex++;
- } /* so long as there are more vertices to read, and
- we have room, read them in. We start where we left
- off of the last sscanf, not at the beginning. */
-
- pointarray[vertex][X] = -1; /* signals the end of vertices */
-
- if (showmenu) {
- if (!href_text) {
- read_quoted(&string_pos, &href_text); /* href text could be here instead */
- }
- redirect = imap_url(r, base, value);
- if (!redirect)
- goto menu_bail;
- menu_directive(r, imap_menu, redirect, href_text ? href_text : value);
- continue;
- }
- /* note that we don't make it past here if we are making a menu */
-
- if (testpoint[X] == -1 || pointarray[0][X] == -1)
- continue; /* don't try the following tests if testpoints
- are invalid, or if there are no coordinates */
-
- if (!strcasecmp(directive, "poly")) { /* poly */
-
- if (pointinpoly(testpoint, pointarray)) {
- pfclose(r->pool, imap);
- redirect = imap_url(r, base, value);
- if (!redirect)
- return HTTP_INTERNAL_SERVER_ERROR;
- return (imap_reply(r, redirect));
- }
- continue;
- }
-
- if (!strcasecmp(directive, "circle")) { /* circle */
-
- if (pointincircle(testpoint, pointarray)) {
- pfclose(r->pool, imap);
- redirect = imap_url(r, base, value);
- if (!redirect)
- return HTTP_INTERNAL_SERVER_ERROR;
- return (imap_reply(r, redirect));
- }
- continue;
- }
-
- if (!strcasecmp(directive, "rect")) { /* rect */
-
- if (pointinrect(testpoint, pointarray)) {
- pfclose(r->pool, imap);
- redirect = imap_url(r, base, value);
- if (!redirect)
- return HTTP_INTERNAL_SERVER_ERROR;
- return (imap_reply(r, redirect));
- }
- continue;
- }
-
- if (!strcasecmp(directive, "point")) { /* point */
-
- if (is_closer(testpoint, pointarray, &closest_yet)) {
- closest = pstrdup(r->pool, value);
- }
-
- continue;
- } /* move on to next line whether it's closest or not */
-
- } /* nothing matched, so we get another line! */
-
- pfclose(r->pool, imap); /* we are done with the map file, so close it */
-
- if (showmenu) {
- menu_footer(r); /* finish the menu and we are done */
- return OK;
- }
-
- if (closest) { /* if a 'point' directive has been seen */
- redirect = imap_url(r, base, closest);
- if (!redirect)
- return HTTP_INTERNAL_SERVER_ERROR;
- return (imap_reply(r, redirect));
- }
-
- if (mapdflt) { /* a default should be defined, even if only 'nocontent' */
- redirect = imap_url(r, base, mapdflt);
- if (!redirect)
- return HTTP_INTERNAL_SERVER_ERROR;
- return (imap_reply(r, redirect));
- }
-
- return SERVER_ERROR; /* If we make it this far, we failed. They lose! */
-
-need_2_fields:
- log_reason("all map file lines require at least two fields", r->uri, r);
- /* fall through */
-menu_bail:
- pfclose(r->pool, imap);
- if (showmenu) {
- /* There's not much else we can do ... we've already sent the headers
- * to the client.
- */
- rputs("\n\n[an internal server error occured]\n", r);
- menu_footer(r);
- return OK;
- }
- return HTTP_INTERNAL_SERVER_ERROR;
-}
-
-
-static handler_rec imap_handlers[] =
-{
- {IMAP_MAGIC_TYPE, imap_handler},
- {"imap-file", imap_handler},
- {NULL}
-};
-
-module imap_module =
-{
- STANDARD_MODULE_STUFF,
- NULL, /* initializer */
- create_imap_dir_config, /* dir config creater */
- merge_imap_dir_configs, /* dir merger --- default is to override */
- NULL, /* server config */
- NULL, /* merge server config */
- imap_cmds, /* command table */
- imap_handlers, /* handlers */
- NULL, /* filename translation */
- NULL, /* check_user_id */
- NULL, /* check auth */
- NULL, /* check access */
- NULL, /* type_checker */
- NULL, /* fixups */
- NULL, /* logger */
- NULL /* header parser */
-};
diff --git a/usr.sbin/httpd/src/mod_include.c b/usr.sbin/httpd/src/mod_include.c
deleted file mode 100644
index 2b53f24aaa1..00000000000
--- a/usr.sbin/httpd/src/mod_include.c
+++ /dev/null
@@ -1,2329 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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_include.c: Handles the server-parsed HTML documents
- *
- * Original by Rob McCool; substantial fixups by David Robinson;
- * incorporated into the Apache module framework by rst.
- *
- */
-/*
- * sub key may be anything a Perl*Handler can be:
- * subroutine name, package name (defaults to package::handler),
- * Class->method call or anoymous sub {}
- *
- * Child <!--#perl sub="sub {print $$}" --> accessed
- * <!--#perl sub="sub {print ++$Access::Cnt }" --> times. <br>
- *
- * <!--#perl arg="one" sub="mymod::includer" -->
- *
- * -Doug MacEachern
- */
-
-#ifdef USE_PERL_SSI
-#include "config.h"
-#ifdef USE_SFIO
-#undef USE_SFIO
-#define USE_STDIO
-#endif
-#include "modules/perl/mod_perl.h"
-#else
-#include "httpd.h"
-#include "http_config.h"
-#include "http_request.h"
-#include "http_core.h"
-#include "http_protocol.h"
-#include "http_log.h"
-#include "http_main.h"
-#include "util_script.h"
-#endif
-
-#define STARTING_SEQUENCE "<!--#"
-#define ENDING_SEQUENCE "-->"
-#define DEFAULT_ERROR_MSG "[an error occurred while processing this directive]"
-#define DEFAULT_TIME_FORMAT "%A, %d-%b-%Y %H:%M:%S %Z"
-#define SIZEFMT_BYTES 0
-#define SIZEFMT_KMG 1
-
-
-static void safe_copy(char *dest, const char *src, size_t max_len)
-{
- strncpy(dest, src, max_len - 1);
- dest[max_len - 1] = '\0';
-}
-
-/* ------------------------ Environment function -------------------------- */
-
-static void add_include_vars(request_rec *r, char *timefmt)
-{
- struct passwd *pw;
- table *e = r->subprocess_env;
- char *t;
- time_t date = r->request_time;
-
- table_set(e, "DATE_LOCAL", ht_time(r->pool, date, timefmt, 0));
- table_set(e, "DATE_GMT", ht_time(r->pool, date, timefmt, 1));
- table_set(e, "LAST_MODIFIED",
- ht_time(r->pool, r->finfo.st_mtime, timefmt, 0));
- table_set(e, "DOCUMENT_URI", r->uri);
- table_set(e, "DOCUMENT_PATH_INFO", r->path_info);
- pw = getpwuid(r->finfo.st_uid);
- if (pw) {
- table_set(e, "USER_NAME", pw->pw_name);
- }
- else {
- char uid[16];
- ap_snprintf(uid, sizeof(uid), "user#%lu",
- (unsigned long) r->finfo.st_uid);
- table_set(e, "USER_NAME", uid);
- }
-
- if ((t = strrchr(r->filename, '/'))) {
- table_set(e, "DOCUMENT_NAME", ++t);
- }
- else {
- table_set(e, "DOCUMENT_NAME", r->uri);
- }
- if (r->args) {
- char *arg_copy = pstrdup(r->pool, r->args);
-
- unescape_url(arg_copy);
- table_set(e, "QUERY_STRING_UNESCAPED",
- escape_shell_cmd(r->pool, arg_copy));
- }
-}
-
-
-
-/* --------------------------- Parser functions --------------------------- */
-
-#define OUTBUFSIZE 4096
-/* PUT_CHAR and FLUSH_BUF currently only work within the scope of
- * find_string(); they are hacks to avoid calling rputc for each and
- * every character output. A common set of buffering calls for this
- * type of output SHOULD be implemented.
- */
-#define PUT_CHAR(c,r) \
- { \
- outbuf[outind++] = c; \
- if (outind == OUTBUFSIZE) { \
- FLUSH_BUF(r) \
- }; \
- }
-
-/* there SHOULD be some error checking on the return value of
- * rwrite, however it is unclear what the API for rwrite returning
- * errors is and little can really be done to help the error in
- * any case.
- */
-#define FLUSH_BUF(r) \
- { \
- rwrite(outbuf, outind, r); \
- outind = 0; \
- }
-
-/*
- * f: file handle being read from
- * c: character to read into
- * ret: return value to use if input fails
- * r: current request_rec
- *
- * This macro is redefined after find_string() for historical reasons
- * to avoid too many code changes. This is one of the many things
- * that should be fixed.
- */
-#define GET_CHAR(f,c,ret,r) \
- { \
- int i = getc(f); \
- if (i == EOF) { /* either EOF or error -- needs error handling if latter */ \
- if (ferror(f)) { \
- fprintf(stderr, "encountered error in GET_CHAR macro, " \
- "mod_include.\n"); \
- } \
- FLUSH_BUF(r); \
- pfclose(r->pool, f); \
- return ret; \
- } \
- c = (char)i; \
- }
-
-static int find_string(FILE *in, const char *str, request_rec *r, int printing)
-{
- int x, l = strlen(str), p;
- char outbuf[OUTBUFSIZE];
- int outind = 0;
- char c;
-
- p = 0;
- while (1) {
- GET_CHAR(in, c, 1, r);
- if (c == str[p]) {
- if ((++p) == l) {
- FLUSH_BUF(r);
- return 0;
- }
- }
- else {
- if (printing) {
- for (x = 0; x < p; x++) {
- PUT_CHAR(str[x], r);
- }
- PUT_CHAR(c, r);
- }
- p = 0;
- }
- }
-}
-
-#undef FLUSH_BUF
-#undef PUT_CHAR
-#undef GET_CHAR
-#define GET_CHAR(f,c,r,p) \
- { \
- int i = getc(f); \
- if (i == EOF) { /* either EOF or error -- needs error handling if latter */ \
- if (ferror(f)) { \
- fprintf(stderr, "encountered error in GET_CHAR macro, " \
- "mod_include.\n"); \
- } \
- pfclose(p, f); \
- return r; \
- } \
- c = (char)i; \
- }
-
-/*
- * decodes a string containing html entities or numeric character references.
- * 's' is overwritten with the decoded string.
- * If 's' is syntatically incorrect, then the followed fixups will be made:
- * unknown entities will be left undecoded;
- * references to unused numeric characters will be deleted.
- * In particular, &#00; will not be decoded, but will be deleted.
- *
- * drtr
- */
-
-/* maximum length of any ISO-LATIN-1 HTML entity name. */
-#define MAXENTLEN (6)
-
-/* The following is a shrinking transformation, therefore safe. */
-
-static void decodehtml(char *s)
-{
- int val, i, j;
- char *p = s;
- const char *ents;
- static const char * const entlist[MAXENTLEN + 1] =
- {
- NULL, /* 0 */
- NULL, /* 1 */
- "lt\074gt\076", /* 2 */
- "amp\046ETH\320eth\360", /* 3 */
- "quot\042Auml\304Euml\313Iuml\317Ouml\326Uuml\334auml\344euml\353\
-iuml\357ouml\366uuml\374yuml\377", /* 4 */
- "Acirc\302Aring\305AElig\306Ecirc\312Icirc\316Ocirc\324Ucirc\333\
-THORN\336szlig\337acirc\342aring\345aelig\346ecirc\352icirc\356ocirc\364\
-ucirc\373thorn\376", /* 5 */
- "Agrave\300Aacute\301Atilde\303Ccedil\307Egrave\310Eacute\311\
-Igrave\314Iacute\315Ntilde\321Ograve\322Oacute\323Otilde\325Oslash\330\
-Ugrave\331Uacute\332Yacute\335agrave\340aacute\341atilde\343ccedil\347\
-egrave\350eacute\351igrave\354iacute\355ntilde\361ograve\362oacute\363\
-otilde\365oslash\370ugrave\371uacute\372yacute\375" /* 6 */
- };
-
- for (; *s != '\0'; s++, p++) {
- if (*s != '&') {
- *p = *s;
- continue;
- }
- /* find end of entity */
- for (i = 1; s[i] != ';' && s[i] != '\0'; i++) {
- continue;
- }
-
- if (s[i] == '\0') { /* treat as normal data */
- *p = *s;
- continue;
- }
-
- /* is it numeric ? */
- if (s[1] == '#') {
- for (j = 2, val = 0; j < i && isdigit(s[j]); j++) {
- val = val * 10 + s[j] - '0';
- }
- s += i;
- if (j < i || val <= 8 || (val >= 11 && val <= 31) ||
- (val >= 127 && val <= 160) || val >= 256) {
- p--; /* no data to output */
- }
- else {
- *p = val;
- }
- }
- else {
- j = i - 1;
- if (i - 1 > MAXENTLEN || entlist[i - 1] == NULL) {
- /* wrong length */
- *p = '&';
- continue; /* skip it */
- }
- for (ents = entlist[i - 1]; *ents != '\0'; ents += i) {
- if (strncmp(s + 1, ents, i - 1) == 0) {
- break;
- }
- }
-
- if (*ents == '\0') {
- *p = '&'; /* unknown */
- }
- else {
- *p = ((const unsigned char *) ents)[i - 1];
- s += i;
- }
- }
- }
-
- *p = '\0';
-}
-
-/*
- * extract the next tag name and value.
- * if there are no more tags, set the tag name to 'done'
- * the tag value is html decoded if dodecode is non-zero
- */
-
-static char *get_tag(pool *p, FILE *in, char *tag, int tagbuf_len, int dodecode)
-{
- char *t = tag, *tag_val, c, term;
-
- /* makes code below a little less cluttered */
- --tagbuf_len;
-
- do { /* skip whitespace */
- GET_CHAR(in, c, NULL, p);
- } while (isspace(c));
-
- /* tags can't start with - */
- if (c == '-') {
- GET_CHAR(in, c, NULL, p);
- if (c == '-') {
- do {
- GET_CHAR(in, c, NULL, p);
- } while (isspace(c));
- if (c == '>') {
- safe_copy(tag, "done", tagbuf_len);
- return tag;
- }
- }
- return NULL; /* failed */
- }
-
- /* find end of tag name */
- while (1) {
- if (t - tag == tagbuf_len) {
- *t = '\0';
- return NULL;
- }
- if (c == '=' || isspace(c)) {
- break;
- }
- *(t++) = tolower(c);
- GET_CHAR(in, c, NULL, p);
- }
-
- *t++ = '\0';
- tag_val = t;
-
- while (isspace(c)) {
- GET_CHAR(in, c, NULL, p); /* space before = */
- }
- if (c != '=') {
- ungetc(c, in);
- return NULL;
- }
-
- do {
- GET_CHAR(in, c, NULL, p); /* space after = */
- } while (isspace(c));
-
- /* we should allow a 'name' as a value */
-
- if (c != '"' && c != '\'') {
- return NULL;
- }
- term = c;
- while (1) {
- GET_CHAR(in, c, NULL, p);
- if (t - tag == tagbuf_len) {
- *t = '\0';
- return NULL;
- }
-/* Want to accept \" as a valid character within a string. */
- if (c == '\\') {
- *(t++) = c; /* Add backslash */
- GET_CHAR(in, c, NULL, p);
- if (c == term) { /* Only if */
- *(--t) = c; /* Replace backslash ONLY for terminator */
- }
- }
- else if (c == term) {
- break;
- }
- *(t++) = c;
- }
- *t = '\0';
- if (dodecode) {
- decodehtml(tag_val);
- }
- return pstrdup(p, tag_val);
-}
-
-static int get_directive(FILE *in, char *dest, size_t len, pool *p)
-{
- char *d = dest;
- char c;
-
- /* make room for nul terminator */
- --len;
-
- /* skip initial whitespace */
- while (1) {
- GET_CHAR(in, c, 1, p);
- if (!isspace(c)) {
- break;
- }
- }
- /* now get directive */
- while (1) {
- if (d - dest == len) {
- return 1;
- }
- *d++ = tolower(c);
- GET_CHAR(in, c, 1, p);
- if (isspace(c)) {
- break;
- }
- }
- *d = '\0';
- return 0;
-}
-
-/*
- * Do variable substitution on strings
- */
-static void parse_string(request_rec *r, const char *in, char *out,
- size_t length, int leave_name)
-{
- char ch;
- char *next = out;
- char *end_out;
-
- /* leave room for nul terminator */
- end_out = out + length - 1;
-
- while ((ch = *in++) != '\0') {
- switch (ch) {
- case '\\':
- if (next == end_out) {
- /* truncated */
- *next = '\0';
- return;
- }
- if (*in == '$') {
- *next++ = *in++;
- }
- else {
- *next++ = ch;
- }
- break;
- case '$':
- {
- char var[MAX_STRING_LEN];
- const char *start_of_var_name;
- const char *end_of_var_name; /* end of var name + 1 */
- const char *expansion;
- const char *val;
- size_t l;
-
- /* guess that the expansion won't happen */
- expansion = in - 1;
- if (*in == '{') {
- ++in;
- start_of_var_name = in;
- in = strchr(in, '}');
- if (in == NULL) {
- log_printf(r->server,
- "Missing '}' on variable \"%s\" in %s",
- expansion, r->filename);
- *next = '\0';
- return;
- }
- end_of_var_name = in;
- ++in;
- }
- else {
- start_of_var_name = in;
- while (isalnum(*in) || *in == '_') {
- ++in;
- }
- end_of_var_name = in;
- }
- /* what a pain, too bad there's no table_getn where you can
- * pass a non-nul terminated string */
- l = end_of_var_name - start_of_var_name;
- l = (l > sizeof(var) - 1) ? (sizeof(var) - 1) : l;
- memcpy(var, start_of_var_name, l);
- var[l] = '\0';
-
- val = table_get(r->subprocess_env, var);
- if (val) {
- expansion = val;
- l = strlen(expansion);
- }
- else if (leave_name) {
- l = in - expansion;
- }
- else {
- break; /* no expansion to be done */
- }
- l = (l > end_out - next) ? (end_out - next) : l;
- memcpy(next, expansion, l);
- next += l;
- break;
- }
- default:
- if (next == end_out) {
- /* truncated */
- *next = '\0';
- return;
- }
- *next++ = ch;
- break;
- }
- }
- *next = '\0';
- return;
-}
-
-/* --------------------------- Action handlers ---------------------------- */
-
-static int include_cgi(char *s, request_rec *r)
-{
- request_rec *rr = sub_req_lookup_uri(s, r);
- int rr_status;
-
- if (rr->status != HTTP_OK) {
- return -1;
- }
-
- /* No hardwired path info or query allowed */
-
- if ((rr->path_info && rr->path_info[0]) || rr->args) {
- return -1;
- }
- if (rr->finfo.st_mode == 0) {
- return -1;
- }
-
- /* Script gets parameters of the *document*, for back compatibility */
-
- rr->path_info = r->path_info; /* hard to get right; see mod_cgi.c */
- rr->args = r->args;
-
- /* Force sub_req to be treated as a CGI request, even if ordinary
- * typing rules would have called it something else.
- */
-
- rr->content_type = CGI_MAGIC_TYPE;
-
- /* Run it. */
-
- rr_status = run_sub_req(rr);
- if (is_HTTP_REDIRECT(rr_status)) {
- char *location = table_get(rr->headers_out, "Location");
- location = escape_html(rr->pool, location);
- rvputs(r, "<A HREF=\"", location, "\">", location, "</A>", NULL);
- }
-
- destroy_sub_req(rr);
- chdir_file(r->filename);
-
- return 0;
-}
-
-/* ensure that path is relative, and does not contain ".." elements
- * ensentially ensure that it does not match the regex:
- * (^/|(^|/)\.\.(/|$))
- * XXX: this needs os abstraction... consider c:..\foo in win32
- */
-static int is_only_below(const char *path)
-{
- if (path[0] == '/') {
- return 0;
- }
- if (path[0] == '.' && path[1] == '.'
- && (path[2] == '\0' || path[2] == '/')) {
- return 0;
- }
- while (*path) {
- if (*path == '/' && path[1] == '.' && path[2] == '.'
- && (path[3] == '\0' || path[3] == '/')) {
- return 0;
- }
- ++path;
- }
- return 1;
-}
-
-static int handle_include(FILE *in, request_rec *r, const char *error, int noexec)
-{
- char tag[MAX_STRING_LEN];
- char parsed_string[MAX_STRING_LEN];
- char *tag_val;
-
- while (1) {
- if (!(tag_val = get_tag(r->pool, in, tag, sizeof(tag), 1))) {
- return 1;
- }
- if (!strcmp(tag, "file") || !strcmp(tag, "virtual")) {
- request_rec *rr = NULL;
- char *error_fmt = NULL;
-
- parse_string(r, tag_val, parsed_string, sizeof(parsed_string), 0);
- if (tag[0] == 'f') {
- /* be safe; only files in this directory or below allowed */
- if (!is_only_below(parsed_string)) {
- error_fmt = "unable to include file \"%s\" "
- "in parsed file %s";
- }
- else {
- rr = sub_req_lookup_file(parsed_string, r);
- }
- }
- else {
- rr = sub_req_lookup_uri(parsed_string, r);
- }
-
- if (!error_fmt && rr->status != HTTP_OK) {
- error_fmt = "unable to include \"%s\" in parsed file %s";
- }
-
- if (!error_fmt && noexec && rr->content_type
- && (strncmp(rr->content_type, "text/", 5))) {
- error_fmt = "unable to include potential exec \"%s\" "
- "in parsed file %s";
- }
- if (error_fmt == NULL) {
- request_rec *p;
-
- for (p = r; p != NULL; p = p->main) {
- if (strcmp(p->filename, rr->filename) == 0) {
- break;
- }
- }
- if (p != NULL) {
- error_fmt = "Recursive include of \"%s\" "
- "in parsed file %s";
- }
- }
-
- if (!error_fmt && run_sub_req(rr)) {
- error_fmt = "unable to include \"%s\" in parsed file %s";
- }
- chdir_file(r->filename);
-
- if (error_fmt) {
- log_printf(r->server, error_fmt, tag_val, r->filename);
- rputs(error, r);
- }
-
- if (rr != NULL) {
- destroy_sub_req(rr);
- }
- }
- else if (!strcmp(tag, "done")) {
- return 0;
- }
- else {
- log_printf(r->server,
- "unknown parameter \"%s\" to tag include in %s",
- tag, r->filename);
- rputs(error, r);
- }
- }
-}
-
-typedef struct {
- request_rec *r;
- char *s;
-} include_cmd_arg;
-
-static void include_cmd_child(void *arg)
-{
- request_rec *r = ((include_cmd_arg *) arg)->r;
- char *s = ((include_cmd_arg *) arg)->s;
- table *env = r->subprocess_env;
-#ifdef DEBUG_INCLUDE_CMD
- FILE *dbg = fopen("/dev/tty", "w");
-#endif
- char err_string[MAX_STRING_LEN];
-
-#ifdef DEBUG_INCLUDE_CMD
-#ifdef __EMX__
- /* under OS/2 /dev/tty is referenced as con */
- FILE *dbg = fopen("con", "w");
-#else
- fprintf(dbg, "Attempting to include command '%s'\n", s);
-#endif
-#endif
-
- if (r->path_info && r->path_info[0] != '\0') {
- request_rec *pa_req;
-
- table_set(env, "PATH_INFO", escape_shell_cmd(r->pool, r->path_info));
-
- pa_req = sub_req_lookup_uri(escape_uri(r->pool, r->path_info), r);
- if (pa_req->filename) {
- table_set(env, "PATH_TRANSLATED",
- pstrcat(r->pool, pa_req->filename, pa_req->path_info,
- NULL));
- }
- }
-
- if (r->args) {
- char *arg_copy = pstrdup(r->pool, r->args);
-
- table_set(env, "QUERY_STRING", r->args);
- unescape_url(arg_copy);
- table_set(env, "QUERY_STRING_UNESCAPED",
- escape_shell_cmd(r->pool, arg_copy));
- }
-
- error_log2stderr(r->server);
-
-#ifdef DEBUG_INCLUDE_CMD
- fprintf(dbg, "Attempting to exec '%s'\n", s);
-#endif
- cleanup_for_exec();
- /* set shellcmd flag to pass arg to SHELL_PATH */
- call_exec(r, s, create_environment(r->pool, env), 1);
- /* Oh, drat. We're still here. The log file descriptors are closed,
- * so we have to whimper a complaint onto stderr...
- */
-
-#ifdef DEBUG_INCLUDE_CMD
- fprintf(dbg, "Exec failed\n");
-#endif
- ap_snprintf(err_string, sizeof(err_string),
- "httpd: exec of %s failed, reason: %s (errno = %d)\n",
- SHELL_PATH, strerror(errno), errno);
- write(STDERR_FILENO, err_string, strlen(err_string));
- exit(0);
-}
-
-static int include_cmd(char *s, request_rec *r)
-{
- include_cmd_arg arg;
- FILE *f;
-
- arg.r = r;
- arg.s = s;
-
- if (!spawn_child(r->pool, include_cmd_child, &arg,
- kill_after_timeout, NULL, &f)) {
- return -1;
- }
-
- send_fd(f, r);
- pfclose(r->pool, f); /* will wait for zombie when
- * r->pool is cleared
- */
- return 0;
-}
-
-
-static int handle_exec(FILE *in, request_rec *r, const char *error)
-{
- char tag[MAX_STRING_LEN];
- char *tag_val;
- char *file = r->filename;
- char parsed_string[MAX_STRING_LEN];
-
- while (1) {
- if (!(tag_val = get_tag(r->pool, in, tag, sizeof(tag), 1))) {
- return 1;
- }
- if (!strcmp(tag, "cmd")) {
- parse_string(r, tag_val, parsed_string, sizeof(parsed_string), 1);
- if (include_cmd(parsed_string, r) == -1) {
- log_printf(r->server,
- "execution failure for parameter \"%s\" "
- "to tag exec in file %s",
- tag, r->filename);
- rputs(error, r);
- }
- /* just in case some stooge changed directories */
- chdir_file(r->filename);
- }
- else if (!strcmp(tag, "cgi")) {
- parse_string(r, tag_val, parsed_string, sizeof(parsed_string), 0);
- if (include_cgi(parsed_string, r) == -1) {
- log_printf(r->server,
- "invalid CGI ref \"%s\" in %s", tag_val, file);
- rputs(error, r);
- }
- /* grumble groan */
- chdir_file(r->filename);
- }
- else if (!strcmp(tag, "done")) {
- return 0;
- }
- else {
- log_printf(r->server,
- "unknown parameter \"%s\" to tag exec in %s",
- tag, file);
- rputs(error, r);
- }
- }
-
-}
-
-static int handle_echo(FILE *in, request_rec *r, const char *error)
-{
- char tag[MAX_STRING_LEN];
- char *tag_val;
-
- while (1) {
- if (!(tag_val = get_tag(r->pool, in, tag, sizeof(tag), 1))) {
- return 1;
- }
- if (!strcmp(tag, "var")) {
- char *val = table_get(r->subprocess_env, tag_val);
-
- if (val) {
- rputs(val, r);
- }
- else {
- rputs("(none)", r);
- }
- }
- else if (!strcmp(tag, "done")) {
- return 0;
- }
- else {
- log_printf(r->server,
- "unknown parameter \"%s\" to tag echo in %s",
- tag, r->filename);
- rputs(error, r);
- }
- }
-}
-
-#ifdef USE_PERL_SSI
-static int handle_perl(FILE *in, request_rec *r, const char *error)
-{
- char tag[MAX_STRING_LEN];
- char *tag_val;
- SV *sub = Nullsv;
- AV *av = newAV();
-
- if (!(allow_options(r) & OPT_INCLUDES)) {
- log_printf(r->server,
- "httpd: #perl SSI disallowed by IncludesNoExec in %s",
- r->filename);
- return DECLINED;
- }
- while (1) {
- if (!(tag_val = get_tag(r->pool, in, tag, sizeof(tag), 1))) {
- break;
- }
- if (strnEQ(tag, "sub", 3)) {
- sub = newSVpv(tag_val, 0);
- }
- else if (strnEQ(tag, "arg", 3)) {
- av_push(av, newSVpv(tag_val, 0));
- }
- else if (strnEQ(tag, "done", 4)) {
- break;
- }
- }
- perl_stdout2client(r);
- perl_call_handler(sub, r, av);
- return OK;
-}
-#endif
-
-/* error and tf must point to a string with room for at
- * least MAX_STRING_LEN characters
- */
-static int handle_config(FILE *in, request_rec *r, char *error, char *tf,
- int *sizefmt)
-{
- char tag[MAX_STRING_LEN];
- char *tag_val;
- char parsed_string[MAX_STRING_LEN];
- table *env = r->subprocess_env;
-
- while (1) {
- if (!(tag_val = get_tag(r->pool, in, tag, sizeof(tag), 0))) {
- return 1;
- }
- if (!strcmp(tag, "errmsg")) {
- parse_string(r, tag_val, error, MAX_STRING_LEN, 0);
- }
- else if (!strcmp(tag, "timefmt")) {
- time_t date = r->request_time;
-
- parse_string(r, tag_val, tf, MAX_STRING_LEN, 0);
- table_set(env, "DATE_LOCAL", ht_time(r->pool, date, tf, 0));
- table_set(env, "DATE_GMT", ht_time(r->pool, date, tf, 1));
- table_set(env, "LAST_MODIFIED",
- ht_time(r->pool, r->finfo.st_mtime, tf, 0));
- }
- else if (!strcmp(tag, "sizefmt")) {
- parse_string(r, tag_val, parsed_string, sizeof(parsed_string), 0);
- decodehtml(parsed_string);
- if (!strcmp(parsed_string, "bytes")) {
- *sizefmt = SIZEFMT_BYTES;
- }
- else if (!strcmp(parsed_string, "abbrev")) {
- *sizefmt = SIZEFMT_KMG;
- }
- }
- else if (!strcmp(tag, "done")) {
- return 0;
- }
- else {
- log_printf(r->server,
- "unknown parameter \"%s\" to tag config in %s",
- tag, r->filename);
- rputs(error, r);
- }
- }
-}
-
-
-static int find_file(request_rec *r, const char *directive, const char *tag,
- char *tag_val, struct stat *finfo, const char *error)
-{
- char *to_send;
-
- if (!strcmp(tag, "file")) {
- getparents(tag_val); /* get rid of any nasties */
- to_send = make_full_path(r->pool, "./", tag_val);
- if (stat(to_send, finfo) == -1) {
- log_printf(r->server,
- "unable to get information about \"%s\" "
- "in parsed file %s",
- to_send, r->filename);
- rputs(error, r);
- return -1;
- }
- return 0;
- }
- else if (!strcmp(tag, "virtual")) {
- request_rec *rr = sub_req_lookup_uri(tag_val, r);
-
- if (rr->status == HTTP_OK && rr->finfo.st_mode != 0) {
- memcpy((char *) finfo, (const char *) &rr->finfo,
- sizeof(struct stat));
- destroy_sub_req(rr);
- return 0;
- }
- else {
- log_printf(r->server,
- "unable to get information about \"%s\" "
- "in parsed file %s",
- tag_val, r->filename);
- rputs(error, r);
- destroy_sub_req(rr);
- return -1;
- }
- }
- else {
- log_printf(r->server,
- "unknown parameter \"%s\" to tag %s in %s",
- tag, directive, r->filename);
- rputs(error, r);
- return -1;
- }
-}
-
-
-static int handle_fsize(FILE *in, request_rec *r, const char *error, int sizefmt)
-{
- char tag[MAX_STRING_LEN];
- char *tag_val;
- struct stat finfo;
- char parsed_string[MAX_STRING_LEN];
-
- while (1) {
- if (!(tag_val = get_tag(r->pool, in, tag, sizeof(tag), 1))) {
- return 1;
- }
- else if (!strcmp(tag, "done")) {
- return 0;
- }
- else {
- parse_string(r, tag_val, parsed_string, sizeof(parsed_string), 0);
- if (!find_file(r, "fsize", tag, parsed_string, &finfo, error)) {
- if (sizefmt == SIZEFMT_KMG) {
- send_size(finfo.st_size, r);
- }
- else {
- int l, x;
-#if defined(BSD) && BSD > 199305
- /* ap_snprintf can't handle %qd */
- sprintf(tag, "%qd", finfo.st_size);
-#else
- ap_snprintf(tag, sizeof(tag), "%ld", finfo.st_size);
-#endif
- l = strlen(tag); /* grrr */
- for (x = 0; x < l; x++) {
- if (x && (!((l - x) % 3))) {
- rputc(',', r);
- }
- rputc(tag[x], r);
- }
- }
- }
- }
- }
-}
-
-static int handle_flastmod(FILE *in, request_rec *r, const char *error, const char *tf)
-{
- char tag[MAX_STRING_LEN];
- char *tag_val;
- struct stat finfo;
- char parsed_string[MAX_STRING_LEN];
-
- while (1) {
- if (!(tag_val = get_tag(r->pool, in, tag, sizeof(tag), 1))) {
- return 1;
- }
- else if (!strcmp(tag, "done")) {
- return 0;
- }
- else {
- parse_string(r, tag_val, parsed_string, sizeof(parsed_string), 0);
- if (!find_file(r, "flastmod", tag, parsed_string, &finfo, error)) {
- rputs(ht_time(r->pool, finfo.st_mtime, tf, 0), r);
- }
- }
- }
-}
-
-static int re_check(request_rec *r, char *string, char *rexp)
-{
- regex_t *compiled;
- int regex_error;
-
- compiled = pregcomp(r->pool, rexp, REG_EXTENDED | REG_NOSUB);
- if (compiled == NULL) {
- log_printf(r->server, "unable to compile pattern \"%s\"", rexp);
- return -1;
- }
- regex_error = regexec(compiled, string, 0, (regmatch_t *) NULL, 0);
- pregfree(r->pool, compiled);
- return (!regex_error);
-}
-
-enum token_type {
- token_string,
- token_and, token_or, token_not, token_eq, token_ne,
- token_rbrace, token_lbrace, token_group,
- token_ge, token_le, token_gt, token_lt
-};
-struct token {
- enum token_type type;
- char value[MAX_STRING_LEN];
-};
-
-/* there is an implicit assumption here that string is at most MAX_STRING_LEN-1
- * characters long...
- */
-static const char *get_ptoken(request_rec *r, const char *string, struct token *token)
-{
- char ch;
- int next = 0;
- int qs = 0;
-
- /* Skip leading white space */
- if (string == (char *) NULL) {
- return (char *) NULL;
- }
- while ((ch = *string++)) {
- if (!isspace(ch)) {
- break;
- }
- }
- if (ch == '\0') {
- return (char *) NULL;
- }
-
- token->type = token_string; /* the default type */
- switch (ch) {
- case '(':
- token->type = token_lbrace;
- return (string);
- case ')':
- token->type = token_rbrace;
- return (string);
- case '=':
- token->type = token_eq;
- return (string);
- case '!':
- if (*string == '=') {
- token->type = token_ne;
- return (string + 1);
- }
- else {
- token->type = token_not;
- return (string);
- }
- case '\'':
- token->type = token_string;
- qs = 1;
- break;
- case '|':
- if (*string == '|') {
- token->type = token_or;
- return (string + 1);
- }
- break;
- case '&':
- if (*string == '&') {
- token->type = token_and;
- return (string + 1);
- }
- break;
- case '>':
- if (*string == '=') {
- token->type = token_ge;
- return (string + 1);
- }
- else {
- token->type = token_gt;
- return (string);
- }
- case '<':
- if (*string == '=') {
- token->type = token_le;
- return (string + 1);
- }
- else {
- token->type = token_lt;
- return (string);
- }
- default:
- token->type = token_string;
- break;
- }
- /* We should only be here if we are in a string */
- if (!qs) {
- token->value[next++] = ch;
- }
-
- /*
- * Yes I know that goto's are BAD. But, c doesn't allow me to
- * exit a loop from a switch statement. Yes, I could use a flag,
- * but that is (IMHO) even less readable/maintainable than the goto.
- */
- /*
- * I used the ++string throughout this section so that string
- * ends up pointing to the next token and I can just return it
- */
- for (ch = *string; ch != '\0'; ch = *++string) {
- if (ch == '\\') {
- if ((ch = *++string) == '\0') {
- goto TOKEN_DONE;
- }
- token->value[next++] = ch;
- continue;
- }
- if (!qs) {
- if (isspace(ch)) {
- goto TOKEN_DONE;
- }
- switch (ch) {
- case '(':
- goto TOKEN_DONE;
- case ')':
- goto TOKEN_DONE;
- case '=':
- goto TOKEN_DONE;
- case '!':
- goto TOKEN_DONE;
- case '|':
- if (*(string + 1) == '|') {
- goto TOKEN_DONE;
- }
- break;
- case '&':
- if (*(string + 1) == '&') {
- goto TOKEN_DONE;
- }
- break;
- case '<':
- goto TOKEN_DONE;
- case '>':
- goto TOKEN_DONE;
- }
- token->value[next++] = ch;
- }
- else {
- if (ch == '\'') {
- qs = 0;
- ++string;
- goto TOKEN_DONE;
- }
- token->value[next++] = ch;
- }
- }
- TOKEN_DONE:
- /* If qs is still set, I have an unmatched ' */
- if (qs) {
- rputs("\nUnmatched '\n", r);
- next = 0;
- }
- token->value[next] = '\0';
- return (string);
-}
-
-
-/*
- * Hey I still know that goto's are BAD. I don't think that I've ever
- * used two in the same project, let alone the same file before. But,
- * I absolutely want to make sure that I clean up the memory in all
- * cases. And, without rewriting this completely, the easiest way
- * is to just branch to the return code which cleans it up.
- */
-/* there is an implicit assumption here that expr is at most MAX_STRING_LEN-1
- * characters long...
- */
-static int parse_expr(request_rec *r, const char *expr, const char *error)
-{
- struct parse_node {
- struct parse_node *left, *right, *parent;
- struct token token;
- int value, done;
- } *root, *current, *new;
- const char *parse;
- char buffer[MAX_STRING_LEN];
- pool *expr_pool;
- int retval = 0;
-
- if ((parse = expr) == (char *) NULL) {
- return (0);
- }
- root = current = (struct parse_node *) NULL;
- expr_pool = make_sub_pool(r->pool);
-
- /* Create Parse Tree */
- while (1) {
- new = (struct parse_node *) palloc(expr_pool,
- sizeof(struct parse_node));
- new->parent = new->left = new->right = (struct parse_node *) NULL;
- new->done = 0;
- if ((parse = get_ptoken(r, parse, &new->token)) == (char *) NULL) {
- break;
- }
- switch (new->token.type) {
-
- case token_string:
-#ifdef DEBUG_INCLUDE
- rvputs(r, " Token: string (", new->token.value, ")\n", NULL);
-#endif
- if (current == (struct parse_node *) NULL) {
- root = current = new;
- break;
- }
- switch (current->token.type) {
- case token_string:
- if (current->token.value[0] != '\0') {
- strncat(current->token.value, " ",
- MAX_STRING_LEN - strlen(current->token.value) - 1);
- }
- strncat(current->token.value, new->token.value,
- MAX_STRING_LEN - strlen(current->token.value) - 1);
- current->token.value[sizeof(current->token.value) - 1] = '\0';
- break;
- case token_eq:
- case token_ne:
- case token_and:
- case token_or:
- case token_lbrace:
- case token_not:
- case token_ge:
- case token_gt:
- case token_le:
- case token_lt:
- new->parent = current;
- current = current->right = new;
- break;
- default:
- log_printf(r->server,
- "Invalid expression \"%s\" in file %s",
- expr, r->filename);
- rputs(error, r);
- goto RETURN;
- }
- break;
-
- case token_and:
- case token_or:
-#ifdef DEBUG_INCLUDE
- rputs(" Token: and/or\n", r);
-#endif
- if (current == (struct parse_node *) NULL) {
- log_printf(r->server,
- "Invalid expression \"%s\" in file %s",
- expr, r->filename);
- rputs(error, r);
- goto RETURN;
- }
- /* Percolate upwards */
- while (current != (struct parse_node *) NULL) {
- switch (current->token.type) {
- case token_string:
- case token_group:
- case token_not:
- case token_eq:
- case token_ne:
- case token_and:
- case token_or:
- case token_ge:
- case token_gt:
- case token_le:
- case token_lt:
- current = current->parent;
- continue;
- case token_lbrace:
- break;
- default:
- log_printf(r->server,
- "Invalid expression \"%s\" in file %s",
- expr, r->filename);
- rputs(error, r);
- goto RETURN;
- }
- break;
- }
- if (current == (struct parse_node *) NULL) {
- new->left = root;
- new->left->parent = new;
- new->parent = (struct parse_node *) NULL;
- root = new;
- }
- else {
- new->left = current->right;
- current->right = new;
- new->parent = current;
- }
- current = new;
- break;
-
- case token_not:
-#ifdef DEBUG_INCLUDE
- rputs(" Token: not\n", r);
-#endif
- if (current == (struct parse_node *) NULL) {
- root = current = new;
- break;
- }
- /* Percolate upwards */
- while (current != (struct parse_node *) NULL) {
- switch (current->token.type) {
- case token_not:
- case token_eq:
- case token_ne:
- case token_and:
- case token_or:
- case token_lbrace:
- case token_ge:
- case token_gt:
- case token_le:
- case token_lt:
- break;
- default:
- log_printf(r->server,
- "Invalid expression \"%s\" in file %s",
- expr, r->filename);
- rputs(error, r);
- goto RETURN;
- }
- break;
- }
- if (current == (struct parse_node *) NULL) {
- new->left = root;
- new->left->parent = new;
- new->parent = (struct parse_node *) NULL;
- root = new;
- }
- else {
- new->left = current->right;
- current->right = new;
- new->parent = current;
- }
- current = new;
- break;
-
- case token_eq:
- case token_ne:
- case token_ge:
- case token_gt:
- case token_le:
- case token_lt:
-#ifdef DEBUG_INCLUDE
- rputs(" Token: eq/ne/ge/gt/le/lt\n", r);
-#endif
- if (current == (struct parse_node *) NULL) {
- log_printf(r->server,
- "Invalid expression \"%s\" in file %s",
- expr, r->filename);
- rputs(error, r);
- goto RETURN;
- }
- /* Percolate upwards */
- while (current != (struct parse_node *) NULL) {
- switch (current->token.type) {
- case token_string:
- case token_group:
- current = current->parent;
- continue;
- case token_lbrace:
- case token_and:
- case token_or:
- break;
- case token_not:
- case token_eq:
- case token_ne:
- case token_ge:
- case token_gt:
- case token_le:
- case token_lt:
- default:
- log_printf(r->server,
- "Invalid expression \"%s\" in file %s",
- expr, r->filename);
- rputs(error, r);
- goto RETURN;
- }
- break;
- }
- if (current == (struct parse_node *) NULL) {
- new->left = root;
- new->left->parent = new;
- new->parent = (struct parse_node *) NULL;
- root = new;
- }
- else {
- new->left = current->right;
- current->right = new;
- new->parent = current;
- }
- current = new;
- break;
-
- case token_rbrace:
-#ifdef DEBUG_INCLUDE
- rputs(" Token: rbrace\n", r);
-#endif
- while (current != (struct parse_node *) NULL) {
- if (current->token.type == token_lbrace) {
- current->token.type = token_group;
- break;
- }
- current = current->parent;
- }
- if (current == (struct parse_node *) NULL) {
- log_printf(r->server, "Unmatched ')' in \"%s\" in file %s",
- expr, r->filename);
- rputs(error, r);
- goto RETURN;
- }
- break;
-
- case token_lbrace:
-#ifdef DEBUG_INCLUDE
- rputs(" Token: lbrace\n", r);
-#endif
- if (current == (struct parse_node *) NULL) {
- root = current = new;
- break;
- }
- /* Percolate upwards */
- while (current != (struct parse_node *) NULL) {
- switch (current->token.type) {
- case token_not:
- case token_eq:
- case token_ne:
- case token_and:
- case token_or:
- case token_lbrace:
- case token_ge:
- case token_gt:
- case token_le:
- case token_lt:
- break;
- case token_string:
- case token_group:
- default:
- log_printf(r->server,
- "Invalid expression \"%s\" in file %s",
- expr, r->filename);
- rputs(error, r);
- goto RETURN;
- }
- break;
- }
- if (current == (struct parse_node *) NULL) {
- new->left = root;
- new->left->parent = new;
- new->parent = (struct parse_node *) NULL;
- root = new;
- }
- else {
- new->left = current->right;
- current->right = new;
- new->parent = current;
- }
- current = new;
- break;
- default:
- break;
- }
- }
-
- /* Evaluate Parse Tree */
- current = root;
- while (current != (struct parse_node *) NULL) {
- switch (current->token.type) {
- case token_string:
-#ifdef DEBUG_INCLUDE
- rputs(" Evaluate string\n", r);
-#endif
- parse_string(r, current->token.value, buffer, sizeof(buffer), 0);
- safe_copy(current->token.value, buffer, sizeof(current->token.value));
- current->value = (current->token.value[0] != '\0');
- current->done = 1;
- current = current->parent;
- break;
-
- case token_and:
- case token_or:
-#ifdef DEBUG_INCLUDE
- rputs(" Evaluate and/or\n", r);
-#endif
- if (current->left == (struct parse_node *) NULL ||
- current->right == (struct parse_node *) NULL) {
- log_printf(r->server, "Invalid expression \"%s\" in file %s",
- expr, r->filename);
- rputs(error, r);
- goto RETURN;
- }
- if (!current->left->done) {
- switch (current->left->token.type) {
- case token_string:
- parse_string(r, current->left->token.value,
- buffer, sizeof(buffer), 0);
- safe_copy(current->left->token.value, buffer,
- sizeof(current->left->token.value));
- current->left->value = (current->left->token.value[0] != '\0');
- current->left->done = 1;
- break;
- default:
- current = current->left;
- continue;
- }
- }
- if (!current->right->done) {
- switch (current->right->token.type) {
- case token_string:
- parse_string(r, current->right->token.value,
- buffer, sizeof(buffer), 0);
- safe_copy(current->right->token.value, buffer,
- sizeof(current->right->token.value));
- current->right->value = (current->right->token.value[0] != '\0');
- current->right->done = 1;
- break;
- default:
- current = current->right;
- continue;
- }
- }
-#ifdef DEBUG_INCLUDE
- rvputs(r, " Left: ", current->left->value ? "1" : "0",
- "\n", NULL);
- rvputs(r, " Right: ", current->right->value ? "1" : "0",
- "\n", NULL);
-#endif
- if (current->token.type == token_and) {
- current->value = current->left->value && current->right->value;
- }
- else {
- current->value = current->left->value || current->right->value;
- }
-#ifdef DEBUG_INCLUDE
- rvputs(r, " Returning ", current->value ? "1" : "0",
- "\n", NULL);
-#endif
- current->done = 1;
- current = current->parent;
- break;
-
- case token_eq:
- case token_ne:
-#ifdef DEBUG_INCLUDE
- rputs(" Evaluate eq/ne\n", r);
-#endif
- if ((current->left == (struct parse_node *) NULL) ||
- (current->right == (struct parse_node *) NULL) ||
- (current->left->token.type != token_string) ||
- (current->right->token.type != token_string)) {
- log_printf(r->server, "Invalid expression \"%s\" in file %s",
- expr, r->filename);
- rputs(error, r);
- goto RETURN;
- }
- parse_string(r, current->left->token.value,
- buffer, sizeof(buffer), 0);
- safe_copy(current->left->token.value, buffer,
- sizeof(current->left->token.value));
- parse_string(r, current->right->token.value,
- buffer, sizeof(buffer), 0);
- safe_copy(current->right->token.value, buffer,
- sizeof(current->right->token.value));
- if (current->right->token.value[0] == '/') {
- int len;
- len = strlen(current->right->token.value);
- if (current->right->token.value[len - 1] == '/') {
- current->right->token.value[len - 1] = '\0';
- }
- else {
- log_printf(r->server, "Invalid rexp \"%s\" in file %s",
- current->right->token.value, r->filename);
- rputs(error, r);
- goto RETURN;
- }
-#ifdef DEBUG_INCLUDE
- rvputs(r, " Re Compare (", current->left->token.value,
- ") with /", &current->right->token.value[1], "/\n", NULL);
-#endif
- current->value =
- re_check(r, current->left->token.value,
- &current->right->token.value[1]);
- }
- else {
-#ifdef DEBUG_INCLUDE
- rvputs(r, " Compare (", current->left->token.value,
- ") with (", current->right->token.value, ")\n", NULL);
-#endif
- current->value =
- (strcmp(current->left->token.value,
- current->right->token.value) == 0);
- }
- if (current->token.type == token_ne) {
- current->value = !current->value;
- }
-#ifdef DEBUG_INCLUDE
- rvputs(r, " Returning ", current->value ? "1" : "0",
- "\n", NULL);
-#endif
- current->done = 1;
- current = current->parent;
- break;
- case token_ge:
- case token_gt:
- case token_le:
- case token_lt:
-#ifdef DEBUG_INCLUDE
- rputs(" Evaluate ge/gt/le/lt\n", r);
-#endif
- if ((current->left == (struct parse_node *) NULL) ||
- (current->right == (struct parse_node *) NULL) ||
- (current->left->token.type != token_string) ||
- (current->right->token.type != token_string)) {
- log_printf(r->server, "Invalid expression \"%s\" in file %s",
- expr, r->filename);
- rputs(error, r);
- goto RETURN;
- }
- parse_string(r, current->left->token.value,
- buffer, sizeof(buffer), 0);
- safe_copy(current->left->token.value, buffer,
- sizeof(current->left->token.value));
- parse_string(r, current->right->token.value,
- buffer, sizeof(buffer), 0);
- safe_copy(current->right->token.value, buffer,
- sizeof(current->right->token.value));
-#ifdef DEBUG_INCLUDE
- rvputs(r, " Compare (", current->left->token.value,
- ") with (", current->right->token.value, ")\n", NULL);
-#endif
- current->value =
- strcmp(current->left->token.value,
- current->right->token.value);
- if (current->token.type == token_ge) {
- current->value = current->value >= 0;
- }
- else if (current->token.type == token_gt) {
- current->value = current->value > 0;
- }
- else if (current->token.type == token_le) {
- current->value = current->value <= 0;
- }
- else if (current->token.type == token_lt) {
- current->value = current->value < 0;
- }
- else {
- current->value = 0; /* Don't return -1 if unknown token */
- }
-#ifdef DEBUG_INCLUDE
- rvputs(r, " Returning ", current->value ? "1" : "0",
- "\n", NULL);
-#endif
- current->done = 1;
- current = current->parent;
- break;
-
- case token_not:
- if (current->right != (struct parse_node *) NULL) {
- if (!current->right->done) {
- current = current->right;
- continue;
- }
- current->value = !current->right->value;
- }
- else {
- current->value = 0;
- }
-#ifdef DEBUG_INCLUDE
- rvputs(r, " Evaluate !: ", current->value ? "1" : "0",
- "\n", NULL);
-#endif
- current->done = 1;
- current = current->parent;
- break;
-
- case token_group:
- if (current->right != (struct parse_node *) NULL) {
- if (!current->right->done) {
- current = current->right;
- continue;
- }
- current->value = current->right->value;
- }
- else {
- current->value = 1;
- }
-#ifdef DEBUG_INCLUDE
- rvputs(r, " Evaluate (): ", current->value ? "1" : "0",
- "\n", NULL);
-#endif
- current->done = 1;
- current = current->parent;
- break;
-
- case token_lbrace:
- log_printf(r->server, "Unmatched '(' in \"%s\" in file %s",
- expr, r->filename);
- rputs(error, r);
- goto RETURN;
-
- case token_rbrace:
- log_printf(r->server, "Unmatched ')' in \"%s\" in file %s\n",
- expr, r->filename);
- rputs(error, r);
- goto RETURN;
-
- default:
- log_printf(r->server, "bad token type");
- rputs(error, r);
- goto RETURN;
- }
- }
-
- retval = (root == (struct parse_node *) NULL) ? 0 : root->value;
- RETURN:
- destroy_pool(expr_pool);
- return (retval);
-}
-
-static int handle_if(FILE *in, request_rec *r, const char *error,
- int *conditional_status, int *printing)
-{
- char tag[MAX_STRING_LEN];
- char *tag_val;
- char *expr;
-
- expr = NULL;
- while (1) {
- tag_val = get_tag(r->pool, in, tag, sizeof(tag), 0);
- if (*tag == '\0') {
- return 1;
- }
- else if (!strcmp(tag, "done")) {
- if (expr == NULL) {
- log_printf(r->server, "missing expr in if statement: %s",
- r->filename);
- rputs(error, r);
- return 1;
- }
- *printing = *conditional_status = parse_expr(r, expr, error);
-#ifdef DEBUG_INCLUDE
- rvputs(r, "**** if conditional_status=\"",
- *conditional_status ? "1" : "0", "\"\n", NULL);
-#endif
- return 0;
- }
- else if (!strcmp(tag, "expr")) {
- expr = tag_val;
-#ifdef DEBUG_INCLUDE
- rvputs(r, "**** if expr=\"", expr, "\"\n", NULL);
-#endif
- }
- else {
- log_printf(r->server, "unknown parameter \"%s\" to tag if in %s",
- tag, r->filename);
- rputs(error, r);
- }
- }
-}
-
-static int handle_elif(FILE *in, request_rec *r, const char *error,
- int *conditional_status, int *printing)
-{
- char tag[MAX_STRING_LEN];
- char *tag_val;
- char *expr;
-
- expr = NULL;
- while (1) {
- tag_val = get_tag(r->pool, in, tag, sizeof(tag), 0);
- if (*tag == '\0') {
- return 1;
- }
- else if (!strcmp(tag, "done")) {
-#ifdef DEBUG_INCLUDE
- rvputs(r, "**** elif conditional_status=\"",
- *conditional_status ? "1" : "0", "\"\n", NULL);
-#endif
- if (*conditional_status) {
- *printing = 0;
- return (0);
- }
- if (expr == NULL) {
- log_printf(r->server, "missing expr in elif statement: %s",
- r->filename);
- rputs(error, r);
- return 1;
- }
- *printing = *conditional_status = parse_expr(r, expr, error);
-#ifdef DEBUG_INCLUDE
- rvputs(r, "**** elif conditional_status=\"",
- *conditional_status ? "1" : "0", "\"\n", NULL);
-#endif
- return 0;
- }
- else if (!strcmp(tag, "expr")) {
- expr = tag_val;
-#ifdef DEBUG_INCLUDE
- rvputs(r, "**** if expr=\"", expr, "\"\n", NULL);
-#endif
- }
- else {
- log_printf(r->server, "unknown parameter \"%s\" to tag if in %s",
- tag, r->filename);
- rputs(error, r);
- }
- }
-}
-
-static int handle_else(FILE *in, request_rec *r, const char *error,
- int *conditional_status, int *printing)
-{
- char tag[MAX_STRING_LEN];
- char *tag_val;
-
- if (!(tag_val = get_tag(r->pool, in, tag, sizeof(tag), 1))) {
- return 1;
- }
- else if (!strcmp(tag, "done")) {
-#ifdef DEBUG_INCLUDE
- rvputs(r, "**** else conditional_status=\"",
- *conditional_status ? "1" : "0", "\"\n", NULL);
-#endif
- *printing = !(*conditional_status);
- *conditional_status = 1;
- return 0;
- }
- else {
- log_printf(r->server, "else directive does not take tags in %s",
- r->filename);
- if (*printing) {
- rputs(error, r);
- }
- return -1;
- }
-}
-
-static int handle_endif(FILE *in, request_rec *r, const char *error,
- int *conditional_status, int *printing)
-{
- char tag[MAX_STRING_LEN];
- char *tag_val;
-
- if (!(tag_val = get_tag(r->pool, in, tag, sizeof(tag), 1))) {
- return 1;
- }
- else if (!strcmp(tag, "done")) {
-#ifdef DEBUG_INCLUDE
- rvputs(r, "**** endif conditional_status=\"",
- *conditional_status ? "1" : "0", "\"\n", NULL);
-#endif
- *printing = 1;
- *conditional_status = 1;
- return 0;
- }
- else {
- log_printf(r->server, "endif directive does not take tags in %s",
- r->filename);
- rputs(error, r);
- return -1;
- }
-}
-
-static int handle_set(FILE *in, request_rec *r, const char *error)
-{
- char tag[MAX_STRING_LEN];
- char parsed_string[MAX_STRING_LEN];
- char *tag_val;
- char *var;
-
- var = (char *) NULL;
- while (1) {
- if (!(tag_val = get_tag(r->pool, in, tag, sizeof(tag), 1))) {
- return 1;
- }
- else if (!strcmp(tag, "done")) {
- return 0;
- }
- else if (!strcmp(tag, "var")) {
- var = tag_val;
- }
- else if (!strcmp(tag, "value")) {
- if (var == (char *) NULL) {
- log_printf(r->server,
- "variable must precede value in set directive in %s",
- r->filename);
- rputs(error, r);
- return -1;
- }
- parse_string(r, tag_val, parsed_string, sizeof(parsed_string), 0);
- table_set(r->subprocess_env, var, parsed_string);
- }
- else {
- log_printf(r->server, "Invalid tag for set directive in %s",
- r->filename);
- rputs(error, r);
- return -1;
- }
- }
-}
-
-static int handle_printenv(FILE *in, request_rec *r, const char *error)
-{
- char tag[MAX_STRING_LEN];
- char *tag_val;
- table_entry *elts = (table_entry *) r->subprocess_env->elts;
- int i;
-
- if (!(tag_val = get_tag(r->pool, in, tag, sizeof(tag), 1))) {
- return 1;
- }
- else if (!strcmp(tag, "done")) {
- for (i = 0; i < r->subprocess_env->nelts; ++i) {
- rvputs(r, elts[i].key, "=", elts[i].val, "\n", NULL);
- }
- return 0;
- }
- else {
- log_printf(r->server, "printenv directive does not take tags in %s",
- r->filename);
- rputs(error, r);
- return -1;
- }
-}
-
-
-
-/* -------------------------- The main function --------------------------- */
-
-/* This is a stub which parses a file descriptor. */
-
-static void send_parsed_content(FILE *f, request_rec *r)
-{
- char directive[MAX_STRING_LEN], error[MAX_STRING_LEN];
- char timefmt[MAX_STRING_LEN];
- int noexec = allow_options(r) & OPT_INCNOEXEC;
- int ret, sizefmt;
- int if_nesting;
- int printing;
- int conditional_status;
-
- safe_copy(error, DEFAULT_ERROR_MSG, sizeof(error));
- safe_copy(timefmt, DEFAULT_TIME_FORMAT, sizeof(timefmt));
- sizefmt = SIZEFMT_KMG;
-
-/* Turn printing on */
- printing = conditional_status = 1;
- if_nesting = 0;
-
- chdir_file(r->filename);
- if (r->args) { /* add QUERY stuff to env cause it ain't yet */
- char *arg_copy = pstrdup(r->pool, r->args);
-
- table_set(r->subprocess_env, "QUERY_STRING", r->args);
- unescape_url(arg_copy);
- table_set(r->subprocess_env, "QUERY_STRING_UNESCAPED",
- escape_shell_cmd(r->pool, arg_copy));
- }
-
- while (1) {
- if (!find_string(f, STARTING_SEQUENCE, r, printing)) {
- if (get_directive(f, directive, sizeof(directive), r->pool)) {
- log_printf(r->server,
- "mod_include: error reading directive in %s",
- r->filename);
- rputs(error, r);
- return;
- }
- if (!strcmp(directive, "if")) {
- if (!printing) {
- if_nesting++;
- }
- else {
- ret = handle_if(f, r, error, &conditional_status,
- &printing);
- if_nesting = 0;
- }
- continue;
- }
- else if (!strcmp(directive, "else")) {
- if (!if_nesting) {
- ret = handle_else(f, r, error, &conditional_status,
- &printing);
- }
- continue;
- }
- else if (!strcmp(directive, "elif")) {
- if (!if_nesting) {
- ret = handle_elif(f, r, error, &conditional_status,
- &printing);
- }
- continue;
- }
- else if (!strcmp(directive, "endif")) {
- if (!if_nesting) {
- ret = handle_endif(f, r, error, &conditional_status,
- &printing);
- }
- else {
- if_nesting--;
- }
- continue;
- }
- if (!printing) {
- continue;
- }
- if (!strcmp(directive, "exec")) {
- if (noexec) {
- log_printf(r->server,
- "httpd: exec used but not allowed in %s",
- r->filename);
- if (printing) {
- rputs(error, r);
- }
- ret = find_string(f, ENDING_SEQUENCE, r, 0);
- }
- else {
- ret = handle_exec(f, r, error);
- }
- }
- else if (!strcmp(directive, "config")) {
- ret = handle_config(f, r, error, timefmt, &sizefmt);
- }
- else if (!strcmp(directive, "set")) {
- ret = handle_set(f, r, error);
- }
- else if (!strcmp(directive, "include")) {
- ret = handle_include(f, r, error, noexec);
- }
- else if (!strcmp(directive, "echo")) {
- ret = handle_echo(f, r, error);
- }
- else if (!strcmp(directive, "fsize")) {
- ret = handle_fsize(f, r, error, sizefmt);
- }
- else if (!strcmp(directive, "flastmod")) {
- ret = handle_flastmod(f, r, error, timefmt);
- }
- else if (!strcmp(directive, "printenv")) {
- ret = handle_printenv(f, r, error);
- }
-#ifdef USE_PERL_SSI
- else if (!strcmp(directive, "perl")) {
- ret = handle_perl(f, r, error);
- }
-#endif
- else {
- log_printf(r->server, "httpd: unknown directive \"%s\" "
- "in parsed doc %s",
- directive, r->filename);
- if (printing) {
- rputs(error, r);
- }
- ret = find_string(f, ENDING_SEQUENCE, r, 0);
- }
- if (ret) {
- log_printf(r->server, "httpd: premature EOF in parsed file %s",
- r->filename);
- return;
- }
- }
- else {
- return;
- }
- }
-}
-
-/*****************************************************************
- *
- * XBITHACK. Sigh... NB it's configurable per-directory; the compile-time
- * option only changes the default.
- */
-
-module includes_module;
-enum xbithack {
- xbithack_off, xbithack_on, xbithack_full
-};
-
-#ifdef XBITHACK
-#define DEFAULT_XBITHACK xbithack_full
-#else
-#define DEFAULT_XBITHACK xbithack_off
-#endif
-
-static void *create_includes_dir_config(pool *p, char *dummy)
-{
- enum xbithack *result = (enum xbithack *) palloc(p, sizeof(enum xbithack));
- *result = DEFAULT_XBITHACK;
- return result;
-}
-
-static const char *set_xbithack(cmd_parms *cmd, void *xbp, char *arg)
-{
- enum xbithack *state = (enum xbithack *) xbp;
-
- if (!strcasecmp(arg, "off")) {
- *state = xbithack_off;
- }
- else if (!strcasecmp(arg, "on")) {
- *state = xbithack_on;
- }
- else if (!strcasecmp(arg, "full")) {
- *state = xbithack_full;
- }
- else {
- return "XBitHack must be set to Off, On, or Full";
- }
-
- return NULL;
-}
-
-static int send_parsed_file(request_rec *r)
-{
- FILE *f;
- enum xbithack *state =
- (enum xbithack *) get_module_config(r->per_dir_config, &includes_module);
- int errstatus;
-
- if (!(allow_options(r) & OPT_INCLUDES)) {
- return DECLINED;
- }
- r->allowed |= (1 << M_GET);
- if (r->method_number != M_GET) {
- return DECLINED;
- }
- if (r->finfo.st_mode == 0) {
- log_printf(r->server, "File does not exist: %s",
- (r->path_info
- ? pstrcat(r->pool, r->filename, r->path_info, NULL)
- : r->filename));
- return HTTP_NOT_FOUND;
- }
-
- if (!(f = pfopen(r->pool, r->filename, "r"))) {
- log_printf(r->server,
- "file permissions deny server access: %s", r->filename);
- return HTTP_FORBIDDEN;
- }
-
- if (*state == xbithack_full
-#ifndef __EMX__
- /* OS/2 dosen't support Groups. */
- && (r->finfo.st_mode & S_IXGRP)
-#endif
- ) {
- errstatus = set_last_modified (r, r->finfo.st_mtime);
- table_unset(r->headers_out, "ETag");
- if (errstatus) {
- return errstatus;
- }
- }
-
- send_http_header(r);
-
- if (r->header_only) {
- pfclose(r->pool, f);
- return OK;
- }
-
- if (r->main) {
- /* Kludge --- for nested includes, we want to keep the
- * subprocess environment of the base document (for compatibility);
- * that means torquing our own last_modified date as well so that
- * the LAST_MODIFIED variable gets reset to the proper value if
- * the nested document resets <!--#config timefmt-->
- */
- r->subprocess_env = r->main->subprocess_env;
- r->finfo.st_mtime = r->main->finfo.st_mtime;
- }
- else {
- add_common_vars(r);
- add_cgi_vars(r);
- add_include_vars(r, DEFAULT_TIME_FORMAT);
- }
- hard_timeout("send SSI", r);
-
- send_parsed_content(f, r);
-
- kill_timeout(r);
- return OK;
-}
-
-static int send_shtml_file(request_rec *r)
-{
- r->content_type = "text/html";
- return send_parsed_file(r);
-}
-
-static int xbithack_handler(request_rec *r)
-{
-#ifdef __EMX__
- /* OS/2 dosen't currently support the xbithack. This is being worked on. */
- return DECLINED;
-#else
- enum xbithack *state;
-
- if (!(r->finfo.st_mode & S_IXUSR)) {
- return DECLINED;
- }
-
- state = (enum xbithack *) get_module_config(r->per_dir_config,
- &includes_module);
-
- if (*state == xbithack_off) {
- return DECLINED;
- }
- return send_parsed_file(r);
-#endif
-}
-
-static command_rec includes_cmds[] =
-{
- {"XBitHack", set_xbithack, NULL, OR_OPTIONS, TAKE1, "Off, On, or Full"},
- {NULL}
-};
-
-static handler_rec includes_handlers[] =
-{
- {INCLUDES_MAGIC_TYPE, send_shtml_file},
- {INCLUDES_MAGIC_TYPE3, send_shtml_file},
- {"server-parsed", send_parsed_file},
- {"text/html", xbithack_handler},
- {NULL}
-};
-
-module includes_module =
-{
- STANDARD_MODULE_STUFF,
- NULL, /* initializer */
- create_includes_dir_config, /* dir config creater */
- NULL, /* dir merger --- default is to override */
- NULL, /* server config */
- NULL, /* merge server config */
- includes_cmds, /* command table */
- includes_handlers, /* handlers */
- NULL, /* filename translation */
- NULL, /* check_user_id */
- NULL, /* check auth */
- NULL, /* check access */
- NULL, /* type_checker */
- NULL, /* fixups */
- NULL, /* logger */
- NULL /* header parser */
-};
diff --git a/usr.sbin/httpd/src/mod_info.c b/usr.sbin/httpd/src/mod_info.c
deleted file mode 100644
index 9aedbec2cd5..00000000000
--- a/usr.sbin/httpd/src/mod_info.c
+++ /dev/null
@@ -1,455 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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/>.
- *
- */
-
-/*
- * Info Module. Display configuration information for the server and
- * all included modules.
- *
- * <Location /server-info>
- * SetHandler server-info
- * </Location>
- *
- * GET /server-info - Returns full configuration page for server and all modules
- * GET /server-info?server - Returns server configuration only
- * GET /server-info?module_name - Returns configuration for a single module
- * GET /server-info?list - Returns quick list of included modules
- *
- * Rasmus Lerdorf <rasmus@vex.net>, May 1996
- *
- * 05.01.96 Initial Version
- *
- */
-
-#include "httpd.h"
-#include "http_config.h"
-#include "http_core.h"
-#include "http_log.h"
-#include "http_main.h"
-#include "http_protocol.h"
-#include "util_script.h"
-
-typedef struct mod_info_config_lines {
- char *cmd;
- char *line;
- struct mod_info_config_lines *next;
-} mod_info_config_lines;
-
-module info_module;
-extern module *top_module;
-
-char *mod_info_html_cmd_string(char *string) {
- char *s,*t;
- static char ret[256]; /* What is the max size of a command? */
- char *end_ret;
-
- ret[0]='\0';
- s = string;
- t=ret;
- end_ret = t + sizeof(ret);
- while((*s) && ((t-ret) < sizeof(ret))) {
- if(*s=='<') {
- strncpy(t,"&lt;", end_ret - t);
- t+=4;
- } else if(*s=='>') {
- strncpy(t,"&gt;", end_ret - t);
- t+=4;
- } else if(*s=='&') {
- strncpy(t,"&amp;", end_ret - t);
- t+=5;
- } else {
- *t++=*s;
- }
- s++;
- }
- *t='\0';
- return(ret);
-}
-
-mod_info_config_lines *mod_info_load_config(pool *p, char *filename, request_rec *r) {
- char s[MAX_STRING_LEN];
- FILE *fp;
- mod_info_config_lines *new, *ret=NULL, *prev=NULL;
- char *t,*tt,o, *msg;
-
- fp = pfopen(p,filename,"r");
- if(!fp) {
- msg = pstrcat
- (
- r->pool,
- "mod_info: couldn't open config file ",
- filename,
- NULL
- );
- log_error (msg, r->server);
- return NULL;
- }
- while(!cfg_getline(s,MAX_STRING_LEN,fp)) {
- if(*s=='#') continue; /* skip comments */
- new = palloc(p,sizeof(struct mod_info_config_lines));
- new->next = NULL;
- if(!ret) ret=new;
- if(prev) prev->next=new;
- t=strchr(s,' ');
- tt=strchr(s,'\t');
- if(t && tt) t = (t<tt)?t:tt;
- else if(tt) t=tt;
- if(t) {
- o=*t;
- *t='\0';
- new->cmd = pstrdup(p,s);
- new->line = pstrdup(p,t+1);
- *t=o;
- } else {
- new->cmd = pstrdup(p,s);
- new->line = NULL;
- }
- prev=new;
- }
- pfclose(p,fp);
- return(ret);
-}
-
-void mod_info_module_cmds(request_rec *r, mod_info_config_lines *cfg, command_rec *cmds,char *label) {
- command_rec *cmd=cmds;
- mod_info_config_lines *li=cfg,*li_st=NULL,*li_se=NULL,*block_start=NULL;
- int lab=0, nest=0;
-
- while(li) {
- if(!strncasecmp(li->cmd,"<directory",10) ||
- !strncasecmp(li->cmd,"<location",9) ||
- !strncasecmp(li->cmd,"<limit",6) ||
- !strncasecmp(li->cmd,"<files",6)) {
- if(nest) li_se=li;
- else li_st=li;
- li=li->next;
- nest++;
- continue;
- } else if(nest && (!strncasecmp(li->cmd,"</limit",7) ||
- !strncasecmp(li->cmd,"</location",10) ||
- !strncasecmp(li->cmd,"</directory",11) ||
- !strncasecmp(li->cmd,"</files",7))) {
- if(block_start) {
- if((nest==1 && block_start==li_st) || (nest==2 && block_start==li_se)) {
- rputs("<dd><tt>",r);
- if(nest==2) rputs("&nbsp;&nbsp;",r);
- rputs(mod_info_html_cmd_string(li->cmd),r);
- rputs(" ",r);
- if(li->line) rputs(mod_info_html_cmd_string(li->line),r);
- rputs("</tt>\n",r);
- nest--;
- if(!nest) {
- block_start=NULL;
- li_st=NULL;
- } else {
- block_start=li_st;
- }
- li_se=NULL;
- } else {
- nest--;
- if(!nest) {
- li_st=NULL;
- }
- li_se=NULL;
- }
- } else {
- nest--;
- if(!nest) {
- li_st=NULL;
- }
- li_se=NULL;
- }
- li=li->next;
- continue;
- }
- cmd = cmds;
- while(cmd) {
- if(cmd->name) {
- if(!strcasecmp(cmd->name,li->cmd)) {
- if(!lab) {
- rputs("<dt><strong>",r);
- rputs(label,r);
- rputs("</strong>\n",r);
- lab=1;
- }
- if(((nest && block_start==NULL) || (nest==2 && block_start==li_st))
- && (strncasecmp(li->cmd,"<directory",10) &&
- strncasecmp(li->cmd,"<location",9) && strncasecmp(li->cmd,"<limit",6) &&
- strncasecmp(li->cmd,"</limit",7) && strncasecmp(li->cmd,"</location",10) &&
- strncasecmp(li->cmd,"</directory",11) &&
- strncasecmp(li->cmd,"</files",7))) {
- rputs("<dd><tt>",r);
- rputs(mod_info_html_cmd_string(li_st->cmd),r);
- rputs(" ",r);
- if(li_st->line) rputs(mod_info_html_cmd_string(li_st->line),r);
- rputs("</tt>\n",r);
- block_start=li_st;
- if(li_se) {
- rputs("<dd><tt>&nbsp;&nbsp;",r);
- rputs(mod_info_html_cmd_string(li_se->cmd),r);
- rputs(" ",r);
- if(li_se->line) rputs(mod_info_html_cmd_string(li_se->line),r);
- rputs("</tt>\n",r);
- block_start=li_se;
- }
- }
- rputs("<dd><tt>",r);
- if(nest) rputs("&nbsp;&nbsp;",r);
- if(nest==2) rputs("&nbsp;&nbsp;",r);
- rputs(mod_info_html_cmd_string(li->cmd),r);
- if(li->line) {
- rputs(" <i>",r);
- rputs(mod_info_html_cmd_string(li->line),r);
- rputs("</i></tt>",r);
- }
- }
- } else break;
- cmd++;
- }
- li = li->next;
- }
-}
-
-int display_info(request_rec *r) {
- module *modp = NULL;
- char buf[512], *cfname;
- command_rec *cmd=NULL;
- handler_rec *hand=NULL;
- server_rec *serv = r->server;
- int comma=0;
- mod_info_config_lines *mod_info_cfg_httpd=NULL;
- mod_info_config_lines *mod_info_cfg_srm=NULL;
- mod_info_config_lines *mod_info_cfg_access=NULL;
- extern int standalone;
- extern uid_t user_id;
- extern char *user_name;
- extern gid_t group_id;
- extern int max_requests_per_child;
- extern char *pid_fname;
- extern char *scoreboard_fname;
- extern int daemons_to_start;
- extern int daemons_min_free;
- extern int daemons_max_free;
- extern int daemons_limit;
- extern char server_root[MAX_STRING_LEN];
- extern char server_confname[MAX_STRING_LEN];
-
- r->allowed |= (1 << M_GET);
- if (r->method_number != M_GET)
- return DECLINED;
-
- r->content_type = "text/html";
- send_http_header(r);
- if(r->header_only) {
- return 0;
- }
- hard_timeout("send server info", r);
-
- rputs("<html><head><title>Server Information</title></head>\n",r);
- rputs("<body><h1 align=center>Apache Server Information</h1>\n",r);
- if(!r->args || strcasecmp(r->args,"list")) {
- cfname = server_root_relative (r->pool, server_confname);
- mod_info_cfg_httpd = mod_info_load_config (r->pool, cfname, r);
- cfname = server_root_relative (r->pool, serv->srm_confname);
- mod_info_cfg_srm = mod_info_load_config(r->pool, cfname, r);
- cfname = server_root_relative (r->pool, serv->access_confname);
- mod_info_cfg_access = mod_info_load_config (r->pool, cfname, r);
- if(!r->args) {
- rputs("<tt><a href=\"#server\">Server Settings</a>, ",r);
- for(modp = top_module; modp; modp = modp->next) {
- ap_snprintf(buf, sizeof(buf), "<a href=\"#%s\">%s</a>",modp->name,modp->name);
- rputs(buf, r);
- if(modp->next) rputs(", ",r);
- }
- rputs("</tt><hr>",r);
-
- }
- if(!r->args || !strcasecmp(r->args,"server")) {
- ap_snprintf(buf, sizeof(buf), "<a name=\"server\"><strong>Server Version:</strong> <font size=+1><tt>%s</tt></a></font><br>\n",SERVER_VERSION);
- rputs(buf,r);
- ap_snprintf(buf, sizeof(buf), "<strong>API Version:</strong> <tt>%d</tt><br>\n",MODULE_MAGIC_NUMBER);
- rputs(buf,r);
- ap_snprintf(buf, sizeof(buf), "<strong>Run Mode:</strong> <tt>%s</tt><br>\n",standalone?"standalone":"inetd");
- rputs(buf,r);
- ap_snprintf(buf, sizeof(buf), "<strong>User/Group:</strong> <tt>%s(%d)/%d</tt><br>\n",user_name,(int)user_id,(int)group_id);
- rputs(buf,r);
- ap_snprintf(buf, sizeof(buf), "<strong>Hostname/port:</strong> <tt>%s:%u</tt><br>\n",serv->server_hostname,serv->port);
- rputs(buf,r);
- ap_snprintf(buf, sizeof(buf), "<strong>Daemons:</strong> <tt>start: %d &nbsp;&nbsp; min idle: %d &nbsp;&nbsp; max idle: %d &nbsp;&nbsp; max: %d</tt><br>\n",daemons_to_start,daemons_min_free,daemons_max_free,daemons_limit);
- rputs(buf,r);
- ap_snprintf(buf, sizeof(buf), "<strong>Max Requests:</strong> <tt>per child: %d &nbsp;&nbsp; keep alive: %s &nbsp;&nbsp; max per connection: %d</tt><br>\n",max_requests_per_child,serv->keep_alive ? "on":"off", serv->keep_alive_max);
- rputs(buf,r);
- ap_snprintf(buf, sizeof(buf), "<strong>Timeouts:</strong> <tt>connection: %d &nbsp;&nbsp; keep-alive: %d</tt><br>",serv->timeout,serv->keep_alive_timeout);
- rputs(buf,r);
- ap_snprintf(buf, sizeof(buf), "<strong>Server Root:</strong> <tt>%s</tt><br>\n",server_root);
- rputs(buf,r);
- ap_snprintf(buf, sizeof(buf), "<strong>Config File:</strong> <tt>%s</tt><br>\n",server_confname);
- rputs(buf,r);
- ap_snprintf(buf, sizeof(buf), "<strong>PID File:</strong> <tt>%s</tt><br>\n",pid_fname);
- rputs(buf,r);
- ap_snprintf(buf, sizeof(buf), "<strong>Scoreboard File:</strong> <tt>%s</tt><br>\n",scoreboard_fname);
- rputs(buf,r);
- }
- rputs("<hr><dl>",r);
- for(modp = top_module; modp; modp = modp->next) {
- if(!r->args || !strcasecmp(modp->name,r->args)) {
- ap_snprintf(buf, sizeof(buf), "<dt><a name=\"%s\"><strong>Module Name:</strong> <font size=+1><tt>%s</tt></a></font>\n",modp->name,modp->name);
- rputs(buf,r);
- rputs("<dt><strong>Content-types affected:</strong>",r);
- hand = modp->handlers;
- if(hand) {
- while(hand) {
- if(hand->content_type) {
- ap_snprintf(buf, sizeof(buf), " <tt>%s</tt>\n",hand->content_type);
- rputs(buf,r);
- } else break;
- hand++;
- if(hand && hand->content_type) rputs(",",r);
- }
- } else {
- rputs("<tt> none</tt>",r);
- }
- rputs("<dt><strong>Module Groups:</strong> \n",r);
- if(modp->translate_handler) {
- rputs("<tt>Translate Handler</tt>\n",r);
- comma=1;
- }
- if(modp->check_user_id) {
- if(comma) rputs(", ",r);
- rputs("<tt>User ID Checking</tt>\n",r);
- comma=1;
- }
- if(modp->auth_checker) {
- if(comma) rputs(", ",r);
- rputs("<tt>Authentication Checking</tt>\n",r);
- comma=1;
- }
- if(modp->access_checker) {
- if(comma) rputs(", ",r);
- rputs("<tt>Access Checking</tt>\n",r);
- comma=1;
- }
- if(modp->type_checker) {
- if(comma) rputs(", ",r);
- rputs("<tt>Type Checking</tt>\n",r);
- comma=1;
- }
- if(modp->fixer_upper) {
- if(comma) rputs(", ",r);
- rputs("<tt>Header Fixer</tt>\n",r);
- comma=1;
- }
- if(modp->logger) {
- if(comma) rputs(", ",r);
- rputs("<tt>Logging</tt>\n",r);
- comma=1;
- }
- if(!comma) rputs("<tt> none</tt>",r);
- comma=0;
- rputs("<dt><strong>Module Configuration Commands:</strong> ",r);
- cmd = modp->cmds;
- if(cmd) {
- while(cmd) {
- if(cmd->name) {
- ap_snprintf(buf, sizeof(buf), "<dd><tt>%s - <i>",mod_info_html_cmd_string(cmd->name));
- rputs(buf,r);
- if(cmd->errmsg) rputs(cmd->errmsg,r);
- rputs("</i></tt>\n",r);
- } else break;
- cmd++;
- }
- rputs("<dt><strong>Current Configuration:</strong>\n",r);
- mod_info_module_cmds(r,mod_info_cfg_httpd,modp->cmds,"httpd.conf");
- mod_info_module_cmds(r,mod_info_cfg_srm,modp->cmds,"srm.conf");
- mod_info_module_cmds(r,mod_info_cfg_access,modp->cmds,"access.conf");
- } else {
- rputs("<tt> none</tt>\n",r);
- }
- rputs("<dt><hr>\n",r);
- if(r->args) break;
- }
- }
- if(!modp && r->args && strcasecmp(r->args,"server")) rputs("<b>No such module</b>\n",r);
- } else {
- for(modp = top_module; modp; modp = modp->next) {
- rputs(modp->name,r);
- if(modp->next) rputs("<br>",r);
- }
- }
- rputs("</dl></body></html>\n",r);
- /* Done, turn off timeout, close file and return */
- kill_timeout(r);
- return 0;
-}
-
-handler_rec info_handlers[] = {
- { "server-info", display_info },
- { NULL }
-};
-
-module info_module = {
- STANDARD_MODULE_STUFF,
- NULL, /* initializer */
- NULL, /* dir config creater */
- NULL, /* dir merger --- default is to override */
- NULL, /* server config */
- NULL, /* merge server config */
- NULL, /* command table */
- info_handlers, /* handlers */
- NULL, /* filename translation */
- NULL, /* check_user_id */
- NULL, /* check auth */
- NULL, /* check access */
- NULL, /* type_checker */
- NULL, /* fixups */
- NULL, /* logger */
- NULL /* header parser */
-};
diff --git a/usr.sbin/httpd/src/mod_log_agent.c b/usr.sbin/httpd/src/mod_log_agent.c
deleted file mode 100644
index 234de33ab24..00000000000
--- a/usr.sbin/httpd/src/mod_log_agent.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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/>.
- *
- */
-
-
-#include "httpd.h"
-#include "http_config.h"
-
-module agent_log_module;
-
-static int xfer_flags = ( O_WRONLY | O_APPEND | O_CREAT );
-#ifdef __EMX__
-/* OS/2 dosen't support users and groups */
-static mode_t xfer_mode = ( S_IREAD | S_IWRITE );
-#else
-static mode_t xfer_mode = ( S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH );
-#endif
-
-typedef struct {
- char *fname;
- int agent_fd;
-} agent_log_state;
-
-void *make_agent_log_state (pool *p, server_rec *s)
-{
- agent_log_state *cls =
- (agent_log_state *)palloc (p, sizeof (agent_log_state));
-
- cls->fname = "";
- cls->agent_fd = -1;
-
-
- return (void *)cls;
-}
-
-const char *set_agent_log (cmd_parms *parms, void *dummy, char *arg)
-{
- agent_log_state *cls = get_module_config (parms->server->module_config,
- &agent_log_module);
-
- cls->fname = arg;
- return NULL;
-}
-
-command_rec agent_log_cmds[] = {
-{ "AgentLog", set_agent_log, NULL, RSRC_CONF, TAKE1,
- "the filename of the agent log" },
-{ NULL }
-};
-
-void agent_log_child (void *cmd)
-{
- /* Child process code for 'AgentLog "|..."';
- * may want a common framework for this, since I expect it will
- * be common for other foo-loggers to want this sort of thing...
- */
-
- cleanup_for_exec();
- signal (SIGHUP, SIG_IGN);
-#ifdef __EMX__
- /* For OS/2 we need to use a '/' */
- execl (SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL);
-#else
- execl (SHELL_PATH, SHELL_PATH, "-c", (char *)cmd, NULL);
-#endif
- perror ("exec");
- fprintf (stderr, "Exec of shell for logging failed!!!\n");
- exit (1);
-}
-
-void open_agent_log (server_rec *s, pool *p)
-{
- agent_log_state *cls = get_module_config (s->module_config,
- &agent_log_module);
-
- char *fname = server_root_relative (p, cls->fname);
-
- if (cls->agent_fd > 0) return; /* virtual log shared w/main server */
-
- if (*cls->fname == '|') {
- FILE *dummy;
-
- if (!spawn_child (p, agent_log_child, (void *)(cls->fname+1),
- kill_after_timeout, &dummy, NULL)) {
- perror ("spawn_child");
- fprintf (stderr, "Couldn't fork child for AgentLog process\n");
- exit (1);
- }
-
- cls->agent_fd = fileno (dummy);
- }
- else if(*cls->fname != '\0') {
- if((cls->agent_fd = popenf(p, fname, xfer_flags, xfer_mode)) < 0) {
- perror("open");
- fprintf(stderr,"httpd: could not open agent log file %s.\n", fname);
- exit(1);
- }
- }
-}
-
-void init_agent_log (server_rec *s, pool *p)
-{
- for (; s; s = s->next) open_agent_log (s, p);
-}
-
-int agent_log_transaction(request_rec *orig)
-{
- agent_log_state *cls = get_module_config (orig->server->module_config,
- &agent_log_module);
-
- char str[HUGE_STRING_LEN];
- char *agent;
- request_rec *r;
-
- if(cls->agent_fd <0)
- return OK;
-
- for (r = orig; r->next; r = r->next)
- continue;
- if (*cls->fname == '\0') /* Don't log agent */
- return DECLINED;
-
- agent = table_get(orig->headers_in, "User-Agent");
- if(agent != NULL)
- {
- ap_snprintf(str, sizeof(str), "%s\n", agent);
- write(cls->agent_fd, str, strlen(str));
- }
-
- return OK;
-}
-
-module agent_log_module = {
- STANDARD_MODULE_STUFF,
- init_agent_log, /* initializer */
- NULL, /* create per-dir config */
- NULL, /* merge per-dir config */
- make_agent_log_state, /* server config */
- NULL, /* merge server config */
- agent_log_cmds, /* command table */
- NULL, /* handlers */
- NULL, /* filename translation */
- NULL, /* check_user_id */
- NULL, /* check auth */
- NULL, /* check access */
- NULL, /* type_checker */
- NULL, /* fixups */
- agent_log_transaction, /* logger */
- NULL /* header parser */
-};
diff --git a/usr.sbin/httpd/src/mod_log_config.c b/usr.sbin/httpd/src/mod_log_config.c
deleted file mode 100644
index d383cd5f6bc..00000000000
--- a/usr.sbin/httpd/src/mod_log_config.c
+++ /dev/null
@@ -1,787 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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 is module implements the TransferLog directive (same as the
- * common log module), and additional directives, LogFormat and CustomLog.
- *
- *
- * Syntax:
- *
- * TransferLog fn Logs transfers to fn in standard log format, unless
- * a custom format is set with LogFormat
- * LogFormat format Set a log format from TransferLog files
- * CustomLog fn format
- * Log to file fn with format given by the format
- * argument
- *
- * CookieLog fn For backwards compatability with old Cookie
- * logging module - now deprecated.
- *
- * There can be any number of TransferLog and CustomLog
- * commands. Each request will be logged to _ALL_ the
- * named files, in the appropriate format.
- *
- * If no TransferLog or CustomLog directive appears in a VirtualHost,
- * the request will be logged to the log file(s) defined outside
- * the virtual host section. If a TransferLog or CustomLog directive
- * appears in the VirtualHost section, the log files defined outside
- * the VirtualHost will _not_ be used. This makes this module compatable
- * with the CLF and config log modules, where the use of TransferLog
- * inside the VirtualHost section overrides its use outside.
- *
- * Examples:
- *
- * TransferLog logs/access_log
- * <VirtualHost>
- * LogFormat "... custom format ..."
- * TransferLog log/virtual_only
- * CustomLog log/virtual_useragents "%t %{user-agent}i"
- * </VirtualHost>
- *
- * This will log using CLF to access_log any requests handled by the
- * main server, while any requests to the virtual host will be logged
- * with the "... custom format..." to virtual_only _AND_ using
- * the custom user-agent log to virtual_useragents.
- *
- * Note that the NCSA referer and user-agent logs are easily added with
- * CustomLog:
- * CustomLog logs/referer "%{referer}i -> %U"
- * CustomLog logs/agent "%{user-agent}i"
- *
- * Except: no RefererIgnore functionality
- * logs '-' if no Referer or User-Agent instead of nothing
- *
- * But using this method allows much easier modification of the
- * log format, e.g. to log hosts along with UA:
- * CustomLog logs/referer "%{referer}i %U %h"
- *
- * The argument to LogFormat and CustomLog is a string, which can include
- * literal characters copied into the log files, and '%' directives as
- * follows:
- *
- * %...b: bytes sent, excluding HTTP headers.
- * %...{FOOBAR}e: The contents of the environment variable FOOBAR
- * %...f: filename
- * %...h: remote host
- * %...{Foobar}i: The contents of Foobar: header line(s) in the request
- * sent to the client.
- * %...l: remote logname (from identd, if supplied)
- * %...{Foobar}n: The contents of note "Foobar" from another module.
- * %...{Foobar}o: The contents of Foobar: header line(s) in the reply.
- * %...p: the port the request was served to
- * %...P: the process ID of the child that serviced the request.
- * %...r: first line of request
- * %...s: status. For requests that got internally redirected, this
- * is status of the *original* request --- %...>s for the last.
- * %...t: time, in common log format time format
- * %...{format}t: The time, in the form given by format, which should
- * be in strftime(3) format.
- * %...T: the time taken to serve the request, in seconds.
- * %...u: remote user (from auth; may be bogus if return status (%s) is 401)
- * %...U: the URL path requested.
- * %...v: the name of the server (i.e. which virtual host?)
- *
- * The '...' can be nothing at all (e.g. "%h %u %r %s %b"), or it can
- * indicate conditions for inclusion of the item (which will cause it
- * to be replaced with '-' if the condition is not met). Note that
- * there is no escaping performed on the strings from %r, %...i and
- * %...o; some with long memories may remember that I thought this was
- * a bad idea, once upon a time, and I'm still not comfortable with
- * it, but it is difficult to see how to "do the right thing" with all
- * of '%..i', unless we URL-escape everything and break with CLF.
- *
- * The forms of condition are a list of HTTP status codes, which may
- * or may not be preceded by '!'. Thus, '%400,501{User-agent}i' logs
- * User-agent: on 400 errors and 501 errors (Bad Request, Not
- * Implemented) only; '%!200,304,302{Referer}i' logs Referer: on all
- * requests which did *not* return some sort of normal status.
- *
- * The default LogFormat reproduces CLF; see below.
- *
- * The way this is supposed to work with virtual hosts is as follows:
- * a virtual host can have its own LogFormat, or its own TransferLog.
- * If it doesn't have its own LogFormat, it inherits from the main
- * server. If it doesn't have its own TransferLog, it writes to the
- * same descriptor (meaning the same process for "| ...").
- *
- * --- rst */
-
-#define DEFAULT_LOG_FORMAT "%h %l %u %t \"%r\" %>s %b"
-
-#include "httpd.h"
-#include "http_config.h"
-#include "http_core.h" /* For REMOTE_NAME */
-
-module config_log_module;
-
-static int xfer_flags = ( O_WRONLY | O_APPEND | O_CREAT );
-#ifdef __EMX__
-/* OS/2 dosen't support users and groups */
-static mode_t xfer_mode = ( S_IREAD | S_IWRITE );
-#else
-static mode_t xfer_mode = ( S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH );
-#endif
-
-/*
- * multi_log_state is our per-(virtual)-server configuration. We store
- * an array of the logs we are going to use, each of type config_log_state.
- * If a default log format is given by LogFormat, store in default_format
- * (backward compat. with mod_log_config). We also store a pointer to
- * the logs specified for the main server for virtual servers, so that
- * if this vhost has now logs defined, we can use the main server's
- * logs instead.
- *
- * So, for the main server, config_logs contains a list of the log files
- * and server_config_logs in empty. For a vhost, server_config_logs
- * points to the same array as config_logs in the main server, and
- * config_logs points to the array of logs defined inside this vhost,
- * which might be empty.
- */
-
-typedef struct {
- array_header *default_format;
- array_header *config_logs;
- array_header *server_config_logs;
-} multi_log_state;
-
-/*
- * config_log_state holds the status of a single log file. fname cannot
- * be NULL. format might be NULL, in which case the default_format from
- * the multi_log_state should be used, or if that is NULL as well, use
- * the CLF. log_fd is -1 before the log file is opened and set to a valid
- * fd after it is opened.
- */
-
-typedef struct {
- char *fname;
- array_header *format;
- int log_fd;
-} config_log_state;
-
-/*
- * Format items...
- */
-
-typedef char *(*item_key_func)(request_rec *, char *);
-
-typedef struct {
- item_key_func func;
- char *arg;
- int condition_sense;
- int want_orig;
- array_header *conditions;
-} log_format_item;
-
-char *format_integer(pool *p, int i)
-{
- char dummy[40];
- ap_snprintf (dummy, sizeof(dummy), "%d", i);
- return pstrdup (p, dummy);
-}
-
-static char *pfmt(pool *p, int i)
-{
- if (i <= 0) return "-";
- else return format_integer (p, i);
-}
-
-char *constant_item (request_rec *dummy, char *stuff) { return stuff; }
-
-char *log_remote_host (request_rec *r, char *a)
-{ return (char *)get_remote_host(r->connection, r->per_dir_config, REMOTE_NAME); }
-
-char *log_remote_logname(request_rec *r, char *a)
-{return (char *)get_remote_logname(r);}
-
-char *log_remote_user (request_rec *r, char *a) {
- char *rvalue = r->connection->user;
-
- if (rvalue == NULL) {
- rvalue = "-";
- } else if (strlen (rvalue) == 0) {
- rvalue = "\"\"";
- }
- return rvalue;
-}
-
-char *log_request_line (request_rec *r, char *a)
-{ return r->the_request; }
-
-char *log_request_file (request_rec *r, char *a)
-{ return r->filename; }
-char *log_request_uri (request_rec *r, char *a)
-{ return r->uri; }
-char *log_status (request_rec *r, char *a)
-{ return pfmt(r->pool, r->status); }
-
-char *log_bytes_sent (request_rec *r, char *a)
-{
- if (!r->sent_bodyct) return "-";
- else
- {
- long int bs;
- char dummy[40];
- bgetopt(r->connection->client, BO_BYTECT, &bs);
- ap_snprintf(dummy, sizeof(dummy), "%ld", bs);
- return pstrdup(r->pool, dummy);
- }
-}
-
-char *log_header_in (request_rec *r, char *a)
-{ return table_get (r->headers_in, a); }
-
-char *log_header_out (request_rec *r, char *a)
-{
- char *cp = table_get (r->headers_out, a);
- if (!strcasecmp(a, "Content-type") && r->content_type)
- cp = r->content_type;
- if (cp) return cp;
- return table_get (r->err_headers_out, a);
-}
-
-char *log_note (request_rec *r, char *a)
-{ return table_get (r->notes, a); }
-char *log_env_var (request_rec *r, char *a)
-{ return table_get (r->subprocess_env, a); }
-
-char *log_request_time (request_rec *r, char *a)
-{
- int timz;
- struct tm *t;
- char tstr[MAX_STRING_LEN];
-
- t = get_gmtoff(&timz);
-
- if (a && *a) /* Custom format */
- strftime(tstr, MAX_STRING_LEN, a, t);
- else { /* CLF format */
- char sign = (timz < 0 ? '-' : '+');
-
- if(timz < 0) timz = -timz;
-
- strftime(tstr,MAX_STRING_LEN,"[%d/%b/%Y:%H:%M:%S ",t);
- ap_snprintf (tstr + strlen(tstr), sizeof(tstr)-strlen(tstr),
- "%c%.2d%.2d]", sign, timz/60, timz%60);
- }
-
- return pstrdup (r->pool, tstr);
-}
-
-char *log_request_duration (request_rec *r, char *a) {
- char duration[22]; /* Long enough for 2^64 */
-
- ap_snprintf(duration, sizeof(duration), "%ld", time(NULL) - r->request_time);
- return pstrdup(r->pool, duration);
-}
-
-char *log_virtual_host (request_rec *r, char *a) {
- return pstrdup(r->pool, r->server->server_hostname);
-}
-
-char *log_server_port (request_rec *r, char *a) {
- char portnum[22];
-
- ap_snprintf(portnum, sizeof(portnum), "%u", r->server->port);
- return pstrdup(r->pool, portnum);
-}
-
-char *log_child_pid (request_rec *r, char *a) {
- char pidnum[22];
- ap_snprintf(pidnum, sizeof(pidnum), "%ld", (long)getpid());
- return pstrdup(r->pool, pidnum);
-}
-/*****************************************************************
- *
- * Parsing the log format string
- */
-
-struct log_item_list {
- char ch;
- item_key_func func;
- int want_orig_default;
-} log_item_keys[] = {
- { 'h', log_remote_host, 0 },
- { 'l', log_remote_logname, 0 },
- { 'u', log_remote_user, 0 },
- { 't', log_request_time, 0 },
- { 'T', log_request_duration, 1 },
- { 'r', log_request_line, 1 },
- { 'f', log_request_file, 0 },
- { 'U', log_request_uri, 1 },
- { 's', log_status, 1 },
- { 'b', log_bytes_sent, 0 },
- { 'i', log_header_in, 0 },
- { 'o', log_header_out, 0 },
- { 'n', log_note, 0 },
- { 'e', log_env_var, 0 },
- { 'v', log_virtual_host, 0 },
- { 'p', log_server_port, 0 },
- { 'P', log_child_pid, 0 },
- { '\0' }
-};
-
-struct log_item_list *find_log_func (char k)
-{
- int i;
-
- for (i = 0; log_item_keys[i].ch; ++i)
- if (k == log_item_keys[i].ch)
- return &log_item_keys[i];
-
- return NULL;
-}
-
-char *log_format_substring (pool *p, const char *start, const char *end)
-{
- char *res = palloc (p, end - start + 1);
- strncpy (res, start, end - start);
- res[end - start] = '\0';
- return res;
-}
-
-char *parse_log_misc_string (pool *p, log_format_item *it, const char **sa)
-{
- const char *s = *sa;
-
- it->func = constant_item;
- it->conditions = NULL;
-
- while (*s && *s != '%') ++s;
- it->arg = log_format_substring (p, *sa, s);
- *sa = s;
-
- return NULL;
-}
-
-char *parse_log_item (pool *p, log_format_item *it, const char **sa)
-{
- const char *s = *sa;
- if (*s != '%') return parse_log_misc_string (p, it, sa);
-
- ++s;
- it->condition_sense = 0;
- it->conditions = NULL;
- it->want_orig = -1;
- it->arg = ""; /* For safety's sake... */
-
- while (*s) {
- int i;
- struct log_item_list *l;
-
- switch (*s) {
- case '!':
- ++s;
- it->condition_sense = !it->condition_sense;
- break;
-
- case '<':
- ++s;
- it->want_orig = 1;
- break;
-
- case '>':
- ++s;
- it->want_orig = 0;
- break;
-
- case ',':
- ++s;
- break;
-
- case '{':
- ++s;
- it->arg = getword (p, &s, '}');
- break;
-
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- i = *s - '0';
- while (isdigit (*++s)) i = i * 10 + (*s) - '0';
- if (!it->conditions)
- it->conditions = make_array (p, 4, sizeof(int));
- *(int *)push_array(it->conditions) = i;
- break;
-
- default:
- l = find_log_func (*s++);
- if (!l) {
- char dummy[] = { '\0', '\0'};
- dummy[0] = s[-1];
- return pstrcat (p, "Unrecognized LogFormat directive %",
- dummy, NULL);
- }
- it->func = l->func;
- if (it->want_orig == -1) it->want_orig = l->want_orig_default;
- *sa = s;
- return NULL;
- }
- }
-
- return "Ran off end of LogFormat parsing args to some directive";
-}
-
-array_header *parse_log_string (pool *p, const char *s, const char **err)
-{
- array_header *a = make_array (p, 30, sizeof (log_format_item));
- char *res;
-
- while (*s) {
- if ((res = parse_log_item (p, (log_format_item *)push_array(a), &s))) {
- *err = res;
- return NULL;
- }
- }
-
- s = "\n";
- parse_log_item (p, (log_format_item *)push_array(a), &s);
- return a;
-}
-
-/*****************************************************************
- *
- * Actually logging.
- */
-
-char *process_item(request_rec *r, request_rec *orig, log_format_item *item)
-{
- char *cp;
-
- /* First, see if we need to process this thing at all... */
-
- if (item->conditions && item->conditions->nelts != 0) {
- int i;
- int *conds = (int *)item->conditions->elts;
- int in_list = 0;
-
- for (i = 0; i < item->conditions->nelts; ++i)
- if (r->status == conds[i]) {
- in_list = 1;
- break;
- }
-
- if ((item->condition_sense && in_list)
- || (!item->condition_sense && !in_list))
- {
- return "-";
- }
- }
-
- /* We do. Do it... */
-
- cp = (*item->func)(item->want_orig ? orig : r, item->arg);
- return cp ? cp : "-";
-}
-
-int config_log_transaction(request_rec *r, config_log_state *cls,
- array_header *default_format) {
- array_header *strsa;
- log_format_item *items;
- char *str, **strs, *s;
- request_rec *orig;
- int i;
- int len = 0;
- array_header *format;
-
- format = cls->format ? cls->format : default_format;
-
- strsa= make_array(r->pool, format->nelts,sizeof(char*));
- items = (log_format_item *)format->elts;
-
- orig = r;
- while (orig->prev) orig = orig->prev;
- while (r->next) r = r->next;
-
- for (i = 0; i < format->nelts; ++i)
- *((char**)push_array (strsa)) = process_item (r, orig, &items[i]);
-
- strs = (char **)strsa->elts;
-
- for (i = 0; i < format->nelts; ++i)
- len += strlen (strs[i]);
-
- str = palloc (r->pool, len + 1);
-
- for (i = 0, s = str; i < format->nelts; ++i) {
- strcpy (s, strs[i]);
- s += strlen (strs[i]);
- }
-
- write(cls->log_fd, str, strlen(str));
-
- return OK;
-}
-
-int multi_log_transaction(request_rec *r)
-{
- multi_log_state *mls = get_module_config (r->server->module_config,
- &config_log_module);
- config_log_state *clsarray;
- int i;
-
- if (mls->config_logs->nelts) {
- clsarray = (config_log_state *)mls->config_logs->elts;
- for (i = 0; i < mls->config_logs->nelts; ++i) {
- config_log_state *cls = &clsarray[i];
-
- config_log_transaction(r, cls, mls->default_format);
- }
- }
- else if (mls->server_config_logs) {
- clsarray = (config_log_state *)mls->server_config_logs->elts;
- for (i = 0; i < mls->server_config_logs->nelts; ++i) {
- config_log_state *cls = &clsarray[i];
-
- config_log_transaction(r, cls, mls->default_format);
- }
- }
-
- return OK;
-}
-
-/*****************************************************************
- *
- * Module glue...
- */
-
-void *make_config_log_state (pool *p, server_rec *s)
-{
- multi_log_state *mls =
- (multi_log_state *)palloc(p, sizeof (multi_log_state));
-
- mls->config_logs =
- make_array(p, 5, sizeof (config_log_state));
- mls->default_format = NULL;
- mls->server_config_logs = NULL;
-
- return mls;
-}
-
-/*
- * Use the merger to simply add a pointer from the vhost log state
- * to the log of logs specified for the non-vhost configuration
- */
-
-void *merge_config_log_state (pool *p, void *basev, void *addv)
-{
- multi_log_state *base = (multi_log_state *)basev;
- multi_log_state *add = (multi_log_state *)addv;
-
- add->server_config_logs = base->config_logs;
- if (!add->default_format)
- add->default_format = base->default_format;
-
- return add;
-}
-
-const char *log_format (cmd_parms *cmd, void *dummy, char *arg)
-{
- const char *err_string = NULL;
- multi_log_state *mls = get_module_config (cmd->server->module_config,
- &config_log_module);
-
- mls->default_format = parse_log_string (cmd->pool, arg, &err_string);
- return err_string;
-}
-
-const char *add_custom_log(cmd_parms *cmd, void *dummy, char *fn, char *fmt)
-{
- const char *err_string = NULL;
- multi_log_state *mls = get_module_config (cmd->server->module_config,
- &config_log_module);
- config_log_state *cls;
-
- cls = (config_log_state*)push_array(mls->config_logs);
- cls->fname = fn;
- if (!fmt)
- cls->format = NULL;
- else
- cls->format = parse_log_string (cmd->pool, fmt, &err_string);
- cls->log_fd = -1;
-
- return err_string;
-}
-
-const char *set_transfer_log(cmd_parms *cmd, void *dummy, char *fn)
-{
- return add_custom_log(cmd, dummy, fn, NULL);
-}
-
-const char *set_cookie_log(cmd_parms *cmd, void *dummy, char *fn)
-{
- return add_custom_log(cmd, dummy, fn, "%{Cookie}n \"%r\" %t");
-}
-
-command_rec config_log_cmds[] = {
-{ "CustomLog", add_custom_log, NULL, RSRC_CONF, TAKE2,
- "a file name and a custom log format string" },
-{ "TransferLog", set_transfer_log, NULL, RSRC_CONF, TAKE1,
- "the filename of the access log" },
-{ "LogFormat", log_format, NULL, RSRC_CONF, TAKE1,
- "a log format string (see docs)" },
-{ "CookieLog", set_cookie_log, NULL, RSRC_CONF, TAKE1,
- "the filename of the cookie log" },
-{ NULL }
-};
-
-void config_log_child (void *cmd)
-{
- /* 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...
- */
-
- cleanup_for_exec();
- signal (SIGHUP, SIG_IGN);
-#ifdef __EMX__
- /* For OS/2 we need to use a '/' */
- execl (SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL);
-#else
- execl (SHELL_PATH, SHELL_PATH, "-c", (char *)cmd, NULL);
-#endif
- perror ("exec");
- fprintf (stderr, "Exec of shell for logging failed!!!\n");
- exit (1);
-}
-
-config_log_state *open_config_log (server_rec *s, pool *p,
- config_log_state *cls,
- array_header *default_format) {
- if (cls->log_fd > 0) return cls; /* virtual config shared w/main server */
-
- if (*cls->fname == '|') {
- FILE *dummy;
-
- if (!spawn_child (p, config_log_child, (void *)(cls->fname+1),
- kill_after_timeout, &dummy, NULL)) {
- perror ("spawn_child");
- fprintf (stderr, "Couldn't fork child for TransferLog process\n");
- exit (1);
- }
-
- cls->log_fd = fileno (dummy);
- }
- else {
- char *fname = server_root_relative (p, cls->fname);
- if((cls->log_fd = popenf(p, fname, xfer_flags, xfer_mode)) < 0) {
- perror("open");
- fprintf (stderr,
- "httpd: could not open transfer log file %s.\n", fname);
- exit(1);
- }
- }
-
- return cls;
-}
-
-config_log_state *open_multi_logs (server_rec *s, pool *p)
-{
- int i;
- multi_log_state *mls = get_module_config(s->module_config,
- &config_log_module);
- config_log_state *clsarray;
- const char *dummy;
-
- if (!mls->default_format)
- mls->default_format = parse_log_string (p, DEFAULT_LOG_FORMAT, &dummy);
-
- if (mls->config_logs->nelts) {
- clsarray = (config_log_state *)mls->config_logs->elts;
- for (i = 0; i < mls->config_logs->nelts; ++i) {
- config_log_state *cls = &clsarray[i];
-
- cls = open_config_log(s, p, cls, mls->default_format);
- }
- }
- else if (mls->server_config_logs) {
- clsarray = (config_log_state *)mls->server_config_logs->elts;
- for (i = 0; i < mls->server_config_logs->nelts; ++i) {
- config_log_state *cls = &clsarray[i];
-
- cls = open_config_log(s, p, cls, mls->default_format);
- }
- }
-
- return NULL;
-}
-
-void init_config_log (server_rec *s, pool *p)
-{
- /* First, do "physical" server, which gets default log fd and format
- * for the virtual servers, if they don't override...
- */
-
- open_multi_logs (s, p);
-
- /* Then, virtual servers */
-
- for (s = s->next; s; s = s->next) open_multi_logs (s, p);
-}
-
-module config_log_module = {
- STANDARD_MODULE_STUFF,
- init_config_log, /* initializer */
- NULL, /* create per-dir config */
- NULL, /* merge per-dir config */
- make_config_log_state, /* server config */
- merge_config_log_state, /* merge server config */
- config_log_cmds, /* command table */
- NULL, /* handlers */
- NULL, /* filename translation */
- NULL, /* check_user_id */
- NULL, /* check auth */
- NULL, /* check access */
- NULL, /* type_checker */
- NULL, /* fixups */
- multi_log_transaction, /* logger */
- NULL /* header parser */
-};
diff --git a/usr.sbin/httpd/src/mod_log_referer.c b/usr.sbin/httpd/src/mod_log_referer.c
deleted file mode 100644
index e494298944c..00000000000
--- a/usr.sbin/httpd/src/mod_log_referer.c
+++ /dev/null
@@ -1,235 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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/>.
- *
- */
-
-
-#include "httpd.h"
-#include "http_config.h"
-
-module referer_log_module;
-
-static int xfer_flags = ( O_WRONLY | O_APPEND | O_CREAT );
-
-#ifdef __EMX__
-/* OS/2 lacks support for users and groups */
-static mode_t xfer_mode = ( S_IREAD | S_IWRITE );
-#else
-static mode_t xfer_mode = ( S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH );
-#endif
-
-typedef struct {
- char *fname;
- int referer_fd;
- array_header *referer_ignore_list;
-} referer_log_state;
-
-void *make_referer_log_state (pool *p, server_rec *s)
-{
- referer_log_state *cls =
- (referer_log_state *)palloc (p, sizeof (referer_log_state));
-
- cls->fname = "";
- cls->referer_fd = -1;
- cls->referer_ignore_list = make_array(p, 1, sizeof(char *));
- return (void *)cls;
-}
-
-const char *set_referer_log (cmd_parms *parms, void *dummy, char *arg)
-{
- referer_log_state *cls = get_module_config (parms->server->module_config,
- &referer_log_module);
-
- cls->fname = arg;
- return NULL;
-}
-
-const char *add_referer_ignore (cmd_parms *parms, void *dummy, char *arg)
-{
- char **addme;
- referer_log_state *cls = get_module_config (parms->server->module_config,
- &referer_log_module);
-
- addme = push_array(cls->referer_ignore_list);
- *addme = pstrdup(cls->referer_ignore_list->pool, arg);
- return NULL;
-}
-
-command_rec referer_log_cmds[] = {
-{ "RefererLog", set_referer_log, NULL, RSRC_CONF, TAKE1,
- "the filename of the referer log" },
-{ "RefererIgnore", add_referer_ignore, NULL, RSRC_CONF, ITERATE,
- "referer hostnames to ignore" },
-{ NULL }
-};
-
-void referer_log_child (void *cmd)
-{
- /* Child process code for 'RefererLog "|..."';
- * may want a common framework for this, since I expect it will
- * be common for other foo-loggers to want this sort of thing...
- */
-
- cleanup_for_exec();
- signal (SIGHUP, SIG_IGN);
-#ifdef __EMX__
- /* For OS/2 we need to use a '/' */
- execl (SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL);
-#else
- execl (SHELL_PATH, SHELL_PATH, "-c", (char *)cmd, NULL);
-#endif
- perror ("execl");
- fprintf (stderr, "Exec of shell for logging failed!!!\n");
- exit (1);
-}
-
-void open_referer_log (server_rec *s, pool *p)
-{
- referer_log_state *cls = get_module_config (s->module_config,
- &referer_log_module);
-
- char *fname = server_root_relative (p, cls->fname);
-
- if (cls->referer_fd > 0) return; /* virtual log shared w/main server */
-
- if (*cls->fname == '|') {
- FILE *dummy;
-
- if (!spawn_child (p, referer_log_child, (void *)(cls->fname+1),
- kill_after_timeout, &dummy, NULL)) {
- perror ("spawn_child");
- fprintf (stderr, "Couldn't fork child for RefererLog process\n");
- exit (1);
- }
-
- cls->referer_fd = fileno (dummy);
- }
- else if(*cls->fname != '\0') {
- if((cls->referer_fd = popenf(p, fname, xfer_flags, xfer_mode)) < 0) {
- perror("open");
- fprintf(stderr,"httpd: could not open referer log file %s.\n", fname);
- exit(1);
- }
- }
-}
-
-void init_referer_log (server_rec *s, pool *p)
-{
- for (; s; s = s->next) open_referer_log (s, p);
-}
-
-int referer_log_transaction(request_rec *orig)
-{
- char **ptrptr, **ptrptr2;
- referer_log_state *cls = get_module_config (orig->server->module_config,
- &referer_log_module);
-
- char *str;
- char *referer;
- request_rec *r;
-
- if(cls->referer_fd <0)
- return OK;
-
- for (r = orig; r->next; r = r->next)
- continue;
- if (*cls->fname == '\0') /* Don't log referer */
- return DECLINED;
-
- referer = table_get(orig->headers_in, "Referer");
- if(referer != NULL)
- {
-
-
- /* The following is an upsetting mess of pointers, I'm sorry
- Anyone with the motiviation and/or the time should feel free
- to make this cleaner... */
-
- ptrptr2 = (char **) (cls->referer_ignore_list->elts +
- (cls->referer_ignore_list->nelts *
- cls->referer_ignore_list->elt_size));
-
- /* Go through each element of the ignore list and compare it to the
- referer_host. If we get a match, return without logging */
-
- for(ptrptr = (char **) cls->referer_ignore_list->elts;
- ptrptr < ptrptr2;
- ptrptr = (char **)((char *)ptrptr + cls->referer_ignore_list->elt_size))
- {
- if(strstr(referer, *ptrptr))
- return OK;
- }
-
-
- str = pstrcat(orig->pool, referer, " -> ", r->uri, "\n", NULL);
- write(cls->referer_fd, str, strlen(str));
- }
-
- return OK;
-}
-
-module referer_log_module = {
- STANDARD_MODULE_STUFF,
- init_referer_log, /* initializer */
- NULL, /* create per-dir config */
- NULL, /* merge per-dir config */
- make_referer_log_state, /* server config */
- NULL, /* merge server config */
- referer_log_cmds, /* command table */
- NULL, /* handlers */
- NULL, /* filename translation */
- NULL, /* check_user_id */
- NULL, /* check auth */
- NULL, /* check access */
- NULL, /* type_checker */
- NULL, /* fixups */
- referer_log_transaction, /* logger */
- NULL /* header parser */
-};
diff --git a/usr.sbin/httpd/src/mod_mime.c b/usr.sbin/httpd/src/mod_mime.c
deleted file mode 100644
index dc84975e1ae..00000000000
--- a/usr.sbin/httpd/src/mod_mime.c
+++ /dev/null
@@ -1,324 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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_mime.c: Sends/gets MIME headers for requests
- *
- * Rob McCool
- *
- */
-
-#define MIME_PRIVATE
-
-#include "httpd.h"
-#include "http_config.h"
-
-typedef struct {
- table *forced_types; /* Additional AddTyped stuff */
- table *encoding_types; /* Added with AddEncoding... */
- table *language_types; /* Added with AddLanguage... */
- table *handlers; /* Added with AddHandler... */
-
- char *type; /* Type forced with ForceType */
- char *handler; /* Handler forced with SetHandler */
-} mime_dir_config;
-
-module mime_module;
-
-void *create_mime_dir_config (pool *p, char *dummy)
-{
- mime_dir_config *new =
- (mime_dir_config *) palloc (p, sizeof(mime_dir_config));
-
- new->forced_types = make_table (p, 4);
- new->encoding_types = make_table (p, 4);
- new->language_types = make_table (p, 4);
- new->handlers = make_table (p, 4);
-
- new->type = NULL;
- new->handler = NULL;
-
- return new;
-}
-
-void *merge_mime_dir_configs (pool *p, void *basev, void *addv)
-{
- mime_dir_config *base = (mime_dir_config *)basev;
- mime_dir_config *add = (mime_dir_config *)addv;
- mime_dir_config *new =
- (mime_dir_config *)palloc (p, sizeof(mime_dir_config));
-
- new->forced_types = overlay_tables (p, add->forced_types,
- base->forced_types);
- new->encoding_types = overlay_tables (p, add->encoding_types,
- base->encoding_types);
- new->language_types = overlay_tables (p, add->language_types,
- base->language_types);
- new->handlers = overlay_tables (p, add->handlers,
- base->handlers);
-
- new->type = add->type ? add->type : base->type;
- new->handler = add->handler ? add->handler : base->handler;
-
- return new;
-}
-
-const char *add_type(cmd_parms *cmd, mime_dir_config *m, char *ct, char *ext)
-{
- if (*ext == '.') ++ext;
- table_set (m->forced_types, ext, ct);
- return NULL;
-}
-
-const char *add_encoding(cmd_parms *cmd, mime_dir_config *m, char *enc,
- char *ext)
-{
- if (*ext == '.') ++ext;
- table_set (m->encoding_types, ext, enc);
- return NULL;
-}
-
-const char *add_language(cmd_parms *cmd, mime_dir_config *m, char *lang,
- char *ext)
-{
- if (*ext == '.') ++ext;
- table_set (m->language_types, ext, lang);
- return NULL;
-}
-
-const char *add_handler(cmd_parms *cmd, mime_dir_config *m, char *hdlr,
- char *ext)
-{
- if (*ext == '.') ++ext;
- table_set (m->handlers, ext, hdlr);
- return NULL;
-}
-
-/* The sole bit of server configuration that the MIME module has is
- * the name of its config file, so...
- */
-
-const char *set_types_config (cmd_parms *cmd, void *dummy, char *arg)
-{
- set_module_config (cmd->server->module_config, &mime_module,
- pstrdup (cmd->pool, arg));
- return NULL;
-}
-
-command_rec mime_cmds[] = {
-{ "AddType", add_type, NULL, OR_FILEINFO, ITERATE2,
- "a mime type followed by one or more file extensions" },
-{ "AddEncoding", add_encoding, NULL, OR_FILEINFO, ITERATE2,
- "an encoding (e.g., gzip), followed by one or more file extensions" },
-{ "AddLanguage", add_language, NULL, OR_FILEINFO, ITERATE2,
- "a language (e.g., fr), followed by one or more file extensions" },
-{ "AddHandler", add_handler, NULL, OR_FILEINFO, ITERATE2,
- "a handler name followed by one or more file extensions" },
-{ "ForceType", set_string_slot, (void*)XtOffsetOf(mime_dir_config, type),
- OR_FILEINFO, TAKE1, "a media type" },
-{ "SetHandler", set_string_slot, (void*)XtOffsetOf(mime_dir_config, handler),
- OR_FILEINFO, TAKE1, "a handler name" },
-{ "TypesConfig", set_types_config, NULL, RSRC_CONF, TAKE1,
- "the MIME types config file" },
-{ NULL }
-};
-
-/* Hash table --- only one of these per daemon; virtual hosts can
- * get private versions through AddType...
- */
-
-#define MIME_HASHSIZE 27
-#define hash(i) (isalpha(i) ? (tolower(i)) - 'a' : 26)
-
-static table *hash_buckets[MIME_HASHSIZE];
-
-void init_mime (server_rec *s, pool *p)
-{
- FILE *f;
- char l[MAX_STRING_LEN];
- int x;
- char *types_confname = get_module_config (s->module_config, &mime_module);
-
- if (!types_confname) types_confname = TYPES_CONFIG_FILE;
-
- types_confname = server_root_relative (p, types_confname);
-
- if(!(f = fopen(types_confname,"r"))) {
- perror("fopen");
- fprintf(stderr,"httpd: could not open mime types file %s\n",
- types_confname);
- exit(1);
- }
-
- for(x=0;x<27;x++)
- hash_buckets[x] = make_table (p, 10);
-
- while(!(cfg_getline(l,MAX_STRING_LEN,f))) {
- const char *ll = l, *ct;
-
- if(l[0] == '#') continue;
- ct = getword_conf (p, &ll);
-
- while(ll[0]) {
- char *ext = getword_conf (p, &ll);
- str_tolower (ext); /* ??? */
- table_set (hash_buckets[hash(ext[0])], ext, ct);
- }
- }
- fclose(f);
-}
-
-int find_ct(request_rec *r)
-{
- const char *fn = strrchr(r->filename, '/');
- mime_dir_config *conf =
- (mime_dir_config *)get_module_config(r->per_dir_config, &mime_module);
- char *ext, *type, *orighandler = r->handler;
-
- if (S_ISDIR(r->finfo.st_mode)) {
- r->content_type = DIR_MAGIC_TYPE;
- return OK;
- }
-
- /* TM -- FIXME
- *
- * if r->filename does not contain a '/', the following passes a null
- * pointer to getword, causing a SEGV ..
- */
-
- if(fn == NULL) fn = r->filename;
-
- /* Parse filename extensions, which can be in any order */
- while ((ext = getword(r->pool, &fn, '.')) && *ext) {
- int found = 0;
-
- /* Check for Content-Type */
- if ((type = table_get (conf->forced_types, ext))
- || (type = table_get (hash_buckets[hash(*ext)], ext))) {
- r->content_type = type;
- found = 1;
- }
-
- /* Check for Content-Language */
- if ((type = table_get (conf->language_types, ext))) {
- char **new;
-
- r->content_language = type; /* back compat. only */
- if (!r->content_languages)
- r->content_languages = make_array (r->pool, 2, sizeof(char*));
- new = (char **)push_array (r->content_languages);
- *new = type;
- found = 1;
- }
-
- /* Check for Content-Encoding */
- if ((type = table_get (conf->encoding_types, ext))) {
- if (!r->content_encoding)
- r->content_encoding = type;
- else
- r->content_encoding = pstrcat(r->pool, r->content_encoding,
- ", ", type, NULL);
- found = 1;
- }
-
- /* Check for a special handler, but not for proxy request */
- if ((type = table_get (conf->handlers, ext)) && !r->proxyreq) {
- r->handler = type;
- found = 1;
- }
-
- /* This is to deal with cases such as foo.gif.bak, which we want
- * to not have a type. So if we find an unknown extension, we
- * zap the type/language/encoding and reset the handler
- */
-
- if (!found) {
- r->content_type = NULL;
- r->content_language = NULL;
- r->content_languages = NULL;
- r->content_encoding = NULL;
- r->handler = orighandler;
- }
-
- }
-
- /* Check for overrides with ForceType/SetHandler */
-
- if (conf->type && strcmp(conf->type, "none"))
- r->content_type = pstrdup(r->pool, conf->type);
- if (conf->handler && strcmp(conf->handler, "none"))
- r->handler = pstrdup(r->pool, conf->handler);
-
- if (!r->content_type) return DECLINED;
-
- return OK;
-}
-
-
-module mime_module = {
- STANDARD_MODULE_STUFF,
- init_mime, /* initializer */
- create_mime_dir_config,
- merge_mime_dir_configs,
- NULL, /* server config */
- NULL, /* merge server config */
- mime_cmds,
- NULL, /* handlers */
- NULL, /* filename translation */
- NULL, /* check_user_id */
- NULL, /* check auth */
- NULL, /* check access */
- find_ct, /* type_checker */
- NULL, /* fixups */
- NULL, /* logger */
- NULL /* header parser */
-};
diff --git a/usr.sbin/httpd/src/mod_negotiation.c b/usr.sbin/httpd/src/mod_negotiation.c
deleted file mode 100644
index 84e15f0ec4e..00000000000
--- a/usr.sbin/httpd/src/mod_negotiation.c
+++ /dev/null
@@ -1,2052 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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_negotiation.c: keeps track of MIME types the client is willing to
- * accept, and contains code to handle type arbitration.
- *
- * rst
- */
-
-#include "httpd.h"
-#include "http_config.h"
-#include "http_request.h"
-#include "http_core.h"
-#include "http_log.h"
-#include "util_script.h"
-
-/* define TCN_02 to allow for Holtman I-D transparent negotiation.
- * This file currently implements the draft-02, except for
- * anything to do with features and cache-control (max-age etc)
- *
- * Since the draft is just that, and we don't yet implement
- * everything, regard the transparent negotiation stuff as experimental.
- */
-/*#define TCN_02*/
-
-/* Commands --- configuring document caching on a per (virtual?)
- * server basis...
- */
-
-typedef struct {
- array_header *language_priority;
-} neg_dir_config;
-
-module negotiation_module;
-
-char *merge_string_array (pool *p, array_header *arr, char *sep)
-{
- int i;
- char *t = "";
-
- for (i = 0; i < arr->nelts; i++) {
- t = pstrcat(p, t, i ? sep : "", ((char**)arr->elts)[i], NULL);
- }
- return t;
-}
-
-void *create_neg_dir_config (pool *p, char *dummy)
-{
- neg_dir_config *new =
- (neg_dir_config *) palloc (p, sizeof (neg_dir_config));
-
- new->language_priority = make_array (p, 4, sizeof (char *));
- return new;
-}
-
-void *merge_neg_dir_configs (pool *p, void *basev, void *addv)
-{
- neg_dir_config *base = (neg_dir_config *)basev;
- neg_dir_config *add = (neg_dir_config *)addv;
- neg_dir_config *new =
- (neg_dir_config *) palloc (p, sizeof (neg_dir_config));
-
- /* give priority to the config in the subdirectory */
- new->language_priority = append_arrays (p, add->language_priority,
- base->language_priority);
- return new;
-}
-
-const char *set_language_priority (cmd_parms *cmd, void *n, char *lang)
-{
- array_header *arr = ((neg_dir_config *) n)->language_priority;
- char **langp = (char **) push_array (arr);
-
- *langp = pstrdup (arr->pool, lang);
- return NULL;
-}
-
-const char *cache_negotiated_docs (cmd_parms *cmd, void *dummy, char *dummy2)
-{
- void *server_conf = cmd->server->module_config;
-
- set_module_config (server_conf, &negotiation_module, "Cache");
- return NULL;
-}
-
-int do_cache_negotiated_docs (server_rec *s)
-{
- return (get_module_config (s->module_config, &negotiation_module) != NULL);
-}
-
-command_rec negotiation_cmds[] = {
-{ "CacheNegotiatedDocs", cache_negotiated_docs, NULL, RSRC_CONF, RAW_ARGS,
- NULL },
-{ "LanguagePriority", set_language_priority, NULL, OR_FILEINFO, ITERATE,
- NULL },
-{ NULL }
-};
-
-/* Record of available info on a media type specified by the client
- * (we also use 'em for encodings and languages)
- */
-
-typedef struct accept_rec {
- char *type_name;
- float quality;
- float max_bytes;
- float level;
- char *charset; /* for content-type only */
-} accept_rec;
-
-/* Record of available info on a particular variant
- *
- * Note that a few of these fields are updated by the actual negotiation
- * code. These are:
- *
- * level_matched --- initialized to zero. Set to the value of level
- * if the client actually accepts this media type at that
- * level (and *not* if it got in on a wildcard). See level_cmp
- * below.
- */
-
-typedef struct var_rec {
- request_rec *sub_req; /* May be NULL (is, for map files) */
- char *type_name;
- char *file_name;
- char *content_encoding;
- array_header *content_languages; /* list of languages for this variant */
- char *content_charset;
- char *description;
-
- /* The next five items give the quality values for the dimensions
- * of negotiation for this variant. They are obtained from the
- * appropriate header lines, except for accept_type_quality, which
- * is obtained from the variant itself (the 'qs' parameter value
- * from the variant's mime-type). Apart from type_quality,
- * these values are set when we find the quality for each variant
- * (see best_match()). type_quality is set from the 'qs' parameter
- * of the variant description or mime type: see set_mime_fields().
- */
- float lang_quality; /* quality of this variant's language */
- int encoding_quality; /* ditto encoding (1 or 0 only) */
- float charset_quality; /* ditto charset */
- float accept_type_quality; /* ditto media type */
- float type_quality; /* quality of source for this type */
-
- /* Now some special values */
- float level; /* Auxiliary to content-type... */
- float bytes; /* content length, if known */
- int lang_index; /* pre HTTP/1.1 language priority stuff */
- int is_pseudo_html; /* text/html, *or* the INCLUDES_MAGIC_TYPEs */
-
- /* Above are all written-once properties of the variant. The
- * three fields below are changed during negotiation:
- */
-
- float level_matched;
- int mime_stars;
- int definite;
-} var_rec;
-
-/* Something to carry around the state of negotiation (and to keep
- * all of this thread-safe)...
- */
-
-typedef struct {
- pool *pool;
- request_rec *r;
- char *dir_name;
- int accept_q; /* 1 if an Accept item has a q= param */
- float default_lang_quality; /* fiddle lang q for variants with no lang */
-
-
- array_header *accepts; /* accept_recs */
- int have_accept_header; /* 1 if Accept-Header present */
- array_header *accept_encodings; /* accept_recs */
- array_header *accept_charsets; /* accept_recs */
- array_header *accept_langs; /* accept_recs */
- array_header *avail_vars; /* available variants */
-
- int ua_can_negotiate; /* 1 if ua can do transparent negotiate */
- int use_transparent_neg; /* 1 if we are using transparent neg */
- int short_accept_headers; /* 1 if ua does trans neg & sent short accpt */
-} negotiation_state;
-
-/* A few functions to manipulate var_recs.
- * Cleaning out the fields...
- */
-
-void clean_var_rec (var_rec *mime_info)
-{
- mime_info->sub_req = NULL;
- mime_info->type_name = "";
- mime_info->file_name = "";
- mime_info->content_encoding = "";
- mime_info->content_languages = NULL;
- mime_info->content_charset = "";
- mime_info->description = "";
-
- mime_info->is_pseudo_html = 0;
- mime_info->level = 0.0;
- mime_info->level_matched = 0.0;
- mime_info->bytes = 0;
- mime_info->lang_index = -1;
- mime_info->mime_stars = 0;
- mime_info->definite = 1;
-
- mime_info->charset_quality = 1.0;
- mime_info->type_quality = 0.0;
- mime_info->encoding_quality = 1;
- mime_info->lang_quality = 1.0;
- mime_info->accept_type_quality = 1.0;
-}
-
-/* Initializing the relevant fields of a variant record from the
- * accept_info read out of its content-type, one way or another.
- */
-
-void set_mime_fields (var_rec *var, accept_rec *mime_info)
-{
- var->type_name = mime_info->type_name;
- var->type_quality = mime_info->quality;
- var->level = mime_info->level;
- var->content_charset = mime_info->charset;
-
- var->is_pseudo_html =
- (!strcmp (var->type_name, "text/html")
- || !strcmp (var->type_name, INCLUDES_MAGIC_TYPE)
- || !strcmp (var->type_name, INCLUDES_MAGIC_TYPE3));
-}
-
-/*****************************************************************
- *
- * Parsing (lists of) media types and their parameters, as seen in
- * HTTPD header lines and elsewhere.
- */
-
-/*
- * Get a single mime type entry --- one media type and parameters;
- * enter the values we recognize into the argument accept_rec
- */
-
-char *get_entry (pool *p, accept_rec *result, char *accept_line)
-{
- result->quality = 1.0;
- result->max_bytes = 0.0;
- result->level = 0.0;
- result->charset = "";
-
- /* Note that this handles what I gather is the "old format",
- *
- * Accept: text/html text/plain moo/zot
- *
- * without any compatibility kludges --- if the token after the
- * MIME type begins with a semicolon, we know we're looking at parms,
- * otherwise, we know we aren't. (So why all the pissing and moaning
- * in the CERN server code? I must be missing something).
- */
-
- result->type_name = get_token (p, &accept_line, 0);
- str_tolower (result->type_name); /* You want case-insensitive,
- * you'll *get* case-insensitive.
- */
-
-
- /* KLUDGE!!! Default HTML to level 2.0 unless the browser
- * *explicitly* says something else.
- */
-
- if (!strcmp (result->type_name, "text/html")
- && result->level == 0.0)
- result->level = 2.0;
- else if (!strcmp (result->type_name, INCLUDES_MAGIC_TYPE))
- result->level = 2.0;
- else if (!strcmp (result->type_name, INCLUDES_MAGIC_TYPE3))
- result->level = 3.0;
-
- while (*accept_line == ';') {
- /* Parameters ... */
-
- char *parm;
- char *cp;
- char *end;
-
- ++accept_line;
- parm = get_token (p, &accept_line, 1);
-
- /* Look for 'var = value' --- and make sure the var is in lcase. */
-
- for (cp = parm; *cp && !isspace(*cp) && *cp != '='; ++cp)
- *cp = tolower(*cp);
-
- if (!*cp) continue; /* No '='; just ignore it. */
-
- *cp++ = '\0'; /* Delimit var */
- while (*cp && (isspace(*cp) || *cp == '='))
- ++cp;
-
- if (*cp == '"') {
- ++cp;
- for (end = cp; *end &&
- *end != '\n' && *end != '\r' && *end != '\"';
- end++)
- ;
- }
- else {
- for (end = cp; *end && !isspace(*end); end++)
- ;
- }
- if (*end)
- *end = '\0'; /* strip ending quote or return */
- str_tolower(cp);
-
- if (parm[0] == 'q'
- && (parm[1] == '\0' || (parm[1] == 's' && parm[2] == '\0')))
- result->quality = atof(cp);
- else if (parm[0] == 'm' && parm[1] == 'x' &&
- parm[2] == 'b' && parm[3] == '\0')
- result->max_bytes = atof(cp);
- else if (parm[0] == 'l' && !strcmp (&parm[1], "evel"))
- result->level = atof(cp);
- else if (!strcmp(parm, "charset"))
- result->charset = cp;
- }
-
- if (*accept_line == ',') ++accept_line;
-
- return accept_line;
-}
-
-/*****************************************************************
- *
- * Dealing with header lines ...
- *
- * Accept, Accept-Charset, Accept-Language and Accept-Encoding
- * are handled by do_header_line() - they all have the same
- * basic structure of a list of items of the format
- * name; q=N; charset=TEXT
- *
- * where q is only valid in Accept, Accept-Charset and Accept-Languages,
- * and charset is only valid in Accept.
- */
-
-array_header *do_header_line (pool *p, char *accept_line)
-{
- array_header *accept_recs = make_array (p, 40, sizeof (accept_rec));
-
- if (!accept_line) return accept_recs;
-
- while (*accept_line) {
- accept_rec *new = (accept_rec *)push_array (accept_recs);
- accept_line = get_entry (p, new, accept_line);
- }
-
- return accept_recs;
-}
-
-/* Given the text of the Content-Languages: line from the var map file,
- * return an array containing the languages of this variant
- */
-
-array_header *do_languages_line (pool *p, char **lang_line)
-{
- array_header *lang_recs = make_array (p, 2, sizeof (char *));
-
- if (!lang_line) return lang_recs;
-
- while (**lang_line) {
- char **new = (char **)push_array (lang_recs);
- *new = get_token (p, lang_line, 0);
- str_tolower (*new);
- if (**lang_line == ',' || **lang_line == ';')
- ++(*lang_line);
- }
-
- return lang_recs;
-}
-
-/*****************************************************************
- *
- * Handling header lines from clients...
- */
-
-negotiation_state *parse_accept_headers (request_rec *r)
-{
- negotiation_state *new =
- (negotiation_state *)pcalloc (r->pool, sizeof (negotiation_state));
- accept_rec *elts;
- table *hdrs = r->headers_in;
- int i;
- char *hdr;
-
- new->pool = r->pool;
- new->r = r;
- new->dir_name = make_dirstr(r->pool, r->filename, count_dirs(r->filename));
-
- new->accepts = do_header_line (r->pool, table_get (hdrs, "Accept"));
-
- hdr = table_get (hdrs, "Accept-encoding");
- if (hdr)
- new->have_accept_header = 1;
- new->accept_encodings = do_header_line (r->pool, hdr);
-
- new->accept_langs =
- do_header_line (r->pool, table_get (hdrs, "Accept-language"));
- new->accept_charsets =
- do_header_line (r->pool, table_get (hdrs, "Accept-charset"));
- new->avail_vars = make_array (r->pool, 40, sizeof (var_rec));
-
-#ifdef TCN_02
- if (table_get(r->headers_in, "Negotiate")) {
- /* Negotiate: header tells us UA does transparent negotiation
- * We have to decide whether we want to ... for now, yes,
- * we do */
-
- new->ua_can_negotiate = 1;
- if (r->method_number == M_GET)
- new->use_transparent_neg = 1; /* should be configurable */
-
- /* Check for 'Short Accept', ie either no Accept: header,
- * or just "Accept: * / *" */
- if (new->accepts->nelts == 0 ||
- (new->accepts->nelts == 1 &&
- (!strcmp(((accept_rec *)new->accepts->elts)[0].type_name,
- "*/*")))) {
- /* Using short accept header */
- new->short_accept_headers = 1;
- }
- }
-#endif
-
- if (!new->use_transparent_neg) {
- /* Now we check for q-values. If they're all 1.0, we assume the
- * client is "broken", and we are allowed to fiddle with the
- * values later. Otherwise, we leave them alone.
- */
-
- elts = (accept_rec *)new->accepts->elts;
-
- for (i = 0; i < new->accepts->nelts; ++i)
- if (elts[i].quality < 1.0) new->accept_q = 1;
- }
- else new->accept_q = 1;
-
- return new;
-}
-
-/* Sometimes clients will give us no Accept info at all; this routine sets
- * up the standard default for that case, and also arranges for us to be
- * willing to run a CGI script if we find one. (In fact, we set up to
- * dramatically prefer CGI scripts in cases where that's appropriate,
- * e.g., POST).
- */
-
-void maybe_add_default_encodings(negotiation_state *neg, int prefer_scripts)
-{
- accept_rec *new_accept = (accept_rec *)push_array (neg->accepts);
-
- new_accept->type_name = CGI_MAGIC_TYPE;
- new_accept->quality = prefer_scripts ? 1e-20 : 1e20;
- new_accept->level = 0.0;
- new_accept->max_bytes = 0.0;
-
- if (neg->accepts->nelts > 1) return;
-
- new_accept = (accept_rec *)push_array (neg->accepts);
-
- new_accept->type_name = "*/*";
- new_accept->quality = 1.0;
- new_accept->level = 0.0;
- new_accept->max_bytes = 0.0;
-}
-
-/*****************************************************************
- *
- * Parsing type-map files, in Roy's meta/http format augmented with
- * #-comments.
- */
-
-/* Reading RFC822-style header lines, ignoring #-comments and
- * handling continuations.
- */
-
-enum header_state { header_eof, header_seen, header_sep };
-
-enum header_state get_header_line (char *buffer, int len, FILE *map)
-{
- char *buf_end = buffer + len;
- char *cp;
- int c;
-
- /* Get a noncommented line */
-
- do {
- if (fgets(buffer, MAX_STRING_LEN, map) == NULL)
- return header_eof;
- } while (buffer[0] == '#');
-
- /* If blank, just return it --- this ends information on this variant */
-
- for (cp = buffer; *cp && isspace (*cp); ++cp)
- continue;
-
- if (*cp == '\0') return header_sep;
-
- /* If non-blank, go looking for header lines, but note that we still
- * have to treat comments specially...
- */
-
- cp += strlen(cp);
-
- while ((c = getc(map)) != EOF)
- {
- if (c == '#') {
- /* Comment line */
- while ((c = getc(map)) != EOF && c != '\n')
- continue;
- } else if (isspace(c)) {
- /* Leading whitespace. POSSIBLE continuation line
- * Also, possibly blank --- if so, we ungetc() the final newline
- * so that we will pick up the blank line the next time 'round.
- */
-
- while (c != EOF && c != '\n' && isspace(c))
- c = getc(map);
-
- ungetc (c, map);
-
- if (c == '\n') return header_seen; /* Blank line */
-
- /* Continuation */
-
- while (cp < buf_end - 2 && (c = getc(map)) != EOF && c != '\n')
- *cp++ = c;
-
- *cp++ = '\n';
- *cp = '\0';
- } else {
-
- /* Line beginning with something other than whitespace */
-
- ungetc (c, map);
- return header_seen;
- }
- }
-
- return header_seen;
-}
-
-/* Stripping out RFC822 comments */
-
-void strip_paren_comments (char *hdr)
-{
- /* Hmmm... is this correct? In Roy's latest draft, (comments) can nest! */
-
- while (*hdr) {
- if (*hdr == '"') {
- while (*++hdr && *hdr != '"')
- continue;
- ++hdr;
- }
- else if (*hdr == '(') {
- while (*hdr && *hdr != ')') *hdr++ = ' ';
-
- if (*hdr) *hdr++ = ' ';
- }
- else ++hdr;
- }
-}
-
-/* Getting to a header body from the header */
-
-char *lcase_header_name_return_body (char *header, request_rec *r)
-{
- char *cp = header;
-
- for ( ; *cp && *cp != ':' ; ++cp) {
- *cp = tolower(*cp);
- }
-
- if (!*cp) {
- log_reason ("Syntax error in type map --- no ':'", r->filename, r);
- return NULL;
- }
-
- do ++cp; while (*cp && isspace (*cp));
-
- if (!*cp) {
- log_reason ("Syntax error in type map --- no header body",
- r->filename, r);
- return NULL;
- }
-
- return cp;
-}
-
-static int read_type_map (negotiation_state *neg, request_rec *rr)
-{
- request_rec *r = neg->r;
- FILE *map;
- char buffer[MAX_STRING_LEN];
- enum header_state hstate;
- struct var_rec mime_info;
-
- if (rr->status != HTTP_OK) {
- return rr->status;
- }
- map = pfopen (neg->pool, rr->filename, "r");
- if (map == NULL) {
- log_reason("cannot access type map file", rr->filename, r);
- return FORBIDDEN;
- }
-
- clean_var_rec (&mime_info);
-
- do {
- hstate = get_header_line (buffer, MAX_STRING_LEN, map);
-
- if (hstate == header_seen) {
- char *body = lcase_header_name_return_body (buffer, neg->r);
-
- if (body == NULL) return SERVER_ERROR;
-
- strip_paren_comments (body);
-
- if (!strncmp (buffer, "uri:", 4)) {
- mime_info.file_name = get_token (neg->pool, &body, 0);
- }
- else if (!strncmp (buffer, "content-type:", 13)) {
- struct accept_rec accept_info;
-
- get_entry (neg->pool, &accept_info, body);
- set_mime_fields (&mime_info, &accept_info);
- }
- else if (!strncmp (buffer, "content-length:", 15)) {
- mime_info.bytes = atoi(body);
- }
- else if (!strncmp (buffer, "content-language:", 17)) {
- mime_info.content_languages =
- do_languages_line(neg->pool, &body);
- }
- else if (!strncmp (buffer, "content-encoding:", 17)) {
- mime_info.content_encoding = get_token (neg->pool, &body, 0);
- str_tolower (mime_info.content_encoding);
- }
- else if (!strncmp (buffer, "description:", 12)) {
- mime_info.description = get_token (neg->pool, &body, 0);
- }
- } else {
- if (mime_info.type_quality > 0 && *mime_info.file_name)
- {
- void *new_var = push_array (neg->avail_vars);
- memcpy (new_var, (void *)&mime_info, sizeof (var_rec));
- }
-
-
- clean_var_rec(&mime_info);
- }
- } while (hstate != header_eof);
-
- pfclose (neg->pool, map);
- return OK;
-}
-
-/*****************************************************************
- *
- * Same, except we use a filtered directory listing as the map...
- */
-
-int read_types_multi (negotiation_state *neg)
-{
- request_rec *r = neg->r;
-
- char *filp;
- int prefix_len;
- DIR *dirp;
- struct DIR_TYPE *dir_entry;
- struct var_rec mime_info;
- struct accept_rec accept_info;
- void *new_var;
-
- clean_var_rec (&mime_info);
-
- if (!(filp = strrchr (r->filename, '/'))) return DECLINED; /* Weird... */
-
- if (strncmp(r->filename, "proxy:", 6) == 0)
- return DECLINED;
-
- ++filp;
- prefix_len = strlen (filp);
-
- dirp = opendir (neg->dir_name); /* Not pool protected; sigh... */
-
- if (dirp == NULL) {
- log_reason("cannot read directory for multi", neg->dir_name, r);
- return FORBIDDEN;
- }
-
- while ((dir_entry = readdir (dirp))) {
-
- request_rec *sub_req;
-
- /* Do we have a match? */
-
- if (strncmp (dir_entry->d_name, filp, prefix_len)) continue;
- if (dir_entry->d_name[prefix_len] != '.') continue;
-
- /* Yep. See if it's something which we have access to, and
- * which has a known type and encoding (as opposed to something
- * which we'll be slapping default_type on later).
- */
-
- sub_req = sub_req_lookup_file (dir_entry->d_name, r);
-
- /* If it has a handler, we'll pretend it's a CGI script,
- * since that's a good indication of the sort of thing it
- * might be doing.
- */
- if (sub_req->handler && !sub_req->content_type)
- sub_req->content_type = CGI_MAGIC_TYPE;
-
- if (sub_req->status != HTTP_OK || !sub_req->content_type) {
- destroy_sub_req(sub_req);
- continue;
- }
-
- /* If it's a map file, we use that instead of the map
- * we're building...
- */
-
- if (((sub_req->content_type) &&
- !strcmp (sub_req->content_type, MAP_FILE_MAGIC_TYPE)) ||
- ((sub_req->handler) &&
- !strcmp (sub_req->handler, "type-map"))) {
- closedir(dirp);
-
- neg->avail_vars->nelts = 0;
- return read_type_map (neg, sub_req);
- }
-
- /* Have reasonable variant --- gather notes.
- */
-
- mime_info.sub_req = sub_req;
- mime_info.file_name = pstrdup(neg->pool, dir_entry->d_name);
- if (sub_req->content_encoding) {
- mime_info.content_encoding = sub_req->content_encoding;
- str_tolower(mime_info.content_encoding);
- }
- if (sub_req->content_languages) {
- int i;
- mime_info.content_languages = sub_req->content_languages;
- if (mime_info.content_languages)
- for (i = 0; i < mime_info.content_languages->nelts; ++i)
- str_tolower(((char**)
- (mime_info.content_languages->elts))[i]);
- }
-
- get_entry (neg->pool, &accept_info, sub_req->content_type);
- set_mime_fields (&mime_info, &accept_info);
-
- new_var = push_array (neg->avail_vars);
- memcpy (new_var, (void *)&mime_info, sizeof (var_rec));
-
- clean_var_rec(&mime_info);
- }
-
- closedir(dirp);
- return OK;
-}
-
-
-/*****************************************************************
- * And now for the code you've been waiting for... actually
- * finding a match to the client's requirements.
- */
-
-/* Matching MIME types ... the star/star and foo/star commenting conventions
- * are implemented here. (You know what I mean by star/star, but just
- * try mentioning those three characters in a C comment). Using strcmp()
- * is legit, because everything has already been smashed to lowercase.
- *
- * Note also that if we get an exact match on the media type, we update
- * level_matched for use in level_cmp below...
- *
- * We also give a value for mime_stars, which is used later. It should
- * be 1 for star/star, 2 for type/star and 3 for type/subtype.
- */
-
-int mime_match (accept_rec *accept, var_rec *avail)
-{
- char *accept_type = accept->type_name;
- char *avail_type = avail->type_name;
- int len = strlen(accept_type);
-
- if (accept_type[0] == '*') { /* Anything matches star/star */
- if (avail->mime_stars < 1)
- avail->mime_stars = 1;
- return 1;
- }
- else if ((accept_type[len - 1] == '*') &&
- !strncmp (accept_type, avail_type, len - 2)) {
- if (avail->mime_stars < 2)
- avail->mime_stars = 2;
- return 1;
- }
- else if (!strcmp (accept_type, avail_type)
- || (!strcmp (accept_type, "text/html")
- && (!strcmp(avail_type, INCLUDES_MAGIC_TYPE)
- || !strcmp(avail_type, INCLUDES_MAGIC_TYPE3)))) {
- if (accept->level >= avail->level) {
- avail->level_matched = avail->level;
- avail->mime_stars = 3;
- return 1;
- }
- }
-
- return OK;
-}
-
-/* This code implements a piece of the tie-breaking algorithm between
- * variants of equal quality. This piece is the treatment of variants
- * of the same base media type, but different levels. What we want to
- * return is the variant at the highest level that the client explicitly
- * claimed to accept.
- *
- * If all the variants available are at a higher level than that, or if
- * the client didn't say anything specific about this media type at all
- * and these variants just got in on a wildcard, we prefer the lowest
- * level, on grounds that that's the one that the client is least likely
- * to choke on.
- *
- * (This is all motivated by treatment of levels in HTML --- we only
- * want to give level 3 to browsers that explicitly ask for it; browsers
- * that don't, including HTTP/0.9 browsers that only get the implicit
- * "Accept: * / *" [space added to avoid confusing cpp --- no, that
- * syntax doesn't really work] should get HTML2 if available).
- *
- * (Note that this code only comes into play when we are choosing among
- * variants of equal quality, where the draft standard gives us a fair
- * bit of leeway about what to do. It ain't specified by the standard;
- * rather, it is a choice made by this server about what to do in cases
- * where the standard does not specify a unique course of action).
- */
-
-int level_cmp (var_rec *var1, var_rec *var2)
-{
- /* Levels are only comparable between matching media types */
-
- if (var1->is_pseudo_html && !var2->is_pseudo_html)
- return 0;
-
- if (!var1->is_pseudo_html && strcmp (var1->type_name, var2->type_name))
- return 0;
-
- /* Take highest level that matched, if either did match. */
-
- if (var1->level_matched > var2->level_matched) return 1;
- if (var1->level_matched < var2->level_matched) return -1;
-
- /* Neither matched. Take lowest level, if there's a difference. */
-
- if (var1->level < var2->level) return 1;
- if (var1->level > var2->level) return -1;
-
- /* Tied */
-
- return 0;
-}
-
-/* Finding languages. The main entry point is set_language_quality()
- * which is called for each variant. It sets two elements in the
- * variant record:
- * language_quality - the 'q' value of the 'best' matching language
- * from Accept-Language: header (HTTP/1.1)
- * lang_index - Pre HTTP/1.1 language priority, using
- * position of language on the Accept-Language:
- * header, if present, else LanguagePriority
- * directive order.
- *
- * When we do the variant checking for best variant, we use language
- * quality first, and if a tie, language_index next (this only
- * applies when _not_ using the network algorithm). If using
- * network algorithm, lang_index is never used.
- *
- * set_language_quality() calls find_lang_index() and find_default_index()
- * to set lang_index.
- */
-
-int find_lang_index (array_header *accept_langs, char *lang)
-{
- accept_rec *accs;
- int i;
-
- if (!lang)
- return -1;
-
- accs = (accept_rec *)accept_langs->elts;
-
- for (i = 0; i < accept_langs->nelts; ++i)
- if (!strncmp (lang, accs[i].type_name, strlen(accs[i].type_name)))
- return i;
-
- return -1;
-}
-
-/* This function returns the priority of a given language
- * according to LanguagePriority. It is used in case of a tie
- * between several languages.
- */
-
-int find_default_index (neg_dir_config *conf, char *lang)
-{
- array_header *arr;
- int nelts;
- char **elts;
- int i;
-
- if (!lang)
- return -1;
-
- arr = conf->language_priority;
- nelts = arr->nelts;
- elts = (char **) arr->elts;
-
- for (i = 0; i < nelts; ++i)
- if (!strcasecmp (elts[i], lang))
- return i;
-
- return -1;
-}
-
-/* set_default_lang_quality() sets the quality we apply to variants
- * which have no language assigned to them. If none of the variants
- * have a language, we are not negotiating on language, so all are
- * acceptable, and we set the default q value to 1.0. However if
- * some of the variants have languages, we set this default to 0.001.
- * The value of this default will be applied to all variants with
- * no explicit language -- which will have the effect of making them
- * acceptable, but only if no variants with an explicit language
- * are acceptable. The default q value set here is assigned to variants
- * with no language type in set_language_quality().
- *
- * Note that if using the transparent negotiation network algorythm,
- * we don't use this fiddle.
- */
-
-void set_default_lang_quality(negotiation_state *neg)
-{
- var_rec *avail_recs = (var_rec *)neg->avail_vars->elts;
- int j;
-
- if (!neg->use_transparent_neg)
- for (j = 0; j < neg->avail_vars->nelts; ++j) {
- var_rec *variant = &avail_recs[j];
- if (variant->content_languages &&
- variant->content_languages->nelts) {
- neg->default_lang_quality = 0.001;
- return;
- }
- }
-
- neg->default_lang_quality = 1.0;
-}
-
-/* Set the language_quality value in the variant record. Also
- * assigns lang_index for back-compat.
- *
- * To find the language_quality value, we look for the 'q' value
- * of the 'best' matching language on the Accept-Language:
- * header. The'best' match is the language on Accept-Language:
- * header which matches the language of this variant either fully,
- * or as far as the prefix marker (-). If two or more languages
- * match, use the longest string from the Accept-Language: header
- * (see HTTP/1.1 [14.4])
- *
- * When a variant has multiple languages, we find the 'best'
- * match for each variant language tag as above, then select the
- * one with the highest q value. Because both the accept-header
- * and variant can have multiple languages, we now have a hairy
- * loop-within-a-loop here.
- *
- * If the variant has no language and we have no Accept-Language
- * items, leave the quality at 1.0 and return.
- *
- * If the variant has no language, we use the default as set by
- * set_default_lang_quality() (1.0 if we are not negotiating on
- * language, 0.001 if we are).
- *
- * Following the setting of the language quality, we drop through to
- * set the old 'lang_index'. This is set based on either the order
- * of the languages on the Accept-Language header, or the
- * order on the LanguagePriority directive. This is only used
- * in the negotiation if the language qualities tie.
- */
-
-void set_language_quality(negotiation_state *neg, var_rec *variant)
-{
- int i;
- int naccept = neg->accept_langs->nelts;
- int index;
- neg_dir_config *conf = NULL;
- char *firstlang;
-
- if (naccept == 0)
- conf = (neg_dir_config *) get_module_config (neg->r->per_dir_config,
- &negotiation_module);
-
- if (naccept == 0 && (!variant->content_languages ||
- !variant->content_languages->nelts))
- return; /* no accept-language and no variant lang */
-
- if (!variant->content_languages || !variant->content_languages->nelts) {
- /* This variant has no content-language, so use the default
- * quality factor for variants with no content-language
- * (previously set by set_default_lang_quality()). */
- variant->lang_quality = neg->default_lang_quality;
-
- if (naccept == 0)
- return; /* no accept-language items */
-
- }
- else if (naccept) {
- /* Variant has one (or more) languages, and we have one (or more)
- * language ranges on the Accept-Language header. Look for
- * the best match. We do this by going through each language
- * on the variant description looking for a match on the
- * Accept-Language header. The best match is the longest matching
- * language on the header. The final result is the best q value
- * from all the languages on the variant description.
- */
- int j;
- float fiddle_q = 0.0;
- accept_rec *accs = (accept_rec *)neg->accept_langs->elts;
- accept_rec *best = NULL, *star = NULL;
- char *p;
-
- for (j = 0; j < variant->content_languages->nelts; ++j) {
- char *lang; /* language from variant description */
- accept_rec *bestthistag = NULL;
- int prefixlen = 0;
- int longest_lang_range_len = 0;
- int len;
- /* lang is the variant's language-tag, which is the one
- * we are allowed to use the prefix of in HTTP/1.1
- */
- lang = ((char **)(variant->content_languages->elts))[j];
- p = strchr(lang, '-'); /* find prefix part (if any) */
- if (p)
- prefixlen = p - lang;
-
- /* now find the best (i.e. longest) matching Accept-Language
- * header language. We put the best match for this tag in
- * bestthistag. We cannot update the overall best (based on
- * q value) because the best match for this tag is the longest
- * language item on the accept header, not necessarily the
- * highest q.
- */
- for (i = 0; i < neg->accept_langs->nelts; ++i) {
- if (!strcmp(accs[i].type_name, "*")) {
- if (!star)
- star = &accs[i];
- continue;
- }
-
- /* Find language. We match if either the variant language
- * tag exactly matches, or the prefix of the tag up to the
- * '-' character matches the whole of the language in the
- * Accept-Language header. We only use this accept-language
- * item as the best match for the current tag if it
- * is longer than the previous best match */
- if ((!strcmp (lang, accs[i].type_name) ||
- (prefixlen &&
- !strncmp(lang, accs[i].type_name, prefixlen) &&
- (accs[i].type_name[prefixlen] == '\0'))) &&
- ((len = strlen(accs[i].type_name)) >
- longest_lang_range_len)) {
- longest_lang_range_len = len;
- bestthistag = &accs[i];
- }
-
- if (! bestthistag) {
- /* The next bit is a fiddle. Some browsers might be
- * configured to send more specific language ranges
- * than desirable. For example, an Accept-Language of
- * en-US should never match variants with languages en
- * or en-GB. But US English speakers might pick en-US
- * as their language choice. So this fiddle checks if
- * the language range has a prefix, and if so, it
- * matches variants which match that prefix with a
- * priority of 0.001. So a request for en-US would
- * match variants of types en and en-GB, but at much
- * lower priority than matches of en-US directly, or
- * of any other language listed on the Accept-Language
- * header
- */
- if ((p = strchr(accs[i].type_name, '-'))) {
- int plen = p - accs[i].type_name;
- if (!strncmp(lang, accs[i].type_name, plen))
- fiddle_q = 0.001;
- }
- }
- }
- /* Finished looking at Accept-Language headers, the best
- * (longest) match is in bestthistag, or NULL if no match
- */
- if (!best ||
- (bestthistag && bestthistag->quality > best->quality))
- best = bestthistag;
- }
-
- variant->lang_quality = best ? best->quality :
- (star ? star->quality : fiddle_q);
- }
-
- /* Now set the old lang_index field. Since this is old
- * stuff anyway, don't both with handling multiple languages
- * per variant, just use the first one assigned to it
- */
- index = 0;
- if (variant->content_languages && variant->content_languages->nelts)
- firstlang = ((char**)variant->content_languages->elts)[0];
- else
- firstlang = "";
- if (naccept == 0) /* Client doesn't care */
- index = find_default_index (conf, firstlang);
- else /* Client has Accept-Language */
- index = find_lang_index (neg->accept_langs, firstlang);
- variant->lang_index = index;
-
- return;
-}
-
-/* Determining the content length --- if the map didn't tell us,
- * we have to do a stat() and remember for next time.
- *
- * Grump. For Apache, even the first stat here may well be
- * redundant (for multiviews) with a stat() done by the sub_req
- * machinery. At some point, that ought to be fixed.
- */
-
-int find_content_length(negotiation_state *neg, var_rec *variant)
-{
- struct stat statb;
-
- if (variant->bytes == 0) {
- char *fullname = make_full_path (neg->pool, neg->dir_name,
- variant->file_name);
-
- if (stat (fullname, &statb) >= 0) variant->bytes = statb.st_size;
- }
-
- return variant->bytes;
-}
-
-/* For a given variant, find the best matching Accept: header
- * and assign the Accept: header's quality value to the
- * accept_type_quality field of the variant, for later use in
- * determining the best matching variant.
- */
-
-void set_accept_quality(negotiation_state *neg, var_rec *variant)
-{
- int i;
- accept_rec *accept_recs = (accept_rec *)neg->accepts->elts;
- float q = 0.0;
- int q_definite = 1;
-
- /* if no Accept: header, leave quality alone (will
- * remain at the default value of 1) */
- if (!neg->accepts || neg->accepts->nelts == 0)
- return;
-
- /*
- * Go through each of the ranges on the Accept: header,
- * looking for the 'best' match with this variant's
- * content-type. We use the best match's quality
- * value (from the Accept: header) for this variant's
- * accept_type_quality field.
- *
- * The best match is determined like this:
- * type/type is better than type/ * is better than * / *
- * if match is type/type, use the level mime param if available
- */
- for (i = 0; i < neg->accepts->nelts; ++i) {
-
- accept_rec *type = &accept_recs[i];
- int prev_mime_stars;
-
- prev_mime_stars = variant->mime_stars;
-
- if (!mime_match(type, variant))
- continue; /* didn't match the content type at all */
- else
- /* did match - see if there were less or more stars than
- * in previous match
- */
- if (prev_mime_stars == variant->mime_stars)
- continue; /* more stars => not as good a match */
-
- /* Check maxbytes -- not in HTTP/1.1 or Holtman */
-
- if (type->max_bytes > 0
- && (find_content_length(neg, variant)
- > type->max_bytes))
- continue;
-
- /* If we are allowed to mess with the q-values,
- * make wildcards very low, so we have a low chance
- * of ending up with them if there's something better.
- */
-
- if (!neg->accept_q && variant->mime_stars == 1) q = 0.01;
- else if (!neg->accept_q && variant->mime_stars == 2) q = 0.02;
- else q = type->quality;
-
- q_definite = (variant->mime_stars == 3);
- }
- variant->accept_type_quality = q;
- variant->definite=variant->definite && q_definite;
-
- /* if the _best_ quality we got for this variant was 0.0,
- * eliminate it now */
-}
-
-/* For a given variant, find the 'q' value of the charset given
- * on the Accept-Charset line. If not charsets are listed,
- * assume value of '1'.
- */
-
-void set_charset_quality(negotiation_state *neg, var_rec *variant)
-{
- int i;
- accept_rec *accept_recs = (accept_rec *)neg->accept_charsets->elts;
- char *charset = variant->content_charset;
- accept_rec *star = NULL;
-
- /* if no Accept-Charset: header, leave quality alone (will
- * remain at the default value of 1) */
- if (!neg->accept_charsets || neg->accept_charsets->nelts == 0)
- return;
-
- if (charset == NULL || !*charset) charset = "iso-8859-1";
-
- /*
- * Go through each of the items on the Accept-Charset: header,
- * looking for a match with this variant's charset. If none
- * match, charset is unacceptable, so set quality to 0.
- */
- for (i = 0; i < neg->accept_charsets->nelts; ++i) {
-
- accept_rec *type = &accept_recs[i];
-
- if (!strcmp(type->type_name, charset)) {
- variant->charset_quality = type->quality;
- return;
- } else
- if (strcmp(type->type_name, "*") == 0) {
- star = type;
- }
- }
- /* No explicit match */
- if (star) {
- variant->charset_quality = star->quality;
- return;
- }
- /* If this variant is in charset iso-8859-1, the default is 1.0 */
- if (strcmp(charset, "iso-8859-1") == 0) {
- variant->charset_quality = 1.0;
- } else {
- variant->charset_quality = 0.0;
- }
-}
-
-/* For a given variant, find the best matching Accept: header
- * and assign the Accept: header's quality value to the
- * accept_type_quality field of the variant, for later use in
- * determining the best matching variant.
- */
-
-/* is_identity_encoding is included for back-compat, but does anyone
- * use 7bit, 8bin or binary in their var files??
- */
-
-int is_identity_encoding (char *enc)
-{
- return (!enc || !enc[0] || !strcmp (enc, "7bit") || !strcmp (enc, "8bit")
- || !strcmp (enc, "binary"));
-}
-
-void set_encoding_quality(negotiation_state *neg, var_rec *variant)
-{
- int i;
- accept_rec *accept_recs = (accept_rec *)neg->accept_encodings->elts;
- char *enc = variant->content_encoding;
-
- if (!enc || is_identity_encoding(enc))
- return;
-
-
- /* if no Accept: header, leave quality alone (will
- * remain at the default value of 1) */
- if (neg->accept_encodings->nelts == 0) {
- /* If we had an empty Accept-Encoding header, assume that
- * no encodings are acceptable, else all encodings are ok */
- variant->encoding_quality = neg->have_accept_header ? 0 : 1;
- return;
- }
-
- /* Go through each of the encodings on the Accept-Encoding: header,
- * looking for a match with our encoding
- */
- for (i = 0; i < neg->accept_encodings->nelts; ++i) {
- char *name = accept_recs[i].type_name;
-
- if (!strcmp(name, enc)) {
- variant->encoding_quality = 1;
- return;
- }
- }
-
- /* Encoding not found on Accept-Encoding: header, so it is
- * _not_ acceptable */
- variant->encoding_quality = 0;
-}
-
-/* Possible results of the network algorithm */
-enum algorithm_results {
- na_not_applied = -1, /* net algorithm not used */
- na_choice = 1, /* choose variant */
- na_list /* list variants */
-};
-
-/*
- * This is a heavily-rewritten 'best_match' function. For a start, it
- * now returns an int, which has one of the three values: na_not_applied,
- * na_choice or na_list, which give the result of the network algorithm
- * (if it was not applied, the return value is na_not_applied).
- * The best variable is returned in *pbest. It also has two possible
- * algorithms for determining the best match: the network algorithm,
- * and the standard Apache algorithm. These are split out into
- * separate functions (is_variant_better_na() and is_variant_better()).
- *
- * Previously, best_match iterated first through the content_types
- * in the Accept: header, then checked each variant, and eliminated
- * those that didn't match the variant's type. We cannot do this because
- * we need full information, including language, charset, etc
- * quality for _every_ variant, for the Alternates: header,
- * and (possibly) the human-readable choice responses or 406 errors.
- *
- * After the 'best' (if any) is determined, the overall result of
- * the negotiation is obtained. If the network algorithm was not
- * in use, the result is na_not_applied. Else the result is
- * na_list if 'short accept header' is in use, else na_list
- * if _no_ best match was found, or na_choice if a best match
- * was found.
- */
-
-/* Firstly, the negotiation 'network algorithm' from Holtman.
- */
-
-int is_variant_better_na(negotiation_state *neg, var_rec *variant, var_rec *best, float *p_bestq)
-{
- float bestq = *p_bestq, q;
-
- /* Note: Encoding is not negotiated in the Holtman
- * transparent neg draft, so we ignored it here. But
- * it does mean we could return encodings the UA
- * or proxy cannot handle. Eek. */
-
- q = variant->accept_type_quality *
- variant->type_quality *
- variant->charset_quality *
- variant->lang_quality;
-
-#ifdef NEG_DEBUG
- fprintf(stderr, "Variant: file=%s type=%s lang=%s acceptq=%1.3f langq=%1.3f typeq=%1.3f q=%1.3f definite=%d\n",
- variant->file_name ? variant->file_name : "",
- variant->type_name ? variant->type_name : "",
- variant->content_languages ? merge_string_array(neg->pool, variant->content_languages, ",") : "",
- variant->accept_type_quality,
- variant->lang_quality,
- variant->type_quality,
- q,
- variant->definite
- );
-#endif
-
- if (q > bestq) {
- *p_bestq = q;
- return 1;
- }
- if (q == bestq) {
- /* If the best variant's charset is ISO-8859-1 and this variant has
- the same charset quality, then we prefer this variant */
- if (variant->charset_quality == best->charset_quality &&
- (variant->content_charset != NULL &&
- *variant->content_charset != '\0' &&
- strcmp(variant->content_charset, "iso-8859-1") != 0) &&
- (best->content_charset == NULL ||
- *best->content_charset == '\0' ||
- strcmp(best->content_charset, "iso-8859-1") == 0)) {
- *p_bestq = q;
- return 1;
- }
- }
- return 0;
-}
-
-/* Negotiation algorithm as used by previous versions of Apache
- * (just about).
- */
-
-float is_variant_better(negotiation_state *neg, var_rec *variant, var_rec *best, float *p_bestq)
-{
- float bestq = *p_bestq, q;
- int levcmp;
-
- /*
- * For non-transparent negotiation, server can choose how
- * to handle the negotiation. We'll use the following in
- * order: content-type, language, content-type level, charset,
- * content length.
- *
- * For each check, we have three possible outcomes:
- * This variant is worse than current best: return 0
- * This variant is better than the current best:
- * assign this variant's q to *p_bestq, and return 1
- * This variant is just as desirable as the current best:
- * drop through to the next test.
- *
- * This code is written in this long-winded way to allow future
- * customisation, either by the addition of additional
- * checks, or to allow the order of the checks to be determined
- * by configuration options (e.g. we might prefer to check
- * language quality _before_ content type).
- */
-
- /* First though, eliminate this variant if it is not
- * acceptable by type, charset, encoding or language.
- */
-
- if (variant->encoding_quality == 0 ||
- variant->lang_quality == 0 ||
- variant->type_quality == 0 ||
- variant->charset_quality == 0 ||
- variant->accept_type_quality == 0)
- return 0; /* don't consider unacceptables */
-
- q = variant->accept_type_quality * variant->type_quality;
- if (q == 0.0 || q < bestq) return 0;
- if (q > bestq || !best) {
- *p_bestq = q;
- return 1;
- }
-
- /* language */
- if (variant->lang_quality < best->lang_quality)
- return 0;
- if (variant->lang_quality > best->lang_quality) {
- *p_bestq = q;
- return 1;
- }
-
- /* if language qualities were equal, try the LanguagePriority
- * stuff */
- if (best->lang_index != -1 && variant->lang_index > best->lang_index)
- return 0;
- if (variant->lang_index != -1 &&
- (variant->lang_index < best->lang_index || best->lang_index == -1)) {
- *p_bestq = q;
- return 1;
- }
-
- /* content-type level (text/html only?) */
- levcmp = level_cmp (variant, best);
- if (levcmp == -1) return 0;
- if (levcmp == 1) {
- *p_bestq = q;
- return 1;
- }
-
- /* encoding -- can only be 1 or 0, and if 0 we eliminated this
- * variant at the start of this function. However we
- * prefer variants with no encoding over those with encoding */
- if (!*best->content_encoding && *variant->content_encoding)
- return 0;
- if (*best->content_encoding && !*variant->content_encoding) {
- *p_bestq = q;
- return 1;
- }
-
-
- /* charset */
- if (variant->charset_quality < best->charset_quality)
- return 0;
- /* If the best variant's charset is ISO-8859-1 and this variant has
- the same charset quality, then we prefer this variant */
- if (variant->charset_quality > best->charset_quality ||
- ((variant->content_charset != NULL &&
- *variant->content_charset != '\0' &&
- strcmp(variant->content_charset, "iso-8859-1") != 0) &&
- (best->content_charset == NULL ||
- *best->content_charset == '\0' ||
- strcmp(best->content_charset, "iso-8859-1") == 0))) {
- *p_bestq = q;
- return 1;
- }
-
-
- /* content length if all else equal */
- if (find_content_length(neg, variant)
- >=
- find_content_length(neg, best))
- return 0;
-
- /* ok, to get here means every thing turned out equal, except
- * we have a shorter content length, so use this variant */
- *p_bestq = q;
- return 1;
-}
-
-int best_match(negotiation_state *neg, var_rec **pbest)
-{
- int j;
- var_rec *best = NULL;
- float bestq = 0.0;
- enum algorithm_results algorithm_result = na_not_applied;
-
- var_rec *avail_recs = (var_rec *)neg->avail_vars->elts;
-
- set_default_lang_quality(neg);
-
- /*
- * Find the 'best' variant
- */
-
- for (j = 0; j < neg->avail_vars->nelts; ++j) {
-
- var_rec *variant = &avail_recs[j];
-
- /* Find all the relevant 'quality' values from the
- * Accept... headers, and store in the variant
- */
- set_accept_quality(neg, variant);
- set_language_quality(neg, variant);
- set_encoding_quality(neg, variant);
- set_charset_quality(neg, variant);
-
- /* Now find out if this variant is better than the current
- * best, either using the network algorithm, or Apache's
- * internal server-driven algorithm. Presumably other
- * server-driven algorithms are possible, and could be
- * implemented here.
- */
-
- if (neg->use_transparent_neg) {
- if (is_variant_better_na(neg, variant, best, &bestq))
- best = variant;
- }
- else {
- if (is_variant_better(neg, variant, best, &bestq))
- best = variant;
- }
- }
-
- /* We now either have a best variant, or no best variant
- */
- if (neg->use_transparent_neg) {
- if (neg->short_accept_headers)
- algorithm_result = na_list;
- else {
- /* From Holtman, result is:
- * If variant & URI are not neigbors, list_ua or list_os
- * Else
- * If UA can do trans neg
- * IF best is definite && best q > 0, choice_ua
- * ELSE list_ua
- * ELSE
- * IF best q > 0, choose_os
- * ELSE list_os (or forward_os on proxy)
- */
-
- /* assume variant and URI are neigbors (since URI in
- * var map must be in same directory) */
-
- if(neg->use_transparent_neg)
- algorithm_result = (best && best->definite) && (bestq>0)
- ? na_choice : na_list;
- else
- algorithm_result = bestq>0 ? na_choice : na_list;
- }
- }
-
- *pbest = best;
- return algorithm_result;
-}
-
-/*
- * Sets the Alternates and Vary headers, used if we are going to
- * return 406 Not Acceptable status, a 300 Multiple Choice status,
- * or a Choice response.
- *
- * 'type' is the result of the network algorithm, if applied.
- * We do different things if the network algorithm was not applied
- * (type == na_not_applied): no Alternates header, and Vary:
- * does not include 'negotiate'.
- *
- * We should also add a max-age lifetime for the Alternates header,
- * but how long we we give it? Presumably this should be
- * configurable in the map file.
- */
-
-void set_neg_headers(request_rec *r, negotiation_state *neg, int na_result)
-{
- int j;
- var_rec *avail_recs = (var_rec *)neg->avail_vars->elts;
- char *sample_type = NULL;
- char *sample_language = NULL;
- char *sample_encoding = NULL;
- char *sample_charset = NULL;
- int vary_by_type = 0;
- int vary_by_language = 0;
- int vary_by_charset = 0;
- int vary_by_encoding = 0;
- array_header *hdrs;
-
- /* Put headers into err_headers_out, new send_http_header()
- * outputs both headers_out and err_headers_out */
- hdrs = r->err_headers_out;
-
- for (j = 0; j < neg->avail_vars->nelts; ++j) {
-
- var_rec *variant = &avail_recs[j];
- char *rec;
- char qstr[6];
- long len;
- char lenstr[22]; /* enough for 2^64 */
-
- ap_snprintf(qstr, sizeof(qstr), "%1.3f", variant->type_quality);
-
- /* Strip trailing zeros (saves those valuable network bytes) */
- if (qstr[4] == '0') {
- qstr[4] = '\0';
- if (qstr[3] == '0') {
- qstr[3] = '\0';
- if (qstr[2] == '0') {
- qstr[1] = '\0';
- }
- }
- }
-
- rec = pstrcat(r->pool, "{\"", variant->file_name, "\" ", qstr, NULL);
- if (variant->type_name) {
- if (*variant->type_name)
- rec = pstrcat(r->pool, rec, " {type ",
- variant->type_name, "}", NULL);
- if (!sample_type) sample_type = variant->type_name;
- else if (strcmp(sample_type, variant->type_name))
- vary_by_type = 1;
- }
- if (variant->content_languages && variant->content_languages->nelts) {
- char *langs =
- merge_string_array (r->pool, variant->content_languages, ",");
- rec = pstrcat(r->pool, rec, " {language ", langs, "}", NULL);
- if (!sample_language) sample_language = langs;
- else if (strcmp(sample_language, langs))
- vary_by_language = 1;
- }
- if (variant->content_encoding) {
- if (!sample_encoding) sample_encoding = variant->content_encoding;
- else if (strcmp(sample_encoding, variant->content_encoding))
- vary_by_encoding = 1;
- }
- if (variant->content_charset) {
- if (*variant->content_charset)
- rec = pstrcat(r->pool, rec, " {charset ",
- variant->content_charset, "}", NULL);
- if (!sample_charset) sample_charset = variant->content_charset;
- else if (strcmp(sample_charset, variant->content_charset))
- vary_by_charset = 1;
- }
- if ((len = find_content_length(neg, variant)) != 0) {
- ap_snprintf(lenstr, sizeof(lenstr), "%ld", len);
- rec = pstrcat(r->pool, rec, " {length ", lenstr, "}", NULL);
- }
-
- rec = pstrcat(r->pool, rec, "}", NULL);
-
- if (na_result != na_not_applied)
- table_merge(hdrs, "Alternates", rec);
- }
-
- if (na_result != na_not_applied)
- table_merge(hdrs, "Vary", "negotiate");
- if (vary_by_type)
- table_merge(hdrs, "Vary", "accept");
- if (vary_by_language)
- table_merge(hdrs, "Vary", "accept-language");
- if (vary_by_charset)
- table_merge(hdrs, "Vary", "accept-charset");
- if (vary_by_encoding && na_result == na_not_applied)
- table_merge(hdrs, "Vary", "accept-encoding");
-}
-
-/**********************************************************************
- *
- * Return an HTML list of variants. This is output as part of the
- * 300 or 406 status body.
- */
-
-char *make_variant_list (request_rec *r, negotiation_state *neg)
-{
- int i;
- char *t;
-
- t = pstrdup(r->pool, "Available variants:\n<ul>\n");
- for (i = 0; i < neg->avail_vars->nelts; ++i) {
- var_rec *variant = &((var_rec *)neg->avail_vars->elts)[i];
- char *filename = variant->file_name ? variant->file_name : "";
- array_header *languages = variant->content_languages;
- char *description = variant->description ? variant->description : "";
-
- /* The format isn't very neat, and it would be nice to make
- * the tags human readable (eg replace 'language en' with
- * 'English'). */
- t = pstrcat(r->pool, t, "<li><a href=\"", filename, "\">",
- filename, "</a> ", description, NULL);
- if (variant->type_name && *variant->type_name)
- t = pstrcat(r->pool, t, ", type ", variant->type_name, NULL);
- if (languages && languages->nelts)
- t = pstrcat(r->pool, t, ", language ",
- merge_string_array(r->pool, languages, ", "),
- NULL);
- if (variant->content_charset && *variant->content_charset)
- t = pstrcat(r->pool, t, ", charset ", variant->content_charset, NULL);
- t = pstrcat(r->pool, t, "\n", NULL);
- }
- t = pstrcat(r->pool, t, "</ul>\n", NULL);
-
- return t;
-}
-
-void store_variant_list (request_rec *r, negotiation_state *neg)
-{
- if (r->main == NULL) {
- table_set (r->notes, "variant-list", make_variant_list (r, neg));
- } else {
- table_set (r->main->notes, "variant-list", make_variant_list (r->main, neg));
- }
-}
-
-/* Called if we got a "Choice" response from the network algorithm.
- * It checks the result of the chosen variant to see if it
- * is itself negotiated (if so, return error VARIANT_ALSO_VARIES).
- * Otherwise, add the appropriate headers to the current response.
- */
-
-int setup_choice_response(request_rec *r, negotiation_state *neg, var_rec *variant)
-{
- request_rec *sub_req;
- char *sub_vary;
-
- if (!variant->sub_req) {
- int status;
-
- sub_req = sub_req_lookup_file(variant->file_name, r);
- status = sub_req->status;
- if (status != HTTP_OK && status != HTTP_MULTIPLE_CHOICES) {
- destroy_sub_req(sub_req);
- return status;
- }
- variant->sub_req = sub_req;
- }
- else
- sub_req = variant->sub_req;
-
-
- /* The network algorithm told us to return a "Choice"
- * response. This is the normal variant response, with
- * some extra headers. First, ensure that the chosen
- * variant did not itself return a "List" or "Choice" response.
- * If not, set the appropriate headers, and fall through to
- * the normal variant handling
- */
-
- if ((sub_req->status == HTTP_MULTIPLE_CHOICES) ||
- (table_get(sub_req->err_headers_out, "Alternates")) ||
- (table_get(sub_req->err_headers_out, "Content-Location")))
- return VARIANT_ALSO_VARIES;
-
- if ((sub_vary = table_get(sub_req->err_headers_out, "Vary")) != NULL)
- table_set(r->err_headers_out, "Variant-Vary", sub_vary);
- table_set(r->err_headers_out, "Content-Location", variant->file_name);
- set_neg_headers(r, neg, na_choice); /* add Alternates and Vary */
- /* to do: add Expires */
-
- return 0;
-}
-
-/****************************************************************
- *
- * Executive...
- */
-
-int handle_map_file (request_rec *r)
-{
- negotiation_state *neg = parse_accept_headers (r);
- var_rec *best;
- int res;
- int na_result;
-
- char *udir;
-
- if ((res = read_type_map (neg, r))) return res;
-
- maybe_add_default_encodings(neg, 0);
-
- na_result = best_match(neg, &best);
-
- /* na_result is one of
- * na_not_applied: we didn't use the network algorithm
- * na_choice: return a "Choice" response
- * na_list: return a "List" response (no variant chosen)
- */
-
- if (na_result == na_list) {
- set_neg_headers(r, neg, na_list);
- store_variant_list (r, neg);
- return MULTIPLE_CHOICES;
- }
-
- if (!best) {
- log_reason ("no acceptable variant", r->filename, r);
-
- set_neg_headers(r, neg, na_result);
- store_variant_list (r, neg);
- return NOT_ACCEPTABLE;
- }
-
- if (na_result == na_choice)
- if ((res = setup_choice_response(r, neg, best)) != 0)
- return res;
-
- /* Make sure caching works - Vary should handle HTTP/1.1, but for
- * HTTP/1.0, we can't allow caching at all. NB that we merge the
- * header in case some other module negotiates on something else.
- */
- if (!do_cache_negotiated_docs(r->server) && (r->proto_num < 1001))
- r->no_cache = 1;
-
- if (na_result == na_not_applied)
- set_neg_headers(r, neg, na_not_applied);
-
- if (r->path_info && *r->path_info) {
- r->uri[find_path_info(r->uri, r->path_info)] = '\0';
- }
- udir = make_dirstr (r->pool, r->uri, count_dirs (r->uri));
- udir = escape_uri(r->pool, udir);
- internal_redirect(pstrcat(r->pool, udir, best->file_name, r->path_info,
- NULL), r);
- return OK;
-}
-
-int handle_multi (request_rec *r)
-{
- negotiation_state *neg;
- var_rec *best, *avail_recs;
- request_rec *sub_req;
- int res;
- int j;
- int na_result; /* result of network algorithm */
-
- if (r->finfo.st_mode != 0 || !(allow_options (r) & OPT_MULTI))
- return DECLINED;
-
- neg = parse_accept_headers (r);
-
- if ((res = read_types_multi (neg))) {
-return_from_multi:
- /* free all allocated memory from subrequests */
- avail_recs = (var_rec *)neg->avail_vars->elts;
- for (j = 0; j < neg->avail_vars->nelts; ++j) {
- var_rec *variant = &avail_recs[j];
- if (variant->sub_req) {
- destroy_sub_req(variant->sub_req);
- }
- }
- return res;
- }
- if (neg->avail_vars->nelts == 0) return DECLINED;
-
- maybe_add_default_encodings(neg,
- r->method_number != M_GET
- || r->args || r->path_info);
-
- na_result = best_match(neg, &best);
- if (na_result == na_list) {
- /*
- * Network algorithm tols us to output a "List" response.
- * This is output at a 300 status code, which we will
- * return. The list of variants will be stored in r->notes
- * under the name "variants-list".
- */
- set_neg_headers(r, neg, na_list); /* set Alternates: and Vary: */
-
- store_variant_list (r, neg);
- res = MULTIPLE_CHOICES;
- goto return_from_multi;
- }
-
- if (!best) {
- log_reason ("no acceptable variant", r->filename, r);
-
- set_neg_headers (r, neg, na_result);
- store_variant_list (r, neg);
- res = NOT_ACCEPTABLE;
- goto return_from_multi;
- }
-
- if (na_result == na_choice)
- if ((res = setup_choice_response(r, neg, best)) != 0) {
- goto return_from_multi;
- }
-
- if (! (sub_req = best->sub_req)) {
- /* We got this out of a map file, so we don't actually have
- * a sub_req structure yet. Get one now.
- */
-
- sub_req = sub_req_lookup_file (best->file_name, r);
- if (sub_req->status != HTTP_OK) {
- res = sub_req->status;
- destroy_sub_req(sub_req);
- goto return_from_multi;
- }
- }
-
- /* BLETCH --- don't multi-resolve non-ordinary files */
-
- if (!S_ISREG(sub_req->finfo.st_mode)) {
- res = NOT_FOUND;
- goto return_from_multi;
- }
-
- /* Otherwise, use it. */
-
- if (!do_cache_negotiated_docs(r->server) && (r->proto_num < 1001))
- r->no_cache = 1;
-
- if (na_result == na_not_applied)
- set_neg_headers(r, neg, na_not_applied);
-
- r->filename = sub_req->filename;
- r->handler = sub_req->handler;
- r->content_type = sub_req->content_type;
- r->content_encoding = sub_req->content_encoding;
- r->content_languages = sub_req->content_languages;
- r->content_language = sub_req->content_language;
- r->finfo = sub_req->finfo;
- r->per_dir_config = sub_req->per_dir_config;
- /* copy output headers from subrequest, but leave negotiation headers */
- r->notes = overlay_tables(r->pool, sub_req->notes, r->notes);
- r->headers_out = overlay_tables(r->pool, sub_req->headers_out,
- r->headers_out);
- r->err_headers_out = overlay_tables(r->pool, sub_req->err_headers_out,
- r->err_headers_out);
- r->subprocess_env = overlay_tables(r->pool, sub_req->subprocess_env,
- r->subprocess_env);
- avail_recs = (var_rec *)neg->avail_vars->elts;
- for (j = 0; j < neg->avail_vars->nelts; ++j) {
- var_rec *variant = &avail_recs[j];
- if (variant != best && variant->sub_req) {
- destroy_sub_req(variant->sub_req);
- }
- }
- return OK;
-}
-
-handler_rec negotiation_handlers[] = {
-{ MAP_FILE_MAGIC_TYPE, handle_map_file },
-{ "type-map", handle_map_file },
-{ NULL }
-};
-
-module negotiation_module = {
- STANDARD_MODULE_STUFF,
- NULL, /* initializer */
- create_neg_dir_config, /* dir config creater */
- merge_neg_dir_configs, /* dir merger --- default is to override */
- NULL, /* server config */
- NULL, /* merge server config */
- negotiation_cmds, /* command table */
- negotiation_handlers, /* handlers */
- NULL, /* filename translation */
- NULL, /* check_user_id */
- NULL, /* check auth */
- NULL, /* check access */
- handle_multi, /* type_checker */
- NULL, /* fixups */
- NULL, /* logger */
- NULL /* header parser */
-};
diff --git a/usr.sbin/httpd/src/mod_rewrite.c b/usr.sbin/httpd/src/mod_rewrite.c
deleted file mode 100644
index 15fb1d8dffa..00000000000
--- a/usr.sbin/httpd/src/mod_rewrite.c
+++ /dev/null
@@ -1,3335 +0,0 @@
-
-/* ====================================================================
- * Copyright (c) 1996,1997 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. 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/>.
- *
- */
-
-
-/* _ _ _
-** _ __ ___ ___ __| | _ __ _____ ___ __(_) |_ ___
-** | '_ ` _ \ / _ \ / _` | | '__/ _ \ \ /\ / / '__| | __/ _ \
-** | | | | | | (_) | (_| | | | | __/\ V V /| | | | || __/
-** |_| |_| |_|\___/ \__,_|___|_| \___| \_/\_/ |_| |_|\__\___|
-** |_____|
-**
-** URL Rewriting Module
-**
-** This module uses a rule-based rewriting engine (based on a
-** regular-expression parser) to rewrite requested URLs on the fly.
-**
-** It supports an unlimited number of additional rule conditions (which can
-** operate on a lot of variables, even on HTTP headers) for granular
-** matching and even external database lookups (either via plain text
-** tables, DBM hash files or even external processes) for advanced URL
-** substitution.
-**
-** It operates on the full URLs (including the PATH_INFO part) both in
-** per-server context (httpd.conf) and per-dir context (.htaccess) and even
-** can generate QUERY_STRING parts on result. The rewriting result finally
-** can lead to internal subprocessing, external request redirection or even
-** to internal proxy throughput.
-**
-** This module was originally written in April 1996 and
-** gifted exclusively to the The Apache Group in July 1997 by
-**
-** Ralf S. Engelschall
-** rse@engelschall.com
-** www.engelschall.com
-*/
-
-
-
-
- /* from the underlaying Unix system ... */
-#include <string.h>
-#include <stdarg.h>
-#include <time.h>
-#include <signal.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <netinet/in.h>
-
- /* from the Apache server ... */
-#include "httpd.h"
-#include "http_config.h"
-#include "http_request.h"
-#include "http_core.h"
-#include "http_log.h"
-
- /* now our own stuff ... */
-#include "mod_rewrite.h"
-
-
-
-
-/*
-** +-------------------------------------------------------+
-** | |
-** | static module configuration
-** | |
-** +-------------------------------------------------------+
-*/
-
-
-/*
-**
-** our interface to the Apache server kernel
-**
-** keep in mind:
-**
-** o Runtime logic of a request is as following:
-**
-** while(request or subrequest) {
-** foreach(stage #1...#9) {
-** foreach(module) { (**)
-** try to run hook
-** }
-** }
-** }
-**
-** o the order of modules at (**) is the inverted order as
-** given in the "Configuration" file, i.e. the last module
-** specified is the first one called for each hook!
-** The core module is always the last!
-**
-** o there are two different types of result checking and
-** continue processing:
-** for hook #1,#4,#5,#6,#8:
-** hook run loop stops on first modules which gives
-** back a result != DECLINED, i.e. it usually returns OK
-** which says "OK, module has handled this _stage_" and for #1
-** this have not to mean "Ok, the filename is now valid".
-** for hook #2,#3,#7,#9:
-** all hooks are run, independend of result
-**
-** o at the last stage, the core module always
-** - says "BAD_REQUEST" if r->filename does not begin with "/"
-** - prefix URL with document_root or replaced server_root
-** with document_root and sets r->filename
-** - always return a "OK" independed if the file really exists
-** or not!
-**
-*/
-
- /* the table of commands we provide */
-static command_rec command_table[] = {
- { "RewriteEngine", cmd_rewriteengine, NULL, OR_FILEINFO, FLAG,
- "On or Off to enable or disable (default) the whole rewriting engine" },
- { "RewriteOptions", cmd_rewriteoptions, NULL, OR_FILEINFO, ITERATE,
- "List of option strings to set" },
- { "RewriteBase", cmd_rewritebase, NULL, OR_FILEINFO, TAKE1,
- "the base URL of the per-directory context" },
- { "RewriteCond", cmd_rewritecond, NULL, OR_FILEINFO, RAW_ARGS,
- "a input string and a to be applied regexp-pattern" },
- { "RewriteRule", cmd_rewriterule, NULL, OR_FILEINFO, RAW_ARGS,
- "a URL-applied regexp-pattern and a substitution URL" },
- { "RewriteMap", cmd_rewritemap, NULL, RSRC_CONF, TAKE2,
- "a mapname and a filename" },
- { "RewriteLog", cmd_rewritelog, NULL, RSRC_CONF, TAKE1,
- "the filename of the rewriting logfile" },
- { "RewriteLogLevel", cmd_rewriteloglevel, NULL, RSRC_CONF, TAKE1,
- "the level of the rewriting logfile verbosity (0=none, 1=std, .., 9=max)" },
- { NULL }
-};
-
- /* the table of content handlers we provide */
-static handler_rec handler_table[] = {
- { "redirect-handler", handler_redirect },
- { NULL }
-};
-
- /* the main config structure */
-module rewrite_module = {
- STANDARD_MODULE_STUFF,
-
- init_module, /* module initializer */
-
- config_perdir_create, /* create per-dir config structures */
- config_perdir_merge, /* merge per-dir config structures */
- config_server_create, /* create per-server config structures */
- config_server_merge, /* merge per-server config structures */
- command_table, /* table of config file commands */
-
- handler_table, /* [#8] table of MIME-typed-dispatched request action handlers */
-
- hook_uri2file, /* [#1] URI to filename translation */
-
- NULL, /* [#4] check_user_id: get and validate user id from the HTTP request */
- NULL, /* [#5] check_auth: check if the user is ok _here_ */
- NULL, /* [#2] check_access: check access by host address, etc. */
-
- hook_mimetype, /* [#6] determine MIME type */
-
- hook_fixup, /* [#7] pre-run fixups */
- NULL, /* [#9] log a transaction */
- NULL /* [#3] header parser */
-};
-
- /* the cache */
-static cache *cachep;
-
- /* whether proxy module is available or not */
-static int proxy_available;
-
- /* the txt mapfile parsing stuff */
-#define MAPFILE_PATTERN "^([^ \t]+)[ \t]+([^ \t]+).*$"
-#define MAPFILE_OUTPUT "$1,$2"
-static regex_t *lookup_map_txtfile_regexp = NULL;
-static regmatch_t lookup_map_txtfile_regmatch[10];
-
-
-
-
-/*
-** +-------------------------------------------------------+
-** | |
-** | configuration directive handling
-** | |
-** +-------------------------------------------------------+
-*/
-
-
-/*
-**
-** per-server configuration structure handling
-**
-*/
-
-static void *config_server_create(pool *p, server_rec *s)
-{
- rewrite_server_conf *a;
-
- a = (rewrite_server_conf *)pcalloc(p, sizeof(rewrite_server_conf));
-
- a->state = ENGINE_DISABLED;
- a->options = OPTION_NONE;
- a->rewritelogfile = NULL;
- a->rewritelogfp = -1;
- a->rewriteloglevel = 1;
- a->rewritemaps = make_array(p, 2, sizeof(rewritemap_entry));
- a->rewriteconds = make_array(p, 2, sizeof(rewritecond_entry));
- a->rewriterules = make_array(p, 2, sizeof(rewriterule_entry));
-
- return (void *)a;
-}
-
-static void *config_server_merge(pool *p, void *basev, void *overridesv)
-{
- rewrite_server_conf *a, *base, *overrides;
-
- a = (rewrite_server_conf *)pcalloc(p, sizeof(rewrite_server_conf));
- base = (rewrite_server_conf *)basev;
- overrides = (rewrite_server_conf *)overridesv;
-
- a->state = overrides->state;
- a->options = overrides->options;
- a->rewritelogfile = base->rewritelogfile != NULL ? base->rewritelogfile : overrides->rewritelogfile;
- a->rewritelogfp = base->rewritelogfp != -1 ? base->rewritelogfp : overrides->rewritelogfp;
- a->rewriteloglevel = overrides->rewriteloglevel;
-
- if (a->options & OPTION_INHERIT) {
- a->rewritemaps = append_arrays(p, overrides->rewritemaps, base->rewritemaps);
- a->rewriteconds = append_arrays(p, overrides->rewriteconds, base->rewriteconds);
- a->rewriterules = append_arrays(p, overrides->rewriterules, base->rewriterules);
- }
- else {
- a->rewritemaps = overrides->rewritemaps;
- a->rewriteconds = overrides->rewriteconds;
- a->rewriterules = overrides->rewriterules;
- }
-
- return (void *)a;
-}
-
-
-/*
-**
-** per-directory configuration structure handling
-**
-*/
-
-static void *config_perdir_create(pool *p, char *path)
-{
- rewrite_perdir_conf *a;
-
- a = (rewrite_perdir_conf *)pcalloc(p, sizeof(rewrite_perdir_conf));
-
- a->state = ENGINE_DISABLED;
- a->options = OPTION_NONE;
- a->baseurl = NULL;
- a->rewriteconds = make_array(p, 2, sizeof(rewritecond_entry));
- a->rewriterules = make_array(p, 2, sizeof(rewriterule_entry));
-
- if (path == NULL)
- a->directory = NULL;
- else {
- /* make sure it has a trailing slash */
- if (path[strlen(path)-1] == '/')
- a->directory = pstrdup(p, path);
- else
- a->directory = pstrcat(p, path, "/", NULL);
- }
-
- return (void *)a;
-}
-
-static void *config_perdir_merge(pool *p, void *basev, void *overridesv)
-{
- rewrite_perdir_conf *a, *base, *overrides;
-
- a = (rewrite_perdir_conf *)pcalloc(p, sizeof(rewrite_perdir_conf));
- base = (rewrite_perdir_conf *)basev;
- overrides = (rewrite_perdir_conf *)overridesv;
-
- a->state = overrides->state;
- a->options = overrides->options;
- a->directory = overrides->directory;
- a->baseurl = overrides->baseurl;
-
- if (a->options & OPTION_INHERIT) {
- a->rewriteconds = append_arrays(p, overrides->rewriteconds, base->rewriteconds);
- a->rewriterules = append_arrays(p, overrides->rewriterules, base->rewriterules);
- }
- else {
- a->rewriteconds = overrides->rewriteconds;
- a->rewriterules = overrides->rewriterules;
- }
-
- return (void *)a;
-}
-
-
-/*
-**
-** the configuration commands
-**
-*/
-
-static const char *cmd_rewriteengine(cmd_parms *cmd, rewrite_perdir_conf *dconf, int flag)
-{
- rewrite_server_conf *sconf;
-
- sconf = (rewrite_server_conf *)get_module_config(cmd->server->module_config, &rewrite_module);
- if (cmd->path == NULL) /* is server command */
- sconf->state = (flag ? ENGINE_ENABLED : ENGINE_DISABLED);
- else /* is per-directory command */
- dconf->state = (flag ? ENGINE_ENABLED : ENGINE_DISABLED);
-
- return NULL;
-}
-
-static const char *cmd_rewriteoptions(cmd_parms *cmd, rewrite_perdir_conf *dconf, char *option)
-{
- rewrite_server_conf *sconf;
- const char *err;
-
- sconf = (rewrite_server_conf *)get_module_config(cmd->server->module_config, &rewrite_module);
- if (cmd->path == NULL) /* is server command */
- err = cmd_rewriteoptions_setoption(cmd->pool, &(sconf->options), option);
- else /* is per-directory command */
- err = cmd_rewriteoptions_setoption(cmd->pool, &(dconf->options), option);
-
- return err;
-}
-
-static const char *cmd_rewriteoptions_setoption(pool *p, int *options, char *name)
-{
- if (strcasecmp(name, "inherit") == 0)
- *options |= OPTION_INHERIT;
- else
- return pstrcat(p, "RewriteOptions: unknown option '", name, "'\n", NULL);
- return NULL;
-}
-
-static const char *cmd_rewritelog(cmd_parms *cmd, void *dconf, char *a1)
-{
- rewrite_server_conf *sconf;
-
- sconf = (rewrite_server_conf *)get_module_config(cmd->server->module_config, &rewrite_module);
- sconf->rewritelogfile = a1;
-
- return NULL;
-}
-
-static const char *cmd_rewriteloglevel(cmd_parms *cmd, void *dconf, char *a1)
-{
- rewrite_server_conf *sconf;
-
- sconf = (rewrite_server_conf *)get_module_config(cmd->server->module_config, &rewrite_module);
- sconf->rewriteloglevel = atoi(a1);
-
- return NULL;
-}
-
-static const char *cmd_rewritemap(cmd_parms *cmd, void *dconf, char *a1, char *a2)
-{
- rewrite_server_conf *sconf;
- rewritemap_entry *new;
- struct stat st;
-
- sconf = (rewrite_server_conf *)get_module_config(cmd->server->module_config, &rewrite_module);
- new = push_array(sconf->rewritemaps);
-
- new->name = a1;
- if (strncmp(a2, "txt:", 4) == 0) {
- new->type = MAPTYPE_TXT;
- new->datafile = a2+4;
- new->checkfile = a2+4;
- }
- else if (strncmp(a2, "dbm:", 4) == 0) {
-#ifdef HAS_NDBM_LIB
- new->type = MAPTYPE_DBM;
- new->datafile = a2+4;
- new->checkfile = pstrcat(cmd->pool, a2+4, NDBM_FILE_SUFFIX, NULL);
-#else
- return pstrdup(cmd->pool, "RewriteMap: cannot use NDBM mapfile, because no NDBM support compiled in");
-#endif
- }
- else if (strncmp(a2, "prg:", 4) == 0) {
- new->type = MAPTYPE_PRG;
- new->datafile = a2+4;
- new->checkfile = a2+4;
- }
- else {
- new->type = MAPTYPE_TXT;
- new->datafile = a2;
- new->checkfile = a2;
- }
- new->fpin = 0;
- new->fpout = 0;
-
- if (new->checkfile)
- if (stat(new->checkfile, &st) == -1)
- return pstrcat(cmd->pool, "RewriteMap: map file or program not found:", new->checkfile, NULL);
-
- return NULL;
-}
-
-static const char *cmd_rewritebase(cmd_parms *cmd, rewrite_perdir_conf *dconf, char *a1)
-{
- if (cmd->path == NULL || dconf == NULL)
- return "RewriteBase: only valid in per-directory config files";
- if (a1[0] != '/')
- return "RewriteBase: argument is not a valid URL";
- if (a1[0] == '\0')
- return "RewriteBase: empty URL not allowed";
-
- dconf->baseurl = pstrdup(cmd->pool, a1);
-
- return NULL;
-}
-
-static const char *cmd_rewritecond(cmd_parms *cmd, rewrite_perdir_conf *dconf, char *str)
-{
- rewrite_server_conf *sconf;
- rewritecond_entry *new;
- regex_t *regexp;
- char *a1;
- char *a2;
- char *a3;
- char *cp;
- const char *err;
- int rc;
-
- sconf = (rewrite_server_conf *)get_module_config(cmd->server->module_config, &rewrite_module);
-
- /* make a new entry in the internal temporary rewrite rule list */
- if (cmd->path == NULL) /* is server command */
- new = push_array(sconf->rewriteconds);
- else /* is per-directory command */
- new = push_array(dconf->rewriteconds);
-
- /* parse the argument line ourself */
- if (parseargline(str, &a1, &a2, &a3))
- return pstrcat(cmd->pool, "RewriteCond: bad argument line '", str, "'\n", NULL);
-
- /* arg1: the input string */
- new->input = pstrdup(cmd->pool, a1);
-
- /* arg3: optional flags field
- (this have to be first parsed, because we need to
- know if the regex should be compiled with ICASE!) */
- new->flags = CONDFLAG_NONE;
- if (a3 != NULL) {
- if ((err = cmd_rewritecond_parseflagfield(cmd->pool, new, a3)) != NULL)
- return err;
- }
-
- /* arg2: the pattern
- try to compile the regexp to test if is ok */
- cp = a2;
- if (cp[0] == '!') {
- new->flags |= CONDFLAG_NOTMATCH;
- cp++;
- }
-
- /* now be careful: Under the POSIX regex library
- we can compile the pattern for case-insensitive matching,
- under the old V8 library we have to do it self via a hack */
- if (new->flags & CONDFLAG_NOCASE)
- rc = ((regexp = pregcomp(cmd->pool, cp, REG_EXTENDED|REG_ICASE)) == NULL);
- else
- rc = ((regexp = pregcomp(cmd->pool, cp, REG_EXTENDED)) == NULL);
- if (rc)
- return pstrcat(cmd->pool, "RewriteCond: cannot compile regular expression '", a2, "'\n", NULL);
- new->pattern = pstrdup(cmd->pool, cp);
- new->regexp = regexp;
-
- return NULL;
-}
-
-static const char *cmd_rewritecond_parseflagfield(pool *p, rewritecond_entry *cfg, char *str)
-{
- char *cp;
- char *cp1;
- char *cp2;
- char *cp3;
- char *key;
- char *val;
- const char *err;
-
- if (str[0] != '[' || str[strlen(str)-1] != ']')
- return pstrdup(p, "RewriteCond: bad flag delimiters");
-
- cp = str+1;
- str[strlen(str)-1] = ','; /* for simpler parsing */
- for ( ; *cp != '\0'; ) {
- /* skip whitespaces */
- for ( ; (*cp == ' ' || *cp == '\t') && *cp != '\0'; cp++)
- ;
- if (*cp == '\0')
- break;
- cp1 = cp;
- if ((cp2 = strchr(cp, ',')) != NULL) {
- cp = cp2+1;
- for ( ; (*(cp2-1) == ' ' || *(cp2-1) == '\t'); cp2--)
- ;
- *cp2 = '\0';
- if ((cp3 = strchr(cp1, '=')) != NULL) {
- *cp3 = '\0';
- key = cp1;
- val = cp3+1;
- }
- else {
- key = cp1;
- val = "";
- }
- if ((err = cmd_rewritecond_setflag(p, cfg, key, val)) != NULL)
- return err;
- }
- else
- break;
- }
-
- return NULL;
-}
-
-static const char *cmd_rewritecond_setflag(pool *p, rewritecond_entry *cfg, char *key, char *val)
-{
- if ( strcasecmp(key, "nocase") == 0
- || strcasecmp(key, "NC") == 0 ) {
- cfg->flags |= CONDFLAG_NOCASE;
- }
- else if ( strcasecmp(key, "ornext") == 0
- || strcasecmp(key, "OR") == 0 ) {
- cfg->flags |= CONDFLAG_ORNEXT;
- }
- else {
- return pstrcat(p, "RewriteCond: unknown flag '", key, "'\n", NULL);
- }
- return NULL;
-}
-
-/* NON static */
-const char *cmd_rewriterule(cmd_parms *cmd, rewrite_perdir_conf *dconf, char *str)
-{
- rewrite_server_conf *sconf;
- rewriterule_entry *new;
- regex_t *regexp;
- char *a1;
- char *a2;
- char *a3;
- char *cp;
- const char *err;
-
- sconf = (rewrite_server_conf *)get_module_config(cmd->server->module_config, &rewrite_module);
-
- /* make a new entry in the internal rewrite rule list */
- if (cmd->path == NULL) /* is server command */
- new = push_array(sconf->rewriterules);
- else /* is per-directory command */
- new = push_array(dconf->rewriterules);
-
- /* parse the argument line ourself */
- if (parseargline(str, &a1, &a2, &a3))
- return pstrcat(cmd->pool, "RewriteRule: bad argument line '", str, "'\n", NULL);
-
- /* arg1: the pattern
- try to compile the regexp to test if is ok */
- new->flags = RULEFLAG_NONE;
- cp = a1;
- if (cp[0] == '!') {
- new->flags |= RULEFLAG_NOTMATCH;
- cp++;
- }
- if ((regexp = pregcomp(cmd->pool, cp, REG_EXTENDED)) == NULL)
- return pstrcat(cmd->pool, "RewriteRule: cannot compile regular expression '", a1, "'\n", NULL);
- new->pattern = pstrdup(cmd->pool, cp);
- new->regexp = regexp;
-
- /* arg2: the output string
- replace the $<N> by \<n> which is needed by the currently
- used Regular Expression library */
- new->output = pstrdup(cmd->pool, a2);
-
- /* arg3: optional flags field */
- new->forced_mimetype = NULL;
- new->forced_responsecode = HTTP_MOVED_TEMPORARILY;
- new->env[0] = NULL;
- new->skip = 0;
- if (a3 != NULL) {
- if ((err = cmd_rewriterule_parseflagfield(cmd->pool, new, a3)) != NULL)
- return err;
- }
-
- /* now, if the server or per-dir config holds an
- array of RewriteCond entries, we take it for us
- and clear the array */
- if (cmd->path == NULL) { /* is server command */
- new->rewriteconds = sconf->rewriteconds;
- sconf->rewriteconds = make_array(cmd->pool, 2, sizeof(rewritecond_entry));
- }
- else { /* is per-directory command */
- new->rewriteconds = dconf->rewriteconds;
- dconf->rewriteconds = make_array(cmd->pool, 2, sizeof(rewritecond_entry));
- }
-
- return NULL;
-}
-
-static const char *cmd_rewriterule_parseflagfield(pool *p, rewriterule_entry *cfg, char *str)
-{
- char *cp;
- char *cp1;
- char *cp2;
- char *cp3;
- char *key;
- char *val;
- const char *err;
-
- if (str[0] != '[' || str[strlen(str)-1] != ']')
- return pstrdup(p, "RewriteRule: bad flag delimiters");
-
- cp = str+1;
- str[strlen(str)-1] = ','; /* for simpler parsing */
- for ( ; *cp != '\0'; ) {
- /* skip whitespaces */
- for ( ; (*cp == ' ' || *cp == '\t') && *cp != '\0'; cp++)
- ;
- if (*cp == '\0')
- break;
- cp1 = cp;
- if ((cp2 = strchr(cp, ',')) != NULL) {
- cp = cp2+1;
- for ( ; (*(cp2-1) == ' ' || *(cp2-1) == '\t'); cp2--)
- ;
- *cp2 = '\0';
- if ((cp3 = strchr(cp1, '=')) != NULL) {
- *cp3 = '\0';
- key = cp1;
- val = cp3+1;
- }
- else {
- key = cp1;
- val = "";
- }
- if ((err = cmd_rewriterule_setflag(p, cfg, key, val)) != NULL)
- return err;
- }
- else
- break;
- }
-
- return NULL;
-}
-
-static const char *cmd_rewriterule_setflag(pool *p, rewriterule_entry *cfg, char *key, char *val)
-{
- int status = 0;
- int i;
-
- if ( strcasecmp(key, "redirect") == 0
- || strcasecmp(key, "R") == 0 ) {
- cfg->flags |= RULEFLAG_FORCEREDIRECT;
- if (strlen(val) > 0) {
- if (strcasecmp(val, "permanent") == 0)
- status = HTTP_MOVED_PERMANENTLY;
- else if (strcasecmp(val, "temp") == 0)
- status = HTTP_MOVED_TEMPORARILY;
- else if (strcasecmp(val, "seeother") == 0)
- status = HTTP_SEE_OTHER;
- else if (isdigit(*val))
- status = atoi(val);
- if (!is_HTTP_REDIRECT(status))
- return pstrdup(p, "RewriteRule: invalid HTTP response code for flag 'R'");
- cfg->forced_responsecode = status;
- }
- }
- else if ( strcasecmp(key, "last") == 0
- || strcasecmp(key, "L") == 0 ) {
- cfg->flags |= RULEFLAG_LASTRULE;
- }
- else if ( strcasecmp(key, "next") == 0
- || strcasecmp(key, "N") == 0 ) {
- cfg->flags |= RULEFLAG_NEWROUND;
- }
- else if ( strcasecmp(key, "chain") == 0
- || strcasecmp(key, "C") == 0 ) {
- cfg->flags |= RULEFLAG_CHAIN;
- }
- else if ( strcasecmp(key, "type") == 0
- || strcasecmp(key, "T") == 0 ) {
- cfg->forced_mimetype = pstrdup(p, val);
- }
- else if ( strcasecmp(key, "env") == 0
- || strcasecmp(key, "E") == 0 ) {
- for (i = 0; (cfg->env[i] != NULL) && (i < MAX_ENV_FLAGS); i++)
- ;
- if (i < MAX_ENV_FLAGS) {
- cfg->env[i] = pstrdup(p, val);
- cfg->env[i+1] = NULL;
- }
- else
- return pstrdup(p, "RewriteRule: to much environment flags 'E'");
- }
- else if ( strcasecmp(key, "nosubreq") == 0
- || strcasecmp(key, "NS") == 0 ) {
- cfg->flags |= RULEFLAG_IGNOREONSUBREQ;
- }
- else if ( strcasecmp(key, "proxy") == 0
- || strcasecmp(key, "P") == 0 ) {
- cfg->flags |= RULEFLAG_PROXY;
- }
- else if ( strcasecmp(key, "passthrough") == 0
- || strcasecmp(key, "PT") == 0 ) {
- cfg->flags |= RULEFLAG_PASSTHROUGH;
- }
- else if ( strcasecmp(key, "skip") == 0
- || strcasecmp(key, "S") == 0 ) {
- cfg->skip = atoi(val);
- }
- else if ( strcasecmp(key, "forbidden") == 0
- || strcasecmp(key, "F") == 0 ) {
- cfg->flags |= RULEFLAG_FORBIDDEN;
- }
- else if ( strcasecmp(key, "gone") == 0
- || strcasecmp(key, "G") == 0 ) {
- cfg->flags |= RULEFLAG_GONE;
- }
- else if ( strcasecmp(key, "qsappend") == 0
- || strcasecmp(key, "QSA") == 0 ) {
- cfg->flags |= RULEFLAG_QSAPPEND;
- }
- else {
- return pstrcat(p, "RewriteRule: unknown flag '", key, "'\n", NULL);
- }
- return NULL;
-}
-
-
-/*
-**
-** module initialisation
-** [called from read_config() after all
-** config commands were already called]
-**
-*/
-
-static void init_module(server_rec *s, pool *p)
-{
- /* step through the servers and
- - open eachs rewriting logfile
- - open the RewriteMap prg:xxx programs */
- for (; s; s = s->next) {
- open_rewritelog(s, p);
- run_rewritemap_programs(s, p);
- }
-
- /* create the lookup cache */
- cachep = init_cache(p);
-
- /* check if proxy module is available */
- proxy_available = is_proxy_available(s);
-
- /* precompile a static pattern
- for the txt mapfile parsing */
- lookup_map_txtfile_regexp = pregcomp(p, MAPFILE_PATTERN, REG_EXTENDED);
-}
-
-
-
-
-/*
-** +-------------------------------------------------------+
-** | |
-** | runtime hooks
-** | |
-** +-------------------------------------------------------+
-*/
-
-
-/*
-**
-** URI-to-filename hook
-**
-** [used for the rewriting engine triggered by
-** the per-server 'RewriteRule' directives]
-**
-*/
-
-static int hook_uri2file(request_rec *r)
-{
- void *sconf;
- rewrite_server_conf *conf;
- char *var;
- char *thisserver, *thisport, *thisurl;
- char buf[512];
- char docroot[512];
- char *cp, *cp2;
- struct stat finfo;
- int n;
- int l;
-
- /*
- * retrieve the config structures
- */
- sconf = r->server->module_config;
- conf = (rewrite_server_conf *)get_module_config(sconf, &rewrite_module);
-
- /*
- * only do something under runtime if the engine is really enabled,
- * else return immediately!
- */
- if (conf->state == ENGINE_DISABLED)
- return DECLINED;
-
- /*
- * add the SCRIPT_URL variable to the env. this is a bit complicated
- * due to the fact that apache uses subrequests and internal redirects
- */
-
- if (r->main == NULL) {
- var = pstrcat(r->pool, "REDIRECT_", ENVVAR_SCRIPT_URL, NULL);
- var = table_get(r->subprocess_env, var);
- if (var == NULL)
- table_set(r->subprocess_env, ENVVAR_SCRIPT_URL, pstrdup(r->pool, r->uri));
- else
- table_set(r->subprocess_env, ENVVAR_SCRIPT_URL, pstrdup(r->pool, var));
- }
- else {
- var = table_get(r->main->subprocess_env, ENVVAR_SCRIPT_URL);
- table_set(r->subprocess_env, ENVVAR_SCRIPT_URL, pstrdup(r->pool, var));
- }
-
- /*
- * create the SCRIPT_URI variable for the env
- */
-
- /* add the canonical URI of this URL */
- thisserver = r->server->server_hostname;
-#ifdef APACHE_SSL
- if (((!r->connection->client->ssl) && (r->server->port == DEFAULT_PORT)) ||
- ((r->connection->client->ssl) && (r->server->port == 443)))
-#else
- if (r->server->port == DEFAULT_PORT)
-#endif
- thisport = "";
- else {
- ap_snprintf(buf, sizeof(buf), ":%u", r->server->port);
- thisport = pstrdup(r->pool, buf);
- }
- thisurl = table_get(r->subprocess_env, ENVVAR_SCRIPT_URL);
-
- /* set the variable */
-#ifdef APACHE_SSL
- var = pstrcat(r->pool, http_method(r), "://", thisserver, thisport, thisurl, NULL);
-#else
- var = pstrcat(r->pool, "http://", thisserver, thisport, thisurl, NULL);
-#endif
- table_set(r->subprocess_env, ENVVAR_SCRIPT_URI, pstrdup(r->pool, var));
-
-
- /* if filename was not initially set,
- we start with the requested URI */
- if (r->filename == NULL) {
- r->filename = pstrdup(r->pool, r->uri);
- rewritelog(r, 2, "init rewrite engine with requested uri %s", r->filename);
- }
-
- /*
- * now apply the rules ...
- */
- if (apply_rewrite_list(r, conf->rewriterules, NULL)) {
-
- if (strlen(r->filename) > 6 &&
- strncmp(r->filename, "proxy:", 6) == 0) {
- /* it should be go on as an internal proxy request */
-
- /* check if the proxy module is enabled, so
- we can actually use it! */
- if (!proxy_available) {
- log_reason("attempt to make remote request from mod_rewrite "
- "without proxy enabled", r->filename, r);
- return FORBIDDEN;
- }
-
- /* make sure the QUERY_STRING and
- PATH_INFO parts get incorporated */
- r->filename = pstrcat(r->pool, r->filename,
- r->path_info ? r->path_info : "",
- r->args ? "?" : NULL, r->args,
- NULL);
-
- /* now make sure the request gets handled by the
- proxy handler */
- r->proxyreq = 1;
- r->handler = "proxy-server";
-
- rewritelog(r, 1, "go-ahead with proxy request %s [OK]", r->filename);
- return OK;
- }
- else if ( (strlen(r->filename) > 7 &&
- strncasecmp(r->filename, "http://", 7) == 0)
- || (strlen(r->filename) > 8 &&
- strncasecmp(r->filename, "https://", 8) == 0)
- || (strlen(r->filename) > 9 &&
- strncasecmp(r->filename, "gopher://", 9) == 0)
- || (strlen(r->filename) > 6 &&
- strncasecmp(r->filename, "ftp://", 6) == 0) ) {
- /* it was finally rewritten to a remote URL */
-
- /* skip 'scheme:' */
- for (cp = r->filename; *cp != ':' && *cp != '\0'; cp++)
- ;
- /* skip '://' */
- cp += 3;
- /* skip host part */
- for ( ; *cp != '/' && *cp != '\0'; cp++)
- ;
- if (*cp != '\0') {
- rewritelog(r, 1, "escaping %s for redirect", r->filename);
- cp2 = escape_uri(r->pool, cp);
- *cp = '\0';
- r->filename = pstrcat(r->pool, r->filename, cp2, NULL);
- }
-
- /* append the QUERY_STRING part */
- if (r->args != NULL)
- r->filename = pstrcat(r->pool, r->filename, "?", r->args, NULL);
-
- /* determine HTTP redirect response code */
- if (is_HTTP_REDIRECT(r->status)) {
- n = r->status;
- r->status = HTTP_OK; /* make Apache kernel happy */
- }
- else
- n = REDIRECT;
-
- /* now do the redirection */
- table_set(r->headers_out, "Location", r->filename);
- rewritelog(r, 1, "redirect to %s [REDIRECT/%d]", r->filename, n);
- return n;
- }
- else if (strlen(r->filename) > 10 &&
- strncmp(r->filename, "forbidden:", 10) == 0) {
- /* This URLs is forced to be forbidden for the requester */
- return FORBIDDEN;
- }
- else if (strlen(r->filename) > 5 &&
- strncmp(r->filename, "gone:", 5) == 0) {
- /* This URLs is forced to be gone */
- return HTTP_GONE;
- }
- else if (strlen(r->filename) > 12 &&
- strncmp(r->filename, "passthrough:", 12) == 0) {
- /* Hack because of underpowered API: passing the current
- rewritten filename through to other URL-to-filename handlers
- just as it were the requested URL. This is to enable
- post-processing by mod_alias, etc. which always act on
- r->uri! The difference here is: We do not try to
- add the document root */
- r->uri = pstrdup(r->pool, r->filename+12);
- return DECLINED;
- }
- else {
- /* it was finally rewritten to a local path */
-
- /* expand "/~user" prefix */
- r->filename = expand_tildepaths(r, r->filename);
-
- rewritelog(r, 2, "local path result: %s", r->filename);
-
- /* the filename has to start with a slash! */
- if (r->filename[0] != '/')
- return BAD_REQUEST;
-
- /* if there is no valid prefix, we have
- to emulate the translator from the core and
- prefix the filename with document_root
-
- NOTICE:
- We cannot leave out the prefix_stat because
- - when we always prefix with document_root
- then no absolute path can be created, e.g. via
- emulating a ScriptAlias directive, etc.
- - when we always NOT prefix with document_root
- then the files under document_root have to
- be references directly and document_root
- gets never used and will be a dummy parameter -
- this is also bad
-
- BUT:
- Under real Unix systems this is no problem,
- because we only do stat() on the first directory
- and this gets cached by the kernel for along time!
- */
- n = prefix_stat(r->filename, &finfo);
- if (n == 0) {
- if ((cp = document_root(r)) != NULL) {
- strncpy(docroot, cp, sizeof(docroot)-1);
- EOS_PARANOIA(docroot);
-
- /* always NOT have a trailing slash */
- l = strlen(docroot);
- if (docroot[l-1] == '/') {
- docroot[l-1] = '\0';
- }
- if (r->server->path && !strncmp(r->filename, r->server->path, r->server->pathlen))
- r->filename = pstrcat(r->pool, docroot, (r->filename + r->server->pathlen), NULL);
- else
- r->filename = pstrcat(r->pool, docroot, r->filename, NULL);
- rewritelog(r, 2, "prefixed with document_root to %s", r->filename);
- }
- }
-
- rewritelog(r, 1, "go-ahead with %s [OK]", r->filename);
- return OK;
- }
- }
- else {
- rewritelog(r, 1, "pass through %s", r->filename);
- return DECLINED;
- }
-}
-
-
-/*
-**
-** MIME-type hook
-**
-** [used to support the forced-MIME-type feature]
-**
-*/
-
-static int hook_mimetype(request_rec *r)
-{
- char *t;
-
- /* now check if we have to force a MIME-type */
- t = table_get(r->notes, REWRITE_FORCED_MIMETYPE_NOTEVAR);
- if (t == NULL)
- return DECLINED;
- else {
- rewritelog(r, 1, "force filename %s to have MIME-type '%s'", r->filename, t);
- r->content_type = t;
- return OK;
- }
-}
-
-
-/*
-**
-** Fixup hook
-**
-** [used for the rewriting engine triggered by
-** the per-directory 'RewriteRule' directives]
-**
-*/
-
-static int hook_fixup(request_rec *r)
-{
- rewrite_perdir_conf *dconf;
- char *cp;
- char *cp2;
- char *prefix;
- int l;
- int n;
- char *ofilename;
-
- dconf = (rewrite_perdir_conf *)get_module_config(r->per_dir_config, &rewrite_module);
-
- /* if there is no per-dir config we return immediately */
- if (dconf == NULL)
- return DECLINED;
-
- /* we shouldn't do anything in subrequests */
- if (r->main != NULL)
- return DECLINED;
-
- /* if there are no real (i.e. no RewriteRule directives!)
- per-dir config of us, we return also immediately */
- if (dconf->directory == NULL)
- return DECLINED;
-
- /*
- * only do something under runtime if the engine is really enabled,
- * for this directory, else return immediately!
- */
- if (!(allow_options(r) & (OPT_SYM_LINKS | OPT_SYM_OWNER))) {
- /* FollowSymLinks is mandatory! */
- log_reason("Options FollowSymLinks or SymLinksIfOwnerMatch is off which implies that RewriteRule directive is forbidden", r->filename, r);
- return FORBIDDEN;
- }
- else {
- /* FollowSymLinks is given, but the user can
- still turn off the rewriting engine */
- if (dconf->state == ENGINE_DISABLED)
- return DECLINED;
- }
-
- /*
- * remember the current filename before rewriting for later check
- * to prevent deadlooping because of internal redirects
- * on final URL/filename which can be equal to the inital one.
- */
- ofilename = r->filename;
-
- /*
- * now apply the rules ...
- */
- if (apply_rewrite_list(r, dconf->rewriterules, dconf->directory)) {
-
- if (strlen(r->filename) > 6 &&
- strncmp(r->filename, "proxy:", 6) == 0) {
- /* it should go on as an internal proxy request */
-
- /* make sure the QUERY_STRING and
- PATH_INFO parts get incorporated */
- r->filename = pstrcat(r->pool, r->filename,
- /* r->path_info was already
- appended by the rewriting engine
- because of the per-dir context! */
- r->args ? "?" : NULL, r->args,
- NULL);
-
- /* now make sure the request gets handled by the
- proxy handler */
- r->proxyreq = 1;
- r->handler = "proxy-server";
-
- rewritelog(r, 1, "[per-dir %s] go-ahead with proxy request %s [OK]", dconf->directory, r->filename);
- return OK;
- }
- else if ( (strlen(r->filename) > 7 &&
- strncasecmp(r->filename, "http://", 7) == 0)
- || (strlen(r->filename) > 8 &&
- strncasecmp(r->filename, "https://", 8) == 0)
- || (strlen(r->filename) > 9 &&
- strncasecmp(r->filename, "gopher://", 9) == 0)
- || (strlen(r->filename) > 6 &&
- strncasecmp(r->filename, "ftp://", 6) == 0) ) {
- /* it was finally rewritten to a remote URL */
-
- /* because we are in a per-dir context
- first try to replace the directory with its base-URL
- if there is a base-URL available */
- if (dconf->baseurl != NULL) {
- /* skip 'scheme:' */
- for (cp = r->filename; *cp != ':' && *cp != '\0'; cp++)
- ;
- /* skip '://' */
- cp += 3;
- if ((cp = strchr(cp, '/')) != NULL) {
- rewritelog(r, 2, "[per-dir %s] trying to replace prefix %s with %s", dconf->directory, dconf->directory, dconf->baseurl);
- cp2 = subst_prefix_path(r, cp, dconf->directory, dconf->baseurl);
- if (strcmp(cp2, cp) != 0) {
- *cp = '\0';
- r->filename = pstrcat(r->pool, r->filename, cp2, NULL);
- }
- }
- }
-
- /* now prepare the redirect... */
-
- /* skip 'scheme:' */
- for (cp = r->filename; *cp != ':' && *cp != '\0'; cp++)
- ;
- /* skip '://' */
- cp += 3;
- /* skip host part */
- for ( ; *cp != '/' && *cp != '\0'; cp++)
- ;
- if (*cp != '\0') {
- rewritelog(r, 1, "[per-dir %s] escaping %s for redirect", dconf->directory, r->filename);
- cp2 = escape_uri(r->pool, cp);
- *cp = '\0';
- r->filename = pstrcat(r->pool, r->filename, cp2, NULL);
- }
-
- /* append the QUERY_STRING part */
- if (r->args != NULL)
- r->filename = pstrcat(r->pool, r->filename, "?", r->args, NULL);
-
- /* determine HTTP redirect response code */
- if (is_HTTP_REDIRECT(r->status)) {
- n = r->status;
- r->status = HTTP_OK; /* make Apache kernel happy */
- }
- else
- n = REDIRECT;
-
- /* now do the redirection */
- table_set(r->headers_out, "Location", r->filename);
- rewritelog(r, 1, "[per-dir %s] redirect to %s [REDIRECT/%d]", dconf->directory, r->filename, n);
- return n;
- }
- else if (strlen(r->filename) > 10 &&
- strncmp(r->filename, "forbidden:", 10) == 0) {
- /* This URLs is forced to be forbidden for the requester */
- return FORBIDDEN;
- }
- else if (strlen(r->filename) > 5 &&
- strncmp(r->filename, "gone:", 5) == 0) {
- /* This URLs is forced to be gone */
- return HTTP_GONE;
- }
- else {
- /* it was finally rewritten to a local path */
-
- /* if someone used the PASSTHROUGH flag in per-dir
- context we just ignore it. It is only useful
- in per-server context */
- if (strlen(r->filename) > 12 &&
- strncmp(r->filename, "passthrough:", 12) == 0) {
- r->filename = pstrdup(r->pool, r->filename+12);
- }
-
- /* the filename has to start with a slash! */
- if (r->filename[0] != '/')
- return BAD_REQUEST;
-
- /* Check for deadlooping:
- * At this point we KNOW that at least one rewriting
- * rule was applied, but when the resulting URL is
- * the same as the initial URL, we are not allowed to
- * use the following internal redirection stuff because
- * this would lead to a deadloop.
- */
- if (strcmp(r->filename, ofilename) == 0) {
- rewritelog(r, 1, "[per-dir %s] initial URL equal rewritten URL: %s [IGNORING REWRITE]", dconf->directory, r->filename);
- return OK;
- }
-
- /* if there is a valid base-URL then substitute
- the per-dir prefix with this base-URL if the
- current filename still is inside this per-dir
- context. If not then treat the result as a
- plain URL */
- if (dconf->baseurl != NULL) {
- rewritelog(r, 2, "[per-dir %s] trying to replace prefix %s with %s", dconf->directory, dconf->directory, dconf->baseurl);
- r->filename = subst_prefix_path(r, r->filename, dconf->directory, dconf->baseurl);
- }
- else {
- /* if no explicit base-URL exists we assume
- that the directory prefix is also a valid URL
- for this webserver and only try to remove the
- document_root if it is prefix */
-
- if ((cp = document_root(r)) != NULL) {
- prefix = pstrdup(r->pool, cp);
- /* always NOT have a trailing slash */
- l = strlen(prefix);
- if (prefix[l-1] == '/') {
- prefix[l-1] = '\0';
- l--;
- }
- if (strncmp(r->filename, prefix, l) == 0) {
- rewritelog(r, 2, "[per-dir %s] strip document_root prefix: %s -> %s", dconf->directory, r->filename, r->filename+l);
- r->filename = pstrdup(r->pool, r->filename+l);
- }
- }
- }
-
- /* now initiate the internal redirect */
- rewritelog(r, 1, "[per-dir %s] internal redirect with %s [INTERNAL REDIRECT]", dconf->directory, r->filename);
- r->filename = pstrcat(r->pool, "redirect:", r->filename, NULL);
- r->handler = "redirect-handler";
- return OK;
- }
- }
- else {
- rewritelog(r, 1, "[per-dir %s] pass through %s", dconf->directory, r->filename);
- return DECLINED;
- }
-}
-
-
-/*
-**
-** Content-Handlers
-**
-** [used for redirect support]
-**
-*/
-
-static int handler_redirect(request_rec *r)
-{
- /* just make sure that we are really meant! */
- if (strncmp(r->filename, "redirect:", 9) != 0)
- return DECLINED;
-
- /* now do the internal redirect */
- internal_redirect(pstrcat(r->pool, r->filename+9,
- r->args ? "?" : NULL, r->args, NULL), r);
-
- /* and return gracefully */
- return OK;
-}
-
-
-
-
-/*
-** +-------------------------------------------------------+
-** | |
-** | rewriting engine
-** | |
-** +-------------------------------------------------------+
-*/
-
-
-static int apply_rewrite_list(request_rec *r, array_header *rewriterules, char *perdir)
-{
- rewriterule_entry *entries;
- rewriterule_entry *p;
- int i;
- int changed;
- int rc;
- int s;
-
- entries = (rewriterule_entry *)rewriterules->elts;
- changed = 0;
- loop:
- for (i = 0; i < rewriterules->nelts; i++) {
- p = &entries[i];
-
- /* ignore this rule on subrequests if we are explicitly asked to do so
- or this is a proxy throughput or a forced redirect rule */
- if (r->main != NULL &&
- (p->flags & RULEFLAG_IGNOREONSUBREQ ||
- p->flags & RULEFLAG_PROXY ||
- p->flags & RULEFLAG_FORCEREDIRECT ))
- continue;
-
- /* apply the current rule */
- rc = apply_rewrite_rule(r, p, perdir);
- if (rc) {
- if (rc != 2) /* not a match-only rule */
- changed = 1;
- if (p->flags & RULEFLAG_PASSTHROUGH) {
- rewritelog(r, 2, "forcing '%s' to get passed through to next URI-to-filename handler", r->filename);
- r->filename = pstrcat(r->pool, "passthrough:", r->filename, NULL);
- changed = 1;
- break;
- }
- if (p->flags & RULEFLAG_FORBIDDEN) {
- rewritelog(r, 2, "forcing '%s' to be forbidden", r->filename);
- r->filename = pstrcat(r->pool, "forbidden:", r->filename, NULL);
- changed = 1;
- break;
- }
- if (p->flags & RULEFLAG_GONE) {
- rewritelog(r, 2, "forcing '%s' to be gone", r->filename);
- r->filename = pstrcat(r->pool, "gone:", r->filename, NULL);
- changed = 1;
- break;
- }
- if (p->flags & RULEFLAG_PROXY)
- break;
- if (p->flags & RULEFLAG_LASTRULE)
- break;
- if (p->flags & RULEFLAG_NEWROUND)
- goto loop;
-
- /* if we are forced to skip N next rules, do it now */
- if (p->skip > 0) {
- s = p->skip;
- while ( i < rewriterules->nelts
- && s > 0) {
- i++;
- p = &entries[i];
- s--;
- }
- }
- }
- else {
- /* if current rule is chained with next rule(s),
- skip all this next rule(s) */
- while ( i < rewriterules->nelts
- && p->flags & RULEFLAG_CHAIN) {
- i++;
- p = &entries[i];
- }
- }
- }
- return changed;
-}
-
-static int apply_rewrite_rule(request_rec *r, rewriterule_entry *p, char *perdir)
-{
- char *uri;
- char *output;
- int flags;
- char newuri[MAX_STRING_LEN];
- char env[MAX_STRING_LEN];
- char port[32];
- char env2[MAX_STRING_LEN];
- regex_t *regexp;
- regmatch_t regmatch[10];
- int rc;
- int prefixstrip;
- int i;
- int failed;
- array_header *rewriteconds;
- rewritecond_entry *conds;
- rewritecond_entry *c;
-
- uri = r->filename;
- regexp = p->regexp;
- output = p->output;
- flags = p->flags;
-
- if (perdir != NULL && r->path_info != NULL && r->path_info[0] != '\0') {
- rewritelog(r, 3, "[per-dir %s] add path-info postfix: %s -> %s%s", perdir, uri, uri, r->path_info);
- uri = pstrcat(r->pool, uri, r->path_info, NULL);
- }
-
- prefixstrip = 0;
- if (perdir != NULL) {
- /* this is a per-directory match */
- if ( strlen(uri) >= strlen(perdir)
- && strncmp(uri, perdir, strlen(perdir)) == 0) {
- rewritelog(r, 3, "[per-dir %s] strip per-dir prefix: %s -> %s", perdir, uri, uri+strlen(perdir));
- uri = uri+strlen(perdir);
- prefixstrip = 1;
- }
- }
-
- if (perdir != NULL)
- rewritelog(r, 3, "[per-dir %s] applying pattern '%s' to uri '%s'", perdir, p->pattern, uri);
-
- rc = (regexec(regexp, uri, regexp->re_nsub+1, regmatch, 0) == 0); /* try to match the pattern */
- if (( rc && !(p->flags & RULEFLAG_NOTMATCH)) ||
- (!rc && (p->flags & RULEFLAG_NOTMATCH)) ) {
-
- /* ok, the pattern matched, but we now additionally have to check
- for any preconditions which have to be also true. We do this
- at this very late stage to avoid unnessesary checks which
- slow down the rewriting engine!! */
- rewriteconds = p->rewriteconds;
- conds = (rewritecond_entry *)rewriteconds->elts;
- failed = 0;
- for (i = 0; i < rewriteconds->nelts; i++) {
- c = &conds[i];
- rc = apply_rewrite_cond(r, c, perdir);
- if (c->flags & CONDFLAG_ORNEXT) {
- /* there is a "or" flag */
- if (rc == 0) {
- /* one cond is false, but another can be true... */
- continue;
- }
- else {
- /* one true cond is enough, so skip the other conds
- of the "ornext" chained conds */
- while ( i < rewriteconds->nelts
- && c->flags & CONDFLAG_ORNEXT) {
- i++;
- c = &conds[i];
- }
- continue;
- }
- }
- else {
- /* no "or" flag, so a single fail means total fail */
- if (rc == 0) { /* failed */
- failed = 1;
- break;
- }
- }
- }
- if (failed)
- return 0; /* if any condition fails this complete rule fails */
-
- /* if this is a pure matching rule we return immediately */
- if (strcmp(output, "-") == 0) {
- /* but before we set the env variables... */
- for (i = 0; p->env[i] != NULL; i++) {
- strncpy(env2, p->env[i], sizeof(env2)-1);
- EOS_PARANOIA(env2);
- strncpy(env, pregsub(r->pool, env2, uri, regexp->re_nsub+1, regmatch), sizeof(env)-1); /* substitute in output */
- EOS_PARANOIA(env);
- add_env_variable(r, env);
- }
- return 2;
- }
-
- /* if this is a forced proxy request ... */
- if (p->flags & RULEFLAG_PROXY) {
- if (p->flags & RULEFLAG_NOTMATCH) {
- output = pstrcat(r->pool, "proxy:", output, NULL);
- strncpy(newuri, output, sizeof(newuri)-1);
- EOS_PARANOIA(newuri);
- expand_variables_inbuffer(r, newuri, sizeof(newuri));/* expand %{...} */
- expand_map_lookups(r, newuri, sizeof(newuri)); /* expand ${...} */
- }
- else {
- output = pstrcat(r->pool, "proxy:", output, NULL);
- strncpy(newuri, pregsub(r->pool, output, uri, regexp->re_nsub+1, regmatch), sizeof(newuri)-1); /* substitute in output */
- EOS_PARANOIA(newuri);
- for (i = 0; p->env[i] != NULL; i++) {
- strncpy(env2, p->env[i], sizeof(env2)-1);
- EOS_PARANOIA(env2);
- strncpy(env, pregsub(r->pool, env2, uri, regexp->re_nsub+1, regmatch), sizeof(env)-1); /* substitute in output */
- EOS_PARANOIA(env);
- add_env_variable(r, env);
- }
- expand_variables_inbuffer(r, newuri, sizeof(newuri)); /* expand %{...} */
- expand_map_lookups(r, newuri, sizeof(newuri)); /* expand ${...} */
- }
- if (perdir == NULL)
- rewritelog(r, 2, "rewrite %s -> %s", r->filename, newuri);
- else
- rewritelog(r, 2, "[per-dir %s] rewrite %s -> %s", perdir, r->filename, newuri);
- r->filename = pstrdup(r->pool, newuri);
- return 1;
- }
-
- /* if this is an implicit redirect in a per-dir rule */
- i = strlen(output);
- if (perdir != NULL
- && ( (i > 7 && strncasecmp(output, "http://", 7) == 0)
- || (i > 8 && strncasecmp(output, "https://", 8) == 0)
- || (i > 9 && strncasecmp(output, "gopher://", 9) == 0)
- || (i > 6 && strncasecmp(output, "ftp://", 6) == 0) ) ) {
- if (p->flags & RULEFLAG_NOTMATCH) {
- strncpy(newuri, output, sizeof(newuri)-1);
- EOS_PARANOIA(newuri);
- expand_variables_inbuffer(r, newuri, sizeof(newuri));/* expand %{...} */
- expand_map_lookups(r, newuri, sizeof(newuri)); /* expand ${...} */
- }
- else {
- strncpy(newuri, pregsub(r->pool, output, uri, regexp->re_nsub+1, regmatch), sizeof(newuri)-1); /* substitute in output */
- EOS_PARANOIA(newuri);
- for (i = 0; p->env[i] != NULL; i++) {
- strncpy(env2, p->env[i], sizeof(env2)-1);
- EOS_PARANOIA(env2);
- strncpy(env, pregsub(r->pool, env2, uri, regexp->re_nsub+1, regmatch), sizeof(env)-1); /* substitute in output */
- EOS_PARANOIA(env);
- add_env_variable(r, env);
- }
- expand_variables_inbuffer(r, newuri, sizeof(newuri));/* expand %{...} */
- expand_map_lookups(r, newuri, sizeof(newuri)); /* expand ${...} */
- }
- rewritelog(r, 2, "[per-dir %s] redirect %s -> %s", perdir, r->filename, newuri);
- r->filename = pstrdup(r->pool, newuri);
- splitout_queryargs(r, p->flags & RULEFLAG_QSAPPEND);
- r->status = p->forced_responsecode;
- return 1;
- }
-
- /* add again the previously stripped perdir prefix if the new
- URI is not a new one (i.e. prefixed by a slash which means
- that it is not for this per-dir context) */
- if (prefixstrip && output[0] != '/') {
- rewritelog(r, 3, "[per-dir %s] add per-dir prefix: %s -> %s%s", perdir, output, perdir, output);
- output = pstrcat(r->pool, perdir, output, NULL);
- }
-
- if (p->flags & RULEFLAG_NOTMATCH) {
- /* just overtake the URI */
- strncpy(newuri, output, sizeof(newuri)-1);
- EOS_PARANOIA(newuri);
- }
- else {
- /* substitute in output */
- strncpy(newuri, pregsub(r->pool, output, uri, regexp->re_nsub+1, regmatch), sizeof(newuri)-1); /* substitute in output */
- EOS_PARANOIA(newuri);
- for (i = 0; p->env[i] != NULL; i++) {
- strncpy(env2, p->env[i], sizeof(env2)-1);
- EOS_PARANOIA(env2);
- strncpy(env, pregsub(r->pool, env2, uri, regexp->re_nsub+1, regmatch), sizeof(env)-1); /* substitute in output */
- EOS_PARANOIA(env);
- add_env_variable(r, env);
- }
- }
- expand_variables_inbuffer(r, newuri, sizeof(newuri)); /* expand %{...} */
- expand_map_lookups(r, newuri, sizeof(newuri)); /* expand ${...} */
-
- if (perdir == NULL)
- rewritelog(r, 2, "rewrite %s -> %s", uri, newuri);
- else
- rewritelog(r, 2, "[per-dir %s] rewrite %s -> %s", perdir, uri, newuri);
-
- r->filename = pstrdup(r->pool, newuri);
-
- /* reduce http[s]://<ourhost>[:<port>] */
- reduce_uri(r);
-
- /* split out on-the-fly generated QUERY_STRING '....?xxxxx&xxxx...' */
- splitout_queryargs(r, p->flags & RULEFLAG_QSAPPEND);
-
- /* if a MIME-type should be later forced for this URL, then remember this */
- if (p->forced_mimetype != NULL) {
- table_set(r->notes, REWRITE_FORCED_MIMETYPE_NOTEVAR, p->forced_mimetype);
- if (perdir == NULL)
- rewritelog(r, 2, "remember %s to have MIME-type '%s'", r->filename, p->forced_mimetype);
- else
- rewritelog(r, 2, "[per-dir %s] remember %s to have MIME-type '%s'", perdir, r->filename, p->forced_mimetype);
- }
-
- /* if we are forced to do a explicit redirect by [R] flag
- and the current URL still is not a fully qualified one we
- finally prefix it with http[s]://<ourname> explicitly */
- if (flags & RULEFLAG_FORCEREDIRECT) {
- r->status = p->forced_responsecode;
- if ( !(strlen(r->filename) > 7 &&
- strncasecmp(r->filename, "http://", 7) == 0)
- && !(strlen(r->filename) > 8 &&
- strncasecmp(r->filename, "https://", 8) == 0)
- && !(strlen(r->filename) > 9 &&
- strncasecmp(r->filename, "gopher://", 9) == 0)
- && !(strlen(r->filename) > 6 &&
- strncasecmp(r->filename, "ftp://", 6) == 0) ) {
-
-#ifdef APACHE_SSL
- if ((!r->connection->client->ssl && r->server->port == DEFAULT_PORT) ||
- ( r->connection->client->ssl && r->server->port == 443) )
-#else
- if (r->server->port == DEFAULT_PORT)
-#endif
- port[0] = '\0';
- else
- ap_snprintf(port, sizeof(port), ":%u", r->server->port);
- if (r->filename[0] == '/')
-#ifdef APACHE_SSL
- ap_snprintf(newuri, sizeof(newuri), "%s://%s%s%s", http_method(r), r->server->server_hostname, port, r->filename);
-#else
- ap_snprintf(newuri, sizeof(newuri), "http://%s%s%s", r->server->server_hostname, port, r->filename);
-#endif
- else
-#ifdef APACHE_SSL
- ap_snprintf(newuri, sizeof(newuri), "%s://%s%s/%s", http_method(r), r->server->server_hostname, port, r->filename);
-#else
- ap_snprintf(newuri, sizeof(newuri), "http://%s%s/%s", r->server->server_hostname, port, r->filename);
-#endif
- if (perdir == NULL)
- rewritelog(r, 2, "prepare forced redirect %s -> %s", r->filename, newuri);
- else
- rewritelog(r, 2, "[per-dir %s] prepare forced redirect %s -> %s", perdir, r->filename, newuri);
- r->filename = pstrdup(r->pool, newuri);
- return 1;
- }
- }
-
- return 1;
- }
- return 0;
-}
-
-static int apply_rewrite_cond(request_rec *r, rewritecond_entry *p, char *perdir)
-{
- char *input;
- int rc;
- struct stat sb;
- request_rec *rsub;
-
- /* first, we have to expand the input string to match */
- input = expand_variables(r, p->input);
-
- rc = 0;
- if (strcmp(p->pattern, "-f") == 0) {
- if (stat(input, &sb) == 0)
- if (S_ISREG(sb.st_mode))
- rc = 1;
- }
- else if (strcmp(p->pattern, "-s") == 0) {
- if (stat(input, &sb) == 0)
- if (S_ISREG(sb.st_mode) && sb.st_size > 0)
- rc = 1;
- }
- else if (strcmp(p->pattern, "-l") == 0) {
-#ifndef __EMX__
-/* OS/2 dosen't support links. */
- if (stat(input, &sb) == 0)
- if (S_ISLNK(sb.st_mode))
- rc = 1;
-#endif
- }
- else if (strcmp(p->pattern, "-d") == 0) {
- if (stat(input, &sb) == 0)
- if (S_ISDIR(sb.st_mode))
- rc = 1;
- }
- else if (strcmp(p->pattern, "-U") == 0) {
- /* avoid infinite subrequest recursion */
- if (strlen(input) > 0 /* nonempty path, and */
- && ( r->main == NULL /* - either not in a subrequest */
- || ( r->main->uri != NULL /* - or in a subrequest...*/
- && r->uri != NULL /* ...and then URIs aren't NULL... */
- /* ...and sub and main URIs differ */
- && strcmp(r->main->uri, r->uri) != 0) ) ) {
-
- /* run a URI-based subrequest */
- rsub = sub_req_lookup_uri(input, r);
-
- /* URI exists for any result up to 3xx, redirects allowed */
- if (rsub->status < 400)
- rc = 1;
-
- /* log it */
- rewritelog(r, 5, "RewriteCond URI (-U) check: path=%s -> status=%d", input, rsub->status);
-
- /* cleanup by destroying the subrequest */
- destroy_sub_req(rsub);
- }
- }
- else if (strcmp(p->pattern, "-F") == 0) {
- /* avoid infinite subrequest recursion */
- if (strlen(input) > 0 /* nonempty path, and */
- && ( r->main == NULL /* - either not in a subrequest */
- || ( r->main->uri != NULL /* - or in a subrequest...*/
- && r->uri != NULL /* ...and then URIs aren't NULL... */
- /* ...and sub and main URIs differ */
- && strcmp(r->main->uri, r->uri) != 0) ) ) {
-
- /* process a file-based subrequest:
- this differs from -U in that no path translation is done. */
- rsub = sub_req_lookup_file(input, r);
-
- /* file exists for any result up to 2xx, no redirects */
- if (rsub->status < 300 &&
- /* double-check that file exists since default result is 200 */
- stat(rsub->filename, &sb) == 0)
- rc = 1;
-
- /* log it */
- rewritelog(r, 5, "RewriteCond file (-F) check: path=%s -> file=%s status=%d", input, rsub->filename, rsub->status);
-
- /* cleanup by destroying the subrequest */
- destroy_sub_req(rsub);
- }
- }
- else if (strlen(p->pattern) > 1 && *(p->pattern) == '>') {
- rc = (compare_lexicography(input, p->pattern+1) == 1 ? 1 : 0);
- }
- else if (strlen(p->pattern) > 1 && *(p->pattern) == '<') {
- rc = (compare_lexicography(input, p->pattern+1) == -1 ? 1 : 0);
- }
- else if (strlen(p->pattern) > 1 && *(p->pattern) == '=') {
- rc = (strcmp(input, p->pattern+1) == 0 ? 1 : 0);
- }
- else {
- /* it is really a regexp pattern, so apply it */
- rc = (regexec(p->regexp, input, 0, NULL, 0) == 0);
- }
-
- /* if this is a non-matching regexp, just negate the result */
- if (p->flags & CONDFLAG_NOTMATCH)
- rc = !rc;
-
- rewritelog(r, 4, "RewriteCond: input='%s' pattern='%s%s' => %s",
- input, (p->flags & CONDFLAG_NOTMATCH ? "!" : ""),
- p->pattern, rc ? "matched" : "not-matched");
-
- /* end just return the result */
- return rc;
-}
-
-
-
-
-/*
-** +-------------------------------------------------------+
-** | |
-** | URL transformation functions
-** | |
-** +-------------------------------------------------------+
-*/
-
-
-/*
-**
-** split out a QUERY_STRING part from
-** the current URI string
-**
-*/
-
-static void splitout_queryargs(request_rec *r, int qsappend)
-{
- char *q;
- char *olduri;
-
- q = strchr(r->filename, '?');
- if (q != NULL) {
- olduri = pstrdup(r->pool, r->filename);
- *q++ = '\0';
- if (qsappend)
- r->args = pstrcat(r->pool, q, "&", r->args, NULL);
- else
- r->args = pstrdup(r->pool, q);
- if (strlen(r->args) == 0) {
- r->args = NULL;
- rewritelog(r, 3, "split uri=%s -> uri=%s, args=<none>", olduri, r->filename);
- }
- else {
- if (r->args[strlen(r->args)-1] == '&')
- r->args[strlen(r->args)-1] = '\0';
- rewritelog(r, 3, "split uri=%s -> uri=%s, args=%s", olduri, r->filename, r->args);
- }
- }
- return;
-}
-
-
-/*
-**
-** strip 'http[s]://ourhost/' from URI
-**
-*/
-
-static void reduce_uri(request_rec *r)
-{
- char *cp;
- unsigned short port;
- char *portp;
- char *hostp;
- char *url;
- char c;
- char host[LONG_STRING_LEN];
- char buf[MAX_STRING_LEN];
- char *olduri;
-
-#ifdef APACHE_SSL
- if ( (!r->connection->client->ssl &&
- strncasecmp(r->filename, "http://", 7) == 0)
- || (r->connection->client->ssl &&
- strncasecmp(r->filename, "https://", 8) == 0)) {
-#else
- if (strncasecmp(r->filename, "http://", 7) == 0) {
-#endif
- /* there was really a rewrite to a remote path */
-
- olduri = pstrdup(r->pool, r->filename); /* save for logging */
-
- /* cut the hostname and port out of the URI */
-#ifdef APACHE_SSL
- strncpy(buf, r->filename+strlen(http_method(r))+3, sizeof(buf)-1);
-#else
- strncpy(buf, r->filename+7, sizeof(buf)-1);
-#endif
- EOS_PARANOIA(buf);
- hostp = buf;
- for (cp = hostp; *cp != '\0' && *cp != '/' && *cp != ':'; cp++)
- ;
- if (*cp == ':') {
- /* set host */
- *cp++ = '\0';
- strncpy(host, hostp, sizeof(host)-1);
- EOS_PARANOIA(host);
- /* set port */
- portp = cp;
- for (; *cp != '\0' && *cp != '/'; cp++)
- ;
- c = *cp;
- *cp = '\0';
- port = atoi(portp);
- *cp = c;
- /* set remaining url */
- url = cp;
- }
- else if (*cp == '/') {
- /* set host */
- *cp = '\0';
- strncpy(host, hostp, sizeof(host)-1);
- EOS_PARANOIA(host);
- *cp = '/';
- /* set port */
- port = DEFAULT_PORT;
- /* set remaining url */
- url = cp;
- }
- else {
- /* set host */
- strncpy(host, hostp, sizeof(host)-1);
- EOS_PARANOIA(host);
- /* set port */
- port = DEFAULT_PORT;
- /* set remaining url */
- url = "/";
- }
-
- /* now check whether we could reduce it to a local path... */
- if (is_this_our_host(r, host) && port == r->server->port) {
- /* this is our host, so only the URL remains */
- r->filename = pstrdup(r->pool, url);
- rewritelog(r, 3, "reduce %s -> %s", olduri, r->filename);
- }
- }
- return;
-}
-
-
-/*
-**
-** Expand tilde-paths (~user) through
-** Unix /etc/passwd database information
-**
-*/
-
-static char *expand_tildepaths(request_rec *r, char *uri)
-{
- char user[LONG_STRING_LEN];
- struct passwd *pw;
- char *newuri;
- int i, j;
-
- newuri = uri;
- if (uri != NULL && strlen(uri) > 2 && uri[0] == '/' && uri[1] == '~') {
- /* cut out the username */
- for (j = 0, i = 2; j < sizeof(user)-1 && uri[i] != '\0' &&
- ( (uri[i] >= '0' && uri[i] <= '9')
- || (uri[i] >= 'a' && uri[i] <= 'z')
- || (uri[i] >= 'A' && uri[i] <= 'Z')); )
- user[j++] = uri[i++];
- user[j] = '\0';
-
- /* lookup username in systems passwd file */
- if ((pw = getpwnam(user)) != NULL) {
- /* ok, user was found, so expand the ~user string */
- if (uri[i] != '\0') {
- /* ~user/anything... has to be expanded */
- if (pw->pw_dir[strlen(pw->pw_dir)-1] == '/')
- pw->pw_dir[strlen(pw->pw_dir)-1] = '\0';
- newuri = pstrcat(r->pool, pw->pw_dir, uri+i, NULL);
- }
- else {
- /* only ~user has to be expanded */
- newuri = pstrdup(r->pool, pw->pw_dir);
- }
- }
- }
- return newuri;
-}
-
-
-/*
-**
-** mapfile expansion support
-** i.e. expansion of MAP lookup directives
-** ${<mapname>:<key>} in RewriteRule rhs
-**
-*/
-
-#define limit_length(n) (n > LONG_STRING_LEN-1 ? LONG_STRING_LEN-1 : n)
-
-static void expand_map_lookups(request_rec *r, char *uri, int uri_len)
-{
- char newuri[MAX_STRING_LEN];
- char *cpI;
- char *cpIE;
- char *cpO;
- char *cpT;
- char *cpT2;
- char mapname[LONG_STRING_LEN];
- char mapkey[LONG_STRING_LEN];
- char defaultvalue[LONG_STRING_LEN];
- int n;
-
- cpI = uri;
- cpIE = cpI+strlen(cpI);
- cpO = newuri;
- while (cpI < cpIE) {
- if (cpI+6 < cpIE && strncmp(cpI, "${", 2) == 0) {
- /* missing delimiter -> take it as plain text */
- if ( strchr(cpI+2, ':') == NULL
- || strchr(cpI+2, '}') == NULL) {
- memcpy(cpO, cpI, 2);
- cpO += 2;
- cpI += 2;
- continue;
- }
- cpI += 2;
-
- cpT = strchr(cpI, ':');
- n = cpT-cpI;
- memcpy(mapname, cpI, limit_length(n));
- mapname[limit_length(n)] = '\0';
- cpI += n+1;
-
- cpT2 = strchr(cpI, '|');
- cpT = strchr(cpI, '}');
- if (cpT2 != NULL && cpT2 < cpT) {
- n = cpT2-cpI;
- memcpy(mapkey, cpI, limit_length(n));
- mapkey[limit_length(n)] = '\0';
- cpI += n+1;
-
- n = cpT-cpI;
- memcpy(defaultvalue, cpI, limit_length(n));
- defaultvalue[limit_length(n)] = '\0';
- cpI += n+1;
- }
- else {
- n = cpT-cpI;
- memcpy(mapkey, cpI, limit_length(n));
- mapkey[limit_length(n)] = '\0';
- cpI += n+1;
-
- defaultvalue[0] = '\0';
- }
-
- cpT = lookup_map(r, mapname, mapkey);
- if (cpT != NULL) {
- n = strlen(cpT);
- if (cpO + n >= newuri + sizeof(newuri)) {
- log_printf(r->server, "insufficient space in expand_map_lookups, aborting");
- return;
- }
- memcpy(cpO, cpT, n);
- cpO += n;
- }
- else {
- n = strlen(defaultvalue);
- if (cpO + n >= newuri + sizeof(newuri)) {
- log_printf(r->server, "insufficient space in expand_map_lookups, aborting");
- return;
- }
- memcpy(cpO, defaultvalue, n);
- cpO += n;
- }
- }
- else {
- cpT = strstr(cpI, "${");
- if (cpT == NULL)
- cpT = cpI+strlen(cpI);
- n = cpT-cpI;
- if (cpO + n >= newuri + sizeof(newuri)) {
- log_printf(r->server, "insufficient space in expand_map_lookups, aborting");
- return;
- }
- memcpy(cpO, cpI, n);
- cpO += n;
- cpI += n;
- }
- }
- *cpO = '\0';
- strncpy(uri, newuri, uri_len-1);
- uri[uri_len-1] = '\0';
- return;
-}
-
-#undef limit_length
-
-
-
-/*
-** +-------------------------------------------------------+
-** | |
-** | DBM hashfile support
-** | |
-** +-------------------------------------------------------+
-*/
-
-
-static char *lookup_map(request_rec *r, char *name, char *key)
-{
- void *sconf;
- rewrite_server_conf *conf;
- array_header *rewritemaps;
- rewritemap_entry *entries;
- rewritemap_entry *s;
- char *value;
- struct stat st;
- int i;
-
- /* get map configuration */
- sconf = r->server->module_config;
- conf = (rewrite_server_conf *)get_module_config(sconf, &rewrite_module);
- rewritemaps = conf->rewritemaps;
-
- entries = (rewritemap_entry *)rewritemaps->elts;
- for (i = 0; i < rewritemaps->nelts; i++) {
- s = &entries[i];
- if (strcmp(s->name, name) == 0) {
- if (s->type == MAPTYPE_TXT) {
- stat(s->checkfile, &st); /* existence was checked at startup! */
- value = get_cache_string(cachep, s->name, CACHEMODE_TS, st.st_mtime, key);
- if (value == NULL) {
- rewritelog(r, 6, "cache lookup FAILED, forcing new map lookup");
- if ((value = lookup_map_txtfile(r, s->datafile, key)) != NULL) {
- rewritelog(r, 5, "map lookup OK: map=%s key=%s[txt] -> val=%s", s->name, key, value);
- set_cache_string(cachep, s->name, CACHEMODE_TS, st.st_mtime, key, value);
- return value;
- }
- else {
- rewritelog(r, 5, "map lookup FAILED: map=%s[txt] key=%s", s->name, key);
- return NULL;
- }
- }
- else {
- rewritelog(r, 5, "cache lookup OK: map=%s[txt] key=%s -> val=%s", s->name, key, value);
- return value;
- }
- }
- else if (s->type == MAPTYPE_DBM) {
-#if HAS_NDBM_LIB
- stat(s->checkfile, &st); /* existence was checked at startup! */
- value = get_cache_string(cachep, s->name, CACHEMODE_TS, st.st_mtime, key);
- if (value == NULL) {
- rewritelog(r, 6, "cache lookup FAILED, forcing new map lookup");
- if ((value = lookup_map_dbmfile(r, s->datafile, key)) != NULL) {
- rewritelog(r, 5, "map lookup OK: map=%s[dbm] key=%s -> val=%s", s->name, key, value);
- set_cache_string(cachep, s->name, CACHEMODE_TS, st.st_mtime, key, value);
- return value;
- }
- else {
- rewritelog(r, 5, "map lookup FAILED: map=%s[dbm] key=%s", s->name, key);
- return NULL;
- }
- }
- else {
- rewritelog(r, 5, "cache lookup OK: map=%s[dbm] key=%s -> val=%s", s->name, key, value);
- return value;
- }
-#else
- return NULL;
-#endif
- }
- else if (s->type == MAPTYPE_PRG) {
- if ((value = lookup_map_program(r, s->fpin, s->fpout, key)) != NULL) {
- rewritelog(r, 5, "map lookup OK: map=%s key=%s -> val=%s", s->name, key, value);
- return value;
- }
- else {
- rewritelog(r, 5, "map lookup FAILED: map=%s key=%s", s->name, key);
- }
- }
- }
- }
- return NULL;
-}
-
-
-static char *lookup_map_txtfile(request_rec *r, char *file, char *key)
-{
- FILE *fp = NULL;
- char line[1024];
- char output[1024];
- char result[1024];
- char *value = NULL;
- char *cpT;
- char *curkey;
- char *curval;
-
- if ((fp = pfopen(r->pool, file, "r")) == NULL)
- return NULL;
-
- strncpy(output, MAPFILE_OUTPUT, sizeof(output)-1);
- EOS_PARANOIA(output);
- while (fgets(line, sizeof(line), fp) != NULL) {
- if (line[strlen(line)-1] == '\n')
- line[strlen(line)-1] = '\0';
- if (regexec(lookup_map_txtfile_regexp, line, lookup_map_txtfile_regexp->re_nsub+1, lookup_map_txtfile_regmatch, 0) == 0) {
- strncpy(result, pregsub(r->pool, output, line, lookup_map_txtfile_regexp->re_nsub+1, lookup_map_txtfile_regmatch), sizeof(result)-1); /* substitute in output */
- EOS_PARANOIA(result);
- cpT = strchr(result, ',');
- *cpT = '\0';
- curkey = result;
- curval = cpT+1;
-
- if (strcmp(curkey, key) == 0) {
- value = pstrdup(r->pool, curval);
- break;
- }
- }
- }
- pfclose(r->pool, fp);
- return value;
-}
-
-#if HAS_NDBM_LIB
-static char *lookup_map_dbmfile(request_rec *r, char *file, char *key)
-{
- DBM *dbmfp = NULL;
- datum dbmkey;
- datum dbmval;
- char *value = NULL;
- char buf[MAX_STRING_LEN];
-
- dbmkey.dptr = key;
- dbmkey.dsize = (strlen(key) < sizeof(buf) - 1 ? strlen(key) : sizeof(buf)-1);
- if ((dbmfp = dbm_open(file, O_RDONLY, 0666)) != NULL) {
- dbmval = dbm_fetch(dbmfp, dbmkey);
- if (dbmval.dptr != NULL) {
- memcpy(buf, dbmval.dptr, dbmval.dsize);
- buf[dbmval.dsize] = '\0';
- value = pstrdup(r->pool, buf);
- }
- dbm_close(dbmfp);
- }
- return value;
-}
-#endif
-
-static char *lookup_map_program(request_rec *r, int fpin, int fpout, char *key)
-{
- char buf[LONG_STRING_LEN];
- char c;
- int i;
-
- /* lock the channel */
-#ifdef USE_PIPE_LOCKING
- fd_lock(fpin);
-#endif
-
- /* write out the request key */
- write(fpin, key, strlen(key));
- write(fpin, "\n", 1);
-
- /* read in the response value */
- i = 0;
- while (read(fpout, &c, 1) == 1 && (i < LONG_STRING_LEN-1)) {
- if (c == '\n')
- break;
- buf[i++] = c;
- }
- buf[i] = '\0';
-
- /* unlock the channel */
-#ifdef USE_PIPE_LOCKING
- fd_unlock(fpin);
-#endif
-
- if (strcasecmp(buf, "NULL") == 0)
- return NULL;
- else
- return pstrdup(r->pool, buf);
-}
-
-
-
-
-/*
-** +-------------------------------------------------------+
-** | |
-** | rewriting logfile support
-** | |
-** +-------------------------------------------------------+
-*/
-
-
-static void open_rewritelog(server_rec *s, pool *p)
-{
- rewrite_server_conf *conf;
- char *fname;
- FILE *fp;
- int rewritelog_flags = ( O_WRONLY|O_APPEND|O_CREAT );
- mode_t rewritelog_mode = ( S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH );
-
- conf = get_module_config(s->module_config, &rewrite_module);
-
- if (conf->rewritelogfile == NULL)
- return;
- if (*(conf->rewritelogfile) == '\0')
- return;
- if (conf->rewritelogfp > 0)
- return; /* virtual log shared w/main server */
-
- fname = server_root_relative(p, conf->rewritelogfile);
-
- if (*conf->rewritelogfile == '|') {
- if (!spawn_child(p, rewritelog_child, (void *)(conf->rewritelogfile+1),
- kill_after_timeout, &fp, NULL)) {
- perror("spawn_child");
- fprintf (stderr, "mod_rewrite: could not fork child for RewriteLog process\n");
- exit (1);
- }
- conf->rewritelogfp = fileno(fp);
- }
- else if (*conf->rewritelogfile != '\0') {
- if ((conf->rewritelogfp = popenf(p, fname, rewritelog_flags, rewritelog_mode)) < 0) {
- perror("open");
- fprintf(stderr, "mod_rewrite: could not open RewriteLog file %s.\n", fname);
- exit(1);
- }
- }
- return;
-}
-
-/* Child process code for 'RewriteLog "|..."' */
-static void rewritelog_child(void *cmd)
-{
- cleanup_for_exec();
- signal(SIGHUP, SIG_IGN);
-#ifdef __EMX__
- /* OS/2 needs a '/' */
- execl(SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL);
-#else
- execl(SHELL_PATH, SHELL_PATH, "-c", (char *)cmd, NULL);
-#endif
- exit(1);
-}
-
-static void rewritelog(request_rec *r, int level, const char *text, ...)
-{
- rewrite_server_conf *conf;
- conn_rec *connect;
- char *str1;
- char str2[512];
- char str3[1024];
- char type[20];
- char redir[20];
- va_list ap;
- int i;
- request_rec *req;
- char *ruser;
- const char *rhost;
-
- va_start(ap, text);
- conf = get_module_config(r->server->module_config, &rewrite_module);
- connect = r->connection;
-
- if (conf->rewritelogfp <0)
- return;
- if (conf->rewritelogfile == NULL)
- return;
- if (*(conf->rewritelogfile) == '\0')
- return;
-
- if (level > conf->rewriteloglevel)
- return;
-
- if (connect->user == NULL) {
- ruser = "-";
- }
- else if (strlen (connect->user) != 0) {
- ruser = connect->user;
- }
- else {
- ruser = "\"\"";
- }
-
- rhost = get_remote_host(connect, r->server->module_config, REMOTE_NOLOOKUP);
- if (rhost == NULL)
- rhost = "UNKNOWN-HOST";
-
- str1 = pstrcat(r->pool, rhost, " ",
- (connect->remote_logname != NULL ? connect->remote_logname : "-"), " ",
- ruser, NULL);
- ap_vsnprintf(str2, sizeof(str2), text, ap);
-
- if (r->main == NULL)
- strcpy(type, "initial");
- else
- strcpy(type, "subreq");
-
- for (i = 0, req = r; req->prev != NULL; req = req->prev)
- i++;
- if (i == 0)
- redir[0] = '\0';
- else
- ap_snprintf(redir, sizeof(redir), "/redir#%d", i);
-
- ap_snprintf(str3, sizeof(str3), "%s %s [%s/sid#%x][rid#%x/%s%s] (%d) %s\n", str1, current_logtime(r), r->server->server_hostname, (unsigned int)(r->server), (unsigned int)r, type, redir, level, str2);
-
- fd_lock(conf->rewritelogfp);
- write(conf->rewritelogfp, str3, strlen(str3));
- fd_unlock(conf->rewritelogfp);
-
- va_end(ap);
- return;
-}
-
-static char *current_logtime(request_rec *r)
-{
- int timz;
- struct tm *t;
- char tstr[80];
- char sign;
-
- t = get_gmtoff(&timz);
- sign = (timz < 0 ? '-' : '+');
- if(timz < 0)
- timz = -timz;
-
- strftime(tstr, 80, "[%d/%b/%Y:%H:%M:%S ", t);
- ap_snprintf(tstr + strlen(tstr), 80-strlen(tstr), "%c%.2d%.2d]", sign, timz/60, timz%60);
- return pstrdup(r->pool, tstr);
-}
-
-
-
-
-/*
-** +-------------------------------------------------------+
-** | |
-** | program map support
-** | |
-** +-------------------------------------------------------+
-*/
-
-static void run_rewritemap_programs(server_rec *s, pool *p)
-{
- rewrite_server_conf *conf;
- char *fname;
- FILE *fpin;
- FILE *fpout;
- array_header *rewritemaps;
- rewritemap_entry *entries;
- rewritemap_entry *map;
- int i;
- int rc;
-
- conf = get_module_config(s->module_config, &rewrite_module);
-
- rewritemaps = conf->rewritemaps;
- entries = (rewritemap_entry *)rewritemaps->elts;
- for (i = 0; i < rewritemaps->nelts; i++) {
- map = &entries[i];
- if (map->type != MAPTYPE_PRG)
- continue;
- if (map->datafile == NULL ||
- *(map->datafile) == '\0' ||
- map->fpin > 0 ||
- map->fpout > 0 )
- continue;
- fname = server_root_relative(p, map->datafile);
- fpin = NULL;
- fpout = NULL;
- rc = spawn_child(p, rewritemap_program_child, (void *)map->datafile, kill_after_timeout, &fpin, &fpout);
- if (rc == 0 || fpin == NULL || fpout == NULL) {
- perror("spawn_child");
- fprintf(stderr, "mod_rewrite: could not fork child for RewriteMap process\n");
- exit(1);
- }
- map->fpin = fileno(fpin);
- map->fpout = fileno(fpout);
- }
- return;
-}
-
-/* child process code */
-static void rewritemap_program_child(void *cmd)
-{
- cleanup_for_exec();
- signal(SIGHUP, SIG_IGN);
-#ifdef __EMX__
- /* OS/2 needs a '/' */
- execl(SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL);
-#else
- execl(SHELL_PATH, SHELL_PATH, "-c", (char *)cmd, NULL);
-#endif
- exit(1);
-}
-
-
-
-
-/*
-** +-------------------------------------------------------+
-** | |
-** | environment variable support
-** | |
-** +-------------------------------------------------------+
-*/
-
-
-static void expand_variables_inbuffer(request_rec *r, char *buf, int buf_len)
-{
- char *newbuf;
- newbuf = expand_variables(r, buf);
- if (strcmp(newbuf, buf) != 0) {
- strncpy(buf, newbuf, buf_len-1);
- buf[buf_len-1] = '\0';
- }
- return;
-}
-
-static char *expand_variables(request_rec *r, char *str)
-{
- char output[MAX_STRING_LEN];
- char input[MAX_STRING_LEN];
- char *cp;
- char *cp2;
- char *cp3;
- int expanded;
-
- strncpy(input, str, sizeof(input)-1);
- EOS_PARANOIA(input);
- output[0] = '\0';
- expanded = 0;
- for (cp = input; cp < input+MAX_STRING_LEN; ) {
- if ((cp2 = strstr(cp, "%{")) != NULL) {
- if ((cp3 = strstr(cp2, "}")) != NULL) {
- *cp2 = '\0';
- strncpy(&output[strlen(output)], cp, sizeof(output)-strlen(output)-1);
-
- cp2 += 2;
- *cp3 = '\0';
- strncpy(&output[strlen(output)], lookup_variable(r, cp2), sizeof(output)-strlen(output)-1);
-
- cp = cp3+1;
- expanded = 1;
- continue;
- }
- }
- strncpy(&output[strlen(output)], cp, sizeof(output)-strlen(output)-1);
- EOS_PARANOIA(output);
- break;
- }
- return expanded ? pstrdup(r->pool, output) : str;
-}
-
-static char *lookup_variable(request_rec *r, char *var)
-{
- char *result;
- char resultbuf[LONG_STRING_LEN];
- time_t tc;
- struct tm *tm;
- request_rec *rsub;
- struct passwd *pw;
- struct group *gr;
- struct stat finfo;
-
- result = NULL;
-
- /* HTTP headers */
- if (strcasecmp(var, "HTTP_USER_AGENT") == 0) {
- result = lookup_header(r, "User-Agent");
- }
- else if (strcasecmp(var, "HTTP_REFERER") == 0) {
- result = lookup_header(r, "Referer");
- }
- else if (strcasecmp(var, "HTTP_COOKIE") == 0) {
- result = lookup_header(r, "Cookie");
- }
- else if (strcasecmp(var, "HTTP_FORWARDED") == 0) {
- result = lookup_header(r, "Forwarded");
- }
- else if (strcasecmp(var, "HTTP_HOST") == 0) {
- result = lookup_header(r, "Host");
- }
- else if (strcasecmp(var, "HTTP_PROXY_CONNECTION") == 0) {
- result = lookup_header(r, "Proxy-Connection");
- }
- else if (strcasecmp(var, "HTTP_ACCEPT") == 0) {
- result = lookup_header(r, "Accept");
- }
- /* all other headers from which we are still not know about */
- else if (strlen(var) > 5 && strncasecmp(var, "HTTP:", 5) == 0) {
- result = lookup_header(r, var+5);
- }
-
- /* connection stuff */
- else if (strcasecmp(var, "REMOTE_ADDR") == 0) {
- result = r->connection->remote_ip;
- }
- else if (strcasecmp(var, "REMOTE_HOST") == 0) {
- result = (char *)get_remote_host(r->connection, r->per_dir_config, REMOTE_NAME);
- }
- else if (strcasecmp(var, "REMOTE_USER") == 0) {
- result = r->connection->user;
- }
- else if (strcasecmp(var, "REMOTE_IDENT") == 0) {
- result = (char *)get_remote_logname(r);
- }
-
- /* request stuff */
- else if (strcasecmp(var, "THE_REQUEST") == 0) { /* non-standard */
- result = r->the_request;
- }
- else if (strcasecmp(var, "REQUEST_METHOD") == 0) {
- result = r->method;
- }
- else if (strcasecmp(var, "REQUEST_URI") == 0) { /* non-standard */
- result = r->uri;
- }
- else if (strcasecmp(var, "SCRIPT_FILENAME") == 0 ||
- strcasecmp(var, "REQUEST_FILENAME") == 0 ) {
- result = r->filename;
- }
- else if (strcasecmp(var, "PATH_INFO") == 0) {
- result = r->path_info;
- }
- else if (strcasecmp(var, "QUERY_STRING") == 0) {
- result = r->args;
- }
- else if (strcasecmp(var, "AUTH_TYPE") == 0) {
- result = r->connection->auth_type;
- }
- else if (strcasecmp(var, "IS_SUBREQ") == 0) { /* non-standard */
- result = (r->main != NULL ? "true" : "false");
- }
-
- /* internal server stuff */
- else if (strcasecmp(var, "DOCUMENT_ROOT") == 0) {
- result = document_root(r);
- }
- else if (strcasecmp(var, "SERVER_ADMIN") == 0) {
- result = r->server->server_admin;
- }
- else if (strcasecmp(var, "SERVER_NAME") == 0) {
- result = r->server->server_hostname;
- }
- else if (strcasecmp(var, "SERVER_PORT") == 0) {
- ap_snprintf(resultbuf, sizeof(resultbuf), "%u", r->server->port);
- result = resultbuf;
- }
- else if (strcasecmp(var, "SERVER_PROTOCOL") == 0) {
- result = r->protocol;
- }
- else if (strcasecmp(var, "SERVER_SOFTWARE") == 0) {
- result = pstrdup(r->pool, SERVER_VERSION);
- }
- else if (strcasecmp(var, "API_VERSION") == 0) { /* non-standard */
- ap_snprintf(resultbuf, sizeof(resultbuf), "%d", MODULE_MAGIC_NUMBER);
- result = resultbuf;
- }
-
- /* underlaying Unix system stuff */
- else if (strcasecmp(var, "TIME_YEAR") == 0) {
- tc = time(NULL);
- tm = localtime(&tc);
- ap_snprintf(resultbuf, sizeof(resultbuf), "%02d%02d", (tm->tm_year / 100) + 19, tm->tm_year % 100);
- result = resultbuf;
- }
-#define MKTIMESTR(format, tmfield) \
- tc = time(NULL); \
- tm = localtime(&tc); \
- ap_snprintf(resultbuf, sizeof(resultbuf), format, tm->tmfield); \
- result = resultbuf;
- else if (strcasecmp(var, "TIME_MON") == 0) {
- MKTIMESTR("%02d", tm_mon+1)
- }
- else if (strcasecmp(var, "TIME_DAY") == 0) {
- MKTIMESTR("%02d", tm_mday)
- }
- else if (strcasecmp(var, "TIME_HOUR") == 0) {
- MKTIMESTR("%02d", tm_hour)
- }
- else if (strcasecmp(var, "TIME_MIN") == 0) {
- MKTIMESTR("%02d", tm_min)
- }
- else if (strcasecmp(var, "TIME_SEC") == 0) {
- MKTIMESTR("%02d", tm_sec)
- }
- else if (strcasecmp(var, "TIME_WDAY") == 0) {
- MKTIMESTR("%d", tm_wday)
- }
- else if (strcasecmp(var, "TIME") == 0) {
- tc = time(NULL);
- tm = localtime(&tc);
- ap_snprintf(resultbuf, sizeof(resultbuf), "%02d%02d%02d%02d%02d%02d%02d",
- (tm->tm_year / 100) + 19, (tm->tm_year % 100),
- tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
- result = resultbuf;
- rewritelog(r, 1, "RESULT='%s'", result);
- }
-
- /* all other env-variables from the parent Apache process */
- else if (strlen(var) > 4 && strncasecmp(var, "ENV:", 4) == 0) {
- /* first try the internal Apache notes structure */
- result = table_get(r->notes, var+4);
- /* second try the internal Apache env structure */
- if (result == NULL)
- result = table_get(r->subprocess_env, var+4);
- /* third try the external OS env */
- if (result == NULL)
- result = getenv(var+4);
- }
-
-#define LOOKAHEAD(subrecfunc) \
- if ( \
- /* filename is safe to use */ \
- r->filename != NULL \
- /* - and we're either not in a subrequest */ \
- && ( r->main == NULL \
- /* - or in a subrequest where paths are non-NULL... */ \
- || ( r->main->uri != NULL && r->uri != NULL \
- /* ...and sub and main paths differ */ \
- && strcmp(r->main->uri, r->uri) != 0))) { \
- /* process a file-based subrequest */ \
- rsub = subrecfunc(r->filename, r); \
- /* now recursively lookup the variable in the sub_req */ \
- result = lookup_variable(rsub, var+5); \
- /* copy it up to our scope before we destroy the sub_req's pool */ \
- result = pstrdup(r->pool, result); \
- /* cleanup by destroying the subrequest */ \
- destroy_sub_req(rsub); \
- /* log it */ \
- rewritelog(r, 5, "lookahead: path=%s var=%s -> val=%s", r->filename, var+5, result); \
- /* return ourself to prevent re-pstrdup */ \
- return result; \
- }
-
- /* look-ahead for parameter through URI-based sub-request */
- else if (strlen(var) > 5 && strncasecmp(var, "LA-U:", 5) == 0) {
- LOOKAHEAD(sub_req_lookup_uri)
- }
- /* look-ahead for parameter through file-based sub-request */
- else if (strlen(var) > 5 && strncasecmp(var, "LA-F:", 5) == 0) {
- LOOKAHEAD(sub_req_lookup_file)
- }
-
- /* file stuff */
- else if (strcasecmp(var, "SCRIPT_USER") == 0) {
- result = pstrdup(r->pool, "<unknown>");
- if (r->finfo.st_mode != 0) {
- if ((pw = getpwuid(r->finfo.st_uid)) != NULL) {
- result = pstrdup(r->pool, pw->pw_name);
- }
- }
- else {
- if (stat(r->filename, &finfo) == 0) {
- if ((pw = getpwuid(finfo.st_uid)) != NULL) {
- result = pstrdup(r->pool, pw->pw_name);
- }
- }
- }
- }
- else if (strcasecmp(var, "SCRIPT_GROUP") == 0) {
- result = pstrdup(r->pool, "<unknown>");
- if (r->finfo.st_mode != 0) {
- if ((gr = getgrgid(r->finfo.st_gid)) != NULL) {
- result = pstrdup(r->pool, gr->gr_name);
- }
- }
- else {
- if (stat(r->filename, &finfo) == 0) {
- if ((gr = getgrgid(finfo.st_gid)) != NULL) {
- result = pstrdup(r->pool, gr->gr_name);
- }
- }
- }
- }
-
- if (result == NULL)
- return pstrdup(r->pool, "");
- else
- return pstrdup(r->pool, result);
-}
-
-static char *lookup_header(request_rec *r, const char *name)
-{
- array_header *hdrs_arr;
- table_entry *hdrs;
- int i;
-
- hdrs_arr = table_elts(r->headers_in);
- hdrs = (table_entry *)hdrs_arr->elts;
- for (i = 0; i < hdrs_arr->nelts; ++i) {
- if (hdrs[i].key == NULL)
- continue;
- if (strcasecmp(hdrs[i].key, name) == 0)
- return hdrs[i].val;
- }
- return NULL;
-}
-
-
-
-
-/*
-** +-------------------------------------------------------+
-** | |
-** | caching support
-** | |
-** +-------------------------------------------------------+
-*/
-
-
-static cache *init_cache(pool *p)
-{
- cache *c;
-
- c = (cache *)palloc(p, sizeof(cache));
- c->pool = make_sub_pool(p);
- c->lists = make_array(c->pool, 2, sizeof(cachelist));
- return c;
-}
-
-static void set_cache_string(cache *c, char *res, int mode, time_t time, char *key, char *value)
-{
- cacheentry ce;
-
- ce.time = time;
- ce.key = key;
- ce.value = value;
- store_cache_string(c, res, &ce);
- return;
-}
-
-static char *get_cache_string(cache *c, char *res, int mode, time_t time, char *key)
-{
- cacheentry *ce;
-
- ce = retrieve_cache_string(c, res, key);
- if (ce == NULL)
- return NULL;
- if (mode & CACHEMODE_TS) {
- if (time != ce->time)
- return NULL;
- }
- else if (mode & CACHEMODE_TTL) {
- if (time > ce->time)
- return NULL;
- }
- return pstrdup(c->pool, ce->value);
-}
-
-static void store_cache_string(cache *c, char *res, cacheentry *ce)
-{
- int i;
- int j;
- cachelist *l;
- cacheentry *e;
- int found_list;
-
- found_list = 0;
- /* first try to edit an existing entry */
- for (i = 0; i < c->lists->nelts; i++) {
- l = &(((cachelist *)c->lists->elts)[i]);
- if (strcmp(l->resource, res) == 0) {
- found_list = 1;
- for (j = 0; j < l->entries->nelts; j++) {
- e = &(((cacheentry *)l->entries->elts)[j]);
- if (strcmp(e->key, ce->key) == 0) {
- e->time = ce->time;
- e->value = pstrdup(c->pool, ce->value);
- return;
- }
- }
- }
- }
-
- /* create a needed new list */
- if (!found_list) {
- l = push_array(c->lists);
- l->resource = pstrdup(c->pool, res);
- l->entries = make_array(c->pool, 2, sizeof(cacheentry));
- }
-
- /* create the new entry */
- for (i = 0; i < c->lists->nelts; i++) {
- l = &(((cachelist *)c->lists->elts)[i]);
- if (strcmp(l->resource, res) == 0) {
- e = push_array(l->entries);
- e->time = ce->time;
- e->key = pstrdup(c->pool, ce->key);
- e->value = pstrdup(c->pool, ce->value);
- return;
- }
- }
-
- /* not reached, but when it is no problem... */
- return;
-}
-
-static cacheentry *retrieve_cache_string(cache *c, char *res, char *key)
-{
- int i;
- int j;
- cachelist *l;
- cacheentry *e;
-
- for (i = 0; i < c->lists->nelts; i++) {
- l = &(((cachelist *)c->lists->elts)[i]);
- if (strcmp(l->resource, res) == 0) {
- for (j = 0; j < l->entries->nelts; j++) {
- e = &(((cacheentry *)l->entries->elts)[j]);
- if (strcmp(e->key, key) == 0) {
- return e;
- }
- }
- }
- }
- return NULL;
-}
-
-
-
-
-/*
-** +-------------------------------------------------------+
-** | |
-** | misc functions
-** | |
-** +-------------------------------------------------------+
-*/
-
-static char *subst_prefix_path(request_rec *r, char *input, char *match, char *subst)
-{
- char matchbuf[LONG_STRING_LEN];
- char substbuf[LONG_STRING_LEN];
- char *output;
- int l;
-
- output = input;
-
- /* first create a match string which always has a trailing slash */
- strncpy(matchbuf, match, sizeof(matchbuf)-1);
- EOS_PARANOIA(matchbuf);
- l = strlen(matchbuf);
- if (matchbuf[l-1] != '/') {
- matchbuf[l] = '/';
- matchbuf[l+1] = '\0';
- l++;
- }
- /* now compare the prefix */
- if (strncmp(input, matchbuf, l) == 0) {
- rewritelog(r, 5, "strip matching prefix: %s -> %s", output, output+l);
- output = pstrdup(r->pool, output+l);
-
- /* and now add the base-URL as replacement prefix */
- strncpy(substbuf, subst, sizeof(substbuf)-1);
- EOS_PARANOIA(substbuf);
- l = strlen(substbuf);
- if (substbuf[l-1] != '/') {
- substbuf[l] = '/';
- substbuf[l+1] = '\0';
- l++;
- }
- if (output[0] == '/') {
- rewritelog(r, 4, "add subst prefix: %s -> %s%s", output, substbuf, output+1);
- output = pstrcat(r->pool, substbuf, output+1, NULL);
- }
- else {
- rewritelog(r, 4, "add subst prefix: %s -> %s%s", output, substbuf, output);
- output = pstrcat(r->pool, substbuf, output, NULL);
- }
- }
- return output;
-}
-
-
-/*
-**
-** own command line parser which don't have the '\\' problem
-**
-*/
-
-static int parseargline(char *str, char **a1, char **a2, char **a3)
-{
- char *cp;
- int isquoted;
-
-#define SKIP_WHITESPACE(cp) \
- for ( ; *cp == ' ' || *cp == '\t'; ) \
- cp++;
-
-#define CHECK_QUOTATION(cp,isquoted) \
- isquoted = 0; \
- if (*cp == '"') { \
- isquoted = 1; \
- cp++; \
- }
-
-#define DETERMINE_NEXTSTRING(cp,isquoted) \
- for ( ; *cp != '\0'; cp++) { \
- if ( (isquoted && (*cp == ' ' || *cp == '\t')) \
- || (*cp == '\\' && (*(cp+1) == ' ' || *(cp+1) == '\t'))) { \
- cp++; \
- continue; \
- } \
- if ( (!isquoted && (*cp == ' ' || *cp == '\t')) \
- || (isquoted && *cp == '"') ) \
- break; \
- }
-
- cp = str;
- SKIP_WHITESPACE(cp);
-
- /* determine first argument */
- CHECK_QUOTATION(cp, isquoted);
- *a1 = cp;
- DETERMINE_NEXTSTRING(cp, isquoted);
- if (*cp == '\0')
- return 1;
- *cp++ = '\0';
-
- SKIP_WHITESPACE(cp);
-
- /* determine second argument */
- CHECK_QUOTATION(cp, isquoted);
- *a2 = cp;
- DETERMINE_NEXTSTRING(cp, isquoted);
- if (*cp == '\0') {
- *cp++ = '\0';
- *a3 = NULL;
- return 0;
- }
- *cp++ = '\0';
-
- SKIP_WHITESPACE(cp);
-
- /* again check if there are only two arguments */
- if (*cp == '\0') {
- *cp++ = '\0';
- *a3 = NULL;
- return 0;
- }
-
- /* determine second argument */
- CHECK_QUOTATION(cp, isquoted);
- *a3 = cp;
- DETERMINE_NEXTSTRING(cp, isquoted);
- *cp++ = '\0';
-
- return 0;
-}
-
-
-static void add_env_variable(request_rec *r, char *s)
-{
- char var[MAX_STRING_LEN];
- char val[MAX_STRING_LEN];
- char *cp;
- int n;
-
- if ((cp = strchr(s, ':')) != NULL) {
- n = ((cp-s) > MAX_STRING_LEN-1 ? MAX_STRING_LEN-1 : (cp-s));
- memcpy(var, s, n);
- var[n] = '\0';
- strncpy(val, cp+1, sizeof(val)-1);
- EOS_PARANOIA(val);
- table_set(r->subprocess_env, pstrdup(r->pool, var), pstrdup(r->pool, val));
- rewritelog(r, 5, "setting env variable '%s' to '%s'", var, val);
- }
-}
-
-
-
-/*
-**
-** stat() for only the prefix of a path
-**
-*/
-
-static int prefix_stat(const char *path, struct stat *sb)
-{
- char curpath[LONG_STRING_LEN];
- char *cp;
-
- strncpy(curpath, path, sizeof(curpath)-1);
- EOS_PARANOIA(curpath);
- if (curpath[0] != '/')
- return 0;
- if ((cp = strchr(curpath+1, '/')) != NULL)
- *cp = '\0';
- if (stat(curpath, sb) == 0)
- return 1;
- else
- return 0;
-}
-
-
-/*
-**
-** special DNS lookup functions
-**
-*/
-
-static int is_this_our_host(request_rec *r, char *testhost)
-{
- char **cppHNLour;
- char **cppHNLtest;
- char *ourhostname;
- char *ourhostip;
- const char *names;
- char *name;
- int i, j;
- server_addr_rec *sar;
-
- /* we can check:
- r->
- char *hostname Host, as set by full URI or Host:
- int hostlen Length of http://host:port in full URI
- r->server->
- int is_virtual 0=main, 1=ip-virtual, 2=non-ip-virtual
- char *server_hostname used on compare to r->hostname
- inet_ntoa(r->connection->local_addr.sin_addr)
- used on compare to r->hostname
- unsigned short port for redirects
- char *path name of ServerPath
- int pathlen len of ServerPath
- char *names Wildcarded names for ServerAlias servers
- r->server->addrs->
- struct in_addr host_addr The bound address, for this server
- short host_port The bound port, for this server
- char *virthost The name given in <VirtualHost>
- */
-
- ourhostname = r->server->server_hostname;
- ourhostip = inet_ntoa(r->connection->local_addr.sin_addr);
-
- /* just a simple common case */
- if (strcmp(testhost, ourhostname) == 0 ||
- strcmp(testhost, ourhostip) == 0 )
- return YES;
-
- /* now the complicated cases */
- if (!r->server->is_virtual) {
- /* main servers */
-
- /* check for the alternative IP addresses */
- if ((cppHNLour = resolv_ipaddr_list(r, ourhostname)) == NULL)
- return NO;
- if ((cppHNLtest = resolv_ipaddr_list(r, testhost)) == NULL)
- return NO;
- for (i = 0; cppHNLtest[i] != NULL; i++) {
- for (j = 0; cppHNLour[j] != NULL; j++) {
- if (strcmp(cppHNLtest[i], cppHNLour[j]) == 0) {
- return YES;
- }
- }
- }
- }
- else if (r->server->is_virtual) {
- /* virtual servers */
-
- /* check for the names supplied in the VirtualHost directive */
- for(sar = r->server->addrs; sar != NULL; sar = sar->next) {
- if(strcasecmp(sar->virthost, testhost) == 0)
- return YES;
- }
-
- /* check for the virtual-server aliases */
- if (r->server->names != NULL && r->server->names[0] != '\0') {
- names = r->server->names;
- while (*names != '\0') {
- name = getword_conf(r->pool, &names);
- if ((is_matchexp(name) && !strcasecmp_match(testhost, name)) ||
- (strcasecmp(testhost, name) == 0) ) {
- return YES;
- }
- }
- }
- }
- return NO;
-}
-
-static int isaddr(char *host)
-{
- char *cp;
-
- /* Null pointers and empty strings
- are not addresses. */
- if (host == NULL)
- return NO;
- if (*host == '\0')
- return NO;
- /* Make sure it has only digits and dots. */
- for (cp = host; *cp; cp++) {
- if (!isdigit(*cp) && *cp != '.')
- return NO;
- }
- /* If it has a trailing dot,
- don't treat it as an address. */
- if (*(cp-1) == '.')
- return NO;
- return YES;
-}
-
-static char **resolv_ipaddr_list(request_rec *r, char *name)
-{
- char **cppHNL;
- struct hostent *hep;
- int i;
-
- if (isaddr(name))
- hep = gethostbyaddr(name, sizeof(struct in_addr), AF_INET);
- else
- hep = gethostbyname(name);
- if (hep == NULL)
- return NULL;
- for (i = 0; hep->h_addr_list[i]; i++)
- ;
- cppHNL = (char **)palloc(r->pool, sizeof(char *)*(i+1));
- for (i = 0; hep->h_addr_list[i]; i++)
- cppHNL[i] = pstrdup(r->pool, inet_ntoa(*((struct in_addr *)(hep->h_addr_list[i]))) );
- cppHNL[i] = NULL;
- return cppHNL;
-}
-
-
-/*
-**
-** check if proxy module is available
-** i.e. if it is compiled in and turned on
-**
-*/
-
-static int is_proxy_available(server_rec *s)
-{
- return (find_linked_module("mod_proxy.c") != NULL);
-}
-
-
-/*
-**
-** File locking
-**
-*/
-
-#ifdef USE_FCNTL
-static struct flock lock_it;
-static struct flock unlock_it;
-#endif
-
-static void fd_lock(int fd)
-{
- int rc;
-
-#ifdef USE_FCNTL
- lock_it.l_whence = SEEK_SET; /* from current point */
- lock_it.l_start = 0; /* -"- */
- lock_it.l_len = 0; /* until end of file */
- lock_it.l_type = F_WRLCK; /* set exclusive/write lock */
- lock_it.l_pid = 0; /* pid not actually interesting */
-
- while ( ((rc = fcntl(fd, F_SETLKW, &lock_it)) < 0)
- && (errno == EINTR) )
- continue;
-#endif
-#ifdef USE_FLOCK
- while ( ((rc = flock(fd, LOCK_EX)) < 0)
- && (errno == EINTR) )
- continue;
-#endif
-
- if (rc < 0) {
-#ifdef USE_FLOCK
- perror("flock");
-#else
- perror("fcntl");
-#endif
- fprintf(stderr, "Error getting lock. Exiting!");
- exit(1);
- }
- return;
-}
-
-static void fd_unlock(int fd)
-{
- int rc;
-
-#ifdef USE_FCNTL
- unlock_it.l_whence = SEEK_SET; /* from current point */
- unlock_it.l_start = 0; /* -"- */
- unlock_it.l_len = 0; /* until end of file */
- unlock_it.l_type = F_UNLCK; /* unlock */
- unlock_it.l_pid = 0; /* pid not actually interesting */
-
- rc = fcntl(fd, F_SETLKW, &unlock_it);
-#endif
-#ifdef USE_FLOCK
- rc = flock(fd, LOCK_UN);
-#endif
-
- if (rc < 0) {
-#ifdef USE_FLOCK
- perror("flock");
-#else
- perror("fcntl");
-#endif
- fprintf(stderr, "Error freeing lock. Exiting!");
- exit(1);
- }
-}
-
-/*
-**
-** Lexicographic Compare
-**
-*/
-
-static int compare_lexicography(char *cpNum1, char *cpNum2)
-{
- int i;
- int n1, n2;
-
- n1 = strlen(cpNum1);
- n2 = strlen(cpNum2);
- if (n1 > n2)
- return 1;
- if (n1 < n2)
- return -1;
- for (i = 0; i < n1; i++) {
- if (cpNum1[i] > cpNum2[i])
- return 1;
- if (cpNum1[i] < cpNum2[i])
- return -1;
- }
- return 0;
-}
-
-
-/*EOF*/
diff --git a/usr.sbin/httpd/src/mod_rewrite.h b/usr.sbin/httpd/src/mod_rewrite.h
deleted file mode 100644
index 10f91070a85..00000000000
--- a/usr.sbin/httpd/src/mod_rewrite.h
+++ /dev/null
@@ -1,400 +0,0 @@
-
-/* ====================================================================
- * Copyright (c) 1996,1997 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. 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 _MOD_REWRITE_H
-#define _MOD_REWRITE_H 1
-
-/*
-** _ _ _
-** _ __ ___ ___ __| | _ __ _____ ___ __(_) |_ ___
-** | '_ ` _ \ / _ \ / _` | | '__/ _ \ \ /\ / / '__| | __/ _ \
-** | | | | | | (_) | (_| | | | | __/\ V V /| | | | || __/
-** |_| |_| |_|\___/ \__,_|___|_| \___| \_/\_/ |_| |_|\__\___|
-** |_____|
-**
-** URL Rewriting Module
-**
-** This module uses a rule-based rewriting engine (based on a
-** regular-expression parser) to rewrite requested URLs on the fly.
-**
-** It supports an unlimited number of additional rule conditions (which can
-** operate on a lot of variables, even on HTTP headers) for granular
-** matching and even external database lookups (either via plain text
-** tables, DBM hash files or even external processes) for advanced URL
-** substitution.
-**
-** It operates on the full URLs (including the PATH_INFO part) both in
-** per-server context (httpd.conf) and per-dir context (.htaccess) and even
-** can generate QUERY_STRING parts on result. The rewriting result finally
-** can lead to internal subprocessing, external request redirection or even
-** to internal proxy throughput.
-**
-** This module was originally written in April 1996 and
-** gifted exclusively to the The Apache Group in July 1997 by
-**
-** Ralf S. Engelschall
-** rse@engelschall.com
-** www.engelschall.com
-*/
-
-
-
-
- /* The NDBM support:
- We support only NDBM files.
- But we have to stat the file for the mtime,
- so we also need to know the file extension */
-#if HAS_NDBM_LIB
-#include <ndbm.h>
-#if (__FreeBSD__)
-#define NDBM_FILE_SUFFIX ".db"
-#else
-#define NDBM_FILE_SUFFIX ".pag"
-#endif
-#endif
-
-
- /* The locking support:
- Try to determine whether we should use fcntl() or flock().
- Would be better conf.h could provide this... :-( */
-#if defined(USE_FCNTL_SERIALIZED_ACCEPT)
-#define USE_FCNTL 1
-#include <fcntl.h>
-#endif
-#if defined(USE_FLOCK_SERIALIZED_ACCEPT)
-#define USE_FLOCK 1
-#include <sys/file.h>
-#endif
-#if !defined(USE_FCNTL) && !defined(USE_FLOCK)
-#define USE_FLOCK 1
-#ifndef MPE
-#include <sys/file.h>
-#endif
-#ifndef LOCK_UN
-#undef USE_FLOCK
-#define USE_FCNTL 1
-#include <fcntl.h>
-#endif
-#endif
-#ifdef AIX
-#undef USE_FLOCK
-#define USE_FCNTL 1
-#include <fcntl.h>
-#endif
-
- /* The locking support for the RewriteMap programs:
- Locking a pipe to the child works fine under most
- Unix derivates, but braindead SunOS 4.1.x has
- problems with this approach... */
-#define USE_PIPE_LOCKING 1
-#ifdef SUNOS4
-#undef USE_PIPE_LOCKING
-#endif
-
-
-/*
-**
-** Some defines
-**
-*/
-
-#define ENVVAR_SCRIPT_URL "SCRIPT_URL"
-#define ENVVAR_SCRIPT_URI "SCRIPT_URI"
-
-#ifndef SUPPORT_DBM_REWRITEMAP
-#define SUPPORT_DBM_REWRITEMAP 0
-#endif
-
-#define REWRITE_FORCED_MIMETYPE_NOTEVAR "rewrite-forced-mimetype"
-
-#define CONDFLAG_NONE 1<<0
-#define CONDFLAG_NOCASE 1<<1
-#define CONDFLAG_NOTMATCH 1<<2
-#define CONDFLAG_ORNEXT 1<<3
-
-#define RULEFLAG_NONE 1<<0
-#define RULEFLAG_FORCEREDIRECT 1<<1
-#define RULEFLAG_LASTRULE 1<<2
-#define RULEFLAG_NEWROUND 1<<3
-#define RULEFLAG_CHAIN 1<<4
-#define RULEFLAG_IGNOREONSUBREQ 1<<5
-#define RULEFLAG_NOTMATCH 1<<6
-#define RULEFLAG_PROXY 1<<7
-#define RULEFLAG_PASSTHROUGH 1<<8
-#define RULEFLAG_FORBIDDEN 1<<9
-#define RULEFLAG_GONE 1<<10
-#define RULEFLAG_QSAPPEND 1<<11
-
-#define MAPTYPE_TXT 1<<0
-#define MAPTYPE_DBM 1<<1
-#define MAPTYPE_PRG 1<<2
-
-#define ENGINE_DISABLED 1<<0
-#define ENGINE_ENABLED 1<<1
-
-#define OPTION_NONE 1<<0
-#define OPTION_INHERIT 1<<1
-
-#define CACHEMODE_TS 1<<0
-#define CACHEMODE_TTL 1<<1
-
-#ifndef FALSE
-#define FALSE 0
-#define TRUE !FALSE
-#endif
-
-#ifndef NO
-#define NO FALSE
-#define YES TRUE
-#endif
-
-#ifndef LONG_STRING_LEN
-#define LONG_STRING_LEN 2048
-#endif
-
-#define MAX_ENV_FLAGS 5
-
-#define EOS_PARANOIA(ca) ca[sizeof(ca)-1] = '\0'
-
-
-/*
-**
-** our private data structures we handle with
-**
-*/
-
- /* the list structures for holding the mapfile information
- and the rewrite rules */
-
-typedef struct {
- char *name; /* the name of the map */
- char *datafile; /* the file which contains the data of the map */
- char *checkfile; /* the file which stays for existence of the map */
- int type; /* the type of the map */
- int fpin; /* in filepointer for program maps */
- int fpout; /* out filepointer for program maps */
-} rewritemap_entry;
-
-typedef struct {
- char *input; /* Input string of RewriteCond */
- char *pattern; /* the RegExp pattern string */
- regex_t *regexp;
- int flags; /* Flags which control the match */
-} rewritecond_entry;
-
-typedef struct {
- array_header *rewriteconds; /* the corresponding RewriteCond entries */
- char *pattern; /* the RegExp pattern string */
- regex_t *regexp; /* the RegExp pattern compilation */
- char *output; /* the Substitution string */
- int flags; /* Flags which control the substitution */
- char *forced_mimetype; /* forced MIME type of substitution */
- int forced_responsecode; /* forced HTTP redirect response status */
- char *env[MAX_ENV_FLAGS+1];/* added environment variables */
- int skip; /* number of next rules to skip */
-} rewriterule_entry;
-
-
- /* the per-server or per-virtual-server configuration
- statically generated once on startup for every server */
-
-typedef struct {
- int state; /* the RewriteEngine state */
- int options; /* the RewriteOption state */
- char *rewritelogfile; /* the RewriteLog filename */
- int rewritelogfp; /* the RewriteLog open filepointer */
- int rewriteloglevel; /* the RewriteLog level of verbosity */
- array_header *rewritemaps; /* the RewriteMap entries */
- array_header *rewriteconds; /* the RewriteCond entries (temporary) */
- array_header *rewriterules; /* the RewriteRule entries */
-} rewrite_server_conf;
-
-
- /* the per-directory configuration
- individually generated on-the-fly by Apache server for current request */
-
-typedef struct {
- int state; /* the RewriteEngine state */
- int options; /* the RewriteOption state */
- array_header *rewriteconds; /* the RewriteCond entries (temporary) */
- array_header *rewriterules; /* the RewriteRule entries */
- char *directory; /* the directory where it applies */
- char *baseurl; /* the base-URL where it applies */
-} rewrite_perdir_conf;
-
-
- /* the cache structures */
-
-typedef struct cacheentry {
- time_t time;
- char *key;
- char *value;
-} cacheentry;
-
-typedef struct cachelist {
- char *resource;
- array_header *entries;
-} cachelist;
-
-typedef struct cache {
- pool *pool;
- array_header *lists;
-} cache;
-
-
-/*
-**
-** forward declarations
-**
-*/
-
- /* config structure handling */
-static void *config_server_create(pool *p, server_rec *s);
-static void *config_server_merge (pool *p, void *basev, void *overridesv);
-static void *config_perdir_create(pool *p, char *path);
-static void *config_perdir_merge (pool *p, void *basev, void *overridesv);
-
- /* config directive handling */
-static const char *cmd_rewriteengine (cmd_parms *cmd, rewrite_perdir_conf *dconf, int flag);
-static const char *cmd_rewriteoptions (cmd_parms *cmd, rewrite_perdir_conf *dconf, char *option);
-static const char *cmd_rewriteoptions_setoption(pool *p, int *options, char *name);
-static const char *cmd_rewritelog (cmd_parms *cmd, void *dconf, char *a1);
-static const char *cmd_rewriteloglevel(cmd_parms *cmd, void *dconf, char *a1);
-static const char *cmd_rewritemap (cmd_parms *cmd, void *dconf, char *a1, char *a2);
-
-static const char *cmd_rewritebase(cmd_parms *cmd, rewrite_perdir_conf *dconf, char *a1);
-
-static const char *cmd_rewritecond (cmd_parms *cmd, rewrite_perdir_conf *dconf, char *str);
-static const char *cmd_rewritecond_parseflagfield(pool *p, rewritecond_entry *new, char *str);
-static const char *cmd_rewritecond_setflag (pool *p, rewritecond_entry *cfg, char *key, char *val);
-
-extern const char *cmd_rewriterule (cmd_parms *cmd, rewrite_perdir_conf *dconf, char *str);
-static const char *cmd_rewriterule_parseflagfield(pool *p, rewriterule_entry *new, char *str);
-static const char *cmd_rewriterule_setflag (pool *p, rewriterule_entry *cfg, char *key, char *val);
-
- /* initialisation */
-static void init_module(server_rec *s, pool *p);
-
- /* runtime hooks */
-static int hook_uri2file (request_rec *r);
-static int hook_mimetype (request_rec *r);
-static int hook_fixup (request_rec *r);
-static int handler_redirect(request_rec *r);
-
- /* rewriting engine */
-static int apply_rewrite_list(request_rec *r, array_header *rewriterules, char *perdir);
-static int apply_rewrite_rule(request_rec *r, rewriterule_entry *p, char *perdir);
-static int apply_rewrite_cond(request_rec *r, rewritecond_entry *p, char *perdir);
-
- /* URI transformation function */
-static void splitout_queryargs(request_rec *r, int qsappend);
-static void reduce_uri(request_rec *r);
-static char *expand_tildepaths(request_rec *r, char *uri);
-static void expand_map_lookups(request_rec *r, char *uri, int uri_len);
-
- /* DBM hashfile support functions */
-static char *lookup_map(request_rec *r, char *name, char *key);
-static char *lookup_map_txtfile(request_rec *r, char *file, char *key);
-#if HAS_NDBM_LIB
-static char *lookup_map_dbmfile(request_rec *r, char *file, char *key);
-#endif
-static char *lookup_map_program(request_rec *r, int fpin, int fpout, char *key);
-
- /* rewriting logfile support */
-static void open_rewritelog(server_rec *s, pool *p);
-static void rewritelog_child(void *cmd);
-static void rewritelog(request_rec *r, int level, const char *text, ...);
-static char *current_logtime(request_rec *r);
-
- /* program map support */
-static void run_rewritemap_programs(server_rec *s, pool *p);
-static void rewritemap_program_child(void *cmd);
-
- /* env variable support */
-static void expand_variables_inbuffer(request_rec *r, char *buf, int buf_len);
-static char *expand_variables(request_rec *r, char *str);
-static char *lookup_variable(request_rec *r, char *var);
-static char *lookup_header(request_rec *r, const char *name);
-
- /* caching functions */
-static cache *init_cache(pool *p);
-static char *get_cache_string(cache *c, char *res, int mode, time_t mtime, char *key);
-static void set_cache_string(cache *c, char *res, int mode, time_t mtime, char *key, char *value);
-static cacheentry *retrieve_cache_string(cache *c, char *res, char *key);
-static void store_cache_string(cache *c, char *res, cacheentry *ce);
-
- /* misc functions */
-static char *subst_prefix_path(request_rec *r, char *input, char *match, char *subst);
-static int parseargline(char *str, char **a1, char **a2, char **a3);
-static int prefix_stat(const char *path, struct stat *sb);
-static void add_env_variable(request_rec *r, char *s);
-
- /* DNS functions */
-static int is_this_our_host(request_rec *r, char *testhost);
-static int isaddr(char *host);
-static char **resolv_ipaddr_list(request_rec *r, char *name);
-
- /* Proxy Module check */
-static int is_proxy_available(server_rec *s);
-
- /* File locking */
-static void fd_lock(int fd);
-static void fd_unlock(int fd);
-
- /* Lexicographic Comparison */
-static int compare_lexicography(char *cpNum1, char *cpNum2);
-
-#endif /* _MOD_REWRITE_H */
-
-/*EOF*/
diff --git a/usr.sbin/httpd/src/mod_status.c b/usr.sbin/httpd/src/mod_status.c
deleted file mode 100644
index c00a3a4d5f9..00000000000
--- a/usr.sbin/httpd/src/mod_status.c
+++ /dev/null
@@ -1,643 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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/>.
- *
- */
-
-/* Status Module. Display lots of internal data about how Apache is
- * performing and the state of all children processes.
- *
- * To enable this, add the following lines into any config file:
- *
- * <Location /server-status>
- * SetHandler server-status
- * </Location>
- *
- * You may want to protect this location by password or domain so no one
- * else can look at it. Then you can access the statistics with a URL like:
- *
- * http://your_server_name/server-status
- *
- * /server-status - Returns page using tables
- * /server-status?notable - Returns page for browsers without table support
- * /server-status?refresh - Returns page with 1 second refresh
- * /server-status?refresh=6 - Returns page with refresh every 6 seconds
- * /server-status?auto - Returns page with data for automatic parsing
- *
- * Mark Cox, mark@ukweb.com, November 1995
- *
- * 12.11.95 Initial version for www.telescope.org
- * 13.3.96 Updated to remove rprintf's [Mark]
- * 18.3.96 Added CPU usage, process information, and tidied [Ben Laurie]
- * 18.3.96 Make extra Scoreboard variables #definable
- * 25.3.96 Make short report have full precision [Ben Laurie suggested]
- * 25.3.96 Show uptime better [Mark/Ben Laurie]
- * 29.3.96 Better HTML and explanation [Mark/Rob Hartill suggested]
- * 09.4.96 Added message for non-STATUS compiled version
- * 18.4.96 Added per child and per slot counters [Jim Jagielski]
- * 01.5.96 Table format, cleanup, even more spiffy data [Chuck Murcko/Jim J.]
- * 18.5.96 Adapted to use new rprintf() routine, incidentally fixing a missing
- * piece in short reports [Ben Laurie]
- * 21.5.96 Additional Status codes (DNS and LOGGING only enabled if
- extended STATUS is enabled) [George Burgyan/Jim J.] */
-
-#include "httpd.h"
-#include "http_config.h"
-#include "http_core.h"
-#include "http_protocol.h"
-#include "http_main.h"
-#include "util_script.h"
-#include <time.h>
-#include "scoreboard.h"
-#include "http_log.h"
-
-#ifdef NEXT
-#include <machine/param.h>
-#endif
-
-#define STATUS_MAXLINE 64
-
-#define KBYTE 1024
-#define MBYTE 1048576L
-#define GBYTE 1073741824L
-
-module status_module;
-
-/* Format the number of bytes nicely */
-
-void format_byte_out(request_rec *r,unsigned long bytes)
-{
- if (bytes < (5 * KBYTE))
- rprintf(r,"%d B",(int)bytes);
- else if (bytes < (MBYTE / 2))
- rprintf(r,"%.1f kB",(float)bytes/KBYTE);
- else if (bytes < (GBYTE / 2))
- rprintf(r,"%.1f MB",(float)bytes/MBYTE);
- else
- rprintf(r,"%.1f GB",(float)bytes/GBYTE);
-}
-
-void format_kbyte_out(request_rec *r,unsigned long kbytes)
-{
- if (kbytes < KBYTE)
- rprintf(r,"%d kB",(int)kbytes);
- else if (kbytes < MBYTE)
- rprintf(r,"%.1f MB",(float)kbytes/KBYTE);
- else
- rprintf(r,"%.1f GB",(float)kbytes/MBYTE);
-}
-
-void show_time(request_rec *r,time_t tsecs)
-{
- long days,hrs,mins,secs;
- char buf[100];
- char *s;
-
- secs=tsecs%60;
- tsecs/=60;
- mins=tsecs%60;
- tsecs/=60;
- hrs=tsecs%24;
- days=tsecs/24;
- s=buf;
- *s='\0';
- if(days)
- rprintf(r," %ld day%s",days,days==1?"":"s");
- if(hrs)
- rprintf(r," %ld hour%s",hrs,hrs==1?"":"s");
- if(mins)
- rprintf(r," %ld minute%s",mins,mins==1?"":"s");
- if(secs)
- rprintf(r," %ld second%s",secs,secs==1?"":"s");
-}
-
-#if defined(SUNOS4)
-double
-difftime(time1, time0)
- time_t time1, time0;
-{
- return(time1 - time0);
-}
-#endif
-
-/* Main handler for x-httpd-status requests */
-
-/* ID values for command table */
-
-#define STAT_OPT_END -1
-#define STAT_OPT_REFRESH 0
-#define STAT_OPT_NOTABLE 1
-#define STAT_OPT_AUTO 2
-
-struct stat_opt
-{
- int id;
- char *form_data_str;
- char *hdr_out_str;
-};
-
-int status_handler (request_rec *r)
-{
- struct stat_opt options[] = /* see #defines above */
- {
- { STAT_OPT_REFRESH, "refresh", "Refresh" },
- { STAT_OPT_NOTABLE, "notable", NULL },
- { STAT_OPT_AUTO, "auto", NULL },
- { STAT_OPT_END, NULL, NULL }
- };
- char *loc;
- time_t nowtime=time(NULL);
- time_t up_time;
- int i,res;
- int ready=0;
- int busy=0;
-#if defined(STATUS)
- unsigned long count=0;
- unsigned long lres,bytes;
- unsigned long my_lres,my_bytes,conn_bytes;
- unsigned short conn_lres;
- unsigned long bcount=0;
- unsigned long kbcount=0;
-#ifdef NEXT
- float tick=HZ;
-#else
- float tick=sysconf(_SC_CLK_TCK);
-#endif
-#endif /* STATUS */
- int short_report=0;
- int no_table_report=0;
- server_rec *server = r->server;
- short_score score_record;
- char status[]="??????????";
- char stat_buffer[HARD_SERVER_LIMIT];
- clock_t tu,ts,tcu,tcs;
-
- tu=ts=tcu=tcs=0;
-
- status[SERVER_DEAD]='.'; /* We don't want to assume these are in */
- status[SERVER_READY]='_'; /* any particular order in scoreboard.h */
- status[SERVER_STARTING]='S';
- status[SERVER_BUSY_READ]='R';
- status[SERVER_BUSY_WRITE]='W';
- status[SERVER_BUSY_KEEPALIVE]='K';
- status[SERVER_BUSY_LOG]='L';
- status[SERVER_BUSY_DNS]='D';
- status[SERVER_GRACEFUL]='G';
-
- if (!exists_scoreboard_image()) {
- log_printf(r->server, "Server status unavailable in inetd mode");
- return HTTP_NOT_IMPLEMENTED;
- }
- r->allowed = (1 << M_GET) | (1 << M_TRACE);
- if (r->method_number != M_GET) return HTTP_METHOD_NOT_ALLOWED;
-
- r->content_type = "text/html";
-
- /*
- * Simple table-driven form data set parser that lets you alter the header
- */
-
- if (r->args)
- {
- i = 0;
- while (options[i].id != STAT_OPT_END)
- {
- if ((loc = strstr(r->args,options[i].form_data_str)) != NULL)
- {
- switch (options[i].id)
- {
- case STAT_OPT_REFRESH:
- if(*(loc + strlen(options[i].form_data_str)) == '=')
- table_set(r->headers_out,options[i].hdr_out_str,
- loc+strlen(options[i].hdr_out_str)+1);
- else
- table_set(r->headers_out,options[i].hdr_out_str,"1");
- break;
- case STAT_OPT_NOTABLE:
- no_table_report = 1;
- break;
- case STAT_OPT_AUTO:
- r->content_type = "text/plain";
- short_report = 1;
- break;
- }
- }
- i++;
- }
- }
-
- send_http_header(r);
-
- if (r->header_only)
- return 0;
-
- sync_scoreboard_image();
- for (i = 0; i<HARD_SERVER_LIMIT; ++i)
- {
- score_record = get_scoreboard_info(i);
- res = score_record.status;
- stat_buffer[i] = status[res];
- if (res == SERVER_READY)
- ready++;
- else if (res == SERVER_BUSY_READ || res==SERVER_BUSY_WRITE ||
- res == SERVER_STARTING || res==SERVER_BUSY_KEEPALIVE ||
- res == SERVER_BUSY_LOG || res==SERVER_BUSY_DNS ||
- res == SERVER_GRACEFUL)
- busy++;
-#if defined(STATUS)
- lres = score_record.access_count;
- bytes= score_record.bytes_served;
- if (lres!=0 || (score_record.status != SERVER_READY
- && score_record.status != SERVER_DEAD))
- {
- tu+=score_record.times.tms_utime;
- ts+=score_record.times.tms_stime;
- tcu+=score_record.times.tms_cutime;
- tcs+=score_record.times.tms_cstime;
- count+=lres;
- bcount+=bytes;
- if (bcount>=KBYTE) {
- kbcount += (bcount >> 10);
- bcount = bcount & 0x3ff;
- }
- }
-#endif /* STATUS */
- }
-
- up_time=nowtime-restart_time;
-
- hard_timeout("send status info", r);
-
- if (!short_report)
- {
- rputs("<HTML><HEAD>\n<TITLE>Apache Status</TITLE>\n</HEAD><BODY>\n",r);
- rputs("<H1>Apache Server Status for ",r);
- rvputs(r,server->server_hostname,"</H1>\n\n",NULL);
- rvputs(r,"Current Time: ",asctime(localtime(&nowtime)),"<br>\n",NULL);
- rvputs(r,"Restart Time: ",asctime(localtime(&restart_time)),"<br>\n",
- NULL);
- rputs("Server uptime: ",r);
- show_time(r,up_time);
- rputs("<br>\n",r);
- }
-
-#if defined(STATUS)
- if (short_report)
- {
- rprintf(r,"Total Accesses: %lu\nTotal kBytes: %lu\n",count,kbcount);
-
-#ifndef __EMX__
- /* Allow for OS/2 not having CPU stats */
- if(ts || tu || tcu || tcs)
- rprintf(r,"CPULoad: %g\n",(tu+ts+tcu+tcs)/tick/up_time*100.);
-#endif
-
- rprintf(r,"Uptime: %ld\n",(long)(up_time));
- if (up_time>0)
- rprintf(r,"ReqPerSec: %g\n",(float)count/(float)up_time);
-
- if (up_time>0)
- rprintf(r,"BytesPerSec: %g\n",KBYTE*(float)kbcount/(float)up_time);
-
- if (count>0)
- rprintf(r,"BytesPerReq: %g\n",KBYTE*(float)kbcount/(float)count);
- } else /* !short_report */
- {
- rprintf(r,"Total accesses: %lu - Total Traffic: ", count);
- format_kbyte_out(r,kbcount);
-
-#ifndef __EMX__
- /* Allow for OS/2 not having CPU stats */
- rputs("<br>\n",r);
- rprintf(r,"CPU Usage: u%g s%g cu%g cs%g",
- tu/tick,ts/tick,tcu/tick,tcs/tick);
-
- if(ts || tu || tcu || tcs)
- rprintf(r," - %.3g%% CPU load",(tu+ts+tcu+tcs)/tick/up_time*100.);
-#endif
-
- rputs("<br>\n",r);
-
- if (up_time>0)
- rprintf(r,"%.3g requests/sec - ",
- (float)count/(float)up_time);
-
- if (up_time>0)
- {
- format_byte_out(r,KBYTE*(float)kbcount/(float)up_time);
- rputs("/second - ",r);
- }
-
- if (count>0)
- {
- format_byte_out(r,KBYTE*(float)kbcount/(float)count);
- rputs("/request",r);
- }
-
- rputs("<br>\n",r);
- } /* short_report */
-#endif /* STATUS */
-
- if (!short_report)
- rprintf(r,"\n%d requests currently being processed, %d idle servers\n"
- ,busy,ready);
- else
- rprintf(r,"BusyServers: %d\nIdleServers: %d\n",busy,ready);
-
- /* send the scoreboard 'table' out */
-
- if(!short_report)
- rputs("<PRE>",r);
- else
- rputs("Scoreboard: ",r);
-
- for (i = 0; i<HARD_SERVER_LIMIT; ++i)
- {
- rputc(stat_buffer[i], r);
- if((i%STATUS_MAXLINE == (STATUS_MAXLINE - 1))&&!short_report)
- rputs("\n",r);
- }
-
- if (short_report)
- rputs("\n",r);
- else {
- rputs("</PRE>\n",r);
- rputs("Scoreboard Key: <br>\n",r);
- rputs("\"<B><code>_</code></B>\" Waiting for Connection, \n",r);
- rputs("\"<B><code>S</code></B>\" Starting up, \n",r);
- rputs("\"<B><code>R</code></B>\" Reading Request,<BR>\n",r);
- rputs("\"<B><code>W</code></B>\" Sending Reply, \n",r);
- rputs("\"<B><code>K</code></B>\" Keepalive (read), \n",r);
- rputs("\"<B><code>D</code></B>\" DNS Lookup,<BR>\n",r);
- rputs("\"<B><code>L</code></B>\" Logging, \n",r);
- rputs("\"<B><code>G</code></B>\" Gracefully finishing, \n",r);
- rputs("\"<B><code>.</code></B>\" Open slot with no current process<P>\n",r);
- }
-
-#if defined(STATUS)
- if (!short_report)
- if(no_table_report)
- rputs("<p><hr><h2>Server Details</h2>\n\n",r);
- else
-#ifdef __EMX__
- /* Allow for OS/2 not having CPU stats */
- rputs("<p>\n\n<table border=0><tr><th>Srv<th>PID<th>Acc<th>M\n<th>SS<th>Conn<th>Child<th>Slot<th>Host<th>VHost<th>Request</tr>\n\n",r);
-#else
- rputs("<p>\n\n<table border=0><tr><th>Srv<th>PID<th>Acc<th>M<th>CPU\n<th>SS<th>Conn<th>Child<th>Slot<th>Host<th>VHost<th>Request</tr>\n\n",r);
-#endif
-
-
- for (i = 0; i<HARD_SERVER_LIMIT; ++i)
- {
- score_record=get_scoreboard_info(i);
- lres = score_record.access_count;
- my_lres = score_record.my_access_count;
- conn_lres = score_record.conn_count;
- bytes= score_record.bytes_served;
- my_bytes = score_record.my_bytes_served;
- conn_bytes = score_record.conn_bytes;
- if (lres!=0 || (score_record.status != SERVER_READY
- && score_record.status != SERVER_DEAD))
- {
- if (!short_report)
- {
- if (no_table_report)
- {
- rprintf(r,"<b>Server %d</b> (%d): %d|%lu|%lu [",
- i,(int)score_record.pid,(int)conn_lres,my_lres,lres);
-
- switch (score_record.status)
- {
- case SERVER_READY:
- rputs("Ready",r);
- break;
- case SERVER_STARTING:
- rputs("Starting",r);
- break;
- case SERVER_BUSY_READ:
- rputs("<b>Read</b>",r);
- break;
- case SERVER_BUSY_WRITE:
- rputs("<b>Write</b>",r);
- break;
- case SERVER_BUSY_KEEPALIVE:
- rputs("<b>Keepalive</b>",r);
- break;
- case SERVER_BUSY_LOG:
- rputs("<b>Logging</b>",r);
- break;
- case SERVER_BUSY_DNS:
- rputs("<b>DNS lookup</b>",r);
- break;
- case SERVER_DEAD:
- rputs("Dead",r);
- break;
- case SERVER_GRACEFUL:
- rputs("Graceful",r);
- break;
- default:
- rputs("?STATE?",r);
- break;
- }
-#ifdef __EMX__
- /* Allow for OS/2 not having CPU stats */
- rprintf(r,"]\n %s (",
-#else
-
- rprintf(r,"] u%g s%g cu%g cs%g\n %s (",
- score_record.times.tms_utime/tick,
- score_record.times.tms_stime/tick,
- score_record.times.tms_cutime/tick,
- score_record.times.tms_cstime/tick,
-#endif
- asctime(localtime(&score_record.last_used)));
- format_byte_out(r,conn_bytes);
- rputs("|",r);
- format_byte_out(r,my_bytes);
- rputs("|",r);
- format_byte_out(r,bytes);
- rputs(")\n",r);
- rprintf(r," <i>%s {%s}</i><br>\n\n",
- score_record.client,
- escape_html(r->pool, score_record.request));
- }
- else /* !no_table_report */
- {
- rprintf(r,"<tr><td><b>%d</b><td>%d<td>%d/%lu/%lu",
- i,(int)score_record.pid,(int)conn_lres,my_lres,lres);
-
- switch (score_record.status)
- {
- case SERVER_READY:
- rputs("<td>_",r);
- break;
- case SERVER_STARTING:
- rputs("<td><b>S</b>",r);
- break;
- case SERVER_BUSY_READ:
- rputs("<td><b>R</b>",r);
- break;
- case SERVER_BUSY_WRITE:
- rputs("<td><b>W</b>",r);
- break;
- case SERVER_BUSY_KEEPALIVE:
- rputs("<td><b>K</b>",r);
- break;
- case SERVER_BUSY_LOG:
- rputs("<td><b>L</b>",r);
- break;
- case SERVER_BUSY_DNS:
- rputs("<td><b>D</b>",r);
- break;
- case SERVER_DEAD:
- rputs("<td>.",r);
- break;
- case SERVER_GRACEFUL:
- rputs("<td>G",r);
- break;
- default:
- rputs("<td>?",r);
- break;
- }
-#ifdef __EMX__
- /* Allow for OS/2 not having CPU stats */
- rprintf(r,"\n<td>%.0f",
-#else
- rprintf(r,"\n<td>%.2f<td>%.0f",
- (score_record.times.tms_utime +
- score_record.times.tms_stime +
- score_record.times.tms_cutime +
- score_record.times.tms_cstime)/tick,
-#endif
- difftime(nowtime, score_record.last_used));
- rprintf(r,"<td>%-1.1f<td>%-2.2f<td>%-2.2f\n",
- (float)conn_bytes/KBYTE, (float)my_bytes/MBYTE,
- (float)bytes/MBYTE);
- rprintf(r,"<td>%s<td nowrap>%s<td nowrap>%s</tr>\n\n",
- score_record.client, score_record.vhost,
- escape_html(r->pool, score_record.request));
- } /* no_table_report */
- } /* !short_report */
- } /* if (<active child>) */
- } /* for () */
-
- if (!(short_report || no_table_report))
- {
-#ifdef __EMX__
- rputs("</table>\n \
-<hr> \
-<table>\n \
-<tr><th>Srv<td>Server number\n \
-<tr><th>PID<td>OS process ID\n \
-<tr><th>Acc<td>Number of accesses this connection / this child / this slot\n \
-<tr><th>M<td>Mode of operation\n \
-<tr><th>SS<td>Seconds since beginning of most recent request\n \
-<tr><th>Conn<td>Kilobytes transferred this connection\n \
-<tr><th>Child<td>Megabytes transferred this child\n \
-<tr><th>Slot<td>Total megabytes transferred this slot\n \
-</table>\n",r);
-#else
- rputs("</table>\n \
-<hr> \
-<table>\n \
-<tr><th>Srv<td>Server number\n \
-<tr><th>PID<td>OS process ID\n \
-<tr><th>Acc<td>Number of accesses this connection / this child / this slot\n \
-<tr><th>M<td>Mode of operation\n \
-<tr><th>CPU<td>CPU usage, number of seconds\n \
-<tr><th>SS<td>Seconds since beginning of most recent request\n \
-<tr><th>Conn<td>Kilobytes transferred this connection\n \
-<tr><th>Child<td>Megabytes transferred this child\n \
-<tr><th>Slot<td>Total megabytes transferred this slot\n \
-</table>\n",r);
-#endif
- }
-
-#else /* !defined(STATUS) */
-
- rputs("<hr>To obtain a full report with current status information and",r);
- rputs(" DNS and LOGGING status codes \n",r);
- rputs("you need to recompile Apache after adding the line <pre>",r);
- rputs("Rule STATUS=yes</pre>into the file <code>Configuration</code>\n",r);
-
-#endif /* STATUS */
-
- if (!short_report)
- rputs("</BODY></HTML>\n",r);
-
- kill_timeout(r);
- return 0;
-}
-
-handler_rec status_handlers[] =
-{
-{ STATUS_MAGIC_TYPE, status_handler },
-{ "server-status", status_handler },
-{ NULL }
-};
-
-module status_module =
-{
- STANDARD_MODULE_STUFF,
- NULL, /* initializer */
- NULL, /* dir config creater */
- NULL, /* dir merger --- default is to override */
- NULL, /* server config */
- NULL, /* merge server config */
- NULL, /* command table */
- status_handlers, /* handlers */
- NULL, /* filename translation */
- NULL, /* check_user_id */
- NULL, /* check auth */
- NULL, /* check access */
- NULL, /* type_checker */
- NULL, /* fixups */
- NULL, /* logger */
- NULL /* header parser */
-};
diff --git a/usr.sbin/httpd/src/mod_userdir.c b/usr.sbin/httpd/src/mod_userdir.c
deleted file mode 100644
index d251e92b60b..00000000000
--- a/usr.sbin/httpd/src/mod_userdir.c
+++ /dev/null
@@ -1,214 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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_userdir... implement the UserDir command. Broken away from the
- * Alias stuff for a couple of good and not-so-good reasons:
- *
- * 1) It shows a real minimal working example of how to do something like
- * this.
- * 2) I know people who are actually interested in changing this *particular*
- * aspect of server functionality without changing the rest of it. That's
- * what this whole modular arrangement is supposed to be good at...
- *
- * Modified by Alexei Kosut to support the following constructs
- * (server running at www.foo.com, request for /~bar/one/two.html)
- *
- * UserDir public_html -> ~bar/public_html/one/two.html
- * UserDir /usr/web -> /usr/web/bar/one/two.html
- * UserDir /home/ * /www -> /home/bar/www/one/two.html
- * NOTE: theses ^ ^ space only added allow it to work in a comment, ignore
- * UserDir http://x/users -> (302) http://x/users/bar/one/two.html
- * UserDir http://x/ * /y -> (302) http://x/bar/y/one/two.html
- * NOTE: here also ^ ^
- *
- * In addition, you can use multiple entries, to specify alternate
- * user directories (a la Directory Index). For example:
- *
- * UserDir public_html /usr/web http://www.xyz.com/users
- *
- */
-
-#include "httpd.h"
-#include "http_config.h"
-
-module userdir_module;
-
-/*
- * Sever config for this module is a little unconventional...
- * It's just one string anyway, so why pretend?
- */
-
-void *create_userdir_config (pool *dummy, server_rec *s) {
- return (void*)DEFAULT_USER_DIR;
-}
-
-const char *set_user_dir (cmd_parms *cmd, void *dummy, char *arg)
-{
- void *server_conf = cmd->server->module_config;
-
- set_module_config (server_conf, &userdir_module, pstrdup (cmd->pool, arg));
- return NULL;
-}
-
-command_rec userdir_cmds[] = {
-{ "UserDir", set_user_dir, NULL, RSRC_CONF, RAW_ARGS,
- "the public subdirectory in users' home directories, or 'disabled'" },
-{ NULL }
-};
-
-int translate_userdir (request_rec *r)
-{
- void *server_conf = r->server->module_config;
- const char *userdirs = (char *)get_module_config(server_conf,
- &userdir_module);
- char *name = r->uri;
- const char *w, *dname, *redirect;
- char *x = NULL;
- struct stat statbuf;
-
- if (userdirs == NULL || !strcasecmp(userdirs, "disabled") ||
- (name[0] != '/') || (name[1] != '~')) {
- return DECLINED;
- }
-
- while (*userdirs) {
- const char *userdir = getword_conf (r->pool, &userdirs);
- char *filename = NULL;
-
- dname = name + 2;
- w = getword(r->pool, &dname, '/');
-
- /* disallow the empty username, . and .. */
- if (w[0] == '\0' || (w[1] == '.' && (w[2] == '\0' || (w[2] == '.' && w[3] == '\0'))))
- return DECLINED;
-
- /* The 'dname' funny business involves backing it up to capture
- * the '/' delimiting the "/~user" part from the rest of the URL,
- * in case there was one (the case where there wasn't being just
- * "GET /~user HTTP/1.0", for which we don't want to tack on a
- * '/' onto the filename).
- */
-
- if (dname[-1] == '/') --dname;
-
- if (strchr(userdir, '*'))
- x = getword(r->pool, &userdir, '*');
-
-#ifdef __EMX__
- /* Add support for OS/2 drive letters */
- if ((userdir[0] == '/') || (userdir[1] == ':') || (userdir[0] == '\0')) {
-#else
- if ((userdir[0] == '/') || (userdir[0] == '\0')) {
-#endif
- if (x) {
- if (strchr(x, ':')) {
- redirect = pstrcat(r->pool, x, w, userdir, dname, NULL);
- table_set (r->headers_out, "Location", redirect);
- return REDIRECT;
- }
- else
- filename = pstrcat (r->pool, x, w, userdir, NULL);
- }
- else
- filename = pstrcat (r->pool, userdir, "/", w, NULL);
- }
- else if (strchr(userdir, ':')) {
- redirect = pstrcat(r->pool, userdir, "/", w, dname, NULL);
- table_set (r->headers_out, "Location", redirect);
- return REDIRECT;
- }
- else {
- struct passwd *pw;
- if((pw=getpwnam(w)))
-#ifdef __EMX__
- /* Need to manually add user name for OS/2 */
- filename = pstrcat (r->pool, pw->pw_dir, w, "/", userdir, NULL);
-#else
- filename = pstrcat (r->pool, pw->pw_dir, "/", userdir, NULL);
-#endif
-
- }
-
- /* Now see if it exists, or we're at the last entry. If we are at the
- last entry, then use the filename generated (if there is one) anyway,
- in the hope that some handler might handle it. This can be used, for
- example, to run a CGI script for the user.
- */
- if (filename && (!*userdirs || stat(filename, &statbuf) != -1)) {
- r->filename = pstrcat(r->pool, filename, dname, NULL);
- r->finfo = statbuf;
- return OK;
- }
- }
-
- return DECLINED;
-}
-
-module userdir_module = {
- STANDARD_MODULE_STUFF,
- NULL, /* initializer */
- NULL, /* dir config creater */
- NULL, /* dir merger --- default is to override */
- create_userdir_config, /* server config */
- NULL, /* merge server config */
- userdir_cmds, /* command table */
- NULL, /* handlers */
- translate_userdir, /*filename translation */
- NULL, /* check_user_id */
- NULL, /* check auth */
- NULL, /* check access */
- NULL, /* type_checker */
- NULL, /* fixups */
- NULL, /* logger */
- NULL /* header parser */
-};
diff --git a/usr.sbin/httpd/src/mod_usertrack.c b/usr.sbin/httpd/src/mod_usertrack.c
deleted file mode 100644
index 5be43124151..00000000000
--- a/usr.sbin/httpd/src/mod_usertrack.c
+++ /dev/null
@@ -1,328 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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/>.
- *
- */
-
-/* User Tracking Module (Was mod_cookies.c)
- *
- * This Apache module is designed to track users paths through a site.
- * It uses the client-side state ("Cookie") protocol developed by Netscape.
- * It is known to work on Netscape browsers, Microsoft Internet
- * Explorer and others currently being developed.
- *
- * Each time a page is requested we look to see if the browser is sending
- * us a Cookie: header that we previously generated.
- *
- * If we don't find one then the user hasn't been to this site since
- * starting their browser or their browser doesn't support cookies. So
- * we generate a unique Cookie for the transaction and send it back to
- * the browser (via a "Set-Cookie" header)
- * Future requests from the same browser should keep the same Cookie line.
- *
- * By matching up all the requests with the same cookie you can
- * work out exactly what path a user took through your site. To log
- * the cookie use the " %{Cookie}n " directive in a custom access log;
- *
- * Example 1 : If you currently use the standard Log file format (CLF)
- * and use the command "TransferLog somefilename", add the line
- * LogFormat "%h %l %u %t \"%r\" %s %b %{Cookie}n"
- * to your config file.
- *
- * Example 2 : If you used to use the old "CookieLog" directive, you
- * can emulate it by adding the following command to your config file
- * CustomLog filename "%{Cookie}n \"%r\" %t"
- *
- * Notes:
- * 1. This code now logs the initial transaction (the one that created
- * the cookie to start with).
- * 2. This module has been designed to not interfere with other Cookies
- * your site may be using; just avoid sending out cookies with
- * the name "Apache=" or things will get confused.
- * 3. If you want you can modify the Set-Cookie line so that the Cookie
- * never expires. You would then get the same Cookie each time the
- * user revisits your site.
- *
- * Mark Cox, mark@ukweb.com, 6 July 95
- *
- * This file replaces mod_cookies.c
- */
-
-#include "httpd.h"
-#include "http_config.h"
-#include "http_core.h"
-#ifndef MPE
-#include <sys/time.h>
-#endif
-
-module usertrack_module;
-
-typedef struct {
- int always;
- time_t expires;
-} cookie_log_state;
-
-/* Define this to allow post-2000 cookies. Cookies use two-digit dates,
- * so it might be dicey. (Netscape does it correctly, but others may not)
- */
-#define MILLENIAL_COOKIES
-
-/* Make Cookie: Now we have to generate something that is going to be
- * pretty unique. We can base it on the pid, time, hostip */
-
-#define COOKIE_NAME "Apache="
-
-void make_cookie(request_rec *r)
-{
- cookie_log_state *cls = get_module_config (r->server->module_config,
- &usertrack_module);
-#ifdef MPE
- clock_t mpe_times;
- struct tms mpe_tms;
-#else
- struct timeval tv;
- struct timezone tz = { 0 , 0 };
-#endif
- /* 1024 == hardcoded constants */
- char *new_cookie = palloc( r->pool, 1024);
- char *cookiebuf = palloc( r->pool, 1024);
- char *dot;
- const char *rname = pstrdup(r->pool,
- get_remote_host(r->connection, r->per_dir_config,
- REMOTE_NAME));
-
- if ((dot = strchr(rname,'.'))) *dot='\0'; /* First bit of hostname */
-
-#ifdef MPE
-/* MPE lacks gettimeofday(), so we must use time() to obtain the epoch
- seconds, and then times() to obtain CPU clock ticks (milliseconds).
- Combine this together to obtain a hopefully unique cookie ID. */
-
- mpe_times=times(&mpe_tms);
-
- ap_snprintf(cookiebuf, 1024, "%s%d%ld%ld", rname, (int)getpid(),
- (long)time(NULL), (long)mpe_tms.tms_utime);
-#else
- gettimeofday(&tv, &tz);
-
- ap_snprintf(cookiebuf, 1024, "%s%d%ld%d", rname, (int)getpid(),
- (long)tv.tv_sec, (int)tv.tv_usec/1000);
-#endif
-
- if (cls->expires) {
- static const char *const days[7]=
- {"Sun","Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
- struct tm *tms;
- time_t when = time(NULL) + cls->expires;
-
-#ifndef MILLENIAL_COOKIES
- /* Only two-digit date string, so we can't trust "00" or more.
- * Therefore, we knock it all back to just before midnight on
- * 1/1/2000 (which is 946684799)
- */
-
- if (when > 946684799)
- when = 946684799;
-#endif
- tms = gmtime(&when);
-
- /* Cookie with date; as strftime '%a, %d-%h-%y %H:%M:%S GMT' */
- ap_snprintf(new_cookie, 1024,
- "%s%s; path=/; expires=%s, %.2d-%s-%.2d %.2d:%.2d:%.2d GMT",
- COOKIE_NAME, cookiebuf, days[tms->tm_wday],
- tms->tm_mday, month_snames[tms->tm_mon],
- (tms->tm_year >= 100) ? tms->tm_year - 100 : tms->tm_year,
- tms->tm_hour, tms->tm_min, tms->tm_sec);
- }
- else
- ap_snprintf(new_cookie, 1024, "%s%s; path=/", COOKIE_NAME, cookiebuf);
-
- table_set(r->headers_out,"Set-Cookie",new_cookie);
- table_set(r->notes, "cookie", cookiebuf); /* log first time */
- return;
-}
-
-int spot_cookie(request_rec *r)
-{
- int *enable = (int *)get_module_config(r->per_dir_config,
- &usertrack_module);
- char *cookie;
- char *value;
-
- if (!*enable) return DECLINED;
-
- if ((cookie = table_get (r->headers_in, "Cookie")))
- if ((value=strstr(cookie,COOKIE_NAME))) {
- char *cookiebuf, *cookieend;
-
- value+=strlen(COOKIE_NAME);
- cookiebuf=pstrdup( r->pool, value );
- cookieend=strchr(cookiebuf,';');
- if (cookieend) *cookieend='\0'; /* Ignore anything after a ; */
-
- /* Set the cookie in a note, for logging */
- table_set(r->notes, "cookie", cookiebuf);
-
- return DECLINED; /* Theres already a cookie, no new one */
- }
- make_cookie(r);
- return OK; /* We set our cookie */
-}
-
-void *make_cookie_log_state (pool *p, server_rec *s)
-{
- cookie_log_state *cls =
- (cookie_log_state *)palloc (p, sizeof (cookie_log_state));
-
- cls->expires = 0;
-
- return (void *)cls;
-}
-
-void *make_cookie_dir (pool *p, char *d) {
- return (void *)pcalloc(p, sizeof(int));
-}
-
-const char *set_cookie_enable (cmd_parms *cmd, int *c, int arg)
-{
- *c = arg;
- return NULL;
-}
-
-const char *set_cookie_exp (cmd_parms *parms, void *dummy, const char *arg)
-{
- cookie_log_state *cls = get_module_config (parms->server->module_config,
- &usertrack_module);
- time_t factor, modifier = 0;
- time_t num = 0;
- char *word;
-
- /* The simple case first - all numbers (we assume) */
- if (isdigit(arg[0]) && isdigit(arg[strlen(arg)-1])) {
- cls->expires = atol(arg);
- return NULL;
- }
-
- /* The harder case - stolen from mod_expires
- * CookieExpires "[plus] {<num> <type>}*"
- */
-
- word = getword_conf( parms->pool, &arg );
- if ( !strncasecmp( word, "plus", 1 ) ) {
- word = getword_conf( parms->pool, &arg );
- };
-
- /* {<num> <type>}* */
- while ( word[0] ) {
- /* <num> */
- if ( strchr("0123456789", word[0]) != NULL )
- num = atoi( word );
- else
- return "bad expires code, numeric value expected.";
-
- /* <type> */
- word = getword_conf( parms->pool, &arg );
- if (!word[0] )
- return "bad expires code, missing <type>";
-
- factor = 0;
- if ( !strncasecmp( word, "years", 1 ) )
- factor = 60*60*24*365;
- else if ( !strncasecmp( word, "months", 2 ) )
- factor = 60*60*24*30;
- else if ( !strncasecmp( word, "weeks", 1 ) )
- factor = 60*60*24*7;
- else if ( !strncasecmp( word, "days", 1 ) )
- factor = 60*60*24;
- else if ( !strncasecmp( word, "hours", 1 ) )
- factor = 60*60;
- else if ( !strncasecmp( word, "minutes", 2 ) )
- factor = 60;
- else if ( !strncasecmp( word, "seconds", 1 ) )
- factor = 1;
- else
- return "bad expires code, unrecognized type";
-
- modifier = modifier + factor * num;
-
- /* next <num> */
- word = getword_conf( parms->pool, &arg );
- }
-
- cls->expires = modifier;
-
- return NULL;
-}
-
-command_rec cookie_log_cmds[] = {
-{ "CookieExpires", set_cookie_exp, NULL, RSRC_CONF, TAKE1,
- "an expiry date code" },
-{ "CookieTracking", set_cookie_enable, NULL, OR_FILEINFO, FLAG,
- "whether or not to enable cookies" },
-{ NULL }
-};
-
-module usertrack_module = {
- STANDARD_MODULE_STUFF,
- NULL, /* initializer */
- make_cookie_dir, /* dir config creater */
- NULL, /* dir merger --- default is to override */
- make_cookie_log_state, /* server config */
- NULL, /* merge server configs */
- cookie_log_cmds, /* command table */
- NULL, /* handlers */
- NULL, /* filename translation */
- NULL, /* check_user_id */
- NULL, /* check auth */
- NULL, /* check access */
- NULL, /* type_checker */
- spot_cookie, /* fixups */
- NULL, /* logger */
- NULL /* header parser */
-};
diff --git a/usr.sbin/httpd/src/modules/example/Makefile b/usr.sbin/httpd/src/modules/example/Makefile
deleted file mode 100644
index 9bec391a3bf..00000000000
--- a/usr.sbin/httpd/src/modules/example/Makefile
+++ /dev/null
@@ -1,107 +0,0 @@
-# ====================================================================
-# Copyright (c) 1995-1997 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. 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/>.
-#
-# Makefile for the Apache example module
-#
-
-#
-# This normally lives in modules/example under the Apache source
-# directory. If the depth or relationship changes, the following line
-# may need to be changed.
-#
-INCDIR=../..
-
-#
-# Everything below this point should be invariant.
-#
-SHELL=/bin/sh
-
-#
-# We inherit the definitions of CC, AUX_CFLAGS, and RANLIB from an
-# upline make(1) call.
-#
-CFLAGS=-I$(INCDIR) $(AUX_CFLAGS)
-
-MODULES=mod_example.o
-OBJS= \
- $(MODULES)
-
-#
-# Now the rules saying how things are built.
-#
-.c.o:
- $(CC) -c $(CFLAGS) $<
-
-all: $(OBJS)
-
-clean:
- rm -f $(OBJS)
-
-#
-# Finally, what depnds upon which, so make can figure out what it needs
-# to do.
-#
-
-#
-# Make sure that things get rebuilt if the Makefiles are changed.
-#
-$(OBJS): \
- Makefile \
- $(INCDIR)/Makefile
-
-mod_example.o: \
- $(INCDIR)/httpd.h \
- $(INCDIR)/http_config.h \
- $(INCDIR)/http_core.h \
- $(INCDIR)/http_log.h \
- $(INCDIR)/http_main.h \
- $(INCDIR)/http_protocol.h \
- $(INCDIR)/util_script.h \
- mod_example.c
diff --git a/usr.sbin/httpd/src/modules/proxy/Makefile b/usr.sbin/httpd/src/modules/proxy/Makefile
deleted file mode 100644
index 102dea2a25f..00000000000
--- a/usr.sbin/httpd/src/modules/proxy/Makefile
+++ /dev/null
@@ -1,89 +0,0 @@
-# ====================================================================
-# Copyright (c) 1995-1997 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. 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/>.
-#
-# Makefile for the Apache proxy library
-#
-
-SHELL = /bin/sh
-
-INCDIR = ../..
-
-LIB=libproxy.a
-
-# AUX_CFLAGS comes from higher level Makefile
-CFLAGS=-I$(INCDIR) $(AUX_CFLAGS)
-
-# Internal stuff, should not need changing.
-PROXYSRC=mod_proxy.c proxy_cache.c proxy_connect.c proxy_ftp.c proxy_http.c \
-proxy_util.c
-
-OBJS=$(PROXYSRC:.c=.o)
-
-default: force $(LIB)
-
-.c.a:
- $(MAKE) $(CFLAGS) $<
-
-force:
- rm -f $(LIB)
-
-$(LIB): $(OBJS)
- ar crv $@ $(OBJS)
- $(RANLIB) $@
-
-clean:
- rm -f *.o libproxy.a
-
-# dependencies
-$(OBJS): mod_proxy.h $(INCDIR)/httpd.h $(INCDIR)/http_config.h $(INCDIR)/http_protocol.h
-proxy_cache.o proxy_connect.o proxy_ftp.o proxy_http.o proxy_util.o: $(INCDIR)/http_main.h
-proxy_cache.o proxy_connect.o proxy_http.o: $(INCDIR)/http_log.h
-proxy_cache.o proxy_http.o: $(INCDIR)/util_date.h
-proxy_cache.o proxy_util.o: $(INCDIR)/md5.h
diff --git a/usr.sbin/httpd/src/regex/Makefile b/usr.sbin/httpd/src/regex/Makefile
deleted file mode 100644
index e4ea0154bea..00000000000
--- a/usr.sbin/httpd/src/regex/Makefile
+++ /dev/null
@@ -1,133 +0,0 @@
-SHELL = /bin/sh
-
-# You probably want to take -DREDEBUG out of CFLAGS, and put something like
-# -O in, *after* testing (-DREDEBUG strengthens testing by enabling a lot of
-# internal assertion checking and some debugging facilities).
-# Put -Dconst= in for a pre-ANSI compiler.
-# Do not take -DPOSIX_MISTAKE out.
-# REGCFLAGS isn't important to you (it's for my use in some special contexts).
-CFLAGS=-I. -DPOSIX_MISTAKE $(AUX_CFLAGS)
-
-# If you have a pre-ANSI compiler, put -o into MKHFLAGS. If you want
-# the Berkeley __P macro, put -b in.
-MKHFLAGS=
-
-# Flags for linking but not compiling, if any.
-LDFLAGS=
-
-# Extra libraries for linking, if any.
-LIBS=
-
-# Internal stuff, should not need changing.
-OBJPRODN=regcomp.o regexec.o regerror.o regfree.o
-OBJS=$(OBJPRODN) split.o debug.o main.o
-H=cclass.h cname.h regex2.h utils.h
-REGSRC=regcomp.c regerror.c regexec.c regfree.c
-ALLSRC=$(REGSRC) engine.c debug.c main.c split.c
-
-# Stuff that matters only if you're trying to lint the package.
-LINTFLAGS=-I. -Dstatic= -Dconst= -DREDEBUG
-LINTC=regcomp.c regexec.c regerror.c regfree.c debug.c main.c
-JUNKLINT=possible pointer alignment|null effect
-
-# arrangements to build forward-reference header files
-.SUFFIXES: .ih .h
-.c.ih:
- sh ./mkh $(MKHFLAGS) -p $< >$@
-
-default: r
-
-lib: purge $(OBJPRODN)
- rm -f libregex.a
- ar crv libregex.a $(OBJPRODN)
- $(RANLIB) libregex.a
-
-purge:
- rm -f *.o
-
-# stuff to build regex.h
-REGEXH=regex.h
-REGEXHSRC=regex2.h $(REGSRC)
-$(REGEXH): $(REGEXHSRC) mkh
- sh ./mkh $(MKHFLAGS) -i _REGEX_H_ $(REGEXHSRC) >regex.tmp
- cmp -s regex.tmp regex.h 2>/dev/null || cp regex.tmp regex.h
- rm -f regex.tmp
-
-# dependencies
-$(OBJPRODN) debug.o: utils.h regex.h regex2.h
-regcomp.o: cclass.h cname.h regcomp.ih
-regexec.o: engine.c engine.ih
-regerror.o: regerror.ih
-debug.o: debug.ih
-main.o: main.ih
-
-# tester
-re: $(OBJS)
- $(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) $(LIBS) -o $@
-
-# regression test
-r: re tests
- ./re <tests
- ./re -el <tests
- ./re -er <tests
-
-# 57 variants, and other stuff, for development use -- not useful to you
-ra: ./re tests
- -./re <tests
- -./re -el <tests
- -./re -er <tests
-
-rx: ./re tests
- ./re -x <tests
- ./re -x -el <tests
- ./re -x -er <tests
-
-t: ./re tests
- -time ./re <tests
- -time ./re -cs <tests
- -time ./re -el <tests
- -time ./re -cs -el <tests
-
-l: $(LINTC)
- lint $(LINTFLAGS) -h $(LINTC) 2>&1 | egrep -v '$(JUNKLINT)' | tee lint
-
-fullprint:
- ti README WHATSNEW notes todo | list
- ti *.h | list
- list *.c
- list regex.3 regex.7
-
-print:
- ti README WHATSNEW notes todo | list
- ti *.h | list
- list reg*.c engine.c
-
-
-mf.tmp: Makefile
- sed '/^REGEXH=/s/=.*/=regex.h/' Makefile | sed '/#DEL$$/d' >$@
-
-DTRH=cclass.h cname.h regex2.h utils.h
-PRE=COPYRIGHT README WHATSNEW
-POST=mkh regex.3 regex.7 tests $(DTRH) $(ALLSRC) fake/*.[ch]
-FILES=$(PRE) Makefile $(POST)
-DTR=$(PRE) Makefile=mf.tmp $(POST)
-dtr: $(FILES) mf.tmp
- makedtr $(DTR) >$@
- rm mf.tmp
-
-cio: $(FILES)
- cio $(FILES)
-
-rdf: $(FILES)
- rcsdiff -c $(FILES) 2>&1 | p
-
-# various forms of cleanup
-tidy:
- rm -f junk* core core.* *.core dtr *.tmp lint
-
-clean: tidy
- rm -f *.o *.s *.ih re libregex.a
-
-# don't do this one unless you know what you're doing
-spotless: clean
- rm -f mkh regex.h
diff --git a/usr.sbin/httpd/src/regex/regex.h b/usr.sbin/httpd/src/regex/regex.h
deleted file mode 100644
index dde954d8332..00000000000
--- a/usr.sbin/httpd/src/regex/regex.h
+++ /dev/null
@@ -1,73 +0,0 @@
-#ifndef _REGEX_H_
-#define _REGEX_H_ /* never again */
-/* ========= begin header generated by ./mkh ========= */
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* === regex2.h === */
-typedef off_t regoff_t;
-typedef struct {
- int re_magic;
- size_t re_nsub; /* number of parenthesized subexpressions */
- const char *re_endp; /* end pointer for REG_PEND */
- struct re_guts *re_g; /* none of your business :-) */
-} regex_t;
-typedef struct {
- regoff_t rm_so; /* start of match */
- regoff_t rm_eo; /* end of match */
-} regmatch_t;
-
-
-/* === regcomp.c === */
-extern int regcomp(regex_t *, const char *, int);
-#define REG_BASIC 0000
-#define REG_EXTENDED 0001
-#define REG_ICASE 0002
-#define REG_NOSUB 0004
-#define REG_NEWLINE 0010
-#define REG_NOSPEC 0020
-#define REG_PEND 0040
-#define REG_DUMP 0200
-
-
-/* === regerror.c === */
-#define REG_NOMATCH 1
-#define REG_BADPAT 2
-#define REG_ECOLLATE 3
-#define REG_ECTYPE 4
-#define REG_EESCAPE 5
-#define REG_ESUBREG 6
-#define REG_EBRACK 7
-#define REG_EPAREN 8
-#define REG_EBRACE 9
-#define REG_BADBR 10
-#define REG_ERANGE 11
-#define REG_ESPACE 12
-#define REG_BADRPT 13
-#define REG_EMPTY 14
-#define REG_ASSERT 15
-#define REG_INVARG 16
-#define REG_ATOI 255 /* convert name to number (!) */
-#define REG_ITOA 0400 /* convert number to name (!) */
-extern size_t regerror(int, const regex_t *, char *, size_t);
-
-
-/* === regexec.c === */
-extern int regexec(const regex_t *, const char *, size_t, regmatch_t [], int);
-#define REG_NOTBOL 00001
-#define REG_NOTEOL 00002
-#define REG_STARTEND 00004
-#define REG_TRACE 00400 /* tracing of execution */
-#define REG_LARGE 01000 /* force large representation */
-#define REG_BACKR 02000 /* force use of backref code */
-
-
-/* === regfree.c === */
-extern void regfree(regex_t *);
-
-#ifdef __cplusplus
-}
-#endif
-/* ========= end header generated by ./mkh ========= */
-#endif
diff --git a/usr.sbin/httpd/src/rfc1413.c b/usr.sbin/httpd/src/rfc1413.c
deleted file mode 100644
index 69f7cda92de..00000000000
--- a/usr.sbin/httpd/src/rfc1413.c
+++ /dev/null
@@ -1,239 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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 conf.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 log_unixerr */
-#include "rfc1413.h"
-
-#ifndef SCO
-extern char *strchr();
-extern char *inet_ntoa();
-#endif
-
-/* 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 rfc1413_timeout = RFC1413_TIMEOUT; /* Global so it can be changed */
-
-JMP_BUF timebuf;
-
-/* bind_connect - bind both ends of a socket */
-
-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];
-
- /*
- * 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)
- {
- log_unixerr("bind", NULL, "rfc1413: Error binding to local port", srv);
- 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 */
- 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. */
- i = 0;
- while(i < strlen(buffer)) {
- int j;
- j = write(sock, buffer+i, (strlen(buffer+i)));
- if (j < 0 && errno != EINTR) {
- log_unixerr("write", NULL, "rfc1413: error sending request", srv);
- 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));
- while((cp = strchr(buffer, '\n')) == NULL && i < sizeof(buffer) - 1) {
- int j;
- j = read(sock, buffer+i, (sizeof(buffer) - 1) - i);
- if (j < 0 && errno != EINTR) {
- log_unixerr("read", NULL, "rfc1413: error reading response", srv);
- return -1;
- }
- else if (j > 0) {
- i+=j;
- }
- }
-
-/* RFC1413_USERLEN = 512 */
- 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 *
-rfc1413(conn_rec *conn, server_rec *srv)
-{
- static char user[RFC1413_USERLEN+1]; /* XXX */
- static char *result;
- static int sock;
-
- result = FROM_UNKNOWN;
-
- sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (sock < 0)
- {
- log_unixerr("socket", NULL, "rfc1413: error creating socket", srv);
- conn->remote_logname = result;
- }
-
- /*
- * Set up a timer so we won't get stuck while waiting for the server.
- */
- if (ap_setjmp(timebuf) == 0)
- {
- signal(SIGALRM, ident_timeout);
- alarm(rfc1413_timeout);
-
- if (get_rfc1413(sock, &conn->local_addr, &conn->remote_addr, user,
- srv)
- >= 0)
- result = user;
-
- alarm(0);
- }
- close(sock);
- conn->remote_logname = result;
-
- return conn->remote_logname;
-}
diff --git a/usr.sbin/httpd/src/rfc1413.h b/usr.sbin/httpd/src/rfc1413.h
deleted file mode 100644
index 91bf42e4aef..00000000000
--- a/usr.sbin/httpd/src/rfc1413.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1996,1997 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. 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/>.
- *
- */
-
-extern char *rfc1413(conn_rec *conn, server_rec *srv);
diff --git a/usr.sbin/httpd/src/scoreboard.h b/usr.sbin/httpd/src/scoreboard.h
deleted file mode 100644
index 5aa808cb4d6..00000000000
--- a/usr.sbin/httpd/src/scoreboard.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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/>.
- *
- */
-
-#include <sys/times.h>
-
-/* Scoreboard info on a process is, for now, kept very brief ---
- * just status value and pid (the latter so that the caretaker process
- * can properly update the scoreboard when a process dies). We may want
- * to eventually add a separate set of long_score structures which would
- * give, for each process, the number of requests serviced, and info on
- * the current, or most recent, request.
- *
- * Status values:
- */
-
-#define SERVER_UNKNOWN (-1) /* should never be in this state */
-#define SERVER_DEAD 0
-#define SERVER_READY 1 /* Waiting for connection (or accept() lock) */
-#define SERVER_STARTING 3 /* Server Starting up */
-#define SERVER_BUSY_READ 2 /* Reading a client request */
-#define SERVER_BUSY_WRITE 4 /* Processing a client request */
-#define SERVER_BUSY_KEEPALIVE 5 /* Waiting for more requests via keepalive */
-#define SERVER_BUSY_LOG 6 /* Logging the request */
-#define SERVER_BUSY_DNS 7 /* Looking up a hostname */
-#define SERVER_GRACEFUL 8 /* server is gracefully finishing request */
-
-typedef struct {
- pid_t pid;
- char status;
-#if defined(STATUS)
- unsigned long access_count;
- unsigned long bytes_served;
- unsigned long my_access_count;
- unsigned long my_bytes_served;
- unsigned long conn_bytes;
- unsigned short conn_count;
- struct tms times;
- time_t last_used;
- char client[32]; /* Keep 'em small... */
- char request[64]; /* We just want an idea... */
- char vhost[32]; /* What virtual host is being accessed? */
-#endif
-} short_score;
-
-typedef struct
- {
- int exit_generation; /* Set by the main process if a graceful
- restart is required */
- } global_score;
-
-typedef struct
- {
- short_score servers[HARD_SERVER_LIMIT];
- global_score global;
- } scoreboard;
-
-#define SCOREBOARD_SIZE sizeof(scoreboard)
-
-extern void sync_scoreboard_image(void);
-short_score get_scoreboard_info(int x);
-int exists_scoreboard_image ();
diff --git a/usr.sbin/httpd/src/util.c b/usr.sbin/httpd/src/util.c
deleted file mode 100644
index 12096af0932..00000000000
--- a/usr.sbin/httpd/src/util.c
+++ /dev/null
@@ -1,1369 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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.c: string utility things
- *
- * 3/21/93 Rob McCool
- * 1995-96 Many changes by the Apache Group
- *
- */
-
-#include "httpd.h"
-#include "http_conf_globals.h" /* for user_id & group_id */
-
-const char month_snames[12][4] = {
- "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"
-};
-
-char *get_time() {
- time_t t;
- char *time_string;
-
- t=time(NULL);
- time_string = ctime(&t);
- time_string[strlen(time_string) - 1] = '\0';
- return (time_string);
-}
-
-char *ht_time(pool *p, time_t t, const char *fmt, int gmt) {
- char ts[MAX_STRING_LEN];
- struct tm *tms;
-
- tms = (gmt ? gmtime(&t) : localtime(&t));
-
- /* check return code? */
- strftime(ts,MAX_STRING_LEN,fmt,tms);
- ts[MAX_STRING_LEN - 1] = '\0';
- return pstrdup (p, ts);
-}
-
-char *gm_timestr_822(pool *p, time_t sec) {
- static const char *const days[7]=
- {"Sun","Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
- char ts[50];
- struct tm *tms;
-
- tms = gmtime(&sec);
-
-/* RFC date format; as strftime '%a, %d %b %Y %T GMT' */
- ap_snprintf(ts, sizeof(ts),
- "%s, %.2d %s %d %.2d:%.2d:%.2d GMT", days[tms->tm_wday],
- tms->tm_mday, month_snames[tms->tm_mon], tms->tm_year + 1900,
- tms->tm_hour, tms->tm_min, tms->tm_sec);
-
- return pstrdup (p, ts);
-}
-
-/* What a pain in the ass. */
-#if defined(HAVE_GMTOFF)
-struct tm *get_gmtoff(int *tz) {
- time_t tt = time(NULL);
- struct tm *t;
-
- t = localtime(&tt);
- *tz = (int) (t->tm_gmtoff / 60);
- return t;
-}
-#else
-struct tm *get_gmtoff(int *tz) {
- time_t tt = time(NULL);
- struct tm gmt;
- struct tm *t;
- int days, hours, minutes;
-
- /* Assume we are never more than 24 hours away. */
- gmt = *gmtime(&tt); /* remember gmtime/localtime return ptr to static */
- t = localtime(&tt); /* buffer... so be careful */
- days = t->tm_yday - gmt.tm_yday;
- hours = ((days < -1 ? 24 : 1 < days ? -24 : days * 24)
- + t->tm_hour - gmt.tm_hour);
- minutes = hours * 60 + t->tm_min - gmt.tm_min;
- *tz = minutes;
- return t;
-}
-#endif
-
-
-/* Match = 0, NoMatch = 1, Abort = -1 */
-/* Based loosely on sections of wildmat.c by Rich Salz
- * Hmmm... shouldn't this really go component by component?
- */
-int strcmp_match(const char *str, const char *exp) {
- int x,y;
-
- for(x=0,y=0;exp[y];++y,++x) {
- if((!str[x]) && (exp[y] != '*'))
- return -1;
- if(exp[y] == '*') {
- while(exp[++y] == '*');
- if(!exp[y])
- return 0;
- while(str[x]) {
- int ret;
- if((ret = strcmp_match(&str[x++],&exp[y])) != 1)
- return ret;
- }
- return -1;
- } else
- if((exp[y] != '?') && (str[x] != exp[y]))
- return 1;
- }
- return (str[x] != '\0');
-}
-
-int strcasecmp_match(const char *str, const char *exp) {
- int x,y;
-
- for(x=0,y=0;exp[y];++y,++x) {
- if((!str[x]) && (exp[y] != '*'))
- return -1;
- if(exp[y] == '*') {
- while(exp[++y] == '*');
- if(!exp[y])
- return 0;
- while(str[x]) {
- int ret;
- if((ret = strcasecmp_match(&str[x++],&exp[y])) != 1)
- return ret;
- }
- return -1;
- } else
- if((exp[y] != '?') && (tolower(str[x]) != tolower(exp[y])))
- return 1;
- }
- return (str[x] != '\0');
-}
-
-int is_matchexp(const char *str) {
- register int x;
-
- for(x=0;str[x];x++)
- if((str[x] == '*') || (str[x] == '?'))
- return 1;
- return 0;
-}
-
-/* This function substitutes for $0-$9, filling in regular expression
- * submatches. Pass it the same nmatch and pmatch arguments that you
- * passed regexec(). pmatch should not be greater than the maximum number
- * of subexpressions - i.e. one more than the re_nsub member of regex_t.
- *
- * input should be the string with the $-expressions, source should be the
- * string that was matched against.
- *
- * It returns the substituted string, or NULL on error.
- *
- * Parts of this code are based on Henry Spencer's regsub(), from his
- * AT&T V8 regexp package.
- */
-
-char *pregsub(pool *p, const char *input, const char *source,
- size_t nmatch, regmatch_t pmatch[]) {
- const char *src = input;
- char *dest, *dst;
- char c;
- int no, len;
-
- if (!source) return NULL;
- if (!nmatch) return pstrdup(p, src);
-
- /* First pass, find the size */
-
- len = 0;
-
- while ((c = *src++) != '\0') {
- if (c == '&')
- no = 0;
- else if (c == '$' && isdigit(*src))
- no = *src++ - '0';
- else
- no = -1;
-
- if (no < 0) { /* Ordinary character. */
- if (c == '\\' && (*src == '$' || *src == '&'))
- c = *src++;
- len++;
- } else if (no < nmatch && pmatch[no].rm_so < pmatch[no].rm_eo) {
- len += pmatch[no].rm_eo - pmatch[no].rm_so;
- }
-
- }
-
- dest = dst = pcalloc(p, len + 1);
-
- /* Now actually fill in the string */
-
- src = input;
-
- while ((c = *src++) != '\0') {
- if (c == '&')
- no = 0;
- else if (c == '$' && isdigit(*src))
- no = *src++ - '0';
- else
- no = -1;
-
- if (no < 0) { /* Ordinary character. */
- if (c == '\\' && (*src == '$' || *src == '&'))
- c = *src++;
- *dst++ = c;
- } else if (no < nmatch && pmatch[no].rm_so < pmatch[no].rm_eo) {
- len = pmatch[no].rm_eo - pmatch[no].rm_so;
- strncpy(dst, source + pmatch[no].rm_so, len);
- dst += len;
- if (*(dst-1) == '\0') /* strncpy hit NULL. */
- return NULL;
- }
-
- }
- *dst = '\0';
-
- return dest;
-}
-
-/*
- * Parse .. so we don't compromise security
- */
-void getparents(char *name)
-{
- int l, w;
-
- /* Four paseses, as per RFC 1808 */
- /* a) remove ./ path segments */
-
- for (l=0, w=0; name[l] != '\0';)
- {
- if (name[l] == '.' && name[l+1] == '/' && (l == 0 || name[l-1] == '/'))
- l += 2;
- else
- name[w++] = name[l++];
- }
-
- /* b) remove trailing . path, segment */
- if (w == 1 && name[0] == '.') w--;
- else if (w > 1 && name[w-1] == '.' && name[w-2] == '/') w--;
- name[w] = '\0';
-
- /* c) remove all xx/../ segments. (including leading ../ and /../) */
- l = 0;
-
- while(name[l]!='\0') {
- if(name[l] == '.' && name[l+1] == '.' && name[l+2] == '/' &&
- (l == 0 || name[l-1] == '/')) {
- register int m=l+3,n;
-
- l=l-2;
- if(l>=0) {
- while(l >= 0 && name[l] != '/') l--;
- l++;
- }
- else l=0;
- n=l;
- while((name[n]=name[m])) (++n,++m);
- }
- else ++l;
- }
-
- /* d) remove trailing xx/.. segment. */
- if (l == 2 && name[0] == '.' && name[1] == '.') name[0] = '\0';
- else if (l > 2 && name[l-1] == '.' && name[l-2] == '.' && name[l-3] == '/')
- {
- l = l - 4;
- if (l >= 0)
- {
- while (l >= 0 && name[l] != '/') l--;
- l++;
- }
- else l = 0;
- name[l] = '\0';
- }
-}
-
-void no2slash(char *name)
-{
- char *d, *s;
-
- s = d = name;
- while (*s) {
- if ((*d++ = *s) == '/') {
- do {
- ++s;
- } while (*s == '/');
- }
- else {
- ++s;
- }
- }
- *d = '\0';
-}
-
-char *make_dirstr(pool *p, const char *s, int n) {
- register int x,f;
- char *res;
-
- for(x=0,f=0;s[x];x++) {
- if(s[x] == '/')
- if((++f) == n) {
- res = palloc(p, x + 2);
- strncpy (res, s, x);
- res[x] = '/';
- res[x+1] = '\0';
- return res;
- }
- }
-
- if (s[strlen(s) - 1] == '/')
- return pstrdup (p, s);
- else
- return pstrcat (p, s, "/", NULL);
-}
-
-int count_dirs(const char *path) {
- register int x,n;
-
- for(x=0,n=0;path[x];x++)
- if(path[x] == '/') n++;
- return n;
-}
-
-
-void chdir_file(const char *file) {
- int i;
-
- if((i = rind(file,'/')) == -1)
- return;
- ((char *)file)[i] = '\0';
- chdir(file);
- ((char *)file)[i] = '/';
-}
-
-char *getword_nc(pool* atrans, char **line, char stop)
- {
- return getword(atrans,(const char **)line,stop);
- }
-
-char *getword(pool* atrans, const char **line, char stop) {
- int pos = ind(*line, stop);
- char *res;
-
- if (pos == -1) {
- res = pstrdup (atrans, *line);
- *line += strlen (*line);
- return res;
- }
-
- res = palloc(atrans, pos + 1);
- strncpy (res, *line, pos);
- res[pos] = '\0';
-
- while ((*line)[pos] == stop) ++pos;
-
- *line += pos;
-
- return res;
-}
-
-char *getword_white_nc(pool* atrans, char **line)
-{
- return getword_white(atrans,(const char **)line);
-}
-
-char *getword_white(pool* atrans, const char **line) {
- int pos = -1, x;
- char *res;
-
- for(x=0;(*line)[x];x++) {
- if (isspace((*line)[x])) {
- pos=x;
- break;
- }
- }
-
- if (pos == -1) {
- res = pstrdup (atrans, *line);
- *line += strlen (*line);
- return res;
- }
-
- res = palloc(atrans, pos + 1);
- strncpy (res, *line, pos);
- res[pos] = '\0';
-
- while (isspace((*line)[pos])) ++pos;
-
- *line += pos;
-
- return res;
-}
-
-char *getword_nulls_nc(pool* atrans, char **line, char stop)
-{
- return getword_nulls(atrans,(const char **)line,stop);
-}
-
-char *getword_nulls(pool* atrans, const char **line, char stop) {
- int pos = ind(*line, stop);
- char *res;
-
- if (pos == -1) {
- res = pstrdup (atrans, *line);
- *line += strlen (*line);
- return res;
- }
-
- res = palloc(atrans, pos + 1);
- strncpy (res, *line, pos);
- res[pos] = '\0';
-
- ++pos;
-
- *line += pos;
-
- return res;
-}
-
-/* Get a word, (new) config-file style --- quoted strings and backslashes
- * all honored
- */
-
-static char *substring_conf (pool *p, const char *start, int len, char quote)
-{
- char *result = palloc (p, len + 2);
- char *resp = result;
- int i;
-
- for (i = 0; i < len; ++i) {
- if (start[i] == '\\' && (start[i+1] == '/'
- || (quote && start[i+1] == quote)))
- *resp++ = start[++i];
- else
- *resp++ = start[i];
- }
-
- *resp++ = '\0';
- return result;
-}
-
-char *getword_conf_nc(pool* p, char **line) {
- return getword_conf(p,(const char **)line);
-}
-
-char *getword_conf(pool* p, const char **line) {
- const char *str = *line, *strend;
- char *res;
- char quote;
-
- while (*str && isspace (*str))
- ++str;
-
- if (!*str) {
- *line = str;
- return "";
- }
-
- if ((quote = *str) == '"' || quote == '\'') {
- strend = str + 1;
- while (*strend && *strend != quote) {
- if (*strend == '\\' && strend[1] && strend[1] == quote)
- strend += 2;
- else ++strend;
- }
- res = substring_conf (p, str + 1, strend - str - 1, quote);
-
- if (*strend == quote) ++strend;
- } else {
- strend = str;
- while (*strend && !isspace (*strend))
- ++strend;
-
- res = substring_conf (p, str, strend - str, 0);
- }
-
- while (*strend && isspace(*strend)) ++ strend;
- *line = strend;
- return res;
-}
-
-#ifdef UNDEF
-/* this function is dangerous, and superceded by getword_white, so don't use it
- */
-void cfg_getword(char *word, char *line) {
- int x=0,y;
-
- for(x=0;line[x] && isspace(line[x]);x++);
- y=0;
- while(1) {
- if(!(word[y] = line[x]))
- break;
- if(isspace(line[x]))
- if((!x) || (line[x-1] != '\\'))
- break;
- if(line[x] != '\\') ++y;
- ++x;
- }
- word[y] = '\0';
- while(line[x] && isspace(line[x])) ++x;
- for(y=0;(line[y] = line[x]);++x,++y);
-}
-#endif
-
-int
-cfg_getline(char *s, int n, FILE *f) {
- register int i=0, c;
-
- s[0] = '\0';
- /* skip leading whitespace */
- do {
- c = getc(f);
- } while (c == '\t' || c == ' ');
-
- if(c == EOF)
- return 1;
-
- if(n < 2) {
- /* too small, assume caller is crazy */
- return 1;
- }
-
- while(1) {
- if((c == '\t') || (c == ' ')) {
- s[i++] = ' ';
- while((c == '\t') || (c == ' '))
- c = getc(f);
- }
- if(c == CR) {
- c = getc(f);
- }
- if(c == EOF || c == 0x4 || c == LF || i >= (n-2)) {
- /* blast trailing whitespace */
- while(i && (s[i-1] == ' ')) --i;
- s[i] = '\0';
- return 0;
- }
- s[i] = c;
- ++i;
- c = getc(f);
- }
-}
-
-/* Retrieve a token, spacing over it and returning a pointer to
- * the first non-white byte afterwards. Note that these tokens
- * are delimited by semis and commas; and can also be delimited
- * by whitespace at the caller's option.
- */
-
-char *get_token (pool *p, char **accept_line, int accept_white)
-{
- char *ptr = *accept_line;
- char *tok_start;
- char *token;
- int tok_len;
-
- /* Find first non-white byte */
-
- while (*ptr && isspace(*ptr))
- ++ptr;
-
- tok_start = ptr;
-
- /* find token end, skipping over quoted strings.
- * (comments are already gone).
- */
-
- while (*ptr && (accept_white || !isspace(*ptr))
- && *ptr != ';' && *ptr != ',')
- {
- if (*ptr++ == '"')
- while (*ptr)
- if (*ptr++ == '"') break;
- }
-
- tok_len = ptr - tok_start;
- token = palloc (p, tok_len + 1);
- strncpy (token, tok_start, tok_len);
- token[tok_len] = '\0';
-
- /* Advance accept_line pointer to the next non-white byte */
-
- while (*ptr && isspace(*ptr))
- ++ptr;
-
- *accept_line = ptr;
- return token;
-}
-
-static char* tspecials = " \t()<>@,;:\\/[]?={}";
-
-/* Next HTTP token from a header line. Warning --- destructive!
- * Use only with a copy!
- */
-
-static char *next_token (char **toks) {
- char *cp = *toks;
- char *ret;
-
- while (*cp && (iscntrl (*cp) || strchr (tspecials, *cp))) {
- if (*cp == '"')
- while (*cp && (*cp != '"')) ++cp;
- else
- ++cp;
- }
-
- if (!*cp) ret = NULL;
- else {
- ret = cp;
-
- while (*cp && !iscntrl(*cp) && !strchr (tspecials, *cp))
- ++cp;
-
- if (*cp) {
- *toks = cp + 1;
- *cp = '\0';
- }
- else *toks = cp;
- }
-
- return ret;
-}
-
-int find_token (pool *p, const char *line, const char *tok) {
- char *ltok;
- char *lcopy;
-
- if (!line) return 0;
-
- lcopy = pstrdup (p, line);
- while ((ltok = next_token (&lcopy)))
- if (!strcasecmp (ltok, tok))
- return 1;
-
- return 0;
-}
-
-int find_last_token (pool *p, const char *line, const char *tok)
-{
- int llen, tlen, lidx;
-
- if (!line) return 0;
-
- llen = strlen(line);
- tlen = strlen(tok);
- lidx = llen - tlen;
-
- if ((lidx < 0) ||
- ((lidx > 0) && !(isspace(line[lidx-1]) || line[lidx-1] == ',')))
- return 0;
-
- return (strncasecmp(&line[lidx], tok, tlen) == 0);
-}
-
-char *escape_shell_cmd(pool *p, const char *s) {
- register int x,y,l;
- char *cmd;
-
- l=strlen(s);
- cmd = palloc (p, 2 * l + 1); /* Be safe */
- strcpy (cmd, s);
-
- for(x=0;cmd[x];x++) {
-
-#ifdef __EMX__
- /* Don't allow '&' in parameters under OS/2. */
- /* This can be used to send commands to the shell. */
- if (cmd[x] == '&') {
- cmd[x] = ' ';
- }
-#endif
-
- if(ind("&;`'\"|*?~<>^()[]{}$\\\n",cmd[x]) != -1){
- for(y=l+1;y>x;y--)
- cmd[y] = cmd[y-1];
- l++; /* length has been increased */
- cmd[x] = '\\';
- x++; /* skip the character */
- }
- }
-
- return cmd;
-}
-
-void plustospace(char *str) {
- register int x;
-
- for(x=0;str[x];x++) if(str[x] == '+') str[x] = ' ';
-}
-
-void spacetoplus(char *str) {
- register int x;
-
- for(x=0;str[x];x++) if(str[x] == ' ') str[x] = '+';
-}
-
-static char x2c(const char *what) {
- register char digit;
-
- digit = ((what[0] >= 'A') ? ((what[0] & 0xdf) - 'A')+10 : (what[0] - '0'));
- digit *= 16;
- digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A')+10 : (what[1] - '0'));
- return(digit);
-}
-
-/*
- * Unescapes a URL.
- * Returns 0 on success, non-zero on error
- * Failure is due to
- * bad % escape returns BAD_REQUEST
- *
- * decoding %00 -> \0
- * decoding %2f -> / (a special character)
- * returns NOT_FOUND
- */
-int
-unescape_url(char *url) {
- register int x,y, badesc, badpath;
-
- badesc = 0;
- badpath = 0;
- for(x=0,y=0;url[y];++x,++y) {
- if (url[y] != '%') url[x] = url[y];
- else
- {
- if (!isxdigit(url[y+1]) || !isxdigit(url[y+2]))
- {
- badesc = 1;
- url[x] = '%';
- } else
- {
- url[x] = x2c(&url[y+1]);
- y += 2;
- if (url[x] == '/' || url[x] == '\0') badpath = 1;
- }
- }
- }
- url[x] = '\0';
- if (badesc) return BAD_REQUEST;
- else if (badpath) return NOT_FOUND;
- else return OK;
-}
-
-char *construct_server(pool *p, const char *hostname, unsigned port) {
- char portnum[22];
- /* Long enough, even if port > 16 bits for some reason */
-
- if (port == DEFAULT_PORT)
- return (char *)hostname;
- else {
- ap_snprintf (portnum, sizeof(portnum), "%u", port);
- return pstrcat (p, hostname, ":", portnum, NULL);
- }
-}
-
-char *construct_url(pool *p, const char *uri, const server_rec *s) {
- return pstrcat (p, "http://",
- construct_server(p, s->server_hostname, s->port),
- uri, NULL);
-}
-
-#define c2x(what,where) sprintf(where,"%%%02x",(unsigned char)what)
-
-/*
-escape_path_segment() escapes a path segment, as defined in RFC 1808. This
-routine is (should be) OS independent.
-
-os_escape_path() converts an OS path to a URL, in an OS dependent way. In all
-cases if a ':' occurs before the first '/' in the URL, the URL should be
-prefixed with "./" (or the ':' escaped). In the case of Unix, this means
-leaving '/' alone, but otherwise doing what escape_path_segment() does. For
-efficiency reasons, we don't use escape_path_segment(), which is provided for
-reference. Again, RFC 1808 is where this stuff is defined.
-
-If partial is set, os_escape_path() assumes that the path will be appended to
-something with a '/' in it (and thus does not prefix "./").
-*/
-
-char *escape_path_segment(pool *p, const char *segment) {
- register int x,y;
- char *copy = palloc (p, 3 * strlen (segment) + 1);
-
- for(x=0,y=0; segment[x]; x++,y++) {
- char c=segment[x];
- if((c < 'A' || c > 'Z') && (c < 'a' || c > 'z') && (c < '0' || c >'9')
- && ind("$-_.+!*'(),:@&=~",c) == -1)
- {
- c2x(c,&copy[y]);
- y+=2;
- }
- else
- copy[y]=c;
- }
- copy[y] = '\0';
- return copy;
-}
-
-char *os_escape_path(pool *p,const char *path,int partial) {
- char *copy=palloc(p,3*strlen(path)+3);
- char *s=copy;
-
- if(!partial)
- {
- int colon=ind(path,':');
- int slash=ind(path,'/');
-
- if(colon >= 0 && (colon < slash || slash < 0))
- {
- *s++='.';
- *s++='/';
- }
- }
- for( ; *path ; ++path)
- {
- char c=*path;
- if((c < 'A' || c > 'Z') && (c < 'a' || c > 'z') && (c < '0' || c >'9')
- && ind("$-_.+!*'(),:@&=/~",c) == -1)
- {
- c2x(c,s);
- s+=3;
- }
- else
- *s++=c;
- }
- *s='\0';
- return copy;
-}
-
-/* escape_uri is now a macro for os_escape_path */
-
-char *escape_html(pool *p, const char *s)
-{
- int i, j;
- char *x;
-
-/* first, count the number of extra characters */
- for (i=0, j=0; s[i] != '\0'; i++)
- if (s[i] == '<' || s[i] == '>') j += 3;
- else if (s[i] == '&') j += 4;
-
- if (j == 0) return pstrdup(p, s);
- x = palloc(p, i + j + 1);
- for (i=0, j=0; s[i] != '\0'; i++, j++)
- if (s[i] == '<')
- {
- memcpy(&x[j], "&lt;", 4);
- j += 3;
- } else if (s[i] == '>')
- {
- memcpy(&x[j], "&gt;", 4);
- j += 3;
- } else if (s[i] == '&')
- {
- memcpy(&x[j], "&amp;", 5);
- j += 4;
- } else
- x[j] = s[i];
-
- x[j] = '\0';
- return x;
-}
-
-int is_directory(const char *path) {
- struct stat finfo;
-
- if(stat(path,&finfo) == -1)
- return 0; /* in error condition, just return no */
-
- return(S_ISDIR(finfo.st_mode));
-}
-
-char *make_full_path(pool *a, const char *src1, const char *src2) {
- register int x;
-
- x = strlen(src1);
- if (x == 0) return pstrcat (a, "/", src2, NULL);
-
- if (src1[x - 1] != '/') return pstrcat (a, src1, "/", src2, NULL);
- else return pstrcat (a, src1, src2, NULL);
-}
-
-/*
- * Check for an absoluteURI syntax (see section 3.2 in RFC2068).
- */
-int is_url(const char *u) {
- register int x;
-
- for (x = 0; u[x] != ':'; x++) {
- if ((! u[x]) ||
- ((! isalpha(u[x])) && (! isdigit(u[x])) &&
- (u[x] != '+') && (u[x] != '-') && (u[x] != '.'))) {
- return 0;
- }
- }
-
- return (x ? 1 : 0); /* If the first character is ':', it's broken, too */
-}
-
-int can_exec(const struct stat *finfo) {
-#ifdef MULTIPLE_GROUPS
- int cnt;
-#endif
-#ifdef __EMX__
- /* OS/2 dosen't have Users and Groups */
- return 1;
-#else
- if(user_id == finfo->st_uid)
- if(finfo->st_mode & S_IXUSR)
- return 1;
- if(group_id == finfo->st_gid)
- if(finfo->st_mode & S_IXGRP)
- return 1;
-#ifdef MULTIPLE_GROUPS
- for(cnt=0; cnt < NGROUPS_MAX; cnt++) {
- if(group_id_list[cnt] == finfo->st_gid)
- if(finfo->st_mode & S_IXGRP)
- return 1;
- }
-#endif
- return (finfo->st_mode & S_IXOTH);
-#endif
-}
-
-#ifdef 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
-
-/* The following two routines were donated for SVR4 by Andreas Vogel */
-#ifdef NEED_STRCASECMP
-int strcasecmp (const char *a, const char *b)
-{
- const char *p = a;
- const char *q = b;
- for (p = a, q = b; *p && *q; p++, q++)
- {
- int diff = tolower(*p) - tolower(*q);
- if (diff) return diff;
- }
- if (*p) return 1; /* p was longer than q */
- if (*q) return -1; /* p was shorter than q */
- return 0; /* Exact match */
-}
-
-#endif
-
-#ifdef NEED_STRNCASECMP
-int strncasecmp (const char *a, const char *b, int n)
-{
- const char *p = a;
- const char *q = b;
-
- for (p = a, q = b; /*NOTHING*/; p++, q++)
- {
- int diff;
- if (p == a + n) return 0; /* Match up to n characters */
- if (!(*p && *q)) return *p - *q;
- diff = tolower(*p) - tolower(*q);
- if (diff) return diff;
- }
- /*NOTREACHED*/
-}
-#endif
-
-
-
-#ifdef NEED_INITGROUPS
-int initgroups(const char *name, gid_t basegid)
-{
-#if defined(QNX) || defined(MPE)
-/* QNX and MPE do not appear to support supplementary groups. */
- return 0;
-#else /* ndef QNX */
- gid_t groups[NGROUPS_MAX];
- struct group *g;
- int index = 0;
-
- setgrent();
-
- groups[index++] = basegid;
-
- while (index < NGROUPS_MAX && ((g = getgrent()) != NULL))
- if (g->gr_gid != basegid)
- {
- char **names;
-
- for (names = g->gr_mem; *names != NULL; ++names)
- if (!strcmp(*names, name))
- groups[index++] = g->gr_gid;
- }
-
- endgrent();
-
- return setgroups(index, groups);
-#endif /* def QNX */
-}
-#endif /* def NEED_INITGROUPS */
-
-#ifdef NEED_WAITPID
-/* From ikluft@amdahl.com */
-/* this is not ideal but it works for SVR3 variants */
-/* httpd does not use the options so this doesn't implement them */
-int waitpid(pid_t pid, int *statusp, int options)
-{
- int tmp_pid;
- if ( kill ( pid,0 ) == -1) {
- errno=ECHILD;
- return -1;
- }
- while ((( tmp_pid = wait(statusp)) != pid) && ( tmp_pid != -1 ));
- return tmp_pid;
-}
-#endif
-
-int ind(const char *s, char c) {
- register int x;
-
- for(x=0;s[x];x++)
- if(s[x] == c) return x;
-
- return -1;
-}
-
-int rind(const char *s, char c) {
- register int x;
-
- for(x=strlen(s)-1;x != -1;x--)
- if(s[x] == c) return x;
-
- return -1;
-}
-
-void str_tolower(char *str) {
- while(*str) {
- *str = tolower(*str);
- ++str;
- }
-}
-
-uid_t uname2id(const char *name) {
- struct passwd *ent;
-
- if(name[0] == '#')
- return(atoi(&name[1]));
-
- if(!(ent = getpwnam(name))) {
- fprintf(stderr,"httpd: bad user name %s\n",name);
- exit(1);
- }
- return(ent->pw_uid);
-}
-
-gid_t gname2id(const char *name) {
- struct group *ent;
-
- if(name[0] == '#')
- return(atoi(&name[1]));
-
- if(!(ent = getgrnam(name))) {
- fprintf(stderr,"httpd: bad group name %s\n",name);
- exit(1);
- }
- return(ent->gr_gid);
-}
-
-#if 0
-int get_portnum(int sd) {
- struct sockaddr addr;
- int len;
-
- len = sizeof(struct sockaddr);
- if(getsockname(sd,&addr,&len) < 0)
- return -1;
- return ntohs(((struct sockaddr_in *)&addr)->sin_port);
-}
-
-struct in_addr get_local_addr(int sd) {
- struct sockaddr addr;
- int len;
-
- len = sizeof(struct sockaddr);
- if(getsockname(sd,&addr,&len) < 0) {
- perror ("getsockname");
- fprintf (stderr, "Can't get local host address!\n");
- exit(1);
- }
-
- return ((struct sockaddr_in *)&addr)->sin_addr;
-}
-#endif
-
-/*
- * Parses a host of the form <address>[:port]
- * :port is permitted if 'port' is not NULL
- */
-unsigned long get_virthost_addr (const char *w, unsigned short *ports) {
- struct hostent *hep;
- unsigned long my_addr;
- char *p;
-
- p = strchr(w, ':');
- if (ports != NULL)
- {
- *ports = 0;
- if (p != NULL && strcmp(p+1, "*") != 0) *ports = atoi(p+1);
- }
-
- if (p != NULL) *p = '\0';
- if (strcmp(w, "*") == 0)
- {
- if (p != NULL) *p = ':';
- return htonl(INADDR_ANY);
- }
-
-#ifdef DGUX
- my_addr = inet_network(w);
-#else
- my_addr = inet_addr(w);
-#endif
- if (my_addr != INADDR_NONE)
- {
- if (p != NULL) *p = ':';
- return my_addr;
- }
-
- hep = gethostbyname(w);
-
- if ((!hep) || (hep->h_addrtype != AF_INET || !hep->h_addr_list[0])) {
- fprintf (stderr, "Cannot resolve host name %s --- exiting!\n", w);
- exit(1);
- }
-
- if (hep->h_addr_list[1]) {
- fprintf(stderr, "Host %s has multiple addresses ---\n", w);
- fprintf(stderr, "you must choose one explicitly for use as\n");
- fprintf(stderr, "a virtual host. Exiting!!!\n");
- exit(1);
- }
-
- if (p != NULL) *p = ':';
-
- return ((struct in_addr *)(hep->h_addr))->s_addr;
-}
-
-
-static char *find_fqdn(pool *a, struct hostent *p) {
- int x;
-
- if(ind(p->h_name,'.') == -1) {
- for(x=0;p->h_aliases[x];++x) {
- if((ind(p->h_aliases[x],'.') != -1) &&
- (!strncasecmp(p->h_aliases[x],p->h_name,strlen(p->h_name))))
- return pstrdup(a, p->h_aliases[x]);
- }
- return NULL;
- }
- return pstrdup(a, (void *)p->h_name);
-}
-
-char *get_local_host(pool *a)
-{
-#ifndef MAXHOSTNAMELEN
-#define MAXHOSTNAMELEN 256
-#endif
- char str[MAXHOSTNAMELEN+1];
- char *server_hostname;
- struct hostent *p;
-
- if( gethostname( str, sizeof( str ) - 1 ) != 0 ) {
- perror( "Unable to gethostname" );
- exit(1);
- }
- str[MAXHOSTNAMELEN] = '\0';
- if((!(p=gethostbyname(str))) || (!(server_hostname = find_fqdn(a, p)))) {
- fprintf(stderr,"httpd: cannot determine local host name.\n");
- fprintf(stderr,"Use ServerName to set it manually.\n");
- exit(1);
- }
-
- return server_hostname;
-}
-
-/* aaaack but it's fast and const should make it shared text page. */
-const int pr2six[256]={
- 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
- 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,62,64,64,64,63,
- 52,53,54,55,56,57,58,59,60,61,64,64,64,64,64,64,64,0,1,2,3,4,5,6,7,8,9,
- 10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,64,64,64,64,64,64,26,27,
- 28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,
- 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
- 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
- 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
- 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
- 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
- 64,64,64,64,64,64,64,64,64,64,64,64,64
-};
-
-char *uudecode(pool *p, const char *bufcoded) {
- int nbytesdecoded;
- register unsigned char *bufin;
- register char *bufplain;
- register unsigned char *bufout;
- register int nprbytes;
-
- /* Strip leading whitespace. */
-
- while(*bufcoded==' ' || *bufcoded == '\t') bufcoded++;
-
- /* Figure out how many characters are in the input buffer.
- * Allocate this many from the per-transaction pool for the result.
- */
- bufin = (unsigned char *)bufcoded;
- while(pr2six[*(bufin++)] <= 63);
- nprbytes = (char *)bufin - bufcoded - 1;
- nbytesdecoded = ((nprbytes+3)/4) * 3;
-
- bufplain = palloc(p, nbytesdecoded + 1);
- bufout = (unsigned char *)bufplain;
-
- bufin = (unsigned char *)bufcoded;
-
- while (nprbytes > 0) {
- *(bufout++) =
- (unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
- *(bufout++) =
- (unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
- *(bufout++) =
- (unsigned char) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
- bufin += 4;
- nprbytes -= 4;
- }
-
- if(nprbytes & 03) {
- if(pr2six[bufin[-2]] > 63)
- nbytesdecoded -= 2;
- else
- nbytesdecoded -= 1;
- }
- bufplain[nbytesdecoded] = '\0';
- return bufplain;
-}
-
-#ifdef __EMX__
-void os2pathname(char *path) {
- char newpath[MAX_STRING_LEN];
- int loop;
- int offset;
-
- offset = 0;
- for (loop=0; loop < (strlen(path) + 1) && loop < sizeof(newpath)-1; loop++) {
- if (path[loop] == '/') {
- newpath[offset] = '\\';
- /*
- offset = offset + 1;
- newpath[offset] = '\\';
- */
- } else
- newpath[offset] = path[loop];
- offset = offset + 1;
- };
- /* Debugging code */
- /* fprintf(stderr, "%s \n", newpath); */
-
- strcpy(path, newpath);
-};
-#endif
-
-
-#ifdef NEED_STRERROR
-char *
-strerror (int err) {
-
- char *p;
- extern char *const sys_errlist[];
-
- p = sys_errlist[err];
- return (p);
-}
-#endif
-
-
-int ap_slack (int fd, int line)
-{
-#if !defined(F_DUPFD) || defined(NO_SLACK)
- return fd;
-#else
- int new_fd;
-
-#ifdef HIGH_SLACK_LINE
- if (line == AP_SLACK_HIGH) {
- new_fd = fcntl (fd, F_DUPFD, HIGH_SLACK_LINE);
- if (new_fd != -1) {
- close (fd);
- return new_fd;
- }
- }
-#endif
- /* otherwise just assume line == AP_SLACK_LOW */
- new_fd = fcntl (fd, F_DUPFD, LOW_SLACK_LINE);
- if (new_fd == -1) {
- return fd;
- }
- close (fd);
- return new_fd;
-#endif
-}
diff --git a/usr.sbin/httpd/src/util_date.c b/usr.sbin/httpd/src/util_date.c
deleted file mode 100644
index e544a0fe1cc..00000000000
--- a/usr.sbin/httpd/src/util_date.c
+++ /dev/null
@@ -1,296 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1996,1997 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. 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 "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
- */
-int 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 (!isupper(d)) return 0;
- break;
- case '$': if (!islower(d)) return 0;
- break;
- case '#': if (!isdigit(d)) return 0;
- break;
- case '&': if (!isxdigit(d)) return 0;
- break;
- case '~': if ((d != ' ') && !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().
- */
-time_t tm2sec(const struct tm *t)
-{
- int year;
- time_t days;
- 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.
- *
- */
-time_t parseHTTPdate(const char *date)
-{
- struct tm ds;
- int mint, mon;
- const char *monstr, *timstr;
- 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 && 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 (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 (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 (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 tm2sec(&ds);
-}
-
diff --git a/usr.sbin/httpd/src/util_date.h b/usr.sbin/httpd/src/util_date.h
deleted file mode 100644
index edfd34ad431..00000000000
--- a/usr.sbin/httpd/src/util_date.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1996,1997 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. 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.h: prototypes for date parsing utility routines
- */
-
-#include <time.h>
-
-#define BAD_DATE (time_t)0
-
-int checkmask (const char *data, const char *mask);
-time_t tm2sec (const struct tm *t);
-time_t parseHTTPdate (const char *date);
diff --git a/usr.sbin/httpd/src/util_md5.c b/usr.sbin/httpd/src/util_md5.c
deleted file mode 100644
index bf5565e21f0..00000000000
--- a/usr.sbin/httpd/src/util_md5.c
+++ /dev/null
@@ -1,192 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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"
-
-char *md5 (pool *p, unsigned char *string)
-{
- MD5_CTX my_md5;
- unsigned char hash[16];
- char *r, result[33];
- int i;
-
- /*
- * Take the MD5 hash of the string argument.
- */
-
- MD5Init(&my_md5);
- MD5Update(&my_md5, string, strlen((const char *)string));
- MD5Final(hash, &my_md5);
-
- for (i=0, r=result; i<16; i++, r+=2)
- sprintf(r, "%02x", hash[i]);
- *r = '\0';
-
- return pstrdup(p, result);
-}
-
-/* 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+/";
-
-char *md5contextTo64(pool *a, MD5_CTX *context)
-{
- unsigned char digest[18];
- char *encodedDigest;
- int i;
- char *p;
-
- encodedDigest = (char *)pcalloc(a, 25 * sizeof(char));
-
- 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;
-}
-
-char *md5digest(pool *p, FILE *infile)
-{
- MD5_CTX context;
- unsigned char buf[1000];
- long length = 0;
- int nbytes;
-
- MD5Init(&context);
- while ((nbytes = fread(buf, 1, sizeof(buf), infile))) {
- length += nbytes;
- MD5Update(&context, buf, nbytes);
- }
- rewind(infile);
- return md5contextTo64(p, &context);
-}
-
diff --git a/usr.sbin/httpd/src/util_md5.h b/usr.sbin/httpd/src/util_md5.h
deleted file mode 100644
index 63e2c37cd2b..00000000000
--- a/usr.sbin/httpd/src/util_md5.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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/>.
- *
- */
-
-#include "md5.h"
-
-char *md5(pool *a, unsigned char *string);
-char *md5contextTo64(pool *p, MD5_CTX *context);
-char *md5digest(pool *p, FILE *infile);
-
diff --git a/usr.sbin/httpd/src/util_script.c b/usr.sbin/httpd/src/util_script.c
deleted file mode 100644
index 3fcd3a66cd2..00000000000
--- a/usr.sbin/httpd/src/util_script.c
+++ /dev/null
@@ -1,641 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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/>.
- *
- */
-
-#define CORE_PRIVATE
-#include "httpd.h"
-#include "http_config.h"
-#include "http_conf_globals.h"
-#include "http_main.h"
-#include "http_log.h"
-#include "http_protocol.h"
-#include "http_core.h" /* For document_root. Sigh... */
-#include "http_request.h" /* for sub_req_lookup_uri() */
-#include "util_script.h"
-#include <assert.h>
-
-/*
- * Various utility functions which are common to a whole lot of
- * script-type extensions mechanisms, and might as well be gathered
- * in one place (if only to avoid creating inter-module dependancies
- * where there don't have to be).
- */
-
-#define MALFORMED_MESSAGE "malformed header from script. Bad header="
-#define MALFORMED_HEADER_LENGTH_TO_SHOW 30
-
-/* If a request includes query info in the URL (stuff after "?"), and
- * the query info does not contain "=" (indicative of a FORM submission),
- * then this routine is called to create the argument list to be passed
- * to the CGI script. When suexec is enabled, the suexec path, user, and
- * group are the first three arguments to be passed; if not, all three
- * must be NULL. The query info is split into separate arguments, where
- * "+" is the separator between keyword arguments.
- */
-static char **create_argv(pool *p, char *path, char *user, char *group,
- char *av0, const char *args)
-{
- int x, numwords;
- char **av;
- char *w;
- int idx = 0;
-
- /* count the number of keywords */
-
- for (x = 0, numwords = 1; args[x]; x++)
- if (args[x] == '+') ++numwords;
-
- if (numwords > APACHE_ARG_MAX - 5) {
- numwords = APACHE_ARG_MAX - 5; /* Truncate args to prevent overrun */
- }
- av = (char **)palloc(p, (numwords + 5) * sizeof(char *));
-
- if (path)
- av[idx++] = path;
- if (user)
- av[idx++] = user;
- if (group)
- av[idx++] = group;
-
- av[idx++] = av0;
-
- for (x = 1; x <= numwords; x++) {
- w = getword_nulls(p, &args, '+');
- unescape_url(w);
- av[idx++] = escape_shell_cmd(p, w);
- }
- av[idx] = NULL;
- return av;
-}
-
-
-static char *http2env(pool *a, char *w)
-{
- char *res = pstrcat (a, "HTTP_", w, NULL);
- char *cp = res;
-
- while (*++cp)
- if (*cp == '-') *cp = '_';
- else *cp = toupper(*cp);
-
- return res;
-}
-
-char **create_environment(pool *p, table *t)
-{
- array_header *env_arr = table_elts (t);
- table_entry *elts = (table_entry *)env_arr->elts;
- char **env = (char **)palloc (p, (env_arr->nelts + 2) *sizeof (char *));
- int i, j;
- char *tz;
-
- j = 0;
- tz = getenv("TZ");
- if (tz!= NULL) env[j++] = pstrcat(p, "TZ=", tz, NULL);
- for (i = 0; i < env_arr->nelts; ++i) {
- if (!elts[i].key) continue;
- env[j++] = pstrcat (p, elts[i].key, "=", elts[i].val, NULL);
- }
-
- env[j] = NULL;
- return env;
-}
-
-void add_common_vars(request_rec *r)
-{
- table *e = r->subprocess_env;
- server_rec *s = r->server;
- conn_rec *c = r->connection;
- const char *rem_logname;
-
- char port[40],*env_path;
-
- array_header *hdrs_arr = table_elts (r->headers_in);
- table_entry *hdrs = (table_entry *)hdrs_arr->elts;
- int i;
-
- /* First, add environment vars from headers... this is as per
- * CGI specs, though other sorts of scripting interfaces see
- * the same vars...
- */
-
- for (i = 0; i < hdrs_arr->nelts; ++i) {
- if (!hdrs[i].key) continue;
-
- /* A few headers are special cased --- Authorization to prevent
- * rogue scripts from capturing passwords; content-type and -length
- * for no particular reason.
- */
-
- if (!strcasecmp (hdrs[i].key, "Content-type"))
- table_set (e, "CONTENT_TYPE", hdrs[i].val);
- else if (!strcasecmp (hdrs[i].key, "Content-length"))
- table_set (e, "CONTENT_LENGTH", hdrs[i].val);
- else if (!strcasecmp (hdrs[i].key, "Authorization"))
- continue;
- else
- table_set (e, http2env (r->pool, hdrs[i].key), hdrs[i].val);
- }
-
- ap_snprintf(port, sizeof(port), "%u", s->port);
-
- if(!(env_path = getenv("PATH")))
- env_path=DEFAULT_PATH;
-
- table_set (e, "PATH", env_path);
- table_set (e, "SERVER_SOFTWARE", SERVER_VERSION);
- table_set (e, "SERVER_NAME", s->server_hostname);
- table_set (e, "SERVER_PORT", port);
- table_set (e, "REMOTE_HOST",
- get_remote_host(c, r->per_dir_config, REMOTE_NAME));
- table_set (e, "REMOTE_ADDR", c->remote_ip);
- table_set (e, "DOCUMENT_ROOT", document_root(r)); /* Apache */
- table_set (e, "SERVER_ADMIN", s->server_admin); /* Apache */
- table_set (e, "SCRIPT_FILENAME", r->filename); /* Apache */
-
- ap_snprintf(port, sizeof(port), "%d", ntohs(c->remote_addr.sin_port));
- table_set (e, "REMOTE_PORT", port); /* Apache */
-
- if (c->user) table_set(e, "REMOTE_USER", c->user);
- if (c->auth_type) table_set(e, "AUTH_TYPE", c->auth_type);
- rem_logname = get_remote_logname(r);
- if (rem_logname) table_set(e, "REMOTE_IDENT", rem_logname);
-
- /* Apache custom error responses. If we have redirected set two new vars */
-
- if (r->prev) {
- if (r->prev->args) table_set(e,"REDIRECT_QUERY_STRING", r->prev->args);
- if (r->prev->uri) table_set (e, "REDIRECT_URL", r->prev->uri);
- }
-}
-
-/* This "cute" little function comes about because the path info on
- * filenames and URLs aren't always the same. So we take the two,
- * and find as much of the two that match as possible.
- */
-
-int find_path_info (char *uri, char *path_info)
-{
- int lu = strlen(uri);
- int lp = strlen(path_info);
-
- while (lu-- && lp-- && uri[lu] == path_info[lp]);
-
- if (lu == -1)
- lu=0;
-
- while (uri[lu] != '\0' && uri[lu] != '/')
- lu++;
-
- return lu;
-}
-
-/* Obtain the Request-URI from the original request-line, returning
- * a new string from the request pool containing the URI or "".
- */
-static char *original_uri(request_rec *r)
-{
- char *first, *last;
-
- if (r->the_request == NULL)
- return (char *)pcalloc(r->pool, 1);
-
- first = r->the_request; /* use the request-line */
-
- while (*first && !isspace(*first)) ++first; /* skip over the method */
- while (isspace(*first)) ++first; /* and the space(s) */
-
- last = first;
- while (*last && !isspace(*last)) ++last; /* end at next whitespace */
-
- return pstrndup(r->pool, first, last - first);
-}
-
-void add_cgi_vars(request_rec *r)
-{
- table *e = r->subprocess_env;
-
- table_set (e, "GATEWAY_INTERFACE","CGI/1.1");
- table_set (e, "SERVER_PROTOCOL", r->protocol);
- table_set (e, "REQUEST_METHOD", r->method);
- table_set (e, "QUERY_STRING", r->args ? r->args : "");
- table_set (e, "REQUEST_URI", original_uri(r));
-
- /* Note that the code below special-cases scripts run from includes,
- * because it "knows" that the sub_request has been hacked to have the
- * args and path_info of the original request, and not any that may have
- * come with the script URI in the include command. Ugh.
- */
-
- if (!strcmp (r->protocol, "INCLUDED")) {
- table_set (e, "SCRIPT_NAME", r->uri);
- if (r->path_info && *r->path_info)
- table_set (e, "PATH_INFO", r->path_info);
- } else if (!r->path_info || !*r->path_info) {
- table_set (e, "SCRIPT_NAME", r->uri);
- } else {
- int path_info_start = find_path_info (r->uri, r->path_info);
-
- table_set (e, "SCRIPT_NAME", pstrndup(r->pool, r->uri,
- path_info_start));
-
- table_set (e, "PATH_INFO", r->path_info);
- }
-
- if (r->path_info && r->path_info[0]) {
- /*
- * To get PATH_TRANSLATED, treat PATH_INFO as a URI path.
- * Need to re-escape it for this, since the entire URI was
- * un-escaped before we determined where the PATH_INFO began.
- */
- request_rec *pa_req = sub_req_lookup_uri(
- escape_uri(r->pool, r->path_info), r);
-
- /* Don't bother destroying pa_req --- it's only created in
- * child processes which are about to jettison their address
- * space anyway. BTW, we concatenate filename and path_info
- * from the sub_request to be compatible in case the PATH_INFO
- * is pointing to an object which doesn't exist.
- */
-
- if (pa_req->filename)
- table_set (e, "PATH_TRANSLATED",
- pstrcat (r->pool, pa_req->filename, pa_req->path_info,
- NULL));
- }
-}
-
-int scan_script_header_err(request_rec *r, FILE *f, char *buffer)
-{
- char x[MAX_STRING_LEN];
- char *w, *l;
- int p;
-
- if (buffer) *buffer = '\0';
- w = buffer ? buffer : x;
-
- hard_timeout ("read script header", r);
-
- while(1) {
-
- if (fgets(w, MAX_STRING_LEN-1, f) == NULL) {
- kill_timeout (r);
- log_reason ("Premature end of script headers", r->filename, r);
- return SERVER_ERROR;
- }
-
- /* Delete terminal (CR?)LF */
-
- p = strlen(w);
- if (p > 0 && w[p-1] == '\n')
- {
- if (p > 1 && w[p-2] == '\015') w[p-2] = '\0';
- else w[p-1] = '\0';
- }
-
- if(w[0] == '\0') {
- kill_timeout (r);
- return OK;
- }
-
- /* if we see a bogus header don't ignore it. Shout and scream */
-
- if(!(l = strchr(w,':'))) {
- char malformed[(sizeof MALFORMED_MESSAGE)+1+MALFORMED_HEADER_LENGTH_TO_SHOW];
- strcpy(malformed, MALFORMED_MESSAGE);
- strncat(malformed, w, MALFORMED_HEADER_LENGTH_TO_SHOW);
-
- if (!buffer)
- /* Soak up all the script output --- may save an outright kill */
- while (fgets(w, MAX_STRING_LEN-1, f) != NULL)
- continue;
-
- kill_timeout (r);
- log_reason (malformed, r->filename, r);
- return SERVER_ERROR;
- }
-
- *l++ = '\0';
- while (*l && isspace (*l)) ++l;
-
- if(!strcasecmp(w,"Content-type")) {
-
- /* Nuke trailing whitespace */
-
- char *endp = l + strlen(l) - 1;
- while (endp > l && isspace(*endp)) *endp-- = '\0';
-
- r->content_type = pstrdup (r->pool, l);
- }
- else if(!strcasecmp(w,"Status")) {
- sscanf(l, "%d", &r->status);
- r->status_line = pstrdup(r->pool, l);
- }
- else if(!strcasecmp(w,"Location")) {
- table_set (r->headers_out, w, l);
- }
- else if(!strcasecmp(w,"Content-Length")) {
- table_set (r->headers_out, w, l);
- }
- else if(!strcasecmp(w,"Transfer-Encoding")) {
- table_set (r->headers_out, w, l);
- }
-
-/* The HTTP specification says that it is legal to merge duplicate
- * headers into one. Some browsers that support Cookies don't like
- * merged headers and prefer that each Set-Cookie header is sent
- * separately. Lets humour those browsers.
- */
- else if(!strcasecmp(w, "Set-Cookie")) {
- table_add(r->err_headers_out, w, l);
- }
- else {
- table_merge (r->err_headers_out, w, l);
- }
- }
-}
-
-void send_size(size_t size, request_rec *r) {
- char ss[20];
-
- if(size == -1)
- strcpy(ss, " -");
- else if(!size)
- strcpy(ss, " 0k");
- else if(size < 1024)
- strcpy(ss, " 1k");
- else if(size < 1048576)
- ap_snprintf(ss, sizeof(ss), "%4dk", (size + 512) / 1024);
- else if(size < 103809024)
- ap_snprintf(ss, sizeof(ss), "%4.1fM", size / 1048576.0);
- else
- ap_snprintf(ss, sizeof(ss), "%4dM", (size + 524288) / 1048576);
- rputs(ss, r);
-}
-
-#ifdef __EMX__
-static char **create_argv_cmd(pool *p, char *av0, const char *args, char *path)
-{
- register int x,n;
- char **av;
- char *w;
-
- for(x=0,n=2;args[x];x++)
- if(args[x] == '+') ++n;
-
- /* Add extra strings to array. */
- n = n + 2;
-
- av = (char **)palloc(p, (n+1)*sizeof(char *));
- av[0] = av0;
-
- /* Now insert the extra strings we made room for above. */
- av[1] = strdup("/C");
- av[2] = strdup(path);
-
- for(x=(1+2);x<n;x++) {
- w = getword(p, &args, '+');
- unescape_url(w);
- av[x] = escape_shell_cmd(p, w);
- }
- av[n] = NULL;
- return av;
-}
-#endif
-
-
-void call_exec (request_rec *r, char *argv0, char **env, int shellcmd)
-{
-#if defined(RLIMIT_CPU) || defined(RLIMIT_NPROC) || \
- defined(RLIMIT_DATA) || defined(RLIMIT_VMEM)
-
- core_dir_config *conf =
- (core_dir_config *)get_module_config(r->per_dir_config, &core_module);
-
-#endif
-
- /* the fd on r->server->error_log is closed, but we need somewhere to
- * put the error messages from the log_* functions. So, we use stderr,
- * since that is better than allowing errors to go unnoticed.
- */
- r->server->error_log = stderr;
-
-#ifdef RLIMIT_CPU
- if (conf->limit_cpu != NULL)
- if ((setrlimit (RLIMIT_CPU, conf->limit_cpu)) != 0)
- log_unixerr("setrlimit", NULL, "failed to set CPU usage limit",
- r->server);
-#endif
-#ifdef RLIMIT_NPROC
- if (conf->limit_nproc != NULL)
- if ((setrlimit (RLIMIT_NPROC, conf->limit_nproc)) != 0)
- log_unixerr("setrlimit", NULL, "failed to set process limit",
- r->server);
-#endif
-#ifdef RLIMIT_DATA
- if (conf->limit_mem != NULL)
- if ((setrlimit (RLIMIT_DATA, conf->limit_mem)) != 0)
- log_unixerr("setrlimit", NULL, "failed to set memory usage limit",
- r->server);
-#endif
-#ifdef RLIMIT_VMEM
- if (conf->limit_mem != NULL)
- if ((setrlimit (RLIMIT_VMEM, conf->limit_mem)) != 0)
- log_unixerr("setrlimit", NULL, "failed to set memory usage limit",
- r->server);
-#endif
-
-#ifdef __EMX__
- {
- /* Additions by Alec Kloss, to allow exec'ing of scripts under OS/2 */
- int is_script;
- char interpreter[2048]; /* hope this is large enough for the interpreter path */
- FILE * program;
- program = fopen (r->filename, "r");
- if (!program) {
- char err_string[HUGE_STRING_LEN];
- ap_snprintf(err_string, sizeof(err_string),
- "open of %s failed, reason: fopen: %s (errno = %d)\n",
- r->filename, strerror(errno), errno);
-
- /* write(2, err_string, strlen(err_string)); */
- /* exit(0); */
- log_unixerr("fopen", NULL, err_string, r->server);
- return;
- }
- fgets (interpreter, 2048, program);
- fclose (program);
- if (!strncmp (interpreter, "#!", 2)) {
- is_script = 1;
- interpreter[strlen(interpreter)-1] = '\0';
- } else {
- is_script = 0;
- }
-
- if ((!r->args) || (!r->args[0]) || (ind(r->args,'=') >= 0)) {
- int emxloop;
- char *emxtemp;
-
- /* For OS/2 place the variables in the current
- enviornment then it will be inherited. This way
- the program will also get all of OS/2's other SETs. */
- for (emxloop=0; ((emxtemp = env[emxloop]) != NULL); emxloop++)
- putenv(emxtemp);
-
- /* Additions by Alec Kloss, to allow exec'ing of scripts under OS/2 */
- if (is_script) {
- /* here's the stuff to run the interpreter */
- execl (interpreter+2, interpreter+2, r->filename, NULL);
- } else
-
- if (strstr(strupr(r->filename), ".CMD") > 0) {
- /* Special case to allow use of REXX commands as scripts. */
- os2pathname(r->filename);
- execl("CMD.EXE", "CMD.EXE", "/C", r->filename, NULL);
- }
- else {
- execl(r->filename, argv0, NULL);
- }
- }
- else {
- int emxloop;
- char *emxtemp;
-
- /* For OS/2 place the variables in the current
- environment so that they will be inherited. This way
- the program will also get all of OS/2's other SETs. */
- for (emxloop=0; ((emxtemp = env[emxloop]) != NULL); emxloop++)
- putenv(emxtemp);
-
- if (strstr(strupr(r->filename), ".CMD") > 0) {
- /* Special case to allow use of REXX commands as scripts. */
- os2pathname(r->filename);
- execv("CMD.EXE", create_argv_cmd(r->pool, argv0, r->args, r->filename));
- }
- else
- execv(r->filename,
- create_argv(r->pool, NULL, NULL, NULL, argv0, r->args));
- }
- }
-#else
- if ( suexec_enabled &&
- ((r->server->server_uid != user_id) ||
- (r->server->server_gid != group_id) ||
- (!strncmp("/~",r->uri,2))) ) {
-
- char *execuser, *grpname;
- struct passwd *pw;
- struct group *gr;
-
- if (!strncmp("/~",r->uri,2)) {
- gid_t user_gid;
- char *username = pstrdup(r->pool, r->uri + 2);
- int pos = ind(username, '/');
-
- if (pos >= 0) username[pos] = '\0';
-
- if ((pw = getpwnam(username)) == NULL) {
- log_unixerr("getpwnam",username,"invalid username",r->server);
- return;
- }
- execuser = pstrcat(r->pool, "~", pw->pw_name, NULL);
- user_gid = pw->pw_gid;
-
- if ((gr = getgrgid(user_gid)) == NULL) {
- if ((grpname = palloc (r->pool, 16)) == NULL)
- return;
- else
- ap_snprintf(grpname, 16, "%d", user_gid);
- }
- else
- grpname = gr->gr_name;
- }
- else {
- if ((pw = getpwuid (r->server->server_uid)) == NULL) {
- log_unixerr("getpwuid", NULL, "invalid userid", r->server);
- return;
- }
- execuser = pstrdup(r->pool, pw->pw_name);
-
- if ((gr = getgrgid (r->server->server_gid)) == NULL) {
- log_unixerr("getgrgid", NULL, "invalid groupid", r->server);
- return;
- }
- grpname = gr->gr_name;
- }
-
- if (shellcmd)
- execle(SUEXEC_BIN, SUEXEC_BIN, execuser, grpname, argv0, NULL, env);
-
- else if((!r->args) || (!r->args[0]) || (ind(r->args,'=') >= 0))
- execle(SUEXEC_BIN, SUEXEC_BIN, execuser, grpname, argv0, NULL, env);
-
- else {
- execve(SUEXEC_BIN,
- create_argv(r->pool, SUEXEC_BIN, execuser, grpname,
- argv0, r->args),
- env);
- }
- }
- else {
- if (shellcmd)
- execle(SHELL_PATH, SHELL_PATH, "-c", argv0, NULL, env);
-
- else if((!r->args) || (!r->args[0]) || (ind(r->args,'=') >= 0))
- execle(r->filename, argv0, NULL, env);
-
- else
- execve(r->filename,
- create_argv(r->pool, NULL, NULL, NULL, argv0, r->args),
- env);
- }
-#endif
-}
diff --git a/usr.sbin/httpd/src/util_script.h b/usr.sbin/httpd/src/util_script.h
deleted file mode 100644
index 28258767781..00000000000
--- a/usr.sbin/httpd/src/util_script.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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_ARG_MAX
-#ifdef _POSIX_ARG_MAX
-#define APACHE_ARG_MAX _POSIX_ARG_MAX
-#else
-#define APACHE_ARG_MAX 512
-#endif
-#endif
-
-char **create_environment(pool *p, table *t);
-int find_path_info(char *uri, char *path_info);
-void add_cgi_vars(request_rec *r);
-void add_common_vars(request_rec *r);
-#define scan_script_header(a1,a2) scan_script_header_err(a1,a2,NULL)
-int scan_script_header_err(request_rec *r, FILE *f, char *buffer);
-void send_size(size_t size, request_rec *r);
-void call_exec (request_rec *r, char *argv0, char **env, int shellcmd);
-
diff --git a/usr.sbin/httpd/src/util_snprintf.c b/usr.sbin/httpd/src/util_snprintf.c
deleted file mode 100644
index d37c634f753..00000000000
--- a/usr.sbin/httpd/src/util_snprintf.c
+++ /dev/null
@@ -1,949 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1997 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. 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 code is based on, and used with the permission of, the
- * SIO stdio-replacement strx_* functions by Panos Tsirigotis
- * <panos@alumni.cs.colorado.edu> for xinetd.
- */
-
-#include "conf.h"
-
-#ifndef HAVE_SNPRINTF
-
-#include <stdio.h>
-#include <ctype.h>
-#include <sys/types.h>
-#include <stdarg.h>
-#include <string.h>
-#include <stdlib.h>
-#include <math.h>
-
-#ifdef HAVE_CVT
-
-# define ap_ecvt ecvt
-# define ap_fcvt fcvt
-# define ap_gcvt gcvt
-
-#else
-
-/*
- * cvt.c - IEEE floating point formatting routines for FreeBSD
- * from GNU libc-4.6.27
- */
-
-/*
- * ap_ecvt converts to decimal
- * the number of digits is specified by ndigit
- * decpt is set to the position of the decimal point
- * sign is set to 0 for positive, 1 for negative
- */
-
-#define NDIG 80
-
-static char *
- ap_cvt(double arg, int ndigits, int *decpt, int *sign, int eflag)
-{
- register int r2;
- double fi, fj;
- register char *p, *p1;
- static char buf[NDIG];
-
- if (ndigits >= NDIG - 1)
- ndigits = NDIG - 2;
- r2 = 0;
- *sign = 0;
- p = &buf[0];
- if (arg < 0) {
- *sign = 1;
- arg = -arg;
- }
- arg = modf(arg, &fi);
- p1 = &buf[NDIG];
- /*
- * Do integer part
- */
- if (fi != 0) {
- p1 = &buf[NDIG];
- while (fi != 0) {
- fj = modf(fi / 10, &fi);
- *--p1 = (int) ((fj + .03) * 10) + '0';
- r2++;
- }
- while (p1 < &buf[NDIG])
- *p++ = *p1++;
- }
- else if (arg > 0) {
- while ((fj = arg * 10) < 1) {
- arg = fj;
- r2--;
- }
- }
- p1 = &buf[ndigits];
- if (eflag == 0)
- p1 += r2;
- *decpt = r2;
- if (p1 < &buf[0]) {
- buf[0] = '\0';
- return (buf);
- }
- while (p <= p1 && p < &buf[NDIG]) {
- arg *= 10;
- arg = modf(arg, &fj);
- *p++ = (int) fj + '0';
- }
- if (p1 >= &buf[NDIG]) {
- buf[NDIG - 1] = '\0';
- return (buf);
- }
- p = p1;
- *p1 += 5;
- while (*p1 > '9') {
- *p1 = '0';
- if (p1 > buf)
- ++ * --p1;
- else {
- *p1 = '1';
- (*decpt)++;
- if (eflag == 0) {
- if (p > buf)
- *p = '0';
- p++;
- }
- }
- }
- *p = '\0';
- return (buf);
-}
-
-static char *
- ap_ecvt(double arg, int ndigits, int *decpt, int *sign)
-{
- return (ap_cvt(arg, ndigits, decpt, sign, 1));
-}
-
-static char *
- ap_fcvt(double arg, int ndigits, int *decpt, int *sign)
-{
- return (ap_cvt(arg, ndigits, decpt, sign, 0));
-}
-
-/*
- * ap_gcvt - Floating output conversion to
- * minimal length string
- */
-
-static char *
- ap_gcvt(double number, int ndigit, char *buf)
-{
- int sign, decpt;
- register char *p1, *p2;
- register i;
-
- p1 = ap_ecvt(number, ndigit, &decpt, &sign);
- p2 = buf;
- if (sign)
- *p2++ = '-';
- for (i = ndigit - 1; i > 0 && p1[i] == '0'; i--)
- ndigit--;
- if ((decpt >= 0 && decpt - ndigit > 4)
- || (decpt < 0 && decpt < -3)) { /* use E-style */
- decpt--;
- *p2++ = *p1++;
- *p2++ = '.';
- for (i = 1; i < ndigit; i++)
- *p2++ = *p1++;
- *p2++ = 'e';
- if (decpt < 0) {
- decpt = -decpt;
- *p2++ = '-';
- }
- else
- *p2++ = '+';
- if (decpt / 100 > 0)
- *p2++ = decpt / 100 + '0';
- if (decpt / 10 > 0)
- *p2++ = (decpt % 100) / 10 + '0';
- *p2++ = decpt % 10 + '0';
- }
- else {
- if (decpt <= 0) {
- if (*p1 != '0')
- *p2++ = '.';
- while (decpt < 0) {
- decpt++;
- *p2++ = '0';
- }
- }
- for (i = 1; i <= ndigit; i++) {
- *p2++ = *p1++;
- if (i == decpt)
- *p2++ = '.';
- }
- if (ndigit < decpt) {
- while (ndigit++ < decpt)
- *p2++ = '0';
- *p2++ = '.';
- }
- }
- if (p2[-1] == '.')
- p2--;
- *p2 = '\0';
- return (buf);
-}
-
-#endif /* HAVE_CVT */
-
-typedef enum {
- NO = 0, YES = 1
-} boolean_e;
-
-#define FALSE 0
-#define TRUE 1
-#define NUL '\0'
-#define INT_NULL ((int *)0)
-#define WIDE_INT long
-
-typedef WIDE_INT wide_int;
-typedef unsigned WIDE_INT u_wide_int;
-typedef int bool_int;
-
-#define S_NULL "(null)"
-#define S_NULL_LEN 6
-
-#define FLOAT_DIGITS 6
-#define EXPONENT_LENGTH 10
-
-/*
- * NUM_BUF_SIZE is the size of the buffer used for arithmetic conversions
- *
- * XXX: this is a magic number; do not decrease it
- */
-#define NUM_BUF_SIZE 512
-
-
-/*
- * Descriptor for buffer area
- */
-struct buf_area {
- char *buf_end;
- char *nextb; /* pointer to next byte to read/write */
-};
-
-typedef struct buf_area buffy;
-
-/*
- * The INS_CHAR macro inserts a character in the buffer and writes
- * the buffer back to disk if necessary
- * It uses the char pointers sp and bep:
- * sp points to the next available character in the buffer
- * bep points to the end-of-buffer+1
- * While using this macro, note that the nextb pointer is NOT updated.
- *
- * NOTE: Evaluation of the c argument should not have any side-effects
- */
-#define INS_CHAR( c, sp, bep, cc ) \
- { \
- if ( sp < bep ) \
- { \
- *sp++ = c ; \
- cc++ ; \
- } \
- }
-
-#define NUM( c ) ( c - '0' )
-
-#define STR_TO_DEC( str, num ) \
- num = NUM( *str++ ) ; \
- while ( isdigit( *str ) ) \
- { \
- num *= 10 ; \
- num += NUM( *str++ ) ; \
- }
-
-/*
- * This macro does zero padding so that the precision
- * requirement is satisfied. The padding is done by
- * adding '0's to the left of the string that is going
- * to be printed.
- */
-#define FIX_PRECISION( adjust, precision, s, s_len ) \
- if ( adjust ) \
- while ( s_len < precision ) \
- { \
- *--s = '0' ; \
- s_len++ ; \
- }
-
-/*
- * Macro that does padding. The padding is done by printing
- * the character ch.
- */
-#define PAD( width, len, ch ) do \
- { \
- INS_CHAR( ch, sp, bep, cc ) ; \
- width-- ; \
- } \
- while ( width > len )
-
-/*
- * Prefix the character ch to the string str
- * Increase length
- * Set the has_prefix flag
- */
-#define PREFIX( str, length, ch ) *--str = ch ; length++ ; has_prefix = YES
-
-
-/*
- * Convert num to its decimal format.
- * Return value:
- * - a pointer to a string containing the number (no sign)
- * - len contains the length of the string
- * - is_negative is set to TRUE or FALSE depending on the sign
- * of the number (always set to FALSE if is_unsigned is TRUE)
- *
- * The caller provides a buffer for the string: that is the buf_end argument
- * which is a pointer to the END of the buffer + 1 (i.e. if the buffer
- * is declared as buf[ 100 ], buf_end should be &buf[ 100 ])
- */
-static char *
- conv_10(register wide_int num, register bool_int is_unsigned,
- register bool_int * is_negative, char *buf_end, register int *len)
-{
- register char *p = buf_end;
- register u_wide_int magnitude;
-
- if (is_unsigned) {
- magnitude = (u_wide_int) num;
- *is_negative = FALSE;
- }
- else {
- *is_negative = (num < 0);
-
- /*
- * On a 2's complement machine, negating the most negative integer
- * results in a number that cannot be represented as a signed integer.
- * Here is what we do to obtain the number's magnitude:
- * a. add 1 to the number
- * b. negate it (becomes positive)
- * c. convert it to unsigned
- * d. add 1
- */
- if (*is_negative) {
- wide_int t = num + 1;
-
- magnitude = ((u_wide_int) - t) + 1;
- }
- else
- magnitude = (u_wide_int) num;
- }
-
- /*
- * We use a do-while loop so that we write at least 1 digit
- */
- do {
- register u_wide_int new_magnitude = magnitude / 10;
-
- *--p = magnitude - new_magnitude * 10 + '0';
- magnitude = new_magnitude;
- }
- while (magnitude);
-
- *len = buf_end - p;
- return (p);
-}
-
-
-
-/*
- * Convert a floating point number to a string formats 'f', 'e' or 'E'.
- * The result is placed in buf, and len denotes the length of the string
- * The sign is returned in the is_negative argument (and is not placed
- * in buf).
- */
-static char *
- conv_fp(register char format, register double num,
-boolean_e add_dp, int precision, bool_int * is_negative, char *buf, int *len)
-{
- register char *s = buf;
- register char *p;
- int decimal_point;
-
- if (format == 'f')
- p = ap_fcvt(num, precision, &decimal_point, is_negative);
- else /* either e or E format */
- p = ap_ecvt(num, precision + 1, &decimal_point, is_negative);
-
- /*
- * Check for Infinity and NaN
- */
- if (isalpha(*p)) {
- *len = strlen(strcpy(buf, p));
- *is_negative = FALSE;
- return (buf);
- }
-
- if (format == 'f')
- if (decimal_point <= 0) {
- *s++ = '0';
- if (precision > 0) {
- *s++ = '.';
- while (decimal_point++ < 0)
- *s++ = '0';
- }
- else if (add_dp)
- *s++ = '.';
- }
- else {
- while (decimal_point-- > 0)
- *s++ = *p++;
- if (precision > 0 || add_dp)
- *s++ = '.';
- }
- else {
- *s++ = *p++;
- if (precision > 0 || add_dp)
- *s++ = '.';
- }
-
- /*
- * copy the rest of p, the NUL is NOT copied
- */
- while (*p)
- *s++ = *p++;
-
- if (format != 'f') {
- char temp[EXPONENT_LENGTH]; /* for exponent conversion */
- int t_len;
- bool_int exponent_is_negative;
-
- *s++ = format; /* either e or E */
- decimal_point--;
- if (decimal_point != 0) {
- p = conv_10((wide_int) decimal_point, FALSE, &exponent_is_negative,
- &temp[EXPONENT_LENGTH], &t_len);
- *s++ = exponent_is_negative ? '-' : '+';
-
- /*
- * Make sure the exponent has at least 2 digits
- */
- if (t_len == 1)
- *s++ = '0';
- while (t_len--)
- *s++ = *p++;
- }
- else {
- *s++ = '+';
- *s++ = '0';
- *s++ = '0';
- }
- }
-
- *len = s - buf;
- return (buf);
-}
-
-
-/*
- * Convert num to a base X number where X is a power of 2. nbits determines X.
- * For example, if nbits is 3, we do base 8 conversion
- * Return value:
- * a pointer to a string containing the number
- *
- * The caller provides a buffer for the string: that is the buf_end argument
- * which is a pointer to the END of the buffer + 1 (i.e. if the buffer
- * is declared as buf[ 100 ], buf_end should be &buf[ 100 ])
- */
-static char *
- conv_p2(register u_wide_int num, register int nbits,
- char format, char *buf_end, register int *len)
-{
- register int mask = (1 << nbits) - 1;
- register char *p = buf_end;
- static char low_digits[] = "0123456789abcdef";
- static char upper_digits[] = "0123456789ABCDEF";
- register char *digits = (format == 'X') ? upper_digits : low_digits;
-
- do {
- *--p = digits[num & mask];
- num >>= nbits;
- }
- while (num);
-
- *len = buf_end - p;
- return (p);
-}
-
-
-/*
- * Do format conversion placing the output in buffer
- */
-static int format_converter(register buffy * odp, const char *fmt,
- va_list ap)
-{
- register char *sp;
- register char *bep;
- register int cc = 0;
- register int i;
-
- register char *s = NULL;
- char *q;
- int s_len;
-
- register int min_width = 0;
- int precision = 0;
- enum {
- LEFT, RIGHT
- } adjust;
- char pad_char;
- char prefix_char;
-
- double fp_num;
- wide_int i_num = (wide_int) 0;
- u_wide_int ui_num;
-
- char num_buf[NUM_BUF_SIZE];
- char char_buf[2]; /* for printing %% and %<unknown> */
-
- /*
- * Flag variables
- */
- boolean_e is_long;
- boolean_e alternate_form;
- boolean_e print_sign;
- boolean_e print_blank;
- boolean_e adjust_precision;
- boolean_e adjust_width;
- bool_int is_negative;
-
- sp = odp->nextb;
- bep = odp->buf_end;
-
- while (*fmt) {
- if (*fmt != '%') {
- INS_CHAR(*fmt, sp, bep, cc);
- }
- else {
- /*
- * Default variable settings
- */
- adjust = RIGHT;
- alternate_form = print_sign = print_blank = NO;
- pad_char = ' ';
- prefix_char = NUL;
-
- fmt++;
-
- /*
- * Try to avoid checking for flags, width or precision
- */
- if (isascii(*fmt) && !islower(*fmt)) {
- /*
- * Recognize flags: -, #, BLANK, +
- */
- for (;; fmt++) {
- if (*fmt == '-')
- adjust = LEFT;
- else if (*fmt == '+')
- print_sign = YES;
- else if (*fmt == '#')
- alternate_form = YES;
- else if (*fmt == ' ')
- print_blank = YES;
- else if (*fmt == '0')
- pad_char = '0';
- else
- break;
- }
-
- /*
- * Check if a width was specified
- */
- if (isdigit(*fmt)) {
- STR_TO_DEC(fmt, min_width);
- adjust_width = YES;
- }
- else if (*fmt == '*') {
- min_width = va_arg(ap, int);
- fmt++;
- adjust_width = YES;
- if (min_width < 0) {
- adjust = LEFT;
- min_width = -min_width;
- }
- }
- else
- adjust_width = NO;
-
- /*
- * Check if a precision was specified
- *
- * XXX: an unreasonable amount of precision may be specified
- * resulting in overflow of num_buf. Currently we
- * ignore this possibility.
- */
- if (*fmt == '.') {
- adjust_precision = YES;
- fmt++;
- if (isdigit(*fmt)) {
- STR_TO_DEC(fmt, precision);
- }
- else if (*fmt == '*') {
- precision = va_arg(ap, int);
- fmt++;
- if (precision < 0)
- precision = 0;
- }
- else
- precision = 0;
- }
- else
- adjust_precision = NO;
- }
- else
- adjust_precision = adjust_width = NO;
-
- /*
- * Modifier check
- */
- if (*fmt == 'l') {
- is_long = YES;
- fmt++;
- }
- else
- is_long = NO;
-
- /*
- * Argument extraction and printing.
- * First we determine the argument type.
- * Then, we convert the argument to a string.
- * On exit from the switch, s points to the string that
- * must be printed, s_len has the length of the string
- * The precision requirements, if any, are reflected in s_len.
- *
- * NOTE: pad_char may be set to '0' because of the 0 flag.
- * It is reset to ' ' by non-numeric formats
- */
- switch (*fmt) {
- case 'u':
- if (is_long)
- i_num = va_arg(ap, u_wide_int);
- else
- i_num = (wide_int) va_arg(ap, unsigned int);
- /*
- * The rest also applies to other integer formats, so fall
- * into that case.
- */
- case 'd':
- case 'i':
- /*
- * Get the arg if we haven't already.
- */
- if ((*fmt) != 'u') {
- if (is_long)
- i_num = va_arg(ap, wide_int);
- else
- i_num = (wide_int) va_arg(ap, int);
- };
- s = conv_10(i_num, (*fmt) == 'u', &is_negative,
- &num_buf[NUM_BUF_SIZE], &s_len);
- FIX_PRECISION(adjust_precision, precision, s, s_len);
-
- if (*fmt != 'u') {
- if (is_negative)
- prefix_char = '-';
- else if (print_sign)
- prefix_char = '+';
- else if (print_blank)
- prefix_char = ' ';
- }
- break;
-
-
- case 'o':
- if (is_long)
- ui_num = va_arg(ap, u_wide_int);
- else
- ui_num = (u_wide_int) va_arg(ap, unsigned int);
- s = conv_p2(ui_num, 3, *fmt,
- &num_buf[NUM_BUF_SIZE], &s_len);
- FIX_PRECISION(adjust_precision, precision, s, s_len);
- if (alternate_form && *s != '0') {
- *--s = '0';
- s_len++;
- }
- break;
-
-
- case 'x':
- case 'X':
- if (is_long)
- ui_num = (u_wide_int) va_arg(ap, u_wide_int);
- else
- ui_num = (u_wide_int) va_arg(ap, unsigned int);
- s = conv_p2(ui_num, 4, *fmt,
- &num_buf[NUM_BUF_SIZE], &s_len);
- FIX_PRECISION(adjust_precision, precision, s, s_len);
- if (alternate_form && i_num != 0) {
- *--s = *fmt; /* 'x' or 'X' */
- *--s = '0';
- s_len += 2;
- }
- break;
-
-
- case 's':
- s = va_arg(ap, char *);
- if (s != NULL) {
- s_len = strlen(s);
- if (adjust_precision && precision < s_len)
- s_len = precision;
- }
- else {
- s = S_NULL;
- s_len = S_NULL_LEN;
- }
- pad_char = ' ';
- break;
-
-
- case 'f':
- case 'e':
- case 'E':
- fp_num = va_arg(ap, double);
-
- s = conv_fp(*fmt, fp_num, alternate_form,
- (adjust_precision == NO) ? FLOAT_DIGITS : precision,
- &is_negative, &num_buf[1], &s_len);
- if (is_negative)
- prefix_char = '-';
- else if (print_sign)
- prefix_char = '+';
- else if (print_blank)
- prefix_char = ' ';
- break;
-
-
- case 'g':
- case 'G':
- if (adjust_precision == NO)
- precision = FLOAT_DIGITS;
- else if (precision == 0)
- precision = 1;
- /*
- * * We use &num_buf[ 1 ], so that we have room for the sign
- */
- s = ap_gcvt(va_arg(ap, double), precision, &num_buf[1]);
- if (*s == '-')
- prefix_char = *s++;
- else if (print_sign)
- prefix_char = '+';
- else if (print_blank)
- prefix_char = ' ';
-
- s_len = strlen(s);
-
- if (alternate_form && (q = strchr(s, '.')) == NULL)
- s[s_len++] = '.';
- if (*fmt == 'G' && (q = strchr(s, 'e')) != NULL)
- *q = 'E';
- break;
-
-
- case 'c':
- char_buf[0] = (char) (va_arg(ap, int));
- s = &char_buf[0];
- s_len = 1;
- pad_char = ' ';
- break;
-
-
- case '%':
- char_buf[0] = '%';
- s = &char_buf[0];
- s_len = 1;
- pad_char = ' ';
- break;
-
-
- case 'n':
- *(va_arg(ap, int *)) = cc;
- break;
-
- /*
- * Always extract the argument as a "char *" pointer. We
- * should be using "void *" but there are still machines
- * that don't understand it.
- * If the pointer size is equal to the size of an unsigned
- * integer we convert the pointer to a hex number, otherwise
- * we print "%p" to indicate that we don't handle "%p".
- */
- case 'p':
- ui_num = (u_wide_int) va_arg(ap, char *);
-
- if (sizeof(char *) <= sizeof(u_wide_int))
- s = conv_p2(ui_num, 4, 'x',
- &num_buf[NUM_BUF_SIZE], &s_len);
- else {
- s = "%p";
- s_len = 2;
- }
- pad_char = ' ';
- break;
-
-
- case NUL:
- /*
- * The last character of the format string was %.
- * We ignore it.
- */
- continue;
-
-
- /*
- * The default case is for unrecognized %'s.
- * We print %<char> to help the user identify what
- * option is not understood.
- * This is also useful in case the user wants to pass
- * the output of format_converter to another function
- * that understands some other %<char> (like syslog).
- * Note that we can't point s inside fmt because the
- * unknown <char> could be preceded by width etc.
- */
- default:
- char_buf[0] = '%';
- char_buf[1] = *fmt;
- s = char_buf;
- s_len = 2;
- pad_char = ' ';
- break;
- }
-
- if (prefix_char != NUL) {
- *--s = prefix_char;
- s_len++;
- }
-
- if (adjust_width && adjust == RIGHT && min_width > s_len) {
- if (pad_char == '0' && prefix_char != NUL) {
- INS_CHAR(*s, sp, bep, cc)
- s++;
- s_len--;
- min_width--;
- }
- PAD(min_width, s_len, pad_char);
- }
-
- /*
- * Print the string s.
- */
- for (i = s_len; i != 0; i--) {
- INS_CHAR(*s, sp, bep, cc);
- s++;
- }
-
- if (adjust_width && adjust == LEFT && min_width > s_len)
- PAD(min_width, s_len, pad_char);
- }
- fmt++;
- }
- odp->nextb = sp;
- return (cc);
-}
-
-
-/*
- * This is the general purpose conversion function.
- */
-static void strx_printv(int *ccp, char *buf, size_t len, const char *format,
- va_list ap)
-{
- buffy od;
- int cc;
-
- /*
- * First initialize the descriptor
- * Notice that if no length is given, we initialize buf_end to the
- * highest possible address.
- */
- od.buf_end = len ? &buf[len] : (char *) ~0;
- od.nextb = buf;
-
- /*
- * Do the conversion
- */
- cc = format_converter(&od, format, ap);
- if (len == 0 || od.nextb <= od.buf_end)
- *(od.nextb) = '\0';
- if (ccp)
- *ccp = cc;
-}
-
-
-int ap_snprintf(char *buf, size_t len, const char *format,...)
-{
- int cc;
- va_list ap;
-
- va_start(ap, format);
- strx_printv(&cc, buf, (len - 1), format, ap);
- va_end(ap);
- return (cc);
-}
-
-
-int ap_vsnprintf(char *buf, size_t len, const char *format, va_list ap)
-{
- int cc;
-
- strx_printv(&cc, buf, (len - 1), format, ap);
- return (cc);
-}
-
-#endif /* HAVE_SNPRINTF */