xref: /original-bsd/usr.bin/telnet/sys_bsd.c (revision 57124d5e)
1 /*
2  * The following routines try to encapsulate what is system dependent
3  * (at least between 4.x and dos) which is used in telnet.c.
4  */
5 
6 #if	defined(unix)
7 
8 #include <sys/ioctl.h>
9 #include <sys/time.h>
10 #include <signal.h>
11 
12 #include "defines.h"
13 #include "externs.h"
14 #include "types.h"
15 
16 int
17 	HaveInput;		/* There is input available to scan */
18 
19 #if	defined(TN3270)
20 static char	tline[200];
21 char	*transcom = 0;	/* transparent mode command (default: none) */
22 #endif	/* defined(TN3270) */
23 
24 static struct	tchars otc = { 0 }, ntc = { 0 };
25 static struct	ltchars oltc = { 0 }, nltc = { 0 };
26 static struct	sgttyb ottyb = { 0 }, nttyb = { 0 };
27 
28 
29 TerminalWrite(fd, buf, n)
30 int	fd;
31 char	*buf;
32 int	n;
33 {
34     return write(fd, buf, n);
35 }
36 
37 TerminalRead(fd, buf, n)
38 int	fd;
39 char	*buf;
40 int	n;
41 {
42     return read(fd, buf, n);
43 }
44 
45 /*
46  *
47  */
48 
49 int
50 TerminalAutoFlush()					/* unix */
51 {
52 #if	defined(LNOFLSH)
53     int flush;
54 
55     ioctl(0, TIOCLGET, (char *)&flush);
56     return !(flush&LNOFLSH);	/* if LNOFLSH, no autoflush */
57 #else	/* LNOFLSH */
58     return 1;
59 #endif	/* LNOFLSH */
60 }
61 
62 /*
63  * TerminalSpecialChars()
64  *
65  * Look at an input character to see if it is a special character
66  * and decide what to do.
67  *
68  * Output:
69  *
70  *	0	Don't add this character.
71  *	1	Do add this character
72  */
73 
74 int
75 TerminalSpecialChars(c)			/* unix */
76 int	c;
77 {
78     void doflush(), intp(), sendbrk();
79 
80     if (c == ntc.t_intrc) {
81 	intp();
82 	return 0;
83     } else if (c == ntc.t_quitc) {
84 	sendbrk();
85 	return 0;
86     } else if (c == nltc.t_flushc) {
87 	xmitAO();		/* Transmit Abort Output */
88 	return 0;
89     } else if (!MODE_LOCAL_CHARS(globalmode)) {
90 	if (c == nttyb.sg_kill) {
91 	    xmitEL();
92 	    return 0;
93 	} else if (c == nttyb.sg_erase) {
94 	    xmitEC();		/* Transmit Erase Character */
95 	    return 0;
96 	}
97     }
98     return 1;
99 }
100 
101 
102 /*
103  * Flush output to the terminal
104  */
105 
106 void
107 TerminalFlushOutput()				/* unix */
108 {
109     (void) ioctl(fileno(stdout), TIOCFLUSH, (char *) 0);
110 }
111 
112 void
113 TerminalSaveState()				/* unix */
114 {
115     ioctl(0, TIOCGETP, (char *)&ottyb);
116     ioctl(0, TIOCGETC, (char *)&otc);
117     ioctl(0, TIOCGLTC, (char *)&oltc);
118 
119     ntc = otc;
120     nltc = oltc;
121     nttyb = ottyb;
122 }
123 
124 void
125 TerminalRestoreState()				/* unix */
126 {
127 }
128 
129 /*
130  * TerminalNewMode - set up terminal to a specific mode.
131  */
132 
133 
134 void
135 TerminalNewMode(fd_in, fd_out, f)			/* unix */
136 int	fd_in, fd_out;		/* File descriptor */
137 register int f;
138 {
139     static int prevmode = 0;
140     struct tchars *tc;
141     struct tchars tc3;
142     struct ltchars *ltc;
143     struct sgttyb sb;
144     int onoff;
145     int old;
146     struct	tchars notc2;
147     struct	ltchars noltc2;
148     static struct	tchars notc =	{ -1, -1, -1, -1, -1, -1 };
149     static struct	ltchars noltc =	{ -1, -1, -1, -1, -1, -1 };
150 
151     globalmode = f;
152     if (prevmode == f)
153 	return;
154     old = prevmode;
155     prevmode = f;
156     sb = nttyb;
157 
158     switch (f) {
159 
160     case 0:
161 	onoff = 0;
162 	tc = &otc;
163 	ltc = &oltc;
164 	break;
165 
166     case 1:		/* remote character processing, remote echo */
167     case 2:		/* remote character processing, local echo */
168     case 6:		/* 3270 mode - like 1, but with xon/xoff local */
169 		    /* (might be nice to have "6" in telnet also...) */
170 	    sb.sg_flags |= CBREAK;
171 	    if ((f == 1) || (f == 6)) {
172 		sb.sg_flags &= ~(ECHO|CRMOD);
173 	    } else {
174 		sb.sg_flags |= ECHO|CRMOD;
175 	    }
176 	    sb.sg_erase = sb.sg_kill = -1;
177 	    if (f == 6) {
178 		tc = &tc3;
179 		tc3 = notc;
180 		    /* get XON, XOFF characters */
181 		tc3.t_startc = otc.t_startc;
182 		tc3.t_stopc = otc.t_stopc;
183 	    } else {
184 		/*
185 		 * If user hasn't specified one way or the other,
186 		 * then default to not trapping signals.
187 		 */
188 		if (!donelclchars) {
189 		    localchars = 0;
190 		}
191 		if (localchars) {
192 		    notc2 = notc;
193 		    notc2.t_intrc = ntc.t_intrc;
194 		    notc2.t_quitc = ntc.t_quitc;
195 		    tc = &notc2;
196 		} else {
197 		    tc = &notc;
198 		}
199 	    }
200 	    ltc = &noltc;
201 	    onoff = 1;
202 	    break;
203     case 3:		/* local character processing, remote echo */
204     case 4:		/* local character processing, local echo */
205     case 5:		/* local character processing, no echo */
206 	    sb.sg_flags &= ~CBREAK;
207 	    sb.sg_flags |= CRMOD;
208 	    if (f == 4)
209 		sb.sg_flags |= ECHO;
210 	    else
211 		sb.sg_flags &= ~ECHO;
212 	    notc2 = ntc;
213 	    tc = &notc2;
214 	    noltc2 = oltc;
215 	    ltc = &noltc2;
216 	    /*
217 	     * If user hasn't specified one way or the other,
218 	     * then default to trapping signals.
219 	     */
220 	    if (!donelclchars) {
221 		localchars = 1;
222 	    }
223 	    if (localchars) {
224 		notc2.t_brkc = nltc.t_flushc;
225 		noltc2.t_flushc = -1;
226 	    } else {
227 		notc2.t_intrc = notc2.t_quitc = -1;
228 	    }
229 	    noltc2.t_suspc = escape;
230 	    noltc2.t_dsuspc = -1;
231 	    onoff = 1;
232 	    break;
233 
234     default:
235 	    return;
236     }
237     ioctl(fd_in, TIOCSLTC, (char *)ltc);
238     ioctl(fd_in, TIOCSETC, (char *)tc);
239     ioctl(fd_in, TIOCSETP, (char *)&sb);
240 #if	(!defined(TN3270)) || ((!defined(NOT43)) || defined(PUTCHAR))
241     ioctl(fd_in, FIONBIO, (char *)&onoff);
242     ioctl(fd_out, FIONBIO, (char *)&onoff);
243 #endif	/* (!defined(TN3270)) || ((!defined(NOT43)) || defined(PUTCHAR)) */
244 #if	defined(TN3270)
245     if (noasynch == 0) {
246 	ioctl(fd_in, FIOASYNC, (char *)&onoff);
247     }
248 #endif	/* defined(TN3270) */
249 
250     if (MODE_LINE(f)) {
251 	void doescape();
252 
253 	signal(SIGTSTP, doescape);
254     } else if (MODE_LINE(old)) {
255 	signal(SIGTSTP, SIG_DFL);
256 	sigsetmask(sigblock(0) & ~(1<<(SIGTSTP-1)));
257     }
258 }
259 
260 
261 int
262 NetClose(net)
263 int	net;
264 {
265     return close(net);
266 }
267 
268 
269 void
270 NetNonblockingIO(fd, onoff)				/* unix */
271 int
272 	fd,
273 	onoff;
274 {
275     ioctl(fd, FIONBIO, (char *)&onoff);
276 }
277 
278 void
279 NetSigIO(fd, onoff)				/* unix */
280 int
281 	fd,
282 	onoff;
283 {
284     ioctl(fd, FIOASYNC, (char *)&onoff);	/* hear about input */
285 }
286 
287 void
288 NetSetPgrp(fd)				/* unix */
289 int fd;
290 {
291     int myPid;
292 
293     myPid = getpid();
294 #if	defined(NOT43)
295     myPid = -myPid;
296 #endif	/* defined(NOT43) */
297     ioctl(fd, SIOCSPGRP, (char *)&myPid);	/* set my pid */
298 }
299 
300 
301 #endif	/* defined(unix) */
302