/** * 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; }
/* ==================================================================== * 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; }
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; } }
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; }
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; }
/* ==================================================================== * 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; }
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; }
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; }
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; }
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; }
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"; }
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; }
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; }