static const char *load_file(cmd_parms *cmd, void *dummy, const char *filename) { apr_dso_handle_t *handle; const char *used_file, *error; error = dso_load(cmd, &handle, filename, &used_file); if (error) return error; ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, APLOGNO(01576) "loaded file %s", used_file); return NULL; }
void event_action_init(void) { logprintf(LOG_STACK, "%s(...)", __FUNCTION__); #include "action_init.h" void *handle = NULL; void (*init)(void); void (*compatibility)(struct module_t *module); char path[PATH_MAX]; struct module_t module; char pilight_version[strlen(PILIGHT_VERSION)+1]; char pilight_commit[3]; char *action_root = NULL; int check1 = 0, check2 = 0, valid = 1, action_root_free = 0; strcpy(pilight_version, PILIGHT_VERSION); struct dirent *file = NULL; DIR *d = NULL; struct stat s; memset(pilight_commit, '\0', 3); if(settings_find_string("action-root", &action_root) != 0) { /* If no action root was set, use the default action root */ if(!(action_root = MALLOC(strlen(ACTION_ROOT)+1))) { logprintf(LOG_ERR, "out of memory"); exit(EXIT_FAILURE); } strcpy(action_root, ACTION_ROOT); action_root_free = 1; } size_t len = strlen(action_root); if(action_root[len-1] != '/') { strcat(action_root, "/"); } if((d = opendir(action_root))) { while((file = readdir(d)) != NULL) { memset(path, '\0', PATH_MAX); sprintf(path, "%s%s", action_root, file->d_name); if(stat(path, &s) == 0) { /* Check if file */ if(S_ISREG(s.st_mode)) { if(strstr(file->d_name, ".so") != NULL) { valid = 1; if((handle = dso_load(path)) != NULL) { init = dso_function(handle, "init"); compatibility = dso_function(handle, "compatibility"); if(init && compatibility) { compatibility(&module); if(module.name != NULL && module.version != NULL && module.reqversion != NULL) { char ver[strlen(module.reqversion)+1]; strcpy(ver, module.reqversion); if((check1 = vercmp(ver, pilight_version)) > 0) { valid = 0; } if(check1 == 0 && module.reqcommit != NULL) { char com[strlen(module.reqcommit)+1]; strcpy(com, module.reqcommit); sscanf(HASH, "v%*[0-9].%*[0-9]-%[0-9]-%*[0-9a-zA-Z\n\r]", pilight_commit); if(strlen(pilight_commit) > 0 && (check2 = vercmp(com, pilight_commit)) > 0) { valid = 0; } } if(valid == 1) { char tmp[strlen(module.name)+1]; strcpy(tmp, module.name); event_action_remove(tmp); init(); logprintf(LOG_DEBUG, "loaded event action %s v%s", file->d_name, module.version); } else { if(module.reqcommit != NULL) { logprintf(LOG_ERR, "event action %s requires at least pilight v%s (commit %s)", file->d_name, module.reqversion, module.reqcommit); } else { logprintf(LOG_ERR, "event action %s requires at least pilight v%s", file->d_name, module.reqversion); } } } else { logprintf(LOG_ERR, "invalid module %s", file->d_name); } } } } } } } closedir(d); } if(action_root_free) { FREE(action_root); } }
static const char *load_module(cmd_parms *cmd, void *dummy, const char *modname, const char *filename) { apr_dso_handle_t *modhandle; apr_dso_handle_sym_t modsym; module *modp; const char *module_file; so_server_conf *sconf; ap_module_symbol_t *modi; ap_module_symbol_t *modie; int i; const char *error; /* we need to setup this value for dummy to make sure that we don't try * to add a non-existant tree into the build when we return to * execute_now. */ *(ap_directive_t **)dummy = NULL; /* * check for already existing module * If it already exists, we have nothing to do * Check both dynamically-loaded modules and statically-linked modules. */ sconf = (so_server_conf *)ap_get_module_config(cmd->server->module_config, &so_module); modie = (ap_module_symbol_t *)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_perror(APLOG_MARK, APLOG_WARNING, 0, cmd->pool, APLOGNO(01574) "module %s is already loaded, skipping", modname); return NULL; } } for (i = 0; ap_preloaded_modules[i]; i++) { const char *preload_name; apr_size_t preload_len; apr_size_t thismod_len; modp = ap_preloaded_modules[i]; /* make sure we're comparing apples with apples * make sure name of preloaded module is mod_FOO.c * make sure name of structure being loaded is FOO_module */ if (memcmp(modp->name, "mod_", 4)) { continue; } preload_name = modp->name + strlen("mod_"); preload_len = strlen(preload_name) - 2; if (strlen(modname) <= strlen("_module")) { continue; } thismod_len = strlen(modname) - strlen("_module"); if (strcmp(modname + thismod_len, "_module")) { continue; } if (thismod_len != preload_len) { continue; } if (!memcmp(modname, preload_name, preload_len)) { return apr_pstrcat(cmd->pool, "module ", modname, " is built-in and can't be loaded", NULL); } } modi = apr_array_push(sconf->loaded_modules); modi->name = modname; /* * Load the file into the Apache address space */ error = dso_load(cmd, &modhandle, filename, &module_file); if (error) return error; ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, cmd->pool, APLOGNO(01575) "loaded module %s from %s", modname, module_file); /* * 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 (apr_dso_sym(&modsym, modhandle, modname) != APR_SUCCESS) { char my_error[256]; return apr_pstrcat(cmd->pool, "Can't locate API module structure `", modname, "' in file ", module_file, ": ", apr_dso_error(modhandle, my_error, sizeof(my_error)), NULL); } modp = (module*) modsym; modp->dynamic_load_handle = (apr_dso_handle_t *)modhandle; modi->modp = modp; /* * Make sure the found module structure is really a module structure * */ if (modp->magic != MODULE_MAGIC_COOKIE) { return apr_psprintf(cmd->pool, "API module structure '%s' in file %s " "is garbled - expected signature %08lx but saw " "%08lx - perhaps this is not an Apache module DSO, " "or was compiled for a different Apache version?", modname, module_file, MODULE_MAGIC_COOKIE, modp->magic); } /* * Add this module to the Apache core structures */ error = ap_add_loaded_module(modp, cmd->pool, modname); if (error) { return error; } /* * Register a cleanup in the config apr_pool_t (normally pconf). When * we do a restart (or shutdown) this cleanup will cause the * shared object to be unloaded. */ apr_pool_cleanup_register(cmd->pool, modi, unload_module, apr_pool_cleanup_null); /* * Finally we need to run the configuration process for the module */ ap_single_module_configure(cmd->pool, cmd->server, modp); return NULL; }