if (prompt) { p = (char *) prompt; do {  switch (*p) { case '%':   if (user && *(p+1) == 'u') { (void) fputs(user, output); p++; break; } else if (host && *(p+1) == 'h') { (void) fputs(host, output); p++; break; }  default:    (void) fputc(*p, output); } } while (*(++p)); }   if (input == output) { (void) fflush(output); (void) rewind(output); }
char * tgetpass(prompt, timeout, user, host)    const char *prompt;    int timeout;    char *user;    char *host;{#ifdef HAVE_TERMIOS_H    struct termios term;#else#ifdef HAVE_TERMIO_H    struct termio term;#else    struct sgttyb ttyb;#endif /* HAVE_TERMIO_H */#endif /* HAVE_TERMIOS_H */#ifdef POSIX_SIGNALS    sigset_t oldmask;    sigset_t mask;#else    int oldmask;#endif /* POSIX_SIGNALS */    int n, echo;    FILE *input, *output;    static char buf[_PASSWD_LEN + 1];    fd_set *readfds;    struct timeval tv;    char *p;    /*     * mask out SIGINT and SIGTSTP, should probably just catch and deal.     */#ifdef POSIX_SIGNALS    (void) sigemptyset(&mask);    (void) sigaddset(&mask, SIGINT);    (void) sigaddset(&mask, SIGTSTP);    (void) sigprocmask(SIG_BLOCK, &mask, &oldmask);#else    oldmask = sigblock(sigmask(SIGINT)|sigmask(SIGTSTP));#endif    /*     * open /dev/tty for reading/writing if possible or use     * stdin and stderr instead.     */    if ((input = fopen(_PATH_TTY, "r+")) == NULL) {	input = stdin;	output = stderr;	(void) fflush(output);    } else {	output = input;    }    /*     * turn off echo     */#ifdef HAVE_TERMIOS_H    (void) tcgetattr(fileno(input), &term);    if ((echo = (term.c_lflag & ECHO))) {	term.c_lflag &= ~ECHO;	(void) tcsetattr(fileno(input), TCSAFLUSH|TCSASOFT, &term);    }#else#ifdef HAVE_TERMIO_H    (void) ioctl(fileno(input), TCGETA, &term);    if ((echo = (term.c_lflag & ECHO))) {	term.c_lflag &= ~ECHO;	(void) ioctl(fileno(input), TCSETA, &term);    }#else    (void) ioctl(fileno(input), TIOCGETP, &ttyb);    if ((echo = (ttyb.sg_flags & ECHO))) {	ttyb.sg_flags &= ~ECHO;	(void) ioctl(fileno(input), TIOCSETP, &ttyb);    }#endif /* HAVE_TERMIO_H */#endif /* HAVE_TERMIOS_H */    /* print the prompt */    if (prompt) {	p = (char *) prompt;	do {	    /* expand %u -> username, %h -> host */	    switch (*p) {		case '%':   if (user && *(p+1) == 'u') {				(void) fputs(user, output);				p++;				break;			    } else if (host && *(p+1) == 'h') {				(void) fputs(host, output);				p++;				break;			    }		default:    (void) fputc(*p, output);	    }	} while (*(++p));    }    /* rewind if necesary */    if (input == output) {	(void) fflush(output);	(void) rewind(output);    }    /*     * Timeout of <= 0 means no timeout     */    if (timeout > 0) {	/* setup for select(2) */	n = howmany(fileno(input) + 1, NFDBITS) * sizeof(fd_mask);	if ((readfds = (fd_set *) malloc(n)) == NULL) {	    (void) fprintf(stderr, "Cannot allocate memory: ");	    perror("");	    return(NULL);	}	(void) memset((VOID *)readfds, 0, n);	FD_SET(fileno(input), readfds);	/* set timeout for select */	tv.tv_sec = timeout;	tv.tv_usec = 0;	/*	 * get password or return empty string if nothing to read by timeout	 */	buf[0] = '\0';	if (select(fileno(input) + 1, readfds, 0, 0, &tv) > 0 &&	    fgets(buf, sizeof(buf), input)) {	    n = strlen(buf);	    if (buf[n - 1] == '\n')		buf[n - 1] = '\0';	}	(void) free(readfds);    } else {	buf[0] = '\0';	if (fgets(buf, sizeof(buf), input)) {	    n = strlen(buf);	    if (buf[n - 1] == '\n')		buf[n - 1] = '\0';	}    }     /* turn on echo */#ifdef HAVE_TERMIOS_H    if (echo) {	term.c_lflag |= ECHO;	(void) tcsetattr(fileno(input), TCSAFLUSH|TCSASOFT, &term);    }#else#ifdef HAVE_TERMIO_H    if (echo) {	term.c_lflag |= ECHO;	(void) ioctl(fileno(input), TCSETA, &term);    }#else    if (echo) {	ttyb.sg_flags |= ECHO;	(void) ioctl(fileno(input), TIOCSETP, &ttyb);    }#endif /* HAVE_TERMIO_H */#endif /* HAVE_TERMIOS_H */    /* rewind if necesary */    if (input == output) {	(void) fflush(output);	(void) rewind(output);    }    /* print a newline since echo is turned off */    (void) fputc('\n', output);    /* restore old signal mask */#ifdef POSIX_SIGNALS    (void) sigprocmask(SIG_SETMASK, &oldmask, NULL);#else    (void) sigsetmask(oldmask);#endif    /* close /dev/tty if that's what we opened */    if (input != stdin)	(void) fclose(input);    return(buf);}