summaryrefslogtreecommitdiff
path: root/src/libsystemd-basic/src/proc-cmdline.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsystemd-basic/src/proc-cmdline.c')
-rw-r--r--src/libsystemd-basic/src/proc-cmdline.c188
1 files changed, 188 insertions, 0 deletions
diff --git a/src/libsystemd-basic/src/proc-cmdline.c b/src/libsystemd-basic/src/proc-cmdline.c
new file mode 100644
index 0000000000..9f8e923e28
--- /dev/null
+++ b/src/libsystemd-basic/src/proc-cmdline.c
@@ -0,0 +1,188 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <string.h>
+
+#include "systemd-basic/alloc-util.h"
+#include "systemd-basic/extract-word.h"
+#include "systemd-basic/fileio.h"
+#include "systemd-basic/macro.h"
+#include "systemd-basic/parse-util.h"
+#include "systemd-basic/proc-cmdline.h"
+#include "systemd-basic/process-util.h"
+#include "systemd-basic/special.h"
+#include "systemd-basic/string-util.h"
+#include "systemd-basic/util.h"
+#include "systemd-basic/virt.h"
+
+int proc_cmdline(char **ret) {
+ assert(ret);
+
+ if (detect_container() > 0)
+ return get_process_cmdline(1, 0, false, ret);
+ else
+ return read_one_line_file("/proc/cmdline", ret);
+}
+
+int parse_proc_cmdline(int (*parse_item)(const char *key, const char *value)) {
+ _cleanup_free_ char *line = NULL;
+ const char *p;
+ int r;
+
+ assert(parse_item);
+
+ r = proc_cmdline(&line);
+ if (r < 0)
+ return r;
+
+ p = line;
+ for (;;) {
+ _cleanup_free_ char *word = NULL;
+ char *value = NULL;
+
+ r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ break;
+
+ /* Filter out arguments that are intended only for the
+ * initrd */
+ if (!in_initrd() && startswith(word, "rd."))
+ continue;
+
+ value = strchr(word, '=');
+ if (value)
+ *(value++) = 0;
+
+ r = parse_item(word, value);
+ if (r < 0)
+ return r;
+ }
+
+ return 0;
+}
+
+int get_proc_cmdline_key(const char *key, char **value) {
+ _cleanup_free_ char *line = NULL, *ret = NULL;
+ bool found = false;
+ const char *p;
+ int r;
+
+ assert(key);
+
+ r = proc_cmdline(&line);
+ if (r < 0)
+ return r;
+
+ p = line;
+ for (;;) {
+ _cleanup_free_ char *word = NULL;
+ const char *e;
+
+ r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ break;
+
+ /* Filter out arguments that are intended only for the
+ * initrd */
+ if (!in_initrd() && startswith(word, "rd."))
+ continue;
+
+ if (value) {
+ e = startswith(word, key);
+ if (!e)
+ continue;
+
+ r = free_and_strdup(&ret, e);
+ if (r < 0)
+ return r;
+
+ found = true;
+ } else {
+ if (streq(word, key))
+ found = true;
+ }
+ }
+
+ if (value) {
+ *value = ret;
+ ret = NULL;
+ }
+
+ return found;
+
+}
+
+int shall_restore_state(void) {
+ _cleanup_free_ char *value = NULL;
+ int r;
+
+ r = get_proc_cmdline_key("systemd.restore_state=", &value);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return true;
+
+ return parse_boolean(value);
+}
+
+static const char * const rlmap[] = {
+ "emergency", SPECIAL_EMERGENCY_TARGET,
+ "-b", SPECIAL_EMERGENCY_TARGET,
+ "rescue", SPECIAL_RESCUE_TARGET,
+ "single", SPECIAL_RESCUE_TARGET,
+ "-s", SPECIAL_RESCUE_TARGET,
+ "s", SPECIAL_RESCUE_TARGET,
+ "S", SPECIAL_RESCUE_TARGET,
+ "1", SPECIAL_RESCUE_TARGET,
+ "2", SPECIAL_MULTI_USER_TARGET,
+ "3", SPECIAL_MULTI_USER_TARGET,
+ "4", SPECIAL_MULTI_USER_TARGET,
+ "5", SPECIAL_GRAPHICAL_TARGET,
+ NULL
+};
+
+static const char * const rlmap_initrd[] = {
+ "emergency", SPECIAL_EMERGENCY_TARGET,
+ "rescue", SPECIAL_RESCUE_TARGET,
+ NULL
+};
+
+const char* runlevel_to_target(const char *word) {
+ size_t i;
+ const char * const *rlmap_ptr = in_initrd() ? rlmap_initrd
+ : rlmap;
+
+ if (!word)
+ return NULL;
+
+ if (in_initrd() && (word = startswith(word, "rd.")) == NULL)
+ return NULL;
+
+ for (i = 0; rlmap_ptr[i] != NULL; i += 2)
+ if (streq(word, rlmap_ptr[i]))
+ return rlmap_ptr[i+1];
+
+ return NULL;
+}