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