?? 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. 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 "telnetd.h"/* RCSID("$KTH: sys_term.c,v 1.100 2001/04/24 23:11:43 assar Exp $"); */#if defined(_CRAY) || (defined(__hpux) && !defined(HAVE_UTMPX_H))# define PARENT_DOES_UTMP#endif#ifdef HAVE_UTMP_H#include <utmp.h>#endif#ifdef HAVE_UTMPX_H#include <utmpx.h>#endif#ifdef HAVE_UTMPX_Hstruct utmpx wtmp;#elif defined(HAVE_UTMP_H)struct utmp wtmp;#endif /* HAVE_UTMPX_H */#ifdef HAVE_STRUCT_UTMP_UT_HOSTint utmp_len = sizeof(wtmp.ut_host);#elseint utmp_len = MAXHOSTNAMELEN;#endif#ifndef UTMP_FILE#ifdef _PATH_UTMP#define UTMP_FILE _PATH_UTMP#else#define UTMP_FILE "/etc/utmp"#endif#endif#if !defined(WTMP_FILE) && defined(_PATH_WTMP)#define WTMP_FILE _PATH_WTMP#endif#ifndef PARENT_DOES_UTMP#ifdef WTMP_FILEchar wtmpf[] = WTMP_FILE;#elsechar wtmpf[] = "/usr/adm/wtmp";#endifchar utmpf[] = UTMP_FILE;#else /* PARENT_DOES_UTMP */#ifdef WTMP_FILEchar wtmpf[] = WTMP_FILE;#elsechar wtmpf[] = "/etc/wtmp";#endif#endif /* PARENT_DOES_UTMP */#ifdef HAVE_TMPDIR_H#include <tmpdir.h>#endif /* CRAY */#ifdef STREAMSPTY#ifdef HAVE_SAC_H#include <sac.h>#endif#ifdef HAVE_SYS_STROPTS_H#include <sys/stropts.h>#endif#endif /* STREAMSPTY */#ifdef HAVE_SYS_STREAM_H#ifdef HAVE_SYS_UIO_H#include <sys/uio.h>#endif#ifdef __hpux#undef SE#endif#include <sys/stream.h>#endif#if !(defined(__sgi) || defined(__linux) || defined(_AIX)) && defined(HAVE_SYS_TTY)#include <sys/tty.h>#endif#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#ifdef HAVE_TERMIOS_H#include <termios.h>#else#ifdef HAVE_TERMIO_H#include <termio.h>#endif#endif#ifdef HAVE_UTIL_H#include <util.h>#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 STREAMSPTY static int ttyfd = -1; int really_stream = 0;# endif char *new_login = NULL;/* * 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. */ void init_termbuf(void){# ifdef STREAMSPTY if (really_stream) tcgetattr(ttyfd, &termbuf); else# endif tcgetattr(ourpty, &termbuf); termbuf2 = termbuf;}voidset_termbuf(void){ /* * Only make the necessary changes. */ if (memcmp(&termbuf, &termbuf2, sizeof(termbuf)))# ifdef STREAMSPTY if (really_stream) tcsetattr(ttyfd, TCSANOW, &termbuf); else# endif tcsetattr(ourpty, TCSANOW, &termbuf);}/* * 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. */intspcset(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); }}#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 *//* * 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. */static char Xline[] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";char *line = Xline;int slavefd = -1;#ifdef _CRAYchar myline[] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";#endif /* CRAY */#if !defined(HAVE_PTSNAME) && defined(STREAMSPTY)static char *ptsname(int fd){#ifdef HAVE_TTYNAME return ttyname(fd);#else return NULL;#endif}#endifint getpty(int *ptynum){#if defined(__osf__) || defined(HAVE_OPENPTY) int master; int slave; if(openpty(&master, &slave, line, 0, 0) == 0){ slavefd = slave; return master; } return -1;#else#ifdef HAVE__GETPTY int master, slave; char *p; p = _getpty(&master, O_RDWR, 0600, 1); if(p == NULL) return -1; strlcpy(line, p, sizeof(Xline)); return master;#else int p; char *cp, *p1, *p2; int i;#if SunOS == 40 int dummy;#endif#if 0 /* && defined(HAVE_OPENPTY) */ int master; int slave; if(openpty(&master, &slave, line, 0, 0) == 0){ close(slave); return master; }#else#ifdef STREAMSPTY char *clone[] = { "/dev/ptc", "/dev/ptmx", "/dev/ptm", "/dev/ptym/clone", 0 }; char **q; for(q=clone; *q; q++){ p=open(*q, O_RDWR); if(p >= 0){#ifdef HAVE_GRANTPT grantpt(p);#endif#ifdef HAVE_UNLOCKPT unlockpt(p);#endif strlcpy(line, ptsname(p), sizeof(Xline)); really_stream = 1; return p; } }#endif /* STREAMSPTY */#ifndef _CRAY#ifndef __hpux snprintf(line, sizeof(Xline), "/dev/ptyXX"); p1 = &line[8]; p2 = &line[9];#else snprintf(line, sizeof(Xline), "/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, O_RDWR); 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 SunOS == 40 if (ioctl(p, TIOCGPGRP, &dummy) == 0 || errno != EIO) { chmod(line, 0666); close(p); line[5] = 'p'; } else#endif /* SunOS == 40 */ return(p); } } }#else /* CRAY */ extern lowpty, highpty; struct stat sb; for (*ptynum = lowpty; *ptynum <= highpty; (*ptynum)++) { snprintf(myline, sizeof(myline), "/dev/pty/%03d", *ptynum); p = open(myline, 2); if (p < 0) continue; snprintf(line, sizeof(Xline), "/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) { close(p); continue; } if(sb.st_uid || sb.st_gid || sb.st_mode != 0600) { chown(line, 0, 0); chmod(line, 0600); 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 */ close(p); } }#endif /* CRAY */#endif /* STREAMSPTY */#endif /* OPENPTY */ return(-1);#endif}inttty_isecho(void){ return (termbuf.c_lflag & ECHO);}inttty_flowmode(void){ return((termbuf.c_iflag & IXON) ? 1 : 0);}inttty_restartany(void){ return((termbuf.c_iflag & IXANY) ? 1 : 0);}voidtty_setecho(int on){ if (on) termbuf.c_lflag |= ECHO; else termbuf.c_lflag &= ~ECHO;}inttty_israw(void){ return(!(termbuf.c_lflag & ICANON));}voidtty_binaryin(int on){ if (on) { termbuf.c_iflag &= ~ISTRIP; } else { termbuf.c_iflag |= ISTRIP; }}voidtty_binaryout(int on){ if (on) { termbuf.c_cflag &= ~(CSIZE|PARENB); termbuf.c_cflag |= CS8; termbuf.c_oflag &= ~OPOST; } else { termbuf.c_cflag &= ~CSIZE; termbuf.c_cflag |= CS7|PARENB; termbuf.c_oflag |= OPOST; }}inttty_isbinaryin(void){ return(!(termbuf.c_iflag & ISTRIP));}inttty_isbinaryout(void){ return(!(termbuf.c_oflag&OPOST));}inttty_issofttab(void){# ifdef OXTABS return (termbuf.c_oflag & OXTABS);# endif# ifdef TABDLY return ((termbuf.c_oflag & TABDLY) == TAB3);# endif}voidtty_setsofttab(int on){ if (on) {# ifdef OXTABS termbuf.c_oflag |= OXTABS;# endif# ifdef TABDLY termbuf.c_oflag &= ~TABDLY; termbuf.c_oflag |= TAB3;# endif } else {# ifdef OXTABS termbuf.c_oflag &= ~OXTABS;# endif# ifdef TABDLY termbuf.c_oflag &= ~TABDLY; termbuf.c_oflag |= TAB0;# endif }}inttty_islitecho(void){# ifdef ECHOCTL return (!(termbuf.c_lflag & ECHOCTL));# endif# ifdef TCTLECH return (!(termbuf.c_lflag & TCTLECH));# endif# if !defined(ECHOCTL) && !defined(TCTLECH) return (0); /* assumes ctl chars are echoed '^x' */# endif}void
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -