Branch data 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 : : }
|