1 /* Copyright 1993-95 by Carl Harris, Jr. Copyright 1996 by Eric S. Raymond
3 * For license terms, see the file COPYING in this directory.
6 /***********************************************************************
9 programmer: Carl Harris, ceharris@mal.com
10 description: getpass() replacement which allows for long passwords.
12 ***********************************************************************/
16 #if defined(STDC_HEADERS)
22 #define INPUT_BUF_SIZE MAX_PASSWORD_LENGTH
24 #if defined(HAVE_TERMIOS_H) && defined(HAVE_TCSETATTR)
27 #if defined(HAVE_TERMIO_H)
28 # include <sys/ioctl.h>
31 #if defined(HAVE_SGTTY_H)
39 #if defined(HAVE_TCSETATTR)
40 static struct termios termb;
41 static tcflag_t flags;
43 #if defined(HAVE_TERMIO_H)
44 static struct termio termb;
45 static unsigned short flags;
47 #if defined(HAVE_STTY)
48 static struct sgttyb ttyb;
54 void save_tty_state();
55 void disable_tty_echo();
56 void restore_tty_state();
63 #if !(defined(HAVE_TCSETATTR) || defined(HAVE_TERMIO_H) || defined(HAVE_STTY))
65 #if defined(HAVE_GETPASS)
67 return getpass(prompt);
69 fputs("ERROR: no support for getpassword() routine\n",stderr);
73 #endif /* !(defined(HAVE_TCSETATTR) || ... */
78 static char pbuf[INPUT_BUF_SIZE];
80 RETSIGTYPE sigint_handler();
83 /* get the file descriptor for the input device */
84 if ((fi = fdopen(open("/dev/tty", 2), "r")) == NULL)
87 setbuf(fi, (char *)NULL);
89 /* store descriptor for the tty */
92 /* preserve tty state before turning off echo */
95 /* now that we have the current tty state, we can catch SIGINT and
97 sig = signal(SIGINT, sigint_handler);
99 /* turn off echo on the tty */
102 /* display the prompt and get the input string */
103 fprintf(stderr, "%s", prompt); fflush(stderr);
104 for (p=pbuf; (c = getc(fi))!='\n' && c!=EOF;) {
105 if (p < &pbuf[INPUT_BUF_SIZE - 1])
110 /* write a newline so cursor won't appear to hang */
111 fprintf(stderr, "\n"); fflush(stderr);
113 /* restore previous state of the tty */
116 /* restore previous state of SIGINT */
130 #if defined(HAVE_TCSETATTR)
131 tcgetattr(ttyfd, &termb);
132 flags = termb.c_lflag;
134 #if defined(HAVE_TERMIO_H)
135 ioctl(ttyfd, TCGETA, (char *) &termb);
136 flags = termb.c_lflag;
137 #else /* we HAVE_STTY */
139 flags = ttyb.sg_flags;
148 /* turn off echo on the tty */
149 #if defined(HAVE_TCSETATTR)
150 termb.c_lflag &= ~ECHO;
151 tcsetattr(ttyfd, TCSAFLUSH, &termb);
153 #if defined(HAVE_TERMIO_H)
154 termb.c_lflag &= ~ECHO;
155 ioctl(ttyfd, TCSETA, (char *) &termb);
156 #else /* we HAVE_STTY */
157 ttyb.sg_flags &= ~ECHO;
168 /* restore previous tty echo state */
169 #if defined(HAVE_TCSETATTR)
170 termb.c_lflag = flags;
171 tcsetattr(ttyfd, TCSAFLUSH, &termb);
173 #if defined(HAVE_TERMIO_H)
174 termb.c_lflag = flags;
175 ioctl(ttyfd, TCSETA, (char *) &termb);
176 #else /* we HAVE_STTY */
177 ttyb.sg_flags = flags;
184 RETSIGTYPE sigint_handler ()
187 fputs("\nCaught signal... bailing out.\n", stderr);