xref: /csrg-svn/lib/libc/gen/getpass.c (revision 42624)
135669Sbostic /*
235669Sbostic  * Copyright (c) 1988 The Regents of the University of California.
335669Sbostic  * All rights reserved.
435669Sbostic  *
5*42624Sbostic  * %sccs.include.redist.c%
635669Sbostic  */
735669Sbostic 
826559Sdonn #if defined(LIBC_SCCS) && !defined(lint)
9*42624Sbostic static char sccsid[] = "@(#)getpass.c	5.6 (Berkeley) 06/01/90";
1035669Sbostic #endif /* LIBC_SCCS and not lint */
1122094Smckusick 
1240101Smarc #include <sys/termios.h>
1335669Sbostic #include <sys/signal.h>
142017Swnj #include <stdio.h>
1540101Smarc #include <pwd.h>
162017Swnj 
172017Swnj char *
182017Swnj getpass(prompt)
1935669Sbostic 	char *prompt;
202017Swnj {
2140101Smarc 	struct termios term;
2235669Sbostic 	register int ch;
232017Swnj 	register char *p;
2435669Sbostic 	FILE *fp, *outfp;
2535669Sbostic 	long omask;
2640101Smarc 	int echo;
2740101Smarc 	static char buf[_PASSWORD_LEN + 1];
282017Swnj 
2935669Sbostic 	/*
3035669Sbostic 	 * read and write to /dev/tty if possible; else read from
3135669Sbostic 	 * stdin and write to stderr.
3235669Sbostic 	 */
3335669Sbostic 	if ((outfp = fp = fopen("/dev/tty", "w+")) == NULL) {
3435669Sbostic 		outfp = stderr;
3535669Sbostic 		fp = stdin;
3635669Sbostic 	}
3740101Smarc 	/*
3840101Smarc 	 * note - blocking signals isn't necessarily the
3940101Smarc 	 * right thing, but we leave it for now.
4040101Smarc 	 */
4140101Smarc 	omask = sigblock(sigmask(SIGINT)|sigmask(SIGTSTP));
4240101Smarc 	(void)tcgetattr(fileno(fp), &term);
4340101Smarc 	if (echo = (term.c_lflag & ECHO)) {
4440101Smarc 		term.c_lflag &= ~ECHO;
4540101Smarc 		term.c_cflag |= CIGNORE;
4640101Smarc 		(void)tcsetattr(fileno(fp), TCSADFLUSH, &term);
4740101Smarc 	}
4837901Sbostic 	(void)fputs(prompt, outfp);
4935669Sbostic 	rewind(outfp);			/* implied flush */
5035669Sbostic 	for (p = buf; (ch = getc(fp)) != EOF && ch != '\n';)
5140101Smarc 		if (p < buf + _PASSWORD_LEN)
5235669Sbostic 			*p++ = ch;
532017Swnj 	*p = '\0';
5435669Sbostic 	(void)write(fileno(outfp), "\n", 1);
5540101Smarc 	if (echo) {
5640101Smarc 		term.c_lflag |= ECHO;
5740101Smarc 		term.c_cflag |= CIGNORE;
5840101Smarc 		tcsetattr(fileno(fp), TCSADFLUSH, &term);
5940101Smarc 	}
6035669Sbostic 	(void)sigsetmask(omask);
6135669Sbostic 	if (fp != stdin)
6235669Sbostic 		(void)fclose(fp);
6335669Sbostic 	return(buf);
642017Swnj }
65