1 /* ====================================================================
2 * The Apache Software License, Version 1.1
4 * Copyright (c) 2000-2002 The Apache Software Foundation. All rights
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
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
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.
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.
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.
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
47 * ====================================================================
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/>.
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.
60 #include "apr_strings.h"
61 #include "apr_getopt.h"
62 #include "apr_general.h"
65 #define APR_WANT_STDIO
66 #define APR_WANT_STRFUNC
70 #include "ap_config.h"
72 #include "http_main.h"
74 #include "http_config.h"
75 #include "http_vhost.h"
77 #include "util_ebcdic.h"
80 /* WARNING: Win32 binds http_main.c dynamically to the server. Please place
81 * extern functions and global data in another appropriate module.
83 * Most significant main() global data can be found in http_config.c
86 /* XXX - We should be able to grab the per-MPM settings here too */
87 static void show_compile_settings(void)
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);
94 /* sizeof(foo) is long on some platforms so we might as well
95 * make it long everywhere to keep the printf format
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");
104 #ifdef SECURITY_HOLE_PASS_AUTHORIZATION
105 printf(" -D SECURITY_HOLE_PASS_AUTHORIZATION\n");
108 #ifdef APACHE_MPM_DIR
109 printf(" -D APACHE_MPM_DIR=\"%s\"\n", APACHE_MPM_DIR);
113 printf(" -D HAVE_SHMGET\n");
116 #if APR_FILE_BASED_SHM
117 printf(" -D APR_FILE_BASED_SHM\n");
121 printf(" -D APR_HAS_SENDFILE\n");
125 printf(" -D APR_HAS_MMAP\n");
129 printf(" -D NO_WRITEV\n");
133 printf(" -D NO_LINGCLOSE\n");
137 printf(" -D APR_HAVE_IPV6\n");
140 #if APR_USE_FLOCK_SERIALIZE
141 printf(" -D APR_USE_FLOCK_SERIALIZE\n");
144 #if APR_USE_SYSVSEM_SERIALIZE
145 printf(" -D APR_USE_SYSVSEM_SERIALIZE\n");
148 #if APR_USE_POSIXSEM_SERIALIZE
149 printf(" -D APR_USE_POSIXSEM_SERIALIZE\n");
152 #if APR_USE_FCNTL_SERIALIZE
153 printf(" -D APR_USE_FCNTL_SERIALIZE\n");
156 #if APR_USE_PROC_PTHREAD_SERIALIZE
157 printf(" -D APR_USE_PROC_PTHREAD_SERIALIZE\n");
160 #if APR_USE_PTHREAD_SERIALIZE
161 printf(" -D APR_USE_PTHREAD_SERIALIZE\n");
164 #if APR_PROCESS_LOCK_IS_GLOBAL
165 printf(" -D APR_PROCESS_LOCK_IS_GLOBAL\n");
168 #ifdef SINGLE_LISTEN_UNSERIALIZED_ACCEPT
169 printf(" -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT\n");
172 #if APR_HAS_OTHER_CHILD
173 printf(" -D APR_HAS_OTHER_CHILD\n");
176 #ifdef AP_HAVE_RELIABLE_PIPED_LOGS
177 printf(" -D AP_HAVE_RELIABLE_PIPED_LOGS\n");
181 printf(" -D BUFFERED_LOGS\n");
183 printf(" -D PIPE_BUF=%ld\n",(long)PIPE_BUF);
187 #if APR_CHARSET_EBCDIC
188 printf(" -D APR_CHARSET_EBCDIC\n");
192 printf(" -D APACHE_XLATE\n");
195 #ifdef NEED_HASHBANG_EMUL
196 printf(" -D NEED_HASHBANG_EMUL\n");
200 printf(" -D SHARED_CORE\n");
203 /* This list displays the compiled in default paths: */
205 printf(" -D HTTPD_ROOT=\"" HTTPD_ROOT "\"\n");
209 printf(" -D SUEXEC_BIN=\"" SUEXEC_BIN "\"\n");
212 #if defined(SHARED_CORE) && defined(SHARED_CORE_DIR)
213 printf(" -D SHARED_CORE_DIR=\"" SHARED_CORE_DIR "\"\n");
216 #ifdef DEFAULT_PIDLOG
217 printf(" -D DEFAULT_PIDLOG=\"" DEFAULT_PIDLOG "\"\n");
220 #ifdef DEFAULT_SCOREBOARD
221 printf(" -D DEFAULT_SCOREBOARD=\"" DEFAULT_SCOREBOARD "\"\n");
224 #ifdef DEFAULT_LOCKFILE
225 printf(" -D DEFAULT_LOCKFILE=\"" DEFAULT_LOCKFILE "\"\n");
228 #ifdef DEFAULT_ERRORLOG
229 printf(" -D DEFAULT_ERRORLOG=\"" DEFAULT_ERRORLOG "\"\n");
232 #ifdef TYPES_CONFIG_FILE
233 printf(" -D TYPES_CONFIG_FILE=\"" TYPES_CONFIG_FILE "\"\n");
236 #ifdef SERVER_CONFIG_FILE
237 printf(" -D SERVER_CONFIG_FILE=\"" SERVER_CONFIG_FILE "\"\n");
241 static void destroy_and_exit_process(process_rec *process,
242 int process_exit_value)
244 apr_pool_destroy(process->pool); /* and destroy all descendent pools */
246 exit(process_exit_value);
249 static process_rec *create_process(int argc, const char * const *argv)
251 process_rec *process;
255 stat = apr_pool_create(&cntx, NULL);
256 if (stat != APR_SUCCESS) {
257 /* XXX From the time that we took away the NULL pool->malloc mapping
258 * we have been unable to log here without segfaulting.
260 ap_log_error(APLOG_MARK, APLOG_ERR, stat, NULL,
261 "apr_pool_create() failed to create "
267 apr_pool_tag(cntx, "process");
268 ap_open_stderr_log(cntx);
270 process = apr_palloc(cntx, sizeof(process_rec));
271 process->pool = cntx;
273 apr_pool_create(&process->pconf, process->pool);
274 apr_pool_tag(process->pconf, "pconf");
275 process->argc = argc;
276 process->argv = argv;
277 process->short_name = apr_filename_of_pathname(argv[0]);
281 static void usage(process_rec *process)
283 const char *bin = process->argv[0];
284 char pad[MAX_STRING_LEN];
287 for (i = 0; i < strlen(bin); i++) {
294 ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL ,
295 "Usage: %s [-R directory] [-D name] [-d directory] [-f file]",
298 ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
299 "Usage: %s [-D name] [-d directory] [-f file]", bin);
302 ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
303 " %s [-C \"directive\"] [-c \"directive\"]", pad);
306 ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
307 " %s [-k start|restart|stop|shutdown]", pad);
308 ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
309 " %s [-k install|config|uninstall] [-n service_name]",
313 ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
314 " %s [-v] [-V] [-h] [-l] [-L] [-t] [-T]", pad);
315 ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
319 ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
320 " -R directory : specify an alternate location for "
321 "shared object files");
324 ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
325 " -D name : define a name for use in "
326 "<IfDefine name> directives");
327 ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
328 " -d directory : specify an alternate initial "
330 ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
331 " -f file : specify an alternate ServerConfigFile");
332 ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
333 " -C \"directive\" : process directive before reading "
335 ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
336 " -c \"directive\" : process directive after reading "
340 ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
341 " -n name : set service name and use its "
343 ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
344 " -k start : tell Apache to start");
345 ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
346 " -k restart : tell running Apache to do a graceful "
348 ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
349 " -k stop|shutdown : tell running Apache to shutdown");
350 ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
351 " -k install : install an Apache service");
352 ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
353 " -k config : change startup Options of an Apache "
355 ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
356 " -k uninstall : uninstall an Apache service");
359 ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
360 " -e level : show startup errors of level "
362 ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
363 " -v : show version number");
364 ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
365 " -V : show compile settings");
366 ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
367 " -h : list available command line options "
369 ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
370 " -l : list compiled in modules");
371 ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
372 " -L : list available configuration "
374 ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
375 " -t -D DUMP_VHOSTS : show parsed settings (currently only "
377 ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
378 " -t : run syntax check for config files "
379 "(with docroot check)");
380 ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
381 " -T : run syntax check for config files "
382 "(without docroot check)");
384 destroy_and_exit_process(process, 1);
387 int main(int argc, const char * const argv[])
390 int configtestonly = 0;
391 const char *confname = SERVER_CONFIG_FILE;
392 const char *def_server_root = HTTPD_ROOT;
393 process_rec *process;
394 server_rec *server_conf;
397 apr_pool_t *plog; /* Pool of log streams, reset _after_ each read of conf */
398 apr_pool_t *ptemp; /* Pool for temporary config stuff, reset often */
399 apr_pool_t *pcommands; /* Pool for -D, -C and -c switches */
405 AP_MONCONTROL(0); /* turn of profiling of startup */
409 process = create_process(argc, argv);
410 pglobal = process->pool;
411 pconf = process->pconf;
412 ap_server_argv0 = process->short_name;
414 #if APR_CHARSET_EBCDIC
415 if (ap_init_ebcdic(pglobal) != APR_SUCCESS) {
416 destroy_and_exit_process(process, 1);
420 ap_setup_prelinked_modules(process);
422 apr_pool_create(&pcommands, pglobal);
423 apr_pool_tag(pcommands, "pcommands");
424 ap_server_pre_read_config = apr_array_make(pcommands, 1, sizeof(char *));
425 ap_server_post_read_config = apr_array_make(pcommands, 1, sizeof(char *));
426 ap_server_config_defines = apr_array_make(pcommands, 1, sizeof(char *));
428 ap_run_rewrite_args(process);
430 /* Maintain AP_SERVER_BASEARGS list in http_main.h to allow the MPM
431 * to safely pass on our args from its rewrite_args() handler.
433 apr_getopt_init(&opt, pcommands, process->argc, process->argv);
435 while ((rv = apr_getopt(opt, AP_SERVER_BASEARGS, &c, &optarg))
441 new = (char **)apr_array_push(ap_server_post_read_config);
442 *new = apr_pstrdup(pcommands, optarg);
446 new = (char **)apr_array_push(ap_server_pre_read_config);
447 *new = apr_pstrdup(pcommands, optarg);
451 def_server_root = optarg;
455 new = (char **)apr_array_push(ap_server_config_defines);
456 *new = apr_pstrdup(pcommands, optarg);
460 if (strcasecmp(optarg, "emerg") == 0) {
461 ap_default_loglevel = APLOG_EMERG;
463 else if (strcasecmp(optarg, "alert") == 0) {
464 ap_default_loglevel = APLOG_ALERT;
466 else if (strcasecmp(optarg, "crit") == 0) {
467 ap_default_loglevel = APLOG_CRIT;
469 else if (strncasecmp(optarg, "err", 3) == 0) {
470 ap_default_loglevel = APLOG_ERR;
472 else if (strncasecmp(optarg, "warn", 4) == 0) {
473 ap_default_loglevel = APLOG_WARNING;
475 else if (strcasecmp(optarg, "notice") == 0) {
476 ap_default_loglevel = APLOG_NOTICE;
478 else if (strcasecmp(optarg, "info") == 0) {
479 ap_default_loglevel = APLOG_INFO;
481 else if (strcasecmp(optarg, "debug") == 0) {
482 ap_default_loglevel = APLOG_DEBUG;
490 new = (char **)apr_array_push(ap_server_config_defines);
499 printf("Server version: %s\n", ap_get_server_version());
500 printf("Server built: %s\n", ap_get_server_built());
501 destroy_and_exit_process(process, 0);
504 show_compile_settings();
505 destroy_and_exit_process(process, 0);
509 destroy_and_exit_process(process, 0);
512 ap_show_directives();
513 destroy_and_exit_process(process, 0);
525 /* bad cmdline option? then we die */
530 apr_pool_create(&plog, pglobal);
531 apr_pool_tag(plog, "plog");
532 apr_pool_create(&ptemp, pconf);
533 apr_pool_tag(ptemp, "ptemp");
535 /* Note that we preflight the config file once
536 * before reading it _again_ in the main loop.
537 * This allows things, log files configuration
538 * for example, to settle down.
541 ap_server_root = def_server_root;
542 server_conf = ap_read_config(process, ptemp, confname, &ap_conftree);
543 if (ap_run_pre_config(pconf, plog, ptemp) != OK) {
544 ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR| APLOG_NOERRNO, 0,
545 NULL, "Pre-configuration failed\n");
546 destroy_and_exit_process(process, 1);
549 ap_process_config_tree(server_conf, ap_conftree, process->pconf, ptemp);
550 ap_fixup_virtual_hosts(pconf, server_conf);
551 ap_fini_vhost_config(pconf, server_conf);
553 if (configtestonly) {
554 ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
556 destroy_and_exit_process(process, 0);
559 apr_pool_clear(plog);
561 /* It is assumed that if you are going to fail the open_logs phase, then
562 * you will print out your own message that explains what has gone wrong.
563 * The server doesn't need to do that for you.
565 if ( ap_run_open_logs(pconf, plog, ptemp, server_conf) != OK) {
566 destroy_and_exit_process(process, 1);
569 if ( ap_run_post_config(pconf, plog, ptemp, server_conf) != OK) {
570 ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR| APLOG_NOERRNO, 0,
571 NULL, "Configuration Failed\n");
572 destroy_and_exit_process(process, 1);
575 apr_pool_destroy(ptemp);
578 apr_hook_deregister_all();
579 apr_pool_clear(pconf);
581 for (mod = ap_prelinked_modules; *mod != NULL; mod++) {
582 ap_register_hooks(*mod, pconf);
585 /* This is a hack until we finish the code so that it only reads
586 * the config file once and just operates on the tree already in
590 apr_pool_create(&ptemp, pconf);
591 apr_pool_tag(ptemp, "ptemp");
592 ap_server_root = def_server_root;
593 server_conf = ap_read_config(process, ptemp, confname, &ap_conftree);
594 if (ap_run_pre_config(pconf, plog, ptemp) != OK) {
595 ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR| APLOG_NOERRNO,
596 0, NULL, "Pre-configuration failed\n");
597 destroy_and_exit_process(process, 1);
600 ap_process_config_tree(server_conf, ap_conftree, process->pconf, ptemp);
601 ap_fixup_virtual_hosts(pconf, server_conf);
602 ap_fini_vhost_config(pconf, server_conf);
604 apr_pool_clear(plog);
605 if (ap_run_open_logs(pconf, plog, ptemp, server_conf) != OK) {
606 ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR| APLOG_NOERRNO,
607 0, NULL, "Unable to open logs\n");
608 destroy_and_exit_process(process, 1);
611 if (ap_run_post_config(pconf, plog, ptemp, server_conf) != OK) {
612 ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR | APLOG_NOERRNO,
613 0, NULL, "Configuration Failed\n");
614 destroy_and_exit_process(process, 1);
617 apr_pool_destroy(ptemp);
618 apr_pool_lock(pconf, 1);
620 ap_run_optional_fn_retrieve();
622 if (ap_mpm_run(pconf, plog, server_conf))
625 apr_pool_lock(pconf, 0);
628 apr_pool_lock(pconf, 0);
629 destroy_and_exit_process(process, 0);
631 return 0; /* Supress compiler warning. */
634 /* force Expat to be linked into the server executable */
635 #if defined(USE_EXPAT) && !defined(SHARED_CORE_BOOTSTRAP)
636 #include "xmlparse.h"
637 const XML_LChar *suck_in_expat(void);
638 const XML_LChar *suck_in_expat(void)
640 return XML_ErrorString(XML_ERROR_NONE);
642 #endif /* USE_EXPAT */
644 #ifndef SHARED_CORE_BOOTSTRAP
646 * Force apr_password_validate() into the image so that modules like
647 * mod_auth can use it even if they're dynamically loaded.
649 void suck_in_apr_password_validate(void);
650 void suck_in_apr_password_validate(void)
652 apr_password_validate("a", "b");
656 #ifdef AP_USING_AUTOCONF
657 /* This ugly little hack pulls any function referenced in exports.c into
658 * the web server. exports.c is generated during the build, and it
659 * has all of the APR functions specified by the apr/apr.exports and
660 * apr-util/aprutil.exports files.
662 const void *suck_in_APR(void);
663 const void *suck_in_APR(void)
665 extern const void *ap_ugly_hack;