?? sys_term.c
字號:
/* * Copyright (c) 1989, 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. */#ifndef lintstatic char sccsid[] = "@(#)sys_term.c 8.2 (Berkeley) 12/15/93";#endif /* not lint */#include "telnetd.h"#include "pathnames.h"#if defined(AUTHENTICATION)#include <libtelnet/auth.h>#endif#if defined(CRAY) || defined(__hpux)# define PARENT_DOES_UTMP#endif#ifdef NEWINIT#include <initreq.h>int utmp_len = MAXHOSTNAMELEN; /* sizeof(init_request.host) */#else /* NEWINIT*/# ifdef UTMPX# include <utmpx.h>struct utmpx wtmp;# else# include <utmp.h>struct utmp wtmp;# endif /* UTMPX */int utmp_len = sizeof(wtmp.ut_host);# ifndef PARENT_DOES_UTMPchar wtmpf[] = "/usr/adm/wtmp";char utmpf[] = "/etc/utmp";# else /* PARENT_DOES_UTMP */char wtmpf[] = "/etc/wtmp";# endif /* PARENT_DOES_UTMP */# ifdef CRAY#include <tmpdir.h>#include <sys/wait.h># if defined(_SC_CRAY_SECURE_SYS) && !defined(SCM_SECURITY) /* * UNICOS 6.0/6.1 do not have SCM_SECURITY defined, so we can * use it to tell us to turn off all the socket security code, * since that is only used in UNICOS 7.0 and later. */# undef _SC_CRAY_SECURE_SYS# endif# if defined(_SC_CRAY_SECURE_SYS)#include <sys/sysv.h>#include <sys/secstat.h>extern int secflag;extern struct sysv sysv;# endif /* _SC_CRAY_SECURE_SYS */# endif /* CRAY */#endif /* NEWINIT */#ifdef STREAMSPTY#include <sac.h>#include <sys/stropts.h>#endif#define SCPYN(a, b) (void) strncpy(a, b, sizeof(a))#define SCMPN(a, b) strncmp(a, b, sizeof(a))#ifdef STREAMS#include <sys/stream.h>#endif#ifdef __hpux#include <sys/resource.h>#include <sys/proc.h>#endif#include <sys/tty.h>#ifdef t_erase#undef t_erase#undef t_kill#undef t_intrc#undef t_quitc#undef t_startc#undef t_stopc#undef t_eofc#undef t_brkc#undef t_suspc#undef t_dsuspc#undef t_rprntc#undef t_flushc#undef t_werasc#undef t_lnextc#endif#if defined(UNICOS5) && defined(CRAY2) && !defined(EXTPROC)# define EXTPROC 0400#endif#ifndef USE_TERMIOstruct termbuf { struct sgttyb sg; struct tchars tc; struct ltchars ltc; int state; int lflags;} termbuf, termbuf2;# define cfsetospeed(tp, val) (tp)->sg.sg_ospeed = (val)# define cfsetispeed(tp, val) (tp)->sg.sg_ispeed = (val)# define cfgetospeed(tp) (tp)->sg.sg_ospeed# define cfgetispeed(tp) (tp)->sg.sg_ispeed#else /* USE_TERMIO */# ifdef SYSV_TERMIO# define termios termio# endif# 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, t)# define cfsetospeed(tp, val) (tp)->c_cflag &= ~CBAUD; \ (tp)->c_cflag |= (val)# define cfgetospeed(tp) ((tp)->c_cflag & CBAUD)# ifdef CIBAUD# define cfsetispeed(tp, val) (tp)->c_cflag &= ~CIBAUD; \ (tp)->c_cflag |= ((val)<<IBSHIFT)# define cfgetispeed(tp) (((tp)->c_cflag & CIBAUD)>>IBSHIFT)# else# define cfsetispeed(tp, val) (tp)->c_cflag &= ~CBAUD; \ (tp)->c_cflag |= (val)# define cfgetispeed(tp) ((tp)->c_cflag & CBAUD)# endif# endif /* TCSANOW */struct termios termbuf, termbuf2; /* pty control structure */# ifdef STREAMSPTYint ttyfd = -1;# endif#endif /* USE_TERMIO *//* * init_termbuf() * copy_termbuf(cp) * set_termbuf() * * These three routines are used to get and set the "termbuf" structure * to and from the kernel. init_termbuf() gets the current settings. * copy_termbuf() hands in a new "termbuf" to write to the kernel, and * set_termbuf() writes the structure into the kernel. */ voidinit_termbuf(){#ifndef USE_TERMIO (void) ioctl(pty, TIOCGETP, (char *)&termbuf.sg); (void) ioctl(pty, TIOCGETC, (char *)&termbuf.tc); (void) ioctl(pty, TIOCGLTC, (char *)&termbuf.ltc);# ifdef TIOCGSTATE (void) ioctl(pty, TIOCGSTATE, (char *)&termbuf.state);# endif#else# ifdef STREAMSPTY (void) tcgetattr(ttyfd, &termbuf);# else (void) tcgetattr(pty, &termbuf);# endif#endif termbuf2 = termbuf;}#if defined(LINEMODE) && defined(TIOCPKT_IOCTL) voidcopy_termbuf(cp, len) char *cp; int len;{ if (len > sizeof(termbuf)) len = sizeof(termbuf); bcopy(cp, (char *)&termbuf, len); termbuf2 = termbuf;}#endif /* defined(LINEMODE) && defined(TIOCPKT_IOCTL) */ voidset_termbuf(){ /* * Only make the necessary changes. */#ifndef USE_TERMIO if (bcmp((char *)&termbuf.sg, (char *)&termbuf2.sg, sizeof(termbuf.sg))) (void) ioctl(pty, TIOCSETN, (char *)&termbuf.sg); if (bcmp((char *)&termbuf.tc, (char *)&termbuf2.tc, sizeof(termbuf.tc))) (void) ioctl(pty, TIOCSETC, (char *)&termbuf.tc); if (bcmp((char *)&termbuf.ltc, (char *)&termbuf2.ltc, sizeof(termbuf.ltc))) (void) ioctl(pty, TIOCSLTC, (char *)&termbuf.ltc); if (termbuf.lflags != termbuf2.lflags) (void) ioctl(pty, TIOCLSET, (char *)&termbuf.lflags);#else /* USE_TERMIO */ if (bcmp((char *)&termbuf, (char *)&termbuf2, sizeof(termbuf)))# ifdef STREAMSPTY (void) tcsetattr(ttyfd, TCSANOW, &termbuf);# else (void) tcsetattr(pty, TCSANOW, &termbuf);# endif# if defined(CRAY2) && defined(UNICOS5) needtermstat = 1;# endif#endif /* USE_TERMIO */}/* * spcset(func, valp, valpp) * * This function takes various special characters (func), and * sets *valp to the current value of that character, and * *valpp to point to where in the "termbuf" structure that * value is kept. * * It returns the SLC_ level of support for this function. */#ifndef USE_TERMIO intspcset(func, valp, valpp) int func; cc_t *valp; cc_t **valpp;{ switch(func) { case SLC_EOF: *valp = termbuf.tc.t_eofc; *valpp = (cc_t *)&termbuf.tc.t_eofc; return(SLC_VARIABLE); case SLC_EC: *valp = termbuf.sg.sg_erase; *valpp = (cc_t *)&termbuf.sg.sg_erase; return(SLC_VARIABLE); case SLC_EL: *valp = termbuf.sg.sg_kill; *valpp = (cc_t *)&termbuf.sg.sg_kill; return(SLC_VARIABLE); case SLC_IP: *valp = termbuf.tc.t_intrc; *valpp = (cc_t *)&termbuf.tc.t_intrc; return(SLC_VARIABLE|SLC_FLUSHIN|SLC_FLUSHOUT); case SLC_ABORT: *valp = termbuf.tc.t_quitc; *valpp = (cc_t *)&termbuf.tc.t_quitc; return(SLC_VARIABLE|SLC_FLUSHIN|SLC_FLUSHOUT); case SLC_XON: *valp = termbuf.tc.t_startc; *valpp = (cc_t *)&termbuf.tc.t_startc; return(SLC_VARIABLE); case SLC_XOFF: *valp = termbuf.tc.t_stopc; *valpp = (cc_t *)&termbuf.tc.t_stopc; return(SLC_VARIABLE); case SLC_AO: *valp = termbuf.ltc.t_flushc; *valpp = (cc_t *)&termbuf.ltc.t_flushc; return(SLC_VARIABLE); case SLC_SUSP: *valp = termbuf.ltc.t_suspc; *valpp = (cc_t *)&termbuf.ltc.t_suspc; return(SLC_VARIABLE); case SLC_EW: *valp = termbuf.ltc.t_werasc; *valpp = (cc_t *)&termbuf.ltc.t_werasc; return(SLC_VARIABLE); case SLC_RP: *valp = termbuf.ltc.t_rprntc; *valpp = (cc_t *)&termbuf.ltc.t_rprntc; return(SLC_VARIABLE); case SLC_LNEXT: *valp = termbuf.ltc.t_lnextc; *valpp = (cc_t *)&termbuf.ltc.t_lnextc; return(SLC_VARIABLE); case SLC_FORW1: *valp = termbuf.tc.t_brkc; *valpp = (cc_t *)&termbuf.ltc.t_lnextc; return(SLC_VARIABLE); case SLC_BRK: case SLC_SYNCH: case SLC_AYT: case SLC_EOR: *valp = (cc_t)0; *valpp = (cc_t *)0; return(SLC_DEFAULT); default: *valp = (cc_t)0; *valpp = (cc_t *)0; return(SLC_NOSUPPORT); }}#else /* USE_TERMIO */ intspcset(func, valp, valpp) int func; cc_t *valp; cc_t **valpp;{#define setval(a, b) *valp = termbuf.c_cc[a]; \ *valpp = &termbuf.c_cc[a]; \ return(b);#define defval(a) *valp = ((cc_t)a); *valpp = (cc_t *)0; return(SLC_DEFAULT); switch(func) { case SLC_EOF: setval(VEOF, SLC_VARIABLE); case SLC_EC: setval(VERASE, SLC_VARIABLE); case SLC_EL: setval(VKILL, SLC_VARIABLE); case SLC_IP: setval(VINTR, SLC_VARIABLE|SLC_FLUSHIN|SLC_FLUSHOUT); case SLC_ABORT: setval(VQUIT, SLC_VARIABLE|SLC_FLUSHIN|SLC_FLUSHOUT); case SLC_XON:#ifdef VSTART setval(VSTART, SLC_VARIABLE);#else defval(0x13);#endif case SLC_XOFF:#ifdef VSTOP setval(VSTOP, SLC_VARIABLE);#else defval(0x11);#endif case SLC_EW:#ifdef VWERASE setval(VWERASE, SLC_VARIABLE);#else defval(0);#endif case SLC_RP:#ifdef VREPRINT setval(VREPRINT, SLC_VARIABLE);#else defval(0);#endif case SLC_LNEXT:#ifdef VLNEXT setval(VLNEXT, SLC_VARIABLE);#else defval(0);#endif case SLC_AO:#if !defined(VDISCARD) && defined(VFLUSHO)# define VDISCARD VFLUSHO#endif#ifdef VDISCARD setval(VDISCARD, SLC_VARIABLE|SLC_FLUSHOUT);#else defval(0);#endif case SLC_SUSP:#ifdef VSUSP setval(VSUSP, SLC_VARIABLE|SLC_FLUSHIN);#else defval(0);#endif#ifdef VEOL case SLC_FORW1: setval(VEOL, SLC_VARIABLE);#endif#ifdef VEOL2 case SLC_FORW2: setval(VEOL2, SLC_VARIABLE);#endif case SLC_AYT:#ifdef VSTATUS setval(VSTATUS, SLC_VARIABLE);#else defval(0);#endif case SLC_BRK: case SLC_SYNCH: case SLC_EOR: defval(0); default: *valp = 0; *valpp = 0; return(SLC_NOSUPPORT); }}#endif /* USE_TERMIO */#ifdef CRAY/* * getnpty() * * Return the number of pty's configured into the system. */ intgetnpty(){#ifdef _SC_CRAY_NPTY int numptys; if ((numptys = sysconf(_SC_CRAY_NPTY)) != -1) return numptys; else#endif /* _SC_CRAY_NPTY */ return 128;}#endif /* CRAY */#ifndef convex/* * getpty() * * Allocate a pty. As a side effect, the external character * array "line" contains the name of the slave side. * * Returns the file descriptor of the opened pty. */#ifndef __GNUC__char *line = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";#elsestatic char Xline[] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";char *line = Xline;#endif#ifdef CRAYchar *myline = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";#endif /* CRAY */ intgetpty(ptynum)int *ptynum;{ register int p;#ifdef STREAMSPTY int t; char *ptsname(); p = open("/dev/ptmx", 2); if (p > 0) { grantpt(p); unlockpt(p); strcpy(line, ptsname(p)); return(p); }#else /* ! STREAMSPTY */#ifndef CRAY register char *cp, *p1, *p2; register int i;#if defined(sun) && defined(TIOCGPGRP) && BSD < 199207 int dummy;#endif#ifndef __hpux (void) sprintf(line, "/dev/ptyXX"); p1 = &line[8]; p2 = &line[9];#else (void) sprintf(line, "/dev/ptym/ptyXX"); p1 = &line[13]; p2 = &line[14];#endif for (cp = "pqrstuvwxyzPQRST"; *cp; cp++) { struct stat stb; *p1 = *cp; *p2 = '0'; /* * This stat() check is just to keep us from * looping through all 256 combinations if there * aren't that many ptys available. */ if (stat(line, &stb) < 0) break; for (i = 0; i < 16; i++) { *p2 = "0123456789abcdef"[i]; p = open(line, 2); if (p > 0) {#ifndef __hpux line[5] = 't';#else for (p1 = &line[8]; *p1; p1++) *p1 = *(p1+1); line[9] = 't';#endif chown(line, 0, 0); chmod(line, 0600);#if defined(sun) && defined(TIOCGPGRP) && BSD < 199207 if (ioctl(p, TIOCGPGRP, &dummy) == 0 || errno != EIO) { chmod(line, 0666); close(p); line[5] = 'p'; } else#endif /* defined(sun) && defined(TIOCGPGRP) && BSD < 199207 */ return(p); } } }#else /* CRAY */ extern lowpty, highpty; struct stat sb; for (*ptynum = lowpty; *ptynum <= highpty; (*ptynum)++) { (void) sprintf(myline, "/dev/pty/%03d", *ptynum); p = open(myline, 2); if (p < 0) continue; (void) sprintf(line, "/dev/ttyp%03d", *ptynum); /* * Here are some shenanigans to make sure that there * are no listeners lurking on the line. */ if(stat(line, &sb) < 0) { (void) close(p); continue; } if(sb.st_uid || sb.st_gid || sb.st_mode != 0600) { chown(line, 0, 0); chmod(line, 0600); (void)close(p); p = open(myline, 2); if (p < 0) continue; } /* * Now it should be safe...check for accessability. */ if (access(line, 6) == 0) return(p); else { /* no tty side to pty so skip it */ (void) close(p); } }#endif /* CRAY */#endif /* STREAMSPTY */ return(-1);}#endif /* convex */#ifdef LINEMODE/* * tty_flowmode() Find out if flow control is enabled or disabled. * tty_linemode() Find out if linemode (external processing) is enabled. * tty_setlinemod(on) Turn on/off linemode. * tty_isecho() Find out if echoing is turned on. * tty_setecho(on) Enable/disable character echoing. * tty_israw() Find out if terminal is in RAW mode. * tty_binaryin(on) Turn on/off BINARY on input. * tty_binaryout(on) Turn on/off BINARY on output. * tty_isediting() Find out if line editing is enabled. * tty_istrapsig() Find out if signal trapping is enabled. * tty_setedit(on) Turn on/off line editing. * tty_setsig(on) Turn on/off signal trapping. * tty_issofttab() Find out if tab expansion is enabled. * tty_setsofttab(on) Turn on/off soft tab expansion. * tty_islitecho() Find out if typed control chars are echoed literally * tty_setlitecho() Turn on/off literal echo of control chars * tty_tspeed(val) Set transmit speed to val. * tty_rspeed(val) Set receive speed to val. */#ifdef convexstatic int linestate;#endif inttty_linemode(){#ifndef convex#ifndef USE_TERMIO return(termbuf.state & TS_EXTPROC);#else return(termbuf.c_lflag & EXTPROC);#endif#else return(linestate);#endif} voidtty_setlinemode(on) int on;{#ifdef TIOCEXT# ifndef convex set_termbuf();# else linestate = on;# endif (void) ioctl(pty, TIOCEXT, (char *)&on);# ifndef convex init_termbuf();# endif#else /* !TIOCEXT */# ifdef EXTPROC if (on) termbuf.c_lflag |= EXTPROC; else termbuf.c_lflag &= ~EXTPROC;# endif#endif /* TIOCEXT */}#endif /* LINEMODE */ inttty_isecho(){#ifndef USE_TERMIO return (termbuf.sg.sg_flags & ECHO);#else return (termbuf.c_lflag & ECHO);#endif} inttty_flowmode(){#ifndef USE_TERMIO return(((termbuf.tc.t_startc) > 0 && (termbuf.tc.t_stopc) > 0) ? 1 : 0);#else return((termbuf.c_iflag & IXON) ? 1 : 0);#endif} inttty_restartany(){#ifndef USE_TERMIO# ifdef DECCTQ return((termbuf.lflags & DECCTQ) ? 0 : 1);# else return(-1);# endif#else return((termbuf.c_iflag & IXANY) ? 1 : 0);#endif} voidtty_setecho(on) int on;{#ifndef USE_TERMIO if (on) termbuf.sg.sg_flags |= ECHO|CRMOD; else termbuf.sg.sg_flags &= ~(ECHO|CRMOD);#else if (on) termbuf.c_lflag |= ECHO; else termbuf.c_lflag &= ~ECHO;#endif} inttty_israw(){#ifndef USE_TERMIO return(termbuf.sg.sg_flags & RAW);#else return(!(termbuf.c_lflag & ICANON));#endif
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -