[net.bugs.4bsd] 4.2BSD user telnet can't send return when in local-echo mode

guyton@randvax.UUCP (Jim Guyton) (01/11/85)

Description:
	4.2BSD user telnet can't talk to some half-duplex hosts.
	When telnet puts the user's terminal into local-echo mode, it
	also turns on CRMOD.  This has the effect of turning CR into
	LF on input, and LF into CRLF on output -- when talking to
	the terminal.  Unfortunately, this also has the effect of
	turning CR from the terminal into LF for the remote host,
	making it impossible to send a real carriage-return when you
	are in local-echo mode.  Some hosts will take either CR or
	LF as end-of-line, but if a host requires CR to end a line,
	you're out of luck.

Repeat-By:
	Connect to host "ucl" and wait for the "UCL: " prompt.  Then
	type "help" return.  If you get a help menu, then all's ok
	and you don't have this problem.  If it just sits there, then
	you could use this fix.

Fix:
	Keep track of whether or not the input tty has the CRMOD
	bit turned on.  If it does, then map input LF characters
	to CRLF.  Also included in this diff is an older fix than
	forced CRLF to be sent when the user types CR.

*** old-telnet.c  Thu Jan 10 22:55:51 1985
--- telnet.c        Thu Jan 10 22:51:28 1985
***************
*** 40,45
  int	options;
  int	debug = 0;
  int	crmod = 0;
  char	*prompt;
  char	escape = CTRL(]);
  

--- 40,46 -----
  int	options;
  int	debug = 0;
  int	crmod = 0;
+ int   in_crmod = 0;           /* input tty has crmod turned on */
  char	*prompt;
  char	escape = CTRL(]);
  
***************
*** 112,117
  	ioctl(0, TIOCGETP, (char *)&ottyb);
  	ioctl(0, TIOCGETC, (char *)&otc);
  	ioctl(0, TIOCGLTC, (char *)&oltc);
  	setbuf(stdin, 0);
  	setbuf(stdout, 0);
  	prompt = argv[0];

--- 113,119 -----
  	ioctl(0, TIOCGETP, (char *)&ottyb);
  	ioctl(0, TIOCGETC, (char *)&otc);
  	ioctl(0, TIOCGLTC, (char *)&oltc);
+ 	in_crmod = ottyb.sg_flags & CRMOD;
  	setbuf(stdin, 0);
  	setbuf(stdout, 0);
  	prompt = argv[0];
***************
*** 247,252
  	ioctl(0, TIOCGETP, (char *)&ottyb);
  	ioctl(0, TIOCGETC, (char *)&otc);
  	ioctl(0, TIOCGLTC, (char *)&oltc);
  	(void) mode(save);
  }
  

--- 249,255 -----
  	ioctl(0, TIOCGETP, (char *)&ottyb);
  	ioctl(0, TIOCGETC, (char *)&otc);
  	ioctl(0, TIOCGLTC, (char *)&oltc);
+ 	in_crmod = ottyb.sg_flags & CRMOD;
  	(void) mode(save);
  }
  
***************
*** 364,369
  	ioctl(fileno(stdin), TIOCSETP, (char *)&sb);
  	ioctl(fileno(stdin), FIONBIO, &onoff);
  	ioctl(fileno(stdout), FIONBIO, &onoff);
  	return (old);
  }
  

--- 367,373 -----
  	ioctl(fileno(stdin), TIOCSETP, (char *)&sb);
  	ioctl(fileno(stdin), FIONBIO, &onoff);
  	ioctl(fileno(stdout), FIONBIO, &onoff);
+ 	in_crmod = sb.sg_flags & CRMOD;
  	return (old);
  }
  
***************
*** 443,448
  			}
  			if (c == IAC)
  				*nfrontp++ = c;
  			*nfrontp++ = c;
  		}
  		if ((obits & (1 << s)) && (nfrontp - nbackp) > 0)

--- 447,455 -----
  			}
  			if (c == IAC)
  				*nfrontp++ = c;
+ 
+ 			if (c == '\n' && in_crmod) /* turn lf into crlf */
+ 			      c = '\r';            /* if tty has crmod on */
  			*nfrontp++ = c;
  /* bug: 23 Nov 1983, lwa@mit-csr (added next 2 lines) */
  			if (c == '\r')
***************
*** 444,449
  			if (c == IAC)
  				*nfrontp++ = c;
  			*nfrontp++ = c;
  		}
  		if ((obits & (1 << s)) && (nfrontp - nbackp) > 0)
  			netflush(s);

--- 451,459 -----
  			if (c == '\n' && in_crmod) /* turn lf into crlf */
  			      c = '\r';            /* if tty has crmod on */
  			*nfrontp++ = c;
+ /* bug: 23 Nov 1983, lwa@mit-csr (added next 2 lines) */
+ 			if (c == '\r')
+ 				*nfrontp++ = '\n';
  		}
  		if ((obits & (1 << s)) && (nfrontp - nbackp) > 0)
  			netflush(s);