From d68a12188c2937b2945f592671fa1c21b551b732 Mon Sep 17 00:00:00 2001 From: Brian West Date: Thu, 2 Sep 2010 10:39:52 -0500 Subject: [PATCH] FSCORE-662 --- src/include/switch_loadable_module.h | 19 +++++++ src/include/switch_types.h | 2 + .../applications/mod_commands/mod_commands.c | 3 + src/switch_console.c | 42 ++++++++++++++ src/switch_loadable_module.c | 56 +++++++++++++++++++ 5 files changed, 122 insertions(+) diff --git a/src/include/switch_loadable_module.h b/src/include/switch_loadable_module.h index 158de6ce63..68719062b7 100644 --- a/src/include/switch_loadable_module.h +++ b/src/include/switch_loadable_module.h @@ -120,6 +120,25 @@ SWITCH_DECLARE(switch_codec_interface_t *) switch_loadable_module_get_codec_inte */ SWITCH_DECLARE(switch_dialplan_interface_t *) switch_loadable_module_get_dialplan_interface(const char *name); +/*! + \brief Enumerates a list of all modules discovered in a directory + \param the directory to look for modules in + \param memory pool + \param callback function to call for each module found + \param user data argument to pass to the callback function + \return the resulting status + */ +SWITCH_DECLARE(switch_status_t) switch_loadable_module_enumerate_available(const char *dir_path, switch_modulename_callback_func_t callback, void *user_data); + + +/*! + \brief Enumerates a list of all currently loaded modules + \param callback function to call for each module found + \param user data argument to pass to the callback function + \return the resulting status + */ +SWITCH_DECLARE(switch_status_t) switch_loadable_module_enumerate_loaded(switch_modulename_callback_func_t callback, void *user_data); + /*! \brief build a dynamic module object and register it (for use in double embeded modules) \param filename the name of the modules source file diff --git a/src/include/switch_types.h b/src/include/switch_types.h index dacf2dddda..5a88cd5751 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -1731,6 +1731,8 @@ typedef struct switch_loadable_module_function_table { switch_module_flag_t flags; } switch_loadable_module_function_table_t; +typedef int (*switch_modulename_callback_func_t) (void *user_data, const char *module_name); + #define SWITCH_MODULE_DEFINITION_EX(name, load, shutdown, runtime, flags) \ static const char modname[] = #name ; \ SWITCH_MOD_DECLARE_DATA switch_loadable_module_function_table_t name##_module_interface = { \ diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index cc864a266b..e1eb2a6b6a 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -4651,9 +4651,11 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) switch_console_set_complete("add fsctl flush_db_handles"); switch_console_set_complete("add fsctl min_idle_cpu"); switch_console_set_complete("add fsctl send_sighup"); + switch_console_set_complete("add load ::console::list_available_modules"); switch_console_set_complete("add nat_map reinit"); switch_console_set_complete("add nat_map republish"); switch_console_set_complete("add nat_map status"); + switch_console_set_complete("add reload ::console::list_loaded_modules"); switch_console_set_complete("add reloadacl reloadxml"); switch_console_set_complete("add show aliases"); switch_console_set_complete("add show api"); @@ -4678,6 +4680,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) switch_console_set_complete("add show timer"); switch_console_set_complete("add shutdown"); switch_console_set_complete("add sql_escape"); + switch_console_set_complete("add unload ::console::list_loaded_modules"); switch_console_set_complete("add uuid_audio ::console::list_uuid start read mute"); switch_console_set_complete("add uuid_audio ::console::list_uuid start read level"); switch_console_set_complete("add uuid_audio ::console::list_uuid start write mute"); diff --git a/src/switch_console.c b/src/switch_console.c index e82290bce7..30d1d97fed 100644 --- a/src/switch_console.c +++ b/src/switch_console.c @@ -553,6 +553,46 @@ struct match_helper { switch_console_callback_match_t *my_matches; }; +static int modulename_callback(void *pArg, const char *module_name) +{ + struct match_helper *h = (struct match_helper *) pArg; + + switch_console_push_match(&h->my_matches, module_name); + return 0; +} + +SWITCH_DECLARE_NONSTD(switch_status_t) switch_console_list_available_modules(const char *line, const char *cursor, switch_console_callback_match_t **matches) +{ + struct match_helper h = { 0 }; + + if (switch_loadable_module_enumerate_available(SWITCH_GLOBAL_dirs.mod_dir, modulename_callback, &h) != SWITCH_STATUS_SUCCESS) { + return SWITCH_STATUS_GENERR; + } + + if (h.my_matches) { + *matches = h.my_matches; + return SWITCH_STATUS_SUCCESS; + } + + return SWITCH_STATUS_FALSE; +} + +SWITCH_DECLARE_NONSTD(switch_status_t) switch_console_list_loaded_modules(const char *line, const char *cursor, switch_console_callback_match_t **matches) +{ + struct match_helper h = { 0 }; + + if (switch_loadable_module_enumerate_loaded(modulename_callback, &h) != SWITCH_STATUS_SUCCESS) { + return SWITCH_STATUS_GENERR; + } + + if (h.my_matches) { + *matches = h.my_matches; + return SWITCH_STATUS_SUCCESS; + } + + return SWITCH_STATUS_FALSE; +} + static int uuid_callback(void *pArg, int argc, char **argv, char **columnNames) { struct match_helper *h = (struct match_helper *) pArg; @@ -1542,6 +1582,8 @@ SWITCH_DECLARE(switch_status_t) switch_console_init(switch_memory_pool_t *pool) { switch_mutex_init(&globals.func_mutex, SWITCH_MUTEX_NESTED, pool); switch_core_hash_init(&globals.func_hash, pool); + switch_console_add_complete_func("::console::list_available_modules", (switch_console_complete_callback_t) switch_console_list_available_modules); + switch_console_add_complete_func("::console::list_loaded_modules", (switch_console_complete_callback_t) switch_console_list_loaded_modules); switch_console_add_complete_func("::console::list_uuid", (switch_console_complete_callback_t) switch_console_list_uuid); return SWITCH_STATUS_SUCCESS; } diff --git a/src/switch_loadable_module.c b/src/switch_loadable_module.c index 97cb5e8d70..76024b89cc 100644 --- a/src/switch_loadable_module.c +++ b/src/switch_loadable_module.c @@ -1068,6 +1068,62 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_unload_module(char *dir, } +SWITCH_DECLARE(switch_status_t) switch_loadable_module_enumerate_available(const char *dir_path, switch_modulename_callback_func_t callback, void *user_data) +{ + switch_dir_t *dir = NULL; + switch_status_t status; + char buffer[PATH_MAX]; + const char *fname; + const char *fname_ext; + char *fname_base; + +#ifdef WIN32 + const char *ext = ".dll"; +#else + const char *ext = ".so"; +#endif + + if ((status = switch_dir_open(&dir, dir_path, loadable_modules.pool)) != SWITCH_STATUS_SUCCESS) { + return status; + } + + while((fname = switch_dir_next_file(dir, buffer, sizeof(buffer)))) { + if ((fname_ext = strrchr(fname, '.'))) { + if (!strcmp(fname_ext, ext)) { + if (!(fname_base = switch_mprintf("%.*s", (int)(fname_ext-fname), fname))) { + status = SWITCH_STATUS_GENERR; + goto end; + } + callback(user_data, fname_base); + switch_safe_free(fname_base) + } + } + } + + + end: + switch_dir_close(dir); + return status; +} + +SWITCH_DECLARE(switch_status_t) switch_loadable_module_enumerate_loaded(switch_modulename_callback_func_t callback, void *user_data) +{ + switch_hash_index_t *hi; + void *val; + switch_loadable_module_t *module; + + switch_mutex_lock(loadable_modules.mutex); + for (hi = switch_hash_first(NULL, loadable_modules.module_hash); hi; hi = switch_hash_next(hi)) { + switch_hash_this(hi, NULL, NULL, &val); + module = (switch_loadable_module_t *) val; + + callback(user_data, module->module_interface->module_name); + } + switch_mutex_unlock(loadable_modules.mutex); + + return SWITCH_STATUS_SUCCESS; +} + SWITCH_DECLARE(switch_status_t) switch_loadable_module_build_dynamic(char *filename, switch_module_load_t switch_module_load, switch_module_runtime_t switch_module_runtime,