From 8cfed866d328659477d71d99dffe335f7b104ce4 Mon Sep 17 00:00:00 2001
From: James Golovich <james@gnuinter.net>
Date: Tue, 6 Apr 2004 07:42:01 +0000
Subject: [PATCH] Remove size restiction on remote console command completion
 (bug 1360)

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@2634 65c4cc65-6c06-0410-ace0-fbb531ad65f3
---
 asterisk.c             | 28 +++++++++++++++++++++++++---
 cli.c                  | 13 +++++++++++--
 include/asterisk/cli.h |  2 ++
 3 files changed, 38 insertions(+), 5 deletions(-)

diff --git a/asterisk.c b/asterisk.c
index c5c4656a2c..a11257cdca 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 0068f12597..b29ddeb9a6 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 6dfc621446..1d8564b46d 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 */
-- 
GitLab