chiark / gitweb /
basic: fallback to the fstat if we don't have access to the /proc/self/fdinfo
[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)) {
46         _cleanup_free_ char *line = NULL;
47         const char *p;
48         int r;
49
50         assert(parse_item);
51
52         r = proc_cmdline(&line);
53         if (r < 0)
54                 return r;
55
56         p = line;
57         for (;;) {
58                 _cleanup_free_ char *word = NULL;
59                 char *value = NULL;
60
61                 r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX);
62                 if (r < 0)
63                         return r;
64                 if (r == 0)
65                         break;
66
67                 /* Filter out arguments that are intended only for the
68                  * initrd */
69                 if (!in_initrd() && startswith(word, "rd."))
70                         continue;
71
72                 value = strchr(word, '=');
73                 if (value)
74                         *(value++) = 0;
75
76                 r = parse_item(word, value);
77                 if (r < 0)
78                         return r;
79         }
80
81         return 0;
82 }
83
84 int get_proc_cmdline_key(const char *key, char **value) {
85         _cleanup_free_ char *line = NULL, *ret = NULL;
86         bool found = false;
87         const char *p;
88         int r;
89
90         assert(key);
91
92         r = proc_cmdline(&line);
93         if (r < 0)
94                 return r;
95
96         p = line;
97         for (;;) {
98                 _cleanup_free_ char *word = NULL;
99                 const char *e;
100
101                 r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX);
102                 if (r < 0)
103                         return r;
104                 if (r == 0)
105                         break;
106
107                 /* Filter out arguments that are intended only for the
108                  * initrd */
109                 if (!in_initrd() && startswith(word, "rd."))
110                         continue;
111
112                 if (value) {
113                         e = startswith(word, key);
114                         if (!e)
115                                 continue;
116
117                         r = free_and_strdup(&ret, e);
118                         if (r < 0)
119                                 return r;
120
121                         found = true;
122                 } else {
123                         if (streq(word, key))
124                                 found = true;
125                 }
126         }
127
128         if (value) {
129                 *value = ret;
130                 ret = NULL;
131         }
132
133         return found;
134
135 }
136
137 #if 0 /// UNNEEDED by elogind
138 int shall_restore_state(void) {
139         _cleanup_free_ char *value = NULL;
140         int r;
141
142         r = get_proc_cmdline_key("systemd.restore_state=", &value);
143         if (r < 0)
144                 return r;
145         if (r == 0)
146                 return true;
147
148         return parse_boolean(value);
149 }
150
151 static const char * const rlmap[] = {
152         "emergency", SPECIAL_EMERGENCY_TARGET,
153         "-b",        SPECIAL_EMERGENCY_TARGET,
154         "rescue",    SPECIAL_RESCUE_TARGET,
155         "single",    SPECIAL_RESCUE_TARGET,
156         "-s",        SPECIAL_RESCUE_TARGET,
157         "s",         SPECIAL_RESCUE_TARGET,
158         "S",         SPECIAL_RESCUE_TARGET,
159         "1",         SPECIAL_RESCUE_TARGET,
160         "2",         SPECIAL_MULTI_USER_TARGET,
161         "3",         SPECIAL_MULTI_USER_TARGET,
162         "4",         SPECIAL_MULTI_USER_TARGET,
163         "5",         SPECIAL_GRAPHICAL_TARGET,
164         NULL
165 };
166
167 static const char * const rlmap_initrd[] = {
168         "emergency", SPECIAL_EMERGENCY_TARGET,
169         "rescue",    SPECIAL_RESCUE_TARGET,
170         NULL
171 };
172
173 const char* runlevel_to_target(const char *word) {
174         size_t i;
175         const char * const *rlmap_ptr = in_initrd() ? rlmap_initrd
176                                                     : rlmap;
177
178         if (!word)
179                 return NULL;
180
181         if (in_initrd() && (word = startswith(word, "rd.")) == NULL)
182                 return NULL;
183
184         for (i = 0; rlmap_ptr[i] != NULL; i += 2)
185                 if (streq(word, rlmap_ptr[i]))
186                         return rlmap_ptr[i+1];
187
188         return NULL;
189 }
190 #endif // 0