1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include "apr_strings.h"
19 #include "apr_getopt.h"
20 #include "apr_general.h"
24 #include "apr_version.h"
25 #include "apu_version.h"
27 #define APR_WANT_STDIO
28 #define APR_WANT_STRFUNC
32 #include "ap_config.h"
34 #include "http_main.h"
36 #include "http_config.h"
37 #include "http_vhost.h"
39 #include "util_ebcdic.h"
41 #include "mpm_common.h"
43 /* WARNING: Win32 binds http_main.c dynamically to the server. Please place
44 * extern functions and global data in another appropriate module.
46 * Most significant main() global data can be found in http_config.c
49 /* XXX - We should be able to grab the per-MPM settings here too */
50 static void show_compile_settings(void)
52 printf("Server version: %s\n", ap_get_server_version());
53 printf("Server built: %s\n", ap_get_server_built());
54 printf("Server's Module Magic Number: %u:%u\n",
55 MODULE_MAGIC_NUMBER_MAJOR, MODULE_MAGIC_NUMBER_MINOR);
56 printf("Server loaded: APR %s, APR-UTIL %s\n",
57 apr_version_string(), apu_version_string());
58 printf("Compiled using: APR %s, APR-UTIL %s\n",
59 APR_VERSION_STRING, APU_VERSION_STRING);
60 /* sizeof(foo) is long on some platforms so we might as well
61 * make it long everywhere to keep the printf format
64 printf("Architecture: %ld-bit\n", 8 * (long)sizeof(void *));
65 printf("Server compiled with....\n");
66 #ifdef BIG_SECURITY_HOLE
67 printf(" -D BIG_SECURITY_HOLE\n");
70 #ifdef SECURITY_HOLE_PASS_AUTHORIZATION
71 printf(" -D SECURITY_HOLE_PASS_AUTHORIZATION\n");
75 printf(" -D APACHE_MPM_DIR=\"%s\"\n", APACHE_MPM_DIR);
79 printf(" -D HAVE_SHMGET\n");
82 #if APR_FILE_BASED_SHM
83 printf(" -D APR_FILE_BASED_SHM\n");
87 printf(" -D APR_HAS_SENDFILE\n");
91 printf(" -D APR_HAS_MMAP\n");
95 printf(" -D NO_WRITEV\n");
99 printf(" -D NO_LINGCLOSE\n");
103 printf(" -D APR_HAVE_IPV6 (IPv4-mapped addresses ");
104 #ifdef AP_ENABLE_V4_MAPPED
105 printf("enabled)\n");
107 printf("disabled)\n");
111 #if APR_USE_FLOCK_SERIALIZE
112 printf(" -D APR_USE_FLOCK_SERIALIZE\n");
115 #if APR_USE_SYSVSEM_SERIALIZE
116 printf(" -D APR_USE_SYSVSEM_SERIALIZE\n");
119 #if APR_USE_POSIXSEM_SERIALIZE
120 printf(" -D APR_USE_POSIXSEM_SERIALIZE\n");
123 #if APR_USE_FCNTL_SERIALIZE
124 printf(" -D APR_USE_FCNTL_SERIALIZE\n");
127 #if APR_USE_PROC_PTHREAD_SERIALIZE
128 printf(" -D APR_USE_PROC_PTHREAD_SERIALIZE\n");
131 #if APR_USE_PTHREAD_SERIALIZE
132 printf(" -D APR_USE_PTHREAD_SERIALIZE\n");
135 #if APR_PROCESS_LOCK_IS_GLOBAL
136 printf(" -D APR_PROCESS_LOCK_IS_GLOBAL\n");
139 #ifdef SINGLE_LISTEN_UNSERIALIZED_ACCEPT
140 printf(" -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT\n");
143 #if APR_HAS_OTHER_CHILD
144 printf(" -D APR_HAS_OTHER_CHILD\n");
147 #ifdef AP_HAVE_RELIABLE_PIPED_LOGS
148 printf(" -D AP_HAVE_RELIABLE_PIPED_LOGS\n");
152 printf(" -D BUFFERED_LOGS\n");
154 printf(" -D PIPE_BUF=%ld\n",(long)PIPE_BUF);
158 #if APR_CHARSET_EBCDIC
159 printf(" -D APR_CHARSET_EBCDIC\n");
163 printf(" -D APACHE_XLATE\n");
166 #ifdef NEED_HASHBANG_EMUL
167 printf(" -D NEED_HASHBANG_EMUL\n");
171 printf(" -D SHARED_CORE\n");
174 /* This list displays the compiled in default paths: */
176 printf(" -D HTTPD_ROOT=\"" HTTPD_ROOT "\"\n");
180 printf(" -D SUEXEC_BIN=\"" SUEXEC_BIN "\"\n");
183 #if defined(SHARED_CORE) && defined(SHARED_CORE_DIR)
184 printf(" -D SHARED_CORE_DIR=\"" SHARED_CORE_DIR "\"\n");
187 #ifdef DEFAULT_PIDLOG
188 printf(" -D DEFAULT_PIDLOG=\"" DEFAULT_PIDLOG "\"\n");
191 #ifdef DEFAULT_SCOREBOARD
192 printf(" -D DEFAULT_SCOREBOARD=\"" DEFAULT_SCOREBOARD "\"\n");
195 #ifdef DEFAULT_LOCKFILE
196 printf(" -D DEFAULT_LOCKFILE=\"" DEFAULT_LOCKFILE "\"\n");
199 #ifdef DEFAULT_ERRORLOG
200 printf(" -D DEFAULT_ERRORLOG=\"" DEFAULT_ERRORLOG "\"\n");
203 #ifdef AP_TYPES_CONFIG_FILE
204 printf(" -D AP_TYPES_CONFIG_FILE=\"" AP_TYPES_CONFIG_FILE "\"\n");
207 #ifdef SERVER_CONFIG_FILE
208 printf(" -D SERVER_CONFIG_FILE=\"" SERVER_CONFIG_FILE "\"\n");
212 static void destroy_and_exit_process(process_rec *process,
213 int process_exit_value)
215 apr_pool_destroy(process->pool); /* and destroy all descendent pools */
217 exit(process_exit_value);
220 static process_rec *init_process(int *argc, const char * const * *argv)
222 process_rec *process;
225 const char *failed = "apr_app_initialize()";
227 stat = apr_app_initialize(argc, argv, NULL);
228 if (stat == APR_SUCCESS) {
229 failed = "apr_pool_create()";
230 stat = apr_pool_create(&cntx, NULL);
233 if (stat != APR_SUCCESS) {
234 /* For all intents and purposes, this is impossibly unlikely,
235 * but APR doesn't exist yet, we can't use it for reporting
236 * these earliest two failures;
238 char ctimebuff[APR_CTIME_LEN];
239 apr_ctime(ctimebuff, apr_time_now());
240 fprintf(stderr, "[%s] [crit] (%d) %s: %s failed "
241 "to initial context, exiting\n",
242 ctimebuff, stat, (*argv)[0], failed);
247 apr_pool_tag(cntx, "process");
248 ap_open_stderr_log(cntx);
250 /* Now we have initialized apr and our logger, no more
251 * exceptional error reporting required for the lifetime
252 * of this server process.
255 process = apr_palloc(cntx, sizeof(process_rec));
256 process->pool = cntx;
258 apr_pool_create(&process->pconf, process->pool);
259 apr_pool_tag(process->pconf, "pconf");
260 process->argc = *argc;
261 process->argv = *argv;
262 process->short_name = apr_filepath_name_get((*argv)[0]);
266 static void usage(process_rec *process)
268 const char *bin = process->argv[0];
269 char pad[MAX_STRING_LEN];
272 for (i = 0; i < strlen(bin); i++) {
279 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL ,
280 "Usage: %s [-R directory] [-D name] [-d directory] [-f file]",
283 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
284 "Usage: %s [-D name] [-d directory] [-f file]", bin);
287 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
288 " %s [-C \"directive\"] [-c \"directive\"]", pad);
291 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
292 " %s [-w] [-k start|restart|stop|shutdown]", pad);
293 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
294 " %s [-k install|config|uninstall] [-n service_name]",
297 #ifdef AP_MPM_WANT_SIGNAL_SERVER
298 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
299 " %s [-k start|restart|graceful|stop]",
302 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
303 " %s [-v] [-V] [-h] [-l] [-L] [-t] [-S]", pad);
304 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
308 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
309 " -R directory : specify an alternate location for "
310 "shared object files");
313 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
314 " -D name : define a name for use in "
315 "<IfDefine name> directives");
316 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
317 " -d directory : specify an alternate initial "
319 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
320 " -f file : specify an alternate ServerConfigFile");
321 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
322 " -C \"directive\" : process directive before reading "
324 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
325 " -c \"directive\" : process directive after reading "
329 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
330 " -n name : set screen name");
333 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
334 " -n name : set service name and use its "
336 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
337 " -k start : tell Apache to start");
338 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
339 " -k restart : tell running Apache to do a graceful "
341 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
342 " -k stop|shutdown : tell running Apache to shutdown");
343 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
344 " -k install : install an Apache service");
345 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
346 " -k config : change startup Options of an Apache "
348 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
349 " -k uninstall : uninstall an Apache service");
350 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
351 " -w : hold open the console window on error");
354 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
355 " -e level : show startup errors of level "
357 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
358 " -E file : log startup errors to file");
359 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
360 " -v : show version number");
361 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
362 " -V : show compile settings");
363 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
364 " -h : list available command line options "
366 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
367 " -l : list compiled in modules");
368 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
369 " -L : list available configuration "
371 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
372 " -t -D DUMP_VHOSTS : show parsed settings (currently only "
374 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
375 " -S : a synonym for -t -D DUMP_VHOSTS");
376 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
377 " -t : run syntax check for config files");
379 destroy_and_exit_process(process, 1);
382 int main(int argc, const char * const argv[])
385 int configtestonly = 0;
386 const char *confname = SERVER_CONFIG_FILE;
387 const char *def_server_root = HTTPD_ROOT;
388 const char *temp_error_log = NULL;
389 process_rec *process;
390 server_rec *server_conf;
393 apr_pool_t *plog; /* Pool of log streams, reset _after_ each read of conf */
394 apr_pool_t *ptemp; /* Pool for temporary config stuff, reset often */
395 apr_pool_t *pcommands; /* Pool for -D, -C and -c switches */
400 APR_OPTIONAL_FN_TYPE(ap_signal_server) *signal_server;
402 AP_MONCONTROL(0); /* turn off profiling of startup */
404 process = init_process(&argc, &argv);
405 pglobal = process->pool;
406 pconf = process->pconf;
407 ap_server_argv0 = process->short_name;
409 #if APR_CHARSET_EBCDIC
410 if (ap_init_ebcdic(pglobal) != APR_SUCCESS) {
411 destroy_and_exit_process(process, 1);
415 apr_pool_create(&pcommands, pglobal);
416 apr_pool_tag(pcommands, "pcommands");
417 ap_server_pre_read_config = apr_array_make(pcommands, 1, sizeof(char *));
418 ap_server_post_read_config = apr_array_make(pcommands, 1, sizeof(char *));
419 ap_server_config_defines = apr_array_make(pcommands, 1, sizeof(char *));
421 ap_setup_prelinked_modules(process);
423 ap_run_rewrite_args(process);
425 /* Maintain AP_SERVER_BASEARGS list in http_main.h to allow the MPM
426 * to safely pass on our args from its rewrite_args() handler.
428 apr_getopt_init(&opt, pcommands, process->argc, process->argv);
430 while ((rv = apr_getopt(opt, AP_SERVER_BASEARGS, &c, &optarg))
436 new = (char **)apr_array_push(ap_server_post_read_config);
437 *new = apr_pstrdup(pcommands, optarg);
441 new = (char **)apr_array_push(ap_server_pre_read_config);
442 *new = apr_pstrdup(pcommands, optarg);
446 def_server_root = optarg;
450 new = (char **)apr_array_push(ap_server_config_defines);
451 *new = apr_pstrdup(pcommands, optarg);
455 if (strcasecmp(optarg, "emerg") == 0) {
456 ap_default_loglevel = APLOG_EMERG;
458 else if (strcasecmp(optarg, "alert") == 0) {
459 ap_default_loglevel = APLOG_ALERT;
461 else if (strcasecmp(optarg, "crit") == 0) {
462 ap_default_loglevel = APLOG_CRIT;
464 else if (strncasecmp(optarg, "err", 3) == 0) {
465 ap_default_loglevel = APLOG_ERR;
467 else if (strncasecmp(optarg, "warn", 4) == 0) {
468 ap_default_loglevel = APLOG_WARNING;
470 else if (strcasecmp(optarg, "notice") == 0) {
471 ap_default_loglevel = APLOG_NOTICE;
473 else if (strcasecmp(optarg, "info") == 0) {
474 ap_default_loglevel = APLOG_INFO;
476 else if (strcasecmp(optarg, "debug") == 0) {
477 ap_default_loglevel = APLOG_DEBUG;
485 temp_error_log = apr_pstrdup(process->pool, optarg);
489 new = (char **)apr_array_push(ap_server_config_defines);
498 printf("Server version: %s\n", ap_get_server_version());
499 printf("Server built: %s\n", ap_get_server_built());
500 destroy_and_exit_process(process, 0);
503 show_compile_settings();
504 destroy_and_exit_process(process, 0);
508 destroy_and_exit_process(process, 0);
511 ap_show_directives();
512 destroy_and_exit_process(process, 0);
520 new = (char **)apr_array_push(ap_server_config_defines);
521 *new = "DUMP_VHOSTS";
530 /* bad cmdline option? then we die */
531 if (rv != APR_EOF || opt->ind < opt->argc) {
535 apr_pool_create(&plog, pglobal);
536 apr_pool_tag(plog, "plog");
537 apr_pool_create(&ptemp, pconf);
538 apr_pool_tag(ptemp, "ptemp");
540 /* Note that we preflight the config file once
541 * before reading it _again_ in the main loop.
542 * This allows things, log files configuration
543 * for example, to settle down.
546 ap_server_root = def_server_root;
547 if (temp_error_log) {
548 ap_replace_stderr_log(process->pool, temp_error_log);
550 server_conf = ap_read_config(process, ptemp, confname, &ap_conftree);
551 if (ap_run_pre_config(pconf, plog, ptemp) != OK) {
552 ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR, 0,
553 NULL, "Pre-configuration failed");
554 destroy_and_exit_process(process, 1);
557 ap_process_config_tree(server_conf, ap_conftree, process->pconf, ptemp);
558 ap_fixup_virtual_hosts(pconf, server_conf);
559 ap_fini_vhost_config(pconf, server_conf);
561 if (configtestonly) {
562 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, "Syntax OK");
563 destroy_and_exit_process(process, 0);
566 signal_server = APR_RETRIEVE_OPTIONAL_FN(ap_signal_server);
570 if (signal_server(&exit_status, pconf) != 0) {
571 destroy_and_exit_process(process, exit_status);
575 apr_pool_clear(plog);
577 if ( ap_run_open_logs(pconf, plog, ptemp, server_conf) != OK) {
578 ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR,
579 0, NULL, "Unable to open logs");
580 destroy_and_exit_process(process, 1);
583 if ( ap_run_post_config(pconf, plog, ptemp, server_conf) != OK) {
584 ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR, 0,
585 NULL, "Configuration Failed");
586 destroy_and_exit_process(process, 1);
589 apr_pool_destroy(ptemp);
592 apr_hook_deregister_all();
593 apr_pool_clear(pconf);
595 for (mod = ap_prelinked_modules; *mod != NULL; mod++) {
596 ap_register_hooks(*mod, pconf);
599 /* This is a hack until we finish the code so that it only reads
600 * the config file once and just operates on the tree already in
604 apr_pool_create(&ptemp, pconf);
605 apr_pool_tag(ptemp, "ptemp");
606 ap_server_root = def_server_root;
607 server_conf = ap_read_config(process, ptemp, confname, &ap_conftree);
608 if (ap_run_pre_config(pconf, plog, ptemp) != OK) {
609 ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR,
610 0, NULL, "Pre-configuration failed");
611 destroy_and_exit_process(process, 1);
614 ap_process_config_tree(server_conf, ap_conftree, process->pconf, ptemp);
615 ap_fixup_virtual_hosts(pconf, server_conf);
616 ap_fini_vhost_config(pconf, server_conf);
618 apr_pool_clear(plog);
619 if (ap_run_open_logs(pconf, plog, ptemp, server_conf) != OK) {
620 ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR,
621 0, NULL, "Unable to open logs");
622 destroy_and_exit_process(process, 1);
625 if (ap_run_post_config(pconf, plog, ptemp, server_conf) != OK) {
626 ap_log_error(APLOG_MARK, APLOG_STARTUP |APLOG_ERR,
627 0, NULL, "Configuration Failed");
628 destroy_and_exit_process(process, 1);
631 apr_pool_destroy(ptemp);
632 apr_pool_lock(pconf, 1);
634 ap_run_optional_fn_retrieve();
636 if (ap_mpm_run(pconf, plog, server_conf))
639 apr_pool_lock(pconf, 0);
642 apr_pool_lock(pconf, 0);
643 destroy_and_exit_process(process, 0);
645 return 0; /* Termination 'ok' */
648 /* force Expat to be linked into the server executable */
649 #if defined(USE_EXPAT) && !defined(SHARED_CORE_BOOTSTRAP)
650 #include "xmlparse.h"
651 const XML_LChar *suck_in_expat(void);
652 const XML_LChar *suck_in_expat(void)
654 return XML_ErrorString(XML_ERROR_NONE);
656 #endif /* USE_EXPAT */
658 #ifndef SHARED_CORE_BOOTSTRAP
660 * Force apr_password_validate() into the image so that modules like
661 * mod_auth can use it even if they're dynamically loaded.
663 void suck_in_apr_password_validate(void);
664 void suck_in_apr_password_validate(void)
666 apr_password_validate("a", "b");
670 #ifdef AP_USING_AUTOCONF
671 /* This ugly little hack pulls any function referenced in exports.c into
672 * the web server. exports.c is generated during the build, and it
673 * has all of the APR functions specified by the apr/apr.exports and
674 * apr-util/aprutil.exports files.
676 const void *suck_in_APR(void);
677 const void *suck_in_APR(void)
679 extern const void *ap_ugly_hack;