static int set_time(DBusConnection *bus, char **args, unsigned n) { _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; dbus_bool_t relative = false, interactive = true; usec_t t; dbus_int64_t u; int r; assert(args); assert(n == 2); polkit_agent_open_if_enabled(); r = parse_timestamp(args[1], &t); if (r < 0) { log_error("Failed to parse time specification: %s", args[1]); return r; } u = (dbus_uint64_t) t; return bus_method_call_with_reply( bus, "org.freedesktop.timedate1", "/org/freedesktop/timedate1", "org.freedesktop.timedate1", "SetTime", &reply, NULL, DBUS_TYPE_INT64, &u, DBUS_TYPE_BOOLEAN, &relative, DBUS_TYPE_BOOLEAN, &interactive, DBUS_TYPE_INVALID); }
static int set_vconsole_keymap(DBusConnection *bus, char **args, unsigned n) { _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; dbus_bool_t interactive = true, b; const char *map, *toggle_map; assert(bus); assert(args); if (n > 3) { log_error("Too many arguments."); return -EINVAL; } polkit_agent_open_if_enabled(); map = args[1]; toggle_map = n > 2 ? args[2] : ""; b = arg_convert; return bus_method_call_with_reply( bus, "org.freedesktop.locale1", "/org/freedesktop/locale1", "org.freedesktop.locale1", "SetVConsoleKeyboard", &reply, NULL, DBUS_TYPE_STRING, &map, DBUS_TYPE_STRING, &toggle_map, DBUS_TYPE_BOOLEAN, &b, DBUS_TYPE_BOOLEAN, &interactive, DBUS_TYPE_INVALID); }
static int set_ntp(DBusConnection *bus, char **args, unsigned n) { _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; dbus_bool_t interactive = true, b; int r; assert(args); assert(n == 2); polkit_agent_open_if_enabled(); r = parse_boolean(args[1]); if (r < 0) { log_error("Failed to parse NTP setting: %s", args[1]); return r; } b = r; return bus_method_call_with_reply( bus, "org.freedesktop.timedate1", "/org/freedesktop/timedate1", "org.freedesktop.timedate1", "SetNTP", &reply, NULL, DBUS_TYPE_BOOLEAN, &b, DBUS_TYPE_BOOLEAN, &interactive, DBUS_TYPE_INVALID); }
static int inhibit(DBusConnection *bus, DBusError *error) { _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; int r; r = bus_method_call_with_reply( bus, "org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", "Inhibit", &reply, NULL, DBUS_TYPE_STRING, &arg_what, DBUS_TYPE_STRING, &arg_who, DBUS_TYPE_STRING, &arg_why, DBUS_TYPE_STRING, &arg_mode, DBUS_TYPE_INVALID); if (r < 0) return r; if (!dbus_message_get_args(reply, error, DBUS_TYPE_UNIX_FD, &r, DBUS_TYPE_INVALID)) return -EIO; return r; }
static int set_timezone(DBusConnection *bus, char **args, unsigned n) { _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; dbus_bool_t interactive = true; assert(args); assert(n == 2); polkit_agent_open_if_enabled(); return bus_method_call_with_reply( bus, "org.freedesktop.timedate1", "/org/freedesktop/timedate1", "org.freedesktop.timedate1", "SetTimezone", &reply, NULL, DBUS_TYPE_STRING, &args[1], DBUS_TYPE_BOOLEAN, &interactive, DBUS_TYPE_INVALID); }
static int set_x11_keymap(DBusConnection *bus, char **args, unsigned n) { _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; dbus_bool_t interactive = true, b; const char *layout, *model, *variant, *options; assert(bus); assert(args); if (n > 5) { log_error("Too many arguments."); return -EINVAL; } polkit_agent_open_if_enabled(); layout = args[1]; model = n > 2 ? args[2] : ""; variant = n > 3 ? args[3] : ""; options = n > 3 ? args[4] : ""; b = arg_convert; return bus_method_call_with_reply( bus, "org.freedesktop.locale1", "/org/freedesktop/locale1", "org.freedesktop.locale1", "SetX11Keyboard", &reply, NULL, DBUS_TYPE_STRING, &layout, DBUS_TYPE_STRING, &model, DBUS_TYPE_STRING, &variant, DBUS_TYPE_STRING, &options, DBUS_TYPE_BOOLEAN, &b, DBUS_TYPE_BOOLEAN, &interactive, DBUS_TYPE_INVALID); }
static int show_status(DBusConnection *bus, char **args, unsigned n) { _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; const char *interface = ""; int r; DBusMessageIter iter, sub, sub2, sub3; StatusInfo info; assert(args); r = bus_method_call_with_reply( bus, "org.freedesktop.locale1", "/org/freedesktop/locale1", "org.freedesktop.DBus.Properties", "GetAll", &reply, NULL, DBUS_TYPE_STRING, &interface, DBUS_TYPE_INVALID); if (r < 0) return r; if (!dbus_message_iter_init(reply, &iter) || dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_DICT_ENTRY) { log_error("Failed to parse reply."); return -EIO; } zero(info); dbus_message_iter_recurse(&iter, &sub); while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { const char *name; if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_DICT_ENTRY) { log_error("Failed to parse reply."); return -EIO; } dbus_message_iter_recurse(&sub, &sub2); if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &name, true) < 0) { log_error("Failed to parse reply."); return -EIO; } if (dbus_message_iter_get_arg_type(&sub2) != DBUS_TYPE_VARIANT) { log_error("Failed to parse reply."); return -EIO; } dbus_message_iter_recurse(&sub2, &sub3); r = status_property(name, &sub3, &info); if (r < 0) { log_error("Failed to parse reply."); return r; } dbus_message_iter_next(&sub); } print_status_info(&info); strv_free(info.locale); return 0; }
static int set_hostname(DBusConnection *bus, char **args, unsigned n) { _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; dbus_bool_t interactive = true; _cleanup_free_ char *h = NULL; const char *hostname = args[1]; int r; assert(args); assert(n == 2); polkit_agent_open_if_enabled(); if (arg_set_pretty) { const char *p; /* If the passed hostname is already valid, then * assume the user doesn't know anything about pretty * hostnames, so let's unset the pretty hostname, and * just set the passed hostname as static/dynamic * hostname. */ h = strdup(hostname); if (!h) return log_oom(); hostname_cleanup(h, true); if (arg_set_static && streq(h, hostname)) p = ""; else { p = hostname; hostname = h; } r = bus_method_call_with_reply( bus, "org.freedesktop.hostname1", "/org/freedesktop/hostname1", "org.freedesktop.hostname1", "SetPrettyHostname", &reply, NULL, DBUS_TYPE_STRING, &p, DBUS_TYPE_BOOLEAN, &interactive, DBUS_TYPE_INVALID); if (r < 0) return r; dbus_message_unref(reply); reply = NULL; } if (arg_set_static) { r = bus_method_call_with_reply( bus, "org.freedesktop.hostname1", "/org/freedesktop/hostname1", "org.freedesktop.hostname1", "SetStaticHostname", &reply, NULL, DBUS_TYPE_STRING, &hostname, DBUS_TYPE_BOOLEAN, &interactive, DBUS_TYPE_INVALID); if (r < 0) return r; dbus_message_unref(reply); reply = NULL; } if (arg_set_transient) { r = bus_method_call_with_reply( bus, "org.freedesktop.hostname1", "/org/freedesktop/hostname1", "org.freedesktop.hostname1", "SetHostname", &reply, NULL, DBUS_TYPE_STRING, &hostname, DBUS_TYPE_BOOLEAN, &interactive, DBUS_TYPE_INVALID); if (r < 0) return r; } return 0; }
static int print_inhibitors(DBusConnection *bus, DBusError *error) { _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; unsigned n = 0; DBusMessageIter iter, sub, sub2; int r; r = bus_method_call_with_reply( bus, "org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", "ListInhibitors", &reply, NULL, DBUS_TYPE_INVALID); if (r < 0) return r; if (!dbus_message_iter_init(reply, &iter)) return -ENOMEM; if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) return -EIO; dbus_message_iter_recurse(&iter, &sub); while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { const char *what, *who, *why, *mode; _cleanup_free_ char *comm = NULL, *u = NULL; dbus_uint32_t uid, pid; if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRUCT) return -EIO; dbus_message_iter_recurse(&sub, &sub2); if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &what, true) < 0 || bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &who, true) < 0 || bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &why, true) < 0 || bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &mode, true) < 0 || bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT32, &uid, true) < 0 || bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT32, &pid, false) < 0) return -EIO; get_process_comm(pid, &comm); u = uid_to_name(uid); printf(" Who: %s (UID %lu/%s, PID %lu/%s)\n" " What: %s\n" " Why: %s\n" " Mode: %s\n\n", who, (unsigned long) uid, strna(u), (unsigned long) pid, strna(comm), what, why, mode); dbus_message_iter_next(&sub); n++; } printf("%u inhibitors listed.\n", n); return 0; }
static int manager_connect_bus(Manager *m) { DBusError error; int r; struct epoll_event ev = { .events = EPOLLIN, .data.u32 = FD_BUS, }; assert(m); assert(!m->bus); assert(m->bus_fd < 0); dbus_error_init(&error); m->bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error); if (!m->bus) { log_error("Failed to get system D-Bus connection: %s", bus_error_message(&error)); r = -ECONNREFUSED; goto fail; } if (!dbus_connection_register_object_path(m->bus, "/org/freedesktop/machine1", &bus_manager_vtable, m) || !dbus_connection_register_fallback(m->bus, "/org/freedesktop/machine1/machine", &bus_machine_vtable, m) || !dbus_connection_add_filter(m->bus, bus_message_filter, m, NULL)) { r = log_oom(); goto fail; } dbus_bus_add_match(m->bus, "type='signal'," "sender='org.freedesktop.systemd1'," "interface='org.freedesktop.systemd1.Manager'," "member='JobRemoved'," "path='/org/freedesktop/systemd1'", &error); if (dbus_error_is_set(&error)) { log_error("Failed to add match for JobRemoved: %s", bus_error_message(&error)); dbus_error_free(&error); } dbus_bus_add_match(m->bus, "type='signal'," "sender='org.freedesktop.systemd1'," "interface='org.freedesktop.systemd1.Manager'," "member='UnitRemoved'," "path='/org/freedesktop/systemd1'", &error); if (dbus_error_is_set(&error)) { log_error("Failed to add match for UnitRemoved: %s", bus_error_message(&error)); dbus_error_free(&error); } dbus_bus_add_match(m->bus, "type='signal'," "sender='org.freedesktop.systemd1'," "interface='org.freedesktop.DBus.Properties'," "member='PropertiesChanged'", &error); if (dbus_error_is_set(&error)) { log_error("Failed to add match for PropertiesChanged: %s", bus_error_message(&error)); dbus_error_free(&error); } dbus_bus_add_match(m->bus, "type='signal'," "sender='org.freedesktop.systemd1'," "interface='org.freedesktop.systemd1.Manager'," "member='Reloading'," "path='/org/freedesktop/systemd1'", &error); if (dbus_error_is_set(&error)) { log_error("Failed to add match for Reloading: %s", bus_error_message(&error)); dbus_error_free(&error); } r = bus_method_call_with_reply( m->bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "Subscribe", NULL, &error, DBUS_TYPE_INVALID); if (r < 0) { log_error("Failed to enable subscription: %s", bus_error(&error, r)); dbus_error_free(&error); } r = dbus_bus_request_name(m->bus, "org.freedesktop.machine1", DBUS_NAME_FLAG_DO_NOT_QUEUE, &error); if (dbus_error_is_set(&error)) { log_error("Failed to register name on bus: %s", bus_error_message(&error)); r = -EIO; goto fail; } if (r != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { log_error("Failed to acquire name."); r = -EEXIST; goto fail; } m->bus_fd = bus_loop_open(m->bus); if (m->bus_fd < 0) { r = m->bus_fd; goto fail; } if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->bus_fd, &ev) < 0) goto fail; return 0; fail: dbus_error_free(&error); return r; } void manager_gc(Manager *m, bool drop_not_started) { Machine *machine; assert(m); while ((machine = m->machine_gc_queue)) { LIST_REMOVE(gc_queue, m->machine_gc_queue, machine); machine->in_gc_queue = false; if (machine_check_gc(machine, drop_not_started) == 0) { machine_stop(machine); machine_free(machine); } } }