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 ***********************************************************************/
22 #include "fetchmail.h"
25 #define INPUT_BUF_SIZE PASSWORDLEN
31 static struct termios termb;
32 static tcflag_t flags;
34 static void save_tty_state(void);
35 static void disable_tty_echo(void);
36 static void restore_tty_state(void);
37 static void sigint_handler(int);
39 char *fm_getpassword(char *prompt)
44 static char pbuf[INPUT_BUF_SIZE];
45 SIGHANDLERTYPE sig = 0; /* initialization pacifies -Wall */
47 int istty = isatty(0);
49 /* get the file descriptor for the actual input device if it's a tty */
52 if ((fi = fdopen(open("/dev/tty", 2), "r")) == NULL)
55 setbuf(fi, (char *)NULL);
60 /* store descriptor for the tty */
65 /* preserve tty state before turning off echo */
68 /* now that we have the current tty state, we can catch SIGINT and
70 sig = set_signal_handler(SIGINT, sigint_handler);
72 /* turn off echo on the tty */
75 /* display the prompt and get the input string */
76 fprintf(stderr, "%s", prompt);
79 for (p = pbuf; (c = getc(fi))!='\n' && c!=EOF;)
81 if (p < &pbuf[INPUT_BUF_SIZE - 1])
86 /* write a newline so cursor won't appear to hang */
88 fprintf(stderr, "\n");
92 /* restore previous state of the tty */
95 /* restore previous state of SIGINT */
96 set_signal_handler(SIGINT, sig);
99 fclose(fi); /* not checking should be safe, file mode was "r" */
104 static void save_tty_state (void)
106 tcgetattr(ttyfd, &termb);
107 flags = termb.c_lflag;
110 static void disable_tty_echo(void)
112 /* turn off echo on the tty */
113 termb.c_lflag &= ~ECHO;
114 tcsetattr(ttyfd, TCSAFLUSH, &termb);
117 static void restore_tty_state(void)
119 /* restore previous tty echo state */
120 termb.c_lflag = flags;
121 tcsetattr(ttyfd, TCSAFLUSH, &termb);
124 static void sigint_handler(int signum)
128 report(stderr, GT_("\nCaught SIGINT... bailing out.\n"));
132 /* getpass.c ends here */