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; }
int isapi_handler (request_rec *r) { LPEXTENSION_CONTROL_BLOCK ecb = ap_pcalloc(r->pool, sizeof(struct _EXTENSION_CONTROL_BLOCK)); HSE_VERSION_INFO *pVer = ap_pcalloc(r->pool, sizeof(HSE_VERSION_INFO)); HINSTANCE isapi_handle; BOOL (*isapi_version)(HSE_VERSION_INFO *); /* entry point 1 */ DWORD (*isapi_entry)(LPEXTENSION_CONTROL_BLOCK); /* entry point 2 */ BOOL (*isapi_term)(DWORD); /* optional entry point 3 */ isapi_cid *cid = ap_pcalloc(r->pool, sizeof(isapi_cid)); table *e = r->subprocess_env; DWORD read; char *p; int retval; int res; /* Use similar restrictions as CGIs */ if (!(ap_allow_options(r) & OPT_EXECCGI)) return FORBIDDEN; if (r->finfo.st_mode == 0) return NOT_FOUND; if (S_ISDIR(r->finfo.st_mode)) return FORBIDDEN; if (!(isapi_handle = ap_os_dso_load(r->filename))) { ap_log_rerror(APLOG_MARK, APLOG_ALERT, r, "ISAPI Could not load DLL: %s", r->filename); return SERVER_ERROR; } if (!(isapi_version = (void *)(ap_os_dso_sym(isapi_handle, "GetExtensionVersion")))) { ap_log_rerror(APLOG_MARK, APLOG_ALERT, r, "DLL could not load GetExtensionVersion(): %s", r->filename); ap_os_dso_unload(isapi_handle); return SERVER_ERROR; } if (!(isapi_entry = (void *)(ap_os_dso_sym(isapi_handle, "HttpExtensionProc")))) { ap_log_rerror(APLOG_MARK, APLOG_ALERT, r, "DLL could not load HttpExtensionProc(): %s", r->filename); ap_os_dso_unload(isapi_handle); return SERVER_ERROR; } isapi_term = (void *)(ap_os_dso_sym(isapi_handle, "TerminateExtension")); /* Run GetExtensionVersion() */ if (!(*isapi_version)(pVer)) { ap_log_rerror(APLOG_MARK, APLOG_ALERT, r, "ISAPI GetExtensionVersion() failed: %s", r->filename); ap_os_dso_unload(isapi_handle); return SERVER_ERROR; } /* Set up variables. There are a couple of special cases for ISAPI. * XXX: These were taken verbatim from GetServerVariable, and should * be reviewed carefully. */ ap_add_common_vars(r); ap_add_cgi_vars(r); ap_table_setn(r->subprocess_env, "UNMAPPED_REMOTE_USER", "REMOTE_USER"); ap_table_setn(r->subprocess_env, "SERVER_PORT_SECURE", "0"); ap_table_setn(r->subprocess_env, "URL", r->uri); /* Set up connection ID */ ecb->ConnID = (HCONN)cid; cid->ecb = ecb; cid->r = r; cid->status = 0; ecb->cbSize = sizeof(struct _EXTENSION_CONTROL_BLOCK); ecb->dwVersion = MAKELONG(0, 2); ecb->dwHttpStatusCode = 0; strcpy(ecb->lpszLogData, ""); ecb->lpszMethod = ap_pstrdup(r->pool, r->method); ecb->lpszQueryString = ap_pstrdup(r->pool, ap_table_get(e, "QUERY_STRING")); ecb->lpszPathInfo = ap_pstrdup(r->pool, ap_table_get(e, "PATH_INFO")); ecb->lpszPathTranslated = ap_pstrdup(r->pool, ap_table_get(e, "PATH_TRANSLATED")); ecb->lpszContentType = ap_pstrdup(r->pool, ap_table_get(e, "CONTENT_TYPE")); /* Set up client input */ if ((retval = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR))) { if (isapi_term) (*isapi_term)( 2 /* HSE_TERM_MUST_UNLOAD */); ap_os_dso_unload(isapi_handle); return retval; } if (ap_should_client_block(r)) { /* Time to start reading the appropriate amount of data, * and allow the administrator to tweak the number * TODO: add the httpd.conf option for ReadAheadBuffer. */ if (r->remaining) { ecb->cbTotalBytes = r->remaining; if (ecb->cbTotalBytes > ReadAheadBuffer) ecb->cbAvailable = ReadAheadBuffer; else ecb->cbAvailable = ecb->cbTotalBytes; } else { ecb->cbTotalBytes = 0xffffffff; ecb->cbAvailable = ReadAheadBuffer; } ecb->lpbData = ap_pcalloc(r->pool, ecb->cbAvailable + 1); p = ecb->lpbData; read = 0; while (read < ecb->cbAvailable && ((res = ap_get_client_block(r, ecb->lpbData + read, ecb->cbAvailable - read)) > 0)) { read += res; } if (res < 0) { if (isapi_term) (*isapi_term)(HSE_TERM_MUST_UNLOAD); ap_os_dso_unload(isapi_handle); return SERVER_ERROR; } /* Although its not to spec, IIS seems to null-terminate * its lpdData string. So we will too. * * XXX: This must be an issue... backing out the null * from the count of bytes. */ if (res == 0) ecb->cbAvailable = ecb->cbTotalBytes = read; else ecb->cbAvailable = read; ecb->lpbData[read] = '\0'; } else { ecb->cbTotalBytes = 0; ecb->cbAvailable = 0; ecb->lpbData = NULL; } /* Set up the callbacks */ ecb->GetServerVariable = &GetServerVariable; ecb->WriteClient = &WriteClient; ecb->ReadClient = &ReadClient; ecb->ServerSupportFunction = &ServerSupportFunction; /* All right... try and load the sucker */ retval = (*isapi_entry)(ecb); /* Set the status (for logging) */ if (ecb->dwHttpStatusCode) r->status = ecb->dwHttpStatusCode; /* Check for a log message - and log it */ if (ecb->lpszLogData && strcmp(ecb->lpszLogData, "")) ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r, "ISAPI: %s: %s", ecb->lpszLogData, r->filename); /* Soak up any remaining input */ if (r->remaining > 0) { char argsbuffer[HUGE_STRING_LEN]; while (ap_get_client_block(r, argsbuffer, HUGE_STRING_LEN) > 0); } /* All done with the DLL... get rid of it */ if (isapi_term) (*isapi_term)(HSE_TERM_MUST_UNLOAD); ap_os_dso_unload(isapi_handle); switch(retval) { case 0: /* Strange, but MS isapi accepts this as success */ case HSE_STATUS_SUCCESS: case HSE_STATUS_SUCCESS_AND_KEEP_CONN: /* Ignore the keepalive stuff; Apache handles it just fine without * the ISA's "advice". */ if (cid->status) /* We have a special status to return */ return cid->status; return OK; case HSE_STATUS_PENDING: /* We don't support this */ if (LogNotSupported) ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, r, "ISAPI asynchronous I/O not supported: %s", r->filename); case HSE_STATUS_ERROR: default: return SERVER_ERROR; } }
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; }