Bug Summary

File:build-scan/../src/import/importd.c
Warning:line 206, column 16
Potential leak of memory pointed to by 'n'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name importd.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -menable-no-infs -menable-no-nans -menable-unsafe-fp-math -fno-signed-zeros -mreassociate -freciprocal-math -fdenormal-fp-math=preserve-sign,preserve-sign -ffp-contract=fast -fno-rounding-math -ffast-math -ffinite-math-only -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -include config.h -I systemd-importd.p -I . -I .. -I src/basic -I ../src/basic -I src/shared -I ../src/shared -I src/systemd -I ../src/systemd -I src/journal -I ../src/journal -I src/journal-remote -I ../src/journal-remote -I src/nspawn -I ../src/nspawn -I src/resolve -I ../src/resolve -I src/timesync -I ../src/timesync -I ../src/time-wait-sync -I src/login -I ../src/login -I src/udev -I ../src/udev -I src/libudev -I ../src/libudev -I src/core -I ../src/core -I ../src/libsystemd/sd-bus -I ../src/libsystemd/sd-device -I ../src/libsystemd/sd-hwdb -I ../src/libsystemd/sd-id128 -I ../src/libsystemd/sd-netlink -I ../src/libsystemd/sd-network -I src/libsystemd-network -I ../src/libsystemd-network -D _FILE_OFFSET_BITS=64 -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wwrite-strings -Wno-unused-parameter -Wno-missing-field-initializers -Wno-unused-result -Wno-format-signedness -Wno-error=nonnull -std=gnu99 -fconst-strings -fdebug-compilation-dir /home/mrc0mmand/repos/@redhat-plumbers/systemd-rhel8/build-scan -ferror-limit 19 -fvisibility hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -analyzer-output=html -faddrsig -o /tmp/scan-build-2021-07-16-221226-1465241-1 -x c ../src/import/importd.c
1/* SPDX-License-Identifier: LGPL-2.1+ */
2
3#include <sys/prctl.h>
4#include <sys/wait.h>
5
6#include "sd-bus.h"
7
8#include "alloc-util.h"
9#include "bus-common-errors.h"
10#include "bus-util.h"
11#include "def.h"
12#include "fd-util.h"
13#include "hostname-util.h"
14#include "import-util.h"
15#include "machine-pool.h"
16#include "missing.h"
17#include "mkdir.h"
18#include "parse-util.h"
19#include "path-util.h"
20#include "process-util.h"
21#include "signal-util.h"
22#include "socket-util.h"
23#include "string-table.h"
24#include "strv.h"
25#include "syslog-util.h"
26#include "user-util.h"
27#include "util.h"
28#include "web-util.h"
29
30typedef struct Transfer Transfer;
31typedef struct Manager Manager;
32
33typedef enum TransferType {
34 TRANSFER_IMPORT_TAR,
35 TRANSFER_IMPORT_RAW,
36 TRANSFER_EXPORT_TAR,
37 TRANSFER_EXPORT_RAW,
38 TRANSFER_PULL_TAR,
39 TRANSFER_PULL_RAW,
40 _TRANSFER_TYPE_MAX,
41 _TRANSFER_TYPE_INVALID = -1,
42} TransferType;
43
44struct Transfer {
45 Manager *manager;
46
47 uint32_t id;
48 char *object_path;
49
50 TransferType type;
51 ImportVerify verify;
52
53 char *remote;
54 char *local;
55 bool_Bool force_local;
56 bool_Bool read_only;
57
58 char *format;
59
60 pid_t pid;
61
62 int log_fd;
63
64 char log_message[LINE_MAX2048];
65 size_t log_message_size;
66
67 sd_event_source *pid_event_source;
68 sd_event_source *log_event_source;
69
70 unsigned n_canceled;
71 unsigned progress_percent;
72
73 int stdin_fd;
74 int stdout_fd;
75};
76
77struct Manager {
78 sd_event *event;
79 sd_bus *bus;
80
81 uint32_t current_transfer_id;
82 Hashmap *transfers;
83
84 Hashmap *polkit_registry;
85
86 int notify_fd;
87
88 sd_event_source *notify_event_source;
89};
90
91#define TRANSFERS_MAX64 64
92
93static const char* const transfer_type_table[_TRANSFER_TYPE_MAX] = {
94 [TRANSFER_IMPORT_TAR] = "import-tar",
95 [TRANSFER_IMPORT_RAW] = "import-raw",
96 [TRANSFER_EXPORT_TAR] = "export-tar",
97 [TRANSFER_EXPORT_RAW] = "export-raw",
98 [TRANSFER_PULL_TAR] = "pull-tar",
99 [TRANSFER_PULL_RAW] = "pull-raw",
100};
101
102DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(transfer_type, TransferType)static const char *transfer_type_to_string(TransferType i) { if
(i < 0 || i >= (TransferType) __extension__ (__builtin_choose_expr
( !__builtin_types_compatible_p(typeof(transfer_type_table), typeof
(&*(transfer_type_table))), sizeof(transfer_type_table)/sizeof
((transfer_type_table)[0]), ((void)0)))) return ((void*)0); return
transfer_type_table[i]; }
;
103
104static Transfer *transfer_unref(Transfer *t) {
105 if (!t)
106 return NULL((void*)0);
107
108 if (t->manager)
109 hashmap_remove(t->manager->transfers, UINT32_TO_PTR(t->id)((void *) ((uintptr_t) (t->id))));
110
111 sd_event_source_unref(t->pid_event_source);
112 sd_event_source_unref(t->log_event_source);
113
114 free(t->remote);
115 free(t->local);
116 free(t->format);
117 free(t->object_path);
118
119 if (t->pid > 0) {
120 (void) kill_and_sigcont(t->pid, SIGKILL9);
121 (void) wait_for_terminate(t->pid, NULL((void*)0));
122 }
123
124 safe_close(t->log_fd);
125 safe_close(t->stdin_fd);
126 safe_close(t->stdout_fd);
127
128 return mfree(t);
129}
130
131DEFINE_TRIVIAL_CLEANUP_FUNC(Transfer*, transfer_unref)static inline void transfer_unrefp(Transfer* *p) { if (*p) transfer_unref
(*p); }
;
132
133static int transfer_new(Manager *m, Transfer **ret) {
134 _cleanup_(transfer_unrefp)__attribute__((cleanup(transfer_unrefp))) Transfer *t = NULL((void*)0);
135 uint32_t id;
136 int r;
137
138 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/import/importd.c", 138, __PRETTY_FUNCTION__
); } while (0)
;
139 assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/import/importd.c", 139, __PRETTY_FUNCTION__
); } while (0)
;
140
141 if (hashmap_size(m->transfers) >= TRANSFERS_MAX64)
142 return -E2BIG7;
143
144 r = hashmap_ensure_allocated(&m->transfers, &trivial_hash_ops)internal_hashmap_ensure_allocated(&m->transfers, &
trivial_hash_ops )
;
145 if (r < 0)
146 return r;
147
148 t = new0(Transfer, 1)((Transfer*) calloc((1), sizeof(Transfer)));
149 if (!t)
150 return -ENOMEM12;
151
152 t->type = _TRANSFER_TYPE_INVALID;
153 t->log_fd = -1;
154 t->stdin_fd = -1;
155 t->stdout_fd = -1;
156 t->verify = _IMPORT_VERIFY_INVALID;
157
158 id = m->current_transfer_id + 1;
159
160 if (asprintf(&t->object_path, "/org/freedesktop/import1/transfer/_%" PRIu32"u", id) < 0)
161 return -ENOMEM12;
162
163 r = hashmap_put(m->transfers, UINT32_TO_PTR(id)((void *) ((uintptr_t) (id))), t);
164 if (r < 0)
165 return r;
166
167 m->current_transfer_id = id;
168
169 t->manager = m;
170 t->id = id;
171
172 *ret = TAKE_PTR(t)({ typeof(t) _ptr_ = (t); (t) = ((void*)0); _ptr_; });
173
174 return 0;
175}
176
177static void transfer_send_log_line(Transfer *t, const char *line) {
178 int r, priority = LOG_INFO6;
179
180 assert(t)do { if ((__builtin_expect(!!(!(t)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("t"), "../src/import/importd.c", 180, __PRETTY_FUNCTION__
); } while (0)
;
181 assert(line)do { if ((__builtin_expect(!!(!(line)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("line"), "../src/import/importd.c", 181,
__PRETTY_FUNCTION__); } while (0)
;
182
183 syslog_parse_priority(&line, &priority, true1);
184
185 log_full(priority, "(transfer%" PRIu32 ") %s", t->id, line)({ int _level = (((priority))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/import/importd.c", 185, __func__, "(transfer%" "u" ") %s"
, t->id, line) : -abs(_e); })
;
186
187 r = sd_bus_emit_signal(
188 t->manager->bus,
189 t->object_path,
190 "org.freedesktop.import1.Transfer",
191 "LogMessage",
192 "us",
193 priority,
194 line);
195 if (r < 0)
196 log_error_errno(r, "Cannot emit message: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/import/importd.c", 196, __func__, "Cannot emit message: %m"
) : -abs(_e); })
;
197 }
198
199static void transfer_send_logs(Transfer *t, bool_Bool flush) {
200 assert(t)do { if ((__builtin_expect(!!(!(t)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("t"), "../src/import/importd.c", 200, __PRETTY_FUNCTION__
); } while (0)
;
10
Taking false branch
11
Loop condition is false. Exiting loop
201
202 /* Try to send out all log messages, if we can. But if we
203 * can't we remove the messages from the buffer, but don't
204 * fail */
205
206 while (t->log_message_size > 0) {
12
Assuming field 'log_message_size' is > 0
13
Loop condition is true. Entering loop body
23
Potential leak of memory pointed to by 'n'
207 _cleanup_free___attribute__((cleanup(freep))) char *n = NULL((void*)0);
208 char *e;
209
210 if (t->log_message_size >= sizeof(t->log_message))
14
Assuming the condition is true
15
Taking true branch
211 e = t->log_message + sizeof(t->log_message);
212 else {
213 char *a, *b;
214
215 a = memchr(t->log_message, 0, t->log_message_size);
216 b = memchr(t->log_message, '\n', t->log_message_size);
217
218 if (a && b)
219 e = a < b ? a : b;
220 else if (a)
221 e = a;
222 else
223 e = b;
224 }
225
226 if (!e
15.1
'e' is non-null
) {
16
Taking false branch
227 if (!flush)
228 return;
229
230 e = t->log_message + t->log_message_size;
231 }
232
233 n = strndup(t->log_message, e - t->log_message);
17
Memory is allocated
234
235 /* Skip over NUL and newlines */
236 while (e < t->log_message + t->log_message_size && (*e == 0 || *e == '\n'))
18
Assuming the condition is false
237 e++;
238
239 memmove(t->log_message, e, t->log_message + sizeof(t->log_message) - e);
240 t->log_message_size -= e - t->log_message;
241
242 if (!n) {
19
Assuming 'n' is non-null
20
Taking false branch
243 log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/import/importd.c"
, 243, __func__)
;
244 continue;
245 }
246
247 if (isempty(n))
21
Taking true branch
248 continue;
22
Execution continues on line 206
249
250 transfer_send_log_line(t, n);
251 }
252}
253
254static int transfer_finalize(Transfer *t, bool_Bool success) {
255 int r;
256
257 assert(t)do { if ((__builtin_expect(!!(!(t)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("t"), "../src/import/importd.c", 257, __PRETTY_FUNCTION__
); } while (0)
;
258
259 transfer_send_logs(t, true1);
260
261 r = sd_bus_emit_signal(
262 t->manager->bus,
263 "/org/freedesktop/import1",
264 "org.freedesktop.import1.Manager",
265 "TransferRemoved",
266 "uos",
267 t->id,
268 t->object_path,
269 success ? "done" :
270 t->n_canceled > 0 ? "canceled" : "failed");
271
272 if (r < 0)
273 log_error_errno(r, "Cannot emit message: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/import/importd.c", 273, __func__, "Cannot emit message: %m"
) : -abs(_e); })
;
274
275 transfer_unref(t);
276 return 0;
277}
278
279static int transfer_cancel(Transfer *t) {
280 int r;
281
282 assert(t)do { if ((__builtin_expect(!!(!(t)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("t"), "../src/import/importd.c", 282, __PRETTY_FUNCTION__
); } while (0)
;
283
284 r = kill_and_sigcont(t->pid, t->n_canceled < 3 ? SIGTERM15 : SIGKILL9);
285 if (r < 0)
286 return r;
287
288 t->n_canceled++;
289 return 0;
290}
291
292static int transfer_on_pid(sd_event_source *s, const siginfo_t *si, void *userdata) {
293 Transfer *t = userdata;
294 bool_Bool success = false0;
295
296 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/import/importd.c", 296, __PRETTY_FUNCTION__
); } while (0)
;
297 assert(t)do { if ((__builtin_expect(!!(!(t)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("t"), "../src/import/importd.c", 297, __PRETTY_FUNCTION__
); } while (0)
;
298
299 if (si->si_code == CLD_EXITEDCLD_EXITED) {
300 if (si->si_status_sifields._sigchld.si_status != 0)
301 log_error("Import process failed with exit code %i.", si->si_status)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/import/importd.c", 301, __func__, "Import process failed with exit code %i."
, si->_sifields._sigchld.si_status) : -abs(_e); })
;
302 else {
303 log_debug("Import process succeeded.")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/import/importd.c", 303, __func__, "Import process succeeded."
) : -abs(_e); })
;
304 success = true1;
305 }
306
307 } else if (IN_SET(si->si_code, CLD_KILLED, CLD_DUMPED)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){CLD_KILLED, CLD_DUMPED})/sizeof(int)]; switch
(si->si_code) { case CLD_KILLED: case CLD_DUMPED: _found =
1; break; default: break; } _found; })
)
308
309 log_error("Import process terminated by signal %s.", signal_to_string(si->si_status))({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/import/importd.c", 309, __func__, "Import process terminated by signal %s."
, signal_to_string(si->_sifields._sigchld.si_status)) : -abs
(_e); })
;
310 else
311 log_error("Import process failed due to unknown reason.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/import/importd.c", 311, __func__, "Import process failed due to unknown reason."
) : -abs(_e); })
;
312
313 t->pid = 0;
314
315 return transfer_finalize(t, success);
316}
317
318static int transfer_on_log(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
319 Transfer *t = userdata;
320 ssize_t l;
321
322 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/import/importd.c", 322, __PRETTY_FUNCTION__
); } while (0)
;
1
Assuming 's' is non-null
2
Taking false branch
3
Loop condition is false. Exiting loop
323 assert(t)do { if ((__builtin_expect(!!(!(t)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("t"), "../src/import/importd.c", 323, __PRETTY_FUNCTION__
); } while (0)
;
4
Assuming 't' is non-null
5
Taking false branch
6
Loop condition is false. Exiting loop
324
325 l = read(fd, t->log_message + t->log_message_size, sizeof(t->log_message) - t->log_message_size);
326 if (l <= 0) {
7
Assuming 'l' is > 0
8
Taking false branch
327 /* EOF/read error. We just close the pipe here, and
328 * close the watch, waiting for the SIGCHLD to arrive,
329 * before we do anything else. */
330
331 if (l < 0)
332 log_error_errno(errno, "Failed to read log message: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/import/importd.c", 332, __func__
, "Failed to read log message: %m") : -abs(_e); })
;
333
334 t->log_event_source = sd_event_source_unref(t->log_event_source);
335 return 0;
336 }
337
338 t->log_message_size += l;
339
340 transfer_send_logs(t, false0);
9
Calling 'transfer_send_logs'
341
342 return 0;
343}
344
345static int transfer_start(Transfer *t) {
346 _cleanup_close_pair___attribute__((cleanup(close_pairp))) int pipefd[2] = { -1, -1 };
347 int r;
348
349 assert(t)do { if ((__builtin_expect(!!(!(t)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("t"), "../src/import/importd.c", 349, __PRETTY_FUNCTION__
); } while (0)
;
350 assert(t->pid <= 0)do { if ((__builtin_expect(!!(!(t->pid <= 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("t->pid <= 0"), "../src/import/importd.c"
, 350, __PRETTY_FUNCTION__); } while (0)
;
351
352 if (pipe2(pipefd, O_CLOEXEC02000000) < 0)
353 return -errno(*__errno_location ());
354
355 r = safe_fork("(sd-transfer)", FORK_RESET_SIGNALS|FORK_DEATHSIG, &t->pid);
356 if (r < 0)
357 return r;
358 if (r == 0) {
359 const char *cmd[] = {
360 NULL((void*)0), /* systemd-import, systemd-export or systemd-pull */
361 NULL((void*)0), /* tar, raw */
362 NULL((void*)0), /* --verify= */
363 NULL((void*)0), /* verify argument */
364 NULL((void*)0), /* maybe --force */
365 NULL((void*)0), /* maybe --read-only */
366 NULL((void*)0), /* if so: the actual URL */
367 NULL((void*)0), /* maybe --format= */
368 NULL((void*)0), /* if so: the actual format */
369 NULL((void*)0), /* remote */
370 NULL((void*)0), /* local */
371 NULL((void*)0)
372 };
373 unsigned k = 0;
374
375 /* Child */
376
377 pipefd[0] = safe_close(pipefd[0]);
378
379 r = rearrange_stdio(t->stdin_fd,
380 t->stdout_fd < 0 ? pipefd[1] : t->stdout_fd,
381 pipefd[1]);
382 if (r < 0) {
383 log_error_errno(r, "Failed to set stdin/stdout/stderr: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/import/importd.c", 383, __func__, "Failed to set stdin/stdout/stderr: %m"
) : -abs(_e); })
;
384 _exit(EXIT_FAILURE1);
385 }
386
387 if (setenv("SYSTEMD_LOG_TARGET", "console-prefixed", 1) < 0 ||
388 setenv("NOTIFY_SOCKET", "/run/systemd/import/notify", 1) < 0) {
389 log_error_errno(errno, "setenv() failed: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/import/importd.c", 389, __func__
, "setenv() failed: %m") : -abs(_e); })
;
390 _exit(EXIT_FAILURE1);
391 }
392
393 if (IN_SET(t->type, TRANSFER_IMPORT_TAR, TRANSFER_IMPORT_RAW)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){TRANSFER_IMPORT_TAR, TRANSFER_IMPORT_RAW
})/sizeof(int)]; switch(t->type) { case TRANSFER_IMPORT_TAR
: case TRANSFER_IMPORT_RAW: _found = 1; break; default: break
; } _found; })
)
394 cmd[k++] = SYSTEMD_IMPORT_PATH"/usr/lib/systemd/systemd-import";
395 else if (IN_SET(t->type, TRANSFER_EXPORT_TAR, TRANSFER_EXPORT_RAW)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){TRANSFER_EXPORT_TAR, TRANSFER_EXPORT_RAW
})/sizeof(int)]; switch(t->type) { case TRANSFER_EXPORT_TAR
: case TRANSFER_EXPORT_RAW: _found = 1; break; default: break
; } _found; })
)
396 cmd[k++] = SYSTEMD_EXPORT_PATH"/usr/lib/systemd/systemd-export";
397 else
398 cmd[k++] = SYSTEMD_PULL_PATH"/usr/lib/systemd/systemd-pull";
399
400 if (IN_SET(t->type, TRANSFER_IMPORT_TAR, TRANSFER_EXPORT_TAR, TRANSFER_PULL_TAR)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){TRANSFER_IMPORT_TAR, TRANSFER_EXPORT_TAR
, TRANSFER_PULL_TAR})/sizeof(int)]; switch(t->type) { case
TRANSFER_IMPORT_TAR: case TRANSFER_EXPORT_TAR: case TRANSFER_PULL_TAR
: _found = 1; break; default: break; } _found; })
)
401 cmd[k++] = "tar";
402 else
403 cmd[k++] = "raw";
404
405 if (t->verify != _IMPORT_VERIFY_INVALID) {
406 cmd[k++] = "--verify";
407 cmd[k++] = import_verify_to_string(t->verify);
408 }
409
410 if (t->force_local)
411 cmd[k++] = "--force";
412 if (t->read_only)
413 cmd[k++] = "--read-only";
414
415 if (t->format) {
416 cmd[k++] = "--format";
417 cmd[k++] = t->format;
418 }
419
420 if (!IN_SET(t->type, TRANSFER_EXPORT_TAR, TRANSFER_EXPORT_RAW)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){TRANSFER_EXPORT_TAR, TRANSFER_EXPORT_RAW
})/sizeof(int)]; switch(t->type) { case TRANSFER_EXPORT_TAR
: case TRANSFER_EXPORT_RAW: _found = 1; break; default: break
; } _found; })
) {
421 if (t->remote)
422 cmd[k++] = t->remote;
423 else
424 cmd[k++] = "-";
425 }
426
427 if (t->local)
428 cmd[k++] = t->local;
429 cmd[k] = NULL((void*)0);
430
431 execv(cmd[0], (char * const *) cmd);
432 log_error_errno(errno, "Failed to execute %s tool: %m", cmd[0])({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/import/importd.c", 432, __func__
, "Failed to execute %s tool: %m", cmd[0]) : -abs(_e); })
;
433 _exit(EXIT_FAILURE1);
434 }
435
436 pipefd[1] = safe_close(pipefd[1]);
437 t->log_fd = TAKE_FD(pipefd[0])({ int _fd_ = (pipefd[0]); (pipefd[0]) = -1; _fd_; });
438
439 t->stdin_fd = safe_close(t->stdin_fd);
440
441 r = sd_event_add_child(t->manager->event, &t->pid_event_source, t->pid, WEXITED4, transfer_on_pid, t);
442 if (r < 0)
443 return r;
444
445 r = sd_event_add_io(t->manager->event, &t->log_event_source, t->log_fd, EPOLLINEPOLLIN, transfer_on_log, t);
446 if (r < 0)
447 return r;
448
449 /* Make sure always process logging before SIGCHLD */
450 r = sd_event_source_set_priority(t->log_event_source, SD_EVENT_PRIORITY_NORMAL -5);
451 if (r < 0)
452 return r;
453
454 r = sd_bus_emit_signal(
455 t->manager->bus,
456 "/org/freedesktop/import1",
457 "org.freedesktop.import1.Manager",
458 "TransferNew",
459 "uo",
460 t->id,
461 t->object_path);
462 if (r < 0)
463 return r;
464
465 return 0;
466}
467
468static Manager *manager_unref(Manager *m) {
469 Transfer *t;
470
471 if (!m)
472 return NULL((void*)0);
473
474 sd_event_source_unref(m->notify_event_source);
475 safe_close(m->notify_fd);
476
477 while ((t = hashmap_first(m->transfers)))
478 transfer_unref(t);
479
480 hashmap_free(m->transfers);
481
482 bus_verify_polkit_async_registry_free(m->polkit_registry);
483
484 m->bus = sd_bus_flush_close_unref(m->bus);
485 sd_event_unref(m->event);
486
487 return mfree(m);
488}
489
490DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_unref)static inline void manager_unrefp(Manager* *p) { if (*p) manager_unref
(*p); }
;
491
492static int manager_on_notify(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
493
494 char buf[NOTIFY_BUFFER_MAX4096+1];
495 struct iovec iovec = {
496 .iov_base = buf,
497 .iov_len = sizeof(buf)-1,
498 };
499 union {
500 struct cmsghdr cmsghdr;
501 uint8_t buf[CMSG_SPACE(sizeof(struct ucred))((((sizeof(struct ucred)) + sizeof (size_t) - 1) & (size_t
) ~(sizeof (size_t) - 1)) + (((sizeof (struct cmsghdr)) + sizeof
(size_t) - 1) & (size_t) ~(sizeof (size_t) - 1)))
+
502 CMSG_SPACE(sizeof(int) * NOTIFY_FD_MAX)((((sizeof(int) * 768) + sizeof (size_t) - 1) & (size_t) ~
(sizeof (size_t) - 1)) + (((sizeof (struct cmsghdr)) + sizeof
(size_t) - 1) & (size_t) ~(sizeof (size_t) - 1)))
];
503 } control = {};
504 struct msghdr msghdr = {
505 .msg_iov = &iovec,
506 .msg_iovlen = 1,
507 .msg_control = &control,
508 .msg_controllen = sizeof(control),
509 };
510 struct ucred *ucred = NULL((void*)0);
511 Manager *m = userdata;
512 struct cmsghdr *cmsg;
513 unsigned percent;
514 char *p, *e;
515 Transfer *t;
516 Iterator i;
517 ssize_t n;
518 int r;
519
520 n = recvmsg(fd, &msghdr, MSG_DONTWAITMSG_DONTWAIT|MSG_CMSG_CLOEXECMSG_CMSG_CLOEXEC);
521 if (n < 0) {
522 if (IN_SET(errno, EAGAIN, EINTR)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){11, 4})/sizeof(int)]; switch((*__errno_location
())) { case 11: case 4: _found = 1; break; default: break; }
_found; })
)
523 return 0;
524
525 return -errno(*__errno_location ());
526 }
527
528 cmsg_close_all(&msghdr);
529
530 CMSG_FOREACH(cmsg, &msghdr)for ((cmsg) = ((size_t) (&msghdr)->msg_controllen >=
sizeof (struct cmsghdr) ? (struct cmsghdr *) (&msghdr)->
msg_control : (struct cmsghdr *) 0); (cmsg); (cmsg) = __cmsg_nxthdr
((&msghdr), (cmsg)))
531 if (cmsg->cmsg_level == SOL_SOCKET1 &&
532 cmsg->cmsg_type == SCM_CREDENTIALSSCM_CREDENTIALS &&
533 cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))((((sizeof (struct cmsghdr)) + sizeof (size_t) - 1) & (size_t
) ~(sizeof (size_t) - 1)) + (sizeof(struct ucred)))
)
534 ucred = (struct ucred*) CMSG_DATA(cmsg)((cmsg)->__cmsg_data);
535
536 if (msghdr.msg_flags & MSG_TRUNCMSG_TRUNC) {
537 log_warning("Got overly long notification datagram, ignoring.")({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/import/importd.c", 537, __func__, "Got overly long notification datagram, ignoring."
) : -abs(_e); })
;
538 return 0;
539 }
540
541 if (!ucred || ucred->pid <= 0) {
542 log_warning("Got notification datagram lacking credential information, ignoring.")({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/import/importd.c", 542, __func__, "Got notification datagram lacking credential information, ignoring."
) : -abs(_e); })
;
543 return 0;
544 }
545
546 HASHMAP_FOREACH(t, m->transfers, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .
next_key = ((void*)0) }); hashmap_iterate((m->transfers), &
(i), (void**)&(t), ((void*)0)); )
547 if (ucred->pid == t->pid)
548 break;
549
550 if (!t) {
551 log_warning("Got notification datagram from unexpected peer, ignoring.")({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/import/importd.c", 551, __func__, "Got notification datagram from unexpected peer, ignoring."
) : -abs(_e); })
;
552 return 0;
553 }
554
555 buf[n] = 0;
556
557 p = startswith(buf, "X_IMPORT_PROGRESS=");
558 if (!p) {
559 p = strstr(buf, "\nX_IMPORT_PROGRESS=");
560 if (!p)
561 return 0;
562
563 p += 19;
564 }
565
566 e = strchrnul(p, '\n');
567 *e = 0;
568
569 r = safe_atou(p, &percent);
570 if (r < 0 || percent > 100) {
571 log_warning("Got invalid percent value, ignoring.")({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/import/importd.c", 571, __func__, "Got invalid percent value, ignoring."
) : -abs(_e); })
;
572 return 0;
573 }
574
575 t->progress_percent = percent;
576
577 log_debug("Got percentage from client: %u%%", percent)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/import/importd.c", 577, __func__, "Got percentage from client: %u%%"
, percent) : -abs(_e); })
;
578 return 0;
579}
580
581static int manager_new(Manager **ret) {
582 _cleanup_(manager_unrefp)__attribute__((cleanup(manager_unrefp))) Manager *m = NULL((void*)0);
583 static const union sockaddr_union sa = {
584 .un.sun_family = AF_UNIX1,
585 .un.sun_path = "/run/systemd/import/notify",
586 };
587 static const int one = 1;
588 int r;
589
590 assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/import/importd.c", 590, __PRETTY_FUNCTION__
); } while (0)
;
591
592 m = new0(Manager, 1)((Manager*) calloc((1), sizeof(Manager)));
593 if (!m)
594 return -ENOMEM12;
595
596 r = sd_event_default(&m->event);
597 if (r < 0)
598 return r;
599
600 sd_event_set_watchdog(m->event, true1);
601
602 r = sd_bus_default_system(&m->bus);
603 if (r < 0)
604 return r;
605
606 m->notify_fd = socket(AF_UNIX1, SOCK_DGRAMSOCK_DGRAM|SOCK_CLOEXECSOCK_CLOEXEC|SOCK_NONBLOCKSOCK_NONBLOCK, 0);
607 if (m->notify_fd < 0)
608 return -errno(*__errno_location ());
609
610 (void) mkdir_parents_label(sa.un.sun_path, 0755);
611 (void) unlink(sa.un.sun_path);
612
613 if (bind(m->notify_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)({ const struct sockaddr_un *_sa = &(sa.un); do { if ((__builtin_expect
(!!(!(_sa->sun_family == 1)),0))) log_assert_failed_realm(
LOG_REALM_SYSTEMD, ("_sa->sun_family == AF_UNIX"), "../src/import/importd.c"
, 613, __PRETTY_FUNCTION__); } while (0); __builtin_offsetof(
struct sockaddr_un, sun_path) + (_sa->sun_path[0] == 0 ? 1
+ strnlen(_sa->sun_path+1, sizeof(_sa->sun_path)-1) : strnlen
(_sa->sun_path, sizeof(_sa->sun_path))); })
) < 0)
614 return -errno(*__errno_location ());
615
616 if (setsockopt(m->notify_fd, SOL_SOCKET1, SO_PASSCRED16, &one, sizeof(one)) < 0)
617 return -errno(*__errno_location ());
618
619 r = sd_event_add_io(m->event, &m->notify_event_source, m->notify_fd, EPOLLINEPOLLIN, manager_on_notify, m);
620 if (r < 0)
621 return r;
622
623 *ret = TAKE_PTR(m)({ typeof(m) _ptr_ = (m); (m) = ((void*)0); _ptr_; });
624
625 return 0;
626}
627
628static Transfer *manager_find(Manager *m, TransferType type, const char *remote) {
629 Transfer *t;
630 Iterator i;
631
632 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/import/importd.c", 632, __PRETTY_FUNCTION__
); } while (0)
;
633 assert(type >= 0)do { if ((__builtin_expect(!!(!(type >= 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("type >= 0"), "../src/import/importd.c"
, 633, __PRETTY_FUNCTION__); } while (0)
;
634 assert(type < _TRANSFER_TYPE_MAX)do { if ((__builtin_expect(!!(!(type < _TRANSFER_TYPE_MAX)
),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("type < _TRANSFER_TYPE_MAX"
), "../src/import/importd.c", 634, __PRETTY_FUNCTION__); } while
(0)
;
635
636 HASHMAP_FOREACH(t, m->transfers, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .
next_key = ((void*)0) }); hashmap_iterate((m->transfers), &
(i), (void**)&(t), ((void*)0)); )
{
637
638 if (t->type == type &&
639 streq_ptr(t->remote, remote))
640 return t;
641 }
642
643 return NULL((void*)0);
644}
645
646static int method_import_tar_or_raw(sd_bus_message *msg, void *userdata, sd_bus_error *error) {
647 _cleanup_(transfer_unrefp)__attribute__((cleanup(transfer_unrefp))) Transfer *t = NULL((void*)0);
648 int fd, force, read_only, r;
649 const char *local, *object;
650 Manager *m = userdata;
651 TransferType type;
652 uint32_t id;
653
654 assert(msg)do { if ((__builtin_expect(!!(!(msg)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("msg"), "../src/import/importd.c", 654, __PRETTY_FUNCTION__
); } while (0)
;
655 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/import/importd.c", 655, __PRETTY_FUNCTION__
); } while (0)
;
656
657 r = bus_verify_polkit_async(
658 msg,
659 CAP_SYS_ADMIN21,
660 "org.freedesktop.import1.import",
661 NULL((void*)0),
662 false0,
663 UID_INVALID((uid_t) -1),
664 &m->polkit_registry,
665 error);
666 if (r < 0)
667 return r;
668 if (r == 0)
669 return 1; /* Will call us back */
670
671 r = sd_bus_message_read(msg, "hsbb", &fd, &local, &force, &read_only);
672 if (r < 0)
673 return r;
674
675 if (!machine_name_is_valid(local)hostname_is_valid(local, 0))
676 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS"org.freedesktop.DBus.Error.InvalidArgs", "Local name %s is invalid", local);
677
678 r = setup_machine_directory((uint64_t) -1, error);
679 if (r < 0)
680 return r;
681
682 type = streq_ptr(sd_bus_message_get_member(msg), "ImportTar") ? TRANSFER_IMPORT_TAR : TRANSFER_IMPORT_RAW;
683
684 r = transfer_new(m, &t);
685 if (r < 0)
686 return r;
687
688 t->type = type;
689 t->force_local = force;
690 t->read_only = read_only;
691
692 t->local = strdup(local);
693 if (!t->local)
694 return -ENOMEM12;
695
696 t->stdin_fd = fcntl(fd, F_DUPFD_CLOEXEC1030, 3);
697 if (t->stdin_fd < 0)
698 return -errno(*__errno_location ());
699
700 r = transfer_start(t);
701 if (r < 0)
702 return r;
703
704 object = t->object_path;
705 id = t->id;
706 t = NULL((void*)0);
707
708 return sd_bus_reply_method_return(msg, "uo", id, object);
709}
710
711static int method_export_tar_or_raw(sd_bus_message *msg, void *userdata, sd_bus_error *error) {
712 _cleanup_(transfer_unrefp)__attribute__((cleanup(transfer_unrefp))) Transfer *t = NULL((void*)0);
713 int fd, r;
714 const char *local, *object, *format;
715 Manager *m = userdata;
716 TransferType type;
717 uint32_t id;
718
719 assert(msg)do { if ((__builtin_expect(!!(!(msg)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("msg"), "../src/import/importd.c", 719, __PRETTY_FUNCTION__
); } while (0)
;
720 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/import/importd.c", 720, __PRETTY_FUNCTION__
); } while (0)
;
721
722 r = bus_verify_polkit_async(
723 msg,
724 CAP_SYS_ADMIN21,
725 "org.freedesktop.import1.export",
726 NULL((void*)0),
727 false0,
728 UID_INVALID((uid_t) -1),
729 &m->polkit_registry,
730 error);
731 if (r < 0)
732 return r;
733 if (r == 0)
734 return 1; /* Will call us back */
735
736 r = sd_bus_message_read(msg, "shs", &local, &fd, &format);
737 if (r < 0)
738 return r;
739
740 if (!machine_name_is_valid(local)hostname_is_valid(local, 0))
741 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS"org.freedesktop.DBus.Error.InvalidArgs", "Local name %s is invalid", local);
742
743 type = streq_ptr(sd_bus_message_get_member(msg), "ExportTar") ? TRANSFER_EXPORT_TAR : TRANSFER_EXPORT_RAW;
744
745 r = transfer_new(m, &t);
746 if (r < 0)
747 return r;
748
749 t->type = type;
750
751 if (!isempty(format)) {
752 t->format = strdup(format);
753 if (!t->format)
754 return -ENOMEM12;
755 }
756
757 t->local = strdup(local);
758 if (!t->local)
759 return -ENOMEM12;
760
761 t->stdout_fd = fcntl(fd, F_DUPFD_CLOEXEC1030, 3);
762 if (t->stdout_fd < 0)
763 return -errno(*__errno_location ());
764
765 r = transfer_start(t);
766 if (r < 0)
767 return r;
768
769 object = t->object_path;
770 id = t->id;
771 t = NULL((void*)0);
772
773 return sd_bus_reply_method_return(msg, "uo", id, object);
774}
775
776static int method_pull_tar_or_raw(sd_bus_message *msg, void *userdata, sd_bus_error *error) {
777 _cleanup_(transfer_unrefp)__attribute__((cleanup(transfer_unrefp))) Transfer *t = NULL((void*)0);
778 const char *remote, *local, *verify, *object;
779 Manager *m = userdata;
780 ImportVerify v;
781 TransferType type;
782 int force, r;
783 uint32_t id;
784
785 assert(msg)do { if ((__builtin_expect(!!(!(msg)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("msg"), "../src/import/importd.c", 785, __PRETTY_FUNCTION__
); } while (0)
;
786 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/import/importd.c", 786, __PRETTY_FUNCTION__
); } while (0)
;
787
788 r = bus_verify_polkit_async(
789 msg,
790 CAP_SYS_ADMIN21,
791 "org.freedesktop.import1.pull",
792 NULL((void*)0),
793 false0,
794 UID_INVALID((uid_t) -1),
795 &m->polkit_registry,
796 error);
797 if (r < 0)
798 return r;
799 if (r == 0)
800 return 1; /* Will call us back */
801
802 r = sd_bus_message_read(msg, "sssb", &remote, &local, &verify, &force);
803 if (r < 0)
804 return r;
805
806 if (!http_url_is_valid(remote))
807 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS"org.freedesktop.DBus.Error.InvalidArgs", "URL %s is invalid", remote);
808
809 if (isempty(local))
810 local = NULL((void*)0);
811 else if (!machine_name_is_valid(local)hostname_is_valid(local, 0))
812 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS"org.freedesktop.DBus.Error.InvalidArgs", "Local name %s is invalid", local);
813
814 if (isempty(verify))
815 v = IMPORT_VERIFY_SIGNATURE;
816 else
817 v = import_verify_from_string(verify);
818 if (v < 0)
819 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS"org.freedesktop.DBus.Error.InvalidArgs", "Unknown verification mode %s", verify);
820
821 r = setup_machine_directory((uint64_t) -1, error);
822 if (r < 0)
823 return r;
824
825 type = streq_ptr(sd_bus_message_get_member(msg), "PullTar") ? TRANSFER_PULL_TAR : TRANSFER_PULL_RAW;
826
827 if (manager_find(m, type, remote))
828 return sd_bus_error_setf(error, BUS_ERROR_TRANSFER_IN_PROGRESS"org.freedesktop.import1.TransferInProgress", "Transfer for %s already in progress.", remote);
829
830 r = transfer_new(m, &t);
831 if (r < 0)
832 return r;
833
834 t->type = type;
835 t->verify = v;
836 t->force_local = force;
837
838 t->remote = strdup(remote);
839 if (!t->remote)
840 return -ENOMEM12;
841
842 if (local) {
843 t->local = strdup(local);
844 if (!t->local)
845 return -ENOMEM12;
846 }
847
848 r = transfer_start(t);
849 if (r < 0)
850 return r;
851
852 object = t->object_path;
853 id = t->id;
854 t = NULL((void*)0);
855
856 return sd_bus_reply_method_return(msg, "uo", id, object);
857}
858
859static int method_list_transfers(sd_bus_message *msg, void *userdata, sd_bus_error *error) {
860 _cleanup_(sd_bus_message_unrefp)__attribute__((cleanup(sd_bus_message_unrefp))) sd_bus_message *reply = NULL((void*)0);
861 Manager *m = userdata;
862 Transfer *t;
863 Iterator i;
864 int r;
865
866 assert(msg)do { if ((__builtin_expect(!!(!(msg)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("msg"), "../src/import/importd.c", 866, __PRETTY_FUNCTION__
); } while (0)
;
867 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/import/importd.c", 867, __PRETTY_FUNCTION__
); } while (0)
;
868
869 r = sd_bus_message_new_method_return(msg, &reply);
870 if (r < 0)
871 return r;
872
873 r = sd_bus_message_open_container(reply, 'a', "(usssdo)");
874 if (r < 0)
875 return r;
876
877 HASHMAP_FOREACH(t, m->transfers, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .
next_key = ((void*)0) }); hashmap_iterate((m->transfers), &
(i), (void**)&(t), ((void*)0)); )
{
878
879 r = sd_bus_message_append(
880 reply,
881 "(usssdo)",
882 t->id,
883 transfer_type_to_string(t->type),
884 t->remote,
885 t->local,
886 (double) t->progress_percent / 100.0,
887 t->object_path);
888 if (r < 0)
889 return r;
890 }
891
892 r = sd_bus_message_close_container(reply);
893 if (r < 0)
894 return r;
895
896 return sd_bus_send(NULL((void*)0), reply, NULL((void*)0));
897}
898
899static int method_cancel(sd_bus_message *msg, void *userdata, sd_bus_error *error) {
900 Transfer *t = userdata;
901 int r;
902
903 assert(msg)do { if ((__builtin_expect(!!(!(msg)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("msg"), "../src/import/importd.c", 903, __PRETTY_FUNCTION__
); } while (0)
;
904 assert(t)do { if ((__builtin_expect(!!(!(t)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("t"), "../src/import/importd.c", 904, __PRETTY_FUNCTION__
); } while (0)
;
905
906 r = bus_verify_polkit_async(
907 msg,
908 CAP_SYS_ADMIN21,
909 "org.freedesktop.import1.pull",
910 NULL((void*)0),
911 false0,
912 UID_INVALID((uid_t) -1),
913 &t->manager->polkit_registry,
914 error);
915 if (r < 0)
916 return r;
917 if (r == 0)
918 return 1; /* Will call us back */
919
920 r = transfer_cancel(t);
921 if (r < 0)
922 return r;
923
924 return sd_bus_reply_method_return(msg, NULL((void*)0));
925}
926
927static int method_cancel_transfer(sd_bus_message *msg, void *userdata, sd_bus_error *error) {
928 Manager *m = userdata;
929 Transfer *t;
930 uint32_t id;
931 int r;
932
933 assert(msg)do { if ((__builtin_expect(!!(!(msg)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("msg"), "../src/import/importd.c", 933, __PRETTY_FUNCTION__
); } while (0)
;
934 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/import/importd.c", 934, __PRETTY_FUNCTION__
); } while (0)
;
935
936 r = bus_verify_polkit_async(
937 msg,
938 CAP_SYS_ADMIN21,
939 "org.freedesktop.import1.pull",
940 NULL((void*)0),
941 false0,
942 UID_INVALID((uid_t) -1),
943 &m->polkit_registry,
944 error);
945 if (r < 0)
946 return r;
947 if (r == 0)
948 return 1; /* Will call us back */
949
950 r = sd_bus_message_read(msg, "u", &id);
951 if (r < 0)
952 return r;
953 if (id <= 0)
954 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS"org.freedesktop.DBus.Error.InvalidArgs", "Invalid transfer id");
955
956 t = hashmap_get(m->transfers, UINT32_TO_PTR(id)((void *) ((uintptr_t) (id))));
957 if (!t)
958 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_TRANSFER"org.freedesktop.import1.NoSuchTransfer", "No transfer by id %" PRIu32"u", id);
959
960 r = transfer_cancel(t);
961 if (r < 0)
962 return r;
963
964 return sd_bus_reply_method_return(msg, NULL((void*)0));
965}
966
967static int property_get_progress(
968 sd_bus *bus,
969 const char *path,
970 const char *interface,
971 const char *property,
972 sd_bus_message *reply,
973 void *userdata,
974 sd_bus_error *error) {
975
976 Transfer *t = userdata;
977
978 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/import/importd.c", 978, __PRETTY_FUNCTION__
); } while (0)
;
979 assert(reply)do { if ((__builtin_expect(!!(!(reply)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("reply"), "../src/import/importd.c", 979
, __PRETTY_FUNCTION__); } while (0)
;
980 assert(t)do { if ((__builtin_expect(!!(!(t)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("t"), "../src/import/importd.c", 980, __PRETTY_FUNCTION__
); } while (0)
;
981
982 return sd_bus_message_append(reply, "d", (double) t->progress_percent / 100.0);
983}
984
985static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_type, transfer_type, TransferType)int property_get_type(sd_bus *bus, const char *path, const char
*interface, const char *property, sd_bus_message *reply, void
*userdata, sd_bus_error *error) { TransferType *data = userdata
; do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/import/importd.c", 985, __PRETTY_FUNCTION__
); } while (0); do { if ((__builtin_expect(!!(!(reply)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("reply"), "../src/import/importd.c", 985
, __PRETTY_FUNCTION__); } while (0); do { if ((__builtin_expect
(!!(!(data)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, (
"data"), "../src/import/importd.c", 985, __PRETTY_FUNCTION__)
; } while (0); return sd_bus_message_append(reply, "s", transfer_type_to_string
((*(data)))); }
;
986static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_verify, import_verify, ImportVerify)int property_get_verify(sd_bus *bus, const char *path, const char
*interface, const char *property, sd_bus_message *reply, void
*userdata, sd_bus_error *error) { ImportVerify *data = userdata
; do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/import/importd.c", 986, __PRETTY_FUNCTION__
); } while (0); do { if ((__builtin_expect(!!(!(reply)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("reply"), "../src/import/importd.c", 986
, __PRETTY_FUNCTION__); } while (0); do { if ((__builtin_expect
(!!(!(data)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, (
"data"), "../src/import/importd.c", 986, __PRETTY_FUNCTION__)
; } while (0); return sd_bus_message_append(reply, "s", import_verify_to_string
((*(data)))); }
;
987
988static const sd_bus_vtable transfer_vtable[] = {
989 SD_BUS_VTABLE_START(0){ .type = _SD_BUS_VTABLE_START, .flags = 0, .x = { .start = {
.element_size = sizeof(sd_bus_vtable) }, }, }
,
990 SD_BUS_PROPERTY("Id", "u", NULL, offsetof(Transfer, id), SD_BUS_VTABLE_PROPERTY_CONST){ .type = _SD_BUS_VTABLE_PROPERTY, .flags = SD_BUS_VTABLE_PROPERTY_CONST
, .x = { .property = { .member = "Id", .signature = "u", .get
= ((void*)0), .set = ((void*)0), .offset = __builtin_offsetof
(Transfer, id), }, }, }
,
991 SD_BUS_PROPERTY("Local", "s", NULL, offsetof(Transfer, local), SD_BUS_VTABLE_PROPERTY_CONST){ .type = _SD_BUS_VTABLE_PROPERTY, .flags = SD_BUS_VTABLE_PROPERTY_CONST
, .x = { .property = { .member = "Local", .signature = "s", .
get = ((void*)0), .set = ((void*)0), .offset = __builtin_offsetof
(Transfer, local), }, }, }
,
992 SD_BUS_PROPERTY("Remote", "s", NULL, offsetof(Transfer, remote), SD_BUS_VTABLE_PROPERTY_CONST){ .type = _SD_BUS_VTABLE_PROPERTY, .flags = SD_BUS_VTABLE_PROPERTY_CONST
, .x = { .property = { .member = "Remote", .signature = "s", .
get = ((void*)0), .set = ((void*)0), .offset = __builtin_offsetof
(Transfer, remote), }, }, }
,
993 SD_BUS_PROPERTY("Type", "s", property_get_type, offsetof(Transfer, type), SD_BUS_VTABLE_PROPERTY_CONST){ .type = _SD_BUS_VTABLE_PROPERTY, .flags = SD_BUS_VTABLE_PROPERTY_CONST
, .x = { .property = { .member = "Type", .signature = "s", .get
= property_get_type, .set = ((void*)0), .offset = __builtin_offsetof
(Transfer, type), }, }, }
,
994 SD_BUS_PROPERTY("Verify", "s", property_get_verify, offsetof(Transfer, verify), SD_BUS_VTABLE_PROPERTY_CONST){ .type = _SD_BUS_VTABLE_PROPERTY, .flags = SD_BUS_VTABLE_PROPERTY_CONST
, .x = { .property = { .member = "Verify", .signature = "s", .
get = property_get_verify, .set = ((void*)0), .offset = __builtin_offsetof
(Transfer, verify), }, }, }
,
995 SD_BUS_PROPERTY("Progress", "d", property_get_progress, 0, 0){ .type = _SD_BUS_VTABLE_PROPERTY, .flags = 0, .x = { .property
= { .member = "Progress", .signature = "d", .get = property_get_progress
, .set = ((void*)0), .offset = 0, }, }, }
,
996 SD_BUS_METHOD("Cancel", NULL, NULL, method_cancel, SD_BUS_VTABLE_UNPRIVILEGED){ .type = _SD_BUS_VTABLE_METHOD, .flags = SD_BUS_VTABLE_UNPRIVILEGED
, .x = { .method = { .member = "Cancel", .signature = ((void*
)0), .result = ((void*)0), .handler = method_cancel, .offset =
0, }, }, }
,
997 SD_BUS_SIGNAL("LogMessage", "us", 0){ .type = _SD_BUS_VTABLE_SIGNAL, .flags = 0, .x = { .signal =
{ .member = "LogMessage", .signature = "us", }, }, }
,
998 SD_BUS_VTABLE_END{ .type = _SD_BUS_VTABLE_END, .flags = 0, .x = { { 0 } }, },
999};
1000
1001static const sd_bus_vtable manager_vtable[] = {
1002 SD_BUS_VTABLE_START(0){ .type = _SD_BUS_VTABLE_START, .flags = 0, .x = { .start = {
.element_size = sizeof(sd_bus_vtable) }, }, }
,
1003 SD_BUS_METHOD("ImportTar", "hsbb", "uo", method_import_tar_or_raw, SD_BUS_VTABLE_UNPRIVILEGED){ .type = _SD_BUS_VTABLE_METHOD, .flags = SD_BUS_VTABLE_UNPRIVILEGED
, .x = { .method = { .member = "ImportTar", .signature = "hsbb"
, .result = "uo", .handler = method_import_tar_or_raw, .offset
= 0, }, }, }
,
1004 SD_BUS_METHOD("ImportRaw", "hsbb", "uo", method_import_tar_or_raw, SD_BUS_VTABLE_UNPRIVILEGED){ .type = _SD_BUS_VTABLE_METHOD, .flags = SD_BUS_VTABLE_UNPRIVILEGED
, .x = { .method = { .member = "ImportRaw", .signature = "hsbb"
, .result = "uo", .handler = method_import_tar_or_raw, .offset
= 0, }, }, }
,
1005 SD_BUS_METHOD("ExportTar", "shs", "uo", method_export_tar_or_raw, SD_BUS_VTABLE_UNPRIVILEGED){ .type = _SD_BUS_VTABLE_METHOD, .flags = SD_BUS_VTABLE_UNPRIVILEGED
, .x = { .method = { .member = "ExportTar", .signature = "shs"
, .result = "uo", .handler = method_export_tar_or_raw, .offset
= 0, }, }, }
,
1006 SD_BUS_METHOD("ExportRaw", "shs", "uo", method_export_tar_or_raw, SD_BUS_VTABLE_UNPRIVILEGED){ .type = _SD_BUS_VTABLE_METHOD, .flags = SD_BUS_VTABLE_UNPRIVILEGED
, .x = { .method = { .member = "ExportRaw", .signature = "shs"
, .result = "uo", .handler = method_export_tar_or_raw, .offset
= 0, }, }, }
,
1007 SD_BUS_METHOD("PullTar", "sssb", "uo", method_pull_tar_or_raw, SD_BUS_VTABLE_UNPRIVILEGED){ .type = _SD_BUS_VTABLE_METHOD, .flags = SD_BUS_VTABLE_UNPRIVILEGED
, .x = { .method = { .member = "PullTar", .signature = "sssb"
, .result = "uo", .handler = method_pull_tar_or_raw, .offset =
0, }, }, }
,
1008 SD_BUS_METHOD("PullRaw", "sssb", "uo", method_pull_tar_or_raw, SD_BUS_VTABLE_UNPRIVILEGED){ .type = _SD_BUS_VTABLE_METHOD, .flags = SD_BUS_VTABLE_UNPRIVILEGED
, .x = { .method = { .member = "PullRaw", .signature = "sssb"
, .result = "uo", .handler = method_pull_tar_or_raw, .offset =
0, }, }, }
,
1009 SD_BUS_METHOD("ListTransfers", NULL, "a(usssdo)", method_list_transfers, SD_BUS_VTABLE_UNPRIVILEGED){ .type = _SD_BUS_VTABLE_METHOD, .flags = SD_BUS_VTABLE_UNPRIVILEGED
, .x = { .method = { .member = "ListTransfers", .signature = (
(void*)0), .result = "a(usssdo)", .handler = method_list_transfers
, .offset = 0, }, }, }
,
1010 SD_BUS_METHOD("CancelTransfer", "u", NULL, method_cancel_transfer, SD_BUS_VTABLE_UNPRIVILEGED){ .type = _SD_BUS_VTABLE_METHOD, .flags = SD_BUS_VTABLE_UNPRIVILEGED
, .x = { .method = { .member = "CancelTransfer", .signature =
"u", .result = ((void*)0), .handler = method_cancel_transfer
, .offset = 0, }, }, }
,
1011 SD_BUS_SIGNAL("TransferNew", "uo", 0){ .type = _SD_BUS_VTABLE_SIGNAL, .flags = 0, .x = { .signal =
{ .member = "TransferNew", .signature = "uo", }, }, }
,
1012 SD_BUS_SIGNAL("TransferRemoved", "uos", 0){ .type = _SD_BUS_VTABLE_SIGNAL, .flags = 0, .x = { .signal =
{ .member = "TransferRemoved", .signature = "uos", }, }, }
,
1013 SD_BUS_VTABLE_END{ .type = _SD_BUS_VTABLE_END, .flags = 0, .x = { { 0 } }, },
1014};
1015
1016static int transfer_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
1017 Manager *m = userdata;
1018 Transfer *t;
1019 const char *p;
1020 uint32_t id;
1021 int r;
1022
1023 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/import/importd.c", 1023,
__PRETTY_FUNCTION__); } while (0)
;
1024 assert(path)do { if ((__builtin_expect(!!(!(path)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("path"), "../src/import/importd.c", 1024
, __PRETTY_FUNCTION__); } while (0)
;
1025 assert(interface)do { if ((__builtin_expect(!!(!(interface)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("interface"), "../src/import/importd.c",
1025, __PRETTY_FUNCTION__); } while (0)
;
1026 assert(found)do { if ((__builtin_expect(!!(!(found)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("found"), "../src/import/importd.c", 1026
, __PRETTY_FUNCTION__); } while (0)
;
1027 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/import/importd.c", 1027, __PRETTY_FUNCTION__
); } while (0)
;
1028
1029 p = startswith(path, "/org/freedesktop/import1/transfer/_");
1030 if (!p)
1031 return 0;
1032
1033 r = safe_atou32(p, &id);
1034 if (r < 0 || id == 0)
1035 return 0;
1036
1037 t = hashmap_get(m->transfers, UINT32_TO_PTR(id)((void *) ((uintptr_t) (id))));
1038 if (!t)
1039 return 0;
1040
1041 *found = t;
1042 return 1;
1043}
1044
1045static int transfer_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
1046 _cleanup_strv_free___attribute__((cleanup(strv_freep))) char **l = NULL((void*)0);
1047 Manager *m = userdata;
1048 Transfer *t;
1049 unsigned k = 0;
1050 Iterator i;
1051
1052 l = new0(char*, hashmap_size(m->transfers) + 1)((char**) calloc((hashmap_size(m->transfers) + 1), sizeof(
char*)))
;
1053 if (!l)
1054 return -ENOMEM12;
1055
1056 HASHMAP_FOREACH(t, m->transfers, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .
next_key = ((void*)0) }); hashmap_iterate((m->transfers), &
(i), (void**)&(t), ((void*)0)); )
{
1057
1058 l[k] = strdup(t->object_path);
1059 if (!l[k])
1060 return -ENOMEM12;
1061
1062 k++;
1063 }
1064
1065 *nodes = TAKE_PTR(l)({ typeof(l) _ptr_ = (l); (l) = ((void*)0); _ptr_; });
1066
1067 return 1;
1068}
1069
1070static int manager_add_bus_objects(Manager *m) {
1071 int r;
1072
1073 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/import/importd.c", 1073, __PRETTY_FUNCTION__
); } while (0)
;
1074
1075 r = sd_bus_add_object_vtable(m->bus, NULL((void*)0), "/org/freedesktop/import1", "org.freedesktop.import1.Manager", manager_vtable, m);
1076 if (r < 0)
1077 return log_error_errno(r, "Failed to register object: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/import/importd.c", 1077, __func__, "Failed to register object: %m"
) : -abs(_e); })
;
1078
1079 r = sd_bus_add_fallback_vtable(m->bus, NULL((void*)0), "/org/freedesktop/import1/transfer", "org.freedesktop.import1.Transfer", transfer_vtable, transfer_object_find, m);
1080 if (r < 0)
1081 return log_error_errno(r, "Failed to register object: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/import/importd.c", 1081, __func__, "Failed to register object: %m"
) : -abs(_e); })
;
1082
1083 r = sd_bus_add_node_enumerator(m->bus, NULL((void*)0), "/org/freedesktop/import1/transfer", transfer_node_enumerator, m);
1084 if (r < 0)
1085 return log_error_errno(r, "Failed to add transfer enumerator: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/import/importd.c", 1085, __func__, "Failed to add transfer enumerator: %m"
) : -abs(_e); })
;
1086
1087 r = sd_bus_request_name_async(m->bus, NULL((void*)0), "org.freedesktop.import1", 0, NULL((void*)0), NULL((void*)0));
1088 if (r < 0)
1089 return log_error_errno(r, "Failed to request name: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/import/importd.c", 1089, __func__, "Failed to request name: %m"
) : -abs(_e); })
;
1090
1091 r = sd_bus_attach_event(m->bus, m->event, 0);
1092 if (r < 0)
1093 return log_error_errno(r, "Failed to attach bus to event loop: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/import/importd.c", 1093, __func__, "Failed to attach bus to event loop: %m"
) : -abs(_e); })
;
1094
1095 return 0;
1096}
1097
1098static bool_Bool manager_check_idle(void *userdata) {
1099 Manager *m = userdata;
1100
1101 return hashmap_isempty(m->transfers);
1102}
1103
1104static int manager_run(Manager *m) {
1105 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/import/importd.c", 1105, __PRETTY_FUNCTION__
); } while (0)
;
1106
1107 return bus_event_loop_with_idle(
1108 m->event,
1109 m->bus,
1110 "org.freedesktop.import1",
1111 DEFAULT_EXIT_USEC(30*((usec_t) 1000000ULL)),
1112 manager_check_idle,
1113 m);
1114}
1115
1116int main(int argc, char *argv[]) {
1117 _cleanup_(manager_unrefp)__attribute__((cleanup(manager_unrefp))) Manager *m = NULL((void*)0);
1118 int r;
1119
1120 log_set_target(LOG_TARGET_AUTO);
1121 log_parse_environment()log_parse_environment_realm(LOG_REALM_SYSTEMD);
1122 log_open();
1123
1124 umask(0022);
1125
1126 if (argc != 1) {
1127 log_error("This program takes no arguments.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/import/importd.c", 1127, __func__, "This program takes no arguments."
) : -abs(_e); })
;
1128 r = -EINVAL22;
1129 goto finish;
1130 }
1131
1132 assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGCHLD, -1) >= 0)do { if ((__builtin_expect(!!(!(sigprocmask_many(0, ((void*)0
), 17, -1) >= 0)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD
, ("sigprocmask_many(SIG_BLOCK, NULL, SIGCHLD, -1) >= 0"),
"../src/import/importd.c", 1132, __PRETTY_FUNCTION__); } while
(0)
;
1133
1134 r = manager_new(&m);
1135 if (r < 0) {
1136 log_error_errno(r, "Failed to allocate manager object: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/import/importd.c", 1136, __func__, "Failed to allocate manager object: %m"
) : -abs(_e); })
;
1137 goto finish;
1138 }
1139
1140 r = manager_add_bus_objects(m);
1141 if (r < 0)
1142 goto finish;
1143
1144 r = manager_run(m);
1145 if (r < 0) {
1146 log_error_errno(r, "Failed to run event loop: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/import/importd.c", 1146, __func__, "Failed to run event loop: %m"
) : -abs(_e); })
;
1147 goto finish;
1148 }
1149
1150finish:
1151 return r < 0 ? EXIT_FAILURE1 : EXIT_SUCCESS0;
1152}