aboutsummaryrefslogtreecommitdiffstats
path: root/cli.c
diff options
context:
space:
mode:
author(no author) <(no author)@f38db490-d61c-443f-a65b-d21fe96a405b>2005-11-21 16:53:51 +0000
committer(no author) <(no author)@f38db490-d61c-443f-a65b-d21fe96a405b>2005-11-21 16:53:51 +0000
commit0721731e93eb315ab19418b95fad8690417b8994 (patch)
tree84965a610f6ae7e51cd499f8bd89464f247db803 /cli.c
parent27a9c96742202c8188b53a0173649de479256b69 (diff)
This commit was manufactured by cvs2svn to create tag 'v1-0-10'.
git-svn-id: http://svn.digium.com/svn/asterisk/tags/v1-0-10@7178 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'cli.c')
-rwxr-xr-xcli.c206
1 files changed, 107 insertions, 99 deletions
diff --git a/cli.c b/cli.c
index 613e3a22f..34fb016d6 100755
--- a/cli.c
+++ b/cli.c
@@ -26,6 +26,7 @@
#include <stdio.h>
#include <signal.h>
#include <string.h>
+#include <ctype.h>
/* For rl_filename_completion */
#include "editline/readline/readline.h"
/* For module directory */
@@ -147,8 +148,8 @@ static int handle_set_verbose(int fd, int argc, char *argv[])
if (oldval != option_verbose && option_verbose > 0)
ast_cli(fd, "Verbosity was %d and is now %d\n", oldval, option_verbose);
else if (oldval > 0 && option_verbose > 0)
- ast_cli(fd, "Verbosity is atleast %d\n", option_verbose);
- else if (oldval > 0 && option_debug == 0)
+ ast_cli(fd, "Verbosity is at least %d\n", option_verbose);
+ else if (oldval > 0 && option_verbose == 0)
ast_cli(fd, "Verbosity is now OFF\n");
return RESULT_SUCCESS;
}
@@ -157,6 +158,7 @@ static int handle_set_debug(int fd, int argc, char *argv[])
{
int val = 0;
int oldval = 0;
+
/* Has a hidden 'at least' argument */
if ((argc != 3) && (argc != 4))
return RESULT_SHOWUSAGE;
@@ -173,7 +175,7 @@ static int handle_set_debug(int fd, int argc, char *argv[])
if (oldval != option_debug && option_debug > 0)
ast_cli(fd, "Core debug was %d and is now %d\n", oldval, option_debug);
else if (oldval > 0 && option_debug > 0)
- ast_cli(fd, "Core debug is atleast %d\n", option_debug);
+ ast_cli(fd, "Core debug is at least %d\n", option_debug);
else if (oldval > 0 && option_debug == 0)
ast_cli(fd, "Core debug is now OFF\n");
return RESULT_SUCCESS;
@@ -437,11 +439,11 @@ static char *__ast_cli_generator(char *text, char *word, int state, int lock);
static int handle_commandmatchesarray(int fd, int argc, char *argv[])
{
- char *buf;
+ char *buf, *obuf;
int buflen = 2048;
int len = 0;
char **matches;
- int x;
+ int x, matchlen;
if (argc != 4)
return RESULT_SHOWUSAGE;
@@ -455,11 +457,17 @@ static int handle_commandmatchesarray(int fd, int argc, char *argv[])
#if 0
printf("command matchesarray for '%s' %s got '%s'\n", argv[2], argv[3], matches[x]);
#endif
- if (len + strlen(matches[x]) >= buflen) {
- buflen += strlen(matches[x]) * 3;
- buf = realloc(buf, buflen);
+ matchlen = strlen(matches[x]) + 1;
+ if (len + matchlen >= buflen) {
+ buflen += matchlen * 3;
+ obuf = buf;
+ buf = realloc(obuf, buflen);
+ if (!buf)
+ /* Out of memory... Just free old buffer and be done */
+ free(obuf);
}
- len += sprintf( buf + len, "%s ", matches[x]);
+ if (buf)
+ len += sprintf( buf + len, "%s ", matches[x]);
free(matches[x]);
matches[x] = NULL;
}
@@ -748,7 +756,7 @@ static struct ast_cli_entry *find_cli(char *cmds[], int exact)
return e;
}
-static void join(char *dest, size_t destsize, char *w[])
+static void join(char *dest, size_t destsize, char *w[], int tws)
{
int x;
/* Join words into a string */
@@ -761,6 +769,8 @@ static void join(char *dest, size_t destsize, char *w[])
strncat(dest, " ", destsize - strlen(dest) - 1);
strncat(dest, w[x], destsize - strlen(dest) - 1);
}
+ if (tws)
+ strncat(dest, " ", destsize - strlen(dest) - 1);
}
static void join2(char *dest, size_t destsize, char *w[])
@@ -789,7 +799,7 @@ static char *find_best(char *argv[])
if (!find_cli(myargv, -1))
break;
}
- join(cmdline, sizeof(cmdline), myargv);
+ join(cmdline, sizeof(cmdline), myargv, 0);
return cmdline;
}
@@ -863,20 +873,20 @@ int ast_cli_register(struct ast_cli_entry *e)
static int help_workhorse(int fd, char *match[])
{
- char fullcmd1[80];
- char fullcmd2[80];
+ char fullcmd1[80] = "";
+ char fullcmd2[80] = "";
char matchstr[80];
- char *fullcmd;
+ char *fullcmd = NULL;
struct ast_cli_entry *e, *e1, *e2;
e1 = builtins;
e2 = helpers;
if (match)
- join(matchstr, sizeof(matchstr), match);
+ join(matchstr, sizeof(matchstr), match, 0);
while(e1->cmda[0] || e2) {
if (e2)
- join(fullcmd2, sizeof(fullcmd2), e2->cmda);
+ join(fullcmd2, sizeof(fullcmd2), e2->cmda, 0);
if (e1->cmda[0])
- join(fullcmd1, sizeof(fullcmd1), e1->cmda);
+ join(fullcmd1, sizeof(fullcmd1), e1->cmda, 0);
if (!e1->cmda[0] ||
(e2 && (strcmp(fullcmd2, fullcmd1) < 0))) {
/* Use e2 */
@@ -910,13 +920,18 @@ static int handle_help(int fd, int argc, char *argv[]) {
return RESULT_SHOWUSAGE;
if (argc > 1) {
e = find_cli(argv + 1, 1);
- if (e)
- ast_cli(fd, e->usage);
- else {
+ if (e) {
+ if (e->usage)
+ ast_cli(fd, "%s", e->usage);
+ else {
+ join(fullcmd, sizeof(fullcmd), argv+1, 0);
+ ast_cli(fd, "No help text available for '%s'.\n", fullcmd);
+ }
+ } else {
if (find_cli(argv + 1, -1)) {
return help_workhorse(fd, argv + 1);
} else {
- join(fullcmd, sizeof(fullcmd), argv+1);
+ join(fullcmd, sizeof(fullcmd), argv+1, 0);
ast_cli(fd, "No such command '%s'.\n", fullcmd);
}
}
@@ -926,72 +941,63 @@ static int handle_help(int fd, int argc, char *argv[]) {
return RESULT_SUCCESS;
}
-static char *parse_args(char *s, int *max, char *argv[])
+static char *parse_args(char *s, int *argc, char *argv[], int max, int *trailingwhitespace)
{
char *dup, *cur;
- int x=0;
- int quoted=0;
- int escaped=0;
- int whitespace=1;
-
- dup = strdup(s);
- if (dup) {
- cur = dup;
- while(*s) {
- switch(*s) {
- case '"':
- /* If it's escaped, put a literal quote */
- if (escaped)
- goto normal;
- else
- quoted = !quoted;
- if (quoted && whitespace) {
- /* If we're starting a quote, coming off white space start a new word, too */
- argv[x++] = cur;
- whitespace=0;
- }
- escaped = 0;
- break;
- case ' ':
- case '\t':
- if (!quoted && !escaped) {
- /* If we're not quoted, mark this as whitespace, and
- end the previous argument */
- whitespace = 1;
- *(cur++) = '\0';
- } else
- /* Otherwise, just treat it as anything else */
- goto normal;
- break;
- case '\\':
- /* If we're escaped, print a literal, otherwise enable escaping */
- if (escaped) {
- goto normal;
- } else {
- escaped=1;
+ int x = 0;
+ int quoted = 0;
+ int escaped = 0;
+ int whitespace = 1;
+
+ *trailingwhitespace = 0;
+ if (!(dup = strdup(s)))
+ return NULL;
+
+ cur = dup;
+ while (*s) {
+ if ((*s == '"') && !escaped) {
+ quoted = !quoted;
+ if (quoted & whitespace) {
+ /* If we're starting a quoted string, coming off white space, start a new argument */
+ if (x >= (max - 1)) {
+ ast_log(LOG_WARNING, "Too many arguments, truncating\n");
+ break;
}
- break;
- default:
-normal:
- if (whitespace) {
- if (x >= AST_MAX_ARGS -1) {
- ast_log(LOG_WARNING, "Too many arguments, truncating\n");
- break;
- }
- /* Coming off of whitespace, start the next argument */
- argv[x++] = cur;
- whitespace=0;
+ argv[x++] = cur;
+ whitespace = 0;
+ }
+ escaped = 0;
+ } else if (((*s == ' ') || (*s == '\t')) && !(quoted || escaped)) {
+ /* If we are not already in whitespace, and not in a quoted string or
+ processing an escape sequence, and just entered whitespace, then
+ finalize the previous argument and remember that we are in whitespace
+ */
+ if (!whitespace) {
+ *(cur++) = '\0';
+ whitespace = 1;
+ }
+ } else if ((*s == '\\') && !escaped) {
+ escaped = 1;
+ } else {
+ if (whitespace) {
+ /* If we are coming out of whitespace, start a new argument */
+ if (x >= (max - 1)) {
+ ast_log(LOG_WARNING, "Too many arguments, truncating\n");
+ break;
}
- *(cur++) = *s;
- escaped=0;
+ argv[x++] = cur;
+ whitespace = 0;
}
- s++;
+ *(cur++) = *s;
+ escaped = 0;
}
- /* Null terminate */
- *(cur++) = '\0';
- argv[x] = NULL;
- *max = x;
+ s++;
}
+ /* Null terminate */
+ *(cur++) = '\0';
+ argv[x] = NULL;
+ *argc = x;
+ *trailingwhitespace = whitespace;
return dup;
}
@@ -999,17 +1005,17 @@ normal:
int ast_cli_generatornummatches(char *text, char *word)
{
int matches = 0, i = 0;
- char *buf, *oldbuf = NULL;
-
+ char *buf = NULL, *oldbuf = NULL;
- while ( (buf = ast_cli_generator(text, word, i)) ) {
- if (++i > 1 && strcmp(buf,oldbuf) == 0) {
- continue;
- }
+ while ( (buf = ast_cli_generator(text, word, i++)) ) {
+ if (!oldbuf || strcmp(buf,oldbuf))
+ matches++;
+ if (oldbuf)
+ free(oldbuf);
oldbuf = buf;
- matches++;
}
-
+ if (oldbuf)
+ free(oldbuf);
return matches;
}
@@ -1035,7 +1041,7 @@ char **ast_cli_completion_matches(char *text, char *word)
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++)
+ for (i = 0; i < max_equal && toupper(prevstr[i]) == toupper(match_list[which][i]); i++)
continue;
max_equal = i;
}
@@ -1059,22 +1065,23 @@ static char *__ast_cli_generator(char *text, char *word, int state, int lock)
int x;
int matchnum=0;
char *dup, *res;
- char fullcmd1[80];
- char fullcmd2[80];
+ char fullcmd1[80] = "";
+ char fullcmd2[80] = "";
char matchstr[80];
- char *fullcmd;
+ char *fullcmd = NULL;
+ int tws;
- if ((dup = parse_args(text, &x, argv))) {
- join(matchstr, sizeof(matchstr), argv);
+ if ((dup = parse_args(text, &x, argv, sizeof(argv) / sizeof(argv[0]), &tws))) {
+ join(matchstr, sizeof(matchstr), argv, tws);
if (lock)
ast_mutex_lock(&clilock);
e1 = builtins;
e2 = helpers;
while(e1->cmda[0] || e2) {
if (e2)
- join(fullcmd2, sizeof(fullcmd2), e2->cmda);
+ join(fullcmd2, sizeof(fullcmd2), e2->cmda, tws);
if (e1->cmda[0])
- join(fullcmd1, sizeof(fullcmd1), e1->cmda);
+ join(fullcmd1, sizeof(fullcmd1), e1->cmda, tws);
if (!e1->cmda[0] ||
(e2 && (strcmp(fullcmd2, fullcmd1) < 0))) {
/* Use e2 */
@@ -1135,8 +1142,9 @@ int ast_cli_command(int fd, char *s)
struct ast_cli_entry *e;
int x;
char *dup;
- x = AST_MAX_ARGS;
- if ((dup = parse_args(s, &x, argv))) {
+ int tws;
+
+ if ((dup = parse_args(s, &x, argv, sizeof(argv) / sizeof(argv[0]), &tws))) {
/* We need at least one entry, or ignore */
if (x > 0) {
ast_mutex_lock(&clilock);
@@ -1147,7 +1155,7 @@ int ast_cli_command(int fd, char *s)
if (e) {
switch(e->handler(fd, x, argv)) {
case RESULT_SHOWUSAGE:
- ast_cli(fd, e->usage);
+ ast_cli(fd, "%s", e->usage);
break;
}
} else