1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
6 #include "alloc-util.h"
8 #include "device-private.h"
9 #include "device-util.h"
10 #include "extract-word.h"
11 #include "string-util.h"
13 #include "udev-builtin.h"
15 static const UdevBuiltin
*const builtins
[_UDEV_BUILTIN_MAX
] = {
17 [UDEV_BUILTIN_BLKID
] = &udev_builtin_blkid
,
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
,
26 [UDEV_BUILTIN_KMOD
] = &udev_builtin_kmod
,
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
,
33 [UDEV_BUILTIN_UACCESS
] = &udev_builtin_uaccess
,
35 [UDEV_BUILTIN_USB_ID
] = &udev_builtin_usb_id
,
38 void udev_builtin_init(void) {
39 FOREACH_ELEMENT(b
, builtins
)
44 void udev_builtin_exit(void) {
45 FOREACH_ELEMENT(b
, builtins
)
50 UdevReloadFlags
udev_builtin_should_reload(void) {
51 UdevReloadFlags flags
= 0;
53 for (UdevBuiltinCommand i
= 0; i
< _UDEV_BUILTIN_MAX
; i
++)
54 if (builtins
[i
] && builtins
[i
]->should_reload
&& builtins
[i
]->should_reload())
58 flags
|= UDEV_RELOAD_KILL_WORKERS
;
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
])
67 if (builtins
[i
]->exit
)
69 if (builtins
[i
]->init
)
74 void udev_builtin_list(void) {
75 FOREACH_ELEMENT(b
, builtins
)
77 fprintf(stderr
, " %-14s %s\n", (*b
)->name
, (*b
)->help
);
80 const char* udev_builtin_name(UdevBuiltinCommand cmd
) {
81 assert(cmd
>= 0 && cmd
< _UDEV_BUILTIN_MAX
);
86 return builtins
[cmd
]->name
;
89 bool udev_builtin_run_once(UdevBuiltinCommand cmd
) {
90 assert(cmd
>= 0 && cmd
< _UDEV_BUILTIN_MAX
);
95 return builtins
[cmd
]->run_once
;
98 UdevBuiltinCommand
udev_builtin_lookup(const char *command
) {
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
))
109 return _UDEV_BUILTIN_INVALID
;
112 int udev_builtin_run(UdevEvent
*event
, UdevBuiltinCommand cmd
, const char *command
) {
113 _cleanup_strv_free_
char **argv
= NULL
;
118 assert(cmd
>= 0 && cmd
< _UDEV_BUILTIN_MAX
);
124 r
= strv_split_full(&argv
, command
, NULL
, EXTRACT_UNQUOTE
| EXTRACT_RELAX
| EXTRACT_RETAIN_ESCAPE
);
128 /* we need '0' here to reset the internal state */
130 return builtins
[cmd
]->cmd(event
, strv_length(argv
), argv
);
133 int udev_builtin_add_property(UdevEvent
*event
, const char *key
, const char *val
) {
134 sd_device
*dev
= ASSERT_PTR(ASSERT_PTR(event
)->dev
);
139 r
= device_add_property(dev
, key
, val
);
141 return log_device_debug_errno(dev
, r
, "Failed to add property '%s%s%s'",
142 key
, val
? "=" : "", strempty(val
));
144 if (event
->event_mode
== EVENT_UDEVADM_TEST_BUILTIN
)
145 printf("%s=%s\n", key
, strempty(val
));
150 int udev_builtin_add_propertyf(UdevEvent
*event
, const char *key
, const char *valf
, ...) {
151 _cleanup_free_
char *val
= NULL
;
160 r
= vasprintf(&val
, valf
, ap
);
163 return log_oom_debug();
165 return udev_builtin_add_property(event
, key
, val
);
168 int udev_builtin_import_property(UdevEvent
*event
, const char *key
) {
175 if (!event
->dev_db_clone
)
178 r
= sd_device_get_property_value(event
->dev_db_clone
, key
, &val
);
182 return log_device_debug_errno(event
->dev_db_clone
, r
, "Failed to get property \"%s\", ignoring: %m", key
);
184 r
= udev_builtin_add_property(event
, key
, val
);