]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/udev/udev-builtin.c
5f559f5c9a10c8a19c6b1297549c77e6e6631075
[thirdparty/systemd.git] / src / udev / udev-builtin.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include <getopt.h>
4 #include <stdio.h>
5
6 #include "alloc-util.h"
7 #include "bitfield.h"
8 #include "device-private.h"
9 #include "device-util.h"
10 #include "extract-word.h"
11 #include "string-util.h"
12 #include "strv.h"
13 #include "udev-builtin.h"
14
15 static const UdevBuiltin *const builtins[_UDEV_BUILTIN_MAX] = {
16 #if HAVE_BLKID
17 [UDEV_BUILTIN_BLKID] = &udev_builtin_blkid,
18 #endif
19 [UDEV_BUILTIN_BTRFS] = &udev_builtin_btrfs,
20 [UDEV_BUILTIN_DISSECT_IMAGE] = &udev_builtin_dissect_image,
21 [UDEV_BUILTIN_FACTORY_RESET] = &udev_builtin_factory_reset,
22 [UDEV_BUILTIN_HWDB] = &udev_builtin_hwdb,
23 [UDEV_BUILTIN_INPUT_ID] = &udev_builtin_input_id,
24 [UDEV_BUILTIN_KEYBOARD] = &udev_builtin_keyboard,
25 #if HAVE_KMOD
26 [UDEV_BUILTIN_KMOD] = &udev_builtin_kmod,
27 #endif
28 [UDEV_BUILTIN_NET_DRIVER] = &udev_builtin_net_driver,
29 [UDEV_BUILTIN_NET_ID] = &udev_builtin_net_id,
30 [UDEV_BUILTIN_NET_LINK] = &udev_builtin_net_setup_link,
31 [UDEV_BUILTIN_PATH_ID] = &udev_builtin_path_id,
32 #if HAVE_ACL
33 [UDEV_BUILTIN_UACCESS] = &udev_builtin_uaccess,
34 #endif
35 [UDEV_BUILTIN_USB_ID] = &udev_builtin_usb_id,
36 };
37
38 void udev_builtin_init(void) {
39 FOREACH_ELEMENT(b, builtins)
40 if (*b && (*b)->init)
41 (*b)->init();
42 }
43
44 void udev_builtin_exit(void) {
45 FOREACH_ELEMENT(b, builtins)
46 if (*b && (*b)->exit)
47 (*b)->exit();
48 }
49
50 UdevReloadFlags udev_builtin_should_reload(void) {
51 UdevReloadFlags flags = 0;
52
53 for (UdevBuiltinCommand i = 0; i < _UDEV_BUILTIN_MAX; i++)
54 if (builtins[i] && builtins[i]->should_reload && builtins[i]->should_reload())
55 flags |= 1u << i;
56
57 if (flags != 0)
58 flags |= UDEV_RELOAD_KILL_WORKERS;
59
60 return flags;
61 }
62
63 void udev_builtin_reload(UdevReloadFlags flags) {
64 for (UdevBuiltinCommand i = 0; i < _UDEV_BUILTIN_MAX; i++) {
65 if (!BIT_SET(flags, i) || !builtins[i])
66 continue;
67 if (builtins[i]->exit)
68 builtins[i]->exit();
69 if (builtins[i]->init)
70 builtins[i]->init();
71 }
72 }
73
74 void udev_builtin_list(void) {
75 FOREACH_ELEMENT(b, builtins)
76 if (*b)
77 fprintf(stderr, " %-14s %s\n", (*b)->name, (*b)->help);
78 }
79
80 const char* udev_builtin_name(UdevBuiltinCommand cmd) {
81 assert(cmd >= 0 && cmd < _UDEV_BUILTIN_MAX);
82
83 if (!builtins[cmd])
84 return NULL;
85
86 return builtins[cmd]->name;
87 }
88
89 bool udev_builtin_run_once(UdevBuiltinCommand cmd) {
90 assert(cmd >= 0 && cmd < _UDEV_BUILTIN_MAX);
91
92 if (!builtins[cmd])
93 return false;
94
95 return builtins[cmd]->run_once;
96 }
97
98 UdevBuiltinCommand udev_builtin_lookup(const char *command) {
99 size_t n;
100
101 assert(command);
102
103 command += strspn(command, WHITESPACE);
104 n = strcspn(command, WHITESPACE);
105 for (UdevBuiltinCommand i = 0; i < _UDEV_BUILTIN_MAX; i++)
106 if (builtins[i] && strneq(builtins[i]->name, command, n))
107 return i;
108
109 return _UDEV_BUILTIN_INVALID;
110 }
111
112 int udev_builtin_run(UdevEvent *event, UdevBuiltinCommand cmd, const char *command) {
113 _cleanup_strv_free_ char **argv = NULL;
114 int r;
115
116 assert(event);
117 assert(event->dev);
118 assert(cmd >= 0 && cmd < _UDEV_BUILTIN_MAX);
119 assert(command);
120
121 if (!builtins[cmd])
122 return -EOPNOTSUPP;
123
124 r = strv_split_full(&argv, command, NULL, EXTRACT_UNQUOTE | EXTRACT_RELAX | EXTRACT_RETAIN_ESCAPE);
125 if (r < 0)
126 return r;
127
128 /* we need '0' here to reset the internal state */
129 optind = 0;
130 return builtins[cmd]->cmd(event, strv_length(argv), argv);
131 }
132
133 int udev_builtin_add_property(UdevEvent *event, const char *key, const char *val) {
134 sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev);
135 int r;
136
137 assert(key);
138
139 r = device_add_property(dev, key, val);
140 if (r < 0)
141 return log_device_debug_errno(dev, r, "Failed to add property '%s%s%s'",
142 key, val ? "=" : "", strempty(val));
143
144 if (event->event_mode == EVENT_UDEVADM_TEST_BUILTIN)
145 printf("%s=%s\n", key, strempty(val));
146
147 return 0;
148 }
149
150 int udev_builtin_add_propertyf(UdevEvent *event, const char *key, const char *valf, ...) {
151 _cleanup_free_ char *val = NULL;
152 va_list ap;
153 int r;
154
155 assert(event);
156 assert(key);
157 assert(valf);
158
159 va_start(ap, valf);
160 r = vasprintf(&val, valf, ap);
161 va_end(ap);
162 if (r < 0)
163 return log_oom_debug();
164
165 return udev_builtin_add_property(event, key, val);
166 }
167
168 int udev_builtin_import_property(UdevEvent *event, const char *key) {
169 const char *val;
170 int r;
171
172 assert(event);
173 assert(event->dev);
174
175 if (!event->dev_db_clone)
176 return 0;
177
178 r = sd_device_get_property_value(event->dev_db_clone, key, &val);
179 if (r == -ENOENT)
180 return 0;
181 if (r < 0)
182 return log_device_debug_errno(event->dev_db_clone, r, "Failed to get property \"%s\", ignoring: %m", key);
183
184 r = udev_builtin_add_property(event, key, val);
185 if (r < 0)
186 return r;
187
188 return 1;
189 }