libbb: switch bb_ask_noecho() to "mallocing" string return API
No binary (build failed)
—
(log yok)
| @@ -1408,10 +1408,11 @@ extern int set_loop(char **devname, const char *file, unsigned long long offset, | |
| #define BB_LO_FLAGS_READ_ONLY 1 | |
| #define BB_LO_FLAGS_AUTOCLEAR 4 | |
| - | /* Like bb_ask_noecho below, but asks on stdin with no timeout. */ |
| + | /* Returns malloced str */ |
| + | char *bb_ask_noecho(int fd, int timeout, const char *prompt) FAST_FUNC; |
| + | /* Like bb_ask_noecho, but asks on stdin with no timeout. */ |
| char *bb_ask_noecho_stdin(const char *prompt) FAST_FUNC; | |
| - | //TODO: pass buf pointer or return allocated buf (avoid statics)? |
| - | char *bb_ask_noecho(const int fd, int timeout, const char *prompt) FAST_FUNC; |
| + | |
| int bb_ask_y_confirmation_FILE(FILE *fp) FAST_FUNC; | |
| int bb_ask_y_confirmation(void) FAST_FUNC; | |
| @@ -13,16 +13,9 @@ static void askpass_timeout(int UNUSED_PARAM ignore) | |
| { | |
| } | |
| - | char* FAST_FUNC bb_ask_noecho_stdin(const char *prompt) |
| - | { |
| - | return bb_ask_noecho(STDIN_FILENO, 0, prompt); |
| - | } |
| - | char* FAST_FUNC bb_ask_noecho(const int fd, int timeout, const char *prompt) |
| + | char* FAST_FUNC bb_ask_noecho(int fd, int timeout, const char *prompt) |
| { | |
| - | /* Was static char[BIGNUM] */ |
| - | enum { sizeof_passwd = 128 }; |
| - | |
| - | char *passwd; |
| + | #define MAX_LINE 0xfff |
| char *ret; | |
| int i; | |
| struct sigaction sa, oldsa; | |
| @@ -37,7 +30,17 @@ char* FAST_FUNC bb_ask_noecho(const int fd, int timeout, const char *prompt) | |
| tcgetattr(fd, &oldtio); | |
| tio = oldtio; | |
| - | /* Switch off echo */ |
| + | /* Switch off echo. ECHOxyz meaning: |
| + | * ECHO echo input chars |
| + | * ECHOE echo BS-SP-BS on erase character |
| + | * ECHOK echo kill char specially, not as ^c (ECHOKE controls how exactly) |
| + | * ECHOKE erase all input via BS-SP-BS on kill char (else go to next line) |
| + | * ECHOCTL Echo ctrl chars as ^c (else echo verbatim: |
| + | * e.g. up arrow emits "ESC-something" and thus moves cursor up!) |
| + | * ECHONL Echo NL even if ECHO is not set |
| + | * ECHOPRT On erase, echo erased chars |
| + | * [qwe<BS><BS><BS> input looks like "qwe\ewq/" on screen] |
| + | */ |
| tio.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL); | |
| tcsetattr(fd, TCSANOW, &tio); | |
| @@ -51,20 +54,30 @@ char* FAST_FUNC bb_ask_noecho(const int fd, int timeout, const char *prompt) | |
| alarm(timeout); | |
| } | |
| - | passwd = auto_string(xmalloc(sizeof_passwd)); |
| - | ret = passwd; |
| + | ret = NULL; |
| i = 0; | |
| while (1) { | |
| - | int r = read(fd, &ret[i], 1); |
| + | int r; |
| + | |
| + | /* User input is uber-slow, no need to optimize reallocs. |
| + | * Grow it on every char. |
| + | */ |
| + | ret = xrealloc(ret, i + 2); |
| + | r = read(fd, &ret[i], 1); |
| + | |
| if ((i == 0 && r == 0) /* EOF (^D) with no password */ | |
| || r < 0 /* read is interrupted by timeout or ^C */ | |
| ) { | |
| + | ret[i] = '\0'; /* paranoia */ |
| + | nuke_str(ret); /* paranoia */ |
| + | free(ret); |
| ret = NULL; | |
| break; | |
| } | |
| + | |
| if (r == 0 /* EOF */ | |
| || ret[i] == '\r' || ret[i] == '\n' /* EOL */ | |
| - | || ++i == sizeof_passwd-1 /* line limit */ |
| + | || ++i == MAX_LINE /* line limit */ |
| ) { | |
| ret[i] = '\0'; | |
| break; | |
| @@ -80,3 +93,7 @@ char* FAST_FUNC bb_ask_noecho(const int fd, int timeout, const char *prompt) | |
| fflush_all(); | |
| return ret; | |
| } | |
| + | char* FAST_FUNC bb_ask_noecho_stdin(const char *prompt) |
| + | { |
| + | return bb_ask_noecho(STDIN_FILENO, 0, prompt); |
| + | } |
| @@ -133,7 +133,7 @@ int cryptpw_main(int argc UNUSED_PARAM, char **argv) | |
| if (!password) { | |
| /* Only mkpasswd, and only from tty, prompts. | |
| * Otherwise it is a plain read. */ | |
| - | password = (ENABLE_MKPASSWD && isatty(STDIN_FILENO) && applet_name[0] == 'm') |
| + | password = (ENABLE_MKPASSWD && applet_name[0] == 'm' && isatty(STDIN_FILENO)) |
| ? bb_ask_noecho_stdin("Password: ") | |
| : xmalloc_fgetline(stdin) | |
| ; | |
| @@ -65,11 +65,9 @@ static char* new_password(const struct passwd *pw, uid_t myuid, const char *algo | |
| if (ENABLE_FEATURE_CLEAN_UP) | |
| free(encrypted); | |
| } | |
| - | orig = xstrdup(orig); /* or else bb_ask_noecho_stdin() will destroy it */ |
| newp = bb_ask_noecho_stdin("New password: "); /* returns ptr to static */ | |
| if (!newp) | |
| goto err_ret; | |
| - | newp = xstrdup(newp); /* we are going to bb_ask_noecho_stdin() again, so save it */ |
| if (ENABLE_FEATURE_PASSWD_WEAK_CHECK | |
| && obscure(orig, newp, pw) | |
| && myuid != 0 | |
| @@ -99,6 +97,7 @@ static char* new_password(const struct passwd *pw, uid_t myuid, const char *algo | |
| if (ENABLE_FEATURE_CLEAN_UP) free(newp); | |
| nuke_str(cp); | |
| + | if (ENABLE_FEATURE_CLEAN_UP) free(cp); |
| return ret; | |
| } | |
| @@ -163,8 +163,8 @@ void FAST_FUNC encode_base64(char *fname, const char *text, const char *eol) | |
| void FAST_FUNC get_cred_or_die(int fd) | |
| { | |
| if (isatty(fd)) { | |
| - | G.user = xstrdup(bb_ask_noecho(fd, /* timeout: */ 0, "User: ")); |
| - | G.pass = xstrdup(bb_ask_noecho(fd, /* timeout: */ 0, "Password: ")); |
| + | G.user = bb_ask_noecho(fd, /* timeout: */ 0, "User: "); |
| + | G.pass = bb_ask_noecho(fd, /* timeout: */ 0, "Password: "); |
| } else { | |
| G.user = xmalloc_reads(fd, /* maxsize: */ NULL); | |
| G.pass = xmalloc_reads(fd, /* maxsize: */ NULL); | |