Allow selecting headless action via tizen.recovery key in kernel command line 19/153019/6
authorKarol Lewandowski <k.lewandowsk@samsung.com>
Fri, 29 Sep 2017 07:54:55 +0000 (09:54 +0200)
committerKarol Lewandowski <k.lewandowsk@samsung.com>
Fri, 29 Sep 2017 10:32:23 +0000 (12:32 +0200)
Change-Id: I6035a4ab1e99fbce64881bd6fe943355a67d5352

src/system-recovery/recovery-main.c

index 4d105515cf1f547c95e86164de33356d14bcd0ac..8e12dd0716de28897f28a6bbed5fc8a4f93ef93d 100644 (file)
 #include <stdbool.h>
 #include <libconfig.h>
 #include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
 
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/reboot.h>
 
+#include <asm-generic/setup.h> // for COMMAND_LINE_SIZE
+
 #include <vconf/vconf-keys.h>
 
 #include "rui.h"
@@ -43,6 +47,9 @@
 
 bool volatile running = true;
 
+#define KERNEL_CMDLINE_KEY "tizen.recovery"
+
+
 void sys_power_reboot(void)
 {
        reboot(RB_AUTOBOOT);
@@ -88,21 +95,67 @@ void run_factory_reset(void)
 }
 
 #ifndef RECOVERY_GUI
-static int run_default(config_t *cfg)
+static char *get_action_from_config(config_t *cfg)
 {
        config_setting_t *node;
-       const char *action, *handler;
+       const char *action;
 
        node = config_lookup(cfg, "headless_action");
        if (!node)
-               return -ENOENT;
+               return NULL;
 
        action = config_setting_get_string(node);
+
+       return strdup(action);
+}
+
+// looks for tizen.recovery= key in kernel command line
+static char *get_action_from_cmdline(void)
+{
+       FILE *fp;
+       char cmdline[COMMAND_LINE_SIZE];
+       int len;
+
+       fp = fopen("/proc/cmdline", "r");
+       if (!fp)
+               return NULL;
+
+       char *p = fgets(cmdline, sizeof cmdline, fp);
+       fclose(fp);
+       if (!p)
+               return NULL;
+
+       const char *prefix = KERNEL_CMDLINE_KEY "=";
+       p = strstr(cmdline, prefix);
+       if (!p)
+               return NULL;
+       p += strlen(prefix);
+
+       for (len = 0; *(p + len) != 0 && !isspace(*(p + len)); ++len)
+               ; /* skip */
+
+       return strndup(p, len);
+}
+
+static int run_default(config_t *cfg)
+{
+       config_setting_t *node;
+       const char *action, *handler;
+
        node = config_lookup(cfg, "action_handlers");
        if (!node)
                return -ENOENT;
 
-       if (config_setting_lookup_string(node, action, &handler) == CONFIG_FALSE)
+       action = get_action_from_cmdline();
+       if (!action)
+               action = get_action_from_config(cfg);
+       if (!action)
+               return -ENOENT;
+
+       int r = config_setting_lookup_string(node, action, &handler);
+       free(action);
+
+       if (r == CONFIG_FALSE)
                return -ENOENT;
 
        return system(handler);