+++ /dev/null
-/*
-** Copyright (C) 2006 Thadeu Lima de Souza Cascardo <cascardo@minaslivre.org>
-** Copyright (C) 2009 Thadeu Lima de Souza Cascardo <cascardo@minaslivre.org>
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-**
-*/
-
-#include <glib.h>
-#include <string.h>
-#include "hcconn_internal.h"
-#include "pop.h"
-#include "usermap.h"
-
-typedef struct
-{
- 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)
-{
- gchar *end;
- gchar *s;
- end = pop->line->str + pop->line->len;
- s = pop->line->str;
- while (s < end && *s == ' ') s++;
- if (end - s < 5)
- return -1;
- if (g_ascii_strncasecmp (s, "USER ", 5) != 0)
- return -1;
- s += 5;
- while (s < end && *s == ' ') s++;
- if (s == end)
- return -1;
- end--;
- while (end >= s && (*end == '\n' || *end == '\r')) end--;
- if (end < s)
- return -1;
- if (pop->user)
- g_free (pop->user);
- pop->user = g_strndup (s, end - s + 2);
- pop->user[end - s + 1] = 0;
- return 0;
-}
-
-static int
-pop_getline (pop_t *pop)
-{
- char * end;
- size_t len;
- if (pop->buffer->len == 0)
- return -1;
- end = memchr (pop->buffer->str, '\n', pop->buffer->len);
- if (end == NULL)
- return -1;
- len = end - pop->buffer->str + 1;
- g_string_truncate (pop->line, 0);
- g_string_append_len (pop->line, pop->buffer->str, len);
- g_string_erase (pop->buffer, 0, len);
- return 0;
-}
-
-static void
-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)
-{
- pop_t *pop = data;
- hc_conn_close (pop->lowconn);
- pop_destroy (pop);
-}
-
-int
-hc_conn_set_driver_pop (HCConn *conn, HCConn *lowconn)
-{
- pop_t *pop;
- pop = g_slice_new (pop_t);
- pop->buffer = g_string_sized_new (4096);
- pop->line = g_string_sized_new (4096);
- pop->push = g_string_sized_new (4096);
- pop->user = NULL;
- 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);
- return 0;
-}