+pop_watch (HCConn *conn, HCEvent event, gpointer data)
+{
+ char buffer[4096];
+ int r;
+ HCConn *pop_conn = data;
+ pop_t *pop = pop_conn->layer;
+ switch (event)
+ {
+ case HC_EVENT_READ:
+ while ((r = hc_conn_read (conn, buffer, sizeof (buffer))) > 0)
+ {
+ g_string_append_len (pop->buffer, buffer, r);
+ while (pop_getline (pop) == 0)
+ {
+ 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);
+ }
+ }
+ break;
+ default:
+ if (pop_conn->func)
+ pop_conn->func (pop_conn, event, pop_conn->data);
+ break;
+ }
+}
+
+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)