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