/**
 * Handler for "AddClientEncoding" directive.
 *
 * This registers regex pattern of UserAgent: header and expected
 * encoding(s) from that useragent.
 */
static const char *
add_client_encoding(cmd_parms *cmd, encoding_config *conf, char *args) {
  array_header    *encs;
  char            *arg;

  LOG(APLOG_DEBUG, cmd->server, "add_client_encoding: entered");
  LOG(APLOG_DEBUG, cmd->server, "add_client_encoding: args == %s", args);

  if (! cmd->path) {
    conf = ap_get_module_config(cmd->server->module_config, &encoding_module);
  }

  encs = ap_make_array(cmd->pool, 1, sizeof(void *));

  /* register useragent with UserAgent: pattern */
  if (*args && (arg = ap_getword_conf_nc(cmd->pool, &args))) {
    LOG(APLOG_DEBUG, cmd->server, "add_client_encoding: agent: %s", arg);
    *(void **)ap_push_array(conf->client_encoding) =
      ap_pregcomp(cmd->pool, arg, REG_EXTENDED|REG_ICASE|REG_NOSUB);
  }

  /* register list of possible encodings from above useragent */
  while (*args && (arg = ap_getword_conf_nc(cmd->pool, &args))) {
    LOG(APLOG_DEBUG, cmd->server, "add_client_encoding: encname: %s", arg);
    *(void **)ap_push_array(encs) = ap_pstrdup(cmd->pool, arg);
  }
  *(void **)ap_push_array(conf->client_encoding) = encs;

  return NULL;
}
void *ssl_ds_table_push(ssl_ds_table *t, char *key)
{
    char *k;
    void *d;

    k = (char *)ap_push_array(t->aKey);
    d = (void *)ap_push_array(t->aData);
    ap_cpystrn(k, key, t->aKey->elt_size);
    return d;
}
示例#3
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 *wk_create_dir_config(pool *p, char *dirspec)
{
    wkcfg *cfg;
    char **header;

    /*
     * Allocate the space for our record from the pool supplied.
     */
    cfg = (wkcfg *)ap_pcalloc(p, sizeof(wkcfg));
    /*
     * Now fill in the defaults.  If there are any `parent' configuration
     * records, they'll get merged as part of a separate callback.
     */
    cfg->port = 8086;
    cfg->host = "localhost";
    cfg->addr = resolve_host(cfg->host);
    cfg->retryattempts = 10;
    cfg->retrydelay = 1;
    cfg->passheaders = ap_make_array(p, 1, sizeof(char *));
    /*
     * Pass the "If-Modified-Since" HTTP header through.
     * Servlets may inspect this value and, if the object has not changed,
     * return "Status: 304" and no body.
     */
    header = (char **)ap_push_array(cfg->passheaders);
    *header = "If-Modified-Since";
    return (void *)cfg;
}
示例#4
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;
    }
}
示例#5
0
static array_header *parse_log_string(pool *p, const char *s, const char **err)
{
    array_header *a = ap_make_array(p, 30, sizeof(log_format_item));
    char *res;

    while (*s) {
        if ((res = parse_log_item(p, (log_format_item *) ap_push_array(a), &s))) {
            *err = res;
            return NULL;
        }
    }

    s = "\n";
    parse_log_item(p, (log_format_item *) ap_push_array(a), &s);
    return a;
}
/**
 * Return the list of encoding(s) (defaults to (list "UTF-8"))
 * which named client is expected to send.
 *
 * @param r      Apache request object structure
 * @param encmap Table of UA-to-encoding(s)
 * @param lookup Name of the useragent to look for
 */
static array_header *
get_client_encoding(request_rec *r,
		    array_header *encmap, const char *lookup) {
  void         **list = (void **)encmap->elts;
  array_header  *encs = ap_make_array(r->pool, 1, sizeof(char *));

  int i;

  LOG(APLOG_DEBUG, r->server, "get_client_encoding: entered");

  /* push UTF-8 as the first candidate of expected encoding */
  *((char **)ap_push_array(encs)) = ap_pstrdup(r->pool, "UTF-8");

  if (! lookup)
    return encs;

  LOG(APLOG_DEBUG, r->server, "get_client_encoding: lookup == %s", lookup);

  for (i = 0 ; i < encmap->nelts ; i += 2) {
    if (ap_regexec((regex_t *)list[i], lookup, 0, NULL, 0) == 0) {
      LOG(APLOG_DEBUG, r->server, "get_client_encoding: entry found");
      ap_array_cat(encs, (array_header *)list[i + 1]);
      return encs;
    }
  }

  LOG(APLOG_DEBUG, r->server, "get_client_encoding: entry not found");
  return encs;
}
示例#7
0
static const char *add_custom_log(cmd_parms *cmd, void *dummy, char *fn,
                                  char *fmt, char *envclause)
{
    const char *err_string = NULL;
    multi_log_state *mls = ap_get_module_config(cmd->server->module_config,
						&config_log_module);
    config_log_state *cls;

    cls = (config_log_state *) ap_push_array(mls->config_logs);
    cls->condition_var = NULL;
    if (envclause != NULL) {
	if (strncasecmp(envclause, "env=", 4) != 0) {
	    return "error in condition clause";
	}
	if ((envclause[4] == '\0')
	    || ((envclause[4] == '!') && (envclause[5] == '\0'))) {
	    return "missing environment variable name";
	}
	cls->condition_var = ap_pstrdup(cmd->pool, &envclause[4]);
    }

    cls->fname = fn;
    cls->format_string = fmt;
    if (fmt == NULL) {
        cls->format = NULL;
    }
    else {
        cls->format = parse_log_string(cmd->pool, fmt, &err_string);
    }
    cls->log_fd = -1;

    return err_string;
}
void *ssl_ds_array_push(ssl_ds_array *a)
{
    void *d;

    d = (void *)ap_push_array(a->aData);
    return d;
}
示例#9
0
/* ====================================================================
 * Command handler for the PassHeader command.
 * Takes 1 argument,
 * the HTTP header to pass through to the AppServer.
 * ==================================================================== */
static const char *handle_passheader(cmd_parms *cmd, void *mconfig, char *word1)
{
    wkcfg* cfg;

    cfg = (wkcfg *)mconfig;

    if (word1 != NULL) {
        char **header = (char **)ap_push_array(cfg->passheaders);
        *header = word1;
    }
    return NULL;
}
示例#10
0
static const char *get_pass_header(pool *p, const char **arg, array_header **array)
{
    const char **header;

    if (!*array) {
        *array = ap_make_array(p, 10, sizeof(char*));
    }

    header = (const char **)ap_push_array(*array);
    *header = ap_getword_conf(p, arg);

    return header ? NULL : "\"\"";
}
/**
 * Handler for "DefaultClientEncoding" directive.
 *
 * This registers encodings that work as "fallback" for most clients.
 */
static const char *
default_client_encoding(cmd_parms *cmd, encoding_config *conf, char *args) {
  char *arg;

  LOG(APLOG_DEBUG, cmd->server, "default_client_encoding: entered");
  LOG(APLOG_DEBUG, cmd->server, "default_client_encoding: args == %s", args);

  if (! cmd->path) {
    conf = ap_get_module_config(cmd->server->module_config, &encoding_module);
  }

  conf->default_encoding = ap_make_array(cmd->pool, 1, sizeof(char *));

  /* register list of possible encodings as a default */
  while (*args && (arg = ap_getword_conf_nc(cmd->pool, &args))) {
    LOG(APLOG_DEBUG, cmd->server, "default_client_encoding: encname: %s", arg);
    *(void **)ap_push_array(conf->default_encoding)
      = ap_pstrdup(cmd->pool, arg);
  }

  return NULL;
}
示例#12
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;
}
示例#13
0
static int make_params(void *data, const char *key, const char *val)
{
    array_header *arr = (array_header *)data;
    *(char **)ap_push_array(arr) = (char *)val;
    return 1;
}
示例#14
0
static int check_speling(request_rec *r)
{
    spconfig *cfg;
    char *good, *bad, *postgood, *url;
    int filoc, dotloc, urlen, pglen;
    DIR *dirp;
    struct DIR_TYPE *dir_entry;
    array_header *candidates = NULL;

    cfg = ap_get_module_config(r->per_dir_config, &speling_module);
    if (!cfg->enabled) {
        return DECLINED;
    }

    /* We only want to worry about GETs */
    if (r->method_number != M_GET) {
        return DECLINED;
    }

    /* We've already got a file of some kind or another */
    if (r->proxyreq != NOT_PROXY || (r->finfo.st_mode != 0)) {
        return DECLINED;
    }

    /* This is a sub request - don't mess with it */
    if (r->main) {
        return DECLINED;
    }

    /*
     * The request should end up looking like this:
     * r->uri: /correct-url/mispelling/more
     * r->filename: /correct-file/mispelling r->path_info: /more
     *
     * So we do this in steps. First break r->filename into two pieces
     */

    filoc = ap_rind(r->filename, '/');
    /*
     * Don't do anything if the request doesn't contain a slash, or
     * requests "/" 
     */
    if (filoc == -1 || strcmp(r->uri, "/") == 0) {
        return DECLINED;
    }

    /* good = /correct-file */
    good = ap_pstrndup(r->pool, r->filename, filoc);
    /* bad = mispelling */
    bad = ap_pstrdup(r->pool, r->filename + filoc + 1);
    /* postgood = mispelling/more */
    postgood = ap_pstrcat(r->pool, bad, r->path_info, NULL);

    urlen = strlen(r->uri);
    pglen = strlen(postgood);

    /* Check to see if the URL pieces add up */
    if (strcmp(postgood, r->uri + (urlen - pglen))) {
        return DECLINED;
    }

    /* url = /correct-url */
    url = ap_pstrndup(r->pool, r->uri, (urlen - pglen));

    /* Now open the directory and do ourselves a check... */
    dirp = ap_popendir(r->pool, good);
    if (dirp == NULL) {          /* Oops, not a directory... */
        return DECLINED;
    }

    candidates = ap_make_array(r->pool, 2, sizeof(misspelled_file));

    dotloc = ap_ind(bad, '.');
    if (dotloc == -1) {
        dotloc = strlen(bad);
    }

    while ((dir_entry = readdir(dirp)) != NULL) {
        sp_reason q;

        /*
         * If we end up with a "fixed" URL which is identical to the
         * requested one, we must have found a broken symlink or some such.
         * Do _not_ try to redirect this, it causes a loop!
         */
        if (strcmp(bad, dir_entry->d_name) == 0) {
            ap_pclosedir(r->pool, dirp);
            return OK;
        }
        /*
         * miscapitalization errors are checked first (like, e.g., lower case
         * file, upper case request)
         */
        else if (strcasecmp(bad, dir_entry->d_name) == 0) {
            misspelled_file *sp_new;

	    sp_new = (misspelled_file *) ap_push_array(candidates);
            sp_new->name = ap_pstrdup(r->pool, dir_entry->d_name);
            sp_new->quality = SP_MISCAPITALIZED;
        }
        /*
         * simple typing errors are checked next (like, e.g.,
         * missing/extra/transposed char)
         */
        else if ((q = spdist(bad, dir_entry->d_name)) != SP_VERYDIFFERENT) {
            misspelled_file *sp_new;

	    sp_new = (misspelled_file *) ap_push_array(candidates);
            sp_new->name = ap_pstrdup(r->pool, dir_entry->d_name);
            sp_new->quality = q;
        }
        /*
	 * The spdist() should have found the majority of the misspelled
	 * requests.  It is of questionable use to continue looking for
	 * files with the same base name, but potentially of totally wrong
	 * type (index.html <-> index.db).
	 * I would propose to not set the WANT_BASENAME_MATCH define.
         *      08-Aug-1997 <*****@*****.**>
         *
         * However, Alexei replied giving some reasons to add it anyway:
         * > Oh, by the way, I remembered why having the
         * > extension-stripping-and-matching stuff is a good idea:
         * >
         * > If you're using MultiViews, and have a file named foobar.html,
	 * > which you refer to as "foobar", and someone tried to access
	 * > "Foobar", mod_speling won't find it, because it won't find
	 * > anything matching that spelling. With the extension-munging,
	 * > it would locate "foobar.html". Not perfect, but I ran into
	 * > that problem when I first wrote the module.
	 */
        else {
#ifdef WANT_BASENAME_MATCH
            /*
             * Okay... we didn't find anything. Now we take out the hard-core
             * power tools. There are several cases here. Someone might have
             * entered a wrong extension (.htm instead of .html or vice
             * versa) or the document could be negotiated. At any rate, now
             * we just compare stuff before the first dot. If it matches, we
             * figure we got us a match. This can result in wrong things if
             * there are files of different content types but the same prefix
             * (e.g. foo.gif and foo.html) This code will pick the first one
             * it finds. Better than a Not Found, though.
             */
            int entloc = ap_ind(dir_entry->d_name, '.');
            if (entloc == -1) {
                entloc = strlen(dir_entry->d_name);
	    }

            if ((dotloc == entloc)
                && !strncasecmp(bad, dir_entry->d_name, dotloc)) {
                misspelled_file *sp_new;

		sp_new = (misspelled_file *) ap_push_array(candidates);
                sp_new->name = ap_pstrdup(r->pool, dir_entry->d_name);
                sp_new->quality = SP_VERYDIFFERENT;
            }
#endif
        }
    }
    ap_pclosedir(r->pool, dirp);

    if (candidates->nelts != 0) {
        /* Wow... we found us a mispelling. Construct a fixed url */
        char *nuri;
	const char *ref;
        misspelled_file *variant = (misspelled_file *) candidates->elts;
        int i;

        ref = ap_table_get(r->headers_in, "Referer");

        qsort((void *) candidates->elts, candidates->nelts,
              sizeof(misspelled_file), sort_by_quality);

        /*
         * Conditions for immediate redirection: 
         *     a) the first candidate was not found by stripping the suffix 
         * AND b) there exists only one candidate OR the best match is not
	 *        ambiguous
         * then return a redirection right away.
         */
        if (variant[0].quality != SP_VERYDIFFERENT
	    && (candidates->nelts == 1
		|| variant[0].quality != variant[1].quality)) {

            nuri = ap_escape_uri(r->pool, ap_pstrcat(r->pool, url,
						     variant[0].name,
						     r->path_info, NULL));
	    if (r->parsed_uri.query)
		nuri = ap_pstrcat(r->pool, nuri, "?", r->parsed_uri.query, NULL);

            ap_table_setn(r->headers_out, "Location",
			  ap_construct_url(r->pool, nuri, r));

            ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_INFO, r,
			 ref ? "Fixed spelling: %s to %s from %s"
			     : "Fixed spelling: %s to %s",
			 r->uri, nuri, ref);

            return HTTP_MOVED_PERMANENTLY;
        }
        /*
         * Otherwise, a "[300] Multiple Choices" list with the variants is
         * returned.
         */
        else {
            pool *p;
            table *notes;
	    pool *sub_pool;
	    array_header *t;
	    array_header *v;


            if (r->main == NULL) {
                p = r->pool;
                notes = r->notes;
            }
            else {
                p = r->main->pool;
                notes = r->main->notes;
            }

	    sub_pool = ap_make_sub_pool(p);
	    t = ap_make_array(sub_pool, candidates->nelts * 8 + 8,
			      sizeof(char *));
	    v = ap_make_array(sub_pool, candidates->nelts * 5,
			      sizeof(char *));

            /* Generate the response text. */

	    *(const char **)ap_push_array(t) =
			  "The document name you requested (<code>";
	    *(const char **)ap_push_array(t) = ap_escape_html(sub_pool, r->uri);
	    *(const char **)ap_push_array(t) =
			   "</code>) could not be found on this server.\n"
			   "However, we found documents with names similar "
			   "to the one you requested.<p>"
			   "Available documents:\n<ul>\n";

            for (i = 0; i < candidates->nelts; ++i) {
		char *vuri;
		const char *reason;

		reason = sp_reason_str[(int) (variant[i].quality)];
                /* The format isn't very neat... */
		vuri = ap_pstrcat(sub_pool, url, variant[i].name, r->path_info,
				  (r->parsed_uri.query != NULL) ? "?" : "",
				  (r->parsed_uri.query != NULL)
				      ? r->parsed_uri.query : "",
				  NULL);
		*(const char **)ap_push_array(v) = "\"";
		*(const char **)ap_push_array(v) = ap_escape_uri(sub_pool, vuri);
		*(const char **)ap_push_array(v) = "\";\"";
		*(const char **)ap_push_array(v) = reason;
		*(const char **)ap_push_array(v) = "\"";

		*(const char **)ap_push_array(t) = "<li><a href=\"";
		*(const char **)ap_push_array(t) = ap_escape_uri(sub_pool, vuri);
		*(const char **)ap_push_array(t) = "\">";
		*(const char **)ap_push_array(t) = ap_escape_html(sub_pool, vuri);
		*(const char **)ap_push_array(t) = "</a> (";
		*(const char **)ap_push_array(t) = reason;
		*(const char **)ap_push_array(t) = ")\n";

                /*
                 * when we have printed the "close matches" and there are
                 * more "distant matches" (matched by stripping the suffix),
                 * then we insert an additional separator text to suggest
                 * that the user LOOK CLOSELY whether these are really the
                 * files she wanted.
                 */
                if (i > 0 && i < candidates->nelts - 1
                    && variant[i].quality != SP_VERYDIFFERENT
                    && variant[i + 1].quality == SP_VERYDIFFERENT) {
		    *(const char **)ap_push_array(t) = 
				   "</ul>\nFurthermore, the following related "
				   "documents were found:\n<ul>\n";
                }
            }
	    *(const char **)ap_push_array(t) = "</ul>\n";

            /* If we know there was a referring page, add a note: */
            if (ref != NULL) {
                *(const char **)ap_push_array(t) =
			       "Please consider informing the owner of the "
			       "<a href=\"";
		*(const char **)ap_push_array(t) = ap_escape_uri(sub_pool, ref);
                *(const char **)ap_push_array(t) = "\">referring page</a> "
			       "about the broken link.\n";
	    }


            /* Pass our table to http_protocol.c (see mod_negotiation): */
            ap_table_setn(notes, "variant-list", ap_array_pstrcat(p, t, 0));

	    ap_table_mergen(r->subprocess_env, "VARIANTS",
			    ap_array_pstrcat(p, v, ','));
	  
	    ap_destroy_pool(sub_pool);

            ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_INFO, r,
			 ref ? "Spelling fix: %s: %d candidates from %s"
			     : "Spelling fix: %s: %d candidates",
			 r->uri, candidates->nelts, ref);

            return HTTP_MULTIPLE_CHOICES;
        }
    }

    return OK;
}
示例#15
0
static char *parse_log_item(pool *p, log_format_item *it, const char **sa)
{
    const char *s = *sa;

    if (*s != '%') {
        return parse_log_misc_string(p, it, sa);
    }

    ++s;
    it->condition_sense = 0;
    it->conditions = NULL;
    it->want_orig = -1;
    it->arg = "";               /* For safety's sake... */

    while (*s) {
        int i;
        struct log_item_list *l;

        switch (*s) {
        case '!':
            ++s;
            it->condition_sense = !it->condition_sense;
            break;

        case '<':
            ++s;
            it->want_orig = 1;
            break;

        case '>':
            ++s;
            it->want_orig = 0;
            break;

        case ',':
            ++s;
            break;

        case '{':
            ++s;
            it->arg = ap_getword(p, &s, '}');
            break;

        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            i = *s - '0';
            while (ap_isdigit(*++s)) {
                i = i * 10 + (*s) - '0';
            }
            if (!it->conditions) {
                it->conditions = ap_make_array(p, 4, sizeof(int));
            }
            *(int *) ap_push_array(it->conditions) = i;
            break;

        default:
            l = find_log_func(*s++);
            if (!l) {
                char dummy[2];

                dummy[0] = s[-1];
                dummy[1] = '\0';
                return ap_pstrcat(p, "Unrecognized LogFormat directive %",
                               dummy, NULL);
            }
            it->func = l->func;
            if (it->want_orig == -1) {
                it->want_orig = l->want_orig_default;
            }
            *sa = s;
            return NULL;
        }
    }

    return "Ran off end of LogFormat parsing args to some directive";
}
示例#16
0
static const char *allow_cmd(cmd_parms *cmd, void *dv, char *from, char *where)
{
    access_dir_conf *d = (access_dir_conf *) dv;
    allowdeny *a;
    char *s;

    if (strcasecmp(from, "from"))
	return "allow and deny must be followed by 'from'";

    a = (allowdeny *) ap_push_array(cmd->info ? d->allows : d->denys);
    a->x.from = where;
    a->limited = cmd->limited;

    if (!strncasecmp(where, "env=", 4)) {
	a->type = T_ENV;
	a->x.from += 4;

    }
    else if (!strcasecmp(where, "all")) {
	a->type = T_ALL;

    }
    else if ((s = strchr(where, '/'))) {
	struct in_addr mask;

	a->type = T_IP;
	/* trample on where, we won't be using it any more */
	*s++ = '\0';

	if (!is_ip(where)
	    || (a->x.ip.net.s_addr = ap_inet_addr(where)) == INADDR_NONE) {
	    a->type = T_FAIL;
	    return "syntax error in network portion of network/netmask";
	}

	/* is_ip just tests if it matches [\d.]+ */
	if (!is_ip(s)) {
	    a->type = T_FAIL;
	    return "syntax error in mask portion of network/netmask";
	}
	/* is it in /a.b.c.d form? */
	if (strchr(s, '.')) {
	    mask.s_addr = ap_inet_addr(s);
	    if (mask.s_addr == INADDR_NONE) {
		a->type = T_FAIL;
		return "syntax error in mask portion of network/netmask";
	    }
	}
	else {
	    int i;

	    /* assume it's in /nnn form */
	    i = atoi(s);
	    if (i > 32 || i <= 0) {
		a->type = T_FAIL;
		return "invalid mask in network/netmask";
	    }
	    mask.s_addr = 0xFFFFFFFFUL << (32 - i);
	    mask.s_addr = htonl(mask.s_addr);
	}
	a->x.ip.mask = mask;
        a->x.ip.net.s_addr  = (a->x.ip.net.s_addr & mask.s_addr);   /* pjr - This fixes PR 4770 */
    }
    else if (ap_isdigit(*where) && is_ip(where)) {
	/* legacy syntax for ip addrs: a.b.c. ==> a.b.c.0/24 for example */
	int shift;
	char *t;
	int octet;

	a->type = T_IP;
	/* parse components */
	s = where;
	a->x.ip.net.s_addr = 0;
	a->x.ip.mask.s_addr = 0;
	shift = 24;
	while (*s) {
	    t = s;
	    if (!ap_isdigit(*t)) {
		a->type = T_FAIL;
		return "invalid ip address";
	    }
	    while (ap_isdigit(*t)) {
		++t;
	    }
	    if (*t == '.') {
		*t++ = 0;
	    }
	    else if (*t) {
		a->type = T_FAIL;
		return "invalid ip address";
	    }
	    if (shift < 0) {
		a->type = T_FAIL;
		return "invalid ip address, only 4 octets allowed";
	    }
	    octet = atoi(s);
	    if (octet < 0 || octet > 255) {
		a->type = T_FAIL;
		return "each octet must be between 0 and 255 inclusive";
	    }
	    a->x.ip.net.s_addr |= (unsigned int)octet << shift;
	    a->x.ip.mask.s_addr |= 0xFFUL << shift;
	    s = t;
	    shift -= 8;
	}
	a->x.ip.net.s_addr = ntohl(a->x.ip.net.s_addr);
	a->x.ip.mask.s_addr = ntohl(a->x.ip.mask.s_addr);
    }
    else {
	a->type = T_HOST;
    }

    return NULL;
}
示例#17
0
static const char *load_module(cmd_parms *cmd, void *dummy, 
                               char *modname, char *filename)
{
    ap_os_dso_handle_t modhandle;
    module *modp;
    const char *szModuleFile=ap_server_root_relative(cmd->pool, filename);
    so_server_conf *sconf;
    moduleinfo *modi;
    moduleinfo *modie;
    int i;

    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
    if (err != NULL) {
        return err;
    }
    
    /* 
     * check for already existing module
     * If it already exists, we have nothing to do 
     */
    sconf = (so_server_conf *)ap_get_module_config(cmd->server->module_config, 
	                                        &so_module);
    modie = (moduleinfo *)sconf->loaded_modules->elts;
    for (i = 0; i < sconf->loaded_modules->nelts; i++) {
        modi = &modie[i];
        if (modi->name != NULL && strcmp(modi->name, modname) == 0) {
            ap_log_error(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, cmd->server,
                          "module %s is already loaded, skipping", modname);
            return NULL;
        }
    }
    modi = ap_push_array(sconf->loaded_modules);
    modi->name = modname;

    /*
     * Load the file into the Apache address space
     */
    ap_server_strip_chroot(szModuleFile, 0);
    if (!(modhandle = ap_os_dso_load(szModuleFile))) {
	const char *my_error = ap_os_dso_error();
	return ap_pstrcat (cmd->pool, "Cannot load ", szModuleFile,
			" into server: ", 
			my_error ? my_error : "(reason unknown)",
			NULL);
    }
    ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, NULL,
		"loaded module %s", modname);

    /*
     * Retrieve the pointer to the module structure through the module name:
     * First with the hidden variant (prefix `AP_') and then with the plain
     * symbol name.
     */
    if (!(modp = (module *)(ap_os_dso_sym(modhandle, modname)))) {
	return ap_pstrcat(cmd->pool, "Can't locate API module structure `", modname,
		       "' in file ", szModuleFile, ": ", ap_os_dso_error(), NULL);
    }
    modi->modp = modp;
    modp->dynamic_load_handle = (void *)modhandle;

    /* 
     * Make sure the found module structure is really a module structure
     * 
     */
    if (   modp->magic != MODULE_MAGIC_COOKIE_AP13 
        && modp->magic != MODULE_MAGIC_COOKIE_EAPI) {
        return ap_pstrcat(cmd->pool, "API module structure `", modname,
                          "' in file ", szModuleFile, " is garbled -"
                          " perhaps this is not an Apache module DSO?", NULL);
    }
    if (modp->magic == MODULE_MAGIC_COOKIE_AP13) {
        ap_log_error(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, NULL,
                     "Loaded DSO %s uses plain Apache 1.3 API, "
                     "this module might crash under EAPI! "
                     "(please recompile it with -DEAPI)", filename);
    }

    /* 
     * Add this module to the Apache core structures
     */
    ap_add_loaded_module(modp);

    /* 
     * Register a cleanup in the config pool (normally pconf). When
     * we do a restart (or shutdown) this cleanup will cause the
     * shared object to be unloaded.
     */
    ap_register_cleanup(cmd->pool, modi, 
		     (void (*)(void*))unload_module, ap_null_cleanup);

    /* 
     * Finally we need to run the configuration process for the module
     */
    ap_single_module_configure(cmd->pool, cmd->server, modp);

    return NULL;
}