Line data Source code
1 : /* SPDX-License-Identifier: LGPL-2.1+ */
2 :
3 : #include <getopt.h>
4 : #include <stdio.h>
5 :
6 : #include "alloc-util.h"
7 : #include "id128-print.h"
8 : #include "main-func.h"
9 : #include "pretty-print.h"
10 : #include "util.h"
11 : #include "verbs.h"
12 :
13 : static bool arg_pretty = false;
14 : static sd_id128_t arg_app = {};
15 :
16 0 : static int verb_new(int argc, char **argv, void *userdata) {
17 0 : return id128_print_new(arg_pretty);
18 : }
19 :
20 0 : static int verb_machine_id(int argc, char **argv, void *userdata) {
21 : sd_id128_t id;
22 : int r;
23 :
24 0 : if (sd_id128_is_null(arg_app))
25 0 : r = sd_id128_get_machine(&id);
26 : else
27 0 : r = sd_id128_get_machine_app_specific(arg_app, &id);
28 0 : if (r < 0)
29 0 : return log_error_errno(r, "Failed to get %smachine-ID: %m",
30 : sd_id128_is_null(arg_app) ? "" : "app-specific ");
31 :
32 0 : return id128_pretty_print(id, arg_pretty);
33 : }
34 :
35 0 : static int verb_boot_id(int argc, char **argv, void *userdata) {
36 : sd_id128_t id;
37 : int r;
38 :
39 0 : if (sd_id128_is_null(arg_app))
40 0 : r = sd_id128_get_boot(&id);
41 : else
42 0 : r = sd_id128_get_boot_app_specific(arg_app, &id);
43 0 : if (r < 0)
44 0 : return log_error_errno(r, "Failed to get %sboot-ID: %m",
45 : sd_id128_is_null(arg_app) ? "" : "app-specific ");
46 :
47 0 : return id128_pretty_print(id, arg_pretty);
48 : }
49 :
50 0 : static int verb_invocation_id(int argc, char **argv, void *userdata) {
51 : sd_id128_t id;
52 : int r;
53 :
54 0 : if (!sd_id128_is_null(arg_app))
55 0 : return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
56 : "Verb \"invocation-id\" cannot be combined with --app-specific=.");
57 :
58 0 : r = sd_id128_get_invocation(&id);
59 0 : if (r < 0)
60 0 : return log_error_errno(r, "Failed to get invocation-ID: %m");
61 :
62 0 : return id128_pretty_print(id, arg_pretty);
63 : }
64 :
65 3 : static int help(void) {
66 3 : _cleanup_free_ char *link = NULL;
67 : int r;
68 :
69 3 : r = terminal_urlify_man("systemd-id128", "1", &link);
70 3 : if (r < 0)
71 0 : return log_oom();
72 :
73 3 : printf("%s [OPTIONS...] {COMMAND}\n\n"
74 : "Generate and print id128 strings.\n\n"
75 : " -h --help Show this help\n"
76 : " -p --pretty Generate samples of program code\n"
77 : " -a --app-specific=ID Generate app-specific IDs\n"
78 : "\nCommands:\n"
79 : " new Generate a new id128 string\n"
80 : " machine-id Print the ID of current machine\n"
81 : " boot-id Print the ID of current boot\n"
82 : " invocation-id Print the ID of current invocation\n"
83 : " help Show this help\n"
84 : "\nSee the %s for details.\n"
85 : , program_invocation_short_name
86 : , link
87 : );
88 :
89 3 : return 0;
90 : }
91 :
92 0 : static int verb_help(int argc, char **argv, void *userdata) {
93 0 : return help();
94 : }
95 :
96 4 : static int parse_argv(int argc, char *argv[]) {
97 : enum {
98 : ARG_VERSION = 0x100,
99 : };
100 :
101 : static const struct option options[] = {
102 : { "help", no_argument, NULL, 'h' },
103 : { "version", no_argument, NULL, ARG_VERSION },
104 : { "pretty", no_argument, NULL, 'p' },
105 : { "app-specific", required_argument, NULL, 'a' },
106 : {},
107 : };
108 :
109 : int c, r;
110 :
111 4 : assert(argc >= 0);
112 4 : assert(argv);
113 :
114 4 : while ((c = getopt_long(argc, argv, "hpa:", options, NULL)) >= 0)
115 4 : switch (c) {
116 :
117 3 : case 'h':
118 3 : return help();
119 :
120 0 : case ARG_VERSION:
121 0 : return version();
122 :
123 0 : case 'p':
124 0 : arg_pretty = true;
125 0 : break;
126 :
127 0 : case 'a':
128 0 : r = sd_id128_from_string(optarg, &arg_app);
129 0 : if (r < 0)
130 0 : return log_error_errno(r, "Failed to parse \"%s\" as application-ID: %m", optarg);
131 0 : break;
132 :
133 1 : case '?':
134 1 : return -EINVAL;
135 :
136 0 : default:
137 0 : assert_not_reached("Unhandled option");
138 : }
139 :
140 0 : return 1;
141 : }
142 :
143 0 : static int id128_main(int argc, char *argv[]) {
144 : static const Verb verbs[] = {
145 : { "new", VERB_ANY, 1, 0, verb_new },
146 : { "machine-id", VERB_ANY, 1, 0, verb_machine_id },
147 : { "boot-id", VERB_ANY, 1, 0, verb_boot_id },
148 : { "invocation-id", VERB_ANY, 1, 0, verb_invocation_id },
149 : { "help", VERB_ANY, VERB_ANY, 0, verb_help },
150 : {}
151 : };
152 :
153 0 : return dispatch_verb(argc, argv, verbs, NULL);
154 : }
155 :
156 4 : static int run(int argc, char *argv[]) {
157 : int r;
158 :
159 4 : log_show_color(true);
160 4 : log_parse_environment();
161 4 : log_open();
162 :
163 4 : r = parse_argv(argc, argv);
164 4 : if (r <= 0)
165 4 : return r;
166 :
167 0 : return id128_main(argc, argv);
168 : }
169 :
170 4 : DEFINE_MAIN_FUNCTION(run);
|