Beispiel #1
0
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);
}
Beispiel #2
0
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);
}
Beispiel #3
0
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);
}
Beispiel #4
0
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;
}
Beispiel #5
0
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);
}
Beispiel #6
0
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);
}
Beispiel #7
0
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;
}
Beispiel #8
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;
}
Beispiel #9
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;
}
Beispiel #10
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);
                }
        }
}