8 |
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details. |
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details. |
9 |
*/ |
*/ |
10 |
|
|
|
#include <stdio.h> |
|
|
#include <string.h> |
|
|
#include <unistd.h> |
|
|
#include <fcntl.h> |
|
|
#include <signal.h> |
|
11 |
#include <termios.h> |
#include <termios.h> |
|
#include <sys/ioctl.h> |
|
12 |
|
|
13 |
#include "libbb.h" |
#include "libbb.h" |
14 |
|
|
15 |
/* do nothing signal handler */ |
/* do nothing signal handler */ |
16 |
static void askpass_timeout(int ATTRIBUTE_UNUSED ignore) |
static void askpass_timeout(int UNUSED_PARAM ignore) |
17 |
{ |
{ |
18 |
} |
} |
19 |
|
|
20 |
char *bb_askpass(int timeout, const char * prompt) |
char* FAST_FUNC bb_askpass(int timeout, const char *prompt) |
21 |
{ |
{ |
22 |
static char passwd[64]; |
/* Was static char[BIGNUM] */ |
23 |
|
enum { sizeof_passwd = 128 }; |
24 |
|
static char *passwd; |
25 |
|
|
26 |
char *ret; |
char *ret; |
27 |
int i; |
int i; |
28 |
struct sigaction sa; |
struct sigaction sa, oldsa; |
29 |
struct termios old, new; |
struct termios tio, oldtio; |
30 |
|
|
31 |
tcgetattr(STDIN_FILENO, &old); |
if (!passwd) |
32 |
tcflush(STDIN_FILENO, TCIFLUSH); |
passwd = xmalloc(sizeof_passwd); |
33 |
|
memset(passwd, 0, sizeof_passwd); |
|
memset(passwd, 0, sizeof(passwd)); |
|
|
|
|
|
fputs(prompt, stdout); |
|
|
fflush(stdout); |
|
|
|
|
|
tcgetattr(STDIN_FILENO, &new); |
|
|
new.c_iflag &= ~(IUCLC|IXON|IXOFF|IXANY); |
|
|
new.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|TOSTOP); |
|
|
tcsetattr(STDIN_FILENO, TCSANOW, &new); |
|
34 |
|
|
35 |
|
tcgetattr(STDIN_FILENO, &oldtio); |
36 |
|
tcflush(STDIN_FILENO, TCIFLUSH); |
37 |
|
tio = oldtio; |
38 |
|
tio.c_iflag &= ~(IUCLC|IXON|IXOFF|IXANY); |
39 |
|
tio.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|TOSTOP); |
40 |
|
tcsetattr_stdin_TCSANOW(&tio); |
41 |
|
|
42 |
|
memset(&sa, 0, sizeof(sa)); |
43 |
|
/* sa.sa_flags = 0; - no SA_RESTART! */ |
44 |
|
/* SIGINT and SIGALRM will interrupt read below */ |
45 |
|
sa.sa_handler = askpass_timeout; |
46 |
|
sigaction(SIGINT, &sa, &oldsa); |
47 |
if (timeout) { |
if (timeout) { |
48 |
sa.sa_flags = 0; |
sigaction_set(SIGALRM, &sa); |
|
sa.sa_handler = askpass_timeout; |
|
|
sigaction(SIGALRM, &sa, NULL); |
|
49 |
alarm(timeout); |
alarm(timeout); |
50 |
} |
} |
51 |
|
|
52 |
|
fputs(prompt, stdout); |
53 |
|
fflush(stdout); |
54 |
ret = NULL; |
ret = NULL; |
55 |
if (read(STDIN_FILENO, passwd, sizeof(passwd)-1) > 0) { |
/* On timeout or Ctrl-C, read will hopefully be interrupted, |
56 |
|
* and we return NULL */ |
57 |
|
if (read(STDIN_FILENO, passwd, sizeof_passwd - 1) > 0) { |
58 |
ret = passwd; |
ret = passwd; |
59 |
i = 0; |
i = 0; |
60 |
/* Last byte is guaranteed to be 0 |
/* Last byte is guaranteed to be 0 |
68 |
if (timeout) { |
if (timeout) { |
69 |
alarm(0); |
alarm(0); |
70 |
} |
} |
71 |
|
sigaction_set(SIGINT, &oldsa); |
72 |
|
|
73 |
tcsetattr(STDIN_FILENO, TCSANOW, &old); |
tcsetattr_stdin_TCSANOW(&oldtio); |
74 |
puts(""); |
bb_putchar('\n'); |
75 |
fflush(stdout); |
fflush(stdout); |
76 |
return ret; |
return ret; |
77 |
} |
} |