?? sys_bsd.c
字號:
/* $OpenBSD: sys_bsd.c,v 1.14 2003/06/03 02:56:18 millert Exp $ *//* $NetBSD: sys_bsd.c,v 1.11 1996/02/28 21:04:10 thorpej Exp $ *//* * 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. 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"#include <err.h>/* * 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;#ifndef USE_TERMIOstruct tchars otc = { 0 }, ntc = { 0 };struct ltchars oltc = { 0 }, nltc = { 0 };struct sgttyb ottyb = { 0 }, nttyb = { 0 };int olmode = 0;# define cfgetispeed(ptr) (ptr)->sg_ispeed# define cfgetospeed(ptr) (ptr)->sg_ospeed# define old_tc ottyb#else /* USE_TERMIO */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 */# ifdef sysV88# define TIOCFLUSH TC_PX_DRAIN# endif#endif /* USE_TERMIO */fd_set *ibitsp, *obitsp, *xbitsp;int fdsn; voidinit_sys(){ tout = fileno(stdout); tin = fileno(stdin); errno = 0;} intTerminalWrite(buf, n) char *buf; int n;{ return write(tout, buf, n);} intTerminalRead(buf, n) unsigned char *buf; int n;{ return read(tin, buf, n);}/* * */ intTerminalAutoFlush(){#if defined(LNOFLSH) int flush; ioctl(0, TIOCLGET, (char *)&flush); return !(flush&LNOFLSH); /* if LNOFLSH, no autoflush */#else /* LNOFLSH */ return 1;#endif /* LNOFLSH */}#ifdef KLUDGELINEMODEextern int kludgelinemode;#endif/* * 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 */extern void xmitAO(), xmitEL(), xmitEC(), intp(), sendbrk(); intTerminalSpecialChars(c) 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 */ voidTerminalFlushOutput(){#ifdef TIOCFLUSH int com = FWRITE; (void) ioctl(fileno(stdout), TIOCFLUSH, (int *) &com);#else (void) ioctl(fileno(stdout), TCFLSH, (int *) 0);#endif} voidTerminalSaveState(){#ifndef USE_TERMIO ioctl(0, TIOCGETP, (char *)&ottyb); ioctl(0, TIOCGETC, (char *)&otc); ioctl(0, TIOCGLTC, (char *)&oltc); ioctl(0, TIOCLGET, (char *)&olmode); ntc = otc; nltc = oltc; nttyb = ottyb;#else /* USE_TERMIO */ 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#endif /* USE_TERMIO */} cc_t *tcval(func) 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);#ifdef USE_TERMIO 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#endif case SLC_SYNCH: case SLC_BRK: case SLC_EOR: default: return((cc_t *)0); }} voidTerminalDefaultChars(){#ifndef USE_TERMIO ntc = otc; nltc = oltc; nttyb.sg_kill = ottyb.sg_kill; nttyb.sg_erase = ottyb.sg_erase;#else /* USE_TERMIO */ 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#endif /* USE_TERMIO */}#ifdef notdefvoidTerminalRestoreState(){}#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 SIGTSTPstatic void susp();#endif /* SIGTSTP */#ifdef SIGINFOstatic void ayt();#endif voidTerminalNewMode(f) int f;{ static int prevmode = 0;#ifndef USE_TERMIO struct tchars tc; struct ltchars ltc; struct sgttyb sb; int lmode;#else /* USE_TERMIO */ struct termios tmp_tc;#endif /* USE_TERMIO */ 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.#ifndef USE_TERMIO * We would really like ask the kernel to wait for the output * to drain, like we can do with the TCSADRAIN, but we don't have * that option. The only ioctl that waits for the output to * drain, TIOCSETP, also flushes the input queue, which is NOT * what we want (TIOCSETP is like TCSADFLUSH).#endif */ old = ttyflush(SYNCHing|flushout); if (old < 0 || old > 1) {#ifdef USE_TERMIO tcgetattr(tin, &tmp_tc);#endif /* USE_TERMIO */ do { /* * Wait for data to drain, then flush again. */#ifdef USE_TERMIO tcsetattr(tin, TCSADRAIN, &tmp_tc);#endif /* USE_TERMIO */ old = ttyflush(SYNCHing|flushout); } while (old < 0 || old > 1); } old = prevmode; prevmode = f&~MODE_FORCE;#ifndef USE_TERMIO sb = nttyb; tc = ntc; ltc = nltc; lmode = olmode;#else tmp_tc = new_tc;#endif if (f&MODE_ECHO) {#ifndef USE_TERMIO sb.sg_flags |= ECHO;#else tmp_tc.c_lflag |= ECHO; tmp_tc.c_oflag |= ONLCR; if (crlf) tmp_tc.c_iflag |= ICRNL;#endif } else {#ifndef USE_TERMIO sb.sg_flags &= ~ECHO;#else tmp_tc.c_lflag &= ~ECHO; tmp_tc.c_oflag &= ~ONLCR;# ifdef notdef if (crlf) tmp_tc.c_iflag &= ~ICRNL;# endif#endif } if ((f&MODE_FLOW) == 0) {#ifndef USE_TERMIO tc.t_startc = _POSIX_VDISABLE; tc.t_stopc = _POSIX_VDISABLE;#else 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; }#endif } if ((f&MODE_TRAPSIG) == 0) {#ifndef USE_TERMIO tc.t_intrc = _POSIX_VDISABLE; tc.t_quitc = _POSIX_VDISABLE; tc.t_eofc = _POSIX_VDISABLE; ltc.t_suspc = _POSIX_VDISABLE; ltc.t_dsuspc = _POSIX_VDISABLE;#else tmp_tc.c_lflag &= ~ISIG;#endif localchars = 0; } else {#ifdef USE_TERMIO tmp_tc.c_lflag |= ISIG;#endif localchars = 1; } if (f&MODE_EDIT) {#ifndef USE_TERMIO sb.sg_flags &= ~CBREAK; sb.sg_flags |= CRMOD;#else tmp_tc.c_lflag |= ICANON;#endif } else {#ifndef USE_TERMIO sb.sg_flags |= CBREAK; if (f&MODE_ECHO) sb.sg_flags |= CRMOD; else sb.sg_flags &= ~CRMOD;#else tmp_tc.c_lflag &= ~ICANON; tmp_tc.c_iflag &= ~ICRNL; tmp_tc.c_cc[VMIN] = 1; tmp_tc.c_cc[VTIME] = 0;#endif } if ((f&(MODE_EDIT|MODE_TRAPSIG)) == 0) {#ifndef USE_TERMIO ltc.t_lnextc = _POSIX_VDISABLE;#else tmp_tc.c_lflag &= ~IEXTEN;#endif } if (f&MODE_SOFT_TAB) {#ifndef USE_TERMIO sb.sg_flags |= XTABS;#else# ifdef OXTABS tmp_tc.c_oflag |= OXTABS;# endif# ifdef TABDLY tmp_tc.c_oflag &= ~TABDLY; tmp_tc.c_oflag |= TAB3;# endif#endif } else {#ifndef USE_TERMIO sb.sg_flags &= ~XTABS;#else# ifdef OXTABS tmp_tc.c_oflag &= ~OXTABS;# endif# ifdef TABDLY tmp_tc.c_oflag &= ~TABDLY;# endif#endif } if (f&MODE_LIT_ECHO) {#ifndef USE_TERMIO lmode &= ~LCTLECH;#else# ifdef ECHOCTL tmp_tc.c_lflag &= ~ECHOCTL;# endif#endif } else {#ifndef USE_TERMIO lmode |= LCTLECH;#else# ifdef ECHOCTL tmp_tc.c_lflag |= ECHOCTL;# endif#endif } if (f == -1) { onoff = 0; } else {#ifndef USE_TERMIO if (f & MODE_OUTBIN) lmode |= LLITOUT; else lmode &= ~LLITOUT; if (f & MODE_INBIN) lmode |= LPASS8; else lmode &= ~LPASS8;#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; }#endif onoff = 1; } if (f != -1) {#ifdef SIGTSTP (void) signal(SIGTSTP, susp);#endif /* SIGTSTP */#ifdef SIGINFO (void) signal(SIGINFO, ayt);#endif#if defined(USE_TERMIO) && defined(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. */#ifndef USE_TERMIO ltc.t_dsuspc = _POSIX_VDISABLE;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -