]> granicus.if.org Git - apache/blob - server/main.c
changed the following APIs to return an error instead of hard exiting:
[apache] / server / main.c
1 /* Copyright 1999-2004 The Apache Software Foundation
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #include "apr.h"
17 #include "apr_strings.h"
18 #include "apr_getopt.h"
19 #include "apr_general.h"
20 #include "apr_lib.h"
21 #include "apr_md5.h"
22
23 #define APR_WANT_STDIO
24 #define APR_WANT_STRFUNC
25 #include "apr_want.h"
26
27 #define CORE_PRIVATE
28 #include "ap_config.h"
29 #include "httpd.h"
30 #include "http_main.h"
31 #include "http_log.h"
32 #include "http_config.h"
33 #include "http_vhost.h"
34 #include "apr_uri.h"
35 #include "util_ebcdic.h"
36 #include "ap_mpm.h"
37 #include "mpm_common.h"
38
39 /* WARNING: Win32 binds http_main.c dynamically to the server. Please place
40  *          extern functions and global data in another appropriate module.
41  *
42  * Most significant main() global data can be found in http_config.c
43  */
44
45 static void show_mpm_settings(void)
46 {
47     int mpm_query_info;
48     apr_status_t retval;
49
50     printf("Server MPM:     %s\n", ap_show_mpm());
51
52     retval = ap_mpm_query(AP_MPMQ_IS_THREADED, &mpm_query_info);
53
54     if (retval == APR_SUCCESS) {
55         printf("  threaded:     ");
56
57         if (mpm_query_info == AP_MPMQ_DYNAMIC) {
58             printf("yes (variable thread count)\n");
59         }
60         else if (mpm_query_info == AP_MPMQ_STATIC) {
61             printf("yes (fixed thread count)\n");
62         }
63         else {
64             printf("no\n");
65         }
66     }
67
68     retval = ap_mpm_query(AP_MPMQ_IS_FORKED, &mpm_query_info);
69
70     if (retval == APR_SUCCESS) {
71         printf("    forked:     ");
72
73         if (mpm_query_info == AP_MPMQ_DYNAMIC) {
74             printf("yes (variable process count)\n");
75         }
76         else if (mpm_query_info == AP_MPMQ_STATIC) {
77             printf("yes (fixed process count)\n");
78         }
79         else {
80             printf("no\n");
81         }
82     }
83 }
84
85 static void show_compile_settings(void)
86 {
87     printf("Server version: %s\n", ap_get_server_version());
88     printf("Server built:   %s\n", ap_get_server_built());
89     printf("Server's Module Magic Number: %u:%u\n",
90            MODULE_MAGIC_NUMBER_MAJOR, MODULE_MAGIC_NUMBER_MINOR);
91
92     /* sizeof(foo) is long on some platforms so we might as well
93      * make it long everywhere to keep the printf format
94      * consistent
95      */
96     printf("Architecture:   %ld-bit\n", 8 * (long)sizeof(void *));
97
98     show_mpm_settings();
99
100     printf("Server compiled with....\n");
101 #ifdef BIG_SECURITY_HOLE
102     printf(" -D BIG_SECURITY_HOLE\n");
103 #endif
104
105 #ifdef SECURITY_HOLE_PASS_AUTHORIZATION
106     printf(" -D SECURITY_HOLE_PASS_AUTHORIZATION\n");
107 #endif
108
109 #ifdef HAVE_SHMGET
110     printf(" -D HAVE_SHMGET\n");
111 #endif
112
113 #if APR_FILE_BASED_SHM
114     printf(" -D APR_FILE_BASED_SHM\n");
115 #endif
116
117 #if APR_HAS_SENDFILE
118     printf(" -D APR_HAS_SENDFILE\n");
119 #endif
120
121 #if APR_HAS_MMAP
122     printf(" -D APR_HAS_MMAP\n");
123 #endif
124
125 #ifdef NO_WRITEV
126     printf(" -D NO_WRITEV\n");
127 #endif
128
129 #ifdef NO_LINGCLOSE
130     printf(" -D NO_LINGCLOSE\n");
131 #endif
132
133 #if APR_HAVE_IPV6
134     printf(" -D APR_HAVE_IPV6 (IPv4-mapped addresses ");
135 #ifdef AP_ENABLE_V4_MAPPED
136     printf("enabled)\n");
137 #else
138     printf("disabled)\n");
139 #endif
140 #endif
141
142 #if APR_USE_FLOCK_SERIALIZE
143     printf(" -D APR_USE_FLOCK_SERIALIZE\n");
144 #endif
145
146 #if APR_USE_SYSVSEM_SERIALIZE
147     printf(" -D APR_USE_SYSVSEM_SERIALIZE\n");
148 #endif
149
150 #if APR_USE_POSIXSEM_SERIALIZE
151     printf(" -D APR_USE_POSIXSEM_SERIALIZE\n");
152 #endif
153
154 #if APR_USE_FCNTL_SERIALIZE
155     printf(" -D APR_USE_FCNTL_SERIALIZE\n");
156 #endif
157
158 #if APR_USE_PROC_PTHREAD_SERIALIZE
159     printf(" -D APR_USE_PROC_PTHREAD_SERIALIZE\n");
160 #endif
161
162 #if APR_USE_PTHREAD_SERIALIZE
163     printf(" -D APR_USE_PTHREAD_SERIALIZE\n");
164 #endif
165
166 #if APR_PROCESS_LOCK_IS_GLOBAL
167     printf(" -D APR_PROCESS_LOCK_IS_GLOBAL\n");
168 #endif
169
170 #ifdef SINGLE_LISTEN_UNSERIALIZED_ACCEPT
171     printf(" -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT\n");
172 #endif
173
174 #if APR_HAS_OTHER_CHILD
175     printf(" -D APR_HAS_OTHER_CHILD\n");
176 #endif
177
178 #ifdef AP_HAVE_RELIABLE_PIPED_LOGS
179     printf(" -D AP_HAVE_RELIABLE_PIPED_LOGS\n");
180 #endif
181
182 #ifdef BUFFERED_LOGS
183     printf(" -D BUFFERED_LOGS\n");
184 #ifdef PIPE_BUF
185     printf(" -D PIPE_BUF=%ld\n",(long)PIPE_BUF);
186 #endif
187 #endif
188
189 #if APR_CHARSET_EBCDIC
190     printf(" -D APR_CHARSET_EBCDIC\n");
191 #endif
192
193 #ifdef NEED_HASHBANG_EMUL
194     printf(" -D NEED_HASHBANG_EMUL\n");
195 #endif
196
197 #ifdef SHARED_CORE
198     printf(" -D SHARED_CORE\n");
199 #endif
200
201 /* This list displays the compiled in default paths: */
202 #ifdef HTTPD_ROOT
203     printf(" -D HTTPD_ROOT=\"" HTTPD_ROOT "\"\n");
204 #endif
205
206 #ifdef SUEXEC_BIN
207     printf(" -D SUEXEC_BIN=\"" SUEXEC_BIN "\"\n");
208 #endif
209
210 #if defined(SHARED_CORE) && defined(SHARED_CORE_DIR)
211     printf(" -D SHARED_CORE_DIR=\"" SHARED_CORE_DIR "\"\n");
212 #endif
213
214 #ifdef DEFAULT_PIDLOG
215     printf(" -D DEFAULT_PIDLOG=\"" DEFAULT_PIDLOG "\"\n");
216 #endif
217
218 #ifdef DEFAULT_SCOREBOARD
219     printf(" -D DEFAULT_SCOREBOARD=\"" DEFAULT_SCOREBOARD "\"\n");
220 #endif
221
222 #ifdef DEFAULT_LOCKFILE
223     printf(" -D DEFAULT_LOCKFILE=\"" DEFAULT_LOCKFILE "\"\n");
224 #endif
225
226 #ifdef DEFAULT_ERRORLOG
227     printf(" -D DEFAULT_ERRORLOG=\"" DEFAULT_ERRORLOG "\"\n");
228 #endif
229
230 #ifdef AP_TYPES_CONFIG_FILE
231     printf(" -D AP_TYPES_CONFIG_FILE=\"" AP_TYPES_CONFIG_FILE "\"\n");
232 #endif
233
234 #ifdef SERVER_CONFIG_FILE
235     printf(" -D SERVER_CONFIG_FILE=\"" SERVER_CONFIG_FILE "\"\n");
236 #endif
237 }
238
239 static void destroy_and_exit_process(process_rec *process,
240                                      int process_exit_value)
241 {
242     apr_pool_destroy(process->pool); /* and destroy all descendent pools */
243     apr_terminate();
244     exit(process_exit_value);
245 }
246
247 static process_rec *create_process(int argc, const char * const *argv)
248 {
249     process_rec *process;
250     apr_pool_t *cntx;
251     apr_status_t stat;
252
253     stat = apr_pool_create(&cntx, NULL);
254     if (stat != APR_SUCCESS) {
255         /* XXX From the time that we took away the NULL pool->malloc mapping
256          *     we have been unable to log here without segfaulting.
257          */
258         ap_log_error(APLOG_MARK, APLOG_ERR, stat, NULL,
259                      "apr_pool_create() failed to create "
260                      "initial context");
261         apr_terminate();
262         exit(1);
263     }
264
265     apr_pool_tag(cntx, "process");
266     ap_open_stderr_log(cntx);
267
268     process = apr_palloc(cntx, sizeof(process_rec));
269     process->pool = cntx;
270
271     apr_pool_create(&process->pconf, process->pool);
272     apr_pool_tag(process->pconf, "pconf");
273     process->argc = argc;
274     process->argv = argv;
275     process->short_name = apr_filepath_name_get(argv[0]);
276     return process;
277 }
278
279 static void usage(process_rec *process)
280 {
281     const char *bin = process->argv[0];
282     char pad[MAX_STRING_LEN];
283     unsigned i;
284
285     for (i = 0; i < strlen(bin); i++) {
286         pad[i] = ' ';
287     }
288
289     pad[i] = '\0';
290
291 #ifdef SHARED_CORE
292     ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL ,
293                  "Usage: %s [-R directory] [-D name] [-d directory] [-f file]",
294                  bin);
295 #else
296     ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
297                  "Usage: %s [-D name] [-d directory] [-f file]", bin);
298 #endif
299
300     ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
301                  "       %s [-C \"directive\"] [-c \"directive\"]", pad);
302
303 #ifdef WIN32
304     ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
305                  "       %s [-w] [-k start|restart|stop|shutdown]", pad);
306     ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
307                  "       %s [-k install|config|uninstall] [-n service_name]",
308                  pad);
309 #endif
310 #ifdef AP_MPM_WANT_SIGNAL_SERVER
311     ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
312                  "       %s [-k start|restart|graceful|stop]",
313                  pad);
314 #endif
315     ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
316                  "       %s [-v] [-V] [-h] [-l] [-L] [-t] [-S]", pad);
317     ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
318                  "Options:");
319
320 #ifdef SHARED_CORE
321     ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
322                  "  -R directory      : specify an alternate location for "
323                  "shared object files");
324 #endif
325
326     ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
327                  "  -D name           : define a name for use in "
328                  "<IfDefine name> directives");
329     ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
330                  "  -d directory      : specify an alternate initial "
331                  "ServerRoot");
332     ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
333                  "  -f file           : specify an alternate ServerConfigFile");
334     ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
335                  "  -C \"directive\"    : process directive before reading "
336                  "config files");
337     ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
338                  "  -c \"directive\"    : process directive after reading "
339                  "config files");
340
341 #ifdef NETWARE
342     ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
343                  "  -n name           : set screen name");
344 #endif
345 #ifdef WIN32
346     ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
347                  "  -n name           : set service name and use its "
348                  "ServerConfigFile");
349     ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
350                  "  -k start          : tell Apache to start");
351     ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
352                  "  -k restart        : tell running Apache to do a graceful "
353                  "restart");
354     ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
355                  "  -k stop|shutdown  : tell running Apache to shutdown");
356     ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
357                  "  -k install        : install an Apache service");
358     ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
359                  "  -k config         : change startup Options of an Apache "
360                  "service");
361     ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
362                  "  -k uninstall      : uninstall an Apache service");
363     ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
364                  "  -w                : hold open the console window on error");
365 #endif
366
367     ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
368                  "  -e level          : show startup errors of level "
369                  "(see LogLevel)");
370     ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
371                  "  -E file           : log startup errors to file");
372     ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
373                  "  -v                : show version number");
374     ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
375                  "  -V                : show compile settings");
376     ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
377                  "  -h                : list available command line options "
378                  "(this page)");
379     ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
380                  "  -l                : list compiled in modules");
381     ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
382                  "  -L                : list available configuration "
383                  "directives");
384     ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
385                  "  -t -D DUMP_VHOSTS : show parsed settings (currently only "
386                  "vhost settings)");
387     ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
388                  "  -S                : a synonym for -t -D DUMP_VHOSTS");   
389     ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
390                  "  -t                : run syntax check for config files");
391
392     destroy_and_exit_process(process, 1);
393 }
394
395 int main(int argc, const char * const argv[])
396 {
397     char c;
398     int configtestonly = 0;
399     const char *confname = SERVER_CONFIG_FILE;
400     const char *def_server_root = HTTPD_ROOT;
401     const char *temp_error_log = NULL;
402     const char *error;
403     process_rec *process;
404     server_rec *server_conf;
405     apr_pool_t *pglobal;
406     apr_pool_t *pconf;
407     apr_pool_t *plog; /* Pool of log streams, reset _after_ each read of conf */
408     apr_pool_t *ptemp; /* Pool for temporary config stuff, reset often */
409     apr_pool_t *pcommands; /* Pool for -D, -C and -c switches */
410     apr_getopt_t *opt;
411     apr_status_t rv;
412     module **mod;
413     const char *optarg;
414     APR_OPTIONAL_FN_TYPE(ap_signal_server) *signal_server;
415
416     AP_MONCONTROL(0); /* turn off profiling of startup */
417
418     apr_app_initialize(&argc, &argv, NULL);
419
420     process = create_process(argc, argv);
421     pglobal = process->pool;
422     pconf = process->pconf;
423     ap_server_argv0 = process->short_name;
424
425 #if APR_CHARSET_EBCDIC
426     if (ap_init_ebcdic(pglobal) != APR_SUCCESS) {
427         destroy_and_exit_process(process, 1);
428     }
429 #endif
430
431     error = ap_setup_prelinked_modules(process);
432     if (error) {
433         ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_EMERG, 0, NULL, "%s: %s",
434                      ap_server_argv0, error);
435         destroy_and_exit_process(process, 1);
436     }
437
438     apr_pool_create(&pcommands, pglobal);
439     apr_pool_tag(pcommands, "pcommands");
440     ap_server_pre_read_config  = apr_array_make(pcommands, 1, sizeof(char *));
441     ap_server_post_read_config = apr_array_make(pcommands, 1, sizeof(char *));
442     ap_server_config_defines   = apr_array_make(pcommands, 1, sizeof(char *));
443
444     ap_run_rewrite_args(process);
445
446     /* Maintain AP_SERVER_BASEARGS list in http_main.h to allow the MPM
447      * to safely pass on our args from its rewrite_args() handler.
448      */
449     apr_getopt_init(&opt, pcommands, process->argc, process->argv);
450
451     while ((rv = apr_getopt(opt, AP_SERVER_BASEARGS, &c, &optarg))
452             == APR_SUCCESS) {
453         char **new;
454
455         switch (c) {
456         case 'c':
457             new = (char **)apr_array_push(ap_server_post_read_config);
458             *new = apr_pstrdup(pcommands, optarg);
459             break;
460
461         case 'C':
462             new = (char **)apr_array_push(ap_server_pre_read_config);
463             *new = apr_pstrdup(pcommands, optarg);
464             break;
465
466         case 'd':
467             def_server_root = optarg;
468             break;
469
470         case 'D':
471             new = (char **)apr_array_push(ap_server_config_defines);
472             *new = apr_pstrdup(pcommands, optarg);
473             /* Setting -D DUMP_VHOSTS is equivalent to setting -S */
474             if (strcmp(optarg, "DUMP_VHOSTS") == 0)
475                 configtestonly = 1;
476             break;
477
478         case 'e':
479             if (strcasecmp(optarg, "emerg") == 0) {
480                 ap_default_loglevel = APLOG_EMERG;
481             }
482             else if (strcasecmp(optarg, "alert") == 0) {
483                 ap_default_loglevel = APLOG_ALERT;
484             }
485             else if (strcasecmp(optarg, "crit") == 0) {
486                 ap_default_loglevel = APLOG_CRIT;
487             }
488             else if (strncasecmp(optarg, "err", 3) == 0) {
489                 ap_default_loglevel = APLOG_ERR;
490             }
491             else if (strncasecmp(optarg, "warn", 4) == 0) {
492                 ap_default_loglevel = APLOG_WARNING;
493             }
494             else if (strcasecmp(optarg, "notice") == 0) {
495                 ap_default_loglevel = APLOG_NOTICE;
496             }
497             else if (strcasecmp(optarg, "info") == 0) {
498                 ap_default_loglevel = APLOG_INFO;
499             }
500             else if (strcasecmp(optarg, "debug") == 0) {
501                 ap_default_loglevel = APLOG_DEBUG;
502             }
503             else {
504                 usage(process);
505             }
506             break;
507
508         case 'E':
509             temp_error_log = apr_pstrdup(process->pool, optarg);
510             break;
511
512         case 'X':
513             new = (char **)apr_array_push(ap_server_config_defines);
514             *new = "DEBUG";
515             break;
516
517         case 'f':
518             confname = optarg;
519             break;
520
521         case 'v':
522             printf("Server version: %s\n", ap_get_server_version());
523             printf("Server built:   %s\n", ap_get_server_built());
524             destroy_and_exit_process(process, 0);
525
526         case 'V':
527             show_compile_settings();
528             destroy_and_exit_process(process, 0);
529
530         case 'l':
531             ap_show_modules();
532             destroy_and_exit_process(process, 0);
533
534         case 'L':
535             ap_show_directives();
536             destroy_and_exit_process(process, 0);
537
538         case 't':
539             configtestonly = 1;
540             break;
541         
542         case 'S':
543             configtestonly = 1;
544             new = (char **)apr_array_push(ap_server_config_defines);
545             *new = "DUMP_VHOSTS";
546             break;
547             
548         case 'h':
549         case '?':
550             usage(process);
551         }
552     }
553
554     /* bad cmdline option?  then we die */
555     if (rv != APR_EOF || opt->ind < opt->argc) {
556         usage(process);
557     }
558
559     apr_pool_create(&plog, pglobal);
560     apr_pool_tag(plog, "plog");
561     apr_pool_create(&ptemp, pconf);
562     apr_pool_tag(ptemp, "ptemp");
563
564     /* Note that we preflight the config file once
565      * before reading it _again_ in the main loop.
566      * This allows things, log files configuration
567      * for example, to settle down.
568      */
569
570     ap_server_root = def_server_root;
571     if (temp_error_log) {
572         ap_replace_stderr_log(process->pool, temp_error_log);
573     }
574     server_conf = ap_read_config(process, ptemp, confname, &ap_conftree);
575     if (!server_conf) {
576         destroy_and_exit_process(process, 1);
577     }
578
579     if (ap_run_pre_config(pconf, plog, ptemp) != OK) {
580         ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR, 0,
581                      NULL, "Pre-configuration failed");
582         destroy_and_exit_process(process, 1);
583     }
584
585     rv = ap_process_config_tree(server_conf, ap_conftree,
586                                 process->pconf, ptemp);
587     if (rv == OK) {
588         ap_fixup_virtual_hosts(pconf, server_conf);
589         ap_fini_vhost_config(pconf, server_conf);
590         apr_hook_sort_all();
591         if (configtestonly) {
592             ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, "Syntax OK");
593             destroy_and_exit_process(process, 0);
594         }
595     }
596
597     signal_server = APR_RETRIEVE_OPTIONAL_FN(ap_signal_server);
598     if (signal_server) {
599         int exit_status;
600
601         if (signal_server(&exit_status, pconf) != 0) {
602             destroy_and_exit_process(process, exit_status);
603         }
604     }
605
606     /* If our config failed, deal with that here. */
607     if (rv != OK) {
608         destroy_and_exit_process(process, 1);
609     }
610
611     apr_pool_clear(plog);
612
613     if ( ap_run_open_logs(pconf, plog, ptemp, server_conf) != OK) {
614         ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR,
615                      0, NULL, "Unable to open logs");
616         destroy_and_exit_process(process, 1);
617     }
618
619     if ( ap_run_post_config(pconf, plog, ptemp, server_conf) != OK) {
620         ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR, 0,
621                      NULL, "Configuration Failed");
622         destroy_and_exit_process(process, 1);
623     }
624
625     apr_pool_destroy(ptemp);
626
627     for (;;) {
628         apr_hook_deregister_all();
629         apr_pool_clear(pconf);
630
631         for (mod = ap_prelinked_modules; *mod != NULL; mod++) {
632             ap_register_hooks(*mod, pconf);
633         }
634
635         /* This is a hack until we finish the code so that it only reads
636          * the config file once and just operates on the tree already in
637          * memory.  rbb
638          */
639         ap_conftree = NULL;
640         apr_pool_create(&ptemp, pconf);
641         apr_pool_tag(ptemp, "ptemp");
642         ap_server_root = def_server_root;
643         server_conf = ap_read_config(process, ptemp, confname, &ap_conftree);
644         if (!server_conf) {
645             destroy_and_exit_process(process, 1);
646         }
647
648         if (ap_run_pre_config(pconf, plog, ptemp) != OK) {
649             ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR,
650                          0, NULL, "Pre-configuration failed");
651             destroy_and_exit_process(process, 1);
652         }
653
654         if (ap_process_config_tree(server_conf, ap_conftree, process->pconf,
655                                    ptemp) != OK) {
656             destroy_and_exit_process(process, 1);
657         }
658         ap_fixup_virtual_hosts(pconf, server_conf);
659         ap_fini_vhost_config(pconf, server_conf);
660         apr_hook_sort_all();
661         apr_pool_clear(plog);
662         if (ap_run_open_logs(pconf, plog, ptemp, server_conf) != OK) {
663             ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR,
664                          0, NULL, "Unable to open logs");
665             destroy_and_exit_process(process, 1);
666         }
667
668         if (ap_run_post_config(pconf, plog, ptemp, server_conf) != OK) {
669             ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR,
670                          0, NULL, "Configuration Failed");
671             destroy_and_exit_process(process, 1);
672         }
673
674         apr_pool_destroy(ptemp);
675         apr_pool_lock(pconf, 1);
676
677         ap_run_optional_fn_retrieve();
678
679         if (ap_mpm_run(pconf, plog, server_conf))
680             break;
681
682         apr_pool_lock(pconf, 0);
683     }
684
685     apr_pool_lock(pconf, 0);
686     destroy_and_exit_process(process, 0);
687
688     return 0; /* Termination 'ok' */
689 }
690
691 #ifndef SHARED_CORE_BOOTSTRAP
692 /*
693  * Force apr_password_validate() into the image so that modules like
694  * mod_auth can use it even if they're dynamically loaded.
695  */
696 void suck_in_apr_password_validate(void);
697 void suck_in_apr_password_validate(void)
698 {
699     apr_password_validate("a", "b");
700 }
701 #endif
702
703 #ifdef AP_USING_AUTOCONF
704 /* This ugly little hack pulls any function referenced in exports.c into
705  * the web server.  exports.c is generated during the build, and it
706  * has all of the APR functions specified by the apr/apr.exports and
707  * apr-util/aprutil.exports files.
708  */
709 const void *suck_in_APR(void);
710 const void *suck_in_APR(void)
711 {
712     extern const void *ap_ugly_hack;
713
714     return ap_ugly_hack;
715 }
716 #endif