133686Sbostic /*
262313Sbostic * Copyright (c) 1988, 1990, 1993
362313Sbostic * The Regents of the University of California. All rights reserved.
433686Sbostic *
542770Sbostic * %sccs.include.redist.c%
633686Sbostic */
733686Sbostic
833686Sbostic #ifndef lint
9*68344Sdab static char sccsid[] = "@(#)terminal.c 8.2 (Berkeley) 02/16/95";
1033686Sbostic #endif /* not lint */
1133686Sbostic
1232148Sminshall #include <arpa/telnet.h>
1332381Sminshall #include <sys/types.h>
1432148Sminshall
1532381Sminshall #include "ring.h"
1632381Sminshall
1732148Sminshall #include "externs.h"
1832148Sminshall #include "types.h"
1932148Sminshall
2046808Sdab Ring ttyoring, ttyiring;
2146808Sdab unsigned char ttyobuf[2*BUFSIZ], ttyibuf[BUFSIZ];
2232148Sminshall
2338208Sminshall int termdata; /* Debugging flag */
2438208Sminshall
2538690Sborman #ifdef USE_TERMIO
2645232Sborman # ifndef VDISCARD
2744360Sborman cc_t termFlushChar;
2839529Sborman # endif
2939529Sborman # ifndef VLNEXT
3044360Sborman cc_t termLiteralNextChar;
3139529Sborman # endif
3239529Sborman # ifndef VSUSP
3344360Sborman cc_t termSuspChar;
3439529Sborman # endif
3539529Sborman # ifndef VWERASE
3644360Sborman cc_t termWerasChar;
3739529Sborman # endif
3839529Sborman # ifndef VREPRINT
3944360Sborman cc_t termRprntChar;
4039529Sborman # endif
4139529Sborman # ifndef VSTART
4244360Sborman cc_t termStartChar;
4339529Sborman # endif
4439529Sborman # ifndef VSTOP
4544360Sborman cc_t termStopChar;
4639529Sborman # endif
4740245Sborman # ifndef VEOL
4844360Sborman cc_t termForw1Char;
4940245Sborman # endif
5040245Sborman # ifndef VEOL2
5144360Sborman cc_t termForw2Char;
5240245Sborman # endif
5345232Sborman # ifndef VSTATUS
5445232Sborman cc_t termAytChar;
5545232Sborman # endif
5640245Sborman #else
5744360Sborman cc_t termForw2Char;
5845232Sborman cc_t termAytChar;
5938690Sborman #endif
6032148Sminshall
6132148Sminshall /*
6232148Sminshall * initialize the terminal data structures.
6332148Sminshall */
6432148Sminshall
6546808Sdab void
init_terminal()6632148Sminshall init_terminal()
6732148Sminshall {
6834848Sminshall if (ring_init(&ttyoring, ttyobuf, sizeof ttyobuf) != 1) {
6934848Sminshall exit(1);
7034848Sminshall }
7134848Sminshall if (ring_init(&ttyiring, ttyibuf, sizeof ttyibuf) != 1) {
7234848Sminshall exit(1);
7334848Sminshall }
7432148Sminshall autoflush = TerminalAutoFlush();
7532148Sminshall }
7632148Sminshall
7732148Sminshall
7832148Sminshall /*
7932148Sminshall * Send as much data as possible to the terminal.
8032148Sminshall *
8138690Sborman * Return value:
8238690Sborman * -1: No useful work done, data waiting to go out.
8338690Sborman * 0: No data was waiting, so nothing was done.
8438690Sborman * 1: All waiting data was written out.
8538690Sborman * n: All data - n was written out.
8632148Sminshall */
8732148Sminshall
8832148Sminshall
8946808Sdab int
ttyflush(drop)9032257Sminshall ttyflush(drop)
9146808Sdab int drop;
9232148Sminshall {
9332667Sminshall register int n, n0, n1;
9432148Sminshall
9532667Sminshall n0 = ring_full_count(&ttyoring);
9632667Sminshall if ((n1 = n = ring_full_consecutive(&ttyoring)) > 0) {
9732257Sminshall if (drop) {
9832148Sminshall TerminalFlushOutput();
9932148Sminshall /* we leave 'n' alone! */
10032257Sminshall } else {
10133286Sminshall n = TerminalWrite(ttyoring.consume, n);
10232148Sminshall }
10332148Sminshall }
10432667Sminshall if (n > 0) {
10538208Sminshall if (termdata && n) {
10638208Sminshall Dump('>', ttyoring.consume, n);
10738208Sminshall }
10832667Sminshall /*
10932667Sminshall * If we wrote everything, and the full count is
11032667Sminshall * larger than what we wrote, then write the
11132667Sminshall * rest of the buffer.
11232667Sminshall */
11332667Sminshall if (n1 == n && n0 > n) {
11432667Sminshall n1 = n0 - n;
11532667Sminshall if (!drop)
11633286Sminshall n1 = TerminalWrite(ttyoring.bottom, n1);
117*68344Sdab if (n1 > 0)
118*68344Sdab n += n1;
11932667Sminshall }
12032528Sminshall ring_consumed(&ttyoring, n);
12132148Sminshall }
12238690Sborman if (n < 0)
12338690Sborman return -1;
12438690Sborman if (n == n0) {
12538690Sborman if (n0)
12638690Sborman return -1;
12738690Sborman return 0;
12838690Sborman }
12938690Sborman return n0 - n + 1;
13032148Sminshall }
13132148Sminshall
13232148Sminshall
13332148Sminshall /*
13432148Sminshall * These routines decides on what the mode should be (based on the values
13532148Sminshall * of various global variables).
13632148Sminshall */
13732148Sminshall
13832148Sminshall
13946808Sdab int
getconnmode()14032148Sminshall getconnmode()
14132148Sminshall {
14238690Sborman extern int linemode;
14338690Sborman int mode = 0;
14438690Sborman #ifdef KLUDGELINEMODE
14538690Sborman extern int kludgelinemode;
14638690Sborman #endif
14732148Sminshall
14838690Sborman if (In3270)
14938690Sborman return(MODE_FLOW);
15038690Sborman
15138690Sborman if (my_want_state_is_dont(TELOPT_ECHO))
15238690Sborman mode |= MODE_ECHO;
15338690Sborman
15438690Sborman if (localflow)
15538690Sborman mode |= MODE_FLOW;
15638690Sborman
15739529Sborman if (my_want_state_is_will(TELOPT_BINARY))
15839529Sborman mode |= MODE_INBIN;
15939529Sborman
16039529Sborman if (his_want_state_is_will(TELOPT_BINARY))
16139529Sborman mode |= MODE_OUTBIN;
16239529Sborman
16338690Sborman #ifdef KLUDGELINEMODE
16438690Sborman if (kludgelinemode) {
16538690Sborman if (my_want_state_is_dont(TELOPT_SGA)) {
16638690Sborman mode |= (MODE_TRAPSIG|MODE_EDIT);
16738690Sborman if (dontlecho && (clocks.echotoggle > clocks.modenegotiated)) {
16838690Sborman mode &= ~MODE_ECHO;
16938690Sborman }
17038690Sborman }
17138690Sborman return(mode);
17232148Sminshall }
17338690Sborman #endif
17438690Sborman if (my_want_state_is_will(TELOPT_LINEMODE))
17538690Sborman mode |= linemode;
17638690Sborman return(mode);
17732148Sminshall }
17832148Sminshall
17946808Sdab void
setconnmode(force)18038690Sborman setconnmode(force)
18146808Sdab int force;
18232148Sminshall {
18357213Sdab #ifdef ENCRYPTION
18446808Sdab static int enc_passwd = 0;
18560149Sdab #endif /* ENCRYPTION */
18646808Sdab register int newmode;
18746808Sdab
18846808Sdab newmode = getconnmode()|(force?MODE_FORCE:0);
18946808Sdab
19046808Sdab TerminalNewMode(newmode);
19146808Sdab
19257213Sdab #ifdef ENCRYPTION
19346808Sdab if ((newmode & (MODE_ECHO|MODE_EDIT)) == MODE_EDIT) {
19446808Sdab if (my_want_state_is_will(TELOPT_ENCRYPT)
19546808Sdab && (enc_passwd == 0) && !encrypt_output) {
19647609Sdab encrypt_request_start(0, 0);
19746808Sdab enc_passwd = 1;
19846808Sdab }
19946808Sdab } else {
20046808Sdab if (enc_passwd) {
20146808Sdab encrypt_request_end();
20246808Sdab enc_passwd = 0;
20346808Sdab }
20446808Sdab }
20560149Sdab #endif /* ENCRYPTION */
20646808Sdab
20732148Sminshall }
20832148Sminshall
20932148Sminshall
21046808Sdab void
setcommandmode()21132148Sminshall setcommandmode()
21232148Sminshall {
21338690Sborman TerminalNewMode(-1);
21432148Sminshall }
215