Index: channels/chan_features.c =================================================================== --- channels/chan_features.c (revision 82911) +++ channels/chan_features.c (working copy) @@ -509,36 +509,41 @@ return chan; } -static int features_show(int fd, int argc, char **argv) +static char *features_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { struct feature_pvt *p; - if (argc != 3) - return RESULT_SHOWUSAGE; + switch (cmd) { + case CLI_INIT: + e->command = "feature show channels"; + e->usage = + "Usage: feature show channels\n" + " Provides summary information on feature channels.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + if (a->argc != 3) + return CLI_SHOWUSAGE; + if (AST_LIST_EMPTY(&features)) { - ast_cli(fd, "No feature channels in use\n"); - return RESULT_SUCCESS; + ast_cli(a->fd, "No feature channels in use\n"); + return CLI_SUCCESS; } AST_LIST_LOCK(&features); AST_LIST_TRAVERSE(&features, p, list) { ast_mutex_lock(&p->lock); - ast_cli(fd, "%s -- %s/%s\n", p->owner ? p->owner->name : "", p->tech, p->dest); + ast_cli(a->fd, "%s -- %s/%s\n", p->owner ? p->owner->name : "", p->tech, p->dest); ast_mutex_unlock(&p->lock); } AST_LIST_UNLOCK(&features); - return RESULT_SUCCESS; + return CLI_SUCCESS; } -static const char show_features_usage[] = -"Usage: feature show channels\n" -" Provides summary information on feature channels.\n"; - static struct ast_cli_entry cli_features[] = { - { { "feature", "show", "channels", NULL }, - features_show, "List status of feature channels", - show_features_usage }, + NEW_CLI(features_show, "List status of feature channels"), }; static int load_module(void) Index: channels/chan_sip.c =================================================================== --- channels/chan_sip.c (revision 82911) +++ channels/chan_sip.c (working copy) @@ -1598,14 +1598,14 @@ /*--- Applications, functions, CLI and manager command helpers */ static const char *sip_nat_mode(const struct sip_pvt *p); -static int sip_show_inuse(int fd, int argc, char *argv[]); +static char *sip_show_inuse(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a); static char *transfermode2str(enum transfermodes mode) attribute_const; static const char *nat2str(int nat) attribute_const; static int peer_status(struct sip_peer *peer, char *status, int statuslen); -static int sip_show_users(int fd, int argc, char *argv[]); -static int _sip_show_peers(int fd, int *total, struct mansession *s, const struct message *m, int argc, const char *argv[]); -static int sip_show_peers(int fd, int argc, char *argv[]); -static int sip_show_objects(int fd, int argc, char *argv[]); +static char *sip_show_users(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a); +static char * _sip_show_peers(int fd, int *total, struct mansession *s, const struct message *m, int argc, const char *argv[]); +static char *sip_show_peers(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a); +static char *sip_show_objects(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a); static void print_group(int fd, ast_group_t group, int crlf); static const char *dtmfmode2str(int mode) attribute_const; static int str2dtmfmode(const char *str) attribute_unused; @@ -1613,13 +1613,13 @@ static void cleanup_stale_contexts(char *new, char *old); static void print_codec_to_cli(int fd, struct ast_codec_pref *pref); static const char *domain_mode_to_text(const enum domain_mode mode); -static int sip_show_domains(int fd, int argc, char *argv[]); -static int _sip_show_peer(int type, int fd, struct mansession *s, const struct message *m, int argc, const char *argv[]); -static int sip_show_peer(int fd, int argc, char *argv[]); -static int sip_show_user(int fd, int argc, char *argv[]); -static int sip_show_registry(int fd, int argc, char *argv[]); -static int sip_unregister(int fd, int argc, char *argv[]); -static int sip_show_settings(int fd, int argc, char *argv[]); +static char *sip_show_domains(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a); +static char *_sip_show_peer(int type, int fd, struct mansession *s, const struct message *m, int argc, const char *argv[]); +static char *sip_show_peer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a); +static char *sip_show_user(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a); +static char *sip_show_registry(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a); +static char *sip_unregister(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a); +static char *sip_show_settings(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a); static const char *subscription_type2str(enum subscriptiontype subtype) attribute_pure; static const struct cfsubscription_types *find_subscription_type(enum subscriptiontype subtype); static char *complete_sip_peer(const char *word, int state, int flags2); @@ -1630,18 +1630,18 @@ static char *complete_sip_user(const char *word, int state, int flags2); static char *complete_sip_show_user(const char *line, const char *word, int pos, int state); static char *complete_sipnotify(const char *line, const char *word, int pos, int state); -static int sip_show_channel(int fd, int argc, char *argv[]); -static int sip_show_history(int fd, int argc, char *argv[]); +static char *sip_show_channel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a); +static char *sip_show_history(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a); static char *sip_do_debug_ip(int fd, char *arg); static char *sip_do_debug_peer(int fd, char *arg); static char *sip_do_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a); -static int sip_notify(int fd, int argc, char *argv[]); -static int sip_do_history(int fd, int argc, char *argv[]); -static int sip_no_history(int fd, int argc, char *argv[]); +static char *sip_notify(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a); +static char *sip_do_history(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a); +static char *sip_no_history(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a); static int sip_dtmfmode(struct ast_channel *chan, void *data); static int sip_addheader(struct ast_channel *chan, void *data); static int sip_do_reload(enum channelreloadreason reason); -static int sip_reload(int fd, int argc, char *argv[]); +static char *sip_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a); static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *preparse, char *buf, size_t buflen); /*--- Debugging @@ -10481,7 +10481,7 @@ } /*! \brief CLI Command to show calls within limits set by call_limit */ -static int sip_show_inuse(int fd, int argc, char *argv[]) +static char *sip_show_inuse(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { #define FORMAT "%-25.25s %-15.15s %-15.15s \n" #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" @@ -10489,13 +10489,25 @@ char iused[40]; int showall = FALSE; - if (argc < 3) - return RESULT_SHOWUSAGE; + switch (cmd) { + case CLI_INIT: + e->command = "sip show inuse"; + e->usage = + "Usage: sip show inuse [all]\n" + " List all SIP users and peers usage counters and limits.\n" + " Add option \"all\" to show all devices, not only those with a limit.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } - if (argc == 4 && !strcmp(argv[3],"all")) - showall = TRUE; + if (a->argc < 3) + return CLI_SHOWUSAGE; + + if (a->argc == 4 && !strcmp(a->argv[3],"all")) + showall = TRUE; - ast_cli(fd, FORMAT, "* User name", "In use", "Limit"); + ast_cli(a->fd, FORMAT, "* User name", "In use", "Limit"); ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { ASTOBJ_RDLOCK(iterator); if (iterator->call_limit) @@ -10504,11 +10516,11 @@ ast_copy_string(ilimits, "N/A", sizeof(ilimits)); snprintf(iused, sizeof(iused), "%d", iterator->inUse); if (showall || iterator->call_limit) - ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); + ast_cli(a->fd, FORMAT2, iterator->name, iused, ilimits); ASTOBJ_UNLOCK(iterator); } while (0) ); - ast_cli(fd, FORMAT, "* Peer name", "In use", "Limit"); + ast_cli(a->fd, FORMAT, "* Peer name", "In use", "Limit"); ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { ASTOBJ_RDLOCK(iterator); @@ -10518,11 +10530,11 @@ ast_copy_string(ilimits, "N/A", sizeof(ilimits)); snprintf(iused, sizeof(iused), "%d/%d/%d", iterator->inUse, iterator->inRinging, iterator->onHold); if (showall || iterator->call_limit) - ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); + ast_cli(a->fd, FORMAT2, iterator->name, iused, ilimits); ASTOBJ_UNLOCK(iterator); } while (0) ); - return RESULT_SUCCESS; + return CLI_SUCCESS; #undef FORMAT #undef FORMAT2 } @@ -10588,28 +10600,40 @@ } /*! \brief CLI Command 'SIP Show Users' */ -static int sip_show_users(int fd, int argc, char *argv[]) +static char *sip_show_users(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { regex_t regexbuf; int havepattern = FALSE; #define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" - switch (argc) { + switch (cmd) { + case CLI_INIT: + e->command = "sip show users"; + e->usage = + "Usage: sip show users [like ]\n" + " Lists all known SIP users.\n" + " Optional regular expression pattern is used to filter the user list.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + switch (a->argc) { case 5: - if (!strcasecmp(argv[3], "like")) { - if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) - return RESULT_SHOWUSAGE; + if (!strcasecmp(a->argv[3], "like")) { + if (regcomp(®exbuf, a->argv[4], REG_EXTENDED | REG_NOSUB)) + return CLI_SHOWUSAGE; havepattern = TRUE; } else - return RESULT_SHOWUSAGE; + return CLI_SHOWUSAGE; case 3: break; default: - return RESULT_SHOWUSAGE; + return CLI_SHOWUSAGE; } - ast_cli(fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT"); + ast_cli(a->fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT"); ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { ASTOBJ_RDLOCK(iterator); @@ -10618,7 +10642,7 @@ continue; } - ast_cli(fd, FORMAT, iterator->name, + ast_cli(a->fd, FORMAT, iterator->name, iterator->secret, iterator->accountcode, iterator->context, @@ -10631,7 +10655,7 @@ if (havepattern) regfree(®exbuf); - return RESULT_SUCCESS; + return CLI_SUCCESS; #undef FORMAT } @@ -10668,13 +10692,25 @@ } /*! \brief CLI Show Peers command */ -static int sip_show_peers(int fd, int argc, char *argv[]) +static char *sip_show_peers(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { - return _sip_show_peers(fd, NULL, NULL, NULL, argc, (const char **) argv); + switch (cmd) { + case CLI_INIT: + e->command = "sip show peers"; + e->usage = + "Usage: sip show peers [like ]\n" + " Lists all known SIP peers.\n" + " Optional regular expression pattern is used to filter the peer list.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + return _sip_show_peers(a->fd, NULL, NULL, NULL, a->argc, (const char **) a->argv); } /*! \brief _sip_show_peers: Execute sip show peers command */ -static int _sip_show_peers(int fd, int *total, struct mansession *s, const struct message *m, int argc, const char *argv[]) +static char *_sip_show_peers(int fd, int *total, struct mansession *s, const struct message *m, int argc, const char *argv[]) { regex_t regexbuf; int havepattern = FALSE; @@ -10705,14 +10741,14 @@ case 5: if (!strcasecmp(argv[3], "like")) { if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) - return RESULT_SHOWUSAGE; + return CLI_SHOWUSAGE; havepattern = TRUE; } else - return RESULT_SHOWUSAGE; + return CLI_SHOWUSAGE; case 3: break; default: - return RESULT_SHOWUSAGE; + return CLI_SHOWUSAGE; } if (!s) /* Normal list */ @@ -10809,24 +10845,36 @@ *total = total_peers; - return RESULT_SUCCESS; + return CLI_SUCCESS; #undef FORMAT #undef FORMAT2 } /*! \brief List all allocated SIP Objects (realtime or static) */ -static int sip_show_objects(int fd, int argc, char *argv[]) +static char *sip_show_objects(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { char tmp[256]; - if (argc != 3) - return RESULT_SHOWUSAGE; - ast_cli(fd, "-= User objects: %d static, %d realtime =-\n\n", suserobjs, ruserobjs); - ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &userl); - ast_cli(fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs); - ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &peerl); - ast_cli(fd, "-= Registry objects: %d =-\n\n", regobjs); - ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), ®l); - return RESULT_SUCCESS; + + switch (cmd) { + case CLI_INIT: + e->command = "sip show objects"; + e->usage = + "Usage: sip show objects\n" + " Lists status of known SIP objects\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + if (a->argc != 3) + return CLI_SHOWUSAGE; + ast_cli(a->fd, "-= User objects: %d static, %d realtime =-\n\n", suserobjs, ruserobjs); + ASTOBJ_CONTAINER_DUMP(a->fd, tmp, sizeof(tmp), &userl); + ast_cli(a->fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs); + ASTOBJ_CONTAINER_DUMP(a->fd, tmp, sizeof(tmp), &peerl); + ast_cli(a->fd, "-= Registry objects: %d =-\n\n", regobjs); + ASTOBJ_CONTAINER_DUMP(a->fd, tmp, sizeof(tmp), ®l); + return CLI_SUCCESS; } /*! \brief Print call group and pickup group */ static void print_group(int fd, ast_group_t group, int crlf) @@ -11085,23 +11133,35 @@ } /*! \brief CLI command to list local domains */ -static int sip_show_domains(int fd, int argc, char *argv[]) +static char *sip_show_domains(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { struct domain *d; #define FORMAT "%-40.40s %-20.20s %-16.16s\n" + switch (cmd) { + case CLI_INIT: + e->command = "sip show domains"; + e->usage = + "Usage: sip show domains\n" + " Lists all configured SIP local domains.\n" + " Asterisk only responds to SIP messages to local domains.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + if (AST_LIST_EMPTY(&domain_list)) { - ast_cli(fd, "SIP Domain support not enabled.\n\n"); - return RESULT_SUCCESS; + ast_cli(a->fd, "SIP Domain support not enabled.\n\n"); + return CLI_SUCCESS; } else { - ast_cli(fd, FORMAT, "Our local SIP domains:", "Context", "Set by"); + ast_cli(a->fd, FORMAT, "Our local SIP domains:", "Context", "Set by"); AST_LIST_LOCK(&domain_list); AST_LIST_TRAVERSE(&domain_list, d, list) - ast_cli(fd, FORMAT, d->domain, S_OR(d->context, "(default)"), + ast_cli(a->fd, FORMAT, d->domain, S_OR(d->context, "(default)"), domain_mode_to_text(d->mode)); AST_LIST_UNLOCK(&domain_list); - ast_cli(fd, "\n"); - return RESULT_SUCCESS; + ast_cli(a->fd, "\n"); + return CLI_SUCCESS; } } #undef FORMAT @@ -11117,7 +11177,6 @@ { const char *a[4]; const char *peer; - int ret; peer = astman_get_header(m,"Peer"); if (ast_strlen_zero(peer)) { @@ -11129,17 +11188,28 @@ a[2] = "peer"; a[3] = peer; - ret = _sip_show_peer(1, -1, s, m, 4, a); + _sip_show_peer(1, -1, s, m, 4, a); astman_append(s, "\r\n\r\n" ); - return ret; + return 0; } /*! \brief Show one peer in detail */ -static int sip_show_peer(int fd, int argc, char *argv[]) +static char *sip_show_peer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { - return _sip_show_peer(0, fd, NULL, NULL, argc, (const char **) argv); + switch (cmd) { + case CLI_INIT: + e->command = "sip show peer"; + e->usage = + "Usage: sip show peer [load]\n" + " Shows all details on one SIP peer and the current status.\n" + " Option \"load\" forces lookup of peer in realtime storage.\n"; + return NULL; + case CLI_GENERATE: + return complete_sip_show_peer(a->line, a->word, a->pos, a->n); + } + return _sip_show_peer(0, a->fd, NULL, NULL, a->argc, (const char **) a->argv); } static void peer_mailboxes_to_str(struct ast_str **mailbox_str, struct sip_peer *peer) @@ -11156,7 +11226,7 @@ } /*! \brief Show one peer in detail (main function) */ -static int _sip_show_peer(int type, int fd, struct mansession *s, const struct message *m, int argc, const char *argv[]) +static char *_sip_show_peer(int type, int fd, struct mansession *s, const struct message *m, int argc, const char *argv[]) { char status[30] = ""; char cbuf[256]; @@ -11171,7 +11241,7 @@ realtimepeers = ast_check_realtime("sippeers"); if (argc < 4) - return RESULT_SHOWUSAGE; + return CLI_SHOWUSAGE; load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; peer = find_peer(argv[3], NULL, load_realtime); @@ -11185,7 +11255,7 @@ } else { snprintf (cbuf, sizeof(cbuf), "Peer %s not found.\n", argv[3]); astman_send_error(s, m, cbuf); - return 0; + return CLI_SUCCESS; } } if (peer && type==0 ) { /* Normal listing */ @@ -11375,66 +11445,78 @@ ast_cli(fd,"\n"); } - return RESULT_SUCCESS; + return CLI_SUCCESS; } /*! \brief Show one user in detail */ -static int sip_show_user(int fd, int argc, char *argv[]) +static char *sip_show_user(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { char cbuf[256]; struct sip_user *user; struct ast_variable *v; int load_realtime; - if (argc < 4) - return RESULT_SHOWUSAGE; + switch (cmd) { + case CLI_INIT: + e->command = "sip show user"; + e->usage = + "Usage: sip show user [load]\n" + " Shows all details on one SIP user and the current status.\n" + " Option \"load\" forces lookup of peer in realtime storage.\n"; + return NULL; + case CLI_GENERATE: + return complete_sip_show_user(a->line, a->word, a->pos, a->n); + } + if (a->argc < 4) + return CLI_SHOWUSAGE; + /* Load from realtime storage? */ - load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; + load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? TRUE : FALSE; - user = find_user(argv[3], load_realtime); + user = find_user(a->argv[3], load_realtime); if (user) { - ast_cli(fd,"\n\n"); - ast_cli(fd, " * Name : %s\n", user->name); - ast_cli(fd, " Secret : %s\n", ast_strlen_zero(user->secret)?"":""); - ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(user->md5secret)?"":""); - ast_cli(fd, " Context : %s\n", user->context); - ast_cli(fd, " Language : %s\n", user->language); + ast_cli(a->fd,"\n\n"); + ast_cli(a->fd, " * Name : %s\n", user->name); + ast_cli(a->fd, " Secret : %s\n", ast_strlen_zero(user->secret)?"":""); + ast_cli(a->fd, " MD5Secret : %s\n", ast_strlen_zero(user->md5secret)?"":""); + ast_cli(a->fd, " Context : %s\n", user->context); + ast_cli(a->fd, " Language : %s\n", user->language); if (!ast_strlen_zero(user->accountcode)) - ast_cli(fd, " Accountcode : %s\n", user->accountcode); - ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(user->amaflags)); - ast_cli(fd, " Transfer mode: %s\n", transfermode2str(user->allowtransfer)); - ast_cli(fd, " MaxCallBR : %d kbps\n", user->maxcallbitrate); - ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(user->callingpres)); - ast_cli(fd, " Call limit : %d\n", user->call_limit); - ast_cli(fd, " Callgroup : "); - print_group(fd, user->callgroup, 0); - ast_cli(fd, " Pickupgroup : "); - print_group(fd, user->pickupgroup, 0); - ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "")); - ast_cli(fd, " ACL : %s\n", cli_yesno(user->ha != NULL)); - ast_cli(fd, " Codec Order : ("); - print_codec_to_cli(fd, &user->prefs); - ast_cli(fd, ")\n"); + ast_cli(a->fd, " Accountcode : %s\n", user->accountcode); + ast_cli(a->fd, " AMA flags : %s\n", ast_cdr_flags2str(user->amaflags)); + ast_cli(a->fd, " Transfer mode: %s\n", transfermode2str(user->allowtransfer)); + ast_cli(a->fd, " MaxCallBR : %d kbps\n", user->maxcallbitrate); + ast_cli(a->fd, " CallingPres : %s\n", ast_describe_caller_presentation(user->callingpres)); + ast_cli(a->fd, " Call limit : %d\n", user->call_limit); + ast_cli(a->fd, " Callgroup : "); + print_group(a->fd, user->callgroup, 0); + ast_cli(a->fd, " Pickupgroup : "); + print_group(a->fd, user->pickupgroup, 0); + ast_cli(a->fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "")); + ast_cli(a->fd, " ACL : %s\n", cli_yesno(user->ha != NULL)); + ast_cli(a->fd, " Codec Order : ("); + print_codec_to_cli(a->fd, &user->prefs); + ast_cli(a->fd, ")\n"); - ast_cli(fd, " Auto-Framing: %s \n", cli_yesno(user->autoframing)); + ast_cli(a->fd, " Auto-Framing: %s \n", cli_yesno(user->autoframing)); if (user->chanvars) { - ast_cli(fd, " Variables :\n"); + ast_cli(a->fd, " Variables :\n"); for (v = user->chanvars ; v ; v = v->next) - ast_cli(fd, " %s = %s\n", v->name, v->value); + ast_cli(a->fd, " %s = %s\n", v->name, v->value); } - ast_cli(fd,"\n"); + ast_cli(a->fd,"\n"); unref_user(user); } else { - ast_cli(fd,"User %s not found.\n", argv[3]); - ast_cli(fd,"\n"); + ast_cli(a->fd,"User %s not found.\n", a->argv[3]); + ast_cli(a->fd,"\n"); } - return RESULT_SUCCESS; + return CLI_SUCCESS; } /*! \brief Show SIP Registry (registrations with other SIP proxies */ -static int sip_show_registry(int fd, int argc, char *argv[]) +static char *sip_show_registry(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { #define FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n" #define FORMAT "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n" @@ -11443,9 +11525,20 @@ struct ast_tm tm; int counter = 0; - if (argc != 3) - return RESULT_SHOWUSAGE; - ast_cli(fd, FORMAT2, "Host", "Username", "Refresh", "State", "Reg.Time"); + switch (cmd) { + case CLI_INIT: + e->command = "sip show registry"; + e->usage = + "Usage: sip show registry\n" + " Lists all registration requests and status.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + if (a->argc != 3) + return CLI_SHOWUSAGE; + ast_cli(a->fd, FORMAT2, "Host", "Username", "Refresh", "State", "Reg.Time"); ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { ASTOBJ_RDLOCK(iterator); snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT); @@ -11454,12 +11547,12 @@ ast_strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T", &tm); } else tmpdat[0] = '\0'; - ast_cli(fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate), tmpdat); + ast_cli(a->fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate), tmpdat); ASTOBJ_UNLOCK(iterator); counter++; } while(0)); - ast_cli(fd, "%d SIP registrations.\n", counter); - return RESULT_SUCCESS; + ast_cli(a->fd, "%d SIP registrations.\n", counter); + return CLI_SUCCESS; #undef FORMAT #undef FORMAT2 } @@ -11468,30 +11561,41 @@ \note This function does not tell the SIP device what's going on, so use it with great care. */ -static int sip_unregister(int fd, int argc, char *argv[]) +static char *sip_unregister(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { struct sip_peer *peer; int load_realtime = 0; - if (argc != 3) - return RESULT_SHOWUSAGE; + switch (cmd) { + case CLI_INIT: + e->command = "sip unregister"; + e->usage = + "Usage: sip unregister \n" + " Unregister (force expiration) a SIP peer from the registry\n"; + return NULL; + case CLI_GENERATE: + return complete_sip_unregister(a->line, a->word, a->pos, a->n); + } - if ((peer = find_peer(argv[2], NULL, load_realtime))) { + if (a->argc != 3) + return CLI_SHOWUSAGE; + + if ((peer = find_peer(a->argv[2], NULL, load_realtime))) { if (peer->expire > 0) { expire_register(peer); - ast_cli(fd, "Unregistered peer \'%s\'\n\n", argv[2]); + ast_cli(a->fd, "Unregistered peer \'%s\'\n\n", a->argv[2]); } else { - ast_cli(fd, "Peer %s not registered\n", argv[2]); + ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]); } } else { - ast_cli(fd, "Peer unknown: \'%s\'. Not unregistered.\n", argv[2]); + ast_cli(a->fd, "Peer unknown: \'%s\'. Not unregistered.\n", a->argv[2]); } - return 0; + return CLI_SUCCESS; } /*! \brief List global settings for the SIP channel */ -static int sip_show_settings(int fd, int argc, char *argv[]) +static char *sip_show_settings(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { int realtimepeers; int realtimeusers; @@ -11499,67 +11603,79 @@ char codec_buf[BUFSIZ]; const char *msg; /* temporary msg pointer */ + switch (cmd) { + case CLI_INIT: + e->command = "sip show settings"; + e->usage = + "Usage: sip show settings\n" + " Provides detailed list of the configuration of the SIP channel.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + realtimepeers = ast_check_realtime("sippeers"); realtimeusers = ast_check_realtime("sipusers"); realtimeregs = ast_check_realtime("sipregs"); - if (argc != 3) - return RESULT_SHOWUSAGE; - ast_cli(fd, "\n\nGlobal Settings:\n"); - ast_cli(fd, "----------------\n"); - ast_cli(fd, " SIP Port: %d\n", ntohs(bindaddr.sin_port)); - ast_cli(fd, " Bindaddress: %s\n", ast_inet_ntoa(bindaddr.sin_addr)); - ast_cli(fd, " Videosupport: %s\n", cli_yesno(ast_test_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT))); - ast_cli(fd, " Textsupport: %s\n", cli_yesno(ast_test_flag(&global_flags[1], SIP_PAGE2_TEXTSUPPORT))); - ast_cli(fd, " AutoCreatePeer: %s\n", cli_yesno(autocreatepeer)); - ast_cli(fd, " MatchAuthUsername: %s\n", cli_yesno(global_match_auth_username)); - ast_cli(fd, " Allow unknown access: %s\n", cli_yesno(global_allowguest)); - ast_cli(fd, " Allow subscriptions: %s\n", cli_yesno(ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE))); - ast_cli(fd, " Allow overlap dialing: %s\n", cli_yesno(ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP))); - ast_cli(fd, " Promsic. redir: %s\n", cli_yesno(ast_test_flag(&global_flags[0], SIP_PROMISCREDIR))); - ast_cli(fd, " SIP domain support: %s\n", cli_yesno(!AST_LIST_EMPTY(&domain_list))); - ast_cli(fd, " Call to non-local dom.: %s\n", cli_yesno(allow_external_domains)); - ast_cli(fd, " URI user is phone no: %s\n", cli_yesno(ast_test_flag(&global_flags[0], SIP_USEREQPHONE))); - ast_cli(fd, " Our auth realm %s\n", global_realm); - ast_cli(fd, " Realm. auth: %s\n", cli_yesno(authl != NULL)); - ast_cli(fd, " Always auth rejects: %s\n", cli_yesno(global_alwaysauthreject)); - ast_cli(fd, " Call limit peers only: %s\n", cli_yesno(global_limitonpeers)); - ast_cli(fd, " Direct RTP setup: %s\n", cli_yesno(global_directrtpsetup)); - ast_cli(fd, " User Agent: %s\n", global_useragent); - ast_cli(fd, " Reg. context: %s\n", S_OR(global_regcontext, "(not set)")); - ast_cli(fd, " Regexten on Qualify: %s\n", cli_yesno(global_regextenonqualify)); - ast_cli(fd, " Caller ID: %s\n", default_callerid); - ast_cli(fd, " From: Domain: %s\n", default_fromdomain); - ast_cli(fd, " Record SIP history: %s\n", recordhistory ? "On" : "Off"); - ast_cli(fd, " Call Events: %s\n", global_callevents ? "On" : "Off"); - ast_cli(fd, " IP ToS SIP: %s\n", ast_tos2str(global_tos_sip)); - ast_cli(fd, " IP ToS RTP audio: %s\n", ast_tos2str(global_tos_audio)); - ast_cli(fd, " IP ToS RTP video: %s\n", ast_tos2str(global_tos_video)); - ast_cli(fd, " IP ToS RTP text: %s\n", ast_tos2str(global_tos_text)); - ast_cli(fd, " 802.1p CoS SIP: %d\n", global_cos_sip); - ast_cli(fd, " 802.1p CoS RTP audio: %d\n", global_cos_audio); - ast_cli(fd, " 802.1p CoS RTP video: %d\n", global_cos_video); - ast_cli(fd, " 802.1p CoS RTP text: %d\n", global_cos_text); + if (a->argc != 3) + return CLI_SHOWUSAGE; + ast_cli(a->fd, "\n\nGlobal Settings:\n"); + ast_cli(a->fd, "----------------\n"); + ast_cli(a->fd, " SIP Port: %d\n", ntohs(bindaddr.sin_port)); + ast_cli(a->fd, " Bindaddress: %s\n", ast_inet_ntoa(bindaddr.sin_addr)); + ast_cli(a->fd, " Videosupport: %s\n", cli_yesno(ast_test_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT))); + ast_cli(a->fd, " Textsupport: %s\n", cli_yesno(ast_test_flag(&global_flags[1], SIP_PAGE2_TEXTSUPPORT))); + ast_cli(a->fd, " AutoCreatePeer: %s\n", cli_yesno(autocreatepeer)); + ast_cli(a->fd, " MatchAuthUsername: %s\n", cli_yesno(global_match_auth_username)); + ast_cli(a->fd, " Allow unknown access: %s\n", cli_yesno(global_allowguest)); + ast_cli(a->fd, " Allow subscriptions: %s\n", cli_yesno(ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE))); + ast_cli(a->fd, " Allow overlap dialing: %s\n", cli_yesno(ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP))); + ast_cli(a->fd, " Promsic. redir: %s\n", cli_yesno(ast_test_flag(&global_flags[0], SIP_PROMISCREDIR))); + ast_cli(a->fd, " SIP domain support: %s\n", cli_yesno(!AST_LIST_EMPTY(&domain_list))); + ast_cli(a->fd, " Call to non-local dom.: %s\n", cli_yesno(allow_external_domains)); + ast_cli(a->fd, " URI user is phone no: %s\n", cli_yesno(ast_test_flag(&global_flags[0], SIP_USEREQPHONE))); + ast_cli(a->fd, " Our auth realm %s\n", global_realm); + ast_cli(a->fd, " Realm. auth: %s\n", cli_yesno(authl != NULL)); + ast_cli(a->fd, " Always auth rejects: %s\n", cli_yesno(global_alwaysauthreject)); + ast_cli(a->fd, " Call limit peers only: %s\n", cli_yesno(global_limitonpeers)); + ast_cli(a->fd, " Direct RTP setup: %s\n", cli_yesno(global_directrtpsetup)); + ast_cli(a->fd, " User Agent: %s\n", global_useragent); + ast_cli(a->fd, " Reg. context: %s\n", S_OR(global_regcontext, "(not set)")); + ast_cli(a->fd, " Regexten on Qualify: %s\n", cli_yesno(global_regextenonqualify)); + ast_cli(a->fd, " Caller ID: %s\n", default_callerid); + ast_cli(a->fd, " From: Domain: %s\n", default_fromdomain); + ast_cli(a->fd, " Record SIP history: %s\n", recordhistory ? "On" : "Off"); + ast_cli(a->fd, " Call Events: %s\n", global_callevents ? "On" : "Off"); + ast_cli(a->fd, " IP ToS SIP: %s\n", ast_tos2str(global_tos_sip)); + ast_cli(a->fd, " IP ToS RTP audio: %s\n", ast_tos2str(global_tos_audio)); + ast_cli(a->fd, " IP ToS RTP video: %s\n", ast_tos2str(global_tos_video)); + ast_cli(a->fd, " IP ToS RTP text: %s\n", ast_tos2str(global_tos_text)); + ast_cli(a->fd, " 802.1p CoS SIP: %d\n", global_cos_sip); + ast_cli(a->fd, " 802.1p CoS RTP audio: %d\n", global_cos_audio); + ast_cli(a->fd, " 802.1p CoS RTP video: %d\n", global_cos_video); + ast_cli(a->fd, " 802.1p CoS RTP text: %d\n", global_cos_text); - ast_cli(fd, " T38 fax pt UDPTL: %s\n", cli_yesno(ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_UDPTL))); + ast_cli(a->fd, " T38 fax pt UDPTL: %s\n", cli_yesno(ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_UDPTL))); #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS - ast_cli(fd, " T38 fax pt RTP: %s\n", cli_yesno(ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_RTP))); - ast_cli(fd, " T38 fax pt TCP: %s\n", cli_yesno(ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_TCP))); + ast_cli(a->fd, " T38 fax pt RTP: %s\n", cli_yesno(ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_RTP))); + ast_cli(a->fd, " T38 fax pt TCP: %s\n", cli_yesno(ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_TCP))); #endif - ast_cli(fd, " RFC2833 Compensation: %s\n", cli_yesno(ast_test_flag(&global_flags[1], SIP_PAGE2_RFC2833_COMPENSATE))); - ast_cli(fd, " Jitterbuffer enabled: %s\n", cli_yesno(ast_test_flag(&global_jbconf, AST_JB_ENABLED))); - ast_cli(fd, " Jitterbuffer forced: %s\n", cli_yesno(ast_test_flag(&global_jbconf, AST_JB_FORCED))); - 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", cli_yesno(ast_test_flag(&global_jbconf, AST_JB_LOG))); + ast_cli(a->fd, " RFC2833 Compensation: %s\n", cli_yesno(ast_test_flag(&global_flags[1], SIP_PAGE2_RFC2833_COMPENSATE))); + ast_cli(a->fd, " Jitterbuffer enabled: %s\n", cli_yesno(ast_test_flag(&global_jbconf, AST_JB_ENABLED))); + ast_cli(a->fd, " Jitterbuffer forced: %s\n", cli_yesno(ast_test_flag(&global_jbconf, AST_JB_FORCED))); + 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", cli_yesno(ast_test_flag(&global_jbconf, AST_JB_LOG))); if (!realtimepeers && !realtimeusers && !realtimeregs) - ast_cli(fd, " SIP realtime: Disabled\n" ); + ast_cli(a->fd, " SIP realtime: Disabled\n" ); else - ast_cli(fd, " SIP realtime: Enabled\n" ); + ast_cli(a->fd, " SIP realtime: Enabled\n" ); - ast_cli(fd, "\nNetwork Settings:\n"); - ast_cli(fd, "---------------------------\n"); + ast_cli(a->fd, "\nNetwork Settings:\n"); + ast_cli(a->fd, "---------------------------\n"); /* determine if/how SIP address can be remapped */ if (localaddr == NULL) msg = "Disabled, no localnet list"; @@ -11571,82 +11687,82 @@ msg = "Enabled using externhost"; else msg = "Enabled using externip"; - ast_cli(fd, " SIP address remapping: %s\n", msg); - ast_cli(fd, " Externhost: %s\n", S_OR(externhost, "")); - ast_cli(fd, " Externip: %s:%d\n", ast_inet_ntoa(externip.sin_addr), ntohs(externip.sin_port)); - ast_cli(fd, " Externrefresh: %d\n", externrefresh); - ast_cli(fd, " Internal IP: %s:%d\n", ast_inet_ntoa(internip.sin_addr), ntohs(internip.sin_port)); + ast_cli(a->fd, " SIP address remapping: %s\n", msg); + ast_cli(a->fd, " Externhost: %s\n", S_OR(externhost, "")); + ast_cli(a->fd, " Externip: %s:%d\n", ast_inet_ntoa(externip.sin_addr), ntohs(externip.sin_port)); + ast_cli(a->fd, " Externrefresh: %d\n", externrefresh); + ast_cli(a->fd, " Internal IP: %s:%d\n", ast_inet_ntoa(internip.sin_addr), ntohs(internip.sin_port)); { - struct ast_ha *a; + struct ast_ha *d; const char *prefix = "Localnet:"; char buf[INET_ADDRSTRLEN]; /* need to print two addresses */ - for (a = localaddr; a ; prefix = "", a = a->next) { - ast_cli(fd, " %-24s%s/%s\n", - prefix, ast_inet_ntoa(a->netaddr), - inet_ntop(AF_INET, &a->netmask, buf, sizeof(buf)) ); + for (d = localaddr; d ; prefix = "", d = d->next) { + ast_cli(a->fd, " %-24s%s/%s\n", + prefix, ast_inet_ntoa(d->netaddr), + inet_ntop(AF_INET, &d->netmask, buf, sizeof(buf)) ); } } - ast_cli(fd, " STUN server: %s:%d\n", ast_inet_ntoa(stunaddr.sin_addr), ntohs(stunaddr.sin_port)); + ast_cli(a->fd, " STUN server: %s:%d\n", ast_inet_ntoa(stunaddr.sin_addr), ntohs(stunaddr.sin_port)); - ast_cli(fd, "\nGlobal Signalling Settings:\n"); - ast_cli(fd, "---------------------------\n"); - ast_cli(fd, " Codecs: "); + ast_cli(a->fd, "\nGlobal Signalling Settings:\n"); + ast_cli(a->fd, "---------------------------\n"); + ast_cli(a->fd, " Codecs: "); ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, global_capability); - ast_cli(fd, "%s\n", codec_buf); - ast_cli(fd, " Codec Order: "); - print_codec_to_cli(fd, &default_prefs); - ast_cli(fd, "\n"); - ast_cli(fd, " T1 minimum: %d\n", global_t1min); - ast_cli(fd, " Relax DTMF: %s\n", cli_yesno(global_relaxdtmf)); - ast_cli(fd, " Compact SIP headers: %s\n", cli_yesno(compactheaders)); - ast_cli(fd, " RTP Keepalive: %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" ); - ast_cli(fd, " RTP Timeout: %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" ); - ast_cli(fd, " RTP Hold Timeout: %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)"); - ast_cli(fd, " MWI NOTIFY mime type: %s\n", default_notifymime); - ast_cli(fd, " DNS SRV lookup: %s\n", cli_yesno(global_srvlookup)); - ast_cli(fd, " Pedantic SIP support: %s\n", cli_yesno(pedanticsipchecking)); - ast_cli(fd, " Reg. min duration %d secs\n", min_expiry); - ast_cli(fd, " Reg. max duration: %d secs\n", max_expiry); - ast_cli(fd, " Reg. default duration: %d secs\n", default_expiry); - ast_cli(fd, " Outbound reg. timeout: %d secs\n", global_reg_timeout); - ast_cli(fd, " Outbound reg. attempts: %d\n", global_regattempts_max); - ast_cli(fd, " Notify ringing state: %s\n", cli_yesno(global_notifyringing)); - ast_cli(fd, " Notify hold state: %s\n", cli_yesno(global_notifyhold)); - ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(global_allowtransfer)); - ast_cli(fd, " Max Call Bitrate: %d kbps\n", default_maxcallbitrate); - ast_cli(fd, " Auto-Framing: %s\n", cli_yesno(global_autoframing)); - ast_cli(fd, " Outb. proxy: %s %s\n", ast_strlen_zero(global_outboundproxy.name) ? "" : global_outboundproxy.name, + ast_cli(a->fd, "%s\n", codec_buf); + ast_cli(a->fd, " Codec Order: "); + print_codec_to_cli(a->fd, &default_prefs); + ast_cli(a->fd, "\n"); + ast_cli(a->fd, " T1 minimum: %d\n", global_t1min); + ast_cli(a->fd, " Relax DTMF: %s\n", cli_yesno(global_relaxdtmf)); + ast_cli(a->fd, " Compact SIP headers: %s\n", cli_yesno(compactheaders)); + ast_cli(a->fd, " RTP Keepalive: %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" ); + ast_cli(a->fd, " RTP Timeout: %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" ); + ast_cli(a->fd, " RTP Hold Timeout: %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)"); + ast_cli(a->fd, " MWI NOTIFY mime type: %s\n", default_notifymime); + ast_cli(a->fd, " DNS SRV lookup: %s\n", cli_yesno(global_srvlookup)); + ast_cli(a->fd, " Pedantic SIP support: %s\n", cli_yesno(pedanticsipchecking)); + ast_cli(a->fd, " Reg. min duration %d secs\n", min_expiry); + ast_cli(a->fd, " Reg. max duration: %d secs\n", max_expiry); + ast_cli(a->fd, " Reg. default duration: %d secs\n", default_expiry); + ast_cli(a->fd, " Outbound reg. timeout: %d secs\n", global_reg_timeout); + ast_cli(a->fd, " Outbound reg. attempts: %d\n", global_regattempts_max); + ast_cli(a->fd, " Notify ringing state: %s\n", cli_yesno(global_notifyringing)); + ast_cli(a->fd, " Notify hold state: %s\n", cli_yesno(global_notifyhold)); + ast_cli(a->fd, " SIP Transfer mode: %s\n", transfermode2str(global_allowtransfer)); + ast_cli(a->fd, " Max Call Bitrate: %d kbps\n", default_maxcallbitrate); + ast_cli(a->fd, " Auto-Framing: %s\n", cli_yesno(global_autoframing)); + ast_cli(a->fd, " Outb. proxy: %s %s\n", ast_strlen_zero(global_outboundproxy.name) ? "" : global_outboundproxy.name, global_outboundproxy.force ? "(forced)" : ""); - ast_cli(fd, "\nDefault Settings:\n"); - ast_cli(fd, "-----------------\n"); - ast_cli(fd, " Context: %s\n", default_context); - ast_cli(fd, " Nat: %s\n", nat2str(ast_test_flag(&global_flags[0], SIP_NAT))); - ast_cli(fd, " DTMF: %s\n", dtmfmode2str(ast_test_flag(&global_flags[0], SIP_DTMF))); - ast_cli(fd, " Qualify: %d\n", default_qualify); - ast_cli(fd, " Use ClientCode: %s\n", cli_yesno(ast_test_flag(&global_flags[0], SIP_USECLIENTCODE))); - ast_cli(fd, " Progress inband: %s\n", (ast_test_flag(&global_flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER) ? "Never" : (ast_test_flag(&global_flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NO) ? "No" : "Yes" ); - ast_cli(fd, " Language: %s\n", default_language); - ast_cli(fd, " MOH Interpret: %s\n", default_mohinterpret); - ast_cli(fd, " MOH Suggest: %s\n", default_mohsuggest); - ast_cli(fd, " Voice Mail Extension: %s\n", default_vmexten); + ast_cli(a->fd, "\nDefault Settings:\n"); + ast_cli(a->fd, "-----------------\n"); + ast_cli(a->fd, " Context: %s\n", default_context); + ast_cli(a->fd, " Nat: %s\n", nat2str(ast_test_flag(&global_flags[0], SIP_NAT))); + ast_cli(a->fd, " DTMF: %s\n", dtmfmode2str(ast_test_flag(&global_flags[0], SIP_DTMF))); + ast_cli(a->fd, " Qualify: %d\n", default_qualify); + ast_cli(a->fd, " Use ClientCode: %s\n", cli_yesno(ast_test_flag(&global_flags[0], SIP_USECLIENTCODE))); + ast_cli(a->fd, " Progress inband: %s\n", (ast_test_flag(&global_flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER) ? "Never" : (ast_test_flag(&global_flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NO) ? "No" : "Yes" ); + ast_cli(a->fd, " Language: %s\n", default_language); + ast_cli(a->fd, " MOH Interpret: %s\n", default_mohinterpret); + ast_cli(a->fd, " MOH Suggest: %s\n", default_mohsuggest); + ast_cli(a->fd, " Voice Mail Extension: %s\n", default_vmexten); if (realtimepeers || realtimeusers || realtimeregs) { - ast_cli(fd, "\nRealtime SIP Settings:\n"); - ast_cli(fd, "----------------------\n"); - ast_cli(fd, " Realtime Peers: %s\n", cli_yesno(realtimepeers)); - ast_cli(fd, " Realtime Users: %s\n", cli_yesno(realtimeusers)); - ast_cli(fd, " Realtime Regs: %s\n", cli_yesno(realtimeregs)); - ast_cli(fd, " Cache Friends: %s\n", cli_yesno(ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS))); - ast_cli(fd, " Update: %s\n", cli_yesno(sip_cfg.peer_rtupdate)); - ast_cli(fd, " Ignore Reg. Expire: %s\n", cli_yesno(sip_cfg.ignore_regexpire)); - ast_cli(fd, " Save sys. name: %s\n", cli_yesno(sip_cfg.rtsave_sysname)); - ast_cli(fd, " Auto Clear: %d\n", global_rtautoclear); + ast_cli(a->fd, "\nRealtime SIP Settings:\n"); + ast_cli(a->fd, "----------------------\n"); + ast_cli(a->fd, " Realtime Peers: %s\n", cli_yesno(realtimepeers)); + ast_cli(a->fd, " Realtime Users: %s\n", cli_yesno(realtimeusers)); + ast_cli(a->fd, " Realtime Regs: %s\n", cli_yesno(realtimeregs)); + ast_cli(a->fd, " Cache Friends: %s\n", cli_yesno(ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS))); + ast_cli(a->fd, " Update: %s\n", cli_yesno(sip_cfg.peer_rtupdate)); + ast_cli(a->fd, " Ignore Reg. Expire: %s\n", cli_yesno(sip_cfg.ignore_regexpire)); + ast_cli(a->fd, " Save sys. name: %s\n", cli_yesno(sip_cfg.rtsave_sysname)); + ast_cli(a->fd, " Auto Clear: %d\n", global_rtautoclear); } - ast_cli(fd, "\n----\n"); - return RESULT_SUCCESS; + ast_cli(a->fd, "\n----\n"); + return CLI_SUCCESS; } /*! \brief Show subscription type in string format */ @@ -11927,110 +12043,132 @@ } /*! \brief Show details of one active dialog */ -static int sip_show_channel(int fd, int argc, char *argv[]) +static char *sip_show_channel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { struct sip_pvt *cur; size_t len; int found = 0; - if (argc != 4) - return RESULT_SHOWUSAGE; - len = strlen(argv[3]); + switch (cmd) { + case CLI_INIT: + e->command = "sip show channel"; + e->usage = + "Usage: sip show channel \n" + " Provides detailed status on a given SIP channel.\n"; + return NULL; + case CLI_GENERATE: + return complete_sipch(a->line, a->word, a->pos, a->n); + } + + if (a->argc != 4) + return CLI_SHOWUSAGE; + len = strlen(a->argv[3]); dialoglist_lock(); for (cur = dialoglist; cur; cur = cur->next) { - if (!strncasecmp(cur->callid, argv[3], len)) { + if (!strncasecmp(cur->callid, a->argv[3], len)) { char formatbuf[BUFSIZ/2]; - ast_cli(fd,"\n"); + ast_cli(a->fd,"\n"); if (cur->subscribed != NONE) - ast_cli(fd, " * Subscription (type: %s)\n", subscription_type2str(cur->subscribed)); + ast_cli(a->fd, " * Subscription (type: %s)\n", subscription_type2str(cur->subscribed)); else - ast_cli(fd, " * SIP Call\n"); - ast_cli(fd, " Curr. trans. direction: %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING) ? "Outgoing" : "Incoming"); - ast_cli(fd, " Call-ID: %s\n", cur->callid); - ast_cli(fd, " Owner channel ID: %s\n", cur->owner ? cur->owner->name : ""); - ast_cli(fd, " Our Codec Capability: %d\n", cur->capability); - ast_cli(fd, " Non-Codec Capability (DTMF): %d\n", cur->noncodeccapability); - ast_cli(fd, " Their Codec Capability: %d\n", cur->peercapability); - ast_cli(fd, " Joint Codec Capability: %d\n", cur->jointcapability); - ast_cli(fd, " Format: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0) ); - ast_cli(fd, " T.38 support %s\n", cli_yesno(cur->udptl != NULL)); - ast_cli(fd, " Video support %s\n", cli_yesno(cur->vrtp != NULL)); - ast_cli(fd, " MaxCallBR: %d kbps\n", cur->maxcallbitrate); - ast_cli(fd, " Theoretical Address: %s:%d\n", ast_inet_ntoa(cur->sa.sin_addr), ntohs(cur->sa.sin_port)); - ast_cli(fd, " Received Address: %s:%d\n", ast_inet_ntoa(cur->recv.sin_addr), ntohs(cur->recv.sin_port)); - ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(cur->allowtransfer)); - ast_cli(fd, " NAT Support: %s\n", nat2str(ast_test_flag(&cur->flags[0], SIP_NAT))); - ast_cli(fd, " Audio IP: %s %s\n", ast_inet_ntoa(cur->redirip.sin_addr.s_addr ? cur->redirip.sin_addr : cur->ourip.sin_addr), cur->redirip.sin_addr.s_addr ? "(Outside bridge)" : "(local)" ); - ast_cli(fd, " Our Tag: %s\n", cur->tag); - ast_cli(fd, " Their Tag: %s\n", cur->theirtag); - ast_cli(fd, " SIP User agent: %s\n", cur->useragent); + ast_cli(a->fd, " * SIP Call\n"); + ast_cli(a->fd, " Curr. trans. direction: %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING) ? "Outgoing" : "Incoming"); + ast_cli(a->fd, " Call-ID: %s\n", cur->callid); + ast_cli(a->fd, " Owner channel ID: %s\n", cur->owner ? cur->owner->name : ""); + ast_cli(a->fd, " Our Codec Capability: %d\n", cur->capability); + ast_cli(a->fd, " Non-Codec Capability (DTMF): %d\n", cur->noncodeccapability); + ast_cli(a->fd, " Their Codec Capability: %d\n", cur->peercapability); + ast_cli(a->fd, " Joint Codec Capability: %d\n", cur->jointcapability); + ast_cli(a->fd, " Format: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0) ); + ast_cli(a->fd, " T.38 support %s\n", cli_yesno(cur->udptl != NULL)); + ast_cli(a->fd, " Video support %s\n", cli_yesno(cur->vrtp != NULL)); + ast_cli(a->fd, " MaxCallBR: %d kbps\n", cur->maxcallbitrate); + ast_cli(a->fd, " Theoretical Address: %s:%d\n", ast_inet_ntoa(cur->sa.sin_addr), ntohs(cur->sa.sin_port)); + ast_cli(a->fd, " Received Address: %s:%d\n", ast_inet_ntoa(cur->recv.sin_addr), ntohs(cur->recv.sin_port)); + ast_cli(a->fd, " SIP Transfer mode: %s\n", transfermode2str(cur->allowtransfer)); + ast_cli(a->fd, " NAT Support: %s\n", nat2str(ast_test_flag(&cur->flags[0], SIP_NAT))); + ast_cli(a->fd, " Audio IP: %s %s\n", ast_inet_ntoa(cur->redirip.sin_addr.s_addr ? cur->redirip.sin_addr : cur->ourip.sin_addr), cur->redirip.sin_addr.s_addr ? "(Outside bridge)" : "(local)" ); + ast_cli(a->fd, " Our Tag: %s\n", cur->tag); + ast_cli(a->fd, " Their Tag: %s\n", cur->theirtag); + ast_cli(a->fd, " SIP User agent: %s\n", cur->useragent); if (!ast_strlen_zero(cur->username)) - ast_cli(fd, " Username: %s\n", cur->username); + ast_cli(a->fd, " Username: %s\n", cur->username); if (!ast_strlen_zero(cur->peername)) - ast_cli(fd, " Peername: %s\n", cur->peername); + ast_cli(a->fd, " Peername: %s\n", cur->peername); if (!ast_strlen_zero(cur->uri)) - ast_cli(fd, " Original uri: %s\n", cur->uri); + ast_cli(a->fd, " Original uri: %s\n", cur->uri); if (!ast_strlen_zero(cur->cid_num)) - ast_cli(fd, " Caller-ID: %s\n", cur->cid_num); - ast_cli(fd, " Need Destroy: %s\n", cli_yesno(cur->needdestroy)); - ast_cli(fd, " Last Message: %s\n", cur->lastmsg); - ast_cli(fd, " Promiscuous Redir: %s\n", cli_yesno(ast_test_flag(&cur->flags[0], SIP_PROMISCREDIR))); - ast_cli(fd, " Route: %s\n", cur->route ? cur->route->hop : "N/A"); - ast_cli(fd, " DTMF Mode: %s\n", dtmfmode2str(ast_test_flag(&cur->flags[0], SIP_DTMF))); - ast_cli(fd, " SIP Options: "); + ast_cli(a->fd, " Caller-ID: %s\n", cur->cid_num); + ast_cli(a->fd, " Need Destroy: %s\n", cli_yesno(cur->needdestroy)); + ast_cli(a->fd, " Last Message: %s\n", cur->lastmsg); + ast_cli(a->fd, " Promiscuous Redir: %s\n", cli_yesno(ast_test_flag(&cur->flags[0], SIP_PROMISCREDIR))); + ast_cli(a->fd, " Route: %s\n", cur->route ? cur->route->hop : "N/A"); + ast_cli(a->fd, " DTMF Mode: %s\n", dtmfmode2str(ast_test_flag(&cur->flags[0], SIP_DTMF))); + ast_cli(a->fd, " SIP Options: "); if (cur->sipoptions) { int x; for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { if (cur->sipoptions & sip_options[x].id) - ast_cli(fd, "%s ", sip_options[x].text); + ast_cli(a->fd, "%s ", sip_options[x].text); } } else - ast_cli(fd, "(none)\n"); - ast_cli(fd, "\n\n"); + ast_cli(a->fd, "(none)\n"); + ast_cli(a->fd, "\n\n"); found++; } } dialoglist_unlock(); if (!found) - ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); - return RESULT_SUCCESS; + ast_cli(a->fd, "No such SIP Call ID starting with '%s'\n", a->argv[3]); + return CLI_SUCCESS; } /*! \brief Show history details of one dialog */ -static int sip_show_history(int fd, int argc, char *argv[]) +static char *sip_show_history(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { struct sip_pvt *cur; size_t len; int found = 0; - if (argc != 4) - return RESULT_SHOWUSAGE; + switch (cmd) { + case CLI_INIT: + e->command = "sip show history"; + e->usage = + "Usage: sip show history \n" + " Provides detailed dialog history on a given SIP channel.\n"; + return NULL; + case CLI_GENERATE: + return complete_sip_show_history(a->line, a->word, a->pos, a->n); + } + + if (a->argc != 4) + return CLI_SHOWUSAGE; if (!recordhistory) - ast_cli(fd, "\n***Note: History recording is currently DISABLED. Use 'sip history' to ENABLE.\n"); - len = strlen(argv[3]); + ast_cli(a->fd, "\n***Note: History recording is currently DISABLED. Use 'sip history' to ENABLE.\n"); + len = strlen(a->argv[3]); dialoglist_lock(); for (cur = dialoglist; cur; cur = cur->next) { - if (!strncasecmp(cur->callid, argv[3], len)) { + if (!strncasecmp(cur->callid, a->argv[3], len)) { struct sip_history *hist; int x = 0; - ast_cli(fd,"\n"); + ast_cli(a->fd,"\n"); if (cur->subscribed != NONE) - ast_cli(fd, " * Subscription\n"); + ast_cli(a->fd, " * Subscription\n"); else - ast_cli(fd, " * SIP Call\n"); + ast_cli(a->fd, " * SIP Call\n"); if (cur->history) AST_LIST_TRAVERSE(cur->history, hist, list) - ast_cli(fd, "%d. %s\n", ++x, hist->event); + ast_cli(a->fd, "%d. %s\n", ++x, hist->event); if (x == 0) - ast_cli(fd, "Call '%s' has no history\n", cur->callid); + ast_cli(a->fd, "Call '%s' has no history\n", cur->callid); found++; } } dialoglist_unlock(); if (!found) - ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); - return RESULT_SUCCESS; + ast_cli(a->fd, "No such SIP Call ID starting with '%s'\n", a->argv[3]); + return CLI_SUCCESS; } /*! \brief Dump SIP history to debug log file at end of lifespan for SIP dialog */ @@ -12291,40 +12429,53 @@ } /*! \brief Cli command to send SIP notify to peer */ -static int sip_notify(int fd, int argc, char *argv[]) +static char *sip_notify(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { struct ast_variable *varlist; int i; - if (argc < 4) - return RESULT_SHOWUSAGE; + switch (cmd) { + case CLI_INIT: + e->command = "sip notify"; + e->usage = + "Usage: sip notify [...]\n" + " Send a NOTIFY message to a SIP peer or peers\n" + " Message types are defined in sip_notify.conf\n"; + return NULL; + case CLI_GENERATE: + return complete_sipnotify(a->line, a->word, a->pos, a->n); + } + + if (a->argc < 4) + return CLI_SHOWUSAGE; + if (!notify_types) { - ast_cli(fd, "No %s file found, or no types listed there\n", notify_config); - return RESULT_FAILURE; + ast_cli(a->fd, "No %s file found, or no types listed there\n", notify_config); + return CLI_FAILURE; } - varlist = ast_variable_browse(notify_types, argv[2]); + varlist = ast_variable_browse(notify_types, a->argv[2]); if (!varlist) { - ast_cli(fd, "Unable to find notify type '%s'\n", argv[2]); - return RESULT_FAILURE; + ast_cli(a->fd, "Unable to find notify type '%s'\n", a->argv[2]); + return CLI_FAILURE; } - for (i = 3; i < argc; i++) { + for (i = 3; i < a->argc; i++) { struct sip_pvt *p; struct sip_request req; struct ast_variable *var; if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) { ast_log(LOG_WARNING, "Unable to build sip pvt data for notify (memory/socket error)\n"); - return RESULT_FAILURE; + return CLI_FAILURE; } - if (create_addr(p, argv[i])) { + if (create_addr(p, a->argv[i])) { /* Maybe they're not registered, etc. */ sip_destroy(p); - ast_cli(fd, "Could not create address for '%s'\n", argv[i]); + ast_cli(a->fd, "Could not create address for '%s'\n", a->argv[i]); continue; } @@ -12337,35 +12488,59 @@ ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip); build_via(p); build_callid_pvt(p); - ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]); + ast_cli(a->fd, "Sending NOTIFY of type '%s' to '%s'\n", a->argv[2], a->argv[i]); transmit_sip_request(p, &req); sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); dialog_unref(p); } - return RESULT_SUCCESS; + return CLI_SUCCESS; } /*! \brief Enable SIP History logging (CLI) */ -static int sip_do_history(int fd, int argc, char *argv[]) +static char *sip_do_history(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 = "sip history"; + e->usage = + "Usage: sip history\n" + " Enables recording of SIP dialog history for debugging purposes.\n" + " Use 'sip show history' to view the history of a call number.\n"; + return NULL; + case CLI_GENERATE: + return NULL; } + + if (a->argc != 2) { + return CLI_SHOWUSAGE; + } recordhistory = TRUE; - ast_cli(fd, "SIP History Recording Enabled (use 'sip show history')\n"); - return RESULT_SUCCESS; + ast_cli(a->fd, "SIP History Recording Enabled (use 'sip show history')\n"); + return CLI_SUCCESS; } /*! \brief Disable SIP History logging (CLI) */ -static int sip_no_history(int fd, int argc, char *argv[]) +static char *sip_no_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 = "sip history off"; + e->usage = + "Usage: sip history off\n" + " Disables recording of SIP dialog history for debugging purposes\n"; + return NULL; + case CLI_GENERATE: + return NULL; } + + if (a->argc != 3) { + return CLI_SHOWUSAGE; + } recordhistory = FALSE; - ast_cli(fd, "SIP History Recording Disabled\n"); - return RESULT_SUCCESS; + ast_cli(a->fd, "SIP History Recording Disabled\n"); + return CLI_SUCCESS; } /*! \brief Authenticate for outbound registration */ @@ -12561,82 +12736,6 @@ return 0; } -static const char show_domains_usage[] = -"Usage: sip show domains\n" -" Lists all configured SIP local domains.\n" -" Asterisk only responds to SIP messages to local domains.\n"; - -static const char notify_usage[] = -"Usage: sip notify [...]\n" -" Send a NOTIFY message to a SIP peer or peers\n" -" Message types are defined in sip_notify.conf\n"; - -static const char show_users_usage[] = -"Usage: sip show users [like ]\n" -" Lists all known SIP users.\n" -" Optional regular expression pattern is used to filter the user list.\n"; - -static const char show_user_usage[] = -"Usage: sip show user [load]\n" -" Shows all details on one SIP user and the current status.\n" -" Option \"load\" forces lookup of peer in realtime storage.\n"; - -static const char show_inuse_usage[] = -"Usage: sip show inuse [all]\n" -" List all SIP users and peers usage counters and limits.\n" -" Add option \"all\" to show all devices, not only those with a limit.\n"; - -static const char show_channel_usage[] = -"Usage: sip show channel \n" -" Provides detailed status on a given SIP channel.\n"; - -static const char show_history_usage[] = -"Usage: sip show history \n" -" Provides detailed dialog history on a given SIP channel.\n"; - -static const char show_peers_usage[] = -"Usage: sip show peers [like ]\n" -" Lists all known SIP peers.\n" -" Optional regular expression pattern is used to filter the peer list.\n"; - -static const char show_peer_usage[] = -"Usage: sip show peer [load]\n" -" Shows all details on one SIP peer and the current status.\n" -" Option \"load\" forces lookup of peer in realtime storage.\n"; - -static const char show_reg_usage[] = -"Usage: sip show registry\n" -" Lists all registration requests and status.\n"; - -static const char sip_unregister_usage[] = -"Usage: sip unregister \n" -" Unregister (force expiration) a SIP peer from the registry\n"; - -static const char no_history_usage[] = -"Usage: sip history off\n" -" Disables recording of SIP dialog history for debugging purposes\n"; - -static const char history_usage[] = -"Usage: sip history\n" -" Enables recording of SIP dialog history for debugging purposes.\n" -"Use 'sip show history' to view the history of a call number.\n"; - -static const char sip_reload_usage[] = -"Usage: sip reload\n" -" Reloads SIP configuration from sip.conf\n"; - -static const char show_subscriptions_usage[] = -"Usage: sip show subscriptions\n" -" Lists active SIP subscriptions for extension states\n"; - -static const char show_objects_usage[] = -"Usage: sip show objects\n" -" Lists status of known SIP objects\n"; - -static const char show_settings_usage[] = -"Usage: sip show settings\n" -" Provides detailed list of the configuration of the SIP channel.\n"; - /*! \brief Read SIP header (dialplan function) */ static int func_header_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t len) { @@ -18769,97 +18868,62 @@ } /*! \brief Force reload of module from cli */ -static int sip_reload(int fd, int argc, char *argv[]) +static char *sip_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { + + switch (cmd) { + case CLI_INIT: + e->command = "sip reload"; + e->usage = + "Usage: sip reload\n" + " Reloads SIP configuration from sip.conf\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + ast_mutex_lock(&sip_reload_lock); if (sip_reloading) ast_verbose("Previous SIP reload not yet done\n"); else { sip_reloading = TRUE; - sip_reloadreason = fd ? CHANNEL_CLI_RELOAD : CHANNEL_MODULE_RELOAD; + sip_reloadreason = a->fd ? CHANNEL_CLI_RELOAD : CHANNEL_MODULE_RELOAD; } ast_mutex_unlock(&sip_reload_lock); restart_monitor(); - return 0; + return CLI_SUCCESS; } /*! \brief Part of Asterisk module interface */ static int reload(void) { - return sip_reload(0, 0, NULL); + if (sip_reload(0, 0, NULL)) + return 0; + return 1; } /*! \brief SIP Cli commands definition */ static struct ast_cli_entry cli_sip[] = { NEW_CLI(sip_show_channels, "List active SIP channels/subscriptions"), - - { { "sip", "show", "domains", NULL }, - sip_show_domains, "List our local SIP domains.", - show_domains_usage }, - - { { "sip", "show", "inuse", NULL }, - sip_show_inuse, "List all inuse/limits", - show_inuse_usage }, - - { { "sip", "show", "objects", NULL }, - sip_show_objects, "List all SIP object allocations", - show_objects_usage }, - - { { "sip", "show", "peers", NULL }, - sip_show_peers, "List defined SIP peers", - show_peers_usage }, - - { { "sip", "show", "registry", NULL }, - sip_show_registry, "List SIP registration status", - show_reg_usage }, - - { { "sip", "unregister", NULL }, - sip_unregister, "Unregister (force expiration) a SIP peer from the registery\n", - sip_unregister_usage, complete_sip_unregister }, - - { { "sip", "show", "settings", NULL }, - sip_show_settings, "Show SIP global settings", - show_settings_usage }, - - { { "sip", "show", "users", NULL }, - sip_show_users, "List defined SIP users", - show_users_usage }, - - { { "sip", "notify", NULL }, - sip_notify, "Send a notify packet to a SIP peer", - notify_usage, complete_sipnotify }, - - { { "sip", "show", "channel", NULL }, - sip_show_channel, "Show detailed SIP channel info", - show_channel_usage, complete_sipch }, - - { { "sip", "show", "history", NULL }, - sip_show_history, "Show SIP dialog history", - show_history_usage, complete_sip_show_history }, - - { { "sip", "show", "peer", NULL }, - sip_show_peer, "Show details on specific SIP peer", - show_peer_usage, complete_sip_show_peer }, - - { { "sip", "show", "user", NULL }, - sip_show_user, "Show details on specific SIP user", - show_user_usage, complete_sip_show_user }, - + NEW_CLI(sip_show_domains, "List our local SIP domains."), + NEW_CLI(sip_show_inuse, "List all inuse/limits"), + NEW_CLI(sip_show_objects, "List all SIP object allocations"), + NEW_CLI(sip_show_peers, "List defined SIP peers"), + NEW_CLI(sip_show_registry, "List SIP registration status"), + NEW_CLI(sip_unregister, "Unregister (force expiration) a SIP peer from the registery\n"), + NEW_CLI(sip_show_settings, "Show SIP global settings"), + NEW_CLI(sip_notify, "Send a notify packet to a SIP peer"), + NEW_CLI(sip_show_channel, "Show detailed SIP channel info"), + NEW_CLI(sip_show_history, "Show SIP dialog history"), + NEW_CLI(sip_show_peer, "Show details on specific SIP peer"), + NEW_CLI(sip_show_users, "List defined SIP users"), + NEW_CLI(sip_show_user, "Show details on specific SIP user"), NEW_CLI(sip_prune_realtime, "Prune cached Realtime users/peers"), NEW_CLI(sip_do_debug, "Enable/Disable SIP debugging"), - - { { "sip", "history", NULL }, - sip_do_history, "Enable SIP history", - history_usage }, - - { { "sip", "history", "off", NULL }, - sip_no_history, "Disable SIP history", - no_history_usage }, - - { { "sip", "reload", NULL }, - sip_reload, "Reload SIP configuration", - sip_reload_usage }, + NEW_CLI(sip_do_history, "Enable SIP history"), + NEW_CLI(sip_no_history, "Disable SIP history"), + NEW_CLI(sip_reload, "Reload SIP configuration"), }; /*! \brief PBX load module - initialization */ Index: channels/chan_agent.c =================================================================== --- channels/chan_agent.c (revision 82911) +++ channels/chan_agent.c (working copy) @@ -230,6 +230,7 @@ static int agent_fixup(struct ast_channel *oldchan, struct ast_channel *newchan); static struct ast_channel *agent_bridgedchannel(struct ast_channel *chan, struct ast_channel *bridge); static void set_agentbycallerid(const char *callerid, const char *agent); +static char *complete_agent_logoff_cmd(const char *line, const char *word, int pos, int state); /*! \brief Channel interface description for PBX integration */ static const struct ast_channel_tech agent_tech = { @@ -1496,22 +1497,34 @@ return ret; } -static int agent_logoff_cmd(int fd, int argc, char **argv) +static char *agent_logoff_cmd(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { int ret; char *agent; - if (argc < 3 || argc > 4) - return RESULT_SHOWUSAGE; - if (argc == 4 && strcasecmp(argv[3], "soft")) - return RESULT_SHOWUSAGE; + switch (cmd) { + case CLI_INIT: + e->command = "agent logoff"; + e->usage = + "Usage: agent logoff [soft]\n" + " Sets an agent as no longer logged in.\n" + " If 'soft' is specified, do not hangup existing calls.\n"; + return NULL; + case CLI_GENERATE: + return complete_agent_logoff_cmd(a->line, a->word, a->pos, a->n); + } - agent = argv[2] + 6; - ret = agent_logoff(agent, argc == 4); + if (a->argc < 3 || a->argc > 4) + return CLI_SHOWUSAGE; + if (a->argc == 4 && strcasecmp(a->argv[3], "soft")) + return CLI_SHOWUSAGE; + + agent = a->argv[2] + 6; + ret = agent_logoff(agent, a->argc == 4); if (ret == 0) - ast_cli(fd, "Logging out %s\n", agent); + ast_cli(a->fd, "Logging out %s\n", agent); - return RESULT_SUCCESS; + return CLI_SUCCESS; } /*! @@ -1565,7 +1578,7 @@ /*! * Show agents in cli. */ -static int agents_show(int fd, int argc, char **argv) +static char *agents_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { struct agent_pvt *p; char username[AST_MAX_BUF]; @@ -1575,16 +1588,29 @@ int count_agents = 0; /*!< Number of agents configured */ int online_agents = 0; /*!< Number of online agents */ int offline_agents = 0; /*!< Number of offline agents */ - if (argc != 2) - return RESULT_SHOWUSAGE; + + switch (cmd) { + case CLI_INIT: + e->command = "agent show"; + e->usage = + "Usage: agent show\n" + " Provides summary information on agents.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + if (a->argc != 2) + return CLI_SHOWUSAGE; + AST_LIST_LOCK(&agents); AST_LIST_TRAVERSE(&agents, p, list) { ast_mutex_lock(&p->lock); if (p->pending) { if (p->group) - ast_cli(fd, "-- Pending call to group %d\n", powerof(p->group)); + ast_cli(a->fd, "-- Pending call to group %d\n", powerof(p->group)); else - ast_cli(fd, "-- Pending call to agent %s\n", p->agent); + ast_cli(a->fd, "-- Pending call to agent %s\n", p->agent); } else { if (!ast_strlen_zero(p->name)) snprintf(username, sizeof(username), "(%s) ", p->name); @@ -1613,7 +1639,7 @@ } if (!ast_strlen_zero(p->moh)) snprintf(moh, sizeof(moh), " (musiconhold is '%s')", p->moh); - ast_cli(fd, "%-12.12s %s%s%s%s\n", p->agent, + ast_cli(a->fd, "%-12.12s %s%s%s%s\n", p->agent, username, location, talkingto, moh); count_agents++; } @@ -1621,16 +1647,16 @@ } AST_LIST_UNLOCK(&agents); if ( !count_agents ) - ast_cli(fd, "No Agents are configured in %s\n",config); + ast_cli(a->fd, "No Agents are configured in %s\n",config); else - ast_cli(fd, "%d agents configured [%d online , %d offline]\n",count_agents, online_agents, offline_agents); - ast_cli(fd, "\n"); + ast_cli(a->fd, "%d agents configured [%d online , %d offline]\n",count_agents, online_agents, offline_agents); + ast_cli(a->fd, "\n"); - return RESULT_SUCCESS; + return CLI_SUCCESS; } -static int agents_show_online(int fd, int argc, char **argv) +static char *agents_show_online(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { struct agent_pvt *p; char username[AST_MAX_BUF]; @@ -1640,8 +1666,21 @@ int count_agents = 0; /* Number of agents configured */ int online_agents = 0; /* Number of online agents */ int agent_status = 0; /* 0 means offline, 1 means online */ - if (argc != 3) - return RESULT_SHOWUSAGE; + + switch (cmd) { + case CLI_INIT: + e->command = "agent show online"; + e->usage = + "Usage: agent show online\n" + " Provides a list of all online agents.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + if (a->argc != 3) + return CLI_SHOWUSAGE; + AST_LIST_LOCK(&agents); AST_LIST_TRAVERSE(&agents, p, list) { agent_status = 0; /* reset it to offline */ @@ -1669,46 +1708,28 @@ if (!ast_strlen_zero(p->moh)) snprintf(moh, sizeof(moh), " (musiconhold is '%s')", p->moh); if (agent_status) - ast_cli(fd, "%-12.12s %s%s%s%s\n", p->agent, username, location, talkingto, moh); + ast_cli(a->fd, "%-12.12s %s%s%s%s\n", p->agent, username, location, talkingto, moh); count_agents++; ast_mutex_unlock(&p->lock); } AST_LIST_UNLOCK(&agents); if (!count_agents) - ast_cli(fd, "No Agents are configured in %s\n", config); + ast_cli(a->fd, "No Agents are configured in %s\n", config); else - ast_cli(fd, "%d agents online\n", online_agents); - ast_cli(fd, "\n"); - return RESULT_SUCCESS; + ast_cli(a->fd, "%d agents online\n", online_agents); + ast_cli(a->fd, "\n"); + return CLI_SUCCESS; } - - -static const char show_agents_usage[] = -"Usage: agent show\n" -" Provides summary information on agents.\n"; - -static const char show_agents_online_usage[] = -"Usage: agent show online\n" -" Provides a list of all online agents.\n"; - static const char agent_logoff_usage[] = "Usage: agent logoff [soft]\n" " Sets an agent as no longer logged in.\n" " If 'soft' is specified, do not hangup existing calls.\n"; static struct ast_cli_entry cli_agents[] = { - { { "agent", "show", NULL }, - agents_show, "Show status of agents", - show_agents_usage }, - - { { "agent", "show", "online" }, - agents_show_online, "Show all online agents", - show_agents_online_usage }, - - { { "agent", "logoff", NULL }, - agent_logoff_cmd, "Sets an agent offline", - agent_logoff_usage, complete_agent_logoff_cmd }, + NEW_CLI(agents_show, "Show status of agents"), + NEW_CLI(agents_show_online, "Show all online agents"), + NEW_CLI(agent_logoff_cmd, "Sets an agent offline"), }; /*! Index: channels/chan_alsa.c =================================================================== --- channels/chan_alsa.c (revision 82911) +++ channels/chan_alsa.c (working copy) @@ -838,26 +838,6 @@ return tmp; } -static int console_autoanswer(int fd, int argc, char *argv[]) -{ - int res = RESULT_SUCCESS;; - if ((argc != 2) && (argc != 3)) - return RESULT_SHOWUSAGE; - ast_mutex_lock(&alsalock); - if (argc == 2) { - ast_cli(fd, "Auto answer is %s.\n", autoanswer ? "on" : "off"); - } else { - if (!strcasecmp(argv[2], "on")) - autoanswer = -1; - else if (!strcasecmp(argv[2], "off")) - autoanswer = 0; - else - res = RESULT_SHOWUSAGE; - } - ast_mutex_unlock(&alsalock); - return res; -} - static char *autoanswer_complete(const char *line, const char *word, int pos, int state) { #ifndef MIN @@ -876,24 +856,65 @@ return NULL; } -static const char autoanswer_usage[] = - "Usage: console autoanswer [on|off]\n" - " Enables or disables autoanswer feature. If used without\n" - " argument, displays the current on/off status of autoanswer.\n" - " The default value of autoanswer is in 'alsa.conf'.\n"; +static char *console_autoanswer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) +{ + char *res = CLI_SUCCESS; -static int console_answer(int fd, int argc, char *argv[]) + switch (cmd) { + case CLI_INIT: + e->command = "console autoanswer"; + e->usage = + "Usage: console autoanswer [on|off]\n" + " Enables or disables autoanswer feature. If used without\n" + " argument, displays the current on/off status of autoanswer.\n" + " The default value of autoanswer is in 'alsa.conf'.\n"; + return NULL; + case CLI_GENERATE: + return autoanswer_complete(a->line, a->word, a->pos, a->n); + } + + if ((a->argc != 2) && (a->argc != 3)) + return CLI_SHOWUSAGE; + ast_mutex_lock(&alsalock); + if (a->argc == 2) { + ast_cli(a->fd, "Auto answer is %s.\n", autoanswer ? "on" : "off"); + } else { + if (!strcasecmp(a->argv[2], "on")) + autoanswer = -1; + else if (!strcasecmp(a->argv[2], "off")) + autoanswer = 0; + else + res = CLI_SHOWUSAGE; + } + ast_mutex_unlock(&alsalock); + return res; +} + +static char *console_answer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { - int res = RESULT_SUCCESS; + char *res = CLI_SUCCESS; - if (argc != 2) - return RESULT_SHOWUSAGE; + switch (cmd) { + case CLI_INIT: + e->command = "console answer"; + e->usage = + "Usage: console answer\n" + " Answers an incoming call on the console (ALSA) channel.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + + if (a->argc != 2) + return CLI_SHOWUSAGE; + ast_mutex_lock(&alsalock); if (!alsa.owner) { - ast_cli(fd, "No one is calling us\n"); - res = RESULT_FAILURE; + ast_cli(a->fd, "No one is calling us\n"); + res = CLI_FAILURE; } else { hookstate = 1; cursound = -1; @@ -911,32 +932,39 @@ ast_mutex_unlock(&alsalock); - return RESULT_SUCCESS; + return res; } -static const char sendtext_usage[] = - "Usage: console send text \n" - " Sends a text message for display on the remote terminal.\n"; - -static int console_sendtext(int fd, int argc, char *argv[]) +static char *console_sendtext(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { int tmparg = 3; - int res = RESULT_SUCCESS; + char *res = CLI_SUCCESS; - if (argc < 3) - return RESULT_SHOWUSAGE; + switch (cmd) { + case CLI_INIT: + e->command = "console send text"; + e->usage = + "Usage: console send text \n" + " Sends a text message for display on the remote terminal.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + if (a->argc < 3) + return CLI_SHOWUSAGE; + ast_mutex_lock(&alsalock); if (!alsa.owner) { - ast_cli(fd, "No one is calling us\n"); - res = RESULT_FAILURE; + ast_cli(a->fd, "No one is calling us\n"); + res = CLI_FAILURE; } else { struct ast_frame f = { AST_FRAME_TEXT, 0 }; char text2send[256] = ""; text2send[0] = '\0'; - while (tmparg < argc) { - strncat(text2send, argv[tmparg++], sizeof(text2send) - strlen(text2send) - 1); + while (tmparg < a->argc) { + strncat(text2send, a->argv[tmparg++], sizeof(text2send) - strlen(text2send) - 1); strncat(text2send, " ", sizeof(text2send) - strlen(text2send) - 1); } text2send[strlen(text2send) - 1] = '\n'; @@ -959,24 +987,32 @@ return res; } -static const char answer_usage[] = - "Usage: console answer\n" - " Answers an incoming call on the console (ALSA) channel.\n"; - -static int console_hangup(int fd, int argc, char *argv[]) +static char *console_hangup(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { - int res = RESULT_SUCCESS; + char *res = CLI_SUCCESS; - if (argc != 2) - return RESULT_SHOWUSAGE; + switch (cmd) { + case CLI_INIT: + e->command = "console hangup"; + e->usage = + "Usage: console hangup\n" + " Hangs up any call currently placed on the console.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + if (a->argc != 2) + return CLI_SHOWUSAGE; + cursound = -1; ast_mutex_lock(&alsalock); if (!alsa.owner && !hookstate) { - ast_cli(fd, "No call to hangup up\n"); - res = RESULT_FAILURE; + ast_cli(a->fd, "No call to hangup up\n"); + res = CLI_FAILURE; } else { hookstate = 0; grab_owner(); @@ -991,25 +1027,32 @@ return res; } -static const char hangup_usage[] = - "Usage: console hangup\n" - " Hangs up any call currently placed on the console.\n"; - -static int console_dial(int fd, int argc, char *argv[]) +static char *console_dial(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { char tmp[256], *tmp2; char *mye, *myc; char *d; - int res = RESULT_SUCCESS; + char *res = CLI_SUCCESS; - if ((argc != 2) && (argc != 3)) - return RESULT_SHOWUSAGE; + switch (cmd) { + case CLI_INIT: + e->command = "console dial"; + e->usage = + "Usage: console dial [extension[@context]]\n" + " Dials a given extension (and context if specified)\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + if ((a->argc != 2) && (a->argc != 3)) + return CLI_SHOWUSAGE; + ast_mutex_lock(&alsalock); if (alsa.owner) { - if (argc == 3) { - d = argv[2]; + if (a->argc == 3) { + d = a->argv[2]; if (alsa.owner) { struct ast_frame f = { AST_FRAME_DTMF }; while (*d) { @@ -1019,15 +1062,15 @@ } } } else { - ast_cli(fd, "You're already in a call. You can use this only to dial digits until you hangup\n"); - res = RESULT_FAILURE; + ast_cli(a->fd, "You're already in a call. You can use this only to dial digits until you hangup\n"); + res = CLI_FAILURE; } } else { mye = exten; myc = context; - if (argc == 3) { + if (a->argc == 3) { char *stringp = NULL; - ast_copy_string(tmp, argv[2], sizeof(tmp)); + ast_copy_string(tmp, a->argv[2], sizeof(tmp)); stringp = tmp; strsep(&stringp, "@"); tmp2 = strsep(&stringp, "@"); @@ -1042,7 +1085,7 @@ hookstate = 1; alsa_new(&alsa, AST_STATE_RINGING); } else - ast_cli(fd, "No such extension '%s' in context '%s'\n", mye, myc); + ast_cli(a->fd, "No such extension '%s' in context '%s'\n", mye, myc); } ast_mutex_unlock(&alsalock); @@ -1050,30 +1093,12 @@ return res; } -static const char dial_usage[] = - "Usage: console dial [extension[@context]]\n" - " Dials a given extension (and context if specified)\n"; - static struct ast_cli_entry cli_alsa[] = { - { { "console", "answer", NULL }, - console_answer, "Answer an incoming console call", - answer_usage }, - - { { "console", "hangup", NULL }, - console_hangup, "Hangup a call on the console", - hangup_usage }, - - { { "console", "dial", NULL }, - console_dial, "Dial an extension on the console", - dial_usage }, - - { { "console", "send", "text", NULL }, - console_sendtext, "Send text to the remote device", - sendtext_usage }, - - { { "console", "autoanswer", NULL }, - console_autoanswer, "Sets/displays autoanswer", - autoanswer_usage, autoanswer_complete }, + NEW_CLI(console_answer, "Answer an incoming console call"), + NEW_CLI(console_hangup, "Hangup a call on the console"), + NEW_CLI(console_dial, "Dial an extension on the console"), + NEW_CLI(console_sendtext, "Send text to the remote device"), + NEW_CLI(console_autoanswer, "Sets/displays autoanswer"), }; static int load_module(void) Index: channels/chan_local.c =================================================================== --- channels/chan_local.c (revision 82911) +++ channels/chan_local.c (working copy) @@ -670,35 +670,40 @@ } /*! \brief CLI command "local show channels" */ -static int locals_show(int fd, int argc, char **argv) +static char *locals_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { struct local_pvt *p = NULL; - if (argc != 3) - return RESULT_SHOWUSAGE; + switch (cmd) { + case CLI_INIT: + e->command = "local show channels"; + e->usage = + "Usage: local show channels\n" + " Provides summary information on active local proxy channels.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + if (a->argc != 3) + return CLI_SHOWUSAGE; + AST_LIST_LOCK(&locals); if (!AST_LIST_EMPTY(&locals)) { AST_LIST_TRAVERSE(&locals, p, list) { ast_mutex_lock(&p->lock); - ast_cli(fd, "%s -- %s@%s\n", p->owner ? p->owner->name : "", p->exten, p->context); + ast_cli(a->fd, "%s -- %s@%s\n", p->owner ? p->owner->name : "", p->exten, p->context); ast_mutex_unlock(&p->lock); } } else - ast_cli(fd, "No local channels in use\n"); + ast_cli(a->fd, "No local channels in use\n"); AST_LIST_UNLOCK(&locals); - return RESULT_SUCCESS; + return CLI_SUCCESS; } -static const char show_locals_usage[] = -"Usage: local show channels\n" -" Provides summary information on active local proxy channels.\n"; - static struct ast_cli_entry cli_local[] = { - { { "local", "show", "channels", NULL }, - locals_show, "List status of local channels", - show_locals_usage }, + NEW_CLI(locals_show, "List status of local channels"), }; /*! \brief Load module into PBX, register channel */ Index: main/manager.c =================================================================== --- main/manager.c (revision 82911) +++ main/manager.c (working copy) @@ -406,45 +406,6 @@ return get_perm(string); } -static char *complete_show_mancmd(const char *line, const char *word, int pos, int state) -{ - struct manager_action *cur; - int l = strlen(word), which = 0; - char *ret = NULL; - - AST_RWLIST_RDLOCK(&actions); - AST_RWLIST_TRAVERSE(&actions, cur, list) { - if (!strncasecmp(word, cur->action, l) && ++which > state) { - ret = ast_strdup(cur->action); - break; /* make sure we exit even if ast_strdup() returns NULL */ - } - } - AST_RWLIST_UNLOCK(&actions); - - return ret; -} - -static char *complete_show_manuser(const char *line, const char *word, int pos, int state) -{ - struct ast_manager_user *user = NULL; - int l = strlen(word), which = 0; - char *ret = NULL; - - if (pos != 3) - return NULL; - - AST_RWLIST_RDLOCK(&users); - AST_RWLIST_TRAVERSE(&users, user, list) { - if (!strncasecmp(word, user->username, l) && ++which > state) { - ret = ast_strdup(user->username); - break; - } - } - AST_RWLIST_UNLOCK(&users); - - return ret; -} - static int check_manager_session_inuse(const char *name) { struct mansession *session = NULL; @@ -491,20 +452,40 @@ return ret; } -static int handle_showmancmd(int fd, int argc, char *argv[]) +static char *handle_showmancmd(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { struct manager_action *cur; - struct ast_str *authority = ast_str_alloca(80); - int num; + struct ast_str *authority; + int num, l, which; + char *ret = NULL; + switch ( cmd ) { + case CLI_INIT: + e->command = "manager show command"; + e->usage = + "Usage: manager show command \n" + " Shows the detailed description for a specific Asterisk manager interface command.\n"; + return NULL; + case CLI_GENERATE: + l = strlen(a->word), which = 0; + AST_RWLIST_RDLOCK(&actions); + AST_RWLIST_TRAVERSE(&actions, cur, list) { + if (!strncasecmp(a->word, cur->action, l) && ++which > a->n) { + ret = ast_strdup(cur->action); + break; /* make sure we exit even if ast_strdup() returns NULL */ + } + } + AST_RWLIST_UNLOCK(&actions); + return ret; + } + authority = ast_str_alloca(80); + if ( 4 != a->argc ) + return CLI_SHOWUSAGE; - if (argc != 4) - return RESULT_SHOWUSAGE; - AST_RWLIST_RDLOCK(&actions); AST_RWLIST_TRAVERSE(&actions, cur, list) { - for (num = 3; num < argc; num++) { - if (!strcasecmp(cur->action, argv[num])) { - ast_cli(fd, "Action: %s\nSynopsis: %s\nPrivilege: %s\n%s\n", + for (num = 3; num < a->argc; num++) { + if (!strcasecmp(cur->action, a->argv[num])) { + ast_cli(a->fd, "Action: %s\nSynopsis: %s\nPrivilege: %s\n%s\n", cur->action, cur->synopsis, authority_to_str(cur->authority, &authority), S_OR(cur->description, "") ); @@ -513,41 +494,72 @@ } AST_RWLIST_UNLOCK(&actions); - return RESULT_SUCCESS; + return CLI_SUCCESS; } -static int handle_mandebug(int fd, int argc, char *argv[]) +static char *handle_mandebug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { - if (argc == 2) - ast_cli(fd, "manager debug is %s\n", manager_debug? "on" : "off"); - else if (argc == 3) { - if (!strcasecmp(argv[2], "on")) + switch ( cmd ) { + case CLI_INIT: + e->command = "manager debug [on|off]"; + e->usage = "Usage: manager debug [on|off]\n Show, enable, disable debugging of the manager code.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + if ( 2 == a->argc ) + ast_cli(a->fd, "manager debug is %s\n", manager_debug? "on" : "off"); + else if ( 3 == a->argc ) { + if ( !strcasecmp(a->argv[2], "on") ) manager_debug = 1; - else if (!strcasecmp(argv[2], "off")) + else if ( !strcasecmp(a->argv[2], "off") ) manager_debug = 0; else - return RESULT_SHOWUSAGE; + return CLI_SHOWUSAGE; } - return RESULT_SUCCESS; + return CLI_SUCCESS; } -static int handle_showmanager(int fd, int argc, char *argv[]) +static char *handle_showmanager(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { struct ast_manager_user *user = NULL; + int l, which; + char *ret = NULL; + switch ( cmd ) { + case CLI_INIT: + e->command = "manager show user"; + e->usage = + " Usage: manager show user \n" + " Display all information related to the manager user specified.\n"; + return NULL; + case CLI_GENERATE: + l = strlen(a->word), which = 0; + if ( 3 != a->pos ) + return NULL; + AST_RWLIST_RDLOCK(&users); + AST_RWLIST_TRAVERSE(&users, user, list) { + if ( !strncasecmp(a->word, user->username, l) && ++which > a->n ) { + ret = ast_strdup(user->username); + break; + } + } + AST_RWLIST_UNLOCK(&users); + return ret; + } - if (argc != 4) - return RESULT_SHOWUSAGE; + if ( 4 != a->argc ) + return CLI_SHOWUSAGE; AST_RWLIST_RDLOCK(&users); - if (!(user = get_manager_by_name_locked(argv[3]))) { - ast_cli(fd, "There is no manager called %s\n", argv[3]); + if ( !( user = get_manager_by_name_locked(a->argv[3]) ) ) { + ast_cli(a->fd, "There is no manager called %s\n", a->argv[3]); AST_RWLIST_UNLOCK(&users); - return -1; + return CLI_SUCCESS; } - ast_cli(fd,"\n"); - ast_cli(fd, + ast_cli(a->fd,"\n"); + ast_cli(a->fd, " username: %s\n" " secret: %s\n" " deny: %s\n" @@ -565,154 +577,147 @@ AST_RWLIST_UNLOCK(&users); - return RESULT_SUCCESS; + return CLI_SUCCESS; } -static int handle_showmanagers(int fd, int argc, char *argv[]) +static char *handle_showmanagers(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { struct ast_manager_user *user = NULL; int count_amu = 0; + switch ( cmd ) { + case CLI_INIT: + e->command = "manager show users"; + e->usage = + "Usage: manager show users\n" + " Prints a listing of all managers that are currently configured on that\n" + " system.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + if ( 3 != a->argc ) + return CLI_SHOWUSAGE; - if (argc != 3) - return RESULT_SHOWUSAGE; - AST_RWLIST_RDLOCK(&users); /* If there are no users, print out something along those lines */ if (AST_RWLIST_EMPTY(&users)) { - ast_cli(fd, "There are no manager users.\n"); + ast_cli(a->fd, "There are no manager users.\n"); AST_RWLIST_UNLOCK(&users); - return RESULT_SUCCESS; + return CLI_SUCCESS; } - ast_cli(fd, "\nusername\n--------\n"); + ast_cli(a->fd, "\nusername\n--------\n"); AST_RWLIST_TRAVERSE(&users, user, list) { - ast_cli(fd, "%s\n", user->username); + ast_cli(a->fd, "%s\n", user->username); count_amu++; } AST_RWLIST_UNLOCK(&users); - ast_cli(fd,"-------------------\n"); - ast_cli(fd,"%d manager users configured.\n", count_amu); + ast_cli(a->fd,"-------------------\n"); + ast_cli(a->fd,"%d manager users configured.\n", count_amu); - return RESULT_SUCCESS; + return CLI_SUCCESS; } /*! \brief CLI command manager list commands */ -static int handle_showmancmds(int fd, int argc, char *argv[]) +static char *handle_showmancmds(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { struct manager_action *cur; - struct ast_str *authority = ast_str_alloca(80); - char *format = " %-15.15s %-15.15s %-55.55s\n"; + struct ast_str *authority; + static const char *format = " %-15.15s %-15.15s %-55.55s\n"; + switch ( cmd ) { + case CLI_INIT: + e->command = "manager show commands"; + e->usage = + "Usage: manager show commands\n" + " Prints a listing of all the available Asterisk manager interface commands.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + authority = ast_str_alloca(80); + ast_cli(a->fd, format, "Action", "Privilege", "Synopsis"); + ast_cli(a->fd, format, "------", "---------", "--------"); - ast_cli(fd, format, "Action", "Privilege", "Synopsis"); - ast_cli(fd, format, "------", "---------", "--------"); - AST_RWLIST_RDLOCK(&actions); AST_RWLIST_TRAVERSE(&actions, cur, list) - ast_cli(fd, format, cur->action, authority_to_str(cur->authority, &authority), cur->synopsis); + ast_cli(a->fd, format, cur->action, authority_to_str(cur->authority, &authority), cur->synopsis); AST_RWLIST_UNLOCK(&actions); - return RESULT_SUCCESS; + return CLI_SUCCESS; } /*! \brief CLI command manager list connected */ -static int handle_showmanconn(int fd, int argc, char *argv[]) +static char *handle_showmanconn(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { struct mansession *s; - char *format = " %-15.15s %-15.15s\n"; + static const char *format = " %-15.15s %-15.15s\n"; int count = 0; + switch ( cmd ) { + case CLI_INIT: + e->command = "manager show connected"; + e->usage = + "Usage: manager show connected\n" + " Prints a listing of the users that are currently connected to the\n" + "Asterisk manager interface.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + ast_cli(a->fd, format, "Username", "IP Address"); - ast_cli(fd, format, "Username", "IP Address"); - AST_LIST_LOCK(&sessions); AST_LIST_TRAVERSE(&sessions, s, list) { - ast_cli(fd, format,s->username, ast_inet_ntoa(s->sin.sin_addr)); + ast_cli(a->fd, format,s->username, ast_inet_ntoa(s->sin.sin_addr)); count++; } AST_LIST_UNLOCK(&sessions); - ast_cli(fd, "%d users connected.\n", count); + ast_cli(a->fd, "%d users connected.\n", count); - return RESULT_SUCCESS; + return CLI_SUCCESS; } /*! \brief CLI command manager list eventq */ /* Should change to "manager show connected" */ -static int handle_showmaneventq(int fd, int argc, char *argv[]) +static char *handle_showmaneventq(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { struct eventqent *s; - + switch ( cmd ) { + case CLI_INIT: + e->command = "manager show eventq"; + e->usage = + "Usage: manager show eventq\n" + " Prints a listing of all events pending in the Asterisk manger\n" + "event queue.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } AST_LIST_LOCK(&all_events); AST_LIST_TRAVERSE(&all_events, s, eq_next) { - ast_cli(fd, "Usecount: %d\n",s->usecount); - ast_cli(fd, "Category: %d\n", s->category); - ast_cli(fd, "Event:\n%s", s->eventdata); + ast_cli(a->fd, "Usecount: %d\n",s->usecount); + ast_cli(a->fd, "Category: %d\n", s->category); + ast_cli(a->fd, "Event:\n%s", s->eventdata); } AST_LIST_UNLOCK(&all_events); - return RESULT_SUCCESS; + return CLI_SUCCESS; } -static char showmancmd_help[] = -"Usage: manager show command \n" -" Shows the detailed description for a specific Asterisk manager interface command.\n"; - -static char showmancmds_help[] = -"Usage: manager show commands\n" -" Prints a listing of all the available Asterisk manager interface commands.\n"; - -static char showmanconn_help[] = -"Usage: manager show connected\n" -" Prints a listing of the users that are currently connected to the\n" -"Asterisk manager interface.\n"; - -static char showmaneventq_help[] = -"Usage: manager show eventq\n" -" Prints a listing of all events pending in the Asterisk manger\n" -"event queue.\n"; - -static char showmanagers_help[] = -"Usage: manager show users\n" -" Prints a listing of all managers that are currently configured on that\n" -" system.\n"; - -static char showmanager_help[] = -" Usage: manager show user \n" -" Display all information related to the manager user specified.\n"; - static struct ast_cli_entry cli_manager[] = { - { { "manager", "show", "command", NULL }, - handle_showmancmd, "Show a manager interface command", - showmancmd_help, complete_show_mancmd }, - - { { "manager", "show", "commands", NULL }, - handle_showmancmds, "List manager interface commands", - showmancmds_help }, - - { { "manager", "show", "connected", NULL }, - handle_showmanconn, "List connected manager interface users", - showmanconn_help }, - - { { "manager", "show", "eventq", NULL }, - handle_showmaneventq, "List manager interface queued events", - showmaneventq_help }, - - { { "manager", "show", "users", NULL }, - handle_showmanagers, "List configured manager users", - showmanagers_help, NULL, NULL }, - - { { "manager", "show", "user", NULL }, - handle_showmanager, "Display information on a specific manager user", - showmanager_help, complete_show_manuser, NULL }, - - { { "manager", "debug", NULL }, - handle_mandebug, "Show, enable, disable debugging of the manager code", - "Usage: manager debug [on|off]\n Show, enable, disable debugging of the manager code.\n", NULL, NULL }, + NEW_CLI(handle_showmancmd, "Show a manager interface command"), + NEW_CLI(handle_showmancmds, "List manager interface commands"), + NEW_CLI(handle_showmanconn, "List connected manager interface users"), + NEW_CLI(handle_showmaneventq, "List manager interface queued events"), + NEW_CLI(handle_showmanagers, "List configured manager users"), + NEW_CLI(handle_showmanager, "Display information on a specific manager user"), + NEW_CLI(handle_mandebug, "Show, enable, disable debugging of the manager code"), }; /* Index: main/http.c =================================================================== --- main/http.c (revision 82911) +++ main/http.c (working copy) @@ -1232,15 +1232,26 @@ return 0; } -static int handle_show_http(int fd, int argc, char *argv[]) +static char *handle_show_http(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { struct ast_http_uri *urih; struct http_uri_redirect *redirect; struct ast_http_post_mapping *post_map; - - if (argc != 3) - return RESULT_SHOWUSAGE; - + int fd; + switch ( cmd ) { + case CLI_INIT: + e->command = "http show status"; + e->usage = + "Usage: http show status\n" + " Lists status of internal HTTP engine\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + if ( 3 != a->argc ) + return CLI_SHOWUSAGE; + fd = a->fd; ast_cli(fd, "HTTP Server Status:\n"); ast_cli(fd, "Prefix: %s\n", prefix); if (!http_desc.oldsin.sin_family) @@ -1281,7 +1292,7 @@ ast_cli(fd, "%s\n", AST_LIST_EMPTY(&post_mappings) ? "None.\n" : ""); AST_RWLIST_UNLOCK(&post_mappings); - return RESULT_SUCCESS; + return CLI_SUCCESS; } int ast_http_reload(void) @@ -1289,14 +1300,8 @@ return __ast_http_load(1); } -static char show_http_help[] = -"Usage: http show status\n" -" Lists status of internal HTTP engine\n"; - static struct ast_cli_entry cli_http[] = { - { { "http", "show", "status", NULL }, - handle_show_http, "Display HTTP server status", - show_http_help }, + NEW_CLI(handle_show_http, "Display HTTP server status"), }; int ast_http_init(void) Index: main/frame.c =================================================================== --- main/frame.c (revision 82911) +++ main/frame.c (working copy) @@ -611,13 +611,29 @@ return ret; } -static int show_codecs(int fd, int argc, char *argv[]) +static char *show_codecs(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { + int argc, fd; + char **argv; int i, found=0; char hex[25]; + + switch ( cmd ) { + case CLI_INIT: + e->command = "core show codecs [audio|video|image]"; + e->usage = + "Usage: core show codecs [audio|video|image]\n" + " Displays codec mapping\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + fd = a->fd; + argc = a->argc; + argv = a->argv; if ((argc < 3) || (argc > 4)) - return RESULT_SHOWUSAGE; + return CLI_SHOWUSAGE; if (!ast_opt_dont_warn) ast_cli(fd, "Disclaimer: this command is for informational purposes only.\n" @@ -649,25 +665,36 @@ } } - if (! found) - return RESULT_SHOWUSAGE; + if ( !found ) + return CLI_SHOWUSAGE; else - return RESULT_SUCCESS; + return CLI_SUCCESS; } -static const char frame_show_codecs_usage[] = -"Usage: core show codecs [audio|video|image]\n" -" Displays codec mapping\n"; - -static int show_codec_n(int fd, int argc, char *argv[]) +static char *show_codec_n(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { - int codec, i, found=0; + int codec, i, fd, argc, found=0; + char **argv; + switch ( cmd ) { + case CLI_INIT: + e->command = "core show codec"; + e->usage = + "Usage: core show codec \n" + " Displays codec mapping\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + fd = a->fd; + argc = a->argc; + argv = a->argv; + if (argc != 4) - return RESULT_SHOWUSAGE; + return CLI_SHOWUSAGE; if (sscanf(argv[3],"%d",&codec) != 1) - return RESULT_SHOWUSAGE; + return CLI_SHOWUSAGE; for (i = 0; i < 32; i++) if (codec & (1 << i)) { @@ -678,13 +705,9 @@ if (!found) ast_cli(fd, "Codec %d not found\n", codec); - return RESULT_SUCCESS; + return CLI_SUCCESS; } -static char frame_show_codec_n_usage[] = -"Usage: core show codec \n" -" Displays codec mapping\n"; - /*! Dump a frame for debugging purposes */ void ast_frame_dump(const char *name, struct ast_frame *f, char *prefix) { @@ -867,12 +890,25 @@ #ifdef TRACE_FRAMES -static int show_frame_stats(int fd, int argc, char *argv[]) +static char *show_frame_stats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { struct ast_frame *f; - int x=1; - if (argc != 4) - return RESULT_SHOWUSAGE; + int fd, x=1; + + switch ( cmd ) { + case CLI_INIT: + e->command = "core show frame stats"; + e->usage = + "Usage: core show frame stats\n" + " Displays debugging statistics from framer\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + fd = a->fd; + + if (a->argc != 4) + return CLI_SHOWUSAGE; AST_LIST_LOCK(&headerlist); ast_cli(fd, " Framer Statistics \n"); ast_cli(fd, "---------------------------\n"); @@ -881,40 +917,16 @@ AST_LIST_TRAVERSE(&headerlist, f, frame_list) ast_cli(fd, "%d. Type %d, subclass %d from %s\n", x++, f->frametype, f->subclass, f->src ? f->src : ""); AST_LIST_UNLOCK(&headerlist); - return RESULT_SUCCESS; + return CLI_SUCCESS; } - -static const char frame_stats_usage[] = -"Usage: core show frame stats\n" -" Displays debugging statistics from framer\n"; #endif /* Builtin Asterisk CLI-commands for debugging */ static struct ast_cli_entry my_clis[] = { - { { "core", "show", "codecs", NULL }, - show_codecs, "Displays a list of codecs", - frame_show_codecs_usage }, - - { { "core", "show", "codecs", "audio", NULL }, - show_codecs, "Displays a list of audio codecs", - frame_show_codecs_usage }, - - { { "core", "show", "codecs", "video", NULL }, - show_codecs, "Displays a list of video codecs", - frame_show_codecs_usage }, - - { { "core", "show", "codecs", "image", NULL }, - show_codecs, "Displays a list of image codecs", - frame_show_codecs_usage }, - - { { "core", "show", "codec", NULL }, - show_codec_n, "Shows a specific codec", - frame_show_codec_n_usage }, - + NEW_CLI(show_codecs, "Displays a list of codecs"), + NEW_CLI(show_codec_n, "Shows a specific codec"), #ifdef TRACE_FRAMES - { { "core", "show", "frame", "stats", NULL }, - show_frame_stats, "Shows frame statistics", - frame_stats_usage }, + NEW_CLI(show_frame_stats, "Shows frame statistics"), #endif }; Index: main/logger.c =================================================================== --- main/logger.c (revision 82911) +++ main/logger.c (working copy) @@ -616,30 +616,68 @@ return res; } -static int handle_logger_reload(int fd, int argc, char *argv[]) +static char *handle_logger_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { + int fd; + switch ( cmd ) { + case CLI_INIT: + e->command = "logger reload"; + e->usage = + "Usage: logger reload\n" + " Reloads the logger subsystem state. Use after restarting syslogd(8) if you are using syslog logging.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + fd = a->fd; if (reload_logger(0)) { ast_cli(fd, "Failed to reload the logger\n"); - return RESULT_FAILURE; + return CLI_FAILURE; } else - return RESULT_SUCCESS; + return CLI_SUCCESS; } -static int handle_logger_rotate(int fd, int argc, char *argv[]) +static char *handle_logger_rotate(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { + int fd; + switch ( cmd ) { + case CLI_INIT: + e->command = "logger rotate"; + e->usage = + "Usage: logger rotate\n" + " Rotates and Reopens the log files.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + fd = a->fd; if (reload_logger(1)) { ast_cli(fd, "Failed to reload the logger and rotate log files\n"); - return RESULT_FAILURE; + return CLI_FAILURE; } else - return RESULT_SUCCESS; + return CLI_SUCCESS; } /*! \brief CLI command to show logging system configuration */ -static int handle_logger_show_channels(int fd, int argc, char *argv[]) +static char *handle_logger_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { #define FORMATL "%-35.35s %-8.8s %-9.9s " + int fd, argc; + char **argv; struct logchannel *chan; - + switch ( cmd ) { + case CLI_INIT: + e->command = "logger show channels"; + e->usage = + "Usage: logger show channels\n" + " List configured logger channels.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + fd = a->fd; + argc = a->argc; + argv = a->argv; ast_cli(fd,FORMATL, "Channel", "Type", "Status"); ast_cli(fd, "Configuration\n"); ast_cli(fd,FORMATL, "-------", "----", "------"); @@ -668,7 +706,7 @@ AST_RWLIST_UNLOCK(&logchannels); ast_cli(fd, "\n"); - return RESULT_SUCCESS; + return CLI_SUCCESS; } struct verb { @@ -678,30 +716,10 @@ static AST_RWLIST_HEAD_STATIC(verbosers, verb); -static char logger_reload_help[] = -"Usage: logger reload\n" -" Reloads the logger subsystem state. Use after restarting syslogd(8) if you are using syslog logging.\n"; - -static char logger_rotate_help[] = -"Usage: logger rotate\n" -" Rotates and Reopens the log files.\n"; - -static char logger_show_channels_help[] = -"Usage: logger show channels\n" -" List configured logger channels.\n"; - static struct ast_cli_entry cli_logger[] = { - { { "logger", "show", "channels", NULL }, - handle_logger_show_channels, "List configured log channels", - logger_show_channels_help }, - - { { "logger", "reload", NULL }, - handle_logger_reload, "Reopens the log files", - logger_reload_help }, - - { { "logger", "rotate", NULL }, - handle_logger_rotate, "Rotates and reopens the log files", - logger_rotate_help }, + NEW_CLI(handle_logger_show_channels, "List configured log channels"), + NEW_CLI(handle_logger_reload, "Reopens the log files"), + NEW_CLI(handle_logger_rotate, "Rotates and reopens the log files") }; static int handle_SIGXFSZ(int sig) Index: main/pbx.c =================================================================== --- main/pbx.c (revision 82911) +++ main/pbx.c (working copy) @@ -1246,16 +1246,33 @@ } } -static int handle_show_functions(int fd, int argc, char *argv[]) +static char *handle_show_functions(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { struct ast_custom_function *acf; int count_acf = 0; int like = 0; + int fd, argc; + char **argv; + switch ( cmd ) { + case CLI_INIT: + e->command = "core show functions [like]"; + e->usage = + "Usage: core show functions [like ]\n" + " List builtin functions, optionally only those matching a given string\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + fd = a->fd; + argc = a->argc; + argv = a->argv; + if (argc == 5 && (!strcmp(argv[3], "like")) ) { like = 1; } else if (argc != 3) { - return RESULT_SHOWUSAGE; + return CLI_SHOWUSAGE; } ast_cli(fd, "%s Custom Functions:\n--------------------------------------------------------------------------------\n", like ? "Matching" : "Installed"); @@ -1271,10 +1288,10 @@ ast_cli(fd, "%d %scustom functions installed.\n", count_acf, like ? "matching " : ""); - return RESULT_SUCCESS; + return CLI_SUCCESS; } -static int handle_show_function(int fd, int argc, char *argv[]) +static char *handle_show_function(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { struct ast_custom_function *acf; /* Maximum number of characters added by terminal coloring is 22 */ @@ -1282,13 +1299,44 @@ char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL; char stxtitle[40], *syntax = NULL; int synopsis_size, description_size, syntax_size; + int fd, argc; + char **argv; + char *ret = NULL; + int which = 0; + int wordlen; + switch ( cmd ) { + case CLI_INIT: + e->command = "core show function"; + e->usage = + "Usage: core show function \n" + " Describe a particular dialplan function.\n"; + return NULL; + case CLI_GENERATE: + wordlen = strlen(a->word); + /* case-insensitive for convenience in this 'complete' function */ + AST_RWLIST_RDLOCK(&acf_root); + AST_RWLIST_TRAVERSE(&acf_root, acf, acflist) { + if (!strncasecmp(a->word, acf->name, wordlen) && ++which > a->n) { + ret = ast_strdup(acf->name); + break; + } + } + AST_RWLIST_UNLOCK(&acf_root); + + return ret; + } + + fd = a->fd; + argc = a->argc; + argv = a->argv; + if (argc < 4) - return RESULT_SHOWUSAGE; + return CLI_SHOWUSAGE; if (!(acf = ast_custom_function_find(argv[3]))) { ast_cli(fd, "No function by that name registered.\n"); - return RESULT_FAILURE; + return CLI_FAILURE; } @@ -1327,29 +1375,9 @@ ast_cli(fd,"%s%s%s\n\n%s%s\n\n%s%s\n", infotitle, stxtitle, syntax, syntitle, synopsis, destitle, description); - return RESULT_SUCCESS; + return CLI_SUCCESS; } -static char *complete_show_function(const char *line, const char *word, int pos, int state) -{ - struct ast_custom_function *acf; - char *ret = NULL; - int which = 0; - int wordlen = strlen(word); - - /* case-insensitive for convenience in this 'complete' function */ - AST_RWLIST_RDLOCK(&acf_root); - AST_RWLIST_TRAVERSE(&acf_root, acf, acflist) { - if (!strncasecmp(word, acf->name, wordlen) && ++which > state) { - ret = ast_strdup(acf->name); - break; - } - } - AST_RWLIST_UNLOCK(&acf_root); - - return ret; -} - struct ast_custom_function *ast_custom_function_find(const char *name) { struct ast_custom_function *acf = NULL; @@ -3008,89 +3036,55 @@ /* * Help for CLI commands ... */ -static char show_applications_help[] = -"Usage: core show applications [{like|describing} ]\n" -" List applications which are currently available.\n" -" If 'like', will be a substring of the app name\n" -" If 'describing', will be a substring of the description\n"; -static char show_functions_help[] = -"Usage: core show functions [like ]\n" -" List builtin functions, optionally only those matching a given string\n"; - -static char show_switches_help[] = -"Usage: core show switches\n" -" List registered switches\n"; - -static char show_hints_help[] = -"Usage: core show hints\n" -" List registered hints\n"; - -static char show_globals_help[] = -"Usage: core show globals\n" -" List current global dialplan variables and their values\n"; - -static char show_application_help[] = -"Usage: core show application [ [ [...]]]\n" -" Describes a particular application.\n"; - -static char show_function_help[] = -"Usage: core show function \n" -" Describe a particular dialplan function.\n"; - -static char show_dialplan_help[] = -"Usage: core show dialplan [exten@][context]\n" -" Show dialplan\n"; - -static char set_global_help[] = -"Usage: core set global \n" -" Set global dialplan variable to \n"; - - /* - * \brief 'show application' CLI command implementation functions ... + * \brief 'show application' CLI command implementation function... */ - -/* - * There is a possibility to show informations about more than one - * application at one time. You can type 'show application Dial Echo' and - * you will see informations about these two applications ... - */ -static char *complete_show_application(const char *line, const char *word, int pos, int state) +static char *handle_show_application(struct ast_cli_entry *e, int cmd, struct ast_cli_args *ar) { struct ast_app *a; + int app, no_registered_app = 1; char *ret = NULL; int which = 0; - int wordlen = strlen(word); + int wordlen; - /* return the n-th [partial] matching entry */ - AST_RWLIST_RDLOCK(&apps); - AST_RWLIST_TRAVERSE(&apps, a, list) { - if (!strncasecmp(word, a->name, wordlen) && ++which > state) { - ret = ast_strdup(a->name); - break; + switch ( cmd ) { + case CLI_INIT: + e->command = "core show application"; + e->usage = + "Usage: core show application [ [ [...]]]\n" + " Describes a particular application.\n"; + return NULL; + case CLI_GENERATE: + /* + * There is a possibility to show informations about more than one + * application at one time. You can type 'show application Dial Echo' and + * you will see informations about these two applications ... + */ + wordlen = strlen(ar->word); + /* return the n-th [partial] matching entry */ + AST_RWLIST_RDLOCK(&apps); + AST_RWLIST_TRAVERSE(&apps, a, list) { + if (!strncasecmp(ar->word, a->name, wordlen) && ++which > ar->n) { + ret = ast_strdup(a->name); + break; + } } + AST_RWLIST_UNLOCK(&apps); + + return ret; } - AST_RWLIST_UNLOCK(&apps); - return ret; -} + if ( 4 > ar->argc ) + return CLI_SHOWUSAGE; -static int handle_show_application(int fd, int argc, char *argv[]) -{ - struct ast_app *a; - int app, no_registered_app = 1; - - if (argc < 4) - return RESULT_SHOWUSAGE; - /* ... go through all applications ... */ AST_RWLIST_RDLOCK(&apps); AST_RWLIST_TRAVERSE(&apps, a, list) { /* ... compare this application name with all arguments given * to 'show application' command ... */ - for (app = 3; app < argc; app++) { - if (!strcasecmp(a->name, argv[app])) { + for (app = 3; app < ar->argc; app++) { + if (!strcasecmp(a->name, ar->argv[app])) { /* Maximum number of characters added by terminal coloring is 22 */ char infotitle[64 + AST_MAX_APP + 22], syntitle[40], destitle[40]; char info[64 + AST_MAX_APP], *synopsis = NULL, *description = NULL; @@ -3122,10 +3116,10 @@ a->description ? a->description : "Not available", COLOR_CYAN, 0, description_size); - ast_cli(fd,"%s%s%s\n\n%s%s\n", infotitle, syntitle, synopsis, destitle, description); + ast_cli(ar->fd,"%s%s%s\n\n%s%s\n", infotitle, syntitle, synopsis, destitle, description); } else { /* ... one of our applications, show info ...*/ - ast_cli(fd,"\n -= Info about application '%s' =- \n\n" + ast_cli(ar->fd,"\n -= Info about application '%s' =- \n\n" "[Synopsis]\n %s\n\n" "[Description]\n%s\n", a->name, @@ -3139,81 +3133,122 @@ /* we found at least one app? no? */ if (no_registered_app) { - ast_cli(fd, "Your application(s) is (are) not registered\n"); - return RESULT_FAILURE; + ast_cli(ar->fd, "Your application(s) is (are) not registered\n"); + return CLI_FAILURE; } - return RESULT_SUCCESS; + return CLI_SUCCESS; } /*! \brief handle_show_hints: CLI support for listing registered dial plan hints */ -static int handle_show_hints(int fd, int argc, char *argv[]) +static char *handle_show_hints(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { struct ast_hint *hint; int num = 0; int watchers; struct ast_state_cb *watcher; + switch ( cmd ) { + case CLI_INIT: + e->command = "core show hints"; + e->usage = + "Usage: core show hints\n" + " List registered hints\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + AST_RWLIST_RDLOCK(&hints); if (AST_RWLIST_EMPTY(&hints)) { - ast_cli(fd, "There are no registered dialplan hints\n"); + ast_cli(a->fd, "There are no registered dialplan hints\n"); AST_RWLIST_UNLOCK(&hints); - return RESULT_SUCCESS; + return CLI_SUCCESS; } /* ... we have hints ... */ - ast_cli(fd, "\n -= Registered Asterisk Dial Plan Hints =-\n"); + ast_cli(a->fd, "\n -= Registered Asterisk Dial Plan Hints =-\n"); AST_RWLIST_TRAVERSE(&hints, hint, list) { watchers = 0; for (watcher = hint->callbacks; watcher; watcher = watcher->next) watchers++; - ast_cli(fd, " %20s@%-20.20s: %-20.20s State:%-15.15s Watchers %2d\n", + ast_cli(a->fd, " %20s@%-20.20s: %-20.20s State:%-15.15s Watchers %2d\n", ast_get_extension_name(hint->exten), ast_get_context_name(ast_get_extension_context(hint->exten)), ast_get_extension_app(hint->exten), ast_extension_state2str(hint->laststate), watchers); num++; } - ast_cli(fd, "----------------\n"); - ast_cli(fd, "- %d hints registered\n", num); + ast_cli(a->fd, "----------------\n"); + ast_cli(a->fd, "- %d hints registered\n", num); AST_RWLIST_UNLOCK(&hints); - return RESULT_SUCCESS; + return CLI_SUCCESS; } /*! \brief handle_show_switches: CLI support for listing registered dial plan switches */ -static int handle_show_switches(int fd, int argc, char *argv[]) +static char *handle_show_switches(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { struct ast_switch *sw; + switch ( cmd ) { + case CLI_INIT: + e->command = "core show switches"; + e->usage = + "Usage: core show switches\n" + " List registered switches\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + AST_RWLIST_RDLOCK(&switches); if (AST_RWLIST_EMPTY(&switches)) { AST_RWLIST_UNLOCK(&switches); - ast_cli(fd, "There are no registered alternative switches\n"); + ast_cli(a->fd, "There are no registered alternative switches\n"); return RESULT_SUCCESS; } - ast_cli(fd, "\n -= Registered Asterisk Alternative Switches =-\n"); + ast_cli(a->fd, "\n -= Registered Asterisk Alternative Switches =-\n"); AST_RWLIST_TRAVERSE(&switches, sw, list) - ast_cli(fd, "%s: %s\n", sw->name, sw->description); + ast_cli(a->fd, "%s: %s\n", sw->name, sw->description); AST_RWLIST_UNLOCK(&switches); - return RESULT_SUCCESS; + return CLI_SUCCESS; } -static int handle_show_applications(int fd, int argc, char *argv[]) +static char *handle_show_applications(struct ast_cli_entry *e, int cmd, struct ast_cli_args *ar) { struct ast_app *a; int like = 0, describing = 0; int total_match = 0; /* Number of matches in like clause */ int total_apps = 0; /* Number of apps registered */ + static char* choices[] = { "like", "describing", NULL }; + int fd, argc; + char **argv; + switch ( cmd ) { + case CLI_INIT: + e->command = "core show applications [like|describing]"; + e->usage = + "Usage: core show applications [{like|describing} ]\n" + " List applications which are currently available.\n" + " If 'like', will be a substring of the app name\n" + " If 'describing', will be a substring of the description\n"; + return NULL; + case CLI_GENERATE: + return ( 3 != ar->pos ) ? NULL : ast_cli_complete(ar->word, choices, ar->n); + } + fd = ar->fd; + argc = ar->argc; + argv = ar->argv; + AST_RWLIST_RDLOCK(&apps); if (AST_RWLIST_EMPTY(&apps)) { ast_cli(fd, "There are no registered applications\n"); AST_RWLIST_UNLOCK(&apps); - return -1; + return CLI_SUCCESS; } /* core list applications like */ @@ -3267,16 +3302,9 @@ AST_RWLIST_UNLOCK(&apps); - return RESULT_SUCCESS; + return CLI_SUCCESS; } -static char *complete_show_applications(const char *line, const char *word, int pos, int state) -{ - static char* choices[] = { "like", "describing", NULL }; - - return (pos != 3) ? NULL : ast_cli_complete(word, choices, state); -} - /* * 'show dialplan' CLI command implementation functions ... */ @@ -3485,17 +3513,33 @@ return (dpc->total_exten == old_total_exten) ? -1 : res; } -static int handle_show_dialplan(int fd, int argc, char *argv[]) +static char *handle_show_dialplan(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { char *exten = NULL, *context = NULL; /* Variables used for different counters */ struct dialplan_counters counters; + const char *incstack[AST_PBX_MAX_STACK]; + int fd, argc; + char **argv; - const char *incstack[AST_PBX_MAX_STACK]; + switch ( cmd ) { + case CLI_INIT: + e->command = "dialplan show"; + e->usage = + "Usage: core show dialplan [exten@][context]\n" + " Show dialplan\n"; + return NULL; + case CLI_GENERATE: + return complete_show_dialplan_context(a->line, a->word, a->pos, a->n); + } + + fd = a->fd; + argc = a->argc; + argv = a->argv; memset(&counters, 0, sizeof(counters)); if (argc != 2 && argc != 3) - return RESULT_SHOWUSAGE; + return CLI_SHOWUSAGE; /* we obtain [exten@]context? if yes, split them ... */ if (argc == 3) { @@ -3517,7 +3561,7 @@ /* check for input failure and throw some error messages */ if (context && !counters.context_existence) { ast_cli(fd, "There is no existence of '%s' context\n", context); - return RESULT_FAILURE; + return CLI_FAILURE; } if (exten && !counters.extension_existence) { @@ -3528,7 +3572,7 @@ ast_cli(fd, "There is no existence of '%s' extension in all contexts\n", exten); - return RESULT_FAILURE; + return CLI_FAILURE; } ast_cli(fd,"-= %d %s (%d %s) in %d %s. =-\n", @@ -3537,7 +3581,7 @@ counters.total_context, counters.total_context == 1 ? "context" : "contexts"); /* everything ok */ - return RESULT_SUCCESS; + return CLI_SUCCESS; } /*! \brief Send ack once */ @@ -3751,74 +3795,68 @@ /*! \brief CLI support for listing global variables in a parseable way */ -static int handle_show_globals(int fd, int argc, char *argv[]) +static char *handle_show_globals(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { int i = 0; struct ast_var_t *newvariable; + switch ( cmd ) { + case CLI_INIT: + e->command = "core show globals"; + e->usage = + "Usage: core show globals\n" + " List current global dialplan variables and their values\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + ast_rwlock_rdlock(&globalslock); AST_LIST_TRAVERSE (&globals, newvariable, entries) { i++; - ast_cli(fd, " %s=%s\n", ast_var_name(newvariable), ast_var_value(newvariable)); + ast_cli(a->fd, " %s=%s\n", ast_var_name(newvariable), ast_var_value(newvariable)); } ast_rwlock_unlock(&globalslock); - ast_cli(fd, "\n -- %d variables\n", i); + ast_cli(a->fd, "\n -- %d variables\n", i); - return RESULT_SUCCESS; + return CLI_SUCCESS; } -static int handle_set_global(int fd, int argc, char *argv[]) +static char *handle_set_global(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { - if (argc != 5) - return RESULT_SHOWUSAGE; + switch ( cmd ) { + case CLI_INIT: + e->command = "core set global"; + e->usage = + "Usage: core set global \n" + " Set global dialplan variable to \n"; + return NULL; + case CLI_GENERATE: + return NULL; + } - pbx_builtin_setvar_helper(NULL, argv[3], argv[4]); - ast_cli(fd, "\n -- Global variable %s set to %s\n", argv[3], argv[4]); + if ( 5 != a->argc ) + return CLI_SHOWUSAGE; - return RESULT_SUCCESS; + pbx_builtin_setvar_helper(NULL, a->argv[3], a->argv[4]); + ast_cli(a->fd, "\n -- Global variable %s set to %s\n", a->argv[3], a->argv[4]); + + return CLI_SUCCESS; } - - /* * CLI entries for upper commands ... */ static struct ast_cli_entry pbx_cli[] = { - { { "core", "show", "applications", NULL }, - handle_show_applications, "Shows registered dialplan applications", - show_applications_help, complete_show_applications }, - - { { "core", "show", "functions", NULL }, - handle_show_functions, "Shows registered dialplan functions", - show_functions_help }, - - { { "core", "show", "switches", NULL }, - handle_show_switches, "Show alternative switches", - show_switches_help }, - - { { "core", "show", "hints", NULL }, - handle_show_hints, "Show dialplan hints", - show_hints_help }, - - { { "core", "show", "globals", NULL }, - handle_show_globals, "Show global dialplan variables", - show_globals_help }, - - { { "core", "show" , "function", NULL }, - handle_show_function, "Describe a specific dialplan function", - show_function_help, complete_show_function }, - - { { "core", "show", "application", NULL }, - handle_show_application, "Describe a specific dialplan application", - show_application_help, complete_show_application }, - - { { "core", "set", "global", NULL }, - handle_set_global, "Set global dialplan variable", - set_global_help }, - - { { "dialplan", "show", NULL }, - handle_show_dialplan, "Show dialplan", - show_dialplan_help, complete_show_dialplan_context }, + NEW_CLI(handle_show_applications, "Shows registered dialplan applications"), + NEW_CLI(handle_show_functions, "Shows registered dialplan functions"), + NEW_CLI(handle_show_switches, "Show alternative switches"), + NEW_CLI(handle_show_hints, "Show dialplan hints"), + NEW_CLI(handle_show_globals, "Show global dialplan variables"), + NEW_CLI(handle_show_function, "Describe a specific dialplan function"), + NEW_CLI(handle_show_application, "Describe a specific dialplan application"), + NEW_CLI(handle_set_global, "Set global dialplan variable"), + NEW_CLI(handle_show_dialplan, "Show dialplan"), }; static void unreference_cached_app(struct ast_app *app) Index: main/dnsmgr.c =================================================================== --- main/dnsmgr.c (revision 82911) +++ main/dnsmgr.c (working copy) @@ -255,28 +255,48 @@ static int do_reload(int loading); -static int handle_cli_reload(int fd, int argc, char *argv[]) +static char *handle_cli_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 = "dnsmgr reload"; + e->usage = + "Usage: dnsmgr reload\n" + " Reloads the DNS manager configuration.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + if ( 2 < a->argc ) + return CLI_SHOWUSAGE; do_reload(0); - return 0; + return CLI_SUCCESS; } -static int handle_cli_refresh(int fd, int argc, char *argv[]) +static char *handle_cli_refresh(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { struct refresh_info info = { .entries = &entry_list, .verbose = 1, }; + switch ( cmd ) { + case CLI_INIT: + e->command = "dnsmgr refresh"; + e->usage = + "Usage: dnsmgr refresh [pattern]\n" + " Peforms an immediate refresh of the managed DNS entries.\n" + " Optional regular expression pattern is used to filter the entries to refresh.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + if ( 3 < a->argc ) + return CLI_SHOWUSAGE; - if (argc > 3) - return RESULT_SHOWUSAGE; - - if (argc == 3) { - if (regcomp(&info.filter, argv[2], REG_EXTENDED | REG_NOSUB)) - return RESULT_SHOWUSAGE; + if ( 3 == a->argc ) { + if ( regcomp(&info.filter, a->argv[2], REG_EXTENDED | REG_NOSUB) ) + return CLI_SHOWUSAGE; else info.regex_present = 1; } @@ -286,50 +306,42 @@ if (info.regex_present) regfree(&info.filter); - return 0; + return CLI_SUCCESS; } -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) { int count = 0; struct ast_dnsmgr_entry *entry; + switch ( cmd ) { + case CLI_INIT: + e->command = "dnsmgr status"; + e->usage = + "Usage: dnsmgr status\n" + " Displays the DNS manager status.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } - if (argc > 2) - return RESULT_SHOWUSAGE; + if ( 2 < a->argc ) + return CLI_SHOWUSAGE; - ast_cli(fd, "DNS Manager: %s\n", enabled ? "enabled" : "disabled"); - ast_cli(fd, "Refresh Interval: %d seconds\n", refresh_interval); + ast_cli(a->fd, "DNS Manager: %s\n", enabled ? "enabled" : "disabled"); + ast_cli(a->fd, "Refresh Interval: %d seconds\n", refresh_interval); AST_RWLIST_RDLOCK(&entry_list); AST_RWLIST_TRAVERSE(&entry_list, entry, list) count++; AST_RWLIST_UNLOCK(&entry_list); - ast_cli(fd, "Number of entries: %d\n", count); + ast_cli(a->fd, "Number of entries: %d\n", count); - return 0; + return CLI_SUCCESS; } -static struct ast_cli_entry cli_reload = { - { "dnsmgr", "reload", NULL }, - handle_cli_reload, "Reloads the DNS manager configuration", - "Usage: dnsmgr reload\n" - " Reloads the DNS manager configuration.\n" -}; +static struct ast_cli_entry cli_reload = NEW_CLI(handle_cli_reload, "Reloads the DNS manager configuration"); +static struct ast_cli_entry cli_refresh = NEW_CLI(handle_cli_refresh, "Performs an immediate refresh"); +static struct ast_cli_entry cli_status = NEW_CLI(handle_cli_status, "Display the DNS manager status"); -static struct ast_cli_entry cli_refresh = { - { "dnsmgr", "refresh", NULL }, - handle_cli_refresh, "Performs an immediate refresh", - "Usage: dnsmgr refresh [pattern]\n" - " Peforms an immediate refresh of the managed DNS entries.\n" - " Optional regular expression pattern is used to filter the entries to refresh.\n", -}; - -static struct ast_cli_entry cli_status = { - { "dnsmgr", "status", NULL }, - handle_cli_status, "Display the DNS manager status", - "Usage: dnsmgr status\n" - " Displays the DNS manager status.\n" -}; - int dnsmgr_init(void) { if (!(sched = sched_context_create())) { @@ -338,6 +350,7 @@ } ast_cli_register(&cli_reload); ast_cli_register(&cli_status); + ast_cli_register(&cli_refresh); return do_reload(1); } Index: res/res_jabber.c =================================================================== --- res/res_jabber.c (revision 82911) +++ res/res_jabber.c (working copy) @@ -87,11 +87,11 @@ static int aji_initialize(struct aji_client *client); static int aji_client_connect(void *data, ikspak *pak); static void aji_set_presence(struct aji_client *client, char *to, char *from, int level, char *desc); -static int aji_do_debug(int fd, int argc, char *argv[]); -static int aji_do_reload(int fd, int argc, char *argv[]); -static int aji_no_debug(int fd, int argc, char *argv[]); -static int aji_test(int fd, int argc, char *argv[]); -static int aji_show_clients(int fd, int argc, char *argv[]); +static char *aji_do_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a); +static char *aji_do_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a); +static char *aji_no_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a); +static char *aji_test(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a); +static char *aji_show_clients(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a); static int aji_create_client(char *label, struct ast_variable *var, int debug); static int aji_create_buddy(char *label, struct aji_client *client); static int aji_reload(int reload); @@ -113,43 +113,12 @@ static int aji_register_transport2(void *data, ikspak *pak); */ -static const char debug_usage[] = -"Usage: jabber debug\n" -" Enables dumping of Jabber packets for debugging purposes.\n"; - -static const char no_debug_usage[] = -"Usage: jabber debug off\n" -" Disables dumping of Jabber packets for debugging purposes.\n"; - -static const char reload_usage[] = -"Usage: jabber reload\n" -" Enables reloading of Jabber module.\n"; - -static const char test_usage[] = -"Usage: jabber test [client]\n" -" Sends test message for debugging purposes. A specific client\n" -" as configured in jabber.conf can be optionally specified.\n"; - static struct ast_cli_entry aji_cli[] = { - { { "jabber", "debug", NULL}, - aji_do_debug, "Enable Jabber debugging", - debug_usage }, - - { { "jabber", "reload", NULL}, - aji_do_reload, "Reload Jabber configuration", - reload_usage }, - - { { "jabber", "show", "connected", NULL}, - aji_show_clients, "Show state of clients and components", - debug_usage }, - - { { "jabber", "debug", "off", NULL}, - aji_no_debug, "Disable Jabber debug", - no_debug_usage }, - - { { "jabber", "test", NULL}, - aji_test, "Shows roster, but is generally used for mog's debugging.", - test_usage }, + NEW_CLI(aji_do_debug, "Enable jabber debugging"), + NEW_CLI(aji_no_debug, "Disable Jabber debug"), + NEW_CLI(aji_do_reload, "Reload Jabber configuration"), + NEW_CLI(aji_show_clients, "Show state of clients and components"), + NEW_CLI(aji_test, "Shows roster, but is generally used for mog's debugging."), }; static char *app_ajisend = "JabberSend"; @@ -2037,67 +2006,101 @@ } /*! - * \brief turnon console debugging. - * \param fd - * \param argc Integer. Number of args - * \param argv List of arguements - * \return RESULT_SUCCESS. + * \brief Turn on console debugging. + * \return CLI_SUCCESS. */ -static int aji_do_debug(int fd, int argc, char *argv[]) +static char *aji_do_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { + + switch (cmd) { + case CLI_INIT: + e->command = "jabber debug"; + e->usage = + "Usage: jabber debug\n" + " Enables dumping of Jabber packets for debugging purposes.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + ASTOBJ_CONTAINER_TRAVERSE(&clients, 1, { ASTOBJ_RDLOCK(iterator); iterator->debug = 1; ASTOBJ_UNLOCK(iterator); }); - ast_cli(fd, "Jabber Debugging Enabled.\n"); - return RESULT_SUCCESS; + ast_cli(a->fd, "Jabber Debugging Enabled.\n"); + return CLI_SUCCESS; } /*! - * \brief reload jabber module. - * \param fd - * \param argc no of args - * \param argv list of arguements - * \return RESULT_SUCCESS. + * \brief Reload jabber module. + * \return CLI_SUCCESS. */ -static int aji_do_reload(int fd, int argc, char *argv[]) +static char *aji_do_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { + switch (cmd) { + case CLI_INIT: + e->command = "jabber reload"; + e->usage = + "Usage: jabber reload\n" + " Reloads the Jabber module.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + aji_reload(1); - ast_cli(fd, "Jabber Reloaded.\n"); - return RESULT_SUCCESS; + ast_cli(a->fd, "Jabber Reloaded.\n"); + return CLI_SUCCESS; } /*! - * \brief turnoff console debugging. - * \param fd - * \param argc Integer. number of args - * \param argv list of arguements - * \return RESULT_SUCCESS. + * \brief Turn off console debugging. + * \return CLI_SUCCESS. */ -static int aji_no_debug(int fd, int argc, char *argv[]) +static char *aji_no_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { + switch (cmd) { + case CLI_INIT: + e->command = "jabber debug off"; + e->usage = + "Usage: jabber debug off\n" + " Disables dumping of Jabber packets for debugging purposes.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + ASTOBJ_CONTAINER_TRAVERSE(&clients, 1, { ASTOBJ_RDLOCK(iterator); iterator->debug = 0; ASTOBJ_UNLOCK(iterator); }); - ast_cli(fd, "Jabber Debugging Disabled.\n"); - return RESULT_SUCCESS; + ast_cli(a->fd, "Jabber Debugging Disabled.\n"); + return CLI_SUCCESS; } /*! - * \brief show client status. - * \param fd - * \param argc Integer. number of args - * \param argv list of arguements - * \return RESULT_SUCCESS. + * \brief Show client status. + * \return CLI_SUCCESS. */ -static int aji_show_clients(int fd, int argc, char *argv[]) +static char *aji_show_clients(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { char *status; int count = 0; - ast_cli(fd, "Jabber Users and their status:\n"); + + switch (cmd) { + case CLI_INIT: + e->command = "jabber show connected"; + e->usage = + "Usage: jabber show connected\n" + " Shows state of clients and components\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + ast_cli(a->fd, "Jabber Users and their status:\n"); ASTOBJ_CONTAINER_TRAVERSE(&clients, 1, { ASTOBJ_RDLOCK(iterator); count++; @@ -2114,36 +2117,45 @@ default: status = "Unknown"; } - ast_cli(fd, " User: %s - %s\n", iterator->user, status); + ast_cli(a->fd, " User: %s - %s\n", iterator->user, status); ASTOBJ_UNLOCK(iterator); }); - ast_cli(fd, "----\n"); - ast_cli(fd, " Number of users: %d\n", count); - return RESULT_SUCCESS; + ast_cli(a->fd, "----\n"); + ast_cli(a->fd, " Number of users: %d\n", count); + return CLI_SUCCESS; } /*! - * \brief send test message for debugging. - * \param fd - * \param argc Integer. number of args - * \param argv list of arguements - * \return RESULT_SUCCESS,RESULT_FAILURE. + * \brief Send test message for debugging. + * \return CLI_SUCCESS,CLI_FAILURE. */ -static int aji_test(int fd, int argc, char *argv[]) +static char *aji_test(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { struct aji_client *client; struct aji_resource *resource; const char *name = "asterisk"; struct aji_message *tmp; - if (argc > 3) - return RESULT_SHOWUSAGE; - else if (argc == 3) - name = argv[2]; + switch (cmd) { + case CLI_INIT: + e->command = "jabber test"; + e->usage = + "Usage: jabber test [client]\n" + " Sends test message for debugging purposes. A specific client\n" + " as configured in jabber.conf can be optionally specified.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + if (a->argc > 3) + return CLI_SHOWUSAGE; + else if (a->argc == 3) + name = a->argv[2]; + if (!(client = ASTOBJ_CONTAINER_FIND(&clients, name))) { - ast_cli(fd, "Unable to find client '%s'!\n", name); - return RESULT_FAILURE; + ast_cli(a->fd, "Unable to find client '%s'!\n", name); + return CLI_FAILURE; } /* XXX Does Matt really want everyone to use his personal address for tests? */ /* XXX yes he does */ @@ -2172,7 +2184,7 @@ AST_LIST_UNLOCK(&client->messages); ASTOBJ_UNREF(client, aji_client_destroy); - return RESULT_SUCCESS; + return CLI_SUCCESS; } /*! Index: res/res_agi.c =================================================================== --- res/res_agi.c (revision 82911) +++ res/res_agi.c (working copy) @@ -1300,30 +1300,33 @@ return RESULT_SUCCESS; } -static const char debug_usage[] = -"Usage: agi debug\n" -" Enables dumping of AGI transactions for debugging purposes\n"; - -static const char no_debug_usage[] = -"Usage: agi debug off\n" -" Disables dumping of AGI transactions for debugging purposes\n"; - -static int agi_do_debug(int fd, int argc, char *argv[]) +static char *handle_cli_agi_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { - if (argc != 2) - return RESULT_SHOWUSAGE; - agidebug = 1; - ast_cli(fd, "AGI Debugging Enabled\n"); - return RESULT_SUCCESS; -} + switch (cmd) { + case CLI_INIT: + e->command = "agi debug [off]"; + e->usage = + "Usage: agi debug [off]\n" + " Enables/disables dumping of AGI transactions for\n" + " debugging purposes.\n"; + return NULL; -static int agi_no_debug(int fd, int argc, char *argv[]) -{ - if (argc != 3) - return RESULT_SHOWUSAGE; - agidebug = 0; - ast_cli(fd, "AGI Debugging Disabled\n"); - return RESULT_SUCCESS; + case CLI_GENERATE: + return NULL; + } + if (a->argc < e->args - 1 || a->argc > e->args ) + return CLI_SHOWUSAGE; + if (a->argc == e->args - 1) { + agidebug = 1; + } else { + if (strncasecmp(a->argv[e->args - 1], "off", 3) == 0) { + agidebug = 0; + } else { + return CLI_SHOWUSAGE; + } + } + ast_cli(a->fd, "AGI Debugging %sabled\n", agidebug ? "En" : "Dis"); + return CLI_SUCCESS; } static int handle_noop(struct ast_channel *chan, AGI *agi, int arg, char *argv[]) @@ -1634,7 +1637,7 @@ static AST_RWLIST_HEAD_STATIC(agi_commands, agi_command); -static int help_workhorse(int fd, char *match[]) +static char *help_workhorse(int fd, char *match[]) { char fullcmd[80], matchstr[80]; struct agi_command *e; @@ -1656,7 +1659,8 @@ ast_cli(fd, "%5.5s %20.20s %s\n", e->dead ? "Yes" : "No" , fullcmd, e->summary); } AST_RWLIST_UNLOCK(&agi_commands); - return 0; + + return CLI_SUCCESS; } int ast_agi_register(struct ast_module *mod, agi_command *cmd) @@ -1951,31 +1955,42 @@ return returnstatus; } -static int handle_showagi(int fd, int argc, char *argv[]) +static char *handle_cli_agi_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { - struct agi_command *e; + struct agi_command *command; char fullcmd[80]; - if ((argc < 2)) - return RESULT_SHOWUSAGE; - - if (argc > 2) { - e = find_command(argv + 2, 1); - if (e) { - ast_cli(fd, e->usage); - ast_cli(fd, " Runs Dead : %s\n", e->dead ? "Yes" : "No"); + switch (cmd) { + case CLI_INIT: + e->command = "agi show"; + e->usage = + "Usage: agi show [topic]\n" + " When called with a topic as an argument, displays usage\n" + " information on the given command. If called without a\n" + " topic, it provides a list of AGI commands.\n"; + break; + case CLI_GENERATE: + return NULL; + } + if (a->argc < e->args) + return CLI_SHOWUSAGE; + if (a->argc > e->args) { + command = find_command(a->argv + e->args, 1); + if (command) { + ast_cli(a->fd, command->usage); + ast_cli(a->fd, " Runs Dead : %s\n", command->dead ? "Yes" : "No"); } else { - if (find_command(argv + 2, -1)) { - return help_workhorse(fd, argv + 2); + if (find_command(a->argv + e->args, -1)) { + return help_workhorse(a->fd, a->argv + e->args); } else { - ast_join(fullcmd, sizeof(fullcmd), argv + 2); - ast_cli(fd, "No such command '%s'.\n", fullcmd); + ast_join(fullcmd, sizeof(fullcmd), a->argv + e->args); + ast_cli(a->fd, "No such command '%s'.\n", fullcmd); } } } else { - return help_workhorse(fd, NULL); + return help_workhorse(a->fd, NULL); } - return RESULT_SUCCESS; + return CLI_SUCCESS; } /*! \brief Convert string to use HTML escaped characters @@ -2009,49 +2024,57 @@ return; } -static int handle_agidumphtml(int fd, int argc, char *argv[]) +static char *handle_cli_agi_dumphtml(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { - struct agi_command *e; + struct agi_command *command; char fullcmd[80]; FILE *htmlfile; - if ((argc < 3)) - return RESULT_SHOWUSAGE; + switch (cmd) { + case CLI_INIT: + e->command = "agi dumphtml"; + e->usage = + "Usage: agi dumphtml \n" + " Dumps the AGI command list in HTML format to the given\n" + " file.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + if (a->argc < e->args + 1) + return CLI_SHOWUSAGE; - if (!(htmlfile = fopen(argv[2], "wt"))) { - ast_cli(fd, "Could not create file '%s'\n", argv[2]); - return RESULT_SHOWUSAGE; + if (!(htmlfile = fopen(a->argv[2], "wt"))) { + ast_cli(a->fd, "Could not create file '%s'\n", a->argv[2]); + return CLI_SHOWUSAGE; } fprintf(htmlfile, "\n\nAGI Commands\n\n"); fprintf(htmlfile, "\n

AGI Commands

\n\n"); - - fprintf(htmlfile, "\n"); AST_RWLIST_RDLOCK(&agi_commands); - AST_RWLIST_TRAVERSE(&agi_commands, e, list) { + AST_RWLIST_TRAVERSE(&agi_commands, command, list) { char *stringp, *tempstr; - if (!e->cmda[0]) /* end ? */ + if (!command->cmda[0]) /* end ? */ break; /* Hide commands that start with '_' */ - if ((e->cmda[0])[0] == '_') + if ((command->cmda[0])[0] == '_') continue; - ast_join(fullcmd, sizeof(fullcmd), e->cmda); + ast_join(fullcmd, sizeof(fullcmd), command->cmda); fprintf(htmlfile, "
\n"); - fprintf(htmlfile, "\n", fullcmd,e->summary); + fprintf(htmlfile, "\n", fullcmd, command->summary); - stringp=e->usage; + stringp = command->usage; tempstr = strsep(&stringp, "\n"); fprintf(htmlfile, "\n"); - - fprintf(htmlfile, "
%s - %s
%s - %s
"); write_html_escaped(htmlfile, tempstr); fprintf(htmlfile, "
\n"); + while ((tempstr = strsep(&stringp, "\n")) != NULL) { write_html_escaped(htmlfile, tempstr); fprintf(htmlfile, "
\n"); @@ -2062,8 +2085,8 @@ AST_RWLIST_UNLOCK(&agi_commands); fprintf(htmlfile, "
\n\n\n"); fclose(htmlfile); - ast_cli(fd, "AGI HTML Commands Dumped to: %s\n", argv[2]); - return RESULT_SUCCESS; + ast_cli(a->fd, "AGI HTML commands dumped to: %s\n", a->argv[2]); + return CLI_SUCCESS; } static int agi_exec_full(struct ast_channel *chan, void *data, int enhanced, int dead) @@ -2170,38 +2193,14 @@ return agi_exec(chan, data); } -static char showagi_help[] = -"Usage: agi show [topic]\n" -" When called with a topic as an argument, displays usage\n" -" information on the given command. If called without a\n" -" topic, it provides a list of AGI commands.\n"; - - -static char dumpagihtml_help[] = -"Usage: agi dumphtml \n" -" Dumps the agi command list in html format to given filename\n"; - static struct ast_cli_entry cli_agi[] = { - { { "agi", "debug", NULL }, - agi_do_debug, "Enable AGI debugging", - debug_usage }, - - { { "agi", "debug", "off", NULL }, - agi_no_debug, "Disable AGI debugging", - no_debug_usage }, - - { { "agi", "show", NULL }, - handle_showagi, "List AGI commands or specific help", - showagi_help }, - - { { "agi", "dumphtml", NULL }, - handle_agidumphtml, "Dumps a list of agi commands in html format", - dumpagihtml_help }, + NEW_CLI(handle_cli_agi_debug, "Enable/Disable AGI debugging"), + NEW_CLI(handle_cli_agi_show, "List AGI commands or specific help"), + NEW_CLI(handle_cli_agi_dumphtml, "Dumps a list of AGI commands in HTML format") }; static int unload_module(void) { - ast_cli_unregister_multiple(cli_agi, sizeof(cli_agi) / sizeof(struct ast_cli_entry)); ast_agi_unregister_multiple(ast_module_info->self, commands, sizeof(commands) / sizeof(struct agi_command)); ast_unregister_application(eapp); Index: res/res_realtime.c =================================================================== --- res/res_realtime.c (revision 82911) +++ res/res_realtime.c (working copy) @@ -47,68 +47,78 @@ #include "asterisk/cli.h" -static int cli_realtime_load(int fd, int argc, char **argv) +static char *cli_realtime_load(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { char *header_format = "%30s %-30s\n"; struct ast_variable *var=NULL; - if(argc<5) { - ast_cli(fd, "You must supply a family name, a column to match on, and a value to match to.\n"); - return RESULT_FAILURE; + switch (cmd) { + case CLI_INIT: + e->command = "realtime load"; + e->usage = + "Usage: realtime load \n" + " Prints out a list of variables using the RealTime driver.\n" + " You must supply a family name, a column to match on, and a value to match to.\n"; + return NULL; + case CLI_GENERATE: + return NULL; } - var = ast_load_realtime_all(argv[2], argv[3], argv[4], NULL); - if(var) { - ast_cli(fd, header_format, "Column Name", "Column Value"); - ast_cli(fd, header_format, "--------------------", "--------------------"); - while(var) { - ast_cli(fd, header_format, var->name, var->value); + if (a->argc < 5) + return CLI_SHOWUSAGE; + + var = ast_load_realtime_all(a->argv[2], a->argv[3], a->argv[4], NULL); + + if (var) { + ast_cli(a->fd, header_format, "Column Name", "Column Value"); + ast_cli(a->fd, header_format, "--------------------", "--------------------"); + while (var) { + ast_cli(a->fd, header_format, var->name, var->value); var = var->next; } } else { - ast_cli(fd, "No rows found matching search criteria.\n"); + ast_cli(a->fd, "No rows found matching search criteria.\n"); } - return RESULT_SUCCESS; + return CLI_SUCCESS; } -static int cli_realtime_update(int fd, int argc, char **argv) { +static char *cli_realtime_update(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { int res = 0; - if(argc<7) { - ast_cli(fd, "You must supply a family name, a column to update on, a new value, column to match, and value to to match.\n"); - ast_cli(fd, "Ex: realtime update sipfriends name bobsphone port 4343\n will execute SQL as UPDATE sipfriends SET port = 4343 WHERE name = bobsphone\n"); - return RESULT_FAILURE; + switch (cmd) { + case CLI_INIT: + e->command = "realtime update"; + e->usage = + "Usage: realtime update \n" + " Update a single variable using the RealTime driver.\n" + " You must supply a family name, a column to update on, a new value, column to match, and value to match.\n" + " Ex: realtime update sipfriends name bobsphone port 4343\n" + " will execute SQL as UPDATE sipfriends SET port = 4343 WHERE name = bobsphone\n"; + return NULL; + case CLI_GENERATE: + return NULL; } - res = ast_update_realtime(argv[2], argv[3], argv[4], argv[5], argv[6], NULL); + if (a->argc < 7) + return CLI_SHOWUSAGE; + + res = ast_update_realtime(a->argv[2], a->argv[3], a->argv[4], a->argv[5], a->argv[6], NULL); + if(res < 0) { - ast_cli(fd, "Failed to update. Check the debug log for possible SQL related entries.\n"); - return RESULT_SUCCESS; + ast_cli(a->fd, "Failed to update. Check the debug log for possible SQL related entries.\n"); + return CLI_FAILURE; } - ast_cli(fd, "Updated %d RealTime record%s.\n", res, ESS(res)); + ast_cli(a->fd, "Updated %d RealTime record%s.\n", res, ESS(res)); - return RESULT_SUCCESS; + return CLI_SUCCESS; } -static const char cli_realtime_load_usage[] = -"Usage: realtime load \n" -" Prints out a list of variables using the RealTime driver.\n"; - -static const char cli_realtime_update_usage[] = -"Usage: realtime update \n" -" Update a single variable using the RealTime driver.\n"; - static struct ast_cli_entry cli_realtime[] = { - { { "realtime", "load", NULL, NULL }, - cli_realtime_load, "Used to print out RealTime variables.", - cli_realtime_load_usage, NULL }, - - { { "realtime", "update", NULL, NULL }, - cli_realtime_update, "Used to update RealTime variables.", - cli_realtime_update_usage, NULL }, + NEW_CLI(cli_realtime_load, "Used to print out RealTime variables."), + NEW_CLI(cli_realtime_update, "Used to update RealTime variables."), }; static int unload_module(void) Index: res/res_odbc.c =================================================================== --- res/res_odbc.c (revision 82911) +++ res/res_odbc.c (working copy) @@ -333,47 +333,70 @@ return res; } -static int odbc_show_command(int fd, int argc, char **argv) +static char *handle_cli_odbc_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { struct odbc_class *class; struct odbc_obj *current; + int length = 0; + int which = 0; + char *ret = NULL; + switch (cmd) { + case CLI_INIT: + e->command = "odbc show"; + e->usage = + "Usage: odbc show [class]\n" + " List settings of a particular ODBC class or,\n" + " if not specified, all classes.\n"; + return NULL; + case CLI_GENERATE: + if (a->pos != 2) + return NULL; + length = strlen(a->word); + AST_LIST_LOCK(&odbc_list); + AST_LIST_TRAVERSE(&odbc_list, class, list) { + if (!strncasecmp(a->word, class->name, length) && ++which > a->n) { + ret = ast_strdup(class->name); + break; + } + } + if (!ret && !strncasecmp(a->word, "all", length) && ++which > a->n) { + ret = ast_strdup("all"); + } + AST_LIST_UNLOCK(&odbc_list); + return ret; + } + + ast_cli(a->fd, "\nODBC DSN Settings\n"); + ast_cli(a->fd, "-----------------\n\n"); AST_LIST_LOCK(&odbc_list); AST_LIST_TRAVERSE(&odbc_list, class, list) { - if ((argc == 2) || (argc == 3 && !strcmp(argv[2], "all")) || (!strcmp(argv[2], class->name))) { + if ((a->argc == 2) || (a->argc == 3 && !strcmp(a->argv[2], "all")) || (!strcmp(a->argv[2], class->name))) { int count = 0; - ast_cli(fd, "Name: %s\nDSN: %s\n", class->name, class->dsn); + ast_cli(a->fd, " Name: %s\n DSN: %s\n", class->name, class->dsn); if (class->haspool) { - ast_cli(fd, "Pooled: yes\nLimit: %d\nConnections in use: %d\n", class->limit, class->count); + ast_cli(a->fd, " Pooled: Yes\n Limit: %d\n Connections in use: %d\n", class->limit, class->count); AST_LIST_TRAVERSE(&(class->odbc_obj), current, list) { - ast_cli(fd, " Connection %d: %s\n", ++count, current->up && ast_odbc_sanity_check(current) ? "connected" : "disconnected"); + ast_cli(a->fd, " - Connection %d: %s\n", ++count, current->up && ast_odbc_sanity_check(current) ? "Connected" : "Disconnected"); } } else { /* Should only ever be one of these */ AST_LIST_TRAVERSE(&(class->odbc_obj), current, list) { - ast_cli(fd, "Pooled: no\nConnected: %s\n", current->up && ast_odbc_sanity_check(current) ? "yes" : "no"); + ast_cli(a->fd, " Pooled: No\n Connected: %s\n", current->up && ast_odbc_sanity_check(current) ? "Yes" : "No"); } } - - ast_cli(fd, "\n"); + ast_cli(a->fd, "\n"); } } AST_LIST_UNLOCK(&odbc_list); - return 0; + return CLI_SUCCESS; } -static const char show_usage[] = -"Usage: odbc show []\n" -" List settings of a particular ODBC class.\n" -" or, if not specified, all classes.\n"; - static struct ast_cli_entry cli_odbc[] = { - { { "odbc", "show", NULL }, - odbc_show_command, "List ODBC DSN(s)", - show_usage }, + NEW_CLI(handle_cli_odbc_show, "List ODBC DSN(s)") }; static int odbc_register_class(struct odbc_class *class, int connect) Index: res/res_features.c =================================================================== --- res/res_features.c (revision 82911) +++ res/res_features.c (working copy) @@ -2364,41 +2364,61 @@ return res; } -static int handle_showfeatures(int fd, int argc, char *argv[]) -{ +/*! + * \brief CLI command to list configured features + * \param e + * \param cmd + * \param a + * + * \retval CLI_SUCCESS on success. + * \retval NULL when tab completion is used. + */ +static char *handle_feature_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { int i; struct ast_call_feature *feature; char format[] = "%-25s %-7s %-7s\n"; - ast_cli(fd, format, "Builtin Feature", "Default", "Current"); - ast_cli(fd, format, "---------------", "-------", "-------"); + switch (cmd) { + + case CLI_INIT: + e->command = "features show"; + e->usage = + "Usage: features show\n" + " Lists configured features\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } - ast_cli(fd, format, "Pickup", "*8", ast_pickup_ext()); /* default hardcoded above, so we'll hardcode it here */ + ast_cli(a->fd, format, "Builtin Feature", "Default", "Current"); + ast_cli(a->fd, format, "---------------", "-------", "-------"); + ast_cli(a->fd, format, "Pickup", "*8", ast_pickup_ext()); /* default hardcoded above, so we'll hardcode it here */ + ast_rwlock_rdlock(&features_lock); for (i = 0; i < FEATURES_COUNT; i++) - ast_cli(fd, format, builtin_features[i].fname, builtin_features[i].default_exten, builtin_features[i].exten); + ast_cli(a->fd, format, builtin_features[i].fname, builtin_features[i].default_exten, builtin_features[i].exten); ast_rwlock_unlock(&features_lock); - ast_cli(fd, "\n"); - ast_cli(fd, format, "Dynamic Feature", "Default", "Current"); - ast_cli(fd, format, "---------------", "-------", "-------"); + ast_cli(a->fd, "\n"); + ast_cli(a->fd, format, "Dynamic Feature", "Default", "Current"); + ast_cli(a->fd, format, "---------------", "-------", "-------"); if (AST_LIST_EMPTY(&feature_list)) - ast_cli(fd, "(none)\n"); + ast_cli(a->fd, "(none)\n"); else { AST_LIST_LOCK(&feature_list); AST_LIST_TRAVERSE(&feature_list, feature, feature_entry) - ast_cli(fd, format, feature->sname, "no def", feature->exten); + ast_cli(a->fd, format, feature->sname, "no def", feature->exten); AST_LIST_UNLOCK(&feature_list); } - ast_cli(fd, "\nCall parking\n"); - ast_cli(fd, "------------\n"); - ast_cli(fd,"%-20s: %s\n", "Parking extension", parking_ext); - ast_cli(fd,"%-20s: %s\n", "Parking context", parking_con); - ast_cli(fd,"%-20s: %d-%d\n", "Parked call extensions", parking_start, parking_stop); - ast_cli(fd,"\n"); - - return RESULT_SUCCESS; + ast_cli(a->fd, "\nCall parking\n"); + ast_cli(a->fd, "------------\n"); + ast_cli(a->fd,"%-20s: %s\n", "Parking extension", parking_ext); + ast_cli(a->fd,"%-20s: %s\n", "Parking context", parking_con); + ast_cli(a->fd,"%-20s: %d-%d\n", "Parked call extensions", parking_start, parking_stop); + ast_cli(a->fd,"\n"); + + return CLI_SUCCESS; } static char mandescr_bridge[] = @@ -2542,10 +2562,6 @@ return 0; } -static char showfeatures_help[] = -"Usage: feature list\n" -" Lists currently configured features.\n"; - /*! * \brief CLI command to list parked calls * \param e @@ -2605,10 +2621,7 @@ static struct ast_cli_entry cli_show_parkedcalls_deprecated = NEW_CLI(handle_parkedcalls_deprecated, "List currently parked calls."); static struct ast_cli_entry cli_features[] = { - { { "feature", "show", NULL }, - handle_showfeatures, "Lists configured features", - showfeatures_help }, - + NEW_CLI(handle_feature_show, "Lists configured features"), NEW_CLI(handle_parkedcalls, "List currently parked calls", .deprecate_cmd = &cli_show_parkedcalls_deprecated), }; Index: res/res_musiconhold.c =================================================================== --- res/res_musiconhold.c (revision 82911) +++ res/res_musiconhold.c (working copy) @@ -854,10 +854,8 @@ if (!S_ISREG(statbuf.st_mode)) continue; - if ((ext = strrchr(filepath, '.'))) { + if ((ext = strrchr(filepath, '.'))) *ext = '\0'; - ext++; - } /* if the file is present in multiple formats, ensure we only put it into the list once */ for (i = 0; i < class->total_files; i++) @@ -1147,66 +1145,102 @@ AST_RWLIST_UNLOCK(&mohclasses); } -static int moh_cli(int fd, int argc, char *argv[]) +static char *handle_cli_moh_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { + switch (cmd) { + case CLI_INIT: + e->command = "moh reload"; + e->usage = + "Usage: moh reload\n" + " Reloads the MusicOnHold module.\n" + " Alias for 'module reload res_musiconhold.so'\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + if (a->argc != e->args) + return CLI_SHOWUSAGE; + reload(); - return 0; + return CLI_SUCCESS; } -static int cli_files_show(int fd, int argc, char *argv[]) +static char *handle_cli_moh_show_files(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { int i; struct mohclass *class; + switch (cmd) { + case CLI_INIT: + e->command = "moh show files"; + e->usage = + "Usage: moh show files\n" + " Lists all loaded file-based MusicOnHold classes and their\n" + " files.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + if (a->argc != e->args) + return CLI_SHOWUSAGE; + AST_RWLIST_RDLOCK(&mohclasses); AST_RWLIST_TRAVERSE(&mohclasses, class, list) { if (!class->total_files) continue; - ast_cli(fd, "Class: %s\n", class->name); + ast_cli(a->fd, "Class: %s\n", class->name); for (i = 0; i < class->total_files; i++) - ast_cli(fd, "\tFile: %s\n", class->filearray[i]); + ast_cli(a->fd, "\tFile: %s\n", class->filearray[i]); } AST_RWLIST_UNLOCK(&mohclasses); - return 0; + return CLI_SUCCESS; } -static int moh_classes_show(int fd, int argc, char *argv[]) +static char *handle_cli_moh_show_classes(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { struct mohclass *class; + switch (cmd) { + case CLI_INIT: + e->command = "moh show classes"; + e->usage = + "Usage: moh show classes\n" + " Lists all MusicOnHold classes.\n"; + return NULL; + case CLI_GENERATE: + return NULL; + } + + if (a->argc != e->args) + return CLI_SHOWUSAGE; + AST_RWLIST_RDLOCK(&mohclasses); AST_RWLIST_TRAVERSE(&mohclasses, class, list) { - ast_cli(fd, "Class: %s\n", class->name); - ast_cli(fd, "\tMode: %s\n", S_OR(class->mode, "")); - ast_cli(fd, "\tDirectory: %s\n", S_OR(class->dir, "")); - ast_cli(fd, "\tUse Count: %d\n", class->inuse); + ast_cli(a->fd, "Class: %s\n", class->name); + ast_cli(a->fd, "\tMode: %s\n", S_OR(class->mode, "")); + ast_cli(a->fd, "\tDirectory: %s\n", S_OR(class->dir, "")); + ast_cli(a->fd, "\tUse Count: %d\n", class->inuse); if (class->digit) - ast_cli(fd, "\tDigit: %c\n", class->digit); + ast_cli(a->fd, "\tDigit: %c\n", class->digit); if (ast_test_flag(class, MOH_CUSTOM)) - ast_cli(fd, "\tApplication: %s\n", S_OR(class->args, "")); + ast_cli(a->fd, "\tApplication: %s\n", S_OR(class->args, "")); if (strcasecmp(class->mode, "files")) - ast_cli(fd, "\tFormat: %s\n", ast_getformatname(class->format)); + ast_cli(a->fd, "\tFormat: %s\n", ast_getformatname(class->format)); } AST_RWLIST_UNLOCK(&mohclasses); - return 0; + return CLI_SUCCESS; } static struct ast_cli_entry cli_moh[] = { - { { "moh", "reload"}, - moh_cli, "Music On Hold", - "Music On Hold" }, - - { { "moh", "show", "classes"}, - moh_classes_show, "List MOH classes", - "Lists all MOH classes" }, - - { { "moh", "show", "files"}, - cli_files_show, "List MOH file-based classes", - "Lists all loaded file-based MOH classes and their files" }, + NEW_CLI(handle_cli_moh_reload, "Reload MusicOnHold"), + NEW_CLI(handle_cli_moh_show_classes, "List MusicOnHold classes"), + NEW_CLI(handle_cli_moh_show_files, "List MusicOnHold file-based classes") }; static int init_classes(int reload)