]> granicus.if.org Git - apache/blob - server/main.c
Use APR's getopt.
[apache] / server / main.c
1 /* ====================================================================
2  * Copyright (c) 1995-1999 The Apache Group.  All rights reserved.
3  * 
4  * Redistribution and use in source and binary forms, with or without 
5  * modification, are permitted provided that the following conditions 
6  * are met: 
7  * 
8  * 1. Redistributions of source code must retain the above copyright 
9  *    notice, this list of conditions and the following disclaimer.  
10  * 
11  * 2. Redistributions in binary form must reproduce the above copyright 
12  *    notice, this list of conditions and the following disclaimer in 
13  *    the documentation and/or other materials provided with the 
14  *    distribution. 
15  * 
16  * 3. All advertising materials mentioning features or use of this 
17  *    software must display the following acknowledgment: 
18  *    "This product includes software developed by the Apache Group 
19  *    for use in the Apache HTTP server project (http://www.apache.org/)." 
20  * 
21  * 4. The names "Apache Server" and "Apache Group" must not be used to 
22  *    endorse or promote products derived from this software without 
23  *    prior written permission. For written permission, please contact 
24  *    apache@apache.org. 
25  * 
26  * 5. Products derived from this software may not be called "Apache" 
27  *    nor may "Apache" appear in their names without prior written 
28  *    permission of the Apache Group. 
29  * 
30  * 6. Redistributions of any form whatsoever must retain the following 
31  *    acknowledgment: 
32  *    "This product includes software developed by the Apache Group 
33  *    for use in the Apache HTTP server project (http://www.apache.org/)." 
34  * 
35  * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY 
36  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
37  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
38  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR 
39  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
40  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
41  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
42  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
43  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
44  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
45  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
46  * OF THE POSSIBILITY OF SUCH DAMAGE. 
47  * ==================================================================== 
48  * 
49  * This software consists of voluntary contributions made by many 
50  * individuals on behalf of the Apache Group and was originally based 
51  * on public domain software written at the National Center for 
52  * Supercomputing Applications, University of Illinois, Urbana-Champaign. 
53  * For more information on the Apache Group and the Apache HTTP server 
54  * project, please see <http://www.apache.org/>. 
55  * 
56  */ 
57
58 #define CORE_PRIVATE
59 #include "httpd.h" 
60 #include "http_main.h" 
61 #include "http_config.h"
62 #include "util_uri.h" 
63 #include "ap_mpm.h"
64
65 const char *ap_server_argv0;
66
67 API_VAR_EXPORT const char *ap_server_root;
68
69 ap_array_header_t *ap_server_pre_read_config;
70 ap_array_header_t *ap_server_post_read_config;
71 ap_array_header_t *ap_server_config_defines;
72
73 static void show_compile_settings(void)
74 {
75     printf("Server version: %s\n", ap_get_server_version());
76     printf("Server built:   %s\n", ap_get_server_built());
77     printf("Server's Module Magic Number: %u:%u\n",
78            MODULE_MAGIC_NUMBER_MAJOR, MODULE_MAGIC_NUMBER_MINOR);
79     printf("Server compiled with....\n");
80 #ifdef BIG_SECURITY_HOLE
81     printf(" -D BIG_SECURITY_HOLE\n");
82 #endif
83 #ifdef SECURITY_HOLE_PASS_AUTHORIZATION
84     printf(" -D SECURITY_HOLE_PASS_AUTHORIZATION\n");
85 #endif
86 #ifdef HAVE_MMAP
87     printf(" -D HAVE_MMAP\n");
88 #endif
89 #ifdef HAVE_SHMGET
90     printf(" -D HAVE_SHMGET\n");
91 #endif
92 #ifdef USE_MMAP_SCOREBOARD
93     printf(" -D USE_MMAP_SCOREBOARD\n");
94 #endif
95 #ifdef USE_SHMGET_SCOREBOARD
96     printf(" -D USE_SHMGET_SCOREBOARD\n");
97 #endif
98 #ifdef USE_OS2_SCOREBOARD
99     printf(" -D USE_OS2_SCOREBOARD\n");
100 #endif
101 #ifdef USE_POSIX_SCOREBOARD
102     printf(" -D USE_POSIX_SCOREBOARD\n");
103 #endif
104 #ifdef USE_MMAP_FILES
105     printf(" -D USE_MMAP_FILES\n");
106 #ifdef MMAP_SEGMENT_SIZE
107         printf(" -D MMAP_SEGMENT_SIZE=%ld\n",(long)MMAP_SEGMENT_SIZE);
108 #endif
109 #endif /*USE_MMAP_FILES*/
110 #ifdef NO_WRITEV
111     printf(" -D NO_WRITEV\n");
112 #endif
113 #ifdef NO_LINGCLOSE
114     printf(" -D NO_LINGCLOSE\n");
115 #endif
116 #ifdef USE_FCNTL_SERIALIZED_ACCEPT
117     printf(" -D USE_FCNTL_SERIALIZED_ACCEPT\n");
118 #endif
119 #ifdef USE_FLOCK_SERIALIZED_ACCEPT
120     printf(" -D USE_FLOCK_SERIALIZED_ACCEPT\n");
121 #endif
122 #ifdef USE_USLOCK_SERIALIZED_ACCEPT
123     printf(" -D USE_USLOCK_SERIALIZED_ACCEPT\n");
124 #endif
125 #ifdef USE_SYSVSEM_SERIALIZED_ACCEPT
126     printf(" -D USE_SYSVSEM_SERIALIZED_ACCEPT\n");
127 #endif
128 #ifdef USE_PTHREAD_SERIALIZED_ACCEPT
129     printf(" -D USE_PTHREAD_SERIALIZED_ACCEPT\n");
130 #endif
131 #ifdef SINGLE_LISTEN_UNSERIALIZED_ACCEPT
132     printf(" -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT\n");
133 #endif
134 #ifdef HAS_OTHER_CHILD
135     printf(" -D HAS_OTHER_CHILD\n");
136 #endif
137 #ifdef NO_RELIABLE_PIPED_LOGS
138     printf(" -D NO_RELIABLE_PIPED_LOGS\n");
139 #endif
140 #ifdef BUFFERED_LOGS
141     printf(" -D BUFFERED_LOGS\n");
142 #ifdef PIPE_BUF
143         printf(" -D PIPE_BUF=%ld\n",(long)PIPE_BUF);
144 #endif
145 #endif
146 #ifdef MULTITHREAD
147     printf(" -D MULTITHREAD\n");
148 #endif
149 #ifdef CHARSET_EBCDIC
150     printf(" -D CHARSET_EBCDIC\n");
151 #endif
152 #ifdef NEED_HASHBANG_EMUL
153     printf(" -D NEED_HASHBANG_EMUL\n");
154 #endif
155 #ifdef SHARED_CORE
156     printf(" -D SHARED_CORE\n");
157 #endif
158
159 /* This list displays the compiled in default paths: */
160 #ifdef HTTPD_ROOT
161     printf(" -D HTTPD_ROOT=\"" HTTPD_ROOT "\"\n");
162 #endif
163 #ifdef SUEXEC_BIN
164     printf(" -D SUEXEC_BIN=\"" SUEXEC_BIN "\"\n");
165 #endif
166 #if defined(SHARED_CORE) && defined(SHARED_CORE_DIR)
167     printf(" -D SHARED_CORE_DIR=\"" SHARED_CORE_DIR "\"\n");
168 #endif
169 #ifdef DEFAULT_PIDLOG
170     printf(" -D DEFAULT_PIDLOG=\"" DEFAULT_PIDLOG "\"\n");
171 #endif
172 #ifdef DEFAULT_SCOREBOARD
173     printf(" -D DEFAULT_SCOREBOARD=\"" DEFAULT_SCOREBOARD "\"\n");
174 #endif
175 #ifdef DEFAULT_LOCKFILE
176     printf(" -D DEFAULT_LOCKFILE=\"" DEFAULT_LOCKFILE "\"\n");
177 #endif
178 #ifdef DEFAULT_XFERLOG
179     printf(" -D DEFAULT_XFERLOG=\"" DEFAULT_XFERLOG "\"\n");
180 #endif
181 #ifdef DEFAULT_ERRORLOG
182     printf(" -D DEFAULT_ERRORLOG=\"" DEFAULT_ERRORLOG "\"\n");
183 #endif
184 #ifdef TYPES_CONFIG_FILE
185     printf(" -D TYPES_CONFIG_FILE=\"" TYPES_CONFIG_FILE "\"\n");
186 #endif
187 #ifdef SERVER_CONFIG_FILE
188     printf(" -D SERVER_CONFIG_FILE=\"" SERVER_CONFIG_FILE "\"\n");
189 #endif
190 #ifdef ACCESS_CONFIG_FILE
191     printf(" -D ACCESS_CONFIG_FILE=\"" ACCESS_CONFIG_FILE "\"\n");
192 #endif
193 #ifdef RESOURCE_CONFIG_FILE
194     printf(" -D RESOURCE_CONFIG_FILE=\"" RESOURCE_CONFIG_FILE "\"\n");
195 #endif
196 }
197
198 static void destroy_and_exit_process(process_rec *process, int process_exit_value)
199 {
200     ap_destroy_pool(process->pool); /* and destroy all descendent pools */
201     exit(process_exit_value);
202 }
203
204 static process_rec *create_process(int argc, const char **argv)
205 {
206     process_rec *process;
207     
208     {
209         ap_context_t *cntx;
210
211         ap_create_context(&cntx, NULL);
212         process = ap_palloc(cntx, sizeof(process_rec));
213         process->pool = cntx;
214     }
215     ap_create_context(&process->pconf, process->pool);
216     process->argc = argc;
217     process->argv = argv;
218     process->short_name = ap_filename_of_pathname(argv[0]);
219     return process;
220 }
221
222 static void usage(process_rec *process)
223 {
224     const char *bin = process->argv[0];
225     char pad[MAX_STRING_LEN];
226     unsigned i;
227
228     for (i = 0; i < strlen(bin); i++)
229         pad[i] = ' ';
230     pad[i] = '\0';
231 #ifdef SHARED_CORE
232     fprintf(stderr, "Usage: %s [-R directory] [-D name] [-d directory] [-f file]\n", bin);
233 #else
234     fprintf(stderr, "Usage: %s [-D name] [-d directory] [-f file]\n", bin);
235 #endif
236     fprintf(stderr, "       %s [-C \"directive\"] [-c \"directive\"]\n", pad);
237     fprintf(stderr, "       %s [-v] [-V] [-h] [-l] [-L] [-S] [-t] [-T]\n", pad);
238     fprintf(stderr, "Options:\n");
239 #ifdef SHARED_CORE
240     fprintf(stderr, "  -R directory     : specify an alternate location for shared object files\n");
241 #endif
242     fprintf(stderr, "  -D name          : define a name for use in <IfDefine name> directives\n");
243     fprintf(stderr, "  -d directory     : specify an alternate initial ServerRoot\n");
244     fprintf(stderr, "  -f file          : specify an alternate ServerConfigFile\n");
245     fprintf(stderr, "  -C \"directive\"   : process directive before reading config files\n");
246     fprintf(stderr, "  -c \"directive\"   : process directive after  reading config files\n");
247     fprintf(stderr, "  -v               : show version number\n");
248     fprintf(stderr, "  -V               : show compile settings\n");
249     fprintf(stderr, "  -h               : list available command line options (this page)\n");
250     fprintf(stderr, "  -l               : list compiled in modules\n");
251     fprintf(stderr, "  -L               : list available configuration directives\n");
252     /* TODOC: -S has been replaced by '-t -D DUMP_VHOSTS' */
253     /* fprintf(stderr, "  -S               : show parsed settings (currently only vhost settings)\n"); */
254     fprintf(stderr, "  -t               : run syntax check for config files (with docroot check)\n");
255     fprintf(stderr, "  -T               : run syntax check for config files (without docroot check)\n");
256     /* TODOC: -X goes away, expect MPMs to use -D options */
257     destroy_and_exit_process(process, 1);
258 }
259
260
261
262
263
264 ap_context_t *g_pHookPool;
265
266 extern char *optarg;
267
268 #ifdef WIN32
269 API_EXPORT_NONSTD(int) apache_main(int argc, char *argv[])
270 #else
271 API_EXPORT_NONSTD(int)        main(int argc, char *argv[])
272 #endif
273 {
274     int c;
275     int configtestonly = 0;
276     const char *confname = SERVER_CONFIG_FILE;
277     const char *def_server_root = HTTPD_ROOT;
278     process_rec *process = create_process(argc, (const char **)argv);
279     server_rec *server_conf;
280     ap_context_t *pglobal = process->pool;
281     ap_context_t *pconf = process->pconf;
282     ap_context_t *plog; /* Pool of log streams, reset _after_ each read of conf */
283     ap_context_t *ptemp; /* Pool for temporary config stuff, reset often */
284     ap_context_t *pcommands; /* Pool for -C and -c switches */
285
286     ap_server_argv0 = process->short_name;
287     
288     ap_util_uri_init();
289
290     g_pHookPool=pglobal;
291
292     ap_setup_prelinked_modules(process);
293
294     ap_create_context(&pcommands, pglobal);
295     ap_server_pre_read_config  = ap_make_array(pcommands, 1, sizeof(char *));
296     ap_server_post_read_config = ap_make_array(pcommands, 1, sizeof(char *));
297     ap_server_config_defines   = ap_make_array(pcommands, 1, sizeof(char *));
298
299     while (ap_getopt(pcommands, argc, argv, "C:c:d:f:vVlLth", &c) == APR_SUCCESS) {
300         char **new;
301         switch (c) {
302         case 'c':
303             new = (char **)ap_push_array(ap_server_post_read_config);
304             *new = ap_pstrdup(pcommands, optarg);
305             break;
306         case 'C':
307             new = (char **)ap_push_array(ap_server_pre_read_config);
308             *new = ap_pstrdup(pcommands, optarg);
309             break;
310         case 'd':
311             def_server_root = optarg;
312             break;
313         case 'f':
314             confname = optarg;
315             break;
316         case 'v':
317             printf("Server version: %s\n", ap_get_server_version());
318             printf("Server built:   %s\n", ap_get_server_built());
319             destroy_and_exit_process(process, 0);
320         case 'V':
321             show_compile_settings();
322             destroy_and_exit_process(process, 0);
323         case 'l':
324             ap_show_modules();
325             destroy_and_exit_process(process, 0);
326         case 'L':
327             ap_show_directives();
328             destroy_and_exit_process(process, 0);
329         case 't':
330             configtestonly = 1;
331             break;
332         case 'h':
333             usage(process);
334         case '?':
335             usage(process);
336         }
337     }
338
339     ap_create_context(&plog, pglobal);
340     ap_create_context(&ptemp, pconf);
341
342     /* Note that we preflight the config file once
343        before reading it _again_ in the main loop.
344        This allows things, log files configuration 
345        for example, to settle down. */
346
347     ap_server_root = def_server_root;
348     ap_run_pre_config(pconf, plog, ptemp);
349     server_conf = ap_read_config(process, ptemp, confname);
350     if (configtestonly) {
351         fprintf(stderr, "Syntax OK\n");
352         destroy_and_exit_process(process, 0);
353     }
354     ap_clear_pool(plog);
355     ap_run_open_logs(pconf, plog, ptemp, server_conf);
356     ap_post_config_hook(pconf, plog, ptemp, server_conf);
357     ap_destroy_pool(ptemp);
358
359     for (;;) {
360         ap_clear_pool(pconf);
361         ap_create_context(&ptemp, pconf);
362         ap_server_root = def_server_root;
363         ap_run_pre_config(pconf, plog, ptemp);
364         server_conf = ap_read_config(process, ptemp, confname);
365         ap_clear_pool(plog);
366         ap_run_open_logs(pconf, plog, ptemp, server_conf);
367         ap_post_config_hook(pconf, plog, ptemp, server_conf);
368         ap_destroy_pool(ptemp);
369
370         if (ap_mpm_run(pconf, plog, server_conf)) break;
371     }
372     destroy_and_exit_process(process, 0);
373     return 0; /* Supress compiler warning. */
374 }
375
376 /* force Expat to be linked into the server executable */
377 #if defined(USE_EXPAT) && !defined(SHARED_CORE_BOOTSTRAP)
378 #include "xmlparse.h"
379 const XML_LChar *suck_in_expat(void);
380 const XML_LChar *suck_in_expat(void)
381 {
382     return XML_ErrorString(XML_ERROR_NONE);
383 }
384 #endif /* USE_EXPAT */
385
386 #ifndef SHARED_CORE_BOOTSTRAP
387 /*
388  * Force ap_validate_password() into the image so that modules like
389  * mod_auth can use it even if they're dynamically loaded.
390  */
391 void suck_in_ap_validate_password(void);
392 void suck_in_ap_validate_password(void)
393 {
394     ap_validate_password("a", "b");
395 }
396 #endif
397