xref: /original-bsd/libexec/telnetd/state.c (revision c3e32dec)
1 /*
2  * Copyright (c) 1989, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)state.c	8.1 (Berkeley) 06/04/93";
10 #endif /* not lint */
11 
12 #include "telnetd.h"
13 #if	defined(AUTHENTICATION)
14 #include <libtelnet/auth.h>
15 #endif
16 
17 char	doopt[] = { IAC, DO, '%', 'c', 0 };
18 char	dont[] = { IAC, DONT, '%', 'c', 0 };
19 char	will[] = { IAC, WILL, '%', 'c', 0 };
20 char	wont[] = { IAC, WONT, '%', 'c', 0 };
21 int	not42 = 1;
22 
23 /*
24  * Buffer for sub-options, and macros
25  * for suboptions buffer manipulations
26  */
27 unsigned char subbuffer[512], *subpointer= subbuffer, *subend= subbuffer;
28 
29 #define	SB_CLEAR()	subpointer = subbuffer
30 #define	SB_TERM()	{ subend = subpointer; SB_CLEAR(); }
31 #define	SB_ACCUM(c)	if (subpointer < (subbuffer+sizeof subbuffer)) { \
32 				*subpointer++ = (c); \
33 			}
34 #define	SB_GET()	((*subpointer++)&0xff)
35 #define	SB_EOF()	(subpointer >= subend)
36 #define	SB_LEN()	(subend - subpointer)
37 
38 #ifdef	ENV_HACK
39 unsigned char *subsave;
40 #define SB_SAVE()	subsave = subpointer;
41 #define	SB_RESTORE()	subpointer = subsave;
42 #endif
43 
44 
45 /*
46  * State for recv fsm
47  */
48 #define	TS_DATA		0	/* base state */
49 #define	TS_IAC		1	/* look for double IAC's */
50 #define	TS_CR		2	/* CR-LF ->'s CR */
51 #define	TS_SB		3	/* throw away begin's... */
52 #define	TS_SE		4	/* ...end's (suboption negotiation) */
53 #define	TS_WILL		5	/* will option negotiation */
54 #define	TS_WONT		6	/* wont " */
55 #define	TS_DO		7	/* do " */
56 #define	TS_DONT		8	/* dont " */
57 
58 	void
59 telrcv()
60 {
61 	register int c;
62 	static int state = TS_DATA;
63 #if	defined(CRAY2) && defined(UNICOS5)
64 	char *opfrontp = pfrontp;
65 #endif
66 
67 	while (ncc > 0) {
68 		if ((&ptyobuf[BUFSIZ] - pfrontp) < 2)
69 			break;
70 		c = *netip++ & 0377, ncc--;
71 #ifdef	ENCRYPTION
72 		if (decrypt_input)
73 			c = (*decrypt_input)(c);
74 #endif	/* ENCRYPTION */
75 		switch (state) {
76 
77 		case TS_CR:
78 			state = TS_DATA;
79 			/* Strip off \n or \0 after a \r */
80 			if ((c == 0) || (c == '\n')) {
81 				break;
82 			}
83 			/* FALL THROUGH */
84 
85 		case TS_DATA:
86 			if (c == IAC) {
87 				state = TS_IAC;
88 				break;
89 			}
90 			/*
91 			 * We now map \r\n ==> \r for pragmatic reasons.
92 			 * Many client implementations send \r\n when
93 			 * the user hits the CarriageReturn key.
94 			 *
95 			 * We USED to map \r\n ==> \n, since \r\n says
96 			 * that we want to be in column 1 of the next
97 			 * printable line, and \n is the standard
98 			 * unix way of saying that (\r is only good
99 			 * if CRMOD is set, which it normally is).
100 			 */
101 			if ((c == '\r') && his_state_is_wont(TELOPT_BINARY)) {
102 				int nc = *netip;
103 #ifdef	ENCRYPTION
104 				if (decrypt_input)
105 					nc = (*decrypt_input)(nc & 0xff);
106 #endif	/* ENCRYPTION */
107 #ifdef	LINEMODE
108 				/*
109 				 * If we are operating in linemode,
110 				 * convert to local end-of-line.
111 				 */
112 				if (linemode && (ncc > 0) && (('\n' == nc) ||
113 					 ((0 == nc) && tty_iscrnl())) ) {
114 					netip++; ncc--;
115 					c = '\n';
116 				} else
117 #endif
118 				{
119 #ifdef	ENCRYPTION
120 					if (decrypt_input)
121 						(void)(*decrypt_input)(-1);
122 #endif	/* ENCRYPTION */
123 					state = TS_CR;
124 				}
125 			}
126 			*pfrontp++ = c;
127 			break;
128 
129 		case TS_IAC:
130 gotiac:			switch (c) {
131 
132 			/*
133 			 * Send the process on the pty side an
134 			 * interrupt.  Do this with a NULL or
135 			 * interrupt char; depending on the tty mode.
136 			 */
137 			case IP:
138 				DIAG(TD_OPTIONS,
139 					printoption("td: recv IAC", c));
140 				interrupt();
141 				break;
142 
143 			case BREAK:
144 				DIAG(TD_OPTIONS,
145 					printoption("td: recv IAC", c));
146 				sendbrk();
147 				break;
148 
149 			/*
150 			 * Are You There?
151 			 */
152 			case AYT:
153 				DIAG(TD_OPTIONS,
154 					printoption("td: recv IAC", c));
155 				recv_ayt();
156 				break;
157 
158 			/*
159 			 * Abort Output
160 			 */
161 			case AO:
162 			    {
163 				DIAG(TD_OPTIONS,
164 					printoption("td: recv IAC", c));
165 				ptyflush();	/* half-hearted */
166 				init_termbuf();
167 
168 				if (slctab[SLC_AO].sptr &&
169 				    *slctab[SLC_AO].sptr != (cc_t)(_POSIX_VDISABLE)) {
170 				    *pfrontp++ =
171 					(unsigned char)*slctab[SLC_AO].sptr;
172 				}
173 
174 				netclear();	/* clear buffer back */
175 				*nfrontp++ = IAC;
176 				*nfrontp++ = DM;
177 				neturg = nfrontp-1; /* off by one XXX */
178 				DIAG(TD_OPTIONS,
179 					printoption("td: send IAC", DM));
180 				break;
181 			    }
182 
183 			/*
184 			 * Erase Character and
185 			 * Erase Line
186 			 */
187 			case EC:
188 			case EL:
189 			    {
190 				cc_t ch;
191 
192 				DIAG(TD_OPTIONS,
193 					printoption("td: recv IAC", c));
194 				ptyflush();	/* half-hearted */
195 				init_termbuf();
196 				if (c == EC)
197 					ch = *slctab[SLC_EC].sptr;
198 				else
199 					ch = *slctab[SLC_EL].sptr;
200 				if (ch != (cc_t)(_POSIX_VDISABLE))
201 					*pfrontp++ = (unsigned char)ch;
202 				break;
203 			    }
204 
205 			/*
206 			 * Check for urgent data...
207 			 */
208 			case DM:
209 				DIAG(TD_OPTIONS,
210 					printoption("td: recv IAC", c));
211 				SYNCHing = stilloob(net);
212 				settimer(gotDM);
213 				break;
214 
215 
216 			/*
217 			 * Begin option subnegotiation...
218 			 */
219 			case SB:
220 				state = TS_SB;
221 				SB_CLEAR();
222 				continue;
223 
224 			case WILL:
225 				state = TS_WILL;
226 				continue;
227 
228 			case WONT:
229 				state = TS_WONT;
230 				continue;
231 
232 			case DO:
233 				state = TS_DO;
234 				continue;
235 
236 			case DONT:
237 				state = TS_DONT;
238 				continue;
239 			case EOR:
240 				if (his_state_is_will(TELOPT_EOR))
241 					doeof();
242 				break;
243 
244 			/*
245 			 * Handle RFC 10xx Telnet linemode option additions
246 			 * to command stream (EOF, SUSP, ABORT).
247 			 */
248 			case xEOF:
249 				doeof();
250 				break;
251 
252 			case SUSP:
253 				sendsusp();
254 				break;
255 
256 			case ABORT:
257 				sendbrk();
258 				break;
259 
260 			case IAC:
261 				*pfrontp++ = c;
262 				break;
263 			}
264 			state = TS_DATA;
265 			break;
266 
267 		case TS_SB:
268 			if (c == IAC) {
269 				state = TS_SE;
270 			} else {
271 				SB_ACCUM(c);
272 			}
273 			break;
274 
275 		case TS_SE:
276 			if (c != SE) {
277 				if (c != IAC) {
278 					/*
279 					 * bad form of suboption negotiation.
280 					 * handle it in such a way as to avoid
281 					 * damage to local state.  Parse
282 					 * suboption buffer found so far,
283 					 * then treat remaining stream as
284 					 * another command sequence.
285 					 */
286 
287 					/* for DIAGNOSTICS */
288 					SB_ACCUM(IAC);
289 					SB_ACCUM(c);
290 					subpointer -= 2;
291 
292 					SB_TERM();
293 					suboption();
294 					state = TS_IAC;
295 					goto gotiac;
296 				}
297 				SB_ACCUM(c);
298 				state = TS_SB;
299 			} else {
300 				/* for DIAGNOSTICS */
301 				SB_ACCUM(IAC);
302 				SB_ACCUM(SE);
303 				subpointer -= 2;
304 
305 				SB_TERM();
306 				suboption();	/* handle sub-option */
307 				state = TS_DATA;
308 			}
309 			break;
310 
311 		case TS_WILL:
312 			willoption(c);
313 			state = TS_DATA;
314 			continue;
315 
316 		case TS_WONT:
317 			wontoption(c);
318 			state = TS_DATA;
319 			continue;
320 
321 		case TS_DO:
322 			dooption(c);
323 			state = TS_DATA;
324 			continue;
325 
326 		case TS_DONT:
327 			dontoption(c);
328 			state = TS_DATA;
329 			continue;
330 
331 		default:
332 			syslog(LOG_ERR, "telnetd: panic state=%d\n", state);
333 			printf("telnetd: panic state=%d\n", state);
334 			exit(1);
335 		}
336 	}
337 #if	defined(CRAY2) && defined(UNICOS5)
338 	if (!linemode) {
339 		char	xptyobuf[BUFSIZ+NETSLOP];
340 		char	xbuf2[BUFSIZ];
341 		register char *cp;
342 		int n = pfrontp - opfrontp, oc;
343 		bcopy(opfrontp, xptyobuf, n);
344 		pfrontp = opfrontp;
345 		pfrontp += term_input(xptyobuf, pfrontp, n, BUFSIZ+NETSLOP,
346 					xbuf2, &oc, BUFSIZ);
347 		for (cp = xbuf2; oc > 0; --oc)
348 			if ((*nfrontp++ = *cp++) == IAC)
349 				*nfrontp++ = IAC;
350 	}
351 #endif	/* defined(CRAY2) && defined(UNICOS5) */
352 }  /* end of telrcv */
353 
354 /*
355  * The will/wont/do/dont state machines are based on Dave Borman's
356  * Telnet option processing state machine.
357  *
358  * These correspond to the following states:
359  *	my_state = the last negotiated state
360  *	want_state = what I want the state to go to
361  *	want_resp = how many requests I have sent
362  * All state defaults are negative, and resp defaults to 0.
363  *
364  * When initiating a request to change state to new_state:
365  *
366  * if ((want_resp == 0 && new_state == my_state) || want_state == new_state) {
367  *	do nothing;
368  * } else {
369  *	want_state = new_state;
370  *	send new_state;
371  *	want_resp++;
372  * }
373  *
374  * When receiving new_state:
375  *
376  * if (want_resp) {
377  *	want_resp--;
378  *	if (want_resp && (new_state == my_state))
379  *		want_resp--;
380  * }
381  * if ((want_resp == 0) && (new_state != want_state)) {
382  *	if (ok_to_switch_to new_state)
383  *		want_state = new_state;
384  *	else
385  *		want_resp++;
386  *	send want_state;
387  * }
388  * my_state = new_state;
389  *
390  * Note that new_state is implied in these functions by the function itself.
391  * will and do imply positive new_state, wont and dont imply negative.
392  *
393  * Finally, there is one catch.  If we send a negative response to a
394  * positive request, my_state will be the positive while want_state will
395  * remain negative.  my_state will revert to negative when the negative
396  * acknowlegment arrives from the peer.  Thus, my_state generally tells
397  * us not only the last negotiated state, but also tells us what the peer
398  * wants to be doing as well.  It is important to understand this difference
399  * as we may wish to be processing data streams based on our desired state
400  * (want_state) or based on what the peer thinks the state is (my_state).
401  *
402  * This all works fine because if the peer sends a positive request, the data
403  * that we receive prior to negative acknowlegment will probably be affected
404  * by the positive state, and we can process it as such (if we can; if we
405  * can't then it really doesn't matter).  If it is that important, then the
406  * peer probably should be buffering until this option state negotiation
407  * is complete.
408  *
409  */
410 	void
411 send_do(option, init)
412 	int option, init;
413 {
414 	if (init) {
415 		if ((do_dont_resp[option] == 0 && his_state_is_will(option)) ||
416 		    his_want_state_is_will(option))
417 			return;
418 		/*
419 		 * Special case for TELOPT_TM:  We send a DO, but pretend
420 		 * that we sent a DONT, so that we can send more DOs if
421 		 * we want to.
422 		 */
423 		if (option == TELOPT_TM)
424 			set_his_want_state_wont(option);
425 		else
426 			set_his_want_state_will(option);
427 		do_dont_resp[option]++;
428 	}
429 	(void) sprintf(nfrontp, doopt, option);
430 	nfrontp += sizeof (dont) - 2;
431 
432 	DIAG(TD_OPTIONS, printoption("td: send do", option));
433 }
434 
435 #ifdef	AUTHENTICATION
436 extern void auth_request();
437 #endif
438 #ifdef	LINEMODE
439 extern void doclientstat();
440 #endif
441 #ifdef	ENCRYPTION
442 extern void encrypt_send_support();
443 #endif	/* ENCRYPTION */
444 
445 	void
446 willoption(option)
447 	int option;
448 {
449 	int changeok = 0;
450 	void (*func)() = 0;
451 
452 	/*
453 	 * process input from peer.
454 	 */
455 
456 	DIAG(TD_OPTIONS, printoption("td: recv will", option));
457 
458 	if (do_dont_resp[option]) {
459 		do_dont_resp[option]--;
460 		if (do_dont_resp[option] && his_state_is_will(option))
461 			do_dont_resp[option]--;
462 	}
463 	if (do_dont_resp[option] == 0) {
464 	    if (his_want_state_is_wont(option)) {
465 		switch (option) {
466 
467 		case TELOPT_BINARY:
468 			init_termbuf();
469 			tty_binaryin(1);
470 			set_termbuf();
471 			changeok++;
472 			break;
473 
474 		case TELOPT_ECHO:
475 			/*
476 			 * See comments below for more info.
477 			 */
478 			not42 = 0;	/* looks like a 4.2 system */
479 			break;
480 
481 		case TELOPT_TM:
482 #if	defined(LINEMODE) && defined(KLUDGELINEMODE)
483 			/*
484 			 * This telnetd implementation does not really
485 			 * support timing marks, it just uses them to
486 			 * support the kludge linemode stuff.  If we
487 			 * receive a will or wont TM in response to our
488 			 * do TM request that may have been sent to
489 			 * determine kludge linemode support, process
490 			 * it, otherwise TM should get a negative
491 			 * response back.
492 			 */
493 			/*
494 			 * Handle the linemode kludge stuff.
495 			 * If we are not currently supporting any
496 			 * linemode at all, then we assume that this
497 			 * is the client telling us to use kludge
498 			 * linemode in response to our query.  Set the
499 			 * linemode type that is to be supported, note
500 			 * that the client wishes to use linemode, and
501 			 * eat the will TM as though it never arrived.
502 			 */
503 			if (lmodetype < KLUDGE_LINEMODE) {
504 				lmodetype = KLUDGE_LINEMODE;
505 				clientstat(TELOPT_LINEMODE, WILL, 0);
506 				send_wont(TELOPT_SGA, 1);
507 			} else if (lmodetype == NO_AUTOKLUDGE) {
508 				lmodetype = KLUDGE_OK;
509 			}
510 #endif	/* defined(LINEMODE) && defined(KLUDGELINEMODE) */
511 			/*
512 			 * We never respond to a WILL TM, and
513 			 * we leave the state WONT.
514 			 */
515 			return;
516 
517 		case TELOPT_LFLOW:
518 			/*
519 			 * If we are going to support flow control
520 			 * option, then don't worry peer that we can't
521 			 * change the flow control characters.
522 			 */
523 			slctab[SLC_XON].defset.flag &= ~SLC_LEVELBITS;
524 			slctab[SLC_XON].defset.flag |= SLC_DEFAULT;
525 			slctab[SLC_XOFF].defset.flag &= ~SLC_LEVELBITS;
526 			slctab[SLC_XOFF].defset.flag |= SLC_DEFAULT;
527 		case TELOPT_TTYPE:
528 		case TELOPT_SGA:
529 		case TELOPT_NAWS:
530 		case TELOPT_TSPEED:
531 		case TELOPT_XDISPLOC:
532 		case TELOPT_ENVIRON:
533 			changeok++;
534 			break;
535 
536 #ifdef	LINEMODE
537 		case TELOPT_LINEMODE:
538 # ifdef	KLUDGELINEMODE
539 			/*
540 			 * Note client's desire to use linemode.
541 			 */
542 			lmodetype = REAL_LINEMODE;
543 # endif	/* KLUDGELINEMODE */
544 			func = doclientstat;
545 			changeok++;
546 			break;
547 #endif	/* LINEMODE */
548 
549 #ifdef	AUTHENTICATION
550 		case TELOPT_AUTHENTICATION:
551 			func = auth_request;
552 			changeok++;
553 			break;
554 #endif
555 
556 #ifdef	ENCRYPTION
557 		case TELOPT_ENCRYPT:
558 			func = encrypt_send_support;
559 			changeok++;
560 			break;
561 #endif	/* ENCRYPTION */
562 
563 		default:
564 			break;
565 		}
566 		if (changeok) {
567 			set_his_want_state_will(option);
568 			send_do(option, 0);
569 		} else {
570 			do_dont_resp[option]++;
571 			send_dont(option, 0);
572 		}
573 	    } else {
574 		/*
575 		 * Option processing that should happen when
576 		 * we receive conformation of a change in
577 		 * state that we had requested.
578 		 */
579 		switch (option) {
580 		case TELOPT_ECHO:
581 			not42 = 0;	/* looks like a 4.2 system */
582 			/*
583 			 * Egads, he responded "WILL ECHO".  Turn
584 			 * it off right now!
585 			 */
586 			send_dont(option, 1);
587 			/*
588 			 * "WILL ECHO".  Kludge upon kludge!
589 			 * A 4.2 client is now echoing user input at
590 			 * the tty.  This is probably undesireable and
591 			 * it should be stopped.  The client will
592 			 * respond WONT TM to the DO TM that we send to
593 			 * check for kludge linemode.  When the WONT TM
594 			 * arrives, linemode will be turned off and a
595 			 * change propogated to the pty.  This change
596 			 * will cause us to process the new pty state
597 			 * in localstat(), which will notice that
598 			 * linemode is off and send a WILL ECHO
599 			 * so that we are properly in character mode and
600 			 * all is well.
601 			 */
602 			break;
603 #ifdef	LINEMODE
604 		case TELOPT_LINEMODE:
605 # ifdef	KLUDGELINEMODE
606 			/*
607 			 * Note client's desire to use linemode.
608 			 */
609 			lmodetype = REAL_LINEMODE;
610 # endif	/* KLUDGELINEMODE */
611 			func = doclientstat;
612 			break;
613 #endif	/* LINEMODE */
614 
615 #ifdef	AUTHENTICATION
616 		case TELOPT_AUTHENTICATION:
617 			func = auth_request;
618 			break;
619 #endif
620 
621 #ifdef	ENCRYPTION
622 		case TELOPT_ENCRYPT:
623 			func = encrypt_send_support;
624 			break;
625 #endif	/* ENCRYPTION */
626 		case TELOPT_LFLOW:
627 			func = flowstat;
628 			break;
629 		}
630 	    }
631 	}
632 	set_his_state_will(option);
633 	if (func)
634 		(*func)();
635 }  /* end of willoption */
636 
637 	void
638 send_dont(option, init)
639 	int option, init;
640 {
641 	if (init) {
642 		if ((do_dont_resp[option] == 0 && his_state_is_wont(option)) ||
643 		    his_want_state_is_wont(option))
644 			return;
645 		set_his_want_state_wont(option);
646 		do_dont_resp[option]++;
647 	}
648 	(void) sprintf(nfrontp, dont, option);
649 	nfrontp += sizeof (doopt) - 2;
650 
651 	DIAG(TD_OPTIONS, printoption("td: send dont", option));
652 }
653 
654 	void
655 wontoption(option)
656 	int option;
657 {
658 	/*
659 	 * Process client input.
660 	 */
661 
662 	DIAG(TD_OPTIONS, printoption("td: recv wont", option));
663 
664 	if (do_dont_resp[option]) {
665 		do_dont_resp[option]--;
666 		if (do_dont_resp[option] && his_state_is_wont(option))
667 			do_dont_resp[option]--;
668 	}
669 	if (do_dont_resp[option] == 0) {
670 	    if (his_want_state_is_will(option)) {
671 		/* it is always ok to change to negative state */
672 		switch (option) {
673 		case TELOPT_ECHO:
674 			not42 = 1; /* doesn't seem to be a 4.2 system */
675 			break;
676 
677 		case TELOPT_BINARY:
678 			init_termbuf();
679 			tty_binaryin(0);
680 			set_termbuf();
681 			break;
682 
683 #ifdef	LINEMODE
684 		case TELOPT_LINEMODE:
685 # ifdef	KLUDGELINEMODE
686 			/*
687 			 * If real linemode is supported, then client is
688 			 * asking to turn linemode off.
689 			 */
690 			if (lmodetype != REAL_LINEMODE)
691 				break;
692 			lmodetype = KLUDGE_LINEMODE;
693 # endif	/* KLUDGELINEMODE */
694 			clientstat(TELOPT_LINEMODE, WONT, 0);
695 			break;
696 #endif	/* LINEMODE */
697 
698 		case TELOPT_TM:
699 			/*
700 			 * If we get a WONT TM, and had sent a DO TM,
701 			 * don't respond with a DONT TM, just leave it
702 			 * as is.  Short circut the state machine to
703 			 * achive this.
704 			 */
705 			set_his_want_state_wont(TELOPT_TM);
706 			return;
707 
708 		case TELOPT_LFLOW:
709 			/*
710 			 * If we are not going to support flow control
711 			 * option, then let peer know that we can't
712 			 * change the flow control characters.
713 			 */
714 			slctab[SLC_XON].defset.flag &= ~SLC_LEVELBITS;
715 			slctab[SLC_XON].defset.flag |= SLC_CANTCHANGE;
716 			slctab[SLC_XOFF].defset.flag &= ~SLC_LEVELBITS;
717 			slctab[SLC_XOFF].defset.flag |= SLC_CANTCHANGE;
718 			break;
719 
720 #if	defined(AUTHENTICATION)
721 		case TELOPT_AUTHENTICATION:
722 			auth_finished(0, AUTH_REJECT);
723 			break;
724 #endif
725 
726 		/*
727 		 * For options that we might spin waiting for
728 		 * sub-negotiation, if the client turns off the
729 		 * option rather than responding to the request,
730 		 * we have to treat it here as if we got a response
731 		 * to the sub-negotiation, (by updating the timers)
732 		 * so that we'll break out of the loop.
733 		 */
734 		case TELOPT_TTYPE:
735 			settimer(ttypesubopt);
736 			break;
737 
738 		case TELOPT_TSPEED:
739 			settimer(tspeedsubopt);
740 			break;
741 
742 		case TELOPT_XDISPLOC:
743 			settimer(xdisplocsubopt);
744 			break;
745 
746 		case TELOPT_ENVIRON:
747 			settimer(environsubopt);
748 			break;
749 
750 		default:
751 			break;
752 		}
753 		set_his_want_state_wont(option);
754 		if (his_state_is_will(option))
755 			send_dont(option, 0);
756 	    } else {
757 		switch (option) {
758 		case TELOPT_TM:
759 #if	defined(LINEMODE) && defined(KLUDGELINEMODE)
760 			if (lmodetype < NO_AUTOKLUDGE) {
761 				lmodetype = NO_LINEMODE;
762 				clientstat(TELOPT_LINEMODE, WONT, 0);
763 				send_will(TELOPT_SGA, 1);
764 				send_will(TELOPT_ECHO, 1);
765 			}
766 #endif	/* defined(LINEMODE) && defined(KLUDGELINEMODE) */
767 			break;
768 
769 #if	defined(AUTHENTICATION)
770 		case TELOPT_AUTHENTICATION:
771 			auth_finished(0, AUTH_REJECT);
772 			break;
773 #endif
774 		default:
775 			break;
776 		}
777 	    }
778 	}
779 	set_his_state_wont(option);
780 
781 }  /* end of wontoption */
782 
783 	void
784 send_will(option, init)
785 	int option, init;
786 {
787 	if (init) {
788 		if ((will_wont_resp[option] == 0 && my_state_is_will(option))||
789 		    my_want_state_is_will(option))
790 			return;
791 		set_my_want_state_will(option);
792 		will_wont_resp[option]++;
793 	}
794 	(void) sprintf(nfrontp, will, option);
795 	nfrontp += sizeof (doopt) - 2;
796 
797 	DIAG(TD_OPTIONS, printoption("td: send will", option));
798 }
799 
800 #if	!defined(LINEMODE) || !defined(KLUDGELINEMODE)
801 /*
802  * When we get a DONT SGA, we will try once to turn it
803  * back on.  If the other side responds DONT SGA, we
804  * leave it at that.  This is so that when we talk to
805  * clients that understand KLUDGELINEMODE but not LINEMODE,
806  * we'll keep them in char-at-a-time mode.
807  */
808 int turn_on_sga = 0;
809 #endif
810 
811 	void
812 dooption(option)
813 	int option;
814 {
815 	int changeok = 0;
816 
817 	/*
818 	 * Process client input.
819 	 */
820 
821 	DIAG(TD_OPTIONS, printoption("td: recv do", option));
822 
823 	if (will_wont_resp[option]) {
824 		will_wont_resp[option]--;
825 		if (will_wont_resp[option] && my_state_is_will(option))
826 			will_wont_resp[option]--;
827 	}
828 	if ((will_wont_resp[option] == 0) && (my_want_state_is_wont(option))) {
829 		switch (option) {
830 		case TELOPT_ECHO:
831 #ifdef	LINEMODE
832 # ifdef	KLUDGELINEMODE
833 			if (lmodetype == NO_LINEMODE)
834 # else
835 			if (his_state_is_wont(TELOPT_LINEMODE))
836 # endif
837 #endif
838 			{
839 				init_termbuf();
840 				tty_setecho(1);
841 				set_termbuf();
842 			}
843 			changeok++;
844 			break;
845 
846 		case TELOPT_BINARY:
847 			init_termbuf();
848 			tty_binaryout(1);
849 			set_termbuf();
850 			changeok++;
851 			break;
852 
853 		case TELOPT_SGA:
854 #if	defined(LINEMODE) && defined(KLUDGELINEMODE)
855 			/*
856 			 * If kludge linemode is in use, then we must
857 			 * process an incoming do SGA for linemode
858 			 * purposes.
859 			 */
860 			if (lmodetype == KLUDGE_LINEMODE) {
861 				/*
862 				 * Receipt of "do SGA" in kludge
863 				 * linemode is the peer asking us to
864 				 * turn off linemode.  Make note of
865 				 * the request.
866 				 */
867 				clientstat(TELOPT_LINEMODE, WONT, 0);
868 				/*
869 				 * If linemode did not get turned off
870 				 * then don't tell peer that we did.
871 				 * Breaking here forces a wont SGA to
872 				 * be returned.
873 				 */
874 				if (linemode)
875 					break;
876 			}
877 #else
878 			turn_on_sga = 0;
879 #endif	/* defined(LINEMODE) && defined(KLUDGELINEMODE) */
880 			changeok++;
881 			break;
882 
883 		case TELOPT_STATUS:
884 			changeok++;
885 			break;
886 
887 		case TELOPT_TM:
888 			/*
889 			 * Special case for TM.  We send a WILL, but
890 			 * pretend we sent a WONT.
891 			 */
892 			send_will(option, 0);
893 			set_my_want_state_wont(option);
894 			set_my_state_wont(option);
895 			return;
896 
897 		case TELOPT_LOGOUT:
898 			/*
899 			 * When we get a LOGOUT option, respond
900 			 * with a WILL LOGOUT, make sure that
901 			 * it gets written out to the network,
902 			 * and then just go away...
903 			 */
904 			set_my_want_state_will(TELOPT_LOGOUT);
905 			send_will(TELOPT_LOGOUT, 0);
906 			set_my_state_will(TELOPT_LOGOUT);
907 			(void)netflush();
908 			cleanup(0);
909 			/* NOT REACHED */
910 			break;
911 
912 #ifdef	ENCRYPTION
913 		case TELOPT_ENCRYPT:
914 			changeok++;
915 			break;
916 #endif	/* ENCRYPTION */
917 		case TELOPT_LINEMODE:
918 		case TELOPT_TTYPE:
919 		case TELOPT_NAWS:
920 		case TELOPT_TSPEED:
921 		case TELOPT_LFLOW:
922 		case TELOPT_XDISPLOC:
923 		case TELOPT_ENVIRON:
924 		default:
925 			break;
926 		}
927 		if (changeok) {
928 			set_my_want_state_will(option);
929 			send_will(option, 0);
930 		} else {
931 			will_wont_resp[option]++;
932 			send_wont(option, 0);
933 		}
934 	}
935 	set_my_state_will(option);
936 
937 }  /* end of dooption */
938 
939 	void
940 send_wont(option, init)
941 	int option, init;
942 {
943 	if (init) {
944 		if ((will_wont_resp[option] == 0 && my_state_is_wont(option)) ||
945 		    my_want_state_is_wont(option))
946 			return;
947 		set_my_want_state_wont(option);
948 		will_wont_resp[option]++;
949 	}
950 	(void) sprintf(nfrontp, wont, option);
951 	nfrontp += sizeof (wont) - 2;
952 
953 	DIAG(TD_OPTIONS, printoption("td: send wont", option));
954 }
955 
956 	void
957 dontoption(option)
958 	int option;
959 {
960 	/*
961 	 * Process client input.
962 	 */
963 
964 
965 	DIAG(TD_OPTIONS, printoption("td: recv dont", option));
966 
967 	if (will_wont_resp[option]) {
968 		will_wont_resp[option]--;
969 		if (will_wont_resp[option] && my_state_is_wont(option))
970 			will_wont_resp[option]--;
971 	}
972 	if ((will_wont_resp[option] == 0) && (my_want_state_is_will(option))) {
973 		switch (option) {
974 		case TELOPT_BINARY:
975 			init_termbuf();
976 			tty_binaryout(0);
977 			set_termbuf();
978 			break;
979 
980 		case TELOPT_ECHO:	/* we should stop echoing */
981 #ifdef	LINEMODE
982 # ifdef	KLUDGELINEMODE
983 			if ((lmodetype != REAL_LINEMODE) &&
984 			    (lmodetype != KLUDGE_LINEMODE))
985 # else
986 			if (his_state_is_wont(TELOPT_LINEMODE))
987 # endif
988 #endif
989 			{
990 				init_termbuf();
991 				tty_setecho(0);
992 				set_termbuf();
993 			}
994 			break;
995 
996 		case TELOPT_SGA:
997 #if	defined(LINEMODE) && defined(KLUDGELINEMODE)
998 			/*
999 			 * If kludge linemode is in use, then we
1000 			 * must process an incoming do SGA for
1001 			 * linemode purposes.
1002 			 */
1003 			if ((lmodetype == KLUDGE_LINEMODE) ||
1004 			    (lmodetype == KLUDGE_OK)) {
1005 				/*
1006 				 * The client is asking us to turn
1007 				 * linemode on.
1008 				 */
1009 				lmodetype = KLUDGE_LINEMODE;
1010 				clientstat(TELOPT_LINEMODE, WILL, 0);
1011 				/*
1012 				 * If we did not turn line mode on,
1013 				 * then what do we say?  Will SGA?
1014 				 * This violates design of telnet.
1015 				 * Gross.  Very Gross.
1016 				 */
1017 			}
1018 			break;
1019 #else
1020 			set_my_want_state_wont(option);
1021 			if (my_state_is_will(option))
1022 				send_wont(option, 0);
1023 			set_my_state_wont(option);
1024 			if (turn_on_sga ^= 1)
1025 				send_will(option, 1);
1026 			return;
1027 #endif	/* defined(LINEMODE) && defined(KLUDGELINEMODE) */
1028 
1029 		default:
1030 			break;
1031 		}
1032 
1033 		set_my_want_state_wont(option);
1034 		if (my_state_is_will(option))
1035 			send_wont(option, 0);
1036 	}
1037 	set_my_state_wont(option);
1038 
1039 }  /* end of dontoption */
1040 
1041 #ifdef	ENV_HACK
1042 int env_var = -1;
1043 int env_value = -1;
1044 #else	/* ENV_HACK */
1045 # define env_var ENV_VAR
1046 # define env_value ENV_VALUE
1047 #endif	/* ENV_HACK */
1048 
1049 /*
1050  * suboption()
1051  *
1052  *	Look at the sub-option buffer, and try to be helpful to the other
1053  * side.
1054  *
1055  *	Currently we recognize:
1056  *
1057  *	Terminal type is
1058  *	Linemode
1059  *	Window size
1060  *	Terminal speed
1061  */
1062 	void
1063 suboption()
1064 {
1065     register int subchar;
1066 
1067     DIAG(TD_OPTIONS, {netflush(); printsub('<', subpointer, SB_LEN()+2);});
1068 
1069     subchar = SB_GET();
1070     switch (subchar) {
1071     case TELOPT_TSPEED: {
1072 	register int xspeed, rspeed;
1073 
1074 	if (his_state_is_wont(TELOPT_TSPEED))	/* Ignore if option disabled */
1075 		break;
1076 
1077 	settimer(tspeedsubopt);
1078 
1079 	if (SB_EOF() || SB_GET() != TELQUAL_IS)
1080 		return;
1081 
1082 	xspeed = atoi((char *)subpointer);
1083 
1084 	while (SB_GET() != ',' && !SB_EOF());
1085 	if (SB_EOF())
1086 		return;
1087 
1088 	rspeed = atoi((char *)subpointer);
1089 	clientstat(TELOPT_TSPEED, xspeed, rspeed);
1090 
1091 	break;
1092 
1093     }  /* end of case TELOPT_TSPEED */
1094 
1095     case TELOPT_TTYPE: {		/* Yaaaay! */
1096 	static char terminalname[41];
1097 
1098 	if (his_state_is_wont(TELOPT_TTYPE))	/* Ignore if option disabled */
1099 		break;
1100 	settimer(ttypesubopt);
1101 
1102 	if (SB_EOF() || SB_GET() != TELQUAL_IS) {
1103 	    return;		/* ??? XXX but, this is the most robust */
1104 	}
1105 
1106 	terminaltype = terminalname;
1107 
1108 	while ((terminaltype < (terminalname + sizeof terminalname-1)) &&
1109 								    !SB_EOF()) {
1110 	    register int c;
1111 
1112 	    c = SB_GET();
1113 	    if (isupper(c)) {
1114 		c = tolower(c);
1115 	    }
1116 	    *terminaltype++ = c;    /* accumulate name */
1117 	}
1118 	*terminaltype = 0;
1119 	terminaltype = terminalname;
1120 	break;
1121     }  /* end of case TELOPT_TTYPE */
1122 
1123     case TELOPT_NAWS: {
1124 	register int xwinsize, ywinsize;
1125 
1126 	if (his_state_is_wont(TELOPT_NAWS))	/* Ignore if option disabled */
1127 		break;
1128 
1129 	if (SB_EOF())
1130 		return;
1131 	xwinsize = SB_GET() << 8;
1132 	if (SB_EOF())
1133 		return;
1134 	xwinsize |= SB_GET();
1135 	if (SB_EOF())
1136 		return;
1137 	ywinsize = SB_GET() << 8;
1138 	if (SB_EOF())
1139 		return;
1140 	ywinsize |= SB_GET();
1141 	clientstat(TELOPT_NAWS, xwinsize, ywinsize);
1142 
1143 	break;
1144 
1145     }  /* end of case TELOPT_NAWS */
1146 
1147 #ifdef	LINEMODE
1148     case TELOPT_LINEMODE: {
1149 	register int request;
1150 
1151 	if (his_state_is_wont(TELOPT_LINEMODE))	/* Ignore if option disabled */
1152 		break;
1153 	/*
1154 	 * Process linemode suboptions.
1155 	 */
1156 	if (SB_EOF())
1157 	    break;		/* garbage was sent */
1158 	request = SB_GET();	/* get will/wont */
1159 
1160 	if (SB_EOF())
1161 	    break;		/* another garbage check */
1162 
1163 	if (request == LM_SLC) {  /* SLC is not preceeded by WILL or WONT */
1164 		/*
1165 		 * Process suboption buffer of slc's
1166 		 */
1167 		start_slc(1);
1168 		do_opt_slc(subpointer, subend - subpointer);
1169 		(void) end_slc(0);
1170 		break;
1171 	} else if (request == LM_MODE) {
1172 		if (SB_EOF())
1173 		    return;
1174 		useeditmode = SB_GET();  /* get mode flag */
1175 		clientstat(LM_MODE, 0, 0);
1176 		break;
1177 	}
1178 
1179 	if (SB_EOF())
1180 	    break;
1181 	switch (SB_GET()) {  /* what suboption? */
1182 	case LM_FORWARDMASK:
1183 		/*
1184 		 * According to spec, only server can send request for
1185 		 * forwardmask, and client can only return a positive response.
1186 		 * So don't worry about it.
1187 		 */
1188 
1189 	default:
1190 		break;
1191 	}
1192 	break;
1193     }  /* end of case TELOPT_LINEMODE */
1194 #endif
1195     case TELOPT_STATUS: {
1196 	int mode;
1197 
1198 	if (SB_EOF())
1199 	    break;
1200 	mode = SB_GET();
1201 	switch (mode) {
1202 	case TELQUAL_SEND:
1203 	    if (my_state_is_will(TELOPT_STATUS))
1204 		send_status();
1205 	    break;
1206 
1207 	case TELQUAL_IS:
1208 	    break;
1209 
1210 	default:
1211 	    break;
1212 	}
1213 	break;
1214     }  /* end of case TELOPT_STATUS */
1215 
1216     case TELOPT_XDISPLOC: {
1217 	if (SB_EOF() || SB_GET() != TELQUAL_IS)
1218 		return;
1219 	settimer(xdisplocsubopt);
1220 	subpointer[SB_LEN()] = '\0';
1221 	(void)setenv("DISPLAY", (char *)subpointer, 1);
1222 	break;
1223     }  /* end of case TELOPT_XDISPLOC */
1224 
1225     case TELOPT_ENVIRON: {
1226 	register int c;
1227 	register char *cp, *varp, *valp;
1228 
1229 	if (SB_EOF())
1230 		return;
1231 	c = SB_GET();
1232 	if (c == TELQUAL_IS)
1233 		settimer(environsubopt);
1234 	else if (c != TELQUAL_INFO)
1235 		return;
1236 
1237 #ifdef	ENV_HACK
1238 	/*
1239 	 * We only want to do this if we haven't already decided
1240 	 * whether or not the other side has its VALUE and VAR
1241 	 * reversed.
1242 	 */
1243 	if (env_var < 0) {
1244 		register int last = -1;		/* invalid value */
1245 		int empty = 0;
1246 		int got_var = 0, got_value = 0, got_uservar = 0;
1247 
1248 		/*
1249 		 * The other side might have its VALUE and VAR values
1250 		 * reversed.  To be interoperable, we need to determine
1251 		 * which way it is.  If the first recognized character
1252 		 * is a VAR or VALUE, then that will tell us what
1253 		 * type of client it is.  If the fist recognized
1254 		 * character is a USERVAR, then we continue scanning
1255 		 * the suboption looking for two consecutive
1256 		 * VAR or VALUE fields.  We should not get two
1257 		 * consecutive VALUE fields, so finding two
1258 		 * consecutive VALUE or VAR fields will tell us
1259 		 * what the client is.
1260 		 */
1261 		SB_SAVE();
1262 		while (!SB_EOF()) {
1263 			c = SB_GET();
1264 			switch(c) {
1265 			case ENV_VAR:
1266 				if (last < 0 || last == ENV_VAR
1267 				    || (empty && (last == ENV_VALUE)))
1268 					goto env_var_ok;
1269 				got_var++;
1270 				last = ENV_VAR;
1271 				break;
1272 			case ENV_VALUE:
1273 				if (last < 0 || last == ENV_VALUE
1274 				    || (empty && (last == ENV_VAR)))
1275 					goto env_var_wrong;
1276 				got_value++;
1277 				last = ENV_VALUE;
1278 				break;
1279 			case ENV_USERVAR:
1280 				/* count strings of USERVAR as one */
1281 				if (last != ENV_USERVAR)
1282 					got_uservar++;
1283 				if (empty) {
1284 					if (last == ENV_VALUE)
1285 						goto env_var_ok;
1286 					if (last == ENV_VAR)
1287 						goto env_var_wrong;
1288 				}
1289 				last = ENV_USERVAR;
1290 				break;
1291 			case ENV_ESC:
1292 				if (!SB_EOF())
1293 					c = SB_GET();
1294 				/* FALL THROUGH */
1295 			default:
1296 				empty = 0;
1297 				continue;
1298 			}
1299 			empty = 1;
1300 		}
1301 		if (empty) {
1302 			if (last == ENV_VALUE)
1303 				goto env_var_ok;
1304 			if (last == ENV_VAR)
1305 				goto env_var_wrong;
1306 		}
1307 		/*
1308 		 * Ok, the first thing was a USERVAR, and there
1309 		 * are not two consecutive VAR or VALUE commands,
1310 		 * and none of the VAR or VALUE commands are empty.
1311 		 * If the client has sent us a well-formed option,
1312 		 * then the number of VALUEs received should always
1313 		 * be less than or equal to the number of VARs and
1314 		 * USERVARs received.
1315 		 *
1316 		 * If we got exactly as many VALUEs as VARs and
1317 		 * USERVARs, the client has the same definitions.
1318 		 *
1319 		 * If we got exactly as many VARs as VALUEs and
1320 		 * USERVARS, the client has reversed definitions.
1321 		 */
1322 		if (got_uservar + got_var == got_value) {
1323 	    env_var_ok:
1324 			env_var = ENV_VAR;
1325 			env_value = ENV_VALUE;
1326 		} else if (got_uservar + got_value == got_var) {
1327 	    env_var_wrong:
1328 			env_var = ENV_VALUE;
1329 			env_value = ENV_VAR;
1330 			DIAG(TD_OPTIONS, {sprintf(nfrontp,
1331 				"ENVIRON VALUE and VAR are reversed!\r\n");
1332 				nfrontp += strlen(nfrontp);});
1333 
1334 		}
1335 	}
1336 	SB_RESTORE();
1337 #endif
1338 
1339 	while (!SB_EOF()) {
1340 		c = SB_GET();
1341 		if ((c == env_var) || (c == ENV_USERVAR))
1342 			break;
1343 	}
1344 
1345 	if (SB_EOF())
1346 		return;
1347 
1348 	cp = varp = (char *)subpointer;
1349 	valp = 0;
1350 
1351 	while (!SB_EOF()) {
1352 		c = SB_GET();
1353 #ifdef	ENV_HACK
1354 		if (c == env_var)
1355 			c = ENV_VAR;
1356 		else if (c == env_value)
1357 			c = ENV_VALUE;
1358 #endif
1359 		switch (c) {
1360 
1361 		case ENV_VALUE:
1362 			*cp = '\0';
1363 			cp = valp = (char *)subpointer;
1364 			break;
1365 
1366 		case ENV_VAR:
1367 		case ENV_USERVAR:
1368 			*cp = '\0';
1369 			if (valp)
1370 				(void)setenv(varp, valp, 1);
1371 			else
1372 				unsetenv(varp);
1373 			cp = varp = (char *)subpointer;
1374 			valp = 0;
1375 			break;
1376 
1377 		case ENV_ESC:
1378 			if (SB_EOF())
1379 				break;
1380 			c = SB_GET();
1381 			/* FALL THROUGH */
1382 		default:
1383 			*cp++ = c;
1384 			break;
1385 		}
1386 	}
1387 	*cp = '\0';
1388 	if (valp)
1389 		(void)setenv(varp, valp, 1);
1390 	else
1391 		unsetenv(varp);
1392 	break;
1393     }  /* end of case TELOPT_ENVIRON */
1394 #if	defined(AUTHENTICATION)
1395     case TELOPT_AUTHENTICATION:
1396 	if (SB_EOF())
1397 		break;
1398 	switch(SB_GET()) {
1399 	case TELQUAL_SEND:
1400 	case TELQUAL_REPLY:
1401 		/*
1402 		 * These are sent by us and cannot be sent by
1403 		 * the client.
1404 		 */
1405 		break;
1406 	case TELQUAL_IS:
1407 		auth_is(subpointer, SB_LEN());
1408 		break;
1409 	case TELQUAL_NAME:
1410 		auth_name(subpointer, SB_LEN());
1411 		break;
1412 	}
1413 	break;
1414 #endif
1415 #ifdef	ENCRYPTION
1416     case TELOPT_ENCRYPT:
1417 	if (SB_EOF())
1418 		break;
1419 	switch(SB_GET()) {
1420 	case ENCRYPT_SUPPORT:
1421 		encrypt_support(subpointer, SB_LEN());
1422 		break;
1423 	case ENCRYPT_IS:
1424 		encrypt_is(subpointer, SB_LEN());
1425 		break;
1426 	case ENCRYPT_REPLY:
1427 		encrypt_reply(subpointer, SB_LEN());
1428 		break;
1429 	case ENCRYPT_START:
1430 		encrypt_start(subpointer, SB_LEN());
1431 		break;
1432 	case ENCRYPT_END:
1433 		encrypt_end();
1434 		break;
1435 	case ENCRYPT_REQSTART:
1436 		encrypt_request_start(subpointer, SB_LEN());
1437 		break;
1438 	case ENCRYPT_REQEND:
1439 		/*
1440 		 * We can always send an REQEND so that we cannot
1441 		 * get stuck encrypting.  We should only get this
1442 		 * if we have been able to get in the correct mode
1443 		 * anyhow.
1444 		 */
1445 		encrypt_request_end();
1446 		break;
1447 	case ENCRYPT_ENC_KEYID:
1448 		encrypt_enc_keyid(subpointer, SB_LEN());
1449 		break;
1450 	case ENCRYPT_DEC_KEYID:
1451 		encrypt_dec_keyid(subpointer, SB_LEN());
1452 		break;
1453 	default:
1454 		break;
1455 	}
1456 	break;
1457 #endif	/* ENCRYPTION */
1458 
1459     default:
1460 	break;
1461     }  /* end of switch */
1462 
1463 }  /* end of suboption */
1464 
1465 	void
1466 doclientstat()
1467 {
1468 	clientstat(TELOPT_LINEMODE, WILL, 0);
1469 }
1470 
1471 #define	ADD(c)	 *ncp++ = c;
1472 #define	ADD_DATA(c) { *ncp++ = c; if (c == SE) *ncp++ = c; }
1473 	void
1474 send_status()
1475 {
1476 	unsigned char statusbuf[256];
1477 	register unsigned char *ncp;
1478 	register unsigned char i;
1479 
1480 	ncp = statusbuf;
1481 
1482 	netflush();	/* get rid of anything waiting to go out */
1483 
1484 	ADD(IAC);
1485 	ADD(SB);
1486 	ADD(TELOPT_STATUS);
1487 	ADD(TELQUAL_IS);
1488 
1489 	/*
1490 	 * We check the want_state rather than the current state,
1491 	 * because if we received a DO/WILL for an option that we
1492 	 * don't support, and the other side didn't send a DONT/WONT
1493 	 * in response to our WONT/DONT, then the "state" will be
1494 	 * WILL/DO, and the "want_state" will be WONT/DONT.  We
1495 	 * need to go by the latter.
1496 	 */
1497 	for (i = 0; i < NTELOPTS; i++) {
1498 		if (my_want_state_is_will(i)) {
1499 			ADD(WILL);
1500 			ADD_DATA(i);
1501 			if (i == IAC)
1502 				ADD(IAC);
1503 		}
1504 		if (his_want_state_is_will(i)) {
1505 			ADD(DO);
1506 			ADD_DATA(i);
1507 			if (i == IAC)
1508 				ADD(IAC);
1509 		}
1510 	}
1511 
1512 	if (his_want_state_is_will(TELOPT_LFLOW)) {
1513 		ADD(SB);
1514 		ADD(TELOPT_LFLOW);
1515 		if (flowmode) {
1516 			ADD(LFLOW_ON);
1517 		} else {
1518 			ADD(LFLOW_OFF);
1519 		}
1520 		ADD(SE);
1521 
1522 		if (restartany >= 0) {
1523 			ADD(SB)
1524 			ADD(TELOPT_LFLOW);
1525 			if (restartany) {
1526 				ADD(LFLOW_RESTART_ANY);
1527 			} else {
1528 				ADD(LFLOW_RESTART_XON);
1529 			}
1530 			ADD(SE)
1531 			ADD(SB);
1532 		}
1533 	}
1534 
1535 #ifdef	LINEMODE
1536 	if (his_want_state_is_will(TELOPT_LINEMODE)) {
1537 		unsigned char *cp, *cpe;
1538 		int len;
1539 
1540 		ADD(SB);
1541 		ADD(TELOPT_LINEMODE);
1542 		ADD(LM_MODE);
1543 		ADD_DATA(editmode);
1544 		if (editmode == IAC)
1545 			ADD(IAC);
1546 		ADD(SE);
1547 
1548 		ADD(SB);
1549 		ADD(TELOPT_LINEMODE);
1550 		ADD(LM_SLC);
1551 		start_slc(0);
1552 		send_slc();
1553 		len = end_slc(&cp);
1554 		for (cpe = cp + len; cp < cpe; cp++)
1555 			ADD_DATA(*cp);
1556 		ADD(SE);
1557 	}
1558 #endif	/* LINEMODE */
1559 
1560 	ADD(IAC);
1561 	ADD(SE);
1562 
1563 	writenet(statusbuf, ncp - statusbuf);
1564 	netflush();	/* Send it on its way */
1565 
1566 	DIAG(TD_OPTIONS,
1567 		{printsub('>', statusbuf, ncp - statusbuf); netflush();});
1568 }
1569