From df6c1d755f39308c77f3c49ef0f5fa539e627330 Mon Sep 17 00:00:00 2001 From: Corey Farrell Date: Mon, 4 May 2015 17:41:08 -0400 Subject: [PATCH] CLI: Enable automatic references to modules. * Pass module to ast_cli_register and ast_cli_register_multiple. * Add a module reference before executing any CLI callback, remove the reference when complete. ASTERISK-25049 #close Reported by: Corey Farrell Change-Id: I7aafc7c9f2b912918f28fe51d51e9e8a755750e3 --- include/asterisk/cli.h | 11 ++++++++--- main/cli.c | 31 ++++++++++++++----------------- res/res_clioriginate.c | 8 -------- res/res_convert.c | 5 ----- utils/ael_main.c | 4 ++-- utils/clicompat.c | 4 ++-- utils/conf2ael.c | 4 ++-- 7 files changed, 28 insertions(+), 39 deletions(-) diff --git a/include/asterisk/cli.h b/include/asterisk/cli.h index 458ebc8aa8..82363c15f4 100644 --- a/include/asterisk/cli.h +++ b/include/asterisk/cli.h @@ -177,7 +177,7 @@ struct ast_cli_entry { const char * usage; /*!< Detailed usage information */ int inuse; /*!< For keeping track of usage */ - struct module *module; /*!< module this belongs to */ + struct ast_module *module; /*!< module this belongs to */ char *_full_cmd; /*!< built at load time from cmda[] */ int cmdlen; /*!< len up to the first invalid char [<{% */ /*! \brief This gets set in ast_cli_register() @@ -253,14 +253,19 @@ int ast_cli_command_multiple_full(int uid, int gid, int fd, size_t size, const c * \retval 0 on success * \retval -1 on failure */ -int ast_cli_register(struct ast_cli_entry *e); +#define ast_cli_register(e) __ast_cli_register(e, AST_MODULE_SELF) + +int __ast_cli_register(struct ast_cli_entry *e, struct ast_module *mod); /*! * \brief Register multiple commands * \param e pointer to first cli entry to register * \param len number of entries to register */ -int ast_cli_register_multiple(struct ast_cli_entry *e, int len); +#define ast_cli_register_multiple(e, len) \ + __ast_cli_register_multiple(e, len, AST_MODULE_SELF) + +int __ast_cli_register_multiple(struct ast_cli_entry *e, int len, struct ast_module *mod); /*! * \brief Unregisters a command or an array of commands diff --git a/main/cli.c b/main/cli.c index a230c20ac6..eb8800f5e5 100644 --- a/main/cli.c +++ b/main/cli.c @@ -2203,7 +2203,7 @@ static int cli_is_registered(struct ast_cli_entry *e) return 0; } -static int __ast_cli_unregister(struct ast_cli_entry *e, struct ast_cli_entry *ed) +int ast_cli_unregister(struct ast_cli_entry *e) { if (e->inuse) { ast_log(LOG_WARNING, "Can't remove command that is in use\n"); @@ -2225,7 +2225,7 @@ static int __ast_cli_unregister(struct ast_cli_entry *e, struct ast_cli_entry *e return 0; } -static int __ast_cli_register(struct ast_cli_entry *e, struct ast_cli_entry *ed) +int __ast_cli_register(struct ast_cli_entry *e, struct ast_module *module) { struct ast_cli_entry *cur; int i, lf, ret = -1; @@ -2244,7 +2244,11 @@ static int __ast_cli_register(struct ast_cli_entry *e, struct ast_cli_entry *ed) } memset(&a, '\0', sizeof(a)); + + e->module = module; + /* No module reference needed here, the module called us. */ e->handler(e, CLI_INIT, &a); + /* XXX check that usage and command are filled up */ s = ast_skip_blanks(e->command); s = e->command = ast_strdup(s); @@ -2295,27 +2299,16 @@ done: return ret; } -/* wrapper function, so we can unregister deprecated commands recursively */ -int ast_cli_unregister(struct ast_cli_entry *e) -{ - return __ast_cli_unregister(e, NULL); -} - -/* wrapper function, so we can register deprecated commands recursively */ -int ast_cli_register(struct ast_cli_entry *e) -{ - return __ast_cli_register(e, NULL); -} - /* * register/unregister an array of entries. */ -int ast_cli_register_multiple(struct ast_cli_entry *e, int len) +int __ast_cli_register_multiple(struct ast_cli_entry *e, int len, struct ast_module *module) { int i, res = 0; - for (i = 0; i < len; i++) - res |= ast_cli_register(e + i); + for (i = 0; i < len; i++) { + res |= __ast_cli_register(e + i, module); + } return res; } @@ -2657,7 +2650,9 @@ static char *__ast_cli_generator(const char *text, const char *word, int state, .n = state - matchnum, .argv = argv, .argc = x}; + ast_module_ref(e->module); ret = e->handler(e, CLI_GENERATE, &a); + ast_module_unref(e->module); } if (ret) break; @@ -2714,7 +2709,9 @@ int ast_cli_command_full(int uid, int gid, int fd, const char *s) */ args[0] = (char *)e; + ast_module_ref(e->module); retval = e->handler(e, CLI_HANDLER, &a); + ast_module_unref(e->module); if (retval == CLI_SHOWUSAGE) { ast_cli(fd, "%s", S_OR(e->usage, "Invalid usage, but no usage information available.\n")); diff --git a/res/res_clioriginate.c b/res/res_clioriginate.c index 173f9f579d..451b1745de 100644 --- a/res/res_clioriginate.c +++ b/res/res_clioriginate.c @@ -156,8 +156,6 @@ static char *handle_orig(struct ast_cli_entry *e, int cmd, struct ast_cli_args * "used. If no extension is given, the 's' extension will be used.\n"; return NULL; case CLI_GENERATE: - /* ugly, can be removed when CLI entries have ast_module pointers */ - ast_module_ref(ast_module_info->self); if (a->pos == 3) { res = ast_cli_complete(a->word, choices, a->n); } else if (a->pos == 4) { @@ -165,16 +163,12 @@ static char *handle_orig(struct ast_cli_entry *e, int cmd, struct ast_cli_args * res = ast_complete_applications(a->line, a->word, a->n); } } - ast_module_unref(ast_module_info->self); return res; } if (ast_strlen_zero(a->argv[2]) || ast_strlen_zero(a->argv[3])) return CLI_SHOWUSAGE; - /* ugly, can be removed when CLI entries have ast_module pointers */ - ast_module_ref(ast_module_info->self); - if (!strcasecmp("application", a->argv[3])) { res = orig_app(a->fd, a->argv[2], a->argv[4], a->argv[5]); } else if (!strcasecmp("extension", a->argv[3])) { @@ -183,8 +177,6 @@ static char *handle_orig(struct ast_cli_entry *e, int cmd, struct ast_cli_args * res = CLI_SHOWUSAGE; } - ast_module_unref(ast_module_info->self); - return res; } diff --git a/res/res_convert.c b/res/res_convert.c index 2a691a56a8..3ca596511a 100644 --- a/res/res_convert.c +++ b/res/res_convert.c @@ -88,9 +88,6 @@ static char *handle_cli_file_convert(struct ast_cli_entry *e, int cmd, struct as return NULL; } - /* ugly, can be removed when CLI entries have ast_module pointers */ - ast_module_ref(ast_module_info->self); - if (a->argc != 4 || ast_strlen_zero(a->argv[2]) || ast_strlen_zero(a->argv[3])) { ret = CLI_SHOWUSAGE; goto fail_out; @@ -142,8 +139,6 @@ fail_out: if (fs_in) ast_closestream(fs_in); - ast_module_unref(ast_module_info->self); - return ret; } diff --git a/utils/ael_main.c b/utils/ael_main.c index 2237625970..06ba8e66ec 100644 --- a/utils/ael_main.c +++ b/utils/ael_main.c @@ -103,7 +103,7 @@ static char var_dir[PATH_MAX]; const char *ast_config_AST_CONFIG_DIR = config_dir; const char *ast_config_AST_VAR_DIR = var_dir; -void ast_cli_register_multiple(void); +void __ast_cli_register_multiple(void); int ast_add_extension2(struct ast_context *con, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void (*datad)(void *), @@ -208,7 +208,7 @@ void ast_module_unregister(const struct ast_module_info *x) } -void ast_cli_register_multiple(void) +void __ast_cli_register_multiple(void) { if(!no_comp) printf("Executed ast_cli_register_multiple();\n"); diff --git a/utils/clicompat.c b/utils/clicompat.c index d25a7102e8..426dd5cdea 100644 --- a/utils/clicompat.c +++ b/utils/clicompat.c @@ -21,8 +21,8 @@ int ast_register_cleanup(void (*func)(void)) return 0; } -int ast_cli_register_multiple(struct ast_cli_entry *e, int len); -int ast_cli_register_multiple(struct ast_cli_entry *e, int len) +int __ast_cli_register_multiple(struct ast_cli_entry *e, int len); +int __ast_cli_register_multiple(struct ast_cli_entry *e, int len) { return 0; } diff --git a/utils/conf2ael.c b/utils/conf2ael.c index 99304b2f5a..76a3ad3f2d 100644 --- a/utils/conf2ael.c +++ b/utils/conf2ael.c @@ -605,9 +605,9 @@ struct ast_context *ast_context_find_or_create(struct ast_context **extcontexts, return localized_context_find_or_create(extcontexts, exttable, name, registrar); } -void ast_cli_register_multiple(void); +void __ast_cli_register_multiple(void); -void ast_cli_register_multiple(void) +void __ast_cli_register_multiple(void) { }