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
This commit is contained in:
parent
a8bfa9e104
commit
df6c1d755f
|
@ -177,7 +177,7 @@ struct ast_cli_entry {
|
||||||
const char * usage; /*!< Detailed usage information */
|
const char * usage; /*!< Detailed usage information */
|
||||||
|
|
||||||
int inuse; /*!< For keeping track of usage */
|
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[] */
|
char *_full_cmd; /*!< built at load time from cmda[] */
|
||||||
int cmdlen; /*!< len up to the first invalid char [<{% */
|
int cmdlen; /*!< len up to the first invalid char [<{% */
|
||||||
/*! \brief This gets set in ast_cli_register()
|
/*! \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 0 on success
|
||||||
* \retval -1 on failure
|
* \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
|
* \brief Register multiple commands
|
||||||
* \param e pointer to first cli entry to register
|
* \param e pointer to first cli entry to register
|
||||||
* \param len number of entries 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
|
* \brief Unregisters a command or an array of commands
|
||||||
|
|
31
main/cli.c
31
main/cli.c
|
@ -2203,7 +2203,7 @@ static int cli_is_registered(struct ast_cli_entry *e)
|
||||||
return 0;
|
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) {
|
if (e->inuse) {
|
||||||
ast_log(LOG_WARNING, "Can't remove command that is in use\n");
|
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;
|
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;
|
struct ast_cli_entry *cur;
|
||||||
int i, lf, ret = -1;
|
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));
|
memset(&a, '\0', sizeof(a));
|
||||||
|
|
||||||
|
e->module = module;
|
||||||
|
/* No module reference needed here, the module called us. */
|
||||||
e->handler(e, CLI_INIT, &a);
|
e->handler(e, CLI_INIT, &a);
|
||||||
|
|
||||||
/* XXX check that usage and command are filled up */
|
/* XXX check that usage and command are filled up */
|
||||||
s = ast_skip_blanks(e->command);
|
s = ast_skip_blanks(e->command);
|
||||||
s = e->command = ast_strdup(s);
|
s = e->command = ast_strdup(s);
|
||||||
|
@ -2295,27 +2299,16 @@ done:
|
||||||
return ret;
|
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.
|
* 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;
|
int i, res = 0;
|
||||||
|
|
||||||
for (i = 0; i < len; i++)
|
for (i = 0; i < len; i++) {
|
||||||
res |= ast_cli_register(e + i);
|
res |= __ast_cli_register(e + i, module);
|
||||||
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -2657,7 +2650,9 @@ static char *__ast_cli_generator(const char *text, const char *word, int state,
|
||||||
.n = state - matchnum,
|
.n = state - matchnum,
|
||||||
.argv = argv,
|
.argv = argv,
|
||||||
.argc = x};
|
.argc = x};
|
||||||
|
ast_module_ref(e->module);
|
||||||
ret = e->handler(e, CLI_GENERATE, &a);
|
ret = e->handler(e, CLI_GENERATE, &a);
|
||||||
|
ast_module_unref(e->module);
|
||||||
}
|
}
|
||||||
if (ret)
|
if (ret)
|
||||||
break;
|
break;
|
||||||
|
@ -2714,7 +2709,9 @@ int ast_cli_command_full(int uid, int gid, int fd, const char *s)
|
||||||
*/
|
*/
|
||||||
args[0] = (char *)e;
|
args[0] = (char *)e;
|
||||||
|
|
||||||
|
ast_module_ref(e->module);
|
||||||
retval = e->handler(e, CLI_HANDLER, &a);
|
retval = e->handler(e, CLI_HANDLER, &a);
|
||||||
|
ast_module_unref(e->module);
|
||||||
|
|
||||||
if (retval == CLI_SHOWUSAGE) {
|
if (retval == CLI_SHOWUSAGE) {
|
||||||
ast_cli(fd, "%s", S_OR(e->usage, "Invalid usage, but no usage information available.\n"));
|
ast_cli(fd, "%s", S_OR(e->usage, "Invalid usage, but no usage information available.\n"));
|
||||||
|
|
|
@ -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";
|
"used. If no extension is given, the 's' extension will be used.\n";
|
||||||
return NULL;
|
return NULL;
|
||||||
case CLI_GENERATE:
|
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) {
|
if (a->pos == 3) {
|
||||||
res = ast_cli_complete(a->word, choices, a->n);
|
res = ast_cli_complete(a->word, choices, a->n);
|
||||||
} else if (a->pos == 4) {
|
} 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);
|
res = ast_complete_applications(a->line, a->word, a->n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast_module_unref(ast_module_info->self);
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ast_strlen_zero(a->argv[2]) || ast_strlen_zero(a->argv[3]))
|
if (ast_strlen_zero(a->argv[2]) || ast_strlen_zero(a->argv[3]))
|
||||||
return CLI_SHOWUSAGE;
|
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])) {
|
if (!strcasecmp("application", a->argv[3])) {
|
||||||
res = orig_app(a->fd, a->argv[2], a->argv[4], a->argv[5]);
|
res = orig_app(a->fd, a->argv[2], a->argv[4], a->argv[5]);
|
||||||
} else if (!strcasecmp("extension", a->argv[3])) {
|
} 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;
|
res = CLI_SHOWUSAGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ast_module_unref(ast_module_info->self);
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,9 +88,6 @@ static char *handle_cli_file_convert(struct ast_cli_entry *e, int cmd, struct as
|
||||||
return NULL;
|
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])) {
|
if (a->argc != 4 || ast_strlen_zero(a->argv[2]) || ast_strlen_zero(a->argv[3])) {
|
||||||
ret = CLI_SHOWUSAGE;
|
ret = CLI_SHOWUSAGE;
|
||||||
goto fail_out;
|
goto fail_out;
|
||||||
|
@ -142,8 +139,6 @@ fail_out:
|
||||||
if (fs_in)
|
if (fs_in)
|
||||||
ast_closestream(fs_in);
|
ast_closestream(fs_in);
|
||||||
|
|
||||||
ast_module_unref(ast_module_info->self);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,7 +103,7 @@ static char var_dir[PATH_MAX];
|
||||||
const char *ast_config_AST_CONFIG_DIR = config_dir;
|
const char *ast_config_AST_CONFIG_DIR = config_dir;
|
||||||
const char *ast_config_AST_VAR_DIR = var_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 ast_add_extension2(struct ast_context *con,
|
||||||
int replace, const char *extension, int priority, const char *label, const char *callerid,
|
int replace, const char *extension, int priority, const char *label, const char *callerid,
|
||||||
const char *application, void *data, void (*datad)(void *),
|
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)
|
if(!no_comp)
|
||||||
printf("Executed ast_cli_register_multiple();\n");
|
printf("Executed ast_cli_register_multiple();\n");
|
||||||
|
|
|
@ -21,8 +21,8 @@ int ast_register_cleanup(void (*func)(void))
|
||||||
return 0;
|
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 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
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)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue