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, *w, *state, *word = NULL;
85 assert(c->type == CONDITION_KERNEL_COMMAND_LINE);
87 r = proc_cmdline(&line);
89 log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
93 equal = !!strchr(c->parameter, '=');
94 pl = strlen(c->parameter);
96 FOREACH_WORD_QUOTED(w, l, line, state) {
104 if (streq(word, c->parameter)) {
109 if (startswith(word, c->parameter) && (word[pl] == '=' || word[pl] == 0)) {
120 return found == !c->negate;
123 bool condition_test_virtualization(Condition *c) {
128 assert(c->parameter);
129 assert(c->type == CONDITION_VIRTUALIZATION);
131 v = detect_virtualization(&id);
133 log_warning("Failed to detect virtualization, ignoring: %s", strerror(-v));
137 /* First, compare with yes/no */
138 b = parse_boolean(c->parameter);
143 if (v == 0 && b == 0)
146 /* Then, compare categorization */
147 if (v == VIRTUALIZATION_VM && streq(c->parameter, "vm"))
150 if (v == VIRTUALIZATION_CONTAINER && streq(c->parameter, "container"))
153 /* Finally compare id */
154 return (v > 0 && streq(c->parameter, id)) == !c->negate;
157 bool condition_test_architecture(Condition *c) {
161 assert(c->parameter);
162 assert(c->type == CONDITION_ARCHITECTURE);
164 a = uname_architecture();
168 if (streq(c->parameter, "native"))
169 b = native_architecture();
171 b = architecture_from_string(c->parameter);
176 return (a == b) == !c->negate;
179 bool condition_test_host(Condition *c) {
180 _cleanup_free_ char *h = NULL;
185 assert(c->parameter);
186 assert(c->type == CONDITION_HOST);
188 if (sd_id128_from_string(c->parameter, &x) >= 0) {
190 r = sd_id128_get_machine(&y);
194 return sd_id128_equal(x, y) == !c->negate;
197 h = gethostname_malloc();
201 return (fnmatch(c->parameter, h, FNM_CASEFOLD) == 0) == !c->negate;
204 bool condition_test_ac_power(Condition *c) {
208 assert(c->parameter);
209 assert(c->type == CONDITION_AC_POWER);
211 r = parse_boolean(c->parameter);
215 return ((on_ac_power() != 0) == !!r) == !c->negate;
218 void condition_dump(Condition *c, FILE *f, const char *prefix) {
226 "%s\t%s: %s%s%s %s\n",
228 condition_type_to_string(c->type),
229 c->trigger ? "|" : "",
230 c->negate ? "!" : "",
232 c->state < 0 ? "failed" : c->state > 0 ? "succeeded" : "untested");
235 void condition_dump_list(Condition *first, FILE *f, const char *prefix) {
238 LIST_FOREACH(conditions, c, first)
239 condition_dump(c, f, prefix);
242 static const char* const condition_type_table[_CONDITION_TYPE_MAX] = {
243 [CONDITION_PATH_EXISTS] = "ConditionPathExists",
244 [CONDITION_PATH_EXISTS_GLOB] = "ConditionPathExistsGlob",
245 [CONDITION_PATH_IS_DIRECTORY] = "ConditionPathIsDirectory",
246 [CONDITION_PATH_IS_SYMBOLIC_LINK] = "ConditionPathIsSymbolicLink",
247 [CONDITION_PATH_IS_MOUNT_POINT] = "ConditionPathIsMountPoint",
248 [CONDITION_PATH_IS_READ_WRITE] = "ConditionPathIsReadWrite",
249 [CONDITION_DIRECTORY_NOT_EMPTY] = "ConditionDirectoryNotEmpty",
250 [CONDITION_FILE_NOT_EMPTY] = "ConditionFileNotEmpty",
251 [CONDITION_FILE_IS_EXECUTABLE] = "ConditionFileIsExecutable",
252 [CONDITION_KERNEL_COMMAND_LINE] = "ConditionKernelCommandLine",
253 [CONDITION_VIRTUALIZATION] = "ConditionVirtualization",
254 [CONDITION_SECURITY] = "ConditionSecurity",
255 [CONDITION_CAPABILITY] = "ConditionCapability",
256 [CONDITION_HOST] = "ConditionHost",
257 [CONDITION_AC_POWER] = "ConditionACPower",
258 [CONDITION_ARCHITECTURE] = "ConditionArchitecture",
259 [CONDITION_NEEDS_UPDATE] = "ConditionNeedsUpdate",
260 [CONDITION_NULL] = "ConditionNull"
263 DEFINE_STRING_TABLE_LOOKUP(condition_type, ConditionType);