⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tty.c

📁 一个使用des加密传输的unix下的login程序的服务器端和客户端
💻 C
字号:
/*  * @(#) tty.c  RCS: $Revision: 1.10 $ $Date: 95/03/02 12:21:21 $ * * Functions to handle terminal console I/O: * * askTty      - emit a prompt and read in a passphrase with echo disabled * mkCtrlTty   - make the specified device the controlling terminal * setTtyEcho  - enable/disable echoing of typed characters * setTtyAscii - Put terminal in ASCII input mode (echo, backspace etc) * setTtyBin   - Put terminal into transparent mode (no character interperation) * isTty       - query to see if device is a terminal * openCtty    - open the controlling terminal * restoreTty  - restore the original state of the terminal */#if !defined(_POSIX_SOURCE)#define  _POSIX_SOURCE#endif/* * <ioctl.h> is necessary for machines which require it for explicitly making  * a tty the controlling terminal.  This isn't very many. Unfortunately,  * <ioctl.h> won't export TIOCSCTTY if _POSIX_SOURCE is defined on some * machines.  To make this situation even worse, #include files are notoriously * sensitve to order; be very careful before changing it. */#if defined(__ALPHA) || defined(__MIPS) || defined(__bsdi__)#if defined(__MIPS)#undef _POSIX_SOURCE#endif#include <sys/ioctl.h>		/* TIOCNOTTY TIOCSCTTY */#if defined(__MIPS)#define _POSIX_SOURCE#endif#endif#include <unistd.h>	/* open ctermid */#include <stdlib.h>	/* exit */#include <signal.h>#include <stdio.h>#include <sys/types.h>	/* for fcntl.h *//* * BSDI's BSD/386 has no way to #define ONLCR in <termios.h> if__POSIX_SOURCE  * is defined.  Also, its value is not 0x04 as it is on all other machines that * have this problem.  POSIX really blew it by not having a standard #define to * enable non-posix symbol visability.  I can't count on tty drivers enabling  * ONLCR when OPOST in enabled either.  I also can't just do this for all  * machines because HP-UX will make termios.h empty if I undef _POSIX SOURCE. */#if defined(__bsdi__)#undef _POSIX_SOURCE#endif#include <termios.h>	/* tcsetattr ONLCR */#if defined(__bsdi__)#define _POSIX_SOURCE#endif#include <fcntl.h>#include <string.h>	/* memcpy */#include <errno.h>	/* ENOTTY */#include "deslogin.h"#include "log.h"#include "tty.h"#include "posignal.h"extern int debug;/* * Return 1 if the specified fd is associated with a tty device *        0 if not, *       -1 if failure */int isTty(fd)   int fd;{   struct termios modes;   register int res = (tcgetattr(fd, &modes) == 0);   if (res == 0) {      if (errno != ENOTTY) {	 --res;      }   }   return res;}int openCtty(){   char cttyName[L_ctermid];   int ctty;   cttyName[0] = '\0';	/* shouldn't be necessary, but I'm paranoid */   /*    * Linux fails to declare "exter char *ctermid()".  Add it here if you    * get a warning.  Linux's <unistd.h> needs to be fixed.    */   ctty = open(ctermid(cttyName), O_RDWR);	/* in Posix <unistd.h> */   if (debug) {      log("%s: (openCtty) open(ctermid = \"%s\") returned fd %d\n", 	  progName, cttyName, ctty);   }   if (ctty < 0) {      log("%s: open(\"%s\", O_RDWR) failed -- %s\n", 	 progName, cttyName, ERRMSG);   }   return ctty;}int restoreTty(ttyfd, oldmodes)   int ttyfd;   struct termios *oldmodes;{   int res;   res = tcsetattr(ttyfd, TCSANOW, oldmodes);   if (res < 0) {      log("%s: tcsetattr to fd %d failed -- %s\n", progName, ttyfd, ERRMSG);      exit(1);   }   return 0;}/* * Set the specified tty device to binary (with error report) * Put the original modes in oldmodes. */int setTtyBin(ttyfd, oldmodes)   int ttyfd;   struct termios *oldmodes;{   struct termios modes;   int res;   if (oldmodes != (struct termios *) 0) {      res = tcgetattr(ttyfd, &modes);      if (res < 0) {	 log("%s: tcgetattr on fd %d failed--%s\n", progName, ttyfd, ERRMSG);	 exit(1);      }      memcpy(oldmodes, &modes, sizeof (struct termios));   }       modes.c_cflag  = CS8 | CREAD;   modes.c_iflag  = BRKINT;   modes.c_oflag &= ~OPOST;		/* Don't damage other bits */   modes.c_lflag  = 0;   modes.c_cc[VMIN]  = 1;   modes.c_cc[VTIME] = 0;   res = cfsetospeed(&modes, B9600);   if (res < 0) {      log("%s: unsupported speed -- B9600\n", progName);      exit(1);   }   res = tcsetattr(ttyfd, TCSANOW, &modes);   if (res < 0) {      log("%s: tcsetattr to fd %d failed -- %s\n", progName, ttyfd, ERRMSG);      exit(1);   }   return 0;}/* * Set specified tty to interactive mode */int setTtyAscii(ctty)   int ctty;{   int res;   struct termios modes;   res = tcgetattr(ctty, &modes);   if (res < 0) {      log("%s: tcgetattr failed --%s\n", progName, ERRMSG);      exit(1);   }       modes.c_cflag  = CS8 | CREAD | HUPCL;   modes.c_iflag  = ICRNL | BRKINT | IXON;   modes.c_lflag  = ICANON | ECHO | ECHOE | ISIG;   modes.c_oflag |= OPOST;			   modes.c_oflag |= ONLCR;	/* ONLCR is not POSIX, but we must set it! */   modes.c_cc[VERASE] = '\b';   modes.c_cc[VINTR]   = '\003';   res = cfsetospeed(&modes, B9600);   if (res < 0) {      log("%s: unsupported speed -- B9600\n", progName);      exit(1);   }   res = tcsetattr(ctty, TCSANOW, &modes);   if (debug > 1) {      log("%s: tcsetattr returned %d\n", progName, res);   }   if (res < 0) {      log("%s: tcsetattr failed -- %s\n", progName, ERRMSG);      exit(1);   }   return 0;}/* * Set tty echo on(1) or off(0); returns previous setting or -1 */int setTtyEcho(fd, echo)   int fd;   int echo;{   register int res, oldecho;   struct termios modes;   res = tcgetattr(fd, &modes);   if (res < 0) return -1;       oldecho = ((modes.c_lflag & ECHO) != 0);   if (echo) {      modes.c_lflag |= ECHO;   } else {      modes.c_lflag &= ~ECHO;   }   res = tcsetattr(fd, TCSANOW, &modes);   if (res < 0) return -2;   return oldecho;}/* * Make the specified  fd the controlling terminal. * * Some machines require an explicit call.  Only the session leader can * do this successfully.  Returns: >=0 success, < 0 failure w/errno set. *  * If flag is non-zero, make fd a controlling terminal, otherwise make it * not the controlling terminal. */int mkCtrlTty(fd, flag)   int fd, flag;{   int res = 0;   pid_t pid;#if defined(__ALPHA) || defined(__bsdi__)   /* OSF1(DECalpha)tty(7):     * In earlier versions of UNIX systems, a controlling terminal was     * implicitly assigned to a process if, at the time an open was done on     * the terminal, the terminal was not the controlling terminal for any     * process, and if the pro-cess doing the open did not have a controlling     * terminal.  In this version of UNIX, in accordance with POSIX 1003.1,     * a process must be a session leader to allocate a controlling terminal.    * In addition, the allocation is now done explicitly with a call to     * ioctl().  (This implies that the O_NOCTTY flag to the open()     * function is ignored.)     */   if (flag) {      res = ioctl(fd, TIOCSCTTY,0);   } else {      res = ioctl(fd, TIOCNOTTY,0);   }#endif#if defined(__MIPS) /* { */  /* ULTRIX(MIPS)tty(4):   * If a process that has no control terminal opens a terminal file, then   * that terminal file becomes the control terminal for that process.  The   * control terminal is thereafter inherited by a child process during a   * fork(2), even if the control terminal is closed.   */   if (flag) {      res = 0;			/* Hack for DEC MIPS Ultrix 4.1.2 and 4.1.3 */   } else {      res = ioctl(fd, TIOCNOTTY,0);   }#endif /* } */#if defined(__SOLARIS__)	/* { */   pid = getpgrp();   if (pid < 0) {      log("%s: (mkCtrlTty) getpgrp failed -- %s\n", progName, ERRMSG);   } else {      res = ioctl(fd, TIOCSPGRP, &pid);      if (res < 0) {	 log("%s: (mkCtrlTty) ioctl(%d, TIOCSPGRP, %d) failed -- %s\n", 	     progName, fd, pid, ERRMSG);      }   }#endif /* } */   if (debug > 1) {      log("%s: (mkCtrlTty)(%d)=%d\n", progName, fd, res);   }   return res;}int oldEcho = 1;int ttyfd = -1;void restoreEcho(sig)   int sig;{   if (ttyfd >= 0) {      setTtyEcho(ttyfd, oldEcho);      close(ttyfd);   }   exit(0);}/* * Read in a passphrase terminated by '\n' of upto size characters from the * controlling terminal with echo disabled.  The phrase strips the '\n',  * and appends a '\0'.  Intercepts interrupt signal and restores echo. */int askTty(prompt, str, size, echo)   char *prompt;   char *str;   unsigned size;   int echo;{   unsigned len = strlen(prompt);   register int count;   register char *chp = str;   register int res = -1;   char ch;    pfv oldsigint;   ttyfd     = openCtty();   if (ttyfd == -1) return -1;   oldsigint = posignal(SIGINT, restoreEcho);   oldEcho   = setTtyEcho(ttyfd, echo);   count = write(ttyfd, prompt, len);   if (count != len) return -1;   if (size != 0) do {      count = read(ttyfd, &ch, 1);      if (count == 0) break;      if (count != 1) break;      if (ch == '\n') break;      *chp++ = ch;   } while (--size != 0);   if (count >= 0) {      res = chp - str;   }    *chp = '\0';   if (!echo) {      count = write(ttyfd, "\n", 1);			/* goto next line */   }   oldEcho = setTtyEcho(ttyfd, oldEcho);   posignal(SIGINT, oldsigint);   close(ttyfd);   ttyfd = -1;   return res;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -