machinectl.c revision aa1936ea1a89c2bb968ba33e3274898a4eeae771
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering/***
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering This file is part of systemd.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Copyright 2013 Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering systemd is free software; you can redistribute it and/or modify it
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering under the terms of the GNU Lesser General Public License as published by
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering (at your option) any later version.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering systemd is distributed in the hope that it will be useful, but
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Lesser General Public License for more details.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering You should have received a copy of the GNU Lesser General Public License
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering***/
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <dbus/dbus.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <unistd.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <errno.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <string.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <getopt.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <pwd.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <locale.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "log.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "util.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "macro.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "pager.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "dbus-common.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "build.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "strv.h"
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering#include "unit-name.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "cgroup-show.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "spawn-polkit-agent.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic char **arg_property = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic bool arg_all = false;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic bool arg_full = false;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic bool arg_no_pager = false;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic const char *arg_kill_who = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int arg_signal = SIGTERM;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic enum transport {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering TRANSPORT_NORMAL,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering TRANSPORT_SSH,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering TRANSPORT_POLKIT
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering} arg_transport = TRANSPORT_NORMAL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic bool arg_ask_password = true;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic char *arg_host = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic char *arg_user = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic void pager_open_if_enabled(void) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* Cache result before we open the pager */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (arg_no_pager)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering pager_open(false);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int list_machines(DBusConnection *bus, char **args, unsigned n) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering DBusMessageIter iter, sub, sub2;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering unsigned k = 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering pager_open_if_enabled();
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = bus_method_call_with_reply (
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering bus,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "org.freedesktop.machine1",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "/org/freedesktop/machine1",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "org.freedesktop.machine1.Manager",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "ListMachines",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering &reply,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering NULL,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering DBUS_TYPE_INVALID);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!dbus_message_iter_init(reply, &iter) ||
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRUCT) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("Failed to parse reply.");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -EIO;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering dbus_message_iter_recurse(&iter, &sub);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (on_tty())
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering printf("%-32s %-9s %-16s\n", "MACHINE", "CONTAINER", "SERVICE");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering const char *name, *class, *service, *object;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRUCT) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("Failed to parse reply.");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -EIO;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering dbus_message_iter_recurse(&sub, &sub2);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &name, true) < 0 ||
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &class, true) < 0 ||
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &service, true) < 0 ||
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_OBJECT_PATH, &object, false) < 0) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("Failed to parse reply.");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -EIO;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering printf("%-32s %-9s %-16s\n", name, class, service);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering k++;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering dbus_message_iter_next(&sub);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (on_tty())
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering printf("\n%u machines listed.\n", k);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poetteringstatic int show_scope_cgroup(DBusConnection *bus, const char *unit) {
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering const char *interface = "org.freedesktop.systemd1.Scope";
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering const char *property = "ControlGroup";
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering _cleanup_free_ char *path = NULL;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering DBusMessageIter iter, sub;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering const char *cgroup;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering DBusError error;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering int r, output_flags;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering unsigned c;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering assert(bus);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering assert(unit);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (arg_transport == TRANSPORT_SSH)
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering return 0;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering path = unit_dbus_path_from_name(unit);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (!path)
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering return log_oom();
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering r = bus_method_call_with_reply(
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering bus,
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering "org.freedesktop.systemd1",
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering path,
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering "org.freedesktop.DBus.Properties",
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering "Get",
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering &reply,
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering &error,
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering DBUS_TYPE_STRING, &interface,
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering DBUS_TYPE_STRING, &property,
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering DBUS_TYPE_INVALID);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (r < 0) {
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering log_error("Failed to query ControlGroup: %s", bus_error(&error, r));
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering dbus_error_free(&error);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering return r;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering }
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (!dbus_message_iter_init(reply, &iter) ||
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) {
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering log_error("Failed to parse reply.");
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering return -EINVAL;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering }
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering dbus_message_iter_recurse(&iter, &sub);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING) {
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering log_error("Failed to parse reply.");
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering return -EINVAL;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering }
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering dbus_message_iter_get_basic(&sub, &cgroup);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering output_flags =
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering arg_all * OUTPUT_SHOW_ALL |
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering arg_full * OUTPUT_FULL_WIDTH;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering c = columns();
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (c > 18)
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering c -= 18;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering else
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering c = 0;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering show_cgroup_by_path(cgroup, "\t\t ", c, false, output_flags);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering return 0;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering}
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringtypedef struct MachineStatusInfo {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering const char *name;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering sd_id128_t id;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering const char *class;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering const char *service;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering const char *scope;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering const char *root_directory;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering pid_t leader;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering usec_t timestamp;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering} MachineStatusInfo;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poetteringstatic void print_machine_status_info(DBusConnection *bus, MachineStatusInfo *i) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering char since2[FORMAT_TIMESTAMP_MAX], *s2;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(i);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering fputs(strna(i->name), stdout);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!sd_id128_equal(i->id, SD_ID128_NULL))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering printf("(" SD_ID128_FORMAT_STR ")\n", SD_ID128_FORMAT_VAL(i->id));
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering else
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering putchar('\n');
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering s1 = format_timestamp_relative(since1, sizeof(since1), i->timestamp);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering s2 = format_timestamp(since2, sizeof(since2), i->timestamp);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (s1)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering printf("\t Since: %s; %s\n", s2, s1);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering else if (s2)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering printf("\t Since: %s\n", s2);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (i->leader > 0) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _cleanup_free_ char *t = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering printf("\t Leader: %u", (unsigned) i->leader);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering get_process_comm(i->leader, &t);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (t)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering printf(" (%s)", t);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering putchar('\n');
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (i->service) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering printf("\t Service: %s", i->service);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (i->class)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering printf("; class %s", i->class);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering putchar('\n');
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering } else if (i->class)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering printf("\t Class: %s\n", i->class);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (i->root_directory)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering printf("\t Root: %s\n", i->root_directory);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (i->scope) {
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering printf("\t Unit: %s\n", i->scope);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering show_scope_cgroup(bus, i->scope);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int status_property_machine(const char *name, DBusMessageIter *iter, MachineStatusInfo *i) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(name);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(iter);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(i);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering switch (dbus_message_iter_get_arg_type(iter)) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering case DBUS_TYPE_STRING: {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering const char *s;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering dbus_message_iter_get_basic(iter, &s);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!isempty(s)) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (streq(name, "Name"))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering i->name = s;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering else if (streq(name, "Class"))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering i->class = s;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering else if (streq(name, "Service"))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering i->service = s;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering else if (streq(name, "Scope"))
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering i->scope = s;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering else if (streq(name, "RootDirectory"))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering i->root_directory = s;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering break;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering case DBUS_TYPE_UINT32: {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering uint32_t u;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering dbus_message_iter_get_basic(iter, &u);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (streq(name, "Leader"))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering i->leader = (pid_t) u;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering break;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering case DBUS_TYPE_UINT64: {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering uint64_t u;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering dbus_message_iter_get_basic(iter, &u);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (streq(name, "Timestamp"))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering i->timestamp = (usec_t) u;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering break;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering case DBUS_TYPE_ARRAY: {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering DBusMessageIter sub;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering dbus_message_iter_recurse(iter, &sub);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_BYTE && streq(name, "Id")) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering void *v;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int n;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering dbus_message_iter_get_fixed_array(&sub, &v, &n);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (n == 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering i->id = SD_ID128_NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering else if (n == 16)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering memcpy(&i->id, v, n);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering break;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int print_property(const char *name, DBusMessageIter *iter) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(name);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(iter);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (arg_property && !strv_find(arg_property, name))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (generic_print_property(name, iter, arg_all) > 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (arg_all)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering printf("%s=[unprintable]\n", name);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int show_one(const char *verb, DBusConnection *bus, const char *path, bool show_properties, bool *new_line) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering const char *interface = "";
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering DBusMessageIter iter, sub, sub2, sub3;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering MachineStatusInfo machine_info = {};
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(path);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(new_line);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = bus_method_call_with_reply(
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering bus,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "org.freedesktop.machine1",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering path,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "org.freedesktop.DBus.Properties",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "GetAll",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering &reply,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering NULL,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering DBUS_TYPE_STRING, &interface,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering DBUS_TYPE_INVALID);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering goto finish;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!dbus_message_iter_init(reply, &iter) ||
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_DICT_ENTRY) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("Failed to parse reply.");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = -EIO;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering goto finish;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering dbus_message_iter_recurse(&iter, &sub);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (*new_line)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering printf("\n");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering *new_line = true;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering const char *name;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_DICT_ENTRY) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("Failed to parse reply.");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = -EIO;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering goto finish;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering dbus_message_iter_recurse(&sub, &sub2);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &name, true) < 0) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("Failed to parse reply.");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = -EIO;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering goto finish;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (dbus_message_iter_get_arg_type(&sub2) != DBUS_TYPE_VARIANT) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("Failed to parse reply.");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = -EIO;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering goto finish;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering dbus_message_iter_recurse(&sub2, &sub3);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (show_properties)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = print_property(name, &sub3);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering else
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = status_property_machine(name, &sub3, &machine_info);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("Failed to parse reply.");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering goto finish;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering dbus_message_iter_next(&sub);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!show_properties)
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering print_machine_status_info(bus, &machine_info);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringfinish:
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int show(DBusConnection *bus, char **args, unsigned n) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int r, ret = 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering DBusError error;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering unsigned i;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering bool show_properties, new_line = false;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(bus);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(args);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering dbus_error_init(&error);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering show_properties = !strstr(args[0], "status");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering pager_open_if_enabled();
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (show_properties && n <= 1) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* If not argument is specified inspect the manager
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering * itself */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering ret = show_one(args[0], bus, "/org/freedesktop/machine1", show_properties, &new_line);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering goto finish;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering for (i = 1; i < n; i++) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering const char *path = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering ret = bus_method_call_with_reply(
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering bus,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "org.freedesktop.machine1",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "/org/freedesktop/machine1",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "org.freedesktop.machine1.Manager",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "GetMachine",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering &reply,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering NULL,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering DBUS_TYPE_STRING, &args[i],
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering DBUS_TYPE_INVALID);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (ret < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering goto finish;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!dbus_message_get_args(reply, &error,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering DBUS_TYPE_OBJECT_PATH, &path,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering DBUS_TYPE_INVALID)) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("Failed to parse reply: %s", bus_error_message(&error));
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering ret = -EIO;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering goto finish;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = show_one(args[0], bus, path, show_properties, &new_line);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r != 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering ret = r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringfinish:
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering dbus_error_free(&error);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return ret;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int kill_machine(DBusConnection *bus, char **args, unsigned n) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering unsigned i;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(args);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!arg_kill_who)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering arg_kill_who = "all";
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering for (i = 1; i < n; i++) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = bus_method_call_with_reply (
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering bus,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "org.freedesktop.machine1",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "/org/freedesktop/machine1",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "org.freedesktop.machine1.Manager",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "KillMachine",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering NULL,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering NULL,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering DBUS_TYPE_STRING, &args[i],
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering DBUS_TYPE_STRING, &arg_kill_who,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering DBUS_TYPE_INT32, &arg_signal,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering DBUS_TYPE_INVALID);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int terminate_machine(DBusConnection *bus, char **args, unsigned n) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering unsigned i;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(args);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering for (i = 1; i < n; i++) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = bus_method_call_with_reply (
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering bus,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "org.freedesktop.machine1",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "/org/freedesktop/machine1",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "org.freedesktop.machine1.Manager",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "TerminateMachine",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering NULL,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering NULL,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering DBUS_TYPE_STRING, &args[i],
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering DBUS_TYPE_INVALID);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int help(void) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering printf("%s [OPTIONS...] {COMMAND} ...\n\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "Send control commands to or query the virtual machine and container registration manager.\n\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " -h --help Show this help\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " --version Show package version\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " -p --property=NAME Show only properties by this name\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " -a --all Show all properties, including empty ones\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " --kill-who=WHO Who to send signal to\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " -l --full Do not ellipsize output\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " -s --signal=SIGNAL Which signal to send\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " --no-ask-password Don't prompt for password\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " -H --host=[USER@]HOST Show information for remote host\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " -P --privileged Acquire privileges before execution\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " --no-pager Do not pipe output into a pager\n\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "Commands:\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " list List running VMs and containers\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " status [NAME...] Show VM/container status\n"
19887cd06a3af2f045e763986eda19e208bd3f85Zbigniew Jędrzejewski-Szmek " show [NAME...] Show properties of one or more VMs/containers\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " terminate [NAME...] Terminate one or more VMs/containers\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " kill [NAME...] Send signal to processes of a VM/container\n",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering program_invocation_short_name);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int parse_argv(int argc, char *argv[]) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering enum {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering ARG_VERSION = 0x100,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering ARG_NO_PAGER,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering ARG_KILL_WHO,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering ARG_NO_ASK_PASSWORD,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering };
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering static const struct option options[] = {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "help", no_argument, NULL, 'h' },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "version", no_argument, NULL, ARG_VERSION },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "property", required_argument, NULL, 'p' },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "all", no_argument, NULL, 'a' },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "full", no_argument, NULL, 'l' },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "no-pager", no_argument, NULL, ARG_NO_PAGER },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "kill-who", required_argument, NULL, ARG_KILL_WHO },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "signal", required_argument, NULL, 's' },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "host", required_argument, NULL, 'H' },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "privileged", no_argument, NULL, 'P' },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { NULL, 0, NULL, 0 }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering };
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int c;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(argc >= 0);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(argv);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering while ((c = getopt_long(argc, argv, "hp:als:H:P", options, NULL)) >= 0) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering switch (c) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering case 'h':
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering help();
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering case ARG_VERSION:
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering puts(PACKAGE_STRING);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering puts(SYSTEMD_FEATURES);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering case 'p': {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering char **l;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering l = strv_append(arg_property, optarg);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!l)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -ENOMEM;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering strv_free(arg_property);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering arg_property = l;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* If the user asked for a particular
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering * property, show it to him, even if it is
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering * empty. */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering arg_all = true;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering break;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering case 'a':
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering arg_all = true;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering break;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering case 'l':
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering arg_full = true;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering break;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering case ARG_NO_PAGER:
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering arg_no_pager = true;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering break;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering case ARG_NO_ASK_PASSWORD:
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering arg_ask_password = false;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering break;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering case ARG_KILL_WHO:
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering arg_kill_who = optarg;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering break;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering case 's':
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering arg_signal = signal_from_string_try_harder(optarg);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (arg_signal < 0) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("Failed to parse signal string %s.", optarg);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -EINVAL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering break;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering case 'P':
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering arg_transport = TRANSPORT_POLKIT;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering break;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering case 'H':
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering arg_transport = TRANSPORT_SSH;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering parse_user_at_host(optarg, &arg_user, &arg_host);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering break;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering case '?':
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -EINVAL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering default:
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("Unknown option code %c", c);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -EINVAL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 1;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int machinectl_main(DBusConnection *bus, int argc, char *argv[], DBusError *error) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering static const struct {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering const char* verb;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering const enum {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering MORE,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering LESS,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering EQUAL
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering } argc_cmp;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering const int argc;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int (* const dispatch)(DBusConnection *bus, char **args, unsigned n);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering } verbs[] = {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "list", LESS, 1, list_machines },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "status", MORE, 2, show },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "show", MORE, 1, show },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "terminate", MORE, 2, terminate_machine },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "kill", MORE, 2, kill_machine },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering };
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int left;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering unsigned i;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(argc >= 0);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(argv);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(error);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering left = argc - optind;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (left <= 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* Special rule: no arguments means "list-sessions" */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering i = 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering else {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (streq(argv[optind], "help")) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering help();
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering for (i = 0; i < ELEMENTSOF(verbs); i++)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (streq(argv[optind], verbs[i].verb))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering break;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (i >= ELEMENTSOF(verbs)) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("Unknown operation %s", argv[optind]);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -EINVAL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering switch (verbs[i].argc_cmp) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering case EQUAL:
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (left != verbs[i].argc) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("Invalid number of arguments.");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -EINVAL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering break;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering case MORE:
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (left < verbs[i].argc) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("Too few arguments.");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -EINVAL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering break;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering case LESS:
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (left > verbs[i].argc) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("Too many arguments.");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -EINVAL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering break;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering default:
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert_not_reached("Unknown comparison operator.");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!bus) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("Failed to get D-Bus connection: %s", error->message);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -EIO;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return verbs[i].dispatch(bus, argv + optind, left);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringint main(int argc, char*argv[]) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int r, retval = EXIT_FAILURE;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering DBusConnection *bus = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering DBusError error;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering dbus_error_init(&error);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering setlocale(LC_ALL, "");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_parse_environment();
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_open();
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = parse_argv(argc, argv);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering goto finish;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering else if (r == 0) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering retval = EXIT_SUCCESS;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering goto finish;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (arg_transport == TRANSPORT_NORMAL)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering else if (arg_transport == TRANSPORT_POLKIT)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering bus_connect_system_polkit(&bus, &error);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering else if (arg_transport == TRANSPORT_SSH)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering bus_connect_system_ssh(NULL, arg_host, &bus, &error);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering else
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert_not_reached("Uh, invalid transport...");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = machinectl_main(bus, argc, argv, &error);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering retval = r < 0 ? EXIT_FAILURE : r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringfinish:
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (bus) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering dbus_connection_flush(bus);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering dbus_connection_close(bus);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering dbus_connection_unref(bus);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering dbus_error_free(&error);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering dbus_shutdown();
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering strv_free(arg_property);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering pager_close();
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return retval;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}