[comp.unix.wizards] Telnet flow control

scott@gateway.mitre.ORG (06/09/87)

About every couple of months some complains about loosing characters
over telnet.  Well, telnet runs over TCP and TCP does NOT drop characters.
The problem is that the distributed telnet turns off local flow control
(UCB telnet that is, I can't speak for other telnets).  Here is a modified
``mode'' function taken from a 4.2bsd telnet that reinstates local
flow control.  I have heard that the 4.3 telnet is similar but I haven't
had the need to change it yet.

		John <scott@gateway.mitre.org>

	As always Mr. Scott, should you or any of your IM force be
	caught or killed, the secretary will disavow any knowledge
	of the operation.  You're on your own John. Good Luck!


struct	tchars notc =	{ -1, -1, -1, -1, -1, -1 };
struct	ltchars noltc =	{ -1, -1, -1, -1, -1, -1 };

mode(f)
	register int f;
{
	static int prevmode = 0;
	struct tchars *tc;
	struct ltchars *ltc;
	struct sgttyb sb;
	int onoff, old;

	if (prevmode == f)
		return (f);
	old = prevmode;
	prevmode = f;
	sb = ottyb;
	switch (f) {

	case 0:
		onoff = 0;
		tc = &otc;
		ltc = &oltc;
		break;

	case 1:
	case 2:
		sb.sg_flags |= CBREAK;
		if (f == 1)
			sb.sg_flags &= ~(ECHO|CRMOD);
		else
			sb.sg_flags |= ECHO|CRMOD;
		sb.sg_erase = sb.sg_kill = -1;
		tc = &notc;
		tc->t_stopc = otc.t_stopc;		/* hacks to allow */
		tc->t_startc = otc.t_startc;		/* flow control */
		ltc = &noltc;
		onoff = 1;
		break;

	default:
		return;
	}
	ioctl(fileno(stdin), TIOCSLTC, (char *)ltc);
	ioctl(fileno(stdin), TIOCSETC, (char *)tc);
	ioctl(fileno(stdin), TIOCSETP, (char *)&sb);
	ioctl(fileno(stdin), FIONBIO, &onoff);
	ioctl(fileno(stdout), FIONBIO, &onoff);
	return (old);
}

hoey@nrl-aic.arpa (Dan Hoey) (08/14/87)

    Date: Tue, 9 Jun 87 07:39:24 EDT
    From: scott@gateway.mitre.ORG
    Message-Id: <8706091139.AA00676@vlsi-a.mitre.org>
    To: unix-wizards@BRL.ARPA
    Subject: Telnet flow control

    ...The problem is that the distributed telnet turns off local flow
    control (UCB telnet that is, I can't speak for other telnets).  Here is
    a modified ``mode'' function taken from a 4.2bsd telnet that reinstates
    local flow control....

		John <scott@gateway.mitre.org>

    ...
		tc = &notc;
		tc->t_stopc = otc.t_stopc;		/* hacks to allow */
		tc->t_startc = otc.t_startc;		/* flow control */
		ltc = &noltc;
    ....

Well, I got the same complaints, but I am *not* willing to forgo the
ability to send ^S/^Q to the remote host.  The easy way to do this was
to also copy the ^V (literal-next) out of the terminal characteristics.
So if you want to send ^S, ^Q, or ^V over the telnet, you precede them
with ^V.

Since this would annoy people people who just want to type ^S and damn
the flow control, I put the whole thing under control of a telnet flag
(-x) and command (xonxoff) that toggles the state.  The relevant
section of the mode routine then looks like

    ...
	    tc = &notc;
	    ltc = &noltc;
	    if (xonxoff) {
		tc -> t_startc = otc.t_startc;
		tc -> t_stopc = otc.t_stopc;
		ltc -> t_lnextc = oltc.t_lnextc;
	    }
	    else
		tc -> t_startc = tc -> t_stopc = ltc -> t_lnextc = -1;

    ....

Maybe when I fit it into 4.3 I'll send the fixes to Berkeley, though
after the CRLF wars I'm not sure they'll want to listen.

Dan Hoey
Internet: HOEY@NRL-AIC.ARPA
UUCP: IICP: WEALLCP: for MCP