Index: main/cli.c =================================================================== --- main/cli.c (revision 375799) +++ main/cli.c (working copy) @@ -1871,10 +1871,16 @@ return 0; } +static void cli_shutdown(void) +{ + ast_cli_unregister_multiple(cli_cli, ARRAY_LEN(cli_cli)); +} + /*! \brief initialize the _full_cmd string in * each of the builtins. */ void ast_builtins_init(void) { ast_cli_register_multiple(cli_cli, ARRAY_LEN(cli_cli)); + ast_register_atexit(cli_shutdown); } /*! @@ -2039,6 +2045,17 @@ return cmdline; } +static int cli_is_registered(struct ast_cli_entry *e) +{ + struct ast_cli_entry *cur = NULL; + while ((cur = cli_next(cur))) { + if (cur==e) { + return 1; + } + } + return 0; +} + static int __ast_cli_unregister(struct ast_cli_entry *e, struct ast_cli_entry *ed) { if (e->inuse) { @@ -2070,6 +2087,14 @@ char **dst = (char **)e->cmda; /* need to cast as the entry is readonly */ char *s; + AST_RWLIST_WRLOCK(&helpers); + + if (cli_is_registered(e)) { + ast_log(LOG_WARNING, "Command '%s' already registered (the same ast_cli_entry)\n", S_OR(e->_full_cmd, e->command)); + ret = 0; /* report success */ + goto done; + } + memset(&a, '\0', sizeof(a)); e->handler(e, CLI_INIT, &a); /* XXX check that usage and command are filled up */ @@ -2084,11 +2109,10 @@ s = ast_skip_blanks(s); } *dst++ = NULL; - - AST_RWLIST_WRLOCK(&helpers); - + if (find_cli(e->cmda, 1)) { ast_log(LOG_WARNING, "Command '%s' already registered (or something close enough)\n", S_OR(e->_full_cmd, e->command)); + ret = -2; goto done; } if (set_full_cmd(e)) @@ -2112,6 +2136,12 @@ done: AST_RWLIST_UNLOCK(&helpers); + if (ret) { + if (ret==-1) + ast_log(LOG_WARNING, "Error registering CLI Command '%s'\n", S_OR(e->_full_cmd, e->command)); + ast_free(e->command); + e->command = NULL; + } return ret; }