X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=libbb%2Fbb_askpass.c;h=3ad0e97cdd46b79e8f7a5242c109f0028176bb22;hb=e9b76e1f1e37f91ec9b30274594b7953f1afa6a2;hp=1ae1520d9bd9b85e4d28fe7811528868d2704547;hpb=6f9a7783ce2f3ffae28176f8bcfcd6b86c1b41b3;p=oweals%2Fbusybox.git diff --git a/libbb/bb_askpass.c b/libbb/bb_askpass.c index 1ae1520d9..3ad0e97cd 100644 --- a/libbb/bb_askpass.c +++ b/libbb/bb_askpass.c @@ -5,83 +5,73 @@ * * Copyright (C) 1999-2004 by Erik Andersen * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. */ -#include -#include -#include -#include -#include #include -#include -#define PWD_BUFFER_SIZE 256 +#include "libbb.h" /* do nothing signal handler */ -static void askpass_timeout(int ignore) +static void askpass_timeout(int ATTRIBUTE_UNUSED ignore) { } -char *bb_askpass(int timeout, const char * prompt) +char *bb_askpass(int timeout, const char *prompt) { - char *ret; - int i, size; - struct sigaction sa; - struct termios old, new; - static char passwd[PWD_BUFFER_SIZE]; + /* Was static char[BIGNUM] */ + enum { sizeof_passwd = 128 }; + static char *passwd; - tcgetattr(STDIN_FILENO, &old); - - size = sizeof(passwd); - ret = passwd; - memset(passwd, 0, size); + char *ret; + int i; + struct sigaction sa, oldsa; + struct termios tio, oldtio; - fputs(prompt, stdout); - fflush(stdout); + if (!passwd) + passwd = xmalloc(sizeof_passwd); + memset(passwd, 0, sizeof_passwd); - tcgetattr(STDIN_FILENO, &new); - new.c_iflag &= ~(IUCLC|IXON|IXOFF|IXANY); - new.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|TOSTOP); - tcsetattr(STDIN_FILENO, TCSANOW, &new); + tcgetattr(STDIN_FILENO, &oldtio); + tcflush(STDIN_FILENO, TCIFLUSH); + tio = oldtio; + tio.c_iflag &= ~(IUCLC|IXON|IXOFF|IXANY); + tio.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|TOSTOP); + tcsetattr(STDIN_FILENO, TCSANOW, &tio); + memset(&sa, 0, sizeof(sa)); + /* sa.sa_flags = 0; - no SA_RESTART! */ + /* SIGINT and SIGALRM will interrupt read below */ + sa.sa_handler = askpass_timeout; + sigaction(SIGINT, &sa, &oldsa); if (timeout) { - sa.sa_flags = 0; - sa.sa_handler = askpass_timeout; - sigaction(SIGALRM, &sa, NULL); + sigaction_set(SIGALRM, &sa); alarm(timeout); } - if (read(STDIN_FILENO, passwd, size-1) <= 0) { - ret = NULL; - } else { - for(i = 0; i < size && passwd[i]; i++) { - if (passwd[i]== '\r' || passwd[i] == '\n') { - passwd[i]= 0; - break; - } - } + fputs(prompt, stdout); + fflush(stdout); + ret = NULL; + /* On timeout or Ctrl-C, read will hopefully be interrupted, + * and we return NULL */ + if (read(STDIN_FILENO, passwd, sizeof_passwd - 1) > 0) { + ret = passwd; + i = 0; + /* Last byte is guaranteed to be 0 + (read did not overwrite it) */ + do { + if (passwd[i] == '\r' || passwd[i] == '\n') + passwd[i] = '\0'; + } while (passwd[i++]); } if (timeout) { alarm(0); } + sigaction_set(SIGINT, &oldsa); - tcsetattr(STDIN_FILENO, TCSANOW, &old); - fputs("\n", stdout); + tcsetattr(STDIN_FILENO, TCSANOW, &oldtio); + bb_putchar('\n'); fflush(stdout); return ret; } -