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.9 (Berkeley) 05/06/91"; 10 #endif /* LIBC_SCCS and not lint */ 11 12 #include <sys/termios.h> 13 #include <sys/signal.h> 14 #include <stdio.h> 15 #include <unistd.h> 16 #include <pwd.h> 17 18 char * 19 getpass(prompt) 20 const char *prompt; 21 { 22 struct termios term; 23 register int ch; 24 register char *p; 25 FILE *fp, *outfp; 26 long omask; 27 int echo; 28 static char buf[_PASSWORD_LEN + 1]; 29 30 /* 31 * read and write to /dev/tty if possible; else read from 32 * stdin and write to stderr. 33 */ 34 if ((outfp = fp = fopen("/dev/tty", "w+")) == NULL) { 35 outfp = stderr; 36 fp = stdin; 37 } 38 /* 39 * note - blocking signals isn't necessarily the 40 * right thing, but we leave it for now. 41 */ 42 omask = sigblock(sigmask(SIGINT)|sigmask(SIGTSTP)); 43 (void)tcgetattr(fileno(fp), &term); 44 if (echo = (term.c_lflag & ECHO)) { 45 term.c_lflag &= ~ECHO; 46 (void)tcsetattr(fileno(fp), TCSAFLUSH|TCSASOFT, &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 tcsetattr(fileno(fp), TCSAFLUSH|TCSASOFT, &term); 58 } 59 (void)sigsetmask(omask); 60 if (fp != stdin) 61 (void)fclose(fp); 62 return(buf); 63 } 64