xref: /csrg-svn/lib/libc/gen/getpass.c (revision 40101)
135669Sbostic /*
235669Sbostic  * Copyright (c) 1988 The Regents of the University of California.
335669Sbostic  * All rights reserved.
435669Sbostic  *
535669Sbostic  * Redistribution and use in source and binary forms are permitted
635669Sbostic  * provided that the above copyright notice and this paragraph are
735669Sbostic  * duplicated in all such forms and that any documentation,
835669Sbostic  * advertising materials, and other materials related to such
935669Sbostic  * distribution and use acknowledge that the software was developed
1035669Sbostic  * by the University of California, Berkeley.  The name of the
1135669Sbostic  * University may not be used to endorse or promote products derived
1235669Sbostic  * from this software without specific prior written permission.
1335669Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
1435669Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
1535669Sbostic  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1635669Sbostic  */
1735669Sbostic 
1826559Sdonn #if defined(LIBC_SCCS) && !defined(lint)
19*40101Smarc static char sccsid[] = "@(#)getpass.c	5.5 (Berkeley) 02/15/90";
2035669Sbostic #endif /* LIBC_SCCS and not lint */
2122094Smckusick 
22*40101Smarc #include <sys/termios.h>
2335669Sbostic #include <sys/signal.h>
242017Swnj #include <stdio.h>
25*40101Smarc #include <pwd.h>
262017Swnj 
272017Swnj char *
282017Swnj getpass(prompt)
2935669Sbostic 	char *prompt;
302017Swnj {
31*40101Smarc 	struct termios term;
3235669Sbostic 	register int ch;
332017Swnj 	register char *p;
3435669Sbostic 	FILE *fp, *outfp;
3535669Sbostic 	long omask;
36*40101Smarc 	int echo;
37*40101Smarc 	static char buf[_PASSWORD_LEN + 1];
382017Swnj 
3935669Sbostic 	/*
4035669Sbostic 	 * read and write to /dev/tty if possible; else read from
4135669Sbostic 	 * stdin and write to stderr.
4235669Sbostic 	 */
4335669Sbostic 	if ((outfp = fp = fopen("/dev/tty", "w+")) == NULL) {
4435669Sbostic 		outfp = stderr;
4535669Sbostic 		fp = stdin;
4635669Sbostic 	}
47*40101Smarc 	/*
48*40101Smarc 	 * note - blocking signals isn't necessarily the
49*40101Smarc 	 * right thing, but we leave it for now.
50*40101Smarc 	 */
51*40101Smarc 	omask = sigblock(sigmask(SIGINT)|sigmask(SIGTSTP));
52*40101Smarc 	(void)tcgetattr(fileno(fp), &term);
53*40101Smarc 	if (echo = (term.c_lflag & ECHO)) {
54*40101Smarc 		term.c_lflag &= ~ECHO;
55*40101Smarc 		term.c_cflag |= CIGNORE;
56*40101Smarc 		(void)tcsetattr(fileno(fp), TCSADFLUSH, &term);
57*40101Smarc 	}
5837901Sbostic 	(void)fputs(prompt, outfp);
5935669Sbostic 	rewind(outfp);			/* implied flush */
6035669Sbostic 	for (p = buf; (ch = getc(fp)) != EOF && ch != '\n';)
61*40101Smarc 		if (p < buf + _PASSWORD_LEN)
6235669Sbostic 			*p++ = ch;
632017Swnj 	*p = '\0';
6435669Sbostic 	(void)write(fileno(outfp), "\n", 1);
65*40101Smarc 	if (echo) {
66*40101Smarc 		term.c_lflag |= ECHO;
67*40101Smarc 		term.c_cflag |= CIGNORE;
68*40101Smarc 		tcsetattr(fileno(fp), TCSADFLUSH, &term);
69*40101Smarc 	}
7035669Sbostic 	(void)sigsetmask(omask);
7135669Sbostic 	if (fp != stdin)
7235669Sbostic 		(void)fclose(fp);
7335669Sbostic 	return(buf);
742017Swnj }
75