1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
26 #include <sys/statvfs.h>
29 #include "systemd/sd-id128.h"
31 #include "condition-util.h"
33 #include "path-util.h"
36 #include "architecture.h"
38 Condition* condition_new(ConditionType type, const char *parameter, bool trigger, bool negate) {
41 assert(type < _CONDITION_TYPE_MAX);
43 c = new0(Condition, 1);
52 c->parameter = strdup(parameter);
62 void condition_free(Condition *c) {
69 void condition_free_list(Condition *first) {
72 LIST_FOREACH_SAFE(conditions, c, n, first)
76 bool condition_test_kernel_command_line(Condition *c) {
77 char *line, *word = NULL;
78 const char *w, *state;
86 assert(c->type == CONDITION_KERNEL_COMMAND_LINE);
88 r = proc_cmdline(&line);
90 log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
94 equal = !!strchr(c->parameter, '=');
95 pl = strlen(c->parameter);
97 FOREACH_WORD_QUOTED(w, l, line, state) {
100 word = strndup(w, l);
105 if (streq(word, c->parameter)) {
110 if (startswith(word, c->parameter) && (word[pl] == '=' || word[pl] == 0)) {
118 log_warning("Trailing garbage and the end of kernel commandline, ignoring.");
123 return found == !c->negate;
126 bool condition_test_virtualization(Condition *c) {
131 assert(c->parameter);
132 assert(c->type == CONDITION_VIRTUALIZATION);
134 v = detect_virtualization(&id);
136 log_warning("Failed to detect virtualization, ignoring: %s", strerror(-v));
140 /* First, compare with yes/no */
141 b = parse_boolean(c->parameter);
146 if (v == 0 && b == 0)
149 /* Then, compare categorization */
150 if (v == VIRTUALIZATION_VM && streq(c->parameter, "vm"))
153 if (v == VIRTUALIZATION_CONTAINER && streq(c->parameter, "container"))
156 /* Finally compare id */
157 return (v > 0 && streq(c->parameter, id)) == !c->negate;
160 bool condition_test_architecture(Condition *c) {
164 assert(c->parameter);
165 assert(c->type == CONDITION_ARCHITECTURE);
167 a = uname_architecture();
171 if (streq(c->parameter, "native"))
172 b = native_architecture();
174 b = architecture_from_string(c->parameter);
179 return (a == b) == !c->negate;
182 bool condition_test_host(Condition *c) {
183 _cleanup_free_ char *h = NULL;
188 assert(c->parameter);
189 assert(c->type == CONDITION_HOST);
191 if (sd_id128_from_string(c->parameter, &x) >= 0) {
193 r = sd_id128_get_machine(&y);
197 return sd_id128_equal(x, y) == !c->negate;
200 h = gethostname_malloc();
204 return (fnmatch(c->parameter, h, FNM_CASEFOLD) == 0) == !c->negate;
207 bool condition_test_ac_power(Condition *c) {
211 assert(c->parameter);
212 assert(c->type == CONDITION_AC_POWER);
214 r = parse_boolean(c->parameter);
218 return ((on_ac_power() != 0) == !!r) == !c->negate;
221 void condition_dump(Condition *c, FILE *f, const char *prefix) {
229 "%s\t%s: %s%s%s %s\n",
231 condition_type_to_string(c->type),
232 c->trigger ? "|" : "",
233 c->negate ? "!" : "",
235 c->state < 0 ? "failed" : c->state > 0 ? "succeeded" : "untested");
238 void condition_dump_list(Condition *first, FILE *f, const char *prefix) {
241 LIST_FOREACH(conditions, c, first)
242 condition_dump(c, f, prefix);
245 static const char* const condition_type_table[_CONDITION_TYPE_MAX] = {
246 [CONDITION_PATH_EXISTS] = "ConditionPathExists",
247 [CONDITION_PATH_EXISTS_GLOB] = "ConditionPathExistsGlob",
248 [CONDITION_PATH_IS_DIRECTORY] = "ConditionPathIsDirectory",
249 [CONDITION_PATH_IS_SYMBOLIC_LINK] = "ConditionPathIsSymbolicLink",
250 [CONDITION_PATH_IS_MOUNT_POINT] = "ConditionPathIsMountPoint",
251 [CONDITION_PATH_IS_READ_WRITE] = "ConditionPathIsReadWrite",
252 [CONDITION_DIRECTORY_NOT_EMPTY] = "ConditionDirectoryNotEmpty",
253 [CONDITION_FILE_NOT_EMPTY] = "ConditionFileNotEmpty",
254 [CONDITION_FILE_IS_EXECUTABLE] = "ConditionFileIsExecutable",
255 [CONDITION_KERNEL_COMMAND_LINE] = "ConditionKernelCommandLine",
256 [CONDITION_VIRTUALIZATION] = "ConditionVirtualization",
257 [CONDITION_SECURITY] = "ConditionSecurity",
258 [CONDITION_CAPABILITY] = "ConditionCapability",
259 [CONDITION_HOST] = "ConditionHost",
260 [CONDITION_AC_POWER] = "ConditionACPower",
261 [CONDITION_ARCHITECTURE] = "ConditionArchitecture",
262 [CONDITION_NEEDS_UPDATE] = "ConditionNeedsUpdate",
263 [CONDITION_FIRST_BOOT] = "ConditionFirstBoot",
264 [CONDITION_NULL] = "ConditionNull"
267 DEFINE_STRING_TABLE_LOOKUP(condition_type, ConditionType);