]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
agetty: move login argv initialization to utils.c
authorKarel Zak <kzak@redhat.com>
Thu, 14 May 2026 09:54:01 +0000 (11:54 +0200)
committerKarel Zak <kzak@redhat.com>
Thu, 14 May 2026 11:15:16 +0000 (13:15 +0200)
Introduce agetty_init_login_argv() that consolidates the login
command line setup: setting the program name, check_username(),
login_options_to_argv() with replace_u(), and the -h/-H/-f/--
flag logic.

Move LOGIN_ARGV_MAX to the shared header. The check_username(),
login_options_to_argv() and replace_u() helpers become static
in utils.c.

Signed-off-by: Karel Zak <kzak@redhat.com>
agetty-cmd/agetty.c
agetty-cmd/agetty.h
agetty-cmd/utils.c

index 78670f74cf0400dc92336b2f4eb964a662bfeb50..766fa3e2054515300aabe8b4fa49a21eba3d8254 100644 (file)
@@ -93,8 +93,6 @@
 /* Login prompt. */
 #define LOGIN_PROMPT           "login: "
 
-/* Numbers of args for login(1) */
-#define LOGIN_ARGV_MAX 16
 
 #ifdef AGETTY_RELOAD
 # include <sys/inotify.h>
@@ -114,8 +112,6 @@ static void usage(void) __attribute__((__noreturn__));
 #ifdef KDGKBLED
 static ssize_t append(char *dest, size_t len, const char  *sep, const char *src);
 #endif
-static void check_username (const char* nm);
-static void login_options_to_argv(char *argv[], int *argc, char *str, char *username);
 
 
 /* Fake hostname for ut_host specified on command line. */
@@ -181,8 +177,6 @@ int main(int argc, char **argv)
        /* Parse command-line arguments. */
        parse_args(argc, argv, &options);
 
-       login_argv[login_argc++] = options.login;       /* set login program name */
-
        /* Update the utmp file. */
 #ifdef SYSV_STYLE
        agetty_update_utmp(&options, fakehost);
@@ -302,33 +296,7 @@ int main(int argc, char **argv)
        sigaction(SIGQUIT, &sa_quit, NULL);
        sigaction(SIGINT, &sa_int, NULL);
 
-       if (options.username)
-               check_username(options.username);
-
-       if (options.logopt) {
-               /*
-                * The --login-options completely overwrites the default
-                * way how agetty composes login(1) command line.
-                */
-               login_options_to_argv(login_argv, &login_argc,
-                                     options.logopt, options.username);
-       } else {
-               if (options.flags & F_REMOTE) {
-                       if (fakehost) {
-                               login_argv[login_argc++] = "-h";
-                               login_argv[login_argc++] = fakehost;
-                       } else if (options.flags & F_NOHOSTNAME)
-                               login_argv[login_argc++] = "-H";
-               }
-               if (options.username) {
-                       if (options.autolog)
-                               login_argv[login_argc++] = "-f";
-                       login_argv[login_argc++] = "--";
-                       login_argv[login_argc++] = options.username;
-               }
-       }
-
-       login_argv[login_argc] = NULL;  /* last login argv */
+       agetty_init_login_argv(login_argv, &login_argc, &options, fakehost);
 
        if (options.chroot) {
                if (chroot(options.chroot) < 0)
@@ -359,83 +327,6 @@ int main(int argc, char **argv)
        agetty_log_err(_("%s: can't exec %s: %m"), options.tty, login_argv[0]);
 }
 
-/*
- * Returns : @str if \u not found
- *         : @username if @str equal to "\u"
- *         : newly allocated string if \u mixed with something other
- */
-static char *replace_u(char *str, char *username)
-{
-       char *entry = NULL, *p = str;
-       size_t usz = username ? strlen(username) : 0;
-
-       while (*p) {
-               size_t sz;
-               char *tp, *old = entry;
-
-               if (memcmp(p, "\\u", 2) != 0) {
-                       p++;
-                       continue;       /* no \u */
-               }
-               sz = strlen(str);
-
-               if (p == str && sz == 2) {
-                       /* 'str' contains only '\u' */
-                       free(old);
-                       return username;
-               }
-
-               tp = entry = malloc(sz + usz);
-               if (!tp)
-                       agetty_log_err(_("failed to allocate memory: %m"));
-
-               if (p != str)
-                       /* copy chars before \u */
-                       tp = mempcpy(tp, str, p - str);
-               if (usz)
-                       /* copy username */
-                       tp = mempcpy(tp, username, usz);
-
-               if (*(p + 2))
-                       /* copy chars after \u + \0 */
-                       memcpy(tp, p + 2, sz - (p - str) - 1);
-               else
-                       *tp = '\0';
-
-               p = tp;
-               str = entry;
-               free(old);
-       }
-
-       return entry ? entry : str;
-}
-
-static void login_options_to_argv(char *argv[], int *argc,
-                                 char *str, char *username)
-{
-       char *p;
-       int i = *argc;
-
-       while (str && isspace(*str))
-               str++;
-       p = str;
-
-       while (p && *p && i < LOGIN_ARGV_MAX) {
-               if (isspace(*p)) {
-                       *p = '\0';
-                       while (isspace(*++p))
-                               ;
-                       if (*p) {
-                               argv[i++] = replace_u(str, username);
-                               str = p;
-                       }
-               } else
-                       p++;
-       }
-       if (str && *str && i < LOGIN_ARGV_MAX)
-               argv[i++] = replace_u(str, username);
-       *argc = i;
-}
 
 static void output_version(void)
 {
@@ -1246,24 +1137,3 @@ static ssize_t append(char *dest, size_t len, const char  *sep, const char *src)
 }
 #endif /* KDGKBLED */
 
-/*
- * Do not allow the user to pass an option as a user name
- * To be more safe: Use `--' to make sure the rest is
- * interpreted as non-options by the program, if it supports it.
- */
-static void check_username(const char* nm)
-{
-       const char *p = nm;
-       if (!nm)
-               goto err;
-       if (strlen(nm) > 42)
-               goto err;
-       while (isspace(*p))
-               p++;
-       if (*p == '-')
-               goto err;
-       return;
-err:
-       errno = EPERM;
-       agetty_log_err(_("checkname failed: %m"));
-}
index c9c328cb92e15f45f936bd494e3651936185677f..386c28a91da9dc75cfb0217a6b3dc70531bde8ca 100644 (file)
@@ -50,6 +50,9 @@ struct agetty_issue {
        bool do_tcrestore;
 };
 
+/* Numbers of args for login(1) */
+#define LOGIN_ARGV_MAX 16
+
 /* Storage for command-line options. */
 #define        MAX_SPEED       10      /* max. nr. of baud rates */
 
@@ -115,6 +118,8 @@ extern char *agetty_xgetdomainname(void);
 extern void agetty_update_utmp(struct agetty_options *op, const char *fakehost);
 extern void agetty_parse_speeds(struct agetty_options *op, char *arg);
 extern char *agetty_parse_initstring(const char *arg);
+extern void agetty_init_login_argv(char *argv[], int *argc,
+                                  struct agetty_options *op, const char *fakehost);
 
 enum {
        CLOCAL_MODE_AUTO = 0,
index 0344e9a1ee079d633d331a2816d943b078679e82..2fd5087d9d13f00675e71686f4d224d4598a3da5 100644 (file)
@@ -208,3 +208,119 @@ char *agetty_parse_initstring(const char *arg)
        *q = '\0';
        return str;
 }
+
+static char *replace_u(char *str, char *username)
+{
+       char *entry = NULL, *p = str;
+       size_t usz = username ? strlen(username) : 0;
+
+       while (*p) {
+               size_t sz;
+               char *tp, *old = entry;
+
+               if (memcmp(p, "\\u", 2) != 0) {
+                       p++;
+                       continue;
+               }
+               sz = strlen(str);
+
+               if (p == str && sz == 2) {
+                       free(old);
+                       return username;
+               }
+
+               tp = entry = malloc(sz + usz);
+               if (!tp)
+                       agetty_log_err(_("failed to allocate memory: %m"));
+
+               if (p != str)
+                       tp = mempcpy(tp, str, p - str);
+               if (usz)
+                       tp = mempcpy(tp, username, usz);
+
+               if (*(p + 2))
+                       memcpy(tp, p + 2, sz - (p - str) - 1);
+               else
+                       *tp = '\0';
+
+               p = tp;
+               str = entry;
+               free(old);
+       }
+
+       return entry ? entry : str;
+}
+
+static void login_options_to_argv(char *argv[], int *argc,
+                                 char *str, char *username)
+{
+       char *p;
+       int i = *argc;
+
+       while (str && isspace(*str))
+               str++;
+       p = str;
+
+       while (p && *p && i < LOGIN_ARGV_MAX) {
+               if (isspace(*p)) {
+                       *p = '\0';
+                       while (isspace(*++p))
+                               ;
+                       if (*p) {
+                               argv[i++] = replace_u(str, username);
+                               str = p;
+                       }
+               } else
+                       p++;
+       }
+       if (str && *str && i < LOGIN_ARGV_MAX)
+               argv[i++] = replace_u(str, username);
+       *argc = i;
+}
+
+static void check_username(const char *nm)
+{
+       const char *p = nm;
+       if (!nm)
+               goto err;
+       if (strlen(nm) > 42)
+               goto err;
+       while (isspace(*p))
+               p++;
+       if (*p == '-')
+               goto err;
+       return;
+err:
+       errno = EPERM;
+       agetty_log_err(_("checkname failed: %m"));
+}
+
+void agetty_init_login_argv(char *argv[], int *argc,
+                           struct agetty_options *op, const char *fakehost)
+{
+       *argc = 0;
+       argv[(*argc)++] = op->login;
+
+       if (op->username)
+               check_username(op->username);
+
+       if (op->logopt) {
+               login_options_to_argv(argv, argc, op->logopt, op->username);
+       } else {
+               if (op->flags & F_REMOTE) {
+                       if (fakehost) {
+                               argv[(*argc)++] = "-h";
+                               argv[(*argc)++] = (char *) fakehost;
+                       } else if (op->flags & F_NOHOSTNAME)
+                               argv[(*argc)++] = "-H";
+               }
+               if (op->username) {
+                       if (op->autolog)
+                               argv[(*argc)++] = "-f";
+                       argv[(*argc)++] = "--";
+                       argv[(*argc)++] = op->username;
+               }
+       }
+
+       argv[*argc] = NULL;
+}