X-Git-Url: http://git.cascardo.eti.br/?a=blobdiff_plain;f=pop.c;h=63ce258055901fcb379f915c7dd3268aea0aba04;hb=9e01543ef65baeb4e1d477b61391aaef051141e1;hp=1925eb40de9a8dc18f87268d34252804a87c633e;hpb=56de5b8f09f14f10955ac105d77a15ea7321c92a;p=cascardo%2Frnetproxy.git diff --git a/pop.c b/pop.c index 1925eb4..63ce258 100644 --- a/pop.c +++ b/pop.c @@ -18,22 +18,32 @@ ** */ -#include #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) { @@ -79,53 +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); - gnet_conn_disconnect (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); }