1 /* Copyright 1999-2004 The Apache Software Foundation
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
7 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include "apr_strings.h"
18 #include "apr_getopt.h"
19 #include "apr_general.h"
23 #define APR_WANT_STDIO
24 #define APR_WANT_STRFUNC
28 #include "ap_config.h"
30 #include "http_main.h"
32 #include "http_config.h"
33 #include "http_vhost.h"
35 #include "util_ebcdic.h"
37 #include "mpm_common.h"
39 /* WARNING: Win32 binds http_main.c dynamically to the server. Please place
40 * extern functions and global data in another appropriate module.
42 * Most significant main() global data can be found in http_config.c
45 static void show_mpm_settings(void)
50 printf("Server MPM: %s\n", ap_show_mpm());
52 retval = ap_mpm_query(AP_MPMQ_IS_THREADED, &mpm_query_info);
54 if (retval == APR_SUCCESS) {
55 printf(" threaded: ");
57 if (mpm_query_info == AP_MPMQ_DYNAMIC) {
58 printf("yes (variable thread count)\n");
60 else if (mpm_query_info == AP_MPMQ_STATIC) {
61 printf("yes (fixed thread count)\n");
68 retval = ap_mpm_query(AP_MPMQ_IS_FORKED, &mpm_query_info);
70 if (retval == APR_SUCCESS) {
73 if (mpm_query_info == AP_MPMQ_DYNAMIC) {
74 printf("yes (variable process count)\n");
76 else if (mpm_query_info == AP_MPMQ_STATIC) {
77 printf("yes (fixed process count)\n");
85 static void show_compile_settings(void)
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);
92 /* sizeof(foo) is long on some platforms so we might as well
93 * make it long everywhere to keep the printf format
96 printf("Architecture: %ld-bit\n", 8 * (long)sizeof(void *));
100 printf("Server compiled with....\n");
101 #ifdef BIG_SECURITY_HOLE
102 printf(" -D BIG_SECURITY_HOLE\n");
105 #ifdef SECURITY_HOLE_PASS_AUTHORIZATION
106 printf(" -D SECURITY_HOLE_PASS_AUTHORIZATION\n");
110 printf(" -D HAVE_SHMGET\n");
113 #if APR_FILE_BASED_SHM
114 printf(" -D APR_FILE_BASED_SHM\n");
118 printf(" -D APR_HAS_SENDFILE\n");
122 printf(" -D APR_HAS_MMAP\n");
126 printf(" -D NO_WRITEV\n");
130 printf(" -D NO_LINGCLOSE\n");
134 printf(" -D APR_HAVE_IPV6 (IPv4-mapped addresses ");
135 #ifdef AP_ENABLE_V4_MAPPED
136 printf("enabled)\n");
138 printf("disabled)\n");
142 #if APR_USE_FLOCK_SERIALIZE
143 printf(" -D APR_USE_FLOCK_SERIALIZE\n");
146 #if APR_USE_SYSVSEM_SERIALIZE
147 printf(" -D APR_USE_SYSVSEM_SERIALIZE\n");
150 #if APR_USE_POSIXSEM_SERIALIZE
151 printf(" -D APR_USE_POSIXSEM_SERIALIZE\n");
154 #if APR_USE_FCNTL_SERIALIZE
155 printf(" -D APR_USE_FCNTL_SERIALIZE\n");
158 #if APR_USE_PROC_PTHREAD_SERIALIZE
159 printf(" -D APR_USE_PROC_PTHREAD_SERIALIZE\n");
162 #if APR_USE_PTHREAD_SERIALIZE
163 printf(" -D APR_USE_PTHREAD_SERIALIZE\n");
166 #if APR_PROCESS_LOCK_IS_GLOBAL
167 printf(" -D APR_PROCESS_LOCK_IS_GLOBAL\n");
170 #ifdef SINGLE_LISTEN_UNSERIALIZED_ACCEPT
171 printf(" -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT\n");
174 #if APR_HAS_OTHER_CHILD
175 printf(" -D APR_HAS_OTHER_CHILD\n");
178 #ifdef AP_HAVE_RELIABLE_PIPED_LOGS
179 printf(" -D AP_HAVE_RELIABLE_PIPED_LOGS\n");
183 printf(" -D BUFFERED_LOGS\n");
185 printf(" -D PIPE_BUF=%ld\n",(long)PIPE_BUF);
189 #if APR_CHARSET_EBCDIC
190 printf(" -D APR_CHARSET_EBCDIC\n");
193 #ifdef NEED_HASHBANG_EMUL
194 printf(" -D NEED_HASHBANG_EMUL\n");
198 printf(" -D SHARED_CORE\n");
201 /* This list displays the compiled in default paths: */
203 printf(" -D HTTPD_ROOT=\"" HTTPD_ROOT "\"\n");
207 printf(" -D SUEXEC_BIN=\"" SUEXEC_BIN "\"\n");
210 #if defined(SHARED_CORE) && defined(SHARED_CORE_DIR)
211 printf(" -D SHARED_CORE_DIR=\"" SHARED_CORE_DIR "\"\n");
214 #ifdef DEFAULT_PIDLOG
215 printf(" -D DEFAULT_PIDLOG=\"" DEFAULT_PIDLOG "\"\n");
218 #ifdef DEFAULT_SCOREBOARD
219 printf(" -D DEFAULT_SCOREBOARD=\"" DEFAULT_SCOREBOARD "\"\n");
222 #ifdef DEFAULT_LOCKFILE
223 printf(" -D DEFAULT_LOCKFILE=\"" DEFAULT_LOCKFILE "\"\n");
226 #ifdef DEFAULT_ERRORLOG
227 printf(" -D DEFAULT_ERRORLOG=\"" DEFAULT_ERRORLOG "\"\n");
230 #ifdef AP_TYPES_CONFIG_FILE
231 printf(" -D AP_TYPES_CONFIG_FILE=\"" AP_TYPES_CONFIG_FILE "\"\n");
234 #ifdef SERVER_CONFIG_FILE
235 printf(" -D SERVER_CONFIG_FILE=\"" SERVER_CONFIG_FILE "\"\n");
239 static void destroy_and_exit_process(process_rec *process,
240 int process_exit_value)
242 apr_pool_destroy(process->pool); /* and destroy all descendent pools */
244 exit(process_exit_value);
247 static process_rec *create_process(int argc, const char * const *argv)
249 process_rec *process;
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.
258 ap_log_error(APLOG_MARK, APLOG_ERR, stat, NULL,
259 "apr_pool_create() failed to create "
265 apr_pool_tag(cntx, "process");
266 ap_open_stderr_log(cntx);
268 process = apr_palloc(cntx, sizeof(process_rec));
269 process->pool = cntx;
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]);
279 static void usage(process_rec *process)
281 const char *bin = process->argv[0];
282 char pad[MAX_STRING_LEN];
285 for (i = 0; i < strlen(bin); i++) {
292 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL ,
293 "Usage: %s [-R directory] [-D name] [-d directory] [-f file]",
296 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
297 "Usage: %s [-D name] [-d directory] [-f file]", bin);
300 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
301 " %s [-C \"directive\"] [-c \"directive\"]", pad);
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]",
310 #ifdef AP_MPM_WANT_SIGNAL_SERVER
311 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
312 " %s [-k start|restart|graceful|stop]",
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,
321 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
322 " -R directory : specify an alternate location for "
323 "shared object files");
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 "
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 "
337 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
338 " -c \"directive\" : process directive after reading "
342 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
343 " -n name : set screen name");
346 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
347 " -n name : set service name and use its "
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 "
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 "
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");
367 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
368 " -e level : show startup errors of level "
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 "
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 "
384 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
385 " -t -D DUMP_VHOSTS : show parsed settings (currently only "
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");
392 destroy_and_exit_process(process, 1);
395 int main(int argc, const char * const argv[])
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;
403 process_rec *process;
404 server_rec *server_conf;
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 */
414 APR_OPTIONAL_FN_TYPE(ap_signal_server) *signal_server;
416 AP_MONCONTROL(0); /* turn off profiling of startup */
418 apr_app_initialize(&argc, &argv, NULL);
420 process = create_process(argc, argv);
421 pglobal = process->pool;
422 pconf = process->pconf;
423 ap_server_argv0 = process->short_name;
425 #if APR_CHARSET_EBCDIC
426 if (ap_init_ebcdic(pglobal) != APR_SUCCESS) {
427 destroy_and_exit_process(process, 1);
431 apr_pool_create(&pcommands, pglobal);
432 apr_pool_tag(pcommands, "pcommands");
433 ap_server_pre_read_config = apr_array_make(pcommands, 1, sizeof(char *));
434 ap_server_post_read_config = apr_array_make(pcommands, 1, sizeof(char *));
435 ap_server_config_defines = apr_array_make(pcommands, 1, sizeof(char *));
437 error = ap_setup_prelinked_modules(process);
439 ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_EMERG, 0, NULL, "%s: %s",
440 ap_server_argv0, error);
441 destroy_and_exit_process(process, 1);
444 ap_run_rewrite_args(process);
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.
449 apr_getopt_init(&opt, pcommands, process->argc, process->argv);
451 while ((rv = apr_getopt(opt, AP_SERVER_BASEARGS, &c, &optarg))
457 new = (char **)apr_array_push(ap_server_post_read_config);
458 *new = apr_pstrdup(pcommands, optarg);
462 new = (char **)apr_array_push(ap_server_pre_read_config);
463 *new = apr_pstrdup(pcommands, optarg);
467 def_server_root = optarg;
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)
479 if (strcasecmp(optarg, "emerg") == 0) {
480 ap_default_loglevel = APLOG_EMERG;
482 else if (strcasecmp(optarg, "alert") == 0) {
483 ap_default_loglevel = APLOG_ALERT;
485 else if (strcasecmp(optarg, "crit") == 0) {
486 ap_default_loglevel = APLOG_CRIT;
488 else if (strncasecmp(optarg, "err", 3) == 0) {
489 ap_default_loglevel = APLOG_ERR;
491 else if (strncasecmp(optarg, "warn", 4) == 0) {
492 ap_default_loglevel = APLOG_WARNING;
494 else if (strcasecmp(optarg, "notice") == 0) {
495 ap_default_loglevel = APLOG_NOTICE;
497 else if (strcasecmp(optarg, "info") == 0) {
498 ap_default_loglevel = APLOG_INFO;
500 else if (strcasecmp(optarg, "debug") == 0) {
501 ap_default_loglevel = APLOG_DEBUG;
509 temp_error_log = apr_pstrdup(process->pool, optarg);
513 new = (char **)apr_array_push(ap_server_config_defines);
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);
527 show_compile_settings();
528 destroy_and_exit_process(process, 0);
532 destroy_and_exit_process(process, 0);
535 ap_show_directives();
536 destroy_and_exit_process(process, 0);
544 new = (char **)apr_array_push(ap_server_config_defines);
545 *new = "DUMP_VHOSTS";
554 /* bad cmdline option? then we die */
555 if (rv != APR_EOF || opt->ind < opt->argc) {
559 apr_pool_create(&plog, pglobal);
560 apr_pool_tag(plog, "plog");
561 apr_pool_create(&ptemp, pconf);
562 apr_pool_tag(ptemp, "ptemp");
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.
570 ap_server_root = def_server_root;
571 if (temp_error_log) {
572 ap_replace_stderr_log(process->pool, temp_error_log);
574 server_conf = ap_read_config(process, ptemp, confname, &ap_conftree);
576 destroy_and_exit_process(process, 1);
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);
585 rv = ap_process_config_tree(server_conf, ap_conftree,
586 process->pconf, ptemp);
588 ap_fixup_virtual_hosts(pconf, server_conf);
589 ap_fini_vhost_config(pconf, server_conf);
591 if (configtestonly) {
592 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, "Syntax OK");
593 destroy_and_exit_process(process, 0);
597 signal_server = APR_RETRIEVE_OPTIONAL_FN(ap_signal_server);
601 if (signal_server(&exit_status, pconf) != 0) {
602 destroy_and_exit_process(process, exit_status);
606 /* If our config failed, deal with that here. */
608 destroy_and_exit_process(process, 1);
611 apr_pool_clear(plog);
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);
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);
625 apr_pool_destroy(ptemp);
628 apr_hook_deregister_all();
629 apr_pool_clear(pconf);
631 for (mod = ap_prelinked_modules; *mod != NULL; mod++) {
632 ap_register_hooks(*mod, pconf);
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
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);
645 destroy_and_exit_process(process, 1);
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);
654 if (ap_process_config_tree(server_conf, ap_conftree, process->pconf,
656 destroy_and_exit_process(process, 1);
658 ap_fixup_virtual_hosts(pconf, server_conf);
659 ap_fini_vhost_config(pconf, server_conf);
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);
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);
674 apr_pool_destroy(ptemp);
675 apr_pool_lock(pconf, 1);
677 ap_run_optional_fn_retrieve();
679 if (ap_mpm_run(pconf, plog, server_conf))
682 apr_pool_lock(pconf, 0);
685 apr_pool_lock(pconf, 0);
686 destroy_and_exit_process(process, 0);
688 return 0; /* Termination 'ok' */
691 #ifndef SHARED_CORE_BOOTSTRAP
693 * Force apr_password_validate() into the image so that modules like
694 * mod_auth can use it even if they're dynamically loaded.
696 void suck_in_apr_password_validate(void);
697 void suck_in_apr_password_validate(void)
699 apr_password_validate("a", "b");
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.
709 const void *suck_in_APR(void);
710 const void *suck_in_APR(void)
712 extern const void *ap_ugly_hack;