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.
10 This version hacked by Wilfred Teiken, allowing the
11 password to be piped to fetchmail.
13 ***********************************************************************/
20 #if defined(HAVE_UNISTD_H)
23 #include "fetchmail.h"
26 #define INPUT_BUF_SIZE PASSWORDLEN
28 #if defined(HAVE_TERMIOS_H) && defined(HAVE_TCSETATTR)
31 #if defined(HAVE_TERMIO_H)
32 # include <sys/ioctl.h>
35 #if defined(HAVE_SGTTY_H)
43 #if defined(HAVE_TCSETATTR)
44 static struct termios termb;
45 static tcflag_t flags;
47 #if defined(HAVE_TERMIO_H)
48 static struct termio termb;
49 static unsigned short flags;
51 #if defined(HAVE_STTY)
52 static struct sgttyb ttyb;
58 void static save_tty_state(void);
59 void static disable_tty_echo(void);
60 void static restore_tty_state(void);
61 static RETSIGTYPE sigint_handler(int);
63 char *getpassword(prompt)
66 #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);
78 static char pbuf[INPUT_BUF_SIZE];
79 RETSIGTYPE (*sig)(int) = 0; /* initialization pacifies -Wall */
80 RETSIGTYPE sigint_handler(int);
82 int istty = isatty(0);
84 /* get the file descriptor for the actual input device if it's a tty */
87 if ((fi = fdopen(open("/dev/tty", 2), "r")) == NULL)
90 setbuf(fi, (char *)NULL);
95 /* store descriptor for the tty */
100 /* preserve tty state before turning off echo */
103 /* now that we have the current tty state, we can catch SIGINT and
105 sig = signal(SIGINT, sigint_handler);
107 /* turn off echo on the tty */
110 /* display the prompt and get the input string */
111 fprintf(stderr, "%s", prompt);
114 for (p = pbuf; (c = getc(fi))!='\n' && c!=EOF;)
116 if (p < &pbuf[INPUT_BUF_SIZE - 1])
121 /* write a newline so cursor won't appear to hang */
123 fprintf(stderr, "\n");
127 /* restore previous state of the tty */
130 /* restore previous state of SIGINT */
137 #endif /* !(defined(HAVE_TCSETATTR) || ... */
140 static void save_tty_state (void)
142 #if defined(HAVE_TCSETATTR)
143 tcgetattr(ttyfd, &termb);
144 flags = termb.c_lflag;
146 #if defined(HAVE_TERMIO_H)
147 ioctl(ttyfd, TCGETA, (char *) &termb);
148 flags = termb.c_lflag;
149 #else /* we HAVE_STTY */
151 flags = ttyb.sg_flags;
156 static void disable_tty_echo(void)
158 /* turn off echo on the tty */
159 #if defined(HAVE_TCSETATTR)
160 termb.c_lflag &= ~ECHO;
161 tcsetattr(ttyfd, TCSAFLUSH, &termb);
163 #if defined(HAVE_TERMIO_H)
164 termb.c_lflag &= ~ECHO;
165 ioctl(ttyfd, TCSETA, (char *) &termb);
166 #else /* we HAVE_STTY */
167 ttyb.sg_flags &= ~ECHO;
173 static void restore_tty_state(void)
175 /* restore previous tty echo state */
176 #if defined(HAVE_TCSETATTR)
177 termb.c_lflag = flags;
178 tcsetattr(ttyfd, TCSAFLUSH, &termb);
180 #if defined(HAVE_TERMIO_H)
181 termb.c_lflag = flags;
182 ioctl(ttyfd, TCSETA, (char *) &termb);
183 #else /* we HAVE_STTY */
184 ttyb.sg_flags = flags;
190 static RETSIGTYPE sigint_handler(int signum)
193 report(stderr, 1, 0, _("\nCaught signal... bailing out."));
196 /* getpass.c ends here */