summaryrefslogtreecommitdiff
path: root/fmrx-cat.c
blob: c22d0394f2630fb0a2c940e799c53f69d7189ddd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include <stdio.h>
#include <unistd.h>
#include <glib.h>
#include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-lowlevel.h>

static GMainLoop *main_loop;
static DBusConnection *bus;
static int fd;

#define BUS_NAME      "com.javispedro.fmrxd"
#define BUS_PATH      "/com/javispedro/fmrxd"
#define BUS_INTERFACE BUS_NAME

#define BUFFER_SIZE 4*4096

static gchar buffer[BUFFER_SIZE];

static gboolean monitor_callback(GIOChannel *source, GIOCondition condition, gpointer data)
{
	GError *err = NULL;
	gsize read, written = 0;
	do {
		g_io_channel_read_chars(source, buffer, BUFFER_SIZE, &read, &err);
		if (err != NULL) {
			g_printerr("Unable to read from server: %s\n", err->message);
			g_error_free(err);
			g_main_loop_quit(main_loop);
		}
		if (read > 0) {
			written = fwrite(buffer, 1, read, stdout);
			if (written < 0) {
				g_printerr("Unable to write to stdout\n");
				g_main_loop_quit(main_loop);
			}
		}
	} while (read > 0 && written > 0);

	return TRUE;
}

static void monitor()
{
	GIOChannel *channel = g_io_channel_unix_new(fd);
	g_io_channel_set_encoding(channel, NULL, NULL);
	g_io_add_watch(channel, G_IO_IN, monitor_callback, NULL);
	g_io_channel_unref(channel);
}

static void connect()
{
	DBusError err;
	dbus_bool_t ret;
	DBusMessage *reply;
	DBusMessage *msg = dbus_message_new_method_call(BUS_NAME, BUS_PATH,
												  BUS_INTERFACE, "Connect");
	g_assert(msg != NULL);

	dbus_error_init(&err);

	reply = dbus_connection_send_with_reply_and_block(bus, msg, -1, &err);
	dbus_message_unref(msg);

	if (!reply) {
		g_assert(dbus_error_is_set(&err));
		g_printerr("Server error: %s", err.message);
		dbus_error_free(&err);
		return;
	}

	ret = dbus_message_get_args(reply, &err, DBUS_TYPE_UNIX_FD, &fd, DBUS_TYPE_INVALID);
	g_assert(ret == TRUE);
	g_assert(!dbus_error_is_set(&err));
	g_assert(fd != -1);

	dbus_message_unref(reply);
}

static void dbus_init()
{
	DBusError err;	dbus_error_init(&err);
	bus = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
	g_assert(bus != NULL);
	g_assert(!dbus_error_is_set(&err));
	dbus_connection_setup_with_g_main(bus, g_main_loop_get_context(main_loop));
}

int main(int argc, char **argv)
{
	main_loop = g_main_loop_new(NULL, FALSE);

	dbus_init();
	connect();
	monitor();

	g_main_loop_run(main_loop);

	close(fd);

	return 0;
}