MFcrypto/telnet/telnetd: Correct semantics of output_data*() and netflush()

to ensure deterministic operation
This commit is contained in:
kris 2001-07-23 22:00:51 +00:00
parent d051133293
commit da715e7cac
6 changed files with 51 additions and 47 deletions

View File

@ -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));

View File

@ -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

View File

@ -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;
}

View File

@ -909,8 +909,6 @@ telnet(f, p, host)
int if_fd;
struct stat statbuf;
void netflush();
/*
* Initialize the slc mapping table.
*/

View File

@ -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.

View File

@ -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 */