]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/udev/udev-builtin.c
Merge pull request #15669 from andir/systemd-ipv6-pd-subnet-id
[thirdparty/systemd.git] / src / udev / udev-builtin.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2
3 #include <getopt.h>
4 #include <stdio.h>
5
6 #include "device-private.h"
7 #include "device-util.h"
8 #include "string-util.h"
9 #include "strv.h"
10 #include "udev-builtin.h"
11
12 static bool initialized;
13
14 static const UdevBuiltin *const builtins[_UDEV_BUILTIN_MAX] = {
15 #if HAVE_BLKID
16 [UDEV_BUILTIN_BLKID] = &udev_builtin_blkid,
17 #endif
18 [UDEV_BUILTIN_BTRFS] = &udev_builtin_btrfs,
19 [UDEV_BUILTIN_HWDB] = &udev_builtin_hwdb,
20 [UDEV_BUILTIN_INPUT_ID] = &udev_builtin_input_id,
21 [UDEV_BUILTIN_KEYBOARD] = &udev_builtin_keyboard,
22 #if HAVE_KMOD
23 [UDEV_BUILTIN_KMOD] = &udev_builtin_kmod,
24 #endif
25 [UDEV_BUILTIN_NET_ID] = &udev_builtin_net_id,
26 [UDEV_BUILTIN_NET_LINK] = &udev_builtin_net_setup_link,
27 [UDEV_BUILTIN_PATH_ID] = &udev_builtin_path_id,
28 [UDEV_BUILTIN_USB_ID] = &udev_builtin_usb_id,
29 #if HAVE_ACL
30 [UDEV_BUILTIN_UACCESS] = &udev_builtin_uaccess,
31 #endif
32 };
33
34 void udev_builtin_init(void) {
35 unsigned i;
36
37 if (initialized)
38 return;
39
40 for (i = 0; i < _UDEV_BUILTIN_MAX; i++)
41 if (builtins[i] && builtins[i]->init)
42 builtins[i]->init();
43
44 initialized = true;
45 }
46
47 void udev_builtin_exit(void) {
48 unsigned i;
49
50 if (!initialized)
51 return;
52
53 for (i = 0; i < _UDEV_BUILTIN_MAX; i++)
54 if (builtins[i] && builtins[i]->exit)
55 builtins[i]->exit();
56
57 initialized = false;
58 }
59
60 bool udev_builtin_validate(void) {
61 unsigned i;
62
63 for (i = 0; i < _UDEV_BUILTIN_MAX; i++)
64 if (builtins[i] && builtins[i]->validate && builtins[i]->validate())
65 return true;
66 return false;
67 }
68
69 void udev_builtin_list(void) {
70 unsigned i;
71
72 for (i = 0; i < _UDEV_BUILTIN_MAX; i++)
73 if (builtins[i])
74 fprintf(stderr, " %-14s %s\n", builtins[i]->name, builtins[i]->help);
75 }
76
77 const char *udev_builtin_name(UdevBuiltinCommand cmd) {
78 assert(cmd >= 0 && cmd < _UDEV_BUILTIN_MAX);
79
80 if (!builtins[cmd])
81 return NULL;
82
83 return builtins[cmd]->name;
84 }
85
86 bool udev_builtin_run_once(UdevBuiltinCommand cmd) {
87 assert(cmd >= 0 && cmd < _UDEV_BUILTIN_MAX);
88
89 if (!builtins[cmd])
90 return false;
91
92 return builtins[cmd]->run_once;
93 }
94
95 UdevBuiltinCommand udev_builtin_lookup(const char *command) {
96 UdevBuiltinCommand i;
97 size_t n;
98
99 assert(command);
100
101 command += strspn(command, WHITESPACE);
102 n = strcspn(command, WHITESPACE);
103 for (i = 0; i < _UDEV_BUILTIN_MAX; i++)
104 if (builtins[i] && strneq(builtins[i]->name, command, n))
105 return i;
106
107 return _UDEV_BUILTIN_INVALID;
108 }
109
110 int udev_builtin_run(sd_device *dev, UdevBuiltinCommand cmd, const char *command, bool test) {
111 _cleanup_strv_free_ char **argv = NULL;
112
113 assert(dev);
114 assert(cmd >= 0 && cmd < _UDEV_BUILTIN_MAX);
115 assert(command);
116
117 if (!builtins[cmd])
118 return -EOPNOTSUPP;
119
120 argv = strv_split_full(command, NULL, SPLIT_QUOTES | SPLIT_RELAX);
121 if (!argv)
122 return -ENOMEM;
123
124 /* we need '0' here to reset the internal state */
125 optind = 0;
126 return builtins[cmd]->cmd(dev, strv_length(argv), argv, test);
127 }
128
129 int udev_builtin_add_property(sd_device *dev, bool test, const char *key, const char *val) {
130 int r;
131
132 assert(dev);
133 assert(key);
134
135 r = device_add_property(dev, key, val);
136 if (r < 0)
137 return log_device_debug_errno(dev, r, "Failed to add property '%s%s%s'",
138 key, val ? "=" : "", strempty(val));
139
140 if (test)
141 printf("%s=%s\n", key, strempty(val));
142
143 return 0;
144 }