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 int condition_test_kernel_command_line(Condition *c) {
77 _cleanup_free_ char *line = NULL;
84 assert(c->type == CONDITION_KERNEL_COMMAND_LINE);
86 r = proc_cmdline(&line);
92 equal = !!strchr(c->parameter, '=');
96 _cleanup_free_ char *word = NULL;
99 r = unquote_first_word(&p, &word);
106 found = streq(word, c->parameter);
110 f = startswith(word, c->parameter);
111 found = f && (*f == '=' || *f == 0);
121 int condition_test_virtualization(Condition *c) {
126 assert(c->parameter);
127 assert(c->type == CONDITION_VIRTUALIZATION);
129 v = detect_virtualization(&id);
133 /* First, compare with yes/no */
134 b = parse_boolean(c->parameter);
139 if (v == 0 && b == 0)
142 /* Then, compare categorization */
143 if (v == VIRTUALIZATION_VM && streq(c->parameter, "vm"))
146 if (v == VIRTUALIZATION_CONTAINER && streq(c->parameter, "container"))
149 /* Finally compare id */
150 return (v > 0 && streq(c->parameter, id)) == !c->negate;
153 int condition_test_architecture(Condition *c) {
157 assert(c->parameter);
158 assert(c->type == CONDITION_ARCHITECTURE);
160 a = uname_architecture();
164 if (streq(c->parameter, "native"))
165 b = native_architecture();
167 b = architecture_from_string(c->parameter);
171 return (a == b) == !c->negate;
174 int condition_test_host(Condition *c) {
175 _cleanup_free_ char *h = NULL;
180 assert(c->parameter);
181 assert(c->type == CONDITION_HOST);
183 if (sd_id128_from_string(c->parameter, &x) >= 0) {
185 r = sd_id128_get_machine(&y);
189 return sd_id128_equal(x, y) == !c->negate;
192 h = gethostname_malloc();
196 return (fnmatch(c->parameter, h, FNM_CASEFOLD) == 0) == !c->negate;
199 int condition_test_ac_power(Condition *c) {
203 assert(c->parameter);
204 assert(c->type == CONDITION_AC_POWER);
206 r = parse_boolean(c->parameter);
210 return ((on_ac_power() != 0) == !!r) == !c->negate;
213 void condition_dump(Condition *c, FILE *f, const char *prefix) {
221 "%s\t%s: %s%s%s %s\n",
223 condition_type_to_string(c->type),
224 c->trigger ? "|" : "",
225 c->negate ? "!" : "",
227 CONDITION_STATE_IS_FAILED(c->state) ? "failed" : CONDITION_STATE_IS_SUCCEEDED(c->state) ? "succeeded" : "untested");
230 void condition_dump_list(Condition *first, FILE *f, const char *prefix) {
233 LIST_FOREACH(conditions, c, first)
234 condition_dump(c, f, prefix);
237 static const char* const condition_type_table[_CONDITION_TYPE_MAX] = {
238 [CONDITION_PATH_EXISTS] = "ConditionPathExists",
239 [CONDITION_PATH_EXISTS_GLOB] = "ConditionPathExistsGlob",
240 [CONDITION_PATH_IS_DIRECTORY] = "ConditionPathIsDirectory",
241 [CONDITION_PATH_IS_SYMBOLIC_LINK] = "ConditionPathIsSymbolicLink",
242 [CONDITION_PATH_IS_MOUNT_POINT] = "ConditionPathIsMountPoint",
243 [CONDITION_PATH_IS_READ_WRITE] = "ConditionPathIsReadWrite",
244 [CONDITION_DIRECTORY_NOT_EMPTY] = "ConditionDirectoryNotEmpty",
245 [CONDITION_FILE_NOT_EMPTY] = "ConditionFileNotEmpty",
246 [CONDITION_FILE_IS_EXECUTABLE] = "ConditionFileIsExecutable",
247 [CONDITION_KERNEL_COMMAND_LINE] = "ConditionKernelCommandLine",
248 [CONDITION_VIRTUALIZATION] = "ConditionVirtualization",
249 [CONDITION_SECURITY] = "ConditionSecurity",
250 [CONDITION_CAPABILITY] = "ConditionCapability",
251 [CONDITION_HOST] = "ConditionHost",
252 [CONDITION_AC_POWER] = "ConditionACPower",
253 [CONDITION_ARCHITECTURE] = "ConditionArchitecture",
254 [CONDITION_NEEDS_UPDATE] = "ConditionNeedsUpdate",
255 [CONDITION_FIRST_BOOT] = "ConditionFirstBoot",
256 [CONDITION_NULL] = "ConditionNull"
259 DEFINE_STRING_TABLE_LOOKUP(condition_type, ConditionType);