1*7348b5c5SDavid van Moolenbroek /* $NetBSD: sys_bsd.c,v 1.33 2012/01/09 16:08:55 christos Exp $ */
2*7348b5c5SDavid van Moolenbroek
3*7348b5c5SDavid van Moolenbroek /*
4*7348b5c5SDavid van Moolenbroek * Copyright (c) 1988, 1990, 1993
5*7348b5c5SDavid van Moolenbroek * The Regents of the University of California. All rights reserved.
6*7348b5c5SDavid van Moolenbroek *
7*7348b5c5SDavid van Moolenbroek * Redistribution and use in source and binary forms, with or without
8*7348b5c5SDavid van Moolenbroek * modification, are permitted provided that the following conditions
9*7348b5c5SDavid van Moolenbroek * are met:
10*7348b5c5SDavid van Moolenbroek * 1. Redistributions of source code must retain the above copyright
11*7348b5c5SDavid van Moolenbroek * notice, this list of conditions and the following disclaimer.
12*7348b5c5SDavid van Moolenbroek * 2. Redistributions in binary form must reproduce the above copyright
13*7348b5c5SDavid van Moolenbroek * notice, this list of conditions and the following disclaimer in the
14*7348b5c5SDavid van Moolenbroek * documentation and/or other materials provided with the distribution.
15*7348b5c5SDavid van Moolenbroek * 3. Neither the name of the University nor the names of its contributors
16*7348b5c5SDavid van Moolenbroek * may be used to endorse or promote products derived from this software
17*7348b5c5SDavid van Moolenbroek * without specific prior written permission.
18*7348b5c5SDavid van Moolenbroek *
19*7348b5c5SDavid van Moolenbroek * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20*7348b5c5SDavid van Moolenbroek * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21*7348b5c5SDavid van Moolenbroek * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22*7348b5c5SDavid van Moolenbroek * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23*7348b5c5SDavid van Moolenbroek * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24*7348b5c5SDavid van Moolenbroek * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25*7348b5c5SDavid van Moolenbroek * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26*7348b5c5SDavid van Moolenbroek * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27*7348b5c5SDavid van Moolenbroek * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28*7348b5c5SDavid van Moolenbroek * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29*7348b5c5SDavid van Moolenbroek * SUCH DAMAGE.
30*7348b5c5SDavid van Moolenbroek */
31*7348b5c5SDavid van Moolenbroek
32*7348b5c5SDavid van Moolenbroek #include <sys/cdefs.h>
33*7348b5c5SDavid van Moolenbroek #ifndef lint
34*7348b5c5SDavid van Moolenbroek #if 0
35*7348b5c5SDavid van Moolenbroek from: static char sccsid[] = "@(#)sys_bsd.c 8.4 (Berkeley) 5/30/95";
36*7348b5c5SDavid van Moolenbroek #else
37*7348b5c5SDavid van Moolenbroek __RCSID("$NetBSD: sys_bsd.c,v 1.33 2012/01/09 16:08:55 christos Exp $");
38*7348b5c5SDavid van Moolenbroek #endif
39*7348b5c5SDavid van Moolenbroek #endif /* not lint */
40*7348b5c5SDavid van Moolenbroek
41*7348b5c5SDavid van Moolenbroek /*
42*7348b5c5SDavid van Moolenbroek * The following routines try to encapsulate what is system dependent
43*7348b5c5SDavid van Moolenbroek * (at least between 4.x and dos) which is used in telnet.c.
44*7348b5c5SDavid van Moolenbroek */
45*7348b5c5SDavid van Moolenbroek
46*7348b5c5SDavid van Moolenbroek
47*7348b5c5SDavid van Moolenbroek #include <fcntl.h>
48*7348b5c5SDavid van Moolenbroek #include <sys/types.h>
49*7348b5c5SDavid van Moolenbroek #include <sys/time.h>
50*7348b5c5SDavid van Moolenbroek #include <sys/socket.h>
51*7348b5c5SDavid van Moolenbroek #include <signal.h>
52*7348b5c5SDavid van Moolenbroek #include <stdlib.h>
53*7348b5c5SDavid van Moolenbroek #include <unistd.h>
54*7348b5c5SDavid van Moolenbroek #include <errno.h>
55*7348b5c5SDavid van Moolenbroek #include <poll.h>
56*7348b5c5SDavid van Moolenbroek #include <arpa/telnet.h>
57*7348b5c5SDavid van Moolenbroek
58*7348b5c5SDavid van Moolenbroek #include "ring.h"
59*7348b5c5SDavid van Moolenbroek #include "defines.h"
60*7348b5c5SDavid van Moolenbroek #include "externs.h"
61*7348b5c5SDavid van Moolenbroek #include "types.h"
62*7348b5c5SDavid van Moolenbroek
63*7348b5c5SDavid van Moolenbroek #define SIG_FUNC_RET void
64*7348b5c5SDavid van Moolenbroek
65*7348b5c5SDavid van Moolenbroek SIG_FUNC_RET susp(int);
66*7348b5c5SDavid van Moolenbroek SIG_FUNC_RET ayt(int);
67*7348b5c5SDavid van Moolenbroek
68*7348b5c5SDavid van Moolenbroek SIG_FUNC_RET intr(int);
69*7348b5c5SDavid van Moolenbroek SIG_FUNC_RET intr2(int);
70*7348b5c5SDavid van Moolenbroek SIG_FUNC_RET sendwin(int);
71*7348b5c5SDavid van Moolenbroek
72*7348b5c5SDavid van Moolenbroek
73*7348b5c5SDavid van Moolenbroek int
74*7348b5c5SDavid van Moolenbroek tout, /* Output file descriptor */
75*7348b5c5SDavid van Moolenbroek tin, /* Input file descriptor */
76*7348b5c5SDavid van Moolenbroek net;
77*7348b5c5SDavid van Moolenbroek
78*7348b5c5SDavid van Moolenbroek struct termios old_tc = { .c_iflag = 0 };
79*7348b5c5SDavid van Moolenbroek extern struct termios new_tc;
80*7348b5c5SDavid van Moolenbroek
81*7348b5c5SDavid van Moolenbroek # ifndef TCSANOW
82*7348b5c5SDavid van Moolenbroek # ifdef TCSETS
83*7348b5c5SDavid van Moolenbroek # define TCSANOW TCSETS
84*7348b5c5SDavid van Moolenbroek # define TCSADRAIN TCSETSW
85*7348b5c5SDavid van Moolenbroek # define tcgetattr(f, t) ioctl(f, TCGETS, (char *)t)
86*7348b5c5SDavid van Moolenbroek # else
87*7348b5c5SDavid van Moolenbroek # ifdef TCSETA
88*7348b5c5SDavid van Moolenbroek # define TCSANOW TCSETA
89*7348b5c5SDavid van Moolenbroek # define TCSADRAIN TCSETAW
90*7348b5c5SDavid van Moolenbroek # define tcgetattr(f, t) ioctl(f, TCGETA, (char *)t)
91*7348b5c5SDavid van Moolenbroek # else
92*7348b5c5SDavid van Moolenbroek # define TCSANOW TIOCSETA
93*7348b5c5SDavid van Moolenbroek # define TCSADRAIN TIOCSETAW
94*7348b5c5SDavid van Moolenbroek # define tcgetattr(f, t) ioctl(f, TIOCGETA, (char *)t)
95*7348b5c5SDavid van Moolenbroek # endif
96*7348b5c5SDavid van Moolenbroek # endif
97*7348b5c5SDavid van Moolenbroek # define tcsetattr(f, a, t) ioctl(f, a, (char *)t)
98*7348b5c5SDavid van Moolenbroek # define cfgetospeed(ptr) ((ptr)->c_cflag&CBAUD)
99*7348b5c5SDavid van Moolenbroek # ifdef CIBAUD
100*7348b5c5SDavid van Moolenbroek # define cfgetispeed(ptr) (((ptr)->c_cflag&CIBAUD) >> IBSHIFT)
101*7348b5c5SDavid van Moolenbroek # else
102*7348b5c5SDavid van Moolenbroek # define cfgetispeed(ptr) cfgetospeed(ptr)
103*7348b5c5SDavid van Moolenbroek # endif
104*7348b5c5SDavid van Moolenbroek # endif /* TCSANOW */
105*7348b5c5SDavid van Moolenbroek
106*7348b5c5SDavid van Moolenbroek
107*7348b5c5SDavid van Moolenbroek void
init_sys(void)108*7348b5c5SDavid van Moolenbroek init_sys(void)
109*7348b5c5SDavid van Moolenbroek {
110*7348b5c5SDavid van Moolenbroek tout = fileno(stdout);
111*7348b5c5SDavid van Moolenbroek tin = fileno(stdin);
112*7348b5c5SDavid van Moolenbroek
113*7348b5c5SDavid van Moolenbroek errno = 0;
114*7348b5c5SDavid van Moolenbroek }
115*7348b5c5SDavid van Moolenbroek
116*7348b5c5SDavid van Moolenbroek
117*7348b5c5SDavid van Moolenbroek int
TerminalWrite(char * buf,int n)118*7348b5c5SDavid van Moolenbroek TerminalWrite(char *buf, int n)
119*7348b5c5SDavid van Moolenbroek {
120*7348b5c5SDavid van Moolenbroek return write(tout, buf, n);
121*7348b5c5SDavid van Moolenbroek }
122*7348b5c5SDavid van Moolenbroek
123*7348b5c5SDavid van Moolenbroek int
TerminalRead(unsigned char * buf,int n)124*7348b5c5SDavid van Moolenbroek TerminalRead(unsigned char *buf, int n)
125*7348b5c5SDavid van Moolenbroek {
126*7348b5c5SDavid van Moolenbroek return read(tin, buf, n);
127*7348b5c5SDavid van Moolenbroek }
128*7348b5c5SDavid van Moolenbroek
129*7348b5c5SDavid van Moolenbroek /*
130*7348b5c5SDavid van Moolenbroek *
131*7348b5c5SDavid van Moolenbroek */
132*7348b5c5SDavid van Moolenbroek
133*7348b5c5SDavid van Moolenbroek int
TerminalAutoFlush(void)134*7348b5c5SDavid van Moolenbroek TerminalAutoFlush(void)
135*7348b5c5SDavid van Moolenbroek {
136*7348b5c5SDavid van Moolenbroek return 1;
137*7348b5c5SDavid van Moolenbroek }
138*7348b5c5SDavid van Moolenbroek
139*7348b5c5SDavid van Moolenbroek #ifdef KLUDGELINEMODE
140*7348b5c5SDavid van Moolenbroek extern int kludgelinemode;
141*7348b5c5SDavid van Moolenbroek #endif
142*7348b5c5SDavid van Moolenbroek /*
143*7348b5c5SDavid van Moolenbroek * TerminalSpecialChars()
144*7348b5c5SDavid van Moolenbroek *
145*7348b5c5SDavid van Moolenbroek * Look at an input character to see if it is a special character
146*7348b5c5SDavid van Moolenbroek * and decide what to do.
147*7348b5c5SDavid van Moolenbroek *
148*7348b5c5SDavid van Moolenbroek * Output:
149*7348b5c5SDavid van Moolenbroek *
150*7348b5c5SDavid van Moolenbroek * 0 Don't add this character.
151*7348b5c5SDavid van Moolenbroek * 1 Do add this character
152*7348b5c5SDavid van Moolenbroek */
153*7348b5c5SDavid van Moolenbroek
154*7348b5c5SDavid van Moolenbroek int
TerminalSpecialChars(int c)155*7348b5c5SDavid van Moolenbroek TerminalSpecialChars(int c)
156*7348b5c5SDavid van Moolenbroek {
157*7348b5c5SDavid van Moolenbroek if (c == termIntChar) {
158*7348b5c5SDavid van Moolenbroek intp();
159*7348b5c5SDavid van Moolenbroek return 0;
160*7348b5c5SDavid van Moolenbroek } else if (c == termQuitChar) {
161*7348b5c5SDavid van Moolenbroek #ifdef KLUDGELINEMODE
162*7348b5c5SDavid van Moolenbroek if (kludgelinemode)
163*7348b5c5SDavid van Moolenbroek sendbrk();
164*7348b5c5SDavid van Moolenbroek else
165*7348b5c5SDavid van Moolenbroek #endif
166*7348b5c5SDavid van Moolenbroek sendabort();
167*7348b5c5SDavid van Moolenbroek return 0;
168*7348b5c5SDavid van Moolenbroek } else if (c == termEofChar) {
169*7348b5c5SDavid van Moolenbroek if (my_want_state_is_will(TELOPT_LINEMODE)) {
170*7348b5c5SDavid van Moolenbroek sendeof();
171*7348b5c5SDavid van Moolenbroek return 0;
172*7348b5c5SDavid van Moolenbroek }
173*7348b5c5SDavid van Moolenbroek return 1;
174*7348b5c5SDavid van Moolenbroek } else if (c == termSuspChar) {
175*7348b5c5SDavid van Moolenbroek sendsusp();
176*7348b5c5SDavid van Moolenbroek return(0);
177*7348b5c5SDavid van Moolenbroek } else if (c == termFlushChar) {
178*7348b5c5SDavid van Moolenbroek xmitAO(); /* Transmit Abort Output */
179*7348b5c5SDavid van Moolenbroek return 0;
180*7348b5c5SDavid van Moolenbroek } else if (!MODE_LOCAL_CHARS(globalmode)) {
181*7348b5c5SDavid van Moolenbroek if (c == termKillChar) {
182*7348b5c5SDavid van Moolenbroek xmitEL();
183*7348b5c5SDavid van Moolenbroek return 0;
184*7348b5c5SDavid van Moolenbroek } else if (c == termEraseChar) {
185*7348b5c5SDavid van Moolenbroek xmitEC(); /* Transmit Erase Character */
186*7348b5c5SDavid van Moolenbroek return 0;
187*7348b5c5SDavid van Moolenbroek }
188*7348b5c5SDavid van Moolenbroek }
189*7348b5c5SDavid van Moolenbroek return 1;
190*7348b5c5SDavid van Moolenbroek }
191*7348b5c5SDavid van Moolenbroek
192*7348b5c5SDavid van Moolenbroek
193*7348b5c5SDavid van Moolenbroek /*
194*7348b5c5SDavid van Moolenbroek * Flush output to the terminal
195*7348b5c5SDavid van Moolenbroek */
196*7348b5c5SDavid van Moolenbroek
197*7348b5c5SDavid van Moolenbroek void
TerminalFlushOutput(void)198*7348b5c5SDavid van Moolenbroek TerminalFlushOutput(void)
199*7348b5c5SDavid van Moolenbroek {
200*7348b5c5SDavid van Moolenbroek int com = 0;
201*7348b5c5SDavid van Moolenbroek (void) ioctl(fileno(stdout), TIOCFLUSH, &com);
202*7348b5c5SDavid van Moolenbroek }
203*7348b5c5SDavid van Moolenbroek
204*7348b5c5SDavid van Moolenbroek void
TerminalSaveState(void)205*7348b5c5SDavid van Moolenbroek TerminalSaveState(void)
206*7348b5c5SDavid van Moolenbroek {
207*7348b5c5SDavid van Moolenbroek tcgetattr(0, &old_tc);
208*7348b5c5SDavid van Moolenbroek
209*7348b5c5SDavid van Moolenbroek new_tc = old_tc;
210*7348b5c5SDavid van Moolenbroek }
211*7348b5c5SDavid van Moolenbroek
212*7348b5c5SDavid van Moolenbroek cc_t *
tcval(int func)213*7348b5c5SDavid van Moolenbroek tcval(int func)
214*7348b5c5SDavid van Moolenbroek {
215*7348b5c5SDavid van Moolenbroek switch(func) {
216*7348b5c5SDavid van Moolenbroek case SLC_IP: return(&termIntChar);
217*7348b5c5SDavid van Moolenbroek case SLC_ABORT: return(&termQuitChar);
218*7348b5c5SDavid van Moolenbroek case SLC_EOF: return(&termEofChar);
219*7348b5c5SDavid van Moolenbroek case SLC_EC: return(&termEraseChar);
220*7348b5c5SDavid van Moolenbroek case SLC_EL: return(&termKillChar);
221*7348b5c5SDavid van Moolenbroek case SLC_XON: return(&termStartChar);
222*7348b5c5SDavid van Moolenbroek case SLC_XOFF: return(&termStopChar);
223*7348b5c5SDavid van Moolenbroek case SLC_FORW1: return(&termForw1Char);
224*7348b5c5SDavid van Moolenbroek case SLC_FORW2: return(&termForw2Char);
225*7348b5c5SDavid van Moolenbroek case SLC_AO: return(&termFlushChar);
226*7348b5c5SDavid van Moolenbroek case SLC_SUSP: return(&termSuspChar);
227*7348b5c5SDavid van Moolenbroek case SLC_EW: return(&termWerasChar);
228*7348b5c5SDavid van Moolenbroek case SLC_RP: return(&termRprntChar);
229*7348b5c5SDavid van Moolenbroek case SLC_LNEXT: return(&termLiteralNextChar);
230*7348b5c5SDavid van Moolenbroek case SLC_AYT: return(&termAytChar);
231*7348b5c5SDavid van Moolenbroek
232*7348b5c5SDavid van Moolenbroek case SLC_SYNCH:
233*7348b5c5SDavid van Moolenbroek case SLC_BRK:
234*7348b5c5SDavid van Moolenbroek case SLC_EOR:
235*7348b5c5SDavid van Moolenbroek default:
236*7348b5c5SDavid van Moolenbroek return((cc_t *)0);
237*7348b5c5SDavid van Moolenbroek }
238*7348b5c5SDavid van Moolenbroek }
239*7348b5c5SDavid van Moolenbroek
240*7348b5c5SDavid van Moolenbroek void
TerminalDefaultChars(void)241*7348b5c5SDavid van Moolenbroek TerminalDefaultChars(void)
242*7348b5c5SDavid van Moolenbroek {
243*7348b5c5SDavid van Moolenbroek memmove(new_tc.c_cc, old_tc.c_cc, sizeof(old_tc.c_cc));
244*7348b5c5SDavid van Moolenbroek }
245*7348b5c5SDavid van Moolenbroek
246*7348b5c5SDavid van Moolenbroek #ifdef notdef
247*7348b5c5SDavid van Moolenbroek void
TerminalRestoreState(void)248*7348b5c5SDavid van Moolenbroek TerminalRestoreState(void)
249*7348b5c5SDavid van Moolenbroek {
250*7348b5c5SDavid van Moolenbroek }
251*7348b5c5SDavid van Moolenbroek #endif
252*7348b5c5SDavid van Moolenbroek
253*7348b5c5SDavid van Moolenbroek /*
254*7348b5c5SDavid van Moolenbroek * TerminalNewMode - set up terminal to a specific mode.
255*7348b5c5SDavid van Moolenbroek * MODE_ECHO: do local terminal echo
256*7348b5c5SDavid van Moolenbroek * MODE_FLOW: do local flow control
257*7348b5c5SDavid van Moolenbroek * MODE_TRAPSIG: do local mapping to TELNET IAC sequences
258*7348b5c5SDavid van Moolenbroek * MODE_EDIT: do local line editing
259*7348b5c5SDavid van Moolenbroek *
260*7348b5c5SDavid van Moolenbroek * Command mode:
261*7348b5c5SDavid van Moolenbroek * MODE_ECHO|MODE_EDIT|MODE_FLOW|MODE_TRAPSIG
262*7348b5c5SDavid van Moolenbroek * local echo
263*7348b5c5SDavid van Moolenbroek * local editing
264*7348b5c5SDavid van Moolenbroek * local xon/xoff
265*7348b5c5SDavid van Moolenbroek * local signal mapping
266*7348b5c5SDavid van Moolenbroek *
267*7348b5c5SDavid van Moolenbroek * Linemode:
268*7348b5c5SDavid van Moolenbroek * local/no editing
269*7348b5c5SDavid van Moolenbroek * Both Linemode and Single Character mode:
270*7348b5c5SDavid van Moolenbroek * local/remote echo
271*7348b5c5SDavid van Moolenbroek * local/no xon/xoff
272*7348b5c5SDavid van Moolenbroek * local/no signal mapping
273*7348b5c5SDavid van Moolenbroek */
274*7348b5c5SDavid van Moolenbroek
275*7348b5c5SDavid van Moolenbroek
276*7348b5c5SDavid van Moolenbroek void
TerminalNewMode(int f)277*7348b5c5SDavid van Moolenbroek TerminalNewMode(int f)
278*7348b5c5SDavid van Moolenbroek {
279*7348b5c5SDavid van Moolenbroek static int prevmode = 0;
280*7348b5c5SDavid van Moolenbroek struct termios tmp_tc;
281*7348b5c5SDavid van Moolenbroek int onoff;
282*7348b5c5SDavid van Moolenbroek int old;
283*7348b5c5SDavid van Moolenbroek cc_t esc;
284*7348b5c5SDavid van Moolenbroek
285*7348b5c5SDavid van Moolenbroek globalmode = f&~MODE_FORCE;
286*7348b5c5SDavid van Moolenbroek if (prevmode == f)
287*7348b5c5SDavid van Moolenbroek return;
288*7348b5c5SDavid van Moolenbroek
289*7348b5c5SDavid van Moolenbroek /*
290*7348b5c5SDavid van Moolenbroek * Write any outstanding data before switching modes
291*7348b5c5SDavid van Moolenbroek * ttyflush() returns 0 only when there is no more data
292*7348b5c5SDavid van Moolenbroek * left to write out, it returns -1 if it couldn't do
293*7348b5c5SDavid van Moolenbroek * anything at all, otherwise it returns 1 + the number
294*7348b5c5SDavid van Moolenbroek * of characters left to write.
295*7348b5c5SDavid van Moolenbroek #ifndef USE_TERMIO
296*7348b5c5SDavid van Moolenbroek * We would really like to ask the kernel to wait for the output
297*7348b5c5SDavid van Moolenbroek * to drain, like we can do with the TCSADRAIN, but we don't have
298*7348b5c5SDavid van Moolenbroek * that option. The only ioctl that waits for the output to
299*7348b5c5SDavid van Moolenbroek * drain, TIOCSETP, also flushes the input queue, which is NOT
300*7348b5c5SDavid van Moolenbroek * what we want (TIOCSETP is like TCSADFLUSH).
301*7348b5c5SDavid van Moolenbroek #endif
302*7348b5c5SDavid van Moolenbroek */
303*7348b5c5SDavid van Moolenbroek old = ttyflush(SYNCHing|flushout);
304*7348b5c5SDavid van Moolenbroek if (old < 0 || old > 1) {
305*7348b5c5SDavid van Moolenbroek tcgetattr(tin, &tmp_tc);
306*7348b5c5SDavid van Moolenbroek do {
307*7348b5c5SDavid van Moolenbroek /*
308*7348b5c5SDavid van Moolenbroek * Wait for data to drain, then flush again.
309*7348b5c5SDavid van Moolenbroek */
310*7348b5c5SDavid van Moolenbroek tcsetattr(tin, TCSADRAIN, &tmp_tc);
311*7348b5c5SDavid van Moolenbroek old = ttyflush(SYNCHing|flushout);
312*7348b5c5SDavid van Moolenbroek } while (old < 0 || old > 1);
313*7348b5c5SDavid van Moolenbroek }
314*7348b5c5SDavid van Moolenbroek
315*7348b5c5SDavid van Moolenbroek old = prevmode;
316*7348b5c5SDavid van Moolenbroek prevmode = f&~MODE_FORCE;
317*7348b5c5SDavid van Moolenbroek tmp_tc = new_tc;
318*7348b5c5SDavid van Moolenbroek
319*7348b5c5SDavid van Moolenbroek if (f&MODE_ECHO) {
320*7348b5c5SDavid van Moolenbroek tmp_tc.c_lflag |= ECHO;
321*7348b5c5SDavid van Moolenbroek tmp_tc.c_oflag |= ONLCR;
322*7348b5c5SDavid van Moolenbroek if (crlf)
323*7348b5c5SDavid van Moolenbroek tmp_tc.c_iflag |= ICRNL;
324*7348b5c5SDavid van Moolenbroek } else {
325*7348b5c5SDavid van Moolenbroek tmp_tc.c_lflag &= ~ECHO;
326*7348b5c5SDavid van Moolenbroek tmp_tc.c_oflag &= ~ONLCR;
327*7348b5c5SDavid van Moolenbroek # ifdef notdef
328*7348b5c5SDavid van Moolenbroek if (crlf)
329*7348b5c5SDavid van Moolenbroek tmp_tc.c_iflag &= ~ICRNL;
330*7348b5c5SDavid van Moolenbroek # endif
331*7348b5c5SDavid van Moolenbroek }
332*7348b5c5SDavid van Moolenbroek
333*7348b5c5SDavid van Moolenbroek if ((f&MODE_FLOW) == 0) {
334*7348b5c5SDavid van Moolenbroek tmp_tc.c_iflag &= ~(IXOFF|IXON); /* Leave the IXANY bit alone */
335*7348b5c5SDavid van Moolenbroek } else {
336*7348b5c5SDavid van Moolenbroek if (restartany < 0) {
337*7348b5c5SDavid van Moolenbroek tmp_tc.c_iflag |= IXOFF|IXON; /* Leave the IXANY bit alone */
338*7348b5c5SDavid van Moolenbroek } else if (restartany > 0) {
339*7348b5c5SDavid van Moolenbroek tmp_tc.c_iflag |= IXOFF|IXON|IXANY;
340*7348b5c5SDavid van Moolenbroek } else {
341*7348b5c5SDavid van Moolenbroek tmp_tc.c_iflag |= IXOFF|IXON;
342*7348b5c5SDavid van Moolenbroek tmp_tc.c_iflag &= ~IXANY;
343*7348b5c5SDavid van Moolenbroek }
344*7348b5c5SDavid van Moolenbroek }
345*7348b5c5SDavid van Moolenbroek
346*7348b5c5SDavid van Moolenbroek if ((f&MODE_TRAPSIG) == 0) {
347*7348b5c5SDavid van Moolenbroek tmp_tc.c_lflag &= ~ISIG;
348*7348b5c5SDavid van Moolenbroek localchars = 0;
349*7348b5c5SDavid van Moolenbroek } else {
350*7348b5c5SDavid van Moolenbroek tmp_tc.c_lflag |= ISIG;
351*7348b5c5SDavid van Moolenbroek localchars = 1;
352*7348b5c5SDavid van Moolenbroek }
353*7348b5c5SDavid van Moolenbroek
354*7348b5c5SDavid van Moolenbroek if (f&MODE_EDIT) {
355*7348b5c5SDavid van Moolenbroek tmp_tc.c_lflag |= ICANON;
356*7348b5c5SDavid van Moolenbroek } else {
357*7348b5c5SDavid van Moolenbroek tmp_tc.c_lflag &= ~ICANON;
358*7348b5c5SDavid van Moolenbroek tmp_tc.c_iflag &= ~ICRNL;
359*7348b5c5SDavid van Moolenbroek tmp_tc.c_cc[VMIN] = 1;
360*7348b5c5SDavid van Moolenbroek tmp_tc.c_cc[VTIME] = 0;
361*7348b5c5SDavid van Moolenbroek }
362*7348b5c5SDavid van Moolenbroek
363*7348b5c5SDavid van Moolenbroek if ((f&(MODE_EDIT|MODE_TRAPSIG)) == 0) {
364*7348b5c5SDavid van Moolenbroek tmp_tc.c_lflag &= ~IEXTEN;
365*7348b5c5SDavid van Moolenbroek }
366*7348b5c5SDavid van Moolenbroek
367*7348b5c5SDavid van Moolenbroek if (f&MODE_SOFT_TAB) {
368*7348b5c5SDavid van Moolenbroek # ifdef OXTABS
369*7348b5c5SDavid van Moolenbroek tmp_tc.c_oflag |= OXTABS;
370*7348b5c5SDavid van Moolenbroek # endif
371*7348b5c5SDavid van Moolenbroek # ifdef TABDLY
372*7348b5c5SDavid van Moolenbroek tmp_tc.c_oflag &= ~TABDLY;
373*7348b5c5SDavid van Moolenbroek tmp_tc.c_oflag |= TAB3;
374*7348b5c5SDavid van Moolenbroek # endif
375*7348b5c5SDavid van Moolenbroek } else {
376*7348b5c5SDavid van Moolenbroek # ifdef OXTABS
377*7348b5c5SDavid van Moolenbroek tmp_tc.c_oflag &= ~OXTABS;
378*7348b5c5SDavid van Moolenbroek # endif
379*7348b5c5SDavid van Moolenbroek # ifdef TABDLY
380*7348b5c5SDavid van Moolenbroek tmp_tc.c_oflag &= ~TABDLY;
381*7348b5c5SDavid van Moolenbroek # endif
382*7348b5c5SDavid van Moolenbroek }
383*7348b5c5SDavid van Moolenbroek
384*7348b5c5SDavid van Moolenbroek if (f&MODE_LIT_ECHO) {
385*7348b5c5SDavid van Moolenbroek # ifdef ECHOCTL
386*7348b5c5SDavid van Moolenbroek tmp_tc.c_lflag &= ~ECHOCTL;
387*7348b5c5SDavid van Moolenbroek # endif
388*7348b5c5SDavid van Moolenbroek } else {
389*7348b5c5SDavid van Moolenbroek # ifdef ECHOCTL
390*7348b5c5SDavid van Moolenbroek tmp_tc.c_lflag |= ECHOCTL;
391*7348b5c5SDavid van Moolenbroek # endif
392*7348b5c5SDavid van Moolenbroek }
393*7348b5c5SDavid van Moolenbroek
394*7348b5c5SDavid van Moolenbroek if (f == -1) {
395*7348b5c5SDavid van Moolenbroek onoff = 0;
396*7348b5c5SDavid van Moolenbroek } else {
397*7348b5c5SDavid van Moolenbroek if (f & MODE_INBIN)
398*7348b5c5SDavid van Moolenbroek tmp_tc.c_iflag &= ~ISTRIP;
399*7348b5c5SDavid van Moolenbroek else
400*7348b5c5SDavid van Moolenbroek tmp_tc.c_iflag |= ISTRIP;
401*7348b5c5SDavid van Moolenbroek if (f & MODE_OUTBIN) {
402*7348b5c5SDavid van Moolenbroek tmp_tc.c_cflag &= ~(CSIZE|PARENB);
403*7348b5c5SDavid van Moolenbroek tmp_tc.c_cflag |= CS8;
404*7348b5c5SDavid van Moolenbroek tmp_tc.c_oflag &= ~OPOST;
405*7348b5c5SDavid van Moolenbroek } else {
406*7348b5c5SDavid van Moolenbroek tmp_tc.c_cflag &= ~(CSIZE|PARENB);
407*7348b5c5SDavid van Moolenbroek tmp_tc.c_cflag |= old_tc.c_cflag & (CSIZE|PARENB);
408*7348b5c5SDavid van Moolenbroek tmp_tc.c_oflag |= OPOST;
409*7348b5c5SDavid van Moolenbroek }
410*7348b5c5SDavid van Moolenbroek onoff = 1;
411*7348b5c5SDavid van Moolenbroek }
412*7348b5c5SDavid van Moolenbroek
413*7348b5c5SDavid van Moolenbroek if (f != -1) {
414*7348b5c5SDavid van Moolenbroek (void) signal(SIGTSTP, susp);
415*7348b5c5SDavid van Moolenbroek (void) signal(SIGINFO, ayt);
416*7348b5c5SDavid van Moolenbroek #if defined(USE_TERMIO) && defined(NOKERNINFO)
417*7348b5c5SDavid van Moolenbroek tmp_tc.c_lflag |= NOKERNINFO;
418*7348b5c5SDavid van Moolenbroek #endif
419*7348b5c5SDavid van Moolenbroek /*
420*7348b5c5SDavid van Moolenbroek * We don't want to process ^Y here. It's just another
421*7348b5c5SDavid van Moolenbroek * character that we'll pass on to the back end. It has
422*7348b5c5SDavid van Moolenbroek * to process it because it will be processed when the
423*7348b5c5SDavid van Moolenbroek * user attempts to read it, not when we send it.
424*7348b5c5SDavid van Moolenbroek */
425*7348b5c5SDavid van Moolenbroek # ifdef VDSUSP
426*7348b5c5SDavid van Moolenbroek tmp_tc.c_cc[VDSUSP] = (cc_t)(_POSIX_VDISABLE);
427*7348b5c5SDavid van Moolenbroek # endif
428*7348b5c5SDavid van Moolenbroek /*
429*7348b5c5SDavid van Moolenbroek * If the VEOL character is already set, then use VEOL2,
430*7348b5c5SDavid van Moolenbroek * otherwise use VEOL.
431*7348b5c5SDavid van Moolenbroek */
432*7348b5c5SDavid van Moolenbroek esc = (rlogin != _POSIX_VDISABLE) ? rlogin : escape;
433*7348b5c5SDavid van Moolenbroek if ((tmp_tc.c_cc[VEOL] != esc)
434*7348b5c5SDavid van Moolenbroek # ifdef VEOL2
435*7348b5c5SDavid van Moolenbroek && (tmp_tc.c_cc[VEOL2] != esc)
436*7348b5c5SDavid van Moolenbroek # endif
437*7348b5c5SDavid van Moolenbroek ) {
438*7348b5c5SDavid van Moolenbroek if (tmp_tc.c_cc[VEOL] == (cc_t)(_POSIX_VDISABLE))
439*7348b5c5SDavid van Moolenbroek tmp_tc.c_cc[VEOL] = esc;
440*7348b5c5SDavid van Moolenbroek # ifdef VEOL2
441*7348b5c5SDavid van Moolenbroek else if (tmp_tc.c_cc[VEOL2] == (cc_t)(_POSIX_VDISABLE))
442*7348b5c5SDavid van Moolenbroek tmp_tc.c_cc[VEOL2] = esc;
443*7348b5c5SDavid van Moolenbroek # endif
444*7348b5c5SDavid van Moolenbroek }
445*7348b5c5SDavid van Moolenbroek } else {
446*7348b5c5SDavid van Moolenbroek (void) signal(SIGINFO, (void (*)(int)) ayt_status);
447*7348b5c5SDavid van Moolenbroek (void) signal(SIGTSTP, SIG_DFL);
448*7348b5c5SDavid van Moolenbroek (void) sigsetmask(sigblock(0) & ~(1<<(SIGTSTP-1)));
449*7348b5c5SDavid van Moolenbroek tmp_tc = old_tc;
450*7348b5c5SDavid van Moolenbroek }
451*7348b5c5SDavid van Moolenbroek if (tcsetattr(tin, TCSADRAIN, &tmp_tc) < 0)
452*7348b5c5SDavid van Moolenbroek tcsetattr(tin, TCSANOW, &tmp_tc);
453*7348b5c5SDavid van Moolenbroek
454*7348b5c5SDavid van Moolenbroek ioctl(tin, FIONBIO, (char *)&onoff);
455*7348b5c5SDavid van Moolenbroek ioctl(tout, FIONBIO, (char *)&onoff);
456*7348b5c5SDavid van Moolenbroek #if defined(TN3270)
457*7348b5c5SDavid van Moolenbroek if (noasynchtty == 0) {
458*7348b5c5SDavid van Moolenbroek ioctl(tin, FIOASYNC, (char *)&onoff);
459*7348b5c5SDavid van Moolenbroek }
460*7348b5c5SDavid van Moolenbroek #endif /* defined(TN3270) */
461*7348b5c5SDavid van Moolenbroek
462*7348b5c5SDavid van Moolenbroek }
463*7348b5c5SDavid van Moolenbroek
464*7348b5c5SDavid van Moolenbroek void
TerminalSpeeds(long * ispeed,long * ospeed)465*7348b5c5SDavid van Moolenbroek TerminalSpeeds(long *ispeed, long *ospeed)
466*7348b5c5SDavid van Moolenbroek {
467*7348b5c5SDavid van Moolenbroek long in, out;
468*7348b5c5SDavid van Moolenbroek
469*7348b5c5SDavid van Moolenbroek out = cfgetospeed(&old_tc);
470*7348b5c5SDavid van Moolenbroek in = cfgetispeed(&old_tc);
471*7348b5c5SDavid van Moolenbroek if (in == 0)
472*7348b5c5SDavid van Moolenbroek in = out;
473*7348b5c5SDavid van Moolenbroek
474*7348b5c5SDavid van Moolenbroek *ispeed = in;
475*7348b5c5SDavid van Moolenbroek *ospeed = out;
476*7348b5c5SDavid van Moolenbroek }
477*7348b5c5SDavid van Moolenbroek
478*7348b5c5SDavid van Moolenbroek int
TerminalWindowSize(long * rows,long * cols)479*7348b5c5SDavid van Moolenbroek TerminalWindowSize(long *rows, long *cols)
480*7348b5c5SDavid van Moolenbroek {
481*7348b5c5SDavid van Moolenbroek struct winsize ws;
482*7348b5c5SDavid van Moolenbroek
483*7348b5c5SDavid van Moolenbroek if (ioctl(fileno(stdin), TIOCGWINSZ, (char *)&ws) >= 0) {
484*7348b5c5SDavid van Moolenbroek *rows = ws.ws_row;
485*7348b5c5SDavid van Moolenbroek *cols = ws.ws_col;
486*7348b5c5SDavid van Moolenbroek return 1;
487*7348b5c5SDavid van Moolenbroek }
488*7348b5c5SDavid van Moolenbroek return 0;
489*7348b5c5SDavid van Moolenbroek }
490*7348b5c5SDavid van Moolenbroek
491*7348b5c5SDavid van Moolenbroek int
NetClose(int fd)492*7348b5c5SDavid van Moolenbroek NetClose(int fd)
493*7348b5c5SDavid van Moolenbroek {
494*7348b5c5SDavid van Moolenbroek return close(fd);
495*7348b5c5SDavid van Moolenbroek }
496*7348b5c5SDavid van Moolenbroek
497*7348b5c5SDavid van Moolenbroek
498*7348b5c5SDavid van Moolenbroek void
NetNonblockingIO(int fd,int onoff)499*7348b5c5SDavid van Moolenbroek NetNonblockingIO(int fd, int onoff)
500*7348b5c5SDavid van Moolenbroek {
501*7348b5c5SDavid van Moolenbroek ioctl(fd, FIONBIO, (char *)&onoff);
502*7348b5c5SDavid van Moolenbroek }
503*7348b5c5SDavid van Moolenbroek
504*7348b5c5SDavid van Moolenbroek #ifdef TN3270
505*7348b5c5SDavid van Moolenbroek void
NetSigIO(int fd,int onoff)506*7348b5c5SDavid van Moolenbroek NetSigIO(int fd, int onoff)
507*7348b5c5SDavid van Moolenbroek {
508*7348b5c5SDavid van Moolenbroek ioctl(fd, FIOASYNC, (char *)&onoff); /* hear about input */
509*7348b5c5SDavid van Moolenbroek }
510*7348b5c5SDavid van Moolenbroek
511*7348b5c5SDavid van Moolenbroek void
NetSetPgrp(int fd)512*7348b5c5SDavid van Moolenbroek NetSetPgrp(int fd)
513*7348b5c5SDavid van Moolenbroek {
514*7348b5c5SDavid van Moolenbroek int myPid;
515*7348b5c5SDavid van Moolenbroek
516*7348b5c5SDavid van Moolenbroek myPid = getpid();
517*7348b5c5SDavid van Moolenbroek fcntl(fd, F_SETOWN, myPid);
518*7348b5c5SDavid van Moolenbroek }
519*7348b5c5SDavid van Moolenbroek #endif /*defined(TN3270)*/
520*7348b5c5SDavid van Moolenbroek
521*7348b5c5SDavid van Moolenbroek /*
522*7348b5c5SDavid van Moolenbroek * Various signal handling routines.
523*7348b5c5SDavid van Moolenbroek */
524*7348b5c5SDavid van Moolenbroek
525*7348b5c5SDavid van Moolenbroek /* ARGSUSED */
526*7348b5c5SDavid van Moolenbroek SIG_FUNC_RET
intr(int sig)527*7348b5c5SDavid van Moolenbroek intr(int sig)
528*7348b5c5SDavid van Moolenbroek {
529*7348b5c5SDavid van Moolenbroek if (localchars) {
530*7348b5c5SDavid van Moolenbroek intp();
531*7348b5c5SDavid van Moolenbroek return;
532*7348b5c5SDavid van Moolenbroek }
533*7348b5c5SDavid van Moolenbroek setcommandmode();
534*7348b5c5SDavid van Moolenbroek longjmp(toplevel, -1);
535*7348b5c5SDavid van Moolenbroek }
536*7348b5c5SDavid van Moolenbroek
537*7348b5c5SDavid van Moolenbroek /* ARGSUSED */
538*7348b5c5SDavid van Moolenbroek SIG_FUNC_RET
intr2(int sig)539*7348b5c5SDavid van Moolenbroek intr2(int sig)
540*7348b5c5SDavid van Moolenbroek {
541*7348b5c5SDavid van Moolenbroek if (localchars) {
542*7348b5c5SDavid van Moolenbroek #ifdef KLUDGELINEMODE
543*7348b5c5SDavid van Moolenbroek if (kludgelinemode)
544*7348b5c5SDavid van Moolenbroek sendbrk();
545*7348b5c5SDavid van Moolenbroek else
546*7348b5c5SDavid van Moolenbroek #endif
547*7348b5c5SDavid van Moolenbroek sendabort();
548*7348b5c5SDavid van Moolenbroek return;
549*7348b5c5SDavid van Moolenbroek }
550*7348b5c5SDavid van Moolenbroek }
551*7348b5c5SDavid van Moolenbroek
552*7348b5c5SDavid van Moolenbroek /* ARGSUSED */
553*7348b5c5SDavid van Moolenbroek SIG_FUNC_RET
susp(int sig)554*7348b5c5SDavid van Moolenbroek susp(int sig)
555*7348b5c5SDavid van Moolenbroek {
556*7348b5c5SDavid van Moolenbroek if ((rlogin != _POSIX_VDISABLE) && rlogin_susp())
557*7348b5c5SDavid van Moolenbroek return;
558*7348b5c5SDavid van Moolenbroek if (localchars)
559*7348b5c5SDavid van Moolenbroek sendsusp();
560*7348b5c5SDavid van Moolenbroek }
561*7348b5c5SDavid van Moolenbroek
562*7348b5c5SDavid van Moolenbroek /* ARGSUSED */
563*7348b5c5SDavid van Moolenbroek SIG_FUNC_RET
sendwin(int sig)564*7348b5c5SDavid van Moolenbroek sendwin(int sig)
565*7348b5c5SDavid van Moolenbroek {
566*7348b5c5SDavid van Moolenbroek if (connected) {
567*7348b5c5SDavid van Moolenbroek sendnaws();
568*7348b5c5SDavid van Moolenbroek }
569*7348b5c5SDavid van Moolenbroek }
570*7348b5c5SDavid van Moolenbroek
571*7348b5c5SDavid van Moolenbroek /* ARGSUSED */
572*7348b5c5SDavid van Moolenbroek SIG_FUNC_RET
ayt(int sig)573*7348b5c5SDavid van Moolenbroek ayt(int sig)
574*7348b5c5SDavid van Moolenbroek {
575*7348b5c5SDavid van Moolenbroek if (connected)
576*7348b5c5SDavid van Moolenbroek sendayt();
577*7348b5c5SDavid van Moolenbroek else
578*7348b5c5SDavid van Moolenbroek ayt_status();
579*7348b5c5SDavid van Moolenbroek }
580*7348b5c5SDavid van Moolenbroek
581*7348b5c5SDavid van Moolenbroek
582*7348b5c5SDavid van Moolenbroek void
sys_telnet_init(void)583*7348b5c5SDavid van Moolenbroek sys_telnet_init(void)
584*7348b5c5SDavid van Moolenbroek {
585*7348b5c5SDavid van Moolenbroek (void) signal(SIGINT, intr);
586*7348b5c5SDavid van Moolenbroek (void) signal(SIGQUIT, intr2);
587*7348b5c5SDavid van Moolenbroek (void) signal(SIGPIPE, SIG_IGN);
588*7348b5c5SDavid van Moolenbroek (void) signal(SIGWINCH, sendwin);
589*7348b5c5SDavid van Moolenbroek (void) signal(SIGTSTP, susp);
590*7348b5c5SDavid van Moolenbroek (void) signal(SIGINFO, ayt);
591*7348b5c5SDavid van Moolenbroek
592*7348b5c5SDavid van Moolenbroek setconnmode(0);
593*7348b5c5SDavid van Moolenbroek
594*7348b5c5SDavid van Moolenbroek NetNonblockingIO(net, 1);
595*7348b5c5SDavid van Moolenbroek
596*7348b5c5SDavid van Moolenbroek #ifdef TN3270
597*7348b5c5SDavid van Moolenbroek if (noasynchnet == 0) { /* DBX can't handle! */
598*7348b5c5SDavid van Moolenbroek NetSigIO(net, 1);
599*7348b5c5SDavid van Moolenbroek NetSetPgrp(net);
600*7348b5c5SDavid van Moolenbroek }
601*7348b5c5SDavid van Moolenbroek #endif /* defined(TN3270) */
602*7348b5c5SDavid van Moolenbroek
603*7348b5c5SDavid van Moolenbroek if (SetSockOpt(net, SOL_SOCKET, SO_OOBINLINE, 1) == -1) {
604*7348b5c5SDavid van Moolenbroek perror("SetSockOpt");
605*7348b5c5SDavid van Moolenbroek }
606*7348b5c5SDavid van Moolenbroek }
607*7348b5c5SDavid van Moolenbroek
608*7348b5c5SDavid van Moolenbroek /*
609*7348b5c5SDavid van Moolenbroek * Process rings -
610*7348b5c5SDavid van Moolenbroek *
611*7348b5c5SDavid van Moolenbroek * This routine tries to fill up/empty our various rings.
612*7348b5c5SDavid van Moolenbroek *
613*7348b5c5SDavid van Moolenbroek * The parameter specifies whether this is a poll operation,
614*7348b5c5SDavid van Moolenbroek * or a block-until-something-happens operation.
615*7348b5c5SDavid van Moolenbroek *
616*7348b5c5SDavid van Moolenbroek * The return value is 1 if something happened, 0 if not, < 0 if an
617*7348b5c5SDavid van Moolenbroek * error occurred.
618*7348b5c5SDavid van Moolenbroek */
619*7348b5c5SDavid van Moolenbroek
620*7348b5c5SDavid van Moolenbroek int
process_rings(int netin,int netout,int netex,int ttyin,int ttyout,int dopoll)621*7348b5c5SDavid van Moolenbroek process_rings(int netin, int netout, int netex, int ttyin, int ttyout,
622*7348b5c5SDavid van Moolenbroek int dopoll) /* If 0, then block until something to do */
623*7348b5c5SDavid van Moolenbroek {
624*7348b5c5SDavid van Moolenbroek struct pollfd set[3];
625*7348b5c5SDavid van Moolenbroek int c;
626*7348b5c5SDavid van Moolenbroek /* One wants to be a bit careful about setting returnValue
627*7348b5c5SDavid van Moolenbroek * to one, since a one implies we did some useful work,
628*7348b5c5SDavid van Moolenbroek * and therefore probably won't be called to block next
629*7348b5c5SDavid van Moolenbroek * time (TN3270 mode only).
630*7348b5c5SDavid van Moolenbroek */
631*7348b5c5SDavid van Moolenbroek int returnValue = 0;
632*7348b5c5SDavid van Moolenbroek
633*7348b5c5SDavid van Moolenbroek set[0].fd = net;
634*7348b5c5SDavid van Moolenbroek set[0].events = (netout ? POLLOUT : 0) | (netin ? POLLIN : 0) |
635*7348b5c5SDavid van Moolenbroek (netex ? POLLPRI : 0);
636*7348b5c5SDavid van Moolenbroek set[1].fd = tout;
637*7348b5c5SDavid van Moolenbroek set[1].events = ttyout ? POLLOUT : 0;
638*7348b5c5SDavid van Moolenbroek set[2].fd = tin;
639*7348b5c5SDavid van Moolenbroek set[2].events = ttyin ? POLLIN : 0;
640*7348b5c5SDavid van Moolenbroek
641*7348b5c5SDavid van Moolenbroek if ((c = poll(set, 3, dopoll ? 0 : INFTIM)) < 0) {
642*7348b5c5SDavid van Moolenbroek if (c == -1) {
643*7348b5c5SDavid van Moolenbroek /*
644*7348b5c5SDavid van Moolenbroek * we can get EINTR if we are in line mode,
645*7348b5c5SDavid van Moolenbroek * and the user does an escape (TSTP), or
646*7348b5c5SDavid van Moolenbroek * some other signal generator.
647*7348b5c5SDavid van Moolenbroek */
648*7348b5c5SDavid van Moolenbroek if (errno == EINTR) {
649*7348b5c5SDavid van Moolenbroek return 0;
650*7348b5c5SDavid van Moolenbroek }
651*7348b5c5SDavid van Moolenbroek #ifdef TN3270
652*7348b5c5SDavid van Moolenbroek /*
653*7348b5c5SDavid van Moolenbroek * we can get EBADF if we were in transparent
654*7348b5c5SDavid van Moolenbroek * mode, and the transcom process died.
655*7348b5c5SDavid van Moolenbroek */
656*7348b5c5SDavid van Moolenbroek if (errno == EBADF)
657*7348b5c5SDavid van Moolenbroek return 0;
658*7348b5c5SDavid van Moolenbroek #endif /* defined(TN3270) */
659*7348b5c5SDavid van Moolenbroek /* I don't like this, does it ever happen? */
660*7348b5c5SDavid van Moolenbroek printf("sleep(5) from telnet, after poll\r\n");
661*7348b5c5SDavid van Moolenbroek sleep(5);
662*7348b5c5SDavid van Moolenbroek }
663*7348b5c5SDavid van Moolenbroek return 0;
664*7348b5c5SDavid van Moolenbroek }
665*7348b5c5SDavid van Moolenbroek
666*7348b5c5SDavid van Moolenbroek /*
667*7348b5c5SDavid van Moolenbroek * Any urgent data?
668*7348b5c5SDavid van Moolenbroek */
669*7348b5c5SDavid van Moolenbroek if (set[0].revents & POLLPRI) {
670*7348b5c5SDavid van Moolenbroek SYNCHing = 1;
671*7348b5c5SDavid van Moolenbroek (void) ttyflush(1); /* flush already enqueued data */
672*7348b5c5SDavid van Moolenbroek }
673*7348b5c5SDavid van Moolenbroek
674*7348b5c5SDavid van Moolenbroek /*
675*7348b5c5SDavid van Moolenbroek * Something to read from the network...
676*7348b5c5SDavid van Moolenbroek */
677*7348b5c5SDavid van Moolenbroek if (set[0].revents & POLLIN) {
678*7348b5c5SDavid van Moolenbroek int canread;
679*7348b5c5SDavid van Moolenbroek
680*7348b5c5SDavid van Moolenbroek canread = ring_empty_consecutive(&netiring);
681*7348b5c5SDavid van Moolenbroek c = recv(net, (char *)netiring.supply, canread, 0);
682*7348b5c5SDavid van Moolenbroek if (c < 0 && errno == EWOULDBLOCK) {
683*7348b5c5SDavid van Moolenbroek c = 0;
684*7348b5c5SDavid van Moolenbroek } else if (c <= 0) {
685*7348b5c5SDavid van Moolenbroek return -1;
686*7348b5c5SDavid van Moolenbroek }
687*7348b5c5SDavid van Moolenbroek if (netdata) {
688*7348b5c5SDavid van Moolenbroek Dump('<', netiring.supply, c);
689*7348b5c5SDavid van Moolenbroek }
690*7348b5c5SDavid van Moolenbroek if (c)
691*7348b5c5SDavid van Moolenbroek ring_supplied(&netiring, c);
692*7348b5c5SDavid van Moolenbroek returnValue = 1;
693*7348b5c5SDavid van Moolenbroek }
694*7348b5c5SDavid van Moolenbroek
695*7348b5c5SDavid van Moolenbroek /*
696*7348b5c5SDavid van Moolenbroek * Something to read from the tty...
697*7348b5c5SDavid van Moolenbroek */
698*7348b5c5SDavid van Moolenbroek if (set[2].revents & POLLIN) {
699*7348b5c5SDavid van Moolenbroek c = TerminalRead(ttyiring.supply, ring_empty_consecutive(&ttyiring));
700*7348b5c5SDavid van Moolenbroek if (c < 0 && errno == EIO)
701*7348b5c5SDavid van Moolenbroek c = 0;
702*7348b5c5SDavid van Moolenbroek if (c < 0 && errno == EWOULDBLOCK) {
703*7348b5c5SDavid van Moolenbroek c = 0;
704*7348b5c5SDavid van Moolenbroek } else {
705*7348b5c5SDavid van Moolenbroek if (c < 0) {
706*7348b5c5SDavid van Moolenbroek return -1;
707*7348b5c5SDavid van Moolenbroek }
708*7348b5c5SDavid van Moolenbroek if (c == 0) {
709*7348b5c5SDavid van Moolenbroek /* must be an EOF... */
710*7348b5c5SDavid van Moolenbroek if (MODE_LOCAL_CHARS(globalmode) && isatty(tin)) {
711*7348b5c5SDavid van Moolenbroek *ttyiring.supply = termEofChar;
712*7348b5c5SDavid van Moolenbroek c = 1;
713*7348b5c5SDavid van Moolenbroek } else {
714*7348b5c5SDavid van Moolenbroek clienteof = 1;
715*7348b5c5SDavid van Moolenbroek shutdown(net, 1);
716*7348b5c5SDavid van Moolenbroek return 0;
717*7348b5c5SDavid van Moolenbroek }
718*7348b5c5SDavid van Moolenbroek }
719*7348b5c5SDavid van Moolenbroek if (termdata) {
720*7348b5c5SDavid van Moolenbroek Dump('<', ttyiring.supply, c);
721*7348b5c5SDavid van Moolenbroek }
722*7348b5c5SDavid van Moolenbroek ring_supplied(&ttyiring, c);
723*7348b5c5SDavid van Moolenbroek }
724*7348b5c5SDavid van Moolenbroek returnValue = 1; /* did something useful */
725*7348b5c5SDavid van Moolenbroek }
726*7348b5c5SDavid van Moolenbroek
727*7348b5c5SDavid van Moolenbroek if (set[0].revents & POLLOUT) {
728*7348b5c5SDavid van Moolenbroek returnValue |= netflush();
729*7348b5c5SDavid van Moolenbroek }
730*7348b5c5SDavid van Moolenbroek
731*7348b5c5SDavid van Moolenbroek if (set[1].revents & (POLLHUP|POLLNVAL))
732*7348b5c5SDavid van Moolenbroek return(-1);
733*7348b5c5SDavid van Moolenbroek
734*7348b5c5SDavid van Moolenbroek if (set[1].revents & POLLOUT) {
735*7348b5c5SDavid van Moolenbroek returnValue |= (ttyflush(SYNCHing|flushout) > 0);
736*7348b5c5SDavid van Moolenbroek }
737*7348b5c5SDavid van Moolenbroek
738*7348b5c5SDavid van Moolenbroek return returnValue;
739*7348b5c5SDavid van Moolenbroek }
740