CLI: Enable automatic references to modules.
authorCorey Farrell <git@cfware.com>
Mon, 4 May 2015 21:41:08 +0000 (17:41 -0400)
committerCorey Farrell <git@cfware.com>
Tue, 5 May 2015 00:47:18 +0000 (20:47 -0400)
* 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
main/cli.c
res/res_clioriginate.c
res/res_convert.c
utils/ael_main.c
utils/clicompat.c
utils/conf2ael.c

index 458ebc8..82363c1 100644 (file)
@@ -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
index a230c20..eb8800f 100644 (file)
@@ -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"));
index 173f9f5..451b174 100644 (file)
@@ -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;
 }
 
index 2a691a5..3ca5965 100644 (file)
@@ -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;
 }
 
index 2237625..06ba8e6 100644 (file)
@@ -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");
index d25a710..426dd5c 100644 (file)
@@ -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;
 }
index 99304b2..76a3ad3 100644 (file)
@@ -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)
 {
 }