From 13d95b10dd15974a74f645e99f99d934544afe37 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Thu, 4 Oct 2018 12:47:52 +0200
Subject: [PATCH 2/5] libply: Move kernel commandline parsing functions to
 libply/ply-utils

Move kernel commandline parsing functions to libply/ply-utils to avoid
code duplication between the daemon, the client and the plugins.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 src/client/plymouth.c  |  34 +---------
 src/libply/ply-utils.c |  94 ++++++++++++++++++++++++++++
 src/libply/ply-utils.h |   4 ++
 src/main.c             | 137 ++++++-----------------------------------
 4 files changed, 120 insertions(+), 149 deletions(-)

diff --git a/src/client/plymouth.c b/src/client/plymouth.c
index 46a64f5..4e14603 100644
--- a/src/client/plymouth.c
+++ b/src/client/plymouth.c
@@ -49,7 +49,6 @@ typedef struct
         ply_event_loop_t     *loop;
         ply_boot_client_t    *client;
         ply_command_parser_t *command_parser;
-        char                  kernel_command_line[PLY_MAX_COMMAND_LINE_SIZE];
 } state_t;
 
 typedef struct
@@ -704,31 +703,6 @@ on_quit_request (state_t    *state,
                                              on_failure, state);
 }
 
-static bool
-get_kernel_command_line (state_t *state)
-{
-        int fd;
-
-        ply_trace ("opening /proc/cmdline");
-        fd = open ("/proc/cmdline", O_RDONLY);
-
-        if (fd < 0) {
-                ply_trace ("couldn't open it: %m");
-                return false;
-        }
-
-        ply_trace ("reading kernel command line");
-        if (read (fd, state->kernel_command_line, sizeof(state->kernel_command_line) - 1) < 0) {
-                ply_trace ("couldn't read it: %m");
-                close (fd);
-                return false;
-        }
-
-        ply_trace ("Kernel command line is: '%s'", state->kernel_command_line);
-        close (fd);
-        return true;
-}
-
 static void
 on_update_root_fs_request (state_t    *state,
                            const char *command)
@@ -1099,12 +1073,8 @@ main (int    argc,
                 return 0;
         }
 
-        if (get_kernel_command_line (&state)) {
-                if ((strstr (state.kernel_command_line, "plymouth.debug") != NULL ||
-                     strstr (state.kernel_command_line, "plymouth:debug") != NULL)
-                    && !ply_is_tracing ())
-                        ply_toggle_tracing ();
-        }
+        if (ply_kernel_cmd_line_has_argument ("plymouth.debug") && !ply_is_tracing ())
+                ply_toggle_tracing ();
 
         if (should_be_verbose && !ply_is_tracing ())
                 ply_toggle_tracing ();
diff --git a/src/libply/ply-utils.c b/src/libply/ply-utils.c
index 89e37e9..1f7f07c 100644
--- a/src/libply/ply-utils.c
+++ b/src/libply/ply-utils.c
@@ -24,6 +24,7 @@
 #include "ply-utils.h"
 
 #include <assert.h>
+#include <ctype.h>
 #include <dirent.h>
 #include <errno.h>
 #include <fcntl.h>
@@ -80,6 +81,9 @@ static int errno_stack_position = 0;
 
 static int overridden_device_scale = 0;
 
+static char kernel_command_line[PLY_MAX_COMMAND_LINE_SIZE];
+static bool kernel_command_line_is_set;
+
 bool
 ply_open_unidirectional_pipe (int *sender_fd,
                               int *receiver_fd)
@@ -1015,4 +1019,94 @@ ply_get_device_scale (uint32_t width,
         return device_scale;
 }
 
+static const char *
+ply_get_kernel_command_line (void)
+{
+        const char *remaining_command_line;
+        char *key;
+        int fd;
+
+        if (kernel_command_line_is_set)
+                return kernel_command_line;
+
+        ply_trace ("opening /proc/cmdline");
+        fd = open ("/proc/cmdline", O_RDONLY);
+
+        if (fd < 0) {
+                ply_trace ("couldn't open it: %m");
+                return NULL;
+        }
+
+        ply_trace ("reading kernel command line");
+        if (read (fd, kernel_command_line, sizeof(kernel_command_line) - 1) < 0) {
+                ply_trace ("couldn't read it: %m");
+                close (fd);
+                return NULL;
+        }
+
+        /* we now use plymouth.argument for kernel commandline arguments.
+         * It used to be plymouth:argument. This bit just rewrites all : to be .
+         */
+        remaining_command_line = kernel_command_line;
+        while ((key = strstr (remaining_command_line, "plymouth:")) != NULL) {
+                char *colon;
+
+                colon = key + strlen ("plymouth");
+                *colon = '.';
+
+                remaining_command_line = colon + 1;
+        }
+        ply_trace ("Kernel command line is: '%s'", kernel_command_line);
+
+        close (fd);
+
+        kernel_command_line_is_set = true;
+        return kernel_command_line;
+}
+
+const char *
+ply_kernel_cmd_line_get_string_after_prefix (const char *prefix)
+{
+        const char *command_line = ply_get_kernel_command_line();
+        char *argument;
+
+        if (!command_line)
+                return NULL;
+
+        argument = strstr (command_line, prefix);
+
+        if (argument == NULL)
+                return NULL;
+
+        if (argument == command_line ||
+            argument[-1] == ' ')
+                return argument + strlen (prefix);
+
+        return NULL;
+}
+
+bool
+ply_kernel_cmd_line_has_argument (const char *argument)
+{
+        const char *string;
+
+        string = ply_kernel_cmd_line_get_string_after_prefix (argument);
+
+        if (string == NULL)
+                return false;
+
+        if (!isspace ((int) string[0]) && string[0] != '\0')
+                return false;
+
+        return true;
+}
+
+void
+ply_kernel_cmd_line_set (const char *cmd_line)
+{
+        strncpy (kernel_command_line, cmd_line, sizeof(kernel_command_line));
+        kernel_command_line[sizeof(kernel_command_line) - 1] = '\0';
+        kernel_command_line_is_set = true;
+}
+
 /* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */
diff --git a/src/libply/ply-utils.h b/src/libply/ply-utils.h
index c46603e..6016484 100644
--- a/src/libply/ply-utils.h
+++ b/src/libply/ply-utils.h
@@ -128,6 +128,10 @@ int ply_get_device_scale (uint32_t width,
                           uint32_t width_mm,
                           uint32_t height_mm);
 
+const char *ply_kernel_cmd_line_get_string_after_prefix (const char *prefix);
+bool ply_kernel_cmd_line_has_argument (const char *argument);
+void ply_kernel_cmd_line_set (const char *cmd_line);
+
 #endif
 
 #endif /* PLY_UTILS_H */
diff --git a/src/main.c b/src/main.c
index 0564e15..61d94c1 100644
--- a/src/main.c
+++ b/src/main.c
@@ -24,7 +24,6 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <math.h>
-#include <ctype.h>
 #include <limits.h>
 #include <dirent.h>
 #include <fcntl.h>
@@ -56,10 +55,6 @@
 #include "ply-utils.h"
 #include "ply-progress.h"
 
-#ifndef PLY_MAX_COMMAND_LINE_SIZE
-#define PLY_MAX_COMMAND_LINE_SIZE 4097
-#endif
-
 #define BOOT_DURATION_FILE     PLYMOUTH_TIME_DIRECTORY "/boot-duration"
 #define SHUTDOWN_DURATION_FILE PLYMOUTH_TIME_DIRECTORY "/shutdown-duration"
 
@@ -109,8 +104,6 @@ typedef struct
         double                  splash_delay;
         double                  device_timeout;
 
-        char                    kernel_command_line[PLY_MAX_COMMAND_LINE_SIZE];
-        uint32_t                kernel_command_line_is_set : 1;
         uint32_t                no_boot_log : 1;
         uint32_t                showing_details : 1;
         uint32_t                system_initialized : 1;
@@ -381,41 +374,6 @@ show_detailed_splash (state_t *state)
         update_display (state);
 }
 
-static const char *
-command_line_get_string_after_prefix (const char *command_line,
-                                      const char *prefix)
-{
-        char *argument;
-
-        argument = strstr (command_line, prefix);
-
-        if (argument == NULL)
-                return NULL;
-
-        if (argument == command_line ||
-            argument[-1] == ' ')
-                return argument + strlen (prefix);
-
-        return NULL;
-}
-
-static bool
-command_line_has_argument (const char *command_line,
-                           const char *argument)
-{
-        const char *string;
-
-        string = command_line_get_string_after_prefix (command_line, argument);
-
-        if (string == NULL)
-                return false;
-
-        if (!isspace ((int) string[0]) && string[0] != '\0')
-                return false;
-
-        return true;
-}
-
 static void
 find_override_splash (state_t *state)
 {
@@ -424,8 +382,7 @@ find_override_splash (state_t *state)
         if (state->override_splash_path != NULL)
                 return;
 
-        splash_string = command_line_get_string_after_prefix (state->kernel_command_line,
-                                                              "plymouth.splash=");
+        splash_string = ply_kernel_cmd_line_get_string_after_prefix ("plymouth.splash=");
 
         if (splash_string != NULL) {
                 const char *end;
@@ -452,7 +409,7 @@ find_override_splash (state_t *state)
         if (isnan (state->splash_delay)) {
                 const char *delay_string;
 
-                delay_string = command_line_get_string_after_prefix (state->kernel_command_line, "plymouth.splash-delay=");
+                delay_string = ply_kernel_cmd_line_get_string_after_prefix ("plymouth.splash-delay=");
 
                 if (delay_string != NULL)
                         state->splash_delay = atof (delay_string);
@@ -464,7 +421,7 @@ find_force_scale (state_t *state)
 {
         const char *scale_string;
 
-        scale_string = command_line_get_string_after_prefix (state->kernel_command_line, "plymouth.force-scale=");
+        scale_string = ply_kernel_cmd_line_get_string_after_prefix ("plymouth.force-scale=");
 
         if (scale_string != NULL)
                 ply_set_device_scale (strtoul (scale_string, NULL, 0));
@@ -879,10 +836,10 @@ static bool
 plymouth_should_ignore_show_splash_calls (state_t *state)
 {
         ply_trace ("checking if plymouth should be running");
-        if (state->mode != PLY_MODE_BOOT || command_line_has_argument (state->kernel_command_line, "plymouth.force-splash"))
+        if (state->mode != PLY_MODE_BOOT || ply_kernel_cmd_line_has_argument ("plymouth.force-splash"))
                 return false;
 
-        if (command_line_has_argument (state->kernel_command_line, "plymouth.ignore-show-splash"))
+        if (ply_kernel_cmd_line_has_argument ("plymouth.ignore-show-splash"))
                 return true;
 
         return false;
@@ -894,7 +851,7 @@ sh_is_init (state_t *state)
         const char *init_string;
         size_t length;
 
-        init_string = command_line_get_string_after_prefix (state->kernel_command_line, "init=");
+        init_string = ply_kernel_cmd_line_get_string_after_prefix ("init=");
 
         if (init_string) {
                 length = strcspn (init_string, " \n");
@@ -919,28 +876,28 @@ plymouth_should_show_default_splash (state_t *state)
                 return false;
 
         for (i = 0; strings[i] != NULL; i++) {
-                if (command_line_has_argument (state->kernel_command_line, strings[i])) {
+                if (ply_kernel_cmd_line_has_argument (strings[i])) {
                         ply_trace ("no default splash because kernel command line has option \"%s\"", strings[i]);
                         return false;
                 }
         }
 
-        if (command_line_has_argument (state->kernel_command_line, "splash=verbose")) {
+        if (ply_kernel_cmd_line_has_argument ("splash=verbose")) {
                 ply_trace ("no default splash because kernel command line has option \"splash=verbose\"");
                 return false;
         }
 
-        if (command_line_has_argument (state->kernel_command_line, "rhgb")) {
+        if (ply_kernel_cmd_line_has_argument ("rhgb")) {
                 ply_trace ("using default splash because kernel command line has option \"rhgb\"");
                 return true;
         }
 
-        if (command_line_has_argument (state->kernel_command_line, "splash")) {
+        if (ply_kernel_cmd_line_has_argument ("splash")) {
                 ply_trace ("using default splash because kernel command line has option \"splash\"");
                 return true;
         }
 
-        if (command_line_has_argument (state->kernel_command_line, "splash=silent")) {
+        if (ply_kernel_cmd_line_has_argument ("splash=silent")) {
                 ply_trace ("using default splash because kernel command line has option \"splash=silent\"");
                 return true;
         }
@@ -1279,7 +1236,7 @@ deactivate_console (state_t *state)
         }
 
         /* do not let any tty opened where we could write after deactivate */
-        if (command_line_has_argument (state->kernel_command_line, "plymouth.debug"))
+        if (ply_kernel_cmd_line_has_argument ("plymouth.debug"))
                 ply_logger_close_file (ply_logger_get_error_default ());
 
 }
@@ -1872,52 +1829,6 @@ detach_from_running_session (state_t *state)
         state->is_attached = false;
 }
 
-static bool
-get_kernel_command_line (state_t *state)
-{
-        int fd;
-        const char *remaining_command_line;
-        char *key;
-
-        if (state->kernel_command_line_is_set)
-                return true;
-
-        ply_trace ("opening /proc/cmdline");
-        fd = open ("/proc/cmdline", O_RDONLY);
-
-        if (fd < 0) {
-                ply_trace ("couldn't open it: %m");
-                return false;
-        }
-
-        ply_trace ("reading kernel command line");
-        if (read (fd, state->kernel_command_line, sizeof(state->kernel_command_line) - 1) < 0) {
-                ply_trace ("couldn't read it: %m");
-                close (fd);
-                return false;
-        }
-
-
-        /* we now use plymouth.argument for kernel commandline arguments.
-         * It used to be plymouth:argument. This bit just rewrites all : to be .
-         */
-        remaining_command_line = state->kernel_command_line;
-        while ((key = strstr (remaining_command_line, "plymouth:")) != NULL) {
-                char *colon;
-
-                colon = key + strlen ("plymouth");
-                *colon = '.';
-
-                remaining_command_line = colon + 1;
-        }
-        ply_trace ("Kernel command line is: '%s'", state->kernel_command_line);
-
-        close (fd);
-
-        state->kernel_command_line_is_set = true;
-        return true;
-}
-
 static void
 check_verbosity (state_t *state)
 {
@@ -1926,13 +1837,11 @@ check_verbosity (state_t *state)
 
         ply_trace ("checking if tracing should be enabled");
 
-        stream = command_line_get_string_after_prefix (state->kernel_command_line,
-                                                       "plymouth.debug=stream:");
+        stream = ply_kernel_cmd_line_get_string_after_prefix ("plymouth.debug=stream:");
 
-        path = command_line_get_string_after_prefix (state->kernel_command_line,
-                                                     "plymouth.debug=file:");
+        path = ply_kernel_cmd_line_get_string_after_prefix ("plymouth.debug=file:");
         if (stream != NULL || path != NULL ||
-            command_line_has_argument (state->kernel_command_line, "plymouth.debug")) {
+            ply_kernel_cmd_line_has_argument ("plymouth.debug")) {
                 int fd;
 
                 ply_trace ("tracing should be enabled!");
@@ -2010,7 +1919,7 @@ check_logging (state_t *state)
 
         ply_trace ("checking if console messages should be redirected and logged");
 
-        kernel_no_log = command_line_has_argument (state->kernel_command_line, "plymouth.nolog");
+        kernel_no_log = ply_kernel_cmd_line_has_argument ("plymouth.nolog");
         if (kernel_no_log)
                 state->no_boot_log = true;
 
@@ -2064,9 +1973,6 @@ initialize_environment (state_t *state)
 {
         ply_trace ("initializing minimal work environment");
 
-        if (!get_kernel_command_line (state))
-                return false;
-
         if (!state->default_tty)
                 if (getenv ("DISPLAY") != NULL && access (PLYMOUTH_PLUGIN_PATH "renderers/x11.so", F_OK) == 0)
                         state->default_tty = "/dev/tty";
@@ -2279,11 +2185,8 @@ main (int    argc,
         if (tty != NULL)
                 state.default_tty = tty;
 
-        if (kernel_command_line != NULL) {
-                strncpy (state.kernel_command_line, kernel_command_line, sizeof(state.kernel_command_line));
-                state.kernel_command_line[sizeof(state.kernel_command_line) - 1] = '\0';
-                state.kernel_command_line_is_set = true;
-        }
+        if (kernel_command_line != NULL)
+                ply_kernel_cmd_line_set (kernel_command_line);
 
         if (geteuid () != 0) {
                 ply_error ("plymouthd must be run as root user");
@@ -2375,10 +2278,10 @@ main (int    argc,
         find_system_default_splash (&state);
         find_distribution_default_splash (&state);
 
-        if (command_line_has_argument (state.kernel_command_line, "plymouth.ignore-serial-consoles"))
+        if (ply_kernel_cmd_line_has_argument ("plymouth.ignore-serial-consoles"))
                 device_manager_flags |= PLY_DEVICE_MANAGER_FLAGS_IGNORE_SERIAL_CONSOLES;
 
-        if (command_line_has_argument (state.kernel_command_line, "plymouth.ignore-udev") ||
+        if (ply_kernel_cmd_line_has_argument ("plymouth.ignore-udev") ||
             (getenv ("DISPLAY") != NULL))
                 device_manager_flags |= PLY_DEVICE_MANAGER_FLAGS_IGNORE_UDEV;
 
-- 
2.19.0

