]> granicus.if.org Git - apache/blobdiff - server/main.c
Fix default Timeout & KeepaliveTimeout. Still need to limit directive
[apache] / server / main.c
index 0251cf055d2a2d7396ec742113d8051c16108476..47df11db6eadfbc5f404ce6a182b65286dc6131b 100644 (file)
@@ -1,75 +1,81 @@
 /* ====================================================================
- * Copyright (c) 1995-1999 The Apache Group.  All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions 
- * are met: 
- * 
- * 1. Redistributions of source code must retain the above copyright 
- *    notice, this list of conditions and the following disclaimer.  
- * 
- * 2. Redistributions in binary form must reproduce the above copyright 
- *    notice, this list of conditions and the following disclaimer in 
- *    the documentation and/or other materials provided with the 
- *    distribution. 
- * 
- * 3. All advertising materials mentioning features or use of this 
- *    software must display the following acknowledgment: 
- *    "This product includes software developed by the Apache Group 
- *    for use in the Apache HTTP server project (http://www.apache.org/)." 
- * 
- * 4. The names "Apache Server" and "Apache Group" must not be used to 
- *    endorse or promote products derived from this software without 
- *    prior written permission. For written permission, please contact 
- *    apache@apache.org. 
- * 
- * 5. Products derived from this software may not be called "Apache" 
- *    nor may "Apache" appear in their names without prior written 
- *    permission of the Apache Group. 
- * 
- * 6. Redistributions of any form whatsoever must retain the following 
- *    acknowledgment: 
- *    "This product includes software developed by the Apache Group 
- *    for use in the Apache HTTP server project (http://www.apache.org/)." 
- * 
- * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY 
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR 
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
- * OF THE POSSIBILITY OF SUCH DAMAGE. 
- * ==================================================================== 
- * 
- * This software consists of voluntary contributions made by many 
- * individuals on behalf of the Apache Group and was originally based 
- * on public domain software written at the National Center for 
- * Supercomputing Applications, University of Illinois, Urbana-Champaign. 
- * For more information on the Apache Group and the Apache HTTP server 
- * project, please see <http://www.apache.org/>. 
- * 
- */ 
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2000 The Apache Software Foundation.  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. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``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 SOFTWARE FOUNDATION 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 Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * Portions of this software are based upon public domain software
+ * originally written at the National Center for Supercomputing Applications,
+ * University of Illinois, Urbana-Champaign.
+ */
 
 #define CORE_PRIVATE
+#include "ap_config.h"
 #include "httpd.h" 
 #include "http_main.h" 
+#include "http_log.h" 
 #include "http_config.h"
+#include "http_vhost.h"
 #include "util_uri.h" 
+#include "util_ebcdic.h"
+#include "apr_strings.h"
+#include "apr_getopt.h"
 #include "ap_mpm.h"
 
-char *ap_server_argv0;
-
-API_VAR_EXPORT const char *ap_server_root;
-
-ap_array_header_t *ap_server_pre_read_config;
-ap_array_header_t *ap_server_post_read_config;
-ap_array_header_t *ap_server_config_defines;
+/* WARNING: Win32 binds http_main.c dynamically to the server. Please place 
+ *          extern functions and global data in another appropriate module.
+ *
+ * Most significant main() global data can be found in http_config.c
+ */
 
+/* XXX - We should be able to grab the per-MPM settings here too */
 static void show_compile_settings(void)
 {
     printf("Server version: %s\n", ap_get_server_version());
@@ -83,23 +89,17 @@ static void show_compile_settings(void)
 #ifdef SECURITY_HOLE_PASS_AUTHORIZATION
     printf(" -D SECURITY_HOLE_PASS_AUTHORIZATION\n");
 #endif
-#ifdef HAVE_MMAP
+#ifdef APR_HAS_MMAP
     printf(" -D HAVE_MMAP\n");
 #endif
 #ifdef HAVE_SHMGET
     printf(" -D HAVE_SHMGET\n");
 #endif
-#ifdef USE_MMAP_SCOREBOARD
-    printf(" -D USE_MMAP_SCOREBOARD\n");
-#endif
-#ifdef USE_SHMGET_SCOREBOARD
-    printf(" -D USE_SHMGET_SCOREBOARD\n");
+#ifdef USE_FILE_BASED_SCOREBOARD
+    printf(" -D USE_FILE_BASED_SCOREBOARD\n");
 #endif
-#ifdef USE_OS2_SCOREBOARD
-    printf(" -D USE_OS2_SCOREBOARD\n");
-#endif
-#ifdef USE_POSIX_SCOREBOARD
-    printf(" -D USE_POSIX_SCOREBOARD\n");
+#ifdef USE_MEM_BASED_SCOREBOARD
+    printf(" -D USE_MEM_BASED_SCOREBOARD\n");
 #endif
 #ifdef USE_MMAP_FILES
     printf(" -D USE_MMAP_FILES\n");
@@ -113,29 +113,29 @@ static void show_compile_settings(void)
 #ifdef NO_LINGCLOSE
     printf(" -D NO_LINGCLOSE\n");
 #endif
-#ifdef USE_FCNTL_SERIALIZED_ACCEPT
-    printf(" -D USE_FCNTL_SERIALIZED_ACCEPT\n");
+#if APR_USE_FLOCK_SERIALIZE
+    printf(" -D APR_USE_FLOCK_SERIALIZE\n");
 #endif
-#ifdef USE_FLOCK_SERIALIZED_ACCEPT
-    printf(" -D USE_FLOCK_SERIALIZED_ACCEPT\n");
+#if APR_USE_SYSVSEM_SERIALIZE
+    printf(" -D APR_USE_SYSVSEM_SERIALIZE\n");
 #endif
-#ifdef USE_USLOCK_SERIALIZED_ACCEPT
-    printf(" -D USE_USLOCK_SERIALIZED_ACCEPT\n");
+#if APR_USE_FCNTL_SERIALIZE
+    printf(" -D APR_USE_FCNTL_SERIALIZE\n");
 #endif
-#ifdef USE_SYSVSEM_SERIALIZED_ACCEPT
-    printf(" -D USE_SYSVSEM_SERIALIZED_ACCEPT\n");
+#if APR_USE_PROC_PTHREAD_SERIALIZE
+    printf(" -D APR_USE_PROC_PTHREAD_SERIALIZE\n");
 #endif
-#ifdef USE_PTHREAD_SERIALIZED_ACCEPT
-    printf(" -D USE_PTHREAD_SERIALIZED_ACCEPT\n");
+#if APR_USE_PTHREAD_SERIALIZE
+    printf(" -D APR_USE_PTHREAD_SERIALIZE\n");
 #endif
 #ifdef SINGLE_LISTEN_UNSERIALIZED_ACCEPT
     printf(" -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT\n");
 #endif
-#ifdef HAS_OTHER_CHILD
-    printf(" -D HAS_OTHER_CHILD\n");
+#if APR_HAS_OTHER_CHILD
+    printf(" -D APR_HAS_OTHER_CHILD\n");
 #endif
-#ifdef NO_RELIABLE_PIPED_LOGS
-    printf(" -D NO_RELIABLE_PIPED_LOGS\n");
+#ifdef HAVE_RELIABLE_PIPED_LOGS
+    printf(" -D HAVE_RELIABLE_PIPED_LOGS\n");
 #endif
 #ifdef BUFFERED_LOGS
     printf(" -D BUFFERED_LOGS\n");
@@ -143,12 +143,12 @@ static void show_compile_settings(void)
        printf(" -D PIPE_BUF=%ld\n",(long)PIPE_BUF);
 #endif
 #endif
-#ifdef MULTITHREAD
-    printf(" -D MULTITHREAD\n");
-#endif
 #ifdef CHARSET_EBCDIC
     printf(" -D CHARSET_EBCDIC\n");
 #endif
+#ifdef APACHE_XLATE
+    printf(" -D APACHE_XLATE\n");
+#endif
 #ifdef NEED_HASHBANG_EMUL
     printf(" -D NEED_HASHBANG_EMUL\n");
 #endif
@@ -156,7 +156,7 @@ static void show_compile_settings(void)
     printf(" -D SHARED_CORE\n");
 #endif
 
-/* This list displays the compiled ap_context_t n default paths: */
+/* This list displays the compiled in default paths: */
 #ifdef HTTPD_ROOT
     printf(" -D HTTPD_ROOT=\"" HTTPD_ROOT "\"\n");
 #endif
@@ -187,16 +187,45 @@ static void show_compile_settings(void)
 #ifdef SERVER_CONFIG_FILE
     printf(" -D SERVER_CONFIG_FILE=\"" SERVER_CONFIG_FILE "\"\n");
 #endif
-#ifdef ACCESS_CONFIG_FILE
-    printf(" -D ACCESS_CONFIG_FILE=\"" ACCESS_CONFIG_FILE "\"\n");
-#endif
-#ifdef RESOURCE_CONFIG_FILE
-    printf(" -D RESOURCE_CONFIG_FILE=\"" RESOURCE_CONFIG_FILE "\"\n");
-#endif
 }
 
-static void usage(char *bin)
+static void destroy_and_exit_process(process_rec *process, int process_exit_value)
 {
+    apr_destroy_pool(process->pool); /* and destroy all descendent pools */
+    apr_terminate();
+    exit(process_exit_value);
+}
+
+static process_rec *create_process(int argc, char *const *argv)
+{
+    process_rec *process;
+    
+    {
+       apr_pool_t *cntx;
+        apr_status_t stat;
+
+       stat = apr_create_pool(&cntx, NULL);
+        if (stat != APR_SUCCESS) {
+            ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, NULL,
+                         "apr_create_pool() failed to create "
+                         "initial context");
+            apr_terminate();
+            exit(1);
+        }
+
+       process = apr_palloc(cntx, sizeof(process_rec));
+       process->pool = cntx;
+    }
+    apr_create_pool(&process->pconf, process->pool);
+    process->argc = argc;
+    process->argv = argv;
+    process->short_name = apr_filename_of_pathname(argv[0]);
+    return process;
+}
+
+static void usage(process_rec *process)
+{
+    const char *bin = process->argv[0];
     char pad[MAX_STRING_LEN];
     unsigned i;
 
@@ -204,153 +233,189 @@ static void usage(char *bin)
        pad[i] = ' ';
     pad[i] = '\0';
 #ifdef SHARED_CORE
-    fprintf(stderr, "Usage: %s [-R directory] [-D name] [-d directory] [-f file]\n", bin);
+    ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0,NULL , "Usage: %s [-R directory] [-D name] [-d directory] [-f file]", bin);
 #else
-    fprintf(stderr, "Usage: %s [-D name] [-d directory] [-f file]\n", bin);
+    ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, "Usage: %s [-D name] [-d directory] [-f file]", bin);
 #endif
-    fprintf(stderr, "       %s [-C \"directive\"] [-c \"directive\"]\n", pad);
-    fprintf(stderr, "       %s [-v] [-V] [-h] [-l] [-L] [-S] [-t] [-T]\n", pad);
-    fprintf(stderr, "Options:\n");
+    ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, "       %s [-C \"directive\"] [-c \"directive\"]", pad);
+#ifdef WIN32
+    ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, "       %s [-k restart|shutdown|start]", pad);
+    ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, "       %s [-n service_name]", pad);
+    ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, "       %s [-i] [-u]", pad);
+#endif
+    ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, "       %s [-v] [-V] [-h] [-l] [-L] [-S] [-t] [-T]", pad);
+    ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, "Options:");
 #ifdef SHARED_CORE
-    fprintf(stderr, "  -R directory     : specify an alternate location for shared object files\n");
-#endif
-    fprintf(stderr, "  -D name          : define a name for use in <IfDefine name> directives\n");
-    fprintf(stderr, "  -d directory     : specify an alternate initial ServerRoot\n");
-    fprintf(stderr, "  -f file          : specify an alternate ServerConfigFile\n");
-    fprintf(stderr, "  -C \"directive\"   : process directive before reading config files\n");
-    fprintf(stderr, "  -c \"directive\"   : process directive after  reading config files\n");
-    fprintf(stderr, "  -v               : show version number\n");
-    fprintf(stderr, "  -V               : show compile settings\n");
-    fprintf(stderr, "  -h               : list available command line options (this page)\n");
-    fprintf(stderr, "  -l               : list compiled ap_context_t n modules\n");
-    fprintf(stderr, "  -L               : list available configuration directives\n");
+    ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, "  -R directory     : specify an alternate location for shared object files");
+#endif
+    ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, "  -D name          : define a name for use in <IfDefine name> directives");
+    ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, "  -d directory     : specify an alternate initial ServerRoot");
+    ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, "  -f file          : specify an alternate ServerConfigFile");
+    ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, "  -C \"directive\"   : process directive before reading config files");
+    ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, "  -c \"directive\"   : process directive after  reading config files");
+#ifdef WIN32
+    ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, "  -n name          : set service name and use its ServerConfigFile");
+    ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, "  -k shutdown      : tell running Apache to shutdown");
+    ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, "  -k restart       : tell running Apache to do a graceful restart");
+    ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, "  -k start         : tell Apache to start");
+    ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, "  -i               : install an Apache service");
+    ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, "  -u               : uninstall an Apache service");
+#endif
+    ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, "  -v               : show version number");
+    ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, "  -V               : show compile settings");
+    ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, "  -h               : list available command line options (this page)");
+    ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, "  -l               : list compiled in modules");
+    ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, "  -L               : list available configuration directives");
     /* TODOC: -S has been replaced by '-t -D DUMP_VHOSTS' */
-    /* fprintf(stderr, "  -S               : show parsed settings (currently only vhost settings)\n"); */
-    fprintf(stderr, "  -t               : run syntax check for config files (with docroot check)\n");
-    fprintf(stderr, "  -T               : run syntax check for config files (without docroot check)\n");
+    /* ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, "  -S               : show parsed settings (currently only vhost settings)"); */
+    ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, "  -t               : run syntax check for config files (with docroot check)");
+    ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, "  -T               : run syntax check for config files (without docroot check)");
     /* TODOC: -X goes away, expect MPMs to use -D options */
-    exit(1);
+    destroy_and_exit_process(process, 1);
 }
 
-ap_context_t *g_pHookPool;
-
-extern char *optarg;
-
-#ifdef WIN32
-API_EXPORT_NONSTD(int) apache_main(int argc, char *argv[])
-#else
-API_EXPORT_NONSTD(int)        main(int argc, char *argv[])
-#endif
+int main(int argc, char *argv[])
 {
-    int c;
+    char c;
     int configtestonly = 0;
-    char *s;
     const char *confname = SERVER_CONFIG_FILE;
     const char *def_server_root = HTTPD_ROOT;
+    process_rec *process;
     server_rec *server_conf;
-    ap_context_t *pglobal;             /* Global pool */
-    ap_context_t *pconf;               /* Pool for config stuff */
-    ap_context_t *plog;                        /* Pool for error-logging files */
-    ap_context_t *ptemp;               /* Pool for temporart config stuff */
-    ap_context_t *pcommands;           /* Pool for -C and -c switches */
+    apr_pool_t *pglobal;
+    apr_pool_t *pconf;
+    apr_pool_t *plog; /* Pool of log streams, reset _after_ each read of conf */
+    apr_pool_t *ptemp; /* Pool for temporary config stuff, reset often */
+    apr_pool_t *pcommands; /* Pool for -D, -C and -c switches */
+    apr_getopt_t *opt;
+    module **mod;
+    ap_directive_t *conftree = NULL;
+    const char *optarg;
 
-    /* TODO: PATHSEPARATOR should be one of the os defines */
-#define PATHSEPARATOR '/'
-    if ((s = strrchr(argv[0], PATHSEPARATOR)) != NULL) {
-       ap_server_argv0 = ++s;
-    }
-    else {
-       ap_server_argv0 = argv[0];
+    apr_initialize();
+    process = create_process(argc, argv);
+    pglobal = process->pool;
+    pconf = process->pconf;
+    ap_server_argv0 = process->short_name;
+
+#ifdef CHARSET_EBCDIC
+    if (ap_init_ebcdic(pglobal) != APR_SUCCESS) {
+        destroy_and_exit_process(process, 1);
     }
+#endif
 
     ap_util_uri_init();
 
-    ap_create_context(&pglobal, NULL);
-    g_pHookPool=pglobal;
+    ap_setup_prelinked_modules(process);
+
+    apr_create_pool(&pcommands, pglobal);
+    ap_server_pre_read_config  = apr_make_array(pcommands, 1, sizeof(char *));
+    ap_server_post_read_config = apr_make_array(pcommands, 1, sizeof(char *));
+    ap_server_config_defines   = apr_make_array(pcommands, 1, sizeof(char *));
 
-    ap_create_context(&pcommands, pglobal);
-    ap_server_pre_read_config  = ap_make_array(pcommands, 1, sizeof(char *));
-    ap_server_post_read_config = ap_make_array(pcommands, 1, sizeof(char *));
-    ap_server_config_defines   = ap_make_array(pcommands, 1, sizeof(char *));
+    ap_run_rewrite_args(process);
 
-    ap_setup_prelinked_modules();
+    /* Maintain AP_SERVER_BASEARGS list in http_main.h to allow the MPM 
+     * to safely pass on our args from its rewrite_args() handler.
+     */
+    apr_initopt(&opt, pcommands, process->argc, process->argv);
 
-    while ((c = getopt(argc, argv, "C:c:d:f:vVlLth")) != -1) {
+    while (apr_getopt(opt, AP_SERVER_BASEARGS, &c, &optarg) 
+            == APR_SUCCESS) {
         char **new;
         switch (c) {
        case 'c':
-           new = (char **)ap_push_array(ap_server_post_read_config);
-           *new = ap_pstrdup(pcommands, optarg);
+           new = (char **)apr_push_array(ap_server_post_read_config);
+           *new = apr_pstrdup(pcommands, optarg);
            break;
        case 'C':
-           new = (char **)ap_push_array(ap_server_pre_read_config);
-           *new = ap_pstrdup(pcommands, optarg);
+           new = (char **)apr_push_array(ap_server_pre_read_config);
+           *new = apr_pstrdup(pcommands, optarg);
            break;
        case 'd':
            def_server_root = optarg;
            break;
+       case 'D':
+           new = (char **)apr_push_array(ap_server_config_defines);
+           *new = apr_pstrdup(pcommands, optarg);
+           break;
        case 'f':
            confname = optarg;
            break;
        case 'v':
            printf("Server version: %s\n", ap_get_server_version());
            printf("Server built:   %s\n", ap_get_server_built());
-           exit(0);
+           destroy_and_exit_process(process, 0);
        case 'V':
            show_compile_settings();
-           exit(0);
+           destroy_and_exit_process(process, 0);
        case 'l':
            ap_show_modules();
-           exit(0);
+           destroy_and_exit_process(process, 0);
        case 'L':
            ap_show_directives();
-           exit(0);
+           destroy_and_exit_process(process, 0);
        case 't':
            configtestonly = 1;
            break;
-       case 'h':
-           usage(argv[0]);
        case '?':
-           usage(argv[0]);
+       case 'h':
+           usage(process);
        }
     }
 
-    ap_create_context(&pconf, pglobal);
-    ap_create_context(&plog, pglobal);
-    ap_create_context(&ptemp, pconf);
+    apr_create_pool(&plog, pglobal);
+    apr_create_pool(&ptemp, pconf);
 
-    /* for legacy reasons, we read the configuration twice before
-       we actually serve any requests */
+    /* Note that we preflight the config file once
+       before reading it _again_ in the main loop.
+       This allows things, log files configuration 
+       for example, to settle down. */
 
     ap_server_root = def_server_root;
+    server_conf = ap_read_config(process, ptemp, confname, &conftree);
     ap_run_pre_config(pconf, plog, ptemp);
-    server_conf = ap_read_config(pconf, ptemp, confname);
-
+    ap_process_config_tree(server_conf, conftree, process->pconf, ptemp); 
+    ap_fixup_virtual_hosts(pconf, server_conf);
+    ap_fini_vhost_config(pconf, server_conf);
+    ap_sort_hooks();
     if (configtestonly) {
-       fprintf(stderr, "Syntax OK\n");
-       exit(0);
+       ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, "Syntax OK\n");
+       destroy_and_exit_process(process, 0);
     }
-
-    ap_clear_pool(plog);
+    apr_clear_pool(plog);
     ap_run_open_logs(pconf, plog, ptemp, server_conf);
     ap_post_config_hook(pconf, plog, ptemp, server_conf);
-    ap_destroy_pool(ptemp);
+    apr_destroy_pool(ptemp);
 
     for (;;) {
-       ap_create_context(&ptemp, pconf);
-       ap_clear_pool(pconf);
+       ap_hook_deregister_all();
+       apr_clear_pool(pconf);
+       for (mod = ap_prelinked_modules; *mod != NULL; mod++) {
+               ap_register_hooks(*mod);
+       }
+        /* This is a hack until we finish the code so that it only reads
+         * the config file once and just operates on the tree already in
+         * memory.  rbb
+         */
+        conftree = NULL;
+       apr_create_pool(&ptemp, pconf);
        ap_server_root = def_server_root;
+        server_conf = ap_read_config(process, ptemp, confname, &conftree);
        ap_run_pre_config(pconf, plog, ptemp);
-       server_conf = ap_read_config(pconf, ptemp, confname);
-       ap_clear_pool(plog);
+        ap_process_config_tree(server_conf, conftree, process->pconf, ptemp); 
+        ap_fixup_virtual_hosts(pconf, server_conf);
+        ap_fini_vhost_config(pconf, server_conf);
+        ap_sort_hooks();
+       apr_clear_pool(plog);
        ap_run_open_logs(pconf, plog, ptemp, server_conf);
        ap_post_config_hook(pconf, plog, ptemp, server_conf);
-       ap_destroy_pool(ptemp);
+       apr_destroy_pool(ptemp);
 
        if (ap_mpm_run(pconf, plog, server_conf)) break;
     }
-    ap_destroy_pool(pglobal); /* and destroy all descendent pools */
-    exit(0);
+    destroy_and_exit_process(process, 0);
+    return 0; /* Supress compiler warning. */
 }
 
 /* force Expat to be linked into the server executable */
@@ -365,13 +430,13 @@ const XML_LChar *suck_in_expat(void)
 
 #ifndef SHARED_CORE_BOOTSTRAP
 /*
- * Force ap_validate_password() into the image so that modules like
+ * Force apr_validate_password() into the image so that modules like
  * mod_auth can use it even if they're dynamically loaded.
  */
-void suck_in_ap_validate_password(void);
-void suck_in_ap_validate_password(void)
+void suck_in_apr_validate_password(void);
+void suck_in_apr_validate_password(void)
 {
-    ap_validate_password("a", "b");
+    apr_validate_password("a", "b");
 }
 #endif