Ejemplo n.º 1
0
static void push_item(array_header *arr, char *type, char *to, char *path,
		      char *data)
{
    struct item *p = (struct item *) ap_push_array(arr);

    if (!to) {
	to = "";
    }
    if (!path) {
	path = "";
    }

    p->type = type;
    p->data = data ? ap_pstrdup(arr->pool, data) : NULL;
    p->apply_path = ap_pstrcat(arr->pool, path, "*", NULL);

    if ((type == BY_PATH) && (!ap_is_matchexp(to))) {
	p->apply_to = ap_pstrcat(arr->pool, "*", to, NULL);
    }
    else if (to) {
	p->apply_to = ap_pstrdup(arr->pool, to);
    }
    else {
	p->apply_to = NULL;
    }
}
Ejemplo n.º 2
0
 /*******************************************************************************
  * Concat src1 and src2 using the approprate path seperator for the platform. 
  */
static char * make_full_path(pool *a, const char *src1, const char *src2)
{
#ifdef WIN32
    register int x;
    char * p ;
    char * q ;

    x = strlen(src1);

    if (x == 0) {
	    p = ap_pstrcat(a, "\\", src2, NULL);
    }
    else if (src1[x - 1] != '\\' && src1[x - 1] != '/') {
	    p = ap_pstrcat(a, src1, "\\", src2, NULL);
    }
    else {
	    p = ap_pstrcat(a, src1, src2, NULL);
    }

    q = p ;
    while (*q)
	{
        if (*q == '/') {
	        *q = '\\' ;
        }
	    ++q;
	}

    return p ;
#else
    return ap_make_full_path(a, src1, src2);
#endif
}
Ejemplo n.º 3
0
static char *find_digest(request_rec *r, digest_header_rec * h, char *a1)
{
    return ap_md5(r->pool,
		  (unsigned char *)ap_pstrcat(r->pool, a1, ":", h->nonce, ":",
					   ap_md5(r->pool,
		           (unsigned char *)ap_pstrcat(r->pool, r->method, ":",
						    h->requested_uri, NULL)),
					   NULL));
}
Ejemplo n.º 4
0
/*******************************************************************************
 * Build an Inet Socket Address structure, and calculate its size.
 * The error message is allocated from the pool p. If you don't want the
 * struct sockaddr_in also allocated from p, pass it preallocated (!=NULL).
 */
const char *
fcgi_util_socket_make_inet_addr(pool *p, struct sockaddr_in **socket_addr,
        int *socket_addr_len, const char *host, unsigned short port)
{
    if (*socket_addr == NULL)
        *socket_addr = ap_pcalloc(p, sizeof(struct sockaddr_in));
    else
        memset(*socket_addr, 0, sizeof(struct sockaddr_in));

    (*socket_addr)->sin_family = AF_INET;
    (*socket_addr)->sin_port = htons(port);

    /* Get an in_addr represention of the host */
    if (host != NULL) {
        if (convert_string_to_in_addr(host, &(*socket_addr)->sin_addr) != 1) {
            return ap_pstrcat(p, "failed to resolve \"", host,
                           "\" to exactly one IP address", NULL);
        }
    } else {
      (*socket_addr)->sin_addr.s_addr = htonl(INADDR_ANY);
    }

    *socket_addr_len = sizeof(struct sockaddr_in);
    return NULL;
}
Ejemplo n.º 5
0
/*******************************************************************************
 * Get the next configuration directive argument, & return an u_short.
 * The pool arg should be temporary storage.
 */
static const char *get_u_short(pool *p, const char **arg,
        u_short *num, u_short min)
{
    char *ptr;
	long tmp;
    const char *txt = ap_getword_conf(p, arg);

    if (*txt == '\0') {
		return "\"\"";
	}

    tmp = strtol(txt, &ptr, 10);

    if (*ptr != '\0') {
        return ap_pstrcat(p, "\"", txt, "\" must be a positive integer", NULL);
	}
    
	if (tmp < min || tmp > USHRT_MAX) {
        return ap_psprintf(p, "\"%u\" must be >= %u and < %u", *num, min, USHRT_MAX);
	}

	*num = (u_short) tmp;

    return NULL;
}
Ejemplo n.º 6
0
/*******************************************************************************
 * Get the next configuration directive argument, & return an in_addr and port.
 * The arg must be in the form "host:port" where host can be an IP or hostname.
 * The pool arg should be persistant storage.
 */
static const char *get_host_n_port(pool *p, const char **arg,
        const char **host, u_short *port)
{
    char *cvptr, *portStr;
    long tmp;

    *host = ap_getword_conf(p, arg);
    if (**host == '\0')
        return "\"\"";

    portStr = strchr(*host, ':');
    if (portStr == NULL)
        return "missing port specification";

    /* Split the host and port portions */
    *portStr++ = '\0';

    /* Convert port number */
    tmp = (u_short) strtol(portStr, &cvptr, 10);
    if (*cvptr != '\0' || tmp < 1 || tmp > USHRT_MAX)
        return ap_pstrcat(p, "bad port number \"", portStr, "\"", NULL);

    *port = (unsigned short) tmp;

    return NULL;
}
Ejemplo n.º 7
0
/*
 * This function gets called to merge two per-server configuration
 * records.  This is typically done to cope with things like virtual hosts and
 * the default server configuration  The routine has the responsibility of
 * creating a new record and merging the contents of the other two into it
 * appropriately.  If the module doesn't declare a merge routine, the more
 * specific existing record is used exclusively.
 *
 * The routine MUST NOT modify any of its arguments!
 *
 * The return value is a pointer to the created module-specific structure
 * containing the merged values.
 */
static void *example_merge_server_config(pool *p, void *server1_conf,
                                         void *server2_conf)
{

    excfg *merged_config = (excfg *) ap_pcalloc(p, sizeof(excfg));
    excfg *s1conf = (excfg *) server1_conf;
    excfg *s2conf = (excfg *) server2_conf;
    char *note;

    /*
     * Our inheritance rules are our own, and part of our module's semantics.
     * Basically, just note whence we came.
     */
    merged_config->cmode =
        (s1conf->cmode == s2conf->cmode) ? s1conf->cmode : CONFIG_MODE_COMBO;
    merged_config->local = s2conf->local;
    merged_config->congenital = (s1conf->congenital | s1conf->local);
    merged_config->loc = ap_pstrdup(p, s2conf->loc);
    /*
     * Trace our call, including what we were asked to merge.
     */
    note = ap_pstrcat(p, "example_merge_server_config(\"", s1conf->loc, "\",\"",
                   s2conf->loc, "\")", NULL);
    trace_add(NULL, NULL, merged_config, note);
    return (void *) merged_config;
}
Ejemplo n.º 8
0
static int psx_auth_fail(request_rec *r, qEnvApache *renv)
{
// this is kinda wrong.... but for now we keep it....
	
	if (!r->header_only) {
		CStr resp = renv->GetCtx()->Eval("http-noauth");
		if (!resp.IsEmpty()) {
			qStrBuf bufin(resp);
			qStrBuf bufout;
			renv->GetCtx()->ParseTry(&bufin, &bufout);
			ap_custom_response(r, HTTP_UNAUTHORIZED, bufout.GetBuffer());
		}
	}

	if (!ap_auth_type(r)) {
		ap_table_setn(r->err_headers_out,
			  r->proxyreq ? "Proxy-Authenticate" : "WWW-Authenticate",
			  ap_pstrcat(r->pool, "Basic realm=\"", ap_auth_name(r), "\"",
				  NULL));
	} else {
		ap_note_basic_auth_failure(r);
	}
	renv->Free();

	ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, AP2STATUS r, "returning unauthorized: %d, status : %d", HTTP_UNAUTHORIZED, r->status);
	return HTTP_UNAUTHORIZED;
}
Ejemplo n.º 9
0
/*
 * This function gets called to create a per-directory configuration
 * record.  This will be called for the "default" server environment, and for
 * each directory for which the parser finds any of our directives applicable.
 * If a directory doesn't have any of our directives involved (i.e., they
 * aren't in the .htaccess file, or a <Location>, <Directory>, or related
 * block), this routine will *not* be called - the configuration for the
 * closest ancestor is used.
 *
 * The return value is a pointer to the created module-specific
 * structure.
 */
static void *example_create_dir_config(pool *p, char *dirspec)
{

    excfg *cfg;
    char *dname = dirspec;

    /*
     * Allocate the space for our record from the pool supplied.
     */
    cfg = (excfg *) ap_pcalloc(p, sizeof(excfg));
    /*
     * Now fill in the defaults.  If there are any `parent' configuration
     * records, they'll get merged as part of a separate callback.
     */
    cfg->local = 0;
    cfg->congenital = 0;
    cfg->cmode = CONFIG_MODE_DIRECTORY;
    /*
     * Finally, add our trace to the callback list.
     */
    dname = (dname != NULL) ? dname : "";
    cfg->loc = ap_pstrcat(p, "DIR(", dname, ")", NULL);
    trace_add(NULL, NULL, cfg, "example_create_dir_config()");
    return (void *) cfg;
}
Ejemplo n.º 10
0
static const char *load_file(cmd_parms *cmd, void *dummy, char *filename)
{
    ap_os_dso_handle_t handle;
    char *file;

    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
    if (err != NULL) {
        return err;
    }
    
    file = ap_server_root_relative(cmd->pool, filename);
    
    if (!(handle = ap_os_dso_load(file))) {
	const char *my_error = ap_os_dso_error();
	return ap_pstrcat (cmd->pool, "Cannot load ", filename, 
			" into server:", 
			my_error ? my_error : "(reason unknown)",
			NULL);
    }
    
    ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, NULL,
		"loaded file %s", filename);

    ap_register_cleanup(cmd->pool, (void *)handle, unload_file, ap_null_cleanup);

    return NULL;
}
Ejemplo n.º 11
0
static const char *set_digest_slot(cmd_parms *cmd, void *offset, char *f, char *t)
{
    if (t && strcmp(t, "standard"))
	return ap_pstrcat(cmd->pool, "Invalid auth file type: ", t, NULL);

    return ap_set_string_slot(cmd, offset, f);
}
Ejemplo n.º 12
0
/*
** dav_fs_format_locktoken
**
** Generate the URI for a locktoken
*/
static const char *dav_fs_format_locktoken(
    pool *p,
    const dav_locktoken *locktoken)
{
    const char *uuid_token = dav_format_opaquelocktoken(p, &locktoken->uuid);
    return ap_pstrcat(p, "opaquelocktoken:", uuid_token, NULL);
}
Ejemplo n.º 13
0
/*******************************************************************************
 * Compute printable MD5 hash. Pool p is used for scratch as well as for
 * allocating the hash - use temp storage, and dup it if you need to keep it.
 */
char *
fcgi_util_socket_hash_filename(pool *p, const char *path,
        const char *user, const char *group)
{
    char *buf = ap_pstrcat(p, path, user, group, NULL);

    /* Canonicalize the path (remove "//", ".", "..") */
    ap_getparents(buf);

    return ap_md5(p, (unsigned char *)buf);
}
Ejemplo n.º 14
0
/*
 * All our process-death routine does is add its trace to the log.
 */
static void example_child_exit(server_rec *s, pool *p)
{

    char *note;
    char *sname = s->server_hostname;

    /*
     * The arbitrary text we add to our trace entry indicates for which server
     * we're being called.
     */
    sname = (sname != NULL) ? sname : "";
    note = ap_pstrcat(p, "example_child_exit(", sname, ")", NULL);
    trace_add(s, NULL, NULL, note);
}
Ejemplo n.º 15
0
static const char *log_request_line(request_rec *r, char *a)
{
	    /* NOTE: If the original request contained a password, we
	     * re-write the request line here to contain XXXXXX instead:
	     * (note the truncation before the protocol string for HTTP/0.9 requests)
	     * (note also that r->the_request contains the unmodified request)
	     */
    return ap_escape_logitem(r->pool,
			     (r->parsed_uri.password) ? ap_pstrcat(r->pool, r->method, " ",
					 ap_unparse_uri_components(r->pool, &r->parsed_uri, 0),
					 r->assbackwards ? NULL : " ", r->protocol, NULL)
					: r->the_request
			     );
}
Ejemplo n.º 16
0
API_EXPORT(char **) ap_create_environment(pool *p, table *t)
{
    array_header *env_arr = ap_table_elts(t);
    table_entry *elts = (table_entry *) env_arr->elts;
    char **env = (char **) ap_palloc(p, (env_arr->nelts + 2) * sizeof(char *));
    int i, j;
    char *tz;
    char *whack;

    j = 0;
    if (!ap_table_get(t, "TZ")) {
	tz = getenv("TZ");
	if (tz != NULL) {
	    env[j++] = ap_pstrcat(p, "TZ=", tz, NULL);
	}
    }
    for (i = 0; i < env_arr->nelts; ++i) {
        if (!elts[i].key) {
	    continue;
	}
	env[j] = ap_pstrcat(p, elts[i].key, "=", elts[i].val, NULL);
	whack = env[j];
	if (ap_isdigit(*whack)) {
	    *whack++ = '_';
	}
	while (*whack != '=') {
	    if (!ap_isalnum(*whack) && *whack != '_') {
		*whack = '_';
	    }
	    ++whack;
	}
	++j;
    }

    env[j] = NULL;
    return env;
}
Ejemplo n.º 17
0
/*
 * This really wants to be a nested function
 * but C is too feeble to support them.
 */
static ap_inline void vhost_alias_checkspace(request_rec *r, char *buf,
					     char **pdest, int size)
{
    /* XXX: what if size > HUGE_STRING_LEN? */
    if (*pdest + size > buf + HUGE_STRING_LEN) {
	**pdest = '\0';
	if (r->filename) {
	    r->filename = ap_pstrcat(r->pool, r->filename, buf, NULL);
	}
	else {
	    r->filename = ap_pstrdup(r->pool, buf);
	}
	*pdest = buf;
    }
}
Ejemplo n.º 18
0
/*******************************************************************************
 * Get the next configuration directive argument, & return an u_int.
 * The pool arg should be temporary storage.
 */
static const char *get_u_int(pool *p, const char **arg,
        u_int *num, u_int min)
{
    char *ptr;
    const char *val = ap_getword_conf(p, arg);

    if (*val == '\0')
        return "\"\"";
    *num = (u_int)strtol(val, &ptr, 10);

    if (*ptr != '\0')
        return ap_pstrcat(p, "\"", val, "\" must be a positive integer", NULL);
    else if (*num < min)
        return ap_psprintf(p, "\"%u\" must be >= %u", *num, min);
    return NULL;
}
Ejemplo n.º 19
0
char *ApacheRequest_params_as_string(ApacheRequest *req, const char *key)
{
    char *retval = NULL;
    array_header *values = ApacheRequest_params(req, key);
    int i;

    for (i=0; i<values->nelts; i++) {
	retval = ap_pstrcat(req->r->pool,
			    retval ? retval : "",
			    ((char **)values->elts)[i],
			    (i == (values->nelts - 1)) ? NULL : ", ",
			    NULL);
    }

    return retval;
}
Ejemplo n.º 20
0
/*******************************************************************************
 * Get the next configuration directive argument, & return a float.
 * The pool arg should be temporary storage.
 */
static const char *get_float(pool *p, const char **arg,
        float *num, float min, float max)
{
    char *ptr;
    const char *val = ap_getword_conf(p, arg);

    if (*val == '\0')
        return "\"\"";
    *num = (float) strtod(val, &ptr);

    if (*ptr != '\0')
        return ap_pstrcat(p, "\"", val, "\" is not a floating point number", NULL);
    if (*num < min || *num > max)
        return ap_psprintf(p, "\"%f\" is not between %f and %f", *num, min, max);
    return NULL;
}
Ejemplo n.º 21
0
static char *http2env(pool *a, char *w)
{
    char *res = ap_pstrcat(a, "HTTP_", w, NULL);
    char *cp = res;

    while (*++cp) {
	if (!ap_isalnum(*cp) && *cp != '_') {
	    *cp = '_';
	}
	else {
	    *cp = ap_toupper(*cp);
	}
    }

    return res;
}
Ejemplo n.º 22
0
const char *fcgi_config_set_env_var(pool *p, char **envp, unsigned int *envc, char * var)
{
    if (*envc >= MAX_INIT_ENV_VARS) {
        return "too many variables, must be <= MAX_INIT_ENV_VARS";
    }

    if (strchr(var, '=') == NULL) {
        *(envp + *envc) = ap_pstrcat(p, var, "=", getenv(var), NULL);
    }
    else {
        *(envp + *envc) = var;
    }

    (*envc)++;

    return NULL;
}
Ejemplo n.º 23
0
/*
** dav_fs_save_locknull_list:  Saves contents of pbuf into the
**    locknull file for dirpath.
*/
static dav_error * dav_fs_save_locknull_list(pool *p, const char *dirpath,
					     dav_buffer *pbuf)
{
    const char *pathname;
    int fd;
    dav_error *err = NULL;

    if (pbuf->buf == NULL)
	return NULL;

    dav_fs_ensure_state_dir(p, dirpath);
    pathname = ap_pstrcat(p,
			  dirpath,
			  dirpath[strlen(dirpath) - 1] == '/' ? "" : "/",
			  DAV_FS_STATE_DIR "/" DAV_FS_LOCK_NULL_FILE,
			  NULL);

    if (pbuf->cur_len == 0) {
	/* delete the file if cur_len == 0 */
	if (remove(pathname) != 0) {
	    return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
				 ap_psprintf(p,
					     "Error removing %s", pathname));
	}
	return NULL;
    }

    if ((fd = open(pathname, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
		   DAV_FS_MODE_FILE)) == -1) {
	return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
			     ap_psprintf(p,
					 "Error opening %s for writing",
					 pathname));
    }

    if (write(fd, pbuf->buf, pbuf->cur_len) != pbuf->cur_len) {
	err = dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
			    ap_psprintf(p,
					"Error writing %i bytes to %s",
					pbuf->cur_len, pathname));
    }

    close(fd);
    return err;
}
Ejemplo n.º 24
0
/*
 * All our process-initialiser does is add its trace to the log.
 */
static void example_child_init(server_rec *s, pool *p)
{

    char *note;
    char *sname = s->server_hostname;

    /*
     * Set up any module cells that ought to be initialised.
     */
    setup_module_cells();
    /*
     * The arbitrary text we add to our trace entry indicates for which server
     * we're being called.
     */
    sname = (sname != NULL) ? sname : "";
    note = ap_pstrcat(p, "example_child_init(", sname, ")", NULL);
    trace_add(s, NULL, NULL, note);
}
Ejemplo n.º 25
0
/*
 * Canonicalise http-like URLs.
 *  scheme is the scheme for the URL
 *  url    is the URL starting with the first '/'
 *  def_port is the default port for this scheme.
 */
int ap_proxy_http_canon(request_rec *r, char *url, const char *scheme, int def_port)
{
    char *host, *path, *search, sport[7];
    const char *err;
    int port;

    /*
     * do syntatic check. We break the URL into host, port, path, search
     */
    port = def_port;
    err = ap_proxy_canon_netloc(r->pool, &url, NULL, NULL, &host, &port);
    if (err)
        return HTTP_BAD_REQUEST;

    /* now parse path/search args, according to rfc1738 */
    /*
     * N.B. if this isn't a true proxy request, then the URL _path_ has
     * already been decoded.  True proxy requests have r->uri ==
     * r->unparsed_uri, and no others have that property.
     */
    if (r->uri == r->unparsed_uri) {
        search = strchr(url, '?');
        if (search != NULL)
            *(search++) = '\0';
    }
    else
        search = r->args;

    /* process path */
    path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path,
                             r->proxyreq);
    if (path == NULL)
        return HTTP_BAD_REQUEST;

    if (port != def_port)
        ap_snprintf(sport, sizeof(sport), ":%d", port);
    else
        sport[0] = '\0';

    r->filename = ap_pstrcat(r->pool, "proxy:", scheme, "://", host, sport, "/",
                   path, (search) ? "?" : "", (search) ? search : "", NULL);
    return OK;
}
Ejemplo n.º 26
0
/**
 *  get DSAME Cookie
 */
static char *get_cookie(request_rec *r, const char *name)
{
    static const char separators[] = { " ;\n\r\t\f" };
    char *cookie;
    char *part;
    char *marker = NULL;
    char *value = NULL;
    char *last_separator;

    if (!(cookie = (char *)ap_table_get(r->headers_in, "Cookie"))) {
	am_web_log_warning("in get_cookie: no cookie in ap_table");
	return NULL;
    }

    part = ap_pstrcat (r->pool, cookie, ";", NULL);
    am_web_log_debug("in get_cookie: part is  %s", part);

    // get the last IS cookie
    for (part = strtok_r(part, separators, &last_separator);
	part != NULL;
	part = strtok_r(NULL, separators, &last_separator))
    {
	while (part && !(marker = strchr(part, '='))) {
	    part = strtok_r(NULL, separators, &last_separator);
	}

	if (++marker) {
	    if (!strcasecmp(ap_getword(r->pool, (const char **)&part, '='),
		name))
	    {
		value = marker;
	    }
	}
    }

    if (value) {
	am_web_log_debug("in get_cookie: return cookie value of %s", value);
    }

    return value;
}
Ejemplo n.º 27
0
static int dirsize(void *rp, child_info *pinfo)
{
  char **env;
  int child_pid;
  request_rec *r = (request_rec *) rp;

  env = ap_create_environment(r->pool, r->subprocess_env);
  ap_error_log2stderr(r->server);
  r->filename = "/usr/bin/du"; // fixme: ugly!
  r->args = ap_pstrcat(r->pool, "-sk+", r->path_info, NULL);
  ap_cleanup_for_exec();
  child_pid = ap_call_exec(r, pinfo, r->filename, env, 0);
#ifdef WIN32
  return(child_pid);
#else
  ap_log_error(APLOG_MARK, APLOG_ERR, NULL, "exec of %s failed", r->filename);
  exit(0);

  return(0);
#endif
}
Ejemplo n.º 28
0
/* handle the conversion of URLs in the ProxyPassReverse function */
static const char *proxy_location_reverse_map(request_rec *r, const char *url)
{
    void *sconf;
    proxy_server_conf *conf;
    struct proxy_alias *ent;
    int i, l1, l2;
    char *u;

    sconf = r->server->module_config;
    conf = (proxy_server_conf *)ap_get_module_config(sconf, &proxy_module);
    l1 = strlen(url);
    ent = (struct proxy_alias *)conf->raliases->elts;
    for (i = 0; i < conf->raliases->nelts; i++) {
        l2 = strlen(ent[i].real);
        if (l1 >= l2 && strncmp(ent[i].real, url, l2) == 0) {
            u = ap_pstrcat(r->pool, ent[i].fake, &url[l2], NULL);
            return ap_construct_url(r->pool, u, r);
        }
    }
    return url;
}
Ejemplo n.º 29
0
static const char *add_desc(cmd_parms *cmd, void *d, char *desc, char *to)
{
    autoindex_config_rec *dcfg = (autoindex_config_rec *) d;
    ai_desc_t *desc_entry;
    char *prefix = "";

    desc_entry = (ai_desc_t *) ap_push_array(dcfg->desc_list);
    desc_entry->full_path = (strchr(to, '/') == NULL) ? 0 : 1;
    desc_entry->wildcards = (WILDCARDS_REQUIRED
			     || desc_entry->full_path
			     || ap_is_fnmatch(to));
    if (desc_entry->wildcards) {
	prefix = desc_entry->full_path ? "*/" : "*";
	desc_entry->pattern = ap_pstrcat(dcfg->desc_list->pool,
					 prefix, to, "*", NULL);
    }
    else {
	desc_entry->pattern = ap_pstrdup(dcfg->desc_list->pool, to);
    }
    desc_entry->description = ap_pstrdup(dcfg->desc_list->pool, desc);
    return NULL;
}
Ejemplo n.º 30
0
/*
 * This function gets called to create a per-server configuration
 * record.  It will always be called for the "default" server.
 *
 * The return value is a pointer to the created module-specific
 * structure.
 */
static void *example_create_server_config(pool *p, server_rec *s)
{

    excfg *cfg;
    char *sname = s->server_hostname;

    /*
     * As with the example_create_dir_config() reoutine, we allocate and fill
     * in an empty record.
     */
    cfg = (excfg *) ap_pcalloc(p, sizeof(excfg));
    cfg->local = 0;
    cfg->congenital = 0;
    cfg->cmode = CONFIG_MODE_SERVER;
    /*
     * Note that we were called in the trace list.
     */
    sname = (sname != NULL) ? sname : "";
    cfg->loc = ap_pstrcat(p, "SVR(", sname, ")", NULL);
    trace_add(s, NULL, cfg, "example_create_server_config()");
    return (void *) cfg;
}