static switch_status_t switch_loadable_module_load_file(char *filename, switch_loadable_module_t **new_module) { switch_loadable_module_t *module = NULL; apr_dso_handle_t *dso = NULL; apr_status_t status = SWITCH_STATUS_SUCCESS; apr_dso_handle_sym_t function_handle = NULL; switch_module_load_t load_func_ptr = NULL; int loading = 1; const char *err = NULL; switch_loadable_module_interface_t *module_interface = NULL; char derr[512] = ""; assert(filename != NULL); *new_module = NULL; status = apr_dso_load(&dso, filename, loadable_modules.pool); while (loading) { if (status != APR_SUCCESS) { apr_dso_error(dso, derr, sizeof(derr)); err = derr; break; } status = apr_dso_sym(&function_handle, dso, "switch_module_load"); load_func_ptr = (switch_module_load_t) function_handle; if (load_func_ptr == NULL) { err = "Cannot Load"; break; } if (load_func_ptr(&module_interface, filename) != SWITCH_STATUS_SUCCESS) { err = "Module load routine returned an error"; module_interface = NULL; break; } if ((module = switch_core_permenant_alloc(sizeof(switch_loadable_module_t))) == 0) { err = "Could not allocate memory\n"; break; } loading = 0; } if (err) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Error Loading module %s\n**%s**\n", filename, err); return SWITCH_STATUS_GENERR; } module->filename = switch_core_permenant_strdup(filename); module->module_interface = module_interface; module->switch_module_load = load_func_ptr; if ((status = apr_dso_sym(&function_handle, dso, "switch_module_shutdown")) == APR_SUCCESS) { module->switch_module_shutdown = (switch_module_shutdown_t) function_handle; } if ((status = apr_dso_sym(&function_handle, dso, "switch_module_runtime")) == APR_SUCCESS) { module->switch_module_runtime = (switch_module_runtime_t) function_handle; } module->lib = dso; if (module->switch_module_runtime) { switch_core_launch_thread(switch_loadable_module_exec, module, loadable_modules.pool); } *new_module = module; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Successfully Loaded [%s]\n", module_interface->module_name); return SWITCH_STATUS_SUCCESS; }