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 ***********************************************************************/
21 #if defined(HAVE_UNISTD_H)
24 #include "fetchmail.h"
27 #define INPUT_BUF_SIZE PASSWORDLEN
29 #if defined(HAVE_TERMIOS_H) && defined(HAVE_TCSETATTR)
32 #if defined(HAVE_TERMIO_H)
33 # include <sys/ioctl.h>
36 #if defined(HAVE_SGTTY_H)
44 #if defined(HAVE_TCSETATTR)
45 static struct termios termb;
46 static tcflag_t flags;
48 #if defined(HAVE_TERMIO_H)
49 static struct termio termb;
50 static unsigned short flags;
52 #if defined(HAVE_STTY)
53 static struct sgttyb ttyb;
59 static void save_tty_state(void);
60 static void disable_tty_echo(void);
61 static void restore_tty_state(void);
62 static RETSIGTYPE sigint_handler(int);
64 char *fm_getpassword(char *prompt)
66 #if !(defined(HAVE_TCSETATTR) || defined(HAVE_TERMIO_H) || defined(HAVE_STTY))
67 #if defined(HAVE_GETPASS)
69 return getpass(prompt);
71 fputs(GT_("ERROR: no support for getpassword() routine\n"),stderr);
78 static char pbuf[INPUT_BUF_SIZE];
79 SIGHANDLERTYPE sig = 0; /* initialization pacifies -Wall */
81 int istty = isatty(0);
83 /* get the file descriptor for the actual input device if it's a tty */
86 if ((fi = fdopen(open("/dev/tty", 2), "r")) == NULL)
89 setbuf(fi, (char *)NULL);
94 /* store descriptor for the tty */
99 /* preserve tty state before turning off echo */
102 /* now that we have the current tty state, we can catch SIGINT and
104 sig = set_signal_handler(SIGINT, sigint_handler);
106 /* turn off echo on the tty */
109 /* display the prompt and get the input string */
110 fprintf(stderr, "%s", prompt);
113 for (p = pbuf; (c = getc(fi))!='\n' && c!=EOF;)
115 if (p < &pbuf[INPUT_BUF_SIZE - 1])
120 /* write a newline so cursor won't appear to hang */
122 fprintf(stderr, "\n");
126 /* restore previous state of the tty */
129 /* restore previous state of SIGINT */
130 set_signal_handler(SIGINT, sig);
133 fclose(fi); /* not checking should be safe, file mode was "r" */
136 #endif /* !(defined(HAVE_TCSETATTR) || ... */
139 static void save_tty_state (void)
141 #if defined(HAVE_TCSETATTR)
142 tcgetattr(ttyfd, &termb);
143 flags = termb.c_lflag;
145 #if defined(HAVE_TERMIO_H)
146 ioctl(ttyfd, TCGETA, (char *) &termb);
147 flags = termb.c_lflag;
148 #else /* we HAVE_STTY */
150 flags = ttyb.sg_flags;
155 static void disable_tty_echo(void)
157 /* turn off echo on the tty */
158 #if defined(HAVE_TCSETATTR)
159 termb.c_lflag &= ~ECHO;
160 tcsetattr(ttyfd, TCSAFLUSH, &termb);
162 #if defined(HAVE_TERMIO_H)
163 termb.c_lflag &= ~ECHO;
164 ioctl(ttyfd, TCSETA, (char *) &termb);
165 #else /* we HAVE_STTY */
166 ttyb.sg_flags &= ~ECHO;
172 static void restore_tty_state(void)
174 /* restore previous tty echo state */
175 #if defined(HAVE_TCSETATTR)
176 termb.c_lflag = flags;
177 tcsetattr(ttyfd, TCSAFLUSH, &termb);
179 #if defined(HAVE_TERMIO_H)
180 termb.c_lflag = flags;
181 ioctl(ttyfd, TCSETA, (char *) &termb);
182 #else /* we HAVE_STTY */
183 ttyb.sg_flags = flags;
189 static RETSIGTYPE sigint_handler(int signum)
193 report(stderr, GT_("\nCaught SIGINT... bailing out.\n"));
197 /* getpass.c ends here */