From 63d51b566ea270b45b5b34b1feab37b8faa28232 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 9 May 2004 23:20:43 +0000 Subject: main fieryfilter work git-svn-id: file:///home/lennart/svn/public/fieryfilter/fieryfilter@31 79e6afc9-17da-0310-ae3c-b873bff394f4 --- client/daemon.c | 198 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 198 insertions(+) create mode 100644 client/daemon.c (limited to 'client/daemon.c') diff --git a/client/daemon.c b/client/daemon.c new file mode 100644 index 0000000..fd69ef5 --- /dev/null +++ b/client/daemon.c @@ -0,0 +1,198 @@ +#include +#include +#include +#include + +#include "daemon.h" +#include "../daemon/common.h" +#include "connection.h" + +int sock = -1; +GIOChannel *channel = NULL; +GSList *send_message_queue = NULL; + +static void dispatch(message_t *m) { + switch (m->code) { + case MSG_PACKET : + conn_new((ipq_packet_msg_t*) (m+1)); + break; + default: + break; + } + g_free(m); +} + +static gboolean recv_work() { + static guint8 temp[sizeof(message_t)]; + static message_t *m = NULL; + static guint index = 0; + + guint8 *p; + size_t l; + ssize_t r; + + if (index < sizeof(message_t)) { + p = temp + index; + l = sizeof(message_t); + } else { + p = ((guint8*) m) + index; + l = m->length+sizeof(message_t); + } + + if ((r = read(sock, p, l-index)) < 0) { + g_message("read() failed, exiting."); + gtk_main_quit(); + return FALSE; + } + + index += r; + + if (index == sizeof(message_t)) { + m = g_malloc(((message_t*) temp)->length + sizeof(message_t)); + memcpy(m, temp, sizeof(message_t)); + } + + if (index >= sizeof(message_t)) + if (index == sizeof(message_t) + m->length) { + dispatch(m); + m = NULL; + index = 0; + } + + return TRUE; +} + +static gboolean send_work() { + static message_t *m = NULL; + static int index = 0; + guint l, r; + guint8* p; + + if (!m) { + if (!send_message_queue) + return FALSE; + + m = (message_t*) send_message_queue->data; + send_message_queue = g_slist_remove(send_message_queue, m); + + index = 0; + } + + p = ((guint8*) m) + index; + l = m->length + sizeof(message_t); + + if ((r = write(sock, p, l - index)) < 0) { + g_message("write() failed, exiting"); + gtk_main_quit(); + return FALSE; + } + + index += r; + + + if (index >= l) { + g_free(m); + m = NULL; + index = 0; + } + + + return m || send_message_queue; +} + + +static gboolean callback(GIOChannel *source, GIOCondition condition, gpointer data) { + + if (condition & G_IO_HUP) { + gtk_main_quit(); + return FALSE; + } + + if (condition & G_IO_IN) + return recv_work(); + + if (condition & G_IO_OUT) + return send_work(); + + g_error("Huch?"); + return FALSE; +} + +static int enqueue_message(message_t *m) { + + send_message_queue = g_slist_append(send_message_queue, m); + + if (!send_message_queue->next) + g_io_add_watch(channel, G_IO_OUT, callback, NULL); + + return 0; +} + +static message_t* new_message(message_code_t code, guint8* p, guint s) { + message_t* m; + + if (!p) + s = 0; + + m = g_malloc(sizeof(message_t) + s); + + m->code = code; + m->pid = getpid(); + m->length = s; + + if (p) + memcpy(m+1, p, s); + + return m; +} + +static int unix_socket(gchar *p) { + struct sockaddr_un addr; + int sock; + + if ((sock = socket(PF_LOCAL, SOCK_STREAM, 0)) < 0) { + perror("socket(PF_LOCAL, SOCK_STREAM, 0)"); + return -1; + } + + addr.sun_family = AF_LOCAL; + strncpy(addr.sun_path, p, sizeof(addr.sun_path)); + addr.sun_path[sizeof(addr.sun_path)-1] = 0; + + if (connect(sock, (struct sockaddr *) &addr, SUN_LEN(&addr)) < 0) { + perror("connect()"); + return -1; + } + + return sock; +} + +int daemon_init() { + + if ((sock = unix_socket(SOCKET_PATH)) < 0) + return -1; + + channel = g_io_channel_unix_new(sock); + g_io_add_watch(channel, G_IO_IN|G_IO_HUP, callback, NULL); + + return 0; +} + + +void daemon_done() { + if (sock >= 0) + close(sock); + + if (channel) + g_io_channel_unref(channel); +} + + +void daemon_verdict(unsigned long id, guint r) { + static guint8 buf[sizeof(unsigned long) + sizeof(guint32)]; + + *((unsigned long*) &buf[0]) = id; + *((guint32*) &buf[sizeof(unsigned long)]) = r; + + enqueue_message(new_message(MSG_VERDICT, buf, sizeof(buf))); +} -- cgit