]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/machine-id-setup/machine-id-setup-main.c
Merge pull request #31524 from poettering/secure-getenv-naming-fix
[thirdparty/systemd.git] / src / machine-id-setup / machine-id-setup-main.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include <errno.h>
4 #include <getopt.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7
8 #include "alloc-util.h"
9 #include "build.h"
10 #include "dissect-image.h"
11 #include "id128-util.h"
12 #include "log.h"
13 #include "machine-id-setup.h"
14 #include "main-func.h"
15 #include "mount-util.h"
16 #include "parse-argument.h"
17 #include "path-util.h"
18 #include "pretty-print.h"
19 #include "terminal-util.h"
20
21 static char *arg_root = NULL;
22 static char *arg_image = NULL;
23 static bool arg_commit = false;
24 static bool arg_print = false;
25 static ImagePolicy *arg_image_policy = NULL;
26
27 STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
28 STATIC_DESTRUCTOR_REGISTER(arg_image, freep);
29 STATIC_DESTRUCTOR_REGISTER(arg_image_policy, image_policy_freep);
30
31 static int help(void) {
32 _cleanup_free_ char *link = NULL;
33 int r;
34
35 r = terminal_urlify_man("systemd-machine-id-setup", "1", &link);
36 if (r < 0)
37 return log_oom();
38
39 printf("%s [OPTIONS...]\n"
40 "\n%sInitialize /etc/machine-id from a random source.%s\n\n"
41 " -h --help Show this help\n"
42 " --version Show package version\n"
43 " --root=PATH Operate on an alternate filesystem root\n"
44 " --image=PATH Operate on disk image as filesystem root\n"
45 " --image-policy=POLICY Specify disk image dissection policy\n"
46 " --commit Commit transient ID\n"
47 " --print Print used machine ID\n"
48 "\nSee the %s for details.\n",
49 program_invocation_short_name,
50 ansi_highlight(),
51 ansi_normal(),
52 link);
53
54 return 0;
55 }
56
57 static int parse_argv(int argc, char *argv[]) {
58
59 enum {
60 ARG_VERSION = 0x100,
61 ARG_ROOT,
62 ARG_IMAGE,
63 ARG_IMAGE_POLICY,
64 ARG_COMMIT,
65 ARG_PRINT,
66 };
67
68 static const struct option options[] = {
69 { "help", no_argument, NULL, 'h' },
70 { "version", no_argument, NULL, ARG_VERSION },
71 { "root", required_argument, NULL, ARG_ROOT },
72 { "image", required_argument, NULL, ARG_IMAGE },
73 { "image-policy", required_argument, NULL, ARG_IMAGE_POLICY },
74 { "commit", no_argument, NULL, ARG_COMMIT },
75 { "print", no_argument, NULL, ARG_PRINT },
76 {}
77 };
78
79 int c, r;
80
81 assert(argc >= 0);
82 assert(argv);
83
84 while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
85
86 switch (c) {
87
88 case 'h':
89 return help();
90
91 case ARG_VERSION:
92 return version();
93
94 case ARG_ROOT:
95 r = parse_path_argument(optarg, true, &arg_root);
96 if (r < 0)
97 return r;
98 break;
99
100 case ARG_IMAGE:
101 r = parse_path_argument(optarg, false, &arg_image);
102 if (r < 0)
103 return r;
104 break;
105
106 case ARG_IMAGE_POLICY:
107 r = parse_image_policy_argument(optarg, &arg_image_policy);
108 if (r < 0)
109 return r;
110 break;
111
112 case ARG_COMMIT:
113 arg_commit = true;
114 break;
115
116 case ARG_PRINT:
117 arg_print = true;
118 break;
119
120 case '?':
121 return -EINVAL;
122
123 default:
124 assert_not_reached();
125 }
126
127 if (optind < argc)
128 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
129 "Extraneous arguments");
130
131 if (arg_image && arg_root)
132 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Please specify either --root= or --image=, the combination of both is not supported.");
133
134 return 1;
135 }
136
137 static int run(int argc, char *argv[]) {
138 _cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL;
139 _cleanup_(umount_and_freep) char *mounted_dir = NULL;
140 int r;
141
142 log_parse_environment();
143 log_open();
144
145 r = parse_argv(argc, argv);
146 if (r <= 0)
147 return r;
148
149 if (arg_image) {
150 assert(!arg_root);
151
152 r = mount_image_privately_interactively(
153 arg_image,
154 arg_image_policy,
155 DISSECT_IMAGE_REQUIRE_ROOT |
156 DISSECT_IMAGE_VALIDATE_OS |
157 DISSECT_IMAGE_RELAX_VAR_CHECK |
158 DISSECT_IMAGE_FSCK |
159 DISSECT_IMAGE_GROWFS,
160 &mounted_dir,
161 /* ret_dir_fd= */ NULL,
162 &loop_device);
163 if (r < 0)
164 return r;
165
166 arg_root = strdup(mounted_dir);
167 if (!arg_root)
168 return log_oom();
169 }
170
171 if (arg_commit) {
172 sd_id128_t id;
173
174 r = machine_id_commit(arg_root);
175 if (r < 0)
176 return r;
177
178 r = id128_get_machine(arg_root, &id);
179 if (r < 0)
180 return log_error_errno(r, "Failed to read machine ID back: %m");
181
182 if (arg_print)
183 puts(SD_ID128_TO_STRING(id));
184
185 } else if (id128_get_machine(arg_root, NULL) == -ENOPKG) {
186 if (arg_print)
187 puts("uninitialized");
188 } else {
189 sd_id128_t id;
190
191 r = machine_id_setup(arg_root, false, SD_ID128_NULL, &id);
192 if (r < 0)
193 return r;
194
195 if (arg_print)
196 puts(SD_ID128_TO_STRING(id));
197 }
198
199 return 0;
200 }
201
202 DEFINE_MAIN_FUNCTION(run);