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