=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/sudo/Attic/tgetpass.c,v retrieving revision 1.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- src/usr.bin/sudo/Attic/tgetpass.c 2003/04/19 21:57:17 1.9 +++ src/usr.bin/sudo/Attic/tgetpass.c 2004/09/28 15:10:51 1.10 @@ -1,41 +1,27 @@ /* - * Copyright (c) 1996, 1998-2002 Todd C. Miller - * All rights reserved. + * Copyright (c) 1996, 1998-2004 Todd C. Miller * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. Products derived from this software may not be called "Sudo" nor - * may "Sudo" appear in their names without specific prior written - * permission from the author. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * * Sponsored in part by the Defense Advanced Research Projects * Agency (DARPA) and Air Force Research Laboratory, Air Force * Materiel Command, USAF, under agreement number F39502-99-1-0512. */ +#ifdef __TANDEM +# include +#endif + #include "config.h" #include @@ -43,9 +29,6 @@ #ifdef HAVE_SYS_BSDTYPES_H # include #endif /* HAVE_SYS_BSDTYPES_H */ -#ifdef HAVE_SYS_SELECT_H -# include -#endif /* HAVE_SYS_SELECT_H */ #include #include #ifdef STDC_HEADERS @@ -87,7 +70,7 @@ #include "sudo.h" #ifndef lint -static const char rcsid[] = "$Sudo: tgetpass.c,v 1.105 2003/04/16 00:42:10 millert Exp $"; +static const char rcsid[] = "$Sudo: tgetpass.c,v 1.111 2004/06/06 23:58:11 millert Exp $"; #endif /* lint */ #ifndef TCSASOFT @@ -131,8 +114,8 @@ static volatile sig_atomic_t signo; -static char *tgetline __P((int, char *, size_t, int)); static void handler __P((int)); +static char *getln __P((int, char *, size_t)); /* * Like getpass(3) but with timeout and echo flags. @@ -143,16 +126,17 @@ int timeout; int flags; { - sigaction_t sa, saveint, savehup, savequit, saveterm; + sigaction_t sa, savealrm, saveint, savehup, savequit, saveterm; sigaction_t savetstp, savettin, savettou; - static char buf[SUDO_PASS_MAX + 1]; - int input, output, save_errno; struct TERM term, oterm; char *pass; + static char buf[SUDO_PASS_MAX + 1]; + int input, output, save_errno; + (void) fflush(stdout); restart: /* Open /dev/tty for reading/writing if possible else use stdin/stderr. */ - if ((flags & TGP_STDIN) || + if (ISSET(flags, TGP_STDIN) || (input = output = open(_PATH_TTY, O_RDWR|O_NOCTTY)) == -1) { input = STDIN_FILENO; output = STDERR_FILENO; @@ -160,12 +144,12 @@ /* * Catch signals that would otherwise cause the user to end - * up with echo turned off in the shell. Don't worry about - * things like SIGALRM and SIGPIPE for now. + * up with echo turned off in the shell. */ sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; /* don't restart system calls */ + sa.sa_flags = SA_INTERRUPT; /* don't restart system calls */ sa.sa_handler = handler; + (void) sigaction(SIGALRM, &sa, &savealrm); (void) sigaction(SIGINT, &sa, &saveint); (void) sigaction(SIGHUP, &sa, &savehup); (void) sigaction(SIGQUIT, &sa, &savequit); @@ -177,8 +161,8 @@ /* Turn echo off/on as specified by flags. */ if (term_getattr(input, &oterm) == 0) { (void) memcpy(&term, &oterm, sizeof(term)); - if (!(flags & TGP_ECHO)) - term.tflags &= ~(ECHO | ECHONL); + if (!ISSET(flags, TGP_ECHO)) + CLR(term.tflags, (ECHO | ECHONL)); #ifdef VSTATUS term.c_cc[VSTATUS] = _POSIX_VDISABLE; #endif @@ -191,15 +175,19 @@ if (prompt) (void) write(output, prompt, strlen(prompt)); - pass = tgetline(input, buf, sizeof(buf), timeout); + if (timeout > 0) + alarm(timeout); + pass = getln(input, buf, sizeof(buf)); + alarm(0); save_errno = errno; - if (!(term.tflags & ECHO)) + if (!ISSET(term.tflags, ECHO)) (void) write(output, "\n", 1); /* Restore old tty settings and signals. */ if (memcmp(&term, &oterm, sizeof(term)) != 0) (void) term_setattr(input, &oterm); + (void) sigaction(SIGALRM, &savealrm, NULL); (void) sigaction(SIGINT, &saveint, NULL); (void) sigaction(SIGHUP, &savehup, NULL); (void) sigaction(SIGQUIT, &savequit, NULL); @@ -215,7 +203,7 @@ * now that we have restored the signal handlers. */ if (signo) { - kill(getpid(), signo); + kill(getpid(), signo); switch (signo) { case SIGTSTP: case SIGTTIN: @@ -229,22 +217,14 @@ return(pass); } -/* - * Get a line of input (optionally timing out) and place it in buf. - */ static char * -tgetline(fd, buf, bufsiz, timeout) +getln(fd, buf, bufsiz) int fd; char *buf; size_t bufsiz; - int timeout; { - fd_set *readfds = NULL; - struct timeval tv; - size_t left; - char *cp; - char c; - int n; + char c, *cp; + ssize_t nr; if (bufsiz == 0) { errno = EINVAL; @@ -252,53 +232,17 @@ } cp = buf; - left = bufsiz; - - /* - * Timeout of <= 0 means no timeout. - */ - if (timeout > 0) { - /* Setup for select(2) */ - n = howmany(fd + 1, NFDBITS) * sizeof(fd_mask); - readfds = (fd_set *) emalloc(n); - (void) memset((VOID *)readfds, 0, n); - - /* Set timeout for select */ - tv.tv_sec = timeout; - tv.tv_usec = 0; - - while (--left) { - FD_SET(fd, readfds); - - /* Make sure there is something to read (or timeout) */ - while ((n = select(fd + 1, readfds, 0, 0, &tv)) == -1 && - errno == EAGAIN) - ; - if (n <= 0) { - free(readfds); - return(NULL); /* timeout or interrupt */ - } - - /* Read a character, exit loop on error, EOF or EOL */ - n = read(fd, &c, 1); - if (n != 1 || c == '\n' || c == '\r') - break; - *cp++ = c; - } - free(readfds); - } else { - /* Keep reading until out of space, EOF, error, or newline */ - n = -1; - while (--left && (n = read(fd, &c, 1)) == 1 && c != '\n' && c != '\r') - *cp++ = c; - } + nr = -1; + while (--bufsiz && (nr = read(fd, &c, 1)) == 1 && c != '\n' && c != '\r') + *cp++ = c; *cp = '\0'; - - return(n == -1 ? NULL : buf); + return(nr == -1 ? NULL : buf); } -static void handler(s) +static void +handler(s) int s; { - signo = s; + if (s != SIGALRM) + signo = s; }