Merged revisions 328247 via svnmerge from
[asterisk/asterisk.git] / res / res_clialiases.c
index a20947b..d67f3ba 100644 (file)
@@ -26,6 +26,9 @@
  * CLI commands.
  */
 
+/*** MODULEINFO
+       <support_level>core</support_level>
+ ***/
 
 #include "asterisk.h"
 
@@ -46,7 +49,6 @@ struct cli_alias {
        struct ast_cli_entry cli_entry; /*!< Actual CLI structure used for this alias */
        char *alias;                    /*!< CLI Alias */
        char *real_cmd;                 /*!< Actual CLI command it is aliased to */
-       unsigned int marked:1;          /*!< Bit to indicate whether this CLI alias is marked for destruction or not */
 };
 
 static struct ao2_container *cli_aliases;
@@ -59,7 +61,7 @@ static int alias_hash_cb(const void *obj, const int flags)
 }
 
 /*! \brief Comparison function used for aliases */
-static int alias_cmp_cb(void *obj, void *arg, void *data, int flags)
+static int alias_cmp_cb(void *obj, void *arg, int flags)
 {
        const struct cli_alias *alias0 = obj, *alias1 = arg;
 
@@ -88,7 +90,7 @@ static char *cli_alias_passthrough(struct ast_cli_entry *e, int cmd, struct ast_
        const char *line;
 
        /* Try to find the alias based on the CLI entry */
-       if (!(alias = ao2_find(cli_aliases, &tmp, NULL, OBJ_POINTER))) {
+       if (!(alias = ao2_find(cli_aliases, &tmp, OBJ_POINTER))) {
                return 0;
        }
 
@@ -99,10 +101,12 @@ static char *cli_alias_passthrough(struct ast_cli_entry *e, int cmd, struct ast_
        case CLI_GENERATE:
                line = a->line;
                line += (strlen(alias->alias));
-               if (!ast_strlen_zero(a->word)) {
+               if (!strncasecmp(alias->alias, alias->real_cmd, strlen(alias->alias))) {
+                       generator = NULL;
+               } else if (!ast_strlen_zero(a->word)) {
                        struct ast_str *real_cmd = ast_str_alloca(strlen(alias->real_cmd) + strlen(line) + 1);
                        ast_str_append(&real_cmd, 0, "%s%s", alias->real_cmd, line);
-                       generator = ast_cli_generator(real_cmd->str, a->word, a->n);
+                       generator = ast_cli_generator(ast_str_buffer(real_cmd), a->word, a->n);
                } else {
                        generator = ast_cli_generator(alias->real_cmd, a->word, a->n);
                }
@@ -122,7 +126,7 @@ static char *cli_alias_passthrough(struct ast_cli_entry *e, int cmd, struct ast_
                        ast_str_append(&real_cmd, 0, " %s", a->argv[i - 1]);
                }
 
-               ast_cli_command(a->fd, real_cmd->str);
+               ast_cli_command(a->fd, ast_str_buffer(real_cmd));
        } else {
                ast_cli_command(a->fd, alias->real_cmd);
        }
@@ -153,10 +157,10 @@ static char *alias_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a
        ast_cli(a->fd, FORMAT, "Alias Command", "Real Command");
 
        i = ao2_iterator_init(cli_aliases, 0);
-
        for (; (alias = ao2_iterator_next(&i)); ao2_ref(alias, -1)) {
                ast_cli(a->fd, FORMAT, alias->alias, alias->real_cmd);
        }
+       ao2_iterator_destroy(&i);
 
        return CLI_SUCCESS;
 #undef FORMAT
@@ -167,21 +171,6 @@ static struct ast_cli_entry cli_alias[] = {
        AST_CLI_DEFINE(alias_show, "Show CLI command aliases"),
 };
 
-/*! \brief Function called to mark an alias for destruction */
-static int alias_mark(void *obj, void *arg, void *data, int flags)
-{
-       struct cli_alias *alias = obj;
-       alias->marked = 1;
-       return 0;
-}
-
-/*! \brief Function called to see if an alias is marked for destruction */
-static int alias_marked(void *obj, void *arg, void *data, int flags)
-{
-       struct cli_alias *alias = obj;
-       return alias->marked ? CMP_MATCH : 0;
-}
-
 /*! \brief Function called to load or reload the configuration file */
 static void load_config(int reload)
 {
@@ -190,16 +179,16 @@ static void load_config(int reload)
        struct cli_alias *alias;
        struct ast_variable *v, *v1;
 
-       if (!(cfg = ast_config_load(config_file, config_flags))) {
+       if (!(cfg = ast_config_load(config_file, config_flags)) || cfg == CONFIG_STATUS_FILEINVALID) {
                ast_log(LOG_ERROR, "res_clialiases configuration file '%s' not found\n", config_file);
                return;
        } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
                return;
        }
 
-       /* Mark CLI aliases for pruning */
+       /* Destroy any existing CLI aliases */
        if (reload) {
-               ao2_callback(cli_aliases, OBJ_NODATA, alias_mark, NULL, NULL);
+               ao2_callback(cli_aliases, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL);
        }
 
        for (v = ast_variable_browse(cfg, "general"); v; v = v->next) {
@@ -218,7 +207,7 @@ static void load_config(int reload)
                        strcpy(alias->real_cmd, v1->value);
                        alias->cli_entry.handler = cli_alias_passthrough;
                        alias->cli_entry.command = alias->alias;
-                       alias->cli_entry.usage = "Aliased CLI Command";
+                       alias->cli_entry.usage = "Aliased CLI Command\n";
 
                        ast_cli_register(&alias->cli_entry);
                        ao2_link(cli_aliases, alias);
@@ -227,11 +216,6 @@ static void load_config(int reload)
                }
        }
 
-       /* Drop any CLI aliases that should no longer exist */
-       if (reload) {
-               ao2_callback(cli_aliases, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE , alias_marked, NULL, NULL);
-       }
-
        ast_config_destroy(cfg);
 
        return;