]> granicus.if.org Git - apache/blob - server/config.c
More mod_cache tweakage.
[apache] / server / config.c
1 /* Copyright 1999-2005 The Apache Software Foundation or its licensors, as
2  * applicable.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 /*
18  * http_config.c: once was auxillary functions for reading httpd's config
19  * file and converting filenames into a namespace
20  *
21  * Rob McCool
22  *
23  * Wall-to-wall rewrite for Apache... commands which are part of the
24  * server core can now be found next door in "http_core.c".  Now contains
25  * general command loop, and functions which do bookkeeping for the new
26  * Apache config stuff (modules and configuration vectors).
27  *
28  * rst
29  *
30  */
31
32 #include "apr.h"
33 #include "apr_strings.h"
34 #include "apr_portable.h"
35 #include "apr_file_io.h"
36 #include "apr_fnmatch.h"
37
38 #define APR_WANT_STDIO
39 #define APR_WANT_STRFUNC
40 #include "apr_want.h"
41
42 #define CORE_PRIVATE
43
44 #include "ap_config.h"
45 #include "httpd.h"
46 #include "http_config.h"
47 #include "http_protocol.h"
48 #include "http_core.h"
49 #include "http_log.h"           /* for errors in parse_htaccess */
50 #include "http_request.h"       /* for default_handler (see invoke_handler) */
51 #include "http_main.h"
52 #include "http_vhost.h"
53 #include "util_cfgtree.h"
54 #include "mpm.h"
55
56
57 AP_DECLARE_DATA const char *ap_server_argv0 = NULL;
58
59 AP_DECLARE_DATA const char *ap_server_root = NULL;
60
61 AP_DECLARE_DATA apr_array_header_t *ap_server_pre_read_config = NULL;
62 AP_DECLARE_DATA apr_array_header_t *ap_server_post_read_config = NULL;
63 AP_DECLARE_DATA apr_array_header_t *ap_server_config_defines = NULL;
64
65 AP_DECLARE_DATA ap_directive_t *ap_conftree = NULL;
66
67 APR_HOOK_STRUCT(
68            APR_HOOK_LINK(header_parser)
69            APR_HOOK_LINK(pre_config)
70            APR_HOOK_LINK(post_config)
71            APR_HOOK_LINK(open_logs)
72            APR_HOOK_LINK(child_init)
73            APR_HOOK_LINK(handler)
74            APR_HOOK_LINK(quick_handler)
75            APR_HOOK_LINK(optional_fn_retrieve)
76            APR_HOOK_LINK(test_config)
77 )
78
79 AP_IMPLEMENT_HOOK_RUN_ALL(int, header_parser,
80                           (request_rec *r), (r), OK, DECLINED)
81
82 AP_IMPLEMENT_HOOK_RUN_ALL(int, pre_config,
83                           (apr_pool_t *pconf, apr_pool_t *plog,
84                            apr_pool_t *ptemp),
85                           (pconf, plog, ptemp), OK, DECLINED)
86
87 AP_IMPLEMENT_HOOK_VOID(test_config,
88                        (apr_pool_t *pconf, server_rec *s),
89                        (pconf, s))
90
91 AP_IMPLEMENT_HOOK_RUN_ALL(int, post_config,
92                           (apr_pool_t *pconf, apr_pool_t *plog,
93                            apr_pool_t *ptemp, server_rec *s),
94                           (pconf, plog, ptemp, s), OK, DECLINED)
95
96 /* During the course of debugging I expanded this macro out, so
97  * rather than remove all the useful information there is in the
98  * following lines, I'm going to leave it here in case anyone
99  * else finds it useful.
100  *
101  * Ben has looked at it and thinks it correct :)
102  *
103 AP_DECLARE(int) ap_hook_post_config(ap_HOOK_post_config_t *pf,
104                                     const char * const *aszPre,
105                                     const char * const *aszSucc,
106                                     int nOrder)
107 {
108     ap_LINK_post_config_t *pHook;
109
110     if (!_hooks.link_post_config) {
111         _hooks.link_post_config = apr_array_make(apr_hook_global_pool, 1,
112                                                  sizeof(ap_LINK_post_config_t));
113         apr_hook_sort_register("post_config", &_hooks.link_post_config);
114     }
115
116     pHook = apr_array_push(_hooks.link_post_config);
117     pHook->pFunc = pf;
118     pHook->aszPredecessors = aszPre;
119     pHook->aszSuccessors = aszSucc;
120     pHook->nOrder = nOrder;
121     pHook->szName = apr_hook_debug_current;
122
123     if (apr_hook_debug_enabled)
124         apr_hook_debug_show("post_config", aszPre, aszSucc);
125 }
126
127 AP_DECLARE(apr_array_header_t *) ap_hook_get_post_config(void) {
128     return _hooks.link_post_config;
129 }
130
131 AP_DECLARE(int) ap_run_post_config(apr_pool_t *pconf,
132                                    apr_pool_t *plog,
133                                    apr_pool_t *ptemp,
134                                    server_rec *s)
135 {
136     ap_LINK_post_config_t *pHook;
137     int n;
138
139     if(!_hooks.link_post_config)
140         return;
141
142     pHook = (ap_LINK_post_config_t *)_hooks.link_post_config->elts;
143     for (n = 0; n < _hooks.link_post_config->nelts; ++n)
144         pHook[n].pFunc (pconf, plog, ptemp, s);
145 }
146  */
147
148 AP_IMPLEMENT_HOOK_RUN_ALL(int, open_logs,
149                           (apr_pool_t *pconf, apr_pool_t *plog,
150                            apr_pool_t *ptemp, server_rec *s),
151                           (pconf, plog, ptemp, s), OK, DECLINED)
152
153 AP_IMPLEMENT_HOOK_VOID(child_init,
154                        (apr_pool_t *pchild, server_rec *s),
155                        (pchild, s))
156
157 AP_IMPLEMENT_HOOK_RUN_FIRST(int, handler, (request_rec *r),
158                             (r), DECLINED)
159
160 AP_IMPLEMENT_HOOK_RUN_FIRST(int, quick_handler, (request_rec *r, int lookup),
161                             (r, lookup), DECLINED)
162
163 AP_IMPLEMENT_HOOK_VOID(optional_fn_retrieve, (void), ())
164
165 /****************************************************************
166  *
167  * We begin with the functions which deal with the linked list
168  * of modules which control just about all of the server operation.
169  */
170
171 /* total_modules is the number of modules that have been linked
172  * into the server.
173  */
174 static int total_modules = 0;
175
176 /* dynamic_modules is the number of modules that have been added
177  * after the pre-loaded ones have been set up. It shouldn't be larger
178  * than DYNAMIC_MODULE_LIMIT.
179  */
180 static int dynamic_modules = 0;
181
182 AP_DECLARE_DATA module *ap_top_module = NULL;
183 AP_DECLARE_DATA module **ap_loaded_modules=NULL;
184
185 typedef int (*handler_func)(request_rec *);
186 typedef void *(*dir_maker_func)(apr_pool_t *, char *);
187 typedef void *(*merger_func)(apr_pool_t *, void *, void *);
188
189 /* maximum nesting level for config directories */
190 #ifndef AP_MAX_INCLUDE_DIR_DEPTH
191 #define AP_MAX_INCLUDE_DIR_DEPTH (128)
192 #endif
193
194 /* Dealing with config vectors.  These are associated with per-directory,
195  * per-server, and per-request configuration, and have a void* pointer for
196  * each modules.  The nature of the structure pointed to is private to the
197  * module in question... the core doesn't (and can't) know.  However, there
198  * are defined interfaces which allow it to create instances of its private
199  * per-directory and per-server structures, and to merge the per-directory
200  * structures of a directory and its subdirectory (producing a new one in
201  * which the defaults applying to the base directory have been properly
202  * overridden).
203  */
204
205 static ap_conf_vector_t *create_empty_config(apr_pool_t *p)
206 {
207     void *conf_vector = apr_pcalloc(p, sizeof(void *) *
208                                     (total_modules + DYNAMIC_MODULE_LIMIT));
209     return conf_vector;
210 }
211
212 static ap_conf_vector_t *create_default_per_dir_config(apr_pool_t *p)
213 {
214     void **conf_vector = apr_pcalloc(p, sizeof(void *) *
215                                      (total_modules + DYNAMIC_MODULE_LIMIT));
216     module *modp;
217
218     for (modp = ap_top_module; modp; modp = modp->next) {
219         dir_maker_func df = modp->create_dir_config;
220
221         if (df)
222             conf_vector[modp->module_index] = (*df)(p, NULL);
223     }
224
225     return (ap_conf_vector_t *)conf_vector;
226 }
227
228 AP_CORE_DECLARE(ap_conf_vector_t *) ap_merge_per_dir_configs(apr_pool_t *p,
229                                            ap_conf_vector_t *base,
230                                            ap_conf_vector_t *new_conf)
231 {
232     void **conf_vector = apr_palloc(p, sizeof(void *) * total_modules);
233     void **base_vector = (void **)base;
234     void **new_vector = (void **)new_conf;
235     module *modp;
236
237     for (modp = ap_top_module; modp; modp = modp->next) {
238         int i = modp->module_index;
239
240         if (!new_vector[i]) {
241             conf_vector[i] = base_vector[i];
242         }
243         else {
244             merger_func df = modp->merge_dir_config;
245             if (df && base_vector[i]) {
246                 conf_vector[i] = (*df)(p, base_vector[i], new_vector[i]);
247             }
248             else
249                 conf_vector[i] = new_vector[i];
250         }
251     }
252
253     return (ap_conf_vector_t *)conf_vector;
254 }
255
256 static ap_conf_vector_t *create_server_config(apr_pool_t *p, server_rec *s)
257 {
258     void **conf_vector = apr_pcalloc(p, sizeof(void *) *
259                                      (total_modules + DYNAMIC_MODULE_LIMIT));
260     module *modp;
261
262     for (modp = ap_top_module; modp; modp = modp->next) {
263         if (modp->create_server_config)
264             conf_vector[modp->module_index] = (*modp->create_server_config)(p, s);
265     }
266
267     return (ap_conf_vector_t *)conf_vector;
268 }
269
270 static void merge_server_configs(apr_pool_t *p, ap_conf_vector_t *base,
271                                  ap_conf_vector_t *virt)
272 {
273     /* Can reuse the 'virt' vector for the spine of it, since we don't
274      * have to deal with the moral equivalent of .htaccess files here...
275      */
276
277     void **base_vector = (void **)base;
278     void **virt_vector = (void **)virt;
279     module *modp;
280
281     for (modp = ap_top_module; modp; modp = modp->next) {
282         merger_func df = modp->merge_server_config;
283         int i = modp->module_index;
284
285         if (!virt_vector[i])
286             virt_vector[i] = base_vector[i];
287         else if (df)
288             virt_vector[i] = (*df)(p, base_vector[i], virt_vector[i]);
289     }
290 }
291
292 AP_CORE_DECLARE(ap_conf_vector_t *) ap_create_request_config(apr_pool_t *p)
293 {
294     return create_empty_config(p);
295 }
296
297 AP_CORE_DECLARE(ap_conf_vector_t *) ap_create_conn_config(apr_pool_t *p)
298 {
299     return create_empty_config(p);
300 }
301
302 AP_CORE_DECLARE(ap_conf_vector_t *) ap_create_per_dir_config(apr_pool_t *p)
303 {
304     return create_empty_config(p);
305 }
306
307 static int ap_invoke_filter_init(ap_filter_t *filters)
308 {
309     while (filters) {
310         if (filters->frec->filter_init_func) {
311             int result = filters->frec->filter_init_func(filters);
312             if (result != OK) {
313                 return result;
314             }
315         }
316         filters = filters->next;
317     } 
318     return OK;
319 }
320
321 AP_CORE_DECLARE(int) ap_invoke_handler(request_rec *r)
322 {
323     const char *handler;
324     const char *p;
325     int result;
326     const char *old_handler = r->handler;
327
328     /*
329      * The new insert_filter stage makes the most sense here.  We only use
330      * it when we are going to run the request, so we must insert filters
331      * if any are available.  Since the goal of this phase is to allow all
332      * modules to insert a filter if they want to, this filter returns
333      * void.  I just can't see any way that this filter can reasonably
334      * fail, either your modules inserts something or it doesn't.  rbb
335      */
336     ap_run_insert_filter(r);
337
338     /* Before continuing, allow each filter that is in the two chains to
339      * run their init function to let them do any magic before we could
340      * start generating data.
341      */
342     result = ap_invoke_filter_init(r->input_filters);
343     if (result != OK) {
344         return result;
345     }
346     result = ap_invoke_filter_init(r->output_filters);
347     if (result != OK) {
348         return result;
349     }
350
351     if (!r->handler) {
352         handler = r->content_type ? r->content_type : ap_default_type(r);
353         if ((p=ap_strchr_c(handler, ';')) != NULL) {
354             char *new_handler = (char *)apr_pmemdup(r->pool, handler,
355                                                     p - handler + 1);
356             char *p2 = new_handler + (p - handler);
357             handler = new_handler;
358
359             /* MIME type arguments */
360             while (p2 > handler && p2[-1] == ' ')
361                 --p2; /* strip trailing spaces */
362
363             *p2='\0';
364         }
365
366         r->handler = handler;
367     }
368
369     result = ap_run_handler(r);
370
371     r->handler = old_handler;
372
373     if (result == DECLINED && r->handler && r->filename) {
374         ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
375             "handler \"%s\" not found for: %s", r->handler, r->filename);
376     }
377
378     return result == DECLINED ? HTTP_INTERNAL_SERVER_ERROR : result;
379 }
380
381 AP_DECLARE(int) ap_method_is_limited(cmd_parms *cmd, const char *method)
382 {
383     int methnum;
384
385     methnum = ap_method_number_of(method);
386
387     /*
388      * A method number either hardcoded into apache or
389      * added by a module and registered.
390      */
391     if (methnum != M_INVALID) {
392         return (cmd->limited & (AP_METHOD_BIT << methnum)) ? 1 : 0;
393     }
394
395     return 0; /* not found */
396 }
397
398 AP_DECLARE(void) ap_register_hooks(module *m, apr_pool_t *p)
399 {
400     if (m->register_hooks) {
401         if (getenv("SHOW_HOOKS")) {
402             printf("Registering hooks for %s\n", m->name);
403             apr_hook_debug_enabled = 1;
404         }
405
406         apr_hook_debug_current = m->name;
407         m->register_hooks(p);
408     }
409 }
410
411 /* One-time setup for precompiled modules --- NOT to be done on restart */
412
413 AP_DECLARE(const char *) ap_add_module(module *m, apr_pool_t *p)
414 {
415     /* This could be called from a LoadModule httpd.conf command,
416      * after the file has been linked and the module structure within it
417      * teased out...
418      */
419
420     if (m->version != MODULE_MAGIC_NUMBER_MAJOR) {
421         return apr_psprintf(p, "Module \"%s\" is not compatible with this "
422                             "version of Apache (found %d, need %d). Please "
423                             "contact the vendor for the correct version.",
424                             m->name, m->version, MODULE_MAGIC_NUMBER_MAJOR);
425     }
426
427     if (m->next == NULL) {
428         m->next = ap_top_module;
429         ap_top_module = m;
430     }
431
432     if (m->module_index == -1) {
433         m->module_index = total_modules++;
434         dynamic_modules++;
435
436         if (dynamic_modules > DYNAMIC_MODULE_LIMIT) {
437             return apr_psprintf(p, "Module \"%s\" could not be loaded, "
438                                 "because the dynamic module limit was "
439                                 "reached. Please increase "
440                                 "DYNAMIC_MODULE_LIMIT and recompile.", m->name);
441         }
442     }
443
444     /* Some C compilers put a complete path into __FILE__, but we want
445      * only the filename (e.g. mod_includes.c). So check for path
446      * components (Unix and DOS), and remove them.
447      */
448
449     if (ap_strrchr_c(m->name, '/'))
450         m->name = 1 + ap_strrchr_c(m->name, '/');
451
452     if (ap_strrchr_c(m->name, '\\'))
453         m->name = 1 + ap_strrchr_c(m->name, '\\');
454
455 #ifdef _OSD_POSIX
456     /* __FILE__ =
457      * "*POSIX(/home/martin/apache/src/modules/standard/mod_info.c)"
458      */
459
460     /* We cannot fix the string in-place, because it's const */
461     if (m->name[strlen(m->name)-1] == ')') {
462         char *tmp = strdup(m->name); /* FIXME: memory leak, albeit a small one */
463         tmp[strlen(tmp)-1] = '\0';
464         m->name = tmp;
465     }
466 #endif /*_OSD_POSIX*/
467
468     /*  FIXME: is this the right place to call this?
469      *  It doesn't appear to be
470      */
471     ap_register_hooks(m, p);
472
473     return NULL;
474 }
475
476 /*
477  * remove_module undoes what add_module did. There are some caveats:
478  * when the module is removed, its slot is lost so all the current
479  * per-dir and per-server configurations are invalid. So we should
480  * only ever call this function when you are invalidating almost
481  * all our current data. I.e. when doing a restart.
482  */
483
484 AP_DECLARE(void) ap_remove_module(module *m)
485 {
486     module *modp;
487
488     modp = ap_top_module;
489     if (modp == m) {
490         /* We are the top module, special case */
491         ap_top_module = modp->next;
492         m->next = NULL;
493     }
494     else {
495         /* Not the top module, find use. When found modp will
496          * point to the module _before_ us in the list
497          */
498
499         while (modp && modp->next != m) {
500             modp = modp->next;
501         }
502
503         if (!modp) {
504             /* Uh-oh, this module doesn't exist */
505             ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
506                          "Cannot remove module %s: not found in module list",
507                          m->name);
508             return;
509         }
510
511         /* Eliminate us from the module list */
512         modp->next = modp->next->next;
513     }
514
515     m->module_index = -1; /* simulate being unloaded, should
516                            * be unnecessary */
517     dynamic_modules--;
518     total_modules--;
519 }
520
521 AP_DECLARE(const char *) ap_add_loaded_module(module *mod, apr_pool_t *p)
522 {
523     module **m;
524     const char *error;
525
526     /*
527      *  Add module pointer to top of chained module list
528      */
529     error = ap_add_module(mod, p);
530     if (error) {
531         return error;
532     }
533
534     /*
535      *  And module pointer to list of loaded modules
536      *
537      *  Notes: 1. ap_add_module() would already complain if no more space
538      *            exists for adding a dynamically loaded module
539      *         2. ap_add_module() accepts double inclusion, so we have
540      *            to accept this, too.
541      */
542     for (m = ap_loaded_modules; *m != NULL; m++)
543         ;
544     *m++ = mod;
545     *m = NULL;
546
547     return NULL;
548 }
549
550 AP_DECLARE(void) ap_remove_loaded_module(module *mod)
551 {
552     module **m;
553     module **m2;
554     int done;
555
556     /*
557      *  Remove module pointer from chained module list
558      */
559     ap_remove_module(mod);
560
561     /*
562      *  Remove module pointer from list of loaded modules
563      *
564      *  Note: 1. We cannot determine if the module was successfully
565      *           removed by ap_remove_module().
566      *        2. We have not to complain explicity when the module
567      *           is not found because ap_remove_module() did it
568      *           for us already.
569      */
570     for (m = m2 = ap_loaded_modules, done = 0; *m2 != NULL; m2++) {
571         if (*m2 == mod && done == 0)
572             done = 1;
573         else
574             *m++ = *m2;
575     }
576
577     *m = NULL;
578 }
579
580 AP_DECLARE(const char *) ap_setup_prelinked_modules(process_rec *process)
581 {
582     module **m;
583     module **m2;
584     const char *error;
585
586     apr_hook_global_pool=process->pconf;
587
588     /*
589      *  Initialise total_modules variable and module indices
590      */
591     total_modules = 0;
592     for (m = ap_preloaded_modules; *m != NULL; m++)
593         (*m)->module_index = total_modules++;
594
595     /*
596      *  Initialise list of loaded modules
597      */
598     ap_loaded_modules = (module **)apr_palloc(process->pool,
599         sizeof(module *) * (total_modules + DYNAMIC_MODULE_LIMIT + 1));
600
601     if (ap_loaded_modules == NULL) {
602         return "Ouch! Out of memory in ap_setup_prelinked_modules()!";
603     }
604
605     for (m = ap_preloaded_modules, m2 = ap_loaded_modules; *m != NULL; )
606         *m2++ = *m++;
607
608     *m2 = NULL;
609
610     /*
611      *   Initialize chain of linked (=activate) modules
612      */
613     for (m = ap_prelinked_modules; *m != NULL; m++) {
614         error = ap_add_module(*m, process->pconf);
615         if (error) {
616             return error;
617         }
618     }
619
620     apr_hook_sort_all();
621
622     return NULL;
623 }
624
625 AP_DECLARE(const char *) ap_find_module_name(module *m)
626 {
627     return m->name;
628 }
629
630 AP_DECLARE(module *) ap_find_linked_module(const char *name)
631 {
632     module *modp;
633
634     for (modp = ap_top_module; modp; modp = modp->next) {
635         if (strcmp(modp->name, name) == 0)
636             return modp;
637     }
638
639     return NULL;
640 }
641
642 /*****************************************************************
643  *
644  * Resource, access, and .htaccess config files now parsed by a common
645  * command loop.
646  *
647  * Let's begin with the basics; parsing the line and
648  * invoking the function...
649  */
650
651 static const char *invoke_cmd(const command_rec *cmd, cmd_parms *parms,
652                               void *mconfig, const char *args)
653 {
654     char *w, *w2, *w3;
655     const char *errmsg = NULL;
656
657     if ((parms->override & cmd->req_override) == 0)
658         return apr_pstrcat(parms->pool, cmd->name, " not allowed here", NULL);
659
660     parms->info = cmd->cmd_data;
661     parms->cmd = cmd;
662
663     switch (cmd->args_how) {
664     case RAW_ARGS:
665 #ifdef RESOLVE_ENV_PER_TOKEN
666         args = ap_resolve_env(parms->pool,args);
667 #endif
668         return cmd->AP_RAW_ARGS(parms, mconfig, args);
669
670     case NO_ARGS:
671         if (*args != 0)
672             return apr_pstrcat(parms->pool, cmd->name, " takes no arguments",
673                                NULL);
674
675         return cmd->AP_NO_ARGS(parms, mconfig);
676
677     case TAKE1:
678         w = ap_getword_conf(parms->pool, &args);
679
680         if (*w == '\0' || *args != 0)
681             return apr_pstrcat(parms->pool, cmd->name, " takes one argument",
682                                cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
683
684         return cmd->AP_TAKE1(parms, mconfig, w);
685
686     case TAKE2:
687         w = ap_getword_conf(parms->pool, &args);
688         w2 = ap_getword_conf(parms->pool, &args);
689
690         if (*w == '\0' || *w2 == '\0' || *args != 0)
691             return apr_pstrcat(parms->pool, cmd->name, " takes two arguments",
692                                cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
693
694         return cmd->AP_TAKE2(parms, mconfig, w, w2);
695
696     case TAKE12:
697         w = ap_getword_conf(parms->pool, &args);
698         w2 = ap_getword_conf(parms->pool, &args);
699
700         if (*w == '\0' || *args != 0)
701             return apr_pstrcat(parms->pool, cmd->name, " takes 1-2 arguments",
702                                cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
703
704         return cmd->AP_TAKE2(parms, mconfig, w, *w2 ? w2 : NULL);
705
706     case TAKE3:
707         w = ap_getword_conf(parms->pool, &args);
708         w2 = ap_getword_conf(parms->pool, &args);
709         w3 = ap_getword_conf(parms->pool, &args);
710
711         if (*w == '\0' || *w2 == '\0' || *w3 == '\0' || *args != 0)
712             return apr_pstrcat(parms->pool, cmd->name, " takes three arguments",
713                                cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
714
715         return cmd->AP_TAKE3(parms, mconfig, w, w2, w3);
716
717     case TAKE23:
718         w = ap_getword_conf(parms->pool, &args);
719         w2 = ap_getword_conf(parms->pool, &args);
720         w3 = *args ? ap_getword_conf(parms->pool, &args) : NULL;
721
722         if (*w == '\0' || *w2 == '\0' || *args != 0)
723             return apr_pstrcat(parms->pool, cmd->name,
724                                " takes two or three arguments",
725                                cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
726
727         return cmd->AP_TAKE3(parms, mconfig, w, w2, w3);
728
729     case TAKE123:
730         w = ap_getword_conf(parms->pool, &args);
731         w2 = *args ? ap_getword_conf(parms->pool, &args) : NULL;
732         w3 = *args ? ap_getword_conf(parms->pool, &args) : NULL;
733
734         if (*w == '\0' || *args != 0)
735             return apr_pstrcat(parms->pool, cmd->name,
736                                " takes one, two or three arguments",
737                                cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
738
739         return cmd->AP_TAKE3(parms, mconfig, w, w2, w3);
740
741     case TAKE13:
742         w = ap_getword_conf(parms->pool, &args);
743         w2 = *args ? ap_getword_conf(parms->pool, &args) : NULL;
744         w3 = *args ? ap_getword_conf(parms->pool, &args) : NULL;
745
746         if (*w == '\0' || (w2 && *w2 && !w3) || *args != 0)
747             return apr_pstrcat(parms->pool, cmd->name,
748                                " takes one or three arguments",
749                                cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
750
751         return cmd->AP_TAKE3(parms, mconfig, w, w2, w3);
752
753     case ITERATE:
754         while (*(w = ap_getword_conf(parms->pool, &args)) != '\0') {
755
756             errmsg = cmd->AP_TAKE1(parms, mconfig, w);
757
758             if (errmsg && strcmp(errmsg, DECLINE_CMD) != 0)
759                 return errmsg;
760         }
761
762         return errmsg;
763
764     case ITERATE2:
765         w = ap_getword_conf(parms->pool, &args);
766
767         if (*w == '\0' || *args == 0)
768             return apr_pstrcat(parms->pool, cmd->name,
769                                " requires at least two arguments",
770                                cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
771
772         while (*(w2 = ap_getword_conf(parms->pool, &args)) != '\0') {
773
774             errmsg = cmd->AP_TAKE2(parms, mconfig, w, w2);
775
776             if (errmsg && strcmp(errmsg, DECLINE_CMD) != 0)
777                 return errmsg;
778         }
779
780         return errmsg;
781
782     case FLAG:
783         w = ap_getword_conf(parms->pool, &args);
784
785         if (*w == '\0' || (strcasecmp(w, "on") && strcasecmp(w, "off")))
786             return apr_pstrcat(parms->pool, cmd->name, " must be On or Off",
787                                NULL);
788
789         return cmd->AP_FLAG(parms, mconfig, strcasecmp(w, "off") != 0);
790
791     default:
792         return apr_pstrcat(parms->pool, cmd->name,
793                            " is improperly configured internally (server bug)",
794                            NULL);
795     }
796 }
797
798 AP_CORE_DECLARE(const command_rec *) ap_find_command(const char *name,
799                                                      const command_rec *cmds)
800 {
801     while (cmds->name) {
802         if (!strcasecmp(name, cmds->name))
803             return cmds;
804
805         ++cmds;
806     }
807
808     return NULL;
809 }
810
811 AP_CORE_DECLARE(const command_rec *) ap_find_command_in_modules(
812                                           const char *cmd_name, module **mod)
813 {
814     const command_rec *cmdp;
815     module *modp;
816
817     for (modp = *mod; modp; modp = modp->next) {
818         if (modp->cmds && (cmdp = ap_find_command(cmd_name, modp->cmds))) {
819             *mod = modp;
820             return cmdp;
821         }
822     }
823
824     return NULL;
825 }
826
827 AP_CORE_DECLARE(void *) ap_set_config_vectors(server_rec *server,
828                                               ap_conf_vector_t *section_vector,
829                                               const char *section,
830                                               module *mod, apr_pool_t *pconf)
831 {
832     void *section_config = ap_get_module_config(section_vector, mod);
833     void *server_config = ap_get_module_config(server->module_config, mod);
834
835     if (!section_config && mod->create_dir_config) {
836         /* ### need to fix the create_dir_config functions' prototype... */
837         section_config = (*mod->create_dir_config)(pconf, (char *)section);
838         ap_set_module_config(section_vector, mod, section_config);
839     }
840
841     if (!server_config && mod->create_server_config) {
842         server_config = (*mod->create_server_config)(pconf, server);
843         ap_set_module_config(server->module_config, mod, server_config);
844     }
845
846     return section_config;
847 }
848
849 static const char *execute_now(char *cmd_line, const char *args,
850                                cmd_parms *parms,
851                                apr_pool_t *p, apr_pool_t *ptemp,
852                                ap_directive_t **sub_tree,
853                                ap_directive_t *parent);
854
855 static const char *ap_build_config_sub(apr_pool_t *p, apr_pool_t *temp_pool,
856                                        const char *l, cmd_parms *parms,
857                                        ap_directive_t **current,
858                                        ap_directive_t **curr_parent,
859                                        ap_directive_t **conftree)
860 {
861     const char *retval = NULL;
862     const char *args;
863     char *cmd_name;
864     ap_directive_t *newdir;
865     module *mod = ap_top_module;
866     const command_rec *cmd;
867
868     if (*l == '#' || *l == '\0')
869         return NULL;
870
871 #if RESOLVE_ENV_PER_TOKEN
872     args = l;
873 #else
874     args = ap_resolve_env(temp_pool, l);
875 #endif
876
877     cmd_name = ap_getword_conf(p, &args);
878     if (*cmd_name == '\0') {
879         /* Note: this branch should not occur. An empty line should have
880          * triggered the exit further above.
881          */
882         return NULL;
883     }
884
885     if (cmd_name[1] != '/') {
886         char *lastc = cmd_name + strlen(cmd_name) - 1;
887         if (*lastc == '>') {
888             *lastc = '\0' ;
889         }
890         if (cmd_name[0] == '<' && *args == '\0') {
891             args = ">";
892         }
893     }
894
895     newdir = apr_pcalloc(p, sizeof(ap_directive_t));
896     newdir->filename = parms->config_file->name;
897     newdir->line_num = parms->config_file->line_number;
898     newdir->directive = cmd_name;
899     newdir->args = apr_pstrdup(p, args);
900
901     if ((cmd = ap_find_command_in_modules(cmd_name, &mod)) != NULL) {
902         if (cmd->req_override & EXEC_ON_READ) {
903             ap_directive_t *sub_tree = NULL;
904
905             parms->err_directive = newdir;
906             retval = execute_now(cmd_name, args, parms, p, temp_pool,
907                                  &sub_tree, *curr_parent);
908             if (*current) {
909                 (*current)->next = sub_tree;
910             }
911             else {
912                 *current = sub_tree;
913                 if (*curr_parent) {
914                     (*curr_parent)->first_child = (*current);
915                 }
916                 if (*current) {
917                     (*current)->parent = (*curr_parent);
918                 }
919             }
920             if (*current) {
921                 if (!*conftree) {
922                     /* Before walking *current to the end of the list,
923                      * set the head to *current.
924                      */
925                     *conftree = *current;
926                 }
927                 while ((*current)->next != NULL) {
928                     (*current) = (*current)->next;
929                     (*current)->parent = (*curr_parent);
930                 }
931             }
932             return retval;
933         }
934     }
935
936     if (cmd_name[0] == '<') {
937         if (cmd_name[1] != '/') {
938             (*current) = ap_add_node(curr_parent, *current, newdir, 1);
939         }
940         else if (*curr_parent == NULL) {
941             parms->err_directive = newdir;
942             return apr_pstrcat(p, cmd_name,
943                                " without matching <", cmd_name + 2,
944                                " section", NULL);
945         }
946         else {
947             char *bracket = cmd_name + strlen(cmd_name) - 1;
948
949             if (*bracket != '>') {
950                 parms->err_directive = newdir;
951                 return apr_pstrcat(p, cmd_name,
952                                    "> directive missing closing '>'", NULL);
953             }
954
955             *bracket = '\0';
956
957             if (strcasecmp(cmd_name + 2,
958                            (*curr_parent)->directive + 1) != 0) {
959                 parms->err_directive = newdir;
960                 return apr_pstrcat(p, "Expected </",
961                                    (*curr_parent)->directive + 1, "> but saw ",
962                                    cmd_name, ">", NULL);
963             }
964
965             *bracket = '>';
966
967             /* done with this section; move up a level */
968             *current = *curr_parent;
969             *curr_parent = (*current)->parent;
970         }
971     }
972     else {
973         *current = ap_add_node(curr_parent, *current, newdir, 0);
974     }
975
976     return retval;
977 }
978
979 AP_DECLARE(const char *) ap_build_cont_config(apr_pool_t *p,
980                                               apr_pool_t *temp_pool,
981                                               cmd_parms *parms,
982                                               ap_directive_t **current,
983                                               ap_directive_t **curr_parent,
984                                               char *orig_directive)
985 {
986     char *l;
987     char *bracket;
988     const char *retval;
989     ap_directive_t *sub_tree = NULL;
990
991     /* Since this function can be called recursively, allocate
992      * the temporary 8k string buffer from the temp_pool rather 
993      * than the stack to avoid over-running a fixed length stack.
994      */
995     l = apr_palloc(temp_pool, MAX_STRING_LEN);
996
997     bracket = apr_pstrcat(p, orig_directive + 1, ">", NULL);
998     while (!(ap_cfg_getline(l, MAX_STRING_LEN, parms->config_file))) {
999         if (!memcmp(l, "</", 2)
1000             && (strcasecmp(l + 2, bracket) == 0)
1001             && (*curr_parent == NULL)) {
1002             break;
1003         }
1004         retval = ap_build_config_sub(p, temp_pool, l, parms, current,
1005                                      curr_parent, &sub_tree);
1006         if (retval != NULL)
1007             return retval;
1008
1009         if (sub_tree == NULL && curr_parent != NULL) {
1010             sub_tree = *curr_parent;
1011         }
1012
1013         if (sub_tree == NULL && current != NULL) {
1014             sub_tree = *current;
1015         }
1016     }
1017
1018     *current = sub_tree;
1019     return NULL;
1020 }
1021
1022 static const char *ap_walk_config_sub(const ap_directive_t *current,
1023                                       cmd_parms *parms,
1024                                       ap_conf_vector_t *section_vector)
1025 {
1026     module *mod = ap_top_module;
1027
1028     while (1) {
1029         const command_rec *cmd;
1030
1031         if (!(cmd = ap_find_command_in_modules(current->directive, &mod))) {
1032             parms->err_directive = current;
1033             return apr_pstrcat(parms->pool, "Invalid command '",
1034                                current->directive,
1035                                "', perhaps mis-spelled or defined by a module "
1036                                "not included in the server configuration",
1037                                NULL);
1038         }
1039         else {
1040             void *dir_config = ap_set_config_vectors(parms->server,
1041                                                      section_vector,
1042                                                      parms->path,
1043                                                      mod,
1044                                                      parms->pool);
1045             const char *retval;
1046
1047             /* Once was enough? */
1048             if (cmd->req_override & EXEC_ON_READ) {
1049                 return NULL;
1050             }
1051
1052             retval = invoke_cmd(cmd, parms, dir_config, current->args);
1053             if (retval == NULL) {
1054                 return NULL;
1055             }
1056
1057             if (strcmp(retval, DECLINE_CMD) != 0) {
1058                 /* If the directive in error has already been set, don't
1059                  * replace it.  Otherwise, an error inside a container 
1060                  * will be reported as occuring on the first line of the
1061                  * container.
1062                  */
1063                 if (!parms->err_directive) {
1064                     parms->err_directive = current;
1065                 }
1066
1067                 return retval;
1068             }
1069
1070             mod = mod->next; /* Next time around, skip this one */
1071         }
1072     }
1073     /* NOTREACHED */
1074 }
1075
1076 AP_DECLARE(const char *) ap_walk_config(ap_directive_t *current,
1077                                         cmd_parms *parms,
1078                                         ap_conf_vector_t *section_vector)
1079 {
1080     ap_conf_vector_t *oldconfig = parms->context;
1081
1082     parms->context = section_vector;
1083
1084     /* scan through all directives, executing each one */
1085     for (; current != NULL; current = current->next) {
1086         const char *errmsg;
1087
1088         parms->directive = current;
1089
1090         /* actually parse the command and execute the correct function */
1091         errmsg = ap_walk_config_sub(current, parms, section_vector);
1092         if (errmsg != NULL) {
1093             /* restore the context (just in case) */
1094             parms->context = oldconfig;
1095             return errmsg;
1096         }
1097     }
1098
1099     parms->context = oldconfig;
1100     return NULL;
1101 }
1102
1103 AP_DECLARE(const char *) ap_build_config(cmd_parms *parms,
1104                                          apr_pool_t *p, apr_pool_t *temp_pool,
1105                                          ap_directive_t **conftree)
1106 {
1107     ap_directive_t *current = *conftree;
1108     ap_directive_t *curr_parent = NULL;
1109     char *l = apr_palloc (temp_pool, MAX_STRING_LEN);
1110     const char *errmsg;
1111
1112     if (current != NULL) {
1113         while (current->next) {
1114             current = current->next;
1115         }
1116     }
1117
1118     while (!(ap_cfg_getline(l, MAX_STRING_LEN, parms->config_file))) {
1119         errmsg = ap_build_config_sub(p, temp_pool, l, parms,
1120                                      &current, &curr_parent, conftree);
1121         if (errmsg != NULL)
1122             return errmsg;
1123
1124         if (*conftree == NULL && curr_parent != NULL) {
1125             *conftree = curr_parent;
1126         }
1127
1128         if (*conftree == NULL && current != NULL) {
1129             *conftree = current;
1130         }
1131     }
1132
1133     if (curr_parent != NULL) {
1134         errmsg = "";
1135
1136         while (curr_parent != NULL) {
1137             errmsg = apr_psprintf(p, "%s%s%s:%u: %s> was not closed.",
1138                                   errmsg,
1139                                   *errmsg == '\0' ? "" : APR_EOL_STR,
1140                                   curr_parent->filename,
1141                                   curr_parent->line_num,
1142                                   curr_parent->directive);
1143
1144             parms->err_directive = curr_parent;
1145             curr_parent = curr_parent->parent;
1146         }
1147
1148         return errmsg;
1149     }
1150
1151     return NULL;
1152 }
1153
1154 /*
1155  * Generic command functions...
1156  */
1157
1158 AP_DECLARE_NONSTD(const char *) ap_set_string_slot(cmd_parms *cmd,
1159                                                    void *struct_ptr,
1160                                                    const char *arg)
1161 {
1162     int offset = (int)(long)cmd->info;
1163
1164     *(const char **)((char *)struct_ptr + offset) = arg;
1165
1166     return NULL;
1167 }
1168
1169 AP_DECLARE_NONSTD(const char *) ap_set_int_slot(cmd_parms *cmd,
1170                                                 void *struct_ptr,
1171                                                 const char *arg)
1172 {
1173     char *endptr;
1174     char *error_str = NULL;
1175     int offset = (int)(long)cmd->info;
1176
1177     *(int *)((char*)struct_ptr + offset) = strtol(arg, &endptr, 10);
1178
1179     if ((*arg == '\0') || (*endptr != '\0')) {
1180         error_str = apr_psprintf(cmd->pool,
1181                      "Invalid value for directive %s, expected integer",
1182                      cmd->directive->directive);
1183     }
1184
1185     return error_str;
1186 }
1187
1188 AP_DECLARE_NONSTD(const char *) ap_set_string_slot_lower(cmd_parms *cmd,
1189                                                          void *struct_ptr,
1190                                                          const char *arg_)
1191 {
1192     char *arg = apr_pstrdup(cmd->pool,arg_);
1193     int offset = (int)(long)cmd->info;
1194
1195     ap_str_tolower(arg);
1196     *(char **)((char *)struct_ptr + offset) = arg;
1197
1198     return NULL;
1199 }
1200
1201 AP_DECLARE_NONSTD(const char *) ap_set_flag_slot(cmd_parms *cmd,
1202                                                  void *struct_ptr_v, int arg)
1203 {
1204     int offset = (int)(long)cmd->info;
1205     char *struct_ptr = (char *)struct_ptr_v;
1206
1207     *(int *)(struct_ptr + offset) = arg ? 1 : 0;
1208
1209     return NULL;
1210 }
1211
1212 AP_DECLARE_NONSTD(const char *) ap_set_file_slot(cmd_parms *cmd, void *struct_ptr,
1213                                                  const char *arg)
1214 {
1215     /* Prepend server_root to relative arg.
1216      * This allows most args to be independent of server_root,
1217      * so the server can be moved or mirrored with less pain.
1218      */
1219     const char *path;
1220     int offset = (int)(long)cmd->info;
1221
1222     path = ap_server_root_relative(cmd->pool, arg);
1223
1224     if (!path) {
1225         return apr_pstrcat(cmd->pool, "Invalid file path ",
1226                            arg, NULL);
1227     }
1228
1229     *(const char **) ((char*)struct_ptr + offset) = path;
1230
1231     return NULL;
1232 }
1233
1234 AP_DECLARE_NONSTD(const char *) ap_set_deprecated(cmd_parms *cmd,
1235                                                   void *struct_ptr,
1236                                                   const char *arg)
1237 {
1238     return cmd->cmd->errmsg;
1239 }
1240
1241 /*****************************************************************
1242  *
1243  * Reading whole config files...
1244  */
1245
1246 static cmd_parms default_parms =
1247 {NULL, 0, -1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
1248
1249 AP_DECLARE(char *) ap_server_root_relative(apr_pool_t *p, const char *file)
1250 {
1251     char *newpath = NULL;
1252     apr_status_t rv;
1253     rv = apr_filepath_merge(&newpath, ap_server_root, file,
1254                             APR_FILEPATH_TRUENAME, p);
1255     if (newpath && (rv == APR_SUCCESS || APR_STATUS_IS_EPATHWILD(rv) 
1256                                       || APR_STATUS_IS_ENOENT(rv)
1257                                       || APR_STATUS_IS_ENOTDIR(rv))) {
1258         return newpath;
1259     }
1260     else {
1261         return NULL;
1262     }
1263 }
1264
1265 AP_DECLARE(const char *) ap_soak_end_container(cmd_parms *cmd, char *directive)
1266 {
1267     char l[MAX_STRING_LEN];
1268     const char *args;
1269     char *cmd_name;
1270
1271     while(!(ap_cfg_getline(l, MAX_STRING_LEN, cmd->config_file))) {
1272 #if RESOLVE_ENV_PER_TOKEN
1273         args = l;
1274 #else
1275         args = ap_resolve_env(cmd->temp_pool, l);
1276 #endif
1277
1278         cmd_name = ap_getword_conf(cmd->pool, &args);
1279         if (cmd_name[0] == '<') {
1280             if (cmd_name[1] == '/') {
1281                 cmd_name[strlen(cmd_name) - 1] = '\0';
1282
1283                 if (strcasecmp(cmd_name + 2, directive + 1) != 0) {
1284                     return apr_pstrcat(cmd->pool, "Expected </",
1285                                        directive + 1, "> but saw ",
1286                                        cmd_name, ">", NULL);
1287                 }
1288
1289                 return NULL; /* found end of container */
1290             }
1291             else {
1292                 const char *msg;
1293
1294                 if (*args == '\0' && cmd_name[strlen(cmd_name) - 1] == '>') {
1295                     cmd_name[strlen(cmd_name) - 1] = '\0';
1296                 }
1297
1298                 if ((msg = ap_soak_end_container(cmd, cmd_name)) != NULL) {
1299                     return msg;
1300                 }
1301             }
1302         }
1303     }
1304
1305     return apr_pstrcat(cmd->pool, "Expected </",
1306                        directive + 1, "> before end of configuration",
1307                        NULL);
1308 }
1309
1310 static const char *execute_now(char *cmd_line, const char *args,
1311                                cmd_parms *parms,
1312                                apr_pool_t *p, apr_pool_t *ptemp,
1313                                ap_directive_t **sub_tree,
1314                                ap_directive_t *parent)
1315 {
1316     module *mod = ap_top_module;
1317     const command_rec *cmd;
1318
1319     if (!(cmd = ap_find_command_in_modules(cmd_line, &mod))) {
1320         return apr_pstrcat(parms->pool, "Invalid command '",
1321                            cmd_line,
1322                            "', perhaps mis-spelled or defined by a module "
1323                            "not included in the server configuration",
1324                            NULL);
1325     }
1326     else {
1327         return invoke_cmd(cmd, parms, sub_tree, args);
1328     }
1329 }
1330
1331 /* This structure and the following functions are needed for the
1332  * table-based config file reading. They are passed to the
1333  * cfg_open_custom() routine.
1334  */
1335
1336 /* Structure to be passed to cfg_open_custom(): it contains an
1337  * index which is incremented from 0 to nelts on each call to
1338  * cfg_getline() (which in turn calls arr_elts_getstr())
1339  * and an apr_array_header_t pointer for the string array.
1340  */
1341 typedef struct {
1342     apr_array_header_t *array;
1343     int curr_idx;
1344 } arr_elts_param_t;
1345
1346
1347 /* arr_elts_getstr() returns the next line from the string array. */
1348 static void *arr_elts_getstr(void *buf, size_t bufsiz, void *param)
1349 {
1350     arr_elts_param_t *arr_param = (arr_elts_param_t *)param;
1351
1352     /* End of array reached? */
1353     if (++arr_param->curr_idx > arr_param->array->nelts)
1354         return NULL;
1355
1356     /* return the line */
1357     apr_cpystrn(buf,
1358                 ((char **)arr_param->array->elts)[arr_param->curr_idx - 1],
1359                 bufsiz);
1360
1361     return buf;
1362 }
1363
1364
1365 /* arr_elts_close(): dummy close routine (makes sure no more lines can be read) */
1366 static int arr_elts_close(void *param)
1367 {
1368     arr_elts_param_t *arr_param = (arr_elts_param_t *)param;
1369
1370     arr_param->curr_idx = arr_param->array->nelts;
1371
1372     return 0;
1373 }
1374
1375 static const char *process_command_config(server_rec *s,
1376                                           apr_array_header_t *arr,
1377                                           ap_directive_t **conftree,
1378                                           apr_pool_t *p,
1379                                           apr_pool_t *ptemp)
1380 {
1381     const char *errmsg;
1382     cmd_parms parms;
1383     arr_elts_param_t arr_parms;
1384
1385     arr_parms.curr_idx = 0;
1386     arr_parms.array = arr;
1387
1388     parms = default_parms;
1389     parms.pool = p;
1390     parms.temp_pool = ptemp;
1391     parms.server = s;
1392     parms.override = (RSRC_CONF | OR_ALL) & ~(OR_AUTHCFG | OR_LIMIT);
1393     parms.override_opts = OPT_ALL | OPT_INCNOEXEC | OPT_SYM_OWNER | OPT_MULTI;
1394
1395     parms.config_file = ap_pcfg_open_custom(p, "-c/-C directives",
1396                                             &arr_parms, NULL,
1397                                             arr_elts_getstr, arr_elts_close);
1398
1399     errmsg = ap_build_config(&parms, p, ptemp, conftree);
1400     ap_cfg_closefile(parms.config_file);
1401
1402     if (errmsg) {
1403         return apr_pstrcat(p, "Syntax error in -C/-c directive: ", errmsg,
1404                            NULL);
1405     }
1406
1407     return NULL;
1408 }
1409
1410 typedef struct {
1411     char *fname;
1412 } fnames;
1413
1414 static int fname_alphasort(const void *fn1, const void *fn2)
1415 {
1416     const fnames *f1 = fn1;
1417     const fnames *f2 = fn2;
1418
1419     return strcmp(f1->fname,f2->fname);
1420 }
1421
1422 static const char *process_resource_config_nofnmatch(server_rec *s,
1423                                                      const char *fname,
1424                                                      ap_directive_t **conftree,
1425                                                      apr_pool_t *p,
1426                                                      apr_pool_t *ptemp,
1427                                                      unsigned depth)
1428 {
1429     cmd_parms parms;
1430     ap_configfile_t *cfp;
1431     const char *error;
1432
1433     if (ap_is_directory(p, fname)) {
1434         apr_dir_t *dirp;
1435         apr_finfo_t dirent;
1436         int current;
1437         apr_array_header_t *candidates = NULL;
1438         fnames *fnew;
1439         apr_status_t rv;
1440         char *path = apr_pstrdup(p, fname);
1441
1442         if (++depth > AP_MAX_INCLUDE_DIR_DEPTH) {
1443             return apr_psprintf(p, "Directory %s exceeds the maximum include "
1444                                 "directory nesting level of %u. You have "
1445                                 "probably a recursion somewhere.", path,
1446                                 AP_MAX_INCLUDE_DIR_DEPTH);
1447         }
1448
1449         /*
1450          * first course of business is to grok all the directory
1451          * entries here and store 'em away. Recall we need full pathnames
1452          * for this.
1453          */
1454         rv = apr_dir_open(&dirp, path, p);
1455         if (rv != APR_SUCCESS) {
1456             char errmsg[120];
1457             return apr_psprintf(p, "Could not open config directory %s: %s",
1458                                 path, apr_strerror(rv, errmsg, sizeof errmsg));
1459         }
1460
1461         candidates = apr_array_make(p, 1, sizeof(fnames));
1462         while (apr_dir_read(&dirent, APR_FINFO_DIRENT, dirp) == APR_SUCCESS) {
1463             /* strip out '.' and '..' */
1464             if (strcmp(dirent.name, ".")
1465                 && strcmp(dirent.name, "..")) {
1466                 fnew = (fnames *) apr_array_push(candidates);
1467                 fnew->fname = ap_make_full_path(p, path, dirent.name);
1468             }
1469         }
1470
1471         apr_dir_close(dirp);
1472         if (candidates->nelts != 0) {
1473             qsort((void *) candidates->elts, candidates->nelts,
1474                   sizeof(fnames), fname_alphasort);
1475
1476             /*
1477              * Now recurse these... we handle errors and subdirectories
1478              * via the recursion, which is nice
1479              */
1480             for (current = 0; current < candidates->nelts; ++current) {
1481                 fnew = &((fnames *) candidates->elts)[current];
1482                 error = process_resource_config_nofnmatch(s, fnew->fname,
1483                                                           conftree, p, ptemp,
1484                                                           depth);
1485                 if (error) {
1486                     return error;
1487                 }
1488             }
1489         }
1490
1491         return NULL;
1492     }
1493
1494     /* GCC's initialization extensions are soooo nice here... */
1495     parms = default_parms;
1496     parms.pool = p;
1497     parms.temp_pool = ptemp;
1498     parms.server = s;
1499     parms.override = (RSRC_CONF | OR_ALL) & ~(OR_AUTHCFG | OR_LIMIT);
1500     parms.override_opts = OPT_ALL | OPT_INCNOEXEC | OPT_SYM_OWNER | OPT_MULTI;
1501
1502     if (ap_pcfg_openfile(&cfp, p, fname) != APR_SUCCESS) {
1503         return apr_pstrcat(p, "Could not open document config file ",
1504                            fname, NULL);
1505     }
1506
1507     parms.config_file = cfp;
1508     error = ap_build_config(&parms, p, ptemp, conftree);
1509     ap_cfg_closefile(cfp);
1510
1511     if (error) {
1512         return apr_psprintf(p, "Syntax error on line %d of %s: %s",
1513                             parms.err_directive->line_num,
1514                             parms.err_directive->filename, error);
1515     }
1516
1517     return NULL;
1518 }
1519
1520 AP_DECLARE(const char *) ap_process_resource_config(server_rec *s,
1521                                                     const char *fname,
1522                                                     ap_directive_t **conftree,
1523                                                     apr_pool_t *p,
1524                                                     apr_pool_t *ptemp)
1525 {
1526     /* XXX: lstat() won't work on the wildcard pattern...
1527      */
1528
1529     /* don't require conf/httpd.conf if we have a -C or -c switch */
1530     if ((ap_server_pre_read_config->nelts
1531         || ap_server_post_read_config->nelts)
1532         && !(strcmp(fname, ap_server_root_relative(p, SERVER_CONFIG_FILE)))) {
1533         apr_finfo_t finfo;
1534
1535         if (apr_stat(&finfo, fname, APR_FINFO_LINK | APR_FINFO_TYPE, p) != APR_SUCCESS)
1536             return NULL;
1537     }
1538
1539     if (!apr_fnmatch_test(fname)) {
1540         return process_resource_config_nofnmatch(s, fname, conftree, p, ptemp,
1541                                                  0);
1542     }
1543     else {
1544         apr_dir_t *dirp;
1545         apr_finfo_t dirent;
1546         int current;
1547         apr_array_header_t *candidates = NULL;
1548         fnames *fnew;
1549         apr_status_t rv;
1550         char *path = apr_pstrdup(p, fname), *pattern = NULL;
1551
1552         pattern = ap_strrchr(path, '/');
1553
1554         AP_DEBUG_ASSERT(pattern != NULL); /* path must be absolute. */
1555
1556         *pattern++ = '\0';
1557
1558         if (apr_fnmatch_test(path)) {
1559             return apr_pstrcat(p, "Wildcard patterns not allowed in Include ",
1560                                fname, NULL);
1561         }
1562
1563         if (!ap_is_directory(p, path)){ 
1564             return apr_pstrcat(p, "Include directory '", path, "' not found",
1565                                NULL);
1566         }
1567
1568         if (!apr_fnmatch_test(pattern)) {
1569             return apr_pstrcat(p, "Must include a wildcard pattern for "
1570                                "Include ", fname, NULL);
1571         }
1572
1573         /*
1574          * first course of business is to grok all the directory
1575          * entries here and store 'em away. Recall we need full pathnames
1576          * for this.
1577          */
1578         rv = apr_dir_open(&dirp, path, p);
1579         if (rv != APR_SUCCESS) {
1580             char errmsg[120];
1581             return apr_psprintf(p, "Could not open config directory %s: %s",
1582                                 path, apr_strerror(rv, errmsg, sizeof errmsg));
1583         }
1584
1585         candidates = apr_array_make(p, 1, sizeof(fnames));
1586         while (apr_dir_read(&dirent, APR_FINFO_DIRENT, dirp) == APR_SUCCESS) {
1587             /* strip out '.' and '..' */
1588             if (strcmp(dirent.name, ".")
1589                 && strcmp(dirent.name, "..")
1590                 && (apr_fnmatch(pattern, dirent.name,
1591                                 APR_FNM_PERIOD) == APR_SUCCESS)) {
1592                 fnew = (fnames *) apr_array_push(candidates);
1593                 fnew->fname = ap_make_full_path(p, path, dirent.name);
1594             }
1595         }
1596
1597         apr_dir_close(dirp);
1598         if (candidates->nelts != 0) {
1599             const char *error;
1600
1601             qsort((void *) candidates->elts, candidates->nelts,
1602                   sizeof(fnames), fname_alphasort);
1603
1604             /*
1605              * Now recurse these... we handle errors and subdirectories
1606              * via the recursion, which is nice
1607              */
1608             for (current = 0; current < candidates->nelts; ++current) {
1609                 fnew = &((fnames *) candidates->elts)[current];
1610                 error = process_resource_config_nofnmatch(s, fnew->fname,
1611                                                           conftree, p,
1612                                                           ptemp, 0);
1613                 if (error) {
1614                     return error;
1615                 }
1616             }
1617         }
1618     }
1619
1620     return NULL;
1621 }
1622
1623 AP_DECLARE(int) ap_process_config_tree(server_rec *s,
1624                                        ap_directive_t *conftree,
1625                                        apr_pool_t *p,
1626                                        apr_pool_t *ptemp)
1627 {
1628     const char *errmsg;
1629     cmd_parms parms;
1630
1631     parms = default_parms;
1632     parms.pool = p;
1633     parms.temp_pool = ptemp;
1634     parms.server = s;
1635     parms.override = (RSRC_CONF | OR_ALL) & ~(OR_AUTHCFG | OR_LIMIT);
1636     parms.override_opts = OPT_ALL | OPT_INCNOEXEC | OPT_SYM_OWNER | OPT_MULTI;
1637     parms.limited = -1;
1638
1639     errmsg = ap_walk_config(conftree, &parms, s->lookup_defaults);
1640     if (errmsg) {
1641         ap_log_perror(APLOG_MARK, APLOG_STARTUP, 0, p,
1642                      "Syntax error on line %d of %s:",
1643                      parms.err_directive->line_num,
1644                      parms.err_directive->filename);
1645         ap_log_perror(APLOG_MARK, APLOG_STARTUP, 0, p,
1646                      "%s", errmsg);
1647         return HTTP_INTERNAL_SERVER_ERROR;
1648     }
1649
1650     return OK;
1651 }
1652
1653 AP_CORE_DECLARE(int) ap_parse_htaccess(ap_conf_vector_t **result,
1654                                        request_rec *r, int override,
1655                                        int override_opts,
1656                                        const char *d, const char *access_name)
1657 {
1658     ap_configfile_t *f = NULL;
1659     cmd_parms parms;
1660     char *filename = NULL;
1661     const struct htaccess_result *cache;
1662     struct htaccess_result *new;
1663     ap_conf_vector_t *dc = NULL;
1664     apr_status_t status;
1665
1666     /* firstly, search cache */
1667     for (cache = r->htaccess; cache != NULL; cache = cache->next) {
1668         if (cache->override == override && strcmp(cache->dir, d) == 0) {
1669             *result = cache->htaccess;
1670             return OK;
1671         }
1672     }
1673
1674     parms = default_parms;
1675     parms.override = override;
1676     parms.override_opts = override_opts;
1677     parms.pool = r->pool;
1678     parms.temp_pool = r->pool;
1679     parms.server = r->server;
1680     parms.path = apr_pstrdup(r->pool, d);
1681
1682     /* loop through the access names and find the first one */
1683     while (access_name[0]) {
1684         /* AFAICT; there is no use of the actual 'filename' against
1685          * any canonicalization, so we will simply take the given
1686          * name, ignoring case sensitivity and aliases
1687          */
1688         filename = ap_make_full_path(r->pool, d,
1689                                      ap_getword_conf(r->pool, &access_name));
1690         status = ap_pcfg_openfile(&f, r->pool, filename);
1691
1692         if (status == APR_SUCCESS) {
1693             const char *errmsg;
1694             ap_directive_t *temptree = NULL;
1695
1696             dc = ap_create_per_dir_config(r->pool);
1697
1698             parms.config_file = f;
1699             errmsg = ap_build_config(&parms, r->pool, r->pool, &temptree);
1700             if (errmsg == NULL)
1701                 errmsg = ap_walk_config(temptree, &parms, dc);
1702
1703             ap_cfg_closefile(f);
1704
1705             if (errmsg) {
1706                 ap_log_rerror(APLOG_MARK, APLOG_ALERT, 0, r,
1707                               "%s: %s", filename, errmsg);
1708                 return HTTP_INTERNAL_SERVER_ERROR;
1709             }
1710
1711             *result = dc;
1712             break;
1713         }
1714         else {
1715             if (!APR_STATUS_IS_ENOENT(status)
1716                 && !APR_STATUS_IS_ENOTDIR(status)) {
1717                 ap_log_rerror(APLOG_MARK, APLOG_CRIT, status, r,
1718                               "%s pcfg_openfile: unable to check htaccess file, "
1719                               "ensure it is readable",
1720                               filename);
1721                 apr_table_setn(r->notes, "error-notes",
1722                                "Server unable to read htaccess file, denying "
1723                                "access to be safe");
1724                 return HTTP_FORBIDDEN;
1725             }
1726         }
1727     }
1728
1729     /* cache it */
1730     new = apr_palloc(r->pool, sizeof(struct htaccess_result));
1731     new->dir = parms.path;
1732     new->override = override;
1733     new->override_opts = override_opts;
1734     new->htaccess = dc;
1735
1736     /* add to head of list */
1737     new->next = r->htaccess;
1738     r->htaccess = new;
1739
1740     return OK;
1741 }
1742
1743 AP_CORE_DECLARE(const char *) ap_init_virtual_host(apr_pool_t *p,
1744                                                    const char *hostname,
1745                                                    server_rec *main_server,
1746                                                    server_rec **ps)
1747 {
1748     server_rec *s = (server_rec *) apr_pcalloc(p, sizeof(server_rec));
1749
1750     /* TODO: this crap belongs in http_core */
1751     s->process = main_server->process;
1752     s->server_admin = NULL;
1753     s->server_hostname = NULL;
1754     s->error_fname = NULL;
1755     s->timeout = 0;
1756     s->keep_alive_timeout = 0;
1757     s->keep_alive = -1;
1758     s->keep_alive_max = -1;
1759     s->error_log = main_server->error_log;
1760     s->loglevel = main_server->loglevel;
1761     /* useful default, otherwise we get a port of 0 on redirects */
1762     s->port = main_server->port;
1763     s->next = NULL;
1764
1765     s->is_virtual = 1;
1766     s->names = apr_array_make(p, 4, sizeof(char **));
1767     s->wild_names = apr_array_make(p, 4, sizeof(char **));
1768
1769     s->module_config = create_empty_config(p);
1770     s->lookup_defaults = ap_create_per_dir_config(p);
1771
1772     s->limit_req_line = main_server->limit_req_line;
1773     s->limit_req_fieldsize = main_server->limit_req_fieldsize;
1774     s->limit_req_fields = main_server->limit_req_fields;
1775
1776     *ps = s;
1777
1778     return ap_parse_vhost_addrs(p, hostname, s);
1779 }
1780
1781
1782 AP_DECLARE(void) ap_fixup_virtual_hosts(apr_pool_t *p, server_rec *main_server)
1783 {
1784     server_rec *virt;
1785
1786     for (virt = main_server->next; virt; virt = virt->next) {
1787         merge_server_configs(p, main_server->module_config,
1788                              virt->module_config);
1789
1790         virt->lookup_defaults =
1791             ap_merge_per_dir_configs(p, main_server->lookup_defaults,
1792                                      virt->lookup_defaults);
1793
1794         if (virt->server_admin == NULL)
1795             virt->server_admin = main_server->server_admin;
1796
1797         if (virt->timeout == 0)
1798             virt->timeout = main_server->timeout;
1799
1800         if (virt->keep_alive_timeout == 0)
1801             virt->keep_alive_timeout = main_server->keep_alive_timeout;
1802
1803         if (virt->keep_alive == -1)
1804             virt->keep_alive = main_server->keep_alive;
1805
1806         if (virt->keep_alive_max == -1)
1807             virt->keep_alive_max = main_server->keep_alive_max;
1808
1809         /* XXX: this is really something that should be dealt with by a
1810          * post-config api phase
1811          */
1812         ap_core_reorder_directories(p, virt);
1813     }
1814
1815     ap_core_reorder_directories(p, main_server);
1816 }
1817
1818 /*****************************************************************
1819  *
1820  * Getting *everything* configured...
1821  */
1822
1823 static void init_config_globals(apr_pool_t *p)
1824 {
1825     /* Global virtual host hash bucket pointers.  Init to null. */
1826     ap_init_vhost_config(p);
1827 }
1828
1829 static server_rec *init_server_config(process_rec *process, apr_pool_t *p)
1830 {
1831     apr_status_t rv;
1832     server_rec *s = (server_rec *) apr_pcalloc(p, sizeof(server_rec));
1833
1834     apr_file_open_stderr(&s->error_log, p);
1835     s->process = process;
1836     s->port = 0;
1837     s->server_admin = DEFAULT_ADMIN;
1838     s->server_hostname = NULL;
1839     s->error_fname = DEFAULT_ERRORLOG;
1840     s->loglevel = DEFAULT_LOGLEVEL;
1841     s->limit_req_line = DEFAULT_LIMIT_REQUEST_LINE;
1842     s->limit_req_fieldsize = DEFAULT_LIMIT_REQUEST_FIELDSIZE;
1843     s->limit_req_fields = DEFAULT_LIMIT_REQUEST_FIELDS;
1844     s->timeout = apr_time_from_sec(DEFAULT_TIMEOUT);
1845     s->keep_alive_timeout = apr_time_from_sec(DEFAULT_KEEPALIVE_TIMEOUT);
1846     s->keep_alive_max = DEFAULT_KEEPALIVE;
1847     s->keep_alive = 1;
1848     s->next = NULL;
1849     s->addrs = apr_pcalloc(p, sizeof(server_addr_rec));
1850
1851     /* NOT virtual host; don't match any real network interface */
1852     rv = apr_sockaddr_info_get(&s->addrs->host_addr,
1853                                NULL, APR_INET, 0, 0, p);
1854     ap_assert(rv == APR_SUCCESS); /* otherwise: bug or no storage */
1855
1856     s->addrs->host_port = 0; /* matches any port */
1857     s->addrs->virthost = ""; /* must be non-NULL */
1858     s->names = s->wild_names = NULL;
1859
1860     s->module_config = create_server_config(p, s);
1861     s->lookup_defaults = create_default_per_dir_config(p);
1862
1863     return s;
1864 }
1865
1866
1867 AP_DECLARE(server_rec*) ap_read_config(process_rec *process, apr_pool_t *ptemp,
1868                                        const char *filename,
1869                                        ap_directive_t **conftree)
1870 {
1871     const char *confname, *error;
1872     apr_pool_t *p = process->pconf;
1873     server_rec *s = init_server_config(process, p);
1874
1875     init_config_globals(p);
1876
1877     /* All server-wide config files now have the SAME syntax... */
1878     error = process_command_config(s, ap_server_pre_read_config, conftree,
1879                                    p, ptemp);
1880     if (error) {
1881         ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, 0, NULL, "%s: %s",
1882                      ap_server_argv0, error);
1883         return NULL;
1884     }
1885
1886     /* process_command_config may change the ServerRoot so
1887      * compute this config file name afterwards.
1888      */
1889     confname = ap_server_root_relative(p, filename);
1890
1891     if (!confname) {
1892         ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT,
1893                      APR_EBADPATH, NULL, "Invalid config file path %s",
1894                      filename);
1895         return NULL;
1896     }
1897
1898     error = ap_process_resource_config(s, confname, conftree, p, ptemp);
1899     if (error) {
1900         ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, 0, NULL,
1901                      "%s: %s", ap_server_argv0, error);
1902         return NULL;
1903     }
1904
1905     error = process_command_config(s, ap_server_post_read_config, conftree,
1906                                    p, ptemp);
1907
1908     if (error) {
1909         ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, 0, NULL, "%s: %s",
1910                      ap_server_argv0, error);
1911         return NULL;
1912     }
1913
1914     return s;
1915 }
1916
1917 AP_DECLARE(void) ap_single_module_configure(apr_pool_t *p, server_rec *s,
1918                                             module *m)
1919 {
1920     if (m->create_server_config)
1921         ap_set_module_config(s->module_config, m,
1922                              (*m->create_server_config)(p, s));
1923
1924     if (m->create_dir_config)
1925         ap_set_module_config(s->lookup_defaults, m,
1926                              (*m->create_dir_config)(p, NULL));
1927 }
1928
1929 AP_DECLARE(void) ap_run_rewrite_args(process_rec *process)
1930 {
1931     module *m;
1932
1933     for (m = ap_top_module; m; m = m->next) {
1934         if (m->rewrite_args) {
1935             (*m->rewrite_args)(process);
1936         }
1937     }
1938 }
1939
1940 /********************************************************************
1941  * Configuration directives are restricted in terms of where they may
1942  * appear in the main configuration files and/or .htaccess files according
1943  * to the bitmask req_override in the command_rec structure.
1944  * If any of the overrides set in req_override are also allowed in the
1945  * context in which the command is read, then the command is allowed.
1946  * The context is determined as follows:
1947  *
1948  *    inside *.conf --> override = (RSRC_CONF|OR_ALL)&~(OR_AUTHCFG|OR_LIMIT);
1949  *    within <Directory> or <Location> --> override = OR_ALL|ACCESS_CONF;
1950  *    within .htaccess --> override = AllowOverride for current directory;
1951  *
1952  * the result is, well, a rather confusing set of possibilities for when
1953  * a particular directive is allowed to be used.  This procedure prints
1954  * in English where the given (pc) directive can be used.
1955  */
1956 static void show_overrides(const command_rec *pc, module *pm)
1957 {
1958     int n = 0;
1959
1960     printf("\tAllowed in *.conf ");
1961     if ((pc->req_override & (OR_OPTIONS | OR_FILEINFO | OR_INDEXES))
1962         || ((pc->req_override & RSRC_CONF)
1963         && ((pc->req_override & (ACCESS_CONF | OR_AUTHCFG | OR_LIMIT))))) {
1964         printf("anywhere");
1965     }
1966     else if (pc->req_override & RSRC_CONF) {
1967         printf("only outside <Directory>, <Files> or <Location>");
1968     }
1969     else {
1970         printf("only inside <Directory>, <Files> or <Location>");
1971     }
1972
1973     /* Warn if the directive is allowed inside <Directory> or .htaccess
1974      * but module doesn't support per-dir configuration
1975      */
1976     if ((pc->req_override & (OR_ALL | ACCESS_CONF)) && !pm->create_dir_config)
1977         printf(" [no per-dir config]");
1978
1979     if (pc->req_override & OR_ALL) {
1980         printf(" and in .htaccess\n\twhen AllowOverride");
1981
1982         if ((pc->req_override & OR_ALL) == OR_ALL) {
1983             printf(" isn't None");
1984         }
1985         else {
1986             printf(" includes ");
1987
1988             if (pc->req_override & OR_AUTHCFG) {
1989                 if (n++)
1990                     printf(" or ");
1991
1992                 printf("AuthConfig");
1993             }
1994
1995             if (pc->req_override & OR_LIMIT) {
1996                 if (n++)
1997                     printf(" or ");
1998
1999                 printf("Limit");
2000             }
2001
2002             if (pc->req_override & OR_OPTIONS) {
2003                 if (n++)
2004                     printf(" or ");
2005
2006                 printf("Options");
2007             }
2008
2009             if (pc->req_override & OR_FILEINFO) {
2010                 if (n++)
2011                     printf(" or ");
2012
2013                 printf("FileInfo");
2014             }
2015
2016             if (pc->req_override & OR_INDEXES) {
2017                 if (n++)
2018                     printf(" or ");
2019
2020                 printf("Indexes");
2021             }
2022         }
2023     }
2024
2025     printf("\n");
2026 }
2027
2028 /* Show the preloaded configuration directives, the help string explaining
2029  * the directive arguments, in what module they are handled, and in
2030  * what parts of the configuration they are allowed.  Used for httpd -L.
2031  */
2032 AP_DECLARE(void) ap_show_directives(void)
2033 {
2034     const command_rec *pc;
2035     int n;
2036
2037     for (n = 0; ap_loaded_modules[n]; ++n) {
2038         for (pc = ap_loaded_modules[n]->cmds; pc && pc->name; ++pc) {
2039             printf("%s (%s)\n", pc->name, ap_loaded_modules[n]->name);
2040
2041             if (pc->errmsg)
2042                 printf("\t%s\n", pc->errmsg);
2043
2044             show_overrides(pc, ap_loaded_modules[n]);
2045         }
2046     }
2047 }
2048
2049 /* Show the preloaded module names.  Used for httpd -l. */
2050 AP_DECLARE(void) ap_show_modules(void)
2051 {
2052     int n;
2053
2054     printf("Compiled in modules:\n");
2055     for (n = 0; ap_loaded_modules[n]; ++n)
2056         printf("  %s\n", ap_loaded_modules[n]->name);
2057 }
2058
2059 AP_DECLARE(const char *) ap_show_mpm(void)
2060 {
2061     return MPM_NAME;
2062 }