*: introduce and use ffulsh_all()
[platform/upstream/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 "libbb.h"
12
13 /* do nothing signal handler */
14 static void askpass_timeout(int UNUSED_PARAM ignore)
15 {
16 }
17
18 char* FAST_FUNC bb_ask_stdin(const char *prompt)
19 {
20         return bb_ask(STDIN_FILENO, 0, prompt);
21 }
22 char* FAST_FUNC bb_ask(const int fd, int timeout, const char *prompt)
23 {
24         /* Was static char[BIGNUM] */
25         enum { sizeof_passwd = 128 };
26         static char *passwd;
27
28         char *ret;
29         int i;
30         struct sigaction sa, oldsa;
31         struct termios tio, oldtio;
32
33         if (!passwd)
34                 passwd = xmalloc(sizeof_passwd);
35         memset(passwd, 0, sizeof_passwd);
36
37         tcgetattr(fd, &oldtio);
38         tcflush(fd, TCIFLUSH);
39         tio = oldtio;
40 #ifndef IUCLC
41 # define IUCLC 0
42 #endif
43         tio.c_iflag &= ~(IUCLC|IXON|IXOFF|IXANY);
44         tio.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|TOSTOP);
45         tcsetattr_stdin_TCSANOW(&tio);
46
47         memset(&sa, 0, sizeof(sa));
48         /* sa.sa_flags = 0; - no SA_RESTART! */
49         /* SIGINT and SIGALRM will interrupt read below */
50         sa.sa_handler = askpass_timeout;
51         sigaction(SIGINT, &sa, &oldsa);
52         if (timeout) {
53                 sigaction_set(SIGALRM, &sa);
54                 alarm(timeout);
55         }
56
57         fputs(prompt, stdout);
58         fflush_all();
59         ret = NULL;
60         /* On timeout or Ctrl-C, read will hopefully be interrupted,
61          * and we return NULL */
62         if (read(fd, passwd, sizeof_passwd - 1) > 0) {
63                 ret = passwd;
64                 i = 0;
65                 /* Last byte is guaranteed to be 0
66                    (read did not overwrite it) */
67                 do {
68                         if (passwd[i] == '\r' || passwd[i] == '\n')
69                                 passwd[i] = '\0';
70                 } while (passwd[i++]);
71         }
72
73         if (timeout) {
74                 alarm(0);
75         }
76         sigaction_set(SIGINT, &oldsa);
77
78         tcsetattr_stdin_TCSANOW(&oldtio);
79         bb_putchar('\n');
80         fflush_all();
81         return ret;
82 }