]> granicus.if.org Git - apache/blob - server/config.c
Fold on Jeff's DefaultRuntimeDir impl... docs on the way
[apache] / server / config.c
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
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 #include "ap_config.h"
43 #include "httpd.h"
44 #include "http_config.h"
45 #include "http_protocol.h"
46 #include "http_core.h"
47 #include "http_log.h"      /* for errors in parse_htaccess */
48 #include "http_request.h"  /* for default_handler (see invoke_handler) */
49 #include "http_main.h"
50 #include "http_vhost.h"
51 #include "util_cfgtree.h"
52 #include "util_varbuf.h"
53 #include "mpm_common.h"
54
55 #define APLOG_UNSET   (APLOG_NO_MODULE - 1)
56 /* we know core's module_index is 0 */
57 #undef APLOG_MODULE_INDEX
58 #define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
59
60 AP_DECLARE_DATA const char *ap_server_argv0 = NULL;
61 AP_DECLARE_DATA const char *ap_server_root = NULL;
62 AP_DECLARE_DATA const char *ap_runtime_dir = NULL;
63 AP_DECLARE_DATA server_rec *ap_server_conf = NULL;
64 AP_DECLARE_DATA apr_pool_t *ap_pglobal = NULL;
65
66 AP_DECLARE_DATA apr_array_header_t *ap_server_pre_read_config = NULL;
67 AP_DECLARE_DATA apr_array_header_t *ap_server_post_read_config = NULL;
68 AP_DECLARE_DATA apr_array_header_t *ap_server_config_defines = NULL;
69
70 AP_DECLARE_DATA ap_directive_t *ap_conftree = NULL;
71
72 APR_HOOK_STRUCT(
73            APR_HOOK_LINK(header_parser)
74            APR_HOOK_LINK(pre_config)
75            APR_HOOK_LINK(check_config)
76            APR_HOOK_LINK(post_config)
77            APR_HOOK_LINK(open_logs)
78            APR_HOOK_LINK(child_init)
79            APR_HOOK_LINK(handler)
80            APR_HOOK_LINK(quick_handler)
81            APR_HOOK_LINK(optional_fn_retrieve)
82            APR_HOOK_LINK(test_config)
83 )
84
85 AP_IMPLEMENT_HOOK_RUN_ALL(int, header_parser,
86                           (request_rec *r), (r), OK, DECLINED)
87
88 AP_IMPLEMENT_HOOK_RUN_ALL(int, pre_config,
89                           (apr_pool_t *pconf, apr_pool_t *plog,
90                            apr_pool_t *ptemp),
91                           (pconf, plog, ptemp), OK, DECLINED)
92
93 AP_IMPLEMENT_HOOK_RUN_ALL(int, check_config,
94                           (apr_pool_t *pconf, apr_pool_t *plog,
95                            apr_pool_t *ptemp, server_rec *s),
96                           (pconf, plog, ptemp, s), OK, DECLINED)
97
98 AP_IMPLEMENT_HOOK_VOID(test_config,
99                        (apr_pool_t *pconf, server_rec *s),
100                        (pconf, s))
101
102 AP_IMPLEMENT_HOOK_RUN_ALL(int, post_config,
103                           (apr_pool_t *pconf, apr_pool_t *plog,
104                            apr_pool_t *ptemp, server_rec *s),
105                           (pconf, plog, ptemp, s), OK, DECLINED)
106
107 /* During the course of debugging I expanded this macro out, so
108  * rather than remove all the useful information there is in the
109  * following lines, I'm going to leave it here in case anyone
110  * else finds it useful.
111  *
112  * Ben has looked at it and thinks it correct :)
113  *
114 AP_DECLARE(int) ap_hook_post_config(ap_HOOK_post_config_t *pf,
115                                     const char * const *aszPre,
116                                     const char * const *aszSucc,
117                                     int nOrder)
118 {
119     ap_LINK_post_config_t *pHook;
120
121     if (!_hooks.link_post_config) {
122         _hooks.link_post_config = apr_array_make(apr_hook_global_pool, 1,
123                                                  sizeof(ap_LINK_post_config_t));
124         apr_hook_sort_register("post_config", &_hooks.link_post_config);
125     }
126
127     pHook = apr_array_push(_hooks.link_post_config);
128     pHook->pFunc = pf;
129     pHook->aszPredecessors = aszPre;
130     pHook->aszSuccessors = aszSucc;
131     pHook->nOrder = nOrder;
132     pHook->szName = apr_hook_debug_current;
133
134     if (apr_hook_debug_enabled)
135         apr_hook_debug_show("post_config", aszPre, aszSucc);
136 }
137
138 AP_DECLARE(apr_array_header_t *) ap_hook_get_post_config(void) {
139     return _hooks.link_post_config;
140 }
141
142 AP_DECLARE(int) ap_run_post_config(apr_pool_t *pconf,
143                                    apr_pool_t *plog,
144                                    apr_pool_t *ptemp,
145                                    server_rec *s)
146 {
147     ap_LINK_post_config_t *pHook;
148     int n;
149
150     if(!_hooks.link_post_config)
151         return;
152
153     pHook = (ap_LINK_post_config_t *)_hooks.link_post_config->elts;
154     for (n = 0; n < _hooks.link_post_config->nelts; ++n)
155         pHook[n].pFunc (pconf, plog, ptemp, s);
156 }
157  */
158
159 AP_IMPLEMENT_HOOK_RUN_ALL(int, open_logs,
160                           (apr_pool_t *pconf, apr_pool_t *plog,
161                            apr_pool_t *ptemp, server_rec *s),
162                           (pconf, plog, ptemp, s), OK, DECLINED)
163
164 AP_IMPLEMENT_HOOK_VOID(child_init,
165                        (apr_pool_t *pchild, server_rec *s),
166                        (pchild, s))
167
168 AP_IMPLEMENT_HOOK_RUN_FIRST(int, handler, (request_rec *r),
169                             (r), DECLINED)
170
171 AP_IMPLEMENT_HOOK_RUN_FIRST(int, quick_handler, (request_rec *r, int lookup),
172                             (r, lookup), DECLINED)
173
174 /* hooks with no args are implemented last, after disabling APR hook probes */
175 #if defined(APR_HOOK_PROBES_ENABLED)
176 #undef APR_HOOK_PROBES_ENABLED
177 #undef APR_HOOK_PROBE_ENTRY
178 #define APR_HOOK_PROBE_ENTRY(ud,ns,name,args)
179 #undef APR_HOOK_PROBE_RETURN
180 #define APR_HOOK_PROBE_RETURN(ud,ns,name,rv,args)
181 #undef APR_HOOK_PROBE_INVOKE
182 #define APR_HOOK_PROBE_INVOKE(ud,ns,name,src,args)
183 #undef APR_HOOK_PROBE_COMPLETE
184 #define APR_HOOK_PROBE_COMPLETE(ud,ns,name,src,rv,args)
185 #undef APR_HOOK_INT_DCL_UD
186 #define APR_HOOK_INT_DCL_UD
187 #endif
188 AP_IMPLEMENT_HOOK_VOID(optional_fn_retrieve, (void), ())
189
190 /****************************************************************
191  *
192  * We begin with the functions which deal with the linked list
193  * of modules which control just about all of the server operation.
194  */
195
196 /* total_modules is the number of modules that have been linked
197  * into the server.
198  */
199 static int total_modules = 0;
200
201 /* dynamic_modules is the number of modules that have been added
202  * after the pre-loaded ones have been set up. It shouldn't be larger
203  * than DYNAMIC_MODULE_LIMIT.
204  */
205 static int dynamic_modules = 0;
206
207 /* The maximum possible value for total_modules, i.e. number of static
208  * modules plus DYNAMIC_MODULE_LIMIT.
209  */
210 static int max_modules = 0;
211
212 /* The number of elements we need to alloc for config vectors. Before loading
213  * of dynamic modules, we must be liberal and set this to max_modules. After
214  * loading of dynamic modules, we can trim it down to total_modules. On
215  * restart, reset to max_modules.
216  */
217 static int conf_vector_length = 0;
218
219 static int reserved_module_slots = 0;
220
221 AP_DECLARE_DATA module *ap_top_module = NULL;
222 AP_DECLARE_DATA module **ap_loaded_modules=NULL;
223
224 static apr_hash_t *ap_config_hash = NULL;
225
226 /* a list of the module symbol names with the trailing "_module"removed */
227 static char **ap_module_short_names = NULL;
228
229 typedef int (*handler_func)(request_rec *);
230 typedef void *(*dir_maker_func)(apr_pool_t *, char *);
231 typedef void *(*merger_func)(apr_pool_t *, void *, void *);
232
233 /* A list of the merge_dir_config functions of all loaded modules, sorted
234  * by module_index.
235  * Using this list in ap_merge_per_dir_configs() is faster than following
236  * the module->next linked list because of better memory locality (resulting
237  * in better cache usage).
238  */
239 static merger_func *merger_func_cache;
240
241 /* maximum nesting level for config directories */
242 #ifndef AP_MAX_INCLUDE_DIR_DEPTH
243 #define AP_MAX_INCLUDE_DIR_DEPTH (128)
244 #endif
245
246 /* Dealing with config vectors.  These are associated with per-directory,
247  * per-server, and per-request configuration, and have a void* pointer for
248  * each modules.  The nature of the structure pointed to is private to the
249  * module in question... the core doesn't (and can't) know.  However, there
250  * are defined interfaces which allow it to create instances of its private
251  * per-directory and per-server structures, and to merge the per-directory
252  * structures of a directory and its subdirectory (producing a new one in
253  * which the defaults applying to the base directory have been properly
254  * overridden).
255  */
256
257 static ap_conf_vector_t *create_empty_config(apr_pool_t *p)
258 {
259     void *conf_vector = apr_pcalloc(p, sizeof(void *) * conf_vector_length);
260     return conf_vector;
261 }
262
263 static ap_conf_vector_t *create_default_per_dir_config(apr_pool_t *p)
264 {
265     void **conf_vector = apr_pcalloc(p, sizeof(void *) * conf_vector_length);
266     module *modp;
267
268     for (modp = ap_top_module; modp; modp = modp->next) {
269         dir_maker_func df = modp->create_dir_config;
270
271         if (df)
272             conf_vector[modp->module_index] = (*df)(p, NULL);
273     }
274
275     return (ap_conf_vector_t *)conf_vector;
276 }
277
278 AP_CORE_DECLARE(ap_conf_vector_t *) ap_merge_per_dir_configs(apr_pool_t *p,
279                                            ap_conf_vector_t *base,
280                                            ap_conf_vector_t *new_conf)
281 {
282     void **conf_vector = apr_palloc(p, sizeof(void *) * conf_vector_length);
283     void **base_vector = (void **)base;
284     void **new_vector = (void **)new_conf;
285     int i;
286
287     for (i = 0; i < total_modules; i++) {
288         if (!new_vector[i]) {
289             conf_vector[i] = base_vector[i];
290         }
291         else {
292             const merger_func df = merger_func_cache[i];
293             if (df && base_vector[i]) {
294                 conf_vector[i] = (*df)(p, base_vector[i], new_vector[i]);
295             }
296             else
297                 conf_vector[i] = new_vector[i];
298         }
299     }
300
301     return (ap_conf_vector_t *)conf_vector;
302 }
303
304 static ap_conf_vector_t *create_server_config(apr_pool_t *p, server_rec *s)
305 {
306     void **conf_vector = apr_pcalloc(p, sizeof(void *) * conf_vector_length);
307     module *modp;
308
309     for (modp = ap_top_module; modp; modp = modp->next) {
310         if (modp->create_server_config)
311             conf_vector[modp->module_index] = (*modp->create_server_config)(p, s);
312     }
313
314     return (ap_conf_vector_t *)conf_vector;
315 }
316
317 static void merge_server_configs(apr_pool_t *p, ap_conf_vector_t *base,
318                                  ap_conf_vector_t *virt)
319 {
320     /* Can reuse the 'virt' vector for the spine of it, since we don't
321      * have to deal with the moral equivalent of .htaccess files here...
322      */
323
324     void **base_vector = (void **)base;
325     void **virt_vector = (void **)virt;
326     module *modp;
327
328     for (modp = ap_top_module; modp; modp = modp->next) {
329         merger_func df = modp->merge_server_config;
330         int i = modp->module_index;
331
332         if (!virt_vector[i])
333             virt_vector[i] = base_vector[i];
334         else if (df)
335             virt_vector[i] = (*df)(p, base_vector[i], virt_vector[i]);
336     }
337 }
338
339 AP_CORE_DECLARE(ap_conf_vector_t *) ap_create_request_config(apr_pool_t *p)
340 {
341     return create_empty_config(p);
342 }
343
344 AP_CORE_DECLARE(ap_conf_vector_t *) ap_create_conn_config(apr_pool_t *p)
345 {
346     return create_empty_config(p);
347 }
348
349 AP_CORE_DECLARE(ap_conf_vector_t *) ap_create_per_dir_config(apr_pool_t *p)
350 {
351     return create_empty_config(p);
352 }
353
354 /* Invoke the filter_init_func for all filters with FILTERS where f->r
355  * matches R.  Restricting to a matching R avoids re-running init
356  * functions for filters configured for r->main where r is a
357  * subrequest.  */
358 static int invoke_filter_init(request_rec *r, ap_filter_t *filters)
359 {
360     while (filters) {
361         if (filters->frec->filter_init_func && filters->r == r) {
362             int result = filters->frec->filter_init_func(filters);
363             if (result != OK) {
364                 return result;
365             }
366         }
367         filters = filters->next;
368     }
369     return OK;
370 }
371
372 /*
373  * TODO: Move this to an appropriate include file and possibly prefix it
374  * with AP_.
375  */
376 #define DEFAULT_HANDLER_NAME ""
377
378 AP_CORE_DECLARE(int) ap_invoke_handler(request_rec *r)
379 {
380     const char *handler;
381     const char *p;
382     int result;
383     const char *old_handler = r->handler;
384     const char *ignore;
385
386     /*
387      * The new insert_filter stage makes the most sense here.  We only use
388      * it when we are going to run the request, so we must insert filters
389      * if any are available.  Since the goal of this phase is to allow all
390      * modules to insert a filter if they want to, this filter returns
391      * void.  I just can't see any way that this filter can reasonably
392      * fail, either your modules inserts something or it doesn't.  rbb
393      */
394     ap_run_insert_filter(r);
395
396     /* Before continuing, allow each filter that is in the two chains to
397      * run their init function to let them do any magic before we could
398      * start generating data.
399      */
400     result = invoke_filter_init(r, r->input_filters);
401     if (result != OK) {
402         return result;
403     }
404     result = invoke_filter_init(r, r->output_filters);
405     if (result != OK) {
406         return result;
407     }
408
409     if (!r->handler) {
410         if (r->content_type) {
411             handler = r->content_type;
412             if ((p=ap_strchr_c(handler, ';')) != NULL) {
413                 char *new_handler = (char *)apr_pmemdup(r->pool, handler,
414                                                         p - handler + 1);
415                 char *p2 = new_handler + (p - handler);
416                 handler = new_handler;
417
418                 /* exclude media type arguments */
419                 while (p2 > handler && p2[-1] == ' ')
420                     --p2; /* strip trailing spaces */
421
422                 *p2='\0';
423             }
424         }
425         else {
426             handler = DEFAULT_HANDLER_NAME;
427         }
428
429         r->handler = handler;
430     }
431
432     result = ap_run_handler(r);
433
434     r->handler = old_handler;
435
436     if (result == DECLINED && r->handler && r->filename) {
437         ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(00523)
438             "handler \"%s\" not found for: %s", r->handler, r->filename);
439     }
440     if ((result != OK) && (result != DONE) && (result != DECLINED) && (result != SUSPENDED)
441         && (result != AP_FILTER_ERROR) /* ap_die() knows about this specifically */
442         && !ap_is_HTTP_VALID_RESPONSE(result)) {
443         /* If a module is deliberately returning something else
444          * (request_rec in non-HTTP or proprietary extension?)
445          * let it set a note to allow it explicitly.
446          * Otherwise, a return code that is neither reserved nor HTTP
447          * is a bug, as in PR#31759.
448          */
449         ignore = apr_table_get(r->notes, "HTTP_IGNORE_RANGE");
450         if (!ignore) {
451             ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00524)
452                           "Handler for %s returned invalid result code %d",
453                           r->handler, result);
454             result = HTTP_INTERNAL_SERVER_ERROR;
455         }
456     }
457
458     return result == DECLINED ? HTTP_INTERNAL_SERVER_ERROR : result;
459 }
460
461 AP_DECLARE(int) ap_method_is_limited(cmd_parms *cmd, const char *method)
462 {
463     int methnum;
464
465     methnum = ap_method_number_of(method);
466
467     /*
468      * A method number either hardcoded into apache or
469      * added by a module and registered.
470      */
471     if (methnum != M_INVALID) {
472         return (cmd->limited & (AP_METHOD_BIT << methnum)) ? 1 : 0;
473     }
474
475     return 0; /* not found */
476 }
477
478 AP_DECLARE(void) ap_register_hooks(module *m, apr_pool_t *p)
479 {
480     if (m->register_hooks) {
481         if (getenv("SHOW_HOOKS")) {
482             printf("Registering hooks for %s\n", m->name);
483             apr_hook_debug_enabled = 1;
484         }
485
486         apr_hook_debug_current = m->name;
487         m->register_hooks(p);
488     }
489 }
490
491 static void ap_add_module_commands(module *m, apr_pool_t *p);
492
493 typedef struct ap_mod_list_struct ap_mod_list;
494 struct ap_mod_list_struct {
495     struct ap_mod_list_struct *next;
496     module *m;
497     const command_rec *cmd;
498 };
499
500 static void rebuild_conf_hash(apr_pool_t *p, int add_prelinked)
501 {
502     module **m;
503
504     ap_config_hash = apr_hash_make(p);
505
506     apr_pool_cleanup_register(p, &ap_config_hash, ap_pool_cleanup_set_null,
507                               apr_pool_cleanup_null);
508     if (add_prelinked) {
509         for (m = ap_prelinked_modules; *m != NULL; m++) {
510             ap_add_module_commands(*m, p);
511         }
512     }
513 }
514
515 static void ap_add_module_commands(module *m, apr_pool_t *p)
516 {
517     apr_pool_t *tpool;
518     ap_mod_list *mln;
519     const command_rec *cmd;
520     char *dir;
521
522     cmd = m->cmds;
523
524     if (ap_config_hash == NULL) {
525         rebuild_conf_hash(p, 0);
526     }
527
528     tpool = apr_hash_pool_get(ap_config_hash);
529
530     while (cmd && cmd->name) {
531         mln = apr_palloc(tpool, sizeof(ap_mod_list));
532         mln->cmd = cmd;
533         mln->m = m;
534         dir = apr_pstrdup(tpool, cmd->name);
535
536         ap_str_tolower(dir);
537
538         mln->next = apr_hash_get(ap_config_hash, dir, APR_HASH_KEY_STRING);
539         apr_hash_set(ap_config_hash, dir, APR_HASH_KEY_STRING, mln);
540         ++cmd;
541     }
542 }
543
544
545 /* One-time setup for precompiled modules --- NOT to be done on restart */
546
547 AP_DECLARE(const char *) ap_add_module(module *m, apr_pool_t *p,
548                                        const char *sym_name)
549 {
550     ap_module_symbol_t *sym = ap_prelinked_module_symbols;
551
552     /* This could be called from a LoadModule httpd.conf command,
553      * after the file has been linked and the module structure within it
554      * teased out...
555      */
556
557     if (m->version != MODULE_MAGIC_NUMBER_MAJOR) {
558         return apr_psprintf(p, "Module \"%s\" is not compatible with this "
559                             "version of Apache (found %d, need %d). Please "
560                             "contact the vendor for the correct version.",
561                             m->name, m->version, MODULE_MAGIC_NUMBER_MAJOR);
562     }
563
564     if (m->module_index == -1) {
565         if (dynamic_modules >= DYNAMIC_MODULE_LIMIT) {
566             return apr_psprintf(p, "Module \"%s\" could not be loaded, "
567                                 "because the dynamic module limit was "
568                                 "reached. Please increase "
569                                 "DYNAMIC_MODULE_LIMIT and recompile.", m->name);
570         }
571         /*
572          * If this fails some module forgot to call ap_reserve_module_slots*.
573          */
574         ap_assert(total_modules < conf_vector_length);
575
576         m->module_index = total_modules++;
577         dynamic_modules++;
578
579     }
580     else if (!sym_name) {
581         while (sym->modp != NULL) {
582             if (sym->modp == m) {
583                 sym_name = sym->name;
584                 break;
585             }
586             sym++;
587         }
588     }
589
590     if (m->next == NULL) {
591         m->next = ap_top_module;
592         ap_top_module = m;
593     }
594
595     if (sym_name) {
596         int len = strlen(sym_name);
597         int slen = strlen("_module");
598         if (len > slen && !strcmp(sym_name + len - slen, "_module")) {
599             len -= slen;
600         }
601
602         ap_module_short_names[m->module_index] = strdup(sym_name);
603         ap_module_short_names[m->module_index][len] = '\0';
604         merger_func_cache[m->module_index] = m->merge_dir_config;
605     }
606
607
608     /* Some C compilers put a complete path into __FILE__, but we want
609      * only the filename (e.g. mod_includes.c). So check for path
610      * components (Unix and DOS), and remove them.
611      */
612
613     if (ap_strrchr_c(m->name, '/'))
614         m->name = 1 + ap_strrchr_c(m->name, '/');
615
616     if (ap_strrchr_c(m->name, '\\'))
617         m->name = 1 + ap_strrchr_c(m->name, '\\');
618
619 #ifdef _OSD_POSIX
620     /* __FILE__ =
621      * "*POSIX(/home/martin/apache/src/modules/standard/mod_info.c)"
622      */
623
624     /* We cannot fix the string in-place, because it's const */
625     if (m->name[strlen(m->name)-1] == ')') {
626         char *tmp = strdup(m->name); /* FIXME: memory leak, albeit a small one */
627         tmp[strlen(tmp)-1] = '\0';
628         m->name = tmp;
629     }
630 #endif /*_OSD_POSIX*/
631
632     ap_add_module_commands(m, p);
633     /*  FIXME: is this the right place to call this?
634      *  It doesn't appear to be
635      */
636     ap_register_hooks(m, p);
637
638     return NULL;
639 }
640
641 /*
642  * remove_module undoes what add_module did. There are some caveats:
643  * when the module is removed, its slot is lost so all the current
644  * per-dir and per-server configurations are invalid. So we should
645  * only ever call this function when you are invalidating almost
646  * all our current data. I.e. when doing a restart.
647  */
648
649 AP_DECLARE(void) ap_remove_module(module *m)
650 {
651     module *modp;
652
653     modp = ap_top_module;
654     if (modp == m) {
655         /* We are the top module, special case */
656         ap_top_module = modp->next;
657         m->next = NULL;
658     }
659     else {
660         /* Not the top module, find use. When found modp will
661          * point to the module _before_ us in the list
662          */
663
664         while (modp && modp->next != m) {
665             modp = modp->next;
666         }
667
668         if (!modp) {
669             /* Uh-oh, this module doesn't exist */
670             ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, APLOGNO(00525)
671                          "Cannot remove module %s: not found in module list",
672                          m->name);
673             return;
674         }
675
676         /* Eliminate us from the module list */
677         modp->next = modp->next->next;
678     }
679
680     free(ap_module_short_names[m->module_index]);
681     ap_module_short_names[m->module_index] = NULL;
682     merger_func_cache[m->module_index] = NULL;
683
684     m->module_index = -1; /* simulate being unloaded, should
685                            * be unnecessary */
686     dynamic_modules--;
687     total_modules--;
688 }
689
690 AP_DECLARE(const char *) ap_add_loaded_module(module *mod, apr_pool_t *p,
691                                               const char *short_name)
692 {
693     module **m;
694     const char *error;
695
696     /*
697      *  Add module pointer to top of chained module list
698      */
699     error = ap_add_module(mod, p, short_name);
700     if (error) {
701         return error;
702     }
703
704     /*
705      *  And module pointer to list of loaded modules
706      *
707      *  Notes: 1. ap_add_module() would already complain if no more space
708      *            exists for adding a dynamically loaded module
709      *         2. ap_add_module() accepts double inclusion, so we have
710      *            to accept this, too.
711      */
712     for (m = ap_loaded_modules; *m != NULL; m++)
713         ;
714     *m++ = mod;
715     *m = NULL;
716
717     return NULL;
718 }
719
720 AP_DECLARE(void) ap_remove_loaded_module(module *mod)
721 {
722     module **m;
723     module **m2;
724     int done;
725
726     /*
727      *  Remove module pointer from chained module list
728      */
729     ap_remove_module(mod);
730
731     /*
732      *  Remove module pointer from list of loaded modules
733      *
734      *  Note: 1. We cannot determine if the module was successfully
735      *           removed by ap_remove_module().
736      *        2. We have not to complain explicity when the module
737      *           is not found because ap_remove_module() did it
738      *           for us already.
739      */
740     for (m = m2 = ap_loaded_modules, done = 0; *m2 != NULL; m2++) {
741         if (*m2 == mod && done == 0)
742             done = 1;
743         else
744             *m++ = *m2;
745     }
746
747     *m = NULL;
748 }
749
750 AP_DECLARE(const char *) ap_setup_prelinked_modules(process_rec *process)
751 {
752     module **m;
753     module **m2;
754     const char *error;
755
756     apr_hook_global_pool=process->pconf;
757
758     rebuild_conf_hash(process->pconf, 0);
759
760     /*
761      *  Initialise total_modules variable and module indices
762      */
763     total_modules = 0;
764     for (m = ap_preloaded_modules; *m != NULL; m++)
765         (*m)->module_index = total_modules++;
766
767     max_modules = total_modules + DYNAMIC_MODULE_LIMIT + 1;
768     conf_vector_length = max_modules;
769
770     /*
771      *  Initialise list of loaded modules and short names
772      */
773     ap_loaded_modules = (module **)apr_palloc(process->pool,
774         sizeof(module *) * conf_vector_length);
775     if (!ap_module_short_names)
776         ap_module_short_names = ap_calloc(sizeof(char *), conf_vector_length);
777
778     if (!merger_func_cache)
779         merger_func_cache = ap_calloc(sizeof(merger_func), conf_vector_length);
780
781     if (ap_loaded_modules == NULL || ap_module_short_names == NULL
782         || merger_func_cache == NULL)
783         return "Ouch! Out of memory in ap_setup_prelinked_modules()!";
784
785     for (m = ap_preloaded_modules, m2 = ap_loaded_modules; *m != NULL; )
786         *m2++ = *m++;
787
788     *m2 = NULL;
789
790     /*
791      *   Initialize chain of linked (=activate) modules
792      */
793     for (m = ap_prelinked_modules; *m != NULL; m++) {
794         error = ap_add_module(*m, process->pconf, NULL);
795         if (error) {
796             return error;
797         }
798     }
799
800     apr_hook_sort_all();
801
802     return NULL;
803 }
804
805 AP_DECLARE(const char *) ap_find_module_name(module *m)
806 {
807     return m->name;
808 }
809
810 AP_DECLARE(const char *) ap_find_module_short_name(int module_index)
811 {
812         if (module_index < 0 || module_index >= conf_vector_length)
813                 return NULL;
814         return ap_module_short_names[module_index];
815 }
816
817 AP_DECLARE(module *) ap_find_linked_module(const char *name)
818 {
819     module *modp;
820
821     for (modp = ap_top_module; modp; modp = modp->next) {
822         if (strcmp(modp->name, name) == 0)
823             return modp;
824     }
825
826     return NULL;
827 }
828
829 /*****************************************************************
830  *
831  * Resource, access, and .htaccess config files now parsed by a common
832  * command loop.
833  *
834  * Let's begin with the basics; parsing the line and
835  * invoking the function...
836  */
837
838 #define AP_MAX_ARGC 64
839
840 static const char *invoke_cmd(const command_rec *cmd, cmd_parms *parms,
841                               void *mconfig, const char *args)
842 {
843     int override_list_ok = 0;
844     char *w, *w2, *w3;
845     const char *errmsg = NULL;
846
847     /** Have we been provided a list of acceptable directives? */
848     if(parms->override_list != NULL)
849          if(apr_table_get(parms->override_list, cmd->name) != NULL)
850               override_list_ok = 1;
851
852     if ((parms->override & cmd->req_override) == 0 && !override_list_ok) {
853         if (parms->override & NONFATAL_OVERRIDE) {
854             ap_log_perror(APLOG_MARK, APLOG_WARNING, 0, parms->temp_pool,
855                           APLOGNO(02295)
856                           "%s in .htaccess forbidden by AllowOverride",
857                           cmd->name);
858             return NULL;
859         }
860         else {
861             return apr_pstrcat(parms->pool, cmd->name,
862                                " not allowed here", NULL);
863         }
864     }
865
866     parms->info = cmd->cmd_data;
867     parms->cmd = cmd;
868
869     switch (cmd->args_how) {
870     case RAW_ARGS:
871 #ifdef RESOLVE_ENV_PER_TOKEN
872         args = ap_resolve_env(parms->pool,args);
873 #endif
874         return cmd->AP_RAW_ARGS(parms, mconfig, args);
875
876     case TAKE_ARGV:
877         {
878             char *argv[AP_MAX_ARGC];
879             int argc = 0;
880
881             do {
882                 w = ap_getword_conf(parms->pool, &args);
883                 if (*w == '\0' && *args == '\0') {
884                     break;
885                 }
886                 argv[argc] = w;
887                 argc++;
888             } while (argc < AP_MAX_ARGC && *args != '\0');
889
890             return cmd->AP_TAKE_ARGV(parms, mconfig, argc, argv);
891         }
892
893     case NO_ARGS:
894         if (*args != 0)
895             return apr_pstrcat(parms->pool, cmd->name, " takes no arguments",
896                                NULL);
897
898         return cmd->AP_NO_ARGS(parms, mconfig);
899
900     case TAKE1:
901         w = ap_getword_conf(parms->pool, &args);
902
903         if (*w == '\0' || *args != 0)
904             return apr_pstrcat(parms->pool, cmd->name, " takes one argument",
905                                cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
906
907         return cmd->AP_TAKE1(parms, mconfig, w);
908
909     case TAKE2:
910         w = ap_getword_conf(parms->pool, &args);
911         w2 = ap_getword_conf(parms->pool, &args);
912
913         if (*w == '\0' || *w2 == '\0' || *args != 0)
914             return apr_pstrcat(parms->pool, cmd->name, " takes two arguments",
915                                cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
916
917         return cmd->AP_TAKE2(parms, mconfig, w, w2);
918
919     case TAKE12:
920         w = ap_getword_conf(parms->pool, &args);
921         w2 = ap_getword_conf(parms->pool, &args);
922
923         if (*w == '\0' || *args != 0)
924             return apr_pstrcat(parms->pool, cmd->name, " takes 1-2 arguments",
925                                cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
926
927         return cmd->AP_TAKE2(parms, mconfig, w, *w2 ? w2 : NULL);
928
929     case TAKE3:
930         w = ap_getword_conf(parms->pool, &args);
931         w2 = ap_getword_conf(parms->pool, &args);
932         w3 = ap_getword_conf(parms->pool, &args);
933
934         if (*w == '\0' || *w2 == '\0' || *w3 == '\0' || *args != 0)
935             return apr_pstrcat(parms->pool, cmd->name, " takes three arguments",
936                                cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
937
938         return cmd->AP_TAKE3(parms, mconfig, w, w2, w3);
939
940     case TAKE23:
941         w = ap_getword_conf(parms->pool, &args);
942         w2 = ap_getword_conf(parms->pool, &args);
943         w3 = *args ? ap_getword_conf(parms->pool, &args) : NULL;
944
945         if (*w == '\0' || *w2 == '\0' || *args != 0)
946             return apr_pstrcat(parms->pool, cmd->name,
947                                " takes two or three arguments",
948                                cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
949
950         return cmd->AP_TAKE3(parms, mconfig, w, w2, w3);
951
952     case TAKE123:
953         w = ap_getword_conf(parms->pool, &args);
954         w2 = *args ? ap_getword_conf(parms->pool, &args) : NULL;
955         w3 = *args ? ap_getword_conf(parms->pool, &args) : NULL;
956
957         if (*w == '\0' || *args != 0)
958             return apr_pstrcat(parms->pool, cmd->name,
959                                " takes one, two or three arguments",
960                                cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
961
962         return cmd->AP_TAKE3(parms, mconfig, w, w2, w3);
963
964     case TAKE13:
965         w = ap_getword_conf(parms->pool, &args);
966         w2 = *args ? ap_getword_conf(parms->pool, &args) : NULL;
967         w3 = *args ? ap_getword_conf(parms->pool, &args) : NULL;
968
969         if (*w == '\0' || (w2 && *w2 && !w3) || *args != 0)
970             return apr_pstrcat(parms->pool, cmd->name,
971                                " takes one or three arguments",
972                                cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
973
974         return cmd->AP_TAKE3(parms, mconfig, w, w2, w3);
975
976     case ITERATE:
977         while (*(w = ap_getword_conf(parms->pool, &args)) != '\0') {
978
979             errmsg = cmd->AP_TAKE1(parms, mconfig, w);
980
981             if (errmsg && strcmp(errmsg, DECLINE_CMD) != 0)
982                 return errmsg;
983         }
984
985         return errmsg;
986
987     case ITERATE2:
988         w = ap_getword_conf(parms->pool, &args);
989
990         if (*w == '\0' || *args == 0)
991             return apr_pstrcat(parms->pool, cmd->name,
992                                " requires at least two arguments",
993                                cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
994
995         while (*(w2 = ap_getword_conf(parms->pool, &args)) != '\0') {
996
997             errmsg = cmd->AP_TAKE2(parms, mconfig, w, w2);
998
999             if (errmsg && strcmp(errmsg, DECLINE_CMD) != 0)
1000                 return errmsg;
1001         }
1002
1003         return errmsg;
1004
1005     case FLAG:
1006         w = ap_getword_conf(parms->pool, &args);
1007
1008         if (*w == '\0' || (strcasecmp(w, "on") && strcasecmp(w, "off")))
1009             return apr_pstrcat(parms->pool, cmd->name, " must be On or Off",
1010                                NULL);
1011
1012         return cmd->AP_FLAG(parms, mconfig, strcasecmp(w, "off") != 0);
1013
1014     default:
1015         return apr_pstrcat(parms->pool, cmd->name,
1016                            " is improperly configured internally (server bug)",
1017                            NULL);
1018     }
1019 }
1020
1021 AP_CORE_DECLARE(const command_rec *) ap_find_command(const char *name,
1022                                                      const command_rec *cmds)
1023 {
1024     while (cmds->name) {
1025         if (!strcasecmp(name, cmds->name))
1026             return cmds;
1027
1028         ++cmds;
1029     }
1030
1031     return NULL;
1032 }
1033
1034 AP_CORE_DECLARE(const command_rec *) ap_find_command_in_modules(
1035                                           const char *cmd_name, module **mod)
1036 {
1037     const command_rec *cmdp;
1038     module *modp;
1039
1040     for (modp = *mod; modp; modp = modp->next) {
1041         if (modp->cmds && (cmdp = ap_find_command(cmd_name, modp->cmds))) {
1042             *mod = modp;
1043             return cmdp;
1044         }
1045     }
1046
1047     return NULL;
1048 }
1049
1050 AP_CORE_DECLARE(void *) ap_set_config_vectors(server_rec *server,
1051                                               ap_conf_vector_t *section_vector,
1052                                               const char *section,
1053                                               module *mod, apr_pool_t *pconf)
1054 {
1055     void *section_config = ap_get_module_config(section_vector, mod);
1056     void *server_config = ap_get_module_config(server->module_config, mod);
1057
1058     if (!section_config && mod->create_dir_config) {
1059         /* ### need to fix the create_dir_config functions' prototype... */
1060         section_config = (*mod->create_dir_config)(pconf, (char *)section);
1061         ap_set_module_config(section_vector, mod, section_config);
1062     }
1063
1064     if (!server_config && mod->create_server_config) {
1065         server_config = (*mod->create_server_config)(pconf, server);
1066         ap_set_module_config(server->module_config, mod, server_config);
1067     }
1068
1069     return section_config;
1070 }
1071
1072 static const char *execute_now(char *cmd_line, const char *args,
1073                                cmd_parms *parms,
1074                                apr_pool_t *p, apr_pool_t *ptemp,
1075                                ap_directive_t **sub_tree,
1076                                ap_directive_t *parent);
1077
1078 static const char *ap_build_config_sub(apr_pool_t *p, apr_pool_t *temp_pool,
1079                                        const char *l, cmd_parms *parms,
1080                                        ap_directive_t **current,
1081                                        ap_directive_t **curr_parent,
1082                                        ap_directive_t **conftree)
1083 {
1084     const char *retval = NULL;
1085     const char *args;
1086     char *cmd_name;
1087     ap_directive_t *newdir;
1088     module *mod = ap_top_module;
1089     const command_rec *cmd;
1090
1091     if (*l == '#' || *l == '\0')
1092         return NULL;
1093
1094 #if RESOLVE_ENV_PER_TOKEN
1095     args = l;
1096 #else
1097     args = ap_resolve_env(temp_pool, l);
1098 #endif
1099
1100     cmd_name = ap_getword_conf(p, &args);
1101     if (*cmd_name == '\0') {
1102         /* Note: this branch should not occur. An empty line should have
1103          * triggered the exit further above.
1104          */
1105         return NULL;
1106     }
1107
1108     if (cmd_name[1] != '/') {
1109         char *lastc = cmd_name + strlen(cmd_name) - 1;
1110         if (*lastc == '>') {
1111             *lastc = '\0' ;
1112         }
1113         if (cmd_name[0] == '<' && *args == '\0') {
1114             args = ">";
1115         }
1116     }
1117
1118     newdir = apr_pcalloc(p, sizeof(ap_directive_t));
1119     newdir->filename = parms->config_file->name;
1120     newdir->line_num = parms->config_file->line_number;
1121     newdir->directive = cmd_name;
1122     newdir->args = apr_pstrdup(p, args);
1123
1124     if ((cmd = ap_find_command_in_modules(cmd_name, &mod)) != NULL) {
1125         if (cmd->req_override & EXEC_ON_READ) {
1126             ap_directive_t *sub_tree = NULL;
1127
1128             parms->err_directive = newdir;
1129             retval = execute_now(cmd_name, args, parms, p, temp_pool,
1130                                  &sub_tree, *curr_parent);
1131             if (*current) {
1132                 (*current)->next = sub_tree;
1133             }
1134             else {
1135                 *current = sub_tree;
1136                 if (*curr_parent) {
1137                     (*curr_parent)->first_child = (*current);
1138                 }
1139                 if (*current) {
1140                     (*current)->parent = (*curr_parent);
1141                 }
1142             }
1143             if (*current) {
1144                 if (!*conftree) {
1145                     /* Before walking *current to the end of the list,
1146                      * set the head to *current.
1147                      */
1148                     *conftree = *current;
1149                 }
1150                 while ((*current)->next != NULL) {
1151                     (*current) = (*current)->next;
1152                     (*current)->parent = (*curr_parent);
1153                 }
1154             }
1155             return retval;
1156         }
1157     }
1158
1159     if (cmd_name[0] == '<') {
1160         if (cmd_name[1] != '/') {
1161             (*current) = ap_add_node(curr_parent, *current, newdir, 1);
1162         }
1163         else if (*curr_parent == NULL) {
1164             parms->err_directive = newdir;
1165             return apr_pstrcat(p, cmd_name,
1166                                " without matching <", cmd_name + 2,
1167                                " section", NULL);
1168         }
1169         else {
1170             char *bracket = cmd_name + strlen(cmd_name) - 1;
1171
1172             if (*bracket != '>') {
1173                 parms->err_directive = newdir;
1174                 return apr_pstrcat(p, cmd_name,
1175                                    "> directive missing closing '>'", NULL);
1176             }
1177
1178             *bracket = '\0';
1179
1180             if (strcasecmp(cmd_name + 2,
1181                            (*curr_parent)->directive + 1) != 0) {
1182                 parms->err_directive = newdir;
1183                 return apr_pstrcat(p, "Expected </",
1184                                    (*curr_parent)->directive + 1, "> but saw ",
1185                                    cmd_name, ">", NULL);
1186             }
1187
1188             *bracket = '>';
1189
1190             /* done with this section; move up a level */
1191             *current = *curr_parent;
1192             *curr_parent = (*current)->parent;
1193         }
1194     }
1195     else {
1196         *current = ap_add_node(curr_parent, *current, newdir, 0);
1197     }
1198
1199     return retval;
1200 }
1201
1202 #define VARBUF_INIT_LEN 200
1203 #define VARBUF_MAX_LEN  (16*1024*1024)
1204
1205 AP_DECLARE(const char *) ap_build_cont_config(apr_pool_t *p,
1206                                               apr_pool_t *temp_pool,
1207                                               cmd_parms *parms,
1208                                               ap_directive_t **current,
1209                                               ap_directive_t **curr_parent,
1210                                               char *orig_directive)
1211 {
1212     char *bracket;
1213     const char *retval;
1214     ap_directive_t *sub_tree = NULL;
1215     apr_status_t rc;
1216     struct ap_varbuf vb;
1217     apr_size_t max_len = VARBUF_MAX_LEN;
1218     if (p == temp_pool)
1219         max_len = HUGE_STRING_LEN; /* lower limit for .htaccess */
1220
1221     bracket = apr_pstrcat(temp_pool, orig_directive + 1, ">", NULL);
1222     ap_varbuf_init(temp_pool, &vb, VARBUF_INIT_LEN);
1223
1224     while ((rc = ap_varbuf_cfg_getline(&vb, parms->config_file, max_len))
1225            == APR_SUCCESS) {
1226         if (!memcmp(vb.buf, "</", 2)
1227             && (strcasecmp(vb.buf + 2, bracket) == 0)
1228             && (*curr_parent == NULL)) {
1229             break;
1230         }
1231         retval = ap_build_config_sub(p, temp_pool, vb.buf, parms, current,
1232                                      curr_parent, &sub_tree);
1233         if (retval != NULL)
1234             return retval;
1235
1236         if (sub_tree == NULL) {
1237             sub_tree = *curr_parent;
1238         }
1239
1240         if (sub_tree == NULL) {
1241             sub_tree = *current;
1242         }
1243     }
1244     ap_varbuf_free(&vb);
1245     if (rc != APR_EOF && rc != APR_SUCCESS)
1246         return ap_pcfg_strerror(temp_pool, parms->config_file, rc);
1247
1248     *current = sub_tree;
1249     return NULL;
1250 }
1251
1252 static const char *ap_walk_config_sub(const ap_directive_t *current,
1253                                       cmd_parms *parms,
1254                                       ap_conf_vector_t *section_vector)
1255 {
1256     const command_rec *cmd;
1257     ap_mod_list *ml;
1258     char *dir = apr_pstrdup(parms->temp_pool, current->directive);
1259
1260     ap_str_tolower(dir);
1261
1262     ml = apr_hash_get(ap_config_hash, dir, APR_HASH_KEY_STRING);
1263
1264     if (ml == NULL) {
1265         parms->err_directive = current;
1266         if (parms->override & NONFATAL_UNKNOWN) {
1267             ap_log_perror(APLOG_MARK, APLOG_WARNING, 0, parms->temp_pool,
1268                           APLOGNO(02296) "Unknown directive %s "
1269                           "perhaps misspelled or defined by a module "
1270                           "not included in the server configuration", dir);
1271             return NULL;
1272         }
1273         else {
1274             return apr_pstrcat(parms->pool, "Invalid command '",
1275                                current->directive,
1276                                "', perhaps misspelled or defined by a module "
1277                                "not included in the server configuration",
1278                                NULL);
1279         }
1280     }
1281
1282     for ( ; ml != NULL; ml = ml->next) {
1283         void *dir_config = ap_set_config_vectors(parms->server,
1284                                                  section_vector,
1285                                                  parms->path,
1286                                                  ml->m,
1287                                                  parms->pool);
1288         const char *retval;
1289         cmd = ml->cmd;
1290
1291         /* Once was enough? */
1292         if (cmd->req_override & EXEC_ON_READ) {
1293             continue;
1294         }
1295
1296         retval = invoke_cmd(cmd, parms, dir_config, current->args);
1297
1298         if (retval != NULL && strcmp(retval, DECLINE_CMD) != 0) {
1299             /* If the directive in error has already been set, don't
1300              * replace it.  Otherwise, an error inside a container
1301              * will be reported as occuring on the first line of the
1302              * container.
1303              */
1304             if (!parms->err_directive) {
1305                 parms->err_directive = current;
1306             }
1307             return retval;
1308         }
1309     }
1310
1311     return NULL;
1312 }
1313
1314 AP_DECLARE(const char *) ap_walk_config(ap_directive_t *current,
1315                                         cmd_parms *parms,
1316                                         ap_conf_vector_t *section_vector)
1317 {
1318     ap_conf_vector_t *oldconfig = parms->context;
1319
1320     parms->context = section_vector;
1321
1322     /* scan through all directives, executing each one */
1323     for (; current != NULL; current = current->next) {
1324         const char *errmsg;
1325
1326         parms->directive = current;
1327
1328         /* actually parse the command and execute the correct function */
1329         errmsg = ap_walk_config_sub(current, parms, section_vector);
1330         if (errmsg != NULL) {
1331             /* restore the context (just in case) */
1332             parms->context = oldconfig;
1333             return errmsg;
1334         }
1335     }
1336
1337     parms->context = oldconfig;
1338     return NULL;
1339 }
1340
1341 AP_DECLARE(const char *) ap_build_config(cmd_parms *parms,
1342                                          apr_pool_t *p, apr_pool_t *temp_pool,
1343                                          ap_directive_t **conftree)
1344 {
1345     ap_directive_t *current = *conftree;
1346     ap_directive_t *curr_parent = NULL;
1347     const char *errmsg;
1348     ap_directive_t **last_ptr = NULL;
1349     apr_status_t rc;
1350     struct ap_varbuf vb;
1351     apr_size_t max_len = VARBUF_MAX_LEN;
1352     if (p == temp_pool)
1353         max_len = HUGE_STRING_LEN; /* lower limit for .htaccess */
1354
1355     ap_varbuf_init(temp_pool, &vb, VARBUF_INIT_LEN);
1356
1357     if (current != NULL) {
1358         /* If we have to traverse the whole tree again for every included
1359          * config file, the required time grows as O(n^2) with the number of
1360          * files. This can be a significant delay for large configurations.
1361          * Therefore we cache a pointer to the last node.
1362          */
1363         last_ptr = &(current->last);
1364
1365         if(last_ptr && *last_ptr) {
1366             current = *last_ptr;
1367         }
1368
1369         while (current->next) {
1370             current = current->next;
1371         }
1372
1373         if(last_ptr) {
1374             /* update cached pointer to last node */
1375             *last_ptr = current;
1376         }
1377     }
1378
1379     while ((rc = ap_varbuf_cfg_getline(&vb, parms->config_file, max_len))
1380            == APR_SUCCESS) {
1381         errmsg = ap_build_config_sub(p, temp_pool, vb.buf, parms,
1382                                      &current, &curr_parent, conftree);
1383         if (errmsg != NULL)
1384             return errmsg;
1385
1386         if (*conftree == NULL && curr_parent != NULL) {
1387             *conftree = curr_parent;
1388         }
1389
1390         if (*conftree == NULL && current != NULL) {
1391             *conftree = current;
1392         }
1393     }
1394     ap_varbuf_free(&vb);
1395     if (rc != APR_EOF && rc != APR_SUCCESS)
1396         return ap_pcfg_strerror(temp_pool, parms->config_file, rc);
1397
1398     if (curr_parent != NULL) {
1399         errmsg = "";
1400
1401         while (curr_parent != NULL) {
1402             errmsg = apr_psprintf(p, "%s%s%s:%u: %s> was not closed.",
1403                                   errmsg,
1404                                   *errmsg == '\0' ? "" : APR_EOL_STR,
1405                                   curr_parent->filename,
1406                                   curr_parent->line_num,
1407                                   curr_parent->directive);
1408
1409             parms->err_directive = curr_parent;
1410             curr_parent = curr_parent->parent;
1411         }
1412
1413         return errmsg;
1414     }
1415
1416     return NULL;
1417 }
1418
1419 /*
1420  * Generic command functions...
1421  */
1422
1423 AP_DECLARE_NONSTD(const char *) ap_set_string_slot(cmd_parms *cmd,
1424                                                    void *struct_ptr,
1425                                                    const char *arg)
1426 {
1427     int offset = (int)(long)cmd->info;
1428
1429     *(const char **)((char *)struct_ptr + offset) = arg;
1430
1431     return NULL;
1432 }
1433
1434 AP_DECLARE_NONSTD(const char *) ap_set_int_slot(cmd_parms *cmd,
1435                                                 void *struct_ptr,
1436                                                 const char *arg)
1437 {
1438     char *endptr;
1439     char *error_str = NULL;
1440     int offset = (int)(long)cmd->info;
1441
1442     *(int *)((char*)struct_ptr + offset) = strtol(arg, &endptr, 10);
1443
1444     if ((*arg == '\0') || (*endptr != '\0')) {
1445         error_str = apr_psprintf(cmd->pool,
1446                      "Invalid value for directive %s, expected integer",
1447                      cmd->directive->directive);
1448     }
1449
1450     return error_str;
1451 }
1452
1453 AP_DECLARE_NONSTD(const char *) ap_set_string_slot_lower(cmd_parms *cmd,
1454                                                          void *struct_ptr,
1455                                                          const char *arg_)
1456 {
1457     char *arg = apr_pstrdup(cmd->pool,arg_);
1458     int offset = (int)(long)cmd->info;
1459
1460     ap_str_tolower(arg);
1461     *(char **)((char *)struct_ptr + offset) = arg;
1462
1463     return NULL;
1464 }
1465
1466 AP_DECLARE_NONSTD(const char *) ap_set_flag_slot(cmd_parms *cmd,
1467                                                  void *struct_ptr_v, int arg)
1468 {
1469     int offset = (int)(long)cmd->info;
1470     char *struct_ptr = (char *)struct_ptr_v;
1471
1472     *(int *)(struct_ptr + offset) = arg ? 1 : 0;
1473
1474     return NULL;
1475 }
1476
1477 AP_DECLARE_NONSTD(const char *) ap_set_flag_slot_char(cmd_parms *cmd,
1478                                                       void *struct_ptr_v, int arg)
1479 {
1480     int offset = (int)(long)cmd->info;
1481     char *struct_ptr = (char *)struct_ptr_v;
1482
1483     *(struct_ptr + offset) = arg ? 1 : 0;
1484
1485     return NULL;
1486 }
1487
1488
1489 AP_DECLARE_NONSTD(const char *) ap_set_file_slot(cmd_parms *cmd, void *struct_ptr,
1490                                                  const char *arg)
1491 {
1492     /* Prepend server_root to relative arg.
1493      * This allows most args to be independent of server_root,
1494      * so the server can be moved or mirrored with less pain.
1495      */
1496     const char *path;
1497     int offset = (int)(long)cmd->info;
1498
1499     path = ap_server_root_relative(cmd->pool, arg);
1500
1501     if (!path) {
1502         return apr_pstrcat(cmd->pool, "Invalid file path ",
1503                            arg, NULL);
1504     }
1505
1506     *(const char **) ((char*)struct_ptr + offset) = path;
1507
1508     return NULL;
1509 }
1510
1511 AP_DECLARE_NONSTD(const char *) ap_set_deprecated(cmd_parms *cmd,
1512                                                   void *struct_ptr,
1513                                                   const char *arg)
1514 {
1515     return cmd->cmd->errmsg;
1516 }
1517
1518 AP_DECLARE(void) ap_reset_module_loglevels(struct ap_logconf *l, int val)
1519 {
1520     if (l->module_levels)
1521         memset(l->module_levels, val, conf_vector_length);
1522 }
1523
1524 AP_DECLARE(void) ap_set_module_loglevel(apr_pool_t *pool, struct ap_logconf *l,
1525                                         int index, int level)
1526 {
1527     if (!l->module_levels) {
1528         l->module_levels = apr_palloc(pool, conf_vector_length);
1529         if (l->level == APLOG_UNSET) {
1530                 ap_reset_module_loglevels(l, APLOG_UNSET);
1531         }
1532         else {
1533                 ap_reset_module_loglevels(l, APLOG_NO_MODULE);
1534         }
1535     }
1536
1537     l->module_levels[index] = level;
1538 }
1539
1540 /*****************************************************************
1541  *
1542  * Reading whole config files...
1543  */
1544
1545 static cmd_parms default_parms =
1546 {NULL, 0, 0, NULL, -1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
1547
1548 AP_DECLARE(char *) ap_server_root_relative(apr_pool_t *p, const char *file)
1549 {
1550     char *newpath = NULL;
1551     apr_status_t rv;
1552     rv = apr_filepath_merge(&newpath, ap_server_root, file,
1553                             APR_FILEPATH_TRUENAME, p);
1554     if (newpath && (rv == APR_SUCCESS || APR_STATUS_IS_EPATHWILD(rv)
1555                                       || APR_STATUS_IS_ENOENT(rv)
1556                                       || APR_STATUS_IS_ENOTDIR(rv))) {
1557         return newpath;
1558     }
1559     else {
1560         return NULL;
1561     }
1562 }
1563
1564 AP_DECLARE(char *) ap_runtime_dir_relative(apr_pool_t *p, const char *file)
1565 {
1566     char *newpath = NULL;
1567     apr_status_t rv;
1568     const char *runtime_dir = ap_runtime_dir ? ap_runtime_dir : ap_server_root_relative(p, DEFAULT_REL_RUNTIMEDIR);
1569
1570     rv = apr_filepath_merge(&newpath, runtime_dir, file,
1571                             APR_FILEPATH_TRUENAME, p);
1572     if (newpath && (rv == APR_SUCCESS || APR_STATUS_IS_EPATHWILD(rv)
1573                                       || APR_STATUS_IS_ENOENT(rv)
1574                                       || APR_STATUS_IS_ENOTDIR(rv))) {
1575         return newpath;
1576     }
1577     else {
1578         return NULL;
1579     }
1580 }
1581
1582
1583 AP_DECLARE(const char *) ap_soak_end_container(cmd_parms *cmd, char *directive)
1584 {
1585     struct ap_varbuf vb;
1586     const char *args;
1587     char *cmd_name;
1588     apr_status_t rc;
1589     apr_size_t max_len = VARBUF_MAX_LEN;
1590     if (cmd->pool == cmd->temp_pool)
1591         max_len = HUGE_STRING_LEN; /* lower limit for .htaccess */
1592
1593     ap_varbuf_init(cmd->temp_pool, &vb, VARBUF_INIT_LEN);
1594
1595     while((rc = ap_varbuf_cfg_getline(&vb, cmd->config_file, max_len))
1596           == APR_SUCCESS) {
1597 #if RESOLVE_ENV_PER_TOKEN
1598         args = vb.buf;
1599 #else
1600         args = ap_resolve_env(cmd->temp_pool, vb.buf);
1601 #endif
1602
1603         cmd_name = ap_getword_conf(cmd->temp_pool, &args);
1604         if (cmd_name[0] == '<') {
1605             if (cmd_name[1] == '/') {
1606                 cmd_name[strlen(cmd_name) - 1] = '\0';
1607
1608                 if (strcasecmp(cmd_name + 2, directive + 1) != 0) {
1609                     return apr_pstrcat(cmd->pool, "Expected </",
1610                                        directive + 1, "> but saw ",
1611                                        cmd_name, ">", NULL);
1612                 }
1613
1614                 ap_varbuf_free(&vb);
1615                 return NULL; /* found end of container */
1616             }
1617             else {
1618                 const char *msg;
1619
1620                 if (*args == '\0' && cmd_name[strlen(cmd_name) - 1] == '>') {
1621                     cmd_name[strlen(cmd_name) - 1] = '\0';
1622                 }
1623
1624                 if ((msg = ap_soak_end_container(cmd, cmd_name)) != NULL) {
1625                     return msg;
1626                 }
1627             }
1628         }
1629     }
1630     if (rc != APR_EOF && rc != APR_SUCCESS)
1631         return ap_pcfg_strerror(cmd->temp_pool, cmd->config_file, rc);
1632
1633     return apr_pstrcat(cmd->pool, "Expected </",
1634                        directive + 1, "> before end of configuration",
1635                        NULL);
1636 }
1637
1638 static const char *execute_now(char *cmd_line, const char *args,
1639                                cmd_parms *parms,
1640                                apr_pool_t *p, apr_pool_t *ptemp,
1641                                ap_directive_t **sub_tree,
1642                                ap_directive_t *parent)
1643 {
1644     const command_rec *cmd;
1645     ap_mod_list *ml;
1646     char *dir = apr_pstrdup(parms->temp_pool, cmd_line);
1647
1648     ap_str_tolower(dir);
1649
1650     ml = apr_hash_get(ap_config_hash, dir, APR_HASH_KEY_STRING);
1651
1652     if (ml == NULL) {
1653         return apr_pstrcat(parms->pool, "Invalid command '",
1654                            cmd_line,
1655                            "', perhaps misspelled or defined by a module "
1656                            "not included in the server configuration",
1657                            NULL);
1658     }
1659
1660     for ( ; ml != NULL; ml = ml->next) {
1661         const char *retval;
1662         cmd = ml->cmd;
1663
1664         retval = invoke_cmd(cmd, parms, sub_tree, args);
1665
1666         if (retval != NULL) {
1667             return retval;
1668         }
1669     }
1670
1671     return NULL;
1672 }
1673
1674 /* This structure and the following functions are needed for the
1675  * table-based config file reading. They are passed to the
1676  * cfg_open_custom() routine.
1677  */
1678
1679 /* Structure to be passed to cfg_open_custom(): it contains an
1680  * index which is incremented from 0 to nelts on each call to
1681  * cfg_getline() (which in turn calls arr_elts_getstr())
1682  * and an apr_array_header_t pointer for the string array.
1683  */
1684 typedef struct {
1685     apr_array_header_t *array;
1686     int curr_idx;
1687 } arr_elts_param_t;
1688
1689
1690 /* arr_elts_getstr() returns the next line from the string array. */
1691 static apr_status_t arr_elts_getstr(void *buf, apr_size_t bufsiz, void *param)
1692 {
1693     arr_elts_param_t *arr_param = (arr_elts_param_t *)param;
1694     char *elt;
1695
1696     /* End of array reached? */
1697     if (++arr_param->curr_idx > arr_param->array->nelts)
1698         return APR_EOF;
1699
1700     /* return the line */
1701     elt = ((char **)arr_param->array->elts)[arr_param->curr_idx - 1];
1702     if (apr_cpystrn(buf, elt, bufsiz) - (char *)buf >= bufsiz - 1)
1703         return APR_ENOSPC;
1704     return APR_SUCCESS;
1705 }
1706
1707
1708 /* arr_elts_close(): dummy close routine (makes sure no more lines can be read) */
1709 static apr_status_t arr_elts_close(void *param)
1710 {
1711     arr_elts_param_t *arr_param = (arr_elts_param_t *)param;
1712
1713     arr_param->curr_idx = arr_param->array->nelts;
1714
1715     return APR_SUCCESS;
1716 }
1717
1718 static const char *process_command_config(server_rec *s,
1719                                           apr_array_header_t *arr,
1720                                           ap_directive_t **conftree,
1721                                           apr_pool_t *p,
1722                                           apr_pool_t *ptemp)
1723 {
1724     const char *errmsg;
1725     cmd_parms parms;
1726     arr_elts_param_t arr_parms;
1727
1728     arr_parms.curr_idx = 0;
1729     arr_parms.array = arr;
1730
1731     if (ap_config_hash == NULL) {
1732         rebuild_conf_hash(s->process->pconf, 1);
1733     }
1734
1735     parms = default_parms;
1736     parms.pool = p;
1737     parms.temp_pool = ptemp;
1738     parms.server = s;
1739     parms.override = (RSRC_CONF | OR_ALL) & ~(OR_AUTHCFG | OR_LIMIT);
1740     parms.override_opts = OPT_ALL | OPT_SYM_OWNER | OPT_MULTI;
1741
1742     parms.config_file = ap_pcfg_open_custom(p, "-c/-C directives",
1743                                             &arr_parms, NULL,
1744                                             arr_elts_getstr, arr_elts_close);
1745
1746     errmsg = ap_build_config(&parms, p, ptemp, conftree);
1747     ap_cfg_closefile(parms.config_file);
1748
1749     if (errmsg) {
1750         return apr_pstrcat(p, "Syntax error in -C/-c directive: ", errmsg,
1751                            NULL);
1752     }
1753
1754     return NULL;
1755 }
1756
1757 typedef struct {
1758     const char *fname;
1759 } fnames;
1760
1761 static int fname_alphasort(const void *fn1, const void *fn2)
1762 {
1763     const fnames *f1 = fn1;
1764     const fnames *f2 = fn2;
1765
1766     return strcmp(f1->fname,f2->fname);
1767 }
1768
1769 AP_DECLARE(const char *) ap_process_resource_config(server_rec *s,
1770                                                     const char *fname,
1771                                                     ap_directive_t **conftree,
1772                                                     apr_pool_t *p,
1773                                                     apr_pool_t *ptemp)
1774 {
1775     ap_configfile_t *cfp;
1776     cmd_parms parms;
1777     apr_status_t rv;
1778     const char *error;
1779
1780     parms = default_parms;
1781     parms.pool = p;
1782     parms.temp_pool = ptemp;
1783     parms.server = s;
1784     parms.override = (RSRC_CONF | OR_ALL) & ~(OR_AUTHCFG | OR_LIMIT);
1785     parms.override_opts = OPT_ALL | OPT_SYM_OWNER | OPT_MULTI;
1786
1787     rv = ap_pcfg_openfile(&cfp, p, fname);
1788     if (rv != APR_SUCCESS) {
1789         char errmsg[120];
1790         return apr_psprintf(p, "Could not open configuration file %s: %s",
1791                             fname, apr_strerror(rv, errmsg, sizeof errmsg));
1792     }
1793
1794     parms.config_file = cfp;
1795     error = ap_build_config(&parms, p, ptemp, conftree);
1796     ap_cfg_closefile(cfp);
1797
1798     if (error) {
1799         if (parms.err_directive)
1800             return apr_psprintf(p, "Syntax error on line %d of %s: %s",
1801                                 parms.err_directive->line_num,
1802                                 parms.err_directive->filename, error);
1803         else
1804             return error;
1805     }
1806
1807     return NULL;
1808 }
1809
1810 static const char *process_resource_config_nofnmatch(server_rec *s,
1811                                                      const char *fname,
1812                                                      ap_directive_t **conftree,
1813                                                      apr_pool_t *p,
1814                                                      apr_pool_t *ptemp,
1815                                                      unsigned depth,
1816                                                      int optional)
1817 {
1818     const char *error;
1819     apr_status_t rv;
1820
1821     if (ap_is_directory(ptemp, fname)) {
1822         apr_dir_t *dirp;
1823         apr_finfo_t dirent;
1824         int current;
1825         apr_array_header_t *candidates = NULL;
1826         fnames *fnew;
1827         char *path = apr_pstrdup(ptemp, fname);
1828
1829         if (++depth > AP_MAX_INCLUDE_DIR_DEPTH) {
1830             return apr_psprintf(p, "Directory %s exceeds the maximum include "
1831                                 "directory nesting level of %u. You have "
1832                                 "probably a recursion somewhere.", path,
1833                                 AP_MAX_INCLUDE_DIR_DEPTH);
1834         }
1835
1836         /*
1837          * first course of business is to grok all the directory
1838          * entries here and store 'em away. Recall we need full pathnames
1839          * for this.
1840          */
1841         rv = apr_dir_open(&dirp, path, ptemp);
1842         if (rv != APR_SUCCESS) {
1843             char errmsg[120];
1844             return apr_psprintf(p, "Could not open config directory %s: %s",
1845                                 path, apr_strerror(rv, errmsg, sizeof errmsg));
1846         }
1847
1848         candidates = apr_array_make(ptemp, 1, sizeof(fnames));
1849         while (apr_dir_read(&dirent, APR_FINFO_DIRENT, dirp) == APR_SUCCESS) {
1850             /* strip out '.' and '..' */
1851             if (strcmp(dirent.name, ".")
1852                 && strcmp(dirent.name, "..")) {
1853                 fnew = (fnames *) apr_array_push(candidates);
1854                 fnew->fname = ap_make_full_path(ptemp, path, dirent.name);
1855             }
1856         }
1857
1858         apr_dir_close(dirp);
1859         if (candidates->nelts != 0) {
1860             qsort((void *) candidates->elts, candidates->nelts,
1861                   sizeof(fnames), fname_alphasort);
1862
1863             /*
1864              * Now recurse these... we handle errors and subdirectories
1865              * via the recursion, which is nice
1866              */
1867             for (current = 0; current < candidates->nelts; ++current) {
1868                 fnew = &((fnames *) candidates->elts)[current];
1869                 error = process_resource_config_nofnmatch(s, fnew->fname,
1870                                                           conftree, p, ptemp,
1871                                                           depth, optional);
1872                 if (error) {
1873                     return error;
1874                 }
1875             }
1876         }
1877
1878         return NULL;
1879     }
1880
1881     return ap_process_resource_config(s, fname, conftree, p, ptemp);
1882 }
1883
1884 static const char *process_resource_config_fnmatch(server_rec *s,
1885                                                    const char *path,
1886                                                    const char *fname,
1887                                                    ap_directive_t **conftree,
1888                                                    apr_pool_t *p,
1889                                                    apr_pool_t *ptemp,
1890                                                    unsigned depth,
1891                                                    int optional)
1892 {
1893     const char *rest;
1894     apr_status_t rv;
1895     apr_dir_t *dirp;
1896     apr_finfo_t dirent;
1897     apr_array_header_t *candidates = NULL;
1898     fnames *fnew;
1899     int current;
1900
1901     /* find the first part of the filename */
1902     rest = ap_strchr_c(fname, '/');
1903     if (rest) {
1904         fname = apr_pstrndup(ptemp, fname, rest - fname);
1905         rest++;
1906     }
1907
1908     /* optimisation - if the filename isn't a wildcard, process it directly */
1909     if (!apr_fnmatch_test(fname)) {
1910         path = ap_make_full_path(ptemp, path, fname);
1911         if (!rest) {
1912             return process_resource_config_nofnmatch(s, path,
1913                                                      conftree, p,
1914                                                      ptemp, 0, optional);
1915         }
1916         else {
1917             return process_resource_config_fnmatch(s, path, rest,
1918                                                    conftree, p,
1919                                                    ptemp, 0, optional);
1920         }
1921     }
1922
1923     /*
1924      * first course of business is to grok all the directory
1925      * entries here and store 'em away. Recall we need full pathnames
1926      * for this.
1927      */
1928     rv = apr_dir_open(&dirp, path, ptemp);
1929     if (rv != APR_SUCCESS) {
1930         char errmsg[120];
1931         return apr_psprintf(p, "Could not open config directory %s: %s",
1932                             path, apr_strerror(rv, errmsg, sizeof errmsg));
1933     }
1934
1935     candidates = apr_array_make(ptemp, 1, sizeof(fnames));
1936     while (apr_dir_read(&dirent, APR_FINFO_DIRENT | APR_FINFO_TYPE, dirp) == APR_SUCCESS) {
1937         /* strip out '.' and '..' */
1938         if (strcmp(dirent.name, ".")
1939             && strcmp(dirent.name, "..")
1940             && (apr_fnmatch(fname, dirent.name,
1941                             APR_FNM_PERIOD) == APR_SUCCESS)) {
1942             const char *full_path = ap_make_full_path(ptemp, path, dirent.name);
1943             /* If matching internal to path, and we happen to match something
1944              * other than a directory, skip it
1945              */
1946             if (rest && (rv == APR_SUCCESS) && (dirent.filetype != APR_DIR)) {
1947                 continue;
1948             }
1949             fnew = (fnames *) apr_array_push(candidates);
1950             fnew->fname = full_path;
1951         }
1952     }
1953
1954     apr_dir_close(dirp);
1955     if (candidates->nelts != 0) {
1956         const char *error;
1957
1958         qsort((void *) candidates->elts, candidates->nelts,
1959               sizeof(fnames), fname_alphasort);
1960
1961         /*
1962          * Now recurse these... we handle errors and subdirectories
1963          * via the recursion, which is nice
1964          */
1965         for (current = 0; current < candidates->nelts; ++current) {
1966             fnew = &((fnames *) candidates->elts)[current];
1967             if (!rest) {
1968                 error = process_resource_config_nofnmatch(s, fnew->fname,
1969                                                           conftree, p,
1970                                                           ptemp, 0, optional);
1971             }
1972             else {
1973                 error = process_resource_config_fnmatch(s, fnew->fname, rest,
1974                                                         conftree, p,
1975                                                         ptemp, 0, optional);
1976             }
1977             if (error) {
1978                 return error;
1979             }
1980         }
1981     }
1982     else {
1983
1984         if (!optional) {
1985             return apr_psprintf(p, "No matches for the wildcard '%s' in '%s', failing "
1986                                    "(use IncludeOptional if required)", fname, path);
1987         }
1988     }
1989
1990     return NULL;
1991 }
1992
1993 AP_DECLARE(const char *) ap_process_fnmatch_configs(server_rec *s,
1994                                                     const char *fname,
1995                                                     ap_directive_t **conftree,
1996                                                     apr_pool_t *p,
1997                                                     apr_pool_t *ptemp,
1998                                                     int optional)
1999 {
2000     /* XXX: lstat() won't work on the wildcard pattern...
2001      */
2002
2003     /* don't require conf/httpd.conf if we have a -C or -c switch */
2004     if ((ap_server_pre_read_config->nelts
2005         || ap_server_post_read_config->nelts)
2006         && !(strcmp(fname, ap_server_root_relative(ptemp, SERVER_CONFIG_FILE)))) {
2007         apr_finfo_t finfo;
2008
2009         if (apr_stat(&finfo, fname, APR_FINFO_LINK | APR_FINFO_TYPE, ptemp) != APR_SUCCESS)
2010             return NULL;
2011     }
2012
2013     if (!apr_fnmatch_test(fname)) {
2014         return ap_process_resource_config(s, fname, conftree, p, ptemp);
2015     }
2016     else {
2017         apr_status_t status;
2018         const char *rootpath, *filepath = fname;
2019
2020         /* locate the start of the directories proper */
2021         status = apr_filepath_root(&rootpath, &filepath, APR_FILEPATH_TRUENAME, ptemp);
2022
2023         /* we allow APR_SUCCESS and APR_EINCOMPLETE */
2024         if (APR_ERELATIVE == status) {
2025             return apr_pstrcat(p, "Include must have an absolute path, ", fname, NULL);
2026         }
2027         else if (APR_EBADPATH == status) {
2028             return apr_pstrcat(p, "Include has a bad path, ", fname, NULL);
2029         }
2030
2031         /* walk the filepath */
2032         return process_resource_config_fnmatch(s, rootpath, filepath, conftree, p, ptemp,
2033                                                0, optional);
2034     }
2035 }
2036
2037 AP_DECLARE(int) ap_process_config_tree(server_rec *s,
2038                                        ap_directive_t *conftree,
2039                                        apr_pool_t *p,
2040                                        apr_pool_t *ptemp)
2041 {
2042     const char *errmsg;
2043     cmd_parms parms;
2044
2045     parms = default_parms;
2046     parms.pool = p;
2047     parms.temp_pool = ptemp;
2048     parms.server = s;
2049     parms.override = (RSRC_CONF | OR_ALL) & ~(OR_AUTHCFG | OR_LIMIT);
2050     parms.override_opts = OPT_ALL | OPT_SYM_OWNER | OPT_MULTI;
2051     parms.limited = -1;
2052
2053     errmsg = ap_walk_config(conftree, &parms, s->lookup_defaults);
2054     if (errmsg) {
2055         if (parms.err_directive)
2056             ap_log_perror(APLOG_MARK, APLOG_STARTUP, 0, p, APLOGNO(00526)
2057                           "Syntax error on line %d of %s:",
2058                           parms.err_directive->line_num,
2059                           parms.err_directive->filename);
2060         ap_log_perror(APLOG_MARK, APLOG_STARTUP, 0, p, "%s", errmsg);
2061         return HTTP_INTERNAL_SERVER_ERROR;
2062     }
2063
2064     return OK;
2065 }
2066
2067 AP_CORE_DECLARE(int) ap_parse_htaccess(ap_conf_vector_t **result,
2068                                        request_rec *r, int override,
2069                                        int override_opts, apr_table_t *override_list,
2070                                        const char *d, const char *access_name)
2071 {
2072     ap_configfile_t *f = NULL;
2073     cmd_parms parms;
2074     char *filename = NULL;
2075     const struct htaccess_result *cache;
2076     struct htaccess_result *new;
2077     ap_conf_vector_t *dc = NULL;
2078     apr_status_t status;
2079
2080     /* firstly, search cache */
2081     for (cache = r->htaccess; cache != NULL; cache = cache->next) {
2082         if (cache->override == override && strcmp(cache->dir, d) == 0) {
2083             *result = cache->htaccess;
2084             return OK;
2085         }
2086     }
2087
2088     parms = default_parms;
2089     parms.override = override;
2090     parms.override_opts = override_opts;
2091     parms.override_list = override_list;
2092     parms.pool = r->pool;
2093     parms.temp_pool = r->pool;
2094     parms.server = r->server;
2095     parms.path = apr_pstrdup(r->pool, d);
2096
2097     /* loop through the access names and find the first one */
2098     while (access_name[0]) {
2099         /* AFAICT; there is no use of the actual 'filename' against
2100          * any canonicalization, so we will simply take the given
2101          * name, ignoring case sensitivity and aliases
2102          */
2103         filename = ap_make_full_path(r->pool, d,
2104                                      ap_getword_conf(r->pool, &access_name));
2105         status = ap_pcfg_openfile(&f, r->pool, filename);
2106
2107         if (status == APR_SUCCESS) {
2108             const char *errmsg;
2109             ap_directive_t *temptree = NULL;
2110
2111             dc = ap_create_per_dir_config(r->pool);
2112
2113             parms.config_file = f;
2114             errmsg = ap_build_config(&parms, r->pool, r->pool, &temptree);
2115             if (errmsg == NULL)
2116                 errmsg = ap_walk_config(temptree, &parms, dc);
2117
2118             ap_cfg_closefile(f);
2119
2120             if (errmsg) {
2121                 ap_log_rerror(APLOG_MARK, APLOG_ALERT, 0, r,
2122                               "%s: %s", filename, errmsg);
2123                 return HTTP_INTERNAL_SERVER_ERROR;
2124             }
2125
2126             *result = dc;
2127             break;
2128         }
2129         else {
2130             if (!APR_STATUS_IS_ENOENT(status)
2131                 && !APR_STATUS_IS_ENOTDIR(status)) {
2132                 ap_log_rerror(APLOG_MARK, APLOG_CRIT, status, r, APLOGNO(00529)
2133                               "%s pcfg_openfile: unable to check htaccess file, "
2134                               "ensure it is readable and that '%s' "
2135                               "is executable",
2136                               filename, d);
2137                 apr_table_setn(r->notes, "error-notes",
2138                                "Server unable to read htaccess file, denying "
2139                                "access to be safe");
2140                 return HTTP_FORBIDDEN;
2141             }
2142         }
2143     }
2144
2145     /* cache it */
2146     new = apr_palloc(r->pool, sizeof(struct htaccess_result));
2147     new->dir = parms.path;
2148     new->override = override;
2149     new->override_opts = override_opts;
2150     new->htaccess = dc;
2151
2152     /* add to head of list */
2153     new->next = r->htaccess;
2154     r->htaccess = new;
2155
2156     return OK;
2157 }
2158
2159 AP_CORE_DECLARE(const char *) ap_init_virtual_host(apr_pool_t *p,
2160                                                    const char *hostname,
2161                                                    server_rec *main_server,
2162                                                    server_rec **ps)
2163 {
2164     server_rec *s = (server_rec *) apr_pcalloc(p, sizeof(server_rec));
2165
2166     /* TODO: this crap belongs in http_core */
2167     s->process = main_server->process;
2168     s->server_admin = NULL;
2169     s->server_hostname = NULL;
2170     s->server_scheme = NULL;
2171     s->error_fname = NULL;
2172     s->timeout = 0;
2173     s->keep_alive_timeout = 0;
2174     s->keep_alive = -1;
2175     s->keep_alive_max = -1;
2176     s->error_log = main_server->error_log;
2177     s->log.level = APLOG_UNSET;
2178     s->log.module_levels = NULL;
2179     /* useful default, otherwise we get a port of 0 on redirects */
2180     s->port = main_server->port;
2181     s->next = NULL;
2182
2183     s->is_virtual = 1;
2184     s->names = apr_array_make(p, 4, sizeof(char **));
2185     s->wild_names = apr_array_make(p, 4, sizeof(char **));
2186
2187     s->module_config = create_empty_config(p);
2188     s->lookup_defaults = ap_create_per_dir_config(p);
2189
2190     s->limit_req_line = main_server->limit_req_line;
2191     s->limit_req_fieldsize = main_server->limit_req_fieldsize;
2192     s->limit_req_fields = main_server->limit_req_fields;
2193
2194     *ps = s;
2195
2196     return ap_parse_vhost_addrs(p, hostname, s);
2197 }
2198
2199 AP_DECLARE(struct ap_logconf *) ap_new_log_config(apr_pool_t *p,
2200                                                   const struct ap_logconf *old)
2201 {
2202     struct ap_logconf *l = apr_pcalloc(p, sizeof(struct ap_logconf));
2203     if (old) {
2204         l->level = old->level;
2205         if (old->module_levels) {
2206             l->module_levels =
2207                 apr_pmemdup(p, old->module_levels, conf_vector_length);
2208         }
2209     }
2210     else {
2211         l->level = APLOG_UNSET;
2212     }
2213     return l;
2214 }
2215
2216 AP_DECLARE(void) ap_merge_log_config(const struct ap_logconf *old_conf,
2217                                      struct ap_logconf *new_conf)
2218 {
2219     if (new_conf->level != APLOG_UNSET) {
2220         /* Setting the main loglevel resets all per-module log levels.
2221          * I.e. if new->level has been set, we must ignore old->module_levels.
2222          */
2223         return;
2224     }
2225
2226     new_conf->level = old_conf->level;
2227     if (new_conf->module_levels == NULL) {
2228         new_conf->module_levels = old_conf->module_levels;
2229     }
2230     else if (old_conf->module_levels != NULL) {
2231         int i;
2232         for (i = 0; i < conf_vector_length; i++) {
2233             if (new_conf->module_levels[i] == APLOG_UNSET)
2234                 new_conf->module_levels[i] = old_conf->module_levels[i];
2235         }
2236     }
2237 }
2238
2239 AP_DECLARE(void) ap_fixup_virtual_hosts(apr_pool_t *p, server_rec *main_server)
2240 {
2241     server_rec *virt;
2242     core_dir_config *dconf =
2243         ap_get_core_module_config(main_server->lookup_defaults);
2244     dconf->log = &main_server->log;
2245
2246     for (virt = main_server->next; virt; virt = virt->next) {
2247         merge_server_configs(p, main_server->module_config,
2248                              virt->module_config);
2249
2250         virt->lookup_defaults =
2251             ap_merge_per_dir_configs(p, main_server->lookup_defaults,
2252                                      virt->lookup_defaults);
2253
2254         if (virt->server_admin == NULL)
2255             virt->server_admin = main_server->server_admin;
2256
2257         if (virt->timeout == 0)
2258             virt->timeout = main_server->timeout;
2259
2260         if (virt->keep_alive_timeout == 0)
2261             virt->keep_alive_timeout = main_server->keep_alive_timeout;
2262
2263         if (virt->keep_alive == -1)
2264             virt->keep_alive = main_server->keep_alive;
2265
2266         if (virt->keep_alive_max == -1)
2267             virt->keep_alive_max = main_server->keep_alive_max;
2268
2269         ap_merge_log_config(&main_server->log, &virt->log);
2270
2271         dconf = ap_get_core_module_config(virt->lookup_defaults);
2272         dconf->log = &virt->log;
2273
2274         /* XXX: this is really something that should be dealt with by a
2275          * post-config api phase
2276          */
2277         ap_core_reorder_directories(p, virt);
2278     }
2279
2280     ap_core_reorder_directories(p, main_server);
2281 }
2282
2283 /*****************************************************************
2284  *
2285  * Getting *everything* configured...
2286  */
2287
2288 static void init_config_globals(apr_pool_t *p)
2289 {
2290     /* Global virtual host hash bucket pointers.  Init to null. */
2291     ap_init_vhost_config(p);
2292 }
2293
2294 static server_rec *init_server_config(process_rec *process, apr_pool_t *p)
2295 {
2296     apr_status_t rv;
2297     server_rec *s = (server_rec *) apr_pcalloc(p, sizeof(server_rec));
2298
2299     apr_file_open_stderr(&s->error_log, p);
2300     s->process = process;
2301     s->port = 0;
2302     s->server_admin = DEFAULT_ADMIN;
2303     s->server_hostname = NULL;
2304     s->server_scheme = NULL;
2305     s->error_fname = DEFAULT_ERRORLOG;
2306     s->log.level = DEFAULT_LOGLEVEL;
2307     s->log.module_levels = NULL;
2308     s->limit_req_line = DEFAULT_LIMIT_REQUEST_LINE;
2309     s->limit_req_fieldsize = DEFAULT_LIMIT_REQUEST_FIELDSIZE;
2310     s->limit_req_fields = DEFAULT_LIMIT_REQUEST_FIELDS;
2311     s->timeout = apr_time_from_sec(DEFAULT_TIMEOUT);
2312     s->keep_alive_timeout = apr_time_from_sec(DEFAULT_KEEPALIVE_TIMEOUT);
2313     s->keep_alive_max = DEFAULT_KEEPALIVE;
2314     s->keep_alive = 1;
2315     s->next = NULL;
2316     s->addrs = apr_pcalloc(p, sizeof(server_addr_rec));
2317
2318     /* NOT virtual host; don't match any real network interface */
2319     rv = apr_sockaddr_info_get(&s->addrs->host_addr,
2320                                NULL, APR_UNSPEC, 0, 0, p);
2321     if (rv != APR_SUCCESS) {
2322         /* should we test here for rv being an EAIERR? */
2323         ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, rv, NULL, APLOGNO(00530)
2324                      "initialisation: bug or getaddrinfo fail");
2325         return NULL;
2326     }
2327
2328     s->addrs->host_port = 0; /* matches any port */
2329     s->addrs->virthost = ""; /* must be non-NULL */
2330     s->names = s->wild_names = NULL;
2331
2332     s->module_config = create_server_config(p, s);
2333     s->lookup_defaults = create_default_per_dir_config(p);
2334
2335     return s;
2336 }
2337
2338
2339 static apr_status_t reset_conf_vector_length(void *dummy)
2340 {
2341     reserved_module_slots = 0;
2342     conf_vector_length = max_modules;
2343     return APR_SUCCESS;
2344 }
2345
2346 static int conf_vector_length_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
2347                                          apr_pool_t *ptemp)
2348 {
2349     /*
2350      * We have loaded all modules that are loaded by EXEC_ON_READ directives.
2351      * From now on we reduce the size of the config vectors to what we need,
2352      * plus what has been reserved (e.g. by mod_perl) for additional modules
2353      * loaded later on.
2354      * If max_modules is too small, ap_add_module() will abort.
2355      */
2356     if (total_modules + reserved_module_slots < max_modules) {
2357         conf_vector_length = total_modules + reserved_module_slots;
2358     }
2359     apr_pool_cleanup_register(pconf, NULL, reset_conf_vector_length,
2360                               apr_pool_cleanup_null);
2361     return OK;
2362 }
2363
2364
2365 AP_CORE_DECLARE(void) ap_register_config_hooks(apr_pool_t *p)
2366 {
2367     ap_hook_pre_config(conf_vector_length_pre_config, NULL, NULL,
2368                        APR_HOOK_REALLY_LAST);
2369 }
2370
2371 AP_DECLARE(server_rec*) ap_read_config(process_rec *process, apr_pool_t *ptemp,
2372                                        const char *filename,
2373                                        ap_directive_t **conftree)
2374 {
2375     const char *confname, *error;
2376     apr_pool_t *p = process->pconf;
2377     server_rec *s = init_server_config(process, p);
2378     if (s == NULL) {
2379         return s;
2380     }
2381
2382     init_config_globals(p);
2383
2384     /* All server-wide config files now have the SAME syntax... */
2385     error = process_command_config(s, ap_server_pre_read_config, conftree,
2386                                    p, ptemp);
2387     if (error) {
2388         ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, 0, NULL, "%s: %s",
2389                      ap_server_argv0, error);
2390         return NULL;
2391     }
2392
2393     /* process_command_config may change the ServerRoot so
2394      * compute this config file name afterwards.
2395      */
2396     confname = ap_server_root_relative(p, filename);
2397
2398     if (!confname) {
2399         ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT,
2400                      APR_EBADPATH, NULL, APLOGNO(00532) "Invalid config file path %s",
2401                      filename);
2402         return NULL;
2403     }
2404
2405     error = ap_process_resource_config(s, confname, conftree, p, ptemp);
2406     if (error) {
2407         ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, 0, NULL,
2408                      "%s: %s", ap_server_argv0, error);
2409         return NULL;
2410     }
2411
2412     error = ap_check_mpm();
2413     if (error) {
2414         ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, 0, NULL, APLOGNO(00534)
2415                      "%s: Configuration error: %s", ap_server_argv0, error);
2416         return NULL;
2417     }
2418
2419     error = process_command_config(s, ap_server_post_read_config, conftree,
2420                                    p, ptemp);
2421
2422     if (error) {
2423         ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, 0, NULL, "%s: %s",
2424                      ap_server_argv0, error);
2425         return NULL;
2426     }
2427
2428     return s;
2429 }
2430
2431 AP_DECLARE(void) ap_single_module_configure(apr_pool_t *p, server_rec *s,
2432                                             module *m)
2433 {
2434     if (m->create_server_config)
2435         ap_set_module_config(s->module_config, m,
2436                              (*m->create_server_config)(p, s));
2437
2438     if (m->create_dir_config)
2439         ap_set_module_config(s->lookup_defaults, m,
2440                              (*m->create_dir_config)(p, NULL));
2441 }
2442
2443 AP_DECLARE(void) ap_run_rewrite_args(process_rec *process)
2444 {
2445     module *m;
2446
2447     for (m = ap_top_module; m; m = m->next) {
2448         if (m->rewrite_args) {
2449             (*m->rewrite_args)(process);
2450         }
2451     }
2452 }
2453
2454 /********************************************************************
2455  * Configuration directives are restricted in terms of where they may
2456  * appear in the main configuration files and/or .htaccess files according
2457  * to the bitmask req_override in the command_rec structure.
2458  * If any of the overrides set in req_override are also allowed in the
2459  * context in which the command is read, then the command is allowed.
2460  * The context is determined as follows:
2461  *
2462  *    inside *.conf --> override = (RSRC_CONF|OR_ALL)&~(OR_AUTHCFG|OR_LIMIT);
2463  *    within <Directory> or <Location> --> override = OR_ALL|ACCESS_CONF;
2464  *    within .htaccess --> override = AllowOverride for current directory;
2465  *
2466  * the result is, well, a rather confusing set of possibilities for when
2467  * a particular directive is allowed to be used.  This procedure prints
2468  * in English where the given (pc) directive can be used.
2469  */
2470 static void show_overrides(const command_rec *pc, module *pm)
2471 {
2472     int n = 0;
2473
2474     printf("\tAllowed in *.conf ");
2475     if ((pc->req_override & (OR_OPTIONS | OR_FILEINFO | OR_INDEXES))
2476         || ((pc->req_override & RSRC_CONF)
2477         && ((pc->req_override & (ACCESS_CONF | OR_AUTHCFG | OR_LIMIT))))) {
2478         printf("anywhere");
2479     }
2480     else if (pc->req_override & RSRC_CONF) {
2481         printf("only outside <Directory>, <Files>, <Location>, or <If>");
2482     }
2483     else {
2484         printf("only inside <Directory>, <Files>, <Location>, or <If>");
2485     }
2486
2487     /* Warn if the directive is allowed inside <Directory> or .htaccess
2488      * but module doesn't support per-dir configuration
2489      */
2490     if ((pc->req_override & (OR_ALL | ACCESS_CONF)) && !pm->create_dir_config)
2491         printf(" [no per-dir config]");
2492
2493     if (pc->req_override & OR_ALL) {
2494         printf(" and in .htaccess\n\twhen AllowOverride");
2495
2496         if ((pc->req_override & OR_ALL) == OR_ALL) {
2497             printf(" isn't None");
2498         }
2499         else {
2500             printf(" includes ");
2501
2502             if (pc->req_override & OR_AUTHCFG) {
2503                 if (n++)
2504                     printf(" or ");
2505
2506                 printf("AuthConfig");
2507             }
2508
2509             if (pc->req_override & OR_LIMIT) {
2510                 if (n++)
2511                     printf(" or ");
2512
2513                 printf("Limit");
2514             }
2515
2516             if (pc->req_override & OR_OPTIONS) {
2517                 if (n++)
2518                     printf(" or ");
2519
2520                 printf("Options");
2521             }
2522
2523             if (pc->req_override & OR_FILEINFO) {
2524                 if (n++)
2525                     printf(" or ");
2526
2527                 printf("FileInfo");
2528             }
2529
2530             if (pc->req_override & OR_INDEXES) {
2531                 if (n++)
2532                     printf(" or ");
2533
2534                 printf("Indexes");
2535             }
2536         }
2537     }
2538
2539     printf("\n");
2540 }
2541
2542 /* Show the preloaded configuration directives, the help string explaining
2543  * the directive arguments, in what module they are handled, and in
2544  * what parts of the configuration they are allowed.  Used for httpd -L.
2545  */
2546 AP_DECLARE(void) ap_show_directives(void)
2547 {
2548     const command_rec *pc;
2549     int n;
2550
2551     for (n = 0; ap_loaded_modules[n]; ++n) {
2552         for (pc = ap_loaded_modules[n]->cmds; pc && pc->name; ++pc) {
2553             printf("%s (%s)\n", pc->name, ap_loaded_modules[n]->name);
2554
2555             if (pc->errmsg)
2556                 printf("\t%s\n", pc->errmsg);
2557
2558             show_overrides(pc, ap_loaded_modules[n]);
2559         }
2560     }
2561 }
2562
2563 /* Show the preloaded module names.  Used for httpd -l. */
2564 AP_DECLARE(void) ap_show_modules(void)
2565 {
2566     int n;
2567
2568     printf("Compiled in modules:\n");
2569     for (n = 0; ap_loaded_modules[n]; ++n)
2570         printf("  %s\n", ap_loaded_modules[n]->name);
2571 }
2572
2573 AP_DECLARE(void *) ap_retained_data_get(const char *key)
2574 {
2575     void *retained;
2576
2577     apr_pool_userdata_get((void *)&retained, key, ap_pglobal);
2578     return retained;
2579 }
2580
2581 AP_DECLARE(void *) ap_retained_data_create(const char *key, apr_size_t size)
2582 {
2583     void *retained;
2584
2585     retained = apr_pcalloc(ap_pglobal, size);
2586     apr_pool_userdata_set((const void *)retained, key, apr_pool_cleanup_null, ap_pglobal);
2587     return retained;
2588 }
2589
2590 static int count_directives_sub(const char *directive, ap_directive_t *current)
2591 {
2592     int count = 0;
2593     while (current != NULL) {
2594         if (current->first_child != NULL)
2595             count += count_directives_sub(directive, current->first_child);
2596         if (strcasecmp(current->directive, directive) == 0)
2597             count++;
2598         current = current->next;
2599     }
2600     return count;
2601 }
2602
2603 AP_DECLARE(void) ap_reserve_module_slots(int count)
2604 {
2605     reserved_module_slots += count;
2606 }
2607
2608 AP_DECLARE(void) ap_reserve_module_slots_directive(const char *directive)
2609 {
2610     ap_reserve_module_slots(count_directives_sub(directive, ap_conftree));
2611 }