4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering/***
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering This file is part of systemd.
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering Copyright 2010 Lennart Poettering
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering systemd is free software; you can redistribute it and/or modify it
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering under the terms of the GNU Lesser General Public License as published by
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering (at your option) any later version.
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering systemd is distributed in the hope that it will be useful, but
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering Lesser General Public License for more details.
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering You should have received a copy of the GNU Lesser General Public License
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering***/
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering
11c3a36649e5e5e77db499c92f3cdcbd619efd3aThomas Hindoe Paaboel Andersen#include <stdbool.h>
11c3a36649e5e5e77db499c92f3cdcbd619efd3aThomas Hindoe Paaboel Andersen#include <stddef.h>
11c3a36649e5e5e77db499c92f3cdcbd619efd3aThomas Hindoe Paaboel Andersen#include <string.h>
11c3a36649e5e5e77db499c92f3cdcbd619efd3aThomas Hindoe Paaboel Andersen
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering#include "alloc-util.h"
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering#include "extract-word.h"
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering#include "fileio.h"
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering#include "macro.h"
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering#include "parse-util.h"
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering#include "proc-cmdline.h"
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering#include "process-util.h"
c573dcfeb1abd390cd4c4288056df97752ef18f0Evgeny Vereshchagin#include "special.h"
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering#include "string-util.h"
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering#include "util.h"
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering#include "virt.h"
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poetteringint proc_cmdline(char **ret) {
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering assert(ret);
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering if (detect_container() > 0)
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering return get_process_cmdline(1, 0, false, ret);
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering else
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering return read_one_line_file("/proc/cmdline", ret);
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering}
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poetteringint parse_proc_cmdline(int (*parse_item)(const char *key, const char *value)) {
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering _cleanup_free_ char *line = NULL;
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering const char *p;
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering int r;
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering assert(parse_item);
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering r = proc_cmdline(&line);
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering if (r < 0)
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering return r;
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering p = line;
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering for (;;) {
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering _cleanup_free_ char *word = NULL;
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering char *value = NULL;
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX);
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering if (r < 0)
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering return r;
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering if (r == 0)
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering break;
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering /* Filter out arguments that are intended only for the
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering * initrd */
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering if (!in_initrd() && startswith(word, "rd."))
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering continue;
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering value = strchr(word, '=');
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering if (value)
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering *(value++) = 0;
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering r = parse_item(word, value);
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering if (r < 0)
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering return r;
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering }
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering return 0;
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering}
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poetteringint get_proc_cmdline_key(const char *key, char **value) {
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering _cleanup_free_ char *line = NULL, *ret = NULL;
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering bool found = false;
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering const char *p;
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering int r;
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering assert(key);
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering r = proc_cmdline(&line);
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering if (r < 0)
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering return r;
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering p = line;
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering for (;;) {
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering _cleanup_free_ char *word = NULL;
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering const char *e;
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX);
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering if (r < 0)
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering return r;
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering if (r == 0)
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering break;
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering /* Filter out arguments that are intended only for the
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering * initrd */
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering if (!in_initrd() && startswith(word, "rd."))
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering continue;
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering if (value) {
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering e = startswith(word, key);
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering if (!e)
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering continue;
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering r = free_and_strdup(&ret, e);
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering if (r < 0)
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering return r;
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering found = true;
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering } else {
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering if (streq(word, key))
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering found = true;
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering }
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering }
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering if (value) {
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering *value = ret;
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering ret = NULL;
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering }
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering return found;
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering}
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poetteringint shall_restore_state(void) {
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering _cleanup_free_ char *value = NULL;
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering int r;
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering r = get_proc_cmdline_key("systemd.restore_state=", &value);
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering if (r < 0)
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering return r;
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering if (r == 0)
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering return true;
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering
934ae16baf543af03f3f521277d14524ca772d17Lennart Poettering return parse_boolean(value);
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering}
c573dcfeb1abd390cd4c4288056df97752ef18f0Evgeny Vereshchagin
c573dcfeb1abd390cd4c4288056df97752ef18f0Evgeny Vereshchaginstatic const char * const rlmap[] = {
c573dcfeb1abd390cd4c4288056df97752ef18f0Evgeny Vereshchagin "emergency", SPECIAL_EMERGENCY_TARGET,
c573dcfeb1abd390cd4c4288056df97752ef18f0Evgeny Vereshchagin "-b", SPECIAL_EMERGENCY_TARGET,
c573dcfeb1abd390cd4c4288056df97752ef18f0Evgeny Vereshchagin "rescue", SPECIAL_RESCUE_TARGET,
c573dcfeb1abd390cd4c4288056df97752ef18f0Evgeny Vereshchagin "single", SPECIAL_RESCUE_TARGET,
c573dcfeb1abd390cd4c4288056df97752ef18f0Evgeny Vereshchagin "-s", SPECIAL_RESCUE_TARGET,
c573dcfeb1abd390cd4c4288056df97752ef18f0Evgeny Vereshchagin "s", SPECIAL_RESCUE_TARGET,
c573dcfeb1abd390cd4c4288056df97752ef18f0Evgeny Vereshchagin "S", SPECIAL_RESCUE_TARGET,
c573dcfeb1abd390cd4c4288056df97752ef18f0Evgeny Vereshchagin "1", SPECIAL_RESCUE_TARGET,
c573dcfeb1abd390cd4c4288056df97752ef18f0Evgeny Vereshchagin "2", SPECIAL_MULTI_USER_TARGET,
c573dcfeb1abd390cd4c4288056df97752ef18f0Evgeny Vereshchagin "3", SPECIAL_MULTI_USER_TARGET,
c573dcfeb1abd390cd4c4288056df97752ef18f0Evgeny Vereshchagin "4", SPECIAL_MULTI_USER_TARGET,
c573dcfeb1abd390cd4c4288056df97752ef18f0Evgeny Vereshchagin "5", SPECIAL_GRAPHICAL_TARGET,
c573dcfeb1abd390cd4c4288056df97752ef18f0Evgeny Vereshchagin};
c573dcfeb1abd390cd4c4288056df97752ef18f0Evgeny Vereshchagin
c573dcfeb1abd390cd4c4288056df97752ef18f0Evgeny Vereshchaginconst char* runlevel_to_target(const char *word) {
c573dcfeb1abd390cd4c4288056df97752ef18f0Evgeny Vereshchagin size_t i;
c573dcfeb1abd390cd4c4288056df97752ef18f0Evgeny Vereshchagin
c573dcfeb1abd390cd4c4288056df97752ef18f0Evgeny Vereshchagin if (!word)
c573dcfeb1abd390cd4c4288056df97752ef18f0Evgeny Vereshchagin return NULL;
c573dcfeb1abd390cd4c4288056df97752ef18f0Evgeny Vereshchagin
c573dcfeb1abd390cd4c4288056df97752ef18f0Evgeny Vereshchagin for (i = 0; i < ELEMENTSOF(rlmap); i += 2)
c573dcfeb1abd390cd4c4288056df97752ef18f0Evgeny Vereshchagin if (streq(word, rlmap[i]))
c573dcfeb1abd390cd4c4288056df97752ef18f0Evgeny Vereshchagin return rlmap[i+1];
c573dcfeb1abd390cd4c4288056df97752ef18f0Evgeny Vereshchagin
c573dcfeb1abd390cd4c4288056df97752ef18f0Evgeny Vereshchagin return NULL;
c573dcfeb1abd390cd4c4288056df97752ef18f0Evgeny Vereshchagin}