]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
chfn, chsh: use readline(3) to receive user input
authorSami Kerola <kerolasa@iki.fi>
Sun, 23 Apr 2017 17:51:51 +0000 (18:51 +0100)
committerSami Kerola <kerolasa@iki.fi>
Tue, 2 May 2017 22:22:05 +0000 (23:22 +0100)
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 <kerolasa@iki.fi>
login-utils/Makemodule.am
login-utils/chfn.c
login-utils/chsh.c

index be07ace43f4fa4d0aff4bc75862c4a45cf271c61..f3397b9f48d427a511a542654d3339b67fa8b694 100644 (file)
@@ -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
index faddd89a78c370ef58311f967d318484740d729b..d79a192cfc719c8e9ce2c45ad487d651d7297f3f 100644 (file)
 # include "auth.h"
 #endif
 
+#ifdef HAVE_LIBREADLINE
+# define _FUNCTION_DEF
+# include <readline/readline.h>
+#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;
 }
 
 /*
index 979a287fe245de38650b1912c3b4d1c1afe4617d..1fb377593cf37e7a2b1de1b104afb7ffd25c2589 100644 (file)
 # include "auth.h"
 #endif
 
+#ifdef HAVE_LIBREADLINE
+# define _FUNCTION_DEF
+# include <readline/readline.h>
+#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);