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
8 #include "alloc-util.h"
9 #include "main-func.h"
10 #include "pretty-print.h"
11 #include "process-util.h"
12 #include "selinux-util.h"
13 #include "string-util.h"
14 #include "udev-util.h"
15 #include "udevadm.h"
16 #include "udevd.h"
17 #include "util.h"
18 #include "verbs.h"
19
help(void)20 static int help(void) {
21 static const char *const short_descriptions[][2] = {
22 { "info", "Query sysfs or the udev database" },
23 { "trigger", "Request events from the kernel" },
24 { "settle", "Wait for pending udev events" },
25 { "control", "Control the udev daemon" },
26 { "monitor", "Listen to kernel and udev events" },
27 { "test", "Test an event run" },
28 { "test-builtin", "Test a built-in command" },
29 { "wait", "Wait for device or device symlink" },
30 { "lock", "Lock a block device" },
31 };
32
33 _cleanup_free_ char *link = NULL;
34 size_t i;
35 int r;
36
37 r = terminal_urlify_man("udevadm", "8", &link);
38 if (r < 0)
39 return log_oom();
40
41 printf("%s [--help] [--version] [--debug] COMMAND [COMMAND OPTIONS]\n\n"
42 "Send control commands or test the device manager.\n\n"
43 "Commands:\n",
44 program_invocation_short_name);
45
46 for (i = 0; i < ELEMENTSOF(short_descriptions); i++)
47 printf(" %-12s %s\n", short_descriptions[i][0], short_descriptions[i][1]);
48
49 printf("\nSee the %s for details.\n", link);
50 return 0;
51 }
52
parse_argv(int argc,char * argv[])53 static int parse_argv(int argc, char *argv[]) {
54 static const struct option options[] = {
55 { "debug", no_argument, NULL, 'd' },
56 { "help", no_argument, NULL, 'h' },
57 { "version", no_argument, NULL, 'V' },
58 {}
59 };
60 int c;
61
62 assert(argc >= 0);
63 assert(argv);
64
65 while ((c = getopt_long(argc, argv, "+dhV", options, NULL)) >= 0)
66 switch (c) {
67
68 case 'd':
69 log_set_max_level(LOG_DEBUG);
70 break;
71
72 case 'h':
73 return help();
74
75 case 'V':
76 return print_version();
77
78 case '?':
79 return -EINVAL;
80
81 default:
82 assert_not_reached();
83 }
84
85 return 1; /* work to do */
86 }
87
version_main(int argc,char * argv[],void * userdata)88 static int version_main(int argc, char *argv[], void *userdata) {
89 return print_version();
90 }
91
help_main(int argc,char * argv[],void * userdata)92 static int help_main(int argc, char *argv[], void *userdata) {
93 return help();
94 }
95
udevadm_main(int argc,char * argv[])96 static int udevadm_main(int argc, char *argv[]) {
97 static const Verb verbs[] = {
98 { "info", VERB_ANY, VERB_ANY, 0, info_main },
99 { "trigger", VERB_ANY, VERB_ANY, 0, trigger_main },
100 { "settle", VERB_ANY, VERB_ANY, 0, settle_main },
101 { "control", VERB_ANY, VERB_ANY, 0, control_main },
102 { "monitor", VERB_ANY, VERB_ANY, 0, monitor_main },
103 { "hwdb", VERB_ANY, VERB_ANY, 0, hwdb_main },
104 { "test", VERB_ANY, VERB_ANY, 0, test_main },
105 { "test-builtin", VERB_ANY, VERB_ANY, 0, builtin_main },
106 { "wait", VERB_ANY, VERB_ANY, 0, wait_main },
107 { "lock", VERB_ANY, VERB_ANY, 0, lock_main },
108 { "version", VERB_ANY, VERB_ANY, 0, version_main },
109 { "help", VERB_ANY, VERB_ANY, 0, help_main },
110 {}
111 };
112
113 return dispatch_verb(argc, argv, verbs, NULL);
114 }
115
run(int argc,char * argv[])116 static int run(int argc, char *argv[]) {
117 int r;
118
119 if (invoked_as(argv, "udevd"))
120 return run_udevd(argc, argv);
121
122 udev_parse_config();
123 log_parse_environment();
124 log_open();
125
126 r = parse_argv(argc, argv);
127 if (r <= 0)
128 return r;
129
130 r = mac_selinux_init();
131 if (r < 0)
132 return r;
133
134 return udevadm_main(argc, argv);
135 }
136
137 DEFINE_MAIN_FUNCTION(run);
138