getpass.c
上传用户:xxcykj
上传日期:2007-01-04
资源大小:727k
文件大小:4k
源码类别:

Email客户端

开发平台:

Unix_Linux

  1. /*
  2.  * For license terms, see the file COPYING in this directory.
  3.  */
  4. /***********************************************************************
  5.   module:       getpass.c
  6.   project:      fetchmail
  7.   programmer:   Carl Harris, ceharris@mal.com
  8.   description:  getpass() replacement which allows for long passwords.
  9.                 This version hacked by Wilfred Teiken, allowing the
  10.                 password to be piped to fetchmail.
  11.  
  12.  ***********************************************************************/
  13. #include "config.h"
  14. #include <stdio.h>
  15. #include <signal.h>
  16. #include <fcntl.h>
  17. #if defined(HAVE_UNISTD_H)
  18. #include <unistd.h>
  19. #endif
  20. #include "fetchmail.h"
  21. #include "i18n.h"
  22. #define INPUT_BUF_SIZE PASSWORDLEN
  23. #if defined(HAVE_TERMIOS_H) && defined(HAVE_TCSETATTR)
  24. #  include <termios.h>
  25. #else
  26. #if defined(HAVE_TERMIO_H)
  27. #  include <sys/ioctl.h>
  28. #  include <termio.h>
  29. #else
  30. #if defined(HAVE_SGTTY_H)
  31. #  include <sgtty.h>
  32. #endif
  33. #endif
  34. #endif
  35. static int ttyfd;
  36. #if defined(HAVE_TCSETATTR)
  37.   static struct termios termb;
  38.   static tcflag_t flags;
  39. #else
  40. #if defined(HAVE_TERMIO_H)
  41.   static struct termio termb;
  42.   static unsigned short flags;
  43. #else
  44. #if defined(HAVE_STTY)
  45.   static struct sgttyb ttyb;
  46.   static int flags;
  47. #endif
  48. #endif
  49. #endif
  50. void static save_tty_state(void);
  51. void static disable_tty_echo(void);
  52. void static restore_tty_state(void);
  53. static RETSIGTYPE sigint_handler(int);
  54. char *getpassword(prompt)
  55. char *prompt;
  56. {
  57. #if !(defined(HAVE_TCSETATTR) || defined(HAVE_TERMIO_H) || defined(HAVE_STTY))
  58. #if defined(HAVE_GETPASS) 
  59.     char *getpass();
  60.     return getpass(prompt);
  61. #else
  62.     fputs(_("ERROR: no support for getpassword() routinen"),stderr);
  63.     exit(1);
  64. #endif
  65. #else
  66.     register char *p;
  67.     register int c;
  68.     FILE *fi;
  69.     static char pbuf[INPUT_BUF_SIZE];
  70.     RETSIGTYPE (*sig)(int) = 0; /* initialization pacifies -Wall */
  71.     RETSIGTYPE sigint_handler(int);
  72.     int istty = isatty(0);
  73.     /* get the file descriptor for the actual input device if it's a tty */
  74.     if (istty)
  75.     {
  76. if ((fi = fdopen(open("/dev/tty", 2), "r")) == NULL)
  77.     fi = stdin;
  78. else
  79.     setbuf(fi, (char *)NULL);
  80.     }
  81.     else
  82. fi = stdin;
  83.     /* store descriptor for the tty */
  84.     ttyfd = fileno(fi);
  85.     if (istty)
  86.     {
  87. /* preserve tty state before turning off echo */
  88. save_tty_state();
  89. /* now that we have the current tty state, we can catch SIGINT and  
  90.    exit gracefully */
  91. sig = signal(SIGINT, sigint_handler);
  92. /* turn off echo on the tty */
  93. disable_tty_echo();
  94. /* display the prompt and get the input string */
  95. fprintf(stderr, "%s", prompt);
  96.     }
  97.     for (p = pbuf; (c = getc(fi))!='n' && c!=EOF;)
  98.     {
  99. if (p < &pbuf[INPUT_BUF_SIZE - 1])
  100.     *p++ = c;
  101.     }
  102.     *p = '';
  103.     /* write a newline so cursor won't appear to hang */
  104.     if (fi != stdin)
  105. fprintf(stderr, "n");
  106.     if (istty)
  107.     {
  108. /* restore previous state of the tty */
  109. restore_tty_state();
  110. /* restore previous state of SIGINT */
  111. signal(SIGINT, sig);
  112.     }
  113.     if (fi != stdin)
  114. fclose(fi); /* not checking should be safe, file mode was "r" */
  115.     return(pbuf);
  116. #endif /* !(defined(HAVE_TCSETATTR) || ... */
  117. }
  118. static void save_tty_state (void)
  119. {
  120. #if defined(HAVE_TCSETATTR)
  121.     tcgetattr(ttyfd, &termb);
  122.     flags = termb.c_lflag;
  123. #else
  124. #if defined(HAVE_TERMIO_H)
  125.     ioctl(ttyfd, TCGETA, (char *) &termb);
  126.     flags = termb.c_lflag;
  127. #else  /* we HAVE_STTY */
  128.     gtty(ttyfd, &ttyb);
  129.     flags = ttyb.sg_flags;
  130. #endif
  131. #endif
  132. }
  133. static void disable_tty_echo(void) 
  134. {
  135.     /* turn off echo on the tty */
  136. #if defined(HAVE_TCSETATTR)
  137.     termb.c_lflag &= ~ECHO;
  138.     tcsetattr(ttyfd, TCSAFLUSH, &termb);
  139. #else
  140. #if defined(HAVE_TERMIO_H)
  141.     termb.c_lflag &= ~ECHO;
  142.     ioctl(ttyfd, TCSETA, (char *) &termb);
  143. #else  /* we HAVE_STTY */
  144.     ttyb.sg_flags &= ~ECHO;
  145.     stty(ttyfd, &ttyb);
  146. #endif
  147. #endif
  148. }
  149. static void restore_tty_state(void)
  150. {
  151.     /* restore previous tty echo state */
  152. #if defined(HAVE_TCSETATTR)
  153.     termb.c_lflag = flags;
  154.     tcsetattr(ttyfd, TCSAFLUSH, &termb);
  155. #else
  156. #if defined(HAVE_TERMIO_H)
  157.     termb.c_lflag = flags;
  158.     ioctl(ttyfd, TCSETA, (char *) &termb);
  159. #else  /* we HAVE_STTY */
  160.     ttyb.sg_flags = flags;
  161.     stty(ttyfd, &ttyb);
  162. #endif
  163. #endif
  164. }
  165. static RETSIGTYPE sigint_handler(int signum)
  166. {
  167.     restore_tty_state();
  168.     report(stderr, _("nCaught SIGINT... bailing out.n"));
  169.     exit(1);
  170. }
  171. /* getpass.c ends here */