1 /* readpass.c: The opiereadpass() library function.
3 %%% portions-copyright-cmetz-96
4 Portions of this software are Copyright 1996-1999 by Craig Metz, All Rights
5 Reserved. The Inner Net License Version 2 applies to these portions of
7 You should have received a copy of the license with this software. If
8 you didn't get a copy, you may request one from <license@inner.net>.
10 Portions of this software are Copyright 1995 by Randall Atkinson and Dan
11 McDonald, All Rights Reserved. All Rights under this copyright are assigned
12 to the U.S. Naval Research Laboratory (NRL). The NRL Copyright Notice and
13 License Agreement applies to this software.
17 Modified by cmetz for OPIE 2.31. Use usleep() to delay after setting
18 the terminal attributes; this might help certain buggy
20 Modified by cmetz for OPIE 2.3. Use TCSAFLUSH always.
21 Modified by cmetz for OPIE 2.22. Replaced echo w/ flags.
23 Modified by cmetz for OPIE 2.2. Use FUNCTION declaration et al.
24 Flush extraneous characters up to eol. Handle gobs of possible
25 erase and kill keys if on a terminal. To do so, use RAW
26 terminal I/O and handle echo ourselves. (should also help
27 DOS et al portability). Fixed include order. Re-did MSDOS
28 and OS/2 includes. Set up VMIN and VTIME. Added some non-UNIX
29 portability cruft. Limit backspacing and killing. In terminal
30 mode, eat random other control characters. Added eof handling.
31 Created at NRL for OPIE 2.2 from opiesubr.c. Change opiestrip_crlf to
32 opiestripcrlf. Don't strip to seven bits.
38 #include <stdlib.h> /* ANSI C standard library */
41 #include <fcntl.h> /* POSIX file control function headers */
42 #include <termios.h> /* POSIX Terminal I/O functions */
44 #include <unistd.h> /* POSIX standard definitions */
45 #endif /* HAVE_UNISTD_H */
52 #endif /* __MSDOS__ */
62 #define CONTROL(x) (x - 64)
64 char *bsseq = "\b \b";
67 static jmp_buf jmpbuf;
69 static VOIDRET catch FUNCTION((i), int i)
75 char *opiereadpass FUNCTION((buf, len, flags), char *buf AND int len AND int flags)
78 struct termios attr, orig_attr;
84 memset(erase, 0, sizeof(erase));
85 memset(kill, 0, sizeof(kill));
86 memset(eof, 0, sizeof(eof));
88 /* This section was heavily rewritten by rja following the model of code
89 samples circa page 151 of the POSIX Programmer's Guide by Donald Lewine,
90 ISBN 0-937175-73-0. That book is Copyright 1991 by O'Reilly &
91 Associates, Inc. All Rights Reserved. I recommend the book to anyone
92 trying to write portable software. rja */
98 signal(SIGINT, catch);
101 /* Flush any pending output */
106 /* Get original terminal attributes */
108 if (tcgetattr(0, &orig_attr))
111 /* copy terminal settings into attr */
112 memcpy(&attr, &orig_attr, sizeof(struct termios));
114 attr.c_lflag &= ~(ECHO | ICANON);
115 attr.c_lflag |= ISIG;
118 attr.c_cc[VTIME] = 0;
120 erase[0] = CONTROL('H');
128 if (*(e++) == CERASE)
140 if (*(e++) == attr.c_cc[VERASE])
144 *e = attr.c_cc[VERASE];
148 kill[0] = CONTROL('U');
166 if (*(e++) == attr.c_cc[VKILL])
170 *e = attr.c_cc[VKILL];
174 eof[0] = CONTROL('D');
192 if (*(e++) == attr.c_cc[VEOF])
202 #endif /* HAVE_USLEEP */
204 if (tcsetattr(0, TCSAFLUSH, &attr))
209 #endif /* HAVE_USLEEP */
212 erase[0] = CONTROL('H');
214 kill[0] = CONTROL('U');
215 eof[0] = CONTROL('D');
216 eof[1] = CONTROL('Z');
220 char *c = buf, *end = buf + len, *e;
227 if (read(0, c, 1) != 1)
234 KbdCharIn(&keyInfo, 0, 0);
238 if ((*c == '\r') || (*c == '\n')) {
255 write(1, bsseq, sizeof(bsseq) - 1);
268 write(1, bsseq, sizeof(bsseq) - 1);
291 /* Restore previous tty modes */
293 if (tcsetattr(0, TCSAFLUSH, &orig_attr))
296 signal(SIGINT, SIG_DFL);
299 /* After the secret key is taken from the keyboard, the line feed is
300 written to standard error instead of standard output. That means that
301 anyone using the program from a terminal won't notice, but capturing
302 standard output will get the key words without a newline in front of
305 fprintf(stderr, "\n");