wget: use monotonic_sec instead of gettimeofday
[oweals/busybox.git] / libbb / bb_askpass.c
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 //#include <sys/ioctl.h>
13
14 #include "libbb.h"
15
16 /* do nothing signal handler */
17 static void askpass_timeout(int ATTRIBUTE_UNUSED ignore)
18 {
19 }
20
21 char *bb_askpass(int timeout, const char * prompt)
22 {
23         static char passwd[64];
24
25         char *ret;
26         int i;
27         struct sigaction sa;
28         struct termios old, new;
29
30         tcgetattr(STDIN_FILENO, &old);
31         tcflush(STDIN_FILENO, TCIFLUSH);
32
33         memset(passwd, 0, sizeof(passwd));
34
35         fputs(prompt, stdout);
36         fflush(stdout);
37
38         tcgetattr(STDIN_FILENO, &new);
39         new.c_iflag &= ~(IUCLC|IXON|IXOFF|IXANY);
40         new.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|TOSTOP);
41         tcsetattr(STDIN_FILENO, TCSANOW, &new);
42
43         if (timeout) {
44                 sa.sa_flags = 0;
45                 sa.sa_handler = askpass_timeout;
46                 sigaction(SIGALRM, &sa, NULL);
47                 alarm(timeout);
48         }
49
50         ret = NULL;
51         if (read(STDIN_FILENO, passwd, sizeof(passwd)-1) > 0) {
52                 ret = passwd;
53                 i = 0;
54                 /* Last byte is guaranteed to be 0
55                    (read did not overwrite it) */
56                 do {
57                         if (passwd[i] == '\r' || passwd[i] == '\n')
58                                 passwd[i] = '\0';
59                 } while (passwd[i++]);
60         }
61
62         if (timeout) {
63                 alarm(0);
64         }
65
66         tcsetattr(STDIN_FILENO, TCSANOW, &old);
67         puts("");
68         fflush(stdout);
69         return ret;
70 }