-/*
-** Copyright (C) 2006 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 <gnet.h>
-#include <glib.h>
-#include <iksemel.h>
-#include <gsasl.h>
-#include "iksemel_extra.h"
-#include "jabber.h"
-
-jabber_data_t* jabber_data_new (gpointer hook, gpointer parser)
-{
- jabber_data_t *data;
- data = g_slice_new0 (jabber_data_t);
- data->parser = iks_extra_stream_new (hook, parser);
- gsasl_init (&(data->ctx));
- return data;
-}
-
-void jabber_data_destroy (gpointer data)
-{
- jabber_data_t *jdata = (jabber_data_t*) data;
- if (jdata->parser)
- iks_parser_delete (jdata->parser);
- if (jdata->client)
- gsasl_finish (jdata->client);
- if (jdata->server)
- gsasl_finish (jdata->server);
- if (jdata->ctx)
- gsasl_done (jdata->ctx);
- g_slice_free (jabber_data_t, jdata);
-}
-
-static void jabber_connect (net_hook_t* hook)
-{
-}
-
-static void jabber_close (net_hook_t* hook)
-{
- if (hook->peer)
- {
- hook->peer->peer = NULL;
- gnet_conn_disconnect (hook->peer->conn);
- }
- gnet_conn_delete (hook->conn);
- jabber_data_destroy (hook->data);
- g_slice_free (net_hook_t, hook);
-}
-
-static void jabber_write (net_hook_t* hook)
-{
-}
-
-static void jabber_read (net_hook_t* hook, gchar* buffer, size_t len)
-{
- jabber_data_t *jdata = (jabber_data_t*) hook->data;
- iks_parse (jdata->parser, buffer, len, FALSE);
-}
-
-void jabber_error (net_hook_t* hook)
-{
- g_message ("Error in jabber client connection.");
-}
-
-GString* jabber_new_start (iks* node)
-{
- GString* buffer;
- buffer = g_string_sized_new (256);
- g_string_append (buffer, iks_string (iks_stack (node), node));
- g_string_erase (buffer, buffer->len - 2, 1);
- return buffer;
-}
-
-void jabber_connect_server (net_hook_t* hook, char* server, iks* node)
-{
- net_hook_t* server_hook;
- GString* buffer;
- g_message ("Received new stream.");
- if (hook->peer == NULL)
- {
- server_hook = jabber_server_hook_new (hook, server);
- hook->peer = server_hook;
- g_message ("Trying to connect to server %s.", server);
- gnet_conn_connect (hook->peer->conn);
- gnet_conn_read (hook->peer->conn);
- }
- buffer = jabber_new_start (node);
- gnet_conn_write (hook->peer->conn, buffer->str, buffer->len);
- g_string_free (buffer, TRUE);
-}
-
-void
-jabber_sasl_plain_filter (iks *node)
-{
- if (g_str_equal (iks_name (node), "auth") &&
- g_str_equal (iks_find_attrib (node, "xmlns"),
- "urn:ietf:params:xml:ns:xmpp-sasl"))
- {
- char *b64;
- char *uname;
- gsize uname_len;
- b64 = iks_cdata (iks_child (node));
- uname = g_base64_decode (b64, &uname_len);
- g_message ("User trying authentication as %s", uname);
- g_free (uname);
- }
-}
-
-void jabber_send (net_hook_t* hook, iks* node)
-{
- GString* buffer;
- jabber_sasl_plain_filter (node);
- buffer = g_string_new (iks_string (iks_stack (node), node));
- gnet_conn_write (hook->peer->conn, buffer->str, buffer->len);
- g_string_free (buffer, TRUE);
-}
-
-int jabber_parser (gpointer data, int type, iks* node)
-{
- net_hook_t* hook;
- char* server;
- hook = (net_hook_t*) data;
- switch (type)
- {
- case IKS_NODE_START:
- server = iks_find_attrib (node, "to");
- if (server == NULL)
- {
- jabber_error (hook);
- }
- jabber_connect_server (hook, server, node);
- iks_delete (node);
- break;
- case IKS_NODE_NORMAL:
- jabber_send (hook, node);
- iks_delete (node);
- break;
- case IKS_NODE_STOP:
- gnet_conn_write (hook->peer->conn, "</stream:stream>", 16);
- break;
- case IKS_NODE_ERROR:
- break;
- }
- return IKS_OK;
-}
-
-net_hook_t* jabber_hook_new (GConn* conn)
-{
- net_hook_t* hook;
- hook = g_slice_new (net_hook_t);
- hook->conn = conn;
- hook->peer = NULL;
- hook->server = FALSE;
- hook->connect = jabber_connect;
- hook->close = jabber_close;
- hook->write = jabber_write;
- hook->read = jabber_read;
- hook->data = jabber_data_new (hook, jabber_parser);
- gnet_conn_set_callback (hook->conn, nethook_event, hook);
- return hook;
-}
-
-void jabber_destroy (net_hook_t* hook)
-{
- g_slice_free (net_hook_t, hook);
-}