Index: main/asterisk.c =================================================================== --- main/asterisk.c (revision 355008) +++ main/asterisk.c (working copy) @@ -1252,14 +1252,17 @@ { struct console *con = vconsole; char hostname[MAXHOSTNAMELEN] = ""; - char tmp[512]; + char outbuf[512]; /* output from asterisk to ctl */ + char cmdbuf[512]; /* commands from ctl (con->fd) */ + char *cmdp = cmdbuf; + int cmdleft = sizeof(cmdbuf); int res; struct pollfd fds[2]; if (gethostname(hostname, sizeof(hostname)-1)) ast_copy_string(hostname, "", sizeof(hostname)); - snprintf(tmp, sizeof(tmp), "%s/%ld/%s\n", hostname, (long)ast_mainpid, ast_get_version()); - fdprint(con->fd, tmp); + snprintf(outbuf, sizeof(outbuf), "%s/%ld/%s\n", hostname, (long)ast_mainpid, ast_get_version()); + fdprint(con->fd, outbuf); for (;;) { fds[0].fd = con->fd; fds[0].events = POLLIN; @@ -1275,24 +1278,46 @@ continue; } if (fds[0].revents) { - res = read_credentials(con->fd, tmp, sizeof(tmp) - 1, con); + res = read_credentials(con->fd, cmdp, cmdleft - 1, con); if (res < 1) { break; } - tmp[res] = 0; - if (strncmp(tmp, "cli quit after ", 15) == 0) { - ast_cli_command_multiple_full(con->uid, con->gid, con->fd, res - 15, tmp + 15); + res += (cmdp - cmdbuf); + cmdbuf[res] = 0; + /* buffer filled to the brim? look back and find a NUL */ + if (res == sizeof(cmdbuf) - 1) { + for (cmdp = cmdbuf + sizeof(cmdbuf) - 2; cmdp != cmdbuf && *cmdp != '\0'; --cmdp) { + } + if (cmdp == cmdbuf) { + ast_log(LOG_ERROR, "command too long\n"); + break; + } + res = (++cmdp - cmdbuf); + } + /* XXX: this only works if this happens to be the first command in a series */ + if (strncmp(cmdbuf, "cli quit after ", 15) == 0) { + ast_cli_command_multiple_full(con->uid, con->gid, con->fd, res - 15, cmdbuf + 15); break; } - ast_cli_command_multiple_full(con->uid, con->gid, con->fd, res, tmp); + ast_cli_command_multiple_full(con->uid, con->gid, con->fd, res, cmdbuf); + /* does cmdp point past cmdbuf, then we have leftover data. move it to front. */ + if (cmdp != cmdbuf) { + int leftover = cmdbuf + sizeof(cmdbuf) - cmdp - 1; + memmove(cmdbuf, cmdp, leftover); + cmdp = cmdbuf + leftover; + cmdleft = sizeof(cmdbuf) - leftover; + } else { + cmdp = cmdbuf; + cmdleft = sizeof(cmdbuf); + } } if (fds[1].revents) { - res = read_credentials(con->p[0], tmp, sizeof(tmp), con); + res = read_credentials(con->p[0], outbuf, sizeof(outbuf), con); if (res < 1) { ast_log(LOG_ERROR, "read returned %d\n", res); break; } - res = write(con->fd, tmp, res); + res = write(con->fd, outbuf, res); if (res < 1) break; }