|
|
@ -802,14 +802,21 @@ static char *complete_show_channels(char *line, char *word, int pos, int state)
|
|
|
|
static char *choices[] = { "concise", "verbose" };
|
|
|
|
static char *choices[] = { "concise", "verbose" };
|
|
|
|
int match = 0;
|
|
|
|
int match = 0;
|
|
|
|
int x;
|
|
|
|
int x;
|
|
|
|
|
|
|
|
int wordlen;
|
|
|
|
|
|
|
|
|
|
|
|
if (pos != 2)
|
|
|
|
if (pos != 2)
|
|
|
|
return NULL;
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
wordlen = strlen(word);
|
|
|
|
|
|
|
|
|
|
|
|
for (x = 0; x < sizeof(choices) / sizeof(choices[0]); x++) {
|
|
|
|
for (x = 0; x < sizeof(choices) / sizeof(choices[0]); x++) {
|
|
|
|
if (!strncasecmp(word, choices[x], strlen(word))) {
|
|
|
|
if (!strncasecmp(word, choices[x], wordlen)) {
|
|
|
|
match++;
|
|
|
|
match++;
|
|
|
|
if (match > state) return strdup(choices[x]);
|
|
|
|
if (match > state)
|
|
|
|
|
|
|
|
return strdup(choices[x]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -817,12 +824,16 @@ static char *complete_ch_helper(char *line, char *word, int pos, int state, int
|
|
|
|
{
|
|
|
|
{
|
|
|
|
struct ast_channel *c = NULL;
|
|
|
|
struct ast_channel *c = NULL;
|
|
|
|
int which = 0;
|
|
|
|
int which = 0;
|
|
|
|
|
|
|
|
int wordlen;
|
|
|
|
char *ret = NULL;
|
|
|
|
char *ret = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
if (pos != rpos)
|
|
|
|
if (pos != rpos)
|
|
|
|
return NULL;
|
|
|
|
return NULL;
|
|
|
|
while ( (c = ast_channel_walk_locked(c)) != NULL) {
|
|
|
|
|
|
|
|
if (!strncasecmp(word, c->name, strlen(word))) {
|
|
|
|
wordlen = strlen(word);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while ((c = ast_channel_walk_locked(c))) {
|
|
|
|
|
|
|
|
if (!strncasecmp(word, c->name, wordlen)) {
|
|
|
|
if (++which > state) {
|
|
|
|
if (++which > state) {
|
|
|
|
ret = strdup(c->name);
|
|
|
|
ret = strdup(c->name);
|
|
|
|
ast_mutex_unlock(&c->lock);
|
|
|
|
ast_mutex_unlock(&c->lock);
|
|
|
@ -831,6 +842,7 @@ static char *complete_ch_helper(char *line, char *word, int pos, int state, int
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ast_mutex_unlock(&c->lock);
|
|
|
|
ast_mutex_unlock(&c->lock);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -858,15 +870,20 @@ static char *complete_fn(char *line, char *word, int pos, int state)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
char *c;
|
|
|
|
char *c;
|
|
|
|
char filename[256];
|
|
|
|
char filename[256];
|
|
|
|
|
|
|
|
|
|
|
|
if (pos != 1)
|
|
|
|
if (pos != 1)
|
|
|
|
return NULL;
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
|
|
if (word[0] == '/')
|
|
|
|
if (word[0] == '/')
|
|
|
|
ast_copy_string(filename, word, sizeof(filename));
|
|
|
|
ast_copy_string(filename, word, sizeof(filename));
|
|
|
|
else
|
|
|
|
else
|
|
|
|
snprintf(filename, sizeof(filename), "%s/%s", (char *)ast_config_AST_MODULE_DIR, word);
|
|
|
|
snprintf(filename, sizeof(filename), "%s/%s", ast_config_AST_MODULE_DIR, word);
|
|
|
|
c = (char*)filename_completion_function(filename, state);
|
|
|
|
|
|
|
|
|
|
|
|
c = filename_completion_function(filename, state);
|
|
|
|
|
|
|
|
|
|
|
|
if (c && word[0] != '/')
|
|
|
|
if (c && word[0] != '/')
|
|
|
|
c += (strlen((char*)ast_config_AST_MODULE_DIR) + 1);
|
|
|
|
c += (strlen(ast_config_AST_MODULE_DIR) + 1);
|
|
|
|
|
|
|
|
|
|
|
|
return c ? strdup(c) : c;
|
|
|
|
return c ? strdup(c) : c;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -1020,15 +1037,17 @@ int ast_cli_register(struct ast_cli_entry *e)
|
|
|
|
struct ast_cli_entry *cur, *l=NULL;
|
|
|
|
struct ast_cli_entry *cur, *l=NULL;
|
|
|
|
char fulle[80] ="", fulltst[80] ="";
|
|
|
|
char fulle[80] ="", fulltst[80] ="";
|
|
|
|
static int len;
|
|
|
|
static int len;
|
|
|
|
|
|
|
|
|
|
|
|
ast_mutex_lock(&clilock);
|
|
|
|
ast_mutex_lock(&clilock);
|
|
|
|
join2(fulle, sizeof(fulle), e->cmda);
|
|
|
|
join2(fulle, sizeof(fulle), e->cmda);
|
|
|
|
|
|
|
|
|
|
|
|
if (find_cli(e->cmda, -1)) {
|
|
|
|
if (find_cli(e->cmda, -1)) {
|
|
|
|
ast_mutex_unlock(&clilock);
|
|
|
|
ast_mutex_unlock(&clilock);
|
|
|
|
ast_log(LOG_WARNING, "Command '%s' already registered (or something close enough)\n", fulle);
|
|
|
|
ast_log(LOG_WARNING, "Command '%s' already registered (or something close enough)\n", fulle);
|
|
|
|
return -1;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
cur = helpers;
|
|
|
|
|
|
|
|
while(cur) {
|
|
|
|
for (cur = helpers; cur; cur = cur->next) {
|
|
|
|
join2(fulltst, sizeof(fulltst), cur->cmda);
|
|
|
|
join2(fulltst, sizeof(fulltst), cur->cmda);
|
|
|
|
len = strlen(fulltst);
|
|
|
|
len = strlen(fulltst);
|
|
|
|
if (strlen(fulle) < len)
|
|
|
|
if (strlen(fulle) < len)
|
|
|
@ -1044,8 +1063,8 @@ int ast_cli_register(struct ast_cli_entry *e)
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
l = cur;
|
|
|
|
l = cur;
|
|
|
|
cur = cur->next;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!cur) {
|
|
|
|
if (!cur) {
|
|
|
|
if (l)
|
|
|
|
if (l)
|
|
|
|
l->next = e;
|
|
|
|
l->next = e;
|
|
|
@ -1053,7 +1072,9 @@ int ast_cli_register(struct ast_cli_entry *e)
|
|
|
|
helpers = e;
|
|
|
|
helpers = e;
|
|
|
|
e->next = NULL;
|
|
|
|
e->next = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ast_mutex_unlock(&clilock);
|
|
|
|
ast_mutex_unlock(&clilock);
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -1159,7 +1180,7 @@ static char *parse_args(char *s, int *argc, char *argv[], int max, int *trailing
|
|
|
|
return NULL;
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
|
|
cur = dup;
|
|
|
|
cur = dup;
|
|
|
|
while (*s) {
|
|
|
|
while (!ast_strlen_zero(s)) {
|
|
|
|
if ((*s == '"') && !escaped) {
|
|
|
|
if ((*s == '"') && !escaped) {
|
|
|
|
quoted = !quoted;
|
|
|
|
quoted = !quoted;
|
|
|
|
if (quoted & whitespace) {
|
|
|
|
if (quoted & whitespace) {
|
|
|
@ -1252,7 +1273,7 @@ char **ast_cli_completion_matches(char *text, char *word)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
retstr = malloc(max_equal + 1);
|
|
|
|
retstr = malloc(max_equal + 1);
|
|
|
|
(void) strncpy(retstr, match_list[1], max_equal);
|
|
|
|
strncpy(retstr, match_list[1], max_equal);
|
|
|
|
retstr[max_equal] = '\0';
|
|
|
|
retstr[max_equal] = '\0';
|
|
|
|
match_list[0] = retstr;
|
|
|
|
match_list[0] = retstr;
|
|
|
|
|
|
|
|
|
|
|
@ -1260,7 +1281,7 @@ char **ast_cli_completion_matches(char *text, char *word)
|
|
|
|
match_list = realloc(match_list, (match_list_len + 1) * sizeof(char *));
|
|
|
|
match_list = realloc(match_list, (match_list_len + 1) * sizeof(char *));
|
|
|
|
match_list[matches + 1] = (char *) NULL;
|
|
|
|
match_list[matches + 1] = (char *) NULL;
|
|
|
|
|
|
|
|
|
|
|
|
return (match_list);
|
|
|
|
return match_list;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static char *__ast_cli_generator(char *text, char *word, int state, int lock)
|
|
|
|
static char *__ast_cli_generator(char *text, char *word, int state, int lock)
|
|
|
@ -1352,7 +1373,12 @@ int ast_cli_command(int fd, char *s)
|
|
|
|
char *dup;
|
|
|
|
char *dup;
|
|
|
|
int tws;
|
|
|
|
int tws;
|
|
|
|
|
|
|
|
|
|
|
|
if ((dup = parse_args(s, &x, argv, sizeof(argv) / sizeof(argv[0]), &tws))) {
|
|
|
|
dup = parse_args(s, &x, argv, sizeof(argv) / sizeof(argv[0]), &tws);
|
|
|
|
|
|
|
|
if (!dup) {
|
|
|
|
|
|
|
|
ast_log(LOG_ERROR, "Out of Memory!\n");
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* We need at least one entry, or ignore */
|
|
|
|
/* We need at least one entry, or ignore */
|
|
|
|
if (x > 0) {
|
|
|
|
if (x > 0) {
|
|
|
|
ast_mutex_lock(&clilock);
|
|
|
|
ast_mutex_lock(&clilock);
|
|
|
@ -1375,9 +1401,6 @@ int ast_cli_command(int fd, char *s)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
free(dup);
|
|
|
|
free(dup);
|
|
|
|
} else {
|
|
|
|
|
|
|
|
ast_log(LOG_WARNING, "Out of memory\n");
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|