home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1999 April / PCO0499.ISO / filesbbs / os2 / apach134.arj / APACH134.ZIP / src / main / http_config.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-01-01  |  46.0 KB  |  1,635 lines

  1. /* ====================================================================
  2.  * Copyright (c) 1995-1999 The Apache Group.  All rights reserved.
  3.  *
  4.  * Redistribution and use in source and binary forms, with or without
  5.  * modification, are permitted provided that the following conditions
  6.  * are met:
  7.  *
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer. 
  10.  *
  11.  * 2. Redistributions in binary form must reproduce the above copyright
  12.  *    notice, this list of conditions and the following disclaimer in
  13.  *    the documentation and/or other materials provided with the
  14.  *    distribution.
  15.  *
  16.  * 3. All advertising materials mentioning features or use of this
  17.  *    software must display the following acknowledgment:
  18.  *    "This product includes software developed by the Apache Group
  19.  *    for use in the Apache HTTP server project (http://www.apache.org/)."
  20.  *
  21.  * 4. The names "Apache Server" and "Apache Group" must not be used to
  22.  *    endorse or promote products derived from this software without
  23.  *    prior written permission. For written permission, please contact
  24.  *    apache@apache.org.
  25.  *
  26.  * 5. Products derived from this software may not be called "Apache"
  27.  *    nor may "Apache" appear in their names without prior written
  28.  *    permission of the Apache Group.
  29.  *
  30.  * 6. Redistributions of any form whatsoever must retain the following
  31.  *    acknowledgment:
  32.  *    "This product includes software developed by the Apache Group
  33.  *    for use in the Apache HTTP server project (http://www.apache.org/)."
  34.  *
  35.  * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
  36.  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  37.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  38.  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
  39.  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  41.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  42.  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  43.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  44.  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  45.  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  46.  * OF THE POSSIBILITY OF SUCH DAMAGE.
  47.  * ====================================================================
  48.  *
  49.  * This software consists of voluntary contributions made by many
  50.  * individuals on behalf of the Apache Group and was originally based
  51.  * on public domain software written at the National Center for
  52.  * Supercomputing Applications, University of Illinois, Urbana-Champaign.
  53.  * For more information on the Apache Group and the Apache HTTP server
  54.  * project, please see <http://www.apache.org/>.
  55.  *
  56.  */
  57.  
  58. /*
  59.  * http_config.c: once was auxillary functions for reading httpd's config
  60.  * file and converting filenames into a namespace
  61.  *
  62.  * Rob McCool 
  63.  * 
  64.  * Wall-to-wall rewrite for Apache... commands which are part of the
  65.  * server core can now be found next door in "http_core.c".  Now contains
  66.  * general command loop, and functions which do bookkeeping for the new
  67.  * Apache config stuff (modules and configuration vectors).
  68.  *
  69.  * rst
  70.  *
  71.  */
  72.  
  73. #define CORE_PRIVATE
  74.  
  75. #include "httpd.h"
  76. #include "http_config.h"
  77. #include "http_core.h"
  78. #include "http_log.h"        /* for errors in parse_htaccess */
  79. #include "http_request.h"    /* for default_handler (see invoke_handler) */
  80. #include "http_conf_globals.h"    /* Sigh... */
  81. #include "http_vhost.h"
  82. #include "explain.h"
  83.  
  84. DEF_Explain
  85.  
  86. /****************************************************************
  87.  *
  88.  * We begin with the functions which deal with the linked list
  89.  * of modules which control just about all of the server operation.
  90.  */
  91.  
  92. /* total_modules is the number of modules that have been linked
  93.  * into the server.
  94.  */
  95. static int total_modules = 0;
  96. /* dynamic_modules is the number of modules that have been added
  97.  * after the pre-loaded ones have been set up. It shouldn't be larger
  98.  * than DYNAMIC_MODULE_LIMIT.
  99.  */
  100. static int dynamic_modules = 0;
  101. API_VAR_EXPORT module *top_module = NULL;
  102. API_VAR_EXPORT module **ap_loaded_modules;
  103.  
  104. typedef int (*handler_func) (request_rec *);
  105. typedef void *(*dir_maker_func) (pool *, char *);
  106. typedef void *(*merger_func) (pool *, void *, void *);
  107.  
  108. /* Dealing with config vectors.  These are associated with per-directory,
  109.  * per-server, and per-request configuration, and have a void* pointer for
  110.  * each modules.  The nature of the structure pointed to is private to the
  111.  * module in question... the core doesn't (and can't) know.  However, there
  112.  * are defined interfaces which allow it to create instances of its private
  113.  * per-directory and per-server structures, and to merge the per-directory
  114.  * structures of a directory and its subdirectory (producing a new one in
  115.  * which the defaults applying to the base directory have been properly
  116.  * overridden).
  117.  */
  118.  
  119. #ifndef ap_get_module_config
  120. API_EXPORT(void *) ap_get_module_config(void *conf_vector, module *m)
  121. {
  122.     void **confv = (void **) conf_vector;
  123.     return confv[m->module_index];
  124. }
  125. #endif
  126.  
  127. #ifndef ap_set_module_config
  128. API_EXPORT(void) ap_set_module_config(void *conf_vector, module *m, void *val)
  129. {
  130.     void **confv = (void **) conf_vector;
  131.     confv[m->module_index] = val;
  132. }
  133. #endif
  134.  
  135. static void *create_empty_config(pool *p)
  136. {
  137.     void **conf_vector = (void **) ap_pcalloc(p, sizeof(void *) *
  138.                     (total_modules + DYNAMIC_MODULE_LIMIT));
  139.     return (void *) conf_vector;
  140. }
  141.  
  142. static void *create_default_per_dir_config(pool *p)
  143. {
  144.     void **conf_vector = (void **) ap_pcalloc(p, sizeof(void *) * (total_modules + DYNAMIC_MODULE_LIMIT));
  145.     module *modp;
  146.  
  147.     for (modp = top_module; modp; modp = modp->next) {
  148.     dir_maker_func df = modp->create_dir_config;
  149.  
  150.     if (df)
  151.         conf_vector[modp->module_index] = (*df) (p, NULL);
  152.     }
  153.  
  154.     return (void *) conf_vector;
  155. }
  156.  
  157. void *
  158.      ap_merge_per_dir_configs(pool *p, void *base, void *new)
  159. {
  160.     void **conf_vector = (void **) ap_palloc(p, sizeof(void *) * total_modules);
  161.     void **base_vector = (void **) base;
  162.     void **new_vector = (void **) new;
  163.     module *modp;
  164.  
  165.     for (modp = top_module; modp; modp = modp->next) {
  166.     merger_func df = modp->merge_dir_config;
  167.     int i = modp->module_index;
  168.  
  169.     if (df && new_vector[i])
  170.         conf_vector[i] = (*df) (p, base_vector[i], new_vector[i]);
  171.     else
  172.         conf_vector[i] = new_vector[i] ? new_vector[i] : base_vector[i];
  173.     }
  174.  
  175.     return (void *) conf_vector;
  176. }
  177.  
  178. static void *create_server_config(pool *p, server_rec *s)
  179. {
  180.     void **conf_vector = (void **) ap_pcalloc(p, sizeof(void *) * (total_modules + DYNAMIC_MODULE_LIMIT));
  181.     module *modp;
  182.  
  183.     for (modp = top_module; modp; modp = modp->next) {
  184.     if (modp->create_server_config)
  185.         conf_vector[modp->module_index] = (*modp->create_server_config) (p, s);
  186.     }
  187.  
  188.     return (void *) conf_vector;
  189. }
  190.  
  191. static void merge_server_configs(pool *p, void *base, void *virt)
  192. {
  193.     /* Can reuse the 'virt' vector for the spine of it, since we don't
  194.      * have to deal with the moral equivalent of .htaccess files here...
  195.      */
  196.  
  197.     void **base_vector = (void **) base;
  198.     void **virt_vector = (void **) virt;
  199.     module *modp;
  200.  
  201.     for (modp = top_module; modp; modp = modp->next) {
  202.     merger_func df = modp->merge_server_config;
  203.     int i = modp->module_index;
  204.  
  205.     if (!virt_vector[i])
  206.         virt_vector[i] = base_vector[i];
  207.     else if (df)
  208.         virt_vector[i] = (*df) (p, base_vector[i], virt_vector[i]);
  209.     }
  210. }
  211.  
  212. void *ap_create_request_config(pool *p)
  213. {
  214.     return create_empty_config(p);
  215. }
  216.  
  217. CORE_EXPORT(void *) ap_create_per_dir_config(pool *p)
  218. {
  219.     return create_empty_config(p);
  220. }
  221.  
  222. #ifdef EXPLAIN
  223.  
  224. struct {
  225.     int offset;
  226.     char *method;
  227. } aMethods[] =
  228.  
  229. {
  230. #define m(meth)    { XtOffsetOf(module,meth),#meth }
  231.     m(translate_handler),
  232.     m(ap_check_user_id),
  233.     m(auth_checker),
  234.     m(type_checker),
  235.     m(fixer_upper),
  236.     m(logger),
  237.     { -1, "?" },
  238. #undef m
  239. };
  240.  
  241. char *ShowMethod(module *modp, int offset)
  242. {
  243.     int n;
  244.     static char buf[200];
  245.  
  246.     for (n = 0; aMethods[n].offset >= 0; ++n)
  247.     if (aMethods[n].offset == offset)
  248.         break;
  249.     ap_snprintf(buf, sizeof(buf), "%s:%s", modp->name, aMethods[n].method);
  250.     return buf;
  251. }
  252. #else
  253. #define ShowMethod(modp,offset)
  254. #endif
  255.  
  256. /****************************************************************
  257.  *
  258.  * Dispatch through the modules to find handlers for various phases
  259.  * of request handling.  These are invoked by http_request.c to actually
  260.  * do the dirty work of slogging through the module structures.
  261.  */
  262.  
  263. /*
  264.  * Optimized run_method routines.  The observation here is that many modules
  265.  * have NULL for most of the methods.  So we build optimized lists of
  266.  * everything.  If you think about it, this is really just like a sparse array
  267.  * implementation to avoid scanning the zero entries.
  268.  */
  269. static const int method_offsets[] =
  270. {
  271.     XtOffsetOf(module, translate_handler),
  272.     XtOffsetOf(module, ap_check_user_id),
  273.     XtOffsetOf(module, auth_checker),
  274.     XtOffsetOf(module, access_checker),
  275.     XtOffsetOf(module, type_checker),
  276.     XtOffsetOf(module, fixer_upper),
  277.     XtOffsetOf(module, logger),
  278.     XtOffsetOf(module, header_parser),
  279.     XtOffsetOf(module, post_read_request)
  280. };
  281. #define NMETHODS    (sizeof (method_offsets)/sizeof (method_offsets[0]))
  282.  
  283. static struct {
  284.     int translate_handler;
  285.     int ap_check_user_id;
  286.     int auth_checker;
  287.     int access_checker;
  288.     int type_checker;
  289.     int fixer_upper;
  290.     int logger;
  291.     int header_parser;
  292.     int post_read_request;
  293. } offsets_into_method_ptrs;
  294.  
  295. /*
  296.  * This is just one big array of method_ptrs.  It's constructed such that,
  297.  * for example, method_ptrs[ offsets_into_method_ptrs.logger ] is the first
  298.  * logger function.  You go one-by-one from there until you hit a NULL.
  299.  * This structure was designed to hopefully maximize cache-coolness.
  300.  */
  301. static handler_func *method_ptrs;
  302.  
  303. /* routine to reconstruct all these shortcuts... called after every
  304.  * add_module.
  305.  * XXX: this breaks if modules dink with their methods pointers
  306.  */
  307. static void build_method_shortcuts(void)
  308. {
  309.     module *modp;
  310.     int how_many_ptrs;
  311.     int i;
  312.     int next_ptr;
  313.     handler_func fp;
  314.  
  315.     if (method_ptrs) {
  316.     /* free up any previous set of method_ptrs */
  317.     free(method_ptrs);
  318.     }
  319.  
  320.     /* first we count how many functions we have */
  321.     how_many_ptrs = 0;
  322.     for (modp = top_module; modp; modp = modp->next) {
  323.     for (i = 0; i < NMETHODS; ++i) {
  324.         if (*(handler_func *) (method_offsets[i] + (char *) modp)) {
  325.         ++how_many_ptrs;
  326.         }
  327.     }
  328.     }
  329.     method_ptrs = malloc((how_many_ptrs + NMETHODS) * sizeof(handler_func));
  330.     next_ptr = 0;
  331.     for (i = 0; i < NMETHODS; ++i) {
  332.     /* XXX: This is an itsy bit presumptuous about the alignment
  333.      * constraints on offsets_into_method_ptrs.  I can't remember if
  334.      * ANSI says this has to be true... -djg */
  335.     ((int *) &offsets_into_method_ptrs)[i] = next_ptr;
  336.     for (modp = top_module; modp; modp = modp->next) {
  337.         fp = *(handler_func *) (method_offsets[i] + (char *) modp);
  338.         if (fp) {
  339.         method_ptrs[next_ptr++] = fp;
  340.         }
  341.     }
  342.     method_ptrs[next_ptr++] = NULL;
  343.     }
  344. }
  345.  
  346.  
  347. static int run_method(request_rec *r, int offset, int run_all)
  348. {
  349.     int i;
  350.  
  351.     for (i = offset; method_ptrs[i]; ++i) {
  352.     handler_func mod_handler = method_ptrs[i];
  353.  
  354.     if (mod_handler) {
  355.         int result;
  356.  
  357.         result = (*mod_handler) (r);
  358.  
  359.         if (result != DECLINED && (!run_all || result != OK))
  360.         return result;
  361.     }
  362.     }
  363.  
  364.     return run_all ? OK : DECLINED;
  365. }
  366.  
  367. int ap_translate_name(request_rec *r)
  368. {
  369.     return run_method(r, offsets_into_method_ptrs.translate_handler, 0);
  370. }
  371.  
  372. int ap_check_access(request_rec *r)
  373. {
  374.     return run_method(r, offsets_into_method_ptrs.access_checker, 1);
  375. }
  376.  
  377. int ap_find_types(request_rec *r)
  378. {
  379.     return run_method(r, offsets_into_method_ptrs.type_checker, 0);
  380. }
  381.  
  382. int ap_run_fixups(request_rec *r)
  383. {
  384.     return run_method(r, offsets_into_method_ptrs.fixer_upper, 1);
  385. }
  386.  
  387. int ap_log_transaction(request_rec *r)
  388. {
  389.     return run_method(r, offsets_into_method_ptrs.logger, 1);
  390. }
  391.  
  392. int ap_header_parse(request_rec *r)
  393. {
  394.     return run_method(r, offsets_into_method_ptrs.header_parser, 1);
  395. }
  396.  
  397. int ap_run_post_read_request(request_rec *r)
  398. {
  399.     return run_method(r, offsets_into_method_ptrs.post_read_request, 1);
  400. }
  401.  
  402. /* Auth stuff --- anything that defines one of these will presumably
  403.  * want to define something for the other.  Note that check_auth is
  404.  * separate from check_access to make catching some config errors easier.
  405.  */
  406.  
  407. int ap_check_user_id(request_rec *r)
  408. {
  409.     return run_method(r, offsets_into_method_ptrs.ap_check_user_id, 0);
  410. }
  411.  
  412. int ap_check_auth(request_rec *r)
  413. {
  414.     return run_method(r, offsets_into_method_ptrs.auth_checker, 0);
  415. }
  416.  
  417. /*
  418.  * For speed/efficiency we generate a compact list of all the handlers
  419.  * and wildcard handlers.  This means we won't have to scan the entire
  420.  * module list looking for handlers... where we'll find a whole whack
  421.  * of NULLs.
  422.  */
  423. typedef struct {
  424.     handler_rec hr;
  425.     size_t len;
  426. } fast_handler_rec;
  427.  
  428. static fast_handler_rec *handlers;
  429. static fast_handler_rec *wildhandlers;
  430.  
  431. static void init_handlers(pool *p)
  432. {
  433.     module *modp;
  434.     int nhandlers = 0;
  435.     int nwildhandlers = 0;
  436.     const handler_rec *handp;
  437.     fast_handler_rec *ph, *pw;
  438.     char *starp;
  439.  
  440.     for (modp = top_module; modp; modp = modp->next) {
  441.     if (!modp->handlers)
  442.         continue;
  443.     for (handp = modp->handlers; handp->content_type; ++handp) {
  444.         if (strchr(handp->content_type, '*')) {
  445.                 nwildhandlers ++;
  446.             } else {
  447.                 nhandlers ++;
  448.             }
  449.         }
  450.     }
  451.     ph = handlers = ap_palloc(p, sizeof(*ph)*(nhandlers + 1));
  452.     pw = wildhandlers = ap_palloc(p, sizeof(*pw)*(nwildhandlers + 1));
  453.     for (modp = top_module; modp; modp = modp->next) {
  454.     if (!modp->handlers)
  455.         continue;
  456.     for (handp = modp->handlers; handp->content_type; ++handp) {
  457.         if ((starp = strchr(handp->content_type, '*'))) {
  458.                 pw->hr.content_type = handp->content_type;
  459.                 pw->hr.handler = handp->handler;
  460.         pw->len = starp - handp->content_type;
  461.                 pw ++;
  462.             } else {
  463.                 ph->hr.content_type = handp->content_type;
  464.                 ph->hr.handler = handp->handler;
  465.         ph->len = strlen(handp->content_type);
  466.                 ph ++;
  467.             }
  468.         }
  469.     }
  470.     pw->hr.content_type = NULL;
  471.     pw->hr.handler = NULL;
  472.     ph->hr.content_type = NULL;
  473.     ph->hr.handler = NULL;
  474. }
  475.  
  476. int ap_invoke_handler(request_rec *r)
  477. {
  478.     fast_handler_rec *handp;
  479.     const char *handler;
  480.     char *p;
  481.     size_t handler_len;
  482.     int result = HTTP_INTERNAL_SERVER_ERROR;
  483.  
  484.     if (r->handler) {
  485.     handler = r->handler;
  486.     handler_len = strlen(handler);
  487.     }
  488.     else {
  489.     handler = r->content_type ? r->content_type : ap_default_type(r);
  490.     if ((p = strchr(handler, ';')) != NULL) { /* MIME type arguments */
  491.         while (p > handler && p[-1] == ' ')
  492.         --p;        /* strip trailing spaces */
  493.         handler_len = p - handler;
  494.     }
  495.     else {
  496.         handler_len = strlen(handler);
  497.     }
  498.     }
  499.  
  500.     /* Pass one --- direct matches */
  501.  
  502.     for (handp = handlers; handp->hr.content_type; ++handp) {
  503.     if (handler_len == handp->len
  504.         && !strncmp(handler, handp->hr.content_type, handler_len)) {
  505.             result = (*handp->hr.handler) (r);
  506.  
  507.             if (result != DECLINED)
  508.                 return result;
  509.         }
  510.     }
  511.  
  512.     if (result == HTTP_INTERNAL_SERVER_ERROR && r->handler) {
  513.         ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, r,
  514.             "handler \"%s\" not found for: %s", r->handler, r->filename);
  515.     }
  516.  
  517.     /* Pass two --- wildcard matches */
  518.  
  519.     for (handp = wildhandlers; handp->hr.content_type; ++handp) {
  520.     if (handler_len >= handp->len
  521.         && !strncmp(handler, handp->hr.content_type, handp->len)) {
  522.              result = (*handp->hr.handler) (r);
  523.  
  524.              if (result != DECLINED)
  525.                  return result;
  526.          }
  527.     }
  528.  
  529.     return HTTP_INTERNAL_SERVER_ERROR;
  530. }
  531.  
  532. /* One-time setup for precompiled modules --- NOT to be done on restart */
  533.  
  534. API_EXPORT(void) ap_add_module(module *m)
  535. {
  536.     /* This could be called from an AddModule httpd.conf command,
  537.      * after the file has been linked and the module structure within it
  538.      * teased out...
  539.      */
  540.  
  541.     if (m->version != MODULE_MAGIC_NUMBER_MAJOR) {
  542.     fprintf(stderr, "%s: module \"%s\" is not compatible with this "
  543.         "version of Apache.\n", ap_server_argv0, m->name);
  544.     fprintf(stderr, "Please contact the vendor for the correct version.\n");
  545.     exit(1);
  546.     }
  547.  
  548.     if (m->next == NULL) {
  549.     m->next = top_module;
  550.     top_module = m;
  551.     }
  552.     if (m->module_index == -1) {
  553.     m->module_index = total_modules++;
  554.     dynamic_modules++;
  555.  
  556.     if (dynamic_modules > DYNAMIC_MODULE_LIMIT) {
  557.         fprintf(stderr, "%s: module \"%s\" could not be loaded, because"
  558.             " the dynamic\n", ap_server_argv0, m->name);
  559.         fprintf(stderr, "module limit was reached. Please increase "
  560.             "DYNAMIC_MODULE_LIMIT and recompile.\n");
  561.         exit(1);
  562.     }
  563.     }
  564.  
  565.     /* Some C compilers put a complete path into __FILE__, but we want
  566.      * only the filename (e.g. mod_includes.c). So check for path
  567.      * components (Unix and DOS), and remove them.
  568.      */
  569.  
  570.     if (strrchr(m->name, '/'))
  571.     m->name = 1 + strrchr(m->name, '/');
  572.     if (strrchr(m->name, '\\'))
  573.     m->name = 1 + strrchr(m->name, '\\');
  574.  
  575. #ifdef _OSD_POSIX /* __FILE__="*POSIX(/home/martin/apache/src/modules/standard/mod_info.c)" */
  576.     /* We cannot fix the string in-place, because it's const */
  577.     if (m->name[strlen(m->name)-1]==')') {
  578.     char *tmp = strdup(m->name);    /* FIXME:memory leak, albeit a small one */
  579.     tmp[strlen(tmp)-1] = '\0';
  580.     m->name = tmp;
  581.     }
  582. #endif /*_OSD_POSIX*/
  583. }
  584.  
  585. /* 
  586.  * remove_module undoes what add_module did. There are some caveats:
  587.  * when the module is removed, its slot is lost so all the current
  588.  * per-dir and per-server configurations are invalid. So we should
  589.  * only ever call this function when you are invalidating almost
  590.  * all our current data. I.e. when doing a restart.
  591.  */
  592.  
  593. API_EXPORT(void) ap_remove_module(module *m)
  594. {
  595.     module *modp;
  596.  
  597.     modp = top_module;
  598.     if (modp == m) {
  599.     /* We are the top module, special case */
  600.     top_module = modp->next;
  601.     m->next = NULL;
  602.     }
  603.     else {
  604.     /* Not the top module, find use. When found modp will
  605.      * point to the module _before_ us in the list
  606.      */
  607.  
  608.     while (modp && modp->next != m) {
  609.         modp = modp->next;
  610.     }
  611.     if (!modp) {
  612.         /* Uh-oh, this module doesn't exist */
  613.         ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, NULL,
  614.         "Cannot remove module %s: not found in module list",
  615.         m->name);
  616.         return;
  617.     }
  618.     /* Eliminate us from the module list */
  619.     modp->next = modp->next->next;
  620.     }
  621.  
  622.     m->module_index = -1;    /* simulate being unloaded, should
  623.                  * be unnecessary */
  624.     dynamic_modules--;
  625. }
  626.  
  627. API_EXPORT(void) ap_add_loaded_module(module *mod)
  628. {
  629.     module **m;
  630.  
  631.     /* 
  632.      *  Add module pointer to top of chained module list 
  633.      */
  634.     ap_add_module(mod);
  635.  
  636.     /* 
  637.      *  And module pointer to list of loaded modules 
  638.      *
  639.      *  Notes: 1. ap_add_module() would already complain if no more space
  640.      *            exists for adding a dynamically loaded module
  641.      *         2. ap_add_module() accepts double-inclusion, so we have
  642.      *            to accept this, too.
  643.      */
  644.     for (m = ap_loaded_modules; *m != NULL; m++)
  645.         ;
  646.     *m++ = mod;
  647.     *m = NULL;
  648. }
  649.  
  650. API_EXPORT(void) ap_remove_loaded_module(module *mod)
  651. {
  652.     module **m;
  653.     module **m2;
  654.     int done;
  655.  
  656.     /* 
  657.      *  Remove module pointer from chained module list 
  658.      */
  659.     ap_remove_module(mod);
  660.  
  661.     /* 
  662.      *  Remove module pointer from list of loaded modules
  663.      *
  664.      *  Note: 1. We cannot determine if the module was successfully
  665.      *           removed by ap_remove_module().
  666.      *        2. We have not to complain explicity when the module
  667.      *           is not found because ap_remove_module() did it
  668.      *           for us already.
  669.      */
  670.     for (m = m2 = ap_loaded_modules, done = 0; *m2 != NULL; m2++) {
  671.         if (*m2 == mod && done == 0)
  672.             done = 1;
  673.         else
  674.             *m++ = *m2;
  675.     }
  676.     *m = NULL;
  677. }
  678.  
  679. void ap_setup_prelinked_modules()
  680. {
  681.     module **m;
  682.     module **m2;
  683.  
  684.     /*
  685.      *  Initialise total_modules variable and module indices
  686.      */
  687.     total_modules = 0;
  688.     for (m = ap_preloaded_modules; *m != NULL; m++)
  689.         (*m)->module_index = total_modules++;
  690.  
  691.     /* 
  692.      *  Initialise list of loaded modules
  693.      */
  694.     ap_loaded_modules = (module **)malloc(
  695.         sizeof(module *)*(total_modules+DYNAMIC_MODULE_LIMIT+1));
  696.     for (m = ap_preloaded_modules, m2 = ap_loaded_modules; *m != NULL; )
  697.         *m2++ = *m++;
  698.     *m2 = NULL;
  699.  
  700.     /*
  701.      *   Initialize chain of linked (=activate) modules
  702.      */
  703.     for (m = ap_prelinked_modules; *m != NULL; m++)
  704.         ap_add_module(*m);
  705. }
  706.  
  707. API_EXPORT(const char *) ap_find_module_name(module *m)
  708. {
  709.     return m->name;
  710. }
  711.  
  712. API_EXPORT(module *) ap_find_linked_module(const char *name)
  713. {
  714.     module *modp;
  715.  
  716.     for (modp = top_module; modp; modp = modp->next) {
  717.     if (strcmp(modp->name, name) == 0)
  718.         return modp;
  719.     }
  720.     return NULL;
  721. }
  722.  
  723. /* Add a named module.  Returns 1 if module found, 0 otherwise.  */
  724. API_EXPORT(int) ap_add_named_module(const char *name)
  725. {
  726.     module *modp;
  727.     int i = 0;
  728.  
  729.     for (modp = ap_loaded_modules[i]; modp; modp = ap_loaded_modules[++i]) {
  730.     if (strcmp(modp->name, name) == 0) {
  731.         /* Only add modules that are not already enabled.  */
  732.         if (modp->next == NULL) {
  733.         ap_add_module(modp);
  734.         }
  735.         return 1;
  736.     }
  737.     }
  738.  
  739.     return 0;
  740. }
  741.  
  742. /* Clear the internal list of modules, in preparation for starting over. */
  743. API_EXPORT(void) ap_clear_module_list()
  744. {
  745.     module **m = &top_module;
  746.     module **next_m;
  747.  
  748.     while (*m) {
  749.     next_m = &((*m)->next);
  750.     *m = NULL;
  751.     m = next_m;
  752.     }
  753.  
  754.     /* This is required; so we add it always.  */
  755.     ap_add_named_module("http_core.c");
  756. }
  757.  
  758. /*****************************************************************
  759.  *
  760.  * Resource, access, and .htaccess config files now parsed by a common
  761.  * command loop.
  762.  *
  763.  * Let's begin with the basics; parsing the line and
  764.  * invoking the function...
  765.  */
  766.  
  767. static const char *invoke_cmd(const command_rec *cmd, cmd_parms *parms,
  768.                 void *mconfig, const char *args)
  769. {
  770.     char *w, *w2, *w3;
  771.     const char *errmsg;
  772.  
  773.     if ((parms->override & cmd->req_override) == 0)
  774.     return ap_pstrcat(parms->pool, cmd->name, " not allowed here", NULL);
  775.  
  776.     parms->info = cmd->cmd_data;
  777.     parms->cmd = cmd;
  778.  
  779.     switch (cmd->args_how) {
  780.     case RAW_ARGS:
  781.     return ((const char *(*)(cmd_parms *, void *, const char *))
  782.         (cmd->func)) (parms, mconfig, args);
  783.  
  784.     case NO_ARGS:
  785.     if (*args != 0)
  786.         return ap_pstrcat(parms->pool, cmd->name, " takes no arguments",
  787.                NULL);
  788.  
  789.     return ((const char *(*)(cmd_parms *, void *))
  790.         (cmd->func)) (parms, mconfig);
  791.  
  792.     case TAKE1:
  793.     w = ap_getword_conf(parms->pool, &args);
  794.  
  795.     if (*w == '\0' || *args != 0)
  796.         return ap_pstrcat(parms->pool, cmd->name, " takes one argument",
  797.                 cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
  798.  
  799.     return ((const char *(*)(cmd_parms *, void *, const char *))
  800.         (cmd->func)) (parms, mconfig, w);
  801.  
  802.     case TAKE2:
  803.  
  804.     w = ap_getword_conf(parms->pool, &args);
  805.     w2 = ap_getword_conf(parms->pool, &args);
  806.  
  807.     if (*w == '\0' || *w2 == '\0' || *args != 0)
  808.         return ap_pstrcat(parms->pool, cmd->name, " takes two arguments",
  809.                 cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
  810.  
  811.     return ((const char *(*)(cmd_parms *, void *, const char *,
  812.             const char *)) (cmd->func)) (parms, mconfig, w, w2);
  813.  
  814.     case TAKE12:
  815.  
  816.     w = ap_getword_conf(parms->pool, &args);
  817.     w2 = ap_getword_conf(parms->pool, &args);
  818.  
  819.     if (*w == '\0' || *args != 0)
  820.         return ap_pstrcat(parms->pool, cmd->name, " takes 1-2 arguments",
  821.                 cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
  822.  
  823.     return ((const char *(*)(cmd_parms *, void *, const char *,
  824.                 const char *)) (cmd->func)) (parms, mconfig, w,
  825.                                 *w2 ? w2 : NULL);
  826.  
  827.     case TAKE3:
  828.  
  829.     w = ap_getword_conf(parms->pool, &args);
  830.     w2 = ap_getword_conf(parms->pool, &args);
  831.     w3 = ap_getword_conf(parms->pool, &args);
  832.  
  833.     if (*w == '\0' || *w2 == '\0' || *w3 == '\0' || *args != 0)
  834.         return ap_pstrcat(parms->pool, cmd->name, " takes three arguments",
  835.                 cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
  836.  
  837.     return ((const char *(*)(cmd_parms *, void *, const char *,
  838.                 const char *, const char *)) (cmd->func)) (parms,
  839.                             mconfig, w, w2, w3);
  840.  
  841.     case TAKE23:
  842.  
  843.     w = ap_getword_conf(parms->pool, &args);
  844.     w2 = ap_getword_conf(parms->pool, &args);
  845.     w3 = *args ? ap_getword_conf(parms->pool, &args) : NULL;
  846.  
  847.     if (*w == '\0' || *w2 == '\0' || *args != 0)
  848.         return ap_pstrcat(parms->pool, cmd->name,
  849.                 " takes two or three arguments",
  850.                 cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
  851.  
  852.     return ((const char *(*)(cmd_parms *, void *, const char *,
  853.                 const char *, const char *)) (cmd->func)) (parms,
  854.                             mconfig, w, w2, w3);
  855.  
  856.     case TAKE123:
  857.  
  858.     w = ap_getword_conf(parms->pool, &args);
  859.     w2 = *args ? ap_getword_conf(parms->pool, &args) : NULL;
  860.     w3 = *args ? ap_getword_conf(parms->pool, &args) : NULL;
  861.  
  862.     if (*w == '\0' || *args != 0)
  863.         return ap_pstrcat(parms->pool, cmd->name,
  864.                 " takes one, two or three arguments",
  865.                 cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
  866.  
  867.     return ((const char *(*)(cmd_parms *, void *, const char *,
  868.                 const char *, const char *)) (cmd->func)) (parms,
  869.                             mconfig, w, w2, w3);
  870.  
  871.     case TAKE13:
  872.  
  873.     w = ap_getword_conf(parms->pool, &args);
  874.     w2 = *args ? ap_getword_conf(parms->pool, &args) : NULL;
  875.     w3 = *args ? ap_getword_conf(parms->pool, &args) : NULL;
  876.  
  877.     if (*w == '\0' || (*w2 && !w3) || *args != 0)
  878.         return ap_pstrcat(parms->pool, cmd->name,
  879.                 " takes one or three arguments",
  880.                 cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
  881.  
  882.     return ((const char *(*)(cmd_parms *, void *, const char *,
  883.                 const char *, const char *)) (cmd->func)) (parms,
  884.                             mconfig, w, w2, w3);
  885.  
  886.     case ITERATE:
  887.  
  888.     while (*(w = ap_getword_conf(parms->pool, &args)) != '\0')
  889.     if   ((errmsg = ((const char *(*)(cmd_parms *, void *,
  890.             const char *)) (cmd->func)) (parms, mconfig, w)))
  891.             return errmsg;
  892.  
  893.     return NULL;
  894.  
  895.     case ITERATE2:
  896.  
  897.     w = ap_getword_conf(parms->pool, &args);
  898.  
  899.     if (*w == '\0' || *args == 0)
  900.         return ap_pstrcat(parms->pool, cmd->name,
  901.                 " requires at least two arguments",
  902.                 cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
  903.  
  904.  
  905.     while (*(w2 = ap_getword_conf(parms->pool, &args)) != '\0')
  906.         if   ((errmsg = ((const char *(*)(cmd_parms *, void *,
  907.                 const char *, const char *)) (cmd->func)) (parms,
  908.                                 mconfig, w, w2)))
  909.             return errmsg;
  910.  
  911.     return NULL;
  912.  
  913.     case FLAG:
  914.  
  915.     w = ap_getword_conf(parms->pool, &args);
  916.  
  917.     if (*w == '\0' || (strcasecmp(w, "on") && strcasecmp(w, "off")))
  918.         return ap_pstrcat(parms->pool, cmd->name, " must be On or Off",
  919.                 NULL);
  920.  
  921.     return ((const char *(*)(cmd_parms *, void *, int))
  922.         (cmd->func)) (parms, mconfig, strcasecmp(w, "off") != 0);
  923.  
  924.     default:
  925.  
  926.     return ap_pstrcat(parms->pool, cmd->name,
  927.             " is improperly configured internally (server bug)",
  928.             NULL);
  929.     }
  930. }
  931.  
  932. CORE_EXPORT(const command_rec *) ap_find_command(const char *name, const command_rec *cmds)
  933. {
  934.     while (cmds->name)
  935.     if (!strcasecmp(name, cmds->name))
  936.         return cmds;
  937.     else
  938.         ++cmds;
  939.  
  940.     return NULL;
  941. }
  942.  
  943. CORE_EXPORT(const command_rec *) ap_find_command_in_modules(const char *cmd_name, module **mod)
  944. {
  945.     const command_rec *cmdp;
  946.     module *modp;
  947.  
  948.     for (modp = *mod; modp; modp = modp->next)
  949.     if (modp->cmds && (cmdp = ap_find_command(cmd_name, modp->cmds))) {
  950.         *mod = modp;
  951.         return cmdp;
  952.     }
  953.  
  954.     return NULL;
  955. }
  956.  
  957. CORE_EXPORT(const char *) ap_handle_command(cmd_parms *parms, void *config, const char *l)
  958. {
  959.     const char *args, *cmd_name, *retval;
  960.     const command_rec *cmd;
  961.     module *mod = top_module;
  962.  
  963.     if ((l[0] == '#') || (!l[0]))
  964.     return NULL;
  965.  
  966.     args = l;
  967.     cmd_name = ap_getword_conf(parms->temp_pool, &args);
  968.     if (*cmd_name == '\0')
  969.     return NULL;
  970.  
  971.     do {
  972.     if (!(cmd = ap_find_command_in_modules(cmd_name, &mod))) {
  973.             errno = EINVAL;
  974.             return ap_pstrcat(parms->pool, "Invalid command '", cmd_name,
  975.                            "', perhaps mis-spelled or defined by a module "
  976.                            "not included in the server configuration", NULL);
  977.     }
  978.     else {
  979.         void *mconfig = ap_get_module_config(config, mod);
  980.         void *sconfig =
  981.         ap_get_module_config(parms->server->module_config, mod);
  982.  
  983.         if (!mconfig && mod->create_dir_config) {
  984.         mconfig = (*mod->create_dir_config) (parms->pool, parms->path);
  985.         ap_set_module_config(config, mod, mconfig);
  986.         }
  987.  
  988.         if (!sconfig && mod->create_server_config) {
  989.         sconfig =
  990.             (*mod->create_server_config) (parms->pool, parms->server);
  991.         ap_set_module_config(parms->server->module_config, mod, sconfig);
  992.         }
  993.  
  994.         retval = invoke_cmd(cmd, parms, mconfig, args);
  995.         mod = mod->next;    /* Next time around, skip this one */
  996.     }
  997.     } while (retval && !strcmp(retval, DECLINE_CMD));
  998.  
  999.     return retval;
  1000. }
  1001.  
  1002. API_EXPORT(const char *) ap_srm_command_loop(cmd_parms *parms, void *config)
  1003. {
  1004.     char l[MAX_STRING_LEN];
  1005.  
  1006.     while (!(ap_cfg_getline(l, MAX_STRING_LEN, parms->config_file))) {
  1007.     const char *errmsg = ap_handle_command(parms, config, l);
  1008.         if (errmsg) {
  1009.         return errmsg;
  1010.     }
  1011.     }
  1012.  
  1013.     return NULL;
  1014. }
  1015.  
  1016. /*
  1017.  * Generic command functions...
  1018.  */
  1019.  
  1020. API_EXPORT_NONSTD(const char *) ap_set_string_slot(cmd_parms *cmd,
  1021.                         char *struct_ptr, char *arg)
  1022. {
  1023.     /* This one's pretty generic... */
  1024.  
  1025.     int offset = (int) (long) cmd->info;
  1026.     *(char **) (struct_ptr + offset) = arg;
  1027.     return NULL;
  1028. }
  1029.  
  1030. API_EXPORT_NONSTD(const char *) ap_set_string_slot_lower(cmd_parms *cmd,
  1031.                         char *struct_ptr, char *arg)
  1032. {
  1033.     /* This one's pretty generic... */
  1034.  
  1035.     int offset = (int) (long) cmd->info;
  1036.     ap_str_tolower(arg);
  1037.     *(char **) (struct_ptr + offset) = arg;
  1038.     return NULL;
  1039. }
  1040.  
  1041. API_EXPORT_NONSTD(const char *) ap_set_flag_slot(cmd_parms *cmd,
  1042.                           char *struct_ptr, int arg)
  1043. {
  1044.     /* This one's pretty generic too... */
  1045.  
  1046.     int offset = (int) (long) cmd->info;
  1047.     *(int *) (struct_ptr + offset) = arg ? 1 : 0;
  1048.     return NULL;
  1049. }
  1050.  
  1051. API_EXPORT_NONSTD(const char *) ap_set_file_slot(cmd_parms *cmd, char *struct_ptr, char *arg)
  1052. {
  1053.     /* Prepend server_root to relative arg.
  1054.        This allows .htaccess to be independent of server_root,
  1055.        so the server can be moved or mirrored with less pain.  */
  1056.     char *p;
  1057.     int offset = (int) (long) cmd->info;
  1058.     if (ap_os_is_path_absolute(arg))
  1059.     p = arg;
  1060.     else
  1061.     p = ap_make_full_path(cmd->pool, ap_server_root, arg);
  1062.     *(char **) (struct_ptr + offset) = p;
  1063.     return NULL;
  1064. }
  1065.  
  1066. /*****************************************************************
  1067.  *
  1068.  * Reading whole config files...
  1069.  */
  1070.  
  1071. static cmd_parms default_parms =
  1072. {NULL, 0, -1, NULL, NULL, NULL, NULL, NULL, NULL};
  1073.  
  1074. API_EXPORT(char *) ap_server_root_relative(pool *p, char *file)
  1075. {
  1076.     if(ap_os_is_path_absolute(file))
  1077.     return file;
  1078.     return ap_make_full_path(p, ap_server_root, file);
  1079. }
  1080.  
  1081.  
  1082. /* This structure and the following functions are needed for the
  1083.  * table-based config file reading. They are passed to the
  1084.  * cfg_open_custom() routine.
  1085.  */
  1086.  
  1087. /* Structure to be passed to cfg_open_custom(): it contains an
  1088.  * index which is incremented from 0 to nelts on each call to
  1089.  * cfg_getline() (which in turn calls arr_elts_getstr())
  1090.  * and an array_header pointer for the string array.
  1091.  */
  1092. typedef struct {
  1093.     array_header *array;
  1094.     int curr_idx;
  1095. } arr_elts_param_t;
  1096.  
  1097.  
  1098. /* arr_elts_getstr() returns the next line from the string array. */
  1099. static void *arr_elts_getstr(void *buf, size_t bufsiz, void *param)
  1100. {
  1101.     arr_elts_param_t *arr_param = (arr_elts_param_t *) param;
  1102.  
  1103.     /* End of array reached? */
  1104.     if (++arr_param->curr_idx > arr_param->array->nelts)
  1105.         return NULL;
  1106.  
  1107.     /* return the line */
  1108.     ap_cpystrn(buf, ((char **) arr_param->array->elts)[arr_param->curr_idx - 1], bufsiz);
  1109.  
  1110.     return buf;
  1111. }
  1112.  
  1113.  
  1114. /* arr_elts_close(): dummy close routine (makes sure no more lines can be read) */
  1115. static int arr_elts_close(void *param)
  1116. {
  1117.     arr_elts_param_t *arr_param = (arr_elts_param_t *) param;
  1118.     arr_param->curr_idx = arr_param->array->nelts;
  1119.     return 0;
  1120. }
  1121.  
  1122. static void process_command_config(server_rec *s, array_header *arr, pool *p,
  1123.                     pool *ptemp)
  1124. {
  1125.     const char *errmsg;
  1126.     cmd_parms parms;
  1127.     arr_elts_param_t arr_parms;
  1128.  
  1129.     arr_parms.curr_idx = 0;
  1130.     arr_parms.array = arr;
  1131.  
  1132.     parms = default_parms;
  1133.     parms.pool = p;
  1134.     parms.temp_pool = ptemp;
  1135.     parms.server = s;
  1136.     parms.override = (RSRC_CONF | OR_ALL) & ~(OR_AUTHCFG | OR_LIMIT);
  1137.     parms.config_file = ap_pcfg_open_custom(p, "-c/-C directives",
  1138.                                          &arr_parms, NULL,
  1139.                                          arr_elts_getstr, arr_elts_close);
  1140.  
  1141.     errmsg = ap_srm_command_loop(&parms, s->lookup_defaults);
  1142.  
  1143.     if (errmsg) {
  1144.         fprintf(stderr, "Syntax error in -C/-c directive:\n%s\n", errmsg);
  1145.         exit(1);
  1146.     }
  1147.  
  1148.     ap_cfg_closefile(parms.config_file);
  1149. }
  1150.  
  1151. void ap_process_resource_config(server_rec *s, char *fname, pool *p, pool *ptemp)
  1152. {
  1153.     const char *errmsg;
  1154.     cmd_parms parms;
  1155.     struct stat finfo;
  1156.  
  1157.     fname = ap_server_root_relative(p, fname);
  1158.  
  1159.     if (!(strcmp(fname, ap_server_root_relative(p, RESOURCE_CONFIG_FILE))) ||
  1160.     !(strcmp(fname, ap_server_root_relative(p, ACCESS_CONFIG_FILE)))) {
  1161.     if (stat(fname, &finfo) == -1)
  1162.         return;
  1163.     }
  1164.  
  1165.     /* don't require conf/httpd.conf if we have a -C or -c switch */
  1166.     if((ap_server_pre_read_config->nelts || ap_server_post_read_config->nelts) &&
  1167.        !(strcmp(fname, ap_server_root_relative(p, SERVER_CONFIG_FILE)))) {
  1168.     if (stat(fname, &finfo) == -1)
  1169.         return;
  1170.     }
  1171.  
  1172.     /* GCC's initialization extensions are soooo nice here... */
  1173.  
  1174.     parms = default_parms;
  1175.     parms.pool = p;
  1176.     parms.temp_pool = ptemp;
  1177.     parms.server = s;
  1178.     parms.override = (RSRC_CONF | OR_ALL) & ~(OR_AUTHCFG | OR_LIMIT);
  1179.  
  1180.     if (!(parms.config_file = ap_pcfg_openfile(p,fname))) {
  1181.     perror("fopen");
  1182.     fprintf(stderr, "%s: could not open document config file %s\n",
  1183.         ap_server_argv0, fname);
  1184.     exit(1);
  1185.     }
  1186.  
  1187.     errmsg = ap_srm_command_loop(&parms, s->lookup_defaults);
  1188.  
  1189.     if (errmsg) {
  1190.     fprintf(stderr, "Syntax error on line %d of %s:\n",
  1191.         parms.config_file->line_number, parms.config_file->name);
  1192.     fprintf(stderr, "%s\n", errmsg);
  1193.     exit(1);
  1194.     }
  1195.  
  1196.     ap_cfg_closefile(parms.config_file);
  1197. }
  1198.  
  1199.  
  1200. int ap_parse_htaccess(void **result, request_rec *r, int override,
  1201.            const char *d, const char *access_name)
  1202. {
  1203.     configfile_t *f = NULL;
  1204.     cmd_parms parms;
  1205.     const char *errmsg;
  1206.     char *filename = NULL;
  1207.     const struct htaccess_result *cache;
  1208.     struct htaccess_result *new;
  1209.     void *dc = NULL;
  1210.  
  1211. /* firstly, search cache */
  1212.     for (cache = r->htaccess; cache != NULL; cache = cache->next)
  1213.     if (cache->override == override && strcmp(cache->dir, d) == 0) {
  1214.         if (cache->htaccess != NULL)
  1215.         *result = cache->htaccess;
  1216.         return OK;
  1217.     }
  1218.  
  1219.     parms = default_parms;
  1220.     parms.override = override;
  1221.     parms.pool = r->pool;
  1222.     parms.temp_pool = r->pool;
  1223.     parms.server = r->server;
  1224.     parms.path = ap_pstrdup(r->pool, d);
  1225.  
  1226.     /* loop through the access names and find the first one */
  1227.  
  1228.     while (access_name[0]) {
  1229.         filename = ap_make_full_path(r->pool, d,
  1230.                                      ap_getword_conf(r->pool, &access_name));
  1231.  
  1232.         if ((f = ap_pcfg_openfile(r->pool, filename)) != NULL) {
  1233.  
  1234.             dc = ap_create_per_dir_config(r->pool);
  1235.  
  1236.             parms.config_file = f;
  1237.  
  1238.             errmsg = ap_srm_command_loop(&parms, dc);
  1239.  
  1240.             ap_cfg_closefile(f);
  1241.  
  1242.             if (errmsg) {
  1243.                 ap_log_rerror(APLOG_MARK, APLOG_ALERT|APLOG_NOERRNO, r,
  1244.                               "%s: %s", filename, errmsg);
  1245.                 return HTTP_INTERNAL_SERVER_ERROR;
  1246.             }
  1247.             *result = dc;
  1248.             break;
  1249.         }
  1250.         else if (errno != ENOENT && errno != ENOTDIR) {
  1251.             ap_log_rerror(APLOG_MARK, APLOG_CRIT, r,
  1252.                           "%s pcfg_openfile: unable to check htaccess file, "
  1253.                           "ensure it is readable",
  1254.                           filename);
  1255.             ap_table_setn(r->notes, "error-notes",
  1256.                           "Server unable to read htaccess file, denying "
  1257.                           "access to be safe");
  1258.             return HTTP_FORBIDDEN;
  1259.         }
  1260.     }
  1261.  
  1262. /* cache it */
  1263.     new = ap_palloc(r->pool, sizeof(struct htaccess_result));
  1264.     new->dir = parms.path;
  1265.     new->override = override;
  1266.     new->htaccess = dc;
  1267. /* add to head of list */
  1268.     new->next = r->htaccess;
  1269.     r->htaccess = new;
  1270.  
  1271.     return OK;
  1272. }
  1273.  
  1274.  
  1275. CORE_EXPORT(const char *) ap_init_virtual_host(pool *p, const char *hostname,
  1276.                   server_rec *main_server, server_rec **ps)
  1277. {
  1278.     server_rec *s = (server_rec *) ap_pcalloc(p, sizeof(server_rec));
  1279.  
  1280. #ifdef RLIMIT_NOFILE
  1281.     struct rlimit limits;
  1282.  
  1283.     getrlimit(RLIMIT_NOFILE, &limits);
  1284.     if (limits.rlim_cur < limits.rlim_max) {
  1285.     limits.rlim_cur += 2;
  1286.     if (setrlimit(RLIMIT_NOFILE, &limits) < 0) {
  1287.         perror("setrlimit(RLIMIT_NOFILE)");
  1288.         fprintf(stderr, "Cannot exceed hard limit for open files");
  1289.     }
  1290.     }
  1291. #endif
  1292.  
  1293.     s->server_admin = NULL;
  1294.     s->server_hostname = NULL;
  1295.     s->error_fname = NULL;
  1296.     s->srm_confname = NULL;
  1297.     s->access_confname = NULL;
  1298.     s->timeout = 0;
  1299.     s->keep_alive_timeout = 0;
  1300.     s->keep_alive = -1;
  1301.     s->keep_alive_max = -1;
  1302.     s->error_log = main_server->error_log;
  1303.     s->loglevel = main_server->loglevel;
  1304.     /* useful default, otherwise we get a port of 0 on redirects */
  1305.     s->port = main_server->port;
  1306.     s->next = NULL;
  1307.  
  1308.     s->is_virtual = 1;
  1309.     s->names = ap_make_array(p, 4, sizeof(char **));
  1310.     s->wild_names = ap_make_array(p, 4, sizeof(char **));
  1311.  
  1312.     s->module_config = create_empty_config(p);
  1313.     s->lookup_defaults = ap_create_per_dir_config(p);
  1314.  
  1315.     s->server_uid = ap_user_id;
  1316.     s->server_gid = ap_group_id;
  1317.  
  1318.     s->limit_req_line = main_server->limit_req_line;
  1319.     s->limit_req_fieldsize = main_server->limit_req_fieldsize;
  1320.     s->limit_req_fields = main_server->limit_req_fields;
  1321.  
  1322.     *ps = s;
  1323.  
  1324.     return ap_parse_vhost_addrs(p, hostname, s);
  1325. }
  1326.  
  1327.  
  1328. static void fixup_virtual_hosts(pool *p, server_rec *main_server)
  1329. {
  1330.     server_rec *virt;
  1331.  
  1332.     for (virt = main_server->next; virt; virt = virt->next) {
  1333.     merge_server_configs(p, main_server->module_config,
  1334.                  virt->module_config);
  1335.  
  1336.     virt->lookup_defaults =
  1337.         ap_merge_per_dir_configs(p, main_server->lookup_defaults,
  1338.                   virt->lookup_defaults);
  1339.  
  1340.     if (virt->server_admin == NULL)
  1341.         virt->server_admin = main_server->server_admin;
  1342.  
  1343.     if (virt->srm_confname == NULL)
  1344.         virt->srm_confname = main_server->srm_confname;
  1345.  
  1346.     if (virt->access_confname == NULL)
  1347.         virt->access_confname = main_server->access_confname;
  1348.  
  1349.     if (virt->timeout == 0)
  1350.         virt->timeout = main_server->timeout;
  1351.  
  1352.     if (virt->keep_alive_timeout == 0)
  1353.         virt->keep_alive_timeout = main_server->keep_alive_timeout;
  1354.  
  1355.     if (virt->keep_alive == -1)
  1356.         virt->keep_alive = main_server->keep_alive;
  1357.  
  1358.     if (virt->keep_alive_max == -1)
  1359.         virt->keep_alive_max = main_server->keep_alive_max;
  1360.  
  1361.     if (virt->send_buffer_size == 0)
  1362.         virt->send_buffer_size = main_server->send_buffer_size;
  1363.  
  1364.     /* XXX: this is really something that should be dealt with by a
  1365.      * post-config api phase */
  1366.     ap_core_reorder_directories(p, virt);
  1367.     }
  1368.     ap_core_reorder_directories(p, main_server);
  1369. }
  1370.  
  1371. /*****************************************************************
  1372.  *
  1373.  * Getting *everything* configured... 
  1374.  */
  1375.  
  1376. static void init_config_globals(pool *p)
  1377. {
  1378.     /* ServerRoot, server_confname set in httpd.c */
  1379.  
  1380.     ap_standalone = 1;
  1381.     ap_user_name = DEFAULT_USER;
  1382.     ap_user_id = ap_uname2id(DEFAULT_USER);
  1383.     ap_group_id = ap_gname2id(DEFAULT_GROUP);
  1384.     ap_daemons_to_start = DEFAULT_START_DAEMON;
  1385.     ap_daemons_min_free = DEFAULT_MIN_FREE_DAEMON;
  1386.     ap_daemons_max_free = DEFAULT_MAX_FREE_DAEMON;
  1387.     ap_daemons_limit = HARD_SERVER_LIMIT;
  1388.     ap_pid_fname = DEFAULT_PIDLOG;
  1389.     ap_scoreboard_fname = DEFAULT_SCOREBOARD;
  1390.     ap_lock_fname = DEFAULT_LOCKFILE;
  1391.     ap_max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD;
  1392.     ap_bind_address.s_addr = htonl(INADDR_ANY);
  1393.     ap_listeners = NULL;
  1394.     ap_listenbacklog = DEFAULT_LISTENBACKLOG;
  1395.     ap_extended_status = 0;
  1396.  
  1397.     /* Global virtual host hash bucket pointers.  Init to null. */
  1398.     ap_init_vhost_config(p);
  1399.  
  1400.     ap_cpystrn(ap_coredump_dir, ap_server_root, sizeof(ap_coredump_dir));
  1401. }
  1402.  
  1403. static server_rec *init_server_config(pool *p)
  1404. {
  1405.     server_rec *s = (server_rec *) ap_pcalloc(p, sizeof(server_rec));
  1406.  
  1407.     s->port = 0;
  1408.     s->server_admin = DEFAULT_ADMIN;
  1409.     s->server_hostname = NULL;
  1410.     s->error_fname = DEFAULT_ERRORLOG;
  1411.     s->error_log = stderr;
  1412.     s->loglevel = DEFAULT_LOGLEVEL;
  1413.     s->srm_confname = RESOURCE_CONFIG_FILE;
  1414.     s->access_confname = ACCESS_CONFIG_FILE;
  1415.     s->limit_req_line = DEFAULT_LIMIT_REQUEST_LINE;
  1416.     s->limit_req_fieldsize = DEFAULT_LIMIT_REQUEST_FIELDSIZE;
  1417.     s->limit_req_fields = DEFAULT_LIMIT_REQUEST_FIELDS;
  1418.     s->timeout = DEFAULT_TIMEOUT;
  1419.     s->keep_alive_timeout = DEFAULT_KEEPALIVE_TIMEOUT;
  1420.     s->keep_alive_max = DEFAULT_KEEPALIVE;
  1421.     s->keep_alive = 1;
  1422.     s->next = NULL;
  1423.     s->addrs = ap_pcalloc(p, sizeof(server_addr_rec));
  1424.     /* NOT virtual host; don't match any real network interface */
  1425.     s->addrs->host_addr.s_addr = htonl(INADDR_ANY);
  1426.     s->addrs->host_port = 0;    /* matches any port */
  1427.     s->addrs->virthost = "";    /* must be non-NULL */
  1428.     s->names = s->wild_names = NULL;
  1429.  
  1430.     s->module_config = create_server_config(p, s);
  1431.     s->lookup_defaults = create_default_per_dir_config(p);
  1432.  
  1433.     return s;
  1434. }
  1435.  
  1436.  
  1437. static void default_listeners(pool *p, server_rec *s)
  1438. {
  1439.     listen_rec *new;
  1440.  
  1441.     if (ap_listeners != NULL) {
  1442.     return;
  1443.     }
  1444.     /* allocate a default listener */
  1445.     new = ap_pcalloc(p, sizeof(listen_rec));
  1446.     new->local_addr.sin_family = AF_INET;
  1447.     new->local_addr.sin_addr = ap_bind_address;
  1448.     new->local_addr.sin_port = htons(s->port ? s->port : DEFAULT_HTTP_PORT);
  1449.     new->fd = -1;
  1450.     new->used = 0;
  1451.     new->next = NULL;
  1452.     ap_listeners = new;
  1453. }
  1454.  
  1455.  
  1456. server_rec *ap_read_config(pool *p, pool *ptemp, char *confname)
  1457. {
  1458.     server_rec *s = init_server_config(p);
  1459.  
  1460.     init_config_globals(p);
  1461.  
  1462.     /* All server-wide config files now have the SAME syntax... */
  1463.  
  1464.     process_command_config(s, ap_server_pre_read_config, p, ptemp);
  1465.  
  1466.     ap_process_resource_config(s, confname, p, ptemp);
  1467.     ap_process_resource_config(s, s->srm_confname, p, ptemp);
  1468.     ap_process_resource_config(s, s->access_confname, p, ptemp);
  1469.  
  1470.     process_command_config(s, ap_server_post_read_config, p, ptemp);
  1471.  
  1472.     fixup_virtual_hosts(p, s);
  1473.     default_listeners(p, s);
  1474.     ap_fini_vhost_config(p, s);
  1475.  
  1476.     return s;
  1477. }
  1478.  
  1479. void ap_single_module_configure(pool *p, server_rec *s, module *m)
  1480. {
  1481.     if (m->create_server_config)
  1482.         ap_set_module_config(s->module_config, m,
  1483.                              (*m->create_server_config)(p, s));
  1484.     if (m->create_dir_config)
  1485.         ap_set_module_config(s->lookup_defaults, m,
  1486.                              (*m->create_dir_config)(p, NULL));
  1487. }
  1488.  
  1489. void ap_single_module_init(pool *p, server_rec *s, module *m)
  1490. {
  1491.     if (m->init)
  1492.         (*m->init)(s, p);
  1493.     build_method_shortcuts();
  1494.     init_handlers(p);
  1495. }
  1496.  
  1497. void ap_init_modules(pool *p, server_rec *s)
  1498. {
  1499.     module *m;
  1500.  
  1501.     for (m = top_module; m; m = m->next)
  1502.     if (m->init)
  1503.         (*m->init) (s, p);
  1504.     build_method_shortcuts();
  1505.     init_handlers(p);
  1506. }
  1507.  
  1508. void ap_child_init_modules(pool *p, server_rec *s)
  1509. {
  1510.     module *m;
  1511.  
  1512.     for (m = top_module; m; m = m->next)
  1513.     if (m->child_init)
  1514.         (*m->child_init) (s, p);
  1515. }
  1516.  
  1517. void ap_child_exit_modules(pool *p, server_rec *s)
  1518. {
  1519.     module *m;
  1520.  
  1521. #ifdef SIGHUP
  1522.     signal(SIGHUP, SIG_IGN);
  1523. #endif
  1524. #ifdef SIGUSR1
  1525.     signal(SIGUSR1, SIG_IGN);
  1526. #endif
  1527.  
  1528.     for (m = top_module; m; m = m->next)
  1529.     if (m->child_exit)
  1530.         (*m->child_exit) (s, p);
  1531.  
  1532. }
  1533.  
  1534. /********************************************************************
  1535.  * Configuration directives are restricted in terms of where they may
  1536.  * appear in the main configuration files and/or .htaccess files according
  1537.  * to the bitmask req_override in the command_rec structure.
  1538.  * If any of the overrides set in req_override are also allowed in the
  1539.  * context in which the command is read, then the command is allowed.
  1540.  * The context is determined as follows:
  1541.  *
  1542.  *    inside *.conf --> override = (RSRC_CONF|OR_ALL)&~(OR_AUTHCFG|OR_LIMIT);
  1543.  *    within <Directory> or <Location> --> override = OR_ALL|ACCESS_CONF;
  1544.  *    within .htaccess --> override = AllowOverride for current directory;
  1545.  *
  1546.  * the result is, well, a rather confusing set of possibilities for when
  1547.  * a particular directive is allowed to be used.  This procedure prints
  1548.  * in English where the given (pc) directive can be used.
  1549.  */
  1550. static void show_overrides(const command_rec *pc, module *pm)
  1551. {
  1552.     int n = 0;
  1553.  
  1554.     printf("\tAllowed in *.conf ");
  1555.     if ((pc->req_override & (OR_OPTIONS | OR_FILEINFO | OR_INDEXES)) ||
  1556.     ((pc->req_override & RSRC_CONF) &&
  1557.      ((pc->req_override & (ACCESS_CONF | OR_AUTHCFG | OR_LIMIT)))))
  1558.     printf("anywhere");
  1559.     else if (pc->req_override & RSRC_CONF)
  1560.     printf("only outside <Directory>, <Files> or <Location>");
  1561.     else
  1562.     printf("only inside <Directory>, <Files> or <Location>");
  1563.  
  1564.     /* Warn if the directive is allowed inside <Directory> or .htaccess
  1565.      * but module doesn't support per-dir configuration */
  1566.  
  1567.     if ((pc->req_override & (OR_ALL | ACCESS_CONF)) && !pm->create_dir_config)
  1568.     printf(" [no per-dir config]");
  1569.  
  1570.     if (pc->req_override & OR_ALL) {
  1571.     printf(" and in .htaccess\n\twhen AllowOverride");
  1572.  
  1573.     if ((pc->req_override & OR_ALL) == OR_ALL)
  1574.         printf(" isn't None");
  1575.     else {
  1576.         printf(" includes ");
  1577.  
  1578.         if (pc->req_override & OR_AUTHCFG) {
  1579.         if (n++)
  1580.             printf(" or ");
  1581.         printf("AuthConfig");
  1582.         }
  1583.         if (pc->req_override & OR_LIMIT) {
  1584.         if (n++)
  1585.             printf(" or ");
  1586.         printf("Limit");
  1587.         }
  1588.         if (pc->req_override & OR_OPTIONS) {
  1589.         if (n++)
  1590.             printf(" or ");
  1591.         printf("Options");
  1592.         }
  1593.         if (pc->req_override & OR_FILEINFO) {
  1594.         if (n++)
  1595.             printf(" or ");
  1596.         printf("FileInfo");
  1597.         }
  1598.         if (pc->req_override & OR_INDEXES) {
  1599.         if (n++)
  1600.             printf(" or ");
  1601.         printf("Indexes");
  1602.         }
  1603.     }
  1604.     }
  1605.     printf("\n");
  1606. }
  1607.  
  1608. /* Show the preloaded configuration directives, the help string explaining
  1609.  * the directive arguments, in what module they are handled, and in
  1610.  * what parts of the configuration they are allowed.  Used for httpd -h.
  1611.  */
  1612. void ap_show_directives()
  1613. {
  1614.     const command_rec *pc;
  1615.     int n;
  1616.  
  1617.     for (n = 0; ap_loaded_modules[n]; ++n)
  1618.     for (pc = ap_loaded_modules[n]->cmds; pc && pc->name; ++pc) {
  1619.         printf("%s (%s)\n", pc->name, ap_loaded_modules[n]->name);
  1620.         if (pc->errmsg)
  1621.         printf("\t%s\n", pc->errmsg);
  1622.         show_overrides(pc, ap_loaded_modules[n]);
  1623.     }
  1624. }
  1625.  
  1626. /* Show the preloaded module names.  Used for httpd -l. */
  1627. void ap_show_modules()
  1628. {
  1629.     int n;
  1630.  
  1631.     printf("Compiled-in modules:\n");
  1632.     for (n = 0; ap_loaded_modules[n]; ++n)
  1633.     printf("  %s\n", ap_loaded_modules[n]->name);
  1634. }
  1635.