diff --git a/apps/app_mixmonitor.c b/apps/app_mixmonitor.c index 614adcba12..ca775f163c 100644 --- a/apps/app_mixmonitor.c +++ b/apps/app_mixmonitor.c @@ -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 [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 [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) diff --git a/apps/app_osplookup.c b/apps/app_osplookup.c index 25b3fb5188..5c4e2402bb 100644 --- a/apps/app_osplookup.c +++ b/apps/app_osplookup.c @@ -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 : ""); - 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 : ""); + 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) diff --git a/apps/app_rpt.c b/apps/app_rpt.c index 77e4ee4efb..1f77cee3a5 100644 --- a/apps/app_rpt.c +++ b/apps/app_rpt.c @@ -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 \n" -" Dumps struct debug info to log\n"; - -static char dump_stats[] = -"Usage: rpt stats \n" -" Dumps node statistics to console\n"; - -static char dump_lstats[] = -"Usage: rpt lstats \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 \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 \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, ""); + ast_cli(a->fd, ""); } 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 \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; diff --git a/channels/chan_gtalk.c b/channels/chan_gtalk.c index a67df2c8ae..be3a346c57 100644 --- a/channels/chan_gtalk.c +++ b/channels/chan_gtalk.c @@ -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(>alklock); - ast_cli(fd, FORMAT, "Channel", "Jabber ID", "Resource", "Read", "Write"); + ast_cli(a->fd, FORMAT, "Channel", "Jabber ID", "Resource", "Read", "Write"); ASTOBJ_CONTAINER_TRAVERSE(>alk_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(>alklock); - 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) diff --git a/channels/chan_mgcp.c b/channels/chan_mgcp.c index 7693397c76..a509dea7d0 100644 --- a/channels/chan_mgcp.c +++ b/channels/chan_mgcp.c @@ -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 \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 \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; } diff --git a/channels/chan_oss.c b/channels/chan_oss.c index 42e0546093..cea7984dcd 100644 --- a/channels/chan_oss.c +++ b/channels/chan_oss.c @@ -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 [@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 [@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"), }; /*! diff --git a/channels/chan_skinny.c b/channels/chan_skinny.c index b1a83abbea..0e58689824 100644 --- a/channels/chan_skinny.c +++ b/channels/chan_skinny.c @@ -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 [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 \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 [ on ]\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, "")); - 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, "")); - ast_cli(fd, "Accountcode: %s\n", S_OR(l->accountcode, "")); - ast_cli(fd, "AmaFlag: %s\n", ast_cdr_flags2str(l->amaflags)); - ast_cli(fd, "CallerId Number: %s\n", S_OR(l->cid_num, "")); - ast_cli(fd, "CallerId Name: %s\n", S_OR(l->cid_name, "")); - ast_cli(fd, "Hide CallerId: %s\n", (l->hidecallerid ? "Yes" : "No")); - ast_cli(fd, "CallForward: %s\n", S_OR(l->call_forward, "")); - ast_cli(fd, "VoicemailBox: %s\n", S_OR(l->mailbox, "")); - ast_cli(fd, "VoicemailNumber: %s\n", S_OR(l->vmexten, "")); - ast_cli(fd, "MWIblink: %d\n", l->mwiblink); - ast_cli(fd, "Regextension: %s\n", S_OR(l->regexten, "")); - ast_cli(fd, "Regcontext: %s\n", S_OR(l->regcontext, "")); - ast_cli(fd, "MoHInterpret: %s\n", S_OR(l->mohinterpret, "")); - ast_cli(fd, "MoHSuggest: %s\n", S_OR(l->mohsuggest, "")); - ast_cli(fd, "Last dialed nr: %s\n", S_OR(l->lastnumberdialed, "")); - ast_cli(fd, "Last CallerID: %s\n", S_OR(l->lastcallerid, "")); - 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, "")); + 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, "")); + ast_cli(a->fd, "Accountcode: %s\n", S_OR(l->accountcode, "")); + 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, "")); + ast_cli(a->fd, "CallerId Name: %s\n", S_OR(l->cid_name, "")); + ast_cli(a->fd, "Hide CallerId: %s\n", (l->hidecallerid ? "Yes" : "No")); + ast_cli(a->fd, "CallForward: %s\n", S_OR(l->call_forward, "")); + ast_cli(a->fd, "VoicemailBox: %s\n", S_OR(l->mailbox, "")); + ast_cli(a->fd, "VoicemailNumber: %s\n", S_OR(l->vmexten, "")); + ast_cli(a->fd, "MWIblink: %d\n", l->mwiblink); + ast_cli(a->fd, "Regextension: %s\n", S_OR(l->regexten, "")); + ast_cli(a->fd, "Regcontext: %s\n", S_OR(l->regcontext, "")); + ast_cli(a->fd, "MoHInterpret: %s\n", S_OR(l->mohinterpret, "")); + ast_cli(a->fd, "MoHSuggest: %s\n", S_OR(l->mohsuggest, "")); + ast_cli(a->fd, "Last dialed nr: %s\n", S_OR(l->lastnumberdialed, "")); + ast_cli(a->fd, "Last CallerID: %s\n", S_OR(l->lastcallerid, "")); + 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 \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 [ on ]\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 [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 diff --git a/channels/iax2-provision.c b/channels/iax2-provision.c index 031897fc70..782a4097e1 100644 --- a/channels/iax2-provision.c +++ b/channels/iax2-provision.c @@ -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 : ""); - 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 : ""); + 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) diff --git a/main/asterisk.c b/main/asterisk.c index 59b97e59e3..6e9ccb7d4a 100644 --- a/main/asterisk.c +++ b/main/asterisk.c @@ -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 ]\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 ]\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(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB)) - return RESULT_SHOWUSAGE; + if (!strcasecmp(a->argv[4], "like")) { + if (regcomp(®exbuf, 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(®exbuf, 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(®exbuf); - 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: !\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: !\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 */ }; diff --git a/main/astobj2.c b/main/astobj2.c index f7fde9a293..7e1bdb0217 100644 --- a/main/astobj2.c +++ b/main/astobj2.c @@ -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 \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 */ diff --git a/main/cdr.c b/main/cdr.c index 12d1e37fd5..3c28b1cbdc 100644 --- a/main/cdr.c +++ b/main/cdr.c @@ -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) { diff --git a/main/channel.c b/main/channel.c index 9cdf0521dc..9e209714c9 100644 --- a/main/channel.c +++ b/main/channel.c @@ -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 \n" + " Show details about the specified channel type, .\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 \n" -" Show details about the specified channel type, .\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 */ diff --git a/main/cli.c b/main/cli.c index 7e7514aba1..da4c25fe35 100644 --- a/main/cli.c +++ b/main/cli.c @@ -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 \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 \n" -" Shows lots of information about the specified channel.\n"; - -static const char commandcomplete_help[] = -"Usage: _command complete \"\" 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 \"\" 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 \"\" 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 \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 \"\" 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 \"\" 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 \"\" 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 \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 == ¬found ? 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(®exbuf, argv[3], REG_EXTENDED | REG_NOSUB)) - return RESULT_SHOWUSAGE; + if (a->argc == 4) { + if (regcomp(®exbuf, 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(®exbuf, 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(®exbuf); - 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"), }; /*! diff --git a/main/db.c b/main/db.c index c38d8c8cc5..58245c255b 100644 --- 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 \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 \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 \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 [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 = ""; } 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 \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 = ""; } 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 \n" -" Shows Asterisk database contents, restricted to a given key.\n"; - -static const char database_put_usage[] = -"Usage: database put \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 \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 \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 [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) diff --git a/main/file.c b/main/file.c index 19f50bf81e..93763c8726 100644 --- a/main/file.c +++ b/main/file.c @@ -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) diff --git a/main/image.c b/main/image.c index 718d463a98..0530ec5a42 100644 --- a/main/image.c +++ b/main/image.c @@ -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) diff --git a/main/threadstorage.c b/main/threadstorage.c index 26f3e1c192..de3e9e0df3 100644 --- a/main/threadstorage.c +++ b/main/threadstorage.c @@ -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 []\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 []\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 []\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 []\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) diff --git a/main/translate.c b/main/translate.c index b22a3386dd..88811ddc8e 100644 --- a/main/translate.c +++ b/main/translate.c @@ -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] []\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] []\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 */ diff --git a/main/udptl.c b/main/udptl.c index d3c6163e7b..a140cc4fe5 100644 --- a/main/udptl.c +++ b/main/udptl.c @@ -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) diff --git a/pbx/pbx_ael.c b/pbx/pbx_ael.c index 68902a0731..f5a54f0bf0 100644 --- a/pbx/pbx_ael.c +++ b/pbx/pbx_ael.c @@ -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) diff --git a/pbx/pbx_config.c b/pbx/pbx_config.c index 449bf3583c..4c7c42ae2a 100644 --- a/pbx/pbx_config.c +++ b/pbx/pbx_config.c @@ -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 ,,,\n" -" into [replace]\n\n" -" This command will add new extension into . 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 into \n" -" This command adds a new ignore pattern into context \n" -"\n" -"Example: dialplan add ignorepat _3XX into local\n"; - -static char context_remove_ignorepat_help[] = -"Usage: dialplan remove ignorepat from \n" -" This command removes an ignore pattern from context \n" -"\n" -"Example: dialplan remove ignorepat _3XX from local\n"; - -static char context_add_include_help[] = -"Usage: dialplan add include into \n" -" Include a context in another context.\n"; - -static char context_remove_include_help[] = -"Usage: dialplan remove include from \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 from \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 into \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 ,,,\n" + " into [replace]\n\n" + " This command will add new extension into . 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 into \n" + " This command adds a new ignore pattern into 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 from \n" + " This command removes an ignore pattern from 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 ... diff --git a/pbx/pbx_dundi.c b/pbx/pbx_dundi.c index d33e7c757b..c2851eef23 100644 --- a/pbx/pbx_dundi.c +++ b/pbx/pbx_dundi.c @@ -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 [@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;xfd, "%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 [@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 [@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) : ""); - 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) ? "" : peer->inkey); - ast_cli(fd, "Out Key: %s\n", ast_strlen_zero(peer->outkey) ? "" : 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) : ""); + 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) ? "" : peer->inkey); + ast_cli(a->fd, "Out Key: %s\n", ast_strlen_zero(peer->outkey) ? "" : 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) ? "" : 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) ? "" : 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 [@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 [@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 [@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) diff --git a/res/res_clioriginate.c b/res/res_clioriginate.c index 8497f6387a..7a9245aba5 100644 --- a/res/res_clioriginate.c +++ b/res/res_clioriginate.c @@ -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 application [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 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 execute + * \param a structure that contains either application or extension arguements + * \retval CLI_SUCCESS on success. + * \retval CLI_SHOWUSAGE on failure. */ -static int handle_orig(int fd, int argc, char *argv[]) +static char *handle_orig(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { - int res; + static char *choices[] = { "application", "extension", NULL }; + char *res; + switch (cmd) { + case CLI_INIT: + e->command = "originate"; + e->usage = + " 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 application [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 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"; + return NULL; + case CLI_GENERATE: + if (a->pos != 2) + return NULL; + + /* ugly, can be removed when CLI entries have ast_module pointers */ + ast_module_ref(ast_module_info->self); + res = ast_cli_complete(a->word, choices, a->n); + ast_module_unref(ast_module_info->self); - if (ast_strlen_zero(argv[1]) || ast_strlen_zero(argv[2])) - return RESULT_SHOWUSAGE; + return res; + } + + if (ast_strlen_zero(a->argv[1]) || ast_strlen_zero(a->argv[2])) + return CLI_SHOWUSAGE; /* ugly, can be removed when CLI entries have ast_module pointers */ ast_module_ref(ast_module_info->self); - if (!strcasecmp("application", argv[2])) { - res = orig_app(fd, argv[1], argv[3], argv[4]); - } else if (!strcasecmp("extension", argv[2])) { - res = orig_exten(fd, argv[1], argv[3]); + if (!strcasecmp("application", a->argv[2])) { + res = orig_app(a->fd, a->argv[1], a->argv[3], a->argv[4]); + } else if (!strcasecmp("extension", a->argv[2])) { + res = orig_exten(a->fd, a->argv[1], a->argv[3]); } else - res = RESULT_SHOWUSAGE; + res = CLI_SHOWUSAGE; ast_module_unref(ast_module_info->self); return res; } -/*! - * \brief complete suggestions for orginate command - * \param line - * \param word to be completed word - * \param pos position - * \param state - * \retval completed word - * \retval NULL on failure -*/ -static char *complete_orig(const char *line, const char *word, int pos, int state) -{ - static char *choices[] = { "application", "extension", NULL }; - char *ret; - - if (pos != 2) - return NULL; - - /* ugly, can be removed when CLI entries have ast_module pointers */ - ast_module_ref(ast_module_info->self); - ret = ast_cli_complete(word, choices, state); - ast_module_unref(ast_module_info->self); - - return ret; -} +static struct ast_cli_entry cli_cliorig[] = { + NEW_CLI(handle_orig, "Originate a call"), +}; /*! \brief Unload orginate module */ static int unload_module(void) diff --git a/res/res_convert.c b/res/res_convert.c index 34606ac246..2e514b111a 100644 --- a/res/res_convert.c +++ b/res/res_convert.c @@ -61,45 +61,60 @@ static int split_ext(char *filename, char **name, char **ext) * \param fd file descriptor * \param argc no arguements * \param argv list of arguements - * \retval RESULT_SUCCESS on success. - * \retval RESULT_SHOWUSAGE on failure. + * \retval CLI_SUCCESS on success. + * \retval CLI_SHOWUSAGE or CLI_FAILURE on failure. */ -static int cli_audio_convert(int fd, int argc, char *argv[]) +static char *handle_cli_file_convert(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { - int ret = RESULT_FAILURE; + char *ret = CLI_FAILURE; struct ast_filestream *fs_in = NULL, *fs_out = NULL; struct ast_frame *f; struct timeval start; int cost; char *file_in = NULL, *file_out = NULL; char *name_in, *ext_in, *name_out, *ext_out; + + switch (cmd) { + case CLI_INIT: + e->command = "file convert"; + e->usage = + "Usage: file convert \n" + " Convert from file_in to file_out. If an absolute path\n" + " is not given, the default Asterisk sounds directory\n" + " will be used.\n\n" + " Example:\n" + " file convert tt-weasels.gsm tt-weasels.ulaw\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } /* ugly, can be removed when CLI entries have ast_module pointers */ ast_module_ref(ast_module_info->self); - if (argc != 4 || ast_strlen_zero(argv[2]) || ast_strlen_zero(argv[3])) { - ret = RESULT_SHOWUSAGE; + if (a->argc != 4 || ast_strlen_zero(a->argv[2]) || ast_strlen_zero(a->argv[3])) { + ret = CLI_SHOWUSAGE; goto fail_out; } - file_in = ast_strdupa(argv[2]); - file_out = ast_strdupa(argv[3]); + file_in = ast_strdupa(a->argv[2]); + file_out = ast_strdupa(a->argv[3]); if (split_ext(file_in, &name_in, &ext_in)) { - ast_cli(fd, "'%s' is an invalid filename!\n", argv[2]); + ast_cli(a->fd, "'%s' is an invalid filename!\n", a->argv[2]); goto fail_out; } if (!(fs_in = ast_readfile(name_in, ext_in, NULL, O_RDONLY, 0, 0))) { - ast_cli(fd, "Unable to open input file: %s\n", argv[2]); + ast_cli(a->fd, "Unable to open input file: %s\n", a->argv[2]); goto fail_out; } if (split_ext(file_out, &name_out, &ext_out)) { - ast_cli(fd, "'%s' is an invalid filename!\n", argv[3]); + ast_cli(a->fd, "'%s' is an invalid filename!\n", a->argv[3]); goto fail_out; } if (!(fs_out = ast_writefile(name_out, ext_out, NULL, O_CREAT|O_TRUNC|O_WRONLY, 0, AST_FILE_MODE))) { - ast_cli(fd, "Unable to open output file: %s\n", argv[3]); + ast_cli(a->fd, "Unable to open output file: %s\n", a->argv[3]); goto fail_out; } @@ -107,19 +122,19 @@ static int cli_audio_convert(int fd, int argc, char *argv[]) while ((f = ast_readframe(fs_in))) { if (ast_writestream(fs_out, f)) { - ast_cli(fd, "Failed to convert %s.%s to %s.%s!\n", name_in, ext_in, name_out, ext_out); + ast_cli(a->fd, "Failed to convert %s.%s to %s.%s!\n", name_in, ext_in, name_out, ext_out); goto fail_out; } } cost = ast_tvdiff_ms(ast_tvnow(), start); - ast_cli(fd, "Converted %s.%s to %s.%s in %dms\n", name_in, ext_in, name_out, ext_out, cost); - ret = RESULT_SUCCESS; + ast_cli(a->fd, "Converted %s.%s to %s.%s in %dms\n", name_in, ext_in, name_out, ext_out, cost); + ret = CLI_SUCCESS; fail_out: if (fs_out) { ast_closestream(fs_out); - if (ret != RESULT_SUCCESS) + if (ret != CLI_SUCCESS) ast_filedelete(name_out, ext_out); } @@ -131,17 +146,8 @@ fail_out: return ret; } -static char usage_audio_convert[] = -"Usage: file convert \n" -" Convert from file_in to file_out. If an absolute path is not given, the\n" -"default Asterisk sounds directory will be used.\n\n" -"Example:\n" -" file convert tt-weasels.gsm tt-weasels.ulaw\n"; - static struct ast_cli_entry cli_convert[] = { - { { "file", "convert" , NULL }, - cli_audio_convert, "Convert audio file", - usage_audio_convert }, + NEW_CLI(handle_cli_file_convert, "Convert audio file") }; static int unload_module(void) diff --git a/res/res_crypto.c b/res/res_crypto.c index 65c5b768db..b0b34bd7c7 100644 --- a/res/res_crypto.c +++ b/res/res_crypto.c @@ -499,27 +499,43 @@ static void md52sum(char *sum, unsigned char *md5) * \param argv list of arguements * \return RESULT_SUCCESS */ -static int show_keys(int fd, int argc, char *argv[]) +static char *handle_cli_keys_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { +#define FORMAT "%-18s %-8s %-16s %-33s\n" + struct ast_key *key; char sum[16 * 2 + 1]; int count_keys = 0; - ast_cli(fd, "%-18s %-8s %-16s %-33s\n", "Key Name", "Type", "Status", "Sum"); + switch (cmd) { + case CLI_INIT: + e->command = "keys show"; + e->usage = + "Usage: keys show\n" + " Displays information about RSA keys known by Asterisk\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + ast_cli(a->fd, FORMAT, "Key Name", "Type", "Status", "Sum"); + ast_cli(a->fd, FORMAT, "------------------", "--------", "----------------", "--------------------------------"); AST_RWLIST_RDLOCK(&keys); AST_RWLIST_TRAVERSE(&keys, key, list) { md52sum(sum, key->digest); - ast_cli(fd, "%-18s %-8s %-16s %-33s\n", key->name, + ast_cli(a->fd, FORMAT, key->name, (key->ktype & 0xf) == AST_KEY_PUBLIC ? "PUBLIC" : "PRIVATE", key->ktype & KEY_NEEDS_PASSCODE ? "[Needs Passcode]" : "[Loaded]", sum); count_keys++; } AST_RWLIST_UNLOCK(&keys); - ast_cli(fd, "%d known RSA keys.\n", count_keys); + ast_cli(a->fd, "\n%d known RSA keys.\n", count_keys); + + return CLI_SUCCESS; - return RESULT_SUCCESS; +#undef FORMAT } /*! @@ -529,43 +545,45 @@ static int show_keys(int fd, int argc, char *argv[]) * \param argv list of arguements * \return RESULT_SUCCESS */ -static int init_keys(int fd, int argc, char *argv[]) +static char *handle_cli_keys_init(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { struct ast_key *key; int ign; char *kn, tmp[256] = ""; + switch (cmd) { + case CLI_INIT: + e->command = "keys init"; + e->usage = + "Usage: keys init\n" + " Initializes private keys (by reading in pass code from\n" + " the user)\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + if (a->argc != 2) + return CLI_SHOWUSAGE; + AST_RWLIST_WRLOCK(&keys); AST_RWLIST_TRAVERSE_SAFE_BEGIN(&keys, key, list) { /* Reload keys that need pass codes now */ if (key->ktype & KEY_NEEDS_PASSCODE) { kn = key->fn + strlen(ast_config_AST_KEY_DIR) + 1; ast_copy_string(tmp, kn, sizeof(tmp)); - try_load_key((char *)ast_config_AST_KEY_DIR, tmp, fd, fd, &ign); + try_load_key((char *) ast_config_AST_KEY_DIR, tmp, a->fd, a->fd, &ign); } } AST_RWLIST_TRAVERSE_SAFE_END AST_RWLIST_UNLOCK(&keys); - return RESULT_SUCCESS; + return CLI_SUCCESS; } -static const char show_key_usage[] = -"Usage: keys show\n" -" Displays information about RSA keys known by Asterisk\n"; - -static const char init_keys_usage[] = -"Usage: keys init\n" -" Initializes private keys (by reading in pass code from the user)\n"; - static struct ast_cli_entry cli_crypto[] = { - { { "keys", "show", NULL }, - show_keys, "Displays RSA key information", - show_key_usage }, - - { { "keys", "init", NULL }, - init_keys, "Initialize RSA key passcodes", - init_keys_usage }, + NEW_CLI(handle_cli_keys_show, "Displays RSA key information"), + NEW_CLI(handle_cli_keys_init, "Initialize RSA key passcodes") }; /*! \brief initialise the res_crypto module */ diff --git a/res/res_limit.c b/res/res_limit.c index ca22118363..fcaf03b862 100644 --- a/res/res_limit.c +++ b/res/res_limit.c @@ -49,21 +49,21 @@ static struct limits { char limit[3]; char desc[40]; } limits[] = { - { RLIMIT_CPU, "-t", "cpu time" }, - { RLIMIT_FSIZE, "-f", "file size" }, - { RLIMIT_DATA, "-d", "program data segment" }, - { RLIMIT_STACK, "-s", "program stack size" }, - { RLIMIT_CORE, "-c", "core file size" }, + { RLIMIT_CPU, "-t", "cpu time" }, + { RLIMIT_FSIZE, "-f", "file size" }, + { RLIMIT_DATA, "-d", "program data segment" }, + { RLIMIT_STACK, "-s", "program stack size" }, + { RLIMIT_CORE, "-c", "core file size" }, #ifdef RLIMIT_RSS - { RLIMIT_RSS, "-m", "resident memory" }, + { RLIMIT_RSS, "-m", "resident memory" }, { RLIMIT_MEMLOCK, "-l", "amount of memory locked into RAM" }, #endif #ifdef RLIMIT_NPROC - { RLIMIT_NPROC, "-u", "number of processes" }, + { RLIMIT_NPROC, "-u", "number of processes" }, #endif - { RLIMIT_NOFILE, "-n", "number of file descriptors" }, + { RLIMIT_NOFILE, "-n", "number of file descriptors" }, #ifdef VMEM_DEF - { VMEM_DEF, "-v", "virtual memory" }, + { VMEM_DEF, "-v", "virtual memory" }, #endif }; @@ -87,43 +87,105 @@ static const char *str2desc(const char *string) return ""; } -static int my_ulimit(int fd, int argc, char **argv) +static char *complete_ulimit(struct ast_cli_args *a) +{ + int which = 0, i; + int wordlen = strlen(a->word); + + if (a->pos > 1) + return NULL; + for (i = 0; i < sizeof(limits) / sizeof(limits[0]); i++) { + if (!strncasecmp(limits[i].limit, a->word, wordlen)) { + if (++which > a->n) + return ast_strdup(limits[i].limit); + } + } + return NULL; +} + +static char *handle_cli_ulimit(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { int resource; struct rlimit rlimit = { 0, 0 }; - if (argc > 3) - return RESULT_SHOWUSAGE; - if (argc == 1) { + switch (cmd) { + case CLI_INIT: + e->command = "ulimit"; + e->usage = + "Usage: ulimit {-d|" +#ifdef RLIMIT_RSS + "-l|" +#endif + "-f|" +#ifdef RLIMIT_RSS + "-m|" +#endif + "-s|-t|" +#ifdef RLIMIT_NPROC + "-u|" +#endif +#ifdef VMEM_DEF + "-v|" +#endif + "-c|-n} []\n" + " Shows or sets the corresponding resource limit.\n" + " -d Process data segment [readonly]\n" +#ifdef RLIMIT_RSS + " -l Memory lock size [readonly]\n" +#endif + " -f File size\n" +#ifdef RLIMIT_RSS + " -m Process resident memory [readonly]\n" +#endif + " -s Process stack size [readonly]\n" + " -t CPU usage [readonly]\n" +#ifdef RLIMIT_NPROC + " -u Child processes\n" +#endif +#ifdef VMEM_DEF + " -v Process virtual memory [readonly]\n" +#endif + " -c Core dump file size\n" + " -n Number of file descriptors\n"; + return NULL; + case CLI_GENERATE: + return complete_ulimit(a); + } + + if (a->argc > 3) + return CLI_SHOWUSAGE; + + if (a->argc == 1) { char arg2[3]; char *newargv[2] = { "ulimit", arg2 }; for (resource = 0; resource < sizeof(limits) / sizeof(limits[0]); resource++) { + struct ast_cli_args newArgs = { .argv = newargv, .argc = 2 }; ast_copy_string(arg2, limits[resource].limit, sizeof(arg2)); - my_ulimit(fd, 2, newargv); + handle_cli_ulimit(e, CLI_HANDLER, &newArgs); } - return RESULT_SUCCESS; + return CLI_SUCCESS; } else { - resource = str2limit(argv[1]); + resource = str2limit(a->argv[1]); if (resource == -1) { - ast_cli(fd, "Unknown resource\n"); - return RESULT_FAILURE; + ast_cli(a->fd, "Unknown resource\n"); + return CLI_FAILURE; } - if (argc == 3) { + if (a->argc == 3) { int x; #ifdef RLIMIT_NPROC if (resource != RLIMIT_NOFILE && resource != RLIMIT_CORE && resource != RLIMIT_NPROC && resource != RLIMIT_FSIZE) { #else - if (resource != RLIMIT_NOFILE && resource != RLIMIT_CORE && resource != RLIMIT_FSIZE) { + if (resource != RLIMIT_NOFILE && resource != RLIMIT_CORE && resource != RLIMIT_FSIZE) { #endif - ast_cli(fd, "Resource not permitted to be set\n"); - return RESULT_FAILURE; + ast_cli(a->fd, "Resource not permitted to be set\n"); + return CLI_FAILURE; } - sscanf(argv[2], "%d", &x); + sscanf(a->argv[2], "%d", &x); rlimit.rlim_max = rlimit.rlim_cur = x; setrlimit(resource, &rlimit); - return RESULT_SUCCESS; + return CLI_SUCCESS; } else { if (!getrlimit(resource, &rlimit)) { char printlimit[32]; @@ -131,51 +193,18 @@ static int my_ulimit(int fd, int argc, char **argv) if (rlimit.rlim_max == RLIM_INFINITY) ast_copy_string(printlimit, "effectively unlimited", sizeof(printlimit)); else - snprintf(printlimit, sizeof(printlimit), "limited to %d", (int)rlimit.rlim_cur); - desc = str2desc(argv[1]); - ast_cli(fd, "%c%s (%s) is %s.\n", toupper(desc[0]), desc + 1, argv[1], printlimit); + snprintf(printlimit, sizeof(printlimit), "limited to %d", (int) rlimit.rlim_cur); + desc = str2desc(a->argv[1]); + ast_cli(a->fd, "%c%s (%s) is %s.\n", toupper(desc[0]), desc + 1, a->argv[1], printlimit); } else - ast_cli(fd, "Could not retrieve resource limits for %s: %s\n", str2desc(argv[1]), strerror(errno)); - return RESULT_SUCCESS; - } - } -} - -static char *complete_ulimit(const char *line, const char *word, int pos, int state) -{ - int which = 0, i; - int wordlen = strlen(word); - - if (pos > 2) - return NULL; - for (i = 0; i < sizeof(limits) / sizeof(limits[0]); i++) { - if (!strncasecmp(limits[i].limit, word, wordlen)) { - if (++which > state) - return ast_strdup(limits[i].limit); + ast_cli(a->fd, "Could not retrieve resource limits for %s: %s\n", str2desc(a->argv[1]), strerror(errno)); + return CLI_SUCCESS; } } - return NULL; } -static const char ulimit_usage[] = -"Usage: ulimit {-d|-l|-f|-m|-s|-t|-u|-v|-c|-n} []\n" -" Shows or sets the corresponding resource limit.\n" -" -d Process data segment [readonly]\n" -" -l Memory lock size [readonly]\n" -" -f File size\n" -" -m Process resident memory [readonly]\n" -" -s Process stack size [readonly]\n" -" -t CPU usage [readonly]\n" -" -u Child processes\n" -#ifdef VMEM_DEF -" -v Process virtual memory [readonly]\n" -#endif -" -c Core dump file size\n" -" -n Number of file descriptors\n"; - -static struct ast_cli_entry cli_ulimit = { - { "ulimit", NULL }, my_ulimit, - "Set or show process resource limits", ulimit_usage, complete_ulimit }; +static struct ast_cli_entry cli_ulimit = + NEW_CLI(handle_cli_ulimit, "Set or show process resource limits"); static int unload_module(void) { @@ -184,7 +213,7 @@ static int unload_module(void) static int load_module(void) { - return ast_cli_register(&cli_ulimit)? AST_MODULE_LOAD_FAILURE: AST_MODULE_LOAD_SUCCESS; + return ast_cli_register(&cli_ulimit) ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_SUCCESS; } AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Resource limits");