From: Sami Kerola Date: Sun, 23 Apr 2017 17:51:51 +0000 (+0100) Subject: chfn, chsh: use readline(3) to receive user input X-Git-Tag: v2.30-rc1~28^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e41ae450937e51d6016ba6a43f0559efdc09f4e2;p=thirdparty%2Futil-linux.git chfn, chsh: use readline(3) to receive user input The readline offers editing capabilities while the user is entering the line, unlike fgets(3) and getline(3) that were used earlier. Signed-off-by: Sami Kerola --- diff --git a/login-utils/Makemodule.am b/login-utils/Makemodule.am index be07ace43f..f3397b9f48 100644 --- a/login-utils/Makemodule.am +++ b/login-utils/Makemodule.am @@ -82,7 +82,7 @@ chfn_chsh_sources = \ login-utils/ch-common.c chfn_chsh_cflags = $(SUID_CFLAGS) $(AM_CFLAGS) chfn_chsh_ldflags = $(SUID_LDFLAGS) $(AM_LDFLAGS) -chfn_chsh_ldadd = libcommon.la +chfn_chsh_ldadd = libcommon.la $(READLINE_LIBS) if CHFN_CHSH_PASSWORD chfn_chsh_ldadd += -lpam diff --git a/login-utils/chfn.c b/login-utils/chfn.c index faddd89a78..d79a192cfc 100644 --- a/login-utils/chfn.c +++ b/login-utils/chfn.c @@ -56,6 +56,11 @@ # include "auth.h" #endif +#ifdef HAVE_LIBREADLINE +# define _FUNCTION_DEF +# include +#endif + struct finfo { char *full_name; char *office; @@ -221,31 +226,39 @@ static char *ask_new_field(struct chfn_control *ctl, const char *question, char *def_val) { int len; - char *ans; - char buf[MAX_FIELD_SIZE + 2]; + char *buf; +#ifndef HAVE_LIBREADLINE + size_t dummy = 0; +#endif if (!def_val) def_val = ""; while (true) { printf("%s [%s]: ", question, def_val); __fpurge(stdin); - if (fgets(buf, sizeof(buf), stdin) == NULL) +#ifdef HAVE_LIBREADLINE + if ((buf = readline(NULL)) == NULL) +#else + if (getline(&buf, &dummy, stdin) < 0) +#endif errx(EXIT_FAILURE, _("Aborted.")); - ans = buf; /* remove white spaces from string end */ - ltrim_whitespace((unsigned char *) ans); - len = rtrim_whitespace((unsigned char *) ans); - if (len == 0) + ltrim_whitespace((unsigned char *) buf); + len = rtrim_whitespace((unsigned char *) buf); + if (len == 0) { + free(buf); return xstrdup(def_val); - if (!strcasecmp(ans, "none")) { + } + if (!strcasecmp(buf, "none")) { + free(buf); ctl->changed = 1; return xstrdup(""); } - if (check_gecos_string(question, ans) >= 0) + if (check_gecos_string(question, buf) >= 0) break; } ctl->changed = 1; - return xstrdup(ans); + return buf; } /* diff --git a/login-utils/chsh.c b/login-utils/chsh.c index 979a287fe2..1fb377593c 100644 --- a/login-utils/chsh.c +++ b/login-utils/chsh.c @@ -57,6 +57,11 @@ # include "auth.h" #endif +#ifdef HAVE_LIBREADLINE +# define _FUNCTION_DEF +# include +#endif + struct sinfo { char *username; char *shell; @@ -173,14 +178,18 @@ static char *ask_new_shell(char *question, char *oldshell) { int len; char *ans = NULL; +#ifndef HAVE_LIBREADLINE size_t dummy = 0; - ssize_t sz; +#endif if (!oldshell) oldshell = ""; printf("%s [%s]: ", question, oldshell); - sz = getline(&ans, &dummy, stdin); - if (sz == -1) +#ifdef HAVE_LIBREADLINE + if ((ans = readline(NULL)) == NULL) +#else + if (getline(&ans, &dummy, stdin) < 0) +#endif return NULL; /* remove the newline at the end of ans. */ ltrim_whitespace((unsigned char *) ans);