blob: 3ad0e97cdd46b79e8f7a5242c109f0028176bb22 [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
Denis Vlasenkoe5387a02007-10-20 19:20:22 +000020char *bb_askpass(int timeout, const char *prompt)
Eric Andersen6f9a7782004-05-01 01:27:30 +000021{
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;
Denis Vlasenkoe5387a02007-10-20 19:20:22 +000028 struct sigaction sa, oldsa;
29 struct termios tio, oldtio;
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
Denis Vlasenkoe5387a02007-10-20 19:20:22 +000035 tcgetattr(STDIN_FILENO, &oldtio);
Rob Landleye422af62005-12-12 07:02:15 +000036 tcflush(STDIN_FILENO, TCIFLUSH);
Denis Vlasenkoe5387a02007-10-20 19:20:22 +000037 tio = oldtio;
38 tio.c_iflag &= ~(IUCLC|IXON|IXOFF|IXANY);
39 tio.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|TOSTOP);
40 tcsetattr(STDIN_FILENO, TCSANOW, &tio);
Eric Andersen6f9a7782004-05-01 01:27:30 +000041
Denis Vlasenkoe5387a02007-10-20 19:20:22 +000042 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);
Eric Andersen6f9a7782004-05-01 01:27:30 +000047 if (timeout) {
Denis Vlasenko8e2cfec2008-03-12 23:19:35 +000048 sigaction_set(SIGALRM, &sa);
Eric Andersen6f9a7782004-05-01 01:27:30 +000049 alarm(timeout);
50 }
51
Denis Vlasenkoe5387a02007-10-20 19:20:22 +000052 fputs(prompt, stdout);
53 fflush(stdout);
Denis Vlasenko6429aab2006-09-23 12:22:11 +000054 ret = NULL;
Denis Vlasenkoe5387a02007-10-20 19:20:22 +000055 /* On timeout or Ctrl-C, read will hopefully be interrupted,
Denis Vlasenko91e149a2007-06-18 10:35:06 +000056 * and we return NULL */
Denis Vlasenkoe5387a02007-10-20 19:20:22 +000057 if (read(STDIN_FILENO, passwd, sizeof_passwd - 1) > 0) {
Denis Vlasenko6429aab2006-09-23 12:22:11 +000058 ret = passwd;
59 i = 0;
60 /* Last byte is guaranteed to be 0
61 (read did not overwrite it) */
62 do {
63 if (passwd[i] == '\r' || passwd[i] == '\n')
Denis Vlasenkoab24e182006-11-30 16:41:15 +000064 passwd[i] = '\0';
Denis Vlasenko6429aab2006-09-23 12:22:11 +000065 } while (passwd[i++]);
Eric Andersen6f9a7782004-05-01 01:27:30 +000066 }
67
68 if (timeout) {
69 alarm(0);
70 }
Denis Vlasenko8e2cfec2008-03-12 23:19:35 +000071 sigaction_set(SIGINT, &oldsa);
Eric Andersen6f9a7782004-05-01 01:27:30 +000072
Denis Vlasenkoe5387a02007-10-20 19:20:22 +000073 tcsetattr(STDIN_FILENO, TCSANOW, &oldtio);
Denis Vlasenko4daad902007-09-27 10:20:47 +000074 bb_putchar('\n');
Eric Andersen6f9a7782004-05-01 01:27:30 +000075 fflush(stdout);
76 return ret;
77}