From: Thadeu Lima de Souza Cascardo Date: Fri, 3 Jul 2009 21:11:46 +0000 (-0300) Subject: Rewrite POP nethook as a connection layer. X-Git-Tag: v0.1.3~40 X-Git-Url: http://git.cascardo.eti.br/?p=cascardo%2Frnetproxy.git;a=commitdiff_plain;h=b9ad098fa24048b79514e1a435ab10c9decfd381 Rewrite POP nethook as a connection layer. It seemed the most simple thing to do so we could drop the nethook interface entirely. --- diff --git a/pop.c b/pop.c index 357a394..63ce258 100644 --- a/pop.c +++ b/pop.c @@ -20,19 +20,30 @@ #include #include -#include "nethook.h" +#include "hcconn_internal.h" #include "pop.h" #include "usermap.h" typedef struct { - net_read orig_read; - gpointer orig_data; GString *buffer; GString *line; + GString *push; gchar *user; + HCConn *lowconn; } pop_t; +void +pop_destroy (pop_t *pop) +{ + g_string_free (pop->buffer, TRUE); + g_string_free (pop->line, TRUE); + g_string_free (pop->push, TRUE); + if (pop->user) + g_free (pop->user); + g_slice_free (pop_t, (gpointer) pop); +} + static int pop_check_user (pop_t *pop) { @@ -78,54 +89,95 @@ pop_getline (pop_t *pop) } static void -pop_read (net_hook_t *hook, gchar *buffer, size_t len) +pop_watch (HCConn *conn, HCEvent event, gpointer data) { - pop_t *pop = hook->data; - g_string_append_len (pop->buffer, buffer, len); - while (pop_getline (pop) == 0) + char buffer[4096]; + int r; + HCConn *pop_conn = data; + pop_t *pop = pop_conn->layer; + switch (event) { - if (pop_check_user (pop) == 0) + case HC_EVENT_READ: + while ((r = hc_conn_read (conn, buffer, sizeof (buffer))) > 0) { - g_message ("User is trying to authenticate as %s.", pop->user); - if (usermap_perm (pop->user) == ACCESS_DENY) + g_string_append_len (pop->buffer, buffer, r); + while (pop_getline (pop) == 0) { - g_message ("Denying access to user %s.", pop->user); - pop_destroy (hook); - hc_conn_close (hook->peer->conn); - hc_conn_close (hook->conn); - return; + if (pop_check_user (pop) == 0) + { + g_message ("User is trying to authenticate as %s.", + pop->user); + if (usermap_perm (pop->user) == ACCESS_DENY) + { + g_message ("Denying access to user %s.", pop->user); + if (pop_conn->func) + pop_conn->func (pop_conn, HC_EVENT_CLOSE, + pop_conn->data); + return; + } + } + g_string_append_len (pop->push, pop->line->str, pop->line->len); + if (pop_conn->func) + pop_conn->func (pop_conn, HC_EVENT_READ, pop_conn->data); } } - hook->data = pop->orig_data; - pop->orig_read (hook, pop->line->str, pop->line->len); - hook->data = pop; + break; + case HC_EVENT_CLOSE: + if (pop_conn->func) + pop_conn->func (pop_conn, event, pop_conn->data); + break; } } -net_hook_t * -pop_hook_new (net_hook_t *layer) +static ssize_t +pop_read (gpointer data, gchar *buffer, size_t len) +{ + pop_t *pop = data; + int r; + if (len > pop->push->len) + { + r = pop->push->len; + memcpy (buffer, pop->push->str, r); + g_string_truncate (pop->push, 0); + } + else + { + r = len; + memcpy (buffer, pop->push->str, r); + g_string_erase (pop->push, 0, r); + } + return r; +} + +static ssize_t +pop_write (gpointer data, gchar *buffer, size_t len) +{ + pop_t *pop = data; + hc_conn_write (pop->lowconn, buffer, len); + return len; +} + +static void +pop_close (gpointer data) +{ + pop_t *pop = data; + hc_conn_close (pop->lowconn); + pop_destroy (pop); +} + +void +hc_conn_set_driver_pop (HCConn *conn, HCConn *lowconn) { pop_t *pop; pop = g_slice_new (pop_t); - pop->orig_read = layer->read; - pop->orig_data = layer->data; pop->buffer = g_string_sized_new (4096); pop->line = g_string_sized_new (4096); + pop->push = g_string_sized_new (4096); pop->user = NULL; - layer->read = pop_read; - layer->data = pop; - return layer; -} - -void -pop_destroy (net_hook_t *hook) -{ - pop_t *pop = hook->data; - g_string_free (pop->buffer, TRUE); - g_string_free (pop->line, TRUE); - if (pop->user) - g_free (pop->user); - hook->read = pop->orig_read; - hook->data = pop->orig_data; - g_slice_free (net_hook_t, (gpointer) pop); + pop->lowconn = lowconn; + conn->read = pop_read; + conn->write = pop_write; + conn->close = pop_close; + conn->layer = pop; + hc_conn_set_callback (lowconn, pop_watch, conn); } diff --git a/pop.h b/pop.h index 647fae0..2c64621 100644 --- a/pop.h +++ b/pop.h @@ -21,9 +21,8 @@ #ifndef POPPROXY_POP_H #define POPPROXY_POP_H -#include "nethook.h" +#include "hcconn.h" -net_hook_t* pop_hook_new (net_hook_t *); -void pop_destroy (net_hook_t*); +void hc_conn_set_driver_pop (HCConn *, HCConn *); #endif