1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 
3 #include <getopt.h>
4 
5 #include "sd-hwdb.h"
6 
7 #include "alloc-util.h"
8 #include "hwdb-util.h"
9 #include "main-func.h"
10 #include "pretty-print.h"
11 #include "selinux-util.h"
12 #include "terminal-util.h"
13 #include "util.h"
14 #include "verbs.h"
15 
16 static const char *arg_hwdb_bin_dir = NULL;
17 static const char *arg_root = NULL;
18 static bool arg_strict = false;
19 
verb_query(int argc,char * argv[],void * userdata)20 static int verb_query(int argc, char *argv[], void *userdata) {
21         return hwdb_query(argv[1]);
22 }
23 
verb_update(int argc,char * argv[],void * userdata)24 static int verb_update(int argc, char *argv[], void *userdata) {
25         return hwdb_update(arg_root, arg_hwdb_bin_dir, arg_strict, false);
26 }
27 
help(void)28 static int help(void) {
29         _cleanup_free_ char *link = NULL;
30         int r;
31 
32         r = terminal_urlify_man("systemd-hwdb", "8", &link);
33         if (r < 0)
34                 return log_oom();
35 
36         printf("%s [OPTIONS...] COMMAND ...\n\n"
37                "%sUpdate or query the hardware database.%s\n"
38                "\nCommands:\n"
39                "  update          Update the hwdb database\n"
40                "  query MODALIAS  Query database and print result\n"
41                "\nOptions:\n"
42                "  -h --help       Show this help\n"
43                "     --version    Show package version\n"
44                "  -s --strict     When updating, return non-zero exit value on any parsing error\n"
45                "     --usr        Generate in " UDEVLIBEXECDIR " instead of /etc/udev\n"
46                "  -r --root=PATH  Alternative root path in the filesystem\n"
47                "\nSee the %s for details.\n",
48                program_invocation_short_name,
49                ansi_highlight(),
50                ansi_normal(),
51                link);
52 
53         return 0;
54 }
55 
parse_argv(int argc,char * argv[])56 static int parse_argv(int argc, char *argv[]) {
57         enum {
58                 ARG_VERSION = 0x100,
59                 ARG_USR,
60         };
61 
62         static const struct option options[] = {
63                 { "help",     no_argument,       NULL, 'h'         },
64                 { "version",  no_argument,       NULL, ARG_VERSION },
65                 { "usr",      no_argument,       NULL, ARG_USR     },
66                 { "strict",   no_argument,       NULL, 's'         },
67                 { "root",     required_argument, NULL, 'r'         },
68                 {}
69         };
70 
71         int c;
72 
73         assert(argc >= 0);
74         assert(argv);
75 
76         while ((c = getopt_long(argc, argv, "sr:h", options, NULL)) >= 0)
77                 switch (c) {
78 
79                 case 'h':
80                         return help();
81 
82                 case ARG_VERSION:
83                         return version();
84 
85                 case ARG_USR:
86                         arg_hwdb_bin_dir = UDEVLIBEXECDIR;
87                         break;
88 
89                 case 's':
90                         arg_strict = true;
91                         break;
92 
93                 case 'r':
94                         arg_root = optarg;
95                         break;
96 
97                 case '?':
98                         return -EINVAL;
99 
100                 default:
101                         assert_not_reached();
102                 }
103 
104         return 1;
105 }
106 
hwdb_main(int argc,char * argv[])107 static int hwdb_main(int argc, char *argv[]) {
108         static const Verb verbs[] = {
109                 { "update", 1, 1, 0, verb_update },
110                 { "query",  2, 2, 0, verb_query  },
111                 {},
112         };
113 
114         return dispatch_verb(argc, argv, verbs, NULL);
115 }
116 
run(int argc,char * argv[])117 static int run(int argc, char *argv[]) {
118         int r;
119 
120         log_parse_environment();
121         log_open();
122 
123         r = parse_argv(argc, argv);
124         if (r <= 0)
125                 return r;
126 
127         r = mac_selinux_init();
128         if (r < 0)
129                 return r;
130 
131         return hwdb_main(argc, argv);
132 }
133 
134 DEFINE_MAIN_FUNCTION(run);
135