home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 8 / CDACTUAL8.iso / share / os2 / varios / apache / http_con.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-06-29  |  21.1 KB  |  783 lines

  1.  
  2. /* ====================================================================
  3.  * Copyright (c) 1995 The Apache Group.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  *
  9.  * 1. Redistributions of source code must retain the above copyright
  10.  *    notice, this list of conditions and the following disclaimer. 
  11.  *
  12.  * 2. Redistributions in binary form must reproduce the above copyright
  13.  *    notice, this list of conditions and the following disclaimer in
  14.  *    the documentation and/or other materials provided with the
  15.  *    distribution.
  16.  *
  17.  * 3. All advertising materials mentioning features or use of this
  18.  *    software must display the following acknowledgment:
  19.  *    "This product includes software developed by the Apache Group
  20.  *    for use in the Apache HTTP server project (http://www.apache.org/)."
  21.  *
  22.  * 4. The names "Apache Server" and "Apache Group" must not be used to
  23.  *    endorse or promote products derived from this software without
  24.  *    prior written permission.
  25.  *
  26.  * 5. Redistributions of any form whatsoever must retain the following
  27.  *    acknowledgment:
  28.  *    "This product includes software developed by the Apache Group
  29.  *    for use in the Apache HTTP server project (http://www.apache.org/)."
  30.  *
  31.  * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
  32.  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  33.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  34.  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
  35.  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  36.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  37.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  38.  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  39.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  40.  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  41.  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  42.  * OF THE POSSIBILITY OF SUCH DAMAGE.
  43.  * ====================================================================
  44.  *
  45.  * This software consists of voluntary contributions made by many
  46.  * individuals on behalf of the Apache Group and was originally based
  47.  * on public domain software written at the National Center for
  48.  * Supercomputing Applications, University of Illinois, Urbana-Champaign.
  49.  * For more information on the Apache Group and the Apache HTTP server
  50.  * project, please see <http://www.apache.org/>.
  51.  *
  52.  */
  53.  
  54.  
  55. /*
  56.  * http_config.c: once was auxillary functions for reading httpd's config
  57.  * file and converting filenames into a namespace
  58.  *
  59.  * Rob McCool 
  60.  * 
  61.  * Wall-to-wall rewrite for Shambhala... commands which are part of the
  62.  * server core can now be found next door in "http_core.c".  Now contains
  63.  * general command loop, and functions which do bookkeeping for the new
  64.  * Shambhala config stuff (modules and configuration vectors).
  65.  *
  66.  * rst
  67.  *
  68.  */
  69.  
  70. #define CORE_PRIVATE
  71.  
  72. #include "httpd.h"
  73. #include "http_config.h"
  74. #include "http_core.h"
  75. #include "http_log.h"        /* for errors in parse_htaccess */
  76. #include "http_request.h"    /* for default_handler (see invoke_handler) */
  77. #include "http_conf_globals.h"    /* Sigh... */
  78.  
  79. /****************************************************************
  80.  *
  81.  * We begin with the functions which deal with the linked list
  82.  * of modules which control just about all of server operation in
  83.  * Shambhala.
  84.  */
  85.  
  86. static int num_modules = 0;    
  87. module *top_module = NULL;
  88.     
  89. typedef int (*handler)(request_rec *);
  90. typedef void *(*maker)(pool *);
  91. typedef void *(*dir_maker)(pool *, char *);
  92. typedef void *(*merger)(pool *, void *, void *);    
  93.  
  94. /* Dealing with config vectors.  These are associated with per-directory,
  95.  * per-server, and per-request configuration, and have a void* pointer for
  96.  * each modules.  The nature of the structure pointed to is private to the
  97.  * module in question... the core doesn't (and can't) know.  However, there
  98.  * are defined interfaces which allow it to create instances of its private
  99.  * per-directory and per-server structures, and to merge the per-directory
  100.  * structures of a directory and its subdirectory (producing a new one in
  101.  * which the defaults applying to the base directory have been properly
  102.  * overridden).
  103.  */
  104.  
  105. void *    
  106. get_module_config (void *conf_vector, module *m)
  107. {
  108.    void **confv = (void**)conf_vector;
  109.    return confv[m->module_index];
  110. }
  111.  
  112. void
  113. set_module_config (void *conf_vector, module *m, void *val)
  114. {
  115.    void **confv = (void**)conf_vector;
  116.    confv[m->module_index] = val;
  117. }
  118.  
  119. void *
  120. create_empty_config (pool *p)
  121. {
  122.    void **conf_vector = (void **)pcalloc(p, sizeof(void*) * num_modules);
  123.    return (void *)conf_vector;
  124. }
  125.  
  126. void *
  127. create_default_per_dir_config (pool *p)
  128. {
  129.    void **conf_vector = (void **)pcalloc(p, sizeof(void*) * (num_modules+DYNAMIC_MODULE_LIMIT));
  130.    module *modp;
  131.  
  132.    for (modp = top_module; modp; modp = modp->next) {
  133.        dir_maker df = modp->create_dir_config;
  134.  
  135.        if (df) conf_vector[modp->module_index] = (*df)(p, NULL);
  136.    }
  137.  
  138.    return (void*)conf_vector;
  139. }
  140.  
  141. void *
  142. merge_per_dir_configs (pool *p, void *base, void *new)
  143. {
  144.    void **conf_vector = (void **)pcalloc(p, sizeof(void*) * num_modules);
  145.    void **base_vector = (void **) base;
  146.    void **new_vector = (void **) new;
  147.    module *modp;
  148.  
  149.    for (modp = top_module; modp; modp = modp->next) {
  150.        merger df = modp->merge_dir_config;
  151.        int i = modp->module_index;
  152.  
  153.        if (df && new_vector[i])
  154.        conf_vector[i] = (*df)(p, base_vector[i], new_vector[i]);
  155.        else
  156.        conf_vector[i] = new_vector[i]? new_vector[i] : base_vector[i];
  157.    }
  158.  
  159.    return (void*)conf_vector;
  160. }
  161.  
  162. void *
  163. create_server_config (pool *p, server_rec *s)
  164. {
  165.    void **conf_vector = (void **)pcalloc(p, sizeof(void*) * (num_modules+DYNAMIC_MODULE_LIMIT));
  166.    module *modp;
  167.  
  168.    for (modp = top_module; modp; modp = modp->next) {
  169.        if (modp->create_server_config)
  170.        conf_vector[modp->module_index]=(*modp->create_server_config)(p,s);
  171.    }
  172.  
  173.    return (void*)conf_vector;
  174. }
  175.  
  176. void merge_server_configs (pool *p, void *base, void *virt)
  177. {
  178.     /* Can reuse the 'virt' vector for the spine of it, since we don't
  179.      * have to deal with the moral equivalent of .htaccess files here...
  180.      */
  181.  
  182.     void **base_vector = (void **)base;
  183.     void **virt_vector = (void **)virt;
  184.     module *modp;
  185.     
  186.     for (modp = top_module; modp; modp = modp->next) {
  187.     merger df = modp->merge_server_config;
  188.     int i = modp->module_index;
  189.  
  190.     if (!virt_vector[i])
  191.         virt_vector[i] = base_vector[i];
  192.     else if (df)
  193.         virt_vector[i] = (*df)(p, base_vector[i], virt_vector[i]);
  194.     }
  195. }
  196.  
  197. void *create_connection_config (pool *p) {
  198.     return create_empty_config (p);
  199. }
  200.  
  201. void *create_request_config (pool *p) {
  202.     return create_empty_config (p);
  203. }
  204.  
  205. void *create_per_dir_config (pool *p) {
  206.     return create_empty_config (p);
  207. }
  208.  
  209. /****************************************************************
  210.  *
  211.  * Dispatch through the modules to find handlers for various phases
  212.  * of request handling.  These are invoked by http_request.c to actually
  213.  * do the dirty work of slogging through the module structures.
  214.  */
  215.  
  216. int
  217. run_method (request_rec *r, int offset, int run_all)
  218. {
  219.    module *modp;
  220.    for (modp = top_module; modp; modp = modp->next) {
  221.        handler mod_handler = *(handler *)(offset + (char *)(modp));
  222.  
  223.        if (mod_handler) {
  224.        int result = (*mod_handler)(r);
  225.  
  226.        if (result != DECLINED && (!run_all || result != OK))
  227.            return result;
  228.        }
  229.    }
  230.  
  231.    return run_all ? OK : DECLINED;
  232. }
  233.  
  234. int translate_name(request_rec *r) {
  235.    return run_method (r, XtOffsetOf (module, translate_handler), 0);
  236. }
  237.  
  238. int check_access(request_rec *r) {
  239.    return run_method (r, XtOffsetOf (module, access_checker), 1);
  240. }
  241.  
  242. int find_types (request_rec *r) {
  243.    return run_method (r, XtOffsetOf (module, type_checker), 0);
  244. }
  245.  
  246. int run_fixups (request_rec *r) {
  247.    return run_method (r, XtOffsetOf (module, fixer_upper), 1);
  248. }
  249.  
  250. int log_transaction (request_rec *r) {
  251.    return run_method (r, XtOffsetOf (module, logger), 1);
  252. }
  253.  
  254. /* Auth stuff --- anything that defines one of these will presumably
  255.  * want to define something for the other.  Note that check_auth is
  256.  * separate from check_access to make catching some config errors easier.
  257.  */
  258.  
  259. int check_user_id (request_rec *r) {
  260.    return run_method (r, XtOffsetOf (module, check_user_id), 0);
  261. }
  262.  
  263. int check_auth (request_rec *r) {
  264.    return run_method (r, XtOffsetOf (module, auth_checker), 0);
  265. }
  266.  
  267. int invoke_handler (request_rec *r)
  268. {
  269.    module *modp;
  270.    handler_rec *handp;
  271.    char *content_type = r->content_type ? r->content_type : default_type (r);
  272.    char *handler = r->handler ? r->handler : content_type;
  273.   
  274.    /* Pass one --- direct matches */
  275.    
  276.    for (modp = top_module; modp; modp = modp->next) 
  277.    {
  278.        if (!modp->handlers) continue;
  279.        
  280.        for (handp = modp->handlers; handp->content_type; ++handp) {
  281.        if (!strcasecmp (handler, handp->content_type)) {
  282.            int result = (*handp->handler)(r);
  283.  
  284.            if (result != DECLINED) return result;
  285.        }
  286.        }
  287.    }
  288.    
  289.    /* Pass two --- wildcard matches */
  290.    
  291.    for (modp = top_module; modp; modp = modp->next) 
  292.    {
  293.        if (!modp->handlers) continue;
  294.        
  295.        for (handp = modp->handlers; handp->content_type; ++handp) {
  296.        char *starp = strchr (handp->content_type, '*');
  297.        int len;
  298.  
  299.        if (!starp) continue;
  300.  
  301.        len = starp - handp->content_type;
  302.        
  303.        if (!len || !strncasecmp (handler, handp->content_type, len))
  304.        {
  305.            int result = (*handp->handler)(r);
  306.  
  307.            if (result != DECLINED) return result;
  308.        }
  309.        }
  310.    }
  311.    
  312.    return NOT_IMPLEMENTED;
  313. }
  314.  
  315. /* One-time setup for precompiled modules --- NOT to be done on restart */
  316.  
  317. void add_module (module *m)
  318. {
  319.     /* This could be called from an AddModule httpd.conf command,
  320.      * after the file has been linked and the module structure within it
  321.      * teased out...
  322.      */
  323.  
  324.     m->next = top_module;
  325.     top_module = m;
  326.     m->module_index = num_modules++;
  327. }
  328.  
  329. void setup_prelinked_modules ()
  330. {
  331.     extern module *prelinked_modules[];
  332.     module **m = prelinked_modules;
  333.  
  334.     while (*m) {
  335.         add_module (*m);
  336.     ++m;
  337.     }
  338. }
  339.  
  340. /*****************************************************************
  341.  *
  342.  * Resource, access, and .htaccess config files now parsed by a common
  343.  * command loop.
  344.  *
  345.  * Let's begin with the basics; parsing the line and
  346.  * invoking the function...
  347.  */
  348.  
  349. char *invoke_cmd(command_rec *cmd, cmd_parms *parms, void *mconfig, char *args)
  350. {
  351.     char *w, *w2, *errmsg;
  352.  
  353.     if ((parms->override & cmd->req_override) == 0)
  354.         return pstrcat (parms->pool, cmd->name, " not allowed here", NULL);
  355.     
  356.     parms->info = cmd->cmd_data;
  357.     
  358.     switch (cmd->args_how) {
  359.     case RAW_ARGS:
  360.         return (*cmd->func) (parms, mconfig, args);
  361.  
  362.     case NO_ARGS:
  363.     if (*args != 0)
  364.         return pstrcat (parms->pool, cmd->name, " takes no arguments",
  365.                 NULL);
  366.  
  367.     return (*cmd->func) (parms, mconfig);
  368.     
  369.     case TAKE1:
  370.     w = getword_conf (parms->pool, &args);
  371.     
  372.     if (*w == '\0' || *args != 0) 
  373.         return pstrcat (parms->pool, cmd->name, " takes one argument",
  374.                 cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
  375.  
  376.     return (*cmd->func) (parms, mconfig, w);
  377.     
  378.     case TAKE2:
  379.  
  380.     w = getword_conf (parms->pool, &args);
  381.     w2 = getword_conf (parms->pool, &args);
  382.     
  383.     if (*w == '\0' || *w2 == '\0' || *args != 0) 
  384.         return pstrcat (parms->pool, cmd->name, " takes two arguments",
  385.                 cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
  386.  
  387.     return (*cmd->func) (parms, mconfig, w, w2);
  388.     
  389.     case ITERATE:
  390.  
  391.     while (*(w = getword_conf (parms->pool, &args)) != '\0')
  392.         if ((errmsg = (*cmd->func) (parms, mconfig, w)))
  393.             return errmsg;
  394.  
  395.     return NULL;
  396.     
  397.     case ITERATE2:
  398.  
  399.     w = getword_conf (parms->pool, &args);
  400.     
  401.     if (*w == '\0' || *args == 0) 
  402.         return pstrcat(parms->pool, cmd->name,
  403.                " requires at least two arguments",
  404.                cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
  405.       
  406.  
  407.     while (*(w2 = getword_conf (parms->pool, &args)) != '\0')
  408.         if ((errmsg = (*cmd->func) (parms, mconfig, w, w2)))
  409.             return errmsg;
  410.  
  411.     return NULL;
  412.     
  413.     case FLAG:
  414.  
  415.     w = getword_conf (parms->pool, &args);
  416.  
  417.     if (*w == '\0' || ((!strcasecmp(w, "on")) && (!strcasecmp (w, "off"))))
  418.         return pstrcat (parms->pool, cmd->name, " must be On or Off",
  419.                 NULL);
  420.  
  421.     return (*cmd->func) (parms, mconfig, strcasecmp (w, "off") != 0);
  422.  
  423.     default:
  424.  
  425.     return pstrcat (parms->pool, cmd->name,
  426.             " is improperly configured internally (server bug)",
  427.             NULL);
  428.     }
  429. }
  430.  
  431. command_rec *find_command (char *name, command_rec *cmds)
  432. {
  433.     while (cmds->name) 
  434.         if (!strcasecmp (name, cmds->name))
  435.         return cmds;
  436.     else
  437.         ++cmds;
  438.  
  439.     return NULL;
  440. }
  441.     
  442. command_rec *find_command_in_modules (char *cmd_name, module **mod)
  443. {
  444.    command_rec *cmdp;
  445.    module *modp;
  446.  
  447.    for (modp = top_module; modp; modp = modp->next) 
  448.        if (modp->cmds && (cmdp = find_command (cmd_name, modp->cmds))) {
  449.        *mod = modp;
  450.        return cmdp;
  451.        }
  452.  
  453.    return NULL;
  454. }
  455.  
  456. char *handle_command (cmd_parms *parms, void *config, char *l)
  457. {
  458.     char *args, *cmd_name;
  459.     command_rec *cmd;
  460.     module *mod;
  461.  
  462.     ++parms->config_line;
  463.     if((l[0] == '#') || (!l[0])) return NULL;
  464.     
  465.     args = l;
  466.     cmd_name = getword_conf (parms->temp_pool, &args);
  467.     if (*cmd_name == '\0') return NULL;
  468.     
  469.     if (!(cmd = find_command_in_modules (cmd_name, &mod))) {
  470.     return pstrcat (parms->pool, "Invalid command ", cmd_name, NULL);
  471.     }
  472.     else {
  473.     void *mconfig = get_module_config (config, mod);
  474.     void *sconfig = get_module_config (parms->server->module_config, mod);
  475.           
  476.     if (!mconfig && mod->create_dir_config) {
  477.         mconfig = (*mod->create_dir_config) (parms->pool, parms->path);
  478.         set_module_config (config, mod, mconfig);
  479.     }
  480.         
  481.     if (!sconfig && mod->create_server_config) {
  482.         sconfig = (*mod->create_server_config)(parms->pool, parms->server);
  483.         set_module_config (parms->server->module_config, mod, sconfig);
  484.     }
  485.     
  486.     return invoke_cmd (cmd, parms, mconfig, args);
  487.     }
  488. }
  489.  
  490. char *srm_command_loop (cmd_parms *parms, void *config)
  491. {
  492.     char l[MAX_STRING_LEN];
  493.     
  494.     while (!(cfg_getline (l, MAX_STRING_LEN, parms->infile))) {
  495.     char *errmsg = handle_command (parms, config, l);
  496.     if (errmsg) return errmsg;
  497.     }
  498.  
  499.     return NULL;
  500. }
  501.  
  502. /*
  503.  * Generic command functions...
  504.  */
  505.  
  506. char *set_string_slot (cmd_parms *cmd, char *struct_ptr, char *arg)
  507. {
  508.     /* This one's pretty generic... */
  509.   
  510.     int offset = (int)cmd->info; 
  511.     *(char **)(struct_ptr + offset) = pstrdup (cmd->pool, arg);
  512.     return NULL;
  513. }
  514.  
  515. /*****************************************************************
  516.  *
  517.  * Reading whole config files...
  518.  */
  519.  
  520. cmd_parms default_parms = { NULL, 0, -1, NULL, 0, NULL, NULL, NULL, NULL };
  521.  
  522. char *server_root_relative (pool *p, char *file)
  523. {
  524. #ifdef __EMX__
  525.     /* Add support for OS/2 drive names */
  526.     if ((file[0] == '/') || (file[1] == ':')) return file;
  527. #else
  528.     if (file[0] == '/') return file;
  529. #endif    
  530.     return make_full_path (p, server_root, file);
  531. }
  532.  
  533. void process_resource_config(server_rec *s, char *fname, pool *p, pool *ptemp)
  534. {
  535.     FILE *cfg;
  536.     char *errmsg;
  537.     cmd_parms parms;
  538.     
  539.     fname = server_root_relative (p, fname);
  540.     
  541.     /* GCC's initialization extensions are soooo nice here... */
  542.     
  543.     parms = default_parms;
  544.     parms.config_file = fname;
  545.     parms.pool = p;
  546.     parms.temp_pool = ptemp;
  547.     parms.server = s;
  548.     parms.override = (RSRC_CONF|OR_ALL)&~(OR_AUTHCFG|OR_LIMIT);
  549.     
  550.     if(!(cfg = fopen(fname, "r"))) {
  551.         fprintf(stderr,"httpd: could not open document config file %s\n",
  552.                 fname);
  553.         perror("fopen");
  554.         exit(1);
  555.     } 
  556.  
  557.     parms.infile = cfg;
  558.     
  559.     errmsg = srm_command_loop (&parms, s->lookup_defaults);
  560.     
  561.     if (errmsg) {
  562.         fprintf (stderr, "Syntax error on line %d of %s:\n",
  563.          parms.config_line, fname);
  564.     fprintf (stderr, "%s\n", errmsg);
  565.     exit(1);
  566.     }
  567.     
  568.     fclose(cfg);
  569. }
  570.  
  571.  
  572. int parse_htaccess(void **result, request_rec *r, int override,
  573.            char *d, char *filename)
  574. {
  575.     FILE *f;
  576.     cmd_parms parms;
  577.     char *errmsg;
  578.     const struct htaccess_result *cache;
  579.     struct htaccess_result *new;
  580.     void *dc;
  581.  
  582. /* firstly, search cache */
  583.     for (cache=r->htaccess; cache != NULL; cache=cache->next)
  584.     if (cache->override == override && strcmp(cache->dir, d) == 0)
  585.     {
  586.         if (cache->htaccess != NULL) *result = cache->htaccess;
  587.         return OK;
  588.     }
  589.  
  590.     parms = default_parms;
  591.     parms.override = override;
  592.     parms.pool = r->pool;
  593.     parms.temp_pool = r->pool;
  594.     parms.server = r->server;
  595.     parms.path = d;
  596.  
  597.     if((f=pfopen(r->pool, filename, "r"))) {
  598.         dc = create_per_dir_config (r->pool);
  599.     
  600.         parms.infile = f;
  601.     parms.config_file = filename;
  602.  
  603.     errmsg = srm_command_loop (&parms, dc);
  604.     
  605.         pfclose(r->pool, f);
  606.  
  607.     if (errmsg) {
  608.         log_reason (errmsg, filename, r);
  609.         return SERVER_ERROR;
  610.     }
  611.     
  612.     *result = dc;
  613.     } else
  614.     dc = NULL;
  615.  
  616. /* cache it */
  617.     new = palloc(r->pool, sizeof(struct htaccess_result));
  618.     new->dir = pstrdup(r->pool, d);
  619.     new->override = override;
  620.     new->htaccess = dc;
  621. /* add to head of list */
  622.     new->next = r->htaccess;
  623.     r->htaccess = new;
  624.  
  625.     return OK;
  626. }
  627.  
  628. /*****************************************************************
  629.  *
  630.  * Virtual host stuff; note that the commands that invoke this stuff
  631.  * are with the command table in http_core.c.
  632.  */
  633.  
  634. server_rec *init_virtual_host (pool *p, char *hostname)
  635. {
  636.     server_rec *s = (server_rec *)pcalloc (p, sizeof (server_rec));
  637.  
  638. #ifdef RLIMIT_NOFILE
  639.     struct rlimit limits;
  640.  
  641.     getrlimit ( RLIMIT_NOFILE, &limits );
  642.     if ( limits.rlim_cur < limits.rlim_max ) {
  643.       limits.rlim_cur += 2;
  644.       if ( setrlimit ( RLIMIT_NOFILE, &limits ) < 0 )
  645.     fprintf (stderr, "Cannot exceed hard limit for open files");
  646.     }
  647. #endif
  648.  
  649.     s->server_admin = NULL;
  650.     s->server_hostname = NULL; 
  651.     s->error_fname = NULL;
  652.     s->srm_confname = NULL;
  653.     s->access_confname = NULL;
  654.     s->timeout = 0;
  655.     s->keep_alive_timeout = 0;
  656.     s->keep_alive = -1;
  657.     s->host_addr.s_addr = get_virthost_addr (hostname, &s->host_port);
  658.     s->port = s->host_port;  /* set them the same, by default */
  659.     s->next = NULL;
  660.  
  661.     s->is_virtual = 1;
  662.     s->virthost = pstrdup(p, hostname);
  663.     s->names = NULL;
  664.  
  665.     s->module_config = create_empty_config (p);
  666.     s->lookup_defaults = create_per_dir_config (p);
  667.     
  668.     return s;
  669. }
  670.  
  671. int is_virtual_server (server_rec *s)
  672. {
  673.     return s->is_virtual;
  674. }
  675.  
  676. void fixup_virtual_hosts (pool *p, server_rec *main_server)
  677. {
  678.     server_rec *virt;
  679.  
  680.     for (virt = main_server->next; virt; virt = virt->next) {
  681.     merge_server_configs (p, main_server->module_config,
  682.                   virt->module_config);
  683.     
  684.     virt->lookup_defaults =
  685.         merge_per_dir_configs (p, main_server->lookup_defaults,
  686.                    virt->lookup_defaults);
  687.  
  688.     if (virt->port == 0)
  689.         virt->port = main_server->port;
  690.  
  691.     if (virt->server_admin == NULL)
  692.         virt->server_admin = main_server->server_admin;
  693.  
  694.     if (virt->srm_confname == NULL)
  695.         virt->srm_confname = main_server->srm_confname;
  696.  
  697.     if (virt->access_confname == NULL)
  698.         virt->access_confname = main_server->access_confname;
  699.  
  700.     if (virt->timeout == 0)
  701.         virt->timeout = main_server->timeout;
  702.  
  703.     if (virt->keep_alive_timeout == 0)
  704.         virt->keep_alive_timeout = main_server->keep_alive_timeout;
  705.  
  706.     if (virt->keep_alive == -1)
  707.         virt->keep_alive = main_server->keep_alive;
  708.     }
  709. }
  710.  
  711. /*****************************************************************
  712.  *
  713.  * Getting *everything* configured... 
  714.  */
  715.  
  716. void init_config_globals (pool *p)
  717. {
  718.     /* ServerRoot, server_confname set in httpd.c */
  719.     
  720.     standalone = 1;
  721.     user_name = DEFAULT_USER;
  722.     user_id = uname2id(DEFAULT_USER);
  723.     group_id = gname2id(DEFAULT_GROUP);
  724.     daemons_to_start = DEFAULT_START_DAEMON;
  725.     daemons_min_free = DEFAULT_MIN_FREE_DAEMON;
  726.     daemons_max_free = DEFAULT_MAX_FREE_DAEMON;
  727.     daemons_limit = HARD_SERVER_LIMIT;
  728.     pid_fname = DEFAULT_PIDLOG;
  729.     scoreboard_fname = DEFAULT_SCOREBOARD;
  730.     max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD;
  731.     bind_address.s_addr = htonl(INADDR_ANY);
  732.     listeners = NULL;
  733. }
  734.  
  735. server_rec *init_server_config(pool *p)
  736. {
  737.     server_rec *s = (server_rec *)pcalloc (p, sizeof (server_rec));
  738.  
  739.     s->port = DEFAULT_PORT;
  740.     s->server_admin = DEFAULT_ADMIN;
  741.     s->server_hostname = NULL; 
  742.     s->error_fname = DEFAULT_ERRORLOG;
  743.     s->srm_confname = RESOURCE_CONFIG_FILE;
  744.     s->access_confname = ACCESS_CONFIG_FILE;
  745.     s->timeout = DEFAULT_TIMEOUT;
  746.     s->keep_alive_timeout = DEFAULT_KEEPALIVE_TIMEOUT;
  747.     s->keep_alive = DEFAULT_KEEPALIVE;
  748.     s->next = NULL;
  749.     s->host_addr.s_addr = htonl (INADDR_ANY); /* NOT virtual host;
  750.                            * don't match any real network
  751.                            * interface.
  752.                            */
  753.     s->host_port = 0; /* matches any port */
  754.  
  755.     s->module_config = create_server_config (p, s);
  756.     s->lookup_defaults = create_default_per_dir_config (p);
  757.     
  758.     return s;
  759. }
  760.  
  761. server_rec *read_config(pool *p, pool *ptemp, char *confname)
  762. {
  763.     server_rec *s = init_server_config(p);
  764.     module *m;
  765.     
  766.     init_config_globals(p);
  767.     
  768.     /* All server-wide config files now have the SAME syntax... */
  769.     
  770.     process_resource_config (s, confname, p, ptemp);
  771.     process_resource_config (s, s->srm_confname, p, ptemp);
  772.     process_resource_config (s, s->access_confname, p, ptemp);
  773.     
  774.     fixup_virtual_hosts (p, s);
  775.     
  776.     for (m = top_module; m; m = m->next)
  777.         if (m->init)
  778.         (*m->init) (s, p);
  779.     
  780.     return s;
  781. }
  782.  
  783.