diff --git a/asterisk.c b/asterisk.c index c5c4656a2c81f2e0368f49d92360c2bb60c7eae5..a11257cdcac4256d28de9bb45063bee9634485b7 100755 --- a/asterisk.c +++ b/asterisk.c @@ -985,6 +985,8 @@ static char **ast_el_strtoarr(char *buf) match_list_len = 1; while ( (retstr = strsep(&buf, " ")) != NULL) { + if (!strcmp(retstr, AST_CLI_COMPLETE_EOF)) + break; if (matches + 1 >= match_list_len) { match_list_len <<= 1; match_list = realloc(match_list, match_list_len * sizeof(char *)); @@ -1091,12 +1093,32 @@ static char *cli_complete(EditLine *el, int ch) nummatches = atoi(buf); if (nummatches > 0) { + char *mbuf; + int mlen = 0, maxmbuf = 2048; + /* Start with a 2048 byte buffer */ + mbuf = malloc(maxmbuf); + if (!mbuf) + return (CC_ERROR); snprintf(buf, sizeof(buf),"_COMMAND MATCHESARRAY \"%s\" \"%s\"", lf->buffer, ptr); fdprint(ast_consock, buf); - res = read(ast_consock, buf, sizeof(buf)); - buf[res] = '\0'; + res = 0; + while (!strstr(mbuf, AST_CLI_COMPLETE_EOF) && res != -1) { + if (mlen + 1024 > maxmbuf) { + /* Every step increment buffer 1024 bytes */ + maxmbuf += 1024; + mbuf = realloc(mbuf, maxmbuf); + if (!mbuf) + return (CC_ERROR); + } + /* Only read 1024 bytes at a time */ + res = read(ast_consock, mbuf + mlen, 1024); + if (res > 0) + mlen += res; + } + mbuf[mlen] = '\0'; - matches = ast_el_strtoarr(buf); + matches = ast_el_strtoarr(mbuf); + free(mbuf); } else matches = (char **) NULL; diff --git a/cli.c b/cli.c index 0068f1259760d587af5941e308ac5f97c3611427..b29ddeb9a6dc766559e4a00144b2aec8775494ca 100755 --- a/cli.c +++ b/cli.c @@ -352,13 +352,17 @@ 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[2048]; + char *buf; + int buflen = 2048; int len = 0; char **matches; int x; if (argc != 4) return RESULT_SHOWUSAGE; + buf = malloc(buflen); + if (!buf) + return RESULT_FAILURE; buf[len] = '\0'; matches = ast_cli_completion_matches(argv[2], argv[3]); if (matches) { @@ -366,6 +370,10 @@ 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); + } len += sprintf( buf + len, "%s ", matches[x]); free(matches[x]); matches[x] = NULL; @@ -377,7 +385,8 @@ static int handle_commandmatchesarray(int fd, int argc, char *argv[]) #endif if (buf) { - ast_cli(fd, buf); + ast_cli(fd, "%s%s",buf, AST_CLI_COMPLETE_EOF); + free(buf); } else ast_cli(fd, "NULL\n"); diff --git a/include/asterisk/cli.h b/include/asterisk/cli.h index 6dfc621446e7b0c566a9afff2bfb0a03bbf0e7f2..1d8564b46d4821d5b8df8044a698a758418433c2 100755 --- a/include/asterisk/cli.h +++ b/include/asterisk/cli.h @@ -31,6 +31,8 @@ extern void ast_cli(int fd, char *fmt, ...) #define AST_MAX_ARGS 64 +#define AST_CLI_COMPLETE_EOF "_EOF_" + //! A command line entry */ struct ast_cli_entry { /*! Null terminated list of the words of the command */