1/* vi: set sw=4 ts=4: */ 2/* 3 * Ask for a password 4 * I use a static buffer in this function. Plan accordingly. 5 * 6 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> 7 * 8 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 9 */ 10 11#include <termios.h> 12 13#include "libbb.h" 14 15/* do nothing signal handler */ 16static void askpass_timeout(int ATTRIBUTE_UNUSED ignore) 17{ 18} 19 20char *bb_askpass(int timeout, const char * prompt) 21{ 22 /* Was static char[BIGNUM] */ 23 enum { sizeof_passwd = 128 }; 24 static char *passwd; 25 26 char *ret; 27 int i; 28 struct sigaction sa; 29 struct termios old, new; 30 31 if (!passwd) 32 passwd = xmalloc(sizeof_passwd); 33 memset(passwd, 0, sizeof_passwd); 34 35 tcgetattr(STDIN_FILENO, &old); 36 tcflush(STDIN_FILENO, TCIFLUSH); 37 38 fputs(prompt, stdout); 39 fflush(stdout); 40 41 tcgetattr(STDIN_FILENO, &new); 42 new.c_iflag &= ~(IUCLC|IXON|IXOFF|IXANY); 43 new.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|TOSTOP); 44 tcsetattr(STDIN_FILENO, TCSANOW, &new); 45 46 if (timeout) { 47 sa.sa_flags = 0; 48 sa.sa_handler = askpass_timeout; 49 sigaction(SIGALRM, &sa, NULL); 50 alarm(timeout); 51 } 52 53 ret = NULL; 54 /* On timeout, read will hopefully be interrupted by SIGALRM, 55 * and we return NULL */ 56 if (read(STDIN_FILENO, passwd, sizeof_passwd-1) > 0) { 57 ret = passwd; 58 i = 0; 59 /* Last byte is guaranteed to be 0 60 (read did not overwrite it) */ 61 do { 62 if (passwd[i] == '\r' || passwd[i] == '\n') 63 passwd[i] = '\0'; 64 } while (passwd[i++]); 65 } 66 67 if (timeout) { 68 alarm(0); 69 } 70 71 tcsetattr(STDIN_FILENO, TCSANOW, &old); 72 putchar('\n'); 73 fflush(stdout); 74 return ret; 75} 76