importd.c revision ece174c5439021e32ebcc858842de9586072c006
260672bd3f54ac0cf5bfc2032c7f5a51991c9f4aChad Kienle/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
260672bd3f54ac0cf5bfc2032c7f5a51991c9f4aChad Kienle This file is part of systemd.
12215e8cf03be7141191f455a58ff6abb9129c98Andi Egloff Copyright 2015 Lennart Poettering
260672bd3f54ac0cf5bfc2032c7f5a51991c9f4aChad Kienle systemd is free software; you can redistribute it and/or modify it
260672bd3f54ac0cf5bfc2032c7f5a51991c9f4aChad Kienle under the terms of the GNU Lesser General Public License as published by
260672bd3f54ac0cf5bfc2032c7f5a51991c9f4aChad Kienle the Free Software Foundation; either version 2.1 of the License, or
260672bd3f54ac0cf5bfc2032c7f5a51991c9f4aChad Kienle (at your option) any later version.
along with systemd; If not, see <http://www.gnu.org/licenses/>.
#include "sd-bus.h"
#include "util.h"
#include "strv.h"
#include "bus-util.h"
#include "bus-common-errors.h"
#include "socket-util.h"
#include "mkdir.h"
#include "def.h"
#include "missing.h"
#include "machine-pool.h"
#include "path-util.h"
#include "import-util.h"
#include "process-util.h"
#include "signal-util.h"
#include "hostname-util.h"
typedef enum TransferType {
} TransferType;
struct Transfer {
char *object_path;
char *remote;
char *local;
bool force_local;
bool read_only;
char *dkr_index_url;
char *format;
int log_fd;
unsigned n_canceled;
unsigned progress_percent;
int stdin_fd;
int stdout_fd;
struct Manager {
int notify_fd;
return NULL;
if (t->manager)
if (t->pid > 0) {
free(t);
return NULL;
assert(m);
return -E2BIG;
return -ENOMEM;
return -ENOMEM;
t->manager = m;
*ret = t;
t = NULL;
assert(t);
r = sd_bus_emit_signal(
t->object_path,
line);
assert(t);
while (t->log_message_size > 0) {
if (!flush)
log_oom();
if (isempty(n))
transfer_send_log_line(t, n);
assert(t);
transfer_send_logs(t, true);
r = sd_bus_emit_signal(
"/org/freedesktop/import1",
t->id,
t->object_path,
transfer_unref(t);
assert(t);
t->n_canceled++;
bool success = false;
assert(s);
assert(t);
success = true;
t->pid = 0;
ssize_t l;
assert(s);
assert(t);
t->log_message_size += l;
transfer_send_logs(t, false);
assert(t);
return -errno;
if (t->pid < 0)
return -errno;
if (t->pid == 0) {
const char *cmd[] = {
(void) reset_all_signal_handlers();
(void) reset_signal_mask();
if (t->stdout_fd >= 0) {
if (t->stdin_fd >= 0) {
int null_fd;
if (null_fd < 0) {
if (t->force_local)
if (t->read_only)
if (t->dkr_index_url) {
if (t->format) {
if (t->remote)
if (t->local)
r = sd_event_add_child(t->manager->event, &t->pid_event_source, t->pid, WEXITED, transfer_on_pid, t);
r = sd_event_add_io(t->manager->event, &t->log_event_source, t->log_fd, EPOLLIN, transfer_on_log, t);
r = sd_bus_emit_signal(
"/org/freedesktop/import1",
t->id,
t->object_path);
Transfer *t;
return NULL;
transfer_unref(t);
free(m);
return NULL;
} control = {};
unsigned percent;
Transfer *t;
Iterator i;
ssize_t n;
return -errno;
if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_CREDENTIALS && cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred)))
buf[n] = 0;
return -ENOMEM;
if (m->notify_fd < 0)
return -errno;
if (bind(m->notify_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path)) < 0)
return -errno;
return -errno;
r = sd_event_add_io(m->event, &m->notify_event_source, m->notify_fd, EPOLLIN, manager_on_notify, m);
*ret = m;
m = NULL;
static Transfer *manager_find(Manager *m, TransferType type, const char *dkr_index_url, const char *remote) {
Transfer *t;
Iterator i;
assert(m);
return NULL;
assert(m);
msg,
NULL,
&m->polkit_registry,
error);
type = streq_ptr(sd_bus_message_get_member(msg), "ImportTar") ? TRANSFER_IMPORT_TAR : TRANSFER_IMPORT_RAW;
r = transfer_new(m, &t);
if (!t->local)
return -ENOMEM;
if (t->stdin_fd < 0)
return -errno;
r = transfer_start(t);
t = NULL;
int fd, r;
assert(m);
msg,
NULL,
&m->polkit_registry,
error);
type = streq_ptr(sd_bus_message_get_member(msg), "ExportTar") ? TRANSFER_EXPORT_TAR : TRANSFER_EXPORT_RAW;
r = transfer_new(m, &t);
if (!t->format)
return -ENOMEM;
if (!t->local)
return -ENOMEM;
if (t->stdout_fd < 0)
return -errno;
r = transfer_start(t);
t = NULL;
ImportVerify v;
int force, r;
assert(m);
msg,
NULL,
&m->polkit_registry,
error);
type = streq_ptr(sd_bus_message_get_member(msg), "PullTar") ? TRANSFER_PULL_TAR : TRANSFER_PULL_RAW;
return sd_bus_error_setf(error, BUS_ERROR_TRANSFER_IN_PROGRESS, "Transfer for %s already in progress.", remote);
r = transfer_new(m, &t);
t->verify = v;
if (!t->remote)
return -ENOMEM;
if (local) {
if (!t->local)
return -ENOMEM;
r = transfer_start(t);
t = NULL;
ImportVerify v;
int force, r;
assert(m);
msg,
NULL,
&m->polkit_registry,
error);
if (!index_url)
if (v != IMPORT_VERIFY_NO)
return sd_bus_error_setf(error, BUS_ERROR_TRANSFER_IN_PROGRESS, "Transfer for %s already in progress.", remote);
r = transfer_new(m, &t);
t->verify = v;
if (!t->dkr_index_url)
return -ENOMEM;
if (!t->remote)
return -ENOMEM;
if (local) {
if (!t->local)
return -ENOMEM;
r = transfer_start(t);
t = NULL;
Transfer *t;
Iterator i;
assert(m);
t->id,
t->remote,
t->local,
t->object_path);
assert(t);
msg,
NULL,
error);
r = transfer_cancel(t);
Transfer *t;
assert(m);
msg,
NULL,
&m->polkit_registry,
error);
if (id <= 0)
r = transfer_cancel(t);
static int property_get_progress(
const char *path,
const char *interface,
const char *property,
void *userdata,
assert(t);
SD_BUS_PROPERTY("Type", "s", property_get_type, offsetof(Transfer, type), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Verify", "s", property_get_verify, offsetof(Transfer, verify), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_METHOD("ListTransfers", NULL, "a(usssdo)", method_list_transfers, SD_BUS_VTABLE_UNPRIVILEGED),
static int transfer_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
Transfer *t;
assert(m);
if (r < 0 || id == 0)
*found = t;
static int transfer_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
Transfer *t;
Iterator i;
return -ENOMEM;
return -ENOMEM;
*nodes = l;
l = NULL;
assert(m);
r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/import1", "org.freedesktop.import1.Manager", manager_vtable, m);
r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/import1/transfer", "org.freedesktop.import1.Transfer", transfer_vtable, transfer_object_find, m);
r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/import1/transfer", transfer_node_enumerator, m);
assert(m);
return bus_event_loop_with_idle(
m->event,
m->bus,
log_open();
r = -EINVAL;
goto finish;
r = manager_new(&m);
goto finish;
r = manager_add_bus_objects(m);
goto finish;
r = manager_run(m);
goto finish;