]> granicus.if.org Git - apache/blob - server/main.c
Tag some pools
[apache] / server / main.c
1 /* ====================================================================
2  * The Apache Software License, Version 1.1
3  *
4  * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
5  * reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in
16  *    the documentation and/or other materials provided with the
17  *    distribution.
18  *
19  * 3. The end-user documentation included with the redistribution,
20  *    if any, must include the following acknowledgment:
21  *       "This product includes software developed by the
22  *        Apache Software Foundation (http://www.apache.org/)."
23  *    Alternately, this acknowledgment may appear in the software itself,
24  *    if and wherever such third-party acknowledgments normally appear.
25  *
26  * 4. The names "Apache" and "Apache Software Foundation" must
27  *    not be used to endorse or promote products derived from this
28  *    software without prior written permission. For written
29  *    permission, please contact apache@apache.org.
30  *
31  * 5. Products derived from this software may not be called "Apache",
32  *    nor may "Apache" appear in their name, without prior written
33  *    permission of the Apache Software Foundation.
34  *
35  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
36  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
37  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
38  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
39  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
42  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
44  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
45  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
46  * SUCH DAMAGE.
47  * ====================================================================
48  *
49  * This software consists of voluntary contributions made by many
50  * individuals on behalf of the Apache Software Foundation.  For more
51  * information on the Apache Software Foundation, please see
52  * <http://www.apache.org/>.
53  *
54  * Portions of this software are based upon public domain software
55  * originally written at the National Center for Supercomputing Applications,
56  * University of Illinois, Urbana-Champaign.
57  */
58
59 #include "apr.h"
60 #include "apr_strings.h"
61 #include "apr_getopt.h"
62 #include "apr_general.h"
63 #include "apr_lib.h"
64
65 #define APR_WANT_STDIO
66 #define APR_WANT_STRFUNC
67 #include "apr_want.h"
68
69 #define CORE_PRIVATE
70 #include "ap_config.h"
71 #include "httpd.h"
72 #include "http_main.h"
73 #include "http_log.h"
74 #include "http_config.h"
75 #include "http_vhost.h"
76 #include "apr_uri.h"
77 #include "util_ebcdic.h"
78 #include "ap_mpm.h"
79
80 /* WARNING: Win32 binds http_main.c dynamically to the server. Please place
81  *          extern functions and global data in another appropriate module.
82  *
83  * Most significant main() global data can be found in http_config.c
84  */
85
86 /* XXX - We should be able to grab the per-MPM settings here too */
87 static void show_compile_settings(void)
88 {
89     printf("Server version: %s\n", ap_get_server_version());
90     printf("Server built:   %s\n", ap_get_server_built());
91     printf("Server's Module Magic Number: %u:%u\n",
92            MODULE_MAGIC_NUMBER_MAJOR, MODULE_MAGIC_NUMBER_MINOR);
93
94     /* sizeof(foo) is long on some platforms so we might as well
95      * make it long everywhere to keep the printf format
96      * consistent
97      */
98     printf("Architecture:   %ld-bit\n", 8 * (long)sizeof(void *));
99     printf("Server compiled with....\n");
100 #ifdef BIG_SECURITY_HOLE
101     printf(" -D BIG_SECURITY_HOLE\n");
102 #endif
103
104 #ifdef SECURITY_HOLE_PASS_AUTHORIZATION
105     printf(" -D SECURITY_HOLE_PASS_AUTHORIZATION\n");
106 #endif
107
108 #ifdef APACHE_MPM_DIR
109     printf(" -D APACHE_MPM_DIR=\"%s\"\n", APACHE_MPM_DIR);
110 #endif
111
112 #ifdef HAVE_SHMGET
113     printf(" -D HAVE_SHMGET\n");
114 #endif
115
116 #if APR_FILE_BASED_SHM
117     printf(" -D APR_FILE_BASED_SHM\n");
118 #endif
119
120 #if APR_HAS_SENDFILE
121     printf(" -D APR_HAS_SENDFILE\n");
122 #endif
123
124 #if APR_HAS_MMAP
125     printf(" -D APR_HAS_MMAP\n");
126 #endif
127
128 #ifdef NO_WRITEV
129     printf(" -D NO_WRITEV\n");
130 #endif
131
132 #ifdef NO_LINGCLOSE
133     printf(" -D NO_LINGCLOSE\n");
134 #endif
135
136 #if APR_HAVE_IPV6
137     printf(" -D APR_HAVE_IPV6\n");
138 #endif
139
140 #if APR_USE_FLOCK_SERIALIZE
141     printf(" -D APR_USE_FLOCK_SERIALIZE\n");
142 #endif
143
144 #if APR_USE_SYSVSEM_SERIALIZE
145     printf(" -D APR_USE_SYSVSEM_SERIALIZE\n");
146 #endif
147
148 #if APR_USE_FCNTL_SERIALIZE
149     printf(" -D APR_USE_FCNTL_SERIALIZE\n");
150 #endif
151
152 #if APR_USE_PROC_PTHREAD_SERIALIZE
153     printf(" -D APR_USE_PROC_PTHREAD_SERIALIZE\n");
154 #endif
155
156 #if APR_USE_PTHREAD_SERIALIZE
157     printf(" -D APR_USE_PTHREAD_SERIALIZE\n");
158 #endif
159
160 #if APR_PROCESS_LOCK_IS_GLOBAL
161     printf(" -D APR_PROCESS_LOCK_IS_GLOBAL\n");
162 #endif
163
164 #ifdef SINGLE_LISTEN_UNSERIALIZED_ACCEPT
165     printf(" -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT\n");
166 #endif
167
168 #if APR_HAS_OTHER_CHILD
169     printf(" -D APR_HAS_OTHER_CHILD\n");
170 #endif
171
172 #ifdef AP_HAVE_RELIABLE_PIPED_LOGS
173     printf(" -D AP_HAVE_RELIABLE_PIPED_LOGS\n");
174 #endif
175
176 #ifdef BUFFERED_LOGS
177     printf(" -D BUFFERED_LOGS\n");
178 #ifdef PIPE_BUF
179     printf(" -D PIPE_BUF=%ld\n",(long)PIPE_BUF);
180 #endif
181 #endif
182
183 #if APR_CHARSET_EBCDIC
184     printf(" -D APR_CHARSET_EBCDIC\n");
185 #endif
186
187 #ifdef APACHE_XLATE
188     printf(" -D APACHE_XLATE\n");
189 #endif
190
191 #ifdef NEED_HASHBANG_EMUL
192     printf(" -D NEED_HASHBANG_EMUL\n");
193 #endif
194
195 #ifdef SHARED_CORE
196     printf(" -D SHARED_CORE\n");
197 #endif
198
199 /* This list displays the compiled in default paths: */
200 #ifdef HTTPD_ROOT
201     printf(" -D HTTPD_ROOT=\"" HTTPD_ROOT "\"\n");
202 #endif
203
204 #ifdef SUEXEC_BIN
205     printf(" -D SUEXEC_BIN=\"" SUEXEC_BIN "\"\n");
206 #endif
207
208 #if defined(SHARED_CORE) && defined(SHARED_CORE_DIR)
209     printf(" -D SHARED_CORE_DIR=\"" SHARED_CORE_DIR "\"\n");
210 #endif
211
212 #ifdef DEFAULT_PIDLOG
213     printf(" -D DEFAULT_PIDLOG=\"" DEFAULT_PIDLOG "\"\n");
214 #endif
215
216 #ifdef DEFAULT_SCOREBOARD
217     printf(" -D DEFAULT_SCOREBOARD=\"" DEFAULT_SCOREBOARD "\"\n");
218 #endif
219
220 #ifdef DEFAULT_LOCKFILE
221     printf(" -D DEFAULT_LOCKFILE=\"" DEFAULT_LOCKFILE "\"\n");
222 #endif
223
224 #ifdef DEFAULT_ERRORLOG
225     printf(" -D DEFAULT_ERRORLOG=\"" DEFAULT_ERRORLOG "\"\n");
226 #endif
227
228 #ifdef TYPES_CONFIG_FILE
229     printf(" -D TYPES_CONFIG_FILE=\"" TYPES_CONFIG_FILE "\"\n");
230 #endif
231
232 #ifdef SERVER_CONFIG_FILE
233     printf(" -D SERVER_CONFIG_FILE=\"" SERVER_CONFIG_FILE "\"\n");
234 #endif
235 }
236
237 static void destroy_and_exit_process(process_rec *process,
238                                      int process_exit_value)
239 {
240     apr_pool_destroy(process->pool); /* and destroy all descendent pools */
241     apr_terminate();
242     exit(process_exit_value);
243 }
244
245 static process_rec *create_process(int argc, const char * const *argv)
246 {
247     process_rec *process;
248     apr_pool_t *cntx;
249     apr_status_t stat;
250
251     stat = apr_pool_create(&cntx, NULL);
252     if (stat != APR_SUCCESS) {
253         /* XXX From the time that we took away the NULL pool->malloc mapping
254          *     we have been unable to log here without segfaulting.
255          */
256         ap_log_error(APLOG_MARK, APLOG_ERR, stat, NULL,
257                      "apr_pool_create() failed to create "
258                      "initial context");
259         apr_terminate();
260         exit(1);
261     }
262
263     apr_pool_tag(cntx, "process");
264     ap_open_stderr_log(cntx);
265
266     process = apr_palloc(cntx, sizeof(process_rec));
267     process->pool = cntx;
268
269     apr_pool_create(&process->pconf, process->pool);
270     apr_pool_tag(process->pconf, "pconf");
271     process->argc = argc;
272     process->argv = argv;
273     process->short_name = apr_filename_of_pathname(argv[0]);
274     return process;
275 }
276
277 static void usage(process_rec *process)
278 {
279     const char *bin = process->argv[0];
280     char pad[MAX_STRING_LEN];
281     unsigned i;
282
283     for (i = 0; i < strlen(bin); i++) {
284         pad[i] = ' ';
285     }
286
287     pad[i] = '\0';
288
289 #ifdef SHARED_CORE
290     ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL ,
291                  "Usage: %s [-R directory] [-D name] [-d directory] [-f file]",
292                  bin);
293 #else
294     ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
295                  "Usage: %s [-D name] [-d directory] [-f file]", bin);
296 #endif
297
298     ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
299                  "       %s [-C \"directive\"] [-c \"directive\"]", pad);
300
301 #ifdef WIN32
302     ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
303                  "       %s [-k restart|shutdown|start]", pad);
304     ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
305                  "       %s [-n service_name]", pad);
306     ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
307                  "       %s [-i] [-u]", pad);
308 #endif
309
310     ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
311                  "       %s [-v] [-V] [-h] [-l] [-L] [-t] [-T]", pad);
312     ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
313                  "Options:");
314
315 #ifdef SHARED_CORE
316     ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
317                  "  -R directory      : specify an alternate location for "
318                  "shared object files");
319 #endif
320
321     ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
322                  "  -D name           : define a name for use in "
323                  "<IfDefine name> directives");
324     ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
325                  "  -d directory      : specify an alternate initial "
326                  "ServerRoot");
327     ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
328                  "  -f file           : specify an alternate ServerConfigFile");
329     ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
330                  "  -C \"directive\"    : process directive before reading "
331                  "config files");
332     ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
333                  "  -c \"directive\"    : process directive after reading "
334                  "config files");
335
336 #ifdef WIN32
337     ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
338                  "  -n name           : set service name and use its "
339                  "ServerConfigFile");
340     ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
341                  "  -k shutdown       : tell running Apache to shutdown");
342     ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
343                  "  -k restart        : tell running Apache to do a graceful "
344                  "restart");
345     ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
346                  "  -k start          : tell Apache to start");
347     ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
348                  "  -i                : install an Apache service");
349     ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
350                  "  -u                : uninstall an Apache service");
351 #endif
352
353     ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
354                  "  -e level          : show startup errors of level "
355                  "(see LogLevel)");
356     ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
357                  "  -v                : show version number");
358     ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
359                  "  -V                : show compile settings");
360     ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
361                  "  -h                : list available command line options "
362                  "(this page)");
363     ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
364                  "  -l                : list compiled in modules");
365     ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
366                  "  -L                : list available configuration "
367                  "directives");
368     ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
369                  "  -t -D DUMP_VHOSTS : show parsed settings (currently only "
370                  "vhost settings)");
371     ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
372                  "  -t                : run syntax check for config files "
373                  "(with docroot check)");
374     ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
375                  "  -T                : run syntax check for config files "
376                  "(without docroot check)");
377
378     destroy_and_exit_process(process, 1);
379 }
380
381 int main(int argc, const char * const argv[])
382 {
383     char c;
384     int configtestonly = 0;
385     const char *confname = SERVER_CONFIG_FILE;
386     const char *def_server_root = HTTPD_ROOT;
387     process_rec *process;
388     server_rec *server_conf;
389     apr_pool_t *pglobal;
390     apr_pool_t *pconf;
391     apr_pool_t *plog; /* Pool of log streams, reset _after_ each read of conf */
392     apr_pool_t *ptemp; /* Pool for temporary config stuff, reset often */
393     apr_pool_t *pcommands; /* Pool for -D, -C and -c switches */
394     apr_getopt_t *opt;
395     apr_status_t rv;
396     module **mod;
397     const char *optarg;
398
399     AP_MONCONTROL(0); /* turn of profiling of startup */
400
401     apr_initialize();
402
403     process = create_process(argc, argv);
404     pglobal = process->pool;
405     pconf = process->pconf;
406     ap_server_argv0 = process->short_name;
407
408 #if APR_CHARSET_EBCDIC
409     if (ap_init_ebcdic(pglobal) != APR_SUCCESS) {
410         destroy_and_exit_process(process, 1);
411     }
412 #endif
413
414     ap_setup_prelinked_modules(process);
415
416     apr_pool_create(&pcommands, pglobal);
417     apr_pool_tag(pcommands, "pcommands");
418     ap_server_pre_read_config  = apr_array_make(pcommands, 1, sizeof(char *));
419     ap_server_post_read_config = apr_array_make(pcommands, 1, sizeof(char *));
420     ap_server_config_defines   = apr_array_make(pcommands, 1, sizeof(char *));
421
422     ap_run_rewrite_args(process);
423
424     /* Maintain AP_SERVER_BASEARGS list in http_main.h to allow the MPM
425      * to safely pass on our args from its rewrite_args() handler.
426      */
427     apr_getopt_init(&opt, pcommands, process->argc, process->argv);
428
429     while ((rv = apr_getopt(opt, AP_SERVER_BASEARGS, &c, &optarg))
430             == APR_SUCCESS) {
431         char **new;
432
433         switch (c) {
434         case 'c':
435             new = (char **)apr_array_push(ap_server_post_read_config);
436             *new = apr_pstrdup(pcommands, optarg);
437             break;
438
439         case 'C':
440             new = (char **)apr_array_push(ap_server_pre_read_config);
441             *new = apr_pstrdup(pcommands, optarg);
442             break;
443
444         case 'd':
445             def_server_root = optarg;
446             break;
447
448         case 'D':
449             new = (char **)apr_array_push(ap_server_config_defines);
450             *new = apr_pstrdup(pcommands, optarg);
451             break;
452
453         case 'e':
454             if (strcasecmp(optarg, "emerg") == 0) {
455                 ap_default_loglevel = APLOG_EMERG;
456             }
457             else if (strcasecmp(optarg, "alert") == 0) {
458                 ap_default_loglevel = APLOG_ALERT;
459             }
460             else if (strcasecmp(optarg, "crit") == 0) {
461                 ap_default_loglevel = APLOG_CRIT;
462             }
463             else if (strncasecmp(optarg, "err", 3) == 0) {
464                 ap_default_loglevel = APLOG_ERR;
465             }
466             else if (strncasecmp(optarg, "warn", 4) == 0) {
467                 ap_default_loglevel = APLOG_WARNING;
468             }
469             else if (strcasecmp(optarg, "notice") == 0) {
470                 ap_default_loglevel = APLOG_NOTICE;
471             }
472             else if (strcasecmp(optarg, "info") == 0) {
473                 ap_default_loglevel = APLOG_INFO;
474             }
475             else if (strcasecmp(optarg, "debug") == 0) {
476                 ap_default_loglevel = APLOG_DEBUG;
477             }
478             else {
479                 usage(process);
480             }
481             break;
482
483         case 'X':
484             new = (char **)apr_array_push(ap_server_config_defines);
485             *new = "DEBUG";
486             break;
487
488         case 'f':
489             confname = optarg;
490             break;
491
492         case 'v':
493             printf("Server version: %s\n", ap_get_server_version());
494             printf("Server built:   %s\n", ap_get_server_built());
495             destroy_and_exit_process(process, 0);
496
497         case 'V':
498             show_compile_settings();
499             destroy_and_exit_process(process, 0);
500
501         case 'l':
502             ap_show_modules();
503             destroy_and_exit_process(process, 0);
504
505         case 'L':
506             ap_show_directives();
507             destroy_and_exit_process(process, 0);
508
509         case 't':
510             configtestonly = 1;
511             break;
512
513         case 'h':
514         case '?':
515             usage(process);
516         }
517     }
518
519     /* bad cmdline option?  then we die */
520     if (rv != APR_EOF) {
521         usage(process);
522     }
523
524     apr_pool_create(&plog, pglobal);
525     apr_pool_tag(plog, "plog");
526     apr_pool_create(&ptemp, pconf);
527     apr_pool_tag(ptemp, "ptemp");
528
529     /* Note that we preflight the config file once
530      * before reading it _again_ in the main loop.
531      * This allows things, log files configuration
532      * for example, to settle down.
533      */
534
535     ap_server_root = def_server_root;
536     server_conf = ap_read_config(process, ptemp, confname, &ap_conftree);
537     if (ap_run_pre_config(pconf, plog, ptemp) != OK) {
538         ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR| APLOG_NOERRNO, 0,
539                      NULL, "Pre-configuration failed\n");
540         destroy_and_exit_process(process, 1);
541     }
542
543     ap_process_config_tree(server_conf, ap_conftree, process->pconf, ptemp);
544     ap_fixup_virtual_hosts(pconf, server_conf);
545     ap_fini_vhost_config(pconf, server_conf);
546     apr_sort_hooks();
547     if (configtestonly) {
548         ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
549                      "Syntax OK\n");
550         destroy_and_exit_process(process, 0);
551     }
552
553     apr_pool_clear(plog);
554
555     /* It is assumed that if you are going to fail the open_logs phase, then
556      * you will print out your own message that explains what has gone wrong.
557      * The server doesn't need to do that for you.
558      */
559     if ( ap_run_open_logs(pconf, plog, ptemp, server_conf) != OK) {
560         destroy_and_exit_process(process, 1);
561     }
562
563     if ( ap_run_post_config(pconf, plog, ptemp, server_conf) != OK) {
564         ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR| APLOG_NOERRNO, 0,
565                      NULL, "Configuration Failed\n");
566         destroy_and_exit_process(process, 1);
567     }
568
569     apr_pool_destroy(ptemp);
570
571     for (;;) {
572         apr_hook_deregister_all();
573         apr_pool_clear(pconf);
574
575         for (mod = ap_prelinked_modules; *mod != NULL; mod++) {
576             ap_register_hooks(*mod, pconf);
577         }
578
579         /* This is a hack until we finish the code so that it only reads
580          * the config file once and just operates on the tree already in
581          * memory.  rbb
582          */
583         ap_conftree = NULL;
584         apr_pool_create(&ptemp, pconf);
585         apr_pool_tag(ptemp, "ptemp");
586         ap_server_root = def_server_root;
587         server_conf = ap_read_config(process, ptemp, confname, &ap_conftree);
588         if (ap_run_pre_config(pconf, plog, ptemp) != OK) {
589             ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR| APLOG_NOERRNO,
590                          0, NULL, "Pre-configuration failed\n");
591             destroy_and_exit_process(process, 1);
592         }
593
594         ap_process_config_tree(server_conf, ap_conftree, process->pconf, ptemp);
595         ap_fixup_virtual_hosts(pconf, server_conf);
596         ap_fini_vhost_config(pconf, server_conf);
597         apr_sort_hooks();
598         apr_pool_clear(plog);
599         if (ap_run_open_logs(pconf, plog, ptemp, server_conf) != OK) {
600             ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR| APLOG_NOERRNO,
601                          0, NULL, "Unable to open logs\n");
602             destroy_and_exit_process(process, 1);
603         }
604
605         if (ap_run_post_config(pconf, plog, ptemp, server_conf) != OK) {
606             ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR | APLOG_NOERRNO,
607                          0, NULL, "Configuration Failed\n");
608             destroy_and_exit_process(process, 1);
609         }
610
611         apr_pool_destroy(ptemp);
612         apr_pool_lock(pconf, 1);
613
614         ap_run_optional_fn_retrieve();
615
616         if (ap_mpm_run(pconf, plog, server_conf))
617             break;
618
619         apr_pool_lock(pconf, 0);
620     }
621
622     apr_pool_lock(pconf, 0);
623     destroy_and_exit_process(process, 0);
624
625     return 0; /* Supress compiler warning. */
626 }
627
628 /* force Expat to be linked into the server executable */
629 #if defined(USE_EXPAT) && !defined(SHARED_CORE_BOOTSTRAP)
630 #include "xmlparse.h"
631 const XML_LChar *suck_in_expat(void);
632 const XML_LChar *suck_in_expat(void)
633 {
634     return XML_ErrorString(XML_ERROR_NONE);
635 }
636 #endif /* USE_EXPAT */
637
638 #ifndef SHARED_CORE_BOOTSTRAP
639 /*
640  * Force apr_password_validate() into the image so that modules like
641  * mod_auth can use it even if they're dynamically loaded.
642  */
643 void suck_in_apr_password_validate(void);
644 void suck_in_apr_password_validate(void)
645 {
646     apr_password_validate("a", "b");
647 }
648 #endif
649
650 #ifdef AP_USING_AUTOCONF
651 /* This ugly little hack pulls any function referenced in exports.c into
652  * the web server.  exports.c is generated during the build, and it
653  * has all of the APR functions specified by the apr/apr.exports and
654  * apr-util/aprutil.exports files.
655  */
656 const void *suck_in_APR(void);
657 const void *suck_in_APR(void)
658 {
659     extern const void *ap_ugly_hack;
660
661     return ap_ugly_hack;
662 }
663 #endif