Merge a ton of NEW_CLI conversions. Thanks to everyone that helped out! :)
authorRussell Bryant <russell@russellbryant.com>
Thu, 11 Oct 2007 19:03:06 +0000 (19:03 +0000)
committerRussell Bryant <russell@russellbryant.com>
Thu, 11 Oct 2007 19:03:06 +0000 (19:03 +0000)
(closes issue #10724)
Reported by: eliel
Patches:
      chan_skinny.c.patch uploaded by eliel (license 64)
      chan_oss.c.patch uploaded by eliel (license 64)
      chan_mgcp.c.patch2 uploaded by eliel (license 64)
      pbx_config.c.patch uploaded by seanbright (license 71)
      iax2-provision.c.patch uploaded by eliel (license 64)
      chan_gtalk.c.patch uploaded by eliel (license 64)
      pbx_ael.c.patch uploaded by seanbright (license 71)
      file.c.patch uploaded by seanbright (license 71)
      image.c.patch uploaded by seanbright (license 71)
      cli.c.patch uploaded by moy (license 222)
      astobj2.c.patch uploaded by moy (license 222)
      asterisk.c.patch uploaded by moy (license 222)
      res_limit.c.patch uploaded by seanbright (license 71)
      res_convert.c.patch uploaded by seanbright (license 71)
      res_crypto.c.patch uploaded by seanbright (license 71)
      app_osplookup.c.patch uploaded by seanbright (license 71)
      app_rpt.c.patch uploaded by seanbright (license 71)
      app_mixmonitor.c.patch uploaded by seanbright (license 71)
      channel.c.patch uploaded by seanbright (license 71)
      translate.c.patch uploaded by seanbright (license 71)
      udptl.c.patch uploaded by seanbright (license 71)
      threadstorage.c.patch uploaded by seanbright (license 71)
      db.c.patch uploaded by seanbright (license 71)
      cdr.c.patch uploaded by moy (license 222)
      pbd_dundi.c.patch uploaded by moy (license 222)
      app_osplookup-rev83558.patch uploaded by moy (license 222)
      res_clioriginate.c.patch uploaded by moy (license 222)

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@85460 65c4cc65-6c06-0410-ace0-fbb531ad65f3

26 files changed:
apps/app_mixmonitor.c
apps/app_osplookup.c
apps/app_rpt.c
channels/chan_gtalk.c
channels/chan_mgcp.c
channels/chan_oss.c
channels/chan_skinny.c
channels/iax2-provision.c
main/asterisk.c
main/astobj2.c
main/cdr.c
main/channel.c
main/cli.c
main/db.c
main/file.c
main/image.c
main/threadstorage.c
main/translate.c
main/udptl.c
pbx/pbx_ael.c
pbx/pbx_config.c
pbx/pbx_dundi.c
res/res_clioriginate.c
res/res_convert.c
res/res_crypto.c
res/res_limit.c

index 614adcb..ca775f1 100644 (file)
@@ -362,46 +362,44 @@ static int stop_mixmonitor_exec(struct ast_channel *chan, void *data)
        return 0;
 }
 
-static int mixmonitor_cli(int fd, int argc, char **argv) 
+static char *handle_cli_mixmonitor(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        struct ast_channel *chan;
 
-       if (argc < 3)
-               return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "mixmonitor [start|stop]";
+               e->usage =
+                       "Usage: mixmonitor <start|stop> <chan_name> [args]\n"
+                       "       The optional arguments are passed to the MixMonitor\n"
+                       "       application when the 'start' command is used.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return ast_complete_channels(a->line, a->word, a->pos, a->n, 2);
+       }
+
+       if (a->argc < 3)
+               return CLI_SHOWUSAGE;
 
-       if (!(chan = ast_get_channel_by_name_prefix_locked(argv[2], strlen(argv[2])))) {
-               ast_cli(fd, "No channel matching '%s' found.\n", argv[2]);
-               return RESULT_SUCCESS;
+       if (!(chan = ast_get_channel_by_name_prefix_locked(a->argv[2], strlen(a->argv[2])))) {
+               ast_cli(a->fd, "No channel matching '%s' found.\n", a->argv[2]);
+               /* Technically this is a failure, but we don't want 2 errors printing out */
+               return CLI_SUCCESS;
        }
 
-       if (!strcasecmp(argv[1], "start")) {
-               mixmonitor_exec(chan, argv[3]);
+       if (!strcasecmp(a->argv[1], "start")) {
+               mixmonitor_exec(chan, a->argv[3]);
                ast_channel_unlock(chan);
        } else {
                ast_channel_unlock(chan);
                ast_audiohook_detach_source(chan, mixmonitor_spy_type);
        }
 
-       return RESULT_SUCCESS;
-}
-
-static char *complete_mixmonitor_cli(const char *line, const char *word, int pos, int state)
-{
-       char *options[] = {"start", "stop", NULL};
-
-       if (pos == 1)
-               return ast_cli_complete (word, options, state);
-
-       return ast_complete_channels(line, word, pos, state, 2);
+       return CLI_SUCCESS;
 }
 
 static struct ast_cli_entry cli_mixmonitor[] = {
-       { { "mixmonitor", NULL, NULL },
-       mixmonitor_cli, "Execute a MixMonitor command.",
-       "mixmonitor <start|stop> <chan_name> [args]\n\n"
-       "The optional arguments are passed to the\n"
-       "MixMonitor application when the 'start' command is used.\n",
-       complete_mixmonitor_cli },
+       NEW_CLI(handle_cli_mixmonitor, "Execute a MixMonitor command")
 };
 
 static int unload_module(void)
index 25b3fb5..5c4e240 100644 (file)
@@ -1861,10 +1861,7 @@ static int osp_unload(void)
        return 0;
 }
 
-static int osp_show(
-       int fd,
-       int argc,
-       char* argv[])
+static char *handle_cli_osp_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        int i;
        int found = 0;
@@ -1872,12 +1869,21 @@ static int osp_show(
        const char* provider = NULL;
        const char* tokenalgo;
 
-       if ((argc < 2) || (argc > 3)) {
-               return RESULT_SHOWUSAGE;
-       }
-       if (argc > 2) {
-               provider = argv[2];
-       }
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "osp show";
+               e->usage =
+                       "Usage: osp show\n"
+                       "       Displays information on Open Settlement Protocol support\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
+       if ((a->argc < 2) || (a->argc > 3))
+               return CLI_SHOWUSAGE;
+       if (a->argc > 2) 
+               provider = a->argv[2];
        if (!provider) {
                switch (osp_tokenformat) {
                        case TOKEN_ALGO_BOTH:
@@ -1891,7 +1897,7 @@ static int osp_show(
                                tokenalgo = "Signed";
                                break;
                }
-               ast_cli(fd, "OSP: %s %s %s\n",
+               ast_cli(a->fd, "OSP: %s %s %s\n",
                        osp_initialized ? "Initialized" : "Uninitialized", osp_hardware ? "Accelerated" : "Normal", tokenalgo);
        }
 
@@ -1900,25 +1906,25 @@ static int osp_show(
        while(p) {
                if (!provider || !strcasecmp(p->name, provider)) {
                        if (found) {
-                               ast_cli(fd, "\n");
+                               ast_cli(a->fd, "\n");
                        }
-                       ast_cli(fd, " == OSP Provider '%s' == \n", p->name);
-                       ast_cli(fd, "Local Private Key: %s\n", p->privatekey);
-                       ast_cli(fd, "Local Certificate: %s\n", p->localcert);
+                       ast_cli(a->fd, " == OSP Provider '%s' == \n", p->name);
+                       ast_cli(a->fd, "Local Private Key: %s\n", p->privatekey);
+                       ast_cli(a->fd, "Local Certificate: %s\n", p->localcert);
                        for (i = 0; i < p->cacount; i++) {
-                               ast_cli(fd, "CA Certificate %d:  %s\n", i + 1, p->cacerts[i]);
+                               ast_cli(a->fd, "CA Certificate %d:  %s\n", i + 1, p->cacerts[i]);
                        }
                        for (i = 0; i < p->spcount; i++) {
-                               ast_cli(fd, "Service Point %d:   %s\n", i + 1, p->srvpoints[i]);
+                               ast_cli(a->fd, "Service Point %d:   %s\n", i + 1, p->srvpoints[i]);
                        }
-                       ast_cli(fd, "Max Connections:   %d\n", p->maxconnections);
-                       ast_cli(fd, "Retry Delay:       %d seconds\n", p->retrydelay);
-                       ast_cli(fd, "Retry Limit:       %d\n", p->retrylimit);
-                       ast_cli(fd, "Timeout:           %d milliseconds\n", p->timeout);
-                       ast_cli(fd, "Source:            %s\n", strlen(p->source) ? p->source : "<unspecified>");
-                       ast_cli(fd, "Auth Policy        %d\n", p->authpolicy);
-                       ast_cli(fd, "Default protocol   %s\n", p->defaultprotocol);
-                       ast_cli(fd, "OSP Handle:        %d\n", p->handle);
+                       ast_cli(a->fd, "Max Connections:   %d\n", p->maxconnections);
+                       ast_cli(a->fd, "Retry Delay:       %d seconds\n", p->retrydelay);
+                       ast_cli(a->fd, "Retry Limit:       %d\n", p->retrylimit);
+                       ast_cli(a->fd, "Timeout:           %d milliseconds\n", p->timeout);
+                       ast_cli(a->fd, "Source:            %s\n", strlen(p->source) ? p->source : "<unspecified>");
+                       ast_cli(a->fd, "Auth Policy        %d\n", p->authpolicy);
+                       ast_cli(a->fd, "Default protocol   %s\n", p->defaultprotocol);
+                       ast_cli(a->fd, "OSP Handle:        %d\n", p->handle);
                        found++;
                }
                p = p->next;
@@ -1927,12 +1933,12 @@ static int osp_show(
 
        if (!found) {
                if (provider) {
-                       ast_cli(fd, "Unable to find OSP provider '%s'\n", provider);
+                       ast_cli(a->fd, "Unable to find OSP provider '%s'\n", provider);
                } else {
-                       ast_cli(fd, "No OSP providers configured\n");
-               }
+                       ast_cli(a->fd, "No OSP providers configured\n");
+               }       
        }
-       return RESULT_SUCCESS;
+       return CLI_SUCCESS;
 }
 
 static const char* app1= "OSPAuth";
@@ -1993,14 +1999,8 @@ static const char* descrip4 =
 "      OSPFINISHSTATUS The status of the OSP Finish attempt as a text string, one of\n"
 "              SUCCESS | FAILED | ERROR \n";
 
-static const char osp_usage[] =
-"Usage: osp show\n"
-"       Displays information on Open Settlement Protocol support\n";
-
 static struct ast_cli_entry cli_osp[] = {
-       { {"osp", "show", NULL},
-       osp_show, "Displays OSP information",
-       osp_usage },
+       NEW_CLI(handle_cli_osp_show, "Displays OSF information")
 };
 
 static int load_module(void)
index 77e4ee4..1f77cee 100644 (file)
@@ -300,7 +300,6 @@ static char *remote_rig_rbi = "rbi";
 STANDARD_LOCAL_USER;
 #endif
 
-
 #define        MSWAIT 200
 #define        HANGTIME 5000
 #define        TOTIME 180000
@@ -699,60 +698,20 @@ static void _rpt_mutex_unlock(ast_mutex_t *lockp, struct rpt *myrpt, int line)
 */
 
 /* Debug mode */
-static int rpt_do_debug(int fd, int argc, char *argv[]);
-static int rpt_do_dump(int fd, int argc, char *argv[]);
-static int rpt_do_stats(int fd, int argc, char *argv[]);
-static int rpt_do_lstats(int fd, int argc, char *argv[]);
-static int rpt_do_reload(int fd, int argc, char *argv[]);
-static int rpt_do_restart(int fd, int argc, char *argv[]);
-
-static char debug_usage[] =
-"Usage: rpt debug level {0-7}\n"
-"       Enables debug messages in app_rpt\n";
-
-static char dump_usage[] =
-"Usage: rpt dump <nodename>\n"
-"       Dumps struct debug info to log\n";
-
-static char dump_stats[] =
-"Usage: rpt stats <nodename>\n"
-"       Dumps node statistics to console\n";
-
-static char dump_lstats[] =
-"Usage: rpt lstats <nodename>\n"
-"       Dumps link statistics to console\n";
-
-static char reload_usage[] =
-"Usage: rpt reload\n"
-"       Reloads app_rpt running config parameters\n";
-
-static char restart_usage[] =
-"Usage: rpt restart\n"
-"       Restarts app_rpt\n";
+static char *handle_cli_rpt_debug_level(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
+static char *handle_cli_rpt_dump(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
+static char *handle_cli_rpt_stats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
+static char *handle_cli_rpt_lstats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
+static char *handle_cli_rpt_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
+static char *handle_cli_rpt_restart(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
 
 static struct ast_cli_entry cli_rpt[] = {
-       { { "rpt", "debug", "level" },
-               rpt_do_debug, "Enable app_rpt debugging",
-               debug_usage },
-
-       { { "rpt", "dump" },
-               rpt_do_dump, "Dump app_rpt structs for debugging",
-               dump_usage },
-
-       { { "rpt", "stats" },
-               rpt_do_stats, "Dump node statistics",
-               dump_stats },
-       { { "rpt", "lstats" },
-               rpt_do_lstats, "Dump link statistics",
-               dump_lstats },
-
-       { { "rpt", "reload" },
-               rpt_do_reload, "Reload app_rpt config",
-               reload_usage },
-
-       { { "rpt", "restart" },
-               rpt_do_restart, "Restart app_rpt",
-               restart_usage },
+       NEW_CLI(handle_cli_rpt_debug_level, "Enable app_rpt debuggin"),
+       NEW_CLI(handle_cli_rpt_dump,        "Dump app_rpt structs for debugging"),
+       NEW_CLI(handle_cli_rpt_stats,       "Dump node statistics"),
+       NEW_CLI(handle_cli_rpt_lstats,      "Dump link statistics"),
+       NEW_CLI(handle_cli_rpt_reload,      "Reload app_rpt config"),
+       NEW_CLI(handle_cli_rpt_restart,     "Restart app_rpt")
 };
 
 /*
@@ -1130,48 +1089,70 @@ static void load_rpt_vars(int n, int init)
 /*
 * Enable or disable debug output at a given level at the console
 */
-static int rpt_do_debug(int fd, int argc, char *argv[])
+static char *handle_cli_rpt_debug_level(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        int newlevel;
 
-       if (argc != 4)
-               return RESULT_SHOWUSAGE;
-       newlevel = myatoi(argv[3]);
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "rpt debug level";
+               e->usage =
+                       "Usage: rpt debug level {0-7}\n"
+                       "       Enables debug messages in app_rpt\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+       if (a->argc != 4)
+               return CLI_SHOWUSAGE;
+       newlevel = myatoi(a->argv[3]);
        if ((newlevel < 0) || (newlevel > 7))
-               return RESULT_SHOWUSAGE;
+               return CLI_SHOWUSAGE;
        if (newlevel)
-               ast_cli(fd, "app_rpt Debugging enabled, previous level: %d, new level: %d\n", debug, newlevel);
+               ast_cli(a->fd, "app_rpt Debugging enabled, previous level: %d, new level: %d\n", debug, newlevel);
        else
-               ast_cli(fd, "app_rpt Debugging disabled\n");
+               ast_cli(a->fd, "app_rpt Debugging disabled\n");
+
+       debug = newlevel;
 
-       debug = newlevel;                                                                                                                          
-       return RESULT_SUCCESS;
+       return CLI_SUCCESS;
 }
 
 /*
 * Dump rpt struct debugging onto console
 */
-static int rpt_do_dump(int fd, int argc, char *argv[])
+static char *handle_cli_rpt_dump(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        int i;
 
-       if (argc != 3)
-               return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "rpt dump";
+               e->usage =
+                       "Usage: rpt dump <nodename>\n"
+                       "       Dumps struct debug info to log\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
+       if (a->argc != 3)
+               return CLI_SHOWUSAGE;
 
        for (i = 0; i < nrpts; i++) {
-               if (!strcmp(argv[2], rpt_vars[i].name)) {
+               if (!strcmp(a->argv[2], rpt_vars[i].name)) {
                        rpt_vars[i].disgorgetime = time(NULL) + 10; /* Do it 10 seconds later */
-                       ast_cli(fd, "app_rpt struct dump requested for node %s\n", argv[2]);
-                       return RESULT_SUCCESS;
+                       ast_cli(a->fd, "app_rpt struct dump requested for node %s\n", a->argv[2]);
+                       return CLI_SUCCESS;
                }
        }
-       return RESULT_FAILURE;
+       return CLI_FAILURE;
 }
 
 /*
 * Dump statistics onto console
 */
-static int rpt_do_stats(int fd, int argc, char *argv[])
+static char *handle_cli_rpt_stats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        int i, j;
        int dailytxtime, dailykerchunks;
@@ -1187,8 +1168,19 @@ static int rpt_do_stats(int fd, int argc, char *argv[])
 
        static char *not_applicable = "N/A";
 
-       if (argc != 3)
-               return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "rpt stats";
+               e->usage =
+                       "Usage: rpt stats <nodename>\n"
+                       "       Dumps node statistics to console\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
+       if (a->argc != 3)
+               return CLI_SHOWUSAGE;
 
        for (i = 0 ; i <= MAX_STAT_LINKS; i++)
                listoflinks[i] = NULL;
@@ -1199,7 +1191,7 @@ static int rpt_do_stats(int fd, int argc, char *argv[])
        lastdtmfcommand = not_applicable;
 
        for (i = 0; i < nrpts; i++) {
-               if (!strcmp(argv[2], rpt_vars[i].name)) {
+               if (!strcmp(a->argv[2], rpt_vars[i].name)) {
                        /* Make a copy of all stat variables while locked */
                        myrpt = &rpt_vars[i];
                        rpt_mutex_lock(&myrpt->lock); /* LOCK */
@@ -1283,19 +1275,19 @@ static int rpt_do_stats(int fd, int argc, char *argv[])
 
                        rpt_mutex_unlock(&myrpt->lock); /* UNLOCK */
 
-                       ast_cli(fd, "************************ NODE %s STATISTICS *************************\n\n", myrpt->name);
-                       ast_cli(fd, "Signal on input..................................: %s\n", input_signal);
-                       ast_cli(fd, "Transmitter enabled..............................: %s\n", enable_state);
-                       ast_cli(fd, "Time out timer state.............................: %s\n", tot_state);
-                       ast_cli(fd, "Time outs since system initialization............: %d\n", timeouts);
-                       ast_cli(fd, "Identifier state.................................: %s\n", ider_state);
-                       ast_cli(fd, "Kerchunks today..................................: %d\n", dailykerchunks);
-                       ast_cli(fd, "Kerchunks since system initialization............: %d\n", totalkerchunks);
-                       ast_cli(fd, "Keyups today.....................................: %d\n", dailykeyups);
-                       ast_cli(fd, "Keyups since system initialization...............: %d\n", totalkeyups);
-                       ast_cli(fd, "DTMF commands today..............................: %d\n", dailyexecdcommands);
-                       ast_cli(fd, "DTMF commands since system initialization........: %d\n", totalexecdcommands);
-                       ast_cli(fd, "Last DTMF command executed.......................: %s\n", lastdtmfcommand);
+                       ast_cli(a->fd, "************************ NODE %s STATISTICS *************************\n\n", myrpt->name);
+                       ast_cli(a->fd, "Signal on input..................................: %s\n", input_signal);
+                       ast_cli(a->fd, "Transmitter enabled..............................: %s\n", enable_state);
+                       ast_cli(a->fd, "Time out timer state.............................: %s\n", tot_state);
+                       ast_cli(a->fd, "Time outs since system initialization............: %d\n", timeouts);
+                       ast_cli(a->fd, "Identifier state.................................: %s\n", ider_state);
+                       ast_cli(a->fd, "Kerchunks today..................................: %d\n", dailykerchunks);
+                       ast_cli(a->fd, "Kerchunks since system initialization............: %d\n", totalkerchunks);
+                       ast_cli(a->fd, "Keyups today.....................................: %d\n", dailykeyups);
+                       ast_cli(a->fd, "Keyups since system initialization...............: %d\n", totalkeyups);
+                       ast_cli(a->fd, "DTMF commands today..............................: %d\n", dailyexecdcommands);
+                       ast_cli(a->fd, "DTMF commands since system initialization........: %d\n", totalexecdcommands);
+                       ast_cli(a->fd, "Last DTMF command executed.......................: %s\n", lastdtmfcommand);
 
                        hours = dailytxtime / 3600000;
                        dailytxtime %= 3600000;
@@ -1304,7 +1296,7 @@ static int rpt_do_stats(int fd, int argc, char *argv[])
                        seconds = dailytxtime / 1000;
                        dailytxtime %= 1000;
 
-                       ast_cli(fd, "TX time today ...................................: %02d:%02d:%02d.%d\n",
+                       ast_cli(a->fd, "TX time today ...................................: %02d:%02d:%02d.%d\n",
                                hours, minutes, seconds, dailytxtime);
 
                        hours = (int) totaltxtime / 3600000;
@@ -1314,57 +1306,69 @@ static int rpt_do_stats(int fd, int argc, char *argv[])
                        seconds = (int)  totaltxtime / 1000;
                        totaltxtime %= 1000;
 
-                       ast_cli(fd, "TX time since system initialization..............: %02d:%02d:%02d.%d\n",
+                       ast_cli(a->fd, "TX time since system initialization..............: %02d:%02d:%02d.%d\n",
                                 hours, minutes, seconds, (int) totaltxtime);
-                       ast_cli(fd, "Nodes currently connected to us..................: ");
+                       ast_cli(a->fd, "Nodes currently connected to us..................: ");
                        for (j = 0;; j++) {
                                if (!listoflinks[j]) {
                                        if (!j) {
-                                               ast_cli(fd, "<NONE>");
+                                               ast_cli(a->fd, "<NONE>");
                                        }
                                        break;
                                }
-                               ast_cli(fd, "%s", listoflinks[j]);
+                               ast_cli(a->fd, "%s", listoflinks[j]);
                                if (j % 4 == 3) {
-                                       ast_cli(fd, "\n");
-                                       ast_cli(fd, "                                                 : ");
+                                       ast_cli(a->fd, "\n");
+                                       ast_cli(a->fd, "                                                 : ");
                                } else {
                                        if (listoflinks[j + 1])
-                                               ast_cli(fd, ", ");
+                                               ast_cli(a->fd, ", ");
                                }
                        }
-                       ast_cli(fd, "\n");
+                       ast_cli(a->fd, "\n");
 
-                       ast_cli(fd, "Last node which transmitted to us................: %s\n", lastnodewhichkeyedusup);
-                       ast_cli(fd, "Autopatch state..................................: %s\n", patch_state);
-                       ast_cli(fd, "Autopatch called number..........................: %s\n", called_number);
-                       ast_cli(fd, "Reverse patch/IAXRPT connected...................: %s\n\n", reverse_patch_state);
+                       ast_cli(a->fd, "Last node which transmitted to us................: %s\n", lastnodewhichkeyedusup);
+                       ast_cli(a->fd, "Autopatch state..................................: %s\n", patch_state);
+                       ast_cli(a->fd, "Autopatch called number..........................: %s\n", called_number);
+                       ast_cli(a->fd, "Reverse patch/IAXRPT connected...................: %s\n\n", reverse_patch_state);
 
-                       return RESULT_SUCCESS;
+                       return CLI_SUCCESS;
                }
        }
-       return RESULT_FAILURE;
+       return CLI_FAILURE;
 }
 
 /*
 * Link stats function
 */
-static int rpt_do_lstats(int fd, int argc, char *argv[])
+static char *handle_cli_rpt_lstats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        int i, j;
        struct rpt *myrpt;
        struct rpt_link *l;
        struct rpt_lstat *s, *t;
        struct rpt_lstat s_head;
-       if (argc != 3)
-               return RESULT_SHOWUSAGE;
+
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "rpt lstats";
+               e->usage =
+                       "Usage: rpt lstats <nodename>\n"
+                       "       Dumps link statistics to console\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
+       if (a->argc != 3)
+               return CLI_SHOWUSAGE;
 
        s = NULL;
        s_head.next = &s_head;
        s_head.prev = &s_head;
 
        for (i = 0; i < nrpts; i++) {
-               if (!strcmp(argv[2], rpt_vars[i].name)) {
+               if (!strcmp(a->argv[2], rpt_vars[i].name)) {
                        /* Make a copy of all stat variables while locked */
                        myrpt = &rpt_vars[i];
                        rpt_mutex_lock(&myrpt->lock); /* LOCK */
@@ -1379,7 +1383,7 @@ static int rpt_do_lstats(int fd, int argc, char *argv[])
                                if ((s = ast_calloc(1, sizeof(*s))) == NULL) {
                                        ast_log(LOG_ERROR, "Malloc failed in rpt_do_lstats\n");
                                        rpt_mutex_unlock(&myrpt->lock); /* UNLOCK */
-                                       return RESULT_FAILURE;
+                                       return CLI_FAILURE;
                                }
                                ast_copy_string(s->name, l->name, MAXREMSTR);
                                pbx_substitute_variables_helper(l->chan, "${IAXPEER(CURRENTCHANNEL)}", s->peer, MAXPEERSTR - 1);
@@ -1391,8 +1395,8 @@ static int rpt_do_lstats(int fd, int argc, char *argv[])
                                l = l->next;
                        }
                        rpt_mutex_unlock(&myrpt->lock); /* UNLOCK */
-                       ast_cli(fd, "NODE      PEER                RECONNECTS  DIRECTION  CONNECT TIME\n");
-                       ast_cli(fd, "----      ----                ----------  ---------  ------------\n");
+                       ast_cli(a->fd, "NODE      PEER                RECONNECTS  DIRECTION  CONNECT TIME\n");
+                       ast_cli(a->fd, "----      ----                ----------  ---------  ------------\n");
 
                        for (s = s_head.next; s != &s_head; s = s->next) {
                                int hours, minutes, seconds;
@@ -1406,7 +1410,7 @@ static int rpt_do_lstats(int fd, int argc, char *argv[])
                                connecttime %= 1000;
                                snprintf(conntime, sizeof(conntime), "%02d:%02d:%02d.%d",
                                        hours, minutes, seconds, (int) connecttime);
-                               ast_cli(fd, "%-10s%-20s%-12d%-11s%-30s\n",
+                               ast_cli(a->fd, "%-10s%-20s%-12d%-11s%-30s\n",
                                        s->name, s->peer, s->reconnects, (s->outbound)? "OUT":"IN", conntime);
                        }       
                        /* destroy our local link queue */
@@ -1417,42 +1421,65 @@ static int rpt_do_lstats(int fd, int argc, char *argv[])
                                remque((struct qelem *)t);
                                ast_free(t);
                        }                       
-                       return RESULT_SUCCESS;
+                       return CLI_SUCCESS;
                }
        }
-       return RESULT_FAILURE;
+
+       return CLI_FAILURE;
 }
 
 /*
 * reload vars 
 */
-static int rpt_do_reload(int fd, int argc, char *argv[])
+static char *handle_cli_rpt_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        int     n;
 
-       if (argc > 2)
-               return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "rpt reload";
+               e->usage =
+                       "Usage: rpt reload\n"
+                       "       Reloads app_rpt running config parameters\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
+       if (a->argc > 2)
+               return CLI_SHOWUSAGE;
 
        for (n = 0; n < nrpts; n++)
                rpt_vars[n].reload = 1;
 
-       return RESULT_FAILURE;
+       return CLI_SUCCESS;
 }
 
 /*
 * restart app_rpt
 */
-static int rpt_do_restart(int fd, int argc, char *argv[])
+static char *handle_cli_rpt_restart(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        int     i;
 
-       if (argc > 2)
-               return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "rpt restart";
+               e->usage =
+                       "Usage: rpt restart\n"
+                       "       Restarts app_rpt\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
+       if (a->argc > 2)
+               return CLI_SHOWUSAGE;
        for (i = 0; i < nrpts; i++) {
                if (rpt_vars[i].rxchannel)
                        ast_softhangup(rpt_vars[i].rxchannel, AST_SOFTHANGUP_DEV);
        }
-       return RESULT_FAILURE;
+       return CLI_SUCCESS;
 }
 
 static int play_tone_pair(struct ast_channel *chan, int f1, int f2, int duration, int amplitude)
@@ -4627,7 +4654,7 @@ static int function_remote(struct rpt *myrpt, char *param, char *digitbuf, int c
        char multimode = 0;
        char oc;
        char tmp[20], freq[20] = "", savestr[20] = "";
-       int mhz, decimals;
+       int mhz = 0, decimals = 0;
        struct ast_channel *mychannel;
        AST_DECLARE_APP_ARGS(args1,
                AST_APP_ARG(freq);
@@ -6800,7 +6827,7 @@ static int rpt_exec(struct ast_channel *chan, void *data)
 {
        int res = -1, i, rem_totx, n, phone_mode = 0;
        char *tmp, keyed = 0;
-       char *options, *tele, c;
+       char *options = NULL, *tele, c;
        struct rpt *myrpt;
        struct ast_frame *f;
        struct ast_channel *who;
index a67df2c..be3a346 100644 (file)
@@ -191,8 +191,8 @@ static int gtalk_indicate(struct ast_channel *ast, int condition, const void *da
 static int gtalk_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
 static int gtalk_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen);
 static struct gtalk_pvt *gtalk_alloc(struct gtalk *client, const char *us, const char *them, const char *sid);
-static int gtalk_do_reload(int fd, int argc, char **argv);
-static int gtalk_show_channels(int fd, int argc, char **argv);
+static char *gtalk_do_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
+static char *gtalk_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
 /*----- RTP interface functions */
 static int gtalk_set_rtp_peer(struct ast_channel *chan, struct ast_rtp *rtp,
                                                           struct ast_rtp *vrtp, struct ast_rtp *trtp, int codecs, int nat_active);
@@ -226,7 +226,6 @@ static struct sched_context *sched; /*!< The scheduling context */
 static struct io_context *io;  /*!< The IO context */
 static struct in_addr __ourip;
 
-
 /*! \brief RTP driver interface */
 static struct ast_rtp_protocol gtalk_rtp = {
        type: "Gtalk",
@@ -235,21 +234,10 @@ static struct ast_rtp_protocol gtalk_rtp = {
        get_codec: gtalk_get_codec,
 };
 
-static const char debug_usage[] = 
-"Usage: gtalk show channels\n" 
-"       Shows current state of the Gtalk channels.\n";
-
-static const char reload_usage[] = 
-"Usage: gtalk reload\n" 
-"       Reload gtalk channel driver.\n";
-
-
 static struct ast_cli_entry gtalk_cli[] = {
-       {{ "gtalk", "reload", NULL}, gtalk_do_reload, "Enable Jabber debugging", reload_usage },
-       {{ "gtalk", "show", "channels", NULL}, gtalk_show_channels, "Show GoogleTalk Channels", debug_usage },
- };
-
-
+       NEW_CLI(gtalk_do_reload, "Enable Jabber debugging"),
+       NEW_CLI(gtalk_show_channels, "Show GoogleTalk Channels"),
+};
 
 static char externip[16];
 
@@ -265,7 +253,7 @@ static struct gtalk *find_gtalk(char *name, char *connection)
        struct gtalk *gtalk = NULL;
        char *domain = NULL , *s = NULL;
 
-       if(strchr(connection, '@')) {
+       if (strchr(connection, '@')) {
                s = ast_strdupa(connection);
                domain = strsep(&s, "@");
                ast_verbose("OOOOH domain = %s\n", domain);
@@ -1581,7 +1569,7 @@ static struct ast_channel *gtalk_request(const char *type, int format, void *dat
 }
 
 /*! \brief CLI command "gtalk show channels" */
-static int gtalk_show_channels(int fd, int argc, char **argv)
+static char *gtalk_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 #define FORMAT  "%-30.30s  %-30.30s  %-15.15s  %-5.5s %-5.5s \n"
        struct gtalk_pvt *p;
@@ -1591,11 +1579,22 @@ static int gtalk_show_channels(int fd, int argc, char **argv)
        char *jid = NULL;
        char *resource = NULL;
 
-       if (argc != 3)
-               return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "gtalk show channels";
+               e->usage =
+                       "Usage: gtalk show channels\n"
+                       "       Shows current state of the Gtalk channels.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
+       if (a->argc != 3)
+               return CLI_SHOWUSAGE;
 
        ast_mutex_lock(&gtalklock);
-       ast_cli(fd, FORMAT, "Channel", "Jabber ID", "Resource", "Read", "Write");
+       ast_cli(a->fd, FORMAT, "Channel", "Jabber ID", "Resource", "Read", "Write");
        ASTOBJ_CONTAINER_TRAVERSE(&gtalk_list, 1, {
                ASTOBJ_WRLOCK(iterator);
                p = iterator->p;
@@ -1611,7 +1610,7 @@ static int gtalk_show_channels(int fd, int argc, char **argv)
                                resource ++;
                        }
                        if (chan)
-                               ast_cli(fd, FORMAT, 
+                               ast_cli(a->fd, FORMAT, 
                                        chan->name,
                                        jid,
                                        resource,
@@ -1628,16 +1627,27 @@ static int gtalk_show_channels(int fd, int argc, char **argv)
 
        ast_mutex_unlock(&gtalklock);
 
-       ast_cli(fd, "%d active gtalk channel%s\n", numchans, (numchans != 1) ? "s" : "");
-       return RESULT_SUCCESS;
+       ast_cli(a->fd, "%d active gtalk channel%s\n", numchans, (numchans != 1) ? "s" : "");
+       return CLI_SUCCESS;
 #undef FORMAT
 }
 
-/*! \brief CLI command "gtalk show channels" */
-static int gtalk_do_reload(int fd, int argc, char **argv)
+/*! \brief CLI command "gtalk reload" */
+static char *gtalk_do_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "gtalk reload";
+               e->usage =
+                       "Usage: gtalk reload\n"
+                       "       Reload gtalk channel driver.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }       
+       
        ast_verbose("IT DOES WORK!\n");
-       return RESULT_SUCCESS;
+       return CLI_SUCCESS;
 }
 
 static int gtalk_parser(void *data, ikspak *pak)
index 7693397..a509dea 100644 (file)
@@ -422,7 +422,7 @@ static void start_rtp(struct mgcp_subchannel *sub);
 static void handle_response(struct mgcp_endpoint *p, struct mgcp_subchannel *sub,  
                             int result, unsigned int ident, struct mgcp_request *resp);
 static void dump_cmd_queues(struct mgcp_endpoint *p, struct mgcp_subchannel *sub);
-static int mgcp_reload(int fd, int argc, char *argv[]);
+static char *mgcp_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
 static int reload_config(int reload);
 
 static struct ast_channel *mgcp_request(const char *type, int format, void *data, int *cause);
@@ -1041,71 +1041,72 @@ static int mgcp_hangup(struct ast_channel *ast)
        return 0;
 }
 
-static int mgcp_show_endpoints(int fd, int argc, char *argv[])
+static char *handle_mgcp_show_endpoints(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-       struct mgcp_gateway  *g;
-       struct mgcp_endpoint *e;
+       struct mgcp_gateway  *mg;
+       struct mgcp_endpoint *me;
        int hasendpoints = 0;
 
-       if (argc != 3) 
-               return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "mgcp show endpoints";
+               e->usage =
+                       "Usage: mgcp show endpoints\n"
+                       "       Lists all endpoints known to the MGCP (Media Gateway Control Protocol) subsystem.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
+       if (a->argc != 3) 
+               return CLI_SHOWUSAGE;
        ast_mutex_lock(&gatelock);
-       g = gateways;
-       while(g) {
-               e = g->endpoints;
-               ast_cli(fd, "Gateway '%s' at %s (%s)\n", g->name, g->addr.sin_addr.s_addr ? ast_inet_ntoa(g->addr.sin_addr) : ast_inet_ntoa(g->defaddr.sin_addr), g->dynamic ? "Dynamic" : "Static");
-               while(e) {
+       mg = gateways;
+       while(mg) {
+               me = mg->endpoints;
+               ast_cli(a->fd, "Gateway '%s' at %s (%s)\n", mg->name, mg->addr.sin_addr.s_addr ? ast_inet_ntoa(mg->addr.sin_addr) : ast_inet_ntoa(mg->defaddr.sin_addr), mg->dynamic ? "Dynamic" : "Static");
+               while(me) {
                        /* Don't show wilcard endpoint */
-                       if (strcmp(e->name, g->wcardep) !=0)
-                               ast_cli(fd, "   -- '%s@%s in '%s' is %s\n", e->name, g->name, e->context, e->sub->owner ? "active" : "idle");
+                       if (strcmp(me->name, mg->wcardep) != 0)
+                               ast_cli(a->fd, "   -- '%s@%s in '%s' is %s\n", me->name, mg->name, me->context, me->sub->owner ? "active" : "idle");
                        hasendpoints = 1;
-                       e = e->next;
+                       me = me->next;
                }
                if (!hasendpoints) {
-                       ast_cli(fd, "   << No Endpoints Defined >>     ");
+                       ast_cli(a->fd, "   << No Endpoints Defined >>     ");
                }
-               g = g->next;
+               mg = mg->next;
        }
        ast_mutex_unlock(&gatelock);
-       return RESULT_SUCCESS;
+       return CLI_SUCCESS;
 }
 
-static const char show_endpoints_usage[] = 
-"Usage: mgcp show endpoints\n"
-"       Lists all endpoints known to the MGCP (Media Gateway Control Protocol) subsystem.\n";
-
-static const char audit_endpoint_usage[] = 
-"Usage: mgcp audit endpoint <endpointid>\n"
-"       Lists the capabilities of an endpoint in the MGCP (Media Gateway Control Protocol) subsystem.\n"
-"       mgcp debug MUST be on to see the results of this command.\n";
-
-static const char debug_usage[] = 
-"Usage: mgcp set debug\n"
-"       Enables dumping of MGCP packets for debugging purposes\n";
-
-static const char no_debug_usage[] = 
-"Usage: mgcp set debug off\n"
-"       Disables dumping of MGCP packets for debugging purposes\n";
-
-static const char mgcp_reload_usage[] =
-"Usage: mgcp reload\n"
-"       Reloads MGCP configuration from mgcp.conf\n"
-"       Deprecated:  please use 'reload chan_mgcp.so' instead.\n";
-
-static int mgcp_audit_endpoint(int fd, int argc, char *argv[])
+static char *handle_mgcp_audit_endpoint(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-       struct mgcp_gateway  *g;
-       struct mgcp_endpoint *e;
+       struct mgcp_gateway  *mg;
+       struct mgcp_endpoint *me;
        int found = 0;
        char *ename,*gname, *c;
 
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "mgcp audit endpoint";
+               e->usage =
+                       "Usage: mgcp audit endpoint <endpointid>\n"
+                       "       Lists the capabilities of an endpoint in the MGCP (Media Gateway Control Protocol) subsystem.\n"
+                       "       mgcp debug MUST be on to see the results of this command.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
        if (!mgcpdebug) {
-               return RESULT_SHOWUSAGE;
+               return CLI_SHOWUSAGE;
        }
-       if (argc != 4) 
-               return RESULT_SHOWUSAGE;
+       if (a->argc != 4)
+               return CLI_SHOWUSAGE;
        /* split the name into parts by null */
-       ename = argv[3];
+       ename = a->argv[3];
        gname = ename;
        while (*gname) {
                if (*gname == '@') {
@@ -1120,69 +1121,77 @@ static int mgcp_audit_endpoint(int fd, int argc, char *argv[])
        if ((c = strrchr(gname, ']')))
                *c = '\0';
        ast_mutex_lock(&gatelock);
-       g = gateways;
-       while(g) {
-               if (!strcasecmp(g->name, gname)) {
-                       e = g->endpoints;
-                       while(e) {
-                               if (!strcasecmp(e->name, ename)) {
+       mg = gateways;
+       while(mg) {
+               if (!strcasecmp(mg->name, gname)) {
+                       me = mg->endpoints;
+                       while(me) {
+                               if (!strcasecmp(me->name, ename)) {
                                        found = 1;
-                                       transmit_audit_endpoint(e);
+                                       transmit_audit_endpoint(me);
                                        break;
                                }
-                               e = e->next;
+                               me = me->next;
                        }
                        if (found) {
                                break;
                        }
                }
-               g = g->next;
+               mg = mg->next;
        }
        if (!found) {
-               ast_cli(fd, "   << Could not find endpoint >>     ");
+               ast_cli(a->fd, "   << Could not find endpoint >>     ");
        }
        ast_mutex_unlock(&gatelock);
-       return RESULT_SUCCESS;
+       return CLI_SUCCESS;
 }
 
-static int mgcp_do_debug(int fd, int argc, char *argv[])
+static char *handle_mgcp_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-       if (argc != 3)
-               return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "mgcp set debug";
+               e->usage =
+                       "Usage: mgcp set debug\n"
+                       "       Enables dumping of MGCP packets for debugging purposes\n";      
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
+       if (a->argc != 3)
+               return CLI_SHOWUSAGE;
        mgcpdebug = 1;
-       ast_cli(fd, "MGCP Debugging Enabled\n");
-       return RESULT_SUCCESS;
+       ast_cli(a->fd, "MGCP Debugging Enabled\n");
+       return CLI_SUCCESS;
 }
 
-static int mgcp_no_debug(int fd, int argc, char *argv[])
+static char *handle_mgcp_set_debug_off(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-       if (argc != 4)
-               return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "mgcp set debug off";
+               e->usage =
+                       "Usage: mgcp set debug off\n"
+                       "       Disables dumping of MGCP packets for debugging purposes\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
+       if (a->argc != 4)
+               return CLI_SHOWUSAGE;
        mgcpdebug = 0;
-       ast_cli(fd, "MGCP Debugging Disabled\n");
-       return RESULT_SUCCESS;
+       ast_cli(a->fd, "MGCP Debugging Disabled\n");
+       return CLI_SUCCESS;
 }
 
 static struct ast_cli_entry cli_mgcp[] = {
-       { { "mgcp", "audit", "endpoint", NULL },
-       mgcp_audit_endpoint, "Audit specified MGCP endpoint",
-       audit_endpoint_usage },
-
-       { { "mgcp", "show", "endpoints", NULL },
-       mgcp_show_endpoints, "List defined MGCP endpoints",
-       show_endpoints_usage },
-
-       { { "mgcp", "set", "debug", NULL },
-       mgcp_do_debug, "Enable MGCP debugging",
-       debug_usage },
-
-       { { "mgcp", "set", "debug", "off", NULL },
-       mgcp_no_debug, "Disable MGCP debugging",
-       no_debug_usage },
-
-       { { "mgcp", "reload", NULL },
-       mgcp_reload, "Reload MGCP configuration",
-       mgcp_reload_usage },
+       NEW_CLI(handle_mgcp_audit_endpoint, "Audit specified MGCP endpoint"),
+       NEW_CLI(handle_mgcp_show_endpoints, "List defined MGCP endpoints"),
+       NEW_CLI(handle_mgcp_set_debug, "Enable MGCP debugging"),
+       NEW_CLI(handle_mgcp_set_debug_off, "Disable MGCP debugging"),
+       NEW_CLI(mgcp_reload, "Reload MGCP configuration"),
 };
 
 static int mgcp_answer(struct ast_channel *ast)
@@ -4242,10 +4251,24 @@ static int load_module(void)
        return AST_MODULE_LOAD_SUCCESS;
 }
 
-static int mgcp_reload(int fd, int argc, char *argv[])
+static char *mgcp_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        static int deprecated = 0;
-       if (!deprecated && argc > 0) {
+
+       if (e) {
+               switch (cmd) {
+               case CLI_INIT:
+                       e->command = "mgcp reload";
+                       e->usage =
+                               "Usage: mgcp reload\n"
+                               "       'mgcp reload' is deprecated.  Please use 'reload chan_mgcp.so' instead.\n";
+                       return NULL;
+               case CLI_GENERATE:
+                       return NULL;
+               }
+       }
+
+       if (!deprecated && a && a->argc > 0) {
                ast_log(LOG_WARNING, "'mgcp reload' is deprecated.  Please use 'reload chan_mgcp.so' instead.\n");
                deprecated = 1;
        }
@@ -4257,12 +4280,12 @@ static int mgcp_reload(int fd, int argc, char *argv[])
                mgcp_reloading = 1;
        ast_mutex_unlock(&mgcp_reload_lock);
        restart_monitor();
-       return 0;
+       return CLI_SUCCESS;
 }
 
 static int reload(void)
 {
-       mgcp_reload(0, 0, NULL);
+       mgcp_reload(NULL, 0, NULL);
        return 0;
 }
 
@@ -4297,7 +4320,7 @@ static int unload_module(void)
                /* We always want to leave this in a consistent state */
                ast_channel_register(&mgcp_tech);
                mgcp_reloading = 0;
-               mgcp_reload(0, 0, NULL);
+               mgcp_reload(NULL, 0, NULL);
                return -1;
        }
 
@@ -4317,7 +4340,7 @@ static int unload_module(void)
                /* Allow the monitor to restart */
                monitor_thread = AST_PTHREADT_NULL;
                mgcp_reloading = 0;
-               mgcp_reload(0, 0, NULL);
+               mgcp_reload(NULL, 0, NULL);
                return -1;
        }
 
index 42e0546..cea7984 100644 (file)
@@ -1333,69 +1333,83 @@ static char *console_mute(struct ast_cli_entry *e, int cmd, struct ast_cli_args
        return CLI_SUCCESS;
 }
 
-static int console_transfer(int fd, int argc, char *argv[])
+static char *console_transfer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        struct chan_oss_pvt *o = find_desc(oss_active);
        struct ast_channel *b = NULL;
        char *tmp, *ext, *ctx;
 
-       if (argc != 3)
-               return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "console transfer";
+               e->usage =
+                       "Usage: console transfer <extension>[@context]\n"
+                       "       Transfers the currently connected call to the given extension (and\n"
+                       "       context if specified)\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
+       if (a->argc != 3)
+               return CLI_SHOWUSAGE;
        if (o == NULL)
-               return RESULT_FAILURE;
+               return CLI_FAILURE;
        if (o->owner == NULL || (b = ast_bridged_channel(o->owner)) == NULL) {
-               ast_cli(fd, "There is no call to transfer\n");
-               return RESULT_SUCCESS;
+               ast_cli(a->fd, "There is no call to transfer\n");
+               return CLI_SUCCESS;
        }
 
-       tmp = ast_ext_ctx(argv[2], &ext, &ctx);
+       tmp = ast_ext_ctx(a->argv[2], &ext, &ctx);
        if (ctx == NULL)                        /* supply default context if needed */
                ctx = o->owner->context;
        if (!ast_exists_extension(b, ctx, ext, 1, b->cid.cid_num))
-               ast_cli(fd, "No such extension exists\n");
+               ast_cli(a->fd, "No such extension exists\n");
        else {
-               ast_cli(fd, "Whee, transferring %s to %s@%s.\n", b->name, ext, ctx);
+               ast_cli(a->fd, "Whee, transferring %s to %s@%s.\n", b->name, ext, ctx);
                if (ast_async_goto(b, ctx, ext, 1))
-                       ast_cli(fd, "Failed to transfer :(\n");
+                       ast_cli(a->fd, "Failed to transfer :(\n");
        }
        if (tmp)
                ast_free(tmp);
-       return RESULT_SUCCESS;
+       return CLI_SUCCESS;
 }
 
-static const char transfer_usage[] =
-       "Usage: console transfer <extension>[@context]\n"
-       "       Transfers the currently connected call to the given extension (and\n"
-       "context if specified)\n";
-
-static int console_active(int fd, int argc, char *argv[])
+static char *console_active(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-       if (argc == 2)
-               ast_cli(fd, "active console is [%s]\n", oss_active);
-       else if (argc != 3)
-               return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "console active";
+               e->usage =
+                       "Usage: console active [device]\n"
+                       "       If used without a parameter, displays which device is the current\n"
+                       "       console.  If a device is specified, the console sound device is changed to\n"
+                       "       the device specified.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
+       if (a->argc == 2)
+               ast_cli(a->fd, "active console is [%s]\n", oss_active);
+       else if (a->argc != 3)
+               return CLI_SHOWUSAGE;
        else {
                struct chan_oss_pvt *o;
-               if (strcmp(argv[2], "show") == 0) {
+               if (strcmp(a->argv[2], "show") == 0) {
                        for (o = oss_default.next; o; o = o->next)
-                               ast_cli(fd, "device [%s] exists\n", o->name);
-                       return RESULT_SUCCESS;
+                               ast_cli(a->fd, "device [%s] exists\n", o->name);
+                       return CLI_SUCCESS;
                }
-               o = find_desc(argv[2]);
+               o = find_desc(a->argv[2]);
                if (o == NULL)
-                       ast_cli(fd, "No device [%s] exists\n", argv[2]);
+                       ast_cli(a->fd, "No device [%s] exists\n", a->argv[2]);
                else
                        oss_active = o->name;
        }
-       return RESULT_SUCCESS;
+       return CLI_SUCCESS;
 }
 
-static const char active_usage[] =
-       "Usage: console active [device]\n"
-       "       If used without a parameter, displays which device is the current\n"
-       "console.  If a device is specified, the console sound device is changed to\n"
-       "the device specified.\n";
-
 /*!
  * \brief store the boost factor
  */
@@ -1418,15 +1432,26 @@ static void store_boost(struct chan_oss_pvt *o, char *s)
        ast_log(LOG_WARNING, "setting boost %s to %d\n", s, o->boost);
 }
 
-static int do_boost(int fd, int argc, char *argv[])
+static char *console_boost(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        struct chan_oss_pvt *o = find_desc(oss_active);
 
-       if (argc == 2)
-               ast_cli(fd, "boost currently %5.1f\n", 20 * log10(((double) o->boost / (double) BOOST_SCALE)));
-       else if (argc == 3)
-               store_boost(o, argv[2]);
-       return RESULT_SUCCESS;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "console boost";
+               e->usage =
+                       "Usage: console boost [boost in dB]\n"
+                       "       Sets or display mic boost in dB\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
+       if (a->argc == 2)
+               ast_cli(a->fd, "boost currently %5.1f\n", 20 * log10(((double) o->boost / (double) BOOST_SCALE)));
+       else if (a->argc == 3)
+               store_boost(o, a->argv[2]);
+       return CLI_SUCCESS;
 }
 
 static struct ast_cli_entry cli_oss[] = {
@@ -1435,20 +1460,11 @@ static struct ast_cli_entry cli_oss[] = {
        NEW_CLI(console_flash, "Flash a call on the console"),
        NEW_CLI(console_dial, "Dial an extension on the console"),
        NEW_CLI(console_mute, "Disable/Enable mic input"),
-       { { "console", "transfer", NULL },
-       console_transfer, "Transfer a call to a different extension",
-       transfer_usage },
-
+       NEW_CLI(console_transfer, "Transfer a call to a different extension"),  
        NEW_CLI(console_sendtext, "Send text to the remote device"),
        NEW_CLI(console_autoanswer, "Sets/displays autoanswer"),
-
-       { { "console", "boost", NULL },
-       do_boost, "Sets/displays mic boost in dB",
-       NULL },
-
-       { { "console", "active", NULL },
-       console_active, "Sets/displays active console",
-       active_usage },
+       NEW_CLI(console_boost, "Sets/displays mic boost in dB"),
+       NEW_CLI(console_active, "Sets/displays active console"),
 };
 
 /*!
index b1a83ab..0e58689 100644 (file)
@@ -2262,24 +2262,46 @@ static struct ast_rtp_protocol skinny_rtp = {
        .set_rtp_peer = skinny_set_rtp_peer,
 };
 
-static int skinny_do_debug(int fd, int argc, char *argv[])
+static char *handle_skinny_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-       if (argc != 3)
-               return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "skinny set debug";
+               e->usage =
+                       "Usage: skinny set debug\n"
+                       "       Enables dumping of Skinny packets for debugging purposes\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+       
+       if (a->argc != 3)
+               return CLI_SHOWUSAGE;
 
        skinnydebug = 1;
-       ast_cli(fd, "Skinny Debugging Enabled\n");
-       return RESULT_SUCCESS;
+       ast_cli(a->fd, "Skinny Debugging Enabled\n");
+       return CLI_SUCCESS;
 }
 
-static int skinny_no_debug(int fd, int argc, char *argv[])
+static char *handle_skinny_set_debug_off(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-       if (argc != 4)
-               return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "skinny set debug off";
+               e->usage =
+                       "Usage: skinny set debug off\n"
+                       "       Disables dumping of Skinny packets for debugging purposes\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
+       if (a->argc != 4)
+               return CLI_SHOWUSAGE;
 
        skinnydebug = 0;
-       ast_cli(fd, "Skinny Debugging Disabled\n");
-       return RESULT_SUCCESS;
+       ast_cli(a->fd, "Skinny Debugging Disabled\n");
+       return CLI_SUCCESS;
 }
 
 static char *complete_skinny_devices(const char *word, int state)
@@ -2306,7 +2328,7 @@ static char *complete_skinny_reset(const char *line, const char *word, int pos,
        return (pos == 2 ? ast_strdup(complete_skinny_devices(word, state)) : NULL);
 }
 
-static char *complete_skinny_show_lines(const char *line, const char *word, int pos, int state)
+static char *complete_skinny_show_line(const char *line, const char *word, int pos, int state)
 {
        struct skinny_device *d;
        struct skinny_line *l;
@@ -2326,26 +2348,37 @@ static char *complete_skinny_show_lines(const char *line, const char *word, int
        return result;
 }
 
-static int skinny_reset_device(int fd, int argc, char *argv[])
+static char *handle_skinny_reset(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        struct skinny_device *d;
        struct skinny_req *req;
 
-       if (argc < 3 || argc > 4)
-               return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "skinny reset";
+               e->usage =
+                       "Usage: skinny reset <DeviceId|DeviceName|all> [restart]\n"
+                       "       Causes a Skinny device to reset itself, optionally with a full restart\n";
+               return NULL;
+       case CLI_GENERATE:
+               return complete_skinny_reset(a->line, a->word, a->pos, a->n);
+       }
+
+       if (a->argc < 3 || a->argc > 4)
+               return CLI_SHOWUSAGE;
 
        ast_mutex_lock(&devicelock);
 
        for (d = devices; d; d = d->next) {
                int fullrestart = 0;
-               if (!strcasecmp(argv[2], d->id) || !strcasecmp(argv[2], d->name) || !strcasecmp(argv[2], "all")) {
+               if (!strcasecmp(a->argv[2], d->id) || !strcasecmp(a->argv[2], d->name) || !strcasecmp(a->argv[2], "all")) {
                        if (!(d->session))
                                continue;
 
                        if (!(req = req_alloc(sizeof(struct reset_message), RESET_MESSAGE)))
                                continue;
 
-                       if (argc == 4 && !strcasecmp(argv[3], "restart"))
+                       if (a->argc == 4 && !strcasecmp(a->argv[3], "restart"))
                                fullrestart = 1;
 
                        if (fullrestart)
@@ -2358,7 +2391,7 @@ static int skinny_reset_device(int fd, int argc, char *argv[])
                }
        }
        ast_mutex_unlock(&devicelock);
-       return RESULT_SUCCESS;
+       return CLI_SUCCESS;
 }
 
 static char *device2str(int type)
@@ -2450,18 +2483,29 @@ static void print_codec_to_cli(int fd, struct ast_codec_pref *pref)
                ast_cli(fd, "none");
 }
 
-static int skinny_show_devices(int fd, int argc, char *argv[])
+static char *handle_skinny_show_devices(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        struct skinny_device *d;
        struct skinny_line *l;
 
-       if (argc != 3)
-               return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "skinny show devices";
+               e->usage =
+                       "Usage: skinny show devices\n"
+                       "       Lists all devices known to the Skinny subsystem.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
+       if (a->argc != 3)
+               return CLI_SHOWUSAGE;
 
        ast_mutex_lock(&devicelock);
 
-       ast_cli(fd, "Name                 DeviceId         IP              Type            R NL\n");
-       ast_cli(fd, "-------------------- ---------------- --------------- --------------- - --\n");
+       ast_cli(a->fd, "Name                 DeviceId         IP              Type            R NL\n");
+       ast_cli(a->fd, "-------------------- ---------------- --------------- --------------- - --\n");
 
        for (d = devices; d; d = d->next) {
                int numlines = 0;
@@ -2469,7 +2513,7 @@ static int skinny_show_devices(int fd, int argc, char *argv[])
                for (l = d->lines; l; l = l->next)
                        numlines++;
                
-               ast_cli(fd, "%-20s %-16s %-15s %-15s %c %2d\n",
+               ast_cli(a->fd, "%-20s %-16s %-15s %-15s %c %2d\n",
                        d->name,
                        d->id,
                        d->session?ast_inet_ntoa(d->session->sin.sin_addr):"",
@@ -2480,69 +2524,91 @@ static int skinny_show_devices(int fd, int argc, char *argv[])
 
        ast_mutex_unlock(&devicelock);
 
-       return RESULT_SUCCESS;
+       return CLI_SUCCESS;
 }
 
 /*! \brief Show device information */
-static int skinny_show_device(int fd, int argc, char *argv[])
+static char *handle_skinny_show_device(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        struct skinny_device *d;
        struct skinny_line *l;
        struct skinny_speeddial *sd;
-       struct skinny_addon *a;
+       struct skinny_addon *sa;
+
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "skinny show device";
+               e->usage =
+                       "Usage: skinny show device <DeviceId|DeviceName>\n"
+                       "       Lists all deviceinformation of a specific device known to the Skinny subsystem.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return complete_skinny_show_device(a->line, a->word, a->pos, a->n);
+       }
 
-       if (argc < 4)
-               return RESULT_SHOWUSAGE;
+       if (a->argc < 4)
+               return CLI_SHOWUSAGE;
 
        ast_mutex_lock(&devicelock);
        for (d = devices; d; d = d->next) {
-               if (!strcasecmp(argv[3], d->id) || !strcasecmp(argv[3], d->name)) {
+               if (!strcasecmp(a->argv[3], d->id) || !strcasecmp(a->argv[3], d->name)) {
                        int numlines = 0, numaddons = 0, numspeeddials = 0;
 
                        for (l = d->lines; l; l = l->next)
                                numlines++;
 
-                       ast_cli(fd, "Name:        %s\n", d->name);
-                       ast_cli(fd, "Id:          %s\n", d->id);
-                       ast_cli(fd, "version:     %s\n", S_OR(d->version_id, "Unknown"));
-                       ast_cli(fd, "Ip address:  %s\n", (d->session ? ast_inet_ntoa(d->session->sin.sin_addr) : "Unknown"));
-                       ast_cli(fd, "Port:        %d\n", (d->session ? ntohs(d->session->sin.sin_port) : 0));
-                       ast_cli(fd, "Device Type: %s\n", device2str(d->type));
-                       ast_cli(fd, "Registered:  %s\n", (d->registered ? "Yes" : "No"));
-                       ast_cli(fd, "Lines:       %d\n", numlines);
+                       ast_cli(a->fd, "Name:        %s\n", d->name);
+                       ast_cli(a->fd, "Id:          %s\n", d->id);
+                       ast_cli(a->fd, "version:     %s\n", S_OR(d->version_id, "Unknown"));
+                       ast_cli(a->fd, "Ip address:  %s\n", (d->session ? ast_inet_ntoa(d->session->sin.sin_addr) : "Unknown"));
+                       ast_cli(a->fd, "Port:        %d\n", (d->session ? ntohs(d->session->sin.sin_port) : 0));
+                       ast_cli(a->fd, "Device Type: %s\n", device2str(d->type));
+                       ast_cli(a->fd, "Registered:  %s\n", (d->registered ? "Yes" : "No"));
+                       ast_cli(a->fd, "Lines:       %d\n", numlines);
                        for (l = d->lines; l; l = l->next)
-                               ast_cli(fd, "  %s (%s)\n", l->name, l->label);
-                       for (a = d->addons; a; a = a->next)
+                               ast_cli(a->fd, "  %s (%s)\n", l->name, l->label);
+                       for (sa = d->addons; sa; sa = sa->next)
                                numaddons++;
-                       ast_cli(fd, "Addons:      %d\n", numaddons);
-                       for (a = d->addons; a; a = a->next)
-                               ast_cli(fd, "  %s\n", a->type);
+                       ast_cli(a->fd, "Addons:      %d\n", numaddons);
+                       for (sa = d->addons; sa; sa = sa->next)
+                               ast_cli(a->fd, "  %s\n", sa->type);
                        for (sd = d->speeddials; sd; sd = sd->next)
                                numspeeddials++;
-                       ast_cli(fd, "Speeddials:  %d\n", numspeeddials);
+                       ast_cli(a->fd, "Speeddials:  %d\n", numspeeddials);
                        for (sd = d->speeddials; sd; sd = sd->next)
-                               ast_cli(fd, "  %s (%s) ishint: %d\n", sd->exten, sd->label, sd->isHint);
+                               ast_cli(a->fd, "  %s (%s) ishint: %d\n", sd->exten, sd->label, sd->isHint);
                }
        }
        ast_mutex_unlock(&devicelock);
-       return RESULT_SUCCESS;
+       return CLI_SUCCESS;
 }
 
-static int skinny_show_lines(int fd, int argc, char *argv[])
+static char *handle_skinny_show_lines(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        struct skinny_device *d;
        struct skinny_line *l;
 
-       if (argc != 3)
-               return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "skinny show lines";
+               e->usage =
+                       "Usage: skinny show lines\n"
+                       "       Lists all lines known to the Skinny subsystem.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
+       if (a->argc != 3)
+               return CLI_SHOWUSAGE;
        
        ast_mutex_lock(&devicelock);
        
-       ast_cli(fd, "Device Name          Instance Name                 Label               \n");
-       ast_cli(fd, "-------------------- -------- -------------------- --------------------\n");
+       ast_cli(a->fd, "Device Name          Instance Name                 Label               \n");
+       ast_cli(a->fd, "-------------------- -------- -------------------- --------------------\n");
        for (d = devices; d; d = d->next) {
                for (l = d->lines; l; l = l->next) {
-                       ast_cli(fd, "%-20s %8d %-20s %-20s\n",
+                       ast_cli(a->fd, "%-20s %8d %-20s %-20s\n",
                                d->name,
                                l->instance,
                                l->name,
@@ -2551,162 +2617,128 @@ static int skinny_show_lines(int fd, int argc, char *argv[])
        }
        
        ast_mutex_unlock(&devicelock);
-       return RESULT_SUCCESS;
+       return CLI_SUCCESS;
 }
 
 /*! \brief List line information. */
-static int skinny_show_line(int fd, int argc, char *argv[])
+static char *handle_skinny_show_line(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        struct skinny_device *d;
        struct skinny_line *l;
-
        char codec_buf[512];
        char group_buf[256];
 
-       if (argc < 4)
-               return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "skinny show line";
+               e->usage =
+                       "Usage: skinny show line <Line> [ on <DeviceID|DeviceName> ]\n"
+                       "       List all lineinformation of a specific line known to the Skinny subsystem.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return complete_skinny_show_line(a->line, a->word, a->pos, a->n);
+       }
+
+       if (a->argc < 4)
+               return CLI_SHOWUSAGE;
        
        ast_mutex_lock(&devicelock);
 
        /* Show all lines matching the one supplied */
        for (d = devices; d; d = d->next) {
-               if (argc == 6 && (strcasecmp(argv[5], d->id) && strcasecmp(argv[5], d->name)))
+               if (a->argc == 6 && (strcasecmp(a->argv[5], d->id) && strcasecmp(a->argv[5], d->name)))
                        continue;
                for (l = d->lines; l; l = l->next) {
-                       if (strcasecmp(argv[3], l->name))
+                       if (strcasecmp(a->argv[3], l->name))
                                continue;
-                       ast_cli(fd, "Line:             %s\n", l->name);
-                       ast_cli(fd, "On Device:        %s\n", d->name);
-                       ast_cli(fd, "Line Label:       %s\n", l->label);
-                       ast_cli(fd, "Extension:        %s\n", S_OR(l->exten, "<not set>"));
-                       ast_cli(fd, "Context:          %s\n", l->context);
-                       ast_cli(fd, "CallGroup:        %s\n", ast_print_group(group_buf, sizeof(group_buf), l->callgroup));
-                       ast_cli(fd, "PickupGroup:      %s\n", ast_print_group(group_buf, sizeof(group_buf), l->pickupgroup));
-                       ast_cli(fd, "Language:         %s\n", S_OR(l->language, "<not set>"));
-                       ast_cli(fd, "Accountcode:      %s\n", S_OR(l->accountcode, "<not set>"));
-                       ast_cli(fd, "AmaFlag:          %s\n", ast_cdr_flags2str(l->amaflags));
-                       ast_cli(fd, "CallerId Number:  %s\n", S_OR(l->cid_num, "<not set>"));
-                       ast_cli(fd, "CallerId Name:    %s\n", S_OR(l->cid_name, "<not set>"));
-                       ast_cli(fd, "Hide CallerId:    %s\n", (l->hidecallerid ? "Yes" : "No"));
-                       ast_cli(fd, "CallForward:      %s\n", S_OR(l->call_forward, "<not set>"));
-                       ast_cli(fd, "VoicemailBox:     %s\n", S_OR(l->mailbox, "<not set>"));
-                       ast_cli(fd, "VoicemailNumber:  %s\n", S_OR(l->vmexten, "<not set>"));
-                       ast_cli(fd, "MWIblink:         %d\n", l->mwiblink);
-                       ast_cli(fd, "Regextension:     %s\n", S_OR(l->regexten, "<not set>"));
-                       ast_cli(fd, "Regcontext:       %s\n", S_OR(l->regcontext, "<not set>"));
-                       ast_cli(fd, "MoHInterpret:     %s\n", S_OR(l->mohinterpret, "<not set>"));
-                       ast_cli(fd, "MoHSuggest:       %s\n", S_OR(l->mohsuggest, "<not set>"));
-                       ast_cli(fd, "Last dialed nr:   %s\n", S_OR(l->lastnumberdialed, "<no calls made yet>"));
-                       ast_cli(fd, "Last CallerID:    %s\n", S_OR(l->lastcallerid, "<not set>"));
-                       ast_cli(fd, "Transfer enabled: %s\n", (l->transfer ? "Yes" : "No"));
-                       ast_cli(fd, "Callwaiting:      %s\n", (l->callwaiting ? "Yes" : "No"));
-                       ast_cli(fd, "3Way Calling:     %s\n", (l->threewaycalling ? "Yes" : "No"));
-                       ast_cli(fd, "Can forward:      %s\n", (l->cancallforward ? "Yes" : "No"));
-                       ast_cli(fd, "Do Not Disturb:   %s\n", (l->dnd ? "Yes" : "No"));
-                       ast_cli(fd, "NAT:              %s\n", (l->nat ? "Yes" : "No"));
-                       ast_cli(fd, "immediate:        %s\n", (l->immediate ? "Yes" : "No"));
-                       ast_cli(fd, "Group:            %d\n", l->group);
-                       ast_cli(fd, "Codecs:           ");
-                       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, l->capability);
-                       ast_cli(fd, "%s\n", codec_buf);
-                       ast_cli(fd, "Codec Order:      (");
-                       print_codec_to_cli(fd, &l->prefs);
-                       ast_cli(fd, ")\n");
-                       ast_cli(fd, "\n");
+                       ast_cli(a->fd, "Line:             %s\n", l->name);
+                       ast_cli(a->fd, "On Device:        %s\n", d->name);
+                       ast_cli(a->fd, "Line Label:       %s\n", l->label);
+                       ast_cli(a->fd, "Extension:        %s\n", S_OR(l->exten, "<not set>"));
+                       ast_cli(a->fd, "Context:          %s\n", l->context);
+                       ast_cli(a->fd, "CallGroup:        %s\n", ast_print_group(group_buf, sizeof(group_buf), l->callgroup));
+                       ast_cli(a->fd, "PickupGroup:      %s\n", ast_print_group(group_buf, sizeof(group_buf), l->pickupgroup));
+                       ast_cli(a->fd, "Language:         %s\n", S_OR(l->language, "<not set>"));
+                       ast_cli(a->fd, "Accountcode:      %s\n", S_OR(l->accountcode, "<not set>"));
+                       ast_cli(a->fd, "AmaFlag:          %s\n", ast_cdr_flags2str(l->amaflags));
+                       ast_cli(a->fd, "CallerId Number:  %s\n", S_OR(l->cid_num, "<not set>"));
+                       ast_cli(a->fd, "CallerId Name:    %s\n", S_OR(l->cid_name, "<not set>"));
+                       ast_cli(a->fd, "Hide CallerId:    %s\n", (l->hidecallerid ? "Yes" : "No"));
+                       ast_cli(a->fd, "CallForward:      %s\n", S_OR(l->call_forward, "<not set>"));
+                       ast_cli(a->fd, "VoicemailBox:     %s\n", S_OR(l->mailbox, "<not set>"));
+                       ast_cli(a->fd, "VoicemailNumber:  %s\n", S_OR(l->vmexten, "<not set>"));
+                       ast_cli(a->fd, "MWIblink:         %d\n", l->mwiblink);
+                       ast_cli(a->fd, "Regextension:     %s\n", S_OR(l->regexten, "<not set>"));
+                       ast_cli(a->fd, "Regcontext:       %s\n", S_OR(l->regcontext, "<not set>"));
+                       ast_cli(a->fd, "MoHInterpret:     %s\n", S_OR(l->mohinterpret, "<not set>"));
+                       ast_cli(a->fd, "MoHSuggest:       %s\n", S_OR(l->mohsuggest, "<not set>"));
+                       ast_cli(a->fd, "Last dialed nr:   %s\n", S_OR(l->lastnumberdialed, "<no calls made yet>"));
+                       ast_cli(a->fd, "Last CallerID:    %s\n", S_OR(l->lastcallerid, "<not set>"));
+                       ast_cli(a->fd, "Transfer enabled: %s\n", (l->transfer ? "Yes" : "No"));
+                       ast_cli(a->fd, "Callwaiting:      %s\n", (l->callwaiting ? "Yes" : "No"));
+                       ast_cli(a->fd, "3Way Calling:     %s\n", (l->threewaycalling ? "Yes" : "No"));
+                       ast_cli(a->fd, "Can forward:      %s\n", (l->cancallforward ? "Yes" : "No"));
+                       ast_cli(a->fd, "Do Not Disturb:   %s\n", (l->dnd ? "Yes" : "No"));
+                       ast_cli(a->fd, "NAT:              %s\n", (l->nat ? "Yes" : "No"));
+                       ast_cli(a->fd, "immediate:        %s\n", (l->immediate ? "Yes" : "No"));
+                       ast_cli(a->fd, "Group:            %d\n", l->group);
+                       ast_cli(a->fd, "Codecs:           ");
+                       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, l->capability);
+                       ast_cli(a->fd, "%s\n", codec_buf);
+                       ast_cli(a->fd, "Codec Order:      (");
+                       print_codec_to_cli(a->fd, &l->prefs);
+                       ast_cli(a->fd, ")\n");
+                       ast_cli(a->fd, "\n");
                }
        }
        
        ast_mutex_unlock(&devicelock);
-       return RESULT_SUCCESS;
+       return CLI_SUCCESS;
 }
 
 /*! \brief List global settings for the Skinny subsystem. */
-static int skinny_show_settings(int fd, int argc, char *argv[])
+static char *handle_skinny_show_settings(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-       if (argc != 3)
-               return RESULT_SHOWUSAGE;
-
-       ast_cli(fd, "\nGlobal Settings:\n");
-       ast_cli(fd, "  Skinny Port:            %d\n", ntohs(bindaddr.sin_port));
-       ast_cli(fd, "  Bindaddress:            %s\n", ast_inet_ntoa(bindaddr.sin_addr));
-       ast_cli(fd, "  KeepAlive:              %d\n", keep_alive);
-       ast_cli(fd, "  Date Format:            %s\n", date_format);
-       ast_cli(fd, "  Voice Mail Extension:   %s\n", S_OR(vmexten, "(not set)"));
-       ast_cli(fd, "  Reg. context:           %s\n", S_OR(regcontext, "(not set)"));
-       ast_cli(fd, "  Jitterbuffer enabled:   %s\n", (ast_test_flag(&global_jbconf, AST_JB_ENABLED) ? "Yes" : "No"));
-       ast_cli(fd, "  Jitterbuffer forced:    %s\n", (ast_test_flag(&global_jbconf, AST_JB_FORCED) ? "Yes" : "No"));
-       ast_cli(fd, "  Jitterbuffer max size:  %ld\n", global_jbconf.max_size);
-       ast_cli(fd, "  Jitterbuffer resync:    %ld\n", global_jbconf.resync_threshold);
-       ast_cli(fd, "  Jitterbuffer impl:      %s\n", global_jbconf.impl);
-       ast_cli(fd, "  Jitterbuffer log:       %s\n", (ast_test_flag(&global_jbconf, AST_JB_LOG) ? "Yes" : "No"));
-
-       return RESULT_SUCCESS;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "skinny show settings";
+               e->usage =
+                       "Usage: skinny show settings\n"
+                       "       Lists all global configuration settings of the Skinny subsystem.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }       
+
+       if (a->argc != 3)
+               return CLI_SHOWUSAGE;
+
+       ast_cli(a->fd, "\nGlobal Settings:\n");
+       ast_cli(a->fd, "  Skinny Port:            %d\n", ntohs(bindaddr.sin_port));
+       ast_cli(a->fd, "  Bindaddress:            %s\n", ast_inet_ntoa(bindaddr.sin_addr));
+       ast_cli(a->fd, "  KeepAlive:              %d\n", keep_alive);
+       ast_cli(a->fd, "  Date Format:            %s\n", date_format);
+       ast_cli(a->fd, "  Voice Mail Extension:   %s\n", S_OR(vmexten, "(not set)"));
+       ast_cli(a->fd, "  Reg. context:           %s\n", S_OR(regcontext, "(not set)"));
+       ast_cli(a->fd, "  Jitterbuffer enabled:   %s\n", (ast_test_flag(&global_jbconf, AST_JB_ENABLED) ? "Yes" : "No"));
+       ast_cli(a->fd, "  Jitterbuffer forced:    %s\n", (ast_test_flag(&global_jbconf, AST_JB_FORCED) ? "Yes" : "No"));
+       ast_cli(a->fd, "  Jitterbuffer max size:  %ld\n", global_jbconf.max_size);
+       ast_cli(a->fd, "  Jitterbuffer resync:    %ld\n", global_jbconf.resync_threshold);
+       ast_cli(a->fd, "  Jitterbuffer impl:      %s\n", global_jbconf.impl);
+       ast_cli(a->fd, "  Jitterbuffer log:       %s\n", (ast_test_flag(&global_jbconf, AST_JB_LOG) ? "Yes" : "No"));
+
+       return CLI_SUCCESS;
 }
 
-static const char show_devices_usage[] =
-"Usage: skinny show devices\n"
-"       Lists all devices known to the Skinny subsystem.\n";
-
-static const char show_device_usage[] =
-"Usage: skinny show device <DeviceId|DeviceName>\n"
-"       Lists all deviceinformation of a specific device known to the Skinny subsystem.\n";
-
-static const char show_lines_usage[] =
-"Usage: skinny show lines\n"
-"       Lists all lines known to the Skinny subsystem.\n";
-
-static const char show_line_usage[] =
-"Usage: skinny show line <Line> [ on <DeviceID|DeviceName> ]\n"
-"       List all lineinformation of a specific line known to the Skinny subsystem.\n";
-
-static const char show_settings_usage[] =
-"Usage: skinny show settings\n"
-"       Lists all global configuration settings of the Skinny subsystem.\n";
-
-static const char debug_usage[] =
-"Usage: skinny set debug\n"
-"       Enables dumping of Skinny packets for debugging purposes\n";
-
-static const char no_debug_usage[] =
-"Usage: skinny set debug off\n"
-"       Disables dumping of Skinny packets for debugging purposes\n";
-
-static const char reset_usage[] =
-"Usage: skinny reset <DeviceId|DeviceName|all> [restart]\n"
-"       Causes a Skinny device to reset itself, optionally with a full restart\n";
-
 static struct ast_cli_entry cli_skinny[] = {
-       { { "skinny", "show", "devices", NULL },
-       skinny_show_devices, "List defined Skinny devices",
-       show_devices_usage },
-
-       { { "skinny", "show", "device", NULL },
-       skinny_show_device, "List Skinny device information",
-       show_device_usage, complete_skinny_show_device },
-
-       { { "skinny", "show", "lines", NULL },
-       skinny_show_lines, "List defined Skinny lines per device",
-       show_lines_usage },
-
-       { { "skinny", "show", "line", NULL },
-       skinny_show_line, "List Skinny line information",
-       show_line_usage, complete_skinny_show_lines },
-
-       { { "skinny", "show", "settings", NULL },
-       skinny_show_settings, "List global Skinny settings",
-       show_settings_usage },
-
-       { { "skinny", "set", "debug", NULL },
-       skinny_do_debug, "Enable Skinny debugging",
-       debug_usage },
-
-       { { "skinny", "set", "debug", "off", NULL },
-       skinny_no_debug, "Disable Skinny debugging",
-       no_debug_usage },
-
-       { { "skinny", "reset", NULL },
-       skinny_reset_device, "Reset Skinny device(s)",
-       reset_usage, complete_skinny_reset },
+       NEW_CLI(handle_skinny_show_devices, "List defined Skinny devices"),
+       NEW_CLI(handle_skinny_show_device, "List Skinny device information"),
+       NEW_CLI(handle_skinny_show_lines, "List defined Skinny lines per device"),      
+       NEW_CLI(handle_skinny_show_line, "List Skinny line information"),
+       NEW_CLI(handle_skinny_show_settings, "List global Skinny settings"),
+       NEW_CLI(handle_skinny_set_debug, "Enable Skinny debugging"),
+       NEW_CLI(handle_skinny_set_debug_off, "Disable Skinny debugging"),
+       NEW_CLI(handle_skinny_reset, "Reset Skinny device(s)"),
 };
 
 #if 0
index 031897f..782a409 100644 (file)
@@ -166,15 +166,16 @@ char *iax_prov_complete_template(const char *line, const char *word, int pos, in
        char *ret = NULL;
        int wordlen = strlen(word);
 
-       ast_mutex_lock(&provlock);
-       for (c = templates; c; c = c->next) {
-               if (!strncasecmp(word, c->name, wordlen) && ++which > state) {
-                       ret = ast_strdup(c->name);
-                       break;
+       if (pos == 3) {
+               ast_mutex_lock(&provlock);
+               for (c = templates; c; c = c->next) {
+                       if (!strncasecmp(word, c->name, wordlen) && ++which > state) {
+                               ret = ast_strdup(c->name);
+                               break;
+                       }
                }
+               ast_mutex_unlock(&provlock);
        }
-       ast_mutex_unlock(&provlock);
-       
        return ret;
 }
 
@@ -398,11 +399,6 @@ static int iax_process_template(struct ast_config *cfg, char *s, char *def)
        return 0;
 }
 
-static const char show_provisioning_usage[] = 
-"Usage: iax list provisioning [template]\n"
-"       Lists all known IAX provisioning templates or a\n"
-"       specific one if specified.\n";
-
 static const char *ifthere(const char *s)
 {
        if (strlen(s))
@@ -424,51 +420,62 @@ static const char *iax_server(unsigned int addr)
 }
 
 
-static int iax_show_provisioning(int fd, int argc, char *argv[])
+static char *iax_show_provisioning(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        struct iax_template *cur;
        char server[INET_ADDRSTRLEN];
        char alternate[INET_ADDRSTRLEN];
        char flags[80]; /* Has to be big enough for 'flags' too */
        int found = 0;
-       if ((argc != 3) && (argc != 4))
-               return RESULT_SHOWUSAGE;
+
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "iax2 show provisioning";
+               e->usage =
+                       "Usage: iax2 show provisioning [template]\n"
+                       "       Lists all known IAX provisioning templates or a\n"
+                       "       specific one if specified.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return iax_prov_complete_template(a->line, a->word, a->pos, a->n);
+       }
+
+       if ((a->argc != 3) && (a->argc != 4))
+               return CLI_SHOWUSAGE;
        ast_mutex_lock(&provlock);
        for (cur = templates;cur;cur = cur->next) {
-               if ((argc == 3) || (!strcasecmp(argv[3], cur->name)))  {
+               if ((a->argc == 3) || (!strcasecmp(a->argv[3], cur->name)))  {
                        if (found) 
-                               ast_cli(fd, "\n");
+                               ast_cli(a->fd, "\n");
                        ast_copy_string(server, iax_server(cur->server), sizeof(server));
                        ast_copy_string(alternate, iax_server(cur->altserver), sizeof(alternate));
-                       ast_cli(fd, "== %s ==\n", cur->name);
-                       ast_cli(fd, "Base Templ:   %s\n", strlen(cur->src) ? cur->src : "<none>");
-                       ast_cli(fd, "Username:     %s\n", ifthere(cur->user));
-                       ast_cli(fd, "Secret:       %s\n", ifthere(cur->pass));
-                       ast_cli(fd, "Language:     %s\n", ifthere(cur->lang));
-                       ast_cli(fd, "Bind Port:    %d\n", cur->port);
-                       ast_cli(fd, "Server:       %s\n", server);
-                       ast_cli(fd, "Server Port:  %d\n", cur->serverport);
-                       ast_cli(fd, "Alternate:    %s\n", alternate);
-                       ast_cli(fd, "Flags:        %s\n", iax_provflags2str(flags, sizeof(flags), cur->flags));
-                       ast_cli(fd, "Format:       %s\n", ast_getformatname(cur->format));
-                       ast_cli(fd, "TOS:          0x%x\n", cur->tos);
+                       ast_cli(a->fd, "== %s ==\n", cur->name);
+                       ast_cli(a->fd, "Base Templ:   %s\n", strlen(cur->src) ? cur->src : "<none>");
+                       ast_cli(a->fd, "Username:     %s\n", ifthere(cur->user));
+                       ast_cli(a->fd, "Secret:       %s\n", ifthere(cur->pass));
+                       ast_cli(a->fd, "Language:     %s\n", ifthere(cur->lang));
+                       ast_cli(a->fd, "Bind Port:    %d\n", cur->port);
+                       ast_cli(a->fd, "Server:       %s\n", server);
+                       ast_cli(a->fd, "Server Port:  %d\n", cur->serverport);
+                       ast_cli(a->fd, "Alternate:    %s\n", alternate);
+                       ast_cli(a->fd, "Flags:        %s\n", iax_provflags2str(flags, sizeof(flags), cur->flags));
+                       ast_cli(a->fd, "Format:       %s\n", ast_getformatname(cur->format));
+                       ast_cli(a->fd, "TOS:          0x%x\n", cur->tos);
                        found++;
                }
        }
        ast_mutex_unlock(&provlock);
        if (!found) {
-               if (argc == 3)
-                       ast_cli(fd, "No provisioning templates found\n");
+               if (a->argc == 3)
+                       ast_cli(a->fd, "No provisioning templates found\n");
                else
-                       ast_cli(fd, "No provisioning template matching '%s' found\n", argv[3]);
+                       ast_cli(a->fd, "No provisioning template matching '%s' found\n", a->argv[3]);
        }
-       return RESULT_SUCCESS;
+       return CLI_SUCCESS;
 }
 
 static struct ast_cli_entry cli_iax2_provision[] = {
-       { { "iax2", "show", "provisioning", NULL },
-       iax_show_provisioning, "Display iax provisioning",
-       show_provisioning_usage, iax_prov_complete_template, },
+       NEW_CLI(iax_show_provisioning, "Display iax provisioning"),
 };
 
 static int iax_provision_init(void)
index 59b97e5..6e9ccb7 100644 (file)
@@ -305,10 +305,6 @@ struct thread_list_t {
 
 static AST_RWLIST_HEAD_STATIC(thread_list, thread_list_t);
 
-static const char show_threads_help[] =
-"Usage: core show threads\n"
-"       List threads currently active in the system.\n";
-
 void ast_register_thread(char *name)
 { 
        struct thread_list_t *new = ast_calloc(1, sizeof(*new));
@@ -342,105 +338,130 @@ void ast_unregister_thread(void *id)
 }
 
 /*! \brief Give an overview of core settings */
-static int handle_show_settings(int fd, int argc, char *argv[])
+static char *handle_show_settings(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        char buf[BUFSIZ];
        struct ast_tm tm;
 
-       ast_cli(fd, "\nPBX Core settings\n");
-       ast_cli(fd, "-----------------\n");
-       ast_cli(fd, "  Version:                     %s\n", "" ASTERISK_VERSION "" );
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "core show settings";
+               e->usage = "Usage: core show settings\n"
+                          "       Show core misc settings";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
+       ast_cli(a->fd, "\nPBX Core settings\n");
+       ast_cli(a->fd, "-----------------\n");
+       ast_cli(a->fd, "  Version:                     %s\n", "" ASTERISK_VERSION "" );
        if (option_maxcalls)
-               ast_cli(fd, "  Max. calls:                  %d (Current %d)\n", option_maxcalls, ast_active_channels());
+               ast_cli(a->fd, "  Max. calls:                  %d (Current %d)\n", option_maxcalls, ast_active_channels());
        else
-               ast_cli(fd, "  Max. calls:                  Not set\n");
+               ast_cli(a->fd, "  Max. calls:                  Not set\n");
        if (option_maxfiles)
-               ast_cli(fd, "  Max. open file handles:      %d\n", option_maxfiles); 
+               ast_cli(a->fd, "  Max. open file handles:      %d\n", option_maxfiles); 
        else
-               ast_cli(fd, "  Max. open file handles:      Not set\n");
-       ast_cli(fd, "  Verbosity:                   %d\n", option_verbose);
-       ast_cli(fd, "  Debug level:                 %d\n", option_debug);
-       ast_cli(fd, "  Max load avg:                %lf\n", option_maxload);
+               ast_cli(a->fd, "  Max. open file handles:      Not set\n");
+       ast_cli(a->fd, "  Verbosity:                   %d\n", option_verbose);
+       ast_cli(a->fd, "  Debug level:                 %d\n", option_debug);
+       ast_cli(a->fd, "  Max load avg:                %lf\n", option_maxload);
 #if defined(HAVE_SYSINFO)
-       ast_cli(fd, "  Min Free Memory:             %ld MB\n", option_minmemfree);
+       ast_cli(a->fd, "  Min Free Memory:             %ld MB\n", option_minmemfree);
 #endif
        if (ast_localtime(&ast_startuptime, &tm, NULL)) {
                ast_strftime(buf, sizeof(buf), "%H:%M:%S", &tm);
-               ast_cli(fd, "  Startup time:                %s\n", buf);
+               ast_cli(a->fd, "  Startup time:                %s\n", buf);
        }
        if (ast_localtime(&ast_lastreloadtime, &tm, NULL)) {
                ast_strftime(buf, sizeof(buf), "%H:%M:%S", &tm);
-               ast_cli(fd, "  Last reload time:            %s\n", buf);
-       }
-       ast_cli(fd, "  System:                      %s/%s built by %s on %s %s\n", ast_build_os, ast_build_kernel, ast_build_user, ast_build_machine, ast_build_date);
-       ast_cli(fd, "  System name:                 %s\n", ast_config_AST_SYSTEM_NAME);
-       ast_cli(fd, "  Default language:            %s\n", defaultlanguage);
-       ast_cli(fd, "  Language prefix:             %s\n", ast_language_is_prefix ? "Enabled" : "Disabled");
-       ast_cli(fd, "  User name and group:         %s/%s\n", ast_config_AST_RUN_USER, ast_config_AST_RUN_GROUP);
-       ast_cli(fd, "  Executable includes:         %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_EXEC_INCLUDES) ? "Enabled" : "Disabled");
-       ast_cli(fd, "  Transcode via SLIN:          %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSCODE_VIA_SLIN) ? "Enabled" : "Disabled");
-       ast_cli(fd, "  Internal timing:             %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_INTERNAL_TIMING) ? "Enabled" : "Disabled");
-       ast_cli(fd, "  Transmit silence during rec: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_INTERNAL_TIMING) ? "Enabled" : "Disabled");
-
-       ast_cli(fd, "\n* Subsystems\n");
-       ast_cli(fd, "  -------------\n");
-       ast_cli(fd, "  Manager (AMI):               %s\n", check_manager_enabled() ? "Enabled" : "Disabled");
-       ast_cli(fd, "  Web Manager (AMI/HTTP):      %s\n", check_webmanager_enabled() ? "Enabled" : "Disabled");
-       ast_cli(fd, "  Call data records:           %s\n", check_cdr_enabled() ? "Enabled" : "Disabled");
-       ast_cli(fd, "  Realtime Architecture (ARA): %s\n", ast_realtime_enabled() ? "Enabled" : "Disabled");
+               ast_cli(a->fd, "  Last reload time:            %s\n", buf);
+       }
+       ast_cli(a->fd, "  System:                      %s/%s built by %s on %s %s\n", ast_build_os, ast_build_kernel, ast_build_user, ast_build_machine, ast_build_date);
+       ast_cli(a->fd, "  System name:                 %s\n", ast_config_AST_SYSTEM_NAME);
+       ast_cli(a->fd, "  Default language:            %s\n", defaultlanguage);
+       ast_cli(a->fd, "  Language prefix:             %s\n", ast_language_is_prefix ? "Enabled" : "Disabled");
+       ast_cli(a->fd, "  User name and group:         %s/%s\n", ast_config_AST_RUN_USER, ast_config_AST_RUN_GROUP);
+       ast_cli(a->fd, "  Executable includes:         %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_EXEC_INCLUDES) ? "Enabled" : "Disabled");
+       ast_cli(a->fd, "  Transcode via SLIN:          %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSCODE_VIA_SLIN) ? "Enabled" : "Disabled");
+       ast_cli(a->fd, "  Internal timing:             %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_INTERNAL_TIMING) ? "Enabled" : "Disabled");
+       ast_cli(a->fd, "  Transmit silence during rec: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_INTERNAL_TIMING) ? "Enabled" : "Disabled");
+
+       ast_cli(a->fd, "\n* Subsystems\n");
+       ast_cli(a->fd, "  -------------\n");
+       ast_cli(a->fd, "  Manager (AMI):               %s\n", check_manager_enabled() ? "Enabled" : "Disabled");
+       ast_cli(a->fd, "  Web Manager (AMI/HTTP):      %s\n", check_webmanager_enabled() ? "Enabled" : "Disabled");
+       ast_cli(a->fd, "  Call data records:           %s\n", check_cdr_enabled() ? "Enabled" : "Disabled");
+       ast_cli(a->fd, "  Realtime Architecture (ARA): %s\n", ast_realtime_enabled() ? "Enabled" : "Disabled");
 
        /*! \todo we could check musiconhold, voicemail, smdi, adsi, queues  */
 
-       ast_cli(fd, "\n* Directories\n");
-       ast_cli(fd, "  -------------\n");
-       ast_cli(fd, "  Configuration file:          %s\n", ast_config_AST_CONFIG_FILE);
-       ast_cli(fd, "  Configuration directory:     %s\n", ast_config_AST_CONFIG_DIR);
-       ast_cli(fd, "  Module directory:            %s\n", ast_config_AST_MODULE_DIR);
-       ast_cli(fd, "  Spool directory:             %s\n", ast_config_AST_SPOOL_DIR);
-       ast_cli(fd, "  Log directory:               %s\n", ast_config_AST_LOG_DIR);
-       ast_cli(fd, "\n\n");
-       return 0;
+       ast_cli(a->fd, "\n* Directories\n");
+       ast_cli(a->fd, "  -------------\n");
+       ast_cli(a->fd, "  Configuration file:          %s\n", ast_config_AST_CONFIG_FILE);
+       ast_cli(a->fd, "  Configuration directory:     %s\n", ast_config_AST_CONFIG_DIR);
+       ast_cli(a->fd, "  Module directory:            %s\n", ast_config_AST_MODULE_DIR);
+       ast_cli(a->fd, "  Spool directory:             %s\n", ast_config_AST_SPOOL_DIR);
+       ast_cli(a->fd, "  Log directory:               %s\n", ast_config_AST_LOG_DIR);
+       ast_cli(a->fd, "\n\n");
+       return CLI_SUCCESS;
 }
 
-static int handle_show_threads(int fd, int argc, char *argv[])
+static char *handle_show_threads(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        int count = 0;
        struct thread_list_t *cur;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "core show threads";
+               e->usage = 
+                       "Usage: core show threads\n"
+                       "       List threads currently active in the system.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
 
        AST_RWLIST_RDLOCK(&thread_list);
        AST_RWLIST_TRAVERSE(&thread_list, cur, list) {
-               ast_cli(fd, "%p %s\n", (void *)cur->id, cur->name);
+               ast_cli(a->fd, "%p %s\n", (void *)cur->id, cur->name);
                count++;
        }
         AST_RWLIST_UNLOCK(&thread_list);
-       ast_cli(fd, "%d threads listed.\n", count);
-       return 0;
+       ast_cli(a->fd, "%d threads listed.\n", count);
+       return CLI_SUCCESS;
 }
 
 #if defined(HAVE_SYSINFO)
-static const char show_sysinfo_help[] =
-"Usage: core show sysinfo\n"
-"       List current system information.\n";
-
 /*! \brief Give an overview of system statistics */
-static int handle_show_sysinfo(int fd, int argc, char *argv[])
+static char *handle_show_sysinfo(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        struct sysinfo sys_info;
-
-       if (sysinfo(&sys_info)) {
-               ast_cli(fd, "FAILED to retrieve system information\n\n");
-               return 0;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "core show sysinfo";
+               e->usage =
+                       "Usage: core show sysinfo\n"
+                       "       List current system information.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
        }
-       ast_cli(fd, "\nSystem Statistics\n");
-       ast_cli(fd, "-----------------\n");
-       ast_cli(fd, "  System Uptime:             %ld hours\n", sys_info.uptime/3600);
-       ast_cli(fd, "  Total RAM:                 %ld KiB\n", (sys_info.totalram / sys_info.mem_unit)/1024);
-       ast_cli(fd, "  Free RAM:                  %ld KiB\n", (sys_info.freeram / sys_info.mem_unit)/1024);
-       ast_cli(fd, "  Buffer RAM:                %ld KiB\n", (sys_info.bufferram / sys_info.mem_unit)/1024);
-       ast_cli(fd, "  Total Swap Space:          %ld KiB\n", (sys_info.totalswap / sys_info.mem_unit)/1024);
-       ast_cli(fd, "  Free Swap Space:           %ld KiB\n\n", (sys_info.freeswap / sys_info.mem_unit)/1024);
-       ast_cli(fd, "  Number of Processes:       %d \n\n", sys_info.procs);
-       return 0;
+       if (sysinfo(&sys_info)) {
+               ast_cli(a->fd, "FAILED to retrieve system information\n\n");
+               return CLI_FAILURE;
+       }
+       ast_cli(a->fd, "\nSystem Statistics\n");
+       ast_cli(a->fd, "-----------------\n");
+       ast_cli(a->fd, "  System Uptime:             %ld hours\n", sys_info.uptime/3600);
+       ast_cli(a->fd, "  Total RAM:                 %ld KiB\n", (sys_info.totalram / sys_info.mem_unit)/1024);
+       ast_cli(a->fd, "  Free RAM:                  %ld KiB\n", (sys_info.freeram / sys_info.mem_unit)/1024);
+       ast_cli(a->fd, "  Buffer RAM:                %ld KiB\n", (sys_info.bufferram / sys_info.mem_unit)/1024);
+       ast_cli(a->fd, "  Total Swap Space:          %ld KiB\n", (sys_info.totalswap / sys_info.mem_unit)/1024);
+       ast_cli(a->fd, "  Free Swap Space:           %ld KiB\n\n", (sys_info.freeswap / sys_info.mem_unit)/1024);
+       ast_cli(a->fd, "  Number of Processes:       %d \n\n", sys_info.procs);
+       return CLI_SUCCESS;
 }
 #endif
 
@@ -541,59 +562,84 @@ int64_t ast_mark(int i, int startstop)
        return prof_data->e[i].mark;
 }
 
-static int handle_show_profile(int fd, int argc, char *argv[])
+#define DEFINE_PROFILE_MIN_MAX_VALUES min = 0; \
+       max = prof_data->entries;\
+       if  (a->argc > 3) { /* specific entries */ \
+               if (isdigit(a->argv[3][0])) { \
+                       min = atoi(a->argv[3]); \
+                       if (a->argc == 5 && strcmp(a->argv[4], "-")) \
+                               max = atoi(a->argv[4]); \
+               } else \
+                       search = a->argv[3]; \
+       } \
+       if (max > prof_data->entries) \
+               max = prof_data->entries;
+
+static char *handle_show_profile(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        int i, min, max;
        char *search = NULL;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "core show profile";
+               e->usage = "Usage: core show profile\n"
+                          "       show profile information";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
 
        if (prof_data == NULL)
                return 0;
 
-       min = 0;
-       max = prof_data->entries;
-       if  (argc > 3) { /* specific entries */
-               if (isdigit(argv[3][0])) {
-                       min = atoi(argv[3]);
-                       if (argc == 5 && strcmp(argv[4], "-"))
-                               max = atoi(argv[4]);
-               } else
-                       search = argv[3];
-       }
-       if (max > prof_data->entries)
-               max = prof_data->entries;
-       if (!strcmp(argv[1], "clear")) {
-               for (i= min; i < max; i++) {
-                       if (!search || strstr(prof_data->e[i].name, search)) {
-                               prof_data->e[i].value = 0;
-                               prof_data->e[i].events = 0;
-                       }
-               }
-               return 0;
-       }
-       ast_cli(fd, "profile values (%d, allocated %d)\n-------------------\n",
+       DEFINE_PROFILE_MIN_MAX_VALUES;
+       ast_cli(a->fd, "profile values (%d, allocated %d)\n-------------------\n",
                prof_data->entries, prof_data->max_size);
-       ast_cli(fd, "%6s   %8s  %10s %12s %12s  %s\n", "ID", "Scale", "Events",
+       ast_cli(a->fd, "%6s   %8s  %10s %12s %12s  %s\n", "ID", "Scale", "Events",
                        "Value", "Average", "Name");
        for (i = min; i < max; i++) {
                struct profile_entry *e = &prof_data->e[i];
                if (!search || strstr(prof_data->e[i].name, search))
-                   ast_cli(fd, "%6d: [%8ld] %10ld %12lld %12lld  %s\n",
+                   ast_cli(a->fd, "%6d: [%8ld] %10ld %12lld %12lld  %s\n",
                        i,
                        (long)e->scale,
                        (long)e->events, (long long)e->value,
                        (long long)(e->events ? e->value / e->events : e->value),
                        e->name);
        }
-       return 0;
+       return CLI_SUCCESS;
 }
 
-static const char show_version_files_help[] = 
-"Usage: core show file version [like <pattern>]\n"
-"       Lists the revision numbers of the files used to build this copy of Asterisk.\n"
-"       Optional regular expression pattern is used to filter the file list.\n";
+static char *handle_clear_profile(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+       int i, min, max;
+       char *search = NULL;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "core clear profile";
+               e->usage = "Usage: core clear profile\n"
+                          "       clear profile information";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
+       if (prof_data == NULL)
+               return 0;
+
+       DEFINE_PROFILE_MIN_MAX_VALUES;
+       for (i= min; i < max; i++) {
+               if (!search || strstr(prof_data->e[i].name, search)) {
+                       prof_data->e[i].value = 0;
+                       prof_data->e[i].events = 0;
+               }
+       }
+       return CLI_SUCCESS;
+}
+#undef DEFINE_PROFILE_MIN_MAX_VALUES
 
 /*! \brief CLI command to list module versions */
-static int handle_show_version_files(int fd, int argc, char *argv[])
+static char *handle_show_version_files(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 #define FORMAT "%-25.25s %-40.40s\n"
        struct file_version *iterator;
@@ -601,15 +647,42 @@ static int handle_show_version_files(int fd, int argc, char *argv[])
        int havepattern = 0;
        int havename = 0;
        int count_files = 0;
+       char *ret = NULL;
+       int matchlen, which = 0;
+       struct file_version *find;
+
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "core show file version [like]";
+               e->usage = 
+                       "Usage: core show file version [like <pattern>]\n"
+                       "       Lists the revision numbers of the files used to build this copy of Asterisk.\n"
+                       "       Optional regular expression pattern is used to filter the file list.\n";
+               return NULL;
+       case CLI_GENERATE:
+               matchlen = strlen(a->word);
+               if (a->pos != 3)
+                       return NULL;
+               AST_RWLIST_RDLOCK(&file_versions);
+               AST_RWLIST_TRAVERSE(&file_versions, find, list) {
+                       if (!strncasecmp(a->word, find->file, matchlen) && ++which > a->n) {
+                               ret = ast_strdup(find->file);
+                               break;
+                       }
+               }
+               AST_RWLIST_UNLOCK(&file_versions);
+               return ret;
+       }
 
-       switch (argc) {
+
+       switch (a->argc) {
        case 6:
-               if (!strcasecmp(argv[4], "like")) {
-                       if (regcomp(&regexbuf, argv[5], REG_EXTENDED | REG_NOSUB))
-                               return RESULT_SHOWUSAGE;
+               if (!strcasecmp(a->argv[4], "like")) {
+                       if (regcomp(&regexbuf, a->argv[5], REG_EXTENDED | REG_NOSUB))
+                               return CLI_SHOWUSAGE;
                        havepattern = 1;
                } else
-                       return RESULT_SHOWUSAGE;
+                       return CLI_SHOWUSAGE;
                break;
        case 5:
                havename = 1;
@@ -617,57 +690,36 @@ static int handle_show_version_files(int fd, int argc, char *argv[])
        case 4:
                break;
        default:
-               return RESULT_SHOWUSAGE;
+               return CLI_SHOWUSAGE;
        }
 
-       ast_cli(fd, FORMAT, "File", "Revision");
-       ast_cli(fd, FORMAT, "----", "--------");
+       ast_cli(a->fd, FORMAT, "File", "Revision");
+       ast_cli(a->fd, FORMAT, "----", "--------");
        AST_RWLIST_RDLOCK(&file_versions);
        AST_RWLIST_TRAVERSE(&file_versions, iterator, list) {
-               if (havename && strcasecmp(iterator->file, argv[4]))
+               if (havename && strcasecmp(iterator->file, a->argv[4]))
                        continue;
 
                if (havepattern && regexec(&regexbuf, iterator->file, 0, NULL, 0))
                        continue;
 
-               ast_cli(fd, FORMAT, iterator->file, iterator->version);
+               ast_cli(a->fd, FORMAT, iterator->file, iterator->version);
                count_files++;
                if (havename)
                        break;
        }
        AST_RWLIST_UNLOCK(&file_versions);
        if (!havename) {
-               ast_cli(fd, "%d files listed.\n", count_files);
+               ast_cli(a->fd, "%d files listed.\n", count_files);
        }
 
        if (havepattern)
                regfree(&regexbuf);
 
-       return RESULT_SUCCESS;
+       return CLI_SUCCESS;
 #undef FORMAT
 }
 
-static char *complete_show_version_files(const char *line, const char *word, int pos, int state)
-{
-       struct file_version *find;
-       int which = 0;
-       char *ret = NULL;
-       int matchlen = strlen(word);
-
-       if (pos != 3)
-               return NULL;
-
-       AST_RWLIST_RDLOCK(&file_versions);
-       AST_RWLIST_TRAVERSE(&file_versions, find, list) {
-               if (!strncasecmp(word, find->file, matchlen) && ++which > state) {
-                       ret = ast_strdup(find->file);
-                       break;
-               }
-       }
-       AST_RWLIST_UNLOCK(&file_versions);
-
-       return ret;
-}
 #endif /* ! LOW_MEMORY */
 
 int ast_register_atexit(void (*func)(void))
@@ -1409,62 +1461,25 @@ static int remoteconsolehandler(char *s)
        return ret;
 }
 
-static const char abort_halt_help[] = 
-"Usage: abort shutdown\n"
-"       Causes Asterisk to abort an executing shutdown or restart, and resume normal\n"
-"       call operations.\n";
-
-static const char shutdown_now_help[] = 
-"Usage: stop now\n"
-"       Shuts down a running Asterisk immediately, hanging up all active calls .\n";
-
-static const char shutdown_gracefully_help[] = 
-"Usage: stop gracefully\n"
-"       Causes Asterisk to not accept new calls, and exit when all\n"
-"       active calls have terminated normally.\n";
-
-static const char shutdown_when_convenient_help[] = 
-"Usage: stop when convenient\n"
-"       Causes Asterisk to perform a shutdown when all active calls have ended.\n";
-
-static const char restart_now_help[] = 
-"Usage: restart now\n"
-"       Causes Asterisk to hangup all calls and exec() itself performing a cold\n"
-"       restart.\n";
-
-static const char restart_gracefully_help[] = 
-"Usage: restart gracefully\n"
-"       Causes Asterisk to stop accepting new calls and exec() itself performing a cold\n"
-"       restart when all active calls have ended.\n";
-
-static const char restart_when_convenient_help[] = 
-"Usage: restart when convenient\n"
-"       Causes Asterisk to perform a cold restart when all active calls have ended.\n";
-
-static const char bang_help[] =
-"Usage: !<command>\n"
-"       Executes a given shell command\n";
-
-static const char show_warranty_help[] =
-"Usage: core show warranty\n"
-"       Shows the warranty (if any) for this copy of Asterisk.\n";
-
-static const char show_license_help[] =
-"Usage: core show license\n"
-"       Shows the license(s) for this copy of Asterisk.\n";
-
-static const char version_help[] =
-"Usage: core show version\n"
-"       Shows Asterisk version information.\n";
-
-static int handle_version(int fd, int argc, char *argv[])
+static char *handle_version(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-       if (argc != 3)
-               return RESULT_SHOWUSAGE;
-       ast_cli(fd, "Asterisk %s built by %s @ %s on a %s running %s on %s\n",
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "core show version";
+               e->usage = 
+                       "Usage: core show version\n"
+                       "       Shows Asterisk version information.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
+       if (a->argc != 3)
+               return CLI_SHOWUSAGE;
+       ast_cli(a->fd, "Asterisk %s built by %s @ %s on a %s running %s on %s\n",
                ASTERISK_VERSION, ast_build_user, ast_build_hostname,
                ast_build_machine, ast_build_os, ast_build_date);
-       return RESULT_SUCCESS;
+       return CLI_SUCCESS;
 }
 
 #if 0
@@ -1477,68 +1492,160 @@ static int handle_quit(int fd, int argc, char *argv[])
 }
 #endif
 
-static int handle_shutdown_now(int fd, int argc, char *argv[])
+static char *handle_stop_now(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-       if (argc != 2)
-               return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "stop now";
+               e->usage = 
+                       "Usage: stop now\n"
+                       "       Shuts down a running Asterisk immediately, hanging up all active calls .\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
+       if (a->argc != 2)
+               return CLI_SHOWUSAGE;
        quit_handler(0, 0 /* Not nice */, 1 /* safely */, 0 /* not restart */);
-       return RESULT_SUCCESS;
+       return CLI_SUCCESS;
 }
 
-static int handle_shutdown_gracefully(int fd, int argc, char *argv[])
+static char *handle_stop_gracefully(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-       if (argc != 2)
-               return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "stop gracefully";
+               e->usage = 
+                       "Usage: stop gracefully\n"
+                       "       Causes Asterisk to not accept new calls, and exit when all\n"
+                       "       active calls have terminated normally.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
+       if (a->argc != 2)
+               return CLI_SHOWUSAGE;
        quit_handler(0, 1 /* nicely */, 1 /* safely */, 0 /* no restart */);
-       return RESULT_SUCCESS;
+       return CLI_SUCCESS;
 }
 
-static int handle_shutdown_when_convenient(int fd, int argc, char *argv[])
+static char *handle_stop_when_convenient(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-       if (argc != 3)
-               return RESULT_SHOWUSAGE;
-       ast_cli(fd, "Waiting for inactivity to perform halt\n");
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "stop when convenient";
+               e->usage = 
+                       "Usage: stop when convenient\n"
+                       "       Causes Asterisk to perform a shutdown when all active calls have ended.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
+       if (a->argc != 3)
+               return CLI_SHOWUSAGE;
+       ast_cli(a->fd, "Waiting for inactivity to perform halt\n");
        quit_handler(0, 2 /* really nicely */, 1 /* safely */, 0 /* don't restart */);
-       return RESULT_SUCCESS;
+       return CLI_SUCCESS;
 }
 
-static int handle_restart_now(int fd, int argc, char *argv[])
+static char *handle_restart_now(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-       if (argc != 2)
-               return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "restart now";
+               e->usage = 
+                       "Usage: restart now\n"
+                       "       Causes Asterisk to hangup all calls and exec() itself performing a cold\n"
+                       "       restart.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
+       if (a->argc != 2)
+               return CLI_SHOWUSAGE;
        quit_handler(0, 0 /* not nicely */, 1 /* safely */, 1 /* restart */);
-       return RESULT_SUCCESS;
+       return CLI_SUCCESS;
 }
 
-static int handle_restart_gracefully(int fd, int argc, char *argv[])
+static char *handle_restart_gracefully(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-       if (argc != 2)
-               return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "restart gracefully";
+               e->usage = 
+                       "Usage: restart gracefully\n"
+                       "       Causes Asterisk to stop accepting new calls and exec() itself performing a cold\n"
+                       "       restart when all active calls have ended.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
+       if (a->argc != 2)
+               return CLI_SHOWUSAGE;
        quit_handler(0, 1 /* nicely */, 1 /* safely */, 1 /* restart */);
-       return RESULT_SUCCESS;
+       return CLI_SUCCESS;
 }
 
-static int handle_restart_when_convenient(int fd, int argc, char *argv[])
+static char *handle_restart_when_convenient(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-       if (argc != 3)
-               return RESULT_SHOWUSAGE;
-       ast_cli(fd, "Waiting for inactivity to perform restart\n");
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "restart when convenient";
+               e->usage = 
+                       "Usage: restart when convenient\n"
+                       "       Causes Asterisk to perform a cold restart when all active calls have ended.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
+       if (a->argc != 3)
+               return CLI_SHOWUSAGE;
+       ast_cli(a->fd, "Waiting for inactivity to perform restart\n");
        quit_handler(0, 2 /* really nicely */, 1 /* safely */, 1 /* restart */);
-       return RESULT_SUCCESS;
+       return CLI_SUCCESS;
 }
 
-static int handle_abort_halt(int fd, int argc, char *argv[])
+static char *handle_abort_shutdown(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-       if (argc != 2)
-               return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "abort shutdown";
+               e->usage = 
+                       "Usage: abort shutdown\n"
+                       "       Causes Asterisk to abort an executing shutdown or restart, and resume normal\n"
+                       "       call operations.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
+       if (a->argc != 2)
+               return CLI_SHOWUSAGE;
        ast_cancel_shutdown();
        shuttingdown = 0;
-       return RESULT_SUCCESS;
+       return CLI_SUCCESS;
 }
 
-static int handle_bang(int fd, int argc, char *argv[])
+static char *handle_bang(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-       return RESULT_SUCCESS;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "!";
+               e->usage = 
+                       "Usage: !<command>\n"
+                       "       Executes a given shell command\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
+       return CLI_SUCCESS;
 }
 static const char warranty_lines[] = {
        "\n"
@@ -1565,11 +1672,22 @@ static const char warranty_lines[] = {
        "POSSIBILITY OF SUCH DAMAGES.\n"
 };
 
-static int show_warranty(int fd, int argc, char *argv[])
+static char *show_warranty(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-       ast_cli(fd, warranty_lines);
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "core show warranty";
+               e->usage = 
+                       "Usage: core show warranty\n"
+                       "       Shows the warranty (if any) for this copy of Asterisk.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
 
-       return RESULT_SUCCESS;
+       ast_cli(a->fd, warranty_lines);
+
+       return CLI_SUCCESS;
 }
 
 static const char license_lines[] = {
@@ -1591,11 +1709,22 @@ static const char license_lines[] = {
        "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n"
 };
 
-static int show_license(int fd, int argc, char *argv[])
+static char *show_license(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-       ast_cli(fd, license_lines);
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "core show license";
+               e->usage = 
+                       "Usage: core show license\n"
+                       "       Shows the license(s) for this copy of Asterisk.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
 
-       return RESULT_SUCCESS;
+       ast_cli(a->fd, license_lines);
+
+       return CLI_SUCCESS;
 }
 
 #define ASTERISK_PROMPT "*CLI> "
@@ -1603,75 +1732,26 @@ static int show_license(int fd, int argc, char *argv[])
 #define ASTERISK_PROMPT2 "%s*CLI> "
 
 static struct ast_cli_entry cli_asterisk[] = {
-       { { "abort", "halt", NULL },
-       handle_abort_halt, "Cancel a running halt",
-       abort_halt_help },
-
-       { { "stop", "now", NULL },
-       handle_shutdown_now, "Shut down Asterisk immediately",
-       shutdown_now_help },
-
-       { { "stop", "gracefully", NULL },
-       handle_shutdown_gracefully, "Gracefully shut down Asterisk",
-       shutdown_gracefully_help },
-
-       { { "stop", "when", "convenient", NULL },
-       handle_shutdown_when_convenient, "Shut down Asterisk at empty call volume",
-       shutdown_when_convenient_help },
-
-       { { "restart", "now", NULL },
-       handle_restart_now, "Restart Asterisk immediately", restart_now_help },
-
-       { { "restart", "gracefully", NULL },
-       handle_restart_gracefully, "Restart Asterisk gracefully",
-       restart_gracefully_help },
-
-       { { "restart", "when", "convenient", NULL },
-       handle_restart_when_convenient, "Restart Asterisk at empty call volume",
-       restart_when_convenient_help },
-
-       { { "core", "show", "warranty", NULL },
-       show_warranty, "Show the warranty (if any) for this copy of Asterisk",
-       show_warranty_help },
-
-       { { "core", "show", "license", NULL },
-       show_license, "Show the license(s) for this copy of Asterisk",
-       show_license_help },
-
-       { { "core", "show", "version", NULL },
-       handle_version, "Display version info",
-       version_help },
-
-       { { "!", NULL },
-       handle_bang, "Execute a shell command",
-       bang_help },
-
+       NEW_CLI(handle_abort_shutdown, "Cancel a running shutdown"),
+       NEW_CLI(handle_stop_now, "Shut down Asterisk immediately"),
+       NEW_CLI(handle_stop_gracefully, "Gracefully shut down Asterisk"),
+       NEW_CLI(handle_stop_when_convenient, "Shut down Asterisk at empty call volume"),
+       NEW_CLI(handle_restart_now, "Restart Asterisk immediately"), 
+       NEW_CLI(handle_restart_gracefully, "Restart Asterisk gracefully"),
+       NEW_CLI(handle_restart_when_convenient, "Restart Asterisk at empty call volume"),
+       NEW_CLI(show_warranty, "Show the warranty (if any) for this copy of Asterisk"),
+       NEW_CLI(show_license, "Show the license(s) for this copy of Asterisk"),
+       NEW_CLI(handle_version, "Display version info"),
+       NEW_CLI(handle_bang, "Execute a shell command"),
 #if !defined(LOW_MEMORY)
-       { { "core", "show", "file", "version", NULL },
-       handle_show_version_files, "List versions of files used to build Asterisk",
-       show_version_files_help, complete_show_version_files },
-
-       { { "core", "show", "threads", NULL },
-       handle_show_threads, "Show running threads",
-       show_threads_help },
-
+       NEW_CLI(handle_show_version_files, "List versions of files used to build Asterisk"),
+       NEW_CLI(handle_show_threads, "Show running threads"),
 #if defined(HAVE_SYSINFO)
-       { { "core", "show", "sysinfo", NULL },
-       handle_show_sysinfo, "Show System Information",
-       show_sysinfo_help },
+       NEW_CLI(handle_show_sysinfo, "Show System Information"),
 #endif
-
-       { { "core", "show", "profile", NULL },
-       handle_show_profile, "Display profiling info",
-       NULL },
-
-       { { "core", "show", "settings", NULL },
-       handle_show_settings, "Show some core settings",
-       NULL },
-
-       { { "core", "clear", "profile", NULL },
-       handle_show_profile, "Clear profiling info",
-       NULL },
+       NEW_CLI(handle_show_profile, "Display profiling info"),
+       NEW_CLI(handle_show_settings, "Show some core settings"),
+       NEW_CLI(handle_clear_profile, "Clear profiling info"),
 #endif /* ! LOW_MEMORY */
 };
 
index f7fde9a..7e1bdb0 100644 (file)
@@ -607,40 +607,65 @@ static int print_cb(void *obj, void *arg, int flag)
 /*
  * Print stats
  */
-static int handle_astobj2_stats(int fd, int argc, char *argv[])
+static char *handle_astobj2_stats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-       ast_cli(fd, "Objects    : %d\n", ao2.total_objects);
-       ast_cli(fd, "Containers : %d\n", ao2.total_containers);
-       ast_cli(fd, "Memory     : %d\n", ao2.total_mem);
-       ast_cli(fd, "Locked     : %d\n", ao2.total_locked);
-       ast_cli(fd, "Refs       : %d\n", ao2.total_refs);
-       return 0;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "astobj2 stats";
+               e->usage = "Usage: astobj2 stats\n"
+                          "       Show astobj2 stats\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+       ast_cli(a->fd, "Objects    : %d\n", ao2.total_objects);
+       ast_cli(a->fd, "Containers : %d\n", ao2.total_containers);
+       ast_cli(a->fd, "Memory     : %d\n", ao2.total_mem);
+       ast_cli(a->fd, "Locked     : %d\n", ao2.total_locked);
+       ast_cli(a->fd, "Refs       : %d\n", ao2.total_refs);
+       return CLI_SUCCESS;
 }
 
 /*
  * This is testing code for astobj
  */
-static int handle_astobj2_test(int fd, int argc, char *argv[])
+static char *handle_astobj2_test(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        struct ao2_container *c1;
        int i, lim;
        char *obj;
        static int prof_id = -1;
+       struct ast_cli_args fake_args = { a->fd, 0, NULL };
+
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "astobj2 test";
+               e->usage = "Usage: astobj2 test <num>\n"
+                          "       Runs astobj2 test. Creates 'num' objects,\n"
+                          "       and test iterators, callbacks and may be other stuff\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
+       if (a->argc != 3) {
+               return CLI_SHOWUSAGE;
+       }
 
        if (prof_id == -1)
                prof_id = ast_add_profile("ao2_alloc", 0);
 
-       ast_cli(fd, "argc %d argv %s %s %s\n", argc, argv[0], argv[1], argv[2]);
-       lim = atoi(argv[2]);
-       ast_cli(fd, "called astobj_test\n");
+       ast_cli(a->fd, "argc %d argv %s %s %s\n", a->argc, a->argv[0], a->argv[1], a->argv[2]);
+       lim = atoi(a->argv[2]);
+       ast_cli(a->fd, "called astobj_test\n");
 
-       handle_astobj2_stats(fd, 0, NULL);
+       handle_astobj2_stats(e, CLI_HANDLER, &fake_args);
        /*
         * allocate a container with no default callback, and no hash function.
         * No hash means everything goes in the same bucket.
         */
        c1 = ao2_container_alloc(100, NULL /* no callback */, NULL /* no hash */);
-       ast_cli(fd, "container allocated as %p\n", c1);
+       ast_cli(a->fd, "container allocated as %p\n", c1);
 
        /*
         * fill the container with objects.
@@ -651,48 +676,47 @@ static int handle_astobj2_test(int fd, int argc, char *argv[])
                ast_mark(prof_id, 1 /* start */);
                obj = ao2_alloc(80, NULL);
                ast_mark(prof_id, 0 /* stop */);
-               ast_cli(fd, "object %d allocated as %p\n", i, obj);
+               ast_cli(a->fd, "object %d allocated as %p\n", i, obj);
                sprintf(obj, "-- this is obj %d --", i);
                ao2_link(c1, obj);
        }
-       ast_cli(fd, "testing callbacks\n");
-       ao2_callback(c1, 0, print_cb, &fd);
+       ast_cli(a->fd, "testing callbacks\n");
+       ao2_callback(c1, 0, print_cb, &a->fd);
 
-       ast_cli(fd, "testing iterators, remove every second object\n");
+       ast_cli(a->fd, "testing iterators, remove every second object\n");
        {
                struct ao2_iterator ai;
                int x = 0;
 
                ai = ao2_iterator_init(c1, 0);
                while ( (obj = ao2_iterator_next(&ai)) ) {
-                       ast_cli(fd, "iterator on <%s>\n", obj);
+                       ast_cli(a->fd, "iterator on <%s>\n", obj);
                        if (x++ & 1)
                                ao2_unlink(c1, obj);
                        ao2_ref(obj, -1);
                }
-               ast_cli(fd, "testing iterators again\n");
+               ast_cli(a->fd, "testing iterators again\n");
                ai = ao2_iterator_init(c1, 0);
                while ( (obj = ao2_iterator_next(&ai)) ) {
-                       ast_cli(fd, "iterator on <%s>\n", obj);
+                       ast_cli(a->fd, "iterator on <%s>\n", obj);
                        ao2_ref(obj, -1);
                }
        }
-       ast_cli(fd, "testing callbacks again\n");
-       ao2_callback(c1, 0, print_cb, &fd);
+       ast_cli(a->fd, "testing callbacks again\n");
+       ao2_callback(c1, 0, print_cb, &a->fd);
 
        ast_verbose("now you should see an error message:\n");
        ao2_ref(&i, -1);        /* i is not a valid object so we print an error here */
 
-       ast_cli(fd, "destroy container\n");
+       ast_cli(a->fd, "destroy container\n");
        ao2_ref(c1, -1);        /* destroy container */
-       handle_astobj2_stats(fd, 0, NULL);
-       return 0;
+       handle_astobj2_stats(e, CLI_HANDLER, &fake_args);
+       return CLI_SUCCESS;
 }
 
 static struct ast_cli_entry cli_astobj2[] = {
-       { { "astobj2", "stats", NULL },
-       handle_astobj2_stats, "Print astobj2 statistics", },
-       { { "astobj2", "test", NULL } , handle_astobj2_test, "Test astobj2", },
+       NEW_CLI(handle_astobj2_stats, "Print astobj2 statistics"),
+       NEW_CLI(handle_astobj2_test, "Test astobj2"),
 };
 #endif /* AO2_DEBUG */
 
index 12d1e37..3c28b1c 100644 (file)
@@ -1225,64 +1225,74 @@ static void *do_cdr(void *data)
        return NULL;
 }
 
-static int handle_cli_status(int fd, int argc, char *argv[])
+static char *handle_cli_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        struct ast_cdr_beitem *beitem=NULL;
        int cnt=0;
        long nextbatchtime=0;
 
-       if (argc > 2)
-               return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "cdr status";
+               e->usage = 
+                       "Usage: cdr status\n"
+                       "       Displays the Call Detail Record engine system status.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
 
-       ast_cli(fd, "CDR logging: %s\n", enabled ? "enabled" : "disabled");
-       ast_cli(fd, "CDR mode: %s\n", batchmode ? "batch" : "simple");
+       if (a->argc > 2)
+               return CLI_SHOWUSAGE;
+
+       ast_cli(a->fd, "CDR logging: %s\n", enabled ? "enabled" : "disabled");
+       ast_cli(a->fd, "CDR mode: %s\n", batchmode ? "batch" : "simple");
        if (enabled) {
                if (batchmode) {
                        if (batch)
                                cnt = batch->size;
                        if (cdr_sched > -1)
                                nextbatchtime = ast_sched_when(sched, cdr_sched);
-                       ast_cli(fd, "CDR safe shut down: %s\n", batchsafeshutdown ? "enabled" : "disabled");
-                       ast_cli(fd, "CDR batch threading model: %s\n", batchscheduleronly ? "scheduler only" : "scheduler plus separate threads");
-                       ast_cli(fd, "CDR current batch size: %d record%s\n", cnt, ESS(cnt));
-                       ast_cli(fd, "CDR maximum batch size: %d record%s\n", batchsize, ESS(batchsize));
-                       ast_cli(fd, "CDR maximum batch time: %d second%s\n", batchtime, ESS(batchtime));
-                       ast_cli(fd, "CDR next scheduled batch processing time: %ld second%s\n", nextbatchtime, ESS(nextbatchtime));
+                       ast_cli(a->fd, "CDR safe shut down: %s\n", batchsafeshutdown ? "enabled" : "disabled");
+                       ast_cli(a->fd, "CDR batch threading model: %s\n", batchscheduleronly ? "scheduler only" : "scheduler plus separate threads");
+                       ast_cli(a->fd, "CDR current batch size: %d record%s\n", cnt, ESS(cnt));
+                       ast_cli(a->fd, "CDR maximum batch size: %d record%s\n", batchsize, ESS(batchsize));
+                       ast_cli(a->fd, "CDR maximum batch time: %d second%s\n", batchtime, ESS(batchtime));
+                       ast_cli(a->fd, "CDR next scheduled batch processing time: %ld second%s\n", nextbatchtime, ESS(nextbatchtime));
                }
                AST_RWLIST_RDLOCK(&be_list);
                AST_RWLIST_TRAVERSE(&be_list, beitem, list) {
-                       ast_cli(fd, "CDR registered backend: %s\n", beitem->name);
+                       ast_cli(a->fd, "CDR registered backend: %s\n", beitem->name);
                }
                AST_RWLIST_UNLOCK(&be_list);
        }
 
-       return 0;
+       return CLI_SUCCESS;
 }
 
-static int handle_cli_submit(int fd, int argc, char *argv[])
+static char *handle_cli_submit(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-       if (argc > 2)
-               return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "cdr submit";
+               e->usage = 
+                       "Usage: cdr submit\n"
+                       "       Posts all pending batched CDR data to the configured CDR backend engine modules.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+       if (a->argc > 2)
+               return CLI_SHOWUSAGE;
 
        submit_unscheduled_batch();
-       ast_cli(fd, "Submitted CDRs to backend engines for processing.  This may take a while.\n");
+       ast_cli(a->fd, "Submitted CDRs to backend engines for processing.  This may take a while.\n");
 
-       return 0;
+       return CLI_SUCCESS;
 }
 
-static struct ast_cli_entry cli_submit = {
-       { "cdr", "submit", NULL },
-       handle_cli_submit, "Posts all pending batched CDR data",
-       "Usage: cdr submit\n"
-       "       Posts all pending batched CDR data to the configured CDR backend engine modules.\n"
-};
-
-static struct ast_cli_entry cli_status = {
-       { "cdr", "status", NULL },
-       handle_cli_status, "Display the CDR status",
-       "Usage: cdr status\n"
-       "       Displays the Call Detail Record engine system status.\n"
-};
+static struct ast_cli_entry cli_submit = NEW_CLI(handle_cli_submit, "Posts all pending batched CDR data");
+static struct ast_cli_entry cli_status = NEW_CLI(handle_cli_status, "Display the CDR status");
 
 static int do_reload(int reload)
 {
index 9cdf052..9e20971 100644 (file)
@@ -188,60 +188,106 @@ struct ast_variable *ast_channeltype_list(void)
 }
 
 /*! \brief Show channel types - CLI command */
-static int show_channeltypes(int fd, int argc, char *argv[])
+static char *handle_cli_core_show_channeltypes(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 #define FORMAT  "%-10.10s  %-40.40s %-12.12s %-12.12s %-12.12s\n"
        struct chanlist *cl;
        int count_chan = 0;
 
-       ast_cli(fd, FORMAT, "Type", "Description",       "Devicestate", "Indications", "Transfer");
-       ast_cli(fd, FORMAT, "----------", "-----------", "-----------", "-----------", "--------");
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "core show channeltypes";
+               e->usage =
+                       "Usage: core show channeltypes\n"
+                       "       Lists available channel types registered in your\n"
+                       "       Asterisk server.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
+       if (a->argc != 3)
+               return CLI_SHOWUSAGE;
+
+       ast_cli(a->fd, FORMAT, "Type", "Description",       "Devicestate", "Indications", "Transfer");
+       ast_cli(a->fd, FORMAT, "----------", "-----------", "-----------", "-----------", "--------");
        if (AST_RWLIST_RDLOCK(&channels)) {
                ast_log(LOG_WARNING, "Unable to lock channel list\n");
-               return -1;
+               return CLI_FAILURE;
        }
        AST_LIST_TRAVERSE(&backends, cl, list) {
-               ast_cli(fd, FORMAT, cl->tech->type, cl->tech->description,
+               ast_cli(a->fd, FORMAT, cl->tech->type, cl->tech->description,
                        (cl->tech->devicestate) ? "yes" : "no",
                        (cl->tech->indicate) ? "yes" : "no",
                        (cl->tech->transfer) ? "yes" : "no");
                count_chan++;
        }
        AST_RWLIST_UNLOCK(&channels);
-       ast_cli(fd, "----------\n%d channel drivers registered.\n", count_chan);
-       return RESULT_SUCCESS;
+       ast_cli(a->fd, "----------\n%d channel drivers registered.\n", count_chan);
+       return CLI_SUCCESS;
 
 #undef FORMAT
+}
+
+static char *complete_channeltypes(struct ast_cli_args *a)
+{
+       struct chanlist *cl;
+       int which = 0;
+       int wordlen;
+       char *ret = NULL;
+
+       if (a->pos != 3)
+               return NULL;
 
+       wordlen = strlen(a->word);
+
+       AST_LIST_TRAVERSE(&backends, cl, list) {
+               if (!strncasecmp(a->word, cl->tech->type, wordlen) && ++which > a->n) {
+                       ret = ast_strdup(cl->tech->type);
+                       break;
+               }
+       }
+       
+       return ret;
 }
 
 /*! \brief Show details about a channel driver - CLI command */
-static int show_channeltype(int fd, int argc, char *argv[])
+static char *handle_cli_core_show_channeltype(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        struct chanlist *cl = NULL;
 
-       if (argc != 4)
-               return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "core show channeltype";
+               e->usage =
+                       "Usage: core show channeltype <name>\n"
+                       "       Show details about the specified channel type, <name>.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return complete_channeltypes(a);
+       }
+
+       if (a->argc != 4)
+               return CLI_SHOWUSAGE;
        
        if (AST_RWLIST_RDLOCK(&channels)) {
                ast_log(LOG_WARNING, "Unable to lock channel list\n");
-               return RESULT_FAILURE;
+               return CLI_FAILURE;
        }
 
        AST_LIST_TRAVERSE(&backends, cl, list) {
-               if (!strncasecmp(cl->tech->type, argv[3], strlen(cl->tech->type))) {
+               if (!strncasecmp(cl->tech->type, a->argv[3], strlen(cl->tech->type)))
                        break;
-               }
        }
 
 
        if (!cl) {
-               ast_cli(fd, "\n%s is not a registered channel driver.\n", argv[3]);
+               ast_cli(a->fd, "\n%s is not a registered channel driver.\n", a->argv[3]);
                AST_RWLIST_UNLOCK(&channels);
-               return RESULT_FAILURE;
+               return CLI_FAILURE;
        }
 
-       ast_cli(fd,
+       ast_cli(a->fd,
                "-- Info about channel driver: %s --\n"
                "  Device State: %s\n"
                "    Indication: %s\n"
@@ -266,47 +312,12 @@ static int show_channeltype(int fd, int argc, char *argv[])
        );
 
        AST_RWLIST_UNLOCK(&channels);
-       return RESULT_SUCCESS;
-}
-
-static char *complete_channeltypes(const char *line, const char *word, int pos, int state)
-{
-       struct chanlist *cl;
-       int which = 0;
-       int wordlen;
-       char *ret = NULL;
-
-       if (pos != 3)
-               return NULL;
-
-       wordlen = strlen(word);
-
-       AST_LIST_TRAVERSE(&backends, cl, list) {
-               if (!strncasecmp(word, cl->tech->type, wordlen) && ++which > state) {
-                       ret = ast_strdup(cl->tech->type);
-                       break;
-               }
-       }
-       
-       return ret;
+       return CLI_SUCCESS;
 }
 
-static const char show_channeltypes_usage[] =
-"Usage: core show channeltypes\n"
-"       Lists available channel types registered in your Asterisk server.\n";
-
-static const char show_channeltype_usage[] =
-"Usage: core show channeltype <name>\n"
-"      Show details about the specified channel type, <name>.\n";
-
 static struct ast_cli_entry cli_channel[] = {
-       { { "core", "show", "channeltypes", NULL },
-       show_channeltypes, "List available channel types",
-       show_channeltypes_usage },
-
-       { { "core", "show", "channeltype", NULL },
-       show_channeltype, "Give more details on that channel type",
-       show_channeltype_usage, complete_channeltypes },
+       NEW_CLI(handle_cli_core_show_channeltypes, "List available channel types"),
+       NEW_CLI(handle_cli_core_show_channeltype,  "Give more details on that channel type")
 };
 
 /*! \brief Checks to see if a channel is needing hang up */
index 7e7514a..da4c25f 100644 (file)
@@ -123,22 +123,6 @@ unsigned int ast_verbose_get_by_file(const char *file)
 
 static AST_RWLIST_HEAD_STATIC(helpers, ast_cli_entry);
 
-static const char logger_mute_help[] = 
-"Usage: logger mute\n"
-"       Disables logging output to the current console, making it possible to\n"
-"       gather information without being disturbed by scrolling lines.\n";
-
-static const char softhangup_help[] =
-"Usage: soft hangup <channel>\n"
-"       Request that a channel be hung up. The hangup takes effect\n"
-"       the next time the driver reads or writes from the channel\n";
-
-static const char group_show_channels_help[] = 
-"Usage: group show channels [pattern]\n"
-"       Lists all currently active channels with channel group(s) specified.\n"
-"       Optional regular expression pattern is matched to group names for each\n"
-"       channel.\n";
-
 static char *complete_fn(const char *word, int state)
 {
        char *c;
@@ -373,12 +357,24 @@ done:
        return CLI_SUCCESS;
 }
 
-static int handle_logger_mute(int fd, int argc, char *argv[])
+static char *handle_logger_mute(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-       if (argc != 2)
-               return RESULT_SHOWUSAGE;
-       ast_console_toggle_mute(fd);
-       return RESULT_SUCCESS;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "logger mute";
+               e->usage = 
+                       "Usage: logger mute\n"
+                       "       Disables logging output to the current console, making it possible to\n"
+                       "       gather information without being disturbed by scrolling lines.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
+       if (a->argc != 2)
+               return CLI_SHOWUSAGE;
+       ast_console_toggle_mute(a->fd);
+       return CLI_SUCCESS;
 }
 
 static char *handle_unload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
@@ -690,56 +686,61 @@ static char *handle_chanlist(struct ast_cli_entry *e, int cmd, struct ast_cli_ar
 #undef VERBOSE_FORMAT_STRING2
 }
 
-static const char showchan_help[] = 
-"Usage: core show channel <channel>\n"
-"       Shows lots of information about the specified channel.\n";
-
-static const char commandcomplete_help[] = 
-"Usage: _command complete \"<line>\" text state\n"
-"       This function is used internally to help with command completion and should.\n"
-"       never be called by the user directly.\n";
-
-static const char commandnummatches_help[] = 
-"Usage: _command nummatches \"<line>\" text \n"
-"       This function is used internally to help with command completion and should.\n"
-"       never be called by the user directly.\n";
-
-static const char commandmatchesarray_help[] = 
-"Usage: _command matchesarray \"<line>\" text \n"
-"       This function is used internally to help with command completion and should.\n"
-"       never be called by the user directly.\n";
-
-static int handle_softhangup(int fd, int argc, char *argv[])
+static char *handle_softhangup(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        struct ast_channel *c=NULL;
-       if (argc != 3)
-               return RESULT_SHOWUSAGE;
-       c = ast_get_channel_by_name_locked(argv[2]);
+
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "soft hangup";
+               e->usage =
+                       "Usage: soft hangup <channel>\n"
+                       "       Request that a channel be hung up. The hangup takes effect\n"
+                       "       the next time the driver reads or writes from the channel\n";
+               return NULL;
+       case CLI_GENERATE:
+               return ast_complete_channels(a->line, a->word, a->pos, a->n, 2);
+       }
+       if (a->argc != 3)
+               return CLI_SHOWUSAGE;
+       c = ast_get_channel_by_name_locked(a->argv[2]);
        if (c) {
-               ast_cli(fd, "Requested Hangup on channel '%s'\n", c->name);
+               ast_cli(a->fd, "Requested Hangup on channel '%s'\n", c->name);
                ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT);
                ast_channel_unlock(c);
        } else
-               ast_cli(fd, "%s is not a known channel\n", argv[2]);
-       return RESULT_SUCCESS;
+               ast_cli(a->fd, "%s is not a known channel\n", a->argv[2]);
+       return CLI_SUCCESS;
 }
 
 static char *__ast_cli_generator(const char *text, const char *word, int state, int lock);
 
-static int handle_commandmatchesarray(int fd, int argc, char *argv[])
+static char *handle_commandmatchesarray(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        char *buf, *obuf;
        int buflen = 2048;
        int len = 0;
        char **matches;
        int x, matchlen;
+       
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "_command matchesarray";
+               e->usage = 
+                       "Usage: _command matchesarray \"<line>\" text \n"
+                       "       This function is used internally to help with command completion and should.\n"
+                       "       never be called by the user directly.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
 
-       if (argc != 4)
-               return RESULT_SHOWUSAGE;
+       if (a->argc != 4)
+               return CLI_SHOWUSAGE;
        if (!(buf = ast_malloc(buflen)))
-               return RESULT_FAILURE;
+               return CLI_FAILURE;
        buf[len] = '\0';
-       matches = ast_cli_completion_matches(argv[2], argv[3]);
+       matches = ast_cli_completion_matches(a->argv[2], a->argv[3]);
        if (matches) {
                for (x=0; matches[x]; x++) {
                        matchlen = strlen(matches[x]) + 1;
@@ -759,43 +760,65 @@ static int handle_commandmatchesarray(int fd, int argc, char *argv[])
        }
 
        if (buf) {
-               ast_cli(fd, "%s%s",buf, AST_CLI_COMPLETE_EOF);
+               ast_cli(a->fd, "%s%s",buf, AST_CLI_COMPLETE_EOF);
                ast_free(buf);
        } else
-               ast_cli(fd, "NULL\n");
+               ast_cli(a->fd, "NULL\n");
 
-       return RESULT_SUCCESS;
+       return CLI_SUCCESS;
 }
 
 
 
-static int handle_commandnummatches(int fd, int argc, char *argv[])
+static char *handle_commandnummatches(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        int matches = 0;
 
-       if (argc != 4)
-               return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "_command nummatches";
+               e->usage = 
+                       "Usage: _command nummatches \"<line>\" text \n"
+                       "       This function is used internally to help with command completion and should.\n"
+                       "       never be called by the user directly.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
+       if (a->argc != 4)
+               return CLI_SHOWUSAGE;
 
-       matches = ast_cli_generatornummatches(argv[2], argv[3]);
+       matches = ast_cli_generatornummatches(a->argv[2], a->argv[3]);
 
-       ast_cli(fd, "%d", matches);
+       ast_cli(a->fd, "%d", matches);
 
-       return RESULT_SUCCESS;
+       return CLI_SUCCESS;
 }
 
-static int handle_commandcomplete(int fd, int argc, char *argv[])
+static char *handle_commandcomplete(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        char *buf;
-
-       if (argc != 5)
-               return RESULT_SHOWUSAGE;
-       buf = __ast_cli_generator(argv[2], argv[3], atoi(argv[4]), 0);
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "_command complete";
+               e->usage = 
+                       "Usage: _command complete \"<line>\" text state\n"
+                       "       This function is used internally to help with command completion and should.\n"
+                       "       never be called by the user directly.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+       if (a->argc != 5)
+               return CLI_SHOWUSAGE;
+       buf = __ast_cli_generator(a->argv[2], a->argv[3], atoi(a->argv[4]), 0);
        if (buf) {
-               ast_cli(fd, buf);
+               ast_cli(a->fd, buf);
                ast_free(buf);
        } else
-               ast_cli(fd, "NULL\n");
-       return RESULT_SUCCESS;
+               ast_cli(a->fd, "NULL\n");
+       return CLI_SUCCESS;
 }
 
 static char *handle_core_set_debug_channel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
@@ -891,7 +914,7 @@ static char *handle_nodebugchan_deprecated(struct ast_cli_entry *e, int cmd, str
        return res;
 }
                
-static int handle_showchan(int fd, int argc, char *argv[])
+static char *handle_showchan(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        struct ast_channel *c=NULL;
        struct timeval now;
@@ -900,14 +923,25 @@ static int handle_showchan(int fd, int argc, char *argv[])
        char nf[256], wf[256], rf[256];
        long elapsed_seconds=0;
        int hour=0, min=0, sec=0;
+
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "core show channel";
+               e->usage = 
+                       "Usage: core show channel <channel>\n"
+                       "       Shows lots of information about the specified channel.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return ast_complete_channels(a->line, a->word, a->pos, a->n, 3);
+       }
        
-       if (argc != 4)
-               return RESULT_SHOWUSAGE;
+       if (a->argc != 4)
+               return CLI_SHOWUSAGE;
        now = ast_tvnow();
-       c = ast_get_channel_by_name_locked(argv[3]);
+       c = ast_get_channel_by_name_locked(a->argv[3]);
        if (!c) {
-               ast_cli(fd, "%s is not a known channel\n", argv[3]);
-               return RESULT_SUCCESS;
+               ast_cli(a->fd, "%s is not a known channel\n", a->argv[3]);
+               return CLI_SUCCESS;
        }
        if (c->cdr) {
                elapsed_seconds = now.tv_sec - c->cdr->start.tv_sec;
@@ -917,7 +951,7 @@ static int handle_showchan(int fd, int argc, char *argv[])
                snprintf(cdrtime, sizeof(cdrtime), "%dh%dm%ds", hour, min, sec);
        } else
                strcpy(cdrtime, "N/A");
-       ast_cli(fd, 
+       ast_cli(a->fd, 
                " -- General --\n"
                "           Name: %s\n"
                "           Type: %s\n"
@@ -970,12 +1004,12 @@ static int handle_showchan(int fd, int argc, char *argv[])
                (ast_test_flag(c, AST_FLAG_BLOCKING) ? c->blockproc : "(Not Blocking)"));
        
        if (pbx_builtin_serialize_variables(c, &out))
-               ast_cli(fd,"      Variables:\n%s\n", out->str);
+               ast_cli(a->fd,"      Variables:\n%s\n", out->str);
        if (c->cdr && ast_cdr_serialize_variables(c->cdr, &out, '=', '\n', 1))
-               ast_cli(fd,"  CDR Variables:\n%s\n", out->str);
+               ast_cli(a->fd,"  CDR Variables:\n%s\n", out->str);
        
        ast_channel_unlock(c);
-       return RESULT_SUCCESS;
+       return CLI_SUCCESS;
 }
 
 /*
@@ -1015,17 +1049,7 @@ char *ast_complete_channels(const char *line, const char *word, int pos, int sta
        return ret == &notfound ? NULL : ret;
 }
 
-static char *complete_ch_3(const char *line, const char *word, int pos, int state)
-{
-       return ast_complete_channels(line, word, pos, state, 2);
-}
-
-static char *complete_ch_4(const char *line, const char *word, int pos, int state)
-{
-       return ast_complete_channels(line, word, pos, state, 3);
-}
-
-static int group_show_channels(int fd, int argc, char *argv[])
+static char *group_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 #define FORMAT_STRING  "%-25s  %-20s  %-20s\n"
 
@@ -1034,23 +1058,36 @@ static int group_show_channels(int fd, int argc, char *argv[])
        regex_t regexbuf;
        int havepattern = 0;
 
-       if (argc < 3 || argc > 4)
-               return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "group show channels";
+               e->usage = 
+                       "Usage: group show channels [pattern]\n"
+                       "       Lists all currently active channels with channel group(s) specified.\n"
+                       "       Optional regular expression pattern is matched to group names for each\n"
+                       "       channel.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
+       if (a->argc < 3 || a->argc > 4)
+               return CLI_SHOWUSAGE;
        
-       if (argc == 4) {
-               if (regcomp(&regexbuf, argv[3], REG_EXTENDED | REG_NOSUB))
-                       return RESULT_SHOWUSAGE;
+       if (a->argc == 4) {
+               if (regcomp(&regexbuf, a->argv[3], REG_EXTENDED | REG_NOSUB))
+                       return CLI_SHOWUSAGE;
                havepattern = 1;
        }
 
-       ast_cli(fd, FORMAT_STRING, "Channel", "Group", "Category");
+       ast_cli(a->fd, FORMAT_STRING, "Channel", "Group", "Category");
 
        ast_app_group_list_rdlock();
        
        gi = ast_app_group_list_head();
        while (gi) {
                if (!havepattern || !regexec(&regexbuf, gi->group, 0, NULL, 0)) {
-                       ast_cli(fd, FORMAT_STRING, gi->chan->name, gi->group, (ast_strlen_zero(gi->category) ? "(default)" : gi->category));
+                       ast_cli(a->fd, FORMAT_STRING, gi->chan->name, gi->group, (ast_strlen_zero(gi->category) ? "(default)" : gi->category));
                        numchans++;
                }
                gi = AST_LIST_NEXT(gi, list);
@@ -1061,8 +1098,8 @@ static int group_show_channels(int fd, int argc, char *argv[])
        if (havepattern)
                regfree(&regexbuf);
 
-       ast_cli(fd, "%d active channel%s\n", numchans, ESS(numchans));
-       return RESULT_SUCCESS;
+       ast_cli(a->fd, "%d active channel%s\n", numchans, ESS(numchans));
+       return CLI_SUCCESS;
 #undef FORMAT_STRING
 }
 
@@ -1072,18 +1109,9 @@ static int group_show_channels(int fd, int argc, char *argv[])
  */
 static struct ast_cli_entry builtins[] = {
        /* Keep alphabetized, with longer matches first (example: abcd before abc) */
-       { { "_command", "complete", NULL },
-       handle_commandcomplete, "Command complete",
-       commandcomplete_help },
-
-       { { "_command", "nummatches", NULL },
-       handle_commandnummatches, "Returns number of command matches",
-       commandnummatches_help },
-
-       { { "_command", "matchesarray", NULL },
-       handle_commandmatchesarray, "Returns command matches array",
-       commandmatchesarray_help },
-
+       NEW_CLI(handle_commandcomplete, "Command complete"),
+       NEW_CLI(handle_commandnummatches, "Returns number of command matches"),
+       NEW_CLI(handle_commandmatchesarray, "Returns command matches array"),
        { { NULL }, NULL, NULL, NULL }
 };
 
@@ -1100,24 +1128,18 @@ static struct ast_cli_entry cli_cli[] = {
 
        NEW_CLI(handle_chanlist, "Display information on channels"),
 
-       { { "core", "show", "channel", NULL },
-       handle_showchan, "Display information on a specific channel",
-       showchan_help, complete_ch_4 },
+       NEW_CLI(handle_showchan, "Display information on a specific channel"),
 
        NEW_CLI(handle_core_set_debug_channel, "Enable/disable debugging on a channel",
                .deprecate_cmd = &cli_debug_channel_deprecated),
 
        NEW_CLI(handle_verbose, "Set level of debug/verbose chattiness"),
 
-       { { "group", "show", "channels", NULL },
-       group_show_channels, "Display active channels with group(s)",
-       group_show_channels_help },
+       NEW_CLI(group_show_channels, "Display active channels with group(s)"),
 
        NEW_CLI(handle_help, "Display help list, or specific help on a command"),
 
-       { { "logger", "mute", NULL },
-       handle_logger_mute, "Toggle logging output to a console",
-       logger_mute_help },
+       NEW_CLI(handle_logger_mute, "Toggle logging output to a console"),
 
        NEW_CLI(handle_modlist, "List modules and info"),
 
@@ -1129,9 +1151,7 @@ static struct ast_cli_entry cli_cli[] = {
 
        NEW_CLI(handle_showuptime, "Show uptime information"),
 
-       { { "soft", "hangup", NULL },
-       handle_softhangup, "Request a hangup on a given channel",
-       softhangup_help, complete_ch_3 },
+       NEW_CLI(handle_softhangup, "Request a hangup on a given channel"),
 };
 
 /*!
index c38d8c8..58245c2 100644 (file)
--- a/main/db.c
+++ b/main/db.c
@@ -240,68 +240,120 @@ int ast_db_del(const char *family, const char *keys)
        return res;
 }
 
-static int database_put(int fd, int argc, char *argv[])
+static char *handle_cli_database_put(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        int res;
-       if (argc != 5)
-               return RESULT_SHOWUSAGE;
-       res = ast_db_put(argv[2], argv[3], argv[4]);
+
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "database put";
+               e->usage =
+                       "Usage: database put <family> <key> <value>\n"
+                       "       Adds or updates an entry in the Asterisk database for\n"
+                       "       a given family, key, and value.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
+       if (a->argc != 5)
+               return CLI_SHOWUSAGE;
+       res = ast_db_put(a->argv[2], a->argv[3], a->argv[4]);
        if (res)  {
-               ast_cli(fd, "Failed to update entry\n");
+               ast_cli(a->fd, "Failed to update entry\n");
        } else {
-               ast_cli(fd, "Updated database successfully\n");
+               ast_cli(a->fd, "Updated database successfully\n");
        }
-       return RESULT_SUCCESS;
+       return CLI_SUCCESS;
 }
 
-static int database_get(int fd, int argc, char *argv[])
+static char *handle_cli_database_get(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        int res;
        char tmp[256];
-       if (argc != 4)
-               return RESULT_SHOWUSAGE;
-       res = ast_db_get(argv[2], argv[3], tmp, sizeof(tmp));
+
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "database get";
+               e->usage =
+                       "Usage: database get <family> <key>\n"
+                       "       Retrieves an entry in the Asterisk database for a given\n"
+                       "       family and key.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
+       if (a->argc != 4)
+               return CLI_SHOWUSAGE;
+       res = ast_db_get(a->argv[2], a->argv[3], tmp, sizeof(tmp));
        if (res) {
-               ast_cli(fd, "Database entry not found.\n");
+               ast_cli(a->fd, "Database entry not found.\n");
        } else {
-               ast_cli(fd, "Value: %s\n", tmp);
+               ast_cli(a->fd, "Value: %s\n", tmp);
        }
-       return RESULT_SUCCESS;
+       return CLI_SUCCESS;
 }
 
-static int database_del(int fd, int argc, char *argv[])
+static char *handle_cli_database_del(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        int res;
-       if (argc != 4)
-               return RESULT_SHOWUSAGE;
-       res = ast_db_del(argv[2], argv[3]);
+
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "database del";
+               e->usage =
+                       "Usage: database del <family> <key>\n"
+                       "       Deletes an entry in the Asterisk database for a given\n"
+                       "       family and key.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
+       if (a->argc != 4)
+               return CLI_SHOWUSAGE;
+       res = ast_db_del(a->argv[2], a->argv[3]);
        if (res) {
-               ast_cli(fd, "Database entry does not exist.\n");
+               ast_cli(a->fd, "Database entry does not exist.\n");
        } else {
-               ast_cli(fd, "Database entry removed.\n");
+               ast_cli(a->fd, "Database entry removed.\n");
        }
-       return RESULT_SUCCESS;
+       return CLI_SUCCESS;
 }
 
-static int database_deltree(int fd, int argc, char *argv[])
+static char *handle_cli_database_deltree(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        int res;
-       if ((argc < 3) || (argc > 4))
-               return RESULT_SHOWUSAGE;
-       if (argc == 4) {
-               res = ast_db_deltree(argv[2], argv[3]);
+
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "database deltree";
+               e->usage =
+                       "Usage: database deltree <family> [keytree]\n"
+                       "       Deletes a family or specific keytree within a family\n"
+                       "       in the Asterisk database.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
+       if ((a->argc < 3) || (a->argc > 4))
+               return CLI_SHOWUSAGE;
+       if (a->argc == 4) {
+               res = ast_db_deltree(a->argv[2], a->argv[3]);
        } else {
-               res = ast_db_deltree(argv[2], NULL);
+               res = ast_db_deltree(a->argv[2], NULL);
        }
        if (res < 0) {
-               ast_cli(fd, "Database entries do not exist.\n");
+               ast_cli(a->fd, "Database entries do not exist.\n");
        } else {
-               ast_cli(fd, "%d database entries removed.\n",res);
+               ast_cli(a->fd, "%d database entries removed.\n",res);
        }
-       return RESULT_SUCCESS;
+       return CLI_SUCCESS;
 }
 
-static int database_show(int fd, int argc, char *argv[])
+static char *handle_cli_database_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        char prefix[256];
        DBT key, data;
@@ -310,23 +362,35 @@ static int database_show(int fd, int argc, char *argv[])
        int pass;
        int counter = 0;
 
-       if (argc == 4) {
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "database show";
+               e->usage =
+                       "Usage: database show [family [keytree]]\n"
+                       "       Shows Asterisk database contents, optionally restricted\n"
+                       "       to a given family, or family and keytree.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
+       if (a->argc == 4) {
                /* Family and key tree */
-               snprintf(prefix, sizeof(prefix), "/%s/%s", argv[2], argv[3]);
-       } else if (argc == 3) {
+               snprintf(prefix, sizeof(prefix), "/%s/%s", a->argv[2], a->argv[3]);
+       } else if (a->argc == 3) {
                /* Family only */
-               snprintf(prefix, sizeof(prefix), "/%s", argv[2]);
-       } else if (argc == 2) {
+               snprintf(prefix, sizeof(prefix), "/%s", a->argv[2]);
+       } else if (a->argc == 2) {
                /* Neither */
                prefix[0] = '\0';
        } else {
-               return RESULT_SHOWUSAGE;
+               return CLI_SHOWUSAGE;
        }
        ast_mutex_lock(&dblock);
        if (dbinit()) {
                ast_mutex_unlock(&dblock);
-               ast_cli(fd, "Database unavailable\n");
-               return RESULT_SUCCESS;  
+               ast_cli(a->fd, "Database unavailable\n");
+               return CLI_SUCCESS;     
        }
        memset(&key, 0, sizeof(key));
        memset(&data, 0, sizeof(data));
@@ -345,16 +409,16 @@ static int database_show(int fd, int argc, char *argv[])
                        values = "<bad value>";
                }
                if (keymatch(keys, prefix)) {
-                       ast_cli(fd, "%-50s: %-25s\n", keys, values);
+                       ast_cli(a->fd, "%-50s: %-25s\n", keys, values);
                        counter++;
                }
        }
        ast_mutex_unlock(&dblock);
-       ast_cli(fd, "%d results found.\n", counter);
-       return RESULT_SUCCESS;  
+       ast_cli(a->fd, "%d results found.\n", counter);
+       return CLI_SUCCESS;     
 }
 
-static int database_showkey(int fd, int argc, char *argv[])
+static char *handle_cli_database_showkey(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        char suffix[256];
        DBT key, data;
@@ -363,17 +427,28 @@ static int database_showkey(int fd, int argc, char *argv[])
        int pass;
        int counter = 0;
 
-       if (argc == 3) {
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "database show";
+               e->usage =
+                       "Usage: database showkey <keytree>\n"
+                       "       Shows Asterisk database contents, restricted to a given key.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
+       if (a->argc == 3) {
                /* Key only */
-               snprintf(suffix, sizeof(suffix), "/%s", argv[2]);
+               snprintf(suffix, sizeof(suffix), "/%s", a->argv[2]);
        } else {
-               return RESULT_SHOWUSAGE;
+               return CLI_SHOWUSAGE;
        }
        ast_mutex_lock(&dblock);
        if (dbinit()) {
                ast_mutex_unlock(&dblock);
-               ast_cli(fd, "Database unavailable\n");
-               return RESULT_SUCCESS;  
+               ast_cli(a->fd, "Database unavailable\n");
+               return CLI_SUCCESS;     
        }
        memset(&key, 0, sizeof(key));
        memset(&data, 0, sizeof(data));
@@ -392,13 +467,13 @@ static int database_showkey(int fd, int argc, char *argv[])
                        values = "<bad value>";
                }
                if (subkeymatch(keys, suffix)) {
-                       ast_cli(fd, "%-50s: %-25s\n", keys, values);
+                       ast_cli(a->fd, "%-50s: %-25s\n", keys, values);
                        counter++;
                }
        }
        ast_mutex_unlock(&dblock);
-       ast_cli(fd, "%d results found.\n", counter);
-       return RESULT_SUCCESS;  
+       ast_cli(a->fd, "%d results found.\n", counter);
+       return CLI_SUCCESS;     
 }
 
 struct ast_db_entry *ast_db_gettree(const char *family, const char *keytree)
@@ -473,59 +548,13 @@ void ast_db_freetree(struct ast_db_entry *dbe)
        }
 }
 
-static const char database_show_usage[] =
-"Usage: database show [family [keytree]]\n"
-"       Shows Asterisk database contents, optionally restricted\n"
-"to a given family, or family and keytree.\n";
-
-static const char database_showkey_usage[] =
-"Usage: database showkey <keytree>\n"
-"       Shows Asterisk database contents, restricted to a given key.\n";
-
-static const char database_put_usage[] =
-"Usage: database put <family> <key> <value>\n"
-"       Adds or updates an entry in the Asterisk database for\n"
-"a given family, key, and value.\n";
-
-static const char database_get_usage[] =
-"Usage: database get <family> <key>\n"
-"       Retrieves an entry in the Asterisk database for a given\n"
-"family and key.\n";
-
-static const char database_del_usage[] =
-"Usage: database del <family> <key>\n"
-"       Deletes an entry in the Asterisk database for a given\n"
-"family and key.\n";
-
-static const char database_deltree_usage[] =
-"Usage: database deltree <family> [keytree]\n"
-"       Deletes a family or specific keytree within a family\n"
-"in the Asterisk database.\n";
-
 struct ast_cli_entry cli_database[] = {
-       { { "database", "show", NULL },
-       database_show, "Shows database contents",
-       database_show_usage },
-
-       { { "database", "showkey", NULL },
-       database_showkey, "Shows database contents",
-       database_showkey_usage },
-
-       { { "database", "get", NULL },
-       database_get, "Gets database value",
-       database_get_usage },
-
-       { { "database", "put", NULL },
-       database_put, "Adds/updates database value",
-       database_put_usage },
-
-       { { "database", "del", NULL },
-       database_del, "Removes database key/value",
-       database_del_usage },
-
-       { { "database", "deltree", NULL },
-       database_deltree, "Removes database keytree/values",
-       database_deltree_usage },
+       NEW_CLI(handle_cli_database_show,    "Shows database contents"),
+       NEW_CLI(handle_cli_database_showkey, "Shows database contents"),
+       NEW_CLI(handle_cli_database_get,     "Gets database value"),
+       NEW_CLI(handle_cli_database_put,     "Adds/updates database value"),
+       NEW_CLI(handle_cli_database_del,     "Removes database key/value"),
+       NEW_CLI(handle_cli_database_deltree, "Removes database keytree/values")
 };
 
 static int manager_dbput(struct mansession *s, const struct message *m)
index 19f50bf..93763c8 100644 (file)
@@ -1202,37 +1202,44 @@ int ast_stream_and_wait(struct ast_channel *chan, const char *file, const char *
         return res;
 } 
 
-static int show_file_formats(int fd, int argc, char *argv[])
+static char *handle_cli_core_show_file_formats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 #define FORMAT "%-10s %-10s %-20s\n"
 #define FORMAT2 "%-10s %-10s %-20s\n"
        struct ast_format *f;
        int count_fmt = 0;
 
-       if (argc != 4)
-               return RESULT_SHOWUSAGE;
-       ast_cli(fd, FORMAT, "Format", "Name", "Extensions");
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "core show file formats";
+               e->usage =
+                       "Usage: core show file formats\n"
+                       "       Displays currently registered file formats (if any).\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
+       if (a->argc != 4)
+               return CLI_SHOWUSAGE;
+
+       ast_cli(a->fd, FORMAT, "Format", "Name", "Extensions");
+       ast_cli(a->fd, FORMAT, "------", "----", "----------");
 
        AST_RWLIST_RDLOCK(&formats);
        AST_RWLIST_TRAVERSE(&formats, f, list) {
-               ast_cli(fd, FORMAT2, ast_getformatname(f->format), f->name, f->exts);
+               ast_cli(a->fd, FORMAT2, ast_getformatname(f->format), f->name, f->exts);
                count_fmt++;
        }
        AST_RWLIST_UNLOCK(&formats);
-       ast_cli(fd, "%d file formats registered.\n", count_fmt);
-       return RESULT_SUCCESS;
+       ast_cli(a->fd, "%d file formats registered.\n", count_fmt);
+       return CLI_SUCCESS;
 #undef FORMAT
 #undef FORMAT2
 }
 
-static const char show_file_formats_usage[] = 
-"Usage: core show file formats\n"
-"       Displays currently registered file formats (if any)\n";
-
 struct ast_cli_entry cli_file[] = {
-       { { "core", "show", "file", "formats" },
-       show_file_formats, "Displays file formats",
-       show_file_formats_usage },
+       NEW_CLI(handle_cli_core_show_file_formats, "Displays file formats")
 };
 
 int ast_file_init(void)
index 718d463..0530ec5 100644 (file)
@@ -179,27 +179,39 @@ int ast_send_image(struct ast_channel *chan, char *filename)
        return res;
 }
 
-static int show_image_formats(int fd, int argc, char *argv[])
+static char *handle_core_show_image_formats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 #define FORMAT "%10s %10s %50s %10s\n"
 #define FORMAT2 "%10s %10s %50s %10s\n"
        struct ast_imager *i;
-       if (argc != 4)
-               return RESULT_SHOWUSAGE;
-       ast_cli(fd, FORMAT, "Name", "Extensions", "Description", "Format");
+       int count_fmt = 0;
+
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "core show image formats";
+               e->usage =
+                       "Usage: core show image formats\n"
+                       "       Displays currently registered image formats (if any).\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+       if (a->argc != 4)
+               return CLI_SHOWUSAGE;
+       ast_cli(a->fd, FORMAT, "Name", "Extensions", "Description", "Format");
+       ast_cli(a->fd, FORMAT, "----", "----------", "-----------", "------");
        AST_RWLIST_RDLOCK(&imagers);
        AST_RWLIST_TRAVERSE(&imagers, i, list) {
-               ast_cli(fd, FORMAT2, i->name, i->exts, i->desc, ast_getformatname(i->format));
+               ast_cli(a->fd, FORMAT2, i->name, i->exts, i->desc, ast_getformatname(i->format));
+               count_fmt++;
        }
        AST_RWLIST_UNLOCK(&imagers);
-       return RESULT_SUCCESS;
+       ast_cli(a->fd, "\n%d image format%s registered.\n", count_fmt, count_fmt == 1 ? "" : "s");
+       return CLI_SUCCESS;
 }
 
 struct ast_cli_entry cli_image[] = {
-       { { "core", "show", "image", "formats" },
-       show_image_formats, "Displays image formats",
-       "Usage: core show image formats\n"
-       "       displays currently registered image formats (if any)\n" },
+       NEW_CLI(handle_core_show_image_formats, "Displays image formats")
 };
 
 int ast_image_init(void)
index 26f3e1c..de3e9e0 100644 (file)
@@ -104,15 +104,30 @@ void __ast_threadstorage_object_replace(void *key_old, void *key_new, size_t len
        AST_RWLIST_UNLOCK(&tls_objects);
 }
 
-static int handle_show_allocations(int fd, int argc, char *argv[])
+static char *handle_cli_threadstorage_show_allocations(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        char *fn = NULL;
        size_t len = 0;
        unsigned int count = 0;
        struct tls_object *to;
 
-       if (argc > 3)
-               fn = argv[3];
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "threadstorage show allocations";
+               e->usage =
+                       "Usage: threadstorage show allocations [<file>]\n"
+                       "       Dumps a list of all thread-specific memory allocations,\n"
+                       "       optionally limited to those from a specific file\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
+       if (a->argc > 4)
+               return CLI_SHOWUSAGE;
+
+       if (a->argc > 3)
+               fn = a->argv[3];
 
        AST_RWLIST_RDLOCK(&tls_objects);
 
@@ -120,7 +135,7 @@ static int handle_show_allocations(int fd, int argc, char *argv[])
                if (fn && strcasecmp(to->file, fn))
                        continue;
 
-               ast_cli(fd, "%10d bytes allocated in %20s at line %5d of %25s (thread %p)\n",
+               ast_cli(a->fd, "%10d bytes allocated in %20s at line %5d of %25s (thread %p)\n",
                        (int) to->size, to->function, to->line, to->file, (void *) to->thread);
                len += to->size;
                count++;
@@ -128,12 +143,12 @@ static int handle_show_allocations(int fd, int argc, char *argv[])
 
        AST_RWLIST_UNLOCK(&tls_objects);
 
-       ast_cli(fd, "%10d bytes allocated in %d allocation%s\n", (int) len, count, count > 1 ? "s" : "");
+       ast_cli(a->fd, "%10d bytes allocated in %d allocation%s\n", (int) len, count, count > 1 ? "s" : "");
        
-       return RESULT_SUCCESS;
+       return CLI_SUCCESS;
 }
 
-static int handle_show_summary(int fd, int argc, char *argv[])
+static char *handle_cli_threadstorage_show_summary(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        char *fn = NULL;
        size_t len = 0;
@@ -145,10 +160,26 @@ static int handle_show_summary(int fd, int argc, char *argv[])
                unsigned int count;
                AST_LIST_ENTRY(file) entry;
        } *file;
+
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "threadstorage show summary";
+               e->usage =
+                       "Usage: threadstorage show summary [<file>]\n"
+                       "       Summarizes thread-specific memory allocations by file, or optionally\n"
+                       "       by function, if a file is specified\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
+       if (a->argc > 4)
+               return CLI_SHOWUSAGE;
+
        AST_LIST_HEAD_NOLOCK_STATIC(file_summary, file);
 
-       if (argc > 3)
-               fn = argv[3];
+       if (a->argc > 3)
+               fn = a->argv[3];
 
        AST_RWLIST_RDLOCK(&tls_objects);
 
@@ -178,38 +209,22 @@ static int handle_show_summary(int fd, int argc, char *argv[])
                len += file->len;
                count += file->count;
                if (fn) {
-                       ast_cli(fd, "%10d bytes in %d allocation%ss in function %s\n",
+                       ast_cli(a->fd, "%10d bytes in %d allocation%ss in function %s\n",
                                (int) file->len, file->count, file->count > 1 ? "s" : "", file->name);
                } else {
-                       ast_cli(fd, "%10d bytes in %d allocation%s in file %s\n",
+                       ast_cli(a->fd, "%10d bytes in %d allocation%s in file %s\n",
                                (int) file->len, file->count, file->count > 1 ? "s" : "", file->name);
                }
        }
 
-       ast_cli(fd, "%10d bytes allocated in %d allocation%s\n", (int) len, count, count > 1 ? "s" : "");
-       
-       return RESULT_SUCCESS;
+       ast_cli(a->fd, "%10d bytes allocated in %d allocation%s\n", (int) len, count, count > 1 ? "s" : "");
+
+       return CLI_SUCCESS;
 }
 
 static struct ast_cli_entry cli[] = {
-       {
-               .cmda = { "threadstorage", "show", "allocations", NULL },
-               .handler = handle_show_allocations,
-               .summary = "Display outstanding thread local storage allocations",
-               .usage =
-               "Usage: threadstorage show allocations [<file>]\n"
-               "       Dumps a list of all thread-specific memory allocations,\n"
-               "optionally limited to those from a specific file\n",
-       },
-       {
-               .cmda = { "threadstorage", "show", "summary", NULL },
-               .handler = handle_show_summary,
-               .summary = "Summarize outstanding memory allocations",
-               .usage =
-               "Usage: threadstorage show summary [<file>]\n"
-               "       Summarizes thread-specific memory allocations by file, or optionally\n"
-               "by function, if a file is specified\n",
-       },
+       NEW_CLI(handle_cli_threadstorage_show_allocations, "Display outstanding thread local storage allocations"),
+       NEW_CLI(handle_cli_threadstorage_show_summary,     "Summarize outstanding memory allocations")
 };
 
 void threadstorage_init(void)
index b22a338..88811dd 100644 (file)
@@ -491,28 +491,42 @@ static void rebuild_matrix(int samples)
        }
 }
 
-static int show_translation(int fd, int argc, char *argv[])
+static char *handle_cli_core_show_translation(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 #define SHOW_TRANS 13
        int x, y, z;
        int curlen = 0, longest = 0;
 
-       if (argc > 5)
-               return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "core show translation [recalc]";
+               e->usage =
+                       "Usage: core show translation [recalc] [<recalc seconds>]\n"
+                       "       Displays known codec translators and the cost associated\n"
+                       "       with each conversion.  If the argument 'recalc' is supplied along\n"
+                       "       with optional number of seconds to test a new test will be performed\n"
+                       "       as the chart is being displayed.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
+       if (a->argc > 5)
+               return CLI_SHOWUSAGE;
        
-       if (argv[3] && !strcasecmp(argv[3], "recalc")) {
-               z = argv[4] ? atoi(argv[4]) : 1;
+       if (a->argv[3] && !strcasecmp(a->argv[3], "recalc")) {
+               z = a->argv[4] ? atoi(a->argv[4]) : 1;
 
                if (z <= 0) {
-                       ast_cli(fd, "         C'mon let's be serious here... defaulting to 1.\n");
+                       ast_cli(a->fd, "         Recalc must be greater than 0.  Defaulting to 1.\n");
                        z = 1;
                }
 
                if (z > MAX_RECALC) {
-                       ast_cli(fd, "         Maximum limit of recalc exceeded by %d, truncating value to %d\n", z - MAX_RECALC, MAX_RECALC);
+                       ast_cli(a->fd, "         Maximum limit of recalc exceeded by %d, truncating value to %d\n", z - MAX_RECALC, MAX_RECALC);
                        z = MAX_RECALC;
                }
-               ast_cli(fd, "         Recalculating Codec Translation (number of sample seconds: %d)\n\n", z);
+               ast_cli(a->fd, "         Recalculating Codec Translation (number of sample seconds: %d)\n\n", z);
                AST_RWLIST_WRLOCK(&translators);
                rebuild_matrix(z);
                AST_RWLIST_UNLOCK(&translators);
@@ -520,8 +534,8 @@ static int show_translation(int fd, int argc, char *argv[])
 
        AST_RWLIST_RDLOCK(&translators);
 
-       ast_cli(fd, "         Translation times between formats (in microseconds) for one second of data\n");
-       ast_cli(fd, "          Source Format (Rows) Destination Format (Columns)\n\n");
+       ast_cli(a->fd, "         Translation times between formats (in microseconds) for one second of data\n");
+       ast_cli(a->fd, "          Source Format (Rows) Destination Format (Columns)\n\n");
        /* Get the length of the longest (usable?) codec name, so we know how wide the left side should be */
        for (x = 0; x < SHOW_TRANS; x++) {
                curlen = strlen(ast_getformatname(1 << (x + 1)));
@@ -554,23 +568,14 @@ static int show_translation(int fd, int argc, char *argv[])
                        }
                }
                ast_str_append(&out, -1, "\n");
-               ast_cli(fd, out->str);                  
+               ast_cli(a->fd, out->str);                       
        }
        AST_RWLIST_UNLOCK(&translators);
-       return RESULT_SUCCESS;
+       return CLI_SUCCESS;
 }
 
-static const char show_trans_usage[] =
-"Usage: core show translation [recalc] [<recalc seconds>]\n"
-"       Displays known codec translators and the cost associated\n"
-"with each conversion.  If the argument 'recalc' is supplied along\n"
-"with optional number of seconds to test a new test will be performed\n"
-"as the chart is being displayed.\n";
-
 static struct ast_cli_entry cli_translate[] = {
-       { { "core", "show", "translation", NULL },
-       show_translation, "Display translation matrix",
-       show_trans_usage, NULL, NULL },
+       NEW_CLI(handle_cli_core_show_translation, "Display translation matrix")
 };
 
 /*! \brief register codec translator */
index d3c6163..a140cc4 100644 (file)
@@ -1107,7 +1107,7 @@ int ast_udptl_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags,
        return -1;
 }
 
-static int udptl_do_debug_ip(int fd, int argc, char *argv[])
+static char *handle_cli_udptl_debug_ip(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        struct hostent *hp;
        struct ast_hostent ahp;
@@ -1115,10 +1115,22 @@ static int udptl_do_debug_ip(int fd, int argc, char *argv[])
        char *p;
        char *arg;
 
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "udptl debug ip";
+               e->usage =
+                       "Usage: udptl debug [ip host[:port]]\n"
+                       "       Enable dumping of all UDPTL packets to and from host.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
        port = 0;
-       if (argc != 4)
-               return RESULT_SHOWUSAGE;
-       arg = argv[3];
+
+       if (a->argc != 4)
+               return CLI_SHOWUSAGE;
+       arg = a->argv[3];
        p = strstr(arg, ":");
        if (p) {
                *p = '\0';
@@ -1127,60 +1139,67 @@ static int udptl_do_debug_ip(int fd, int argc, char *argv[])
        }
        hp = ast_gethostbyname(arg, &ahp);
        if (hp == NULL)
-               return RESULT_SHOWUSAGE;
+               return CLI_SHOWUSAGE;
        udptldebugaddr.sin_family = AF_INET;
        memcpy(&udptldebugaddr.sin_addr, hp->h_addr, sizeof(udptldebugaddr.sin_addr));
        udptldebugaddr.sin_port = htons(port);
        if (port == 0)
-               ast_cli(fd, "UDPTL Debugging Enabled for IP: %s\n", ast_inet_ntoa(udptldebugaddr.sin_addr));
+               ast_cli(a->fd, "UDPTL Debugging Enabled for IP: %s\n", ast_inet_ntoa(udptldebugaddr.sin_addr));
        else
-               ast_cli(fd, "UDPTL Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(udptldebugaddr.sin_addr), port);
+               ast_cli(a->fd, "UDPTL Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(udptldebugaddr.sin_addr), port);
        udptldebug = 1;
-       return RESULT_SUCCESS;
+       return CLI_SUCCESS;
 }
 
-static int udptl_do_debug(int fd, int argc, char *argv[])
+static char *handle_cli_udptl_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-       if (argc != 2) {
-               if (argc != 4)
-                       return RESULT_SHOWUSAGE;
-               return udptl_do_debug_ip(fd, argc, argv);
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "udptl debug";
+               e->usage =
+                       "Usage: udptl debug\n"
+                       "       Enable dumping of all UDPTL packets.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
        }
+
+       if (a->argc != 2)
+               return CLI_SHOWUSAGE;
+
        udptldebug = 1;
-       memset(&udptldebugaddr,0,sizeof(udptldebugaddr));
-       ast_cli(fd, "UDPTL Debugging Enabled\n");
-       return RESULT_SUCCESS;
-}
+       memset(&udptldebugaddr, 0, sizeof(udptldebugaddr));
 
-static int udptl_nodebug(int fd, int argc, char *argv[])
-{
-       if (argc != 3)
-               return RESULT_SHOWUSAGE;
-       udptldebug = 0;
-       ast_cli(fd,"UDPTL Debugging Disabled\n");
-       return RESULT_SUCCESS;
+       ast_cli(a->fd, "UDPTL Debugging Enabled\n");
+       return CLI_SUCCESS;
 }
 
-static const char debug_usage[] =
-  "Usage: udptl debug [ip host[:port]]\n"
-  "       Enable dumping of all UDPTL packets to and from host.\n";
+static char *handle_cli_udptl_debug_off(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "udptl debug off";
+               e->usage =
+                       "Usage: udptl debug off\n"
+                       "       Disable dumping of all UDPTL packets.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
 
-static const char nodebug_usage[] =
-  "Usage: udptl debug off\n"
-  "       Disable all UDPTL debugging\n";
+       if (a->argc != 3)
+               return CLI_SHOWUSAGE;
 
-static struct ast_cli_entry cli_udptl[] = {
-       { { "udptl", "debug", NULL },
-       udptl_do_debug, "Enable UDPTL debugging",
-       debug_usage },
+       udptldebug = 0;
 
-       { { "udptl", "debug", "ip", NULL },
-       udptl_do_debug, "Enable UDPTL debugging on IP",
-       debug_usage },
+       ast_cli(a->fd, "UDPTL Debugging Disabled\n");
+       return CLI_SUCCESS;
+}
 
-       { { "udptl", "debug", "off", NULL },
-       udptl_nodebug, "Disable UDPTL debugging",
-       nodebug_usage },
+static struct ast_cli_entry cli_udptl[] = {
+       NEW_CLI(handle_cli_udptl_debug,     "Enable UDPTL debugging"),
+       NEW_CLI(handle_cli_udptl_debug_ip,  "Enable UDPTL debugging on IP"),
+       NEW_CLI(handle_cli_udptl_debug_off, "Disable UDPTL debugging")
 };
 
 static void __ast_udptl_reload(int reload)
index 68902a0..f5a54f0 100644 (file)
@@ -948,65 +948,62 @@ static int pbx_load_module(void)
 }
 
 /* CLI interface */
-static int ael2_debug_read(int fd, int argc, char *argv[])
+static char *handle_cli_ael_debug_multiple(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-       aeldebug |= DEBUG_READ;
-       return 0;
-}
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "ael debug [read|tokens|macros|contexts|off]";
+               e->usage =
+                       "Usage: ael debug [read|tokens|macros|contexts|off]\n"
+                       "       Enable AEL read, token, macro, or context debugging,\n"
+                       "       or disable all AEL debugging messages.  Note: this\n"
+                       "       currently does nothing.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
 
-static int ael2_debug_tokens(int fd, int argc, char *argv[])
-{
-       aeldebug |= DEBUG_TOKENS;
-       return 0;
-}
+       if (a->argc != 3)
+               return CLI_SHOWUSAGE;
+
+       if (!strcasecmp(a->argv[2], "read"))
+               aeldebug |= DEBUG_READ;
+       else if (!strcasecmp(a->argv[2], "tokens"))
+               aeldebug |= DEBUG_TOKENS;
+       else if (!strcasecmp(a->argv[2], "macros"))
+               aeldebug |= DEBUG_MACROS;
+       else if (!strcasecmp(a->argv[2], "contexts"))
+               aeldebug |= DEBUG_CONTEXTS;
+       else if (!strcasecmp(a->argv[2], "off"))
+               aeldebug = 0;
+       else
+               return CLI_SHOWUSAGE;
 
-static int ael2_debug_macros(int fd, int argc, char *argv[])
-{
-       aeldebug |= DEBUG_MACROS;
-       return 0;
+       return CLI_SUCCESS;
 }
 
-static int ael2_debug_contexts(int fd, int argc, char *argv[])
+static char *handle_cli_ael_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-       aeldebug |= DEBUG_CONTEXTS;
-       return 0;
-}
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "ael reload";
+               e->usage =
+                       "Usage: ael reload\n"
+                       "       Reloads AEL configuration.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
 
-static int ael2_no_debug(int fd, int argc, char *argv[])
-{
-       aeldebug = 0;
-       return 0;
-}
+       if (a->argc != 2)
+               return CLI_SHOWUSAGE;
 
-static int ael2_reload(int fd, int argc, char *argv[])
-{
-       return (pbx_load_module());
+       return (pbx_load_module() ? CLI_FAILURE : CLI_SUCCESS);
 }
 
-static struct ast_cli_entry cli_ael_no_debug = {
-       { "ael", "no", "debug", NULL },
-       ael2_no_debug, NULL,
-       NULL };
-
 static struct ast_cli_entry cli_ael[] = {
-       { { "ael", "reload", NULL },
-       ael2_reload, "Reload AEL configuration" },
-
-       { { "ael", "debug", "read", NULL },
-       ael2_debug_read, "Enable AEL read debug (does nothing)" },
-
-       { { "ael", "debug", "tokens", NULL },
-       ael2_debug_tokens, "Enable AEL tokens debug (does nothing)" },
-
-       { { "ael", "debug", "macros", NULL },
-       ael2_debug_macros, "Enable AEL macros debug (does nothing)" },
-
-       { { "ael", "debug", "contexts", NULL },
-       ael2_debug_contexts, "Enable AEL contexts debug (does nothing)" },
-
-       { { "ael", "nodebug", NULL },
-       ael2_no_debug, "Disable AEL debug messages",
-       NULL, NULL, &cli_ael_no_debug },
+       NEW_CLI(handle_cli_ael_reload,         "Reload AEL configuration"),
+       NEW_CLI(handle_cli_ael_debug_multiple, "Enable AEL debugging flags")
 };
 
 static int unload_module(void)
index 449bf35..4c7c42a 100644 (file)
@@ -56,56 +56,14 @@ AST_MUTEX_DEFINE_STATIC(save_dialplan_lock);
 static struct ast_context *local_contexts = NULL;
 
 /*
- * Help for commands provided by this module ...
+ * Prototypes for our completion functions
  */
-static char context_add_extension_help[] =
-"Usage: dialplan add extension <exten>,<priority>,<app>,<app-data>\n"
-"       into <context> [replace]\n\n"
-"       This command will add new extension into <context>. If there is an\n"
-"       existence of extension with the same priority and last 'replace'\n"
-"       arguments is given here we simply replace this extension.\n"
-"\n"
-"Example: dialplan add extension 6123,1,Dial,IAX/216.207.245.56/6123 into local\n"
-"         Now, you can dial 6123 and talk to Markster :)\n";
-
-static char context_remove_extension_help[] =
-"Usage: dialplan remove extension exten@context [priority]\n"
-"       Remove an extension from a given context. If a priority\n"
-"       is given, only that specific priority from the given extension\n"
-"       will be removed.\n";
-
-static char context_add_ignorepat_help[] =
-"Usage: dialplan add ignorepat <pattern> into <context>\n"
-"       This command adds a new ignore pattern into context <context>\n"
-"\n"
-"Example: dialplan add ignorepat _3XX into local\n";
-
-static char context_remove_ignorepat_help[] =
-"Usage: dialplan remove ignorepat <pattern> from <context>\n"
-"       This command removes an ignore pattern from context <context>\n"
-"\n"
-"Example: dialplan remove ignorepat _3XX from local\n";
-
-static char context_add_include_help[] =
-"Usage: dialplan add include <context> into <context>\n"
-"       Include a context in another context.\n";
-
-static char context_remove_include_help[] =
-"Usage: dialplan remove include <context> from <context>\n"
-"       Remove an included context from another context.\n";
-
-static char save_dialplan_help[] =
-"Usage: dialplan save [/path/to/extension/file]\n"
-"       Save dialplan created by pbx_config module.\n"
-"\n"
-"Example: dialplan save                 (/etc/asterisk/extensions.conf)\n"
-"         dialplan save /home/markster  (/home/markster/extensions.conf)\n";
-
-static char reload_extensions_help[] =
-"Usage: dialplan reload\n"
-"       reload extensions.conf without reloading any other modules\n"
-"       This command does not delete global variables unless\n"
-"       clearglobalvars is set to yes in extensions.conf\n";
+static char *complete_dialplan_remove_include(struct ast_cli_args *);
+static char *complete_dialplan_add_include(struct ast_cli_args *);
+static char *complete_dialplan_remove_ignorepat(struct ast_cli_args *);
+static char *complete_dialplan_add_ignorepat(struct ast_cli_args *);
+static char *complete_dialplan_remove_extension(struct ast_cli_args *);
+static char *complete_dialplan_add_extension(struct ast_cli_args *);
 
 /*
  * Implementation of functions provided by this module
@@ -114,23 +72,31 @@ static char reload_extensions_help[] =
 /*!
  * REMOVE INCLUDE command stuff
  */
-static int handle_context_remove_include(int fd, int argc, char *argv[])
+static char *handle_cli_dialplan_remove_include(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-       if (argc != 6)
-               return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "dialplan remove include";
+               e->usage =
+                       "Usage: dialplan remove include <context> from <context>\n"
+                       "       Remove an included context from another context.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return complete_dialplan_remove_include(a);
+       }
 
-       if (strcmp(argv[4], "into"))
-               return RESULT_SHOWUSAGE;
+       if (strcmp(a->argv[4], "from"))
+               return CLI_SHOWUSAGE;
 
-       if (!ast_context_remove_include(argv[5], argv[3], registrar)) {
-               ast_cli(fd, "We are not including '%s' into '%s' now\n",
-                       argv[3], argv[5]);
-               return RESULT_SUCCESS;
+       if (!ast_context_remove_include(a->argv[5], a->argv[3], registrar)) {
+               ast_cli(a->fd, "We are not including '%s' into '%s' now\n",
+                       a->argv[3], a->argv[5]);
+               return CLI_SUCCESS;
        }
 
-       ast_cli(fd, "Failed to remove '%s' include from '%s' context\n",
-               argv[3], argv[5]);
-       return RESULT_FAILURE;
+       ast_cli(a->fd, "Failed to remove '%s' include from '%s' context\n",
+               a->argv[3], a->argv[5]);
+       return CLI_FAILURE;
 }
 
 /*! \brief return true if 'name' is included by context c */
@@ -208,15 +174,14 @@ static int split_ec(const char *src, char **ext, char ** const ctx)
 }
 
 /* _X_ is the string we need to complete */
-static char *complete_context_remove_include(const char *line, const char *word,
-       int pos, int state)
+static char *complete_dialplan_remove_include(struct ast_cli_args *a)
 {
        int which = 0;
        char *res = NULL;
-       int len = strlen(word); /* how many bytes to match */
+       int len = strlen(a->word); /* how many bytes to match */
        struct ast_context *c = NULL;
 
-       if (pos == 3) {         /* "dialplan remove include _X_" */
+       if (a->pos == 3) {              /* "dialplan remove include _X_" */
                if (ast_wrlock_contexts()) {
                        ast_log(LOG_ERROR, "Failed to lock context list\n");
                        return NULL;
@@ -233,7 +198,7 @@ static char *complete_context_remove_include(const char *line, const char *word,
                                struct ast_context *nc = NULL;
                                int already_served = 0;
 
-                               if (!partial_match(i_name, word, len))
+                               if (!partial_match(i_name, a->word, len))
                                        continue;       /* not matched */
 
                                /* check if this include is already served or not */
@@ -244,7 +209,7 @@ static char *complete_context_remove_include(const char *line, const char *word,
                                while ( (nc = ast_walk_contexts(nc)) && nc != c && !already_served)
                                        already_served = lookup_ci(nc, i_name);
 
-                               if (!already_served && ++which > state)
+                               if (!already_served && ++which > a->n)
                                        res = strdup(i_name);
                        }
                        ast_unlock_context(c);
@@ -252,15 +217,15 @@ static char *complete_context_remove_include(const char *line, const char *word,
 
                ast_unlock_contexts();
                return res;
-       } else if (pos == 4) { /* "dialplan remove include CTX _X_" */
+       } else if (a->pos == 4) { /* "dialplan remove include CTX _X_" */
                /*
                 * complete as 'from', but only if previous context is really
                 * included somewhere
                 */
                char *context, *dupline;
-               const char *s = skip_words(line, 3); /* skip 'dialplan' 'remove' 'include' */
+               const char *s = skip_words(a->line, 3); /* skip 'dialplan' 'remove' 'include' */
 
-               if (state > 0)
+               if (a->n > 0)
                        return NULL;
                context = dupline = strdup(s);
                if (!dupline) {
@@ -284,12 +249,12 @@ static char *complete_context_remove_include(const char *line, const char *word,
                        ast_log(LOG_WARNING, "%s not included anywhere\n", context);
                free(context);
                return res;
-       } else if (pos == 5) { /* "dialplan remove include CTX from _X_" */
+       } else if (a->pos == 5) { /* "dialplan remove include CTX from _X_" */
                /*
                 * Context from which we removing include ... 
                 */
                char *context, *dupline, *from;
-               const char *s = skip_words(line, 3); /* skip 'dialplan' 'remove' 'include' */
+               const char *s = skip_words(a->line, 3); /* skip 'dialplan' 'remove' 'include' */
                context = dupline = strdup(s);
                if (!dupline) {
                        ast_log(LOG_ERROR, "Out of free memory\n");
@@ -315,10 +280,10 @@ static char *complete_context_remove_include(const char *line, const char *word,
                c = NULL;
                while ( !res && (c = ast_walk_contexts(c))) {
                        const char *c_name = ast_get_context_name(c);
-                       if (!partial_match(c_name, word, len))  /* not a good target */
+                       if (!partial_match(c_name, a->word, len))       /* not a good target */
                                continue;
                        /* walk through all includes and check if it is our context */  
-                       if (lookup_ci(c, context) && ++which > state)
+                       if (lookup_ci(c, context) && ++which > a->n)
                                res = strdup(c_name);
                }
                ast_unlock_contexts();
@@ -332,19 +297,33 @@ static char *complete_context_remove_include(const char *line, const char *word,
 /*!
  * REMOVE EXTENSION command stuff
  */
-static int handle_context_remove_extension(int fd, int argc, char *argv[])
+static char *handle_cli_dialplan_remove_extension(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        int removing_priority = 0;
        char *exten, *context;
-       int ret = RESULT_FAILURE;
+       char *ret = CLI_FAILURE;
+
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "dialplan remove extension";
+               e->usage =
+                       "Usage: dialplan remove extension exten@context [priority]\n"
+                       "       Remove an extension from a given context. If a priority\n"
+                       "       is given, only that specific priority from the given extension\n"
+                       "       will be removed.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return complete_dialplan_remove_extension(a);
+       }
 
-       if (argc != 5 && argc != 4) return RESULT_SHOWUSAGE;
+       if (a->argc != 5 && a->argc != 4)
+               return CLI_SHOWUSAGE;
 
        /*
         * Priority input checking ...
         */
-       if (argc == 5) {
-               char *c = argv[4];
+       if (a->argc == 5) {
+               char *c = a->argv[4];
 
                /* check for digits in whole parameter for right priority ...
                 * why? because atoi (strtol) returns 0 if any characters in
@@ -356,16 +335,16 @@ static int handle_context_remove_extension(int fd, int argc, char *argv[])
                        while (*c && isdigit(*c))
                                c++;
                        if (*c) { /* non-digit in string */
-                               ast_cli(fd, "Invalid priority '%s'\n", argv[4]);
-                               return RESULT_FAILURE;
+                               ast_cli(a->fd, "Invalid priority '%s'\n", a->argv[4]);
+                               return CLI_FAILURE;
                        }
-                       removing_priority = atoi(argv[4]);
+                       removing_priority = atoi(a->argv[4]);
                }
 
                if (removing_priority == 0) {
-                       ast_cli(fd, "If you want to remove whole extension, please " \
+                       ast_cli(a->fd, "If you want to remove whole extension, please " \
                                "omit priority argument\n");
-                       return RESULT_FAILURE;
+                       return CLI_FAILURE;
                }
        }
 
@@ -373,27 +352,27 @@ static int handle_context_remove_extension(int fd, int argc, char *argv[])
        /*
         * Format exten@context checking ...
         */
-       if (split_ec(argv[3], &exten, &context))
-               return RESULT_FAILURE; /* XXX malloc failure */
+       if (split_ec(a->argv[3], &exten, &context))
+               return CLI_FAILURE; /* XXX malloc failure */
        if ((!strlen(exten)) || (!(strlen(context)))) {
-               ast_cli(fd, "Missing extension or context name in third argument '%s'\n",
-                       argv[3]);
+               ast_cli(a->fd, "Missing extension or context name in third argument '%s'\n",
+                       a->argv[3]);
                free(exten);
-               return RESULT_FAILURE;
+               return CLI_FAILURE;
        }
 
        if (!ast_context_remove_extension(context, exten, removing_priority, registrar)) {
                if (!removing_priority)
-                       ast_cli(fd, "Whole extension %s@%s removed\n",
+                       ast_cli(a->fd, "Whole extension %s@%s removed\n",
                                exten, context);
                else
-                       ast_cli(fd, "Extension %s@%s with priority %d removed\n",
+                       ast_cli(a->fd, "Extension %s@%s with priority %d removed\n",
                                exten, context, removing_priority);
                        
-               ret = RESULT_SUCCESS;
+               ret = CLI_SUCCESS;
        } else {
-               ast_cli(fd, "Failed to remove extension %s@%s\n", exten, context);
-               ret = RESULT_FAILURE;
+               ast_cli(a->fd, "Failed to remove extension %s@%s\n", exten, context);
+               ret = CLI_FAILURE;
        }
        free(exten);
        return ret;
@@ -446,8 +425,7 @@ static int fix_complete_args(const char *line, char **word, int *pos)
 }
 #endif /* BROKEN_READLINE */
 
-static char *complete_context_remove_extension(const char *line, const char *word, int pos,
-       int state)
+static char *complete_dialplan_remove_extension(struct ast_cli_args *a)
 {
        char *ret = NULL;
        int which = 0;
@@ -458,20 +436,20 @@ static char *complete_context_remove_extension(const char *line, const char *wor
         * Fix arguments, *word is a new allocated structure, REMEMBER to
         * free *word when you want to return from this function ...
         */
-       if (fix_complete_args(line, &word2, &pos)) {
+       if (fix_complete_args(a->line, &word2, &a->pos)) {
                ast_log(LOG_ERROR, "Out of free memory\n");
                return NULL;
        }
-       word = word2;
+       a->word = word2;
 #endif
 
-       if (pos == 3) { /* 'dialplan remove extension _X_' (exten@context ... */
+       if (a->pos == 3) { /* 'dialplan remove extension _X_' (exten@context ... */
                struct ast_context *c = NULL;
                char *context = NULL, *exten = NULL;
                int le = 0;     /* length of extension */
                int lc = 0;     /* length of context */
 
-               lc = split_ec(word, &exten, &context);
+               lc = split_ec(a->word, &exten, &context);
 #ifdef BROKEN_READLINE
                free(word2);
 #endif
@@ -492,7 +470,7 @@ static char *complete_context_remove_extension(const char *line, const char *wor
                        if (!partial_match(ast_get_context_name(c), context, lc))
                                continue;       /* context not matched */
                        while ( (e = ast_walk_context_extensions(c, e)) ) { /* try to complete extensions ... */
-                               if ( partial_match(ast_get_extension_name(e), exten, le) && ++which > state) { /* n-th match */
+                               if ( partial_match(ast_get_extension_name(e), exten, le) && ++which > a->n) { /* n-th match */
                                        /* If there is an extension then return exten@context. XXX otherwise ? */
                                        if (exten)
                                                asprintf(&ret, "%s@%s", ast_get_extension_name(e), ast_get_context_name(c));
@@ -507,11 +485,11 @@ static char *complete_context_remove_extension(const char *line, const char *wor
        error2:
                if (exten)
                        free(exten);
-       } else if (pos == 4) { /* 'dialplan remove extension EXT _X_' (priority) */
+       } else if (a->pos == 4) { /* 'dialplan remove extension EXT _X_' (priority) */
                char *exten = NULL, *context, *p;
                struct ast_context *c;
                int le, lc, len;
-               const char *s = skip_words(line, 3); /* skip 'dialplan' 'remove' 'extension' */
+               const char *s = skip_words(a->line, 3); /* skip 'dialplan' 'remove' 'extension' */
                int i = split_ec(s, &exten, &context);  /* parse ext@context */
 
                if (i)  /* error */
@@ -522,7 +500,7 @@ static char *complete_context_remove_extension(const char *line, const char *wor
                        *p = '\0';
                le = strlen(exten);
                lc = strlen(context);
-               len = strlen(word);
+               len = strlen(a->word);
                if (le == 0 || lc == 0)
                        goto error3;
 
@@ -550,7 +528,7 @@ static char *complete_context_remove_extension(const char *line, const char *wor
                                priority = NULL;
                                while ( !ret && (priority = ast_walk_extension_priorities(e, priority)) ) {
                                        snprintf(buffer, sizeof(buffer), "%u", ast_get_extension_priority(priority));
-                                       if (partial_match(buffer, word, len) && ++which > state) /* n-th match */
+                                       if (partial_match(buffer, a->word, len) && ++which > a->n) /* n-th match */
                                                ret = strdup(buffer);
                                }
                                break;
@@ -571,76 +549,86 @@ static char *complete_context_remove_extension(const char *line, const char *wor
 /*!
  * Include context ...
  */
-static int handle_context_add_include(int fd, int argc, char *argv[])
+static char *handle_cli_dialplan_add_include(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-       if (argc != 6) /* dialplan add include CTX in CTX */
-               return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "dialplan add include";
+               e->usage =
+                       "Usage: dialplan add include <context> into <context>\n"
+                       "       Include a context in another context.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return complete_dialplan_add_include(a);
+       }
+
+       if (a->argc != 6) /* dialplan add include CTX in CTX */
+               return CLI_SHOWUSAGE;
 
        /* fifth arg must be 'into' ... */
-       if (strcmp(argv[4], "into"))
-               return RESULT_SHOWUSAGE;
+       if (strcmp(a->argv[4], "into"))
+               return CLI_SHOWUSAGE;
 
-       if (ast_context_add_include(argv[5], argv[3], registrar)) {
+       if (ast_context_add_include(a->argv[5], a->argv[3], registrar)) {
                switch (errno) {
                case ENOMEM:
-                       ast_cli(fd, "Out of memory for context addition\n");
+                       ast_cli(a->fd, "Out of memory for context addition\n");
                        break;
 
                case EBUSY:
-                       ast_cli(fd, "Failed to lock context(s) list, please try again later\n");
+                       ast_cli(a->fd, "Failed to lock context(s) list, please try again later\n");
                        break;
 
                case EEXIST:
-                       ast_cli(fd, "Context '%s' already included in '%s' context\n",
-                               argv[3], argv[5]);
+                       ast_cli(a->fd, "Context '%s' already included in '%s' context\n",
+                               a->argv[3], a->argv[5]);
                        break;
 
                case ENOENT:
                case EINVAL:
-                       ast_cli(fd, "There is no existence of context '%s'\n",
-                               errno == ENOENT ? argv[5] : argv[3]);
+                       ast_cli(a->fd, "There is no existence of context '%s'\n",
+                               errno == ENOENT ? a->argv[5] : a->argv[3]);
                        break;
 
                default:
-                       ast_cli(fd, "Failed to include '%s' in '%s' context\n",
-                               argv[3], argv[5]);
+                       ast_cli(a->fd, "Failed to include '%s' in '%s' context\n",
+                               a->argv[3], a->argv[5]);
                        break;
                }
-               return RESULT_FAILURE;
+               return CLI_FAILURE;
        }
 
        /* show some info ... */
-       ast_cli(fd, "Context '%s' included in '%s' context\n",
-               argv[3], argv[5]);
+       ast_cli(a->fd, "Context '%s' included in '%s' context\n",
+               a->argv[3], a->argv[5]);
 
-       return RESULT_SUCCESS;
+       return CLI_SUCCESS;
 }
 
-static char *complete_context_add_include(const char *line, const char *word, int pos,
-    int state)
+static char *complete_dialplan_add_include(struct ast_cli_args *a)
 {
        struct ast_context *c;
        int which = 0;
        char *ret = NULL;
-       int len = strlen(word);
+       int len = strlen(a->word);
 
-       if (pos == 3) {         /* 'dialplan add include _X_' (context) ... */
+       if (a->pos == 3) {              /* 'dialplan add include _X_' (context) ... */
                if (ast_rdlock_contexts()) {
                        ast_log(LOG_ERROR, "Failed to lock context list\n");
                        return NULL;
                }
                for (c = NULL; !ret && (c = ast_walk_contexts(c)); )
-                       if (partial_match(ast_get_context_name(c), word, len) && ++which > state)
+                       if (partial_match(ast_get_context_name(c), a->word, len) && ++which > a->n)
                                ret = strdup(ast_get_context_name(c));
                ast_unlock_contexts();
                return ret;
-       } else if (pos == 4) { /* dialplan add include CTX _X_ */
+       } else if (a->pos == 4) { /* dialplan add include CTX _X_ */
                /* complete  as 'into' if context exists or we are unable to check */
                char *context, *dupline;
                struct ast_context *c;
-               const char *s = skip_words(line, 3); /* should not fail */
+               const char *s = skip_words(a->line, 3); /* should not fail */
 
-               if (state != 0) /* only once */
+               if (a->n != 0)  /* only once */
                        return NULL;
 
                /* parse context from line ... */
@@ -664,9 +652,9 @@ static char *complete_context_add_include(const char *line, const char *word, in
                }
                free(context);
                return ret;
-       } else if (pos == 5) { /* 'dialplan add include CTX into _X_' (dst context) */
+       } else if (a->pos == 5) { /* 'dialplan add include CTX into _X_' (dst context) */
                char *context, *dupline, *into;
-               const char *s = skip_words(line, 3); /* should not fail */
+               const char *s = skip_words(a->line, 3); /* should not fail */
                context = dupline = strdup(s);
                if (!dupline) {
                        ast_log(LOG_ERROR, "Out of free memory\n");
@@ -694,9 +682,9 @@ static char *complete_context_add_include(const char *line, const char *word, in
                        for (c = NULL; !ret && (c = ast_walk_contexts(c)); ) {
                                if (!strcmp(context, ast_get_context_name(c)))
                                        continue; /* skip ourselves */
-                               if (partial_match(ast_get_context_name(c), word, len) &&
+                               if (partial_match(ast_get_context_name(c), a->word, len) &&
                                                !lookup_ci(c, context) /* not included yet */ &&
-                                               ++which > state)
+                                               ++which > a->n)
                                        ret = strdup(ast_get_context_name(c));
                        }
                } else {
@@ -714,7 +702,7 @@ static char *complete_context_add_include(const char *line, const char *word, in
 /*!
  * \brief 'save dialplan' CLI command implementation functions ...
  */
-static int handle_save_dialplan(int fd, int argc, char *argv[])
+static char *handle_cli_dialplan_save(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        char filename[256];
        struct ast_context *c;
@@ -723,32 +711,45 @@ static int handle_save_dialplan(int fd, int argc, char *argv[])
        int incomplete = 0; /* incomplete config write? */
        FILE *output;
        struct ast_flags config_flags = { 0 };
-
        const char *base, *slash, *file;
 
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "dialplan save";
+               e->usage =
+                       "Usage: dialplan save [/path/to/extension/file]\n"
+                       "       Save dialplan created by pbx_config module.\n"
+                       "\n"
+                       "Example: dialplan save                 (/etc/asterisk/extensions.conf)\n"
+                       "         dialplan save /home/markster  (/home/markster/extensions.conf)\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
        if (! (static_config && !write_protect_config)) {
-               ast_cli(fd,
+               ast_cli(a->fd,
                        "I can't save dialplan now, see '%s' example file.\n",
                        config);
-               return RESULT_FAILURE;
+               return CLI_FAILURE;
        }
 
-       if (argc != 2 && argc != 3)
-               return RESULT_SHOWUSAGE;
+       if (a->argc != 2 && a->argc != 3)
+               return CLI_SHOWUSAGE;
 
        if (ast_mutex_lock(&save_dialplan_lock)) {
-               ast_cli(fd,
+               ast_cli(a->fd,
                        "Failed to lock dialplan saving (another proccess saving?)\n");
-               return RESULT_FAILURE;
+               return CLI_FAILURE;
        }
        /* XXX the code here is quite loose, a pathname with .conf in it
         * is assumed to be a complete pathname
         */
-       if (argc == 3) {        /* have config path. Look for *.conf */
-               base = argv[2];
-               if (!strstr(argv[2], ".conf")) { /*no, this is assumed to be a pathname */
+       if (a->argc == 3) {     /* have config path. Look for *.conf */
+               base = a->argv[2];
+               if (!strstr(a->argv[2], ".conf")) { /*no, this is assumed to be a pathname */
                        /* if filename ends with '/', do not add one */
-                       slash = (*(argv[2] + strlen(argv[2]) -1) == '/') ? "/" : "";
+                       slash = (*(a->argv[2] + strlen(a->argv[2]) -1) == '/') ? "/" : "";
                        file = config;  /* default: 'extensions.conf' */
                } else {        /* yes, complete file name */
                        slash = "";
@@ -766,20 +767,20 @@ static int handle_save_dialplan(int fd, int argc, char *argv[])
 
        /* try to lock contexts list */
        if (ast_rdlock_contexts()) {
-               ast_cli(fd, "Failed to lock contexts list\n");
+               ast_cli(a->fd, "Failed to lock contexts list\n");
                ast_mutex_unlock(&save_dialplan_lock);
                ast_config_destroy(cfg);
-               return RESULT_FAILURE;
+               return CLI_FAILURE;
        }
 
        /* create new file ... */
        if (!(output = fopen(filename, "wt"))) {
-               ast_cli(fd, "Failed to create file '%s'\n",
+               ast_cli(a->fd, "Failed to create file '%s'\n",
                        filename);
                ast_unlock_contexts();
                ast_mutex_unlock(&save_dialplan_lock);
                ast_config_destroy(cfg);
-               return RESULT_FAILURE;
+               return CLI_FAILURE;
        }
 
        /* fireout general info */
@@ -845,7 +846,7 @@ static int handle_save_dialplan(int fd, int argc, char *argv[])
                        
                                PUT_CTX_HDR;
 
-                               if (ast_get_extension_priority(p)==PRIORITY_HINT) { /* easy */
+                               if (ast_get_extension_priority(p) == PRIORITY_HINT) { /* easy */
                                        fprintf(output, "exten => %s,hint,%s\n",
                                                    ast_get_extension_name(p),
                                                    ast_get_extension_app(p));
@@ -914,19 +915,19 @@ static int handle_save_dialplan(int fd, int argc, char *argv[])
        fclose(output);
 
        if (incomplete) {
-               ast_cli(fd, "Saved dialplan is incomplete\n");
-               return RESULT_FAILURE;
+               ast_cli(a->fd, "Saved dialplan is incomplete\n");
+               return CLI_FAILURE;
        }
 
-       ast_cli(fd, "Dialplan successfully saved into '%s'\n",
+       ast_cli(a->fd, "Dialplan successfully saved into '%s'\n",
                filename);
-       return RESULT_SUCCESS;
+       return CLI_SUCCESS;
 }
 
 /*!
  * \brief ADD EXTENSION command stuff
  */
-static int handle_context_add_extension(int fd, int argc, char *argv[])
+static char *handle_cli_dialplan_add_extension(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        char *whole_exten;
        char *exten, *prior;
@@ -934,16 +935,35 @@ static int handle_context_add_extension(int fd, int argc, char *argv[])
        char *cidmatch, *app, *app_data;
        char *start, *end;
 
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "dialplan add extension";
+               e->usage =
+                       "Usage: dialplan add extension <exten>,<priority>,<app>,<app-data>\n"
+                       "       into <context> [replace]\n\n"
+                       "       This command will add new extension into <context>. If there is an\n"
+                       "       existence of extension with the same priority and last 'replace'\n"
+                       "       arguments is given here we simply replace this extension.\n"
+                       "\n"
+                       "Example: dialplan add extension 6123,1,Dial,IAX/216.207.245.56/6123 into local\n"
+                       "         Now, you can dial 6123 and talk to Markster :)\n";
+               return NULL;
+       case CLI_GENERATE:
+               return complete_dialplan_add_extension(a);
+       }
+
        /* check for arguments at first */
-       if (argc != 6 && argc != 7)
-               return RESULT_SHOWUSAGE;
-       if (strcmp(argv[4], "into"))
-               return RESULT_SHOWUSAGE;
-       if (argc == 7) if (strcmp(argv[6], "replace")) return RESULT_SHOWUSAGE;
+       if (a->argc != 6 && a->argc != 7)
+               return CLI_SHOWUSAGE;
+       if (strcmp(a->argv[4], "into"))
+               return CLI_SHOWUSAGE;
+       if (a->argc == 7)
+               if (strcmp(a->argv[6], "replace"))
+                       return CLI_SHOWUSAGE;
 
        /* XXX overwrite argv[3] */
-       whole_exten = argv[3];
-       exten   = strsep(&whole_exten,",");
+       whole_exten = a->argv[3];
+       exten = strsep(&whole_exten,",");
        if (strchr(exten, '/')) {
                cidmatch = exten;
                strsep(&cidmatch,"/");
@@ -956,7 +976,7 @@ static int handle_context_add_extension(int fd, int argc, char *argv[])
                        iprior = PRIORITY_HINT;
                } else {
                        if (sscanf(prior, "%d", &iprior) != 1) {
-                               ast_cli(fd, "'%s' is not a valid priority\n", prior);
+                               ast_cli(a->fd, "'%s' is not a valid priority\n", prior);
                                prior = NULL;
                        }
                }
@@ -977,58 +997,58 @@ static int handle_context_add_extension(int fd, int argc, char *argv[])
        }
 
        if (!exten || !prior || !app || (!app_data && iprior != PRIORITY_HINT))
-               return RESULT_SHOWUSAGE;
+               return CLI_SHOWUSAGE;
 
        if (!app_data)
                app_data="";
-       if (ast_add_extension(argv[5], argc == 7 ? 1 : 0, exten, iprior, NULL, cidmatch, app,
+       if (ast_add_extension(a->argv[5], a->argc == 7 ? 1 : 0, exten, iprior, NULL, cidmatch, app,
                (void *)strdup(app_data), free, registrar)) {
                switch (errno) {
                case ENOMEM:
-                       ast_cli(fd, "Out of free memory\n");
+                       ast_cli(a->fd, "Out of free memory\n");
                        break;
 
                case EBUSY:
-                       ast_cli(fd, "Failed to lock context(s) list, please try again later\n");
+                       ast_cli(a->fd, "Failed to lock context(s) list, please try again later\n");
                        break;
 
                case ENOENT:
-                       ast_cli(fd, "No existence of '%s' context\n", argv[5]);
+                       ast_cli(a->fd, "No existence of '%s' context\n", a->argv[5]);
                        break;
 
                case EEXIST:
-                       ast_cli(fd, "Extension %s@%s with priority %s already exists\n",
-                               exten, argv[5], prior);
+                       ast_cli(a->fd, "Extension %s@%s with priority %s already exists\n",
+                               exten, a->argv[5], prior);
                        break;
 
                default:
-                       ast_cli(fd, "Failed to add '%s,%s,%s,%s' extension into '%s' context\n",
-                                       exten, prior, app, app_data, argv[5]);
+                       ast_cli(a->fd, "Failed to add '%s,%s,%s,%s' extension into '%s' context\n",
+                                       exten, prior, app, app_data, a->argv[5]);
                        break;
                }
-               return RESULT_FAILURE;
+               return CLI_FAILURE;
        }
 
-       if (argc == 7)
-               ast_cli(fd, "Extension %s@%s (%s) replace by '%s,%s,%s,%s'\n",
-                       exten, argv[5], prior, exten, prior, app, app_data);
+       if (a->argc == 7)
+               ast_cli(a->fd, "Extension %s@%s (%s) replace by '%s,%s,%s,%s'\n",
+                       exten, a->argv[5], prior, exten, prior, app, app_data);
        else
-               ast_cli(fd, "Extension '%s,%s,%s,%s' added into '%s' context\n",
-                       exten, prior, app, app_data, argv[5]);
+               ast_cli(a->fd, "Extension '%s,%s,%s,%s' added into '%s' context\n",
+                       exten, prior, app, app_data, a->argv[5]);
 
-       return RESULT_SUCCESS;
+       return CLI_SUCCESS;
 }
 
 /*! dialplan add extension 6123,1,Dial,IAX/212.71.138.13/6123 into local */
-static char *complete_context_add_extension(const char *line, const char *word, int pos, int state)
+static char *complete_dialplan_add_extension(struct ast_cli_args *a)
 {
        int which = 0;
 
-       if (pos == 4) {         /* complete 'into' word ... */
-               return (state == 0) ? strdup("into") : NULL;
-       } else if (pos == 5) { /* complete context */
+       if (a->pos == 4) {              /* complete 'into' word ... */
+               return (a->n == 0) ? strdup("into") : NULL;
+       } else if (a->pos == 5) { /* complete context */
                struct ast_context *c = NULL;
-               int len = strlen(word);
+               int len = strlen(a->word);
                char *res = NULL;
 
                /* try to lock contexts list ... */
@@ -1039,12 +1059,12 @@ static char *complete_context_add_extension(const char *line, const char *word,
 
                /* walk through all contexts */
                while ( !res && (c = ast_walk_contexts(c)) )
-                       if (partial_match(ast_get_context_name(c), word, len) && ++which > state)
+                       if (partial_match(ast_get_context_name(c), a->word, len) && ++which > a->n)
                                res = strdup(ast_get_context_name(c));
                ast_unlock_contexts();
                return res;
-       } else if (pos == 6) {
-               return state == 0 ? strdup("replace") : NULL;
+       } else if (a->pos == 6) {
+               return a->n == 0 ? strdup("replace") : NULL;
        }
        return NULL;
 }
@@ -1052,60 +1072,74 @@ static char *complete_context_add_extension(const char *line, const char *word,
 /*!
  * IGNOREPAT CLI stuff
  */
-static int handle_context_add_ignorepat(int fd, int argc, char *argv[])
+static char *handle_cli_dialplan_add_ignorepat(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-       if (argc != 6)
-               return RESULT_SHOWUSAGE;
-       if (strcmp(argv[4], "into"))
-               return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "dialplan add ignorepat";
+               e->usage =
+                       "Usage: dialplan add ignorepat <pattern> into <context>\n"
+                       "       This command adds a new ignore pattern into context <context>\n"
+                       "\n"
+                       "Example: dialplan add ignorepat _3XX into local\n";
+               return NULL;
+       case CLI_GENERATE:
+               return complete_dialplan_add_ignorepat(a);
+       }
+
+       if (a->argc != 6)
+               return CLI_SHOWUSAGE;
+
+       if (strcmp(a->argv[4], "into"))
+               return CLI_SHOWUSAGE;
 
-       if (ast_context_add_ignorepat(argv[5], argv[3], registrar)) {
+       if (ast_context_add_ignorepat(a->argv[5], a->argv[3], registrar)) {
                switch (errno) {
                case ENOMEM:
-                       ast_cli(fd, "Out of free memory\n");
+                       ast_cli(a->fd, "Out of free memory\n");
                        break;
 
                case ENOENT:
-                       ast_cli(fd, "There is no existence of '%s' context\n", argv[5]);
+                       ast_cli(a->fd, "There is no existence of '%s' context\n", a->argv[5]);
                        break;
 
                case EEXIST:
-                       ast_cli(fd, "Ignore pattern '%s' already included in '%s' context\n",
-                               argv[3], argv[5]);
+                       ast_cli(a->fd, "Ignore pattern '%s' already included in '%s' context\n",
+                               a->argv[3], a->argv[5]);
                        break;
 
                case EBUSY:
-                       ast_cli(fd, "Failed to lock context(s) list, please, try again later\n");
+                       ast_cli(a->fd, "Failed to lock context(s) list, please, try again later\n");
                        break;
 
                default:
-                       ast_cli(fd, "Failed to add ingore pattern '%s' into '%s' context\n",
-                               argv[3], argv[5]);
+                       ast_cli(a->fd, "Failed to add ingore pattern '%s' into '%s' context\n",
+                               a->argv[3], a->argv[5]);
                        break;
                }
-               return RESULT_FAILURE;
+               return CLI_FAILURE;
        }
 
-       ast_cli(fd, "Ignore pattern '%s' added into '%s' context\n",
-               argv[3], argv[5]);
-       return RESULT_SUCCESS;
+       ast_cli(a->fd, "Ignore pattern '%s' added into '%s' context\n",
+               a->argv[3], a->argv[5]);
+
+       return CLI_SUCCESS;
 }
 
-static char *complete_context_add_ignorepat(const char *line, const char *word,
-       int pos, int state)
+static char *complete_dialplan_add_ignorepat(struct ast_cli_args *a)
 {
-       if (pos == 4)
-               return state == 0 ? strdup("into") : NULL;
-       else if (pos == 5) {
+       if (a->pos == 4)
+               return a->n == 0 ? strdup("into") : NULL;
+       else if (a->pos == 5) {
                struct ast_context *c;
                int which = 0;
                char *dupline, *ignorepat = NULL;
                const char *s;
                char *ret = NULL;
-               int len = strlen(word);
+               int len = strlen(a->word);
 
                /* XXX skip first three words 'dialplan' 'add' 'ignorepat' */
-               s = skip_words(line, 3);
+               s = skip_words(a->line, 3);
                if (s == NULL)
                        return NULL;
                dupline = strdup(s);
@@ -1123,11 +1157,11 @@ static char *complete_context_add_ignorepat(const char *line, const char *word,
                for (c = NULL; !ret && (c = ast_walk_contexts(c));) {
                        int found = 0;
 
-                       if (!partial_match(ast_get_context_name(c), word, len))
+                       if (!partial_match(ast_get_context_name(c), a->word, len))
                                continue; /* not mine */
                        if (ignorepat) /* there must be one, right ? */
                                found = lookup_c_ip(c, ignorepat);
-                       if (!found && ++which > state)
+                       if (!found && ++which > a->n)
                                ret = strdup(ast_get_context_name(c));
                }
 
@@ -1140,49 +1174,63 @@ static char *complete_context_add_ignorepat(const char *line, const char *word,
        return NULL;
 }
 
-static int handle_context_remove_ignorepat(int fd, int argc, char *argv[])
+static char *handle_cli_dialplan_remove_ignorepat(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-       if (argc != 6)
-               return RESULT_SHOWUSAGE;
-       if (strcmp(argv[4], "from"))
-               return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "dialplan remove ignorepat";
+               e->usage =
+                       "Usage: dialplan remove ignorepat <pattern> from <context>\n"
+                       "       This command removes an ignore pattern from context <context>\n"
+                       "\n"
+                       "Example: dialplan remove ignorepat _3XX from local\n";
+               return NULL;
+       case CLI_GENERATE:
+               return complete_dialplan_remove_ignorepat(a);
+       }
+
+       if (a->argc != 6)
+               return CLI_SHOWUSAGE;
+
+       if (strcmp(a->argv[4], "from"))
+               return CLI_SHOWUSAGE;
 
-       if (ast_context_remove_ignorepat(argv[5], argv[3], registrar)) {
+       if (ast_context_remove_ignorepat(a->argv[5], a->argv[3], registrar)) {
                switch (errno) {
                case EBUSY:
-                       ast_cli(fd, "Failed to lock context(s) list, please try again later\n");
+                       ast_cli(a->fd, "Failed to lock context(s) list, please try again later\n");
                        break;
 
                case ENOENT:
-                       ast_cli(fd, "There is no existence of '%s' context\n", argv[5]);
+                       ast_cli(a->fd, "There is no existence of '%s' context\n", a->argv[5]);
                        break;
 
                case EINVAL:
-                       ast_cli(fd, "There is no existence of '%s' ignore pattern in '%s' context\n",
-                                       argv[3], argv[5]);
+                       ast_cli(a->fd, "There is no existence of '%s' ignore pattern in '%s' context\n",
+                                       a->argv[3], a->argv[5]);
                        break;
 
                default:
-                       ast_cli(fd, "Failed to remove ignore pattern '%s' from '%s' context\n", argv[3], argv[5]);
+                       ast_cli(a->fd, "Failed to remove ignore pattern '%s' from '%s' context\n",
+                                       a->argv[3], a->argv[5]);
                        break;
                }
-               return RESULT_FAILURE;
+               return CLI_FAILURE;
        }
 
-       ast_cli(fd, "Ignore pattern '%s' removed from '%s' context\n",
-               argv[3], argv[5]);
-       return RESULT_SUCCESS;
+       ast_cli(a->fd, "Ignore pattern '%s' removed from '%s' context\n",
+               a->argv[3], a->argv[5]);
+       return CLI_SUCCESS;
 }
 
-static char *complete_context_remove_ignorepat(const char *line, const char *word,
-       int pos, int state)
+static char *complete_dialplan_remove_ignorepat(struct ast_cli_args *a)
 {
        struct ast_context *c;
        int which = 0;
        char *ret = NULL;
 
-       if (pos == 3) {
-               int len = strlen(word);
+       if (a->pos == 3) {
+               int len = strlen(a->word);
                if (ast_rdlock_contexts()) {
                        ast_log(LOG_WARNING, "Failed to lock contexts list\n");
                        return NULL;
@@ -1195,7 +1243,7 @@ static char *complete_context_remove_ignorepat(const char *line, const char *wor
                                continue;
                        
                        for (ip = NULL; !ret && (ip = ast_walk_context_ignorepats(c, ip));) {
-                               if (partial_match(ast_get_ignorepat_name(ip), word, len) && ++which > state) {
+                               if (partial_match(ast_get_ignorepat_name(ip), a->word, len) && ++which > a->n) {
                                        /* n-th match */
                                        struct ast_context *cw = NULL;
                                        int found = 0;
@@ -1211,13 +1259,13 @@ static char *complete_context_remove_ignorepat(const char *line, const char *wor
                }
                ast_unlock_contexts();
                return ret;
-       } else if (pos == 4) {
-                return state == 0 ? strdup("from") : NULL;
-       } else if (pos == 5) { /* XXX check this */
+       } else if (a->pos == 4) {
+                return a->n == 0 ? strdup("from") : NULL;
+       } else if (a->pos == 5) { /* XXX check this */
                char *dupline, *duplinet, *ignorepat;
-               int len = strlen(word);
+               int len = strlen(a->word);
 
-               dupline = strdup(line);
+               dupline = strdup(a->line);
                if (!dupline) {
                        ast_log(LOG_WARNING, "Out of free memory\n");
                        return NULL;
@@ -1242,9 +1290,9 @@ static char *complete_context_remove_ignorepat(const char *line, const char *wor
                for (c = NULL; !ret && (c = ast_walk_contexts(c)); ) {
                        if (ast_rdlock_context(c))      /* fail, skip it */
                                continue;
-                       if (!partial_match(ast_get_context_name(c), word, len))
+                       if (!partial_match(ast_get_context_name(c), a->word, len))
                                continue;
-                       if (lookup_c_ip(c, ignorepat) && ++which > state)
+                       if (lookup_c_ip(c, ignorepat) && ++which > a->n)
                                ret = strdup(ast_get_context_name(c));
                        ast_unlock_context(c);
                }
@@ -1258,54 +1306,47 @@ static char *complete_context_remove_ignorepat(const char *line, const char *wor
 
 static int pbx_load_module(void);
 
-static int handle_reload_extensions(int fd, int argc, char *argv[])
+static char *handle_cli_dialplan_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-       if (argc != 2)
-               return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "dialplan reload";
+               e->usage =
+                       "Usage: dialplan reload\n"
+                       "       Reload extensions.conf without reloading any other\n"
+                       "       modules.  This command does not delete global variables\n"
+                       "       unless clearglobalvars is set to yes in extensions.conf\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
+       if (a->argc != 2)
+               return CLI_SHOWUSAGE;
+
        if (clearglobalvars_config)
                pbx_builtin_clear_globals();
+
        pbx_load_module();
-       return RESULT_SUCCESS;
+
+       return CLI_SUCCESS;
 }
 
 /*!
  * CLI entries for commands provided by this module
  */
 static struct ast_cli_entry cli_pbx_config[] = {
-       { { "dialplan", "add", "extension", NULL },
-       handle_context_add_extension, "Add new extension into context",
-       context_add_extension_help, complete_context_add_extension },
-
-       { { "dialplan", "remove", "extension", NULL },
-       handle_context_remove_extension, "Remove a specified extension",
-       context_remove_extension_help, complete_context_remove_extension },
-
-       { { "dialplan", "add", "ignorepat", NULL },
-       handle_context_add_ignorepat, "Add new ignore pattern",
-       context_add_ignorepat_help, complete_context_add_ignorepat },
-
-       { { "dialplan", "remove", "ignorepat", NULL },
-       handle_context_remove_ignorepat, "Remove ignore pattern from context",
-       context_remove_ignorepat_help, complete_context_remove_ignorepat },
-
-       { { "dialplan", "add", "include", NULL },
-       handle_context_add_include, "Include context in other context",
-       context_add_include_help, complete_context_add_include },
-
-       { { "dialplan", "remove", "include", NULL },
-       handle_context_remove_include, "Remove a specified include from context",
-       context_remove_include_help, complete_context_remove_include },
-
-       { { "dialplan", "reload", NULL },
-       handle_reload_extensions, "Reload extensions and *only* extensions",
-       reload_extensions_help },
+       NEW_CLI(handle_cli_dialplan_add_extension,    "Add new extension into context"),
+       NEW_CLI(handle_cli_dialplan_remove_extension, "Remove a specified extension"),
+       NEW_CLI(handle_cli_dialplan_add_ignorepat,    "Add new ignore pattern"),
+       NEW_CLI(handle_cli_dialplan_remove_ignorepat, "Remove ignore pattern from context"),
+       NEW_CLI(handle_cli_dialplan_add_include,      "Include context in other context"),
+       NEW_CLI(handle_cli_dialplan_remove_include,   "Remove a specified include from context"),
+       NEW_CLI(handle_cli_dialplan_reload,           "Reload extensions and *only* extensions")
 };
 
-
-static struct ast_cli_entry cli_dialplan_save = {
-       { "dialplan", "save", NULL },
-       handle_save_dialplan, "Save dialplan",
-       save_dialplan_help };
+static struct ast_cli_entry cli_dialplan_save =
+       NEW_CLI(handle_cli_dialplan_save, "Save dialplan");
 
 /*!
  * Standard module functions ...
index d33e7c7..c2851ee 100644 (file)
@@ -2227,34 +2227,67 @@ static int start_network_thread(void)
        return 0;
 }
 
-static int dundi_do_debug(int fd, int argc, char *argv[])
+static char *dundi_do_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-       if (argc != 2)
-               return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "dundi debug";
+               e->usage = 
+                       "Usage: dundi debug\n"
+                       "       Enables dumping of DUNDi packets for debugging purposes\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+       if (a->argc != 2)
+               return CLI_SHOWUSAGE;
        dundidebug = 1;
-       ast_cli(fd, "DUNDi Debugging Enabled\n");
-       return RESULT_SUCCESS;
+       ast_cli(a->fd, "DUNDi Debugging Enabled\n");
+       return CLI_SUCCESS;
 }
 
-static int dundi_do_store_history(int fd, int argc, char *argv[])
+static char *dundi_do_store_history(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-       if (argc != 3)
-               return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "dundi store history";
+               e->usage = 
+                       "Usage: dundi store history\n"
+                       "       Enables storing of DUNDi requests and times for debugging\n"
+                       "purposes\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+       if (a->argc != 3)
+               return CLI_SHOWUSAGE;
        global_storehistory = 1;
-       ast_cli(fd, "DUNDi History Storage Enabled\n");
-       return RESULT_SUCCESS;
+       ast_cli(a->fd, "DUNDi History Storage Enabled\n");
+       return CLI_SUCCESS;
 }
 
-static int dundi_flush(int fd, int argc, char *argv[])
+static char *dundi_flush(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        int stats = 0;
-       if ((argc < 2) || (argc > 3))
-               return RESULT_SHOWUSAGE;
-       if (argc > 2) {
-               if (!strcasecmp(argv[2], "stats"))
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "dundi flush [stats]";
+               e->usage = 
+                       "Usage: dundi flush [stats]\n"
+                       "       Flushes DUNDi answer cache, used primarily for debug.  If\n"
+                       "'stats' is present, clears timer statistics instead of normal\n"
+                       "operation.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+       if ((a->argc < 2) || (a->argc > 3))
+               return CLI_SHOWUSAGE;
+       if (a->argc > 2) {
+               if (!strcasecmp(a->argv[2], "stats"))
                        stats = 1;
                else
-                       return RESULT_SHOWUSAGE;
+                       return CLI_SHOWUSAGE;
        }
        if (stats) {
                /* Flush statistics */
@@ -2273,27 +2306,48 @@ static int dundi_flush(int fd, int argc, char *argv[])
                AST_LIST_UNLOCK(&peers);
        } else {
                ast_db_deltree("dundi/cache", NULL);
-               ast_cli(fd, "DUNDi Cache Flushed\n");
+               ast_cli(a->fd, "DUNDi Cache Flushed\n");
        }
-       return RESULT_SUCCESS;
+       return CLI_SUCCESS;
 }
 
-static int dundi_no_debug(int fd, int argc, char *argv[])
+static char *dundi_no_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-       if (argc != 3)
-               return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "dundi no debug";
+               e->usage = 
+                       "Usage: dundi no debug\n"
+                       "       Disables dumping of DUNDi packets for debugging purposes\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+       if (a->argc != 3)
+               return CLI_SHOWUSAGE;
        dundidebug = 0;
-       ast_cli(fd, "DUNDi Debugging Disabled\n");
-       return RESULT_SUCCESS;
+       ast_cli(a->fd, "DUNDi Debugging Disabled\n");
+       return CLI_SUCCESS;
 }
 
-static int dundi_no_store_history(int fd, int argc, char *argv[])
+static char *dundi_no_store_history(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-       if (argc != 4)
-               return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "dundi no store history";
+               e->usage =
+                       "Usage: dundi no store history\n"
+                       "       Disables storing of DUNDi requests and times for debugging\n"
+                       "purposes\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+       if (a->argc != 4)
+               return CLI_SHOWUSAGE;
        global_storehistory = 0;
-       ast_cli(fd, "DUNDi History Storage Disabled\n");
-       return RESULT_SUCCESS;
+       ast_cli(a->fd, "DUNDi History Storage Disabled\n");
+       return CLI_SUCCESS;
 }
 
 static char *model2str(int model)
@@ -2330,11 +2384,6 @@ static char *complete_peer_helper(const char *line, const char *word, int pos, i
        return ret;
 }
 
-static char *complete_peer_4(const char *line, const char *word, int pos, int state)
-{
-       return complete_peer_helper(line, word, pos, state, 3);
-}
-
 static int rescomp(const void *a, const void *b)
 {
        const struct dundi_result *resa, *resb;
@@ -2352,7 +2401,7 @@ static void sort_results(struct dundi_result *results, int count)
        qsort(results, count, sizeof(results[0]), rescomp);
 }
 
-static int dundi_do_lookup(int fd, int argc, char *argv[])
+static char *dundi_do_lookup(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        int res;
        char tmp[256];
@@ -2362,15 +2411,28 @@ static int dundi_do_lookup(int fd, int argc, char *argv[])
        int bypass = 0;
        struct dundi_result dr[MAX_RESULTS];
        struct timeval start;
-       if ((argc < 3) || (argc > 4))
-               return RESULT_SHOWUSAGE;
-       if (argc > 3) {
-               if (!strcasecmp(argv[3], "bypass"))
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "dundi lookup";
+               e->usage =
+                       "Usage: dundi lookup <number>[@context] [bypass]\n"
+                       "       Lookup the given number within the given DUNDi context\n"
+                       "(or e164 if none is specified).  Bypasses cache if 'bypass'\n"
+                       "keyword is specified.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+
+       if ((a->argc < 3) || (a->argc > 4))
+               return CLI_SHOWUSAGE;
+       if (a->argc > 3) {
+               if (!strcasecmp(a->argv[3], "bypass"))
                        bypass=1;
                else
-                       return RESULT_SHOWUSAGE;
+                       return CLI_SHOWUSAGE;
        }
-       ast_copy_string(tmp, argv[2], sizeof(tmp));
+       ast_copy_string(tmp, a->argv[2], sizeof(tmp));
        context = strchr(tmp, '@');
        if (context) {
                *context = '\0';
@@ -2380,28 +2442,40 @@ static int dundi_do_lookup(int fd, int argc, char *argv[])
        res = dundi_lookup(dr, MAX_RESULTS, NULL, context, tmp, bypass);
        
        if (res < 0) 
-               ast_cli(fd, "DUNDi lookup returned error.\n");
+               ast_cli(a->fd, "DUNDi lookup returned error.\n");
        else if (!res) 
-               ast_cli(fd, "DUNDi lookup returned no results.\n");
+               ast_cli(a->fd, "DUNDi lookup returned no results.\n");
        else
                sort_results(dr, res);
        for (x=0;x<res;x++) {
-               ast_cli(fd, "%3d. %5d %s/%s (%s)\n", x + 1, dr[x].weight, dr[x].tech, dr[x].dest, dundi_flags2str(fs, sizeof(fs), dr[x].flags));
-               ast_cli(fd, "     from %s, expires in %d s\n", dr[x].eid_str, dr[x].expiration);
+               ast_cli(a->fd, "%3d. %5d %s/%s (%s)\n", x + 1, dr[x].weight, dr[x].tech, dr[x].dest, dundi_flags2str(fs, sizeof(fs), dr[x].flags));
+               ast_cli(a->fd, "     from %s, expires in %d s\n", dr[x].eid_str, dr[x].expiration);
        }
-       ast_cli(fd, "DUNDi lookup completed in %d ms\n", ast_tvdiff_ms(ast_tvnow(), start));
-       return RESULT_SUCCESS;
+       ast_cli(a->fd, "DUNDi lookup completed in %d ms\n", ast_tvdiff_ms(ast_tvnow(), start));
+       return CLI_SUCCESS;
 }
 
-static int dundi_do_precache(int fd, int argc, char *argv[])
+static char *dundi_do_precache(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        int res;
        char tmp[256];
        char *context;
        struct timeval start;
-       if ((argc < 3) || (argc > 3))
-               return RESULT_SHOWUSAGE;
-       ast_copy_string(tmp, argv[2], sizeof(tmp));
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "dundi precache";
+               e->usage = 
+                       "Usage: dundi precache <number>[@context]\n"
+                       "       Lookup the given number within the given DUNDi context\n"
+                       "(or e164 if none is specified) and precaches the results to any\n"
+                       "upstream DUNDi push servers.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+       if ((a->argc < 3) || (a->argc > 3))
+               return CLI_SHOWUSAGE;
+       ast_copy_string(tmp, a->argv[2], sizeof(tmp));
        context = strchr(tmp, '@');
        if (context) {
                *context = '\0';
@@ -2411,27 +2485,39 @@ static int dundi_do_precache(int fd, int argc, char *argv[])
        res = dundi_precache(context, tmp);
        
        if (res < 0) 
-               ast_cli(fd, "DUNDi precache returned error.\n");
+               ast_cli(a->fd, "DUNDi precache returned error.\n");
        else if (!res) 
-               ast_cli(fd, "DUNDi precache returned no error.\n");
-       ast_cli(fd, "DUNDi lookup completed in %d ms\n", ast_tvdiff_ms(ast_tvnow(), start));
-       return RESULT_SUCCESS;
+               ast_cli(a->fd, "DUNDi precache returned no error.\n");
+       ast_cli(a->fd, "DUNDi lookup completed in %d ms\n", ast_tvdiff_ms(ast_tvnow(), start));
+       return CLI_SUCCESS;
 }
 
-static int dundi_do_query(int fd, int argc, char *argv[])
+static char *dundi_do_query(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        int res;
        char tmp[256];
        char *context;
        dundi_eid eid;
        struct dundi_entity_info dei;
-       if ((argc < 3) || (argc > 3))
-               return RESULT_SHOWUSAGE;
-       if (dundi_str_to_eid(&eid, argv[2])) {
-               ast_cli(fd, "'%s' is not a valid EID!\n", argv[2]);
-               return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "dundi query";
+               e->usage = 
+                       "Usage: dundi query <entity>[@context]\n"
+                       "       Attempts to retrieve contact information for a specific\n"
+                       "DUNDi entity identifier (EID) within a given DUNDi context (or\n"
+                       "e164 if none is specified).\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
        }
-       ast_copy_string(tmp, argv[2], sizeof(tmp));
+       if ((a->argc < 3) || (a->argc > 3))
+               return CLI_SHOWUSAGE;
+       if (dundi_str_to_eid(&eid, a->argv[2])) {
+               ast_cli(a->fd, "'%s' is not a valid EID!\n", a->argv[2]);
+               return CLI_SHOWUSAGE;
+       }
+       ast_copy_string(tmp, a->argv[2], sizeof(tmp));
        context = strchr(tmp, '@');
        if (context) {
                *context = '\0';
@@ -2439,36 +2525,45 @@ static int dundi_do_query(int fd, int argc, char *argv[])
        }
        res = dundi_query_eid(&dei, context, eid);
        if (res < 0) 
-               ast_cli(fd, "DUNDi Query EID returned error.\n");
+               ast_cli(a->fd, "DUNDi Query EID returned error.\n");
        else if (!res) 
-               ast_cli(fd, "DUNDi Query EID returned no results.\n");
+               ast_cli(a->fd, "DUNDi Query EID returned no results.\n");
        else {
-               ast_cli(fd, "DUNDi Query EID succeeded:\n");
-               ast_cli(fd, "Department:      %s\n", dei.orgunit);
-               ast_cli(fd, "Organization:    %s\n", dei.org);
-               ast_cli(fd, "City/Locality:   %s\n", dei.locality);
-               ast_cli(fd, "State/Province:  %s\n", dei.stateprov);
-               ast_cli(fd, "Country:         %s\n", dei.country);
-               ast_cli(fd, "E-mail:          %s\n", dei.email);
-               ast_cli(fd, "Phone:           %s\n", dei.phone);
-               ast_cli(fd, "IP Address:      %s\n", dei.ipaddr);
-       }
-       return RESULT_SUCCESS;
+               ast_cli(a->fd, "DUNDi Query EID succeeded:\n");
+               ast_cli(a->fd, "Department:      %s\n", dei.orgunit);
+               ast_cli(a->fd, "Organization:    %s\n", dei.org);
+               ast_cli(a->fd, "City/Locality:   %s\n", dei.locality);
+               ast_cli(a->fd, "State/Province:  %s\n", dei.stateprov);
+               ast_cli(a->fd, "Country:         %s\n", dei.country);
+               ast_cli(a->fd, "E-mail:          %s\n", dei.email);
+               ast_cli(a->fd, "Phone:           %s\n", dei.phone);
+               ast_cli(a->fd, "IP Address:      %s\n", dei.ipaddr);
+       }
+       return CLI_SUCCESS;
 }
 
-static int dundi_show_peer(int fd, int argc, char *argv[])
+static char *dundi_show_peer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        struct dundi_peer *peer;
        struct permission *p;
        char *order;
        char eid_str[20];
        int x, cnt;
-       
-       if (argc != 4)
-               return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "dundi show peer";
+               e->usage =
+                       "Usage: dundi show peer [peer]\n"
+                       "       Provide a detailed description of a specifid DUNDi peer.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return complete_peer_helper(a->line, a->word, a->pos, a->n, 3);
+       }
+       if (a->argc != 4)
+               return CLI_SHOWUSAGE;
        AST_LIST_LOCK(&peers);
        AST_LIST_TRAVERSE(&peers, peer, list) {
-               if (!strcasecmp(dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid), argv[3]))
+               if (!strcasecmp(dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid), a->argv[3]))
                        break;
        }
        if (peer) {
@@ -2488,39 +2583,39 @@ static int dundi_show_peer(int fd, int argc, char *argv[])
                default:
                        order = "Unknown";
                }
-               ast_cli(fd, "Peer:    %s\n", dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid));
-               ast_cli(fd, "Model:   %s\n", model2str(peer->model));
-               ast_cli(fd, "Host:    %s\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "<Unspecified>");
-               ast_cli(fd, "Dynamic: %s\n", peer->dynamic ? "yes" : "no");
-               ast_cli(fd, "Reg:     %s\n", peer->registerid < 0 ? "No" : "Yes");
-               ast_cli(fd, "In Key:  %s\n", ast_strlen_zero(peer->inkey) ? "<None>" : peer->inkey);
-               ast_cli(fd, "Out Key: %s\n", ast_strlen_zero(peer->outkey) ? "<None>" : peer->outkey);
+               ast_cli(a->fd, "Peer:    %s\n", dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid));
+               ast_cli(a->fd, "Model:   %s\n", model2str(peer->model));
+               ast_cli(a->fd, "Host:    %s\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "<Unspecified>");
+               ast_cli(a->fd, "Dynamic: %s\n", peer->dynamic ? "yes" : "no");
+               ast_cli(a->fd, "Reg:     %s\n", peer->registerid < 0 ? "No" : "Yes");
+               ast_cli(a->fd, "In Key:  %s\n", ast_strlen_zero(peer->inkey) ? "<None>" : peer->inkey);
+               ast_cli(a->fd, "Out Key: %s\n", ast_strlen_zero(peer->outkey) ? "<None>" : peer->outkey);
                if (!AST_LIST_EMPTY(&peer->include))
-                       ast_cli(fd, "Include logic%s:\n", peer->model & DUNDI_MODEL_OUTBOUND ? "" : " (IGNORED)");
+                       ast_cli(a->fd, "Include logic%s:\n", peer->model & DUNDI_MODEL_OUTBOUND ? "" : " (IGNORED)");
                AST_LIST_TRAVERSE(&peer->include, p, list)
-                       ast_cli(fd, "-- %s %s\n", p->allow ? "include" : "do not include", p->name);
+                       ast_cli(a->fd, "-- %s %s\n", p->allow ? "include" : "do not include", p->name);
                if (!AST_LIST_EMPTY(&peer->permit))
-                       ast_cli(fd, "Query logic%s:\n", peer->model & DUNDI_MODEL_INBOUND ? "" : " (IGNORED)");
+                       ast_cli(a->fd, "Query logic%s:\n", peer->model & DUNDI_MODEL_INBOUND ? "" : " (IGNORED)");
                AST_LIST_TRAVERSE(&peer->permit, p, list)
-                       ast_cli(fd, "-- %s %s\n", p->allow ? "permit" : "deny", p->name);
+                       ast_cli(a->fd, "-- %s %s\n", p->allow ? "permit" : "deny", p->name);
                cnt = 0;
                for (x = 0;x < DUNDI_TIMING_HISTORY; x++) {
                        if (peer->lookups[x]) {
                                if (!cnt)
-                                       ast_cli(fd, "Last few query times:\n");
-                               ast_cli(fd, "-- %d. %s (%d ms)\n", x + 1, peer->lookups[x], peer->lookuptimes[x]);
+                                       ast_cli(a->fd, "Last few query times:\n");
+                               ast_cli(a->fd, "-- %d. %s (%d ms)\n", x + 1, peer->lookups[x], peer->lookuptimes[x]);
                                cnt++;
                        }
                }
                if (cnt)
-                       ast_cli(fd, "Average query time: %d ms\n", peer->avgms);
+                       ast_cli(a->fd, "Average query time: %d ms\n", peer->avgms);
        } else
-               ast_cli(fd, "No such peer '%s'\n", argv[3]);
+               ast_cli(a->fd, "No such peer '%s'\n", a->argv[3]);
        AST_LIST_UNLOCK(&peers);
-       return RESULT_SUCCESS;
+       return CLI_SUCCESS;
 }
 
-static int dundi_show_peers(int fd, int argc, char *argv[])
+static char *dundi_show_peers(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 #define FORMAT2 "%-20.20s %-15.15s     %-10.10s %-8.8s %-15.15s\n"
 #define FORMAT "%-20.20s %-15.15s %s %-10.10s %-8.8s %-15.15s\n"
@@ -2532,17 +2627,28 @@ static int dundi_show_peers(int fd, int argc, char *argv[])
        int offline_peers = 0;
        int unmonitored_peers = 0;
        int total_peers = 0;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "dundi show peers [registered|include|exclude|begin]";
+               e->usage = 
+                       "Usage: dundi show peers [registered|include|exclude|begin]\n"
+                       "       Lists all known DUNDi peers.\n"
+                       "       If 'registered' is present, only registered peers are shown.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
 
-       if ((argc != 3) && (argc != 4) && (argc != 5))
-               return RESULT_SHOWUSAGE;
-       if ((argc == 4)) {
-               if (!strcasecmp(argv[3], "registered")) {
+       if ((a->argc != 3) && (a->argc != 4) && (a->argc != 5))
+               return CLI_SHOWUSAGE;
+       if ((a->argc == 4)) {
+               if (!strcasecmp(a->argv[3], "registered")) {
                        registeredonly = 1;
                } else
-                       return RESULT_SHOWUSAGE;
+                       return CLI_SHOWUSAGE;
        }
        AST_LIST_LOCK(&peers);
-       ast_cli(fd, FORMAT2, "EID", "Host", "Model", "AvgTime", "Status");
+       ast_cli(a->fd, FORMAT2, "EID", "Host", "Model", "AvgTime", "Status");
        AST_LIST_TRAVERSE(&peers, peer, list) {
                char status[20];
                int print_line = -1;
@@ -2579,12 +2685,12 @@ static int dundi_show_peers(int fd, int argc, char *argv[])
                                        peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
                                        peer->dynamic ? "(D)" : "(S)", model2str(peer->model), avgms, status);
 
-                if (argc == 5) {
-                  if (!strcasecmp(argv[3],"include") && strstr(srch,argv[4])) {
+                if (a->argc == 5) {
+                  if (!strcasecmp(a->argv[3],"include") && strstr(srch,a->argv[4])) {
                         print_line = -1;
-                   } else if (!strcasecmp(argv[3],"exclude") && !strstr(srch,argv[4])) {
+                   } else if (!strcasecmp(a->argv[3],"exclude") && !strstr(srch,a->argv[4])) {
                         print_line = 1;
-                   } else if (!strcasecmp(argv[3],"begin") && !strncasecmp(srch,argv[4],strlen(argv[4]))) {
+                   } else if (!strcasecmp(a->argv[3],"begin") && !strncasecmp(srch,a->argv[4],strlen(a->argv[4]))) {
                         print_line = -1;
                    } else {
                         print_line = 0;
@@ -2592,106 +2698,155 @@ static int dundi_show_peers(int fd, int argc, char *argv[])
                 }
                
         if (print_line) {
-                       ast_cli(fd, FORMAT, dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid), 
+                       ast_cli(a->fd, FORMAT, dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid), 
                                        peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
                                        peer->dynamic ? "(D)" : "(S)", model2str(peer->model), avgms, status);
                }
        }
-       ast_cli(fd, "%d dundi peers [%d online, %d offline, %d unmonitored]\n", total_peers, online_peers, offline_peers, unmonitored_peers);
+       ast_cli(a->fd, "%d dundi peers [%d online, %d offline, %d unmonitored]\n", total_peers, online_peers, offline_peers, unmonitored_peers);
        AST_LIST_UNLOCK(&peers);
-       return RESULT_SUCCESS;
+       return CLI_SUCCESS;
 #undef FORMAT
 #undef FORMAT2
 }
 
-static int dundi_show_trans(int fd, int argc, char *argv[])
+static char *dundi_show_trans(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 #define FORMAT2 "%-22.22s %-5.5s %-5.5s %-3.3s %-3.3s %-3.3s\n"
 #define FORMAT "%-16.16s:%5d %-5.5d %-5.5d %-3.3d %-3.3d %-3.3d\n"
        struct dundi_transaction *trans;
-       if (argc != 3)
-               return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "dundi show trans";
+               e->usage = 
+                       "Usage: dundi show trans\n"
+                       "       Lists all known DUNDi transactions.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+       if (a->argc != 3)
+               return CLI_SHOWUSAGE;
        AST_LIST_LOCK(&peers);
-       ast_cli(fd, FORMAT2, "Remote", "Src", "Dst", "Tx", "Rx", "Ack");
+       ast_cli(a->fd, FORMAT2, "Remote", "Src", "Dst", "Tx", "Rx", "Ack");
        AST_LIST_TRAVERSE(&alltrans, trans, all) {
-               ast_cli(fd, FORMAT, ast_inet_ntoa(trans->addr.sin_addr), 
+               ast_cli(a->fd, FORMAT, ast_inet_ntoa(trans->addr.sin_addr), 
                        ntohs(trans->addr.sin_port), trans->strans, trans->dtrans, trans->oseqno, trans->iseqno, trans->aseqno);
        }
        AST_LIST_UNLOCK(&peers);
-       return RESULT_SUCCESS;
+       return CLI_SUCCESS;
 #undef FORMAT
 #undef FORMAT2
 }
 
-static int dundi_show_entityid(int fd, int argc, char *argv[])
+static char *dundi_show_entityid(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        char eid_str[20];
-       if (argc != 3)
-               return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "dundi show entityid";
+               e->usage =
+                       "Usage: dundi show entityid\n"
+                       "       Displays the global entityid for this host.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+       if (a->argc != 3)
+               return CLI_SHOWUSAGE;
        AST_LIST_LOCK(&peers);
        dundi_eid_to_str(eid_str, sizeof(eid_str), &global_eid);
        AST_LIST_UNLOCK(&peers);
-       ast_cli(fd, "Global EID for this system is '%s'\n", eid_str);
-       return RESULT_SUCCESS;
+       ast_cli(a->fd, "Global EID for this system is '%s'\n", eid_str);
+       return CLI_SUCCESS;
 }
 
-static int dundi_show_requests(int fd, int argc, char *argv[])
+static char *dundi_show_requests(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 #define FORMAT2 "%-15s %-15s %-15s %-3.3s %-3.3s\n"
 #define FORMAT "%-15s %-15s %-15s %-3.3d %-3.3d\n"
        struct dundi_request *req;
        char eidstr[20];
-       if (argc != 3)
-               return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "dundi show requests";
+               e->usage = 
+                       "Usage: dundi show requests\n"
+                       "       Lists all known pending DUNDi requests.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+       if (a->argc != 3)
+               return CLI_SHOWUSAGE;
        AST_LIST_LOCK(&peers);
-       ast_cli(fd, FORMAT2, "Number", "Context", "Root", "Max", "Rsp");
+       ast_cli(a->fd, FORMAT2, "Number", "Context", "Root", "Max", "Rsp");
        AST_LIST_TRAVERSE(&requests, req, list) {
-               ast_cli(fd, FORMAT, req->number, req->dcontext,
+               ast_cli(a->fd, FORMAT, req->number, req->dcontext,
                        dundi_eid_zero(&req->root_eid) ? "<unspecified>" : dundi_eid_to_str(eidstr, sizeof(eidstr), &req->root_eid), req->maxcount, req->respcount);
        }
        AST_LIST_UNLOCK(&peers);
-       return RESULT_SUCCESS;
+       return CLI_SUCCESS;
 #undef FORMAT
 #undef FORMAT2
 }
 
 /* Grok-a-dial DUNDi */
 
-static int dundi_show_mappings(int fd, int argc, char *argv[])
+static char *dundi_show_mappings(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 #define FORMAT2 "%-12.12s %-7.7s %-12.12s %-10.10s %-5.5s %-25.25s\n"
 #define FORMAT "%-12.12s %-7s %-12.12s %-10.10s %-5.5s %-25.25s\n"
        struct dundi_mapping *map;
        char fs[256];
        char weight[8];
-       if (argc != 3)
-               return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "dundi show mappings";
+               e->usage = 
+                       "Usage: dundi show mappings\n"
+                       "       Lists all known DUNDi mappings.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+       if (a->argc != 3)
+               return CLI_SHOWUSAGE;
        AST_LIST_LOCK(&peers);
-       ast_cli(fd, FORMAT2, "DUNDi Cntxt", "Weight", "Local Cntxt", "Options", "Tech", "Destination");
+       ast_cli(a->fd, FORMAT2, "DUNDi Cntxt", "Weight", "Local Cntxt", "Options", "Tech", "Destination");
        AST_LIST_TRAVERSE(&mappings, map, list) {
                snprintf(weight, sizeof(weight), "%d", get_mapping_weight(map));
-               ast_cli(fd, FORMAT, map->dcontext, weight,
+               ast_cli(a->fd, FORMAT, map->dcontext, weight,
                        ast_strlen_zero(map->lcontext) ? "<none>" : map->lcontext, 
                        dundi_flags2str(fs, sizeof(fs), map->options), tech2str(map->tech), map->dest);
        }
        AST_LIST_UNLOCK(&peers);
-       return RESULT_SUCCESS;
+       return CLI_SUCCESS;
 #undef FORMAT
 #undef FORMAT2
 }
 
-static int dundi_show_precache(int fd, int argc, char *argv[])
+static char *dundi_show_precache(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 #define FORMAT2 "%-12.12s %-12.12s %-10.10s\n"
 #define FORMAT "%-12.12s %-12.12s %02d:%02d:%02d\n"
        struct dundi_precache_queue *qe;
        int h,m,s;
        time_t now;
-       
-       if (argc != 3)
-               return RESULT_SHOWUSAGE;
+       switch (cmd) {
+       case CLI_INIT:
+               e->command = "dundi show precache";
+               e->usage = 
+                       "Usage: dundi show precache\n"
+                       "       Lists all known DUNDi scheduled precache updates.\n";
+               return NULL;
+       case CLI_GENERATE:
+               return NULL;
+       }
+       if (a->argc != 3)
+               return CLI_SHOWUSAGE;
        time(&now);
-       ast_cli(fd, FORMAT2, "Number", "Context", "Expiration");
+       ast_cli(a->fd, FORMAT2, "Number", "Context", "Expiration");
        AST_LIST_LOCK(&pcq);
        AST_LIST_TRAVERSE(&pcq, qe, list) {
                s = qe->expiration - now;
@@ -2699,145 +2854,31 @@ static int dundi_show_precache(int fd, int argc, char *argv[])
                s = s % 3600;
                m = s / 60;
                s = s % 60;
-               ast_cli(fd, FORMAT, qe->number, qe->context, h,m,s);
+               ast_cli(a->fd, FORMAT, qe->number, qe->context, h,m,s);
        }
        AST_LIST_UNLOCK(&pcq);
        
-       return RESULT_SUCCESS;
+       return CLI_SUCCESS;
 #undef FORMAT
 #undef FORMAT2
 }
 
-static const char debug_usage[] = 
-"Usage: dundi debug\n"
-"       Enables dumping of DUNDi packets for debugging purposes\n";
-
-static const char no_debug_usage[] = 
-"Usage: dundi no debug\n"
-"       Disables dumping of DUNDi packets for debugging purposes\n";
-
-static const char store_history_usage[] = 
-"Usage: dundi store history\n"
-"       Enables storing of DUNDi requests and times for debugging\n"
-"purposes\n";
-
-static const char no_store_history_usage[] = 
-"Usage: dundi no store history\n"
-"       Disables storing of DUNDi requests and times for debugging\n"
-"purposes\n";
-
-static const char show_peers_usage[] = 
-"Usage: dundi show peers\n"
-"       Lists all known DUNDi peers.\n";
-
-static const char show_trans_usage[] = 
-"Usage: dundi show trans\n"
-"       Lists all known DUNDi transactions.\n";
-
-static const char show_mappings_usage[] = 
-"Usage: dundi show mappings\n"
-"       Lists all known DUNDi mappings.\n";
-
-static const char show_precache_usage[] = 
-"Usage: dundi show precache\n"
-"       Lists all known DUNDi scheduled precache updates.\n";
-
-static const char show_entityid_usage[] = 
-"Usage: dundi show entityid\n"
-"       Displays the global entityid for this host.\n";
-
-static const char show_peer_usage[] = 
-"Usage: dundi show peer [peer]\n"
-"       Provide a detailed description of a specifid DUNDi peer.\n";
-
-static const char show_requests_usage[] = 
-"Usage: dundi show requests\n"
-"       Lists all known pending DUNDi requests.\n";
-
-static const char lookup_usage[] =
-"Usage: dundi lookup <number>[@context] [bypass]\n"
-"       Lookup the given number within the given DUNDi context\n"
-"(or e164 if none is specified).  Bypasses cache if 'bypass'\n"
-"keyword is specified.\n";
-
-static const char precache_usage[] =
-"Usage: dundi precache <number>[@context]\n"
-"       Lookup the given number within the given DUNDi context\n"
-"(or e164 if none is specified) and precaches the results to any\n"
-"upstream DUNDi push servers.\n";
-
-static const char query_usage[] =
-"Usage: dundi query <entity>[@context]\n"
-"       Attempts to retrieve contact information for a specific\n"
-"DUNDi entity identifier (EID) within a given DUNDi context (or\n"
-"e164 if none is specified).\n";
-
-static const char flush_usage[] =
-"Usage: dundi flush [stats]\n"
-"       Flushes DUNDi answer cache, used primarily for debug.  If\n"
-"'stats' is present, clears timer statistics instead of normal\n"
-"operation.\n";
-
 static struct ast_cli_entry cli_dundi[] = {
-       { { "dundi", "debug", NULL },
-       dundi_do_debug, "Enable DUNDi debugging",
-       debug_usage },
-
-       { { "dundi", "store", "history", NULL },
-       dundi_do_store_history, "Enable DUNDi historic records",
-       store_history_usage },
-
-       { { "dundi", "no", "store", "history", NULL },
-       dundi_no_store_history, "Disable DUNDi historic records",
-       no_store_history_usage },
-
-       { { "dundi", "flush", NULL },
-       dundi_flush, "Flush DUNDi cache",
-       flush_usage },
-
-       { { "dundi", "no", "debug", NULL },
-       dundi_no_debug, "Disable DUNDi debugging",
-       no_debug_usage },
-
-       { { "dundi", "show", "peers", NULL },
-       dundi_show_peers, "Show defined DUNDi peers",
-       show_peers_usage },
-
-       { { "dundi", "show", "trans", NULL },
-       dundi_show_trans, "Show active DUNDi transactions",
-       show_trans_usage },
-
-       { { "dundi", "show", "entityid", NULL },
-       dundi_show_entityid, "Display Global Entity ID",
-       show_entityid_usage },
-
-       { { "dundi", "show", "mappings", NULL },
-       dundi_show_mappings, "Show DUNDi mappings",
-       show_mappings_usage },
-
-       { { "dundi", "show", "precache", NULL },
-       dundi_show_precache, "Show DUNDi precache",
-       show_precache_usage },
-
-       { { "dundi", "show", "requests", NULL },
-       dundi_show_requests, "Show DUNDi requests",
-       show_requests_usage },
-
-       { { "dundi", "show", "peer", NULL },
-       dundi_show_peer, "Show info on a specific DUNDi peer",
-       show_peer_usage, complete_peer_4 },
-
-       { { "dundi", "lookup", NULL },
-       dundi_do_lookup, "Lookup a number in DUNDi",
-       lookup_usage },
-
-       { { "dundi", "precache", NULL },
-       dundi_do_precache, "Precache a number in DUNDi",
-       precache_usage },
-
-       { { "dundi", "query", NULL },
-       dundi_do_query, "Query a DUNDi EID",
-       query_usage },
+       NEW_CLI(dundi_do_debug, "Enable DUNDi debugging"),
+       NEW_CLI(dundi_no_debug, "Disable DUNDi debugging"),
+       NEW_CLI(dundi_do_store_history, "Enable DUNDi historic records"),
+       NEW_CLI(dundi_no_store_history, "Disable DUNDi historic records"),
+       NEW_CLI(dundi_flush, "Flush DUNDi cache"),
+       NEW_CLI(dundi_show_peers, "Show defined DUNDi peers"),
+       NEW_CLI(dundi_show_trans, "Show active DUNDi transactions"),
+       NEW_CLI(dundi_show_entityid, "Display Global Entity ID"),
+       NEW_CLI(dundi_show_mappings, "Show DUNDi mappings"),
+       NEW_CLI(dundi_show_precache, "Show DUNDi precache"),
+       NEW_CLI(dundi_show_requests, "Show DUNDi requests"),
+       NEW_CLI(dundi_show_peer, "Show info on a specific DUNDi peer"),
+       NEW_CLI(dundi_do_precache, "Precache a number in DUNDi"),
+       NEW_CLI(dundi_do_lookup, "Lookup a number in DUNDi"),
+       NEW_CLI(dundi_do_query, "Query a DUNDi EID"),
 };
 
 static struct dundi_transaction *create_transaction(struct dundi_peer *p)
index 8497f63..7a9245a 100644 (file)
@@ -43,61 +43,35 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$");
 /*! The timeout for originated calls, in seconds */
 #define TIMEOUT 30
 
-static char orig_help[] = 
-"  There are two ways to use this command. A call can be originated between a\n"
-"channel and a specific application, or between a channel and an extension in\n"
-"the dialplan. This is similar to call files or the manager originate action.\n"
-"Calls originated with this command are given a timeout of 30 seconds.\n\n"
-
-"Usage1: originate <tech/data> application <appname> [appdata]\n"
-"  This will originate a call between the specified channel tech/data and the\n"
-"given application. Arguments to the application are optional. If the given\n"
-"arguments to the application include spaces, all of the arguments to the\n"
-"application need to be placed in quotation marks.\n\n"
-
-"Usage2: originate <tech/data> extension [exten@][context]\n"
-"  This will originate a call between the specified channel tech/data and the\n"
-"given extension. If no context is specified, the 'default' context will be\n"
-"used. If no extension is given, the 's' extension will be used.\n";
-
-static int handle_orig(int fd, int argc, char *argv[]);
-static char *complete_orig(const char *line, const char *word, int pos, int state);
-
-struct ast_cli_entry cli_cliorig[] = {
-       { { "originate", NULL },
-       handle_orig, "Originate a call",
-       orig_help, complete_orig },
-};
-
 /*!
  * \brief orginate a call from the CLI
  * \param fd file descriptor for cli
  * \param chan channel to create type/data
  * \param app application you want to run
  * \param appdata data for application
- * \retval RESULT_SUCCESS on success.
- * \retval RESULT_SHOWUSAGE on failure.
+ * \retval CLI_SUCCESS on success.
+ * \retval CLI_SHOWUSAGE on failure.
 */
-static int orig_app(int fd, const char *chan, const char *app, const char *appdata)
+static char *orig_app(int fd, const char *chan, const char *app, const char *appdata)
 {
        char *chantech;
        char *chandata;
        int reason = 0;
        
        if (ast_strlen_zero(app))
-               return RESULT_SHOWUSAGE;
+               return CLI_SHOWUSAGE;
 
        chandata = ast_strdupa(chan);
        
        chantech = strsep(&chandata, "/");
        if (!chandata) {
                ast_cli(fd, "*** No data provided after channel type! ***\n");
-               return RESULT_SHOWUSAGE;
+               return CLI_SHOWUSAGE;
        }
 
        ast_pbx_outgoing_app(chantech, AST_FORMAT_SLINEAR, chandata, TIMEOUT * 1000, app, appdata, &reason, 1, NULL, NULL, NULL, NULL, NULL);
 
-       return RESULT_SUCCESS;
+       return CLI_SUCCESS;
 }
 
 /*!
@@ -105,10 +79,10 @@ static int orig_app(int fd, const char *chan, const char *app, const char *appda
  * \param fd file descriptor for cli
  * \param chan channel to create type/data
  * \param data contains exten\@context
- * \retval RESULT_SUCCESS on success.
- * \retval RESULT_SHOWUSAGE on failure.
+ * \retval CLI_SUCCESS on success.
+ * \retval CLI_SHOWUSAGE on failure.
 */
-static int orig_exten(int fd, const char *chan, const char *data)
+static char *orig_exten(int fd, const char *chan, const char *data)
 {
        char *chantech;
        char *chandata;
@@ -121,7 +95,7 @@ static int orig_exten(int fd, const char *chan, const char *data)
        chantech = strsep(&chandata, "/");
        if (!chandata) {
                ast_cli(fd, "*** No data provided after channel type! ***\n");
-               return RESULT_SHOWUSAGE;
+               return CLI_SHOWUSAGE;
        }
 
        if (!ast_strlen_zero(data)) {
@@ -136,63 +110,74 @@ static int orig_exten(int fd, const char *chan, const char *data)
        
        ast_pbx_outgoing_exten(chantech, AST_FORMAT_SLINEAR, chandata, TIMEOUT * 1000, context, exten, 1, &reason, 1, NULL, NULL, NULL, NULL, NULL);
 
-       return RESULT_SUCCESS;
+       return CLI_SUCCESS;
 }
 
 /*!
  * \brief handle for orgination app or exten.
- * \param fd file descriptor
- * \param argc no of arguements
- * \param argv contains either application or extension arguements
- * \retval RESULT_SUCCESS on success.
- * \retval RESULT_SHOWUSAGE on failure.
+ * \param e pointer to the CLI structure to initialize
+ * \param cmd operation to