xref: /csrg-svn/usr.bin/telnet/sys_bsd.c (revision 32381)
132147Sminshall /*
232147Sminshall  * The following routines try to encapsulate what is system dependent
332147Sminshall  * (at least between 4.x and dos) which is used in telnet.c.
432147Sminshall  */
532147Sminshall 
632147Sminshall #if	defined(unix)
732147Sminshall 
832147Sminshall #include <sys/ioctl.h>
9*32381Sminshall #include <sys/types.h>
1032147Sminshall #include <sys/time.h>
1132147Sminshall #include <signal.h>
1232147Sminshall 
13*32381Sminshall #include "ring.h"
14*32381Sminshall 
1532147Sminshall #include "defines.h"
1632147Sminshall #include "externs.h"
1732147Sminshall #include "types.h"
1832147Sminshall 
1932147Sminshall int
2032147Sminshall 	HaveInput;		/* There is input available to scan */
2132147Sminshall 
2232147Sminshall #if	defined(TN3270)
2332147Sminshall static char	tline[200];
2432147Sminshall char	*transcom = 0;	/* transparent mode command (default: none) */
2532147Sminshall #endif	/* defined(TN3270) */
2632147Sminshall 
2732147Sminshall static struct	tchars otc = { 0 }, ntc = { 0 };
2832147Sminshall static struct	ltchars oltc = { 0 }, nltc = { 0 };
2932147Sminshall static struct	sgttyb ottyb = { 0 }, nttyb = { 0 };
3032147Sminshall 
3132147Sminshall 
3232147Sminshall TerminalWrite(fd, buf, n)
3332147Sminshall int	fd;
3432147Sminshall char	*buf;
3532147Sminshall int	n;
3632147Sminshall {
3732147Sminshall     return write(fd, buf, n);
3832147Sminshall }
3932147Sminshall 
4032147Sminshall TerminalRead(fd, buf, n)
4132147Sminshall int	fd;
4232147Sminshall char	*buf;
4332147Sminshall int	n;
4432147Sminshall {
4532147Sminshall     return read(fd, buf, n);
4632147Sminshall }
4732147Sminshall 
4832147Sminshall /*
4932147Sminshall  *
5032147Sminshall  */
5132147Sminshall 
5232147Sminshall int
5332147Sminshall TerminalAutoFlush()					/* unix */
5432147Sminshall {
5532147Sminshall #if	defined(LNOFLSH)
5632147Sminshall     int flush;
5732147Sminshall 
5832147Sminshall     ioctl(0, TIOCLGET, (char *)&flush);
5932147Sminshall     return !(flush&LNOFLSH);	/* if LNOFLSH, no autoflush */
6032147Sminshall #else	/* LNOFLSH */
6132147Sminshall     return 1;
6232147Sminshall #endif	/* LNOFLSH */
6332147Sminshall }
6432147Sminshall 
6532147Sminshall /*
6632147Sminshall  * TerminalSpecialChars()
6732147Sminshall  *
6832147Sminshall  * Look at an input character to see if it is a special character
6932147Sminshall  * and decide what to do.
7032147Sminshall  *
7132147Sminshall  * Output:
7232147Sminshall  *
7332147Sminshall  *	0	Don't add this character.
7432147Sminshall  *	1	Do add this character
7532147Sminshall  */
7632147Sminshall 
7732147Sminshall int
7832147Sminshall TerminalSpecialChars(c)			/* unix */
7932147Sminshall int	c;
8032147Sminshall {
8132147Sminshall     void doflush(), intp(), sendbrk();
8232147Sminshall 
8332147Sminshall     if (c == ntc.t_intrc) {
8432147Sminshall 	intp();
8532147Sminshall 	return 0;
8632147Sminshall     } else if (c == ntc.t_quitc) {
8732147Sminshall 	sendbrk();
8832147Sminshall 	return 0;
8932147Sminshall     } else if (c == nltc.t_flushc) {
9032147Sminshall 	xmitAO();		/* Transmit Abort Output */
9132147Sminshall 	return 0;
9232147Sminshall     } else if (!MODE_LOCAL_CHARS(globalmode)) {
9332147Sminshall 	if (c == nttyb.sg_kill) {
9432147Sminshall 	    xmitEL();
9532147Sminshall 	    return 0;
9632147Sminshall 	} else if (c == nttyb.sg_erase) {
9732147Sminshall 	    xmitEC();		/* Transmit Erase Character */
9832147Sminshall 	    return 0;
9932147Sminshall 	}
10032147Sminshall     }
10132147Sminshall     return 1;
10232147Sminshall }
10332147Sminshall 
10432147Sminshall 
10532147Sminshall /*
10632147Sminshall  * Flush output to the terminal
10732147Sminshall  */
10832147Sminshall 
10932147Sminshall void
11032147Sminshall TerminalFlushOutput()				/* unix */
11132147Sminshall {
11232147Sminshall     (void) ioctl(fileno(stdout), TIOCFLUSH, (char *) 0);
11332147Sminshall }
11432147Sminshall 
11532147Sminshall void
11632147Sminshall TerminalSaveState()				/* unix */
11732147Sminshall {
11832147Sminshall     ioctl(0, TIOCGETP, (char *)&ottyb);
11932147Sminshall     ioctl(0, TIOCGETC, (char *)&otc);
12032147Sminshall     ioctl(0, TIOCGLTC, (char *)&oltc);
12132147Sminshall 
12232147Sminshall     ntc = otc;
12332147Sminshall     nltc = oltc;
12432147Sminshall     nttyb = ottyb;
12532254Sminshall 
12632254Sminshall     termEofChar = ntc.t_eofc;
12732254Sminshall     termEraseChar = nttyb.sg_erase;
12832254Sminshall     termFlushChar = nltc.t_flushc;
12932254Sminshall     termIntChar = ntc.t_intrc;
13032254Sminshall     termKillChar = nttyb.sg_kill;
13132254Sminshall     termQuitChar = ntc.t_quitc;
13232147Sminshall }
13332147Sminshall 
13432147Sminshall void
13532147Sminshall TerminalRestoreState()				/* unix */
13632147Sminshall {
13732147Sminshall }
13832147Sminshall 
13932147Sminshall /*
14032147Sminshall  * TerminalNewMode - set up terminal to a specific mode.
14132147Sminshall  */
14232147Sminshall 
14332147Sminshall 
14432147Sminshall void
14532147Sminshall TerminalNewMode(fd_in, fd_out, f)			/* unix */
14632147Sminshall int	fd_in, fd_out;		/* File descriptor */
14732147Sminshall register int f;
14832147Sminshall {
14932147Sminshall     static int prevmode = 0;
15032147Sminshall     struct tchars *tc;
15132147Sminshall     struct tchars tc3;
15232147Sminshall     struct ltchars *ltc;
15332147Sminshall     struct sgttyb sb;
15432147Sminshall     int onoff;
15532147Sminshall     int old;
15632147Sminshall     struct	tchars notc2;
15732147Sminshall     struct	ltchars noltc2;
15832147Sminshall     static struct	tchars notc =	{ -1, -1, -1, -1, -1, -1 };
15932147Sminshall     static struct	ltchars noltc =	{ -1, -1, -1, -1, -1, -1 };
16032147Sminshall 
16132147Sminshall     globalmode = f;
16232147Sminshall     if (prevmode == f)
16332147Sminshall 	return;
16432147Sminshall     old = prevmode;
16532147Sminshall     prevmode = f;
16632147Sminshall     sb = nttyb;
16732147Sminshall 
16832147Sminshall     switch (f) {
16932147Sminshall 
17032147Sminshall     case 0:
17132147Sminshall 	onoff = 0;
17232147Sminshall 	tc = &otc;
17332147Sminshall 	ltc = &oltc;
17432147Sminshall 	break;
17532147Sminshall 
17632147Sminshall     case 1:		/* remote character processing, remote echo */
17732147Sminshall     case 2:		/* remote character processing, local echo */
17832147Sminshall     case 6:		/* 3270 mode - like 1, but with xon/xoff local */
17932147Sminshall 		    /* (might be nice to have "6" in telnet also...) */
18032147Sminshall 	    sb.sg_flags |= CBREAK;
18132147Sminshall 	    if ((f == 1) || (f == 6)) {
18232147Sminshall 		sb.sg_flags &= ~(ECHO|CRMOD);
18332147Sminshall 	    } else {
18432147Sminshall 		sb.sg_flags |= ECHO|CRMOD;
18532147Sminshall 	    }
18632147Sminshall 	    sb.sg_erase = sb.sg_kill = -1;
18732147Sminshall 	    if (f == 6) {
18832147Sminshall 		tc = &tc3;
18932147Sminshall 		tc3 = notc;
19032147Sminshall 		    /* get XON, XOFF characters */
19132147Sminshall 		tc3.t_startc = otc.t_startc;
19232147Sminshall 		tc3.t_stopc = otc.t_stopc;
19332147Sminshall 	    } else {
19432147Sminshall 		/*
19532147Sminshall 		 * If user hasn't specified one way or the other,
19632147Sminshall 		 * then default to not trapping signals.
19732147Sminshall 		 */
19832147Sminshall 		if (!donelclchars) {
19932147Sminshall 		    localchars = 0;
20032147Sminshall 		}
20132147Sminshall 		if (localchars) {
20232147Sminshall 		    notc2 = notc;
20332147Sminshall 		    notc2.t_intrc = ntc.t_intrc;
20432147Sminshall 		    notc2.t_quitc = ntc.t_quitc;
20532147Sminshall 		    tc = &notc2;
20632147Sminshall 		} else {
20732147Sminshall 		    tc = &notc;
20832147Sminshall 		}
20932147Sminshall 	    }
21032147Sminshall 	    ltc = &noltc;
21132147Sminshall 	    onoff = 1;
21232147Sminshall 	    break;
21332147Sminshall     case 3:		/* local character processing, remote echo */
21432147Sminshall     case 4:		/* local character processing, local echo */
21532147Sminshall     case 5:		/* local character processing, no echo */
21632147Sminshall 	    sb.sg_flags &= ~CBREAK;
21732147Sminshall 	    sb.sg_flags |= CRMOD;
21832147Sminshall 	    if (f == 4)
21932147Sminshall 		sb.sg_flags |= ECHO;
22032147Sminshall 	    else
22132147Sminshall 		sb.sg_flags &= ~ECHO;
22232147Sminshall 	    notc2 = ntc;
22332147Sminshall 	    tc = &notc2;
22432147Sminshall 	    noltc2 = oltc;
22532147Sminshall 	    ltc = &noltc2;
22632147Sminshall 	    /*
22732147Sminshall 	     * If user hasn't specified one way or the other,
22832147Sminshall 	     * then default to trapping signals.
22932147Sminshall 	     */
23032147Sminshall 	    if (!donelclchars) {
23132147Sminshall 		localchars = 1;
23232147Sminshall 	    }
23332147Sminshall 	    if (localchars) {
23432147Sminshall 		notc2.t_brkc = nltc.t_flushc;
23532147Sminshall 		noltc2.t_flushc = -1;
23632147Sminshall 	    } else {
23732147Sminshall 		notc2.t_intrc = notc2.t_quitc = -1;
23832147Sminshall 	    }
23932147Sminshall 	    noltc2.t_suspc = escape;
24032147Sminshall 	    noltc2.t_dsuspc = -1;
24132147Sminshall 	    onoff = 1;
24232147Sminshall 	    break;
24332147Sminshall 
24432147Sminshall     default:
24532147Sminshall 	    return;
24632147Sminshall     }
24732147Sminshall     ioctl(fd_in, TIOCSLTC, (char *)ltc);
24832147Sminshall     ioctl(fd_in, TIOCSETC, (char *)tc);
24932147Sminshall     ioctl(fd_in, TIOCSETP, (char *)&sb);
25032147Sminshall #if	(!defined(TN3270)) || ((!defined(NOT43)) || defined(PUTCHAR))
25132147Sminshall     ioctl(fd_in, FIONBIO, (char *)&onoff);
25232147Sminshall     ioctl(fd_out, FIONBIO, (char *)&onoff);
25332147Sminshall #endif	/* (!defined(TN3270)) || ((!defined(NOT43)) || defined(PUTCHAR)) */
25432147Sminshall #if	defined(TN3270)
25532147Sminshall     if (noasynch == 0) {
25632147Sminshall 	ioctl(fd_in, FIOASYNC, (char *)&onoff);
25732147Sminshall     }
25832147Sminshall #endif	/* defined(TN3270) */
25932147Sminshall 
26032147Sminshall     if (MODE_LINE(f)) {
26132147Sminshall 	void doescape();
26232147Sminshall 
26332147Sminshall 	signal(SIGTSTP, doescape);
26432147Sminshall     } else if (MODE_LINE(old)) {
26532147Sminshall 	signal(SIGTSTP, SIG_DFL);
26632147Sminshall 	sigsetmask(sigblock(0) & ~(1<<(SIGTSTP-1)));
26732147Sminshall     }
26832147Sminshall }
26932147Sminshall 
27032147Sminshall 
27132147Sminshall int
27232147Sminshall NetClose(net)
27332147Sminshall int	net;
27432147Sminshall {
27532147Sminshall     return close(net);
27632147Sminshall }
27732147Sminshall 
27832147Sminshall 
27932147Sminshall void
28032147Sminshall NetNonblockingIO(fd, onoff)				/* unix */
28132147Sminshall int
28232147Sminshall 	fd,
28332147Sminshall 	onoff;
28432147Sminshall {
28532147Sminshall     ioctl(fd, FIONBIO, (char *)&onoff);
28632147Sminshall }
28732147Sminshall 
28832147Sminshall void
28932147Sminshall NetSigIO(fd, onoff)				/* unix */
29032147Sminshall int
29132147Sminshall 	fd,
29232147Sminshall 	onoff;
29332147Sminshall {
29432147Sminshall     ioctl(fd, FIOASYNC, (char *)&onoff);	/* hear about input */
29532147Sminshall }
29632147Sminshall 
29732147Sminshall void
29832147Sminshall NetSetPgrp(fd)				/* unix */
29932147Sminshall int fd;
30032147Sminshall {
30132147Sminshall     int myPid;
30232147Sminshall 
30332147Sminshall     myPid = getpid();
30432147Sminshall #if	defined(NOT43)
30532147Sminshall     myPid = -myPid;
30632147Sminshall #endif	/* defined(NOT43) */
30732147Sminshall     ioctl(fd, SIOCSPGRP, (char *)&myPid);	/* set my pid */
30832147Sminshall }
30932147Sminshall 
31032147Sminshall 
31132147Sminshall #endif	/* defined(unix) */
312