src/protocols/msn/servconn.c

branch
cpw.khc.msnp14
changeset 20472
6a6d2ef151e6
parent 13912
463b4fa9f067
parent 20469
b2836a24d81e
child 20473
91e1b3a49d10
--- a/src/protocols/msn/servconn.c	Wed Oct 18 16:28:51 2006 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,539 +0,0 @@
-/**
- * @file servconn.c Server connection functions
- *
- * gaim
- *
- * Gaim is the legal property of its developers, whose names are too numerous
- * to list here.  Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * 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 "msn.h"
-#include "servconn.h"
-#include "error.h"
-
-static void read_cb(gpointer data, gint source, GaimInputCondition cond);
-
-/**************************************************************************
- * Main
- **************************************************************************/
-
-MsnServConn *
-msn_servconn_new(MsnSession *session, MsnServConnType type)
-{
-	MsnServConn *servconn;
-
-	g_return_val_if_fail(session != NULL, NULL);
-
-	servconn = g_new0(MsnServConn, 1);
-
-	servconn->type = type;
-
-	servconn->session = session;
-	servconn->cmdproc = msn_cmdproc_new(session);
-	servconn->cmdproc->servconn = servconn;
-
-	servconn->httpconn = msn_httpconn_new(servconn);
-
-	servconn->num = session->servconns_count++;
-
-	servconn->tx_buf = gaim_circ_buffer_new(MSN_BUF_LEN);
-	servconn->tx_handler = -1;
-
-	return servconn;
-}
-
-void
-msn_servconn_destroy(MsnServConn *servconn)
-{
-	g_return_if_fail(servconn != NULL);
-
-	if (servconn->processing)
-	{
-		servconn->wasted = TRUE;
-		return;
-	}
-
-	if (servconn->connected)
-		msn_servconn_disconnect(servconn);
-
-	if (servconn->destroy_cb)
-		servconn->destroy_cb(servconn);
-
-	if (servconn->httpconn != NULL)
-		msn_httpconn_destroy(servconn->httpconn);
-
-	g_free(servconn->host);
-
-	gaim_circ_buffer_destroy(servconn->tx_buf);
-	if (servconn->tx_handler > 0)
-		gaim_input_remove(servconn->tx_handler);
-
-	msn_cmdproc_destroy(servconn->cmdproc);
-	g_free(servconn);
-}
-
-void
-msn_servconn_set_connect_cb(MsnServConn *servconn,
-							void (*connect_cb)(MsnServConn *))
-{
-	g_return_if_fail(servconn != NULL);
-	servconn->connect_cb = connect_cb;
-}
-
-void
-msn_servconn_set_disconnect_cb(MsnServConn *servconn,
-							   void (*disconnect_cb)(MsnServConn *))
-{
-	g_return_if_fail(servconn != NULL);
-
-	servconn->disconnect_cb = disconnect_cb;
-}
-
-void
-msn_servconn_set_destroy_cb(MsnServConn *servconn,
-							void (*destroy_cb)(MsnServConn *))
-{
-	g_return_if_fail(servconn != NULL);
-
-	servconn->destroy_cb = destroy_cb;
-}
-
-/**************************************************************************
- * Utility
- **************************************************************************/
-
-void
-msn_servconn_got_error(MsnServConn *servconn, MsnServConnError error)
-{
-	char *tmp;
-	const char *reason;
-
-	const char *names[] = { "Notification", "Switchboard" };
-	const char *name;
-
-	name = names[servconn->type];
-
-	switch (error)
-	{
-		case MSN_SERVCONN_ERROR_CONNECT:
-			reason = _("Unable to connect"); break;
-		case MSN_SERVCONN_ERROR_WRITE:
-			reason = _("Writing error"); break;
-		case MSN_SERVCONN_ERROR_READ:
-			reason = _("Reading error"); break;
-		default:
-			reason = _("Unknown error"); break;
-	}
-
-	gaim_debug_error("msn", "Connection error from %s server (%s): %s\n",
-					 name, servconn->host, reason);
-	tmp = g_strdup_printf(_("Connection error from %s server:\n%s"),
-						  name, reason);
-
-	if (servconn->type == MSN_SERVCONN_NS)
-	{
-		msn_session_set_error(servconn->session, MSN_ERROR_SERVCONN, tmp);
-	}
-	else if (servconn->type == MSN_SERVCONN_SB)
-	{
-		MsnSwitchBoard *swboard;
-		swboard = servconn->cmdproc->data;
-		if (swboard != NULL)
-			swboard->error = MSN_SB_ERROR_CONNECTION;
-	}
-
-	msn_servconn_disconnect(servconn);
-
-	g_free(tmp);
-}
-
-/**************************************************************************
- * Connect
- **************************************************************************/
-
-static void
-connect_cb(gpointer data, gint source, GaimInputCondition cond)
-{
-	MsnServConn *servconn = data;
-
-	servconn->processing = FALSE;
-
-	if (servconn->wasted)
-	{
-		msn_servconn_destroy(servconn);
-		return;
-	}
-
-	servconn->fd = source;
-
-	if (source > 0)
-	{
-		servconn->connected = TRUE;
-
-		/* Someone wants to know we connected. */
-		servconn->connect_cb(servconn);
-		servconn->inpa = gaim_input_add(servconn->fd, GAIM_INPUT_READ,
-			read_cb, data);
-	}
-	else
-	{
-		msn_servconn_got_error(servconn, MSN_SERVCONN_ERROR_CONNECT);
-	}
-}
-
-gboolean
-msn_servconn_connect(MsnServConn *servconn, const char *host, int port)
-{
-	MsnSession *session;
-	int r;
-
-	g_return_val_if_fail(servconn != NULL, FALSE);
-	g_return_val_if_fail(host     != NULL, FALSE);
-	g_return_val_if_fail(port      > 0,    FALSE);
-
-	session = servconn->session;
-
-	if (servconn->connected)
-		msn_servconn_disconnect(servconn);
-
-	if (servconn->host != NULL)
-		g_free(servconn->host);
-
-	servconn->host = g_strdup(host);
-
-	if (session->http_method)
-	{
-		/* HTTP Connection. */
-
-		if (!servconn->httpconn->connected)
-			if (!msn_httpconn_connect(servconn->httpconn, host, port))
-				return FALSE;;
-
-		servconn->connected = TRUE;
-		servconn->httpconn->virgin = TRUE;
-
-		/* Someone wants to know we connected. */
-		servconn->connect_cb(servconn);
-
-		return TRUE;
-	}
-
-	r = gaim_proxy_connect(session->account, host, port, connect_cb,
-		servconn);
-
-	if (r == 0){
-		servconn->processing = TRUE;
-		return TRUE;
-	}else{
-		return FALSE;
-	}
-}
-
-void
-msn_servconn_disconnect(MsnServConn *servconn)
-{
-	g_return_if_fail(servconn != NULL);
-
-	if (!servconn->connected)
-	{
-		/* We could not connect. */
-		if (servconn->disconnect_cb != NULL)
-			servconn->disconnect_cb(servconn);
-
-		return;
-	}
-
-	if (servconn->session->http_method)
-	{
-		/* Fake disconnection. */
-		if (servconn->disconnect_cb != NULL)
-			servconn->disconnect_cb(servconn);
-
-		return;
-	}
-
-	if (servconn->inpa > 0)
-	{
-		gaim_input_remove(servconn->inpa);
-		servconn->inpa = 0;
-	}
-
-	close(servconn->fd);
-
-	servconn->rx_buf = NULL;
-	servconn->rx_len = 0;
-	servconn->payload_len = 0;
-
-	servconn->connected = FALSE;
-
-	if (servconn->disconnect_cb != NULL)
-		servconn->disconnect_cb(servconn);
-}
-
-static void
-servconn_write_cb(gpointer data, gint source, GaimInputCondition cond)
-{
-	MsnServConn *servconn = data;
-	int ret, writelen;
-
-	writelen = gaim_circ_buffer_get_max_read(servconn->tx_buf);
-
-	if (writelen == 0) {
-		gaim_input_remove(servconn->tx_handler);
-		servconn->tx_handler = -1;
-		return;
-	}
-
-	ret = write(servconn->fd, servconn->tx_buf->outptr, writelen);
-
-	if (ret < 0 && errno == EAGAIN)
-		return;
-	else if (ret <= 0) {
-		msn_servconn_got_error(servconn, MSN_SERVCONN_ERROR_WRITE);
-		return;
-	}
-
-	gaim_circ_buffer_mark_read(servconn->tx_buf, ret);
-}
-
-ssize_t
-msn_servconn_write(MsnServConn *servconn, const char *buf, size_t len)
-{
-	ssize_t ret = 0;
-
-	g_return_val_if_fail(servconn != NULL, 0);
-
-	if (!servconn->session->http_method)
-	{
-		if (servconn->tx_handler == -1) {
-			switch (servconn->type)
-			{
-				case MSN_SERVCONN_NS:
-				case MSN_SERVCONN_SB:
-					ret = write(servconn->fd, buf, len);
-					break;
-#if 0
-				case MSN_SERVCONN_DC:
-					ret = write(servconn->fd, &buf, sizeof(len));
-					ret = write(servconn->fd, buf, len);
-					break;
-#endif
-				default:
-					ret = write(servconn->fd, buf, len);
-					break;
-			}
-		} else {
-			ret = -1;
-			errno = EAGAIN;
-		}
-
-		if (ret < 0 && errno == EAGAIN)
-			ret = 0;
-		if (ret < len) {
-			if (servconn->tx_handler == -1)
-				servconn->tx_handler = gaim_input_add(
-					servconn->fd, GAIM_INPUT_WRITE,
-					servconn_write_cb, servconn);
-			gaim_circ_buffer_append(servconn->tx_buf, buf + ret,
-				len - ret);
-		}
-	}
-	else
-	{
-		ret = msn_httpconn_write(servconn->httpconn, buf, len);
-	}
-
-	if (ret == -1)
-	{
-		msn_servconn_got_error(servconn, MSN_SERVCONN_ERROR_WRITE);
-	}
-
-	return ret;
-}
-
-static void
-read_cb(gpointer data, gint source, GaimInputCondition cond)
-{
-	MsnServConn *servconn;
-	MsnSession *session;
-	char buf[MSN_BUF_LEN];
-	char *cur, *end, *old_rx_buf;
-	int len, cur_len;
-
-	servconn = data;
-	session = servconn->session;
-
-	len = read(servconn->fd, buf, sizeof(buf) - 1);
-
-	if (len < 0 && errno == EAGAIN)
-		return;
-	else if (len <= 0)
-	{
-		gaim_debug_error("msn", "servconn read error, len: %d error: %s\n", len, strerror(errno));
-		msn_servconn_got_error(servconn, MSN_SERVCONN_ERROR_READ);
-
-		return;
-	}
-
-	buf[len] = '\0';
-
-	servconn->rx_buf = g_realloc(servconn->rx_buf, len + servconn->rx_len + 1);
-	memcpy(servconn->rx_buf + servconn->rx_len, buf, len + 1);
-	servconn->rx_len += len;
-
-	end = old_rx_buf = servconn->rx_buf;
-
-	servconn->processing = TRUE;
-
-	do
-	{
-		cur = end;
-
-		if (servconn->payload_len)
-		{
-			if (servconn->payload_len > servconn->rx_len)
-				/* The payload is still not complete. */
-				break;
-
-			cur_len = servconn->payload_len;
-			end += cur_len;
-		}
-		else
-		{
-			end = strstr(cur, "\r\n");
-
-			if (end == NULL)
-				/* The command is still not complete. */
-				break;
-
-			*end = '\0';
-			end += 2;
-			cur_len = end - cur;
-		}
-
-		servconn->rx_len -= cur_len;
-
-		if (servconn->payload_len){
-			msn_cmdproc_process_payload(servconn->cmdproc, cur, cur_len);
-			servconn->payload_len = 0;
-		}else{
-			msn_cmdproc_process_cmd_text(servconn->cmdproc, cur);
-			servconn->payload_len = servconn->cmdproc->last_cmd->payload_len;
-		}
-	} while (servconn->connected && !servconn->wasted && servconn->rx_len > 0);
-
-	if (servconn->connected && !servconn->wasted)
-	{
-		if (servconn->rx_len > 0)
-			servconn->rx_buf = g_memdup(cur, servconn->rx_len);
-		else
-			servconn->rx_buf = NULL;
-	}
-
-	servconn->processing = FALSE;
-
-	if (servconn->wasted)
-		msn_servconn_destroy(servconn);
-
-	g_free(old_rx_buf);
-}
-
-#if 0
-static int
-create_listener(int port)
-{
-	int fd;
-	const int on = 1;
-
-#if 0
-	struct addrinfo hints;
-	struct addrinfo *c, *res;
-	char port_str[5];
-
-	snprintf(port_str, sizeof(port_str), "%d", port);
-
-	memset(&hints, 0, sizeof(hints));
-
-	hints.ai_flags = AI_PASSIVE;
-	hints.ai_family = AF_UNSPEC;
-	hints.ai_socktype = SOCK_STREAM;
-
-	if (getaddrinfo(NULL, port_str, &hints, &res) != 0)
-	{
-		gaim_debug_error("msn", "Could not get address info: %s.\n",
-						 port_str);
-		return -1;
-	}
-
-	for (c = res; c != NULL; c = c->ai_next)
-	{
-		fd = socket(c->ai_family, c->ai_socktype, c->ai_protocol);
-
-		if (fd < 0)
-			continue;
-
-		setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
-
-		if (bind(fd, c->ai_addr, c->ai_addrlen) == 0)
-			break;
-
-		close(fd);
-	}
-
-	if (c == NULL)
-	{
-		gaim_debug_error("msn", "Could not find socket: %s.\n", port_str);
-		return -1;
-	}
-
-	freeaddrinfo(res);
-#else
-	struct sockaddr_in sockin;
-
-	fd = socket(AF_INET, SOCK_STREAM, 0);
-
-	if (fd < 0)
-		return -1;
-
-	if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) != 0)
-	{
-		close(fd);
-		return -1;
-	}
-
-	memset(&sockin, 0, sizeof(struct sockaddr_in));
-	sockin.sin_family = AF_INET;
-	sockin.sin_port = htons(port);
-
-	if (bind(fd, (struct sockaddr *)&sockin, sizeof(struct sockaddr_in)) != 0)
-	{
-		close(fd);
-		return -1;
-	}
-#endif
-
-	if (listen (fd, 4) != 0)
-	{
-		close (fd);
-		return -1;
-	}
-
-	fcntl(fd, F_SETFL, O_NONBLOCK);
-
-	return fd;
-}
-#endif

mercurial