2 * For license terms, see the file COPYING in this directory.
5 /***********************************************************************
8 programmer: Carl Harris, ceharris@mal.com
9 description: getpass() replacement which allows for long passwords.
11 ***********************************************************************/
17 #if defined(HAVE_UNISTD_H)
20 #include "fetchmail.h"
24 #define INPUT_BUF_SIZE PASSWORDLEN
26 #if defined(HAVE_TERMIOS_H) && defined(HAVE_TCSETATTR)
29 #if defined(HAVE_TERMIO_H)
30 # include <sys/ioctl.h>
33 #if defined(HAVE_SGTTY_H)
41 #if defined(HAVE_TCSETATTR)
42 static struct termios termb;
43 static tcflag_t flags;
45 #if defined(HAVE_TERMIO_H)
46 static struct termio termb;
47 static unsigned short flags;
49 #if defined(HAVE_STTY)
50 static struct sgttyb ttyb;
56 void save_tty_state();
57 void disable_tty_echo();
58 void restore_tty_state();
65 #if !(defined(HAVE_TCSETATTR) || defined(HAVE_TERMIO_H) || defined(HAVE_STTY))
67 #if defined(HAVE_GETPASS)
69 return getpass(prompt);
71 fputs("ERROR: no support for getpassword() routine\n",stderr);
75 #endif /* !(defined(HAVE_TCSETATTR) || ... */
80 static char pbuf[INPUT_BUF_SIZE];
82 RETSIGTYPE sigint_handler();
85 /* get the file descriptor for the input device */
86 if ((fi = fdopen(open("/dev/tty", 2), "r")) == NULL)
89 setbuf(fi, (char *)NULL);
91 /* store descriptor for the tty */
94 /* preserve tty state before turning off echo */
97 /* now that we have the current tty state, we can catch SIGINT and
99 sig = signal(SIGINT, sigint_handler);
101 /* turn off echo on the tty */
104 /* display the prompt and get the input string */
105 fprintf(stderr, "%s", prompt); fflush(stderr);
106 for (p=pbuf; (c = getc(fi))!='\n' && c!=EOF;) {
107 if (p < &pbuf[INPUT_BUF_SIZE - 1])
112 /* write a newline so cursor won't appear to hang */
113 fprintf(stderr, "\n"); fflush(stderr);
115 /* restore previous state of the tty */
118 /* restore previous state of SIGINT */
132 #if defined(HAVE_TCSETATTR)
133 tcgetattr(ttyfd, &termb);
134 flags = termb.c_lflag;
136 #if defined(HAVE_TERMIO_H)
137 ioctl(ttyfd, TCGETA, (char *) &termb);
138 flags = termb.c_lflag;
139 #else /* we HAVE_STTY */
141 flags = ttyb.sg_flags;
150 /* turn off echo on the tty */
151 #if defined(HAVE_TCSETATTR)
152 termb.c_lflag &= ~ECHO;
153 tcsetattr(ttyfd, TCSAFLUSH, &termb);
155 #if defined(HAVE_TERMIO_H)
156 termb.c_lflag &= ~ECHO;
157 ioctl(ttyfd, TCSETA, (char *) &termb);
158 #else /* we HAVE_STTY */
159 ttyb.sg_flags &= ~ECHO;
170 /* restore previous tty echo state */
171 #if defined(HAVE_TCSETATTR)
172 termb.c_lflag = flags;
173 tcsetattr(ttyfd, TCSAFLUSH, &termb);
175 #if defined(HAVE_TERMIO_H)
176 termb.c_lflag = flags;
177 ioctl(ttyfd, TCSETA, (char *) &termb);
178 #else /* we HAVE_STTY */
179 ttyb.sg_flags = flags;
186 RETSIGTYPE sigint_handler ()
189 fputs("\nCaught signal... bailing out.\n", stderr);