Newer
Older
int ast_cli_generatornummatches(char *text, char *word)
{
int matches = 0, i = 0;
while ( (buf = ast_cli_generator(text, word, i)) ) {
if (++i > 1 && strcmp(buf,oldbuf) == 0) {
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
return matches;
}
char **ast_cli_completion_matches(char *text, char *word)
{
char **match_list = NULL, *retstr, *prevstr;
size_t match_list_len, max_equal, which, i;
int matches = 0;
match_list_len = 1;
while ((retstr = ast_cli_generator(text, word, matches)) != NULL) {
if (matches + 1 >= match_list_len) {
match_list_len <<= 1;
match_list = realloc(match_list, match_list_len * sizeof(char *));
}
match_list[++matches] = retstr;
}
if (!match_list)
return (char **) NULL;
which = 2;
prevstr = match_list[1];
max_equal = strlen(prevstr);
for (; which <= matches; which++) {
for (i = 0; i < max_equal && prevstr[i] == match_list[which][i]; i++)
continue;
max_equal = i;
}
retstr = malloc(max_equal + 1);
(void) strncpy(retstr, match_list[1], max_equal);
retstr[max_equal] = '\0';
match_list[0] = retstr;
if (matches + 1 >= match_list_len)
match_list = realloc(match_list, (match_list_len + 1) * sizeof(char *));
match_list[matches + 1] = (char *) NULL;
return (match_list);
}
static char *__ast_cli_generator(char *text, char *word, int state, int lock)
{
char *argv[AST_MAX_ARGS];
struct ast_cli_entry *e, *e1, *e2;
int x;
int matchnum=0;
char *dup, *res;
char fullcmd1[80];
char fullcmd2[80];
char matchstr[80];
char *fullcmd;
if ((dup = parse_args(text, &x, argv))) {
join(matchstr, sizeof(matchstr), argv);
ast_mutex_lock(&clilock);
e1 = builtins;
e2 = helpers;
while(e1->cmda[0] || e2) {
if (e2)
join(fullcmd2, sizeof(fullcmd2), e2->cmda);
if (e1->cmda[0])
join(fullcmd1, sizeof(fullcmd1), e1->cmda);
(e2 && (strcmp(fullcmd2, fullcmd1) < 0))) {
/* Use e2 */
e = e2;
fullcmd = fullcmd2;
/* Increment by going to next */
e2 = e2->next;
} else {
/* Use e1 */
e = e1;
fullcmd = fullcmd1;
e1++;
}
if ((fullcmd[0] != '_') && !strncasecmp(matchstr, fullcmd, strlen(matchstr))) {
/* We contain the first part of one or more commands */
matchnum++;
if (matchnum > state) {
/* Now, what we're supposed to return is the next word... */
res = e->cmda[x-1];
} else {
res = e->cmda[x];
}
if (res) {
ast_mutex_unlock(&clilock);
}
}
}
if (e->generator && !strncasecmp(matchstr, fullcmd, strlen(fullcmd))) {
/* We have a command in its entirity within us -- theoretically only one
command can have this occur */
fullcmd = e->generator(matchstr, word, (!ast_strlen_zero(word) ? (x - 1) : (x)), state);
ast_mutex_unlock(&clilock);
ast_mutex_unlock(&clilock);
char *ast_cli_generator(char *text, char *word, int state)
{
return __ast_cli_generator(text, word, state, 1);
}
int ast_cli_command(int fd, char *s)
{
char *argv[AST_MAX_ARGS];
struct ast_cli_entry *e;
int x;
char *dup;
x = AST_MAX_ARGS;
if ((dup = parse_args(s, &x, argv))) {
/* We need at least one entry, or ignore */
if (x > 0) {
ast_mutex_lock(&clilock);
ast_mutex_unlock(&clilock);
if (e) {
switch(e->handler(fd, x, argv)) {
case RESULT_SHOWUSAGE:
ast_cli(fd, e->usage);
break;
}
} else
ast_cli(fd, "No such command '%s' (type 'help' for help)\n", find_best(argv));
ast_mutex_lock(&clilock);
ast_mutex_unlock(&clilock);
}
free(dup);
} else {
ast_log(LOG_WARNING, "Out of memory\n");
return -1;
}
return 0;
}