* 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
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()
* \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
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");
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;
}
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);
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;
}
.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;
*/
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"));
"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) {
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])) {
res = CLI_SHOWUSAGE;
}
- ast_module_unref(ast_module_info->self);
-
return res;
}
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;
if (fs_in)
ast_closestream(fs_in);
- ast_module_unref(ast_module_info->self);
-
return ret;
}
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 *),
}
-void ast_cli_register_multiple(void)
+void __ast_cli_register_multiple(void)
{
if(!no_comp)
printf("Executed ast_cli_register_multiple();\n");
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;
}
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)
{
}