chiark / gitweb /
core: introduce parse_ip_port (#4825)
[elogind.git] / src / basic / proc-cmdline.c
1 /***
2   This file is part of systemd.
3
4   Copyright 2010 Lennart Poettering
5
6   systemd is free software; you can redistribute it and/or modify it
7   under the terms of the GNU Lesser General Public License as published by
8   the Free Software Foundation; either version 2.1 of the License, or
9   (at your option) any later version.
10
11   systemd is distributed in the hope that it will be useful, but
12   WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14   Lesser General Public License for more details.
15
16   You should have received a copy of the GNU Lesser General Public License
17   along with systemd; If not, see <http://www.gnu.org/licenses/>.
18 ***/
19
20 #include <stdbool.h>
21 #include <stddef.h>
22 #include <string.h>
23
24 #include "alloc-util.h"
25 #include "extract-word.h"
26 #include "fileio.h"
27 #include "macro.h"
28 #include "parse-util.h"
29 #include "proc-cmdline.h"
30 #include "process-util.h"
31 //#include "special.h"
32 #include "string-util.h"
33 #include "util.h"
34 #include "virt.h"
35
36 int proc_cmdline(char **ret) {
37         assert(ret);
38
39         if (detect_container() > 0)
40                 return get_process_cmdline(1, 0, false, ret);
41         else
42                 return read_one_line_file("/proc/cmdline", ret);
43 }
44
45 int parse_proc_cmdline(int (*parse_item)(const char *key, const char *value, void *data),
46                        void *data,
47                        bool strip_prefix) {
48         _cleanup_free_ char *line = NULL;
49         const char *p;
50         int r;
51
52         assert(parse_item);
53
54         r = proc_cmdline(&line);
55         if (r < 0)
56                 return r;
57
58         p = line;
59         for (;;) {
60                 _cleanup_free_ char *word = NULL;
61                 char *value = NULL, *unprefixed;
62
63                 r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX);
64                 if (r < 0)
65                         return r;
66                 if (r == 0)
67                         break;
68
69                 /* Filter out arguments that are intended only for the
70                  * initrd */
71                 unprefixed = startswith(word, "rd.");
72                 if (unprefixed && !in_initrd())
73                         continue;
74
75                 value = strchr(word, '=');
76                 if (value)
77                         *(value++) = 0;
78
79                 r = parse_item(strip_prefix && unprefixed ? unprefixed : word, value, data);
80                 if (r < 0)
81                         return r;
82         }
83
84         return 0;
85 }
86
87 int get_proc_cmdline_key(const char *key, char **value) {
88         _cleanup_free_ char *line = NULL, *ret = NULL;
89         bool found = false;
90         const char *p;
91         int r;
92
93         assert(key);
94
95         r = proc_cmdline(&line);
96         if (r < 0)
97                 return r;
98
99         p = line;
100         for (;;) {
101                 _cleanup_free_ char *word = NULL;
102                 const char *e;
103
104                 r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX);
105                 if (r < 0)
106                         return r;
107                 if (r == 0)
108                         break;
109
110                 /* Filter out arguments that are intended only for the
111                  * initrd */
112                 if (!in_initrd() && startswith(word, "rd."))
113                         continue;
114
115                 if (value) {
116                         e = startswith(word, key);
117                         if (!e)
118                                 continue;
119
120                         r = free_and_strdup(&ret, e);
121                         if (r < 0)
122                                 return r;
123
124                         found = true;
125                 } else {
126                         if (streq(word, key))
127                                 found = true;
128                 }
129         }
130
131         if (value) {
132                 *value = ret;
133                 ret = NULL;
134         }
135
136         return found;
137
138 }
139
140 #if 0 /// UNNEEDED by elogind
141 int shall_restore_state(void) {
142         _cleanup_free_ char *value = NULL;
143         int r;
144
145         r = get_proc_cmdline_key("systemd.restore_state=", &value);
146         if (r < 0)
147                 return r;
148         if (r == 0)
149                 return true;
150
151         return parse_boolean(value);
152 }
153
154 static const char * const rlmap[] = {
155         "emergency", SPECIAL_EMERGENCY_TARGET,
156         "-b",        SPECIAL_EMERGENCY_TARGET,
157         "rescue",    SPECIAL_RESCUE_TARGET,
158         "single",    SPECIAL_RESCUE_TARGET,
159         "-s",        SPECIAL_RESCUE_TARGET,
160         "s",         SPECIAL_RESCUE_TARGET,
161         "S",         SPECIAL_RESCUE_TARGET,
162         "1",         SPECIAL_RESCUE_TARGET,
163         "2",         SPECIAL_MULTI_USER_TARGET,
164         "3",         SPECIAL_MULTI_USER_TARGET,
165         "4",         SPECIAL_MULTI_USER_TARGET,
166         "5",         SPECIAL_GRAPHICAL_TARGET,
167         NULL
168 };
169
170 static const char * const rlmap_initrd[] = {
171         "emergency", SPECIAL_EMERGENCY_TARGET,
172         "rescue",    SPECIAL_RESCUE_TARGET,
173         NULL
174 };
175
176 const char* runlevel_to_target(const char *word) {
177         size_t i;
178         const char * const *rlmap_ptr = in_initrd() ? rlmap_initrd
179                                                     : rlmap;
180
181         if (!word)
182                 return NULL;
183
184         if (in_initrd() && (word = startswith(word, "rd.")) == NULL)
185                 return NULL;
186
187         for (i = 0; rlmap_ptr[i] != NULL; i += 2)
188                 if (streq(word, rlmap_ptr[i]))
189                         return rlmap_ptr[i+1];
190
191         return NULL;
192 }
193 #endif // 0