diff options
Diffstat (limited to 'cli.c')
-rwxr-xr-x | cli.c | 168 |
1 files changed, 85 insertions, 83 deletions
@@ -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; } @@ -863,10 +871,10 @@ 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; @@ -910,9 +918,14 @@ 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, e->usage); + else { + join(fullcmd, sizeof(fullcmd), argv+1); + 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 { @@ -926,72 +939,62 @@ 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) { 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; + + 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; + return dup; } @@ -999,8 +1002,7 @@ 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) { @@ -1035,7 +1037,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,12 +1061,12 @@ 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; - if ((dup = parse_args(text, &x, argv))) { + if ((dup = parse_args(text, &x, argv, sizeof(argv) / sizeof(argv[0])))) { join(matchstr, sizeof(matchstr), argv); if (lock) ast_mutex_lock(&clilock); @@ -1135,8 +1137,8 @@ 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))) { + + if ((dup = parse_args(s, &x, argv, sizeof(argv) / sizeof(argv[0])))) { /* We need at least one entry, or ignore */ if (x > 0) { ast_mutex_lock(&clilock); |