xref: /minix3/minix/lib/libc/gen/getpass.c (revision 433d6423c39e34ec4b79c950597bb2d236f886be)
1*433d6423SLionel Sambuc /*	getpass() - read a password		Author: Kees J. Bot
2*433d6423SLionel Sambuc  *							Feb 16 1993
3*433d6423SLionel Sambuc  */
4*433d6423SLionel Sambuc #include <sys/cdefs.h>
5*433d6423SLionel Sambuc #include "namespace.h"
6*433d6423SLionel Sambuc 
7*433d6423SLionel Sambuc #include <sys/types.h>
8*433d6423SLionel Sambuc #include <fcntl.h>
9*433d6423SLionel Sambuc #include <unistd.h>
10*433d6423SLionel Sambuc #include <signal.h>
11*433d6423SLionel Sambuc #include <termios.h>
12*433d6423SLionel Sambuc #include <string.h>
13*433d6423SLionel Sambuc 
14*433d6423SLionel Sambuc #ifdef __weak_alias
__weak_alias(getpass,_getpass)15*433d6423SLionel Sambuc __weak_alias(getpass, _getpass)
16*433d6423SLionel Sambuc #endif
17*433d6423SLionel Sambuc 
18*433d6423SLionel Sambuc static int intr;
19*433d6423SLionel Sambuc 
20*433d6423SLionel Sambuc static void catch(int sig)
21*433d6423SLionel Sambuc {
22*433d6423SLionel Sambuc 	intr= 1;
23*433d6423SLionel Sambuc }
24*433d6423SLionel Sambuc 
getpass(const char * prompt)25*433d6423SLionel Sambuc char *getpass(const char *prompt)
26*433d6423SLionel Sambuc {
27*433d6423SLionel Sambuc 	struct sigaction osa, sa;
28*433d6423SLionel Sambuc 	struct termios cooked, raw;
29*433d6423SLionel Sambuc 	static char password[32+1];
30*433d6423SLionel Sambuc 	int fd, n= 0;
31*433d6423SLionel Sambuc 
32*433d6423SLionel Sambuc 	/* Try to open the controlling terminal. */
33*433d6423SLionel Sambuc 	if ((fd= open("/dev/tty", O_RDONLY)) < 0) return NULL;
34*433d6423SLionel Sambuc 
35*433d6423SLionel Sambuc 	/* Trap interrupts unless ignored. */
36*433d6423SLionel Sambuc 	intr= 0;
37*433d6423SLionel Sambuc 	sigaction(SIGINT, NULL, &osa);
38*433d6423SLionel Sambuc 	if (osa.sa_handler != SIG_IGN) {
39*433d6423SLionel Sambuc 		sigemptyset(&sa.sa_mask);
40*433d6423SLionel Sambuc 		sa.sa_flags= 0;
41*433d6423SLionel Sambuc 		sa.sa_handler= catch;
42*433d6423SLionel Sambuc 		sigaction(SIGINT, &sa, &osa);
43*433d6423SLionel Sambuc 	}
44*433d6423SLionel Sambuc 
45*433d6423SLionel Sambuc 	/* Set the terminal to non-echo mode. */
46*433d6423SLionel Sambuc 	tcgetattr(fd, &cooked);
47*433d6423SLionel Sambuc 	raw= cooked;
48*433d6423SLionel Sambuc 	raw.c_iflag|= ICRNL;
49*433d6423SLionel Sambuc 	raw.c_lflag&= ~ECHO;
50*433d6423SLionel Sambuc 	raw.c_lflag|= ECHONL;
51*433d6423SLionel Sambuc 	raw.c_oflag|= OPOST | ONLCR;
52*433d6423SLionel Sambuc 	tcsetattr(fd, TCSANOW, &raw);
53*433d6423SLionel Sambuc 
54*433d6423SLionel Sambuc 	/* Print the prompt.  (After setting non-echo!) */
55*433d6423SLionel Sambuc 	write(2, prompt, strlen(prompt));
56*433d6423SLionel Sambuc 
57*433d6423SLionel Sambuc 	/* Read the password, 32 characters max. */
58*433d6423SLionel Sambuc 	while (read(fd, password+n, 1) > 0) {
59*433d6423SLionel Sambuc 		if (password[n] == '\n') break;
60*433d6423SLionel Sambuc 		if (n < 32) n++;
61*433d6423SLionel Sambuc 	}
62*433d6423SLionel Sambuc 	password[n]= 0;
63*433d6423SLionel Sambuc 
64*433d6423SLionel Sambuc 	/* Terminal back to cooked mode. */
65*433d6423SLionel Sambuc 	tcsetattr(fd, TCSANOW, &cooked);
66*433d6423SLionel Sambuc 
67*433d6423SLionel Sambuc 	close(fd);
68*433d6423SLionel Sambuc 
69*433d6423SLionel Sambuc 	/* Interrupt? */
70*433d6423SLionel Sambuc 	sigaction(SIGINT, &osa, NULL);
71*433d6423SLionel Sambuc 	if (intr) raise(SIGINT);
72*433d6423SLionel Sambuc 
73*433d6423SLionel Sambuc 	return password;
74*433d6423SLionel Sambuc }
75