34 #include "asterisk/_private.h"
36 #include <sys/signal.h>
51 #include "editline/readline/readline.h"
103 #define AST_CLI_INITLEN 256
125 struct module_level *ml;
126 unsigned int res = 0;
130 if (!strcasecmp(ml->module, module)) {
142 struct module_level *ml;
143 unsigned int res = 0;
147 if (!strcasecmp(ml->module, module)) {
172 struct usergroup_cli_perm *user_perm;
173 struct cli_perm *perm;
185 if (gid < 0 && uid < 0) {
191 if (user_perm->
gid != gid && user_perm->
uid != uid) {
195 if (strcasecmp(perm->
command,
"all") && strncasecmp(perm->
command, command, strlen(perm->
command))) {
197 ispattern = !regcomp(®exbuf, perm->
command, REG_EXTENDED | REG_NOSUB | REG_ICASE);
198 if (ispattern && regexec(®exbuf, command, 0, NULL, 0)) {
207 if (user_perm->
uid == uid) {
230 char filename[PATH_MAX];
237 c = d = filename_completion_function(filename, state);
239 if (c && word[0] !=
'/')
256 "Usage: module load <module name>\n"
257 " Loads the specified module into Asterisk.\n";
283 "Usage: module reload [module ...]\n"
284 " Reloads configuration files for all listed modules which support\n"
285 " reloading, or for all supported modules if none are listed.\n";
295 for (x = e->
args; x < a->argc; x++) {
303 ast_cli(a->
fd,
"Module '%s' does not support reload\n", a->
argv[x]);
316 "Usage: core reload\n"
317 " Execute a global reload.\n";
338 struct module_level *ml;
342 if (!strcasecmp(ml->module, module))
349 static char *
complete_number(
const char *partial,
unsigned int min,
unsigned int max,
int n)
352 unsigned int prospective[2];
353 unsigned int part = strtoul(partial, NULL, 10);
356 if (part < min || part > max) {
360 for (i = 0; i < 21; i++) {
362 prospective[0] = prospective[1] = part;
366 prospective[0] = prospective[1] = part * 10 + (i - 1);
368 prospective[0] = (part * 10 + (i - 11)) * 10;
369 prospective[1] = prospective[0] + 9;
371 if (i < 11 && (prospective[0] < min || prospective[0] > max)) {
373 }
else if (prospective[1] < min || prospective[0] > max) {
379 snprintf(next,
sizeof(next),
"%u", prospective[0]);
381 snprintf(next,
sizeof(next),
"%u...", prospective[0] / 10);
393 unsigned int is_debug;
397 const char *
const *argv = a->
argv;
398 const char *argv3 = a->
argv ?
S_OR(a->
argv[3],
"") :
"";
401 struct module_level_list *mll;
402 struct module_level *ml;
406 e->
command =
"core set {debug|verbose}";
408 #if !defined(LOW_MEMORY)
409 "Usage: core set {debug|verbose} [atleast] <level> [module]\n"
411 "Usage: core set {debug|verbose} [atleast] <level>\n"
413 " core set {debug|verbose} off\n"
414 #if !defined(LOW_MEMORY)
415 " Sets level of debug or verbose messages to be displayed or\n"
416 " sets a module name to display debug messages from.\n"
418 " Sets level of debug or verbose messages to be displayed.\n"
420 " 0 or off means no messages should be displayed.\n"
421 " Equivalent to -d[d[...]] or -v[v[v...]] on startup\n";
425 if (a->
pos == 3 || (a->
pos == 4 && !strcasecmp(a->
argv[3],
"atleast"))) {
426 const char *pos = a->
pos == 3 ? argv3 :
S_OR(a->
argv[4],
"");
427 int numbermatch = (
ast_strlen_zero(pos) || strchr(
"123456789", pos[0])) ? 0 : 21;
428 if (a->
n < 21 && numbermatch == 0) {
430 }
else if (pos[0] ==
'0') {
436 }
else if (a->
n == (21 - numbermatch)) {
437 if (a->
pos == 3 && !strncasecmp(argv3,
"off", strlen(argv3))) {
439 }
else if (a->
pos == 3 && !strncasecmp(argv3,
"atleast", strlen(argv3))) {
445 #if !defined(LOW_MEMORY)
446 }
else if (a->
pos == 4 || (a->
pos == 5 && !strcasecmp(argv3,
"atleast"))) {
458 if (!strcasecmp(argv[e->
args - 1],
"debug")) {
469 if (argc == e->
args + 1 && !strcasecmp(argv[e->
args],
"off")) {
483 if (!strcasecmp(argv[e->
args],
"atleast"))
485 if (argc != e->
args + atleast + 1 && argc != e->
args + atleast + 2)
487 if (sscanf(argv[e->
args + atleast],
"%30d", &newlevel) != 1)
489 if (argc == e->
args + atleast + 2) {
493 if ((strlen(mod) > 3) && !strcasecmp(mod + strlen(mod) - 3,
".so")) {
494 mod[strlen(mod) - 3] =
'\0';
512 ast_cli(fd,
"%s was %u and has been set to 0 for '%s'\n", what, ml->
level, mod);
518 if ((atleast && newlevel < ml->level) || ml->
level == newlevel) {
519 ast_cli(fd,
"%s is %u for '%s'\n", what, ml->
level, mod);
524 ml->
level = newlevel;
526 ml =
ast_calloc(1,
sizeof(*ml) + strlen(mod) + 1);
532 ml->
level = newlevel;
533 strcpy(ml->module, mod);
541 ast_cli(fd,
"%s was %d and has been set to %u for '%s'\n", what, oldval, ml->
level, ml->module);
544 }
else if (!newlevel) {
557 if (!atleast || newlevel > *dst)
559 if (oldval > 0 && *dst == 0)
560 ast_cli(fd,
"%s is now OFF\n", what);
563 ast_cli(fd,
"%s is at least %d\n", what, *dst);
565 ast_cli(fd,
"%s was %d and is now %d\n", what, oldval, *dst);
577 "Usage: logger mute\n"
578 " Disables logging output to the current console, making it possible to\n"
579 " gather information without being disturbed by scrolling lines.\n";
588 if (a->
argc == 3 && !strcasecmp(a->
argv[2],
"silent"))
607 "Usage: module unload [-f|-h] <module_1> [<module_2> ... ]\n"
608 " Unloads the specified module from Asterisk. The -f\n"
609 " option causes the module to be unloaded even if it is\n"
610 " in use (may cause a crash) and the -h module causes the\n"
611 " module to be unloaded even if the module says it cannot, \n"
612 " which almost always will cause a crash.\n";
625 else if (s[1] ==
'h')
634 for (; x < a->
argc; x++) {
636 ast_cli(a->
fd,
"Unable to unload resource %s\n", a->
argv[x]);
645 #define MODLIST_FORMAT "%-30s %-40.40s %-10d\n"
646 #define MODLIST_FORMAT2 "%-30s %-40.40s %-10s\n"
667 #define MINUTE (SECOND*60)
668 #define HOUR (MINUTE*60)
669 #define DAY (HOUR*24)
671 #define YEAR (DAY*365)
672 #define NEEDCOMMA(x) ((x)? ",": "")
673 if (timeval.tv_sec < 0)
677 ast_cli(fd,
"%s: %lu\n", prefix, (u_long)timeval.tv_sec);
681 if (timeval.tv_sec >
YEAR) {
682 x = (timeval.tv_sec /
YEAR);
683 timeval.tv_sec -= (x *
YEAR);
686 if (timeval.tv_sec >
WEEK) {
687 x = (timeval.tv_sec /
WEEK);
688 timeval.tv_sec -= (x *
WEEK);
691 if (timeval.tv_sec >
DAY) {
692 x = (timeval.tv_sec /
DAY);
693 timeval.tv_sec -= (x *
DAY);
696 if (timeval.tv_sec >
HOUR) {
697 x = (timeval.tv_sec /
HOUR);
698 timeval.tv_sec -= (x *
HOUR);
701 if (timeval.tv_sec >
MINUTE) {
702 x = (timeval.tv_sec /
MINUTE);
703 timeval.tv_sec -= (x *
MINUTE);
728 e->
command =
"core show uptime [seconds]";
730 "Usage: core show uptime [seconds]\n"
731 " Shows Asterisk uptime information.\n"
732 " The seconds word returns the uptime in seconds only.\n";
758 e->
command =
"module show [like]";
760 "Usage: module show [like keyword]\n"
761 " Shows Asterisk modules currently in use, and usage statistics.\n";
775 else if (a->
argc == e->
args + 1 && !strcasecmp(a->
argv[e->
args-1],
"like") )
781 climodentryfd = a->
fd;
788 #undef MODLIST_FORMAT
789 #undef MODLIST_FORMAT2
794 int showuptime, printsec;
798 e->
command =
"core show calls [uptime]";
800 "Usage: core show calls [uptime] [seconds]\n"
801 " Lists number of currently active calls and total number of calls\n"
802 " processed through PBX since last restart. If 'uptime' is specified\n"
803 " the system uptime is also displayed. If 'seconds' is specified in\n"
804 " addition to 'uptime', the system uptime is displayed in seconds.\n";
830 ast_cli(a->
fd,
"%d of %d max active call%s (%5.2f%% of capacity)\n",
848 #define FORMAT_STRING "%-20.20s %-20.20s %-7.7s %-30.30s\n"
849 #define FORMAT_STRING2 "%-20.20s %-20.20s %-7.7s %-30.30s\n"
850 #define CONCISE_FORMAT_STRING "%s!%s!%s!%d!%s!%s!%s!%s!%s!%s!%d!%s!%s!%s\n"
851 #define VERBOSE_FORMAT_STRING "%-20.20s %-20.20s %-16.16s %4d %-7.7s %-12.12s %-25.25s %-15.15s %8.8s %-11.11s %-11.11s %-20.20s\n"
852 #define VERBOSE_FORMAT_STRING2 "%-20.20s %-20.20s %-16.16s %-4.4s %-7.7s %-12.12s %-25.25s %-15.15s %8.8s %-11.11s %-11.11s %-20.20s\n"
855 int numchans = 0, concise = 0, verbose = 0, count = 0;
860 e->
command =
"core show channels [concise|verbose|count]";
862 "Usage: core show channels [concise|verbose|count]\n"
863 " Lists currently defined channels and some information about them. If\n"
864 " 'concise' is specified, the format is abridged and in a more easily\n"
865 " machine parsable format. If 'verbose' is specified, the output includes\n"
866 " more and longer fields. If 'count' is specified only the channel and call\n"
867 " count is output.\n"
868 " The 'concise' option is deprecated and will be removed from future versions\n"
877 if (!strcasecmp(a->
argv[e->
args-1],
"concise"))
879 else if (!strcasecmp(a->
argv[e->
args-1],
"verbose"))
881 else if (!strcasecmp(a->
argv[e->
args-1],
"count"))
889 if (!concise && !verbose)
893 "CallerID",
"Duration",
"Accountcode",
"PeerAccount",
"BridgedTo");
902 char durbuf[10] =
"-";
909 if ((concise || verbose) && c->cdr && !
ast_tvzero(c->cdr->start)) {
912 int durh = duration / 3600;
913 int durm = (duration % 3600) / 60;
914 int durs = duration % 60;
915 snprintf(durbuf,
sizeof(durbuf),
"%02d:%02d:%02d", durh, durm, durs);
917 snprintf(durbuf,
sizeof(durbuf),
"%d", duration);
922 c->appl ? c->appl :
"(None)",
924 S_COR(c->caller.id.number.valid, c->caller.id.number.str,
""),
925 S_OR(c->accountcode,
""),
926 S_OR(c->peeraccount,
""),
929 bc ? bc->
name :
"(None)",
931 }
else if (verbose) {
933 c->appl ? c->appl :
"(None)",
934 c->data ?
S_OR(c->data,
"(Empty)" ):
"(None)",
935 S_COR(c->caller.id.number.valid, c->caller.id.number.str,
""),
937 S_OR(c->accountcode,
""),
938 S_OR(c->peeraccount,
""),
939 bc ? bc->
name :
"(None)");
941 char locbuf[40] =
"(None)";
942 char appdata[40] =
"(None)";
945 snprintf(locbuf,
sizeof(locbuf),
"%s@%s:%d", c->exten, c->context, c->priority);
947 snprintf(appdata,
sizeof(appdata),
"%s(%s)", c->appl,
S_OR(c->data,
""));
960 ast_cli(a->
fd,
"%d active channel%s\n", numchans,
ESS(numchans));
962 ast_cli(a->
fd,
"%d of %d max active call%s (%5.2f%% of capacity)\n",
974 #undef FORMAT_STRING2
975 #undef CONCISE_FORMAT_STRING
976 #undef VERBOSE_FORMAT_STRING
977 #undef VERBOSE_FORMAT_STRING2
986 e->
command =
"channel request hangup";
988 "Usage: channel request hangup <channel>|<all>\n"
989 " Request that a channel be hung up. The hangup takes effect\n"
990 " the next time the driver reads or writes from the channel.\n"
991 " If 'all' is specified instead of a channel name, all channels\n"
992 " will see the hangup request.\n";
1002 if (!strcasecmp(a->
argv[3],
"all")) {
1009 ast_cli(a->
fd,
"Requested Hangup on channel '%s'\n", c->name);
1016 ast_cli(a->
fd,
"Requested Hangup on channel '%s'\n", c->
name);
1030 struct usergroup_cli_perm *cp;
1031 struct cli_perm *perm;
1032 struct passwd *pw = NULL;
1033 struct group *gr = NULL;
1037 e->
command =
"cli show permissions";
1039 "Usage: cli show permissions\n"
1040 " Shows CLI configured permissions.\n";
1049 pw = getpwuid(cp->
uid);
1051 ast_cli(a->
fd,
"user: %s [uid=%d]\n", pw->pw_name, cp->
uid);
1054 gr = getgrgid(cp->
gid);
1056 ast_cli(a->
fd,
"group: %s [gid=%d]\n", gr->gr_name, cp->
gid);
1077 e->
command =
"cli reload permissions";
1079 "Usage: cli reload permissions\n"
1080 " Reload the 'cli_permissions.conf' file.\n";
1094 struct passwd *pw = NULL;
1096 int gid = -1, uid = -1;
1104 e->
command =
"cli check permissions";
1106 "Usage: cli check permissions {<username>|@<groupname>|<username>@<groupname>} [<command>]\n"
1107 " Check permissions config for a user@group or list the allowed commands for the specified user.\n"
1108 " The username or the groupname may be omitted.\n";
1122 group = strchr(tmp,
'@');
1124 gr = getgrnam(&group[1]);
1126 ast_cli(a->
fd,
"Unknown group '%s'\n", &group[1]);
1134 ast_cli(a->
fd,
"You didn't supply a username\n");
1136 ast_cli(a->
fd,
"Unknown user '%s'\n", tmp);
1154 ast_cli(a->
fd,
"You are not allowed to run any command on Asterisk\n");
1158 ast_cli(a->
fd,
"%s '%s%s%s' is %s to run command: '%s'\n", uid >= 0 ?
"User" :
"Group", tmp,
1159 group && uid >= 0 ?
"@" :
"",
1160 group ? &group[1] :
"",
1179 e->
command =
"_command matchesarray";
1181 "Usage: _command matchesarray \"<line>\" text \n"
1182 " This function is used internally to help with command completion and should.\n"
1183 " never be called by the user directly.\n";
1196 for (x=0; matches[x]; x++) {
1197 matchlen = strlen(matches[x]) + 1;
1198 if (len + matchlen >= buflen) {
1199 buflen += matchlen * 3;
1206 len += sprintf( buf + len,
"%s ", matches[x]);
1230 e->
command =
"_command nummatches";
1232 "Usage: _command nummatches \"<line>\" text \n"
1233 " This function is used internally to help with command completion and should.\n"
1234 " never be called by the user directly.\n";
1255 e->
command =
"_command complete";
1257 "Usage: _command complete \"<line>\" text state\n"
1258 " This function is used internally to help with command completion and should.\n"
1259 " never be called by the user directly.\n";
1295 ast_cli(args->
fd,
"Debugging %s on channel %s\n", args->
is_off ?
"disabled" :
"enabled",
1313 e->
command =
"core set debug channel";
1315 "Usage: core set debug channel <all|channel> [off]\n"
1316 " Enables/disables debugging on all or on a specific channel.\n";
1328 }
else if (a->
argc == e->
args + 2) {
1330 if (!strcasecmp(a->
argv[e->
args + 1],
"off"))
1334 }
else if (a->
argc != e->
args + 1) {
1338 if (!strcasecmp(
"all", a->
argv[e->
args])) {
1356 ast_cli(a->
fd,
"Debugging on new channels is %s\n", args.
is_off ?
"disabled" :
"enabled");
1367 e->
command =
"no debug channel";
1393 char nf[256], wf[256], rf[256];
1398 long elapsed_seconds=0;
1399 int hour=0, min=0, sec=0;
1400 #ifdef CHANNEL_TRACE
1406 e->
command =
"core show channel";
1408 "Usage: core show channel <channel>\n"
1409 " Shows lots of information about the specified channel.\n";
1438 elapsed_seconds = now.tv_sec - c->
cdr->
start.tv_sec;
1439 hour = elapsed_seconds / 3600;
1440 min = (elapsed_seconds % 3600) / 60;
1441 sec = elapsed_seconds % 60;
1442 snprintf(cdrtime,
sizeof(cdrtime),
"%dh%dm%ds", hour, min, sec);
1444 strcpy(cdrtime,
"N/A");
1454 " Caller ID Name: %s\n"
1455 "Connected Line ID: %s\n"
1456 "Connected Line ID Name: %s\n"
1457 " DNID Digits: %s\n"
1461 " NativeFormats: %s\n"
1462 " WriteFormat: %s\n"
1464 " WriteTranscode: %s %s\n"
1465 " ReadTranscode: %s %s\n"
1466 "1st File Descriptor: %d\n"
1467 " Frames in: %u%s\n"
1468 " Frames out: %u%s\n"
1469 " Time to Hangup: %ld\n"
1470 " Elapsed Time: %s\n"
1471 " Direct Bridge: %s\n"
1472 "Indirect Bridge: %s\n"
1477 " Call Group: %llu\n"
1478 " Pickup Group: %llu\n"
1479 " Application: %s\n"
1481 " Blocking in: %s\n",
1503 ( c-> data ?
S_OR(c->
data,
"(Empty)") :
"(None)"),
1514 #ifdef CHANNEL_TRACE
1515 trace_enabled = ast_channel_trace_is_enabled(c);
1517 trace_enabled ?
"Enabled" :
"Disabled");
1518 if (trace_enabled && ast_channel_trace_serialize(c, &obuf)) {
1537 int i, which = 0,
len;
1540 for (i = 0; choices[i]; i++) {
1541 if ((!
len || !strncasecmp(word, choices[i],
len)) && ++which > state)
1551 char notfound =
'\0';
1552 char *ret = ¬found;
1570 if (++which > state) {
1580 return ret == ¬found ? NULL : ret;
1585 #define FORMAT_STRING "%-25s %-20s %-20s\n"
1590 int havepattern = 0;
1594 e->
command =
"group show channels";
1596 "Usage: group show channels [pattern]\n"
1597 " Lists all currently active channels with channel group(s) specified.\n"
1598 " Optional regular expression pattern is matched to group names for each\n"
1609 if (regcomp(®exbuf, a->
argv[3], REG_EXTENDED | REG_NOSUB))
1620 if (!havepattern || !regexec(®exbuf, gi->
group, 0, NULL, 0)) {
1632 ast_cli(a->
fd,
"%d active channel%s\n", numchans,
ESS(numchans));
1634 #undef FORMAT_STRING
1641 e->
command =
"core waitfullybooted";
1643 "Usage: core waitfullybooted\n"
1644 " Wait until Asterisk has fully booted.\n";
1654 ast_cli(a->
fd,
"Asterisk has fully booted.\n");
1729 for (i = 0; e->
cmda[i]; i++)
1738 struct cli_perm *perm;
1739 struct usergroup_cli_perm *user_perm;
1758 struct usergroup_cli_perm *user_group, *cp_entry;
1759 struct cli_perm *perm = NULL;
1764 ast_log(
LOG_NOTICE,
"You must wait until last 'cli reload permissions' command finish\n");
1781 if (!strcasecmp(cat,
"general")) {
1784 if (!strcasecmp(v->
name,
"default_perm")) {
1785 cli_default_perm = (!strcasecmp(v->
value,
"permit")) ? 1: 0;
1792 gr = NULL, pw = NULL;
1793 if (cat[0] ==
'@') {
1795 gr = getgrnam(&cat[1]);
1812 if ((pw && cp_entry->
uid == pw->pw_uid) || (gr && cp_entry->
gid == gr->gr_gid)) {
1815 user_group = cp_entry;
1823 user_group =
ast_calloc(1,
sizeof(*user_group));
1827 user_group->
uid = (pw ? pw->pw_uid : -1);
1828 user_group->
gid = (gr ? gr->gr_gid : -1);
1830 if (!user_group->
perms) {
1841 if (!strcasecmp(v->
name,
"permit")) {
1847 }
else if (!strcasecmp(v->
name,
"deny")) {
1904 if (!strchr(cli_rsvd, cli_word[0]))
1905 return (strcasecmp(cmd, cli_word) == 0) ? 1 : -1;
1908 if (l > 0 && cli_word[0] ==
'%') {
1921 if (pos != cli_word && strchr(cli_rsvd, pos[-1]) && strchr(cli_rsvd, pos[l])) {
1937 int pos,
int *actual)
1948 if (strcspn(word, cli_rsvd) != lw)
1950 if (strchr(cli_rsvd, token[0]) == NULL) {
1951 if (strncasecmp(token, word, lw))
1954 return (pos != 0) ? NULL :
ast_strdup(token);
1961 while (pos >= 0 && (s =
strsep(&t1, cli_rsvd)) && *s) {
1964 if (strncasecmp(s, word, lw))
1993 const char *
const *src = cmds;
1994 const char *
const *dst = e->
cmda;
1996 for (;; dst++, src += n) {
2006 if (match_type != 0)
2021 if (src - cmds > matchlen) {
2022 matchlen = src - cmds;
2027 return e ? e : cand;
2032 static char cmdline[80];
2038 for (x = 0; argv[x]; x++) {
2039 myargv[x] = argv[x];
2044 ast_join(cmdline,
sizeof(cmdline), myargv);
2073 memset(cmda,
'\0',
sizeof(e->
cmda));
2085 int i, lf, ret = -1;
2088 char **dst = (
char **)e->
cmda;
2100 memset(&a,
'\0',
sizeof(a));
2116 ast_log(
LOG_WARNING,
"Command '%s' already registered (or something close enough)\n",
2171 for (i = 0; i <
len; i++)
2181 for (i = 0; i <
len; i++)
2193 char matchstr[80] =
"";
2199 ast_join(matchstr,
sizeof(matchstr), match);
2200 len = strlen(matchstr);
2208 if (match && strncasecmp(matchstr, e->
_full_cmd, len))
2215 if (!found && matchstr[0])
2216 ast_cli(fd,
"No such command '%s'.\n", matchstr);
2227 e->
command =
"core show help";
2229 "Usage: core show help [topic]\n"
2230 " When called with a topic as an argument, displays usage\n"
2231 " information on the given command. If called without a\n"
2232 " topic, it provides a list of commands.\n";
2237 int l = strlen(a->
line);
2260 ast_cli(a->
fd,
"No help text available for '%s'.\n", fullcmd);
2266 static char *
parse_args(
const char *s,
int *argc,
const char *argv[],
int max,
int *trailingwhitespace)
2268 char *duplicate, *cur;
2275 if (trailingwhitespace == NULL)
2276 trailingwhitespace = &
dummy;
2277 *trailingwhitespace = 0;
2287 while (isspace(*s)) {
2298 if (*s ==
'"' && !escaped) {
2300 if (quoted && whitespace) {
2305 }
else if ((*s ==
' ' || *s ==
'\t') && !(quoted || escaped)) {
2314 }
else if (*s ==
'\\' && !escaped) {
2334 *trailingwhitespace = whitespace;
2341 int matches = 0, i = 0;
2342 char *buf = NULL, *oldbuf = NULL;
2345 if (!oldbuf || strcmp(buf,oldbuf))
2361 for (idx = 1; idx < matches; ++idx) {
2370 char **match_list = NULL, *retstr, *prevstr;
2372 size_t match_list_len, max_equal, which, i;
2378 if (matches + 1 >= match_list_len) {
2379 match_list_len <<= 1;
2380 new_list =
ast_realloc(match_list, match_list_len *
sizeof(*match_list));
2385 match_list = new_list;
2387 match_list[++matches] = retstr;
2397 prevstr = match_list[1];
2398 max_equal = strlen(prevstr);
2399 for (which = 2; which <= matches; which++) {
2400 for (i = 0; i < max_equal && toupper(prevstr[i]) == toupper(match_list[which][i]); i++)
2411 match_list[0] = retstr;
2414 if (matches + 1 >= match_list_len) {
2415 new_list =
ast_realloc(match_list, (match_list_len + 1) *
sizeof(*match_list));
2421 match_list = new_list;
2423 match_list[matches + 1] = NULL;
2432 for (i = 0; dst[i]; i++) {
2433 if (dst[i][0] !=
'[')
2446 int x = 0, argindex, matchlen;
2449 char matchstr[80] =
"";
2461 ast_join(matchstr,
sizeof(matchstr)-1, argv);
2462 matchlen = strlen(matchstr);
2464 strcat(matchstr,
" ");
2472 int src = 0, dst = 0, n = 0;
2481 for (;src < argindex; dst++, src += n) {
2489 ret =
is_prefix(argv[src], e->
cmda[dst], state - matchnum, &n);
2496 if (matchnum > state)
2510 .n = state - matchnum,
2537 char *retval = NULL;
2539 .
fd =
fd, .argc = x, .argv = args+1 };
2541 if (duplicate == NULL)
2553 ast_cli(fd,
"No such command '%s' (type 'core show help %s' for other possible commands)\n", s,
find_best(args + 1));
2557 ast_join(tmp,
sizeof(tmp), args + 1);
2560 ast_cli(fd,
"You don't have permissions to run '%s' command\n", tmp);
2569 args[0] = (
char *)e;
2574 ast_cli(fd,
"%s",
S_OR(e->
usage,
"Invalid usage, but no usage information available.\n"));
2577 ast_cli(fd,
"Command '%s' failed.\n", s);
2588 int x, y = 0, count = 0;
2590 for (x = 0; x < size; x++) {
#define AST_THREADSTORAGE(name)
Define a thread storage variable.
void ast_std_free(void *ptr)
#define ast_channel_lock(chan)
static char * handle_verbose(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Main Channel structure associated with a channel.
#define AST_CLI_DEFINE(fn, txt,...)
char * str
Subscriber phone number (Malloced)
char ** ast_cli_completion_matches(const char *, const char *)
Generates a NULL-terminated array of strings that 1) begin with the string in the second parameter...
struct ast_party_connected_line connected
Channel Connected Line ID information.
Asterisk locking-related definitions:
static struct ast_cli_entry cli_cli[]
struct ast_channel * ast_channel_iterator_next(struct ast_channel_iterator *i)
Get the next channel for a channel iterator.
Asterisk main include file. File version handling, generic pbx functions.
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
#define VERBOSE_FORMAT_STRING
char * str
Subscriber phone number (Malloced)
int ast_active_calls(void)
Retrieve the number of active calls.
struct ast_party_caller caller
Channel Caller ID information.
char * strsep(char **str, const char *delims)
#define AST_CLI_COMPLETE_EOF
enum ast_module_load_result ast_load_resource(const char *resource_name)
Load a module.
#define AST_RWLIST_HEAD_STATIC(name, type)
Defines a structure to be used to hold a read/write list of specified type, statically initialized...
const ast_string_field uniqueid
static char * group_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
void ast_builtins_init(void)
initialize the _full_cmd string in * each of the builtins.
int ast_cli_register(struct ast_cli_entry *e)
Registers a command or an array of commands.
static int cli_default_perm
Default permissions value 1=Permit 0=Deny.
struct ast_party_id id
Connected party ID.
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
#define ast_channel_unref(c)
Decrease channel reference count.
static char * find_best(const char *argv[])
#define ast_test_flag(p, flag)
static char * handle_showuptime(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Support for translation of data formats. translate.c.
struct ast_party_name name
Subscriber name.
const char * ast_config_AST_MODULE_DIR
unsigned int ast_verbose_get_by_module(const char *module)
Get the verbose level for a module.
int ast_carefulwrite(int fd, char *s, int len, int timeoutms)
Try to write string, but wait no more than ms milliseconds before timing out.
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
char context[AST_MAX_CONTEXT]
#define ast_set_flag(p, flag)
int ast_cli_unregister(struct ast_cli_entry *e)
Unregisters a command or an array of commands.
descriptor for a cli entry.
static char * handle_softhangup(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category)
Goes through variables.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
static char * complete_number(const char *partial, unsigned int min, unsigned int max, int n)
static void dummy(char *unused,...)
char * ast_complete_source_filename(const char *partial, int n)
static ast_mutex_t climodentrylock
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
#define AST_RWLIST_HEAD_INIT_VALUE
Defines initial values for a declaration of AST_RWLIST_HEAD.
static int cli_has_permissions(int uid, int gid, const char *command)
static char * parse_args(const char *s, int *argc, const char *argv[], int max, int *trailingwhitespace)
Structure for variables, used for configurations and for channel variables.
static int cli_is_registered(struct ast_cli_entry *e)
int ast_str_set_va(struct ast_str **buf, ssize_t max_len, const char *fmt, va_list ap)
Set a dynamic string from a va_list.
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
char * str
Subscriber name (Malloced)
unsigned long global_fout
static struct module_level_list debug_modules
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
struct ast_str * ast_str_create(size_t init_len)
Create a malloc'ed dynamic length string.
#define ast_mutex_lock(a)
#define ast_str_alloca(init_len)
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
map a debug or verbose level to a module name
const char * ast_state2str(enum ast_channel_state)
Gives the string form of a given channel state.
static int more_words(const char *const *dst)
returns true if there are more words to match
static int __ast_cli_unregister(struct ast_cli_entry *e, struct ast_cli_entry *ed)
Definitions to aid in the use of thread local storage.
static int __ast_cli_register(struct ast_cli_entry *e, struct ast_cli_entry *ed)
void ast_cli(int fd, const char *fmt,...)
const ast_string_field linkedid
static int channel_set_debug(void *obj, void *arg, void *data, int flags)
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
void ast_config_destroy(struct ast_config *config)
Destroys a config.
char * ast_skip_nonblanks(const char *str)
Gets a pointer to first whitespace character in a string.
struct cli_perm::@239 list
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return * the previous value of *p. This can be used to handle reference co...
void ast_console_toggle_mute(int fd, int silent)
mute or unmute a console from logging
int args
This gets set in ast_cli_register()
static char * handle_chanlist(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
#define VERBOSE_FORMAT_STRING2
static char * is_prefix(const char *word, const char *token, int pos, int *actual)
if word is a valid prefix for token, returns the pos-th match as a malloced string, or NULL otherwise. Always tell in *actual how many matches we got.
char * ast_cli_complete(const char *word, const char *const choices[], int pos)
struct ast_party_id id
Caller party ID.
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
static int word_match(const char *cmd, const char *cli_word)
static char * handle_unload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static const char cli_rsvd[]
General Asterisk PBX channel definitions.
struct ast_party_dialed::@155 number
Dialed/Called number.
Asterisk file paths, configured in asterisk.conf.
#define ast_mutex_trylock(a)
#define AST_CLI_INITLEN
Initial buffer size for resulting strings in ast_cli()
#define CONCISE_FORMAT_STRING
char * ast_module_helper(const char *line, const char *word, int pos, int state, int rpos, int needsreload)
Match modules names for the Asterisk cli.
struct cli_perm_head * perms
static force_inline int attribute_pure ast_strlen_zero(const char *s)
static ast_mutex_t permsconfiglock
mutex used to prevent a user from running the 'cli reload permissions' command while it is already ru...
static struct module_level * find_module_level(const char *module, unsigned int debug)
Find the debug or verbose file setting.
static const char perms_config[]
CLI permissions config file.
char * ast_category_browse(struct ast_config *config, const char *prev)
Goes through categories.
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
int ast_softhangup(struct ast_channel *chan, int reason)
Softly hangup up a channel.
int ast_register_atexit(void(*func)(void))
Register a function to be executed before Asterisk exits.
struct timeval ast_lastreloadtime
static struct ast_cli_entry * find_cli(const char *const cmds[], int match_type)
static char * __ast_cli_generator(const char *text, const char *word, int state, int lock)
int ast_cli_command_full(int uid, int gid, int fd, const char *s)
Interprets a command Interpret a command s, sending output to fd if uid:gid has permissions to run th...
A set of macros to manage forward-linked lists.
struct ast_channel * _bridge
#define AST_RWLIST_INSERT_BEFORE_CURRENT
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Core PBX routines and definitions.
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
struct ast_channel * chan
struct ast_channel * ast_channel_callback(ao2_callback_data_fn *cb_fn, void *arg, void *data, int ao2_flags)
Call a function with every active channel.
List of restrictions per user.
static void print_uptimestr(int fd, struct timeval timeval, const char *prefix, int printsec)
struct ast_party_dialed dialed
Dialed/Called information.
struct ast_trans_pvt * writetrans
struct ast_group_info * ast_app_group_list_head(void)
Get the head of the group count list.
#define AST_LIST_HEAD_NOLOCK(name, type)
Defines a structure to be used to hold a list of specified type (with no lock).
static char * handle_core_set_debug_channel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
#define ast_strdupa(s)
duplicate a string in memory from the stack
int ast_cdr_serialize_variables(struct ast_cdr *cdr, struct ast_str **buf, char delim, char sep, int recur)
int ast_processed_calls(void)
Retrieve the total number of calls processed through the PBX since last restart.
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
list of users to apply restrictions.
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
char *(* handler)(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int modlist_modentry(const char *module, const char *description, int usecnt, const char *like)
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
enum ast_channel_state _state
struct ast_channel * ast_bridged_channel(struct ast_channel *chan)
Find bridged channel.
int ast_unload_resource(const char *resource_name, enum ast_module_unload_mode)
Unload a module.
const ast_string_field name
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
static struct ast_cli_entry * cli_next(struct ast_cli_entry *e)
static char * help1(int fd, const char *const match[], int locked)
helper for final part of handle_help if locked = 1, assume the list is already locked ...
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
#define ast_channel_unlock(chan)
int ast_module_reload(const char *name)
Reload asterisk modules.
static char * complete_fn(const char *word, int state)
void ast_join(char *s, size_t len, const char *const w[])
static void cli_shutdown(void)
#define AST_RWLIST_REMOVE_HEAD
static char * handle_cli_reload_permissions(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
handles CLI command 'cli reload permissions'
static char * handle_cli_show_permissions(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
handles CLI command 'cli show permissions'
char * ast_cli_generator(const char *, const char *, int)
Readline madness Useful for readline, that's about it.
Structure used to handle boolean flags.
struct ast_channel_iterator * ast_channel_iterator_by_name_new(const char *name, size_t name_len)
Create a new channel iterator based on name.
#define ast_clear_flag(p, flag)
static char * handle_showchan(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_nodebugchan_deprecated(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_showcalls(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_commandmatchesarray(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
struct timeval ast_startuptime
int ast_app_group_list_unlock(void)
Unlock the group count list.
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
int ast_cli_command_multiple_full(int uid, int gid, int fd, size_t size, const char *s)
Executes multiple CLI commands Interpret strings separated by NULL and execute each one...
#define AST_RWLIST_INSERT_TAIL
static void destroy_match_list(char **match_list, int matches)
struct ast_flags ast_options
const char * ast_translate_path_to_str(struct ast_trans_pvt *t, struct ast_str **str)
Puts a string representation of the translation path into outbuf.
const char *const summary
Standard Command Line Interface.
int ast_update_module_list(int(*modentry)(const char *module, const char *description, int usecnt, const char *like), const char *like)
Ask for a list of modules, descriptions, and use counts.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
struct ast_group_info::@157 group_list
static void destroy_user_perms(void)
cleanup (free) cli_perms linkedlist.
int ast_cli_register_multiple(struct ast_cli_entry *e, int len)
Register multiple commands.
#define ast_realloc(a, b)
static char * handle_cli_check_permissions(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
handles CLI command 'cli check permissions'
struct ast_channel_iterator * ast_channel_iterator_destroy(struct ast_channel_iterator *i)
Destroy a channel iterator.
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
char * ast_getformatname_multiple(char *buf, size_t size, format_t format)
Get the names of a set of formats.
static char * handle_commandnummatches(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
char * ast_complete_channels(const char *line, const char *word, int pos, int state, int rpos)
Command completion for the list of active channels.
static char * handle_commandcomplete(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
List of users and permissions.
static char * handle_cli_wait_fullybooted(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
int ast_cli_generatornummatches(const char *, const char *)
Return the number of unique matches for the generator.
#define AST_RWLIST_REMOVE
struct timeval ast_tvsub(struct timeval a, struct timeval b)
Returns the difference of two timevals a - b.
struct timeval whentohangup
struct ast_variable * next
static char * handle_logger_mute(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_modlist(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static struct module_level_list verbose_modules
struct ast_trans_pvt * readtrans
struct ast_str * ast_str_thread_get(struct ast_threadstorage *ts, size_t init_len)
Retrieve a thread locally stored dynamic string.
unsigned char valid
TRUE if the name information is valid/present.
struct ast_channel_iterator * ast_channel_iterator_all_new(void)
Create a new channel iterator.
unsigned int ast_debug_get_by_module(const char *module)
Get the debug level for a module.
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
static int set_full_cmd(struct ast_cli_entry *e)
const char *const cmda[AST_MAX_CMD_LEN]
Asterisk module definitions.
char * strcasestr(const char *, const char *)
struct ast_channel_tech * tech
int ast_active_channels(void)
returns number of active/allocated channels
static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
int ast_app_group_list_rdlock(void)
Read Lock the group count list.
unsigned char valid
TRUE if the number information is valid/present.
static char * handle_core_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
#define AST_RWLIST_TRAVERSE_SAFE_END
const ast_string_field language
static char * handle_help(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static struct ast_threadstorage ast_cli_buf
static char * handle_load(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
char exten[AST_MAX_EXTENSION]
#define AST_MUTEX_DEFINE_STATIC(mutex)
int ast_cli_perms_init(int reload)
static char * handle_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
#define AST_RWLIST_HEAD(name, type)
Defines a structure to be used to hold a read/write list of specified type.
#define ASTERISK_FILE_VERSION(file, version)
Register/unregister a source code file with the core.
#define CONFIG_STATUS_FILEUNCHANGED
#define ast_mutex_unlock(a)
int pbx_builtin_serialize_variables(struct ast_channel *chan, struct ast_str **buf)
Create a human-readable string, specifying all variables and their corresponding values.
static char prefix[MAX_PREFIX]
struct ast_party_number number
Subscriber phone number.