diff --git a/cli.c b/cli.c index 983c25deab42f383e951587b0d4f345d3cd74e03..c6be4fefed87e00c0ae7a1ac3986b993e21d8210 100755 --- a/cli.c +++ b/cli.c @@ -117,11 +117,21 @@ static int handle_load(int fd, int argc, char *argv[]) static int handle_reload(int fd, int argc, char *argv[]) { int x; + int res; if (argc < 1) return RESULT_SHOWUSAGE; if (argc > 1) { - for (x=1;x<argc;x++) - ast_module_reload(argv[x]); + for (x=1;x<argc;x++) { + res = ast_module_reload(argv[x]); + switch(res) { + case 0: + ast_cli(fd, "No such module '%s'\n", argv[x]); + break; + case 1: + ast_cli(fd, "Module '%s' does not support reload\n", argv[x]); + break; + } + } } else ast_module_reload(NULL); return RESULT_SUCCESS; @@ -684,6 +694,16 @@ static char *complete_ch_4(char *line, char *word, int pos, int state) return complete_ch_helper(line, word, pos, state, 3); } +static char *complete_mod_2(char *line, char *word, int pos, int state) +{ + return ast_module_helper(line, word, pos, state, 1, 1); +} + +static char *complete_mod_4(char *line, char *word, int pos, int state) +{ + return ast_module_helper(line, word, pos, state, 3, 0); +} + static char *complete_fn(char *line, char *word, int pos, int state) { char *c; @@ -711,12 +731,13 @@ static struct ast_cli_entry builtins[] = { { { "help", NULL }, handle_help, "Display help list, or specific help on a command", help_help }, { { "load", NULL }, handle_load, "Load a dynamic module by name", load_help, complete_fn }, { { "no", "debug", "channel", NULL }, handle_nodebugchan, "Disable debugging on a channel", nodebugchan_help, complete_ch_4 }, - { { "reload", NULL }, handle_reload, "Reload configuration", reload_help }, + { { "reload", NULL }, handle_reload, "Reload configuration", reload_help, complete_mod_2 }, { { "set", "debug", NULL }, handle_set_debug, "Set level of debug chattiness", set_debug_help }, { { "set", "verbose", NULL }, handle_set_verbose, "Set level of verboseness", set_verbose_help }, { { "show", "channels", NULL }, handle_chanlist, "Display information on channels", chanlist_help }, { { "show", "channel", NULL }, handle_showchan, "Display information on a specific channel", showchan_help, complete_ch_3 }, { { "show", "modules", NULL }, handle_modlist, "List modules and info", modlist_help }, + { { "show", "modules", "like", NULL }, handle_modlist, "List modules and info", modlist_help, complete_mod_4 }, { { "show", "uptime", NULL }, handle_showuptime, "Show uptime information", modlist_help }, { { "show", "version", NULL }, handle_version, "Display version info", version_help }, { { "soft", "hangup", NULL }, handle_softhangup, "Request a hangup on a given channel", softhangup_help, complete_ch_3 }, diff --git a/include/asterisk/module.h b/include/asterisk/module.h index d8e5e1285c790cdbf1f7c6cd38fa441b08543d0d..683cd970e2d6f3be0d8ec5a9d0fbcf5433b306cf 100755 --- a/include/asterisk/module.h +++ b/include/asterisk/module.h @@ -138,7 +138,9 @@ int ast_loader_unregister(int (*updater)(void)); * This reloads all modules set to load in asterisk. It does NOT run the unload * routine and then loads them again, it runs the given reload routine. */ -void ast_module_reload(const char *name); +int ast_module_reload(const char *name); + +char *ast_module_helper(char *line, char *word, int pos, int state, int rpos, int needsreload); int ast_register_atexit(void (*func)(void)); void ast_unregister_atexit(void (*func)(void)); diff --git a/loader.c b/loader.c index b042301bf00dbd2fc5fc0e8842ae278c2397b43d..0f3876a2e1cf9ec4b7bbc0ae912b0282800ac8a4 100755 --- a/loader.c +++ b/loader.c @@ -147,31 +147,81 @@ int ast_unload_resource(char *resource_name, int force) return res; } -void ast_module_reload(const char *name) +char *ast_module_helper(char *line, char *word, int pos, int state, int rpos, int needsreload) { struct module *m; + int which=0; + char *ret; + if (pos != rpos) + return NULL; + ast_mutex_lock(&modlock); + m = module_list; + while(m) { + if (!strncasecmp(word, m->resource, strlen(word)) && (m->reload || !needsreload)) { + if (++which > state) + break; + } + m = m->next; + } + if (m) { + ret = strdup(m->resource); + } else { + ret = NULL; + if (!strncasecmp(word, "astconfig", strlen(word))) { + if (++which > state) + ret = strdup("astconfig"); + } else if (!strncasecmp(word, "manager", strlen(word))) { + if (++which > state) + ret = strdup("manager"); + } else if (!strncasecmp(word, "enum", strlen(word))) { + if (++which > state) + ret = strdup("enum"); + } else if (!strncasecmp(word, "rtp", strlen(word))) { + if (++which > state) + ret = strdup("rtp"); + } + + } + ast_mutex_unlock(&modlock); + return ret; +} +int ast_module_reload(const char *name) +{ + struct module *m; + int reloaded = 0; /* We'll do the logger and manager the favor of calling its reload here first */ if (ast_mutex_trylock(&reloadlock)) { ast_verbose("The previous reload command didn't finish yet\n"); - return; + return -1; } - if (!name || !strcasecmp(name, "astconfig")) + if (!name || !strcasecmp(name, "astconfig")) { read_ast_cust_config(); - if (!name || !strcasecmp(name, "manager")) + reloaded = 2; + } + if (!name || !strcasecmp(name, "manager")) { reload_manager(); - if (!name || !strcasecmp(name, "enum")) + reloaded = 2; + } + if (!name || !strcasecmp(name, "enum")) { ast_enum_reload(); - if (!name || !strcasecmp(name, "rtp")) + reloaded = 2; + } + if (!name || !strcasecmp(name, "rtp")) { ast_rtp_reload(); + reloaded = 2; + } time(&ast_lastreloadtime); ast_mutex_lock(&modlock); m = module_list; while(m) { if (!name || !strcasecmp(name, m->resource)) { + if (reloaded < 1) + reloaded = 1; if (m->reload) { + reloaded = 2; if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "Reloading module '%s' (%s)\n", m->resource, m->description()); m->reload(); @@ -181,6 +231,7 @@ void ast_module_reload(const char *name) } ast_mutex_unlock(&modlock); ast_mutex_unlock(&reloadlock); + return reloaded; } int ast_load_resource(char *resource_name)