1 /* 2 * Copyright (c) 1988 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #if defined(LIBC_SCCS) && !defined(lint) 9 static char sccsid[] = "@(#)getpass.c 5.7 (Berkeley) 06/17/90"; 10 #endif /* LIBC_SCCS and not lint */ 11 12 #include <sys/termios.h> 13 #include <sys/signal.h> 14 #include <stdio.h> 15 #include <pwd.h> 16 17 char * 18 getpass(prompt) 19 char *prompt; 20 { 21 struct termios term; 22 register int ch; 23 register char *p; 24 FILE *fp, *outfp; 25 long omask; 26 int echo; 27 static char buf[_PASSWORD_LEN + 1]; 28 29 /* 30 * read and write to /dev/tty if possible; else read from 31 * stdin and write to stderr. 32 */ 33 if ((outfp = fp = fopen("/dev/tty", "w+")) == NULL) { 34 outfp = stderr; 35 fp = stdin; 36 } 37 /* 38 * note - blocking signals isn't necessarily the 39 * right thing, but we leave it for now. 40 */ 41 omask = sigblock(sigmask(SIGINT)|sigmask(SIGTSTP)); 42 (void)tcgetattr(fileno(fp), &term); 43 if (echo = (term.c_lflag & ECHO)) { 44 term.c_lflag &= ~ECHO; 45 term.c_cflag |= CIGNORE; 46 (void)tcsetattr(fileno(fp), TCSAFLUSH, &term); 47 } 48 (void)fputs(prompt, outfp); 49 rewind(outfp); /* implied flush */ 50 for (p = buf; (ch = getc(fp)) != EOF && ch != '\n';) 51 if (p < buf + _PASSWORD_LEN) 52 *p++ = ch; 53 *p = '\0'; 54 (void)write(fileno(outfp), "\n", 1); 55 if (echo) { 56 term.c_lflag |= ECHO; 57 term.c_cflag |= CIGNORE; 58 tcsetattr(fileno(fp), TCSAFLUSH, &term); 59 } 60 (void)sigsetmask(omask); 61 if (fp != stdin) 62 (void)fclose(fp); 63 return(buf); 64 } 65