blob: 5ad234921f822f482330e37cdf63d73d999495b2 [file] [log] [blame]
Eric Andersen6f9a7782004-05-01 01:27:30 +00001/* 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 *
Bernhard Reutner-Fischer20f40002006-01-30 17:17:14 +00008 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
Eric Andersen6f9a7782004-05-01 01:27:30 +00009 */
10
Eric Andersen6f9a7782004-05-01 01:27:30 +000011#include <termios.h>
Bernhard Reutner-Fischer20f40002006-01-30 17:17:14 +000012
13#include "libbb.h"
Eric Andersen6f9a7782004-05-01 01:27:30 +000014
15/* do nothing signal handler */
Bernhard Reutner-Fischer20f40002006-01-30 17:17:14 +000016static void askpass_timeout(int ATTRIBUTE_UNUSED ignore)
Eric Andersen6f9a7782004-05-01 01:27:30 +000017{
18}
19
20char *bb_askpass(int timeout, const char * prompt)
21{
Denis Vlasenko91e149a2007-06-18 10:35:06 +000022 /* Was static char[BIGNUM] */
23 enum { sizeof_passwd = 128 };
24 static char *passwd;
Denis Vlasenko6429aab2006-09-23 12:22:11 +000025
Eric Andersen6f9a7782004-05-01 01:27:30 +000026 char *ret;
Denis Vlasenko6429aab2006-09-23 12:22:11 +000027 int i;
Eric Andersen6f9a7782004-05-01 01:27:30 +000028 struct sigaction sa;
29 struct termios old, new;
Eric Andersen6f9a7782004-05-01 01:27:30 +000030
Denis Vlasenko91e149a2007-06-18 10:35:06 +000031 if (!passwd)
32 passwd = xmalloc(sizeof_passwd);
33 memset(passwd, 0, sizeof_passwd);
34
Eric Andersen6f9a7782004-05-01 01:27:30 +000035 tcgetattr(STDIN_FILENO, &old);
Rob Landleye422af62005-12-12 07:02:15 +000036 tcflush(STDIN_FILENO, TCIFLUSH);
Eric Andersen6f9a7782004-05-01 01:27:30 +000037
Eric Andersen6f9a7782004-05-01 01:27:30 +000038 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
Denis Vlasenko6429aab2006-09-23 12:22:11 +000053 ret = NULL;
Denis Vlasenko91e149a2007-06-18 10:35:06 +000054 /* On timeout, read will hopefully be interrupted by SIGALRM,
55 * and we return NULL */
56 if (read(STDIN_FILENO, passwd, sizeof_passwd-1) > 0) {
Denis Vlasenko6429aab2006-09-23 12:22:11 +000057 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')
Denis Vlasenkoab24e182006-11-30 16:41:15 +000063 passwd[i] = '\0';
Denis Vlasenko6429aab2006-09-23 12:22:11 +000064 } while (passwd[i++]);
Eric Andersen6f9a7782004-05-01 01:27:30 +000065 }
66
67 if (timeout) {
68 alarm(0);
69 }
70
71 tcsetattr(STDIN_FILENO, TCSANOW, &old);
Denis Vlasenko91e149a2007-06-18 10:35:06 +000072 putchar('\n');
Eric Andersen6f9a7782004-05-01 01:27:30 +000073 fflush(stdout);
74 return ret;
75}