Exemplo n.º 1
0
int bus_open_user_systemd(sd_bus **_bus) {
        _cleanup_bus_unref_ sd_bus *bus = NULL;
        _cleanup_free_ char *ee = NULL;
        const char *e;
        int r;

        /* Try via kdbus first, and then directly */

        assert(_bus);

#ifdef ENABLE_KDBUS
        r = sd_bus_new(&bus);
        if (r < 0)
                return r;

        if (asprintf(&bus->address, KERNEL_USER_BUS_FMT, getuid()) < 0)
                return -ENOMEM;

        bus->bus_client = true;

        r = sd_bus_start(bus);
        if (r >= 0) {
                *_bus = bus;
                bus = NULL;
                return 0;
        }

        bus = sd_bus_unref(bus);
#endif

        e = secure_getenv("XDG_RUNTIME_DIR");
        if (!e)
                return sd_bus_open_user(_bus);

        ee = bus_address_escape(e);
        if (!ee)
                return -ENOMEM;

        r = sd_bus_new(&bus);
        if (r < 0)
                return r;

        bus->address = strjoin("unix:path=", ee, "/systemd/private", NULL);
        if (!bus->address)
                return -ENOMEM;

        r = sd_bus_start(bus);
        if (r < 0)
                return sd_bus_open_user(_bus);

        r = bus_check_peercred(bus);
        if (r < 0)
                return r;

        *_bus = bus;
        bus = NULL;

        return 0;
}
Exemplo n.º 2
0
int bus_open_transport(BusTransport transport, const char *host, bool user, sd_bus **bus) {
        int r;

        assert(transport >= 0);
        assert(transport < _BUS_TRANSPORT_MAX);
        assert(bus);

        assert_return((transport == BUS_TRANSPORT_LOCAL) == !host, -EINVAL);
        assert_return(transport == BUS_TRANSPORT_LOCAL || !user, -ENOTSUP);

        switch (transport) {

        case BUS_TRANSPORT_LOCAL:
                if (user)
                        r = sd_bus_open_user(bus);
                else
                        r = sd_bus_open_system(bus);

                break;

        case BUS_TRANSPORT_REMOTE:
                r = sd_bus_open_system_remote(host, bus);
                break;

        case BUS_TRANSPORT_CONTAINER:
                r = sd_bus_open_system_container(host, bus);
                break;

        default:
                assert_not_reached("Hmm, unknown transport type.");
        }

        return r;
}
Exemplo n.º 3
0
static void test_bus_new_signal(void) {
        sd_bus *bus = NULL;
        _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;

        assert_se(sd_bus_open_user(&bus) >= 0);

        assert_se(sd_bus_message_new_signal(bus, &m, "/an/object/path", "an.interface.name", "Name") >= 0);

        printf("after message_new_signal: refcount %u\n", REFCNT_GET(bus->n_ref));

        sd_bus_flush_close_unref(bus);
        printf("after bus_flush_close_unref: refcount %u\n", m->n_ref);
}
Exemplo n.º 4
0
static int test_bus_open(void) {
        _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
        int r;

        r = sd_bus_open_user(&bus);
        if (IN_SET(r, -ECONNREFUSED, -ENOENT))
                return r;

        assert_se(r >= 0);
        printf("after open: refcount %u\n", REFCNT_GET(bus->n_ref));

        return 0;
}
Exemplo n.º 5
0
/*
 * This is the main loop of the d-bus service.  It won't exit until
 * quit_dbus_main_loop() is called.
 *
 * It is should be invoked as the startup function of a thread or the caller
 * should not expect it to return.
 */
void * multipath_main_loop(void * ap) {
	sd_bus_slot *slot = NULL;
	sd_bus *bus = NULL;
	int r;

	/* Connect to the user bus this time */
	r = sd_bus_open_user(&bus);
	if (r < 0) {
		fprintf(stderr, "Failed to connect to system bus: %s\n", strerror(-r));
		goto finish;
	}


	sync_maps(bus, slot);

	/* Take a well-known service name so that clients can find us */
	r = sd_bus_request_name(bus, MULTIPATH_BASE_INTERFACE, 0);

	if (r < 0) {
		fprintf(stderr, "Failed to acquire service name: %s\n", strerror(-r));
		goto finish;
	}

	for (;;) {
		/* Process requests */
		r = sd_bus_process(bus, NULL);
		if (r < 0) {
			fprintf(stderr, "Failed to process bus: %s\n", strerror(-r));
			goto finish;
		}
		if (r > 0) /* we processed a request, try to process another one, right-away */
			continue;

		/* Wait for the next request to process */
		r = sd_bus_wait(bus, (uint64_t) - 1);
		if (r < 0) {
			fprintf(stderr, "Failed to wait on bus: %s\n", strerror(-r));
			goto finish;
		}
	}

	finish: sd_bus_slot_unref(slot);
	sd_bus_unref(bus);

	return NULL;
}
Exemplo n.º 6
0
int main(int argc, char *argv[]) {
        struct bus_match_node root = {
                .type = BUS_MATCH_ROOT,
        };

        _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
        _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
        enum bus_match_node_type i;
        sd_bus_slot slots[19];
        int r;

        r = sd_bus_open_user(&bus);
        if (r < 0)
                return EXIT_TEST_SKIP;

        assert_se(match_add(slots, &root, "arg2='wal\\'do',sender='foo',type='signal',interface='bar.x',", 1) >= 0);
        assert_se(match_add(slots, &root, "arg2='wal\\'do2',sender='foo',type='signal',interface='bar.x',", 2) >= 0);
        assert_se(match_add(slots, &root, "arg3='test',sender='foo',type='signal',interface='bar.x',", 3) >= 0);
        assert_se(match_add(slots, &root, "arg3='test',sender='foo',type='method_call',interface='bar.x',", 4) >= 0);
        assert_se(match_add(slots, &root, "", 5) >= 0);
        assert_se(match_add(slots, &root, "interface='quux.x'", 6) >= 0);
        assert_se(match_add(slots, &root, "interface='bar.x'", 7) >= 0);
        assert_se(match_add(slots, &root, "member='waldo',path='/foo/bar'", 8) >= 0);
        assert_se(match_add(slots, &root, "path='/foo/bar'", 9) >= 0);
        assert_se(match_add(slots, &root, "path_namespace='/foo'", 10) >= 0);
        assert_se(match_add(slots, &root, "path_namespace='/foo/quux'", 11) >= 0);
        assert_se(match_add(slots, &root, "arg1='two'", 12) >= 0);
        assert_se(match_add(slots, &root, "member='waldo',arg2path='/prefix/'", 13) >= 0);
        assert_se(match_add(slots, &root, "member=waldo,path='/foo/bar',arg3namespace='prefix'", 14) >= 0);
        assert_se(match_add(slots, &root, "arg4has='pi'", 15) >= 0);
        assert_se(match_add(slots, &root, "arg4has='pa'", 16) >= 0);
        assert_se(match_add(slots, &root, "arg4has='po'", 17) >= 0);
        assert_se(match_add(slots, &root, "arg4='pi'", 18) >= 0);

        bus_match_dump(&root, 0);

        assert_se(sd_bus_message_new_signal(bus, &m, "/foo/bar", "bar.x", "waldo") >= 0);
        assert_se(sd_bus_message_append(m, "ssssas", "one", "two", "/prefix/three", "prefix.four", 3, "pi", "pa", "po") >= 0);
        assert_se(sd_bus_message_seal(m, 1, 0) >= 0);

        zero(mask);
        assert_se(bus_match_run(NULL, &root, m) == 0);
        assert_se(mask_contains((unsigned[]) { 9, 8, 7, 5, 10, 12, 13, 14, 15, 16, 17 }, 11));
Exemplo n.º 7
0
static int server_init(sd_bus **_bus) {
        sd_bus *bus = NULL;
        sd_id128_t id;
        int r;
        const char *unique;

        assert_se(_bus);

        r = sd_bus_open_user(&bus);
        if (r < 0) {
                log_error_errno(r, "Failed to connect to user bus: %m");
                goto fail;
        }

        r = sd_bus_get_bus_id(bus, &id);
        if (r < 0) {
                log_error_errno(r, "Failed to get server ID: %m");
                goto fail;
        }

        r = sd_bus_get_unique_name(bus, &unique);
        if (r < 0) {
                log_error_errno(r, "Failed to get unique name: %m");
                goto fail;
        }

        log_info("Peer ID is " SD_ID128_FORMAT_STR ".", SD_ID128_FORMAT_VAL(id));
        log_info("Unique ID: %s", unique);
        log_info("Can send file handles: %i", sd_bus_can_send(bus, 'h'));

        r = sd_bus_request_name(bus, "org.freedesktop.systemd.test", 0);
        if (r < 0) {
                log_error_errno(r, "Failed to acquire name: %m");
                goto fail;
        }

        r = sd_bus_add_fallback(bus, NULL, "/foo/bar", object_callback, NULL);
        if (r < 0) {
                log_error_errno(r, "Failed to add object: %m");
                goto fail;
        }

        r = sd_bus_add_match(bus, NULL, "type='signal',interface='foo.bar',member='Notify'", match_callback, NULL);
        if (r < 0) {
                log_error_errno(r, "Failed to add match: %m");
                goto fail;
        }

        r = sd_bus_add_match(bus, NULL, "type='signal',interface='org.freedesktop.DBus',member='NameOwnerChanged'", match_callback, NULL);
        if (r < 0) {
                log_error_errno(r, "Failed to add match: %m");
                goto fail;
        }

        bus_match_dump(&bus->match_callbacks, 0);

        *_bus = bus;
        return 0;

fail:
        if (bus)
                sd_bus_unref(bus);

        return r;
}
Exemplo n.º 8
0
static void* client2(void*p) {
        _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
        _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL;
        _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
        bool quit = false;
        const char *mid;
        int r;

        r = sd_bus_open_user(&bus);
        if (r < 0) {
                log_error_errno(r, "Failed to connect to user bus: %m");
                goto finish;
        }

        r = sd_bus_message_new_method_call(
                        bus,
                        &m,
                        "org.freedesktop.systemd.test",
                        "/foo/bar/waldo/piep",
                        "org.object.test",
                        "Foobar");
        if (r < 0) {
                log_error_errno(r, "Failed to allocate method call: %m");
                goto finish;
        }

        r = sd_bus_send(bus, m, NULL);
        if (r < 0) {
                log_error("Failed to issue method call: %s", bus_error_message(&error, -r));
                goto finish;
        }

        m = sd_bus_message_unref(m);

        r = sd_bus_message_new_signal(
                        bus,
                        &m,
                        "/foobar",
                        "foo.bar",
                        "Notify");
        if (r < 0) {
                log_error_errno(r, "Failed to allocate signal: %m");
                goto finish;
        }

        r = sd_bus_send(bus, m, NULL);
        if (r < 0) {
                log_error("Failed to issue signal: %s", bus_error_message(&error, -r));
                goto finish;
        }

        m = sd_bus_message_unref(m);

        r = sd_bus_message_new_method_call(
                        bus,
                        &m,
                        "org.freedesktop.systemd.test",
                        "/",
                        "org.freedesktop.DBus.Peer",
                        "GetMachineId");
        if (r < 0) {
                log_error_errno(r, "Failed to allocate method call: %m");
                goto finish;
        }

        r = sd_bus_call(bus, m, 0, &error, &reply);
        if (r < 0) {
                log_error("Failed to issue method call: %s", bus_error_message(&error, -r));
                goto finish;
        }

        r = sd_bus_message_read(reply, "s", &mid);
        if (r < 0) {
                log_error_errno(r, "Failed to parse machine ID: %m");
                goto finish;
        }

        log_info("Machine ID is %s.", mid);

        m = sd_bus_message_unref(m);

        r = sd_bus_message_new_method_call(
                        bus,
                        &m,
                        "org.freedesktop.systemd.test",
                        "/",
                        "org.freedesktop.systemd.test",
                        "Slow");
        if (r < 0) {
                log_error_errno(r, "Failed to allocate method call: %m");
                goto finish;
        }

        reply = sd_bus_message_unref(reply);

        r = sd_bus_call(bus, m, 200 * USEC_PER_MSEC, &error, &reply);
        if (r < 0)
                log_info("Failed to issue method call: %s", bus_error_message(&error, -r));
        else
                log_info("Slow call succeed.");

        m = sd_bus_message_unref(m);

        r = sd_bus_message_new_method_call(
                        bus,
                        &m,
                        "org.freedesktop.systemd.test",
                        "/",
                        "org.freedesktop.systemd.test",
                        "Slow");
        if (r < 0) {
                log_error_errno(r, "Failed to allocate method call: %m");
                goto finish;
        }

        r = sd_bus_call_async(bus, NULL, m, quit_callback, &quit, 200 * USEC_PER_MSEC);
        if (r < 0) {
                log_info("Failed to issue method call: %s", bus_error_message(&error, -r));
                goto finish;
        }

        while (!quit) {
                r = sd_bus_process(bus, NULL);
                if (r < 0) {
                        log_error_errno(r, "Failed to process requests: %m");
                        goto finish;
                }
                if (r == 0) {
                        r = sd_bus_wait(bus, (uint64_t) -1);
                        if (r < 0) {
                                log_error_errno(r, "Failed to wait: %m");
                                goto finish;
                        }
                }
        }

        r = 0;

finish:
        if (bus) {
                _cleanup_bus_message_unref_ sd_bus_message *q;

                r = sd_bus_message_new_method_call(
                                bus,
                                &q,
                                "org.freedesktop.systemd.test",
                                "/",
                                "org.freedesktop.systemd.test",
                                "ExitClient2");
                if (r < 0) {
                        log_error_errno(r, "Failed to allocate method call: %m");
                        goto finish;
                }

                (void) sd_bus_send(bus, q, NULL);
        }

        return INT_TO_PTR(r);
}
Exemplo n.º 9
0
static void* client1(void*p) {
        _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
        _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL;
        _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
        const char *hello;
        int r;
        _cleanup_close_pair_ int pp[2] = { -1, -1 };
        char x;

        r = sd_bus_open_user(&bus);
        if (r < 0) {
                log_error_errno(r, "Failed to connect to user bus: %m");
                goto finish;
        }

        r = sd_bus_call_method(
                        bus,
                        "org.freedesktop.systemd.test",
                        "/",
                        "org.freedesktop.systemd.test",
                        "LowerCase",
                        &error,
                        &reply,
                        "s",
                        "HELLO");
        if (r < 0) {
                log_error_errno(r, "Failed to issue method call: %m");
                goto finish;
        }

        r = sd_bus_message_read(reply, "s", &hello);
        if (r < 0) {
                log_error_errno(r, "Failed to get string: %m");
                goto finish;
        }

        assert_se(streq(hello, "hello"));

        if (pipe2(pp, O_CLOEXEC|O_NONBLOCK) < 0) {
                log_error_errno(errno, "Failed to allocate pipe: %m");
                r = -errno;
                goto finish;
        }

        log_info("Sending fd=%d", pp[1]);

        r = sd_bus_call_method(
                        bus,
                        "org.freedesktop.systemd.test",
                        "/",
                        "org.freedesktop.systemd.test",
                        "FileDescriptor",
                        &error,
                        NULL,
                        "h",
                        pp[1]);
        if (r < 0) {
                log_error_errno(r, "Failed to issue method call: %m");
                goto finish;
        }

        errno = 0;
        if (read(pp[0], &x, 1) <= 0) {
                log_error("Failed to read from pipe: %s", errno ? strerror(errno) : "early read");
                goto finish;
        }

        r = 0;

finish:
        if (bus) {
                _cleanup_bus_message_unref_ sd_bus_message *q;

                r = sd_bus_message_new_method_call(
                                bus,
                                &q,
                                "org.freedesktop.systemd.test",
                                "/",
                                "org.freedesktop.systemd.test",
                                "ExitClient1");
                if (r < 0)
                        log_error_errno(r, "Failed to allocate method call: %m");
                else
                        sd_bus_send(bus, q, NULL);

        }

        return INT_TO_PTR(r);
}