summaryrefslogtreecommitdiffstats
path: root/crypto/heimdal/appl/telnet/telnet/sys_bsd.c
diff options
context:
space:
mode:
authorstas <stas@FreeBSD.org>2011-09-29 05:23:57 +0000
committerstas <stas@FreeBSD.org>2011-09-29 05:23:57 +0000
commitf6e720bf7e3d09d00d73f389a5dac8efdce0eb8c (patch)
treecf5b65423910d126fddaaf04b885d0de3507d692 /crypto/heimdal/appl/telnet/telnet/sys_bsd.c
parent51b6601db456e699ea5d4843cbc7239ee92d9c13 (diff)
downloadFreeBSD-src-f6e720bf7e3d09d00d73f389a5dac8efdce0eb8c.zip
FreeBSD-src-f6e720bf7e3d09d00d73f389a5dac8efdce0eb8c.tar.gz
- Flatten the vendor heimdal tree.
Diffstat (limited to 'crypto/heimdal/appl/telnet/telnet/sys_bsd.c')
-rw-r--r--crypto/heimdal/appl/telnet/telnet/sys_bsd.c979
1 files changed, 0 insertions, 979 deletions
diff --git a/crypto/heimdal/appl/telnet/telnet/sys_bsd.c b/crypto/heimdal/appl/telnet/telnet/sys_bsd.c
deleted file mode 100644
index 5bc2d12..0000000
--- a/crypto/heimdal/appl/telnet/telnet/sys_bsd.c
+++ /dev/null
@@ -1,979 +0,0 @@
-/*
- * Copyright (c) 1988, 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "telnet_locl.h"
-
-RCSID("$Id: sys_bsd.c 10941 2002-04-18 16:18:43Z joda $");
-
-/*
- * The following routines try to encapsulate what is system dependent
- * (at least between 4.x and dos) which is used in telnet.c.
- */
-
-int
- tout, /* Output file descriptor */
- tin, /* Input file descriptor */
- net;
-
-struct termios old_tc = { 0 };
-extern struct termios new_tc;
-
-# ifndef TCSANOW
-# ifdef TCSETS
-# define TCSANOW TCSETS
-# define TCSADRAIN TCSETSW
-# define tcgetattr(f, t) ioctl(f, TCGETS, (char *)t)
-# else
-# ifdef TCSETA
-# define TCSANOW TCSETA
-# define TCSADRAIN TCSETAW
-# define tcgetattr(f, t) ioctl(f, TCGETA, (char *)t)
-# else
-# define TCSANOW TIOCSETA
-# define TCSADRAIN TIOCSETAW
-# define tcgetattr(f, t) ioctl(f, TIOCGETA, (char *)t)
-# endif
-# endif
-# define tcsetattr(f, a, t) ioctl(f, a, (char *)t)
-# define cfgetospeed(ptr) ((ptr)->c_cflag&CBAUD)
-# ifdef CIBAUD
-# define cfgetispeed(ptr) (((ptr)->c_cflag&CIBAUD) >> IBSHIFT)
-# else
-# define cfgetispeed(ptr) cfgetospeed(ptr)
-# endif
-# endif /* TCSANOW */
-
-static fd_set ibits, obits, xbits;
-
-
-void
-init_sys(void)
-{
- tout = fileno(stdout);
- tin = fileno(stdin);
- FD_ZERO(&ibits);
- FD_ZERO(&obits);
- FD_ZERO(&xbits);
-
- errno = 0;
-}
-
-
-int
-TerminalWrite(char *buf, int n)
-{
- return write(tout, buf, n);
-}
-
-int
-TerminalRead(unsigned char *buf, int n)
-{
- return read(tin, buf, n);
-}
-
-/*
- *
- */
-
-int
-TerminalAutoFlush(void)
-{
-#if defined(LNOFLSH)
- int flush;
-
- ioctl(0, TIOCLGET, (char *)&flush);
- return !(flush&LNOFLSH); /* if LNOFLSH, no autoflush */
-#else /* LNOFLSH */
- return 1;
-#endif /* LNOFLSH */
-}
-
-/*
- * TerminalSpecialChars()
- *
- * Look at an input character to see if it is a special character
- * and decide what to do.
- *
- * Output:
- *
- * 0 Don't add this character.
- * 1 Do add this character
- */
-
-int
-TerminalSpecialChars(int c)
-{
- if (c == termIntChar) {
- intp();
- return 0;
- } else if (c == termQuitChar) {
-#ifdef KLUDGELINEMODE
- if (kludgelinemode)
- sendbrk();
- else
-#endif
- sendabort();
- return 0;
- } else if (c == termEofChar) {
- if (my_want_state_is_will(TELOPT_LINEMODE)) {
- sendeof();
- return 0;
- }
- return 1;
- } else if (c == termSuspChar) {
- sendsusp();
- return(0);
- } else if (c == termFlushChar) {
- xmitAO(); /* Transmit Abort Output */
- return 0;
- } else if (!MODE_LOCAL_CHARS(globalmode)) {
- if (c == termKillChar) {
- xmitEL();
- return 0;
- } else if (c == termEraseChar) {
- xmitEC(); /* Transmit Erase Character */
- return 0;
- }
- }
- return 1;
-}
-
-
-/*
- * Flush output to the terminal
- */
-
-void
-TerminalFlushOutput(void)
-{
-#ifdef TIOCFLUSH
- ioctl(fileno(stdout), TIOCFLUSH, (char *) 0);
-#else
- ioctl(fileno(stdout), TCFLSH, (char *) 0);
-#endif
-}
-
-void
-TerminalSaveState(void)
-{
- tcgetattr(0, &old_tc);
-
- new_tc = old_tc;
-
-#ifndef VDISCARD
- termFlushChar = CONTROL('O');
-#endif
-#ifndef VWERASE
- termWerasChar = CONTROL('W');
-#endif
-#ifndef VREPRINT
- termRprntChar = CONTROL('R');
-#endif
-#ifndef VLNEXT
- termLiteralNextChar = CONTROL('V');
-#endif
-#ifndef VSTART
- termStartChar = CONTROL('Q');
-#endif
-#ifndef VSTOP
- termStopChar = CONTROL('S');
-#endif
-#ifndef VSTATUS
- termAytChar = CONTROL('T');
-#endif
-}
-
-cc_t*
-tcval(int func)
-{
- switch(func) {
- case SLC_IP: return(&termIntChar);
- case SLC_ABORT: return(&termQuitChar);
- case SLC_EOF: return(&termEofChar);
- case SLC_EC: return(&termEraseChar);
- case SLC_EL: return(&termKillChar);
- case SLC_XON: return(&termStartChar);
- case SLC_XOFF: return(&termStopChar);
- case SLC_FORW1: return(&termForw1Char);
- case SLC_FORW2: return(&termForw2Char);
-# ifdef VDISCARD
- case SLC_AO: return(&termFlushChar);
-# endif
-# ifdef VSUSP
- case SLC_SUSP: return(&termSuspChar);
-# endif
-# ifdef VWERASE
- case SLC_EW: return(&termWerasChar);
-# endif
-# ifdef VREPRINT
- case SLC_RP: return(&termRprntChar);
-# endif
-# ifdef VLNEXT
- case SLC_LNEXT: return(&termLiteralNextChar);
-# endif
-# ifdef VSTATUS
- case SLC_AYT: return(&termAytChar);
-# endif
-
- case SLC_SYNCH:
- case SLC_BRK:
- case SLC_EOR:
- default:
- return((cc_t *)0);
- }
-}
-
-void
-TerminalDefaultChars(void)
-{
- memmove(new_tc.c_cc, old_tc.c_cc, sizeof(old_tc.c_cc));
-# ifndef VDISCARD
- termFlushChar = CONTROL('O');
-# endif
-# ifndef VWERASE
- termWerasChar = CONTROL('W');
-# endif
-# ifndef VREPRINT
- termRprntChar = CONTROL('R');
-# endif
-# ifndef VLNEXT
- termLiteralNextChar = CONTROL('V');
-# endif
-# ifndef VSTART
- termStartChar = CONTROL('Q');
-# endif
-# ifndef VSTOP
- termStopChar = CONTROL('S');
-# endif
-# ifndef VSTATUS
- termAytChar = CONTROL('T');
-# endif
-}
-
-#ifdef notdef
-void
-TerminalRestoreState()
-{
-}
-#endif
-
-/*
- * TerminalNewMode - set up terminal to a specific mode.
- * MODE_ECHO: do local terminal echo
- * MODE_FLOW: do local flow control
- * MODE_TRAPSIG: do local mapping to TELNET IAC sequences
- * MODE_EDIT: do local line editing
- *
- * Command mode:
- * MODE_ECHO|MODE_EDIT|MODE_FLOW|MODE_TRAPSIG
- * local echo
- * local editing
- * local xon/xoff
- * local signal mapping
- *
- * Linemode:
- * local/no editing
- * Both Linemode and Single Character mode:
- * local/remote echo
- * local/no xon/xoff
- * local/no signal mapping
- */
-
-
-#ifdef SIGTSTP
-static RETSIGTYPE susp(int);
-#endif /* SIGTSTP */
-#ifdef SIGINFO
-static RETSIGTYPE ayt(int);
-#endif
-
-void
-TerminalNewMode(int f)
-{
- static int prevmode = 0;
- struct termios tmp_tc;
- int onoff;
- int old;
- cc_t esc;
-
- globalmode = f&~MODE_FORCE;
- if (prevmode == f)
- return;
-
- /*
- * Write any outstanding data before switching modes
- * ttyflush() returns 0 only when there is no more data
- * left to write out, it returns -1 if it couldn't do
- * anything at all, otherwise it returns 1 + the number
- * of characters left to write.
- */
- old = ttyflush(SYNCHing|flushout);
- if (old < 0 || old > 1) {
- tcgetattr(tin, &tmp_tc);
- do {
- /*
- * Wait for data to drain, then flush again.
- */
- tcsetattr(tin, TCSADRAIN, &tmp_tc);
- old = ttyflush(SYNCHing|flushout);
- } while (old < 0 || old > 1);
- }
-
- old = prevmode;
- prevmode = f&~MODE_FORCE;
- tmp_tc = new_tc;
-
- if (f&MODE_ECHO) {
- tmp_tc.c_lflag |= ECHO;
- tmp_tc.c_oflag |= ONLCR;
- if (crlf)
- tmp_tc.c_iflag |= ICRNL;
- } else {
- tmp_tc.c_lflag &= ~ECHO;
- tmp_tc.c_oflag &= ~ONLCR;
-# ifdef notdef
- if (crlf)
- tmp_tc.c_iflag &= ~ICRNL;
-# endif
- }
-
- if ((f&MODE_FLOW) == 0) {
- tmp_tc.c_iflag &= ~(IXOFF|IXON); /* Leave the IXANY bit alone */
- } else {
- if (restartany < 0) {
- tmp_tc.c_iflag |= IXOFF|IXON; /* Leave the IXANY bit alone */
- } else if (restartany > 0) {
- tmp_tc.c_iflag |= IXOFF|IXON|IXANY;
- } else {
- tmp_tc.c_iflag |= IXOFF|IXON;
- tmp_tc.c_iflag &= ~IXANY;
- }
- }
-
- if ((f&MODE_TRAPSIG) == 0) {
- tmp_tc.c_lflag &= ~ISIG;
- localchars = 0;
- } else {
- tmp_tc.c_lflag |= ISIG;
- localchars = 1;
- }
-
- if (f&MODE_EDIT) {
- tmp_tc.c_lflag |= ICANON;
- } else {
- tmp_tc.c_lflag &= ~ICANON;
- tmp_tc.c_iflag &= ~ICRNL;
- tmp_tc.c_cc[VMIN] = 1;
- tmp_tc.c_cc[VTIME] = 0;
- }
-
- if ((f&(MODE_EDIT|MODE_TRAPSIG)) == 0) {
-# ifdef VLNEXT
- tmp_tc.c_cc[VLNEXT] = (cc_t)(_POSIX_VDISABLE);
-# endif
- }
-
- if (f&MODE_SOFT_TAB) {
-# ifdef OXTABS
- tmp_tc.c_oflag |= OXTABS;
-# endif
-# ifdef TABDLY
- tmp_tc.c_oflag &= ~TABDLY;
- tmp_tc.c_oflag |= TAB3;
-# endif
- } else {
-# ifdef OXTABS
- tmp_tc.c_oflag &= ~OXTABS;
-# endif
-# ifdef TABDLY
- tmp_tc.c_oflag &= ~TABDLY;
-# endif
- }
-
- if (f&MODE_LIT_ECHO) {
-# ifdef ECHOCTL
- tmp_tc.c_lflag &= ~ECHOCTL;
-# endif
- } else {
-# ifdef ECHOCTL
- tmp_tc.c_lflag |= ECHOCTL;
-# endif
- }
-
- if (f == -1) {
- onoff = 0;
- } else {
- if (f & MODE_INBIN)
- tmp_tc.c_iflag &= ~ISTRIP;
- else
- tmp_tc.c_iflag |= ISTRIP;
- if ((f & MODE_OUTBIN) || (f & MODE_OUT8)) {
- tmp_tc.c_cflag &= ~(CSIZE|PARENB);
- tmp_tc.c_cflag |= CS8;
- if(f & MODE_OUTBIN)
- tmp_tc.c_oflag &= ~OPOST;
- else
- tmp_tc.c_oflag |= OPOST;
- } else {
- tmp_tc.c_cflag &= ~(CSIZE|PARENB);
- tmp_tc.c_cflag |= old_tc.c_cflag & (CSIZE|PARENB);
- tmp_tc.c_oflag |= OPOST;
- }
- onoff = 1;
- }
-
- if (f != -1) {
-
-#ifdef SIGTSTP
- signal(SIGTSTP, susp);
-#endif /* SIGTSTP */
-#ifdef SIGINFO
- signal(SIGINFO, ayt);
-#endif
-#ifdef NOKERNINFO
- tmp_tc.c_lflag |= NOKERNINFO;
-#endif
- /*
- * We don't want to process ^Y here. It's just another
- * character that we'll pass on to the back end. It has
- * to process it because it will be processed when the
- * user attempts to read it, not when we send it.
- */
-# ifdef VDSUSP
- tmp_tc.c_cc[VDSUSP] = (cc_t)(_POSIX_VDISABLE);
-# endif
- /*
- * If the VEOL character is already set, then use VEOL2,
- * otherwise use VEOL.
- */
- esc = (rlogin != _POSIX_VDISABLE) ? rlogin : escape;
- if ((tmp_tc.c_cc[VEOL] != esc)
-# ifdef VEOL2
- && (tmp_tc.c_cc[VEOL2] != esc)
-# endif
- ) {
- if (tmp_tc.c_cc[VEOL] == (cc_t)(_POSIX_VDISABLE))
- tmp_tc.c_cc[VEOL] = esc;
-# ifdef VEOL2
- else if (tmp_tc.c_cc[VEOL2] == (cc_t)(_POSIX_VDISABLE))
- tmp_tc.c_cc[VEOL2] = esc;
-# endif
- }
- } else {
- sigset_t sm;
-
-#ifdef SIGINFO
- signal(SIGINFO, ayt_status);
-#endif
-#ifdef SIGTSTP
- signal(SIGTSTP, SIG_DFL);
- sigemptyset(&sm);
- sigaddset(&sm, SIGTSTP);
- sigprocmask(SIG_UNBLOCK, &sm, NULL);
-#endif /* SIGTSTP */
- tmp_tc = old_tc;
- }
- if (tcsetattr(tin, TCSADRAIN, &tmp_tc) < 0)
- tcsetattr(tin, TCSANOW, &tmp_tc);
-
- ioctl(tin, FIONBIO, (char *)&onoff);
- ioctl(tout, FIONBIO, (char *)&onoff);
-
-}
-
-/*
- * Try to guess whether speeds are "encoded" (4.2BSD) or just numeric (4.4BSD).
- */
-#if B4800 != 4800
-#define DECODE_BAUD
-#endif
-
-#ifdef DECODE_BAUD
-#ifndef B7200
-#define B7200 B4800
-#endif
-
-#ifndef B14400
-#define B14400 B9600
-#endif
-
-#ifndef B19200
-# define B19200 B14400
-#endif
-
-#ifndef B28800
-#define B28800 B19200
-#endif
-
-#ifndef B38400
-# define B38400 B28800
-#endif
-
-#ifndef B57600
-#define B57600 B38400
-#endif
-
-#ifndef B76800
-#define B76800 B57600
-#endif
-
-#ifndef B115200
-#define B115200 B76800
-#endif
-
-#ifndef B230400
-#define B230400 B115200
-#endif
-
-
-/*
- * This code assumes that the values B0, B50, B75...
- * are in ascending order. They do not have to be
- * contiguous.
- */
-struct termspeeds {
- long speed;
- long value;
-} termspeeds[] = {
- { 0, B0 }, { 50, B50 }, { 75, B75 },
- { 110, B110 }, { 134, B134 }, { 150, B150 },
- { 200, B200 }, { 300, B300 }, { 600, B600 },
- { 1200, B1200 }, { 1800, B1800 }, { 2400, B2400 },
- { 4800, B4800 }, { 7200, B7200 }, { 9600, B9600 },
- { 14400, B14400 }, { 19200, B19200 }, { 28800, B28800 },
- { 38400, B38400 }, { 57600, B57600 }, { 115200, B115200 },
- { 230400, B230400 }, { -1, B230400 }
-};
-#endif /* DECODE_BAUD */
-
-void
-TerminalSpeeds(long *input_speed, long *output_speed)
-{
-#ifdef DECODE_BAUD
- struct termspeeds *tp;
-#endif /* DECODE_BAUD */
- long in, out;
-
- out = cfgetospeed(&old_tc);
- in = cfgetispeed(&old_tc);
- if (in == 0)
- in = out;
-
-#ifdef DECODE_BAUD
- tp = termspeeds;
- while ((tp->speed != -1) && (tp->value < in))
- tp++;
- *input_speed = tp->speed;
-
- tp = termspeeds;
- while ((tp->speed != -1) && (tp->value < out))
- tp++;
- *output_speed = tp->speed;
-#else /* DECODE_BAUD */
- *input_speed = in;
- *output_speed = out;
-#endif /* DECODE_BAUD */
-}
-
-int
-TerminalWindowSize(long *rows, long *cols)
-{
- struct winsize ws;
-
- if (get_window_size (STDIN_FILENO, &ws) == 0) {
- *rows = ws.ws_row;
- *cols = ws.ws_col;
- return 1;
- } else
- return 0;
-}
-
-int
-NetClose(int fd)
-{
- return close(fd);
-}
-
-
-void
-NetNonblockingIO(int fd, int onoff)
-{
- ioctl(fd, FIONBIO, (char *)&onoff);
-}
-
-
-/*
- * Various signal handling routines.
- */
-
-static RETSIGTYPE deadpeer(int),
- intr(int), intr2(int), susp(int), sendwin(int);
-#ifdef SIGINFO
-static RETSIGTYPE ayt(int);
-#endif
-
-
- /* ARGSUSED */
-static RETSIGTYPE
-deadpeer(int sig)
-{
- setcommandmode();
- longjmp(peerdied, -1);
-}
-
-int intr_happened = 0;
-int intr_waiting = 0;
-
- /* ARGSUSED */
-static RETSIGTYPE
-intr(int sig)
-{
- if (intr_waiting) {
- intr_happened = 1;
- return;
- }
- if (localchars) {
- intp();
- return;
- }
- setcommandmode();
- longjmp(toplevel, -1);
-}
-
- /* ARGSUSED */
-static RETSIGTYPE
-intr2(int sig)
-{
- if (localchars) {
-#ifdef KLUDGELINEMODE
- if (kludgelinemode)
- sendbrk();
- else
-#endif
- sendabort();
- return;
- }
-}
-
-#ifdef SIGTSTP
- /* ARGSUSED */
-static RETSIGTYPE
-susp(int sig)
-{
- if ((rlogin != _POSIX_VDISABLE) && rlogin_susp())
- return;
- if (localchars)
- sendsusp();
-}
-#endif
-
-#ifdef SIGWINCH
- /* ARGSUSED */
-static RETSIGTYPE
-sendwin(int sig)
-{
- if (connected) {
- sendnaws();
- }
-}
-#endif
-
-#ifdef SIGINFO
- /* ARGSUSED */
-static RETSIGTYPE
-ayt(int sig)
-{
- if (connected)
- sendayt();
- else
- ayt_status(sig);
-}
-#endif
-
-
-void
-sys_telnet_init(void)
-{
- signal(SIGINT, intr);
- signal(SIGQUIT, intr2);
- signal(SIGPIPE, deadpeer);
-#ifdef SIGWINCH
- signal(SIGWINCH, sendwin);
-#endif
-#ifdef SIGTSTP
- signal(SIGTSTP, susp);
-#endif
-#ifdef SIGINFO
- signal(SIGINFO, ayt);
-#endif
-
- setconnmode(0);
-
- NetNonblockingIO(net, 1);
-
-
-#if defined(SO_OOBINLINE)
- if (SetSockOpt(net, SOL_SOCKET, SO_OOBINLINE, 1) == -1)
- perror("setsockopt (SO_OOBINLINE) (ignored)");
-#endif /* defined(SO_OOBINLINE) */
-}
-
-/*
- * Process rings -
- *
- * This routine tries to fill up/empty our various rings.
- *
- * The parameter specifies whether this is a poll operation,
- * or a block-until-something-happens operation.
- *
- * The return value is 1 if something happened, 0 if not.
- */
-
-int
-process_rings(int netin,
- int netout,
- int netex,
- int ttyin,
- int ttyout,
- int poll) /* If 0, then block until something to do */
-{
- int c;
- /* One wants to be a bit careful about setting returnValue
- * to one, since a one implies we did some useful work,
- * and therefore probably won't be called to block next
- * time (TN3270 mode only).
- */
- int returnValue = 0;
- static struct timeval TimeValue = { 0 };
-
- if (net >= FD_SETSIZE
- || tout >= FD_SETSIZE
- || tin >= FD_SETSIZE)
- errx (1, "fd too large");
-
- if (netout) {
- FD_SET(net, &obits);
- }
- if (ttyout) {
- FD_SET(tout, &obits);
- }
- if (ttyin) {
- FD_SET(tin, &ibits);
- }
- if (netin) {
- FD_SET(net, &ibits);
- }
-#if !defined(SO_OOBINLINE)
- if (netex) {
- FD_SET(net, &xbits);
- }
-#endif
- if ((c = select(FD_SETSIZE, &ibits, &obits, &xbits,
- (poll == 0)? (struct timeval *)0 : &TimeValue)) < 0) {
- if (c == -1) {
- /*
- * we can get EINTR if we are in line mode,
- * and the user does an escape (TSTP), or
- * some other signal generator.
- */
- if (errno == EINTR) {
- return 0;
- }
- /* I don't like this, does it ever happen? */
- printf("sleep(5) from telnet, after select\r\n");
- sleep(5);
- }
- return 0;
- }
-
- /*
- * Any urgent data?
- */
- if (FD_ISSET(net, &xbits)) {
- FD_CLR(net, &xbits);
- SYNCHing = 1;
- ttyflush(1); /* flush already enqueued data */
- }
-
- /*
- * Something to read from the network...
- */
- if (FD_ISSET(net, &ibits)) {
- int canread;
-
- FD_CLR(net, &ibits);
- canread = ring_empty_consecutive(&netiring);
-#if !defined(SO_OOBINLINE)
- /*
- * In 4.2 (and some early 4.3) systems, the
- * OOB indication and data handling in the kernel
- * is such that if two separate TCP Urgent requests
- * come in, one byte of TCP data will be overlaid.
- * This is fatal for Telnet, but we try to live
- * with it.
- *
- * In addition, in 4.2 (and...), a special protocol
- * is needed to pick up the TCP Urgent data in
- * the correct sequence.
- *
- * What we do is: if we think we are in urgent
- * mode, we look to see if we are "at the mark".
- * If we are, we do an OOB receive. If we run
- * this twice, we will do the OOB receive twice,
- * but the second will fail, since the second
- * time we were "at the mark", but there wasn't
- * any data there (the kernel doesn't reset
- * "at the mark" until we do a normal read).
- * Once we've read the OOB data, we go ahead
- * and do normal reads.
- *
- * There is also another problem, which is that
- * since the OOB byte we read doesn't put us
- * out of OOB state, and since that byte is most
- * likely the TELNET DM (data mark), we would
- * stay in the TELNET SYNCH (SYNCHing) state.
- * So, clocks to the rescue. If we've "just"
- * received a DM, then we test for the
- * presence of OOB data when the receive OOB
- * fails (and AFTER we did the normal mode read
- * to clear "at the mark").
- */
- if (SYNCHing) {
- int atmark;
- static int bogus_oob = 0, first = 1;
-
- ioctl(net, SIOCATMARK, (char *)&atmark);
- if (atmark) {
- c = recv(net, netiring.supply, canread, MSG_OOB);
- if ((c == -1) && (errno == EINVAL)) {
- c = recv(net, netiring.supply, canread, 0);
- if (clocks.didnetreceive < clocks.gotDM) {
- SYNCHing = stilloob();
- }
- } else if (first && c > 0) {
- /*
- * Bogosity check. Systems based on 4.2BSD
- * do not return an error if you do a second
- * recv(MSG_OOB). So, we do one. If it
- * succeeds and returns exactly the same
- * data, then assume that we are running
- * on a broken system and set the bogus_oob
- * flag. (If the data was different, then
- * we probably got some valid new data, so
- * increment the count...)
- */
- int i;
- i = recv(net, netiring.supply + c, canread - c, MSG_OOB);
- if (i == c &&
- memcmp(netiring.supply, netiring.supply + c, i) == 0) {
- bogus_oob = 1;
- first = 0;
- } else if (i < 0) {
- bogus_oob = 0;
- first = 0;
- } else
- c += i;
- }
- if (bogus_oob && c > 0) {
- int i;
- /*
- * Bogosity. We have to do the read
- * to clear the atmark to get out of
- * an infinate loop.
- */
- i = read(net, netiring.supply + c, canread - c);
- if (i > 0)
- c += i;
- }
- } else {
- c = recv(net, netiring.supply, canread, 0);
- }
- } else {
- c = recv(net, netiring.supply, canread, 0);
- }
- settimer(didnetreceive);
-#else /* !defined(SO_OOBINLINE) */
- c = recv(net, (char *)netiring.supply, canread, 0);
-#endif /* !defined(SO_OOBINLINE) */
- if (c < 0 && errno == EWOULDBLOCK) {
- c = 0;
- } else if (c <= 0) {
- return -1;
- }
- if (netdata) {
- Dump('<', netiring.supply, c);
- }
- if (c)
- ring_supplied(&netiring, c);
- returnValue = 1;
- }
-
- /*
- * Something to read from the tty...
- */
- if (FD_ISSET(tin, &ibits)) {
- FD_CLR(tin, &ibits);
- c = TerminalRead(ttyiring.supply, ring_empty_consecutive(&ttyiring));
- if (c < 0 && errno == EIO)
- c = 0;
- if (c < 0 && errno == EWOULDBLOCK) {
- c = 0;
- } else {
- /* EOF detection for line mode!!!! */
- if ((c == 0) && MODE_LOCAL_CHARS(globalmode) && isatty(tin)) {
- /* must be an EOF... */
- *ttyiring.supply = termEofChar;
- c = 1;
- }
- if (c <= 0) {
- return -1;
- }
- if (termdata) {
- Dump('<', ttyiring.supply, c);
- }
- ring_supplied(&ttyiring, c);
- }
- returnValue = 1; /* did something useful */
- }
-
- if (FD_ISSET(net, &obits)) {
- FD_CLR(net, &obits);
- returnValue |= netflush();
- }
- if (FD_ISSET(tout, &obits)) {
- FD_CLR(tout, &obits);
- returnValue |= (ttyflush(SYNCHing|flushout) > 0);
- }
-
- return returnValue;
-}
OpenPOWER on IntegriCloud