135669Sbostic /*
2*61111Sbostic * Copyright (c) 1988, 1993
3*61111Sbostic * The Regents of the University of California. All rights reserved.
435669Sbostic *
542624Sbostic * %sccs.include.redist.c%
635669Sbostic */
735669Sbostic
826559Sdonn #if defined(LIBC_SCCS) && !defined(lint)
9*61111Sbostic static char sccsid[] = "@(#)getpass.c 8.1 (Berkeley) 06/04/93";
1035669Sbostic #endif /* LIBC_SCCS and not lint */
1122094Smckusick
1240101Smarc #include <sys/termios.h>
1335669Sbostic #include <sys/signal.h>
1460202Sbostic
1560202Sbostic #include <paths.h>
1660202Sbostic #include <pwd.h>
172017Swnj #include <stdio.h>
1846597Sdonn #include <unistd.h>
192017Swnj
202017Swnj char *
getpass(prompt)212017Swnj getpass(prompt)
2246597Sdonn const char *prompt;
232017Swnj {
2440101Smarc struct termios term;
2535669Sbostic register int ch;
262017Swnj register char *p;
2735669Sbostic FILE *fp, *outfp;
2835669Sbostic long omask;
2940101Smarc int echo;
3040101Smarc static char buf[_PASSWORD_LEN + 1];
312017Swnj
3235669Sbostic /*
3335669Sbostic * read and write to /dev/tty if possible; else read from
3435669Sbostic * stdin and write to stderr.
3535669Sbostic */
3660202Sbostic if ((outfp = fp = fopen(_PATH_TTY, "w+")) == NULL) {
3735669Sbostic outfp = stderr;
3835669Sbostic fp = stdin;
3935669Sbostic }
4040101Smarc /*
4140101Smarc * note - blocking signals isn't necessarily the
4240101Smarc * right thing, but we leave it for now.
4340101Smarc */
4440101Smarc omask = sigblock(sigmask(SIGINT)|sigmask(SIGTSTP));
4540101Smarc (void)tcgetattr(fileno(fp), &term);
4640101Smarc if (echo = (term.c_lflag & ECHO)) {
4740101Smarc term.c_lflag &= ~ECHO;
4849225Sbostic (void)tcsetattr(fileno(fp), TCSAFLUSH|TCSASOFT, &term);
4940101Smarc }
5037901Sbostic (void)fputs(prompt, outfp);
5135669Sbostic rewind(outfp); /* implied flush */
5235669Sbostic for (p = buf; (ch = getc(fp)) != EOF && ch != '\n';)
5340101Smarc if (p < buf + _PASSWORD_LEN)
5435669Sbostic *p++ = ch;
552017Swnj *p = '\0';
5635669Sbostic (void)write(fileno(outfp), "\n", 1);
5740101Smarc if (echo) {
5840101Smarc term.c_lflag |= ECHO;
5960202Sbostic (void)tcsetattr(fileno(fp), TCSAFLUSH|TCSASOFT, &term);
6040101Smarc }
6135669Sbostic (void)sigsetmask(omask);
6235669Sbostic if (fp != stdin)
6335669Sbostic (void)fclose(fp);
6435669Sbostic return(buf);
652017Swnj }
66