📄 sys_bsd.c
字号:
/* 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. */#ifdef SHOW_SCCSIDSstatic char sccsid[] = "@(#)sys_bsd.c 8.4 (Berkeley) 5/30/95";#endif/* The following routines try to encapsulate what is system dependent *//* (at least between 4.x and dos) which is used in telnet.c. */#include "config.h"#include <fcntl.h>#include <sys/types.h>#include <sys/time.h>#include <sys/socket.h>#ifdef HAVE_SYS_SELECT_H#include <sys/select.h>#endif#include <signal.h>#include <errno.h>#include <arpa/telnet.h>#include "ring.h"#include "fdset.h"#include "defines.h"#include "externs.h"#include "types.h"#define DONT_NEED_SIGBLOCK#define DONT_NEED_SIGUNBLOCK#define DONT_NEED_SIGPAUSE#define DONT_NEED_SIGPENDING#include "sigfix.h"extern RETSIGTYPE ayt_status(), ayt(), susp();int tout; /* Output file descriptor */int tin; /* Input file descriptor */int 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 termio old_tc = { 0 };extern struct termio 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 */static fd_set ibits, obits, xbits;void init_sys() { tout = fileno(stdout); tin = fileno(stdin); FD_ZERO(&ibits); FD_ZERO(&obits); FD_ZERO(&xbits); errno = 0;}int TerminalWrite(unsigned char *buf, int n) { return write(tout, buf, n);}int TerminalRead(unsigned char *buf, int n) { return read(tin, buf, n);}int TerminalAutoFlush() {#ifdef LNOFLSH int flush; ioctl(0, TIOCLGET, (char *)&flush); return !(flush & LNOFLSH); /* if LNOFLSH, no autoflush */#else return 1;#endif}#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();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() {#ifdef TIOCFLUSH ioctl(fileno(stdout), TIOCFLUSH, (char *) 0);#else ioctl(fileno(stdout), TCFLSH, (char *) 0);#endif}void TerminalSaveState() {#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(register 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); }}void TerminalDefaultChars() {#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 notdefvoid 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 */void TerminalNewMode(register int f) { static int prevmode = 0;#ifndef USE_TERMIO struct tchars tc; struct ltchars ltc; struct sgttyb sb; int lmode;#else /* USE_TERMIO */ struct termio 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 /* Wait for data to drain, then flush again. */ do {#ifdef USE_TERMIO tcsetattr(tin, TCSADRAIN, &tmp_tc);#endif 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# ifdef VLNEXT tmp_tc.c_cc[VLNEXT] = (cc_t)(_POSIX_VDISABLE);# endif#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 }#ifndef USE_TERMIO if (f & MODE_LIT_ECHO) lmode &= ~LCTLECH; else lmode |= LCTLECH;#elif defined(ECHOCTL) if (f & MODE_LIT_ECHO) tmp_tc.c_lflag &= ~ECHOCTL; else tmp_tc.c_lflag |= ECHOCTL;#endif if (f == -1) { onoff = 0; } else {#ifndef USE_TERMIO if (f & MODE_OUTBIN) lmode |= LLITOUT; else lmode &= ~LLITOUT;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -