MFcrypto/telnet/telnetd: Correct semantics of output_data*() and netflush()
to ensure deterministic operation
This commit is contained in:
parent
d051133293
commit
da715e7cac
@ -192,7 +192,7 @@ extern void
|
||||
wontoption P((int));
|
||||
|
||||
int output_data __P((const char *, ...)) __printflike(1, 2);
|
||||
int output_datalen __P((const char *, size_t));
|
||||
void output_datalen __P((const char *, int));
|
||||
|
||||
|
||||
|
||||
|
@ -176,7 +176,6 @@ end_slc(bufp)
|
||||
register unsigned char **bufp;
|
||||
{
|
||||
register int len;
|
||||
void netflush();
|
||||
|
||||
/*
|
||||
* If a change has occured, store the new terminal control
|
||||
|
@ -1546,40 +1546,46 @@ send_status()
|
||||
|
||||
/*
|
||||
* This function appends data to nfrontp and advances nfrontp.
|
||||
* Returns the number of characters written altogether (the
|
||||
* buffer may have been flushed in the process).
|
||||
*/
|
||||
|
||||
int
|
||||
output_data(const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
size_t remaining, ret;
|
||||
int len;
|
||||
char *buf;
|
||||
|
||||
va_start(args, format);
|
||||
remaining = BUFSIZ - (nfrontp - netobuf);
|
||||
/* try a netflush() if the room is too low */
|
||||
if (strlen(format) > remaining || BUFSIZ / 4 > remaining) {
|
||||
netflush();
|
||||
remaining = BUFSIZ - (nfrontp - netobuf);
|
||||
}
|
||||
ret = vsnprintf(nfrontp, remaining, format, args);
|
||||
nfrontp += (ret < remaining) ? ret : remaining;
|
||||
if ((len = vasprintf(&buf, format, args)) == -1)
|
||||
return -1;
|
||||
output_datalen(buf, len);
|
||||
va_end(args);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
output_datalen(const char *buf, size_t len)
|
||||
{
|
||||
size_t remaining;
|
||||
|
||||
remaining = BUFSIZ - (nfrontp - netobuf);
|
||||
if (remaining < len) {
|
||||
netflush();
|
||||
remaining = BUFSIZ - (nfrontp - netobuf);
|
||||
if (remaining < len)
|
||||
return -1;
|
||||
}
|
||||
memmove(nfrontp, buf, len);
|
||||
nfrontp += len;
|
||||
free(buf);
|
||||
return (len);
|
||||
}
|
||||
|
||||
void
|
||||
output_datalen(const char *buf, int len)
|
||||
{
|
||||
int remaining, copied;
|
||||
|
||||
remaining = BUFSIZ - (nfrontp - netobuf);
|
||||
while (len > 0) {
|
||||
/* Free up enough space if the room is too low*/
|
||||
if ((len > BUFSIZ ? BUFSIZ : len) > remaining) {
|
||||
netflush();
|
||||
remaining = BUFSIZ - (nfrontp - netobuf);
|
||||
}
|
||||
|
||||
/* Copy out as much as will fit */
|
||||
copied = remaining > len ? len : remaining;
|
||||
memmove(nfrontp, buf, copied);
|
||||
nfrontp += copied;
|
||||
len -= copied;
|
||||
remaining -= copied;
|
||||
buf += copied;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -909,8 +909,6 @@ telnet(f, p, host)
|
||||
int if_fd;
|
||||
struct stat statbuf;
|
||||
|
||||
void netflush();
|
||||
|
||||
/*
|
||||
* Initialize the slc mapping table.
|
||||
*/
|
||||
|
@ -136,7 +136,6 @@ int newmap = 1; /* nonzero if \n maps to ^M^J */
|
||||
void
|
||||
localstat()
|
||||
{
|
||||
void netflush();
|
||||
int need_will_echo = 0;
|
||||
|
||||
#if defined(CRAY2) && defined(UNICOS5)
|
||||
@ -381,7 +380,6 @@ flowstat()
|
||||
clientstat(code, parm1, parm2)
|
||||
register int code, parm1, parm2;
|
||||
{
|
||||
void netflush();
|
||||
|
||||
/*
|
||||
* Get a copy of terminal characteristics.
|
||||
|
@ -62,10 +62,9 @@ static const char rcsid[] =
|
||||
void
|
||||
ttloop()
|
||||
{
|
||||
void netflush();
|
||||
|
||||
DIAG(TD_REPORT, output_data("td: ttloop\r\n"));
|
||||
if (nfrontp-nbackp) {
|
||||
if (nfrontp - nbackp > 0) {
|
||||
netflush();
|
||||
}
|
||||
ncc = read(net, netibuf, sizeof netibuf);
|
||||
@ -242,10 +241,13 @@ netflush()
|
||||
int n;
|
||||
extern int not42;
|
||||
|
||||
if ((n = nfrontp - nbackp) > 0) {
|
||||
while ((n = nfrontp - nbackp) > 0) {
|
||||
#if 0
|
||||
/* XXX This causes output_data() to recurse and die */
|
||||
DIAG(TD_REPORT, {
|
||||
n += output_data("td: netflush %d chars\r\n", n);
|
||||
});
|
||||
#endif
|
||||
/*
|
||||
* if no urgent data, or if the other side appears to be an
|
||||
* old 4.2 client (and thus unable to survive TCP urgent data),
|
||||
@ -269,18 +271,19 @@ netflush()
|
||||
n = send(net, nbackp, n, MSG_OOB); /* URGENT data */
|
||||
}
|
||||
}
|
||||
}
|
||||
if (n < 0) {
|
||||
if (errno == EWOULDBLOCK || errno == EINTR)
|
||||
return;
|
||||
cleanup(0);
|
||||
}
|
||||
nbackp += n;
|
||||
if (nbackp >= neturg) {
|
||||
neturg = 0;
|
||||
}
|
||||
if (nbackp == nfrontp) {
|
||||
nbackp = nfrontp = netobuf;
|
||||
if (n == -1) {
|
||||
if (errno == EWOULDBLOCK || errno == EINTR)
|
||||
continue;
|
||||
cleanup(0);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
nbackp += n;
|
||||
if (nbackp >= neturg) {
|
||||
neturg = 0;
|
||||
}
|
||||
if (nbackp == nfrontp) {
|
||||
nbackp = nfrontp = netobuf;
|
||||
}
|
||||
}
|
||||
return;
|
||||
} /* end of netflush */
|
||||
|
Loading…
Reference in New Issue
Block a user