📄 sys_term.c
字号:
/* * A table of available terminal speeds */struct termspeeds { int speed; int 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 }, { 9600, B9600 }, { 19200, B9600 }, { 38400, B9600 }, { -1, B9600 }};void tty_tspeed(int val) { struct termspeeds *tp; for (tp = termspeeds; (tp->speed != -1) && (val > tp->speed); tp++); cfsetospeed(&termbuf, tp->value);}void tty_rspeed(int val) { struct termspeeds *tp; for (tp = termspeeds; (tp->speed != -1) && (val > tp->speed); tp++); cfsetispeed(&termbuf, tp->value);}/* * getptyslave() * * Open the slave side of the pty, and do any initialization * that is necessary. The return value is a file descriptor * for the slave side. */#ifdef TIOCGWINSZextern int def_row, def_col;#endifextern int def_tspeed, def_rspeed;static int getptyslave(void) {#if 0 register int t = -1;# ifdef LINEMODE int waslm;# endif# ifdef TIOCGWINSZ struct winsize ws;# endif /* * Opening the slave side may cause initilization of the * kernel tty structure. We need remember the state of * if linemode was turned on * terminal window size * terminal speed * so that we can re-set them if we need to. */# ifdef LINEMODE waslm = tty_linemode();# endif /* * Make sure that we don't have a controlling tty, and * that we are the session (process group) leader. */ t = open(_PATH_TTY, O_RDWR); if (t >= 0) { ioctl(t, TIOCNOTTY, (char *)0); close(t); } t = cleanopen(line); if (t < 0) fatalperror(net, line);#endif /* 0 */ struct winsize ws; int t = ptyslavefd; /* * set up the tty modes as we like them to be. */ init_termbuf();# ifdef TIOCGWINSZ if (def_row || def_col) { bzero((char *)&ws, sizeof(ws)); ws.ws_col = def_col; ws.ws_row = def_row; ioctl(t, TIOCSWINSZ, (char *)&ws); }# endif /* * Settings for all other termios/termio based * systems, other than 4.4BSD. In 4.4BSD the * kernel does the initial terminal setup. * * XXX what about linux? */# ifndef OXTABS# define OXTABS 0# endif termbuf.c_lflag |= ECHO; termbuf.c_oflag |= OPOST|ONLCR|OXTABS; termbuf.c_iflag |= ICRNL; termbuf.c_iflag &= ~IXOFF; tty_rspeed((def_rspeed > 0) ? def_rspeed : 9600); tty_tspeed((def_tspeed > 0) ? def_tspeed : 9600);# ifdef LINEMODE if (waslm) tty_setlinemode(1);# endif /* LINEMODE */ /* * Set the tty modes, and make this our controlling tty. */ set_termbuf(); if (login_tty(t) == -1) fatalperror(net, "login_tty"); if (net > 2) close(net); if (pty > 2) close(pty); return t;}#if 0#ifndef O_NOCTTY#define O_NOCTTY 0#endif/* * Open the specified slave side of the pty, * making sure that we have a clean tty. */static int cleanopen(char *lyne) { register int t; /* * Make sure that other people can't open the * slave side of the connection. */ chown(lyne, 0, 0); chmod(lyne, 0600);#ifndef NO_REVOKE revoke(lyne);#endif t = open(lyne, O_RDWR|O_NOCTTY); if (t < 0) return(-1); /* * Hangup anybody else using this ttyp, then reopen it for * ourselves. */# if !defined(__linux__) /* this looks buggy to me, our ctty is really a pty at this point */ signal(SIGHUP, SIG_IGN); vhangup(); signal(SIGHUP, SIG_DFL); t = open(lyne, O_RDWR|O_NOCTTY); if (t < 0) return(-1);# endif return(t);}#endif /* 0 */int login_tty(int t) { if (setsid() < 0) fatalperror(net, "setsid()"); if (ioctl(t, TIOCSCTTY, (char *)0) < 0) { fatalperror(net, "ioctl(sctty)"); } if (t != 0) dup2(t, 0); if (t != 1) dup2(t, 1); if (t != 2) dup2(t, 2); if (t > 2) close(t); return 0;}/* * startslave(host) * * Given a hostname, do whatever * is necessary to startup the login process on the slave side of the pty. *//* ARGSUSED */void startslave(const char *host, int autologin, char *autoname) { int i;#if defined(AUTHENTICATE) if (!autoname || !autoname[0]) autologin = 0; if (autologin < auth_level) { fatal(net, "Authorization failed"); exit(1); }#endif i = fork(); if (i < 0) fatalperror(net, "fork"); if (i) { /* parent */ signal(SIGHUP,SIG_IGN); close(ptyslavefd); } else { /* child */ signal(SIGHUP,SIG_IGN); getptyslave(); start_login(host, autologin, autoname); /*NOTREACHED*/ }}char *envinit[3];void init_env(void) { char **envp; envp = envinit; if ((*envp = getenv("TZ"))!=NULL) *envp++ -= 3; *envp = 0; environ = envinit;}/* * start_login(host) * * Assuming that we are now running as a child processes, this * function will turn us into the login process. */struct argv_stuff { const char **argv; int argc; int argmax;};static void addarg(struct argv_stuff *, const char *);static void initarg(struct argv_stuff *);void start_login(const char *host, int autologin, const char *name) { struct argv_stuff avs; char *const *argvfoo; (void)autologin; initarg(&avs); /* * -h : pass on name of host. * WARNING: -h is accepted by login if and only if * getuid() == 0. * -p : don't clobber the environment (so terminal type stays set). * * -f : force this login, he has already been authenticated */ addarg(&avs, loginprg); addarg(&avs, "-h"); addarg(&avs, host);#if !defined(NO_LOGIN_P) addarg(&avs, "-p");#endif#ifdef BFTPDAEMON /* * Are we working as the bftp daemon? If so, then ask login * to start bftp instead of shell. */ if (bftpd) { addarg(&avs, "-e"); addarg(&avs, BFTPPATH); } else#endif {#if defined (SecurID) /* * don't worry about the -f that might get sent. * A -s is supposed to override it anyhow. */ if (require_SecurID) addarg(&avs, "-s");#endif if (*name=='-') { syslog(LOG_ERR, "Attempt to login with an option!"); name = ""; }#if defined (AUTHENTICATE) if (auth_level >= 0 && autologin == AUTH_VALID) {# if !defined(NO_LOGIN_F) addarg(&avs, "-f");# endif addarg(&avs, name); } else#endif { if (getenv("USER")) { addarg(&avs, getenv("USER")); if (*getenv("USER") == '-') { write(1,"I don't hear you!\r\n",19); syslog(LOG_ERR,"Attempt to login with an option!"); exit(1); } } } } closelog(); /* execv() should really take char const* const *, but it can't */ /*argvfoo = argv*/; memcpy(&argvfoo, &avs.argv, sizeof(argvfoo)); execv(loginprg, argvfoo); syslog(LOG_ERR, "%s: %m\n", loginprg); fatalperror(net, loginprg);}static void initarg(struct argv_stuff *avs) { /* * 10 entries and a null */ avs->argmax = 11; avs->argv = malloc(sizeof(avs->argv[0]) * avs->argmax); if (avs->argv == NULL) { fprintf(stderr, "Out of memory\n"); exit(1); } avs->argc = 0; avs->argv[0] = NULL;}static void addarg(struct argv_stuff *avs, const char *val) { if (avs->argc>=avs->argmax-1) { avs->argmax += 10; avs->argv = realloc(avs->argv, sizeof(avs->argv[0])*avs->argmax); if (avs->argv == NULL) { fprintf(stderr, "Out of memory\n"); exit(1); } } avs->argv[avs->argc++] = val; avs->argv[avs->argc] = NULL;}/* * cleanup() * * This is the routine to call when we are all through, to * clean up anything that needs to be cleaned up. */void cleanup(int sig) { char *p; (void)sig; p = line + sizeof("/dev/") - 1; if (logout(p)) logwtmp(p, "", "");#ifdef PARANOID_TTYS /* * dholland 16-Aug-96 chmod the tty when not in use * This will make it harder to attach unwanted stuff to it * (which is a security risk) but will break some programs. */ chmod(line, 0600);#else chmod(line, 0666);#endif chown(line, 0, 0); *p = 'p'; chmod(line, 0666); chown(line, 0, 0); shutdown(net, 2); exit(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -