]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/udev/udevadm-test-builtin.c
udev/net: introduce [Link] Property=, ImportProperty=, and UnsetProperty= settings
[thirdparty/systemd.git] / src / udev / udevadm-test-builtin.c
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2
3 #include <errno.h>
4 #include <getopt.h>
5 #include <stddef.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8
9 #include "device-private.h"
10 #include "device-util.h"
11 #include "log.h"
12 #include "udev-builtin.h"
13 #include "udevadm.h"
14 #include "udevadm-util.h"
15
16 static sd_device_action_t arg_action = SD_DEVICE_ADD;
17 static const char *arg_command = NULL;
18 static const char *arg_syspath = NULL;
19
20 static int help(void) {
21 printf("%s test-builtin [OPTIONS] COMMAND DEVPATH\n\n"
22 "Test a built-in command.\n\n"
23 " -h --help Print this message\n"
24 " -V --version Print version of the program\n\n"
25 " -a --action=ACTION|help Set action string\n"
26 "Commands:\n",
27 program_invocation_short_name);
28
29 udev_builtin_list();
30
31 return 0;
32 }
33
34 static int parse_argv(int argc, char *argv[]) {
35 static const struct option options[] = {
36 { "action", required_argument, NULL, 'a' },
37 { "version", no_argument, NULL, 'V' },
38 { "help", no_argument, NULL, 'h' },
39 {}
40 };
41
42 int r, c;
43
44 while ((c = getopt_long(argc, argv, "a:Vh", options, NULL)) >= 0)
45 switch (c) {
46 case 'a':
47 r = parse_device_action(optarg, &arg_action);
48 if (r < 0)
49 return log_error_errno(r, "Invalid action '%s'", optarg);
50 if (r == 0)
51 return 0;
52 break;
53 case 'V':
54 return print_version();
55 case 'h':
56 return help();
57 case '?':
58 return -EINVAL;
59 default:
60 assert_not_reached();
61 }
62
63 arg_command = argv[optind++];
64 if (!arg_command)
65 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
66 "Command missing.");
67
68 arg_syspath = argv[optind++];
69 if (!arg_syspath)
70 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
71 "device is missing.");
72
73 return 1;
74 }
75
76 int builtin_main(int argc, char *argv[], void *userdata) {
77 _cleanup_(udev_event_freep) UdevEvent *event = NULL;
78 _cleanup_(sd_device_unrefp) sd_device *dev = NULL;
79 UdevBuiltinCommand cmd;
80 int r;
81
82 log_set_max_level(LOG_DEBUG);
83 log_parse_environment();
84
85 r = parse_argv(argc, argv);
86 if (r <= 0)
87 return r;
88
89 udev_builtin_init();
90
91 cmd = udev_builtin_lookup(arg_command);
92 if (cmd < 0) {
93 r = log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown command '%s'", arg_command);
94 goto finish;
95 }
96
97 r = find_device_with_action(arg_syspath, arg_action, &dev);
98 if (r < 0) {
99 log_error_errno(r, "Failed to open device '%s': %m", arg_syspath);
100 goto finish;
101 }
102
103 event = udev_event_new(dev, NULL);
104 if (!event) {
105 r = log_oom();
106 goto finish;
107 }
108
109 if (arg_action != SD_DEVICE_REMOVE) {
110 /* For net_setup_link */
111 r = device_clone_with_db(dev, &event->dev_db_clone);
112 if (r < 0) {
113 log_device_error_errno(dev, r, "Failed to clone device: %m");
114 goto finish;
115 }
116 }
117
118 r = udev_builtin_run(event, cmd, arg_command, true);
119 if (r < 0) {
120 log_debug_errno(r, "Builtin command '%s' fails: %m", arg_command);
121 goto finish;
122 }
123
124 r = 0;
125 finish:
126 udev_builtin_exit();
127 return r;
128 }