summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Ruprecht <cmaiku@gmail.com>2016-10-02 15:41:50 -0500
committerMike Ruprecht <cmaiku@gmail.com>2016-10-02 15:41:50 -0500
commit7bb46730da46048b505728ca1b5708dc89404831 (patch)
tree88294ef95ae34a32e1fd7675cef82ee7a0f0878a
parent4582a99d416116b07bc2d28ce1198200f2f2b11f (diff)
downloadpidgin-7bb46730da46048b505728ca1b5708dc89404831.tar.gz
msn: Remove protocol plugin from tree
The MSN prpl has been unusable and dormant for some time. MSNP18 has been discontinued and this prpl would require a large update to start working again. See: http://ismsndeadyet.com/ Pidgin SkypeWeb however, should provide enough functionality as a replacement if people still want to use MSN: https://github.com/EionRobb/skype4pidgin/tree/master/skypeweb
-rw-r--r--configure.ac16
-rw-r--r--libpurple/protocols/Makefile.am2
-rw-r--r--libpurple/protocols/Makefile.mingw2
-rw-r--r--libpurple/protocols/msn/Makefile.am102
-rw-r--r--libpurple/protocols/msn/Makefile.mingw110
-rw-r--r--libpurple/protocols/msn/cmdproc.c339
-rw-r--r--libpurple/protocols/msn/cmdproc.h100
-rw-r--r--libpurple/protocols/msn/command.c113
-rw-r--r--libpurple/protocols/msn/command.h84
-rw-r--r--libpurple/protocols/msn/contact.c2048
-rw-r--r--libpurple/protocols/msn/contact.h747
-rw-r--r--libpurple/protocols/msn/directconn.c958
-rw-r--r--libpurple/protocols/msn/directconn.h200
-rw-r--r--libpurple/protocols/msn/error.c384
-rw-r--r--libpurple/protocols/msn/error.h57
-rw-r--r--libpurple/protocols/msn/group.c89
-rw-r--r--libpurple/protocols/msn/group.h109
-rw-r--r--libpurple/protocols/msn/history.c93
-rw-r--r--libpurple/protocols/msn/history.h50
-rw-r--r--libpurple/protocols/msn/httpconn.c739
-rw-r--r--libpurple/protocols/msn/httpconn.h112
-rw-r--r--libpurple/protocols/msn/msg.c1217
-rw-r--r--libpurple/protocols/msn/msg.h325
-rw-r--r--libpurple/protocols/msn/msn.c3069
-rw-r--r--libpurple/protocols/msn/msn.h158
-rw-r--r--libpurple/protocols/msn/msnutils.c719
-rw-r--r--libpurple/protocols/msn/msnutils.h244
-rw-r--r--libpurple/protocols/msn/nexus.c670
-rw-r--r--libpurple/protocols/msn/nexus.h219
-rw-r--r--libpurple/protocols/msn/notification.c2480
-rw-r--r--libpurple/protocols/msn/notification.h124
-rw-r--r--libpurple/protocols/msn/object.c459
-rw-r--r--libpurple/protocols/msn/object.h276
-rw-r--r--libpurple/protocols/msn/oim.c886
-rw-r--r--libpurple/protocols/msn/oim.h163
-rw-r--r--libpurple/protocols/msn/p2p.c872
-rw-r--r--libpurple/protocols/msn/p2p.h264
-rw-r--r--libpurple/protocols/msn/page.c85
-rw-r--r--libpurple/protocols/msn/page.h81
-rw-r--r--libpurple/protocols/msn/sbconn.c174
-rw-r--r--libpurple/protocols/msn/sbconn.h41
-rw-r--r--libpurple/protocols/msn/servconn.c608
-rw-r--r--libpurple/protocols/msn/servconn.h193
-rw-r--r--libpurple/protocols/msn/session.c500
-rw-r--r--libpurple/protocols/msn/session.h245
-rw-r--r--libpurple/protocols/msn/slp.c396
-rw-r--r--libpurple/protocols/msn/slp.h51
-rw-r--r--libpurple/protocols/msn/slpcall.c1157
-rw-r--r--libpurple/protocols/msn/slpcall.h98
-rw-r--r--libpurple/protocols/msn/slplink.c646
-rw-r--r--libpurple/protocols/msn/slplink.h98
-rw-r--r--libpurple/protocols/msn/slpmsg.c309
-rw-r--r--libpurple/protocols/msn/slpmsg.h150
-rw-r--r--libpurple/protocols/msn/slpmsg_part.c232
-rw-r--r--libpurple/protocols/msn/slpmsg_part.h66
-rw-r--r--libpurple/protocols/msn/soap.c688
-rw-r--r--libpurple/protocols/msn/soap.h52
-rw-r--r--libpurple/protocols/msn/state.c315
-rw-r--r--libpurple/protocols/msn/state.h69
-rw-r--r--libpurple/protocols/msn/switchboard.c1197
-rw-r--r--libpurple/protocols/msn/switchboard.h266
-rw-r--r--libpurple/protocols/msn/table.c132
-rw-r--r--libpurple/protocols/msn/table.h93
-rw-r--r--libpurple/protocols/msn/tlv.c458
-rw-r--r--libpurple/protocols/msn/tlv.h77
-rw-r--r--libpurple/protocols/msn/transaction.c247
-rw-r--r--libpurple/protocols/msn/transaction.h87
-rw-r--r--libpurple/protocols/msn/user.c801
-rw-r--r--libpurple/protocols/msn/user.h533
-rw-r--r--libpurple/protocols/msn/userlist.c759
-rw-r--r--libpurple/protocols/msn/userlist.h112
-rw-r--r--libpurple/protocols/msn/xfer.c235
-rw-r--r--libpurple/protocols/msn/xfer.h67
-rw-r--r--pidgin/win32/nsis/pidgin-installer.nsi1
-rw-r--r--po/POTFILES.in15
75 files changed, 8 insertions, 29925 deletions
diff --git a/configure.ac b/configure.ac
index 7d0f00f2c7..528ac55ca5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1189,7 +1189,7 @@ if test "x$STATIC_PRPLS" != "x" -a "x$DYNAMIC_PRPLS" = "xall"; then
fi
if test "x$STATIC_PRPLS" = "xall" ; then
- STATIC_PRPLS="bonjour gg irc jabber msn myspace novell oscar sametime silc simple yahoo zephyr"
+ STATIC_PRPLS="bonjour gg irc jabber myspace novell oscar sametime silc simple yahoo zephyr"
fi
if test "x$have_meanwhile" != "xyes" ; then
STATIC_PRPLS=`echo $STATIC_PRPLS | $sedpath 's/sametime//'`
@@ -1238,7 +1238,6 @@ for i in $STATIC_PRPLS ; do
gg) static_gg=yes ;;
irc) static_irc=yes ;;
jabber) static_jabber=yes ;;
- msn) static_msn=yes ;;
myspace) static_myspace=yes ;;
novell) static_novell=yes ;;
oscar) static_oscar=yes ;;
@@ -1257,7 +1256,6 @@ AM_CONDITIONAL(STATIC_BONJOUR, test "x$static_bonjour" = "xyes")
AM_CONDITIONAL(STATIC_GG, test "x$static_gg" = "xyes")
AM_CONDITIONAL(STATIC_IRC, test "x$static_irc" = "xyes")
AM_CONDITIONAL(STATIC_JABBER, test "x$static_jabber" = "xyes")
-AM_CONDITIONAL(STATIC_MSN, test "x$static_msn" = "xyes")
AM_CONDITIONAL(STATIC_MYSPACE, test "x$static_myspace" = "xyes")
AM_CONDITIONAL(STATIC_NOVELL, test "x$static_novell" = "xyes")
AM_CONDITIONAL(STATIC_OSCAR, test "x$static_oscar" = "xyes")
@@ -1272,7 +1270,7 @@ AC_DEFINE_UNQUOTED(STATIC_PROTO_INIT, $extern_init static void static_proto_init
AC_ARG_WITH(dynamic_prpls, [AC_HELP_STRING([--with-dynamic-prpls], [specify which protocols to build dynamically])], [DYNAMIC_PRPLS=`echo $withval | $sedpath 's/,/ /g'`])
if test "x$DYNAMIC_PRPLS" = "xall" ; then
- DYNAMIC_PRPLS="bonjour gg irc jabber msn myspace novell oscar sametime silc simple yahoo zephyr"
+ DYNAMIC_PRPLS="bonjour gg irc jabber myspace novell oscar sametime silc simple yahoo zephyr"
fi
if test "x$have_meanwhile" != "xyes"; then
DYNAMIC_PRPLS=`echo $DYNAMIC_PRPLS | $sedpath 's/sametime//'`
@@ -1293,7 +1291,6 @@ for i in $DYNAMIC_PRPLS ; do
gg) dynamic_gg=yes ;;
irc) dynamic_irc=yes ;;
jabber) dynamic_jabber=yes ;;
- msn) dynamic_msn=yes ;;
myspace) dynamic_myspace=yes ;;
novell) dynamic_novell=yes ;;
null) dynamic_null=yes ;;
@@ -1791,7 +1788,7 @@ AC_ARG_ENABLE(nss,
[enable_nss="$enableval"],
[enable_nss="yes"])
-msg_ssl="None. MSN, Yahoo!, Novell Groupwise and Google Talk will not work without GnuTLS or NSS. OpenSSL is NOT usable!"
+msg_ssl="None. Yahoo!, Novell Groupwise and Google Talk will not work without GnuTLS or NSS. OpenSSL is NOT usable!"
looked_for_gnutls="no"
dnl #
dnl # Check for GnuTLS if it's specified.
@@ -2202,19 +2199,19 @@ elif test "x$looked_for_gnutls" = "xyes" -a "x$looked_for_nss" = "xyes" -a "x$fo
AC_MSG_ERROR([
Neither GnuTLS or NSS SSL development headers found.
Use --disable-nss --disable-gnutls if you do not need SSL support.
-MSN, Yahoo!, Novell Groupwise and Google Talk will not work without GnuTLS or NSS. OpenSSL is NOT usable!
+Yahoo!, Novell Groupwise and Google Talk will not work without GnuTLS or NSS. OpenSSL is NOT usable!
])
elif test "x$looked_for_gnutls" = "xyes" -a "x$force_deps" = "xyes" ; then
AC_MSG_ERROR([
GnuTLS SSL development headers not found.
Use --disable-gnutls if you do not need SSL support.
-MSN, Yahoo!, Novell Groupwise and Google Talk will not work without SSL support.
+Yahoo!, Novell Groupwise and Google Talk will not work without SSL support.
])
elif test "x$looked_for_nss" = "xyes" -a "x$force_deps" = "xyes" ; then
AC_MSG_ERROR([
NSS SSL development headers not found.
Use --disable-nss if you do not need SSL support.
-MSN, Yahoo!, Novell Groupwise and Google Talk will not work without SSL support.
+Yahoo!, Novell Groupwise and Google Talk will not work without SSL support.
])
fi
@@ -2659,7 +2656,6 @@ AC_CONFIG_FILES([Makefile
libpurple/protocols/gg/Makefile
libpurple/protocols/irc/Makefile
libpurple/protocols/jabber/Makefile
- libpurple/protocols/msn/Makefile
libpurple/protocols/myspace/Makefile
libpurple/protocols/novell/Makefile
libpurple/protocols/null/Makefile
diff --git a/libpurple/protocols/Makefile.am b/libpurple/protocols/Makefile.am
index 0e3a2989bd..675ee5818f 100644
--- a/libpurple/protocols/Makefile.am
+++ b/libpurple/protocols/Makefile.am
@@ -1,5 +1,5 @@
EXTRA_DIST = Makefile.mingw
-DIST_SUBDIRS = bonjour gg irc jabber msn myspace novell null oscar sametime silc silc10 simple yahoo zephyr
+DIST_SUBDIRS = bonjour gg irc jabber myspace novell null oscar sametime silc silc10 simple yahoo zephyr
SUBDIRS = $(DYNAMIC_PRPLS) $(STATIC_PRPLS)
diff --git a/libpurple/protocols/Makefile.mingw b/libpurple/protocols/Makefile.mingw
index 0c959d0a8a..36000fc18b 100644
--- a/libpurple/protocols/Makefile.mingw
+++ b/libpurple/protocols/Makefile.mingw
@@ -8,7 +8,7 @@
PIDGIN_TREE_TOP := ../..
include $(PIDGIN_TREE_TOP)/libpurple/win32/global.mak
-SUBDIRS = gg irc jabber msn novell null oscar sametime silc simple yahoo bonjour myspace
+SUBDIRS = gg irc jabber novell null oscar sametime silc simple yahoo bonjour myspace
.PHONY: all install clean
diff --git a/libpurple/protocols/msn/Makefile.am b/libpurple/protocols/msn/Makefile.am
deleted file mode 100644
index f2edc6454e..0000000000
--- a/libpurple/protocols/msn/Makefile.am
+++ /dev/null
@@ -1,102 +0,0 @@
-EXTRA_DIST = \
- directconn.c \
- directconn.h \
- Makefile.mingw
-
-pkgdir = $(libdir)/purple-$(PURPLE_MAJOR_VERSION)
-
-MSNSOURCES = \
- cmdproc.c \
- cmdproc.h \
- command.c \
- command.h \
- contact.c\
- contact.h\
- directconn.c \
- directconn.h \
- error.c \
- error.h \
- group.c \
- group.h \
- history.c \
- history.h \
- httpconn.c \
- httpconn.h \
- msg.c \
- msg.h \
- msn.c \
- msn.h \
- nexus.c \
- nexus.h \
- notification.c \
- notification.h \
- object.c \
- object.h \
- oim.c\
- oim.h\
- p2p.c \
- p2p.h \
- page.c \
- page.h \
- servconn.c \
- servconn.h \
- session.c \
- session.h \
- slp.c \
- slp.h \
- slpcall.c \
- slpcall.h \
- slplink.c \
- slplink.h \
- slpmsg.c \
- slpmsg.h \
- slpmsg_part.c \
- slpmsg_part.h \
- soap.c \
- soap.h \
- state.c \
- state.h \
- sbconn.c \
- sbconn.h \
- switchboard.c \
- switchboard.h \
- table.c \
- table.h \
- tlv.c \
- tlv.h \
- transaction.c \
- transaction.h \
- user.c \
- user.h \
- userlist.c \
- userlist.h \
- xfer.c \
- xfer.h \
- msnutils.c \
- msnutils.h
-
-AM_CFLAGS = $(st)
-
-libmsn_la_LDFLAGS = -module -avoid-version
-
-if STATIC_MSN
-
-st = -DPURPLE_STATIC_PRPL
-noinst_LTLIBRARIES = libmsn.la
-libmsn_la_SOURCES = $(MSNSOURCES)
-libmsn_la_CFLAGS = $(AM_CFLAGS)
-
-else
-
-st =
-pkg_LTLIBRARIES = libmsn.la
-libmsn_la_SOURCES = $(MSNSOURCES)
-libmsn_la_LIBADD = $(GLIB_LIBS)
-
-endif
-
-AM_CPPFLAGS = \
- -I$(top_srcdir)/libpurple \
- -I$(top_builddir)/libpurple \
- $(GLIB_CFLAGS) \
- $(DEBUG_CFLAGS)
diff --git a/libpurple/protocols/msn/Makefile.mingw b/libpurple/protocols/msn/Makefile.mingw
deleted file mode 100644
index 5d3072f97a..0000000000
--- a/libpurple/protocols/msn/Makefile.mingw
+++ /dev/null
@@ -1,110 +0,0 @@
-#
-# Makefile.mingw
-#
-# Description: Makefile for win32 (mingw) version of libmsn
-#
-
-PIDGIN_TREE_TOP := ../../..
-include $(PIDGIN_TREE_TOP)/libpurple/win32/global.mak
-
-TARGET = libmsn
-TYPE = PLUGIN
-
-# Static or Plugin...
-ifeq ($(TYPE),STATIC)
- DEFINES += -DSTATIC
- DLL_INSTALL_DIR = $(PURPLE_INSTALL_DIR)
-else
-ifeq ($(TYPE),PLUGIN)
- DLL_INSTALL_DIR = $(PURPLE_INSTALL_PLUGINS_DIR)
-endif
-endif
-
-##
-## INCLUDE PATHS
-##
-INCLUDE_PATHS += -I. \
- -I$(GTK_TOP)/include \
- -I$(GTK_TOP)/include/glib-2.0 \
- -I$(GTK_TOP)/lib/glib-2.0/include \
- -I$(PURPLE_TOP) \
- -I$(PURPLE_TOP)/win32 \
- -I$(PIDGIN_TREE_TOP)
-
-LIB_PATHS += -L$(GTK_TOP)/lib \
- -L$(PURPLE_TOP)
-
-##
-## SOURCES, OBJECTS
-##
-C_SRC = cmdproc.c \
- command.c \
- contact.c\
- directconn.c \
- error.c \
- group.c \
- history.c \
- httpconn.c \
- msg.c \
- msn.c \
- nexus.c \
- notification.c \
- object.c \
- oim.c\
- p2p.c \
- page.c \
- servconn.c \
- session.c \
- slp.c \
- slpcall.c \
- slplink.c \
- slpmsg.c \
- slpmsg_part.c \
- soap.c\
- state.c \
- sbconn.c \
- switchboard.c \
- table.c \
- tlv.c \
- transaction.c \
- user.c \
- userlist.c \
- xfer.c \
- msnutils.c
-
-OBJECTS = $(C_SRC:%.c=%.o)
-
-##
-## LIBRARIES
-##
-LIBS = \
- -lglib-2.0 \
- -lintl \
- -lws2_32 \
- -lpurple
-
-include $(PIDGIN_COMMON_RULES)
-
-##
-## TARGET DEFINITIONS
-##
-.PHONY: all install clean
-
-all: $(TARGET).dll
-
-install: all $(DLL_INSTALL_DIR)
- cp $(TARGET).dll $(DLL_INSTALL_DIR)
-
-$(OBJECTS): $(PURPLE_CONFIG_H)
-
-$(TARGET).dll: $(PURPLE_DLL).a $(OBJECTS)
- $(CC) -shared $(OBJECTS) $(LIB_PATHS) $(LIBS) $(DLL_LD_FLAGS) -o $(TARGET).dll
-
-##
-## CLEAN RULES
-##
-clean:
- rm -f $(OBJECTS)
- rm -f $(TARGET).dll
-
-include $(PIDGIN_COMMON_TARGETS)
diff --git a/libpurple/protocols/msn/cmdproc.c b/libpurple/protocols/msn/cmdproc.c
deleted file mode 100644
index 7a27f633ac..0000000000
--- a/libpurple/protocols/msn/cmdproc.c
+++ /dev/null
@@ -1,339 +0,0 @@
-/**
- * @file cmdproc.c MSN command processor functions
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-
-#include "internal.h"
-#include "debug.h"
-
-#include "cmdproc.h"
-#include "error.h"
-
-MsnCmdProc *
-msn_cmdproc_new(MsnSession *session)
-{
- MsnCmdProc *cmdproc;
-
- cmdproc = g_new0(MsnCmdProc, 1);
-
- cmdproc->session = session;
- cmdproc->txqueue = g_queue_new();
- cmdproc->history = msn_history_new();
-
- cmdproc->multiparts = g_hash_table_new_full(g_str_hash, g_str_equal,
- NULL, (GDestroyNotify)msn_message_unref);
-
- return cmdproc;
-}
-
-void
-msn_cmdproc_destroy(MsnCmdProc *cmdproc)
-{
- MsnTransaction *trans;
-
- while ((trans = g_queue_pop_head(cmdproc->txqueue)) != NULL)
- msn_transaction_destroy(trans);
-
- g_queue_free(cmdproc->txqueue);
-
- msn_history_destroy(cmdproc->history);
-
- if (cmdproc->last_cmd != NULL)
- msn_command_unref(cmdproc->last_cmd);
-
- g_hash_table_destroy(cmdproc->multiparts);
-
- g_free(cmdproc);
-}
-
-void
-msn_cmdproc_process_queue(MsnCmdProc *cmdproc)
-{
- MsnTransaction *trans;
-
- while ((trans = g_queue_pop_head(cmdproc->txqueue)) != NULL)
- msn_cmdproc_send_trans(cmdproc, trans);
-}
-
-void
-msn_cmdproc_queue_trans(MsnCmdProc *cmdproc, MsnTransaction *trans)
-{
- g_return_if_fail(cmdproc != NULL);
- g_return_if_fail(trans != NULL);
-
- g_queue_push_tail(cmdproc->txqueue, trans);
-}
-
-static void
-show_debug_cmd(MsnCmdProc *cmdproc, gboolean incoming, const char *command)
-{
- MsnServConn *servconn;
- const char *names[] = { "NS", "SB" };
- char *show;
- char tmp;
- size_t len;
-
- servconn = cmdproc->servconn;
- len = strlen(command);
- show = g_strdup(command);
-
- tmp = (incoming) ? 'S' : 'C';
-
- if ((show[len - 1] == '\n') && (show[len - 2] == '\r'))
- {
- show[len - 2] = '\0';
- }
-
- purple_debug_misc("msn", "%c: %s %03d: %s\n", tmp,
- names[servconn->type], servconn->num, show);
-
- g_free(show);
-}
-
-gboolean
-msn_cmdproc_send_trans(MsnCmdProc *cmdproc, MsnTransaction *trans)
-{
- MsnServConn *servconn;
- char *data;
- size_t len;
- gboolean ret;
-
- g_return_val_if_fail(cmdproc != NULL, TRUE);
- g_return_val_if_fail(trans != NULL, TRUE);
-
- servconn = cmdproc->servconn;
-
- if (!servconn->connected) {
- msn_transaction_destroy(trans);
- return FALSE;
- }
-
- if (trans->saveable)
- msn_history_add(cmdproc->history, trans);
-
- data = msn_transaction_to_string(trans);
-
- len = strlen(data);
-
- show_debug_cmd(cmdproc, FALSE, data);
-
- if (trans->callbacks == NULL)
- trans->callbacks = g_hash_table_lookup(cmdproc->cbs_table->cmds,
- trans->command);
-
- if (trans->payload != NULL)
- {
- data = g_realloc(data, len + trans->payload_len);
- memcpy(data + len, trans->payload, trans->payload_len);
- len += trans->payload_len;
-
- /*
- * We're done with trans->payload. Free it so that the memory
- * doesn't sit around in cmdproc->history.
- */
- g_free(trans->payload);
- trans->payload = NULL;
- trans->payload_len = 0;
- }
-
- ret = msn_servconn_write(servconn, data, len) != -1;
-
- if (!trans->saveable)
- msn_transaction_destroy(trans);
- g_free(data);
- return ret;
-}
-
-void
-msn_cmdproc_process_payload(MsnCmdProc *cmdproc, char *payload,
- int payload_len)
-{
- MsnCommand *last;
-
- g_return_if_fail(cmdproc != NULL);
-
- last = cmdproc->last_cmd;
- last->payload = g_memdup(payload, payload_len);
- last->payload_len = payload_len;
-
- if (last->payload_cb != NULL)
- last->payload_cb(cmdproc, last, payload, payload_len);
-}
-
-void
-msn_cmdproc_process_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
-{
- MsnMsgTypeCb cb;
- const char *message_id = NULL;
-
- /* Multi-part messages */
- message_id = msn_message_get_header_value(msg, "Message-ID");
- if (message_id != NULL) {
- /* This is the first in a series of chunks */
-
- const char *chunk_text = msn_message_get_header_value(msg, "Chunks");
- guint chunk;
- if (chunk_text != NULL) {
- chunk = strtol(chunk_text, NULL, 10);
- /* 1024 chunks of ~1300 bytes is ~1MB, which seems OK to prevent
- some random client causing pidgin to hog a ton of memory.
- Probably should figure out the maximum that the official client
- actually supports, though. */
- if (chunk > 0 && chunk < 1024) {
- msg->total_chunks = chunk;
- msg->received_chunks = 1;
- g_hash_table_insert(cmdproc->multiparts, (gpointer)message_id, msn_message_ref(msg));
- purple_debug_info("msn", "Received chunked message, message_id: '%s', total chunks: %d\n",
- message_id, chunk);
- } else {
- purple_debug_error("msn", "MessageId '%s' has too many chunks: %d\n", message_id, chunk);
- }
- return;
- } else {
- chunk_text = msn_message_get_header_value(msg, "Chunk");
- if (chunk_text != NULL) {
- /* This is one chunk in a series of chunks */
-
- MsnMessage *first = g_hash_table_lookup(cmdproc->multiparts, message_id);
- chunk = strtol(chunk_text, NULL, 10);
- if (first != NULL) {
- if (first->received_chunks != chunk) {
- /*
- * We received an out of order chunk number (i.e. not the
- * next one in the sequence). Not sure if this can happen
- * legitimately, but we definitely don't handle it right
- * now.
- */
- g_hash_table_remove(cmdproc->multiparts, message_id);
- return;
- }
-
- /* Chunk is from 1 to total-1 (doesn't count first one) */
- purple_debug_info("msn", "Received chunk %d of %d, message_id: '%s'\n",
- chunk + 1, first->total_chunks, message_id);
- first->body = g_realloc(first->body, first->body_len + msg->body_len);
- memcpy(first->body + first->body_len, msg->body, msg->body_len);
- first->body_len += msg->body_len;
- first->received_chunks++;
- if (first->received_chunks != first->total_chunks)
- /* We're waiting for more chunks */
- return;
-
- /*
- * We have all the chunks for this message, great! Send
- * it along... The caller takes care of freeing the old one.
- */
- msg = first;
- } else {
- purple_debug_error("msn",
- "Unable to find first chunk of message_id '%s' to correspond with chunk %d.\n",
- message_id, chunk + 1);
- }
- } else {
- purple_debug_error("msn", "Received MessageId '%s' with no chunk number!\n", message_id);
- }
- }
- }
-
- if (msn_message_get_content_type(msg) == NULL)
- {
- purple_debug_misc("msn", "failed to find message content\n");
- return;
- }
-
- cb = g_hash_table_lookup(cmdproc->cbs_table->msgs,
- msn_message_get_content_type(msg));
-
- if (cb != NULL)
- cb(cmdproc, msg);
- else
- purple_debug_warning("msn", "Unhandled content-type '%s'\n",
- msn_message_get_content_type(msg));
-
- if (message_id != NULL)
- g_hash_table_remove(cmdproc->multiparts, message_id);
-}
-
-void
-msn_cmdproc_process_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
- MsnTransCb cb = NULL;
- MsnTransaction *trans = NULL;
-
- if (cmd->trId)
- cmd->trans = trans = msn_history_find(cmdproc->history, cmd->trId);
-
- if (trans != NULL)
- if (trans->timer) {
- purple_timeout_remove(trans->timer);
- trans->timer = 0;
- }
-
- if (g_ascii_isdigit(cmd->command[0]) && trans != NULL)
- {
- MsnErrorCb error_cb;
- int error;
-
- error = atoi(cmd->command);
-
- error_cb = trans->error_cb;
- if (error_cb == NULL)
- error_cb = g_hash_table_lookup(cmdproc->cbs_table->errors, trans->command);
-
- if (error_cb != NULL)
- error_cb(cmdproc, trans, error);
- else
- msn_error_handle(cmdproc->session, error);
-
- return;
- }
-
- cb = g_hash_table_lookup(cmdproc->cbs_table->async, cmd->command);
-
- if (cb == NULL && trans != NULL && trans->callbacks != NULL)
- cb = g_hash_table_lookup(trans->callbacks, cmd->command);
-
- if (cb == NULL)
- cb = g_hash_table_lookup(cmdproc->cbs_table->fallback, cmd->command);
-
- if (cb != NULL)
- cb(cmdproc, cmd);
- else
- purple_debug_warning("msn", "Unhandled command '%s'\n",
- cmd->command);
-
- if (trans != NULL && trans->pendent_cmd != NULL)
- msn_transaction_unqueue_cmd(trans, cmdproc);
-}
-
-void
-msn_cmdproc_process_cmd_text(MsnCmdProc *cmdproc, const char *command)
-{
- show_debug_cmd(cmdproc, TRUE, command);
-
- if (cmdproc->last_cmd != NULL)
- msn_command_unref(cmdproc->last_cmd);
-
- cmdproc->last_cmd = msn_command_from_string(command);
-
- msn_cmdproc_process_cmd(cmdproc, cmdproc->last_cmd);
-}
diff --git a/libpurple/protocols/msn/cmdproc.h b/libpurple/protocols/msn/cmdproc.h
deleted file mode 100644
index 9ec6c491da..0000000000
--- a/libpurple/protocols/msn/cmdproc.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/**
- * @file cmdproc.h MSN command processor functions
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-#ifndef MSN_CMDPROC_H
-#define MSN_CMDPROC_H
-
-typedef struct _MsnCmdProc MsnCmdProc;
-
-#include "command.h"
-#include "history.h"
-#include "servconn.h"
-#include "session.h"
-#include "table.h"
-
-struct _MsnCmdProc
-{
- MsnSession *session;
- MsnServConn *servconn;
-
- GQueue *txqueue;
-
- MsnCommand *last_cmd;
-
- MsnTable *cbs_table;
-
- MsnHistory *history;
-
- GHashTable *multiparts; /**< Multi-part message ID's */
-
- void *data; /**< Extra data, like the switchboard. */
-};
-
-/**
- * Creates a MsnCmdProc structure.
- *
- * @param session The session to associate with.
- *
- * @return A new MsnCmdProc structure.
- */
-MsnCmdProc *msn_cmdproc_new(MsnSession *session);
-
-/**
- * Destroys an MsnCmdProc.
- *
- * @param cmdproc The object structure.
- */
-void msn_cmdproc_destroy(MsnCmdProc *cmdproc);
-
-/**
- * Process the queued transactions.
- *
- * @param cmdproc The MsnCmdProc.
- */
-void msn_cmdproc_process_queue(MsnCmdProc *cmdproc);
-
-/**
- * Sends transaction using this servconn.
- *
- * @param cmdproc The MsnCmdProc to be used.
- * @param trans The MsnTransaction to be sent.
- */
-gboolean msn_cmdproc_send_trans(MsnCmdProc *cmdproc, MsnTransaction *trans);
-
-/**
- * Add a transaction to the queue to be processed latter.
- *
- * @param cmdproc The MsnCmdProc in which the transaction will be queued.
- * @param trans The MsnTransaction to be queued.
- */
-void msn_cmdproc_queue_trans(MsnCmdProc *cmdproc,
- MsnTransaction *trans);
-
-void msn_cmdproc_process_msg(MsnCmdProc *cmdproc,
- MsnMessage *msg);
-void msn_cmdproc_process_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd);
-void msn_cmdproc_process_cmd_text(MsnCmdProc *cmdproc, const char *command);
-void msn_cmdproc_process_payload(MsnCmdProc *cmdproc,
- char *payload, int payload_len);
-
-#endif /* MSN_CMDPROC_H */
diff --git a/libpurple/protocols/msn/command.c b/libpurple/protocols/msn/command.c
deleted file mode 100644
index 0be77b4630..0000000000
--- a/libpurple/protocols/msn/command.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/**
- * @file command.c MSN command functions
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-#include "internal.h"
-
-#include "command.h"
-
-static gboolean
-is_num(const char *str)
-{
- const char *c;
- for (c = str; *c; c++) {
- if (!(g_ascii_isdigit(*c)))
- return FALSE;
- }
-
- return TRUE;
-}
-
-MsnCommand *
-msn_command_from_string(const char *string)
-{
- MsnCommand *cmd;
- char *param_start;
-
- g_return_val_if_fail(string != NULL, NULL);
-
- cmd = g_new0(MsnCommand, 1);
- cmd->command = g_strdup(string);
- param_start = strchr(cmd->command, ' ');
-
- if (param_start)
- {
- *param_start++ = '\0';
- cmd->params = g_strsplit_set(param_start, " ", 0);
- }
-
- if (cmd->params != NULL)
- {
- guint c;
-
- for (c = 0; cmd->params[c] && cmd->params[c][0]; c++);
- cmd->param_count = c;
-
- if (cmd->param_count) {
- char *param = cmd->params[0];
- cmd->trId = is_num(param) ? atoi(param) : 0;
- } else {
- cmd->trId = 0;
- }
- }
- else
- {
- cmd->trId = 0;
- }
-
- msn_command_ref(cmd);
-
- return cmd;
-}
-
-static void
-msn_command_destroy(MsnCommand *cmd)
-{
- g_free(cmd->payload);
- g_free(cmd->command);
- g_strfreev(cmd->params);
- g_free(cmd);
-}
-
-MsnCommand *
-msn_command_ref(MsnCommand *cmd)
-{
- g_return_val_if_fail(cmd != NULL, NULL);
-
- cmd->ref_count++;
- return cmd;
-}
-
-void
-msn_command_unref(MsnCommand *cmd)
-{
- g_return_if_fail(cmd != NULL);
- g_return_if_fail(cmd->ref_count > 0);
-
- cmd->ref_count--;
-
- if (cmd->ref_count == 0)
- {
- msn_command_destroy(cmd);
- }
-}
-
diff --git a/libpurple/protocols/msn/command.h b/libpurple/protocols/msn/command.h
deleted file mode 100644
index d5d2d3a75d..0000000000
--- a/libpurple/protocols/msn/command.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/**
- * @file command.h MSN command functions
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-#ifndef MSN_COMMAND_H
-#define MSN_COMMAND_H
-
-typedef struct _MsnCommand MsnCommand;
-
-#include "cmdproc.h"
-#include "transaction.h"
-
-typedef void (*MsnPayloadCb)(MsnCmdProc *cmdproc, MsnCommand *cmd,
- char *payload, size_t len);
-
-/**
- * A received command.
- */
-struct _MsnCommand
-{
- unsigned int trId;
-
- char *command;
- char **params;
- guint param_count;
-
- guint ref_count;
-
- MsnTransaction *trans;
-
- char *payload;
- size_t payload_len;
-
- MsnPayloadCb payload_cb;
- void *payload_cbdata;
-};
-
-/**
- * Create a command object from the incoming string and ref it.
- *
- * @param string The incoming string.
- *
- * @return A MsnCommand object.
- */
-MsnCommand *msn_command_from_string(const char *string);
-
-/**
- * Increment the ref count.
- *
- * @param cmd The MsnCommand to be ref.
- *
- * @return The ref command.
- */
-MsnCommand *msn_command_ref(MsnCommand *cmd);
-
-/**
- * Decrement the ref count. If the count goes to 0, destroy it.
- *
- * @param cmd The MsnCommand to be unref.
- *
- */
-void msn_command_unref(MsnCommand *cmd);
-
-#endif /* MSN_COMMAND_H */
-
diff --git a/libpurple/protocols/msn/contact.c b/libpurple/protocols/msn/contact.c
deleted file mode 100644
index 4fba51ad90..0000000000
--- a/libpurple/protocols/msn/contact.c
+++ /dev/null
@@ -1,2048 +0,0 @@
-/**
- * @file contact.c
- * get MSN contacts via SOAP request
- * created by MaYuan<mayuan2006@gmail.com>
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "internal.h"
-#include "debug.h"
-
-#include "contact.h"
-#include "xmlnode.h"
-#include "group.h"
-#include "msnutils.h"
-#include "soap.h"
-#include "nexus.h"
-#include "user.h"
-
-const char *MsnSoapPartnerScenarioText[] =
-{
- "Initial",
- "ContactSave",
- "MessengerPendingList",
- "ContactMsgrAPI",
- "BlockUnblock",
- "Timer"
-};
-
-const char *MsnMemberRole[] =
-{
- "Forward",
- "Allow",
- "Block",
- "Reverse",
- "Pending"
-};
-
-typedef struct {
- MsnSession *session;
- MsnSoapPartnerScenario which;
-} GetContactListCbData;
-
-MsnCallbackState *
-msn_callback_state_new(MsnSession *session)
-{
- MsnCallbackState *state = g_new0(MsnCallbackState, 1);
-
- state->session = session;
-
- return state;
-}
-
-MsnCallbackState *
-msn_callback_state_dup(MsnCallbackState *state)
-{
- MsnCallbackState *new_state = g_new0(MsnCallbackState, 1);
-
- new_state->session = state->session;
- new_state->who = g_strdup(state->who);
- new_state->uid = g_strdup(state->uid);
- new_state->old_group_name = g_strdup(state->old_group_name);
- new_state->new_group_name = g_strdup(state->new_group_name);
- new_state->guid = g_strdup(state->guid);
- /* The rest should be made new */
-
- return new_state;
-}
-
-void
-msn_callback_state_free(MsnCallbackState *state)
-{
- if (state == NULL)
- return;
-
- g_free(state->who);
- g_free(state->uid);
- g_free(state->old_group_name);
- g_free(state->new_group_name);
- g_free(state->guid);
- if (state->body)
- xmlnode_free(state->body);
-
- g_free(state);
-}
-
-void
-msn_callback_state_set_who(MsnCallbackState *state, const gchar *who)
-{
- g_return_if_fail(state != NULL);
-
- g_free(state->who);
- state->who = g_strdup(who);
-}
-
-void
-msn_callback_state_set_uid(MsnCallbackState *state, const gchar *uid)
-{
- g_return_if_fail(state != NULL);
-
- g_free(state->uid);
- state->uid = g_strdup(uid);
-}
-
-void
-msn_callback_state_set_old_group_name(MsnCallbackState *state, const gchar *old_group_name)
-{
- g_return_if_fail(state != NULL);
-
- g_free(state->old_group_name);
- state->old_group_name = g_strdup(old_group_name);
-}
-
-void
-msn_callback_state_set_new_group_name(MsnCallbackState *state, const gchar *new_group_name)
-{
- g_return_if_fail(state != NULL);
-
- g_free(state->new_group_name);
- state->new_group_name = g_strdup(new_group_name);
-}
-
-void
-msn_callback_state_set_guid(MsnCallbackState *state, const gchar *guid)
-{
- g_return_if_fail(state != NULL);
-
- g_free(state->guid);
- state->guid = g_strdup(guid);
-}
-
-
-void
-msn_callback_state_set_list_id(MsnCallbackState *state, MsnListId list_id)
-{
- g_return_if_fail(state != NULL);
-
- state->list_id = list_id;
-}
-
-void
-msn_callback_state_set_action(MsnCallbackState *state, MsnCallbackAction action)
-{
- g_return_if_fail(state != NULL);
-
- state->action |= action;
-}
-
-/***************************************************************
- * General SOAP handling
- ***************************************************************/
-
-static const char *
-msn_contact_operation_str(MsnCallbackAction action)
-{
- /* Make sure this is large enough when adding more */
- static char buf[BUF_LEN];
- buf[0] = '\0';
-
- if (action & MSN_ADD_BUDDY)
- strcat(buf, "Adding Buddy,");
- if (action & MSN_MOVE_BUDDY)
- strcat(buf, "Moving Buddy,");
- if (action & MSN_ACCEPTED_BUDDY)
- strcat(buf, "Accepted Buddy,");
- if (action & MSN_DENIED_BUDDY)
- strcat(buf, "Denied Buddy,");
- if (action & MSN_ADD_GROUP)
- strcat(buf, "Adding Group,");
- if (action & MSN_DEL_GROUP)
- strcat(buf, "Deleting Group,");
- if (action & MSN_RENAME_GROUP)
- strcat(buf, "Renaming Group,");
- if (action & MSN_UPDATE_INFO)
- strcat(buf, "Updating Contact Info,");
- if (action & MSN_ANNOTATE_USER)
- strcat(buf, "Annotating Contact,");
-
- return buf;
-}
-
-static gboolean msn_contact_request(MsnCallbackState *state);
-
-static void
-msn_contact_request_cb(MsnSoapMessage *req, MsnSoapMessage *resp,
- gpointer data)
-{
- MsnCallbackState *state = data;
- xmlnode *fault;
- char *faultcode_str;
- xmlnode *cachekey;
- char *changed;
-
- if (resp == NULL) {
- purple_debug_error("msn",
- "Operation {%s} failed. No response received from server.\n",
- msn_contact_operation_str(state->action));
- msn_session_set_error(state->session, MSN_ERROR_BAD_BLIST, NULL);
- msn_callback_state_free(state);
- return;
- }
-
- /* Update CacheKey if necessary */
- cachekey = xmlnode_get_child(resp->xml, "Header/ServiceHeader/CacheKeyChanged");
- if (cachekey != NULL) {
- changed = xmlnode_get_data(cachekey);
- if (changed && !strcmp(changed, "true")) {
- cachekey = xmlnode_get_child(resp->xml, "Header/ServiceHeader/CacheKey");
- g_free(state->session->abch_cachekey);
- state->session->abch_cachekey = xmlnode_get_data(cachekey);
- purple_debug_info("msn", "Updated CacheKey for %s to '%s'.\n",
- purple_account_get_username(state->session->account),
- state->session->abch_cachekey);
- }
- g_free(changed);
- }
-
- fault = xmlnode_get_child(resp->xml, "Body/Fault");
-
- if (fault == NULL) {
- /* No errors */
- if (state->cb)
- state->cb(req, resp, data);
- msn_callback_state_free(state);
- return;
- }
-
- faultcode_str = xmlnode_get_data(xmlnode_get_child(fault, "faultcode"));
-
- if (faultcode_str && g_str_equal(faultcode_str, "q0:BadContextToken")) {
- purple_debug_info("msn",
- "Contact Operation {%s} failed because of bad token."
- " Updating token now and retrying operation.\n",
- msn_contact_operation_str(state->action));
- /* Token has expired, so renew it, and try again later */
- msn_nexus_update_token(state->session->nexus, MSN_AUTH_CONTACTS,
- (GSourceFunc)msn_contact_request, data);
- }
- else
- {
- if (state->cb) {
- state->cb(req, resp, data);
- } else {
- /* We don't know how to respond to this faultcode, so log it */
- char *str = xmlnode_to_str(fault, NULL);
- purple_debug_error("msn", "Operation {%s} Failed, SOAP Fault was: %s\n",
- msn_contact_operation_str(state->action), str);
- g_free(str);
- }
- msn_callback_state_free(state);
- }
-
- g_free(faultcode_str);
-}
-
-static gboolean
-msn_contact_request(MsnCallbackState *state)
-{
- xmlnode *cachekey = xmlnode_get_child(state->body,
- "Header/ABApplicationHeader/CacheKey");
- if (cachekey != NULL)
- xmlnode_free(cachekey);
- if (state->session->abch_cachekey != NULL) {
- cachekey = xmlnode_new_child(xmlnode_get_child(state->body, "Header/ABApplicationHeader"), "CacheKey");
- xmlnode_insert_data(cachekey, state->session->abch_cachekey, -1);
- }
- if (state->token == NULL)
- state->token = xmlnode_get_child(state->body,
- "Header/ABAuthHeader/TicketToken");
- /* delete old & replace with new token */
- xmlnode_free(state->token->child);
- xmlnode_insert_data(state->token,
- msn_nexus_get_token_str(state->session->nexus, MSN_AUTH_CONTACTS), -1);
- msn_soap_message_send(state->session,
- msn_soap_message_new(state->post_action, xmlnode_copy(state->body)),
- MSN_CONTACT_SERVER, state->post_url, FALSE,
- msn_contact_request_cb, state);
- return FALSE;
-}
-
-/***************************************************************
- * Address Book and Membership List Operations
- ***************************************************************/
-
-/*get MSN member role utility*/
-static MsnListId
-msn_get_memberrole(const char *role)
-{
- g_return_val_if_fail(role != NULL, 0);
-
- if (!strcmp(role,"Allow")) {
- return MSN_LIST_AL;
- } else if (!strcmp(role,"Block")) {
- return MSN_LIST_BL;
- } else if (!strcmp(role,"Reverse")) {
- return MSN_LIST_RL;
- } else if (!strcmp(role,"Pending")) {
- return MSN_LIST_PL;
- }
- return 0;
-}
-
-/* Create the AddressBook in the server, if we don't have one */
-static void
-msn_create_address_cb(MsnSoapMessage *req, MsnSoapMessage *resp, gpointer data)
-{
- MsnCallbackState *state = data;
- if (resp && xmlnode_get_child(resp->xml, "Body/Fault") == NULL) {
- purple_debug_info("msn", "Address Book successfully created!\n");
- msn_get_address_book(state->session, MSN_PS_INITIAL, NULL, NULL);
- } else {
- purple_debug_info("msn", "Address Book creation failed!\n");
- }
-}
-
-static void
-msn_create_address_book(MsnSession *session)
-{
- gchar *body;
- MsnCallbackState *state;
-
- g_return_if_fail(session != NULL);
- g_return_if_fail(session->user != NULL);
- g_return_if_fail(session->user->passport != NULL);
-
- purple_debug_info("msn", "Creating an Address Book.\n");
-
- body = g_strdup_printf(MSN_ADD_ADDRESSBOOK_TEMPLATE,
- session->user->passport);
-
- state = msn_callback_state_new(session);
- state->body = xmlnode_from_str(body, -1);
- state->post_action = MSN_ADD_ADDRESSBOOK_SOAP_ACTION;
- state->post_url = MSN_ADDRESS_BOOK_POST_URL;
- state->cb = msn_create_address_cb;
- msn_contact_request(state);
-
- g_free(body);
-}
-
-static void
-msn_parse_each_member(MsnSession *session, xmlnode *member, const char *node,
- MsnListId list)
-{
- char *passport;
- char *type;
- char *member_id;
- MsnUser *user;
- xmlnode *annotation;
- guint nid = MSN_NETWORK_UNKNOWN;
- char *invite = NULL;
-
- passport = xmlnode_get_data(xmlnode_get_child(member, node));
- if (!msn_email_is_valid(passport)) {
- g_free(passport);
- return;
- }
-
- type = xmlnode_get_data(xmlnode_get_child(member, "Type"));
- member_id = xmlnode_get_data(xmlnode_get_child(member, "MembershipId"));
-
- user = msn_userlist_find_add_user(session->userlist, passport, NULL);
-
- for (annotation = xmlnode_get_child(member, "Annotations/Annotation");
- annotation;
- annotation = xmlnode_get_next_twin(annotation)) {
- char *name = xmlnode_get_data(xmlnode_get_child(annotation, "Name"));
- char *value = xmlnode_get_data(xmlnode_get_child(annotation, "Value"));
- if (name && value) {
- if (!strcmp(name, "MSN.IM.BuddyType")) {
- nid = strtoul(value, NULL, 10);
- }
- else if (!strcmp(name, "MSN.IM.InviteMessage")) {
- invite = value;
- value = NULL;
- }
- }
- g_free(name);
- g_free(value);
- }
-
- /* For EmailMembers, the network must be found in the annotations, above.
- Otherwise, PassportMembers are on the Passport network. */
- if (!strcmp(node, "PassportName"))
- nid = MSN_NETWORK_PASSPORT;
-
- purple_debug_info("msn", "CL: %s name: %s, Type: %s, MembershipID: %s, NetworkID: %u\n",
- node, passport, type, member_id == NULL ? "(null)" : member_id, nid);
-
- msn_user_set_network(user, nid);
- msn_user_set_invite_message(user, invite);
-
- if (list == MSN_LIST_PL && member_id) {
- user->member_id_on_pending_list = atoi(member_id);
- }
-
- msn_got_lst_user(session, user, 1 << list, NULL);
-
- g_free(passport);
- g_free(type);
- g_free(member_id);
- g_free(invite);
-}
-
-static void
-msn_parse_each_service(MsnSession *session, xmlnode *service)
-{
- xmlnode *type;
-
- if ((type = xmlnode_get_child(service, "Info/Handle/Type"))) {
- char *type_str = xmlnode_get_data(type);
-
- if (g_str_equal(type_str, "Profile")) {
- /* Process Windows Live 'Messenger Roaming Identity' */
- } else if (g_str_equal(type_str, "Messenger")) {
- xmlnode *lastchange = xmlnode_get_child(service, "LastChange");
- char *lastchange_str = xmlnode_get_data(lastchange);
- xmlnode *membership;
-
- purple_debug_info("msn", "CL last change: %s\n", lastchange_str);
- purple_account_set_string(session->account, "CLLastChange",
- lastchange_str);
-
- for (membership = xmlnode_get_child(service,
- "Memberships/Membership");
- membership; membership = xmlnode_get_next_twin(membership)) {
-
- xmlnode *role = xmlnode_get_child(membership, "MemberRole");
- char *role_str = xmlnode_get_data(role);
- MsnListId list = msn_get_memberrole(role_str);
- xmlnode *member;
-
- purple_debug_info("msn", "CL MemberRole role: %s, list: %d\n",
- role_str, list);
-
- for (member = xmlnode_get_child(membership, "Members/Member");
- member; member = xmlnode_get_next_twin(member)) {
- const char *member_type = xmlnode_get_attrib(member, "type");
- if (g_str_equal(member_type, "PassportMember")) {
- msn_parse_each_member(session, member, "PassportName",
- list);
- } else if (g_str_equal(member_type, "PhoneMember")) {
-
- } else if (g_str_equal(member_type, "EmailMember")) {
- msn_parse_each_member(session, member, "Email", list);
- }
- }
-
- g_free(role_str);
- }
-
- g_free(lastchange_str);
- }
-
- g_free(type_str);
- }
-}
-
-/*parse contact list*/
-static gboolean
-msn_parse_contact_list(MsnSession *session, xmlnode *node)
-{
- xmlnode *fault, *faultnode;
-
- /* we may get a response if our cache data is too old:
- *
- * <faultstring>Need to do full sync. Can't sync deltas Client
- * has too old a copy for us to do a delta sync</faultstring>
- *
- * this is not handled yet
- */
- if ((fault = xmlnode_get_child(node, "Body/Fault"))) {
- if ((faultnode = xmlnode_get_child(fault, "detail/errorcode"))) {
- char *errorcode = xmlnode_get_data(faultnode);
-
- if (g_str_equal(errorcode, "ABDoesNotExist")) {
- msn_create_address_book(session);
- g_free(errorcode);
- return FALSE;
- }
-
- g_free(errorcode);
- }
-
- if ((faultnode = xmlnode_get_child(fault, "faultstring"))) {
- char *faultstring = xmlnode_get_data(faultnode);
- purple_debug_info("msn", "Retrieving contact list failed: %s\n",
- faultstring);
- msn_session_set_error(session, MSN_ERROR_BAD_BLIST, faultstring);
- g_free(faultstring);
- } else {
- msn_session_set_error(session, MSN_ERROR_BAD_BLIST, NULL);
- }
- return FALSE;
- } else {
- xmlnode *service;
-
- for (service = xmlnode_get_child(node, "Body/FindMembershipResponse/"
- "FindMembershipResult/Services/Service");
- service; service = xmlnode_get_next_twin(service)) {
- msn_parse_each_service(session, service);
- }
- return TRUE;
- }
-}
-
-static void
-msn_get_contact_list_cb(MsnSoapMessage *req, MsnSoapMessage *resp,
- gpointer data)
-{
- MsnCallbackState *state = data;
- MsnSession *session = state->session;
-
- g_return_if_fail(session != NULL);
-
- if (resp != NULL) {
-#ifdef MSN_PARTIAL_LISTS
- const char *abLastChange;
- const char *dynamicItemLastChange;
-#endif
-
- purple_debug_misc("msn", "Got the contact list!\n");
-
- if (msn_parse_contact_list(session, resp->xml)) {
-#ifdef MSN_PARTIAL_LISTS
- abLastChange = purple_account_get_string(session->account,
- "ablastChange", NULL);
- dynamicItemLastChange = purple_account_get_string(session->account,
- "DynamicItemLastChanged", NULL);
-#endif
-
- if (state->partner_scenario == MSN_PS_INITIAL) {
-#ifdef MSN_PARTIAL_LISTS
- /* XXX: this should be enabled when we can correctly do partial
- syncs with the server. Currently we need to retrieve the whole
- list to detect sync issues */
- msn_get_address_book(session, MSN_PS_INITIAL, abLastChange, dynamicItemLastChange);
-#else
- msn_get_address_book(session, MSN_PS_INITIAL, NULL, NULL);
-#endif
- }
- }
- }
-}
-
-/*SOAP get contact list*/
-void
-msn_get_contact_list(MsnSession *session,
- const MsnSoapPartnerScenario partner_scenario, const char *update_time)
-{
- gchar *body = NULL;
- gchar *update_str = NULL;
- MsnCallbackState *state;
- const gchar *partner_scenario_str = MsnSoapPartnerScenarioText[partner_scenario];
-
- purple_debug_misc("msn", "Getting Contact List.\n");
-
- if (update_time != NULL) {
- purple_debug_info("msn", "CL Last update time: %s\n", update_time);
- update_str = g_strdup_printf(MSN_GET_CONTACT_UPDATE_XML, update_time);
- }
-
- body = g_strdup_printf(MSN_GET_CONTACT_TEMPLATE, partner_scenario_str,
- update_str ? update_str : "");
-
- state = msn_callback_state_new(session);
- state->partner_scenario = partner_scenario;
- state->body = xmlnode_from_str(body, -1);
- state->post_action = MSN_GET_CONTACT_SOAP_ACTION;
- state->post_url = MSN_GET_CONTACT_POST_URL;
- state->cb = msn_get_contact_list_cb;
- msn_contact_request(state);
-
- g_free(update_str);
- g_free(body);
-}
-
-static void
-msn_parse_addressbook_groups(MsnSession *session, xmlnode *node)
-{
- xmlnode *group;
-
- purple_debug_info("msn", "msn_parse_addressbook_groups()\n");
-
- for(group = xmlnode_get_child(node, "Group"); group;
- group = xmlnode_get_next_twin(group)){
- xmlnode *groupId, *groupInfo, *groupname;
- char *group_id = NULL, *group_name = NULL;
-
- if ((groupId = xmlnode_get_child(group, "groupId")))
- group_id = xmlnode_get_data(groupId);
- if ((groupInfo = xmlnode_get_child(group, "groupInfo")) && (groupname = xmlnode_get_child(groupInfo, "name")))
- group_name = xmlnode_get_data(groupname);
-
- if (group_id == NULL) {
- /* Group of ungroupped buddies */
- g_free(group_name);
- continue;
- }
-
- msn_group_new(session->userlist, group_id, group_name);
-
- purple_debug_info("msn", "AB group_id: %s, name: %s\n", group_id, group_name ? group_name : "(null)");
- if ((purple_find_group(group_name)) == NULL) {
- PurpleGroup *g = purple_group_new(group_name);
- purple_blist_add_group(g, NULL);
- }
- g_free(group_id);
- g_free(group_name);
- }
-}
-
-static gboolean
-msn_parse_addressbook_mobile(xmlnode *contactInfo, char **inout_mobile_number)
-{
- xmlnode *phones;
- char *mobile_number = NULL;
- gboolean mobile = FALSE;
-
- *inout_mobile_number = NULL;
-
- if ((phones = xmlnode_get_child(contactInfo, "phones"))) {
- xmlnode *contact_phone;
- char *phone_type = NULL;
-
- for (contact_phone = xmlnode_get_child(phones, "ContactPhone");
- contact_phone;
- contact_phone = xmlnode_get_next_twin(contact_phone)) {
- xmlnode *contact_phone_type;
-
- if (!(contact_phone_type =
- xmlnode_get_child(contact_phone, "contactPhoneType")))
- continue;
-
- phone_type = xmlnode_get_data(contact_phone_type);
-
- if (phone_type && !strcmp(phone_type, "ContactPhoneMobile")) {
- xmlnode *number;
-
- if ((number = xmlnode_get_child(contact_phone, "number"))) {
- xmlnode *messenger_enabled;
- char *is_messenger_enabled = NULL;
-
- g_free(mobile_number);
- mobile_number = xmlnode_get_data(number);
-
- if (mobile_number &&
- (messenger_enabled = xmlnode_get_child(contact_phone, "isMessengerEnabled"))
- && (is_messenger_enabled = xmlnode_get_data(messenger_enabled))
- && !strcmp(is_messenger_enabled, "true"))
- mobile = TRUE;
-
- g_free(is_messenger_enabled);
- }
- }
-
- g_free(phone_type);
- }
- }
-
- *inout_mobile_number = mobile_number;
- return mobile;
-}
-
-static void
-msn_parse_addressbook_contacts(MsnSession *session, xmlnode *node)
-{
- xmlnode *contactNode;
- char *passport = NULL, *Name = NULL, *uid = NULL, *type = NULL, *mobile_number = NULL, *alias = NULL;
- gboolean mobile = FALSE;
- PurpleConnection *pc = purple_account_get_connection(session->account);
-
- for(contactNode = xmlnode_get_child(node, "Contact"); contactNode;
- contactNode = xmlnode_get_next_twin(contactNode)) {
- xmlnode *contactId, *contactInfo, *contactType, *passportName, *displayName, *guid, *groupIds;
- xmlnode *annotation;
- MsnUser *user;
-
- g_free(passport);
- g_free(Name);
- g_free(uid);
- g_free(type);
- g_free(mobile_number);
- g_free(alias);
- passport = Name = uid = type = mobile_number = alias = NULL;
- mobile = FALSE;
-
- if (!(contactId = xmlnode_get_child(contactNode,"contactId"))
- || !(contactInfo = xmlnode_get_child(contactNode, "contactInfo"))
- || !(contactType = xmlnode_get_child(contactInfo, "contactType")))
- continue;
-
- uid = xmlnode_get_data(contactId);
- type = xmlnode_get_data(contactType);
-
- /* Find out our settings */
- if (type && !strcmp(type, "Me")) {
- /* setup the Display Name */
- if (purple_connection_get_display_name(pc) == NULL) {
- char *friendly = NULL;
- if ((displayName = xmlnode_get_child(contactInfo, "displayName")))
- friendly = xmlnode_get_data(displayName);
- purple_connection_set_display_name(pc,
- friendly ? purple_url_decode(friendly) : NULL);
- g_free(friendly);
- }
-
- for (annotation = xmlnode_get_child(contactInfo, "annotations/Annotation");
- annotation;
- annotation = xmlnode_get_next_twin(annotation)) {
- char *name, *value;
- name = xmlnode_get_data(xmlnode_get_child(annotation, "Name"));
- value = xmlnode_get_data(xmlnode_get_child(annotation, "Value"));
- if (name && g_str_equal(name, "MSN.IM.MPOP")) {
- if (!value || atoi(value) != 0)
- session->enable_mpop = TRUE;
- else
- session->enable_mpop = FALSE;
- }
- g_free(name);
- g_free(value);
- }
-
- continue; /* Not adding own account as buddy to buddylist */
- }
-
- passportName = xmlnode_get_child(contactInfo, "passportName");
- if (passportName == NULL) {
- xmlnode *emailsNode, *contactEmailNode, *emailNode;
- xmlnode *messengerEnabledNode;
- char *msnEnabled;
-
- /*TODO: add it to the non-instant Messenger group and recognize as email Membership*/
- /* Yahoo/Federated User? */
- emailsNode = xmlnode_get_child(contactInfo, "emails");
- if (emailsNode == NULL) {
- /*TODO: need to support the Mobile type*/
- continue;
- }
- for (contactEmailNode = xmlnode_get_child(emailsNode, "ContactEmail");
- contactEmailNode;
- contactEmailNode = xmlnode_get_next_twin(contactEmailNode)) {
- if ((messengerEnabledNode = xmlnode_get_child(contactEmailNode, "isMessengerEnabled"))) {
-
- msnEnabled = xmlnode_get_data(messengerEnabledNode);
-
- if (msnEnabled && !strcmp(msnEnabled, "true")) {
- if ((emailNode = xmlnode_get_child(contactEmailNode, "email")))
- passport = xmlnode_get_data(emailNode);
-
- /* Messenger enabled, Get the Passport*/
- purple_debug_info("msn", "AB Yahoo/Federated User %s\n", passport ? passport : "(null)");
- g_free(msnEnabled);
- break;
- }
-
- g_free(msnEnabled);
- }
- }
- } else {
- xmlnode *messenger_user;
- /* ignore non-messenger contacts */
- if ((messenger_user = xmlnode_get_child(contactInfo, "isMessengerUser"))) {
- char *is_messenger_user = xmlnode_get_data(messenger_user);
-
- if (is_messenger_user && !strcmp(is_messenger_user, "false")) {
- g_free(is_messenger_user);
- continue;
- }
-
- g_free(is_messenger_user);
- }
-
- passport = xmlnode_get_data(passportName);
- }
-
- /* Couldn't find anything */
- if (passport == NULL)
- continue;
-
- if (!msn_email_is_valid(passport))
- continue;
-
- if ((displayName = xmlnode_get_child(contactInfo, "displayName")))
- Name = xmlnode_get_data(displayName);
- else
- Name = g_strdup(passport);
-
- for (annotation = xmlnode_get_child(contactInfo, "annotations/Annotation");
- annotation;
- annotation = xmlnode_get_next_twin(annotation)) {
- char *name;
- name = xmlnode_get_data(xmlnode_get_child(annotation, "Name"));
- if (!name)
- continue;
- if (!strcmp(name, "AB.NickName"))
- alias = xmlnode_get_data(xmlnode_get_child(annotation, "Value"));
- else if (!strcmp(name, "MSN.IM.HasSharedFolder"))
- ; /* Do nothing yet... */
- else if (!strcmp(name, "AB.Spouse"))
- ; /* Do nothing yet... */
- else if (!strcmp(name, "MSN.Mobile.ContactId"))
- ; /* Do nothing yet... */
- else
- purple_debug_info("msn",
- "Unknown AB contact annotation: %s\n", name);
- g_free(name);
- }
-
- mobile = msn_parse_addressbook_mobile(contactInfo, &mobile_number);
-
- purple_debug_misc("msn", "AB passport:{%s} uid:{%s} display:{%s} alias: {%s} mobile:{%s} mobile number:{%s}\n",
- passport, uid ? uid : "(null)", Name ? Name : "(null)", alias ? alias : "(null)",
- mobile ? "true" : "false", mobile_number ? mobile_number : "(null)");
-
- user = msn_userlist_find_add_user(session->userlist, passport, Name);
- msn_user_set_uid(user, uid);
- msn_user_set_mobile_phone(user, mobile_number);
-
- groupIds = xmlnode_get_child(contactInfo, "groupIds");
- if (groupIds) {
- for (guid = xmlnode_get_child(groupIds, "guid"); guid;
- guid = xmlnode_get_next_twin(guid)) {
- char *group_id = xmlnode_get_data(guid);
- msn_user_add_group_id(user, group_id);
- purple_debug_misc("msn", "AB guid:%s\n", group_id ? group_id : "(null)");
- g_free(group_id);
- }
- } else {
- purple_debug_info("msn", "User not in any groups, adding to default group.\n");
- /*not in any group,Then set default group*/
- msn_user_add_group_id(user, MSN_INDIVIDUALS_GROUP_ID);
- }
-
- msn_got_lst_user(session, user, MSN_LIST_FL_OP, NULL);
-
- if (mobile && user)
- {
- user->mobile = TRUE;
- purple_prpl_got_user_status(session->account, user->passport, "mobile", NULL);
- purple_prpl_got_user_status(session->account, user->passport, "available", NULL);
- }
- if (alias)
- purple_serv_got_private_alias(pc, passport, alias);
- }
-
- g_free(passport);
- g_free(Name);
- g_free(uid);
- g_free(type);
- g_free(mobile_number);
- g_free(alias);
-}
-
-static void
-msn_parse_addressbook_circles(MsnSession *session, xmlnode *node)
-{
- xmlnode *ticket;
-
- /* TODO: Parse groups */
-
- ticket = xmlnode_get_child(node, "CircleTicket");
- if (ticket) {
- char *data = xmlnode_get_data(ticket);
- msn_notification_send_circle_auth(session, data);
- g_free(data);
- }
-}
-
-static gboolean
-msn_parse_addressbook(MsnSession *session, xmlnode *node)
-{
- xmlnode *result;
- xmlnode *groups;
- xmlnode *contacts;
- xmlnode *abNode;
- xmlnode *circleNode;
- xmlnode *fault;
-
- if ((fault = xmlnode_get_child(node, "Body/Fault"))) {
- xmlnode *faultnode;
-
- if ((faultnode = xmlnode_get_child(fault, "faultstring"))) {
- gchar *faultstring = xmlnode_get_data(faultnode);
- purple_debug_info("msn", "AB Faultstring: %s\n", faultstring);
- g_free(faultstring);
- }
-
- if ((faultnode = xmlnode_get_child(fault, "detail/errorcode"))) {
- gchar *errorcode = xmlnode_get_data(faultnode);
-
- purple_debug_info("msn", "AB Error Code: %s\n", errorcode);
-
- if (g_str_equal(errorcode, "ABDoesNotExist")) {
- g_free(errorcode);
- return TRUE;
- }
- g_free(errorcode);
- }
-
- return FALSE;
- }
-
- result = xmlnode_get_child(node, "Body/ABFindContactsPagedResponse/ABFindContactsPagedResult");
- if (result == NULL) {
- purple_debug_misc("msn", "Received no address book update\n");
- return TRUE;
- }
-
- /* I don't see this "groups" tag documented on msnpiki, need to find out
- if they are really there, and update msnpiki */
- /*Process Group List*/
- groups = xmlnode_get_child(result, "Groups");
- if (groups != NULL) {
- msn_parse_addressbook_groups(session, groups);
- }
-
- /* Add an "Other Contacts" group for buddies who aren't in a group */
- msn_group_new(session->userlist, MSN_INDIVIDUALS_GROUP_ID,
- MSN_INDIVIDUALS_GROUP_NAME);
- purple_debug_misc("msn", "AB group_id:%s name:%s\n",
- MSN_INDIVIDUALS_GROUP_ID, MSN_INDIVIDUALS_GROUP_NAME);
- if ((purple_find_group(MSN_INDIVIDUALS_GROUP_NAME)) == NULL){
- PurpleGroup *g = purple_group_new(MSN_INDIVIDUALS_GROUP_NAME);
- purple_blist_add_group(g, NULL);
- }
-
- /* Add a "Non-IM Contacts" group */
- msn_group_new(session->userlist, MSN_NON_IM_GROUP_ID, MSN_NON_IM_GROUP_NAME);
- purple_debug_misc("msn", "AB group_id:%s name:%s\n", MSN_NON_IM_GROUP_ID, MSN_NON_IM_GROUP_NAME);
- if ((purple_find_group(MSN_NON_IM_GROUP_NAME)) == NULL) {
- PurpleGroup *g = purple_group_new(MSN_NON_IM_GROUP_NAME);
- purple_blist_add_group(g, NULL);
- }
-
- /*Process contact List*/
- purple_debug_info("msn", "Process contact list...\n");
- contacts = xmlnode_get_child(result, "Contacts");
- if (contacts != NULL) {
- msn_parse_addressbook_contacts(session, contacts);
- }
-
- abNode = xmlnode_get_child(result, "Ab");
- if (abNode != NULL) {
- xmlnode *node2;
- char *tmp = NULL;
-
- if ((node2 = xmlnode_get_child(abNode, "lastChange")))
- tmp = xmlnode_get_data(node2);
- purple_debug_info("msn", "AB lastchanged Time:{%s}\n", tmp ? tmp : "(null)");
- purple_account_set_string(session->account, "ablastChange", tmp);
-
- g_free(tmp); tmp = NULL;
- if ((node2 = xmlnode_get_child(abNode, "DynamicItemLastChanged")))
- tmp = xmlnode_get_data(node2);
- purple_debug_info("msn", "AB DynamicItemLastChanged :{%s}\n", tmp ? tmp : "(null)");
- purple_account_set_string(session->account, "DynamicItemLastChanged", tmp);
- g_free(tmp);
- }
-
- circleNode = xmlnode_get_child(result, "CircleResult");
- if (circleNode != NULL) {
- msn_parse_addressbook_circles(session, circleNode);
- }
-
- return TRUE;
-}
-
-static void
-msn_get_address_cb(MsnSoapMessage *req, MsnSoapMessage *resp, gpointer data)
-{
- MsnCallbackState *state = data;
- MsnSession *session = state->session;
-
- g_return_if_fail(session != NULL);
-
- purple_debug_misc("msn", "Got the Address Book!\n");
-
- if (msn_parse_addressbook(session, resp->xml)) {
- msn_send_privacy(session->account->gc);
- msn_notification_dump_contact(session);
- } else {
- /* This is making us loop infinitely when we fail to parse the
- address book, disable for now (we should re-enable when we
- send timestamps)
- */
- /*
- msn_get_address_book(session, NULL, NULL);
- */
- msn_session_set_error(session, MSN_ERROR_BAD_BLIST, NULL);
- }
-}
-
-/*get the address book*/
-void
-msn_get_address_book(MsnSession *session,
- MsnSoapPartnerScenario partner_scenario, const char *LastChanged,
- const char *dynamicItemLastChange)
-{
- char *body, *update_str = NULL;
- MsnCallbackState *state;
-
- purple_debug_misc("msn", "Getting Address Book\n");
-
- /*build SOAP and POST it*/
- if (dynamicItemLastChange != NULL)
- update_str = g_strdup_printf(MSN_GET_ADDRESS_UPDATE_XML, dynamicItemLastChange);
- else if (LastChanged != NULL)
- update_str = g_strdup_printf(MSN_GET_ADDRESS_UPDATE_XML, LastChanged);
-
- body = g_strdup_printf(MSN_GET_ADDRESS_TEMPLATE,
- MsnSoapPartnerScenarioText[partner_scenario],
- update_str ? update_str : "");
-
- state = msn_callback_state_new(session);
- state->body = xmlnode_from_str(body, -1);
- state->post_action = MSN_GET_ADDRESS_SOAP_ACTION;
- state->post_url = MSN_ADDRESS_BOOK_POST_URL;
- state->cb = msn_get_address_cb;
- msn_contact_request(state);
-
- g_free(update_str);
- g_free(body);
-}
-
-/***************************************************************
- * Contact Operations
- ***************************************************************/
-
-static void
-msn_add_contact_read_cb(MsnSoapMessage *req, MsnSoapMessage *resp,
- gpointer data)
-{
- MsnCallbackState *state = data;
- MsnSession *session = state->session;
-
- MsnUserList *userlist;
- MsnUser *user;
- xmlnode *guid;
-
- xmlnode *fault;
-
- g_return_if_fail(session != NULL);
- userlist = session->userlist;
-
- fault = xmlnode_get_child(resp->xml, "Body/Fault");
- if (fault != NULL) {
- char *errorcode = xmlnode_get_data(xmlnode_get_child(fault, "detail/errorcode"));
- if (errorcode && !strcmp(errorcode, "EmailDomainIsFederated")) {
- /* Do something special! */
- purple_debug_error("msn", "Contact is from a federated domain, but don't know what to do yet!\n");
-
- } else if (errorcode && !strcmp(errorcode, "InvalidPassportUser")) {
- PurpleBuddy *buddy = purple_find_buddy(session->account, state->who);
- char *str = g_strdup_printf(_("Unable to add \"%s\"."), state->who);
- purple_notify_error(state->session, _("Buddy Add error"), str,
- _("The username specified does not exist."));
- g_free(str);
- msn_userlist_rem_buddy(userlist, state->who);
- if (buddy != NULL)
- purple_blist_remove_buddy(buddy);
-
- } else {
- /* We don't know how to respond to this faultcode, so log it */
- char *fault_str = xmlnode_to_str(fault, NULL);
- if (fault_str != NULL) {
- purple_debug_error("msn", "Operation {%s} Failed, SOAP Fault was: %s\n",
- msn_contact_operation_str(state->action), fault_str);
- g_free(fault_str);
- }
- }
- return;
- }
-
- purple_debug_info("msn", "Contact added successfully\n");
-
- msn_userlist_add_buddy_to_list(userlist, state->who, MSN_LIST_AL);
- msn_userlist_add_buddy_to_list(userlist, state->who, MSN_LIST_FL);
-
- user = msn_userlist_find_add_user(userlist, state->who, state->who);
- msn_user_add_group_id(user, state->guid);
-
- guid = xmlnode_get_child(resp->xml,
- "Body/ABContactAddResponse/ABContactAddResult/guid");
- if (guid != NULL) {
- char *uid = xmlnode_get_data(guid);
- msn_user_set_uid(user, uid);
- purple_debug_info("msn", "Set %s guid to %s.\n", state->who, uid);
- g_free(uid);
- }
-}
-
-/* add a Contact in MSN_INDIVIDUALS_GROUP */
-void
-msn_add_contact(MsnSession *session, MsnCallbackState *state, const char *passport)
-{
- MsnUser *user;
- gchar *body = NULL;
- gchar *contact_xml = NULL;
-
- purple_debug_info("msn", "Adding contact %s to contact list\n", passport);
-
- user = msn_userlist_find_user(session->userlist, passport);
- if (user == NULL) {
- purple_debug_warning("msn", "Unable to retrieve user %s from the userlist!\n", passport);
- return; /* guess this never happened! */
- }
-
- if (user->networkid != MSN_NETWORK_PASSPORT) {
- contact_xml = g_strdup_printf(MSN_CONTACT_EMAIL_XML,
- user->networkid == MSN_NETWORK_YAHOO ?
- "Messenger2" :
- "Messenger3",
- passport, 0);
- } else {
- contact_xml = g_strdup_printf(MSN_CONTACT_XML, passport);
- }
- body = g_strdup_printf(MSN_ADD_CONTACT_TEMPLATE, contact_xml);
-
- state->body = xmlnode_from_str(body, -1);
- state->post_action = MSN_CONTACT_ADD_SOAP_ACTION;
- state->post_url = MSN_ADDRESS_BOOK_POST_URL;
- state->cb = msn_add_contact_read_cb;
- msn_contact_request(state);
-
- g_free(contact_xml);
- g_free(body);
-}
-
-static void
-msn_add_contact_to_group_read_cb(MsnSoapMessage *req, MsnSoapMessage *resp,
- gpointer data)
-{
- MsnCallbackState *state = data;
- MsnSession *session = state->session;
- MsnUserList *userlist;
- xmlnode *fault;
-
- g_return_if_fail(session != NULL);
- userlist = session->userlist;
-
- fault = xmlnode_get_child(resp->xml, "Body/Fault");
- if (fault != NULL) {
- char *errorcode = xmlnode_get_data(xmlnode_get_child(fault, "detail/errorcode"));
- if (errorcode && !strcmp(errorcode, "EmailDomainIsFederated")) {
- /* Do something special! */
- purple_debug_error("msn", "Contact is from a federated domain, but don't know what to do yet!\n");
-
- } else if (errorcode && !strcmp(errorcode, "InvalidPassportUser")) {
- PurpleBuddy *buddy = purple_find_buddy(session->account, state->who);
- char *str = g_strdup_printf(_("Unable to add \"%s\"."), state->who);
- purple_notify_error(session, _("Buddy Add error"), str,
- _("The username specified does not exist."));
- g_free(str);
- msn_userlist_rem_buddy(userlist, state->who);
- if (buddy != NULL)
- purple_blist_remove_buddy(buddy);
-
- } else {
- /* We don't know how to respond to this faultcode, so log it */
- char *fault_str = xmlnode_to_str(fault, NULL);
- if (fault_str != NULL) {
- purple_debug_error("msn", "Operation {%s} Failed, SOAP Fault was: %s\n",
- msn_contact_operation_str(state->action), fault_str);
- g_free(fault_str);
- }
- }
- return;
- }
-
- if (msn_userlist_add_buddy_to_group(userlist, state->who,
- state->new_group_name)) {
- purple_debug_info("msn", "Contact %s added to group %s successfully!\n", state->who, state->new_group_name);
- } else {
- purple_debug_info("msn", "Contact %s added to group %s successfully on server, but failed in the local list\n", state->who, state->new_group_name);
- }
-
- if (state->action & MSN_ADD_BUDDY) {
- MsnUser *user = msn_userlist_find_user(userlist, state->who);
- xmlnode *guid = xmlnode_get_child(resp->xml,
- "Body/ABGroupContactAddResponse/ABGroupContactAddResult/guid");
-
- if (guid != NULL) {
- char *uid = xmlnode_get_data(guid);
- msn_user_set_uid(user, uid);
- purple_debug_info("msn", "Set %s guid to %s.\n", state->who, uid);
- g_free(uid);
- }
-
- msn_userlist_add_buddy_to_list(userlist, state->who, MSN_LIST_AL);
- msn_userlist_add_buddy_to_list(userlist, state->who, MSN_LIST_FL);
-
- if (msn_user_is_in_list(user, MSN_LIST_PL)) {
- msn_del_contact_from_list(state->session, NULL, state->who, MSN_LIST_PL);
- return;
- }
- }
-
- if (state->action & MSN_MOVE_BUDDY) {
- msn_del_contact_from_group(state->session, state->who, state->old_group_name);
- }
-}
-
-void
-msn_add_contact_to_group(MsnSession *session, MsnCallbackState *state,
- const char *passport, const char *groupId)
-{
- MsnUserList *userlist;
- MsnUser *user;
- gchar *body = NULL, *contact_xml, *invite;
-
- g_return_if_fail(passport != NULL);
- g_return_if_fail(groupId != NULL);
-
- g_return_if_fail(session != NULL);
-
- userlist = session->userlist;
-
- if (!strcmp(groupId, MSN_INDIVIDUALS_GROUP_ID) || !strcmp(groupId, MSN_NON_IM_GROUP_ID)) {
-
- user = msn_userlist_find_add_user(userlist, passport, passport);
-
- if (state->action & MSN_ADD_BUDDY) {
- msn_add_contact(session, state, passport);
- return;
- }
-
- if (state->action & MSN_MOVE_BUDDY) {
- msn_user_add_group_id(user, groupId);
- msn_del_contact_from_group(session, passport, state->old_group_name);
- }
-
- return;
- }
-
- purple_debug_info("msn", "Adding user %s to group %s\n", passport,
- msn_userlist_find_group_name(userlist, groupId));
-
- user = msn_userlist_find_user(userlist, passport);
- if (user == NULL) {
- purple_debug_warning("msn", "Unable to retrieve user %s from the userlist!\n", passport);
- msn_callback_state_free(state);
- return; /* guess this never happened! */
- }
-
- if (user->uid != NULL) {
- contact_xml = g_strdup_printf(MSN_CONTACT_ID_XML, user->uid);
- } else if (user->networkid != MSN_NETWORK_PASSPORT) {
- contact_xml = g_strdup_printf(MSN_CONTACT_EMAIL_XML,
- user->networkid == MSN_NETWORK_YAHOO ?
- "Messenger2" :
- "Messenger3",
- passport, 0);
- } else {
- contact_xml = g_strdup_printf(MSN_CONTACT_XML, passport);
- }
-
- if (user->invite_message) {
- char *tmp;
- body = g_markup_escape_text(user->invite_message, -1);
-
- /* Ignore the cast, we treat it as const anyway. */
- tmp = (char *)purple_connection_get_display_name(session->account->gc);
- tmp = tmp ? g_markup_escape_text(tmp, -1) : g_strdup("");
-
- invite = g_strdup_printf(MSN_CONTACT_INVITE_MESSAGE_XML, body, tmp);
-
- g_free(body);
- g_free(tmp);
-
- /* We can free this now */
- g_free(user->invite_message);
- user->invite_message = NULL;
-
- } else {
- invite = g_strdup("");
- }
-
- body = g_strdup_printf(MSN_ADD_CONTACT_GROUP_TEMPLATE, groupId, contact_xml, invite);
-
- state->body = xmlnode_from_str(body, -1);
- state->post_action = MSN_ADD_CONTACT_GROUP_SOAP_ACTION;
- state->post_url = MSN_ADDRESS_BOOK_POST_URL;
- state->cb = msn_add_contact_to_group_read_cb;
- msn_contact_request(state);
-
- g_free(invite);
- g_free(contact_xml);
- g_free(body);
-}
-
-static void
-msn_delete_contact_read_cb(MsnSoapMessage *req, MsnSoapMessage *resp,
- gpointer data)
-{
- MsnCallbackState *state = data;
- MsnUserList *userlist = state->session->userlist;
- MsnUser *user = msn_userlist_find_user_with_id(userlist, state->uid);
- xmlnode *fault;
-
- /* We don't know how to respond to this faultcode, so log it */
- fault = xmlnode_get_child(resp->xml, "Body/Fault");
- if (fault != NULL) {
- char *fault_str = xmlnode_to_str(fault, NULL);
- purple_debug_error("msn", "Operation {%s} Failed, SOAP Fault was: %s\n",
- msn_contact_operation_str(state->action), fault_str);
- g_free(fault_str);
- return;
- }
-
- purple_debug_info("msn", "Delete contact successful\n");
-
- if (user != NULL) {
- msn_userlist_remove_user(userlist, user);
- }
-}
-
-/*delete a Contact*/
-void
-msn_delete_contact(MsnSession *session, MsnUser *user)
-{
- gchar *body = NULL;
- gchar *contact_id_xml = NULL ;
- MsnCallbackState *state;
-
- if (user->uid != NULL) {
- contact_id_xml = g_strdup_printf(MSN_CONTACT_ID_XML, user->uid);
- purple_debug_info("msn", "Deleting contact with contactId: %s\n", user->uid);
- } else {
- purple_debug_info("msn", "Unable to delete contact %s without a ContactId\n", user->passport);
- return;
- }
-
- state = msn_callback_state_new(session);
- msn_callback_state_set_uid(state, user->uid);
-
- /* build SOAP request */
- body = g_strdup_printf(MSN_DEL_CONTACT_TEMPLATE, contact_id_xml);
-
- state->body = xmlnode_from_str(body, -1);
- state->post_action = MSN_CONTACT_DEL_SOAP_ACTION;
- state->post_url = MSN_ADDRESS_BOOK_POST_URL;
- state->cb = msn_delete_contact_read_cb;
- msn_contact_request(state);
-
- g_free(contact_id_xml);
- g_free(body);
-}
-
-static void
-msn_del_contact_from_group_read_cb(MsnSoapMessage *req, MsnSoapMessage *resp,
- gpointer data)
-{
- MsnCallbackState *state = data;
- xmlnode *fault;
-
- /* We don't know how to respond to this faultcode, so log it */
- fault = xmlnode_get_child(resp->xml, "Body/Fault");
- if (fault != NULL) {
- char *fault_str = xmlnode_to_str(fault, NULL);
- purple_debug_error("msn", "Operation {%s} Failed, SOAP Fault was: %s\n",
- msn_contact_operation_str(state->action), fault_str);
- g_free(fault_str);
- return;
- }
-
- if (msn_userlist_rem_buddy_from_group(state->session->userlist,
- state->who, state->old_group_name)) {
- purple_debug_info("msn", "Contact %s deleted successfully from group %s\n", state->who, state->old_group_name);
- } else {
- purple_debug_info("msn", "Contact %s deleted successfully from group %s in the server, but failed in the local list\n", state->who, state->old_group_name);
- }
-}
-
-void
-msn_del_contact_from_group(MsnSession *session, const char *passport, const char *group_name)
-{
- MsnUserList * userlist;
- MsnUser *user;
- MsnCallbackState *state;
- gchar *body, *contact_id_xml;
- const gchar *groupId;
-
- g_return_if_fail(passport != NULL);
- g_return_if_fail(group_name != NULL);
- g_return_if_fail(session != NULL);
-
- userlist = session->userlist;
-
- groupId = msn_userlist_find_group_id(userlist, group_name);
- if (groupId != NULL) {
- purple_debug_info("msn", "Deleting user %s from group %s\n", passport, group_name);
- } else {
- purple_debug_warning("msn", "Unable to retrieve group id from group %s !\n", group_name);
- return;
- }
-
- user = msn_userlist_find_user(userlist, passport);
-
- if (user == NULL) {
- purple_debug_warning("msn", "Unable to retrieve user from passport %s!\n", passport);
- return;
- }
-
- if ( !strcmp(groupId, MSN_INDIVIDUALS_GROUP_ID) || !strcmp(groupId, MSN_NON_IM_GROUP_ID)) {
- msn_user_remove_group_id(user, groupId);
- return;
- }
-
- state = msn_callback_state_new(session);
- msn_callback_state_set_who(state, passport);
- msn_callback_state_set_guid(state, groupId);
- msn_callback_state_set_old_group_name(state, group_name);
-
- if (user->uid != NULL)
- contact_id_xml = g_strdup_printf(MSN_CONTACT_ID_XML, user->uid);
- else
- contact_id_xml = g_strdup_printf(MSN_CONTACT_XML, passport);
- body = g_strdup_printf(MSN_CONTACT_DEL_GROUP_TEMPLATE, contact_id_xml, groupId);
-
- state->body = xmlnode_from_str(body, -1);
- state->post_action = MSN_CONTACT_DEL_GROUP_SOAP_ACTION;
- state->post_url = MSN_ADDRESS_BOOK_POST_URL;
- state->cb = msn_del_contact_from_group_read_cb;
- msn_contact_request(state);
-
- g_free(contact_id_xml);
- g_free(body);
-}
-
-
-static void
-msn_update_contact_read_cb(MsnSoapMessage *req, MsnSoapMessage *resp,
- gpointer data)
-{
- MsnCallbackState *state = (MsnCallbackState *)data;
- xmlnode *fault;
-
- /* We don't know how to respond to this faultcode, so log it */
- fault = xmlnode_get_child(resp->xml, "Body/Fault");
- if (fault != NULL) {
- char *fault_str = xmlnode_to_str(fault, NULL);
- purple_debug_error("msn", "Operation {%s} Failed, SOAP Fault was: %s\n",
- msn_contact_operation_str(state->action), fault_str);
- g_free(fault_str);
- return;
- }
-
- purple_debug_info("msn", "Contact updated successfully\n");
-}
-
-/* Update a contact's info */
-void
-msn_update_contact(MsnSession *session, const char *passport, MsnContactUpdateType type, const char* value)
-{
- MsnCallbackState *state;
- xmlnode *contact;
- xmlnode *contact_info;
- xmlnode *changes;
- MsnUser *user = NULL;
-
- purple_debug_info("msn", "Update contact information for %s with new %s: %s\n",
- passport ? passport : "(null)",
- type == MSN_UPDATE_DISPLAY ? "display name" : "alias",
- value ? value : "(null)");
- g_return_if_fail(passport != NULL);
-
- if (strcmp(passport, "Me") != 0) {
- user = msn_userlist_find_user(session->userlist, passport);
- if (!user)
- return;
- }
-
- contact_info = xmlnode_new("contactInfo");
- changes = xmlnode_new("propertiesChanged");
-
- switch (type) {
- xmlnode *annotations;
- xmlnode *display;
- xmlnode *a, *n, *v;
- case MSN_UPDATE_DISPLAY:
- display = xmlnode_new_child(contact_info, "displayName");
- xmlnode_insert_data(display, value, -1);
- xmlnode_insert_data(changes, "DisplayName", -1);
- break;
-
- case MSN_UPDATE_ALIAS:
- annotations = xmlnode_new_child(contact_info, "annotations");
- xmlnode_insert_data(changes, "Annotation ", -1);
-
- a = xmlnode_new_child(annotations, "Annotation");
- n = xmlnode_new_child(a, "Name");
- xmlnode_insert_data(n, "AB.NickName", -1);
- v = xmlnode_new_child(a, "Value");
- xmlnode_insert_data(v, value, -1);
- break;
-
- default:
- g_return_if_reached();
- }
-
- state = msn_callback_state_new(session);
-
- state->body = xmlnode_from_str(MSN_CONTACT_UPDATE_TEMPLATE, -1);
- state->action = MSN_UPDATE_INFO;
- state->post_action = MSN_CONTACT_UPDATE_SOAP_ACTION;
- state->post_url = MSN_ADDRESS_BOOK_POST_URL;
- state->cb = msn_update_contact_read_cb;
-
- contact = xmlnode_get_child(state->body, "Body/ABContactUpdate/contacts/Contact");
- xmlnode_insert_child(contact, contact_info);
- xmlnode_insert_child(contact, changes);
-
- xmlnode_insert_data(xmlnode_get_child(state->body,
- "Header/ABApplicationHeader/PartnerScenario"),
- MsnSoapPartnerScenarioText[MSN_PS_SAVE_CONTACT], -1);
-
- if (user) {
- xmlnode *contactId = xmlnode_new_child(contact, "contactId");
- msn_callback_state_set_uid(state, user->uid);
- xmlnode_insert_data(contactId, state->uid, -1);
- } else {
- xmlnode *contactType = xmlnode_new_child(contact_info, "contactType");
- xmlnode_insert_data(contactType, "Me", -1);
- }
-
- msn_contact_request(state);
-}
-
-static void
-msn_annotate_contact_read_cb(MsnSoapMessage *req, MsnSoapMessage *resp,
- gpointer data)
-{
- MsnCallbackState *state = (MsnCallbackState *)data;
- xmlnode *fault;
-
- /* We don't know how to respond to this faultcode, so log it */
- fault = xmlnode_get_child(resp->xml, "Body/Fault");
- if (fault != NULL) {
- char *fault_str = xmlnode_to_str(fault, NULL);
- purple_debug_error("msn", "Operation {%s} Failed, SOAP Fault was: %s\n",
- msn_contact_operation_str(state->action), fault_str);
- g_free(fault_str);
- return;
- }
-
- purple_debug_info("msn", "Contact annotated successfully\n");
-}
-
-/* Update a contact's annotations */
-void
-msn_annotate_contact(MsnSession *session, const char *passport, ...)
-{
- va_list params;
- MsnCallbackState *state;
- xmlnode *contact;
- xmlnode *contact_info;
- xmlnode *annotations;
- MsnUser *user = NULL;
-
- g_return_if_fail(passport != NULL);
-
- if (strcmp(passport, "Me") != 0) {
- user = msn_userlist_find_user(session->userlist, passport);
- if (!user)
- return;
- }
-
- contact_info = xmlnode_new("contactInfo");
- annotations = xmlnode_new_child(contact_info, "annotations");
-
- va_start(params, passport);
- while (TRUE) {
- const char *name;
- const char *value;
- xmlnode *a, *n, *v;
-
- name = va_arg(params, const char *);
- if (!name)
- break;
-
- value = va_arg(params, const char *);
- if (!value)
- break;
-
- a = xmlnode_new_child(annotations, "Annotation");
- n = xmlnode_new_child(a, "Name");
- xmlnode_insert_data(n, name, -1);
- v = xmlnode_new_child(a, "Value");
- xmlnode_insert_data(v, value, -1);
- }
- va_end(params);
-
- state = msn_callback_state_new(session);
-
- state->body = xmlnode_from_str(MSN_CONTACT_ANNOTATE_TEMPLATE, -1);
- state->action = MSN_ANNOTATE_USER;
- state->post_action = MSN_CONTACT_ANNOTATE_SOAP_ACTION;
- state->post_url = MSN_ADDRESS_BOOK_POST_URL;
- state->cb = msn_annotate_contact_read_cb;
-
- xmlnode_insert_data(xmlnode_get_child(state->body,
- "Header/ABApplicationHeader/PartnerScenario"),
- MsnSoapPartnerScenarioText[MSN_PS_SAVE_CONTACT], -1);
-
- contact = xmlnode_get_child(state->body, "Body/ABContactUpdate/contacts/Contact");
- xmlnode_insert_child(contact, contact_info);
-
- if (user) {
- xmlnode *contactId = xmlnode_new_child(contact, "contactId");
- msn_callback_state_set_uid(state, user->uid);
- xmlnode_insert_data(contactId, state->uid, -1);
- } else {
- xmlnode *contactType = xmlnode_new_child(contact_info, "contactType");
- xmlnode_insert_data(contactType, "Me", -1);
- }
-
- msn_contact_request(state);
-}
-
-static void
-msn_del_contact_from_list_read_cb(MsnSoapMessage *req, MsnSoapMessage *resp,
- gpointer data)
-{
- MsnCallbackState *state = data;
- MsnSession *session = state->session;
- xmlnode *fault;
-
- /* We don't know how to respond to this faultcode, so log it */
- fault = xmlnode_get_child(resp->xml, "Body/Fault");
- if (fault != NULL) {
- char *fault_str = xmlnode_to_str(fault, NULL);
- purple_debug_error("msn", "Operation {%s} Failed, SOAP Fault was: %s\n",
- msn_contact_operation_str(state->action), fault_str);
- g_free(fault_str);
- return;
- }
-
- purple_debug_info("msn", "Contact %s deleted successfully from %s list on server!\n", state->who, MsnMemberRole[state->list_id]);
-
- if (state->list_id == MSN_LIST_PL) {
- MsnUser *user = msn_userlist_find_user(session->userlist, state->who);
- MsnCallbackState *new_state = msn_callback_state_dup(state);
-
- if (user != NULL)
- msn_user_unset_op(user, MSN_LIST_PL_OP);
-
- msn_add_contact_to_list(session, new_state, state->who, MSN_LIST_RL);
- return;
- } else if (state->list_id == MSN_LIST_AL) {
- purple_privacy_permit_remove(session->account, state->who, TRUE);
- msn_add_contact_to_list(session, NULL, state->who, MSN_LIST_BL);
- } else if (state->list_id == MSN_LIST_BL) {
- purple_privacy_deny_remove(session->account, state->who, TRUE);
- msn_add_contact_to_list(session, NULL, state->who, MSN_LIST_AL);
- }
-
-}
-
-void
-msn_del_contact_from_list(MsnSession *session, MsnCallbackState *state,
- const gchar *passport, const MsnListId list)
-{
- gchar *body = NULL, *member = NULL;
- MsnSoapPartnerScenario partner_scenario;
- MsnUser *user;
-
- g_return_if_fail(session != NULL);
- g_return_if_fail(session->userlist != NULL);
- g_return_if_fail(passport != NULL);
- g_return_if_fail(list < 5);
-
- purple_debug_info("msn", "Deleting contact %s from %s list\n", passport, MsnMemberRole[list]);
-
- if (state == NULL) {
- state = msn_callback_state_new(session);
- }
- msn_callback_state_set_list_id(state, list);
- msn_callback_state_set_who(state, passport);
-
- user = msn_userlist_find_user(session->userlist, passport);
- g_return_if_fail(user != NULL);
-
- if (list == MSN_LIST_PL) {
- partner_scenario = MSN_PS_CONTACT_API;
- if (user->networkid != MSN_NETWORK_PASSPORT)
- member = g_strdup_printf(MSN_MEMBER_MEMBERSHIPID_XML,
- "EmailMember", "Email",
- user->member_id_on_pending_list);
- else
- member = g_strdup_printf(MSN_MEMBER_MEMBERSHIPID_XML,
- "PassportMember", "Passport",
- user->member_id_on_pending_list);
- } else {
- /* list == MSN_LIST_AL || list == MSN_LIST_BL */
- partner_scenario = MSN_PS_BLOCK_UNBLOCK;
- if (user && user->networkid != MSN_NETWORK_PASSPORT)
- member = g_strdup_printf(MSN_MEMBER_PASSPORT_XML,
- "EmailMember", "Email",
- "Email", passport, "Email");
- else
- member = g_strdup_printf(MSN_MEMBER_PASSPORT_XML,
- "PassportMember", "Passport",
- "PassportName", passport, "PassportName");
- }
-
- body = g_strdup_printf(MSN_CONTACT_DELETE_FROM_LIST_TEMPLATE,
- MsnSoapPartnerScenarioText[partner_scenario],
- MsnMemberRole[list], member);
-
- state->body = xmlnode_from_str(body, -1);
- state->post_action = MSN_DELETE_MEMBER_FROM_LIST_SOAP_ACTION;
- state->post_url = MSN_SHARE_POST_URL;
- state->cb = msn_del_contact_from_list_read_cb;
- msn_contact_request(state);
-
- g_free(member);
- g_free(body);
-}
-
-static void
-msn_add_contact_to_list_read_cb(MsnSoapMessage *req, MsnSoapMessage *resp,
- gpointer data)
-{
- MsnCallbackState *state = data;
- xmlnode *fault;
-
- /* We don't know how to respond to this faultcode, so log it */
- fault = xmlnode_get_child(resp->xml, "Body/Fault");
- if (fault != NULL) {
- char *fault_str = xmlnode_to_str(fault, NULL);
- purple_debug_error("msn", "Operation {%s} Failed, SOAP Fault was: %s\n",
- msn_contact_operation_str(state->action), fault_str);
- g_free(fault_str);
- return;
- }
-
- g_return_if_fail(state->session != NULL);
-
- purple_debug_info("msn", "Contact %s added successfully to %s list on server!\n", state->who, MsnMemberRole[state->list_id]);
-
- if (state->list_id == MSN_LIST_RL) {
- MsnUser *user = msn_userlist_find_user(state->session->userlist, state->who);
-
- if (user != NULL) {
- msn_user_set_op(user, MSN_LIST_RL_OP);
- }
-
- if (state->action & MSN_DENIED_BUDDY) {
- msn_add_contact_to_list(state->session, NULL, state->who, MSN_LIST_BL);
- } else if (state->list_id == MSN_LIST_AL) {
- purple_privacy_permit_add(state->session->account, state->who, TRUE);
- } else if (state->list_id == MSN_LIST_BL) {
- purple_privacy_deny_add(state->session->account, state->who, TRUE);
- }
- }
-}
-
-void
-msn_add_contact_to_list(MsnSession *session, MsnCallbackState *state,
- const gchar *passport, const MsnListId list)
-{
- gchar *body = NULL, *member = NULL;
- MsnSoapPartnerScenario partner_scenario;
- MsnUser *user;
-
- g_return_if_fail(session != NULL);
- g_return_if_fail(passport != NULL);
- g_return_if_fail(list < 5);
-
- purple_debug_info("msn", "Adding contact %s to %s list\n", passport, MsnMemberRole[list]);
-
- if (state == NULL) {
- state = msn_callback_state_new(session);
- }
- msn_callback_state_set_list_id(state, list);
- msn_callback_state_set_who(state, passport);
-
- user = msn_userlist_find_user(session->userlist, passport);
-
- partner_scenario = (list == MSN_LIST_RL) ? MSN_PS_CONTACT_API : MSN_PS_BLOCK_UNBLOCK;
- if (user && user->networkid != MSN_NETWORK_PASSPORT)
- member = g_strdup_printf(MSN_MEMBER_PASSPORT_XML,
- "EmailMember", "Email",
- "Email", state->who, "Email");
- else
- member = g_strdup_printf(MSN_MEMBER_PASSPORT_XML,
- "PassportMember", "Passport",
- "PassportName", state->who, "PassportName");
-
- body = g_strdup_printf(MSN_CONTACT_ADD_TO_LIST_TEMPLATE,
- MsnSoapPartnerScenarioText[partner_scenario],
- MsnMemberRole[list], member);
-
- state->body = xmlnode_from_str(body, -1);
- state->post_action = MSN_ADD_MEMBER_TO_LIST_SOAP_ACTION;
- state->post_url = MSN_SHARE_POST_URL;
- state->cb = msn_add_contact_to_list_read_cb;
- msn_contact_request(state);
-
- g_free(member);
- g_free(body);
-}
-
-#if 0
-static void
-msn_gleams_read_cb(MsnSoapMessage *req, MsnSoapMessage *resp, gpointer data)
-{
- purple_debug_info("msn", "Gleams read done\n");
-}
-
-/*get the gleams info*/
-void
-msn_get_gleams(MsnSession *session)
-{
- MsnSoapReq *soap_request;
-
- purple_debug_info("msn", "msn get gleams info...\n");
-
- state = msn_callback_state_new(session);
- state->body = xmlnode_from_str(MSN_GLEAMS_TEMPLATE, -1);
- state->post_action = MSN_GET_GLEAMS_SOAP_ACTION;
- state->post_url = MSN_ADDRESS_BOOK_POST_URL;
- state->cb = msn_gleams_read_cb;
- msn_contact_request(state);
-}
-#endif
-
-
-/***************************************************************
- * Group Operations
- ***************************************************************/
-
-static void
-msn_group_read_cb(MsnSoapMessage *req, MsnSoapMessage *resp, gpointer data)
-{
- MsnCallbackState *state = data;
- MsnSession *session;
- MsnUserList *userlist;
- xmlnode *fault;
-
- /* We don't know how to respond to this faultcode, so log it */
- fault = xmlnode_get_child(resp->xml, "Body/Fault");
- if (fault != NULL) {
- char *fault_str = xmlnode_to_str(fault, NULL);
- purple_debug_error("msn", "Operation {%s} Failed, SOAP Fault was: %s\n",
- msn_contact_operation_str(state->action), fault_str);
- g_free(fault_str);
- return;
- }
-
- purple_debug_info("msn", "Group request successful.\n");
-
- g_return_if_fail(state->session != NULL);
- g_return_if_fail(state->session->userlist != NULL);
-
- session = state->session;
- userlist = session->userlist;
-
- if (state->action & MSN_RENAME_GROUP) {
- msn_userlist_rename_group_id(session->userlist,
- state->guid,
- state->new_group_name);
- }
-
- if (state->action & MSN_ADD_GROUP) {
- /* the response is taken from
- http://telepathy.freedesktop.org/wiki/Pymsn/MSNP/ContactListActions
- should copy it to msnpiki some day */
- xmlnode *guid_node = xmlnode_get_child(resp->xml,
- "Body/ABGroupAddResponse/ABGroupAddResult/guid");
-
- if (guid_node) {
- char *guid = xmlnode_get_data(guid_node);
-
- /* create and add the new group to the userlist */
- purple_debug_info("msn", "Adding group %s with guid = %s to the userlist\n", state->new_group_name, guid);
- msn_group_new(session->userlist, guid, state->new_group_name);
-
- if (state->action & MSN_ADD_BUDDY) {
- msn_userlist_add_buddy(session->userlist,
- state->who,
- state->new_group_name);
- } else if (state->action & MSN_MOVE_BUDDY) {
- /* This will be freed when the add contact callback fires */
- MsnCallbackState *new_state = msn_callback_state_dup(state);
- msn_add_contact_to_group(session, new_state, state->who, guid);
- g_free(guid);
- return;
- }
- g_free(guid);
- } else {
- purple_debug_info("msn", "Adding group %s failed\n",
- state->new_group_name);
- }
- }
-
- if (state->action & MSN_DEL_GROUP) {
- GList *l;
-
- msn_userlist_remove_group_id(session->userlist, state->guid);
- for (l = userlist->users; l != NULL; l = l->next) {
- msn_user_remove_group_id( (MsnUser *)l->data, state->guid);
- }
- }
-}
-
-/* add group */
-void
-msn_add_group(MsnSession *session, MsnCallbackState *state, const char* group_name)
-{
- char *body = NULL;
- char *escaped_group_name = NULL;
-
- g_return_if_fail(session != NULL);
- g_return_if_fail(group_name != NULL);
-
- purple_debug_info("msn", "Adding group %s to contact list.\n", group_name);
-
- if (state == NULL) {
- state = msn_callback_state_new(session);
- }
-
- msn_callback_state_set_action(state, MSN_ADD_GROUP);
- msn_callback_state_set_new_group_name(state, group_name);
-
- /* escape group name's html special chars so it can safely be sent
- * in a XML SOAP request
- */
- escaped_group_name = g_markup_escape_text(group_name, -1);
- body = g_strdup_printf(MSN_GROUP_ADD_TEMPLATE, escaped_group_name);
-
- state->body = xmlnode_from_str(body, -1);
- state->post_action = MSN_GROUP_ADD_SOAP_ACTION;
- state->post_url = MSN_ADDRESS_BOOK_POST_URL;
- state->cb = msn_group_read_cb;
- msn_contact_request(state);
-
- g_free(escaped_group_name);
- g_free(body);
-}
-
-/* delete group */
-void
-msn_del_group(MsnSession *session, const gchar *group_name)
-{
- MsnCallbackState *state;
- char *body = NULL;
- const gchar *guid;
-
- g_return_if_fail(session != NULL);
-
- g_return_if_fail(group_name != NULL);
- purple_debug_info("msn", "Deleting group %s from contact list\n", group_name);
-
- guid = msn_userlist_find_group_id(session->userlist, group_name);
-
- /* if group uid we need to del is NULL,
- * we need to delete nothing
- */
- if (guid == NULL) {
- purple_debug_info("msn", "Group %s guid not found, returning.\n", group_name);
- return;
- }
-
- if ( !strcmp(guid, MSN_INDIVIDUALS_GROUP_ID) || !strcmp(guid, MSN_NON_IM_GROUP_ID) ) {
- /* XXX add back PurpleGroup since it isn't really removed in the server? */
- return;
- }
-
- state = msn_callback_state_new(session);
- msn_callback_state_set_action(state, MSN_DEL_GROUP);
- msn_callback_state_set_guid(state, guid);
-
- body = g_strdup_printf(MSN_GROUP_DEL_TEMPLATE, guid);
-
- state->body = xmlnode_from_str(body, -1);
- state->post_action = MSN_GROUP_DEL_SOAP_ACTION;
- state->post_url = MSN_ADDRESS_BOOK_POST_URL;
- state->cb = msn_group_read_cb;
- msn_contact_request(state);
-
- g_free(body);
-}
-
-/* rename group */
-void
-msn_contact_rename_group(MsnSession *session, const char *old_group_name, const char *new_group_name)
-{
- gchar *body = NULL;
- const gchar * guid;
- MsnCallbackState *state;
- char *escaped_group_name;
-
- g_return_if_fail(session != NULL);
- g_return_if_fail(session->userlist != NULL);
- g_return_if_fail(old_group_name != NULL);
- g_return_if_fail(new_group_name != NULL);
-
- purple_debug_info("msn", "Renaming group %s to %s.\n", old_group_name, new_group_name);
-
- guid = msn_userlist_find_group_id(session->userlist, old_group_name);
- if (guid == NULL)
- return;
-
- state = msn_callback_state_new(session);
- msn_callback_state_set_guid(state, guid);
- msn_callback_state_set_new_group_name(state, new_group_name);
-
- if ( !strcmp(guid, MSN_INDIVIDUALS_GROUP_ID) || !strcmp(guid, MSN_NON_IM_GROUP_ID) ) {
- MsnCallbackState *new_state = msn_callback_state_dup(state);
- msn_add_group(session, new_state, new_group_name);
- /* XXX move every buddy there (we probably need to fix concurrent SOAP reqs first) */
- }
-
- msn_callback_state_set_action(state, MSN_RENAME_GROUP);
-
- escaped_group_name = g_markup_escape_text(new_group_name, -1);
- body = g_strdup_printf(MSN_GROUP_RENAME_TEMPLATE, guid, escaped_group_name);
-
- state->body = xmlnode_from_str(body, -1);
- state->post_action = MSN_GROUP_RENAME_SOAP_ACTION;
- state->post_url = MSN_ADDRESS_BOOK_POST_URL;
- state->cb = msn_group_read_cb;
- msn_contact_request(state);
-
- g_free(escaped_group_name);
- g_free(body);
-}
-
diff --git a/libpurple/protocols/msn/contact.h b/libpurple/protocols/msn/contact.h
deleted file mode 100644
index fcd60d73de..0000000000
--- a/libpurple/protocols/msn/contact.h
+++ /dev/null
@@ -1,747 +0,0 @@
-/**
- * @file contact.h Header file for contact.c
- * Author
- * MaYuan<mayuan2006@gmail.com>
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-#ifndef MSN_CONTACT_H
-#define MSN_CONTACT_H
-
-typedef struct _MsnCallbackState MsnCallbackState;
-
-typedef enum
-{
- MSN_ADD_BUDDY = 0x01,
- MSN_MOVE_BUDDY = 0x02,
- MSN_ACCEPTED_BUDDY = 0x04,
- MSN_DENIED_BUDDY = 0x08,
- MSN_ADD_GROUP = 0x10,
- MSN_DEL_GROUP = 0x20,
- MSN_RENAME_GROUP = 0x40,
- MSN_UPDATE_INFO = 0x80,
- MSN_ANNOTATE_USER = 0x100
-} MsnCallbackAction;
-
-typedef enum
-{
- MSN_UPDATE_DISPLAY, /* Real display name */
- MSN_UPDATE_ALIAS, /* Aliased display name */
- MSN_UPDATE_COMMENT
-} MsnContactUpdateType;
-
-typedef enum
-{
- MSN_PS_INITIAL,
- MSN_PS_SAVE_CONTACT,
- MSN_PS_PENDING_LIST,
- MSN_PS_CONTACT_API,
- MSN_PS_BLOCK_UNBLOCK,
- MSN_PS_TIMER
-} MsnSoapPartnerScenario;
-
-#include "session.h"
-#include "soap.h"
-
-/* Thanks to TReKiE on the #pidgin channel for this new ID. */
-#define MSN_APPLICATION_ID "F6D2794D-501F-443A-ADBE-8F1490FF30FD"
-
-#define MSN_CONTACT_SERVER "local-bay.contacts.msn.com"
-
-/* Get Contact List */
-
-#define MSN_GET_CONTACT_POST_URL "/abservice/SharingService.asmx"
-#define MSN_GET_CONTACT_SOAP_ACTION "http://www.msn.com/webservices/AddressBook/FindMembership"
-
-#define MSN_GET_CONTACT_UPDATE_XML \
- "<View>Full</View>"\
- "<deltasOnly>true</deltasOnly>"\
- "<lastChange>%s</lastChange>"
-
-#define MSN_GET_CONTACT_TEMPLATE "<?xml version='1.0' encoding='utf-8'?>"\
-"<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"\
- "<soap:Header xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"\
- "<ABApplicationHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<ApplicationId xmlns=\"http://www.msn.com/webservices/AddressBook\">" MSN_APPLICATION_ID "</ApplicationId>"\
- "<IsMigration xmlns=\"http://www.msn.com/webservices/AddressBook\">false</IsMigration>"\
- "<PartnerScenario xmlns=\"http://www.msn.com/webservices/AddressBook\">%s</PartnerScenario>"\
- "</ABApplicationHeader>"\
- "<ABAuthHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<ManagedGroupRequest xmlns=\"http://www.msn.com/webservices/AddressBook\">false</ManagedGroupRequest>"\
- "<TicketToken>EMPTY</TicketToken>"\
- "</ABAuthHeader>"\
- "</soap:Header>"\
- "<soap:Body xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"\
- "<FindMembership xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<serviceFilter xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<Types xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<ServiceType xmlns=\"http://www.msn.com/webservices/AddressBook\">Messenger</ServiceType>"\
- "<ServiceType xmlns=\"http://www.msn.com/webservices/AddressBook\">Invitation</ServiceType>"\
- "<ServiceType xmlns=\"http://www.msn.com/webservices/AddressBook\">SocialNetwork</ServiceType>"\
- "<ServiceType xmlns=\"http://www.msn.com/webservices/AddressBook\">Space</ServiceType>"\
- "<ServiceType xmlns=\"http://www.msn.com/webservices/AddressBook\">Profile</ServiceType>"\
- "</Types>"\
- "</serviceFilter>"\
- "%s"\
- "</FindMembership>"\
- "</soap:Body>"\
-"</soap:Envelope>"
-
-/************************************************
- * Address Book SOAP
- * *********************************************/
-
-#define MSN_ADDRESS_BOOK_POST_URL "/abservice/abservice.asmx"
-
-/* Create AddressBook template */
-#define MSN_ADD_ADDRESSBOOK_SOAP_ACTION "http://www.msn.com/webservices/AddressBook/ABAdd"
-
-#define MSN_ADD_ADDRESSBOOK_TEMPLATE "<?xml version=\"1.0\" encoding=\"utf-8\"?>"\
-"<soap:Envelope"\
- " xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\""\
- " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""\
- " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\""\
- " xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\">"\
- "<soap:Header>"\
- "<ABApplicationHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<ApplicationId>" MSN_APPLICATION_ID "</ApplicationId>"\
- "<IsMigration>false</IsMigration>"\
- "<PartnerScenario>Initial</PartnerScenario>"\
- "</ABApplicationHeader>"\
- "<ABAuthHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<ManagedGroupRequest>false</ManagedGroupRequest>"\
- "<TicketToken>EMPTY</TicketToken>"\
- "</ABAuthHeader>"\
- "</soap:Header>"\
- "<soap:Body>"\
- "<ABAdd xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<abInfo>"\
- "<name/>"\
- "<ownerPuid>0</ownerPuid>"\
- "<ownerEmail>%s</ownerEmail>"\
- "<fDefault>true</fDefault>"\
- "</abInfo>"\
- "</ABAdd>"\
- "</soap:Body>"\
-"</soap:Envelope>"
-
-/* Get AddressBook */
-#define MSN_GET_ADDRESS_SOAP_ACTION "http://www.msn.com/webservices/AddressBook/ABFindContactsPaged"
-#define MSN_GET_ADDRESS_FULL_TIME "0001-01-01T00:00:00.0000000-08:00"
-#define MSN_GET_ADDRESS_UPDATE_XML \
- "<filterOptions>"\
- "<deltasOnly>true</deltasOnly>"\
- "<lastChange>%s</lastChange>"\
- "</filterOptions>"
-
-#define MSN_GET_GLEAM_UPDATE_XML \
- "%s"\
- "<dynamicItemView>Gleam</dynamicItemView>"\
- "<dynamicItemLastChange>%s</dynamicItemLastChange>"
-
-#define MSN_GET_ADDRESS_TEMPLATE "<?xml version=\"1.0\" encoding=\"utf-8\"?>"\
-"<soap:Envelope"\
- " xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\""\
- " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""\
- " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\""\
- " xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\">"\
- "<soap:Header>"\
- "<ABApplicationHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<ApplicationId>" MSN_APPLICATION_ID "</ApplicationId>"\
- "<IsMigration>false</IsMigration>"\
- "<PartnerScenario>%s</PartnerScenario>"\
- "</ABApplicationHeader>"\
- "<ABAuthHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<ManagedGroupRequest>false</ManagedGroupRequest>"\
- "<TicketToken>EMPTY</TicketToken>"\
- "</ABAuthHeader>"\
- "</soap:Header>"\
- "<soap:Body>"\
- "<ABFindContactsPaged xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<abView>Full</abView>"\
- "<extendedContent>AB AllGroups CircleResult</extendedContent>"\
- "%s"\
- "</ABFindContactsPaged>"\
- "</soap:Body>"\
-"</soap:Envelope>"
-
-
-/*Gleams SOAP request template*/
-#define MSN_GET_GLEAMS_SOAP_ACTION "http://www.msn.com/webservices/AddressBook/ABFindAll"
-#define MSN_GLEAMS_TEMPLATE "<?xml version=\"1.0\" encoding=\"utf-8\"?>"\
-"<soap:Envelope"\
- " xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\""\
- " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""\
- " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\""\
- " xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\">"\
- "<soap:Header>"\
- "<ABApplicationHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<ApplicationId>" MSN_APPLICATION_ID "</ApplicationId>"\
- "<IsMigration>false</IsMigration>"\
- "<PartnerScenario>Initial</PartnerScenario>"\
- "</ABApplicationHeader>"\
- "<ABAuthHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<ManagedGroupRequest>false</ManagedGroupRequest>"\
- "<TicketToken>EMPTY</TicketToken>"\
- "</ABAuthHeader>"\
- "</soap:Header>"\
- "<soap:Body>"\
- "<ABFindAll xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<abId>00000000-0000-0000-0000-000000000000</abId>"\
- "<abView>Full</abView>"\
- "<dynamicItemView>Gleam</dynamicItemView>"\
- "<dynamicItemLastChange>0001-01-01T00:00:00.0000000-08:00</dynamicItemLastChange>"\
- "</ABFindAll>"\
- "</soap:Body>"\
-"</soap:Envelope>"
-
-
-/*******************************************************
- * Contact Management SOAP actions
- *******************************************************/
-
-/* Add a new contact */
-#define MSN_CONTACT_ADD_SOAP_ACTION "http://www.msn.com/webservices/AddressBook/ABContactAdd"
-#define MSN_CONTACT_LIVE_PENDING_XML \
- "<Contact xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<contactInfo>"\
- "<contactType>LivePending</contactType>"\
- "<passportName>%s</passportName>"\
- "<isMessengerUser>true</isMessengerUser>"\
- "</contactInfo>"\
- "</Contact>"
-
-#define MSN_CONTACT_XML \
- "<Contact xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<contactInfo>"\
- "<passportName>%s</passportName>"\
- "<isSmtp>false</isSmtp>"\
- "<isMessengerUser>true</isMessengerUser>"\
- "</contactInfo>"\
- "</Contact>"
-
-#define MSN_CONTACT_DISPLAYNAME_XML \
- "<Contact xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<contactInfo>"\
- "<displayName>%s</displayName>"\
- "<passportName>%s</passportName>"\
- "<isMessengerUser>true</isMessengerUser>"\
- "</contactInfo>"\
- "</Contact>"
-
-#define MSN_CONTACT_ID_XML \
- "<Contact>"\
- "<contactId>%s</contactId>"\
- "</Contact>"
-
-#define MSN_CONTACT_EMAIL_XML \
- "<Contact>"\
- "<contactInfo>"\
- "<emails>"\
- "<ContactEmail>"\
- "<contactEmailType>%s</contactEmailType>"\
- "<email>%s</email>"\
- "<isMessengerEnabled>true</isMessengerEnabled>"\
- "<Capability>%d</Capability>"\
- "<MessengerEnabledExternally>false</MessengerEnabledExternally>"\
- "<propertiesChanged/>"\
- "</ContactEmail>"\
- "</emails>"\
- "</contactInfo>"\
- "</Contact>"
-
-#define MSN_CONTACT_INVITE_MESSAGE_XML \
- "<MessengerMemberInfo>"\
- "<PendingAnnotations>"\
- "<Annotation>"\
- "<Name>MSN.IM.InviteMessage</Name>"\
- "<Value>%s</Value>"\
- "</Annotation>"\
- "</PendingAnnotations>"\
- "<DisplayName>%s</DisplayName>"\
- "</MessengerMemberInfo>"
-
-#define MSN_ADD_CONTACT_TEMPLATE "<?xml version=\"1.0\" encoding=\"utf-8\"?>"\
-"<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\""\
- " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""\
- " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\""\
- " xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\">"\
- "<soap:Header>"\
- "<ABApplicationHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<ApplicationId>" MSN_APPLICATION_ID "</ApplicationId>"\
- "<IsMigration>false</IsMigration>"\
- "<PartnerScenario>ContactSave</PartnerScenario>"\
- "</ABApplicationHeader>"\
- "<ABAuthHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<ManagedGroupRequest>false</ManagedGroupRequest>"\
- "<TicketToken>EMPTY</TicketToken>"\
- "</ABAuthHeader>"\
- "</soap:Header>"\
- "<soap:Body>"\
- "<ABContactAdd xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<abId>00000000-0000-0000-0000-000000000000</abId>"\
- "<contacts>%s</contacts>"\
- "<options>"\
- "<EnableAllowListManagement>true</EnableAllowListManagement>"\
- "</options>"\
- "</ABContactAdd>"\
- "</soap:Body>"\
-"</soap:Envelope>"
-
-/* Add a contact to a group */
-#define MSN_ADD_CONTACT_GROUP_SOAP_ACTION "http://www.msn.com/webservices/AddressBook/ABGroupContactAdd"
-#define MSN_ADD_CONTACT_GROUP_TEMPLATE "<?xml version=\"1.0\" encoding=\"utf-8\"?>"\
-"<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\""\
- " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""\
- " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\""\
- " xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\">"\
- "<soap:Header>"\
- "<ABApplicationHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<ApplicationId>" MSN_APPLICATION_ID "</ApplicationId>"\
- "<IsMigration>false</IsMigration>"\
- "<PartnerScenario>ContactSave</PartnerScenario>"\
- "</ABApplicationHeader>"\
- "<ABAuthHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<ManagedGroupRequest>false</ManagedGroupRequest>"\
- "<TicketToken>EMPTY</TicketToken>"\
- "</ABAuthHeader>"\
- "</soap:Header>"\
- "<soap:Body>"\
- "<ABGroupContactAdd xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<abId>00000000-0000-0000-0000-000000000000</abId>"\
- "<groupFilter>"\
- "<groupIds>"\
- "<guid>%s</guid>"\
- "</groupIds>"\
- "</groupFilter>"\
- "<contacts>%s</contacts>"\
- "<groupContactAddOptions>"\
- "<fGenerateMissingQuickName>true</fGenerateMissingQuickName>"\
- "<EnableAllowListManagement>true</EnableAllowListManagement>"\
- "</groupContactAddOptions>"\
- "%s"\
- "</ABGroupContactAdd>"\
- "</soap:Body>"\
-"</soap:Envelope>"
-
-/* Delete a contact from the Contact List */
-#define MSN_CONTACT_DEL_SOAP_ACTION "http://www.msn.com/webservices/AddressBook/ABContactDelete"
-#define MSN_DEL_CONTACT_TEMPLATE "<?xml version=\"1.0\" encoding=\"utf-8\"?>"\
-"<soap:Envelope"\
- " xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\""\
- " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""\
- " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\""\
- " xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\">"\
- "<soap:Header>"\
- "<ABApplicationHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<ApplicationId>" MSN_APPLICATION_ID "</ApplicationId>"\
- "<IsMigration>false</IsMigration>"\
- "<PartnerScenario>Timer</PartnerScenario>"\
- "</ABApplicationHeader>"\
- "<ABAuthHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<ManagedGroupRequest>false</ManagedGroupRequest>"\
- "<TicketToken>EMPTY</TicketToken>"\
- "</ABAuthHeader>"\
- "</soap:Header>"\
- "<soap:Body>"\
- "<ABContactDelete xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<abId>00000000-0000-0000-0000-000000000000</abId>"\
- "<contacts>%s</contacts>"\
- "</ABContactDelete>"\
- "</soap:Body>"\
-"</soap:Envelope>"
-
-/* Remove a contact from a group */
-#define MSN_CONTACT_DEL_GROUP_SOAP_ACTION "http://www.msn.com/webservices/AddressBook/ABGroupContactDelete"
-#define MSN_CONTACT_DEL_GROUP_TEMPLATE "<?xml version=\"1.0\" encoding=\"utf-8\"?>"\
-"<soap:Envelope"\
- " xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\""\
- " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""\
- " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\""\
- " xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\">"\
- "<soap:Header>"\
- "<ABApplicationHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<ApplicationId>" MSN_APPLICATION_ID "</ApplicationId>"\
- "<IsMigration>false</IsMigration>"\
- "<PartnerScenario>Timer</PartnerScenario>"\
- "</ABApplicationHeader>"\
- "<ABAuthHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<ManagedGroupRequest>false</ManagedGroupRequest>"\
- "<TicketToken>EMPTY</TicketToken>"\
- "</ABAuthHeader>"\
- "</soap:Header>"\
- "<soap:Body>"\
- "<ABGroupContactDelete xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<abId>00000000-0000-0000-0000-000000000000</abId>"\
- "<contacts>%s</contacts>"\
- "<groupFilter>"\
- "<groupIds>"\
- "<guid>%s</guid>"\
- "</groupIds>"\
- "</groupFilter>"\
- "</ABGroupContactDelete>"\
- "</soap:Body>"\
-"</soap:Envelope>"
-
-
-/* Update Contact Information */
-#define MSN_CONTACT_UPDATE_SOAP_ACTION "http://www.msn.com/webservices/AddressBook/ABContactUpdate"
-#define MSN_CONTACT_UPDATE_TEMPLATE "<?xml version=\"1.0\" encoding=\"utf-8\"?>"\
-"<soap:Envelope"\
- " xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\""\
- " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""\
- " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\""\
- " xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\">"\
- "<soap:Header>"\
- "<ABApplicationHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<ApplicationId>" MSN_APPLICATION_ID "</ApplicationId>"\
- "<IsMigration>false</IsMigration>"\
- "<PartnerScenario></PartnerScenario>"\
- "</ABApplicationHeader>"\
- "<ABAuthHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<ManagedGroupRequest>false</ManagedGroupRequest>"\
- "<TicketToken>EMPTY</TicketToken>"\
- "</ABAuthHeader>"\
- "</soap:Header>"\
- "<soap:Body>"\
- "<ABContactUpdate xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<abId>00000000-0000-0000-0000-000000000000</abId>"\
- "<contacts>"\
- "<Contact xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- ""\
- "</Contact>"\
- "</contacts>"\
- "</ABContactUpdate>"\
- "</soap:Body>"\
-"</soap:Envelope>"
-
-/* Update Contact Annotations */
-#define MSN_CONTACT_ANNOTATE_SOAP_ACTION "http://www.msn.com/webservices/AddressBook/ABContactUpdate"
-#define MSN_CONTACT_ANNOTATE_TEMPLATE "<?xml version=\"1.0\" encoding=\"utf-8\"?>"\
-"<soap:Envelope"\
- " xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\""\
- " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""\
- " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\""\
- " xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\">"\
- "<soap:Header>"\
- "<ABApplicationHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<ApplicationId>" MSN_APPLICATION_ID "</ApplicationId>"\
- "<IsMigration>false</IsMigration>"\
- "<PartnerScenario></PartnerScenario>"\
- "</ABApplicationHeader>"\
- "<ABAuthHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<ManagedGroupRequest>false</ManagedGroupRequest>"\
- "<TicketToken>EMPTY</TicketToken>"\
- "</ABAuthHeader>"\
- "</soap:Header>"\
- "<soap:Body>"\
- "<ABContactUpdate xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<abId>00000000-0000-0000-0000-000000000000</abId>"\
- "<contacts>"\
- "<Contact xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<propertiesChanged>Annotation</propertiesChanged>"\
- "</Contact>"\
- "</contacts>"\
- "</ABContactUpdate>"\
- "</soap:Body>"\
-"</soap:Envelope>"
-
-/*******************************************************
- * Add/Delete contact from lists SOAP actions
- *******************************************************/
-
-/* block means delete from allow list and add contact to block list */
-#define MSN_SHARE_POST_URL "/abservice/SharingService.asmx"
-
-#define MSN_ADD_MEMBER_TO_LIST_SOAP_ACTION "http://www.msn.com/webservices/AddressBook/AddMember"
-#define MSN_DELETE_MEMBER_FROM_LIST_SOAP_ACTION "http://www.msn.com/webservices/AddressBook/DeleteMember"
-
-#define MSN_MEMBER_PASSPORT_XML \
- "<Member xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"%s\">"\
- "<Type>%s</Type>"\
- "<State>Accepted</State>"\
- "<%s>%s</%s>"\
- "</Member>"
-
-#define MSN_MEMBER_MEMBERSHIPID_XML \
- "<Member xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"%s\">"\
- "<Type>%s</Type>"\
- "<MembershipId>%u</MembershipId>"\
- "<State>Accepted</State>"\
- "</Member>"
-
-/* first delete contact from allow list */
-
-#define MSN_CONTACT_DELETE_FROM_LIST_TEMPLATE "<?xml version=\"1.0\" encoding=\"utf-8\"?>"\
-"<soap:Envelope"\
- " xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\""\
- " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""\
- " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\""\
- " xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\">"\
- "<soap:Header>"\
- "<ABApplicationHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<ApplicationId>" MSN_APPLICATION_ID "</ApplicationId>"\
- "<IsMigration>false</IsMigration>"\
- "<PartnerScenario>%s</PartnerScenario>"\
- "</ABApplicationHeader>"\
- "<ABAuthHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<ManagedGroupRequest>false</ManagedGroupRequest>"\
- "<TicketToken>EMPTY</TicketToken>"\
- "</ABAuthHeader>"\
- "</soap:Header>"\
- "<soap:Body>"\
- "<DeleteMember xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<serviceHandle>"\
- "<Id>0</Id>"\
- "<Type>Messenger</Type>"\
- "<ForeignId></ForeignId>"\
- "</serviceHandle>"\
- "<memberships>"\
- "<Membership>"\
- "<MemberRole>%s</MemberRole>"\
- "<Members>"\
- "%s"\
- "</Members>"\
- "</Membership>"\
- "</memberships>"\
- "</DeleteMember>"\
- "</soap:Body>"\
-"</soap:Envelope>"
-
-#define MSN_CONTACT_ADD_TO_LIST_TEMPLATE "<?xml version=\"1.0\" encoding=\"utf-8\"?>"\
-"<soap:Envelope"\
- " xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\""\
- " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""\
- " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\""\
- " xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\">"\
- "<soap:Header>"\
- "<ABApplicationHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<ApplicationId>" MSN_APPLICATION_ID "</ApplicationId>"\
- "<IsMigration>false</IsMigration>"\
- "<PartnerScenario>%s</PartnerScenario>"\
- "</ABApplicationHeader>"\
- "<ABAuthHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<ManagedGroupRequest>false</ManagedGroupRequest>"\
- "<TicketToken>EMPTY</TicketToken>"\
- "</ABAuthHeader>"\
- "</soap:Header>"\
- "<soap:Body>"\
- "<AddMember xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<serviceHandle>"\
- "<Id>0</Id>"\
- "<Type>Messenger</Type>"\
- "<ForeignId></ForeignId>"\
- "</serviceHandle>"\
- "<memberships>"\
- "<Membership>"\
- "<MemberRole>%s</MemberRole>"\
- "<Members>"\
- "%s"\
- "</Members>"\
- "</Membership>"\
- "</memberships>"\
- "</AddMember>"\
- "</soap:Body>"\
-"</soap:Envelope>"
-
-
-
-/*******************************************************
- * Group management SOAP actions
- *******************************************************/
-
-/* add a group */
-#define MSN_GROUP_ADD_SOAP_ACTION "http://www.msn.com/webservices/AddressBook/ABGroupAdd"
-#define MSN_GROUP_ADD_TEMPLATE "<?xml version=\"1.0\" encoding=\"utf-8\"?>"\
-"<soap:Envelope"\
- " xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\""\
- " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""\
- " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\""\
- " xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\">"\
- "<soap:Header>"\
- "<ABApplicationHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<ApplicationId>" MSN_APPLICATION_ID "</ApplicationId>"\
- "<IsMigration>false</IsMigration>"\
- "<PartnerScenario>GroupSave</PartnerScenario>"\
- "</ABApplicationHeader>"\
- "<ABAuthHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<ManagedGroupRequest>false</ManagedGroupRequest>"\
- "<TicketToken>EMPTY</TicketToken>"\
- "</ABAuthHeader>"\
- "</soap:Header>"\
- "<soap:Body>"\
- "<ABGroupAdd xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<abId>00000000-0000-0000-0000-000000000000</abId>"\
- "<groupAddOptions>"\
- "<fRenameOnMsgrConflict>false</fRenameOnMsgrConflict>"\
- "</groupAddOptions>"\
- "<groupInfo>"\
- "<GroupInfo>"\
- "<name>%s</name>"\
- "<groupType>C8529CE2-6EAD-434d-881F-341E17DB3FF8</groupType>"\
- "<fMessenger>false</fMessenger>"\
- "<annotations>"\
- "<Annotation>"\
- "<Name>MSN.IM.Display</Name>"\
- "<Value>1</Value>"\
- "</Annotation>"\
- "</annotations>"\
- "</GroupInfo>"\
- "</groupInfo>"\
- "</ABGroupAdd>"\
- "</soap:Body>"\
-"</soap:Envelope>"
-
-/* delete a group */
-#define MSN_GROUP_DEL_SOAP_ACTION "http://www.msn.com/webservices/AddressBook/ABGroupDelete"
-#define MSN_GROUP_DEL_TEMPLATE "<?xml version=\"1.0\" encoding=\"utf-8\"?>"\
-"<soap:Envelope"\
- " xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\""\
- " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""\
- " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\""\
- " xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\">"\
- "<soap:Header>"\
- "<ABApplicationHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<ApplicationId>" MSN_APPLICATION_ID "</ApplicationId>"\
- "<IsMigration>false</IsMigration>"\
- "<PartnerScenario>Timer</PartnerScenario>"\
- "</ABApplicationHeader>"\
- "<ABAuthHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<ManagedGroupRequest>false</ManagedGroupRequest>"\
- "<TicketToken>EMPTY</TicketToken>"\
- "</ABAuthHeader>"\
- "</soap:Header>"\
- "<soap:Body>"\
- "<ABGroupDelete xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<abId>00000000-0000-0000-0000-000000000000</abId>"\
- "<groupFilter>"\
- "<groupIds>"\
- "<guid>%s</guid>"\
- "</groupIds>"\
- "</groupFilter>"\
- "</ABGroupDelete>"\
- "</soap:Body>"\
-"</soap:Envelope>"
-
-/* change a group's name */
-#define MSN_GROUP_RENAME_SOAP_ACTION "http://www.msn.com/webservices/AddressBook/ABGroupUpdate"
-#define MSN_GROUP_RENAME_TEMPLATE "<?xml version=\"1.0\" encoding=\"utf-8\"?>"\
-"<soap:Envelope"\
- " xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\""\
- " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""\
- " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\""\
- " xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\">"\
- "<soap:Header>"\
- "<ABApplicationHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<ApplicationId>" MSN_APPLICATION_ID "</ApplicationId>"\
- "<IsMigration>false</IsMigration>"\
- "<PartnerScenario>Timer</PartnerScenario>"\
- "</ABApplicationHeader>"\
- "<ABAuthHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<ManagedGroupRequest>false</ManagedGroupRequest>"\
- "<TicketToken>EMPTY</TicketToken>"\
- "</ABAuthHeader>"\
- "</soap:Header>"\
- "<soap:Body>"\
- "<ABGroupUpdate xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
- "<abId>00000000-0000-0000-0000-000000000000</abId>"\
- "<groups>"\
- "<Group>"\
- "<groupId>%s</groupId>"\
- "<groupInfo>"\
- "<name>%s</name>"\
- "</groupInfo>"\
- "<propertiesChanged>GroupName </propertiesChanged>"\
- "</Group>"\
- "</groups>"\
- "</ABGroupUpdate>"\
- "</soap:Body>"\
-"</soap:Envelope>"
-
-struct _MsnCallbackState
-{
- gchar * who;
- gchar * uid;
- gchar * old_group_name;
- gchar * new_group_name;
- gchar * guid;
- MsnListId list_id;
- MsnCallbackAction action;
- MsnSession *session;
- xmlnode *body;
- xmlnode *token;
- const gchar *post_action;
- const gchar *post_url;
- MsnSoapCallback cb;
- /* For msn_get_contact_list only */
- MsnSoapPartnerScenario partner_scenario;
-};
-
-/************************************************
- * function prototype
- ************************************************/
-MsnCallbackState * msn_callback_state_new(MsnSession *session);
-MsnCallbackState * msn_callback_state_dup(MsnCallbackState *state);
-void msn_callback_state_free(MsnCallbackState *state);
-void msn_callback_state_set_who(MsnCallbackState *state, const gchar *who);
-void msn_callback_state_set_uid(MsnCallbackState *state, const gchar *uid);
-void msn_callback_state_set_old_group_name(MsnCallbackState *state,
- const gchar *old_group_name);
-void msn_callback_state_set_new_group_name(MsnCallbackState *state,
- const gchar *new_group_name);
-void msn_callback_state_set_guid(MsnCallbackState *state, const gchar *guid);
-void msn_callback_state_set_list_id(MsnCallbackState *state, MsnListId list_id);
-void msn_callback_state_set_action(MsnCallbackState *state,
- MsnCallbackAction action);
-
-void msn_get_contact_list(MsnSession *session,
- const MsnSoapPartnerScenario partner_scenario,
- const char *update);
-void msn_get_address_book(MsnSession *session,
- const MsnSoapPartnerScenario partner_scenario,
- const char * update, const char * gupdate);
-
-/* contact SOAP operations */
-void msn_update_contact(MsnSession *session, const char *passport, MsnContactUpdateType type, const char* value);
-
-void msn_annotate_contact(MsnSession *session, const char *passport, ...) G_GNUC_NULL_TERMINATED;
-
-void msn_add_contact(MsnSession *session, MsnCallbackState *state,
- const char *passport);
-void msn_delete_contact(MsnSession *session, MsnUser *user);
-
-void msn_add_contact_to_group(MsnSession *session, MsnCallbackState *state,
- const char *passport, const char *groupId);
-void msn_del_contact_from_group(MsnSession *session, const char *passport,
- const char *group_name);
-/* group operations */
-void msn_add_group(MsnSession *session, MsnCallbackState *state,
- const char* group_name);
-void msn_del_group(MsnSession *session, const gchar *group_name);
-void msn_contact_rename_group(MsnSession *session, const char *old_group_name,
- const char *new_group_name);
-
-/* lists operations */
-void msn_add_contact_to_list(MsnSession *session, MsnCallbackState *state,
- const gchar *passport, const MsnListId list);
-void msn_del_contact_from_list(MsnSession *session, MsnCallbackState *state,
- const gchar *passport, const MsnListId list);
-
-#endif /* MSN_CONTACT_H */
diff --git a/libpurple/protocols/msn/directconn.c b/libpurple/protocols/msn/directconn.c
deleted file mode 100644
index cbffb9fffe..0000000000
--- a/libpurple/protocols/msn/directconn.c
+++ /dev/null
@@ -1,958 +0,0 @@
-/**
- * @file directconn.c MSN direct connection functions
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-
-#include "internal.h"
-#include "cipher.h"
-#include "debug.h"
-
-#include "msn.h"
-#include "msnutils.h"
-#include "directconn.h"
-
-#include "slp.h"
-#include "slpmsg.h"
-#include "p2p.h"
-
-#define DC_MAX_BODY_SIZE 8*1024
-#define DC_MAX_PACKET_SIZE (P2P_PACKET_HEADER_SIZE + DC_MAX_BODY_SIZE)
-
-static void
-msn_dc_calculate_nonce_hash(MsnDirectConnNonceType type,
- const guchar *nonce, gsize nonce_len, gchar nonce_hash[37])
-{
- guchar digest[20];
-
- if (type == DC_NONCE_SHA1) {
- PurpleCipher *cipher = purple_ciphers_find_cipher("sha1");
- PurpleCipherContext *context = purple_cipher_context_new(cipher, NULL);
- purple_cipher_context_append(context, nonce, nonce_len);
- purple_cipher_context_digest(context, sizeof(digest), digest, NULL);
- purple_cipher_context_destroy(context);
- } else if (type == DC_NONCE_PLAIN) {
- memcpy(digest, nonce, nonce_len);
- } else {
- nonce_hash[0] = '\0';
- g_return_if_reached();
- }
-
- g_sprintf(nonce_hash,
- "%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X",
-
- digest[3],
- digest[2],
- digest[1],
- digest[0],
-
- digest[5],
- digest[4],
-
- digest[7],
- digest[6],
-
- digest[8],
- digest[9],
-
- digest[10],
- digest[11],
- digest[12],
- digest[13],
- digest[14],
- digest[15]
- );
-}
-
-static void
-msn_dc_generate_nonce(MsnDirectConn *dc)
-{
- guint32 *nonce;
- int i;
-
- nonce = (guint32 *)&dc->nonce;
- for (i = 0; i < 4; i++)
- nonce[i] = rand();
-
- msn_dc_calculate_nonce_hash(dc->nonce_type, dc->nonce, sizeof(dc->nonce), dc->nonce_hash);
-
- if (purple_debug_is_verbose())
- purple_debug_info("msn", "DC %p generated nonce %s\n", dc, dc->nonce_hash);
-}
-
-static MsnDirectConnPacket *
-msn_dc_new_packet(guint32 length)
-{
- MsnDirectConnPacket *p;
-
- p = g_new0(MsnDirectConnPacket, 1);
- p->length = length;
- p->data = g_malloc(length);
-
- return p;
-}
-
-static void
-msn_dc_destroy_packet(MsnDirectConnPacket *p)
-{
- g_free(p->data);
-
- if (p->part)
- msn_slpmsgpart_unref(p->part);
-
- g_free(p);
-}
-
-MsnDirectConn *
-msn_dc_new(MsnSlpCall *slpcall)
-{
- MsnDirectConn *dc;
-
- g_return_val_if_fail(slpcall != NULL, NULL);
-
- dc = g_new0(MsnDirectConn, 1);
-
- if (purple_debug_is_verbose())
- purple_debug_info("msn", "msn_dc_new %p\n", dc);
-
- dc->slplink = slpcall->slplink;
- dc->slpcall = slpcall;
-
- if (dc->slplink->dc != NULL)
- purple_debug_warning("msn", "msn_dc_new: slplink already has an allocated DC!\n");
-
- dc->slplink->dc = dc;
-
- dc->msg_body = NULL;
- dc->prev_ack = NULL;
- dc->listen_data = NULL;
- dc->connect_data = NULL;
- dc->listenfd = -1;
- dc->listenfd_handle = 0;
- dc->connect_timeout_handle = 0;
- dc->fd = -1;
- dc->recv_handle = 0;
- dc->send_handle = 0;
- dc->state = DC_STATE_CLOSED;
- dc->in_buffer = NULL;
- dc->out_queue = g_queue_new();
- dc->msg_pos = -1;
- dc->send_connection_info_msg_cb = NULL;
- dc->ext_ip = NULL;
- dc->timeout_handle = 0;
- dc->progress = FALSE;
- /*dc->num_calls = 1;*/
-
- /* TODO: Probably should set this based on buddy caps */
- dc->nonce_type = DC_NONCE_PLAIN;
- msn_dc_generate_nonce(dc);
-
- return dc;
-}
-
-void
-msn_dc_destroy(MsnDirectConn *dc)
-{
- MsnSlpLink *slplink;
-
- if (purple_debug_is_verbose())
- purple_debug_info("msn", "msn_dc_destroy %p\n", dc);
-
- g_return_if_fail(dc != NULL);
-
- if (dc->slpcall != NULL)
- dc->slpcall->wait_for_socket = FALSE;
-
- slplink = dc->slplink;
- if (slplink) {
- slplink->dc = NULL;
- if (slplink->swboard == NULL)
- msn_slplink_unref(slplink);
- }
-
- g_free(dc->msg_body);
-
- if (dc->prev_ack) {
- msn_slpmsg_destroy(dc->prev_ack);
- }
-
- if (dc->listen_data != NULL) {
- purple_network_listen_cancel(dc->listen_data);
- }
-
- if (dc->connect_data != NULL) {
- purple_proxy_connect_cancel(dc->connect_data);
- }
-
- if (dc->listenfd != -1) {
- purple_network_remove_port_mapping(dc->listenfd);
- close(dc->listenfd);
- }
-
- if (dc->listenfd_handle != 0) {
- purple_input_remove(dc->listenfd_handle);
- }
-
- if (dc->connect_timeout_handle != 0) {
- purple_timeout_remove(dc->connect_timeout_handle);
- }
-
- if (dc->fd != -1) {
- close(dc->fd);
- }
-
- if (dc->send_handle != 0) {
- purple_input_remove(dc->send_handle);
- }
-
- if (dc->recv_handle != 0) {
- purple_input_remove(dc->recv_handle);
- }
-
- g_free(dc->in_buffer);
-
- if (dc->out_queue != NULL) {
- while (!g_queue_is_empty(dc->out_queue))
- msn_dc_destroy_packet( g_queue_pop_head(dc->out_queue) );
-
- g_queue_free(dc->out_queue);
- }
-
- g_free(dc->ext_ip);
-
- if (dc->timeout_handle != 0) {
- purple_timeout_remove(dc->timeout_handle);
- }
-
- g_free(dc);
-}
-
-/*
-void
-msn_dc_ref(MsnDirectConn *dc)
-{
- g_return_if_fail(dc != NULL);
-
- dc->num_calls++;
-}
-
-void
-msn_dc_unref(MsnDirectConn *dc)
-{
- g_return_if_fail(dc != NULL);
-
-
- if (dc->num_calls > 0) {
- dc->num_calls--;
- }
-}
-*/
-
-void
-msn_dc_send_invite(MsnDirectConn *dc)
-{
- MsnSlpCall *slpcall;
- MsnSlpMessage *msg;
- gchar *header;
-
- if (purple_debug_is_verbose())
- purple_debug_info("msn", "msn_dc_send_invite %p\n", dc);
-
- g_return_if_fail(dc != NULL);
-
- slpcall = dc->slpcall;
- g_return_if_fail(slpcall != NULL);
-
- header = g_strdup_printf(
- "INVITE MSNMSGR:%s MSNSLP/1.0",
- slpcall->slplink->remote_user
- );
-
- msg = msn_slpmsg_sip_new(
- slpcall,
- 0,
- header,
- slpcall->branch,
- "application/x-msnmsgr-transrespbody",
- dc->msg_body
- );
- msg->info = "DC INVITE";
- msg->text_body = TRUE;
- g_free(header);
- g_free(dc->msg_body);
- dc->msg_body = NULL;
-
- msn_slplink_queue_slpmsg(slpcall->slplink, msg);
-}
-
-void
-msn_dc_send_ok(MsnDirectConn *dc)
-{
- if (purple_debug_is_verbose())
- purple_debug_info("msn", "msn_dc_send_ok %p\n", dc);
-
- g_return_if_fail(dc != NULL);
-
- msn_slp_send_ok(dc->slpcall, dc->slpcall->branch,
- "application/x-msnmsgr-transrespbody", dc->msg_body);
- g_free(dc->msg_body);
- dc->msg_body = NULL;
-
- msn_slplink_send_slpmsg(dc->slpcall->slplink, dc->prev_ack);
- msn_slpmsg_destroy(dc->prev_ack);
- dc->prev_ack = NULL;
- msn_slplink_send_queued_slpmsgs(dc->slpcall->slplink);
-}
-
-void
-msn_dc_fallback_to_sb(MsnDirectConn *dc)
-{
- MsnSlpLink *slplink;
- MsnSlpCall *slpcall;
- GQueue *queue = NULL;
-
- purple_debug_info("msn", "msn_dc_fallback_to_sb %p\n", dc);
-
- g_return_if_fail(dc != NULL);
-
- slpcall = dc->slpcall;
- slplink = msn_slplink_ref(dc->slplink);
- if (slpcall && !g_queue_is_empty(dc->out_queue)) {
- queue = dc->out_queue;
- dc->out_queue = NULL;
- }
-
- msn_dc_destroy(dc);
-
- if (slpcall) {
- msn_slpcall_session_init(slpcall);
- if (queue) {
- while (!g_queue_is_empty(queue)) {
- MsnDirectConnPacket *p = g_queue_pop_head(queue);
- msn_slplink_send_msgpart(slplink, (MsnSlpMessage*)p->part->ack_data);
- msn_dc_destroy_packet(p);
- }
- g_queue_free(queue);
- }
- }
- msn_slplink_unref(slplink);
-}
-
-static void
-msn_dc_send_cb(gpointer data, gint fd, PurpleInputCondition cond)
-{
- MsnDirectConn *dc = data;
- MsnDirectConnPacket *p;
- int bytes_to_send;
- int bytes_sent;
-
- g_return_if_fail(dc != NULL);
- g_return_if_fail(fd != -1);
-
- if (g_queue_is_empty(dc->out_queue)) {
- if (dc->send_handle != 0) {
- purple_input_remove(dc->send_handle);
- dc->send_handle = 0;
- }
- return;
- }
-
- p = g_queue_peek_head(dc->out_queue);
-
- if (dc->msg_pos < 0) {
- /* First we send the length of the packet */
- guint32 len = GUINT32_TO_LE(p->length);
- bytes_sent = send(fd, &len, 4, 0);
- if (bytes_sent < 0) {
- if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
- return;
-
- purple_debug_warning("msn", "msn_dc_send_cb: send error\n");
- msn_dc_destroy(dc);
- return;
- }
- dc->msg_pos = 0;
- }
-
- bytes_to_send = p->length - dc->msg_pos;
- bytes_sent = send(fd, p->data + dc->msg_pos, bytes_to_send, 0);
- if (bytes_sent < 0) {
- if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
- return;
-
- purple_debug_warning("msn", "msn_dc_send_cb: send error\n");
- msn_dc_destroy(dc);
- return;
- }
-
- dc->progress = TRUE;
-
- dc->msg_pos += bytes_sent;
- if ((guint32)dc->msg_pos == p->length) {
- if (p->sent_cb != NULL)
- p->sent_cb(p);
-
- g_queue_pop_head(dc->out_queue);
- msn_dc_destroy_packet(p);
-
- dc->msg_pos = -1;
- }
-}
-
-static void
-msn_dc_enqueue_packet(MsnDirectConn *dc, MsnDirectConnPacket *p)
-{
- gboolean was_empty;
-
- was_empty = g_queue_is_empty(dc->out_queue);
- g_queue_push_tail(dc->out_queue, p);
-
- if (was_empty && dc->send_handle == 0) {
- dc->send_handle = purple_input_add(dc->fd, PURPLE_INPUT_WRITE, msn_dc_send_cb, dc);
- msn_dc_send_cb(dc, dc->fd, PURPLE_INPUT_WRITE);
- }
-}
-
-static void
-msn_dc_send_foo(MsnDirectConn *dc)
-{
- MsnDirectConnPacket *p;
-
- if (purple_debug_is_verbose())
- purple_debug_info("msn", "msn_dc_send_foo %p\n", dc);
-
- p = msn_dc_new_packet(4);
-
- memcpy(p->data, "foo\0", 4);
-
- msn_dc_enqueue_packet(dc, p);
-}
-
-#if 0 /* We don't actually need this */
-typedef struct {
- guint32 null;
- guint32 id;
- guint32 null[5];
- guint32 flags;
- guint8 nonce[16];
-} MsnDirectConnNoncePacket;
-#endif
-#define DC_NONCE_PACKET_SIZE (8 * 4 + 16)
-#define DC_NONCE_PACKET_NONCE (8 * 4)
-
-static void
-msn_dc_send_handshake(MsnDirectConn *dc)
-{
- MsnDirectConnPacket *p;
- gchar *h;
-
- p = msn_dc_new_packet(DC_NONCE_PACKET_SIZE);
- h = (gchar *)p->data;
-
- msn_push32le(h, 0); /* NUL */
-
- msn_push32le(h, dc->slpcall->slplink->slp_seq_id++);
-
- /* More NUL stuff */
- msn_push64le(h, 0);
- msn_push64le(h, 0);
- msn_push32le(h, 0);
-
- /* Flags */
- msn_push32le(h, P2P_DC_HANDSHAKE);
-
- /* The real Nonce, yay! */
- memcpy(h, dc->nonce, 16);
-
- msn_dc_enqueue_packet(dc, p);
-}
-
-static gboolean
-msn_dc_verify_handshake(MsnDirectConn *dc, guint32 packet_length)
-{
- guchar nonce[16];
- gchar nonce_hash[37];
-
- if (packet_length != DC_NONCE_PACKET_SIZE)
- return FALSE;
-
- memcpy(nonce, dc->in_buffer + 4 + DC_NONCE_PACKET_NONCE, sizeof(nonce));
-
- if (dc->nonce_type == DC_NONCE_PLAIN) {
- if (memcmp(dc->nonce, nonce, sizeof(nonce)) == 0) {
- purple_debug_info("msn",
- "Nonce from buddy request and nonce from DC attempt match, "
- "allowing direct connection\n");
- return TRUE;
- } else {
- purple_debug_warning("msn",
- "Nonce from buddy request and nonce from DC attempt "
- "don't match, ignoring direct connection\n");
- return FALSE;
- }
-
- } else if (dc->nonce_type == DC_NONCE_SHA1) {
- msn_dc_calculate_nonce_hash(dc->nonce_type, nonce, sizeof(nonce), nonce_hash);
-
- if (g_str_equal(dc->remote_nonce, nonce_hash)) {
- purple_debug_info("msn",
- "Received nonce %s from buddy request "
- "and calculated nonce %s from DC attempt. "
- "Nonces match, allowing direct connection\n",
- dc->remote_nonce, nonce_hash);
- return TRUE;
- } else {
- purple_debug_warning("msn",
- "Received nonce %s from buddy request "
- "and calculated nonce %s from DC attempt. "
- "Nonces don't match, ignoring direct connection\n",
- dc->remote_nonce, nonce_hash);
- return FALSE;
- }
- } else
- return FALSE;
-}
-
-static void
-msn_dc_send_packet_cb(MsnDirectConnPacket *p)
-{
- if (p->part != NULL && p->part->ack_cb != NULL)
- p->part->ack_cb(p->part, p->part->ack_data);
-}
-
-void
-msn_dc_enqueue_part(MsnDirectConn *dc, MsnSlpMessagePart *part)
-{
- MsnDirectConnPacket *p;
- size_t length;
-
- p = msn_dc_new_packet(0);
- p->data = (guchar *)msn_slpmsgpart_serialize(part, &length);
- p->length = length - P2P_PACKET_FOOTER_SIZE; /* DC doesn't need footer? */
-
- p->sent_cb = msn_dc_send_packet_cb;
- p->part = msn_slpmsgpart_ref(part);
-
- msn_dc_enqueue_packet(dc, p);
-}
-
-static int
-msn_dc_process_packet(MsnDirectConn *dc, guint32 packet_length)
-{
- MsnSlpMessagePart *part;
-
- g_return_val_if_fail(dc != NULL, DC_PROCESS_ERROR);
-
- switch (dc->state) {
- case DC_STATE_CLOSED:
- break;
-
- case DC_STATE_FOO:
- /* FOO message is always 4 bytes long */
- if (packet_length != 4 || memcmp(dc->in_buffer, "\4\0\0\0foo", 8) != 0)
- return DC_PROCESS_FALLBACK;
-
- dc->state = DC_STATE_HANDSHAKE;
- break;
-
- case DC_STATE_HANDSHAKE:
- if (!msn_dc_verify_handshake(dc, packet_length))
- return DC_PROCESS_FALLBACK;
-
- msn_dc_send_handshake(dc);
- dc->state = DC_STATE_ESTABLISHED;
-
- msn_slpcall_session_init(dc->slpcall);
- dc->slpcall = NULL;
- break;
-
- case DC_STATE_HANDSHAKE_REPLY:
- if (!msn_dc_verify_handshake(dc, packet_length))
- return DC_PROCESS_FALLBACK;
-
- dc->state = DC_STATE_ESTABLISHED;
-
- msn_slpcall_session_init(dc->slpcall);
- dc->slpcall = NULL;
- break;
-
- case DC_STATE_ESTABLISHED:
- if (packet_length) {
- MsnP2PVersion p2p;
- p2p = msn_slplink_get_p2p_version(dc->slplink);
- part = msn_slpmsgpart_new_from_data(p2p, dc->in_buffer + 4, packet_length);
- if (part) {
- msn_slplink_process_msg(dc->slplink, part);
- msn_slpmsgpart_unref(part);
- }
- }
-
- /*
- if (dc->num_calls == 0) {
- msn_dc_destroy(dc);
-
- return DC_PROCESS_CLOSE;
- }
- */
- break;
- }
-
- return DC_PROCESS_OK;
-}
-
-static void
-msn_dc_recv_cb(gpointer data, gint fd, PurpleInputCondition cond)
-{
- MsnDirectConn *dc;
- int free_buf_space;
- int bytes_received;
- guint32 packet_length;
-
- g_return_if_fail(data != NULL);
- g_return_if_fail(fd != -1);
-
- dc = data;
- free_buf_space = dc->in_size - dc->in_pos;
-
- bytes_received = recv(fd, dc->in_buffer + dc->in_pos, free_buf_space, 0);
- if (bytes_received < 0) {
- if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
- return;
-
- purple_debug_warning("msn", "msn_dc_recv_cb: recv error\n");
-
- if(dc->state != DC_STATE_ESTABLISHED)
- msn_dc_fallback_to_sb(dc);
- else
- msn_dc_destroy(dc);
- return;
-
- } else if (bytes_received == 0) {
- /* EOF. Remote side closed connection. */
- purple_debug_info("msn", "msn_dc_recv_cb: recv EOF\n");
-
- if(dc->state != DC_STATE_ESTABLISHED)
- msn_dc_fallback_to_sb(dc);
- else
- msn_dc_destroy(dc);
- return;
- }
-
- dc->progress = TRUE;
-
- dc->in_pos += bytes_received;
-
- /* Wait for packet length */
- while (dc->in_pos >= 4) {
- packet_length = GUINT32_FROM_LE(*((guint32*)dc->in_buffer));
-
- if (packet_length > DC_MAX_PACKET_SIZE) {
- /* Oversized packet */
- purple_debug_warning("msn", "msn_dc_recv_cb: oversized packet received\n");
- return;
- }
-
- /* Wait for the whole packet to arrive */
- if ((guint32)dc->in_pos < 4 + packet_length)
- return;
-
- switch (msn_dc_process_packet(dc, packet_length)) {
- case DC_PROCESS_CLOSE:
- return;
-
- case DC_PROCESS_FALLBACK:
- purple_debug_warning("msn", "msn_dc_recv_cb: packet processing error, fall back to SB\n");
- msn_dc_fallback_to_sb(dc);
- return;
-
- }
-
- if ((guint32)dc->in_pos > packet_length + 4) {
- g_memmove(dc->in_buffer, dc->in_buffer + 4 + packet_length, dc->in_pos - packet_length - 4);
- }
-
- dc->in_pos -= packet_length + 4;
- }
-}
-
-static gboolean
-msn_dc_timeout(gpointer data)
-{
- MsnDirectConn *dc = data;
-
- g_return_val_if_fail(dc != NULL, FALSE);
-
- if (dc->progress) {
- dc->progress = FALSE;
- return TRUE;
- } else {
- dc->timeout_handle = 0;
- msn_dc_destroy(dc);
- return FALSE;
- }
-}
-
-static void
-msn_dc_init(MsnDirectConn *dc)
-{
- g_return_if_fail(dc != NULL);
-
- dc->in_size = DC_MAX_PACKET_SIZE + 4;
- dc->in_pos = 0;
- dc->in_buffer = g_malloc(dc->in_size);
-
- dc->recv_handle = purple_input_add(dc->fd, PURPLE_INPUT_READ, msn_dc_recv_cb, dc);
- dc->send_handle = purple_input_add(dc->fd, PURPLE_INPUT_WRITE, msn_dc_send_cb, dc);
-
- dc->timeout_handle = purple_timeout_add_seconds(DC_TIMEOUT, msn_dc_timeout, dc);
-}
-
-void
-msn_dc_connected_to_peer_cb(gpointer data, gint fd, const gchar *error_msg)
-{
- MsnDirectConn *dc = data;
-
- if (purple_debug_is_verbose())
- purple_debug_info("msn", "msn_dc_connected_to_peer_cb %p\n", dc);
-
- g_return_if_fail(dc != NULL);
-
- dc->connect_data = NULL;
- purple_timeout_remove(dc->connect_timeout_handle);
- dc->connect_timeout_handle = 0;
-
- dc->fd = fd;
- if (dc->fd != -1) {
- msn_dc_init(dc);
- msn_dc_send_foo(dc);
- msn_dc_send_handshake(dc);
- dc->state = DC_STATE_HANDSHAKE_REPLY;
- }
-}
-
-/*
- * This callback will be called when we're the server
- * and nobody has connected us in DC_INCOMING_TIMEOUT seconds
- */
-static gboolean
-msn_dc_incoming_connection_timeout_cb(gpointer data) {
- MsnDirectConn *dc = data;
-
- if (purple_debug_is_verbose())
- purple_debug_info("msn", "msn_dc_incoming_connection_timeout_cb %p\n", dc);
-
- g_return_val_if_fail(dc != NULL, FALSE);
-
- if (dc->listen_data != NULL) {
- purple_network_listen_cancel(dc->listen_data);
- dc->listen_data = NULL;
- }
-
- if (dc->listenfd_handle != 0) {
- purple_input_remove(dc->listenfd_handle);
- dc->listenfd_handle = 0;
- }
-
- if (dc->listenfd != -1) {
- purple_network_remove_port_mapping(dc->listenfd);
- close(dc->listenfd);
- dc->listenfd = -1;
- }
-
- dc->connect_timeout_handle = 0;
- msn_dc_fallback_to_sb(dc);
-
- return FALSE;
-}
-
-/*
- * This callback will be called when we're unable to connect to
- * the remote host in DC_OUTGOING_TIMEOUT seconds.
- */
-gboolean
-msn_dc_outgoing_connection_timeout_cb(gpointer data)
-{
- MsnDirectConn *dc = data;
-
- purple_debug_info("msn", "msn_dc_outgoing_connection_timeout_cb %p\n", dc);
-
- g_return_val_if_fail(dc != NULL, FALSE);
-
- dc->connect_timeout_handle = 0;
-
- if (dc->connect_data != NULL) {
- purple_proxy_connect_cancel(dc->connect_data);
- dc->connect_data = NULL;
- }
-
- if (dc->ext_ip && dc->ext_port) {
- /* Try external IP/port if available. */
- dc->connect_data = purple_proxy_connect(
- NULL,
- dc->slpcall->slplink->session->account,
- dc->ext_ip,
- dc->ext_port,
- msn_dc_connected_to_peer_cb,
- dc
- );
-
- g_free(dc->ext_ip);
- dc->ext_ip = NULL;
-
- if (dc->connect_data) {
- dc->connect_timeout_handle = purple_timeout_add_seconds(
- DC_OUTGOING_TIMEOUT,
- msn_dc_outgoing_connection_timeout_cb,
- dc
- );
- } else {
- /*
- * Connection failed
- * Fall back to SB transfer
- */
- msn_dc_outgoing_connection_timeout_cb(dc);
- }
-
- } else {
- /*
- * Both internal and external connection attempts failed.
- * Fall back to SB transfer.
- */
- msn_dc_fallback_to_sb(dc);
- }
-
- return FALSE;
-}
-
-/*
- * This callback will be called when we're the server
- * and somebody has connected to us in DC_INCOMING_TIMEOUT seconds.
- */
-static void
-msn_dc_incoming_connection_cb(gpointer data, gint listenfd, PurpleInputCondition cond)
-{
- MsnDirectConn *dc = data;
-
- if (purple_debug_is_verbose())
- purple_debug_info("msn", "msn_dc_incoming_connection_cb %p\n", dc);
-
- g_return_if_fail(dc != NULL);
-
- if (dc->connect_timeout_handle != 0) {
- purple_timeout_remove(dc->connect_timeout_handle);
- dc->connect_timeout_handle = 0;
- }
-
- if (dc->listenfd_handle != 0) {
- purple_input_remove(dc->listenfd_handle);
- dc->listenfd_handle = 0;
- }
-
- dc->fd = accept(listenfd, NULL, 0);
-
- purple_network_remove_port_mapping(dc->listenfd);
- close(dc->listenfd);
- dc->listenfd = -1;
-
- if (dc->fd != -1) {
- msn_dc_init(dc);
- dc->state = DC_STATE_FOO;
- }
-}
-
-void
-msn_dc_listen_socket_created_cb(int listenfd, gpointer data)
-{
- MsnDirectConn *dc = data;
-
- if (purple_debug_is_verbose())
- purple_debug_info("msn", "msn_dc_listen_socket_created_cb %p\n", dc);
-
- g_return_if_fail(dc != NULL);
-
- dc->listen_data = NULL;
-
- if (listenfd != -1) {
- const char *ext_ip;
- const char *int_ip;
- int port;
-
- ext_ip = purple_network_get_my_ip(listenfd);
- int_ip = purple_network_get_local_system_ip(listenfd);
- port = purple_network_get_port_from_fd(listenfd);
-
- dc->listenfd = listenfd;
- dc->listenfd_handle = purple_input_add(
- listenfd,
- PURPLE_INPUT_READ,
- msn_dc_incoming_connection_cb,
- dc
- );
- dc->connect_timeout_handle = purple_timeout_add_seconds(
- DC_INCOMING_TIMEOUT,
- msn_dc_incoming_connection_timeout_cb,
- dc
- );
-
- if (strcmp(int_ip, ext_ip) != 0) {
- dc->msg_body = g_strdup_printf(
- "Bridge: TCPv1\r\n"
- "Listening: true\r\n"
- "%sNonce: {%s}\r\n"
- "IPv4External-Addrs: %s\r\n"
- "IPv4External-Port: %d\r\n"
- "IPv4Internal-Addrs: %s\r\n"
- "IPv4Internal-Port: %d\r\n"
- "\r\n",
-
- dc->nonce_type != DC_NONCE_PLAIN ? "Hashed-" : "",
- dc->nonce_hash,
- ext_ip,
- port,
- int_ip,
- port
- );
-
- } else {
- dc->msg_body = g_strdup_printf(
- "Bridge: TCPv1\r\n"
- "Listening: true\r\n"
- "%sNonce: {%s}\r\n"
- "IPv4External-Addrs: %s\r\n"
- "IPv4External-Port: %d\r\n"
- "\r\n",
-
- dc->nonce_type != DC_NONCE_PLAIN ? "Hashed-" : "",
- dc->nonce_hash,
- ext_ip,
- port
- );
- }
-
- if (dc->slpcall->wait_for_socket) {
- if (dc->send_connection_info_msg_cb != NULL)
- dc->send_connection_info_msg_cb(dc);
-
- dc->slpcall->wait_for_socket = FALSE;
- }
- }
-}
-
diff --git a/libpurple/protocols/msn/directconn.h b/libpurple/protocols/msn/directconn.h
deleted file mode 100644
index 41a05d274e..0000000000
--- a/libpurple/protocols/msn/directconn.h
+++ /dev/null
@@ -1,200 +0,0 @@
-/**
- * @file directconn.h MSN direct connection functions
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-#ifndef MSN_DIRECTCONN_H
-#define MSN_DIRECTCONN_H
-
-typedef struct _MsnDirectConn MsnDirectConn;
-
-#include "network.h"
-#include "proxy.h"
-#include "circbuffer.h"
-
-#include "slp.h"
-#include "slplink.h"
-#include "slpmsg.h"
-#include "slpmsg_part.h"
-#include "p2p.h"
-
-#define MSN_DCCONN_MAX_SIZE 1352
-
-typedef enum
-{
- DC_STATE_CLOSED, /*< No socket opened yet */
- DC_STATE_FOO, /*< Waiting for FOO message */
- DC_STATE_HANDSHAKE, /*< Waiting for handshake message */
- DC_STATE_HANDSHAKE_REPLY, /*< Waiting for handshake reply message */
- DC_STATE_ESTABLISHED /*< Handshake complete */
-} MsnDirectConnState;
-
-typedef enum
-{
- DC_PROCESS_OK = 0,
- DC_PROCESS_ERROR,
- DC_PROCESS_FALLBACK,
- DC_PROCESS_CLOSE
-
-} MsnDirectConnProcessResult;
-
-typedef enum
-{
- DC_NONCE_UNKNOWN, /**< Invalid scheme */
- DC_NONCE_PLAIN, /**< No hashing */
- DC_NONCE_SHA1 /**< First 16 bytes of SHA1 of nonce */
-
-} MsnDirectConnNonceType;
-
-typedef struct _MsnDirectConnPacket MsnDirectConnPacket;
-
-struct _MsnDirectConnPacket {
- guint32 length;
- guchar *data;
-
- void (*sent_cb)(struct _MsnDirectConnPacket*);
- MsnSlpMessagePart *part;
-};
-
-struct _MsnDirectConn
-{
- MsnDirectConnState state; /**< Direct connection status */
- MsnSlpLink *slplink; /**< The slplink using this direct connection */
- MsnSlpCall *slpcall; /**< The slpcall which initiated the direct connection */
- char *msg_body; /**< The body of message sent by send_connection_info_msg_cb */
- MsnSlpMessage *prev_ack; /**< The saved SLP ACK message */
-
- MsnDirectConnNonceType nonce_type; /**< The type of nonce hashing */
- guchar nonce[16]; /**< The nonce used for handshake */
- gchar nonce_hash[37]; /**< The hash of nonce */
- gchar remote_nonce[37]; /**< The remote side's nonce */
-
- PurpleNetworkListenData *listen_data; /**< The pending socket creation request */
- PurpleProxyConnectData *connect_data; /**< The pending connection attempt */
- int listenfd; /**< The socket we're listening for incoming connections */
- guint listenfd_handle; /**< The timeout handle for incoming connection */
- guint connect_timeout_handle; /**< The timeout handle for outgoing connection */
-
- int fd; /**< The direct connection socket */
- guint recv_handle; /**< The incoming data callback handle */
- guint send_handle; /**< The outgoing data callback handle */
-
- gchar *in_buffer; /**< The receive buffer */
- int in_size; /**< The receive buffer size */
- int in_pos; /**< The first free position in receive buffer */
- GQueue *out_queue; /**< The outgoing packet queue */
- int msg_pos; /**< The position of next byte to be sent in the actual packet */
-
- /** The callback used for sending information to the peer about the opened socket */
- void (*send_connection_info_msg_cb)(MsnDirectConn *);
-
- gchar *ext_ip; /**< Our external IP address */
- int ext_port; /**< Our external port */
-
- guint timeout_handle;
- gboolean progress;
-
- /*int num_calls;*/ /**< The number of slpcalls using this direct connection */
-};
-
-/* Outgoing attempt */
-#define DC_OUTGOING_TIMEOUT (5)
-/* Time for internal + external connection attempts */
-#define DC_INCOMING_TIMEOUT (DC_OUTGOING_TIMEOUT * 3)
-/* Timeout for lack of activity */
-#define DC_TIMEOUT (60)
-
-/*
- * Queues an MSN message to be sent via direct connection.
- */
-void
-msn_dc_enqueue_part(MsnDirectConn *dc, MsnSlpMessagePart *part);
-
-/*
- * Creates, initializes, and returns a new MsnDirectConn structure.
- */
-MsnDirectConn *
-msn_dc_new(MsnSlpCall *slpcall);
-
-/*
- * Destroys an MsnDirectConn structure. Frees every buffer allocated earlier
- * restores saved callbacks, etc.
- */
-void
-msn_dc_destroy(MsnDirectConn *dc);
-
-/*
- * Fallback to switchboard connection. Used when neither side is able to
- * create a listening socket.
- */
-void
-msn_dc_fallback_to_sb(MsnDirectConn *dc);
-
-/*
- * Increases the slpcall counter in DC. The direct connection remains open
- * until all slpcalls using it are destroyed.
- */
-void
-msn_dc_ref(MsnDirectConn *dc);
-
-/*
- * Decrease the slpcall counter in DC. The direct connection remains open
- * until all slpcalls using it are destroyed.
- */
-void
-msn_dc_unref(MsnDirectConn *dc);
-
-/*
- * Sends a direct connect INVITE message on the associated slplink
- * with the corresponding connection type and information.
- */
-void
-msn_dc_send_invite(MsnDirectConn *dc);
-
-/*
- * Sends a direct connect OK message as a response to an INVITE received earliaer
- * on the corresponding slplink.
- */
-void
-msn_dc_send_ok(MsnDirectConn *dc);
-
-/*
- * This callback will be called when we're successfully connected to
- * the remote host.
- */
-void
-msn_dc_connected_to_peer_cb(gpointer data, gint fd, const gchar *error_msg);
-
-/*
- * This callback will be called when we're unable to connect to
- * the remote host in DC_CONNECT_TIMEOUT seconds.
- */
-gboolean
-msn_dc_outgoing_connection_timeout_cb(gpointer data);
-
-/*
- * This callback will be called when the listening socket is successfully
- * created and its parameters (IP/port) are available.
- */
-void
-msn_dc_listen_socket_created_cb(int listenfd, gpointer data);
-
-#endif /* MSN_DIRECTCONN_H */
diff --git a/libpurple/protocols/msn/error.c b/libpurple/protocols/msn/error.c
deleted file mode 100644
index 68690ef384..0000000000
--- a/libpurple/protocols/msn/error.c
+++ /dev/null
@@ -1,384 +0,0 @@
-/**
- * @file error.c Error functions
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-
-#include "internal.h"
-#include "debug.h"
-/* Masca: can we get rid of the sync issue dialog? */
-#include "request.h"
-
-#include "error.h"
-
-typedef struct
-{
- MsnSession *session;
- char *who;
- char *group;
- gboolean add;
-
-} MsnAddRemData;
-
-const char *
-msn_error_get_text(unsigned int type, gboolean *debug)
-{
- static char msg[256];
- const char *result;
- *debug = FALSE;
-
- switch (type) {
- case 0:
- result = _("Unable to parse message");
- *debug = TRUE;
- break;
- case 200:
- result = _("Syntax Error (probably a client bug)");
- *debug = TRUE;
- break;
- case 201:
- result = _("Invalid email address");
- break;
- case 205:
- result = _("User does not exist");
- break;
- case 206:
- result = _("Fully qualified domain name missing");
- break;
- case 207:
- result = _("Already logged in");
- break;
- case 208:
- result = _("Invalid username");
- break;
- case 209:
- result = _("Invalid friendly name");
- break;
- case 210:
- result = _("List full");
- break;
- case 215:
- result = _("Already there");
- *debug = TRUE;
- break;
- case 216:
- result = _("Not on list");
- break;
- case 217:
- result = _("User is offline");
- break;
- case 218:
- result = _("Already in the mode");
- *debug = TRUE;
- break;
- case 219:
- result = _("Already in opposite list");
- *debug = TRUE;
- break;
- case 223:
- result = _("Too many groups");
- break;
- case 224:
- result = _("Invalid group");
- break;
- case 225:
- result = _("User not in group");
- break;
- case 229:
- result = _("Group name too long");
- break;
- case 230:
- result = _("Cannot remove group zero");
- *debug = TRUE;
- break;
- case 231:
- result = _("Tried to add a user to a group that doesn't exist");
- break;
- case 280:
- result = _("Switchboard failed");
- *debug = TRUE;
- break;
- case 281:
- result = _("Notify transfer failed");
- *debug = TRUE;
- break;
-
- case 300:
- result = _("Required fields missing");
- *debug = TRUE;
- break;
- case 301:
- result = _("Too many hits to a FND");
- *debug = TRUE;
- break;
- case 302:
- result = _("Not logged in");
- break;
-
- case 500:
- result = _("Service temporarily unavailable");
- break;
- case 501:
- result = _("Database server error");
- *debug = TRUE;
- break;
- case 502:
- result = _("Command disabled");
- *debug = TRUE;
- break;
- case 510:
- result = _("File operation error");
- *debug = TRUE;
- break;
- case 520:
- result = _("Memory allocation error");
- *debug = TRUE;
- break;
- case 540:
- result = _("Wrong CHL value sent to server");
- *debug = TRUE;
- break;
-
- case 600:
- result = _("Server busy");
- break;
- case 601:
- result = _("Server unavailable");
- break;
- case 602:
- result = _("Peer notification server down");
- *debug = TRUE;
- break;
- case 603:
- result = _("Database connect error");
- *debug = TRUE;
- break;
- case 604:
- result = _("Server is going down (abandon ship)");
- break;
- case 605:
- result = _("Server unavailable");
- break;
-
- case 707:
- result = _("Error creating connection");
- *debug = TRUE;
- break;
- case 710:
- result = _("CVR parameters are either unknown or not allowed");
- *debug = TRUE;
- break;
- case 711:
- result = _("Unable to write");
- break;
- case 712:
- result = _("Session overload");
- *debug = TRUE;
- break;
- case 713:
- result = _("User is too active");
- break;
- case 714:
- result = _("Too many sessions");
- break;
- case 715:
- result = _("Passport not verified");
- break;
- case 717:
- result = _("Bad friend file");
- *debug = TRUE;
- break;
- case 731:
- result = _("Not expected");
- *debug = TRUE;
- break;
-
- case 800:
- result = _("Friendly name is changing too rapidly");
- break;
-
- case 910:
- case 912:
- case 918:
- case 919:
- case 921:
- case 922:
- result = _("Server too busy");
- break;
- case 911:
- case 917:
- result = _("Authentication failed");
- break;
- case 913:
- result = _("Not allowed when offline");
- break;
- case 914:
- case 915:
- case 916:
- result = _("Server unavailable");
- break;
- case 920:
- result = _("Not accepting new users");
- break;
- case 923:
- result = _("Kids Passport without parental consent");
- break;
- case 924:
- result = _("Passport account not yet verified");
- break;
- case 927:
- result = _("Passport account suspended");
- break;
- case 928:
- result = _("Bad ticket");
- *debug = TRUE;
- break;
-
- default:
- g_snprintf(msg, sizeof(msg),
- _("Unknown Error Code %d"), type);
- *debug = TRUE;
- result = msg;
- break;
- }
-
- return result;
-}
-
-void
-msn_error_handle(MsnSession *session, unsigned int type)
-{
- char *buf;
- gboolean debug;
-
- buf = g_strdup_printf(_("MSN Error: %s\n"),
- msn_error_get_text(type, &debug));
- if (debug)
- purple_debug_warning("msn", "error %d: %s\n", type, buf);
- else
- purple_notify_error(session->account->gc, NULL, buf, NULL);
- g_free(buf);
-}
-
-/* Remove the buddy referenced by the MsnAddRemData before the serverside list
- * is changed. If the buddy will be added, he'll be added back; if he will be
- * removed, he won't be. */
-/* Actually with our MSNP14 code that isn't true yet, he won't be added back :(
- * */
-static void
-msn_complete_sync_issue(MsnAddRemData *data)
-{
- PurpleBuddy *buddy;
- PurpleGroup *group = NULL;
-
- if (data->group != NULL)
- group = purple_find_group(data->group);
-
- if (group != NULL)
- buddy = purple_find_buddy_in_group(data->session->account, data->who, group);
- else
- buddy = purple_find_buddy(data->session->account, data->who);
-
- if (buddy != NULL)
- purple_blist_remove_buddy(buddy);
-}
-
-
-static void
-msn_add_cb(MsnAddRemData *data)
-{
-#if 0
- /* this *should* be necessary !! */
- msn_complete_sync_issue(data);
-#endif
- MsnUserList *userlist = data->session->userlist;
-
- msn_userlist_add_buddy(userlist, data->who, data->group);
-
- g_free(data->group);
- g_free(data->who);
- g_free(data);
-}
-
-static void
-msn_rem_cb(MsnAddRemData *data)
-{
- MsnUserList *userlist = data->session->userlist;
- msn_complete_sync_issue(data);
-
-
- if (data->group == NULL) {
- msn_userlist_rem_buddy_from_list(userlist, data->who, MSN_LIST_FL);
- } else {
- g_free(data->group);
- }
-
- g_free(data->who);
- g_free(data);
-}
-
-void
-msn_error_sync_issue(MsnSession *session, const char *passport,
- const char *group_name)
-{
- PurpleConnection *gc;
- PurpleAccount *account;
- MsnAddRemData *data;
- char *msg, *reason;
-
- account = session->account;
- gc = purple_account_get_connection(account);
-
- data = g_new0(MsnAddRemData, 1);
- data->who = g_strdup(passport);
- data->group = g_strdup(group_name);
- data->session = session;
-
- msg = g_strdup_printf(_("Buddy list synchronization issue in %s (%s)"),
- purple_account_get_username(account),
- purple_account_get_protocol_name(account));
-
- if (group_name != NULL)
- {
- reason = g_strdup_printf(_("%s on the local list is "
- "inside the group \"%s\" but not on "
- "the server list. "
- "Do you want this buddy to be added?"),
- passport, group_name);
- }
- else
- {
- reason = g_strdup_printf(_("%s is on the local list but "
- "not on the server list. "
- "Do you want this buddy to be added?"),
- passport);
- }
-
- purple_request_action(gc, NULL, msg, reason, PURPLE_DEFAULT_ACTION_NONE,
- account, data->who, NULL,
- data, 2,
- _("Yes"), G_CALLBACK(msn_add_cb),
- _("No"), G_CALLBACK(msn_rem_cb));
-
- g_free(reason);
- g_free(msg);
-}
-
diff --git a/libpurple/protocols/msn/error.h b/libpurple/protocols/msn/error.h
deleted file mode 100644
index 5194eaaac3..0000000000
--- a/libpurple/protocols/msn/error.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- * @file error.h Error functions
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-#ifndef MSN_ERROR_H
-#define MSN_ERROR_H
-
-#include "session.h"
-
-/**
- * Returns the string representation of an error type.
- *
- * @param type The error type.
- * @param debug Whether this should be treated as a debug log message or a user-visible error
- *
- * @return The string representation of the error type.
- */
-const char *msn_error_get_text(unsigned int type, gboolean *debug);
-
-/**
- * Handles an error.
- *
- * @param session The current session.
- * @param type The error type.
- */
-void msn_error_handle(MsnSession *session, unsigned int type);
-
-/**
- * Show the sync issue in a dialog using request api
- *
- * @param sesion MsnSession associated to this error.
- * @param passport The passport associated with the error.
- * @param group_name The group in the buddy is suppoused to be
- */
-void msn_error_sync_issue(MsnSession *session, const char *passport,
- const char *group_name);
-
-#endif /* MSN_ERROR_H */
diff --git a/libpurple/protocols/msn/group.c b/libpurple/protocols/msn/group.c
deleted file mode 100644
index ddb1541919..0000000000
--- a/libpurple/protocols/msn/group.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/**
- * @file group.c Group functions
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-#include "msn.h"
-#include "group.h"
-
-MsnGroup *
-msn_group_new(MsnUserList *userlist, const char *id, const char *name)
-{
- MsnGroup *group;
-
- g_return_val_if_fail(id != NULL, NULL);
- g_return_val_if_fail(name != NULL, NULL);
-
- group = g_new0(MsnGroup, 1);
-
- msn_userlist_add_group(userlist, group);
-
- group->id = g_strdup(id);
- group->name = g_strdup(name);
-
- return group;
-}
-
-void
-msn_group_destroy(MsnGroup *group)
-{
- g_return_if_fail(group != NULL);
-
- g_free(group->id);
- g_free(group->name);
- g_free(group);
-}
-
-void
-msn_group_set_id(MsnGroup *group, const char *id)
-{
- g_return_if_fail(group != NULL);
- g_return_if_fail(id != NULL);
-
- g_free(group->id);
- group->id = g_strdup(id);
-}
-
-void
-msn_group_set_name(MsnGroup *group, const char *name)
-{
- g_return_if_fail(group != NULL);
- g_return_if_fail(name != NULL);
-
- g_free(group->name);
- group->name = g_strdup(name);
-}
-
-char*
-msn_group_get_id(const MsnGroup *group)
-{
- g_return_val_if_fail(group != NULL, NULL);
-
- return group->id;
-}
-
-const char *
-msn_group_get_name(const MsnGroup *group)
-{
- g_return_val_if_fail(group != NULL, NULL);
-
- return group->name;
-}
diff --git a/libpurple/protocols/msn/group.h b/libpurple/protocols/msn/group.h
deleted file mode 100644
index 620d24124f..0000000000
--- a/libpurple/protocols/msn/group.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/**
- * @file group.h Group functions
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-#ifndef MSN_GROUP_H
-#define MSN_GROUP_H
-
-typedef struct _MsnGroup MsnGroup;
-
-#include "internal.h"
-
-#include "session.h"
-#include "user.h"
-#include "userlist.h"
-
-#define MSN_INDIVIDUALS_GROUP_ID "1983"
-#define MSN_INDIVIDUALS_GROUP_NAME _("Other Contacts")
-
-#define MSN_NON_IM_GROUP_ID "email"
-#define MSN_NON_IM_GROUP_NAME _("Non-IM Contacts")
-
-/**
- * A group.
- */
-struct _MsnGroup
-{
- MsnSession *session; /**< The MSN session. */
-
- char *id; /**< The group ID. */
- char *name; /**< The name of the group. */
-};
-
-/**************************************************************************
- ** @name Group API *
- **************************************************************************/
-/*@{*/
-
-/**
- * Creates a new group structure.
- *
- * @param session The MSN session.
- * @param id The group ID.
- * @param name The name of the group.
- *
- * @return A new group structure.
- */
-MsnGroup *msn_group_new(MsnUserList *userlist, const char *id, const char *name);
-
-/**
- * Destroys a group structure.
- *
- * @param group The group to destroy.
- */
-void msn_group_destroy(MsnGroup *group);
-
-/**
- * Sets the ID for a group.
- *
- * @param group The group.
- * @param id The ID.
- */
-void msn_group_set_id(MsnGroup *group, const char *id);
-
-/**
- * Sets the name for a group.
- *
- * @param group The group.
- * @param name The name.
- */
-void msn_group_set_name(MsnGroup *group, const char *name);
-
-/**
- * Returns the ID for a group.
- *
- * @param group The group.
- *
- * @return The ID.
- */
-char* msn_group_get_id(const MsnGroup *group);
-
-/**
- * Returns the name for a group.
- *
- * @param group The group.
- *
- * @return The name.
- */
-const char *msn_group_get_name(const MsnGroup *group);
-
-#endif /* MSN_GROUP_H */
diff --git a/libpurple/protocols/msn/history.c b/libpurple/protocols/msn/history.c
deleted file mode 100644
index 2b23af5ba1..0000000000
--- a/libpurple/protocols/msn/history.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/**
- * @file history.c MSN history functions
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-#include "msn.h"
-#include "history.h"
-
-MsnHistory *
-msn_history_new(void)
-{
- MsnHistory *history = g_new0(MsnHistory, 1);
-
- history->trId = 1;
-
- history->queue = g_queue_new();
-
- return history;
-}
-
-void
-msn_history_destroy(MsnHistory *history)
-{
- MsnTransaction *trans;
-
- while ((trans = g_queue_pop_head(history->queue)) != NULL)
- msn_transaction_destroy(trans);
-
- g_queue_free(history->queue);
- g_free(history);
-}
-
-MsnTransaction *
-msn_history_find(MsnHistory *history, unsigned int trId)
-{
- MsnTransaction *trans;
- GList *list;
-
- for (list = history->queue->head; list != NULL; list = list->next)
- {
- trans = list->data;
- if (trans->trId == trId)
- return trans;
- }
-
- return NULL;
-}
-
-void
-msn_history_add(MsnHistory *history, MsnTransaction *trans)
-{
- GQueue *queue;
- gsize max_elems;
-
- g_return_if_fail(history != NULL);
- g_return_if_fail(trans != NULL);
-
- queue = history->queue;
-
- trans->trId = history->trId++;
-
- g_queue_push_tail(queue, trans);
-
- if (trans->cmdproc->servconn->type == MSN_SERVCONN_NS)
- max_elems = MSN_NS_HIST_ELEMS;
- else
- max_elems = MSN_SB_HIST_ELEMS;
-
- if (queue->length > max_elems)
- {
- trans = g_queue_pop_head(queue);
- msn_transaction_destroy(trans);
- }
-}
-
diff --git a/libpurple/protocols/msn/history.h b/libpurple/protocols/msn/history.h
deleted file mode 100644
index 7ceef1fce4..0000000000
--- a/libpurple/protocols/msn/history.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * @file history.h MSN history functions
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-#ifndef MSN_HISTORY_H
-#define MSN_HISTORY_H
-
-#include "internal.h"
-
-typedef struct _MsnHistory MsnHistory;
-
-#include "transaction.h"
-
-#define MSN_NS_HIST_ELEMS 0x300
-#define MSN_SB_HIST_ELEMS 0x30
-
-/**
- * The history.
- */
-struct _MsnHistory
-{
- GQueue *queue;
- unsigned int trId;
-};
-
-MsnHistory *msn_history_new(void);
-void msn_history_destroy(MsnHistory *history);
-MsnTransaction *msn_history_find(MsnHistory *history, unsigned int triId);
-void msn_history_add(MsnHistory *history, MsnTransaction *trans);
-
-#endif /* MSN_HISTORY_H */
diff --git a/libpurple/protocols/msn/httpconn.c b/libpurple/protocols/msn/httpconn.c
deleted file mode 100644
index 2f52d1ec34..0000000000
--- a/libpurple/protocols/msn/httpconn.c
+++ /dev/null
@@ -1,739 +0,0 @@
-/**
- * @file httpconn.c HTTP connection method
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-#include "msn.h"
-#include "debug.h"
-#include "httpconn.h"
-
-typedef struct
-{
- MsnHttpConn *httpconn;
- char *body;
- size_t body_len;
-} MsnHttpQueueData;
-
-static void
-msn_httpconn_process_queue(MsnHttpConn *httpconn)
-{
- httpconn->waiting_response = FALSE;
-
- if (httpconn->queue != NULL)
- {
- MsnHttpQueueData *queue_data;
-
- queue_data = (MsnHttpQueueData *)httpconn->queue->data;
-
- httpconn->queue = g_list_remove(httpconn->queue, queue_data);
-
- msn_httpconn_write(queue_data->httpconn,
- queue_data->body,
- queue_data->body_len);
-
- g_free(queue_data->body);
- g_free(queue_data);
- }
-}
-
-static gboolean
-msn_httpconn_parse_data(MsnHttpConn *httpconn, const char *buf,
- size_t size, char **ret_buf, size_t *ret_size,
- gboolean *error)
-{
- const char *s, *c;
- char *header, *body;
- const char *body_start;
- char *tmp;
- size_t body_len = 0;
-
- g_return_val_if_fail(httpconn != NULL, FALSE);
- g_return_val_if_fail(buf != NULL, FALSE);
- g_return_val_if_fail(size > 0, FALSE);
- g_return_val_if_fail(ret_buf != NULL, FALSE);
- g_return_val_if_fail(ret_size != NULL, FALSE);
- g_return_val_if_fail(error != NULL, FALSE);
-
-#if 0
- purple_debug_info("msn", "HTTP: parsing data {%s}\n", buf);
-#endif
-
- /* Healthy defaults. */
- body = NULL;
-
- *ret_buf = NULL;
- *ret_size = 0;
- *error = FALSE;
-
- /* First, some tests to see if we have a full block of stuff. */
- if (((strncmp(buf, "HTTP/1.1 200 OK\r\n", 17) != 0) &&
- (strncmp(buf, "HTTP/1.1 100 Continue\r\n", 23) != 0)) &&
- ((strncmp(buf, "HTTP/1.0 200 OK\r\n", 17) != 0) &&
- (strncmp(buf, "HTTP/1.0 100 Continue\r\n", 23) != 0)))
- {
- *error = TRUE;
-
- return FALSE;
- }
-
- if (strncmp(buf, "HTTP/1.1 100 Continue\r\n", 23) == 0)
- {
- if ((s = strstr(buf, "\r\n\r\n")) == NULL)
- return FALSE;
-
- s += 4;
-
- if (*s == '\0')
- {
- *ret_buf = g_strdup("");
- *ret_size = 0;
-
- msn_httpconn_process_queue(httpconn);
-
- return TRUE;
- }
-
- size -= (s - buf);
- buf = s;
- }
-
- if ((s = strstr(buf, "\r\n\r\n")) == NULL)
- /* Need to wait for the full HTTP header to arrive */
- return FALSE;
-
- s += 4; /* Skip \r\n\r\n */
- header = g_strndup(buf, s - buf);
- body_start = s;
- body_len = size - (body_start - buf);
-
- if ((s = purple_strcasestr(header, "Content-Length: ")) != NULL)
- {
- size_t tmp_len;
-
- s += strlen("Content-Length: ");
-
- if ((c = strchr(s, '\r')) == NULL)
- {
- g_free(header);
-
- return FALSE;
- }
-
- tmp = g_strndup(s, c - s);
- tmp_len = atoi(tmp);
- g_free(tmp);
-
- if (body_len != tmp_len)
- {
- /* Need to wait for the full packet to arrive */
-
- g_free(header);
-
-#if 0
- purple_debug_warning("msn",
- "body length (%d) != content length (%d)\n",
- body_len, tmp_len);
-#endif
-
- return FALSE;
- }
- }
-
- body = g_malloc(body_len + 1);
- memcpy(body, body_start, body_len);
- body[body_len] = '\0';
-
- if (purple_debug_is_verbose())
- purple_debug_misc("msn", "Incoming HTTP buffer (header): {%s}\n",
- header);
-
- /* Now we should be able to process the data. */
- if ((s = purple_strcasestr(header, "X-MSN-Messenger: ")) != NULL)
- {
- gchar *full_session_id = NULL, *gw_ip = NULL, *session_action = NULL;
- char *t, *session_id;
- char **elems, **cur, **tokens;
-
- full_session_id = gw_ip = session_action = NULL;
-
- s += strlen("X-MSN-Messenger: ");
-
- if ((c = strchr(s, '\r')) == NULL)
- {
- msn_session_set_error(httpconn->session,
- MSN_ERROR_HTTP_MALFORMED, NULL);
- purple_debug_error("msn", "Malformed X-MSN-Messenger field.\n{%s}\n",
- buf);
-
- g_free(header);
- g_free(body);
- return FALSE;
- }
-
- tmp = g_strndup(s, c - s);
-
- elems = g_strsplit(tmp, "; ", 0);
-
- for (cur = elems; *cur != NULL; cur++)
- {
- tokens = g_strsplit(*cur, "=", 2);
-
- if (strcmp(tokens[0], "SessionID") == 0) {
- g_free(full_session_id);
- full_session_id = tokens[1];
- } else if (strcmp(tokens[0], "GW-IP") == 0) {
- g_free(gw_ip);
- gw_ip = tokens[1];
- } else if (strcmp(tokens[0], "Session") == 0) {
- g_free(session_action);
- session_action = tokens[1];
- } else
- g_free(tokens[1]);
-
- g_free(tokens[0]);
- /* Don't free each of the tokens, only the array. */
- g_free(tokens);
- }
-
- g_strfreev(elems);
-
- g_free(tmp);
-
- t = full_session_id ? strchr(full_session_id, '.') : NULL;
- if (t != NULL)
- session_id = g_strndup(full_session_id, t - full_session_id);
- else {
- purple_debug_error("msn", "Malformed full_session_id[%s]\n",
- full_session_id ? full_session_id : NULL);
- session_id = g_strdup(full_session_id);
- }
-
- if (session_action == NULL || strcmp(session_action, "close") != 0)
- {
- g_free(httpconn->full_session_id);
- httpconn->full_session_id = full_session_id;
-
- g_free(httpconn->session_id);
- httpconn->session_id = session_id;
-
- g_free(httpconn->host);
- httpconn->host = gw_ip;
- }
- else
- {
- /* I'll be honest, I don't fully understand all this, but this
- * causes crashes, Stu. */
-#if 0
- MsnServConn *servconn;
-
- /* It's going to die. */
- /* poor thing */
-
- servconn = httpconn->servconn;
-
- if (servconn != NULL)
- servconn->wasted = TRUE;
-#endif
-
- g_free(full_session_id);
- g_free(session_id);
- g_free(gw_ip);
- }
-
- g_free(session_action);
- }
-
- g_free(header);
-
- *ret_buf = body;
- *ret_size = body_len;
-
- msn_httpconn_process_queue(httpconn);
-
- return TRUE;
-}
-
-static void
-read_cb(gpointer data, gint source, PurpleInputCondition cond)
-{
- MsnHttpConn *httpconn;
- MsnServConn *servconn;
- char buf[MSN_BUF_LEN];
- gssize len;
- char *result_msg = NULL;
- size_t result_len = 0;
- gboolean error = FALSE;
-
- httpconn = data;
- servconn = httpconn->servconn;
-
- if (servconn->type == MSN_SERVCONN_NS)
- servconn->session->account->gc->last_received = time(NULL);
-
- len = read(httpconn->fd, buf, sizeof(buf) - 1);
- if (len < 0 && errno == EAGAIN)
- return;
- if (len <= 0) {
- purple_debug_error("msn", "HTTP: servconn %03d read error, "
- "len: %" G_GSSIZE_FORMAT ", errno: %d, error: %s\n",
- servconn->num, len, error, g_strerror(errno));
- msn_servconn_got_error(servconn, MSN_SERVCONN_ERROR_READ, NULL);
-
- return;
- }
-
- buf[len] = '\0';
-
- httpconn->rx_buf = g_realloc(httpconn->rx_buf, len + httpconn->rx_len + 1);
- memcpy(httpconn->rx_buf + httpconn->rx_len, buf, len + 1);
- httpconn->rx_len += len;
-
- if (!msn_httpconn_parse_data(httpconn, httpconn->rx_buf, httpconn->rx_len,
- &result_msg, &result_len, &error))
- {
- /* Either we must wait for more input, or something went wrong */
- if (error)
- msn_servconn_got_error(servconn, MSN_SERVCONN_ERROR_READ, NULL);
-
- return;
- }
-
- if (error)
- {
- purple_debug_error("msn", "HTTP: Special error\n");
- msn_servconn_got_error(servconn, MSN_SERVCONN_ERROR_READ, NULL);
-
- return;
- }
-
- g_free(httpconn->rx_buf);
- httpconn->rx_buf = NULL;
- httpconn->rx_len = 0;
-
- if (result_len == 0)
- {
- /* Nothing to do here */
-#if 0
- purple_debug_info("msn", "HTTP: nothing to do here\n");
-#endif
- g_free(result_msg);
- return;
- }
-
- g_free(servconn->rx_buf);
- servconn->rx_buf = result_msg;
- servconn->rx_len = result_len;
-
- msn_servconn_process_data(servconn);
-}
-
-static void
-httpconn_write_cb(gpointer data, gint source, PurpleInputCondition cond)
-{
- MsnHttpConn *httpconn;
- gssize ret;
- int writelen;
-
- httpconn = data;
- writelen = purple_circ_buffer_get_max_read(httpconn->tx_buf);
-
- if (writelen == 0)
- {
- purple_input_remove(httpconn->tx_handler);
- httpconn->tx_handler = 0;
- return;
- }
-
- ret = write(httpconn->fd, httpconn->tx_buf->outptr, writelen);
- if (ret <= 0)
- {
- if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
- /* No worries */
- return;
-
- /* Error! */
- msn_servconn_got_error(httpconn->servconn, MSN_SERVCONN_ERROR_WRITE, NULL);
- return;
- }
-
- purple_circ_buffer_mark_read(httpconn->tx_buf, ret);
-
- /* TODO: I don't think these 2 lines are needed. Remove them? */
- if (ret == writelen)
- httpconn_write_cb(data, source, cond);
-}
-
-static gboolean
-write_raw(MsnHttpConn *httpconn, const char *data, size_t data_len)
-{
- gssize res; /* result of the write operation */
-
- if (httpconn->tx_handler == 0)
- res = write(httpconn->fd, data, data_len);
- else
- {
- res = -1;
- errno = EAGAIN;
- }
-
- if ((res <= 0) && ((errno != EAGAIN) && (errno != EWOULDBLOCK)))
- {
- msn_servconn_got_error(httpconn->servconn, MSN_SERVCONN_ERROR_WRITE, NULL);
- return FALSE;
- }
-
- if (res < 0 || (size_t)res < data_len)
- {
- if (res < 0)
- res = 0;
- if (httpconn->tx_handler == 0 && httpconn->fd)
- httpconn->tx_handler = purple_input_add(httpconn->fd,
- PURPLE_INPUT_WRITE, httpconn_write_cb, httpconn);
- purple_circ_buffer_append(httpconn->tx_buf, data + res,
- data_len - res);
- }
-
- return TRUE;
-}
-
-static char *
-msn_httpconn_proxy_auth(MsnHttpConn *httpconn)
-{
- PurpleAccount *account;
- PurpleProxyInfo *gpi;
- const char *username, *password;
- char *auth = NULL;
-
- account = httpconn->session->account;
-
- gpi = purple_proxy_get_setup(account);
-
- if (gpi == NULL || !(purple_proxy_info_get_type(gpi) == PURPLE_PROXY_HTTP ||
- purple_proxy_info_get_type(gpi) == PURPLE_PROXY_USE_ENVVAR))
- return NULL;
-
- username = purple_proxy_info_get_username(gpi);
- password = purple_proxy_info_get_password(gpi);
-
- if (username != NULL) {
- char *tmp;
- auth = g_strdup_printf("%s:%s", username, password ? password : "");
- tmp = purple_base64_encode((const guchar *)auth, strlen(auth));
- g_free(auth);
- auth = g_strdup_printf("Proxy-Authorization: Basic %s\r\n", tmp);
- g_free(tmp);
- }
-
- return auth;
-}
-
-static gboolean
-msn_httpconn_poll(gpointer data)
-{
- MsnHttpConn *httpconn;
- char *header;
- char *auth;
-
- httpconn = data;
-
- g_return_val_if_fail(httpconn != NULL, FALSE);
-
- if ((httpconn->host == NULL) || (httpconn->full_session_id == NULL))
- {
- /* There's no need to poll if the session is not fully established */
- return TRUE;
- }
-
- if (httpconn->waiting_response)
- {
- /* There's no need to poll if we're already waiting for a response */
- return TRUE;
- }
-
- auth = msn_httpconn_proxy_auth(httpconn);
-
- header = g_strdup_printf(
- "POST http://%s/gateway/gateway.dll?Action=poll&SessionID=%s HTTP/1.1\r\n"
- "Accept: */*\r\n"
- "Accept-Language: en-us\r\n"
- "User-Agent: MSMSGS\r\n"
- "Host: %s\r\n"
- "Proxy-Connection: Keep-Alive\r\n"
- "%s" /* Proxy auth */
- "Connection: Keep-Alive\r\n"
- "Pragma: no-cache\r\n"
- "Content-Type: application/x-msn-messenger\r\n"
- "Content-Length: 0\r\n\r\n",
- httpconn->host,
- httpconn->full_session_id,
- httpconn->host,
- auth ? auth : "");
-
- g_free(auth);
-
- if (write_raw(httpconn, header, strlen(header)))
- httpconn->waiting_response = TRUE;
-
- g_free(header);
-
- return TRUE;
-}
-
-gssize
-msn_httpconn_write(MsnHttpConn *httpconn, const char *body, size_t body_len)
-{
- char *params;
- char *data;
- int header_len;
- char *auth;
- const char *server_types[] = { "NS", "SB" };
- const char *server_type;
- char *host;
- MsnServConn *servconn;
-
- /* TODO: remove http data from servconn */
-
- g_return_val_if_fail(httpconn != NULL, 0);
- g_return_val_if_fail(body != NULL, 0);
- g_return_val_if_fail(body_len > 0, 0);
-
- servconn = httpconn->servconn;
-
- if (httpconn->waiting_response)
- {
- MsnHttpQueueData *queue_data = g_new0(MsnHttpQueueData, 1);
-
- queue_data->httpconn = httpconn;
- queue_data->body = g_memdup(body, body_len);
- queue_data->body_len = body_len;
-
- httpconn->queue = g_list_append(httpconn->queue, queue_data);
-
- return body_len;
- }
-
- server_type = server_types[servconn->type];
-
- if (httpconn->virgin)
- {
- /* QuLogic: This doesn't look right to me, but it still seems to work */
- host = MSN_HTTPCONN_SERVER;
-
- /* The first time servconn->host is the host we should connect to. */
- params = g_strdup_printf("Action=open&Server=%s&IP=%s",
- server_type,
- servconn->host);
- httpconn->virgin = FALSE;
- }
- else
- {
- /* The rest of the times servconn->host is the gateway host. */
- host = httpconn->host;
-
- if (host == NULL || httpconn->full_session_id == NULL)
- {
- purple_debug_warning("msn", "Attempted HTTP write before session is established\n");
- return -1;
- }
-
- params = g_strdup_printf("SessionID=%s",
- httpconn->full_session_id);
- }
-
- auth = msn_httpconn_proxy_auth(httpconn);
-
- data = g_strdup_printf(
- "POST http://%s/gateway/gateway.dll?%s HTTP/1.1\r\n"
- "Accept: */*\r\n"
- "Accept-Language: en-us\r\n"
- "User-Agent: MSMSGS\r\n"
- "Host: %s\r\n"
- "Proxy-Connection: Keep-Alive\r\n"
- "%s" /* Proxy auth */
- "Connection: Keep-Alive\r\n"
- "Pragma: no-cache\r\n"
- "Content-Type: application/x-msn-messenger\r\n"
- "Content-Length: %d\r\n\r\n",
- host,
- params,
- host,
- auth ? auth : "",
- (int) body_len);
-
- g_free(params);
-
- g_free(auth);
-
- header_len = strlen(data);
- data = g_realloc(data, header_len + body_len);
- memcpy(data + header_len, body, body_len);
-
- if (write_raw(httpconn, data, header_len + body_len))
- httpconn->waiting_response = TRUE;
-
- g_free(data);
-
- return body_len;
-}
-
-MsnHttpConn *
-msn_httpconn_new(MsnServConn *servconn)
-{
- MsnHttpConn *httpconn;
-
- g_return_val_if_fail(servconn != NULL, NULL);
-
- httpconn = g_new0(MsnHttpConn, 1);
-
- purple_debug_info("msn", "new httpconn (%p)\n", httpconn);
-
- /* TODO: Remove this */
- httpconn->session = servconn->session;
-
- httpconn->servconn = servconn;
-
- httpconn->tx_buf = purple_circ_buffer_new(MSN_BUF_LEN);
- httpconn->tx_handler = 0;
-
- httpconn->fd = -1;
-
- return httpconn;
-}
-
-void
-msn_httpconn_destroy(MsnHttpConn *httpconn)
-{
- g_return_if_fail(httpconn != NULL);
-
- purple_debug_info("msn", "destroy httpconn (%p)\n", httpconn);
-
- if (httpconn->connected)
- msn_httpconn_disconnect(httpconn);
-
- g_free(httpconn->full_session_id);
-
- g_free(httpconn->session_id);
-
- g_free(httpconn->host);
-
- while (httpconn->queue != NULL) {
- MsnHttpQueueData *queue_data;
-
- queue_data = (MsnHttpQueueData *) httpconn->queue->data;
-
- httpconn->queue = g_list_delete_link(httpconn->queue, httpconn->queue);
-
- g_free(queue_data->body);
- g_free(queue_data);
- }
-
- purple_circ_buffer_destroy(httpconn->tx_buf);
- if (httpconn->tx_handler > 0)
- purple_input_remove(httpconn->tx_handler);
-
- g_free(httpconn);
-}
-
-static void
-connect_cb(gpointer data, gint source, const gchar *error_message)
-{
- MsnHttpConn *httpconn;
-
- httpconn = data;
- httpconn->connect_data = NULL;
- httpconn->fd = source;
-
- if (source >= 0)
- {
- httpconn->inpa = purple_input_add(httpconn->fd, PURPLE_INPUT_READ,
- read_cb, data);
-
- httpconn->timer = purple_timeout_add_seconds(2, msn_httpconn_poll, httpconn);
-
- msn_httpconn_process_queue(httpconn);
- }
- else
- {
- purple_debug_error("msn", "HTTP: Connection error: %s\n",
- error_message ? error_message : "(null)");
- msn_servconn_got_error(httpconn->servconn, MSN_SERVCONN_ERROR_CONNECT, error_message);
- }
-}
-
-gboolean
-msn_httpconn_connect(MsnHttpConn *httpconn, const char *host, int port)
-{
- g_return_val_if_fail(httpconn != NULL, FALSE);
- g_return_val_if_fail(host != NULL, FALSE);
- g_return_val_if_fail(port > 0, FALSE);
-
- if (httpconn->connected)
- msn_httpconn_disconnect(httpconn);
-
- httpconn->connect_data = purple_proxy_connect(NULL, httpconn->session->account,
- host, 80, connect_cb, httpconn);
-
- if (httpconn->connect_data != NULL)
- {
- httpconn->waiting_response = TRUE;
- httpconn->connected = TRUE;
- }
-
- return httpconn->connected;
-}
-
-void
-msn_httpconn_disconnect(MsnHttpConn *httpconn)
-{
- g_return_if_fail(httpconn != NULL);
-
- if (!httpconn->connected)
- return;
-
- if (httpconn->connect_data != NULL)
- {
- purple_proxy_connect_cancel(httpconn->connect_data);
- httpconn->connect_data = NULL;
- }
-
- if (httpconn->timer)
- {
- purple_timeout_remove(httpconn->timer);
- httpconn->timer = 0;
- }
-
- if (httpconn->inpa > 0)
- {
- purple_input_remove(httpconn->inpa);
- httpconn->inpa = 0;
- }
-
- close(httpconn->fd);
- httpconn->fd = -1;
-
- g_free(httpconn->rx_buf);
- httpconn->rx_buf = NULL;
- httpconn->rx_len = 0;
-
- httpconn->connected = FALSE;
-
- /* msn_servconn_disconnect(httpconn->servconn); */
-}
diff --git a/libpurple/protocols/msn/httpconn.h b/libpurple/protocols/msn/httpconn.h
deleted file mode 100644
index 381a27b85c..0000000000
--- a/libpurple/protocols/msn/httpconn.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/**
- * @file httpconn.h HTTP connection
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-#ifndef MSN_HTTPCONN_H
-#define MSN_HTTPCONN_H
-
-typedef struct _MsnHttpConn MsnHttpConn;
-
-#include "circbuffer.h"
-#include "servconn.h"
-#include "session.h"
-
-/**
- * An HTTP Connection.
- */
-struct _MsnHttpConn
-{
- MsnSession *session; /**< The MSN Session. */
- MsnServConn *servconn; /**< The connection object. */
-
- PurpleProxyConnectData *connect_data;
-
- char *full_session_id; /**< The full session id. */
- char *session_id; /**< The trimmed session id. */
-
- int timer; /**< The timer for polling. */
-
- gboolean waiting_response; /**< The flag that states if we are waiting
- a response from the server. */
- gboolean connected; /**< The flag that states if the connection is on. */
- gboolean virgin; /**< The flag that states if this connection
- should specify the host (not gateway) to
- connect to. */
-
- char *host; /**< The HTTP gateway host. */
- GList *queue; /**< The queue of data chunks to write. */
-
- int fd; /**< The connection's file descriptor. */
- guint inpa; /**< The connection's input handler. */
-
- char *rx_buf; /**< The receive buffer. */
- int rx_len; /**< The receive buffer length. */
-
- PurpleCircBuffer *tx_buf;
- guint tx_handler;
-};
-
-/**
- * Creates a new HTTP connection object.
- *
- * @param servconn The connection object.
- *
- * @return The new object.
- */
-MsnHttpConn *msn_httpconn_new(MsnServConn *servconn);
-
-/**
- * Destroys an HTTP connection object.
- *
- * @param httpconn The HTTP connection object.
- */
-void msn_httpconn_destroy(MsnHttpConn *httpconn);
-
-/**
- * Writes a chunk of data to the HTTP connection.
- *
- * @param servconn The server connection.
- * @param data The data to write.
- * @param data_len The size of the data to write.
- *
- * @return The number of bytes written.
- */
-gssize msn_httpconn_write(MsnHttpConn *httpconn, const char *data, size_t data_len);
-
-/**
- * Connects the HTTP connection object to a host.
- *
- * @param httpconn The HTTP connection object.
- * @param host The host to connect to.
- * @param port The port to connect to.
- */
-gboolean msn_httpconn_connect(MsnHttpConn *httpconn,
- const char *host, int port);
-
-/**
- * Disconnects the HTTP connection object.
- *
- * @param httpconn The HTTP connection object.
- */
-void msn_httpconn_disconnect(MsnHttpConn *httpconn);
-
-#endif /* MSN_HTTPCONN_H */
diff --git a/libpurple/protocols/msn/msg.c b/libpurple/protocols/msn/msg.c
deleted file mode 100644
index 4f9727392c..0000000000
--- a/libpurple/protocols/msn/msg.c
+++ /dev/null
@@ -1,1217 +0,0 @@
-/**
- * @file msg.c Message functions
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-
-#include "internal.h"
-#include "debug.h"
-
-#include "msn.h"
-#include "msg.h"
-#include "msnutils.h"
-#include "slpmsg.h"
-#include "slpmsg_part.h"
-
-MsnMessage *
-msn_message_new(MsnMsgType type)
-{
- MsnMessage *msg;
-
- msg = g_new0(MsnMessage, 1);
- msg->type = type;
-
- if (purple_debug_is_verbose())
- purple_debug_info("msn", "message new (%p)(%d)\n", msg, type);
-
- msg->header_table = g_hash_table_new_full(g_str_hash, g_str_equal,
- g_free, g_free);
-
- msn_message_ref(msg);
-
- return msg;
-}
-
-/**
- * Destroys a message.
- *
- * @param msg The message to destroy.
- */
-static void
-msn_message_destroy(MsnMessage *msg)
-{
- g_return_if_fail(msg != NULL);
-
- if (purple_debug_is_verbose())
- purple_debug_info("msn", "message destroy (%p)\n", msg);
-
- g_free(msg->remote_user);
- g_free(msg->body);
- g_free(msg->content_type);
- g_free(msg->charset);
-
- g_hash_table_destroy(msg->header_table);
- g_list_free(msg->header_list);
- if (msg->part)
- msn_slpmsgpart_unref(msg->part);
-
- g_free(msg);
-}
-
-MsnMessage *
-msn_message_ref(MsnMessage *msg)
-{
- g_return_val_if_fail(msg != NULL, NULL);
-
- msg->ref_count++;
-
- if (purple_debug_is_verbose())
- purple_debug_info("msn", "message ref (%p)[%u]\n", msg, msg->ref_count);
-
- return msg;
-}
-
-void
-msn_message_unref(MsnMessage *msg)
-{
- g_return_if_fail(msg != NULL);
- g_return_if_fail(msg->ref_count > 0);
-
- msg->ref_count--;
-
- if (purple_debug_is_verbose())
- purple_debug_info("msn", "message unref (%p)[%u]\n", msg, msg->ref_count);
-
- if (msg->ref_count == 0)
- msn_message_destroy(msg);
-}
-
-MsnMessage *
-msn_message_new_plain(const char *message)
-{
- MsnMessage *msg;
- char *message_cr;
-
- msg = msn_message_new(MSN_MSG_TEXT);
- msg->retries = 1;
- msn_message_set_header(msg, "User-Agent", PACKAGE_NAME "/" VERSION);
- msn_message_set_content_type(msg, "text/plain");
- msn_message_set_charset(msg, "UTF-8");
- msn_message_set_flag(msg, 'A');
- msn_message_set_header(msg, "X-MMS-IM-Format",
- "FN=Segoe%20UI; EF=; CO=0; CS=1;PF=0");
-
- message_cr = purple_str_add_cr(message);
- msn_message_set_bin_data(msg, message_cr, strlen(message_cr));
- g_free(message_cr);
-
- return msg;
-}
-
-MsnMessage *
-msn_message_new_msnslp(void)
-{
- MsnMessage *msg;
-
- msg = msn_message_new(MSN_MSG_SLP);
-
- msn_message_set_header(msg, "User-Agent", NULL);
-
- msn_message_set_flag(msg, 'D');
- msn_message_set_content_type(msg, "application/x-msnmsgrp2p");
-
- return msg;
-}
-
-MsnMessage *
-msn_message_new_nudge(void)
-{
- MsnMessage *msg;
-
- msg = msn_message_new(MSN_MSG_NUDGE);
- msn_message_set_content_type(msg, "text/x-msnmsgr-datacast");
- msn_message_set_flag(msg, 'N');
- msn_message_set_bin_data(msg, "ID: 1\r\n", 7);
-
- return msg;
-}
-
-void
-msn_message_parse_payload(MsnMessage *msg,
- const char *payload, size_t payload_len,
- const char *line_dem,const char *body_dem)
-{
- char *tmp_base, *tmp;
- const char *content_type;
- char *end;
- char **elems, **cur, **tokens;
-
- g_return_if_fail(payload != NULL);
- tmp_base = tmp = g_malloc(payload_len + 1);
- memcpy(tmp_base, payload, payload_len);
- tmp_base[payload_len] = '\0';
-
- /* Find the end of the headers */
- end = strstr(tmp, body_dem);
- /* TODO? some clients use \r delimiters instead of \r\n, the official client
- * doesn't send such messages, but does handle receiving them. We'll just
- * avoid crashing for now */
- if (end == NULL) {
- g_free(tmp_base);
- g_return_if_reached();
- }
-
- /* NUL-terminate the end of the headers - it'll get skipped over below */
- *end = '\0';
-
- /* Split the headers and parse each one */
- elems = g_strsplit(tmp, line_dem, 0);
- for (cur = elems; *cur != NULL; cur++)
- {
- const char *key, *value;
-
- /* If this line starts with whitespace, it's been folded from the
- previous line and won't have ':'. */
- if ((**cur == ' ') || (**cur == '\t')) {
- tokens = g_strsplit(g_strchug(*cur), "=\"", 2);
- key = tokens[0];
- value = tokens[1];
-
- /* The only one I care about is 'boundary' (which is folded from
- the key 'Content-Type'), so only process that. */
- if (!strcmp(key, "boundary") && value) {
- char *end = strchr(value, '\"');
- if (end) {
- *end = '\0';
- msn_message_set_header(msg, key, value);
- }
- }
-
- g_strfreev(tokens);
- continue;
- }
-
- tokens = g_strsplit(*cur, ": ", 2);
-
- key = tokens[0];
- value = tokens[1];
-
- if (!strcmp(key, "MIME-Version"))
- {
- /* Ignore MIME-Version header */
- }
- else if (!strcmp(key, "Content-Type"))
- {
- char *charset, *c;
-
- if (value && (c = strchr(value, ';')) != NULL)
- {
- if ((charset = strchr(c, '=')) != NULL)
- {
- charset++;
- msn_message_set_charset(msg, charset);
- }
-
- *c = '\0';
- }
-
- msn_message_set_content_type(msg, value);
- }
- else
- {
- msn_message_set_header(msg, key, value);
- }
-
- g_strfreev(tokens);
- }
- g_strfreev(elems);
-
- /* Proceed to the end of the "\r\n\r\n" */
- tmp = end + strlen(body_dem);
-
- /* Now we *should* be at the body. */
- content_type = msn_message_get_content_type(msg);
-
- if (payload_len - (tmp - tmp_base) > 0) {
- msg->body_len = payload_len - (tmp - tmp_base);
- g_free(msg->body);
- msg->body = g_malloc(msg->body_len + 1);
- memcpy(msg->body, tmp, msg->body_len);
- msg->body[msg->body_len] = '\0';
- }
-
- if (msg->body && content_type && purple_str_has_prefix(content_type, "text/")) {
- char *body = NULL;
-
- if (msg->charset == NULL || g_str_equal(msg->charset, "UTF-8")) {
- /* Charset is UTF-8 */
- if (!g_utf8_validate(msg->body, msg->body_len, NULL)) {
- purple_debug_warning("msn", "Message contains invalid "
- "UTF-8. Attempting to salvage.\n");
- body = purple_utf8_salvage(msg->body);
- payload_len = strlen(body);
- }
- } else {
- /* Charset is something other than UTF-8 */
- GError *err = NULL;
- body = g_convert(msg->body, msg->body_len, "UTF-8",
- msg->charset, NULL, &payload_len, &err);
- if (!body || err) {
- purple_debug_warning("msn", "Unable to convert message from "
- "%s to UTF-8: %s\n", msg->charset,
- err ? err->message : "Unknown error");
- if (err)
- g_error_free(err);
-
- /* Fallback to ISO-8859-1 */
- g_free(body);
- body = g_convert(msg->body, msg->body_len, "UTF-8",
- "ISO-8859-1", NULL, &payload_len, NULL);
- if (!body) {
- g_free(msg->body);
- msg->body = NULL;
- msg->body_len = 0;
- }
- }
- }
-
- if (body) {
- g_free(msg->body);
- msg->body = body;
- msg->body_len = payload_len;
- msn_message_set_charset(msg, "UTF-8");
- }
- }
-
- g_free(tmp_base);
-}
-
-MsnMessage *
-msn_message_new_from_cmd(MsnSession *session, MsnCommand *cmd)
-{
- MsnMessage *msg;
-
- g_return_val_if_fail(cmd != NULL, NULL);
-
- msg = msn_message_new(MSN_MSG_UNKNOWN);
-
- msg->remote_user = g_strdup(cmd->params[0]);
- /* msg->size = atoi(cmd->params[2]); */
- msg->cmd = cmd;
-
- return msg;
-}
-
-char *
-msn_message_gen_payload(MsnMessage *msg, size_t *ret_size)
-{
- GList *l;
- char *n, *base, *end;
- int len;
- size_t body_len = 0;
- const void *body;
-
- g_return_val_if_fail(msg != NULL, NULL);
-
- len = MSN_BUF_LEN;
-
- base = n = end = g_malloc(len + 1);
- end += len;
-
- /* Standard header. */
- if (msg->charset == NULL)
- {
- g_snprintf(n, len,
- "MIME-Version: 1.0\r\n"
- "Content-Type: %s\r\n",
- msg->content_type);
- }
- else
- {
- g_snprintf(n, len,
- "MIME-Version: 1.0\r\n"
- "Content-Type: %s; charset=%s\r\n",
- msg->content_type, msg->charset);
- }
-
- n += strlen(n);
-
- for (l = msg->header_list; l != NULL; l = l->next)
- {
- const char *key;
- const char *value;
-
- key = l->data;
- value = msn_message_get_header_value(msg, key);
-
- g_snprintf(n, end - n, "%s: %s\r\n", key, value);
- n += strlen(n);
- }
-
- if ((end - n) > 2)
- n += g_strlcpy(n, "\r\n", end - n);
-
- body = msn_message_get_bin_data(msg, &body_len);
-
- if (body != NULL && (end - n) > (gssize)body_len)
- {
- memcpy(n, body, body_len);
- n += body_len;
- *n = '\0';
- }
-
- if (ret_size != NULL)
- {
- *ret_size = n - base;
-
- if (*ret_size > 1664)
- *ret_size = 1664;
- }
-
- return base;
-}
-
-void
-msn_message_set_flag(MsnMessage *msg, char flag)
-{
- g_return_if_fail(msg != NULL);
- g_return_if_fail(flag != 0);
-
- msg->flag = flag;
-}
-
-char
-msn_message_get_flag(const MsnMessage *msg)
-{
- g_return_val_if_fail(msg != NULL, 0);
-
- return msg->flag;
-}
-
-void
-msn_message_set_bin_data(MsnMessage *msg, const void *data, size_t len)
-{
- g_return_if_fail(msg != NULL);
-
- /* There is no need to waste memory on data we cannot send anyway */
- if (len > 1664)
- len = 1664;
-
- if (msg->body != NULL)
- g_free(msg->body);
-
- if (data != NULL && len > 0)
- {
- msg->body = g_malloc(len + 1);
- memcpy(msg->body, data, len);
- msg->body[len] = '\0';
- msg->body_len = len;
- }
- else
- {
- msg->body = NULL;
- msg->body_len = 0;
- }
-}
-
-const void *
-msn_message_get_bin_data(const MsnMessage *msg, size_t *len)
-{
- g_return_val_if_fail(msg != NULL, NULL);
-
- if (len)
- *len = msg->body_len;
-
- return msg->body;
-}
-
-void
-msn_message_set_content_type(MsnMessage *msg, const char *type)
-{
- g_return_if_fail(msg != NULL);
-
- g_free(msg->content_type);
- msg->content_type = g_strdup(type);
-}
-
-const char *
-msn_message_get_content_type(const MsnMessage *msg)
-{
- g_return_val_if_fail(msg != NULL, NULL);
-
- return msg->content_type;
-}
-
-void
-msn_message_set_charset(MsnMessage *msg, const char *charset)
-{
- g_return_if_fail(msg != NULL);
-
- g_free(msg->charset);
- msg->charset = g_strdup(charset);
-}
-
-const char *
-msn_message_get_charset(const MsnMessage *msg)
-{
- g_return_val_if_fail(msg != NULL, NULL);
-
- return msg->charset;
-}
-
-void
-msn_message_set_header(MsnMessage *msg, const char *name, const char *value)
-{
- const char *temp;
- char *new_name;
-
- g_return_if_fail(msg != NULL);
- g_return_if_fail(name != NULL);
-
- temp = msn_message_get_header_value(msg, name);
-
- if (value == NULL)
- {
- if (temp != NULL)
- {
- GList *l;
-
- for (l = msg->header_list; l != NULL; l = l->next)
- {
- if (!g_ascii_strcasecmp(l->data, name))
- {
- msg->header_list = g_list_remove(msg->header_list, l->data);
-
- break;
- }
- }
-
- g_hash_table_remove(msg->header_table, name);
- }
-
- return;
- }
-
- new_name = g_strdup(name);
-
- g_hash_table_insert(msg->header_table, new_name, g_strdup(value));
-
- if (temp == NULL)
- msg->header_list = g_list_append(msg->header_list, new_name);
-}
-
-const char *
-msn_message_get_header_value(const MsnMessage *msg, const char *name)
-{
- g_return_val_if_fail(msg != NULL, NULL);
- g_return_val_if_fail(name != NULL, NULL);
-
- return g_hash_table_lookup(msg->header_table, name);
-}
-
-GHashTable *
-msn_message_get_hashtable_from_body(const MsnMessage *msg)
-{
- GHashTable *table;
- size_t body_len;
- const char *body;
- char **elems, **cur, **tokens, *body_str;
-
- g_return_val_if_fail(msg != NULL, NULL);
-
- table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
-
- body = msn_message_get_bin_data(msg, &body_len);
-
- g_return_val_if_fail(body != NULL, NULL);
-
- body_str = g_strndup(body, body_len);
- elems = g_strsplit(body_str, "\r\n", 0);
- g_free(body_str);
-
- for (cur = elems; *cur != NULL; cur++)
- {
- if (**cur == '\0')
- break;
-
- tokens = g_strsplit(*cur, ": ", 2);
-
- if (tokens[0] != NULL && tokens[1] != NULL) {
- g_hash_table_insert(table, tokens[0], tokens[1]);
- g_free(tokens);
- } else
- g_strfreev(tokens);
- }
-
- g_strfreev(elems);
-
- return table;
-}
-
-char *
-msn_message_to_string(MsnMessage *msg)
-{
- size_t body_len;
- const char *body;
-
- g_return_val_if_fail(msg != NULL, NULL);
- g_return_val_if_fail(msg->type == MSN_MSG_TEXT, NULL);
-
- body = msn_message_get_bin_data(msg, &body_len);
-
- return g_strndup(body, body_len);
-}
-
-void
-msn_message_show_readable(MsnMessage *msg, const char *info,
- gboolean text_body)
-{
- GString *str;
- size_t body_len;
- const char *body;
- GList *l;
-
- g_return_if_fail(msg != NULL);
-
- str = g_string_new(NULL);
-
- /* Standard header. */
- if (msg->charset == NULL)
- {
- g_string_append_printf(str,
- "MIME-Version: 1.0\r\n"
- "Content-Type: %s\r\n",
- msg->content_type);
- }
- else
- {
- g_string_append_printf(str,
- "MIME-Version: 1.0\r\n"
- "Content-Type: %s; charset=%s\r\n",
- msg->content_type, msg->charset);
- }
-
- for (l = msg->header_list; l; l = l->next)
- {
- char *key;
- const char *value;
-
- key = l->data;
- value = msn_message_get_header_value(msg, key);
-
- g_string_append_printf(str, "%s: %s\r\n", key, value);
- }
-
- g_string_append(str, "\r\n");
-
- body = msn_message_get_bin_data(msg, &body_len);
-
- if (body != NULL)
- {
- if (msg->type == MSN_MSG_TEXT)
- {
- g_string_append_len(str, body, body_len);
- g_string_append(str, "\r\n");
- }
- else
- {
- size_t i;
- for (i = 0; i < body_len; i++, body++)
- {
- g_string_append_printf(str, "%02x ", (unsigned char)*body);
- if (i % 16 == 0 && i != 0)
- g_string_append_c(str, '\n');
- }
- g_string_append_c(str, '\n');
- }
- }
-
- purple_debug_info("msn", "Message %s:\n{%s}\n", info, str->str);
-
- g_string_free(str, TRUE);
-}
-
-/**************************************************************************
- * Message Handlers
- **************************************************************************/
-void
-msn_plain_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
-{
- PurpleConnection *gc;
- const char *body;
- char *body_enc;
- char *body_final;
- size_t body_len;
- const char *passport;
- const char *value;
-
- gc = cmdproc->session->account->gc;
-
- body = msn_message_get_bin_data(msg, &body_len);
- body_enc = g_markup_escape_text(body, body_len);
-
- passport = msg->remote_user;
-
- if (!strcmp(passport, "messenger@microsoft.com") &&
- strstr(body, "immediate security update"))
- {
- return;
- }
-
-#if 0
- if ((value = msn_message_get_header_value(msg, "User-Agent")) != NULL)
- {
- purple_debug_misc("msn", "User-Agent = '%s'\n", value);
- }
-#endif
-
- if ((value = msn_message_get_header_value(msg, "X-MMS-IM-Format")) != NULL)
- {
- char *pre, *post;
-
- msn_parse_format(value, &pre, &post);
-
- body_final = g_strdup_printf("%s%s%s", pre ? pre : "",
- body_enc ? body_enc : "", post ? post : "");
-
- g_free(pre);
- g_free(post);
- g_free(body_enc);
- }
- else
- {
- body_final = body_enc;
- }
-
- if (cmdproc->servconn->type == MSN_SERVCONN_SB) {
- MsnSwitchBoard *swboard = cmdproc->data;
-
- swboard->flag |= MSN_SB_FLAG_IM;
-
- if (swboard->current_users > 1 ||
- ((swboard->conv != NULL) &&
- purple_conversation_get_type(swboard->conv) == PURPLE_CONV_TYPE_CHAT))
- {
- /* If current_users is always ok as it should then there is no need to
- * check if this is a chat. */
- if (swboard->current_users <= 1)
- purple_debug_misc("msn", "plain_msg: current_users(%d)\n",
- swboard->current_users);
-
- serv_got_chat_in(gc, swboard->chat_id, passport, 0, body_final,
- time(NULL));
- if (swboard->conv == NULL)
- {
- swboard->conv = purple_find_chat(gc, swboard->chat_id);
- swboard->flag |= MSN_SB_FLAG_IM;
- }
- }
- else if (!g_str_equal(passport, purple_account_get_username(gc->account)))
- {
- /* Don't im ourselves ... */
- serv_got_im(gc, passport, body_final, 0, time(NULL));
- if (swboard->conv == NULL)
- {
- swboard->conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM,
- passport, purple_connection_get_account(gc));
- swboard->flag |= MSN_SB_FLAG_IM;
- }
- }
-
- } else {
- serv_got_im(gc, passport, body_final, 0, time(NULL));
- }
-
- g_free(body_final);
-}
-
-void
-msn_control_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
-{
- PurpleConnection *gc;
- char *passport;
-
- gc = cmdproc->session->account->gc;
- passport = msg->remote_user;
-
- if (msn_message_get_header_value(msg, "TypingUser") == NULL)
- return;
-
- if (cmdproc->servconn->type == MSN_SERVCONN_SB) {
- MsnSwitchBoard *swboard = cmdproc->data;
-
- if (swboard->current_users == 1)
- {
- serv_got_typing(gc, passport, MSN_TYPING_RECV_TIMEOUT,
- PURPLE_TYPING);
- }
-
- } else {
- serv_got_typing(gc, passport, MSN_TYPING_RECV_TIMEOUT,
- PURPLE_TYPING);
- }
-}
-
-static void
-datacast_inform_user(MsnSwitchBoard *swboard, const char *who,
- const char *msg, const char *filename)
-{
- char *username, *str;
- PurpleAccount *account;
- PurpleBuddy *b;
- PurpleConnection *pc;
- gboolean chat;
-
- account = swboard->session->account;
- pc = purple_account_get_connection(account);
-
- if ((b = purple_find_buddy(account, who)) != NULL)
- username = g_markup_escape_text(purple_buddy_get_alias(b), -1);
- else
- username = g_markup_escape_text(who, -1);
- str = g_strdup_printf(msg, username, filename);
- g_free(username);
-
- swboard->flag |= MSN_SB_FLAG_IM;
- if (swboard->current_users > 1)
- chat = TRUE;
- else
- chat = FALSE;
-
- if (swboard->conv == NULL) {
- if (chat)
- swboard->conv = purple_find_chat(account->gc, swboard->chat_id);
- else {
- swboard->conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM,
- who, account);
- if (swboard->conv == NULL)
- swboard->conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, who);
- }
- }
-
- if (chat)
- serv_got_chat_in(pc,
- purple_conv_chat_get_id(PURPLE_CONV_CHAT(swboard->conv)),
- who, PURPLE_MESSAGE_RECV|PURPLE_MESSAGE_SYSTEM, str,
- time(NULL));
- else
- serv_got_im(pc, who, str, PURPLE_MESSAGE_RECV|PURPLE_MESSAGE_SYSTEM,
- time(NULL));
- g_free(str);
-
-}
-
-/* TODO: Make these not be such duplicates of each other */
-static void
-got_wink_cb(MsnSlpCall *slpcall, const guchar *data, gsize size)
-{
- FILE *f = NULL;
- char *path = NULL;
- const char *who = slpcall->slplink->remote_user;
- purple_debug_info("msn", "Received wink from %s\n", who);
-
- if ((f = purple_mkstemp(&path, TRUE)) &&
- (fwrite(data, 1, size, f) == size)) {
- datacast_inform_user(slpcall->slplink->swboard,
- who,
- _("%s sent a wink. <a href='msn-wink://%s'>Click here to play it</a>"),
- path);
- } else {
- purple_debug_error("msn", "Couldn\'t create temp file to store wink\n");
- datacast_inform_user(slpcall->slplink->swboard,
- who,
- _("%s sent a wink, but it could not be saved"),
- NULL);
- }
- if (f)
- fclose(f);
- g_free(path);
-}
-
-static void
-got_voiceclip_cb(MsnSlpCall *slpcall, const guchar *data, gsize size)
-{
- FILE *f = NULL;
- char *path = NULL;
- const char *who = slpcall->slplink->remote_user;
- purple_debug_info("msn", "Received voice clip from %s\n", who);
-
- if ((f = purple_mkstemp(&path, TRUE)) &&
- (fwrite(data, 1, size, f) == size)) {
- datacast_inform_user(slpcall->slplink->swboard,
- who,
- _("%s sent a voice clip. <a href='audio://%s'>Click here to play it</a>"),
- path);
- } else {
- purple_debug_error("msn", "Couldn\'t create temp file to store sound\n");
- datacast_inform_user(slpcall->slplink->swboard,
- who,
- _("%s sent a voice clip, but it could not be saved"),
- NULL);
- }
- if (f)
- fclose(f);
- g_free(path);
-}
-
-void
-msn_p2p_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
-{
- MsnSession *session;
- MsnSlpLink *slplink;
- MsnP2PVersion p2p;
-
- session = cmdproc->servconn->session;
- slplink = msn_session_get_slplink(session, msg->remote_user);
-
- if (slplink->swboard == NULL)
- {
- /*
- * We will need swboard in order to change its flags. If its
- * NULL, something has probably gone wrong earlier on. I
- * didn't want to do this, but MSN 7 is somehow causing us
- * to crash here, I couldn't reproduce it to debug more,
- * and people are reporting bugs. Hopefully this doesn't
- * cause more crashes. Stu.
- */
- if (cmdproc->data == NULL)
- g_warning("msn_p2p_msg cmdproc->data was NULL\n");
- else {
- slplink->swboard = (MsnSwitchBoard *)cmdproc->data;
- slplink->swboard->slplinks = g_list_prepend(slplink->swboard->slplinks, slplink);
- }
- }
-
- p2p = msn_slplink_get_p2p_version(slplink);
- msg->part = msn_slpmsgpart_new_from_data(p2p, msg->body, msg->body_len);
-
- if (msg->part)
- msn_slplink_process_msg(slplink, msg->part);
- else
- purple_debug_warning("msn", "P2P message failed to parse.\n");
-}
-
-static void
-got_emoticon(MsnSlpCall *slpcall,
- const guchar *data, gsize size)
-{
- PurpleConversation *conv;
- MsnSwitchBoard *swboard;
-
- swboard = slpcall->slplink->swboard;
- conv = swboard->conv;
-
- if (conv) {
- /* FIXME: it would be better if we wrote the data as we received it
- instead of all at once, calling write multiple times and
- close once at the very end
- */
- purple_conv_custom_smiley_write(conv, slpcall->data_info, data, size);
- purple_conv_custom_smiley_close(conv, slpcall->data_info );
- }
- if (purple_debug_is_verbose())
- purple_debug_info("msn", "Got smiley: %s\n", slpcall->data_info);
-}
-
-void msn_emoticon_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
-{
- MsnSession *session;
- MsnSlpLink *slplink;
- MsnSwitchBoard *swboard;
- MsnObject *obj;
- char **tokens;
- char *smile, *body_str;
- const char *body, *who, *sha1;
- guint tok;
- size_t body_len;
-
- PurpleConversation *conv;
-
- session = cmdproc->servconn->session;
-
- if (!purple_account_get_bool(session->account, "custom_smileys", TRUE))
- return;
-
- swboard = cmdproc->data;
- conv = swboard->conv;
-
- body = msn_message_get_bin_data(msg, &body_len);
- if (!body || !body_len)
- return;
- body_str = g_strndup(body, body_len);
-
- /* MSN Messenger 7 may send more than one MSNObject in a single message...
- * Maybe 10 tokens is a reasonable max value. */
- tokens = g_strsplit(body_str, "\t", 10);
-
- g_free(body_str);
-
- for (tok = 0; tok < 9; tok += 2) {
- if (tokens[tok] == NULL || tokens[tok + 1] == NULL) {
- break;
- }
-
- smile = tokens[tok];
- obj = msn_object_new_from_string(purple_url_decode(tokens[tok + 1]));
-
- if (obj == NULL)
- break;
-
- who = msn_object_get_creator(obj);
- sha1 = msn_object_get_sha1(obj);
-
- slplink = msn_session_get_slplink(session, who);
- if (slplink->swboard != swboard) {
- if (slplink->swboard != NULL)
- /*
- * Apparently we're using a different switchboard now or
- * something? I don't know if this is normal, but it
- * definitely happens. So make sure the old switchboard
- * doesn't still have a reference to us.
- */
- slplink->swboard->slplinks = g_list_remove(slplink->swboard->slplinks, slplink);
- slplink->swboard = swboard;
- slplink->swboard->slplinks = g_list_prepend(slplink->swboard->slplinks, slplink);
- }
-
- /* If the conversation doesn't exist then this is a custom smiley
- * used in the first message in a MSN conversation: we need to create
- * the conversation now, otherwise the custom smiley won't be shown.
- * This happens because every GtkIMHtml has its own smiley tree: if
- * the conversation doesn't exist then we cannot associate the new
- * smiley with its GtkIMHtml widget. */
- if (!conv) {
- conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, session->account, who);
- }
-
- if (purple_conv_custom_smiley_add(conv, smile, "sha1", sha1, TRUE)) {
- msn_slplink_request_object(slplink, smile, got_emoticon, NULL, obj);
- }
-
- msn_object_destroy(obj);
- obj = NULL;
- who = NULL;
- sha1 = NULL;
- }
- g_strfreev(tokens);
-}
-
-void
-msn_datacast_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
-{
- GHashTable *body;
- const char *id;
- body = msn_message_get_hashtable_from_body(msg);
-
- id = g_hash_table_lookup(body, "ID");
-
- if (!strcmp(id, "1")) {
- /* Nudge */
- PurpleAccount *account;
- const char *user;
-
- account = cmdproc->session->account;
- user = msg->remote_user;
-
- if (cmdproc->servconn->type == MSN_SERVCONN_SB) {
- MsnSwitchBoard *swboard = cmdproc->data;
- if (swboard->current_users > 1 ||
- ((swboard->conv != NULL) &&
- purple_conversation_get_type(swboard->conv) == PURPLE_CONV_TYPE_CHAT))
- purple_prpl_got_attention_in_chat(account->gc, swboard->chat_id, user, MSN_NUDGE);
-
- else
- purple_prpl_got_attention(account->gc, user, MSN_NUDGE);
- } else {
- purple_prpl_got_attention(account->gc, user, MSN_NUDGE);
- }
-
- } else if (!strcmp(id, "2")) {
- /* Wink */
- MsnSession *session;
- MsnSlpLink *slplink;
- MsnObject *obj;
- const char *who;
- const char *data;
-
- session = cmdproc->session;
-
- data = g_hash_table_lookup(body, "Data");
- obj = msn_object_new_from_string(data);
- who = msn_object_get_creator(obj);
-
- slplink = msn_session_get_slplink(session, who);
- msn_slplink_request_object(slplink, data, got_wink_cb, NULL, obj);
-
- msn_object_destroy(obj);
-
-
- } else if (!strcmp(id, "3")) {
- /* Voiceclip */
- MsnSession *session;
- MsnSlpLink *slplink;
- MsnObject *obj;
- const char *who;
- const char *data;
-
- session = cmdproc->session;
-
- data = g_hash_table_lookup(body, "Data");
- obj = msn_object_new_from_string(data);
- who = msn_object_get_creator(obj);
-
- slplink = msn_session_get_slplink(session, who);
- msn_slplink_request_object(slplink, data, got_voiceclip_cb, NULL, obj);
-
- msn_object_destroy(obj);
-
- } else if (!strcmp(id, "4")) {
- /* Action */
-
- } else {
- purple_debug_warning("msn", "Got unknown datacast with ID %s.\n", id);
- }
-
- g_hash_table_destroy(body);
-}
-
-void
-msn_invite_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
-{
- GHashTable *body;
- const gchar *command;
- const gchar *cookie;
- gboolean accepted = FALSE;
-
- g_return_if_fail(cmdproc != NULL);
- g_return_if_fail(msg != NULL);
-
- body = msn_message_get_hashtable_from_body(msg);
-
- if (body == NULL) {
- purple_debug_warning("msn",
- "Unable to parse invite msg body.\n");
- return;
- }
-
- /*
- * GUID is NOT always present but Invitation-Command and Invitation-Cookie
- * are mandatory.
- */
- command = g_hash_table_lookup(body, "Invitation-Command");
- cookie = g_hash_table_lookup(body, "Invitation-Cookie");
-
- if (command == NULL || cookie == NULL) {
- purple_debug_warning("msn",
- "Invalid invitation message: either Invitation-Command "
- "or Invitation-Cookie is missing or invalid.\n"
- );
- return;
-
- } else if (!strcmp(command, "INVITE")) {
- const gchar *guid = g_hash_table_lookup(body, "Application-GUID");
-
- if (guid == NULL) {
- purple_debug_warning("msn",
- "Invite msg missing Application-GUID.\n");
-
- accepted = TRUE;
-
- } else if (!strcmp(guid, MSN_FT_GUID)) {
-
- } else if (!strcmp(guid, "{02D3C01F-BF30-4825-A83A-DE7AF41648AA}")) {
- purple_debug_info("msn", "Computer call\n");
-
- if (cmdproc->session) {
- PurpleConversation *conv = NULL;
- gchar *from = msg->remote_user;
- gchar *buf = NULL;
-
- if (from)
- conv = purple_find_conversation_with_account(
- PURPLE_CONV_TYPE_IM, from,
- cmdproc->session->account);
- if (conv)
- buf = g_strdup_printf(
- _("%s sent you a voice chat "
- "invite, which is not yet "
- "supported."), from);
- if (buf) {
- purple_conversation_write(conv, NULL, buf,
- PURPLE_MESSAGE_SYSTEM |
- PURPLE_MESSAGE_NOTIFY,
- time(NULL));
- g_free(buf);
- }
- }
- } else {
- const gchar *application = g_hash_table_lookup(body, "Application-Name");
- purple_debug_warning("msn", "Unhandled invite msg with GUID %s: %s.\n",
- guid, application ? application : "(null)");
- }
-
- if (!accepted) {
- MsnSwitchBoard *swboard = cmdproc->data;
- char *text;
- MsnMessage *cancel;
-
- cancel = msn_message_new(MSN_MSG_TEXT);
- msn_message_set_content_type(cancel, "text/x-msmsgsinvite");
- msn_message_set_charset(cancel, "UTF-8");
- msn_message_set_flag(cancel, 'U');
-
- text = g_strdup_printf("Invitation-Command: CANCEL\r\n"
- "Invitation-Cookie: %s\r\n"
- "Cancel-Code: REJECT_NOT_INSTALLED\r\n",
- cookie);
- msn_message_set_bin_data(cancel, text, strlen(text));
- g_free(text);
-
- msn_switchboard_send_msg(swboard, cancel, TRUE);
- msn_message_unref(cancel);
- }
-
- } else if (!strcmp(command, "CANCEL")) {
- const gchar *code = g_hash_table_lookup(body, "Cancel-Code");
- purple_debug_info("msn", "MSMSGS invitation cancelled: %s.\n",
- code ? code : "no reason given");
-
- } else {
- /*
- * Some other already established invitation session.
- * Can be retrieved by Invitation-Cookie.
- */
- }
-
- g_hash_table_destroy(body);
-}
-
-/* Only called from chats. Handwritten messages for IMs come as a SLP message */
-void
-msn_handwritten_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
-{
- const char *body;
- size_t body_len;
-
- body = msn_message_get_bin_data(msg, &body_len);
- msn_switchboard_show_ink(cmdproc->data, msg->remote_user, body);
-}
-
diff --git a/libpurple/protocols/msn/msg.h b/libpurple/protocols/msn/msg.h
deleted file mode 100644
index 845a839466..0000000000
--- a/libpurple/protocols/msn/msg.h
+++ /dev/null
@@ -1,325 +0,0 @@
-/**
- * @file msg.h Message functions
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-#ifndef MSN_MSG_H
-#define MSN_MSG_H
-
-typedef struct _MsnMessage MsnMessage;
-
-/*
-typedef enum
-{
- MSN_MSG_NORMAL,
- MSN_MSG_SLP_SB,
- MSN_MSG_SLP_DC
-} MsnMsgType;
-*/
-
-typedef enum
-{
- MSN_MSG_UNKNOWN,
- MSN_MSG_TEXT,
- MSN_MSG_TYPING,
- MSN_MSG_CAPS,
- MSN_MSG_SLP,
- MSN_MSG_NUDGE
-} MsnMsgType;
-
-typedef enum
-{
- MSN_MSG_ERROR_NONE, /**< No error. */
- MSN_MSG_ERROR_TIMEOUT, /**< The message timedout. */
- MSN_MSG_ERROR_NAK, /**< The message could not be sent. */
- MSN_MSG_ERROR_SB, /**< The error comes from the switchboard. */
- MSN_MSG_ERROR_UNKNOWN /**< An unknown error occurred. */
-} MsnMsgErrorType;
-
-#include "command.h"
-#include "session.h"
-#include "transaction.h"
-#include "user.h"
-#include "slpmsg.h"
-#include "slpmsg_part.h"
-
-typedef void (*MsnMsgCb)(MsnMessage *, void *data);
-
-#define MSG_BODY_DEM "\r\n\r\n"
-#define MSG_LINE_DEM "\r\n"
-
-#define MSG_OIM_BODY_DEM "\n\n"
-#define MSG_OIM_LINE_DEM "\n"
-
-/**
- * A message.
- */
-struct _MsnMessage
-{
- guint ref_count; /**< The reference count. */
-
- MsnMsgType type;
-
- MsnSlpMessagePart *part;
-
- char *remote_user;
- char flag;
-
- char *content_type;
- char *charset;
- char *body;
- gsize body_len;
- guint total_chunks; /**< How many chunks in this multi-part message */
- guint received_chunks; /**< How many chunks we've received so far */
-
- GHashTable *header_table;
- GList *header_list;
-
- gboolean ack_ref; /**< A flag that states if this message has
- been ref'ed for using it in a callback. */
-
- MsnCommand *cmd;
-
- MsnMsgCb ack_cb; /**< The callback to call when we receive an ACK of this
- message. */
- MsnMsgCb nak_cb; /**< The callback to call when we receive a NAK of this
- message. */
- void *ack_data; /**< The data used by callbacks. */
-
- guint32 retries;
-};
-
-/**
- * Creates a new, empty message.
- *
- * @return A new message.
- */
-MsnMessage *msn_message_new(MsnMsgType type);
-
-/**
- * Creates a new, empty MSNSLP message.
- *
- * @return A new MSNSLP message.
- */
-MsnMessage *msn_message_new_msnslp(void);
-
-/**
- * Creates a new nudge message.
- *
- * @return A new nudge message.
- */
-MsnMessage *msn_message_new_nudge(void);
-
-/**
- * Creates a new plain message.
- *
- * @return A new plain message.
- */
-MsnMessage *msn_message_new_plain(const char *message);
-
-/**
- * Creates a new message based off a command.
- *
- * @param session The MSN session.
- * @param cmd The command.
- *
- * @return The new message.
- */
-MsnMessage *msn_message_new_from_cmd(MsnSession *session, MsnCommand *cmd);
-
-/**
- * Parses the payload of a message.
- *
- * @param msg The message.
- * @param payload The payload.
- * @param payload_len The length of the payload.
- */
-void msn_message_parse_payload(MsnMessage *msg, const char *payload,
- size_t payload_len,
- const char *line_dem,const char *body_dem);
-
-/**
- * Increments the reference count on a message.
- *
- * @param msg The message.
- *
- * @return @a msg
- */
-MsnMessage *msn_message_ref(MsnMessage *msg);
-
-/**
- * Decrements the reference count on a message.
- *
- * This will destroy the structure if the count hits 0.
- *
- * @param msg The message.
- *
- * @return @a msg, or @c NULL if the new count is 0.
- */
-void msn_message_unref(MsnMessage *msg);
-
-/**
- * Generates the payload data of a message.
- *
- * @param msg The message.
- * @param ret_size The returned size of the payload.
- *
- * @return The payload data of the message.
- */
-char *msn_message_gen_payload(MsnMessage *msg, size_t *ret_size);
-
-/**
- * Sets the flag for an outgoing message.
- *
- * @param msg The message.
- * @param flag The flag.
- */
-void msn_message_set_flag(MsnMessage *msg, char flag);
-
-/**
- * Returns the flag for an outgoing message.
- *
- * @param msg The message.
- *
- * @return The flag.
- */
-char msn_message_get_flag(const MsnMessage *msg);
-
-/**
- * Sets the binary content of the message.
- *
- * @param msg The message.
- * @param data The binary data.
- * @param len The length of the data.
- */
-void msn_message_set_bin_data(MsnMessage *msg, const void *data, size_t len);
-
-/**
- * Returns the binary content of the message.
- *
- * @param msg The message.
- * @param len The returned length of the data.
- *
- * @return The binary data.
- */
-const void *msn_message_get_bin_data(const MsnMessage *msg, size_t *len);
-
-/**
- * Sets the content type in a message.
- *
- * @param msg The message.
- * @param type The content-type.
- */
-void msn_message_set_content_type(MsnMessage *msg, const char *type);
-
-/**
- * Returns the content type in a message.
- *
- * @param msg The message.
- *
- * @return The content-type.
- */
-const char *msn_message_get_content_type(const MsnMessage *msg);
-
-/**
- * Sets the charset in a message.
- *
- * @param msg The message.
- * @param charset The charset.
- */
-void msn_message_set_charset(MsnMessage *msg, const char *charset);
-
-/**
- * Returns the charset in a message.
- *
- * @param msg The message.
- *
- * @return The charset.
- */
-const char *msn_message_get_charset(const MsnMessage *msg);
-
-/**
- * Sets a header in a message.
- *
- * @param msg The message.
- * @param header The header name.
- * @param value The header value.
- */
-void msn_message_set_header(MsnMessage *msg, const char *name,
- const char *value);
-
-/**
- * Returns the value of a header from a message.
- *
- * @param msg The message.
- * @param header The header value.
- *
- * @return The value, or @c NULL if not found.
- */
-const char *msn_message_get_header_value(const MsnMessage *msg, const char *name);
-
-/**
- * Parses the body and returns it in the form of a hashtable.
- *
- * @param msg The message.
- *
- * @return The resulting hashtable.
- */
-GHashTable *msn_message_get_hashtable_from_body(const MsnMessage *msg);
-
-void msn_message_show_readable(MsnMessage *msg, const char *info,
- gboolean text_body);
-
-char *msn_message_to_string(MsnMessage *msg);
-
-void msn_plain_msg(MsnCmdProc *cmdproc, MsnMessage *msg);
-
-void msn_control_msg(MsnCmdProc *cmdproc, MsnMessage *msg);
-
-/**
- * Processes peer to peer messages.
- *
- * @param cmdproc The command processor.
- * @param msg The message.
- */
-void msn_p2p_msg(MsnCmdProc *cmdproc, MsnMessage *msg);
-
-/**
- * Processes emoticon messages.
- *
- * @param cmdproc The command processor.
- * @param msg The message.
- */
-void msn_emoticon_msg(MsnCmdProc *cmdproc, MsnMessage *msg);
-
-void msn_datacast_msg(MsnCmdProc *cmdproc, MsnMessage *msg);
-
-/**
- * Processes INVITE messages.
- *
- * @param cmdproc The command processor.
- * @param msg The message.
- */
-void msn_invite_msg(MsnCmdProc *cmdproc, MsnMessage *msg);
-
-void msn_handwritten_msg(MsnCmdProc *cmdproc, MsnMessage *msg);
-
-#endif /* MSN_MSG_H */
diff --git a/libpurple/protocols/msn/msn.c b/libpurple/protocols/msn/msn.c
deleted file mode 100644
index 09ead6b945..0000000000
--- a/libpurple/protocols/msn/msn.c
+++ /dev/null
@@ -1,3069 +0,0 @@
-/**
- * @file msn.c The MSN protocol plugin
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-#define PHOTO_SUPPORT 1
-
-#include "internal.h"
-
-#include "debug.h"
-#include "request.h"
-
-#include "accountopt.h"
-#include "contact.h"
-#include "msg.h"
-#include "page.h"
-#include "pluginpref.h"
-#include "prefs.h"
-#include "session.h"
-#include "smiley.h"
-#include "state.h"
-#include "util.h"
-#include "cmds.h"
-#include "core.h"
-#include "prpl.h"
-#include "msnutils.h"
-#include "version.h"
-
-#include "error.h"
-#include "msg.h"
-#include "switchboard.h"
-#include "notification.h"
-#include "slplink.h"
-
-#if PHOTO_SUPPORT
-#define MAX_HTTP_BUDDYICON_BYTES (200 * 1024)
-#include "imgstore.h"
-#endif
-
-typedef struct
-{
- PurpleConnection *gc;
- const char *passport;
-
-} MsnMobileData;
-
-typedef struct
-{
- PurpleConnection *gc;
- char *name;
-
-} MsnGetInfoData;
-
-typedef struct
-{
- MsnGetInfoData *info_data;
- char *stripped;
- char *url_buffer;
- PurpleNotifyUserInfo *user_info;
- char *photo_url_text;
-
-} MsnGetInfoStepTwoData;
-
-typedef struct
-{
- PurpleConnection *gc;
- const char *who;
- char *msg;
- PurpleMessageFlags flags;
- time_t when;
-} MsnIMData;
-
-typedef struct
-{
- char *smile;
- PurpleSmiley *ps;
- MsnObject *obj;
-} MsnEmoticon;
-
-static const char *
-msn_normalize(const PurpleAccount *account, const char *str)
-{
- static char buf[BUF_LEN];
- char *tmp;
-
- g_return_val_if_fail(str != NULL, NULL);
-
- tmp = g_strchomp(g_utf8_strdown(str, -1));
- g_snprintf(buf, sizeof(buf), "%s%s", tmp,
- (strchr(tmp, '@') ? "" : "@hotmail.com"));
- g_free(tmp);
-
- return buf;
-}
-
-static gboolean
-msn_send_attention(PurpleConnection *gc, const char *username, guint type)
-{
- MsnMessage *msg;
- MsnSession *session;
- MsnSwitchBoard *swboard;
-
- msg = msn_message_new_nudge();
- session = gc->proto_data;
- swboard = msn_session_get_swboard(session, username, MSN_SB_FLAG_IM);
-
- msn_switchboard_send_msg(swboard, msg, TRUE);
- msn_message_unref(msg);
-
- return TRUE;
-}
-
-static GList *
-msn_attention_types(PurpleAccount *account)
-{
- static GList *list = NULL;
-
- if (!list) {
- list = g_list_append(list, purple_attention_type_new("Nudge", _("Nudge"),
- _("%s has nudged you!"), _("Nudging %s...")));
- }
-
- return list;
-}
-
-static GHashTable *
-msn_get_account_text_table(PurpleAccount *unused)
-{
- GHashTable *table;
-
- table = g_hash_table_new(g_str_hash, g_str_equal);
-
- g_hash_table_insert(table, "login_label", (gpointer)_("Email Address..."));
-
- return table;
-}
-
-static PurpleCmdRet
-msn_cmd_nudge(PurpleConversation *conv, const gchar *cmd, gchar **args, gchar **error, void *data)
-{
- PurpleAccount *account = purple_conversation_get_account(conv);
- PurpleConnection *gc = purple_account_get_connection(account);
- const gchar *username;
-
- username = purple_conversation_get_name(conv);
-
- purple_prpl_send_attention(gc, username, MSN_NUDGE);
-
- return PURPLE_CMD_RET_OK;
-}
-
-struct public_alias_closure
-{
- PurpleAccount *account;
- gpointer success_cb;
- gpointer failure_cb;
-};
-
-static gboolean
-set_public_alias_length_error(gpointer data)
-{
- struct public_alias_closure *closure = data;
- PurpleSetPublicAliasFailureCallback failure_cb = closure->failure_cb;
-
- failure_cb(closure->account, _("Your new MSN friendly name is too long."));
- g_free(closure);
-
- return FALSE;
-}
-
-static void
-prp_success_cb(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
- const char *type, *friendlyname;
- struct public_alias_closure *closure;
-
- g_return_if_fail(cmd->param_count >= 3);
- type = cmd->params[1];
- g_return_if_fail(!strcmp(type, "MFN"));
-
- closure = cmd->trans->data;
- friendlyname = purple_url_decode(cmd->params[2]);
-
- msn_update_contact(cmdproc->session, "Me", MSN_UPDATE_DISPLAY, friendlyname);
-
- purple_connection_set_display_name(
- purple_account_get_connection(closure->account),
- friendlyname);
- purple_account_set_string(closure->account, "display-name", friendlyname);
-
- if (closure->success_cb) {
- PurpleSetPublicAliasSuccessCallback success_cb = closure->success_cb;
- success_cb(closure->account, friendlyname);
- }
-}
-
-static void
-prp_error_cb(MsnCmdProc *cmdproc, MsnTransaction *trans, int error)
-{
- struct public_alias_closure *closure = trans->data;
- PurpleSetPublicAliasFailureCallback failure_cb = closure->failure_cb;
- gboolean debug;
- const char *error_text;
-
- error_text = msn_error_get_text(error, &debug);
- failure_cb(closure->account, error_text);
-}
-
-static void
-prp_timeout_cb(MsnCmdProc *cmdproc, MsnTransaction *trans)
-{
- struct public_alias_closure *closure = trans->data;
- PurpleSetPublicAliasFailureCallback failure_cb = closure->failure_cb;
- failure_cb(closure->account, _("Connection Timeout"));
-}
-
-void
-msn_set_public_alias(PurpleConnection *pc, const char *alias,
- PurpleSetPublicAliasSuccessCallback success_cb,
- PurpleSetPublicAliasFailureCallback failure_cb)
-{
- MsnCmdProc *cmdproc;
- MsnSession *session;
- MsnTransaction *trans;
- PurpleAccount *account;
- char real_alias[BUDDY_ALIAS_MAXLEN + 1];
- struct public_alias_closure *closure;
-
- session = purple_connection_get_protocol_data(pc);
- cmdproc = session->notification->cmdproc;
- account = purple_connection_get_account(pc);
-
- if (alias && *alias) {
- if (!msn_encode_spaces(alias, real_alias, BUDDY_ALIAS_MAXLEN + 1)) {
- if (failure_cb) {
- struct public_alias_closure *closure =
- g_new0(struct public_alias_closure, 1);
- closure->account = account;
- closure->failure_cb = failure_cb;
- purple_timeout_add(0, set_public_alias_length_error, closure);
- } else {
- purple_notify_error(pc, NULL,
- _("Your new MSN friendly name is too long."),
- NULL);
- }
- return;
- }
-
- if (real_alias[0] == '\0')
- g_strlcpy(real_alias, purple_account_get_username(account), sizeof(real_alias));
- } else
- g_strlcpy(real_alias, purple_account_get_username(account), sizeof(real_alias));
-
- closure = g_new0(struct public_alias_closure, 1);
- closure->account = account;
- closure->success_cb = success_cb;
- closure->failure_cb = failure_cb;
-
- trans = msn_transaction_new(cmdproc, "PRP", "MFN %s", real_alias);
- msn_transaction_set_data(trans, closure);
- msn_transaction_set_data_free(trans, g_free);
- msn_transaction_add_cb(trans, "PRP", prp_success_cb);
- if (failure_cb) {
- msn_transaction_set_error_cb(trans, prp_error_cb);
- msn_transaction_set_timeout_cb(trans, prp_timeout_cb);
- }
- msn_cmdproc_send_trans(cmdproc, trans);
-}
-
-static gboolean
-get_public_alias_cb(gpointer data)
-{
- struct public_alias_closure *closure = data;
- PurpleGetPublicAliasSuccessCallback success_cb = closure->success_cb;
- const char *alias;
-
- alias = purple_account_get_string(closure->account, "display-name",
- purple_account_get_username(closure->account));
- success_cb(closure->account, alias);
- g_free(closure);
-
- return FALSE;
-}
-
-static void
-msn_get_public_alias(PurpleConnection *pc,
- PurpleGetPublicAliasSuccessCallback success_cb,
- PurpleGetPublicAliasFailureCallback failure_cb)
-{
- struct public_alias_closure *closure = g_new0(struct public_alias_closure, 1);
- PurpleAccount *account = purple_connection_get_account(pc);
-
- closure->account = account;
- closure->success_cb = success_cb;
- purple_timeout_add(0, get_public_alias_cb, closure);
-}
-
-static void
-msn_act_id(PurpleConnection *gc, const char *entry)
-{
- msn_set_public_alias(gc, entry, NULL, NULL);
-}
-
-static void
-msn_set_prp(PurpleConnection *gc, const char *type, const char *entry)
-{
- MsnCmdProc *cmdproc;
- MsnSession *session;
- MsnTransaction *trans;
-
- session = gc->proto_data;
- cmdproc = session->notification->cmdproc;
-
- if (entry == NULL || *entry == '\0')
- {
- trans = msn_transaction_new(cmdproc, "PRP", "%s", type);
- }
- else
- {
- trans = msn_transaction_new(cmdproc, "PRP", "%s %s", type,
- purple_url_encode(entry));
- }
- msn_cmdproc_send_trans(cmdproc, trans);
-}
-
-static void
-msn_set_home_phone_cb(PurpleConnection *gc, const char *entry)
-{
- msn_set_prp(gc, "PHH", entry);
-}
-
-static void
-msn_set_work_phone_cb(PurpleConnection *gc, const char *entry)
-{
- msn_set_prp(gc, "PHW", entry);
-}
-
-static void
-msn_set_mobile_phone_cb(PurpleConnection *gc, const char *entry)
-{
- msn_set_prp(gc, "PHM", entry);
-}
-
-static void
-enable_msn_pages_cb(PurpleConnection *gc)
-{
- msn_set_prp(gc, "MOB", "Y");
-}
-
-static void
-disable_msn_pages_cb(PurpleConnection *gc)
-{
- msn_set_prp(gc, "MOB", "N");
-}
-
-static void
-send_to_mobile(PurpleConnection *gc, const char *who, const char *entry)
-{
- MsnTransaction *trans;
- MsnSession *session;
- MsnCmdProc *cmdproc;
- MsnPage *page;
- MsnMessage *msg;
- MsnUser *user;
- char *payload = NULL;
- const char *mobile_number = NULL;
- gsize payload_len;
-
- session = gc->proto_data;
- cmdproc = session->notification->cmdproc;
-
- page = msn_page_new();
- msn_page_set_body(page, entry);
-
- payload = msn_page_gen_payload(page, &payload_len);
-
- if ((user = msn_userlist_find_user(session->userlist, who)) &&
- (mobile_number = msn_user_get_mobile_phone(user)) &&
- mobile_number[0] == '+') {
- /* if msn_user_get_mobile_phone() has a + in front, it's a number
- that from the buddy's contact card */
- trans = msn_transaction_new(cmdproc, "PGD", "tel:%s 1 %" G_GSIZE_FORMAT,
- mobile_number, payload_len);
- } else {
- /* otherwise we send to whatever phone number the buddy registered
- with msn */
- trans = msn_transaction_new(cmdproc, "PGD", "%s 1 %" G_GSIZE_FORMAT,
- who, payload_len);
- }
-
- msn_transaction_set_payload(trans, payload, payload_len);
- g_free(payload);
-
- msg = msn_message_new_plain(entry);
- msn_transaction_set_data(trans, msg);
-
- msn_page_destroy(page);
-
- msn_cmdproc_send_trans(cmdproc, trans);
-}
-
-static void
-send_to_mobile_cb(MsnMobileData *data, const char *entry)
-{
- send_to_mobile(data->gc, data->passport, entry);
- g_free(data);
-}
-
-static void
-close_mobile_page_cb(MsnMobileData *data, const char *entry)
-{
- g_free(data);
-}
-
-/* -- */
-
-static void
-msn_show_set_friendly_name(PurplePluginAction *action)
-{
- PurpleConnection *gc;
- PurpleAccount *account;
- char *tmp;
-
- gc = (PurpleConnection *) action->context;
- account = purple_connection_get_account(gc);
-
- tmp = g_strdup_printf(_("Set friendly name for %s."),
- purple_account_get_username(account));
- purple_request_input(gc, _("Set Friendly Name"), tmp,
- _("This is the name that other MSN buddies will "
- "see you as."),
- purple_connection_get_display_name(gc), FALSE, FALSE, NULL,
- _("OK"), G_CALLBACK(msn_act_id),
- _("Cancel"), NULL,
- account, NULL, NULL,
- gc);
- g_free(tmp);
-}
-
-typedef struct MsnLocationData {
- PurpleAccount *account;
- MsnSession *session;
- PurpleRequestFieldGroup *group;
-} MsnLocationData;
-
-static void
-update_endpoint_cb(MsnLocationData *data, PurpleRequestFields *fields)
-{
- PurpleAccount *account;
- MsnSession *session;
- const char *old_name;
- const char *name;
- GList *others;
-
- session = data->session;
- account = data->account;
-
- /* Update the current location's name */
- old_name = purple_account_get_string(account, "endpoint-name", NULL);
- name = purple_request_fields_get_string(fields, "endpoint-name");
- if (!g_str_equal(old_name, name)) {
- purple_account_set_string(account, "endpoint-name", name);
- msn_notification_send_uux_private_endpointdata(session);
- }
-
- /* Sign out other locations */
- for (others = purple_request_field_group_get_fields(data->group);
- others;
- others = g_list_next(others)) {
- PurpleRequestField *field = others->data;
- if (purple_request_field_get_type(field) != PURPLE_REQUEST_FIELD_BOOLEAN)
- continue;
- if (purple_request_field_bool_get_value(field)) {
- const char *id = purple_request_field_get_id(field);
- char *user;
- purple_debug_info("msn", "Disconnecting Endpoint %s\n", id);
-
- user = g_strdup_printf("%s;%s", purple_account_get_username(account), id);
- msn_notification_send_uun(session, user, MSN_UNIFIED_NOTIFICATION_MPOP, "goawyplzthxbye");
- g_free(user);
- }
- }
-
- g_free(data);
-}
-
-static void
-msn_show_locations(PurplePluginAction *action)
-{
- PurpleConnection *pc;
- PurpleAccount *account;
- MsnSession *session;
- PurpleRequestFields *fields;
- PurpleRequestFieldGroup *group;
- PurpleRequestField *field;
- gboolean have_other_endpoints;
- GSList *l;
- MsnLocationData *data;
-
- pc = (PurpleConnection *)action->context;
- account = purple_connection_get_account(pc);
- session = purple_connection_get_protocol_data(pc);
-
- fields = purple_request_fields_new();
-
- group = purple_request_field_group_new(_("This Location"));
- purple_request_fields_add_group(fields, group);
- field = purple_request_field_label_new("endpoint-label", _("This is the name that identifies this location"));
- purple_request_field_group_add_field(group, field);
- field = purple_request_field_string_new("endpoint-name",
- _("Name"),
- purple_account_get_string(account, "endpoint-name", NULL),
- FALSE);
- purple_request_field_set_required(field, TRUE);
- purple_request_field_group_add_field(group, field);
-
- group = purple_request_field_group_new(_("Other Locations"));
- purple_request_fields_add_group(fields, group);
-
- have_other_endpoints = FALSE;
- for (l = session->user->endpoints; l; l = l->next) {
- MsnUserEndpoint *ep = l->data;
-
- if (ep->id[0] != '\0' && strncasecmp(ep->id + 1, session->guid, 36) == 0)
- /* Don't add myself to the list */
- continue;
-
- if (!have_other_endpoints) {
- /* We do in fact have an endpoint other than ourselves... let's
- add a label */
- field = purple_request_field_label_new("others-label",
- _("You can sign out from other locations here"));
- purple_request_field_group_add_field(group, field);
- }
-
- have_other_endpoints = TRUE;
- field = purple_request_field_bool_new(ep->id, ep->name, FALSE);
- purple_request_field_group_add_field(group, field);
- }
- if (!have_other_endpoints) {
- /* TODO: Due to limitations in our current request field API, the
- following string will show up with a trailing colon. This should
- be fixed either by adding an "include_colon" boolean, or creating
- a separate purple_request_field_label_new_without_colon function,
- or by never automatically adding the colon and requiring that
- callers add the colon themselves. */
- field = purple_request_field_label_new("others-label", _("You are not signed in from any other locations."));
- purple_request_field_group_add_field(group, field);
- }
-
- data = g_new0(MsnLocationData, 1);
- data->account = account;
- data->session = session;
- data->group = group;
-
- purple_request_fields(pc, NULL, NULL, NULL,
- fields,
- _("OK"), G_CALLBACK(update_endpoint_cb),
- _("Cancel"), G_CALLBACK(g_free),
- account, NULL, NULL,
- data);
-}
-
-static void
-enable_mpop_cb(PurpleConnection *pc)
-{
- MsnSession *session = purple_connection_get_protocol_data(pc);
-
- purple_debug_info("msn", "Enabling MPOP\n");
-
- session->enable_mpop = TRUE;
- msn_annotate_contact(session, "Me", "MSN.IM.MPOP", "1", NULL);
-
- purple_prpl_got_account_actions(purple_connection_get_account(pc));
-}
-
-static void
-disable_mpop_cb(PurpleConnection *pc)
-{
- PurpleAccount *account = purple_connection_get_account(pc);
- MsnSession *session = purple_connection_get_protocol_data(pc);
- GSList *l;
-
- purple_debug_info("msn", "Disabling MPOP\n");
-
- session->enable_mpop = FALSE;
- msn_annotate_contact(session, "Me", "MSN.IM.MPOP", "0", NULL);
-
- for (l = session->user->endpoints; l; l = l->next) {
- MsnUserEndpoint *ep = l->data;
- char *user;
-
- if (ep->id[0] != '\0' && strncasecmp(ep->id + 1, session->guid, 36) == 0)
- /* Don't kick myself */
- continue;
-
- purple_debug_info("msn", "Disconnecting Endpoint %s\n", ep->id);
-
- user = g_strdup_printf("%s;%s", purple_account_get_username(account), ep->id);
- msn_notification_send_uun(session, user, MSN_UNIFIED_NOTIFICATION_MPOP, "goawyplzthxbye");
- g_free(user);
- }
-
- purple_prpl_got_account_actions(account);
-}
-
-static void
-msn_show_set_mpop(PurplePluginAction *action)
-{
- PurpleConnection *pc;
-
- pc = (PurpleConnection *)action->context;
-
- purple_request_action(pc, NULL, _("Allow multiple logins?"),
- _("Do you want to allow or disallow connecting from "
- "multiple locations simultaneously?"),
- PURPLE_DEFAULT_ACTION_NONE,
- purple_connection_get_account(pc), NULL, NULL,
- pc, 3,
- _("Allow"), G_CALLBACK(enable_mpop_cb),
- _("Disallow"), G_CALLBACK(disable_mpop_cb),
- _("Cancel"), NULL);
-}
-
-static void
-msn_show_set_home_phone(PurplePluginAction *action)
-{
- PurpleConnection *gc;
- MsnSession *session;
-
- gc = (PurpleConnection *) action->context;
- session = gc->proto_data;
-
- purple_request_input(gc, NULL, _("Set your home phone number."), NULL,
- msn_user_get_home_phone(session->user), FALSE, FALSE, NULL,
- _("OK"), G_CALLBACK(msn_set_home_phone_cb),
- _("Cancel"), NULL,
- purple_connection_get_account(gc), NULL, NULL,
- gc);
-}
-
-static void
-msn_show_set_work_phone(PurplePluginAction *action)
-{
- PurpleConnection *gc;
- MsnSession *session;
-
- gc = (PurpleConnection *) action->context;
- session = gc->proto_data;
-
- purple_request_input(gc, NULL, _("Set your work phone number."), NULL,
- msn_user_get_work_phone(session->user), FALSE, FALSE, NULL,
- _("OK"), G_CALLBACK(msn_set_work_phone_cb),
- _("Cancel"), NULL,
- purple_connection_get_account(gc), NULL, NULL,
- gc);
-}
-
-static void
-msn_show_set_mobile_phone(PurplePluginAction *action)
-{
- PurpleConnection *gc;
- MsnSession *session;
-
- gc = (PurpleConnection *) action->context;
- session = gc->proto_data;
-
- purple_request_input(gc, NULL, _("Set your mobile phone number."), NULL,
- msn_user_get_mobile_phone(session->user), FALSE, FALSE, NULL,
- _("OK"), G_CALLBACK(msn_set_mobile_phone_cb),
- _("Cancel"), NULL,
- purple_connection_get_account(gc), NULL, NULL,
- gc);
-}
-
-static void
-msn_show_set_mobile_pages(PurplePluginAction *action)
-{
- PurpleConnection *gc;
-
- gc = (PurpleConnection *) action->context;
-
- purple_request_action(gc, NULL, _("Allow MSN Mobile pages?"),
- _("Do you want to allow or disallow people on "
- "your buddy list to send you MSN Mobile pages "
- "to your cell phone or other mobile device?"),
- PURPLE_DEFAULT_ACTION_NONE,
- purple_connection_get_account(gc), NULL, NULL,
- gc, 3,
- _("Allow"), G_CALLBACK(enable_msn_pages_cb),
- _("Disallow"), G_CALLBACK(disable_msn_pages_cb),
- _("Cancel"), NULL);
-}
-
-/* QuLogic: Disabled until confirmed correct. */
-#if 0
-static void
-msn_show_blocked_text(PurplePluginAction *action)
-{
- PurpleConnection *pc = (PurpleConnection *) action->context;
- MsnSession *session;
- char *title;
-
- session = pc->proto_data;
-
- title = g_strdup_printf(_("Blocked Text for %s"), session->account->username);
- if (session->blocked_text == NULL) {
- purple_notify_formatted(pc, title, title, NULL, _("No text is blocked for this account."), NULL, NULL);
- } else {
- char *blocked_text;
- blocked_text = g_strdup_printf(_("MSN servers are currently blocking the following regular expressions:<br/>%s"),
- session->blocked_text);
-
- purple_notify_formatted(pc, title, title, NULL, blocked_text, NULL, NULL);
- g_free(blocked_text);
- }
- g_free(title);
-}
-#endif
-
-static void
-msn_show_hotmail_inbox(PurplePluginAction *action)
-{
- PurpleConnection *gc;
- MsnSession *session;
-
- gc = (PurpleConnection *) action->context;
- session = gc->proto_data;
-
- if (!session->passport_info.email_enabled) {
- purple_notify_error(gc, NULL,
- _("This account does not have email enabled."), NULL);
- return;
- }
-
- /** apparently the correct value is 777, use 750 as a failsafe */
- if ((session->passport_info.mail_url == NULL)
- || (time (NULL) - session->passport_info.mail_timestamp >= 750)) {
- MsnTransaction *trans;
- MsnCmdProc *cmdproc;
-
- cmdproc = session->notification->cmdproc;
-
- trans = msn_transaction_new(cmdproc, "URL", "%s", "INBOX");
- msn_transaction_set_data(trans, GUINT_TO_POINTER(TRUE));
-
- msn_cmdproc_send_trans(cmdproc, trans);
-
- } else
- purple_notify_uri(gc, session->passport_info.mail_url);
-}
-
-static void
-show_send_to_mobile_cb(PurpleBlistNode *node, gpointer ignored)
-{
- PurpleBuddy *buddy;
- PurpleConnection *gc;
- MsnMobileData *data;
- PurpleAccount *account;
- const char *name;
-
- g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
-
- buddy = (PurpleBuddy *) node;
- account = purple_buddy_get_account(buddy);
- gc = purple_account_get_connection(account);
- name = purple_buddy_get_name(buddy);
-
- data = g_new0(MsnMobileData, 1);
- data->gc = gc;
- data->passport = name;
-
- purple_request_input(gc, NULL, _("Send a mobile message."), NULL,
- NULL, TRUE, FALSE, NULL,
- _("Page"), G_CALLBACK(send_to_mobile_cb),
- _("Close"), G_CALLBACK(close_mobile_page_cb),
- account, name, NULL,
- data);
-}
-
-static gboolean
-msn_offline_message(const PurpleBuddy *buddy) {
- return TRUE;
-}
-
-void
-msn_send_privacy(PurpleConnection *gc)
-{
- PurpleAccount *account;
- MsnSession *session;
- MsnCmdProc *cmdproc;
- MsnTransaction *trans;
-
- account = purple_connection_get_account(gc);
- session = gc->proto_data;
- cmdproc = session->notification->cmdproc;
-
- if (account->perm_deny == PURPLE_PRIVACY_ALLOW_ALL ||
- account->perm_deny == PURPLE_PRIVACY_DENY_USERS)
- trans = msn_transaction_new(cmdproc, "BLP", "%s", "AL");
- else
- trans = msn_transaction_new(cmdproc, "BLP", "%s", "BL");
-
- msn_cmdproc_send_trans(cmdproc, trans);
-}
-
-static void
-initiate_chat_cb(PurpleBlistNode *node, gpointer data)
-{
- PurpleBuddy *buddy;
- PurpleConnection *gc;
- PurpleAccount *account;
-
- MsnSession *session;
- MsnSwitchBoard *swboard;
-
- const char *alias;
-
- g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node));
-
- buddy = (PurpleBuddy *) node;
- account = purple_buddy_get_account(buddy);
- gc = purple_account_get_connection(account);
-
- session = gc->proto_data;
-
- swboard = msn_switchboard_new(session);
- msn_switchboard_request(swboard);
- msn_switchboard_request_add_user(swboard, purple_buddy_get_name(buddy));
-
- /* TODO: This might move somewhere else, after USR might be */
- swboard->chat_id = msn_switchboard_get_chat_id();
- swboard->conv = serv_got_joined_chat(gc, swboard->chat_id, "MSN Chat");
- swboard->flag = MSN_SB_FLAG_IM;
-
- /* Local alias > Display name > Username */
- if ((alias = purple_account_get_alias(account)) == NULL)
- if ((alias = purple_connection_get_display_name(gc)) == NULL)
- alias = purple_account_get_username(account);
-
- purple_conv_chat_add_user(PURPLE_CONV_CHAT(swboard->conv),
- alias, NULL, PURPLE_CBFLAGS_NONE, TRUE);
-}
-
-static void
-t_msn_xfer_init(PurpleXfer *xfer)
-{
- msn_request_ft(xfer);
-}
-
-static void
-t_msn_xfer_cancel_send(PurpleXfer *xfer)
-{
- MsnSlpLink *slplink = xfer->data;
- msn_slplink_unref(slplink);
-}
-
-static PurpleXfer*
-msn_new_xfer(PurpleConnection *gc, const char *who)
-{
- MsnSession *session;
- PurpleXfer *xfer;
-
- session = gc->proto_data;
-
- xfer = purple_xfer_new(gc->account, PURPLE_XFER_SEND, who);
-
- g_return_val_if_fail(xfer != NULL, NULL);
-
- xfer->data = msn_slplink_ref(msn_session_get_slplink(session, who));
-
- purple_xfer_set_init_fnc(xfer, t_msn_xfer_init);
- purple_xfer_set_cancel_send_fnc(xfer, t_msn_xfer_cancel_send);
-
- return xfer;
-}
-
-static void
-msn_send_file(PurpleConnection *gc, const char *who, const char *file)
-{
- PurpleXfer *xfer = msn_new_xfer(gc, who);
-
- if (file)
- purple_xfer_request_accepted(xfer, file);
- else
- purple_xfer_request(xfer);
-}
-
-static gboolean
-msn_can_receive_file(PurpleConnection *gc, const char *who)
-{
- PurpleAccount *account;
- gchar *normal;
- gboolean ret;
-
- account = purple_connection_get_account(gc);
-
- normal = g_strdup(msn_normalize(account, purple_account_get_username(account)));
- ret = strcmp(normal, msn_normalize(account, who));
- g_free(normal);
-
- if (ret) {
- MsnSession *session = gc->proto_data;
- if (session) {
- MsnUser *user = msn_userlist_find_user(session->userlist, who);
- if (user) {
- /* Include these too: MSN_CAP_MOBILE_ON|MSN_CAP_WEB_WATCH ? */
- if ((user->clientid & MSN_CAP_VIA_WEBIM) ||
- user->networkid == MSN_NETWORK_YAHOO)
- ret = FALSE;
- else
- ret = TRUE;
- }
- } else
- ret = FALSE;
- }
-
- return ret;
-}
-
-/**************************************************************************
- * Protocol Plugin ops
- **************************************************************************/
-
-static const char *
-msn_list_icon(PurpleAccount *a, PurpleBuddy *b)
-{
- return "msn";
-}
-
-static const char *
-msn_list_emblems(PurpleBuddy *b)
-{
- MsnUser *user = purple_buddy_get_protocol_data(b);
-
- if (user != NULL) {
- if (user->clientid & MSN_CAP_BOT)
- return "bot";
- if (user->clientid & MSN_CAP_VIA_MOBILE)
- return "mobile";
-#if 0
- /* XXX: Since we don't support this, there's no point in showing it just yet */
- if (user->clientid & MSN_CAP_SCHANNEL)
- return "secure";
-#endif
- if (user->clientid & MSN_CAP_VIA_WEBIM)
- return "external";
- if (user->networkid == MSN_NETWORK_YAHOO)
- return "yahoo";
- }
-
- return NULL;
-}
-
-/*
- * Set the User status text
- */
-static char *
-msn_status_text(PurpleBuddy *buddy)
-{
- PurplePresence *presence;
- PurpleStatus *status;
- const char *msg;
-
- presence = purple_buddy_get_presence(buddy);
- status = purple_presence_get_active_status(presence);
-
- /* Official client says media takes precedence over message */
- /* I say message take precedence over media! Plus prpl-jabber agrees
- too */
- msg = purple_status_get_attr_string(status, "message");
- if (msg && *msg)
- return g_markup_escape_text(msg, -1);
-
- if (purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_TUNE)) {
- const char *title, *game, *office;
- char *media, *esc;
- status = purple_presence_get_status(presence, "tune");
- title = purple_status_get_attr_string(status, PURPLE_TUNE_TITLE);
-
- game = purple_status_get_attr_string(status, "game");
- office = purple_status_get_attr_string(status, "office");
-
- if (title && *title) {
- const char *artist = purple_status_get_attr_string(status, PURPLE_TUNE_ARTIST);
- const char *album = purple_status_get_attr_string(status, PURPLE_TUNE_ALBUM);
- media = purple_util_format_song_info(title, artist, album, NULL);
- return media;
- }
- else if (game && *game)
- media = g_strdup_printf("Playing %s", game);
- else if (office && *office)
- media = g_strdup_printf("Editing %s", office);
- else
- return NULL;
- esc = g_markup_escape_text(media, -1);
- g_free(media);
- return esc;
- }
-
- return NULL;
-}
-
-static void
-msn_tooltip_text(PurpleBuddy *buddy, PurpleNotifyUserInfo *user_info, gboolean full)
-{
- MsnUser *user;
- PurplePresence *presence = purple_buddy_get_presence(buddy);
- PurpleStatus *status = purple_presence_get_active_status(presence);
-
- user = purple_buddy_get_protocol_data(buddy);
-
- if (purple_presence_is_online(presence))
- {
- const char *psm, *name;
- const char *mediatype = NULL;
- char *currentmedia = NULL;
-
- psm = purple_status_get_attr_string(status, "message");
- if (purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_TUNE)) {
- PurpleStatus *tune = purple_presence_get_status(presence, "tune");
- const char *title = purple_status_get_attr_string(tune, PURPLE_TUNE_TITLE);
- const char *game = purple_status_get_attr_string(tune, "game");
- const char *office = purple_status_get_attr_string(tune, "office");
- if (title && *title) {
- const char *artist = purple_status_get_attr_string(tune, PURPLE_TUNE_ARTIST);
- const char *album = purple_status_get_attr_string(tune, PURPLE_TUNE_ALBUM);
- mediatype = _("Now Listening");
- currentmedia = purple_util_format_song_info(title, artist, album, NULL);
- } else if (game && *game) {
- mediatype = _("Playing a game");
- currentmedia = g_strdup(game);
- } else if (office && *office) {
- mediatype = _("Working");
- currentmedia = g_strdup(office);
- }
- }
-
- if (!purple_status_is_available(status)) {
- name = purple_status_get_name(status);
- } else {
- name = NULL;
- }
-
- if (name != NULL && *name) {
- char *tmp2;
-
- tmp2 = g_markup_escape_text(name, -1);
- if (purple_presence_is_idle(presence)) {
- char *idle;
- char *tmp3;
- /* Never know what those translations might end up like... */
- idle = g_markup_escape_text(_("Idle"), -1);
- tmp3 = g_strdup_printf("%s/%s", tmp2, idle);
- g_free(idle);
- g_free(tmp2);
- tmp2 = tmp3;
- }
-
- if (psm != NULL && *psm) {
- purple_notify_user_info_add_pair_plaintext(user_info, tmp2, psm);
- } else {
- purple_notify_user_info_add_pair(user_info, _("Status"), tmp2);
- }
-
- g_free(tmp2);
- } else {
- if (psm != NULL && *psm) {
- if (purple_presence_is_idle(presence)) {
- purple_notify_user_info_add_pair_plaintext(user_info, _("Idle"), psm);
- } else {
- purple_notify_user_info_add_pair_plaintext(user_info, _("Status"), psm);
- }
- } else {
- if (purple_presence_is_idle(presence)) {
- purple_notify_user_info_add_pair(user_info, _("Status"),
- _("Idle"));
- } else {
- purple_notify_user_info_add_pair(user_info, _("Status"),
- purple_status_get_name(status));
- }
- }
- }
-
- if (currentmedia) {
- purple_notify_user_info_add_pair(user_info, mediatype, currentmedia);
- g_free(currentmedia);
- }
- }
-
- /* XXX: This is being shown in non-full tooltips because the
- * XXX: blocked icon overlay isn't always accurate for MSN.
- * XXX: This can die as soon as purple_privacy_check() knows that
- * XXX: this prpl always honors both the allow and deny lists. */
- /* While the above comment may be strictly correct (the privacy API needs
- * rewriteing), purple_privacy_check() is going to be more accurate at
- * indicating whether a particular buddy is going to be able to message
- * you, which is the important information that this is trying to convey.
- */
- if (full && user)
- {
- const char *phone;
-
- purple_notify_user_info_add_pair(user_info, _("Has you"),
- ((user->list_op & (1 << MSN_LIST_RL)) ? _("Yes") : _("No")));
-
- purple_notify_user_info_add_pair(user_info, _("Blocked"),
- ((user->list_op & (1 << MSN_LIST_BL)) ? _("Yes") : _("No")));
-
- phone = msn_user_get_home_phone(user);
- if (phone != NULL)
- purple_notify_user_info_add_pair(user_info, _("Home Phone Number"), phone);
-
- phone = msn_user_get_work_phone(user);
- if (phone != NULL)
- purple_notify_user_info_add_pair(user_info, _("Work Phone Number"), phone);
-
- phone = msn_user_get_mobile_phone(user);
- if (phone != NULL)
- purple_notify_user_info_add_pair(user_info, _("Mobile Phone Number"), phone);
- }
-}
-
-static GList *
-msn_status_types(PurpleAccount *account)
-{
- PurpleStatusType *status;
- GList *types = NULL;
-
- status = purple_status_type_new_with_attrs(
- PURPLE_STATUS_AVAILABLE, NULL, NULL, TRUE, TRUE, FALSE,
- "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
- NULL);
- types = g_list_append(types, status);
-
- status = purple_status_type_new_with_attrs(
- PURPLE_STATUS_AWAY, NULL, NULL, TRUE, TRUE, FALSE,
- "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
- NULL);
- types = g_list_append(types, status);
-
- status = purple_status_type_new_with_attrs(
- PURPLE_STATUS_AWAY, "brb", _("Be Right Back"), TRUE, TRUE, FALSE,
- "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
- NULL);
- types = g_list_append(types, status);
-
- status = purple_status_type_new_with_attrs(
- PURPLE_STATUS_UNAVAILABLE, "busy", _("Busy"), TRUE, TRUE, FALSE,
- "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
- NULL);
- types = g_list_append(types, status);
- status = purple_status_type_new_with_attrs(
- PURPLE_STATUS_UNAVAILABLE, "phone", _("On the Phone"), TRUE, TRUE, FALSE,
- "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
- NULL);
- types = g_list_append(types, status);
- status = purple_status_type_new_with_attrs(
- PURPLE_STATUS_AWAY, "lunch", _("Out to Lunch"), TRUE, TRUE, FALSE,
- "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
- NULL);
- types = g_list_append(types, status);
-
- status = purple_status_type_new_full(PURPLE_STATUS_INVISIBLE,
- NULL, NULL, TRUE, TRUE, FALSE);
- types = g_list_append(types, status);
-
- status = purple_status_type_new_full(PURPLE_STATUS_OFFLINE,
- NULL, NULL, TRUE, TRUE, FALSE);
- types = g_list_append(types, status);
-
- status = purple_status_type_new_full(PURPLE_STATUS_MOBILE,
- "mobile", NULL, FALSE, FALSE, TRUE);
- types = g_list_append(types, status);
-
- status = purple_status_type_new_with_attrs(PURPLE_STATUS_TUNE,
- "tune", NULL, FALSE, TRUE, TRUE,
- PURPLE_TUNE_ARTIST, _("Tune Artist"), purple_value_new(PURPLE_TYPE_STRING),
- PURPLE_TUNE_ALBUM, _("Tune Album"), purple_value_new(PURPLE_TYPE_STRING),
- PURPLE_TUNE_TITLE, _("Tune Title"), purple_value_new(PURPLE_TYPE_STRING),
- "game", _("Game Title"), purple_value_new(PURPLE_TYPE_STRING),
- "office", _("Office Title"), purple_value_new(PURPLE_TYPE_STRING),
- NULL);
- types = g_list_append(types, status);
-
- return types;
-}
-
-static GList *
-msn_actions(PurplePlugin *plugin, gpointer context)
-{
- PurpleConnection *gc;
- MsnSession *session;
- GList *m = NULL;
- PurplePluginAction *act;
-
- gc = (PurpleConnection *) context;
- session = gc->proto_data;
-
- act = purple_plugin_action_new(_("Set Friendly Name..."),
- msn_show_set_friendly_name);
- m = g_list_append(m, act);
- m = g_list_append(m, NULL);
-
- if (session->enable_mpop)
- {
- act = purple_plugin_action_new(_("View Locations..."),
- msn_show_locations);
- m = g_list_append(m, act);
- m = g_list_append(m, NULL);
- }
-
- act = purple_plugin_action_new(_("Set Home Phone Number..."),
- msn_show_set_home_phone);
- m = g_list_append(m, act);
-
- act = purple_plugin_action_new(_("Set Work Phone Number..."),
- msn_show_set_work_phone);
- m = g_list_append(m, act);
-
- act = purple_plugin_action_new(_("Set Mobile Phone Number..."),
- msn_show_set_mobile_phone);
- m = g_list_append(m, act);
- m = g_list_append(m, NULL);
-
-#if 0
- act = purple_plugin_action_new(_("Enable/Disable Mobile Devices..."),
- msn_show_set_mobile_support);
- m = g_list_append(m, act);
-#endif
-
- act = purple_plugin_action_new(_("Allow/Disallow Multiple Logins..."),
- msn_show_set_mpop);
- m = g_list_append(m, act);
-
- act = purple_plugin_action_new(_("Allow/Disallow Mobile Pages..."),
- msn_show_set_mobile_pages);
- m = g_list_append(m, act);
-
-/* QuLogic: Disabled until confirmed correct. */
-#if 0
- m = g_list_append(m, NULL);
- act = purple_plugin_action_new(_("View Blocked Text..."),
- msn_show_blocked_text);
- m = g_list_append(m, act);
-#endif
-
- m = g_list_append(m, NULL);
- act = purple_plugin_action_new(_("Open Hotmail Inbox"),
- msn_show_hotmail_inbox);
- m = g_list_append(m, act);
-
- return m;
-}
-
-static GList *
-msn_buddy_menu(PurpleBuddy *buddy)
-{
- MsnUser *user;
-
- GList *m = NULL;
- PurpleMenuAction *act;
-
- g_return_val_if_fail(buddy != NULL, NULL);
-
- user = purple_buddy_get_protocol_data(buddy);
-
- if (user != NULL)
- {
- if (user->mobile)
- {
- act = purple_menu_action_new(_("Send to Mobile"),
- PURPLE_CALLBACK(show_send_to_mobile_cb),
- NULL, NULL);
- m = g_list_append(m, act);
- }
- }
-
- if (g_ascii_strcasecmp(purple_buddy_get_name(buddy),
- purple_account_get_username(purple_buddy_get_account(buddy))))
- {
- act = purple_menu_action_new(_("Initiate _Chat"),
- PURPLE_CALLBACK(initiate_chat_cb),
- NULL, NULL);
- m = g_list_append(m, act);
- }
-
- return m;
-}
-
-static GList *
-msn_blist_node_menu(PurpleBlistNode *node)
-{
- if(PURPLE_BLIST_NODE_IS_BUDDY(node))
- {
- return msn_buddy_menu((PurpleBuddy *) node);
- }
- else
- {
- return NULL;
- }
-}
-
-static void
-msn_login(PurpleAccount *account)
-{
- PurpleConnection *gc;
- MsnSession *session;
- const char *username;
- const char *host;
- gboolean http_method = FALSE;
- int port;
-
- gc = purple_account_get_connection(account);
-
- if (!purple_ssl_is_supported())
- {
- purple_connection_error_reason(gc,
- PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT,
- _("SSL support is needed for MSN. Please install a supported "
- "SSL library."));
- return;
- }
-
- http_method = purple_account_get_bool(account, "http_method", FALSE);
-
- if (http_method)
- host = purple_account_get_string(account, "http_method_server", MSN_HTTPCONN_SERVER);
- else
- host = purple_account_get_string(account, "server", MSN_SERVER);
- port = purple_account_get_int(account, "port", MSN_PORT);
-
- session = msn_session_new(account);
-
- gc->proto_data = session;
- gc->flags |= PURPLE_CONNECTION_HTML | PURPLE_CONNECTION_FORMATTING_WBFO | PURPLE_CONNECTION_NO_BGCOLOR |
- PURPLE_CONNECTION_NO_FONTSIZE | PURPLE_CONNECTION_NO_URLDESC | PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY;
-
- msn_session_set_login_step(session, MSN_LOGIN_STEP_START);
-
- /* Hmm, I don't like this. */
- /* XXX shx: Me neither */
- username = msn_normalize(account, purple_account_get_username(account));
-
- if (strcmp(username, purple_account_get_username(account)))
- purple_account_set_username(account, username);
-
- username = purple_account_get_string(account, "display-name", NULL);
- purple_connection_set_display_name(gc, username);
-
- if (purple_account_get_string(account, "endpoint-name", NULL) == NULL) {
- GHashTable *ui_info = purple_core_get_ui_info();
- const gchar *ui_name = ui_info ? g_hash_table_lookup(ui_info, "name") : NULL;
- purple_account_set_string(account, "endpoint-name",
- ui_name && *ui_name ? ui_name : PACKAGE_NAME);
- }
-
- if (!msn_session_connect(session, host, port, http_method))
- purple_connection_error_reason(gc,
- PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
- _("Unable to connect"));
-}
-
-static void
-msn_close(PurpleConnection *gc)
-{
- MsnSession *session;
-
- session = gc->proto_data;
-
- g_return_if_fail(session != NULL);
-
- msn_session_destroy(session);
-
- gc->proto_data = NULL;
-}
-
-static gboolean
-msn_send_me_im(gpointer data)
-{
- MsnIMData *imdata = data;
- serv_got_im(imdata->gc, imdata->who, imdata->msg, imdata->flags, imdata->when);
- g_free(imdata->msg);
- g_free(imdata);
- return FALSE;
-}
-
-static GString*
-msn_msg_emoticon_add(GString *current, MsnEmoticon *emoticon)
-{
- MsnObject *obj;
- char *strobj;
-
- if (emoticon == NULL)
- return current;
-
- obj = emoticon->obj;
-
- if (!obj)
- return current;
-
- strobj = msn_object_to_string(obj);
-
- if (current)
- g_string_append_printf(current, "\t%s\t%s", emoticon->smile, strobj);
- else {
- current = g_string_new("");
- g_string_printf(current, "%s\t%s", emoticon->smile, strobj);
- }
-
- g_free(strobj);
-
- return current;
-}
-
-static void
-msn_send_emoticons(MsnSwitchBoard *swboard, GString *body)
-{
- MsnMessage *msg;
-
- g_return_if_fail(body != NULL);
-
- msg = msn_message_new(MSN_MSG_SLP);
- msn_message_set_content_type(msg, "text/x-mms-emoticon");
- msn_message_set_flag(msg, 'N');
- msn_message_set_bin_data(msg, body->str, body->len);
-
- msn_switchboard_send_msg(swboard, msg, TRUE);
- msn_message_unref(msg);
-}
-
-static void msn_emoticon_destroy(MsnEmoticon *emoticon)
-{
- if (emoticon->obj)
- msn_object_destroy(emoticon->obj);
- g_free(emoticon->smile);
- g_free(emoticon);
-}
-
-static GSList* msn_msg_grab_emoticons(const char *msg, const char *username)
-{
- GSList *list;
- GList *smileys;
- PurpleSmiley *smiley;
- PurpleStoredImage *img;
- char *ptr;
- MsnEmoticon *emoticon;
- int length;
-
- list = NULL;
- smileys = purple_smileys_get_all();
- length = strlen(msg);
-
- for (; smileys; smileys = g_list_delete_link(smileys, smileys)) {
- smiley = smileys->data;
-
- ptr = g_strstr_len(msg, length, purple_smiley_get_shortcut(smiley));
-
- if (!ptr)
- continue;
-
- img = purple_smiley_get_stored_image(smiley);
-
- emoticon = g_new0(MsnEmoticon, 1);
- emoticon->smile = g_strdup(purple_smiley_get_shortcut(smiley));
- emoticon->ps = smiley;
- emoticon->obj = msn_object_new_from_image(img,
- purple_imgstore_get_filename(img),
- username, MSN_OBJECT_EMOTICON);
-
- purple_imgstore_unref(img);
- list = g_slist_prepend(list, emoticon);
- }
-
- return list;
-}
-
-void
-msn_send_im_message(MsnSession *session, MsnMessage *msg)
-{
- MsnEmoticon *smile;
- GSList *smileys;
- GString *emoticons = NULL;
- const char *username = purple_account_get_username(session->account);
- MsnSwitchBoard *swboard = msn_session_get_swboard(session, msg->remote_user, MSN_SB_FLAG_IM);
-
- smileys = msn_msg_grab_emoticons(msg->body, username);
- while (smileys) {
- smile = (MsnEmoticon *)smileys->data;
- emoticons = msn_msg_emoticon_add(emoticons, smile);
- msn_emoticon_destroy(smile);
- smileys = g_slist_delete_link(smileys, smileys);
- }
-
- if (emoticons) {
- msn_send_emoticons(swboard, emoticons);
- g_string_free(emoticons, TRUE);
- }
-
- msn_switchboard_send_msg(swboard, msg, TRUE);
-}
-
-static int
-msn_send_im(PurpleConnection *gc, const char *who, const char *message,
- PurpleMessageFlags flags)
-{
- PurpleAccount *account;
- PurpleBuddy *buddy = purple_find_buddy(gc->account, who);
- MsnSession *session;
- MsnSwitchBoard *swboard;
- MsnMessage *msg;
- char *msgformat;
- char *msgtext;
- size_t msglen;
- const char *username;
-
- purple_debug_info("msn", "send IM {%s} to %s\n", message, who);
- account = purple_connection_get_account(gc);
- username = purple_account_get_username(account);
-
- session = gc->proto_data;
- swboard = msn_session_find_swboard(session, who);
-
- if (!strncmp("tel:+", who, 5)) {
- char *text = purple_markup_strip_html(message);
- send_to_mobile(gc, who, text);
- g_free(text);
- return 1;
- }
-
- if (buddy) {
- PurplePresence *p = purple_buddy_get_presence(buddy);
- if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_MOBILE)) {
- char *text = purple_markup_strip_html(message);
- send_to_mobile(gc, who, text);
- g_free(text);
- return 1;
- }
- }
-
- msn_import_html(message, &msgformat, &msgtext);
- msglen = strlen(msgtext);
- if (msglen == 0) {
- /* Stuff like <hr> will be ignored. Don't send an empty message
- if that's all there is. */
- g_free(msgtext);
- g_free(msgformat);
-
- return 0;
- }
-
- if (msglen + strlen(msgformat) + strlen(VERSION) > 1564)
- {
- g_free(msgformat);
- g_free(msgtext);
-
- return -E2BIG;
- }
-
- msg = msn_message_new_plain(msgtext);
- msg->remote_user = g_strdup(who);
- msn_message_set_header(msg, "X-MMS-IM-Format", msgformat);
-
- g_free(msgformat);
- g_free(msgtext);
-
- if (g_ascii_strcasecmp(who, username))
- {
- if (flags & PURPLE_MESSAGE_AUTO_RESP) {
- msn_message_set_flag(msg, 'U');
- }
-
- if (msn_user_is_yahoo(account, who) || !(msn_user_is_online(account, who) || swboard != NULL)) {
- /*we send the online and offline Message to Yahoo User via UBM*/
- purple_debug_info("msn", "send to offline or Yahoo user\n");
- msn_notification_send_uum(session, msg);
- } else {
- purple_debug_info("msn", "send via switchboard\n");
- msn_send_im_message(session, msg);
- }
- }
- else
- {
- char *body_str, *body_enc, *pre, *post;
- const char *format;
- MsnIMData *imdata = g_new0(MsnIMData, 1);
- /*
- * In MSN, you can't send messages to yourself, so
- * we'll fake like we received it ;)
- */
- body_str = msn_message_to_string(msg);
- body_enc = g_markup_escape_text(body_str, -1);
- g_free(body_str);
-
- format = msn_message_get_header_value(msg, "X-MMS-IM-Format");
- msn_parse_format(format, &pre, &post);
- body_str = g_strdup_printf("%s%s%s", pre ? pre : "",
- body_enc ? body_enc : "", post ? post : "");
- g_free(body_enc);
- g_free(pre);
- g_free(post);
-
- serv_got_typing_stopped(gc, who);
- imdata->gc = gc;
- imdata->who = who;
- imdata->msg = body_str;
- imdata->flags = flags & ~PURPLE_MESSAGE_SEND;
- imdata->when = time(NULL);
- purple_timeout_add(0, msn_send_me_im, imdata);
- }
-
- msn_message_unref(msg);
-
- return 1;
-}
-
-static unsigned int
-msn_send_typing(PurpleConnection *gc, const char *who, PurpleTypingState state)
-{
- PurpleAccount *account;
- MsnSession *session;
- MsnSwitchBoard *swboard;
- MsnMessage *msg;
-
- account = purple_connection_get_account(gc);
- session = gc->proto_data;
-
- /*
- * TODO: I feel like this should be "if (state != PURPLE_TYPING)"
- * but this is how it was before, and I don't want to break
- * anything. --KingAnt
- */
- if (state == PURPLE_NOT_TYPING)
- return 0;
-
- if (!g_ascii_strcasecmp(who, purple_account_get_username(account)))
- {
- /* We'll just fake it, since we're sending to ourself. */
- serv_got_typing(gc, who, MSN_TYPING_RECV_TIMEOUT, PURPLE_TYPING);
-
- return MSN_TYPING_SEND_TIMEOUT;
- }
-
- swboard = msn_session_find_swboard(session, who);
-
- if (swboard == NULL || !msn_switchboard_can_send(swboard))
- return 0;
-
- swboard->flag |= MSN_SB_FLAG_IM;
-
- msg = msn_message_new(MSN_MSG_TYPING);
- msn_message_set_content_type(msg, "text/x-msmsgscontrol");
- msn_message_set_flag(msg, 'U');
- msn_message_set_header(msg, "TypingUser",
- purple_account_get_username(account));
- msn_message_set_bin_data(msg, "\r\n", 2);
-
- msn_switchboard_send_msg(swboard, msg, FALSE);
-
- msn_message_unref(msg);
-
- return MSN_TYPING_SEND_TIMEOUT;
-}
-
-static void
-msn_set_status(PurpleAccount *account, PurpleStatus *status)
-{
- PurpleConnection *gc;
- MsnSession *session;
-
- gc = purple_account_get_connection(account);
-
- if (gc != NULL)
- {
- session = gc->proto_data;
- msn_change_status(session);
- }
-}
-
-static void
-msn_set_idle(PurpleConnection *gc, int idle)
-{
- MsnSession *session;
-
- session = gc->proto_data;
-
- msn_change_status(session);
-}
-
-/*
- * Actually adds a buddy once we have the response from FQY
- */
-static void
-add_pending_buddy(MsnSession *session,
- const char *who,
- MsnNetwork network,
- MsnUser *user)
-{
- char *group;
- MsnUserList *userlist;
- MsnUser *user2;
-
- g_return_if_fail(user != NULL);
-
- if (network == MSN_NETWORK_UNKNOWN) {
- purple_debug_error("msn", "Network in FQY response was unknown. "
- "Assuming %s is a passport user and adding anyway.\n", who);
- network = MSN_NETWORK_PASSPORT;
- }
-
- group = msn_user_remove_pending_group(user);
-
- userlist = session->userlist;
- user2 = msn_userlist_find_user(userlist, who);
- if (user2 != NULL) {
- /* User already in userlist, so just update it. */
- msn_user_unref(user);
- user = user2;
- } else {
- msn_userlist_add_user(userlist, user);
- msn_user_unref(user);
- }
-
- msn_user_set_network(user, network);
- msn_userlist_add_buddy(userlist, who, group);
-
- g_free(group);
-}
-
-static void
-msn_add_buddy(PurpleConnection *pc, PurpleBuddy *buddy, PurpleGroup *group, const char *message)
-{
- PurpleAccount *account;
- const char *bname, *gname;
- MsnSession *session;
- MsnUserList *userlist;
- MsnUser *user;
-
- account = purple_connection_get_account(pc);
- session = purple_connection_get_protocol_data(pc);
- bname = purple_buddy_get_name(buddy);
-
- if (!session->logged_in)
- {
- purple_debug_error("msn", "msn_add_buddy called before connected\n");
-
- return;
- }
-
- /* XXX - Would group ever be NULL here? I don't think so...
- * shx: Yes it should; MSN handles non-grouped buddies, and this is only
- * internal.
- * KingAnt: But PurpleBuddys must always exist inside PurpleGroups, so
- * won't group always be non-NULL here?
- */
- bname = msn_normalize(account, bname);
- gname = group ? purple_group_get_name(group) : NULL;
- purple_debug_info("msn", "Add user:%s to group:%s\n",
- bname, gname ? gname : "(null)");
-
- if (!msn_email_is_valid(bname)) {
- gchar *buf;
- buf = g_strdup_printf(_("Unable to add the buddy %s because the username is invalid. Usernames must be valid email addresses."), bname);
- if (!purple_conv_present_error(bname, account, buf))
- purple_notify_error(pc, NULL, _("Unable to Add"), buf);
- g_free(buf);
-
- /* Remove from local list */
- purple_blist_remove_buddy(buddy);
-
- return;
- }
-
- /* Make sure name is normalized */
- purple_blist_rename_buddy(buddy, bname);
-
- userlist = session->userlist;
- user = msn_userlist_find_user(userlist, bname);
- if (user && user->authorized) {
- message = NULL;
- }
- if ((user != NULL) && (user->networkid != MSN_NETWORK_UNKNOWN)) {
- /* We already know this buddy and their network. This function knows
- what to do with users already in the list and stuff... */
- msn_user_set_invite_message(user, message);
- msn_userlist_add_buddy(userlist, bname, gname);
- } else {
- char **tokens;
- char *fqy;
- /* We need to check the network for this buddy first */
- user = msn_user_new(userlist, bname, NULL);
- msn_user_set_invite_message(user, message);
- msn_user_set_pending_group(user, gname);
- msn_user_set_network(user, MSN_NETWORK_UNKNOWN);
- /* Should probably re-use the msn_add_contact_xml function here */
- tokens = g_strsplit(bname, "@", 2);
- fqy = g_strdup_printf("<ml><d n=\"%s\"><c n=\"%s\"/></d></ml>",
- tokens[1],
- tokens[0]);
- /* TODO: I think user will leak if we disconnect before receiving
- a response to this FQY request */
- msn_notification_send_fqy(session, fqy, strlen(fqy),
- (MsnFqyCb)add_pending_buddy, user);
- g_free(fqy);
- g_strfreev(tokens);
- }
-}
-
-static void
-msn_rem_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group)
-{
- MsnSession *session;
- MsnUserList *userlist;
-
- session = gc->proto_data;
- userlist = session->userlist;
-
- if (!session->logged_in)
- return;
-
- /* XXX - Does buddy->name need to be msn_normalize'd here? --KingAnt */
- msn_userlist_rem_buddy(userlist, purple_buddy_get_name(buddy));
-}
-
-static void
-msn_add_permit(PurpleConnection *gc, const char *who)
-{
- MsnSession *session;
- MsnUserList *userlist;
- MsnUser *user;
-
- session = gc->proto_data;
- userlist = session->userlist;
- user = msn_userlist_find_user(userlist, who);
-
- if (!session->logged_in)
- return;
-
- if (user != NULL && user->list_op & MSN_LIST_BL_OP) {
- msn_userlist_rem_buddy_from_list(userlist, who, MSN_LIST_BL);
-
- /* delete contact from Block list and add it to Allow in the callback */
- msn_del_contact_from_list(session, NULL, who, MSN_LIST_BL);
- } else {
- /* just add the contact to Allow list */
- msn_add_contact_to_list(session, NULL, who, MSN_LIST_AL);
- }
-
-
- msn_userlist_add_buddy_to_list(userlist, who, MSN_LIST_AL);
-}
-
-static void
-msn_add_deny(PurpleConnection *gc, const char *who)
-{
- MsnSession *session;
- MsnUserList *userlist;
- MsnUser *user;
-
- session = gc->proto_data;
- userlist = session->userlist;
- user = msn_userlist_find_user(userlist, who);
-
- if (!session->logged_in)
- return;
-
- if (user != NULL && user->list_op & MSN_LIST_AL_OP) {
- msn_userlist_rem_buddy_from_list(userlist, who, MSN_LIST_AL);
-
- /* delete contact from Allow list and add it to Block in the callback */
- msn_del_contact_from_list(session, NULL, who, MSN_LIST_AL);
- } else {
- /* just add the contact to Block list */
- msn_add_contact_to_list(session, NULL, who, MSN_LIST_BL);
- }
-
- msn_userlist_add_buddy_to_list(userlist, who, MSN_LIST_BL);
-}
-
-static void
-msn_rem_permit(PurpleConnection *gc, const char *who)
-{
- MsnSession *session;
- MsnUserList *userlist;
- MsnUser *user;
-
- session = gc->proto_data;
- userlist = session->userlist;
-
- if (!session->logged_in)
- return;
-
- user = msn_userlist_find_user(userlist, who);
-
- msn_userlist_rem_buddy_from_list(userlist, who, MSN_LIST_AL);
-
- msn_del_contact_from_list(session, NULL, who, MSN_LIST_AL);
-
- if (user != NULL && user->list_op & MSN_LIST_RL_OP)
- msn_userlist_add_buddy_to_list(userlist, who, MSN_LIST_BL);
-}
-
-static void
-msn_rem_deny(PurpleConnection *gc, const char *who)
-{
- MsnSession *session;
- MsnUserList *userlist;
- MsnUser *user;
-
- session = gc->proto_data;
- userlist = session->userlist;
-
- if (!session->logged_in)
- return;
-
- user = msn_userlist_find_user(userlist, who);
-
- msn_userlist_rem_buddy_from_list(userlist, who, MSN_LIST_BL);
-
- msn_del_contact_from_list(session, NULL, who, MSN_LIST_BL);
-
- if (user != NULL && user->list_op & MSN_LIST_RL_OP)
- msn_userlist_add_buddy_to_list(userlist, who, MSN_LIST_AL);
-}
-
-static void
-msn_set_permit_deny(PurpleConnection *gc)
-{
- msn_send_privacy(gc);
-}
-
-static void
-msn_chat_invite(PurpleConnection *gc, int id, const char *msg,
- const char *who)
-{
- MsnSession *session;
- MsnSwitchBoard *swboard;
-
- session = gc->proto_data;
-
- swboard = msn_session_find_swboard_with_id(session, id);
-
- if (swboard == NULL)
- {
- /* if we have no switchboard, everyone else left the chat already */
- swboard = msn_switchboard_new(session);
- msn_switchboard_request(swboard);
- swboard->chat_id = id;
- swboard->conv = purple_find_chat(gc, id);
- }
-
- swboard->flag |= MSN_SB_FLAG_IM;
-
- msn_switchboard_request_add_user(swboard, who);
-}
-
-static void
-msn_chat_leave(PurpleConnection *gc, int id)
-{
- MsnSession *session;
- MsnSwitchBoard *swboard;
- PurpleConversation *conv;
-
- session = gc->proto_data;
-
- swboard = msn_session_find_swboard_with_id(session, id);
-
- /* if swboard is NULL we were the only person left anyway */
- if (swboard == NULL)
- return;
-
- conv = swboard->conv;
-
- msn_switchboard_release(swboard, MSN_SB_FLAG_IM);
-
- /* If other switchboards managed to associate themselves with this
- * conv, make sure they know it's gone! */
- if (conv != NULL)
- {
- while ((swboard = msn_session_find_swboard_with_conv(session, conv)) != NULL)
- swboard->conv = NULL;
- }
-}
-
-static int
-msn_chat_send(PurpleConnection *gc, int id, const char *message, PurpleMessageFlags flags)
-{
- PurpleAccount *account;
- MsnSession *session;
- const char *username;
- MsnSwitchBoard *swboard;
- MsnMessage *msg;
- char *msgformat;
- char *msgtext;
- size_t msglen;
- MsnEmoticon *smile;
- GSList *smileys;
- GString *emoticons = NULL;
-
- account = purple_connection_get_account(gc);
- session = gc->proto_data;
- username = purple_account_get_username(account);
- swboard = msn_session_find_swboard_with_id(session, id);
-
- if (swboard == NULL)
- return -EINVAL;
-
- if (!swboard->ready)
- return 0;
-
- swboard->flag |= MSN_SB_FLAG_IM;
-
- msn_import_html(message, &msgformat, &msgtext);
- msglen = strlen(msgtext);
-
- if ((msglen == 0) || (msglen + strlen(msgformat) + strlen(VERSION) > 1564))
- {
- g_free(msgformat);
- g_free(msgtext);
-
- return -E2BIG;
- }
-
- msg = msn_message_new_plain(msgtext);
- msn_message_set_header(msg, "X-MMS-IM-Format", msgformat);
-
- smileys = msn_msg_grab_emoticons(msg->body, username);
- while (smileys) {
- smile = (MsnEmoticon *)smileys->data;
- emoticons = msn_msg_emoticon_add(emoticons, smile);
- if (purple_conv_custom_smiley_add(swboard->conv, smile->smile,
- "sha1", purple_smiley_get_checksum(smile->ps),
- FALSE)) {
- gconstpointer data;
- size_t len;
- data = purple_smiley_get_data(smile->ps, &len);
- purple_conv_custom_smiley_write(swboard->conv, smile->smile, data, len);
- purple_conv_custom_smiley_close(swboard->conv, smile->smile);
- }
- msn_emoticon_destroy(smile);
- smileys = g_slist_delete_link(smileys, smileys);
- }
-
- if (emoticons) {
- msn_send_emoticons(swboard, emoticons);
- g_string_free(emoticons, TRUE);
- }
-
- msn_switchboard_send_msg(swboard, msg, FALSE);
- msn_message_unref(msg);
-
- g_free(msgformat);
- g_free(msgtext);
-
- serv_got_chat_in(gc, id, purple_account_get_username(account), flags,
- message, time(NULL));
-
- return 0;
-}
-
-static void
-msn_keepalive(PurpleConnection *gc)
-{
- MsnSession *session;
- MsnTransaction *trans;
-
- session = gc->proto_data;
-
- if (!session->http_method)
- {
- MsnCmdProc *cmdproc;
-
- cmdproc = session->notification->cmdproc;
-
- trans = msn_transaction_new(cmdproc, "PNG", NULL);
- msn_transaction_set_saveable(trans, FALSE);
- msn_cmdproc_send_trans(cmdproc, trans);
- }
-}
-
-static void msn_alias_buddy(PurpleConnection *pc, const char *name, const char *alias)
-{
- MsnSession *session;
-
- session = pc->proto_data;
-
- msn_update_contact(session, name, MSN_UPDATE_ALIAS, alias);
-}
-
-static void
-msn_group_buddy(PurpleConnection *gc, const char *who,
- const char *old_group_name, const char *new_group_name)
-{
- MsnSession *session;
- MsnUserList *userlist;
-
- session = gc->proto_data;
- userlist = session->userlist;
-
- msn_userlist_move_buddy(userlist, who, old_group_name, new_group_name);
-}
-
-static void
-msn_rename_group(PurpleConnection *gc, const char *old_name,
- PurpleGroup *group, GList *moved_buddies)
-{
- MsnSession *session;
- const char *gname;
-
- session = gc->proto_data;
-
- g_return_if_fail(session != NULL);
- g_return_if_fail(session->userlist != NULL);
-
- gname = purple_group_get_name(group);
- if (msn_userlist_find_group_with_name(session->userlist, old_name) != NULL)
- {
- msn_contact_rename_group(session, old_name, gname);
- }
- else
- {
- /* not found */
- msn_add_group(session, NULL, gname);
- }
-}
-
-static void
-msn_convo_closed(PurpleConnection *gc, const char *who)
-{
- MsnSession *session;
- MsnSwitchBoard *swboard;
- PurpleConversation *conv;
-
- session = gc->proto_data;
-
- swboard = msn_session_find_swboard(session, who);
-
- /*
- * Don't perform an assertion here. If swboard is NULL, then the
- * switchboard was either closed by the other party, or the person
- * is talking to himself.
- */
- if (swboard == NULL)
- return;
-
- conv = swboard->conv;
-
- /* If we release the switchboard here, it may still have messages
- pending ACK which would result in incorrect unsent message errors.
- Just let it timeout... This is *so* going to screw with people who
- use dumb clients that report "User has closed the conversation window" */
- /* msn_switchboard_release(swboard, MSN_SB_FLAG_IM); */
- swboard->conv = NULL;
-
- /* If other switchboards managed to associate themselves with this
- * conv, make sure they know it's gone! */
- if (conv != NULL)
- {
- while ((swboard = msn_session_find_swboard_with_conv(session, conv)) != NULL)
- swboard->conv = NULL;
- }
-}
-
-static void
-msn_set_buddy_icon(PurpleConnection *gc, PurpleStoredImage *img)
-{
- MsnSession *session;
- MsnUser *user;
-
- session = gc->proto_data;
- user = session->user;
-
- msn_user_set_buddy_icon(user, img);
-
- msn_change_status(session);
-}
-
-static void
-msn_remove_group(PurpleConnection *gc, PurpleGroup *group)
-{
- MsnSession *session;
- const char *gname;
-
- session = gc->proto_data;
- gname = purple_group_get_name(group);
-
- purple_debug_info("msn", "Remove group %s\n", gname);
- /*we can't delete the default group*/
- if(!strcmp(gname, MSN_INDIVIDUALS_GROUP_NAME)||
- !strcmp(gname, MSN_NON_IM_GROUP_NAME))
- {
- purple_debug_info("msn", "This group can't be removed, returning.\n");
- return ;
- }
-
- msn_del_group(session, gname);
-}
-
-/**
- * Extract info text from info_data and add it to user_info
- */
-static gboolean
-msn_tooltip_extract_info_text(PurpleNotifyUserInfo *user_info, MsnGetInfoData *info_data)
-{
- PurpleBuddy *b;
-
- b = purple_find_buddy(purple_connection_get_account(info_data->gc),
- info_data->name);
-
- if (b)
- {
- char *tmp;
- const char *alias;
-
- alias = purple_buddy_get_local_buddy_alias(b);
- if (alias && alias[0])
- {
- purple_notify_user_info_add_pair_plaintext(user_info, _("Alias"), alias);
- }
-
- if ((alias = purple_buddy_get_server_alias(b)) != NULL)
- {
- char *nicktext = g_markup_escape_text(alias, -1);
- tmp = g_strdup_printf("<font sml=\"msn\">%s</font>", nicktext);
- purple_notify_user_info_add_pair(user_info, _("Nickname"), tmp);
- g_free(tmp);
- g_free(nicktext);
- }
-
- /* Add the tooltip information */
- msn_tooltip_text(b, user_info, TRUE);
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-#if PHOTO_SUPPORT
-
-static char *
-msn_get_photo_url(const char *url_text)
-{
- char *p, *q;
-
- if ((p = strstr(url_text, PHOTO_URL)) != NULL)
- {
- p += strlen(PHOTO_URL);
- }
- if (p && (strncmp(p, "http://", strlen("http://")) == 0) && ((q = strchr(p, '"')) != NULL))
- return g_strndup(p, q - p);
-
- return NULL;
-}
-
-static void msn_got_photo(PurpleUtilFetchUrlData *url_data, gpointer data,
- const gchar *url_text, gsize len, const gchar *error_message);
-
-#endif
-
-#if 0
-static char *msn_info_date_reformat(const char *field, size_t len)
-{
- char *tmp = g_strndup(field, len);
- time_t t = purple_str_to_time(tmp, FALSE, NULL, NULL, NULL);
-
- g_free(tmp);
- return g_strdup(purple_date_format_short(localtime(&t)));
-}
-#endif
-
-#define MSN_GOT_INFO_GET_FIELD(a, b) \
- found = purple_markup_extract_info_field(stripped, stripped_len, user_info, \
- "\n" a ":", 0, "\n", 0, "Undisclosed", b, 0, NULL, NULL); \
- if (found) \
- sect_info = TRUE;
-
-#define MSN_GOT_INFO_GET_FIELD_NO_SEARCH(a, b) \
- found = purple_markup_extract_info_field(stripped, stripped_len, user_info, \
- "\n" a ":", 0, "\n", 0, "Undisclosed", b, 0, NULL, msn_info_strip_search_link); \
- if (found) \
- sect_info = TRUE;
-
-static char *
-msn_info_strip_search_link(const char *field, size_t len)
-{
- const char *c;
- if ((c = strstr(field, " (http://")) == NULL)
- return g_strndup(field, len);
- return g_strndup(field, c - field);
-}
-
-static void
-msn_got_info(PurpleUtilFetchUrlData *url_data, gpointer data,
- const gchar *url_text, size_t len, const gchar *error_message)
-{
- MsnGetInfoData *info_data = (MsnGetInfoData *)data;
- MsnSession *session;
- PurpleNotifyUserInfo *user_info;
- char *stripped, *p, *q, *tmp;
- char *user_url = NULL;
- gboolean found;
- gboolean has_tooltip_text = FALSE;
- gboolean has_info = FALSE;
- gboolean sect_info = FALSE;
- gboolean has_contact_info = FALSE;
- char *url_buffer;
- int stripped_len;
-#if PHOTO_SUPPORT
- char *photo_url_text = NULL;
- MsnGetInfoStepTwoData *info2_data = NULL;
-#endif
-
- purple_debug_info("msn", "In msn_got_info,url_text:{%s}\n",url_text);
-
- session = purple_connection_get_protocol_data(info_data->gc);
- session->url_datas = g_slist_remove(session->url_datas, url_data);
-
- user_info = purple_notify_user_info_new();
- has_tooltip_text = msn_tooltip_extract_info_text(user_info, info_data);
-
- if (error_message != NULL || url_text == NULL || strcmp(url_text, "") == 0)
- {
- purple_notify_user_info_add_pair(user_info,
- _("Error retrieving profile"), NULL);
-
- purple_notify_userinfo(info_data->gc, info_data->name, user_info, NULL, NULL);
- purple_notify_user_info_destroy(user_info);
-
- g_free(info_data->name);
- g_free(info_data);
- return;
- }
-
- url_buffer = g_strdup(url_text);
-
- /* If they have a homepage link, MSN masks it such that we need to
- * fetch the url out before purple_markup_strip_html() nukes it */
- /* I don't think this works with the new spaces profiles - Stu 3/2/06 */
- if ((p = strstr(url_text,
- "Take a look at my </font><A class=viewDesc title=\"")) != NULL)
- {
- p += 50;
-
- if ((q = strchr(p, '"')) != NULL)
- user_url = g_strndup(p, q - p);
- }
-
- /*
- * purple_markup_strip_html() doesn't strip out character entities like &nbsp;
- * and &#183;
- */
- while ((p = strstr(url_buffer, "&nbsp;")) != NULL)
- {
- *p = ' '; /* Turn &nbsp;'s into ordinary blanks */
- p += 1;
- memmove(p, p + 5, strlen(p + 5));
- url_buffer[strlen(url_buffer) - 5] = '\0';
- }
-
- while ((p = strstr(url_buffer, "&#183;")) != NULL)
- {
- memmove(p, p + 6, strlen(p + 6));
- url_buffer[strlen(url_buffer) - 6] = '\0';
- }
-
- /* Nuke the nasty \r's that just get in the way */
- purple_str_strip_char(url_buffer, '\r');
-
- /* MSN always puts in &#39; for apostrophes...replace them */
- while ((p = strstr(url_buffer, "&#39;")) != NULL)
- {
- *p = '\'';
- memmove(p + 1, p + 5, strlen(p + 5));
- url_buffer[strlen(url_buffer) - 4] = '\0';
- }
-
- /* Nuke the html, it's easier than trying to parse the horrid stuff */
- stripped = purple_markup_strip_html(url_buffer);
- stripped_len = strlen(stripped);
-
- purple_debug_misc("msn", "stripped = %p\n", stripped);
- purple_debug_misc("msn", "url_buffer = %p\n", url_buffer);
-
- /* General section header */
- if (has_tooltip_text)
- purple_notify_user_info_add_section_break(user_info);
-
- purple_notify_user_info_add_section_header(user_info, _("General"));
-
- /* Extract their Name and put it in */
- MSN_GOT_INFO_GET_FIELD("Name", _("Name"));
-
- /* General */
- MSN_GOT_INFO_GET_FIELD("Nickname", _("Nickname"));
- MSN_GOT_INFO_GET_FIELD_NO_SEARCH("Age", _("Age"));
- MSN_GOT_INFO_GET_FIELD_NO_SEARCH("Gender", _("Gender"));
- MSN_GOT_INFO_GET_FIELD_NO_SEARCH("Occupation", _("Occupation"));
- MSN_GOT_INFO_GET_FIELD_NO_SEARCH("Location", _("Location"));
-
- /* Extract their Interests and put it in */
- found = purple_markup_extract_info_field(stripped, stripped_len, user_info,
- "\nInterests\t", 0, " (/default.aspx?page=searchresults", 0,
- "Undisclosed", _("Hobbies and Interests") /* _("Interests") */,
- 0, NULL, NULL);
-
- if (found)
- sect_info = TRUE;
-
- MSN_GOT_INFO_GET_FIELD("More about me", _("A Little About Me"));
-
- if (sect_info)
- {
- has_info = TRUE;
- sect_info = FALSE;
- }
- else
- {
- /* Remove the section header */
- purple_notify_user_info_remove_last_item(user_info);
- if (has_tooltip_text)
- purple_notify_user_info_remove_last_item(user_info);
- }
-
- /* Social */
- purple_notify_user_info_add_section_break(user_info);
- purple_notify_user_info_add_section_header(user_info, _("Social"));
-
- MSN_GOT_INFO_GET_FIELD_NO_SEARCH("Marital status", _("Marital Status"));
- MSN_GOT_INFO_GET_FIELD_NO_SEARCH("Interested in", _("Interests"));
- MSN_GOT_INFO_GET_FIELD_NO_SEARCH("Pets", _("Pets"));
- MSN_GOT_INFO_GET_FIELD_NO_SEARCH("Hometown", _("Hometown"));
- MSN_GOT_INFO_GET_FIELD("Places lived", _("Places Lived"));
- MSN_GOT_INFO_GET_FIELD_NO_SEARCH("Fashion", _("Fashion"));
- MSN_GOT_INFO_GET_FIELD_NO_SEARCH("Humor", _("Humor"));
- MSN_GOT_INFO_GET_FIELD_NO_SEARCH("Music", _("Music"));
- MSN_GOT_INFO_GET_FIELD_NO_SEARCH("Favorite quote", _("Favorite Quote"));
-
- if (sect_info)
- {
- has_info = TRUE;
- sect_info = FALSE;
- }
- else
- {
- /* Remove the section header */
- purple_notify_user_info_remove_last_item(user_info);
- purple_notify_user_info_remove_last_item(user_info);
- }
-
- /* Contact Info */
- /* Personal */
- purple_notify_user_info_add_section_break(user_info);
- purple_notify_user_info_add_section_header(user_info, _("Contact Info"));
- purple_notify_user_info_add_section_header(user_info, _("Personal"));
-
- MSN_GOT_INFO_GET_FIELD("Name", _("Name"));
- MSN_GOT_INFO_GET_FIELD("Significant other", _("Significant Other"));
- MSN_GOT_INFO_GET_FIELD("Home phone", _("Home Phone"));
- MSN_GOT_INFO_GET_FIELD("Home phone 2", _("Home Phone 2"));
- MSN_GOT_INFO_GET_FIELD("Home address", _("Home Address"));
- MSN_GOT_INFO_GET_FIELD("Personal Mobile", _("Personal Mobile"));
- MSN_GOT_INFO_GET_FIELD("Home fax", _("Home Fax"));
- MSN_GOT_INFO_GET_FIELD("Personal email", _("Personal Email"));
- MSN_GOT_INFO_GET_FIELD("Personal IM", _("Personal IM"));
- MSN_GOT_INFO_GET_FIELD("Birthday", _("Birthday"));
- MSN_GOT_INFO_GET_FIELD("Anniversary", _("Anniversary"));
- MSN_GOT_INFO_GET_FIELD("Notes", _("Notes"));
-
- if (sect_info)
- {
- has_info = TRUE;
- sect_info = FALSE;
- has_contact_info = TRUE;
- }
- else
- {
- /* Remove the section header */
- purple_notify_user_info_remove_last_item(user_info);
- }
-
- /* Business */
- purple_notify_user_info_add_section_header(user_info, _("Work"));
- MSN_GOT_INFO_GET_FIELD("Name", _("Name"));
- MSN_GOT_INFO_GET_FIELD("Job title", _("Job Title"));
- MSN_GOT_INFO_GET_FIELD("Company", _("Company"));
- MSN_GOT_INFO_GET_FIELD("Department", _("Department"));
- MSN_GOT_INFO_GET_FIELD("Profession", _("Profession"));
- MSN_GOT_INFO_GET_FIELD("Work phone 1", _("Work Phone"));
- MSN_GOT_INFO_GET_FIELD("Work phone 2", _("Work Phone 2"));
- MSN_GOT_INFO_GET_FIELD("Work address", _("Work Address"));
- MSN_GOT_INFO_GET_FIELD("Work mobile", _("Work Mobile"));
- MSN_GOT_INFO_GET_FIELD("Work pager", _("Work Pager"));
- MSN_GOT_INFO_GET_FIELD("Work fax", _("Work Fax"));
- MSN_GOT_INFO_GET_FIELD("Work email", _("Work Email"));
- MSN_GOT_INFO_GET_FIELD("Work IM", _("Work IM"));
- MSN_GOT_INFO_GET_FIELD("Start date", _("Start Date"));
- MSN_GOT_INFO_GET_FIELD("Notes", _("Notes"));
-
- if (sect_info)
- {
- has_info = TRUE;
- sect_info = FALSE;
- has_contact_info = TRUE;
- }
- else
- {
- /* Remove the section header */
- purple_notify_user_info_remove_last_item(user_info);
- }
-
- if (!has_contact_info)
- {
- /* Remove the Contact Info section header */
- purple_notify_user_info_remove_last_item(user_info);
- }
-
-#if 0 /* these probably don't show up any more */
- /*
- * The fields, 'A Little About Me', 'Favorite Things', 'Hobbies
- * and Interests', 'Favorite Quote', and 'My Homepage' may or may
- * not appear, in any combination. However, they do appear in
- * certain order, so we can successively search to pin down the
- * distinct values.
- */
-
- /* Check if they have A Little About Me */
- found = purple_markup_extract_info_field(stripped, stripped_len, s,
- " A Little About Me \n\n", 0, "Favorite Things", '\n', NULL,
- _("A Little About Me"), 0, NULL, NULL);
-
- if (!found)
- {
- found = purple_markup_extract_info_field(stripped, stripped_len, s,
- " A Little About Me \n\n", 0, "Hobbies and Interests", '\n',
- NULL, _("A Little About Me"), 0, NULL, NULL);
- }
-
- if (!found)
- {
- found = purple_markup_extract_info_field(stripped, stripped_len, s,
- " A Little About Me \n\n", 0, "Favorite Quote", '\n', NULL,
- _("A Little About Me"), 0, NULL, NULL);
- }
-
- if (!found)
- {
- found = purple_markup_extract_info_field(stripped, stripped_len, s,
- " A Little About Me \n\n", 0, "My Homepage \n\nTake a look",
- '\n',
- NULL, _("A Little About Me"), 0, NULL, NULL);
- }
-
- if (!found)
- {
- purple_markup_extract_info_field(stripped, stripped_len, s,
- " A Little About Me \n\n", 0, "last updated", '\n', NULL,
- _("A Little About Me"), 0, NULL, NULL);
- }
-
- if (found)
- has_info = TRUE;
-
- /* Check if they have Favorite Things */
- found = purple_markup_extract_info_field(stripped, stripped_len, s,
- " Favorite Things \n\n", 0, "Hobbies and Interests", '\n', NULL,
- _("Favorite Things"), 0, NULL, NULL);
-
- if (!found)
- {
- found = purple_markup_extract_info_field(stripped, stripped_len, s,
- " Favorite Things \n\n", 0, "Favorite Quote", '\n', NULL,
- _("Favorite Things"), 0, NULL, NULL);
- }
-
- if (!found)
- {
- found = purple_markup_extract_info_field(stripped, stripped_len, s,
- " Favorite Things \n\n", 0, "My Homepage \n\nTake a look", '\n',
- NULL, _("Favorite Things"), 0, NULL, NULL);
- }
-
- if (!found)
- {
- purple_markup_extract_info_field(stripped, stripped_len, s,
- " Favorite Things \n\n", 0, "last updated", '\n', NULL,
- _("Favorite Things"), 0, NULL, NULL);
- }
-
- if (found)
- has_info = TRUE;
-
- /* Check if they have Hobbies and Interests */
- found = purple_markup_extract_info_field(stripped, stripped_len, s,
- " Hobbies and Interests \n\n", 0, "Favorite Quote", '\n', NULL,
- _("Hobbies and Interests"), 0, NULL, NULL);
-
- if (!found)
- {
- found = purple_markup_extract_info_field(stripped, stripped_len, s,
- " Hobbies and Interests \n\n", 0, "My Homepage \n\nTake a look",
- '\n', NULL, _("Hobbies and Interests"), 0, NULL, NULL);
- }
-
- if (!found)
- {
- purple_markup_extract_info_field(stripped, stripped_len, s,
- " Hobbies and Interests \n\n", 0, "last updated", '\n', NULL,
- _("Hobbies and Interests"), 0, NULL, NULL);
- }
-
- if (found)
- has_info = TRUE;
-
- /* Check if they have Favorite Quote */
- found = purple_markup_extract_info_field(stripped, stripped_len, s,
- "Favorite Quote \n\n", 0, "My Homepage \n\nTake a look", '\n', NULL,
- _("Favorite Quote"), 0, NULL, NULL);
-
- if (!found)
- {
- purple_markup_extract_info_field(stripped, stripped_len, s,
- "Favorite Quote \n\n", 0, "last updated", '\n', NULL,
- _("Favorite Quote"), 0, NULL, NULL);
- }
-
- if (found)
- has_info = TRUE;
-
- /* Extract the last updated date and put it in */
- found = purple_markup_extract_info_field(stripped, stripped_len, s,
- " last updated:", 1, "\n", 0, NULL, _("Last Updated"), 0,
- NULL, msn_info_date_reformat);
-
- if (found)
- has_info = TRUE;
-#endif
-
- /* If we were able to fetch a homepage url earlier, stick it in there */
- if (user_url != NULL)
- {
- tmp = g_strdup_printf("<a href=\"%s\">%s</a>", user_url, user_url);
- purple_notify_user_info_add_pair(user_info, _("Homepage"), tmp);
- g_free(tmp);
- g_free(user_url);
-
- has_info = TRUE;
- }
-
- if (!has_info)
- {
- /* MSN doesn't actually distinguish between "unknown member" and
- * a known member with an empty profile. Try to explain this fact.
- * Note that if we have a nonempty tooltip_text, we know the user
- * exists.
- */
- /* This doesn't work with the new spaces profiles - Stu 3/2/06
- char *p = strstr(url_buffer, "Unknown Member </TITLE>");
- * This might not work for long either ... */
- /* Nope, it failed some time before 5/2/07 :(
- char *p = strstr(url_buffer, "form id=\"SpacesSearch\" name=\"SpacesSearch\"");
- * Let's see how long this one holds out for ... */
- char *p = strstr(url_buffer, "<form id=\"profile_form\" name=\"profile_form\" action=\"http&#58;&#47;&#47;spaces.live.com&#47;profile.aspx&#63;cid&#61;0\"");
- PurpleBuddy *b = purple_find_buddy
- (purple_connection_get_account(info_data->gc), info_data->name);
- purple_notify_user_info_add_pair(user_info,
- _("Error retrieving profile"), NULL);
- purple_notify_user_info_add_pair(user_info, NULL,
- ((p && b) ? _("The user has not created a public profile.") :
- (p ? _("MSN reported not being able to find the user's profile. "
- "This either means that the user does not exist, "
- "or that the user exists "
- "but has not created a public profile.") :
- _("Could not find " /* This should never happen */
- "any information in the user's profile. "
- "The user most likely does not exist."))));
- }
-
- /* put a link to the actual profile URL */
- purple_notify_user_info_add_section_break(user_info);
- tmp = g_strdup_printf("<a href=\"%s%s\">%s</a>",
- PROFILE_URL, info_data->name, _("View web profile"));
- purple_notify_user_info_add_pair(user_info, NULL, tmp);
- g_free(tmp);
-
-#if PHOTO_SUPPORT
- /* Find the URL to the photo; must be before the marshalling [Bug 994207] */
- photo_url_text = msn_get_photo_url(url_text);
- purple_debug_info("msn", "photo url:{%s}\n", photo_url_text ? photo_url_text : "(null)");
-
- /* Marshall the existing state */
- info2_data = g_new0(MsnGetInfoStepTwoData, 1);
- info2_data->info_data = info_data;
- info2_data->stripped = stripped;
- info2_data->url_buffer = url_buffer;
- info2_data->user_info = user_info;
- info2_data->photo_url_text = photo_url_text;
-
- /* Try to put the photo in there too, if there's one */
- if (photo_url_text)
- {
- url_data = purple_util_fetch_url_len(photo_url_text, FALSE, NULL, FALSE,
- MAX_HTTP_BUDDYICON_BYTES,
- msn_got_photo, info2_data);
- session->url_datas = g_slist_prepend(session->url_datas, url_data);
- }
- else
- {
- /* Finish the Get Info and show the user something */
- msn_got_photo(NULL, info2_data, NULL, 0, NULL);
- }
-}
-
-static void
-msn_got_photo(PurpleUtilFetchUrlData *url_data, gpointer user_data,
- const gchar *url_text, gsize len, const gchar *error_message)
-{
- MsnGetInfoStepTwoData *info2_data = (MsnGetInfoStepTwoData *)user_data;
- int id = -1;
-
- /* Unmarshall the saved state */
- MsnGetInfoData *info_data = info2_data->info_data;
- char *stripped = info2_data->stripped;
- char *url_buffer = info2_data->url_buffer;
- PurpleNotifyUserInfo *user_info = info2_data->user_info;
- char *photo_url_text = info2_data->photo_url_text;
-
- if (url_data) {
- MsnSession *session = purple_connection_get_protocol_data(info_data->gc);
- session->url_datas = g_slist_remove(session->url_datas, url_data);
- }
-
- if (url_text && error_message)
- {
- purple_debug_warning("msn", "invalid connection. ignoring buddy photo info.\n");
- g_free(stripped);
- g_free(url_buffer);
- purple_notify_user_info_destroy(user_info);
- g_free(info_data->name);
- g_free(info_data);
- g_free(photo_url_text);
- g_free(info2_data);
-
- return;
- }
-
- /* Try to put the photo in there too, if there's one and is readable */
- if (url_text && len != 0)
- {
- if (strstr(url_text, "400 Bad Request")
- || strstr(url_text, "403 Forbidden")
- || strstr(url_text, "404 Not Found"))
- {
-
- purple_debug_info("msn", "Error getting %s: %s\n",
- photo_url_text, url_text);
- }
- else
- {
- char buf[1024];
- purple_debug_info("msn", "%s is %" G_GSIZE_FORMAT " bytes\n", photo_url_text, len);
- id = purple_imgstore_add_with_id(g_memdup(url_text, len), len, NULL);
- g_snprintf(buf, sizeof(buf), "<img id=\"%d\"><br>", id);
- purple_notify_user_info_prepend_pair(user_info, NULL, buf);
- }
- }
-
- /* We continue here from msn_got_info, as if nothing has happened */
-#endif
- purple_notify_userinfo(info_data->gc, info_data->name, user_info, NULL, NULL);
-
- g_free(stripped);
- g_free(url_buffer);
- purple_notify_user_info_destroy(user_info);
- g_free(info_data->name);
- g_free(info_data);
-#if PHOTO_SUPPORT
- g_free(photo_url_text);
- g_free(info2_data);
- if (id != -1)
- purple_imgstore_unref_by_id(id);
-#endif
-}
-
-static void
-msn_get_info(PurpleConnection *gc, const char *name)
-{
- MsnSession *session = purple_connection_get_protocol_data(gc);
- MsnGetInfoData *data;
- char *url;
- PurpleUtilFetchUrlData *url_data;
-
- data = g_new0(MsnGetInfoData, 1);
- data->gc = gc;
- data->name = g_strdup(name);
-
- url = g_strdup_printf("%s%s", PROFILE_URL, name);
-
- url_data = purple_util_fetch_url(url, FALSE,
- "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)",
- TRUE, msn_got_info, data);
- session->url_datas = g_slist_prepend(session->url_datas, url_data);
-
- g_free(url);
-}
-
-static gboolean msn_load(PurplePlugin *plugin)
-{
- msn_notification_init();
- msn_switchboard_init();
-
- return TRUE;
-}
-
-static gboolean msn_unload(PurplePlugin *plugin)
-{
- msn_notification_end();
- msn_switchboard_end();
-
- return TRUE;
-}
-
-static PurpleAccount *find_acct(const char *prpl, const char *acct_id)
-{
- PurpleAccount *acct = NULL;
-
- /* If we have a specific acct, use it */
- if (acct_id) {
- acct = purple_accounts_find(acct_id, prpl);
- if (acct && !purple_account_is_connected(acct))
- acct = NULL;
- } else { /* Otherwise find an active account for the protocol */
- GList *l = purple_accounts_get_all();
- while (l) {
- if (!strcmp(prpl, purple_account_get_protocol_id(l->data))
- && purple_account_is_connected(l->data)) {
- acct = l->data;
- break;
- }
- l = l->next;
- }
- }
-
- return acct;
-}
-
-static gboolean msn_uri_handler(const char *proto, const char *cmd, GHashTable *params)
-{
- char *acct_id = g_hash_table_lookup(params, "account");
- PurpleAccount *acct;
-
- if (g_ascii_strcasecmp(proto, "msnim"))
- return FALSE;
-
- acct = find_acct("prpl-msn", acct_id);
-
- if (!acct)
- return FALSE;
-
- /* msnim:chat?contact=user@domain.tld */
- if (!g_ascii_strcasecmp(cmd, "Chat")) {
- char *sname = g_hash_table_lookup(params, "contact");
- if (sname) {
- PurpleConversation *conv = purple_find_conversation_with_account(
- PURPLE_CONV_TYPE_IM, sname, acct);
- if (conv == NULL)
- conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, acct, sname);
- purple_conversation_present(conv);
- }
- /*else
- **If pidgindialogs_im() was in the core, we could use it here.
- * It is all purple_request_* based, but I'm not sure it really belongs in the core
- pidgindialogs_im();*/
-
- return TRUE;
- }
- /* msnim:add?contact=user@domain.tld */
- else if (!g_ascii_strcasecmp(cmd, "Add")) {
- char *name = g_hash_table_lookup(params, "contact");
- purple_blist_request_add_buddy(acct, name, NULL, NULL);
- return TRUE;
- }
-
- return FALSE;
-}
-
-
-static PurplePluginProtocolInfo prpl_info =
-{
- OPT_PROTO_MAIL_CHECK|OPT_PROTO_INVITE_MESSAGE,
- NULL, /* user_splits */
- NULL, /* protocol_options */
- {"png,gif", 0, 0, 96, 96, 0, PURPLE_ICON_SCALE_SEND}, /* icon_spec */
- msn_list_icon, /* list_icon */
- msn_list_emblems, /* list_emblems */
- msn_status_text, /* status_text */
- msn_tooltip_text, /* tooltip_text */
- msn_status_types, /* away_states */
- msn_blist_node_menu, /* blist_node_menu */
- NULL, /* chat_info */
- NULL, /* chat_info_defaults */
- msn_login, /* login */
- msn_close, /* close */
- msn_send_im, /* send_im */
- NULL, /* set_info */
- msn_send_typing, /* send_typing */
- msn_get_info, /* get_info */
- msn_set_status, /* set_away */
- msn_set_idle, /* set_idle */
- NULL, /* change_passwd */
- NULL, /* add_buddy */
- NULL, /* add_buddies */
- msn_rem_buddy, /* remove_buddy */
- NULL, /* remove_buddies */
- msn_add_permit, /* add_permit */
- msn_add_deny, /* add_deny */
- msn_rem_permit, /* rem_permit */
- msn_rem_deny, /* rem_deny */
- msn_set_permit_deny, /* set_permit_deny */
- NULL, /* join_chat */
- NULL, /* reject chat invite */
- NULL, /* get_chat_name */
- msn_chat_invite, /* chat_invite */
- msn_chat_leave, /* chat_leave */
- NULL, /* chat_whisper */
- msn_chat_send, /* chat_send */
- msn_keepalive, /* keepalive */
- NULL, /* register_user */
- NULL, /* get_cb_info */
- NULL, /* get_cb_away */
- msn_alias_buddy, /* alias_buddy */
- msn_group_buddy, /* group_buddy */
- msn_rename_group, /* rename_group */
- NULL, /* buddy_free */
- msn_convo_closed, /* convo_closed */
- msn_normalize, /* normalize */
- msn_set_buddy_icon, /* set_buddy_icon */
- msn_remove_group, /* remove_group */
- NULL, /* get_cb_real_name */
- NULL, /* set_chat_topic */
- NULL, /* find_blist_chat */
- NULL, /* roomlist_get_list */
- NULL, /* roomlist_cancel */
- NULL, /* roomlist_expand_category */
- msn_can_receive_file, /* can_receive_file */
- msn_send_file, /* send_file */
- msn_new_xfer, /* new_xfer */
- msn_offline_message, /* offline_message */
- NULL, /* whiteboard_prpl_ops */
- NULL, /* send_raw */
- NULL, /* roomlist_room_serialize */
- NULL, /* unregister_user */
- msn_send_attention, /* send_attention */
- msn_attention_types, /* attention_types */
- sizeof(PurplePluginProtocolInfo), /* struct_size */
- msn_get_account_text_table, /* get_account_text_table */
- NULL, /* initiate_media */
- NULL, /* get_media_caps */
- NULL, /* get_moods */
- msn_set_public_alias, /* set_public_alias */
- msn_get_public_alias, /* get_public_alias */
- msn_add_buddy, /* add_buddy_with_invite */
- NULL /* add_buddies_with_invite */
-};
-
-static PurplePluginInfo info =
-{
- PURPLE_PLUGIN_MAGIC,
- PURPLE_MAJOR_VERSION,
- PURPLE_MINOR_VERSION,
- PURPLE_PLUGIN_PROTOCOL, /**< type */
- NULL, /**< ui_requirement */
- 0, /**< flags */
- NULL, /**< dependencies */
- PURPLE_PRIORITY_DEFAULT, /**< priority */
-
- "prpl-msn", /**< id */
- "MSN", /**< name */
- DISPLAY_VERSION, /**< version */
- N_("Windows Live Messenger Protocol Plugin"), /**< summary */
- N_("Windows Live Messenger Protocol Plugin"), /**< description */
- NULL, /**< author */
- PURPLE_WEBSITE, /**< homepage */
-
- msn_load, /**< load */
- msn_unload, /**< unload */
- NULL, /**< destroy */
-
- NULL, /**< ui_info */
- &prpl_info, /**< extra_info */
- NULL, /**< prefs_info */
- msn_actions,
-
- /* padding */
- NULL,
- NULL,
- NULL,
- NULL
-};
-
-static void
-init_plugin(PurplePlugin *plugin)
-{
- PurpleAccountOption *option;
-
- option = purple_account_option_string_new(_("Server"), "server",
- MSN_SERVER);
- prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
- option);
-
- option = purple_account_option_int_new(_("Port"), "port", MSN_PORT);
- prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
- option);
-
- option = purple_account_option_bool_new(_("Use HTTP Method"),
- "http_method", FALSE);
- prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
- option);
-
- option = purple_account_option_string_new(_("HTTP Method Server"),
- "http_method_server", MSN_HTTPCONN_SERVER);
- prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
- option);
-
- option = purple_account_option_bool_new(_("Show custom smileys"),
- "custom_smileys", TRUE);
- prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
- option);
-
- option = purple_account_option_bool_new(_("Allow direct connections"),
- "direct_connect", TRUE);
- prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
- option);
-
- option = purple_account_option_bool_new(_("Allow connecting from multiple locations"),
- "mpop", TRUE);
- prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
- option);
-
- purple_cmd_register("nudge", "", PURPLE_CMD_P_PRPL,
- PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_PRPL_ONLY,
- "prpl-msn", msn_cmd_nudge,
- _("nudge: nudge a user to get their attention"), NULL);
-
- purple_prefs_remove("/plugins/prpl/msn");
-
- purple_signal_connect(purple_get_core(), "uri-handler", plugin,
- PURPLE_CALLBACK(msn_uri_handler), NULL);
-}
-
-PURPLE_INIT_PLUGIN(msn, init_plugin, info);
diff --git a/libpurple/protocols/msn/msn.h b/libpurple/protocols/msn/msn.h
deleted file mode 100644
index 7af87eceb2..0000000000
--- a/libpurple/protocols/msn/msn.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/**
- * @file msn.h The MSN protocol plugin
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-#ifndef MSN_H
-#define MSN_H
-
-typedef enum
-{
- MSN_CAP_VIA_MOBILE = 0x0000001,
- MSN_CAP_VIA_TEXAS = 0x0000002,
- MSN_CAP_INK_GIF = 0x0000004,
- MSN_CAP_INK_ISF = 0x0000008,
- MSN_CAP_VIDEO_CHAT = 0x0000010,
- MSN_CAP_PACKET = 0x0000020,
- MSN_CAP_MOBILE_ON = 0x0000040,
- MSN_CAP_WEB_WATCH = 0x0000080,
- MSN_CAP_ACTIVITIES = 0x0000100,
- MSN_CAP_VIA_WEBIM = 0x0000200,
- MSN_CAP_MOBILE_DEV = 0x0000400,
- MSN_CAP_VIA_FEDERATED = 0x0000800,
- MSN_CAP_SPACE = 0x0001000,
- MSN_CAP_MCE = 0x0002000,
- MSN_CAP_DIRECTIM = 0x0004000,
- MSN_CAP_WINKS = 0x0008000,
- MSN_CAP_SEARCH = 0x0010000,
- MSN_CAP_BOT = 0x0020000,
- MSN_CAP_VOICEIM = 0x0040000,
- MSN_CAP_SCHANNEL = 0x0080000,
- MSN_CAP_SIP_INVITE = 0x0100000,
- MSN_CAP_MULTI_VV = 0x0200000,
- MSN_CAP_SDRIVE = 0x0400000,
- MSN_CAP_PAGEMODE_MSG = 0x080000,
- MSN_CAP_ONECARE = 0x1000000,
- MSN_CAP_P2P_TURN = 0x2000000,
- MSN_CAP_P2P_BOOTSTRAP_VIA_UUN = 0x4000000,
- MSN_CAP_ALIASED = 0x8000000
-} MsnClientCaps;
-
-typedef enum
-{
- MSN_EXT_CAP_SMS_ONLY = 0x1,
- MSN_EXT_CAP_VOICE_OVER_MSNP = 0x2,
- MSN_EXT_CAP_UUCP_SIP = 0x4,
- MSN_EXT_CAP_APP_MSGS = 0x8,
- MSN_EXT_CAP_RTC_VIDEO = 0x10,
- MSN_EXT_CAP_P2PV2 = 0x20,
- MSN_EXT_CAP_AUTH_WEBIM = 0x40,
- MSN_EXT_CAP_1ON1_VIA_GROUP = 0x80,
- MSN_EXT_CAP_OFFLINEIM = 0x100,
- MSN_EXT_CAP_SHARING_VIDEO = 0x200,
- MSN_EXT_CAP_NUDGE = 0x400,
- MSN_EXT_CAP_CIRCLE_VOICEIM = 0x800,
- MSN_EXT_CAP_SHARING = 0x1000,
- MSN_EXT_CAP_P2P_MIXER_RELAY = 0x8000,
- MSN_EXT_CAP_CONV_WINDOW_FT = 0x20000,
- MSN_EXT_CAP_VIDEO_16x9 = 0x40000,
- MSN_EXT_CAP_P2P_ENVELOPE = 0x80000,
- MSN_EXT_CAP_YAHOOIM_DISABLE = 0x400000,
- MSN_EXT_CAP_SIP_TUNNELv2 = 0x800000,
- MSN_EXT_CAP_VOICE_CLIP_WMA = 0x1000000,
- MSN_EXT_CAP_VOICE_CLIP_CIRCLEIM = 0x2000000,
- MSN_EXT_CAP_SOCIAL_NEWS = 0x4000000,
- MSN_EXT_CAP_CUSTOM_SMILEY = 0x8000000,
- MSN_EXT_CAP_UTF8_MOODS = 0x10000000,
- MSN_EXT_CAP_FTURN = 0x20000000,
- MSN_EXT_CAP_P4_ACTIVITY = 0x40000000,
- MSN_EXT_CAP_MUC = 0x80000000
-} MsnClientExtCaps;
-
-typedef enum
-{
- MSN_CLIENT_VER_5_0 = 0x00,
- MSN_CLIENT_VER_6_0 = 0x10, /* MSNC1 */
- MSN_CLIENT_VER_6_1 = 0x20, /* MSNC2 */
- MSN_CLIENT_VER_6_2 = 0x30, /* MSNC3 */
- MSN_CLIENT_VER_7_0 = 0x40, /* MSNC4 */
- MSN_CLIENT_VER_7_5 = 0x50, /* MSNC5 */
- MSN_CLIENT_VER_8_0 = 0x60, /* MSNC6 */
- MSN_CLIENT_VER_8_1 = 0x70, /* MSNC7 */
- MSN_CLIENT_VER_8_5 = 0x80, /* MSNC8 */
- MSN_CLIENT_VER_9_0 = 0x90, /* MSNC9 */
- MSN_CLIENT_VER_14_0 = 0xA0, /* MSNC10 */
- MSN_CLIENT_VER_15_0 = 0xB0 /* MSNC11 */
-} MsnClientVerId;
-
-#include "internal.h"
-
-#include "session.h"
-
-#include "msg.h"
-
-#define MSN_BUF_LEN 8192
-
-/* Windows Live Messenger Server*/
-#define MSN_SERVER "messenger.hotmail.com"
-#define MSN_HTTPCONN_SERVER "gateway.messenger.hotmail.com"
-#define MSN_PORT 1863
-#define WLM_PROT_VER 18
-
-#define WLM_MAX_PROTOCOL 18
-#define WLM_MIN_PROTOCOL 18
-
-#define MSN_TYPING_RECV_TIMEOUT 6
-#define MSN_TYPING_SEND_TIMEOUT 4
-
-#define PROFILE_URL "http://spaces.live.com/profile.aspx?mem="
-#define PHOTO_URL " contactparams:photopreauthurl=\""
-
-#define BUDDY_ALIAS_MAXLEN 387
-
-#define MSN_CAM_GUID "4BD96FC0-AB17-4425-A14A-439185962DC8"
-#define MSN_CAM_REQUEST_GUID "1C9AA97E-9C05-4583-A3BD-908A196F1E92"
-#define MSN_FT_GUID "5D3E02AB-6190-11D3-BBBB-00C04F795683"
-#define MSN_OBJ_GUID "A4268EEC-FEC5-49E5-95C3-F126696BDBF6"
-
-#define MSN_CLIENTINFO \
- "Client-Name: Purple/" VERSION "\r\n" \
- "Chat-Logging: Y\r\n"
-
-/* Index into attention_types */
-#define MSN_NUDGE 0
-
-#define MSN_CLIENT_ID_VERSION MSN_CLIENT_VER_9_0
-#define MSN_CLIENT_ID_CAPABILITIES (MSN_CAP_PACKET|MSN_CAP_INK_GIF|MSN_CAP_VOICEIM)
-#define MSN_CLIENT_ID_EXT_CAPS (0)
-
-#define MSN_CLIENT_ID \
- ((MSN_CLIENT_ID_VERSION << 24) | \
- (MSN_CLIENT_ID_CAPABILITIES))
-
-void
-msn_set_public_alias(PurpleConnection *gc, const char *alias,
- PurpleSetPublicAliasSuccessCallback success_cb,
- PurpleSetPublicAliasFailureCallback failure_cb);
-void msn_send_privacy(PurpleConnection *gc);
-void msn_send_im_message(MsnSession *session, MsnMessage *msg);
-
-#endif /* MSN_H */
diff --git a/libpurple/protocols/msn/msnutils.c b/libpurple/protocols/msn/msnutils.c
deleted file mode 100644
index d2edd36fa0..0000000000
--- a/libpurple/protocols/msn/msnutils.c
+++ /dev/null
@@ -1,719 +0,0 @@
-/**
- * @file msnutils.c Utility functions
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-
-#include "internal.h"
-
-#include "msn.h"
-#include "msnutils.h"
-
-#include "cipher.h"
-
-/**************************************************************************
- * Util
- **************************************************************************/
-char *
-rand_guid(void)
-{
- return g_strdup_printf("%4X%4X-%4X-%4X-%4X-%4X%4X%4X",
- rand() % 0xAAFF + 0x1111,
- rand() % 0xAAFF + 0x1111,
- rand() % 0xAAFF + 0x1111,
- rand() % 0xAAFF + 0x1111,
- rand() % 0xAAFF + 0x1111,
- rand() % 0xAAFF + 0x1111,
- rand() % 0xAAFF + 0x1111,
- rand() % 0xAAFF + 0x1111);
-}
-
-void
-msn_parse_format(const char *mime, char **pre_ret, char **post_ret)
-{
- char *cur;
- GString *pre = g_string_new(NULL);
- GString *post = g_string_new(NULL);
- unsigned int colors[3];
-
- if (pre_ret != NULL) *pre_ret = NULL;
- if (post_ret != NULL) *post_ret = NULL;
-
- cur = strstr(mime, "FN=");
-
- if (cur && (*(cur = cur + 3) != ';'))
- {
- pre = g_string_append(pre, "<FONT FACE=\"");
-
- while (*cur && *cur != ';')
- {
- pre = g_string_append_c(pre, *cur);
- cur++;
- }
-
- pre = g_string_append(pre, "\">");
- post = g_string_prepend(post, "</FONT>");
- }
-
- cur = strstr(mime, "EF=");
-
- if (cur && (*(cur = cur + 3) != ';'))
- {
- while (*cur && *cur != ';')
- {
- pre = g_string_append_c(pre, '<');
- pre = g_string_append_c(pre, *cur);
- pre = g_string_append_c(pre, '>');
- post = g_string_prepend_c(post, '>');
- post = g_string_prepend_c(post, *cur);
- post = g_string_prepend_c(post, '/');
- post = g_string_prepend_c(post, '<');
- cur++;
- }
- }
-
- cur = strstr(mime, "CO=");
-
- if (cur && (*(cur = cur + 3) != ';'))
- {
- int i;
-
- i = sscanf(cur, "%02x%02x%02x;", &colors[0], &colors[1], &colors[2]);
-
- if (i > 0)
- {
- char tag[64];
-
- if (i == 1)
- {
- colors[1] = 0;
- colors[2] = 0;
- }
- else if (i == 2)
- {
- unsigned int temp = colors[0];
-
- colors[0] = colors[1];
- colors[1] = temp;
- colors[2] = 0;
- }
- else if (i == 3)
- {
- unsigned int temp = colors[2];
-
- colors[2] = colors[0];
- colors[0] = temp;
- }
-
- g_snprintf(tag, sizeof(tag),
- "<FONT COLOR=\"#%02x%02x%02x\">",
- colors[0] & 0xFF, colors[1] & 0xFF,
- colors[2] & 0xFF);
-
- pre = g_string_append(pre, tag);
- post = g_string_prepend(post, "</FONT>");
- }
- }
-
- cur = strstr(mime, "RL=");
-
- if (cur && (*(cur = cur + 3) != ';'))
- {
- if (*cur == '1')
- {
- /* RTL text was received */
- pre = g_string_append(pre, "<SPAN style=\"direction:rtl;text-align:right;\">");
- post = g_string_prepend(post, "</SPAN>");
- }
- }
-
- cur = g_strdup(purple_url_decode(pre->str));
- g_string_free(pre, TRUE);
-
- if (pre_ret != NULL)
- *pre_ret = cur;
- else
- g_free(cur);
-
- cur = g_strdup(purple_url_decode(post->str));
- g_string_free(post, TRUE);
-
- if (post_ret != NULL)
- *post_ret = cur;
- else
- g_free(cur);
-}
-
-/*encode the str to RFC2047 style
- * Currently only support the UTF-8 and base64 encode
- */
-char *
-msn_encode_mime(const char *str)
-{
- gchar *base64, *retval;
-
- g_return_val_if_fail(str != NULL, NULL);
-
- base64 = purple_base64_encode((guchar *)str, strlen(str));
- retval = g_strdup_printf("=?utf-8?B?%s?=", base64);
- g_free(base64);
-
- return retval;
-}
-
-/*
- * We need this because we're only supposed to encode spaces in the font
- * names. purple_url_encode() isn't acceptable.
- */
-gboolean
-msn_encode_spaces(const char *str, char *buf, size_t len)
-{
- char *nonspace = buf;
-
- while (isspace(*str))
- str++;
-
- for (; *str && len > 1; str++) {
- if (*str == '%') {
- if (len < 4)
- break;
- *buf++ = '%';
- *buf++ = '2';
- *buf++ = '5';
- len -= 3;
- nonspace = buf;
- } else if (*str == ' ') {
- if (len < 4)
- break;
- *buf++ = '%';
- *buf++ = '2';
- *buf++ = '0';
- len -= 3;
- } else {
- *buf++ = *str;
- len--;
- nonspace = buf;
- }
- }
-
- *nonspace = '\0';
-
- return (*str == '\0');
-}
-
-/*
- * Taken from the zephyr plugin.
- * This parses HTML formatting (put out by one of the gtkimhtml widgets
- * and converts it to msn formatting. It doesn't deal with the tag closing,
- * but gtkimhtml widgets give valid html.
- * It currently deals properly with <b>, <u>, <i>, <font face=...>,
- * <font color=...>, <span dir=...>, <span style="direction: ...">.
- * It ignores <font back=...> and <font size=...>
- */
-void
-msn_import_html(const char *html, char **attributes, char **message)
-{
- int len, retcount = 0;
- const char *c;
- char *msg;
- char *fontface = NULL;
- char fontface_encoded[BUF_LEN];
- char fonteffect[5];
- char fontcolor[7];
- char direction = '0';
-
- gboolean has_bold = FALSE;
- gboolean has_italic = FALSE;
- gboolean has_underline = FALSE;
- gboolean has_strikethrough = FALSE;
-
- g_return_if_fail(html != NULL);
- g_return_if_fail(attributes != NULL);
- g_return_if_fail(message != NULL);
-
- len = strlen(html);
- msg = g_malloc0(len + 1);
-
- memset(fontcolor, 0, sizeof(fontcolor));
- strcat(fontcolor, "0");
- memset(fonteffect, 0, sizeof(fonteffect));
-
- for (c = html; *c != '\0';)
- {
- if (*c == '<')
- {
- if (!g_ascii_strncasecmp(c + 1, "br>", 3))
- {
- msg[retcount++] = '\r';
- msg[retcount++] = '\n';
- c += 4;
- }
- else if (!g_ascii_strncasecmp(c + 1, "i>", 2))
- {
- if (!has_italic)
- {
- strcat(fonteffect, "I");
- has_italic = TRUE;
- }
- c += 3;
- }
- else if (!g_ascii_strncasecmp(c + 1, "b>", 2))
- {
- if (!has_bold)
- {
- strcat(fonteffect, "B");
- has_bold = TRUE;
- }
- c += 3;
- }
- else if (!g_ascii_strncasecmp(c + 1, "u>", 2))
- {
- if (!has_underline)
- {
- strcat(fonteffect, "U");
- has_underline = TRUE;
- }
- c += 3;
- }
- else if (!g_ascii_strncasecmp(c + 1, "s>", 2))
- {
- if (!has_strikethrough)
- {
- strcat(fonteffect, "S");
- has_strikethrough = TRUE;
- }
- c += 3;
- }
- else if (!g_ascii_strncasecmp(c + 1, "a href=\"", 8))
- {
- c += 9;
-
- if (!g_ascii_strncasecmp(c, "mailto:", 7))
- c += 7;
-
- while ((*c != '\0') && g_ascii_strncasecmp(c, "\">", 2))
- msg[retcount++] = *c++;
-
- if (*c != '\0')
- c += 2;
-
- /* ignore descriptive string */
- while ((*c != '\0') && g_ascii_strncasecmp(c, "</a>", 4))
- c++;
-
- if (*c != '\0')
- c += 4;
- }
- else if (!g_ascii_strncasecmp(c + 1, "span", 4))
- {
- /* Bi-directional text support using CSS properties in span tags */
- c += 5;
-
- while (*c != '\0' && *c != '>')
- {
- while (*c == ' ')
- c++;
- if (!g_ascii_strncasecmp(c, "dir=\"rtl\"", 9))
- {
- c += 9;
- direction = '1';
- }
- else if (!g_ascii_strncasecmp(c, "style=\"", 7))
- {
- /* Parse inline CSS attributes */
- char *attributes;
- int attr_len = 0;
- c += 7;
- while (*(c + attr_len) != '\0' && *(c + attr_len) != '"')
- attr_len++;
- if (*(c + attr_len) == '"')
- {
- char *attr_dir;
- attributes = g_strndup(c, attr_len);
- attr_dir = purple_markup_get_css_property(attributes, "direction");
- if (attr_dir && (!g_ascii_strncasecmp(attr_dir, "RTL", 3)))
- direction = '1';
- g_free(attr_dir);
- g_free(attributes);
- }
-
- }
- else
- {
- c++;
- }
- }
- if (*c == '>')
- c++;
- }
- else if (!g_ascii_strncasecmp(c + 1, "font", 4))
- {
- c += 5;
-
- while ((*c != '\0') && !g_ascii_strncasecmp(c, " ", 1))
- c++;
-
- if (!g_ascii_strncasecmp(c, "color=\"#", 7))
- {
- c += 8;
-
- fontcolor[0] = *(c + 4);
- fontcolor[1] = *(c + 5);
- fontcolor[2] = *(c + 2);
- fontcolor[3] = *(c + 3);
- fontcolor[4] = *c;
- fontcolor[5] = *(c + 1);
-
- c += 8;
- }
- else if (!g_ascii_strncasecmp(c, "face=\"", 6))
- {
- const char *end = NULL;
- const char *comma = NULL;
- unsigned int namelen = 0;
-
- c += 6;
- end = strchr(c, '\"');
- comma = strchr(c, ',');
-
- if (comma == NULL || comma > end)
- namelen = (unsigned int)(end - c);
- else
- namelen = (unsigned int)(comma - c);
-
- fontface = g_strndup(c, namelen);
- c = end + 2;
- }
- else
- {
- /* Drop all unrecognized/misparsed font tags */
- while ((*c != '\0') && g_ascii_strncasecmp(c, "\">", 2))
- c++;
-
- if (*c != '\0')
- c += 2;
- }
- }
- else
- {
- while ((*c != '\0') && (*c != '>'))
- c++;
- if (*c != '\0')
- c++;
- }
- }
- else if (*c == '&')
- {
- if (!g_ascii_strncasecmp(c, "&lt;", 4))
- {
- msg[retcount++] = '<';
- c += 4;
- }
- else if (!g_ascii_strncasecmp(c, "&gt;", 4))
- {
- msg[retcount++] = '>';
- c += 4;
- }
- else if (!g_ascii_strncasecmp(c, "&nbsp;", 6))
- {
- msg[retcount++] = ' ';
- c += 6;
- }
- else if (!g_ascii_strncasecmp(c, "&quot;", 6))
- {
- msg[retcount++] = '"';
- c += 6;
- }
- else if (!g_ascii_strncasecmp(c, "&amp;", 5))
- {
- msg[retcount++] = '&';
- c += 5;
- }
- else if (!g_ascii_strncasecmp(c, "&apos;", 6))
- {
- msg[retcount++] = '\'';
- c += 6;
- }
- else
- msg[retcount++] = *c++;
- }
- else
- msg[retcount++] = *c++;
- }
-
- if (fontface == NULL)
- fontface = g_strdup("Segoe UI");
-
- msn_encode_spaces(fontface, fontface_encoded, BUF_LEN);
- *attributes = g_strdup_printf("FN=%s; EF=%s; CO=%s; PF=0; RL=%c",
- fontface_encoded,
- fonteffect, fontcolor, direction);
- *message = msg;
-
- g_free(fontface);
-}
-
-void
-msn_parse_socket(const char *str, char **ret_host, int *ret_port)
-{
- char *host;
- char *c;
- int port;
-
- host = g_strdup(str);
-
- if ((c = strchr(host, ':')) != NULL) {
- *c = '\0';
- port = atoi(c + 1);
- } else {
- port = 1863;
- }
-
- *ret_host = host;
- *ret_port = port;
-}
-
-void
-msn_parse_user(const char *str, char **ret_user, int *ret_network)
-{
- char **tokens;
-
- tokens = g_strsplit(str, ":", 2);
-
- *ret_network = atoi(tokens[0]);
- *ret_user = tokens[1];
-
- g_free(tokens[0]);
- /* tokens[1] is returned */
- g_free(tokens);
-}
-
-gboolean
-msn_email_is_valid(const char *passport)
-{
- if (purple_email_is_valid(passport)) {
- /* Special characters aren't allowed in domains, so only go to '@' */
- while (*passport != '@') {
- if (*passport == '/')
- return FALSE;
- else if (*passport == '?')
- return FALSE;
- else if (*passport == '=')
- return FALSE;
- /* MSN also doesn't like colons, but that's checked already */
-
- passport++;
- }
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-/***************************************************************************
- * MSN Challenge Computing Function
- ***************************************************************************/
-
-/*
- * Handle MSN Challenge computation
- * This algorithm references
- * http://imfreedom.org/wiki/index.php/MSN:NS/Challenges
- */
-#define BUFSIZE 256
-void
-msn_handle_chl(char *input, char *output)
-{
- PurpleCipher *cipher;
- PurpleCipherContext *context;
- const guchar productKey[] = MSNP15_WLM_PRODUCT_KEY;
- const guchar productID[] = MSNP15_WLM_PRODUCT_ID;
- const char hexChars[] = "0123456789abcdef";
- char buf[BUFSIZE];
- unsigned char md5Hash[16];
- unsigned char *newHash;
- unsigned int *md5Parts;
- unsigned int *chlStringParts;
- unsigned int newHashParts[5];
-
- long long nHigh = 0, nLow = 0;
-
- int len;
- int i;
-
- /* Create the MD5 hash by using Purple MD5 algorithm */
- cipher = purple_ciphers_find_cipher("md5");
- context = purple_cipher_context_new(cipher, NULL);
-
- purple_cipher_context_append(context, (guchar *)input, strlen(input));
- purple_cipher_context_append(context, productKey, sizeof(productKey) - 1);
- purple_cipher_context_digest(context, sizeof(md5Hash), md5Hash, NULL);
- purple_cipher_context_destroy(context);
-
- /* Split it into four integers */
- md5Parts = (unsigned int *)md5Hash;
- for (i = 0; i < 4; i++) {
- /* adjust endianess */
- md5Parts[i] = GUINT_TO_LE(md5Parts[i]);
-
- /* & each integer with 0x7FFFFFFF */
- /* and save one unmodified array for later */
- newHashParts[i] = md5Parts[i];
- md5Parts[i] &= 0x7FFFFFFF;
- }
-
- /* make a new string and pad with '0' to length that's a multiple of 8 */
- snprintf(buf, BUFSIZE - 5, "%s%s", input, productID);
- len = strlen(buf);
- if ((len % 8) != 0) {
- int fix = 8 - (len % 8);
- strncpy(&buf[len], "00000000", fix);
- buf[len + fix] = '\0';
- len += fix;
- }
-
- /* split into integers */
- chlStringParts = (unsigned int *)buf;
-
- /* this is magic */
- for (i = 0; i < (len / 4); i += 2) {
- long long temp;
-
- chlStringParts[i] = GUINT_TO_LE(chlStringParts[i]);
- chlStringParts[i + 1] = GUINT_TO_LE(chlStringParts[i + 1]);
-
- temp = (0x0E79A9C1 * (long long)chlStringParts[i]) % 0x7FFFFFFF;
- temp = (md5Parts[0] * (temp + nLow) + md5Parts[1]) % 0x7FFFFFFF;
- nHigh += temp;
-
- temp = ((long long)chlStringParts[i + 1] + temp) % 0x7FFFFFFF;
- nLow = (md5Parts[2] * temp + md5Parts[3]) % 0x7FFFFFFF;
- nHigh += nLow;
- }
- nLow = (nLow + md5Parts[1]) % 0x7FFFFFFF;
- nHigh = (nHigh + md5Parts[3]) % 0x7FFFFFFF;
-
- newHashParts[0] ^= nLow;
- newHashParts[1] ^= nHigh;
- newHashParts[2] ^= nLow;
- newHashParts[3] ^= nHigh;
-
- /* adjust endianness */
- for(i = 0; i < 4; i++)
- newHashParts[i] = GUINT_TO_LE(newHashParts[i]);
-
- /* make a string of the parts */
- newHash = (unsigned char *)newHashParts;
-
- /* convert to hexadecimal */
- for (i = 0; i < 16; i++)
- {
- output[i * 2] = hexChars[(newHash[i] >> 4) & 0xF];
- output[(i * 2) + 1] = hexChars[newHash[i] & 0xF];
- }
-
- output[32] = '\0';
-}
-
-guint8
-msn_read8(const char *buf)
-{
- return (guint8)buf[0];
-}
-
-guint16
-msn_read16le(const char *buf)
-{
- return GUINT16_FROM_LE(*(guint16 *)buf);
-}
-
-guint16
-msn_read16be(const char *buf)
-{
- return GUINT16_FROM_BE(*(guint16 *)buf);
-}
-
-guint32
-msn_read32le(const char *buf)
-{
- return GUINT32_FROM_LE(*(guint32 *)buf);
-}
-
-guint32
-msn_read32be(const char *buf)
-{
- return GUINT32_FROM_BE(*(guint32 *)buf);
-}
-
-guint64
-msn_read64le(const char *buf)
-{
- return GUINT64_FROM_LE(*(guint64 *)buf);
-}
-
-guint64
-msn_read64be(const char *buf)
-{
- return GUINT64_FROM_BE(*(guint64 *)buf);
-}
-
-void
-msn_write8(char *buf, guint8 data)
-{
- *(guint8 *)buf = data;
-}
-
-void
-msn_write16le(char *buf, guint16 data)
-{
- *(guint16 *)buf = GUINT16_TO_LE(data);
-}
-
-void
-msn_write16be(char *buf, guint16 data)
-{
- *(guint16 *)buf = GUINT16_TO_BE(data);
-}
-
-void
-msn_write32le(char *buf, guint32 data)
-{
- *(guint32 *)buf = GUINT32_TO_LE(data);
-}
-
-void
-msn_write32be(char *buf, guint32 data)
-{
- *(guint32 *)buf = GUINT32_TO_BE(data);
-}
-
-void
-msn_write64le(char *buf, guint64 data)
-{
- *(guint64 *)buf = GUINT64_TO_LE(data);
-}
-
-void
-msn_write64be(char *buf, guint64 data)
-{
- *(guint64 *)buf = GUINT64_TO_BE(data);
-}
-
diff --git a/libpurple/protocols/msn/msnutils.h b/libpurple/protocols/msn/msnutils.h
deleted file mode 100644
index c4ed8fcbdf..0000000000
--- a/libpurple/protocols/msn/msnutils.h
+++ /dev/null
@@ -1,244 +0,0 @@
-/**
- * @file msnutils.h Utility functions
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-#ifndef MSN_UTILS_H
-#define MSN_UTILS_H
-
-/*encode the str to RFC2047 style*/
-char *msn_encode_mime(const char *str);
-
-/**
- * Generate the Random GUID
- */
-char *rand_guid(void);
-
-/**
- * Encodes the spaces in a string
- *
- * @param str The string to be encoded.
- * @param buf The buffer to hold the encoded string.
- * @param len The maximum length (including NUL) to put in @buf.
- *
- * @return Whether @str was able to fit in @buf.
- */
-gboolean
-msn_encode_spaces(const char *str, char *buf, size_t len);
-
-/**
- * Parses the MSN message formatting into a format compatible with Purple.
- *
- * @param mime The mime header with the formatting.
- * @param pre_ret The returned prefix string.
- * @param post_ret The returned postfix string.
- *
- * @return The new message.
- */
-void msn_parse_format(const char *mime, char **pre_ret, char **post_ret);
-
-/**
- * Parses the Purple message formatting (html) into the MSN format.
- *
- * @param html The html message to format.
- * @param attributes The returned attributes string.
- * @param message The returned message string.
- *
- * @return The new message.
- */
-void msn_import_html(const char *html, char **attributes, char **message);
-
-/**
- * Parses a socket string.
- *
- * @param str A host:port string.
- * @param ret_host Return string value of the host.
- * @param ret_port Return integer value of the port.
- */
-void msn_parse_socket(const char *str, char **ret_host, int *ret_port);
-
-/**
- * Parses a user name
- *
- * @param str A network:username string.
- * @param ret_user Return of the user's passport.
- * @param ret_network Return of the user's network.
- */
-void msn_parse_user(const char *str, char **ret_user, int *ret_network);
-
-/**
- * Verify if the email is a vaild passport.
- *
- * @param passport The email
- *
- * @return True if it is a valid passport, else FALSE
- */
-gboolean msn_email_is_valid(const char *passport);
-
-/**
- * Handle MSN Challenge Computation
- * This algorithm references
- * http://imfreedom.org/wiki/index.php/MSN:NS/Challenges
- *
- * @param input Challenge input.
- * @param output Callenge output.
- */
-void msn_handle_chl(char *input, char *output);
-
-/**
- * Read a byte from a buffer
- *
- * @param buf Pointer to buffer.
- *
- * @return 8-bit byte
- */
-guint8 msn_read8(const char *buf);
-
-/**
- * Read a little-endian short from a buffer
- *
- * @param buf Pointer to buffer.
- *
- * @return 16-bit short
- */
-guint16 msn_read16le(const char *buf);
-
-/**
- * Read a big-endian short from a buffer
- *
- * @param buf Pointer to buffer.
- *
- * @return 16-bit short
- */
-guint16 msn_read16be(const char *buf);
-
-/**
- * Read a little-endian int from a buffer
- *
- * @param buf Pointer to buffer.
- *
- * @return 32-bit int
- */
-guint32 msn_read32le(const char *buf);
-
-/**
- * Read a big-endian int from a buffer
- *
- * @param buf Pointer to buffer.
- *
- * @return 32-bit int
- */
-guint32 msn_read32be(const char *buf);
-
-/**
- * Read a little-endian long from a buffer
- *
- * @param buf Pointer to buffer.
- *
- * @return 64-bit long
- */
-guint64 msn_read64le(const char *buf);
-
-/**
- * Read a big-endian long from a buffer
- *
- * @param buf Pointer to buffer.
- *
- * @return 64-bit long
- */
-guint64 msn_read64be(const char *buf);
-
-/**
- * Write a byte to a buffer
- *
- * @param buf Pointer to buffer.
- * @param data 8-bit byte.
- */
-void msn_write8(char *buf, guint8 data);
-
-/**
- * Write a little-endian short to a buffer
- *
- * @param buf Pointer to buffer.
- * @param data short.
- */
-void msn_write16le(char *buf, guint16 data);
-
-/**
- * Write a big-endian short to a buffer
- *
- * @param buf Pointer to buffer.
- * @param data short.
- */
-void msn_write16be(char *buf, guint16 data);
-
-/**
- * Write a little-endian int to a buffer
- *
- * @param buf Pointer to buffer.
- * @param data int.
- */
-void msn_write32le(char *buf, guint32 data);
-
-/**
- * Write a big-endian int to a buffer
- *
- * @param buf Pointer to buffer.
- * @param data int.
- */
-void msn_write32be(char *buf, guint32 data);
-
-/**
- * Write a little-endian long to a buffer
- *
- * @param buf Pointer to buffer.
- * @param data long.
- */
-void msn_write64le(char *buf, guint64 data);
-
-/**
- * Write a big-endian long to a buffer
- *
- * @param buf Pointer to buffer.
- * @param data short
- */
-void msn_write64be(char *buf, guint64 data);
-
-/**
- * Same as above, but these increment the buf pointer.
- */
-#define msn_pop8(buf) msn_read8((buf+=1)-1)
-#define msn_pop16le(buf) msn_read16le((buf+=2)-2)
-#define msn_pop16be(buf) msn_read16be((buf+=2)-2)
-#define msn_pop32le(buf) msn_read32le((buf+=4)-4)
-#define msn_pop32be(buf) msn_read32be((buf+=4)-4)
-#define msn_pop64le(buf) msn_read64le((buf+=8)-8)
-#define msn_pop64be(buf) msn_read64be((buf+=8)-8)
-#define msn_push8(buf, data) msn_write8(buf, data), buf+=1
-#define msn_push16le(buf, data) msn_write16le(buf, data), buf+=2
-#define msn_push16be(buf, data) msn_write16be(buf, data), buf+=2
-#define msn_push32le(buf, data) msn_write32le(buf, data), buf+=4
-#define msn_push32be(buf, data) msn_write32be(buf, data), buf+=4
-#define msn_push64le(buf, data) msn_write64le(buf, data), buf+=8
-#define msn_push64be(buf, data) msn_write64be(buf, data), buf+=8
-
-#endif /* MSN_UTILS_H */
-
diff --git a/libpurple/protocols/msn/nexus.c b/libpurple/protocols/msn/nexus.c
deleted file mode 100644
index 34e9f66e6f..0000000000
--- a/libpurple/protocols/msn/nexus.c
+++ /dev/null
@@ -1,670 +0,0 @@
-/**
- * @file nexus.c MSN Nexus functions
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-
-#include "internal.h"
-#include "cipher.h"
-#include "debug.h"
-
-#include "msnutils.h"
-#include "soap.h"
-#include "nexus.h"
-#include "notification.h"
-
-/**************************************************************************
- * Valid Ticket Tokens
- **************************************************************************/
-
-#define SSO_VALID_TICKET_DOMAIN 0
-#define SSO_VALID_TICKET_POLICY 1
-static char *ticket_domains[][2] = {
- /* http://msnpiki.msnfanatic.com/index.php/MSNP15:SSO */
- /* {"Domain", "Policy Ref URI"}, Purpose */
- {"messengerclear.live.com", NULL}, /* Authentication for messenger. */
- {"messenger.msn.com", "?id=507"}, /* Authentication for receiving OIMs. */
- {"contacts.msn.com", "MBI"}, /* Authentication for the Contact server. */
- {"messengersecure.live.com", "MBI_SSL"}, /* Authentication for sending OIMs. */
- {"storage.live.com", "MBI"}, /* Storage REST API */
- {"sup.live.com", "MBI"}, /* What's New service */
-};
-
-/**************************************************************************
- * Main
- **************************************************************************/
-
-MsnNexus *
-msn_nexus_new(MsnSession *session)
-{
- MsnNexus *nexus;
- gsize i;
-
- nexus = g_new0(MsnNexus, 1);
- nexus->session = session;
-
- nexus->token_len = sizeof(ticket_domains) / sizeof(char *[2]);
- nexus->tokens = g_new0(MsnTicketToken, nexus->token_len);
-
- for (i = 0; i < nexus->token_len; i++)
- nexus->tokens[i].token = g_hash_table_new_full(g_str_hash, g_str_equal,
- g_free, g_free);
-
- return nexus;
-}
-
-void
-msn_nexus_destroy(MsnNexus *nexus)
-{
- gsize i;
- for (i = 0; i < nexus->token_len; i++) {
- g_hash_table_destroy(nexus->tokens[i].token);
- g_free(nexus->tokens[i].secret);
- g_slist_free(nexus->tokens[i].updates);
- }
-
- g_free(nexus->tokens);
- g_free(nexus->policy);
- g_free(nexus->nonce);
- g_free(nexus->cipher);
- g_free(nexus->secret);
- g_free(nexus);
-}
-
-/**************************************************************************
- * RPS/SSO Authentication
- **************************************************************************/
-
-static char *
-rps_create_key(const char *key, int key_len, const char *data, size_t data_len)
-{
- const guchar magic[] = "WS-SecureConversation";
- const int magic_len = sizeof(magic) - 1;
-
- PurpleCipherContext *hmac;
- guchar hash1[20], hash2[20], hash3[20], hash4[20];
- char *result;
-
- hmac = purple_cipher_context_new_by_name("hmac", NULL);
-
- purple_cipher_context_set_option(hmac, "hash", "sha1");
- purple_cipher_context_set_key_with_len(hmac, (guchar *)key, key_len);
- purple_cipher_context_append(hmac, magic, magic_len);
- purple_cipher_context_append(hmac, (guchar *)data, data_len);
- purple_cipher_context_digest(hmac, sizeof(hash1), hash1, NULL);
-
- purple_cipher_context_reset(hmac, NULL);
- purple_cipher_context_set_option(hmac, "hash", "sha1");
- purple_cipher_context_set_key_with_len(hmac, (guchar *)key, key_len);
- purple_cipher_context_append(hmac, hash1, 20);
- purple_cipher_context_append(hmac, magic, magic_len);
- purple_cipher_context_append(hmac, (guchar *)data, data_len);
- purple_cipher_context_digest(hmac, sizeof(hash2), hash2, NULL);
-
- purple_cipher_context_reset(hmac, NULL);
- purple_cipher_context_set_option(hmac, "hash", "sha1");
- purple_cipher_context_set_key_with_len(hmac, (guchar *)key, key_len);
- purple_cipher_context_append(hmac, hash1, 20);
- purple_cipher_context_digest(hmac, sizeof(hash3), hash3, NULL);
-
- purple_cipher_context_reset(hmac, NULL);
- purple_cipher_context_set_option(hmac, "hash", "sha1");
- purple_cipher_context_set_key_with_len(hmac, (guchar *)key, key_len);
- purple_cipher_context_append(hmac, hash3, sizeof(hash3));
- purple_cipher_context_append(hmac, magic, magic_len);
- purple_cipher_context_append(hmac, (guchar *)data, data_len);
- purple_cipher_context_digest(hmac, sizeof(hash4), hash4, NULL);
-
- purple_cipher_context_destroy(hmac);
-
- result = g_malloc(24);
- memcpy(result, hash2, sizeof(hash2));
- memcpy(result + sizeof(hash2), hash4, 4);
-
- return result;
-}
-
-static char *
-des3_cbc(const char *key, const char *iv, const char *data, int len, gboolean decrypt)
-{
- PurpleCipherContext *des3;
- char *out;
- size_t outlen;
-
- des3 = purple_cipher_context_new_by_name("des3", NULL);
- purple_cipher_context_set_key(des3, (guchar *)key);
- purple_cipher_context_set_batch_mode(des3, PURPLE_CIPHER_BATCH_MODE_CBC);
- purple_cipher_context_set_iv(des3, (guchar *)iv, 8);
-
- out = g_malloc(len);
- if (decrypt)
- purple_cipher_context_decrypt(des3, (guchar *)data, len, (guchar *)out, &outlen);
- else
- purple_cipher_context_encrypt(des3, (guchar *)data, len, (guchar *)out, &outlen);
-
- purple_cipher_context_destroy(des3);
-
- return out;
-}
-
-#define MSN_USER_KEY_SIZE (7*4 + 8 + 20 + 72)
-#define CRYPT_MODE_CBC 1
-#define CIPHER_TRIPLE_DES 0x6603
-#define HASH_SHA1 0x8004
-static char *
-msn_rps_encrypt(MsnNexus *nexus)
-{
- char usr_key_base[MSN_USER_KEY_SIZE], *usr_key;
- const char magic1[] = "SESSION KEY HASH";
- const char magic2[] = "SESSION KEY ENCRYPTION";
- PurpleCipherContext *hmac;
- size_t len;
- guchar *hash;
- char *key1, *key2, *key3;
- gsize key1_len;
- const char *iv;
- char *nonce_fixed;
- char *cipher;
- char *response;
-
- usr_key = &usr_key_base[0];
- /* Header */
- msn_push32le(usr_key, 28); /* Header size */
- msn_push32le(usr_key, CRYPT_MODE_CBC); /* Crypt mode */
- msn_push32le(usr_key, CIPHER_TRIPLE_DES); /* Cipher type */
- msn_push32le(usr_key, HASH_SHA1); /* Hash type */
- msn_push32le(usr_key, 8); /* IV size */
- msn_push32le(usr_key, 20); /* Hash size */
- msn_push32le(usr_key, 72); /* Cipher size */
- /* Data */
- iv = usr_key;
- msn_push32le(usr_key, rand());
- msn_push32le(usr_key, rand());
- hash = (guchar *)usr_key;
- usr_key += 20; /* Remaining is cipher data */
-
- key1 = (char *)purple_base64_decode((const char *)nexus->tokens[MSN_AUTH_MESSENGER].secret, &key1_len);
- key2 = rps_create_key(key1, key1_len, magic1, sizeof(magic1) - 1);
- key3 = rps_create_key(key1, key1_len, magic2, sizeof(magic2) - 1);
-
- len = strlen(nexus->nonce);
- hmac = purple_cipher_context_new_by_name("hmac", NULL);
- purple_cipher_context_set_option(hmac, "hash", "sha1");
- purple_cipher_context_set_key_with_len(hmac, (guchar *)key2, 24);
- purple_cipher_context_append(hmac, (guchar *)nexus->nonce, len);
- purple_cipher_context_digest(hmac, 20, hash, NULL);
- purple_cipher_context_destroy(hmac);
-
- /* We need to pad this to 72 bytes, apparently */
- nonce_fixed = g_malloc(len + 8);
- memcpy(nonce_fixed, nexus->nonce, len);
- memset(nonce_fixed + len, 0x08, 8);
- cipher = des3_cbc(key3, iv, nonce_fixed, len + 8, FALSE);
- g_free(nonce_fixed);
-
- memcpy(usr_key, cipher, 72);
-
- g_free(key1);
- g_free(key2);
- g_free(key3);
- g_free(cipher);
-
- response = purple_base64_encode((guchar *)usr_key_base, MSN_USER_KEY_SIZE);
-
- return response;
-}
-
-/**************************************************************************
- * Login
- **************************************************************************/
-
-/* Used to specify which token to update when only doing single updates */
-typedef struct _MsnNexusUpdateData MsnNexusUpdateData;
-struct _MsnNexusUpdateData {
- MsnNexus *nexus;
- int id;
-};
-
-typedef struct _MsnNexusUpdateCallback MsnNexusUpdateCallback;
-struct _MsnNexusUpdateCallback {
- GSourceFunc cb;
- gpointer data;
-};
-
-static gboolean
-nexus_parse_token(MsnNexus *nexus, int id, xmlnode *node)
-{
- char *token_str, *expiry_str;
- const char *id_str;
- char **elems, **cur, **tokens;
- xmlnode *token = xmlnode_get_child(node, "RequestedSecurityToken/BinarySecurityToken");
- xmlnode *secret = xmlnode_get_child(node, "RequestedProofToken/BinarySecret");
- xmlnode *expires = xmlnode_get_child(node, "LifeTime/Expires");
-
- if (!token)
- return FALSE;
-
- /* Use the ID that the server sent us */
- if (id == -1) {
- id_str = xmlnode_get_attrib(token, "Id");
- if (id_str == NULL)
- return FALSE;
-
- id = atol(id_str + 7) - 1; /* 'Compact#' or 'PPToken#' */
- if (id < 0 || (gsize)id >= nexus->token_len)
- return FALSE; /* Where did this come from? */
- }
-
- token_str = xmlnode_get_data(token);
- if (token_str == NULL)
- return FALSE;
-
- g_hash_table_remove_all(nexus->tokens[id].token);
-
- elems = g_strsplit(token_str, "&", 0);
-
- for (cur = elems; *cur != NULL; cur++) {
- tokens = g_strsplit(*cur, "=", 2);
- g_hash_table_insert(nexus->tokens[id].token, tokens[0], tokens[1]);
- /* Don't free each of the tokens, only the array. */
- g_free(tokens);
- }
- g_strfreev(elems);
- g_free(token_str);
-
- if (secret)
- nexus->tokens[id].secret = xmlnode_get_data(secret);
- else
- nexus->tokens[id].secret = NULL;
-
- /* Yay for MS using ISO-8601 */
- expiry_str = xmlnode_get_data(expires);
- nexus->tokens[id].expiry = purple_str_to_time(expiry_str,
- FALSE, NULL, NULL, NULL);
- g_free(expiry_str);
-
- purple_debug_info("msn", "Updated ticket for domain '%s', expires at %" G_GINT64_FORMAT ".\n",
- ticket_domains[id][SSO_VALID_TICKET_DOMAIN],
- (gint64)nexus->tokens[id].expiry);
- return TRUE;
-}
-
-static gboolean
-nexus_parse_collection(MsnNexus *nexus, int id, xmlnode *collection)
-{
- xmlnode *node;
- gboolean result;
-
- node = xmlnode_get_child(collection, "RequestSecurityTokenResponse");
-
- if (!node)
- return FALSE;
-
- result = TRUE;
- for (; node && result; node = node->next) {
- xmlnode *endpoint = xmlnode_get_child(node, "AppliesTo/EndpointReference/Address");
- char *address = xmlnode_get_data(endpoint);
-
- if (g_str_equal(address, "http://Passport.NET/tb")) {
- /* This node contains the stuff for updating tokens. */
- char *data;
- xmlnode *cipher = xmlnode_get_child(node, "RequestedSecurityToken/EncryptedData/CipherData/CipherValue");
- xmlnode *secret = xmlnode_get_child(node, "RequestedProofToken/BinarySecret");
-
- g_free(nexus->cipher);
- nexus->cipher = xmlnode_get_data(cipher);
- data = xmlnode_get_data(secret);
- g_free(nexus->secret);
- nexus->secret = (char *)purple_base64_decode(data, NULL);
- g_free(data);
-
- } else {
- result = nexus_parse_token(nexus, id, node);
- }
- g_free(address);
- }
-
- return result;
-}
-
-static void
-nexus_got_response_cb(MsnSoapMessage *req, MsnSoapMessage *resp, gpointer data)
-{
- MsnNexus *nexus = data;
- MsnSession *session = nexus->session;
- const char *ticket;
- char *response;
-
- if (resp == NULL) {
- msn_session_set_error(session, MSN_ERROR_SERVCONN, _("Windows Live ID authentication:Unable to connect"));
- return;
- }
-
- if (!nexus_parse_collection(nexus, -1,
- xmlnode_get_child(resp->xml,
- "Body/RequestSecurityTokenResponseCollection"))) {
- msn_session_set_error(session, MSN_ERROR_SERVCONN, _("Windows Live ID authentication:Invalid response"));
- return;
- }
-
- ticket = msn_nexus_get_token_str(nexus, MSN_AUTH_MESSENGER);
- response = msn_rps_encrypt(nexus);
- msn_got_login_params(session, ticket, response);
- g_free(response);
-}
-
-/*when connect, do the SOAP Style windows Live ID authentication */
-void
-msn_nexus_connect(MsnNexus *nexus)
-{
- MsnSession *session = nexus->session;
- const char *username;
- const char *password;
- char *password_xml;
- GString *domains;
- char *request;
- gsize i;
-
- MsnSoapMessage *soap;
-
- purple_debug_info("msn", "Starting Windows Live ID authentication\n");
- msn_session_set_login_step(session, MSN_LOGIN_STEP_GET_COOKIE);
-
- username = purple_account_get_username(session->account);
- password = purple_connection_get_password(session->account->gc);
- if (g_utf8_strlen(password, -1) > 16) {
- /* max byte size for 16 utf8 characters is 64 + 1 for the null */
- gchar truncated[65];
- g_utf8_strncpy(truncated, password, 16);
- password_xml = g_markup_escape_text(truncated, -1);
- } else {
- password_xml = g_markup_escape_text(password, -1);
- }
-
- purple_debug_info("msn", "Logging on %s, with policy '%s', nonce '%s'\n",
- username, nexus->policy, nexus->nonce);
-
- domains = g_string_new(NULL);
- for (i = 0; i < nexus->token_len; i++) {
- g_string_append_printf(domains, MSN_SSO_RST_TEMPLATE,
- (int)i+1,
- ticket_domains[i][SSO_VALID_TICKET_DOMAIN],
- ticket_domains[i][SSO_VALID_TICKET_POLICY] != NULL ?
- ticket_domains[i][SSO_VALID_TICKET_POLICY] :
- nexus->policy);
- }
-
- request = g_strdup_printf(MSN_SSO_TEMPLATE, username, password_xml, domains->str);
- g_free(password_xml);
- g_string_free(domains, TRUE);
-
- soap = msn_soap_message_new(NULL, xmlnode_from_str(request, -1));
- g_free(request);
- msn_soap_message_send(session, soap, MSN_SSO_SERVER, SSO_POST_URL, TRUE,
- nexus_got_response_cb, nexus);
-}
-
-static void
-nexus_got_update_cb(MsnSoapMessage *req, MsnSoapMessage *resp, gpointer data)
-{
- MsnNexusUpdateData *ud = data;
- MsnNexus *nexus = ud->nexus;
- char iv[8] = {0,0,0,0,0,0,0,0};
- xmlnode *enckey;
- char *tmp;
- char *nonce;
- gsize len;
- char *key;
- GSList *updates;
-
-#if 0
- char *decrypted_pp;
-#endif
- char *decrypted_data;
-
- if (resp == NULL)
- return;
-
- purple_debug_info("msn", "Got Update Response for %s.\n", ticket_domains[ud->id][SSO_VALID_TICKET_DOMAIN]);
-
- enckey = xmlnode_get_child(resp->xml, "Header/Security/DerivedKeyToken");
- while (enckey) {
- if (g_str_equal(xmlnode_get_attrib(enckey, "Id"), "EncKey"))
- break;
- enckey = xmlnode_get_next_twin(enckey);
- }
- if (!enckey) {
- purple_debug_error("msn", "Invalid response in token update.\n");
- return;
- }
-
- tmp = xmlnode_get_data(xmlnode_get_child(enckey, "Nonce"));
- nonce = (char *)purple_base64_decode(tmp, &len);
- key = rps_create_key(nexus->secret, 24, nonce, len);
- g_free(tmp);
- g_free(nonce);
-
-#if 0
- /* Don't know what this is for yet */
- tmp = xmlnode_get_data(xmlnode_get_child(resp->xml,
- "Header/EncryptedPP/EncryptedData/CipherData/CipherValue"));
- if (tmp) {
- decrypted_pp = des3_cbc(key, iv, tmp, len, TRUE);
- g_free(tmp);
- purple_debug_info("msn", "Got Response Header EncryptedPP: %s\n", decrypted_pp);
- g_free(decrypted_pp);
- }
-#endif
-
- tmp = xmlnode_get_data(xmlnode_get_child(resp->xml,
- "Body/EncryptedData/CipherData/CipherValue"));
- if (tmp) {
- char *unescaped;
- xmlnode *rstresponse;
-
- unescaped = (char *)purple_base64_decode(tmp, &len);
- g_free(tmp);
-
- decrypted_data = des3_cbc(key, iv, unescaped, len, TRUE);
- g_free(unescaped);
- purple_debug_info("msn", "Got Response Body EncryptedData: %s\n", decrypted_data);
-
- rstresponse = xmlnode_from_str(decrypted_data, -1);
- if (g_str_equal(rstresponse->name, "RequestSecurityTokenResponse"))
- nexus_parse_token(nexus, ud->id, rstresponse);
- else
- nexus_parse_collection(nexus, ud->id, rstresponse);
- g_free(decrypted_data);
- }
-
- updates = nexus->tokens[ud->id].updates;
- nexus->tokens[ud->id].updates = NULL;
- while (updates != NULL) {
- MsnNexusUpdateCallback *update = updates->data;
- if (update->cb)
- purple_timeout_add(0, update->cb, update->data);
- g_free(update);
- updates = g_slist_delete_link(updates, updates);
- }
-
- g_free(ud);
- g_free(key);
-}
-
-void
-msn_nexus_update_token(MsnNexus *nexus, int id, GSourceFunc cb, gpointer data)
-{
- MsnSession *session = nexus->session;
- MsnNexusUpdateData *ud;
- MsnNexusUpdateCallback *update;
- PurpleCipherContext *sha1;
- PurpleCipherContext *hmac;
-
- char *key;
-
- guchar digest[20];
-
- struct tm *tm;
- time_t now;
- char *now_str;
- char *timestamp;
- char *timestamp_b64;
-
- char *domain;
- char *domain_b64;
-
- char *signedinfo;
- gint32 nonce[6];
- int i;
- char *nonce_b64;
- char *signature_b64;
- guchar signature[20];
-
- char *request;
- MsnSoapMessage *soap;
-
- update = g_new0(MsnNexusUpdateCallback, 1);
- update->cb = cb;
- update->data = data;
-
- if (nexus->tokens[id].updates != NULL) {
- /* Update already in progress. Just add to list and return. */
- purple_debug_info("msn",
- "Ticket update for user '%s' on domain '%s' in progress. Adding request to queue.\n",
- purple_account_get_username(session->account),
- ticket_domains[id][SSO_VALID_TICKET_DOMAIN]);
- nexus->tokens[id].updates = g_slist_prepend(nexus->tokens[id].updates,
- update);
- return;
- } else {
- purple_debug_info("msn",
- "Updating ticket for user '%s' on domain '%s'\n",
- purple_account_get_username(session->account),
- ticket_domains[id][SSO_VALID_TICKET_DOMAIN]);
- nexus->tokens[id].updates = g_slist_prepend(nexus->tokens[id].updates,
- update);
- }
-
- ud = g_new0(MsnNexusUpdateData, 1);
- ud->nexus = nexus;
- ud->id = id;
-
- sha1 = purple_cipher_context_new_by_name("sha1", NULL);
-
- domain = g_strdup_printf(MSN_SSO_RST_TEMPLATE,
- id,
- ticket_domains[id][SSO_VALID_TICKET_DOMAIN],
- ticket_domains[id][SSO_VALID_TICKET_POLICY] != NULL ?
- ticket_domains[id][SSO_VALID_TICKET_POLICY] :
- nexus->policy);
- purple_cipher_context_append(sha1, (guchar *)domain, strlen(domain));
- purple_cipher_context_digest(sha1, 20, digest, NULL);
- domain_b64 = purple_base64_encode(digest, 20);
-
- now = time(NULL);
- tm = gmtime(&now);
- now_str = g_strdup(purple_utf8_strftime("%Y-%m-%dT%H:%M:%SZ", tm));
- now += 5*60;
- tm = gmtime(&now);
- timestamp = g_strdup_printf(MSN_SSO_TIMESTAMP_TEMPLATE,
- now_str,
- purple_utf8_strftime("%Y-%m-%dT%H:%M:%SZ", tm));
- purple_cipher_context_reset(sha1, NULL);
- purple_cipher_context_append(sha1, (guchar *)timestamp, strlen(timestamp));
- purple_cipher_context_digest(sha1, 20, digest, NULL);
- timestamp_b64 = purple_base64_encode(digest, 20);
- g_free(now_str);
-
- purple_cipher_context_destroy(sha1);
-
- signedinfo = g_strdup_printf(MSN_SSO_SIGNEDINFO_TEMPLATE,
- id,
- domain_b64,
- timestamp_b64);
-
- for (i = 0; i < 6; i++)
- nonce[i] = rand();
- nonce_b64 = purple_base64_encode((guchar *)&nonce, sizeof(nonce));
-
- key = rps_create_key(nexus->secret, 24, (char *)nonce, sizeof(nonce));
- hmac = purple_cipher_context_new_by_name("hmac", NULL);
- purple_cipher_context_set_option(hmac, "hash", "sha1");
- purple_cipher_context_set_key_with_len(hmac, (guchar *)key, 24);
- purple_cipher_context_append(hmac, (guchar *)signedinfo, strlen(signedinfo));
- purple_cipher_context_digest(hmac, 20, signature, NULL);
- purple_cipher_context_destroy(hmac);
- signature_b64 = purple_base64_encode(signature, 20);
-
- request = g_strdup_printf(MSN_SSO_TOKEN_UPDATE_TEMPLATE,
- nexus->cipher,
- nonce_b64,
- timestamp,
- signedinfo,
- signature_b64,
- domain);
-
- g_free(nonce_b64);
- g_free(domain_b64);
- g_free(timestamp_b64);
- g_free(timestamp);
- g_free(key);
- g_free(signature_b64);
- g_free(signedinfo);
- g_free(domain);
-
- soap = msn_soap_message_new(NULL, xmlnode_from_str(request, -1));
- g_free(request);
- msn_soap_message_send(session, soap, MSN_SSO_SERVER, SSO_POST_URL, TRUE,
- nexus_got_update_cb, ud);
-}
-
-GHashTable *
-msn_nexus_get_token(MsnNexus *nexus, MsnAuthDomains id)
-{
- g_return_val_if_fail(nexus != NULL, NULL);
- g_return_val_if_fail(id < nexus->token_len, NULL);
-
- return nexus->tokens[id].token;
-}
-
-const char *
-msn_nexus_get_token_str(MsnNexus *nexus, MsnAuthDomains id)
-{
- static char buf[1024];
- GHashTable *token = msn_nexus_get_token(nexus, id);
- const char *msn_t;
- const char *msn_p;
- gint ret;
-
- g_return_val_if_fail(token != NULL, NULL);
-
- msn_t = g_hash_table_lookup(token, "t");
- msn_p = g_hash_table_lookup(token, "p");
-
- g_return_val_if_fail(msn_t != NULL, NULL);
- g_return_val_if_fail(msn_p != NULL, NULL);
-
- ret = g_snprintf(buf, sizeof(buf) - 1, "t=%s&p=%s", msn_t, msn_p);
- g_return_val_if_fail(ret != -1, NULL);
-
- return buf;
-}
-
diff --git a/libpurple/protocols/msn/nexus.h b/libpurple/protocols/msn/nexus.h
deleted file mode 100644
index f6150780e9..0000000000
--- a/libpurple/protocols/msn/nexus.h
+++ /dev/null
@@ -1,219 +0,0 @@
-/**
- * @file nexus.h MSN Nexus functions
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-#ifndef MSN_NEXUS_H
-#define MSN_NEXUS_H
-
-#include "internal.h"
-
-typedef struct _MsnNexus MsnNexus;
-typedef struct _MsnTicketToken MsnTicketToken;
-
-/* Index into ticket_tokens in nexus.c Keep updated! */
-typedef enum
-{
- MSN_AUTH_MESSENGER = 0,
- MSN_AUTH_MESSENGER_WEB = 1,
- MSN_AUTH_CONTACTS = 2,
- MSN_AUTH_LIVE_SECURE = 3,
- MSN_AUTH_STORAGE = 4,
- MSN_AUTH_WHATSNEW = 5
-} MsnAuthDomains;
-
-#define MSN_SSO_SERVER "login.live.com"
-#define SSO_POST_URL "/RST.srf"
-
-#define MSN_SSO_RST_TEMPLATE \
-"<wst:RequestSecurityToken xmlns=\"http://schemas.xmlsoap.org/ws/2004/04/trust\" Id=\"RST%d\">"\
- "<wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>"\
- "<wsp:AppliesTo xmlns=\"http://schemas.xmlsoap.org/ws/2002/12/policy\">"\
- "<wsa:EndpointReference xmlns=\"http://schemas.xmlsoap.org/ws/2004/03/addressing\">"\
- "<wsa:Address>%s</wsa:Address>"\
- "</wsa:EndpointReference>"\
- "</wsp:AppliesTo>"\
- "<wsse:PolicyReference xmlns=\"http://schemas.xmlsoap.org/ws/2003/06/secext\" URI=\"%s\"></wsse:PolicyReference>"\
-"</wst:RequestSecurityToken>"
-
-#define MSN_SSO_TEMPLATE "<?xml version='1.0' encoding='utf-8'?>"\
-"<Envelope xmlns=\"http://schemas.xmlsoap.org/soap/envelope/\""\
- " xmlns:wsse=\"http://schemas.xmlsoap.org/ws/2003/06/secext\""\
- " xmlns:saml=\"urn:oasis:names:tc:SAML:1.0:assertion\""\
- " xmlns:wsp=\"http://schemas.xmlsoap.org/ws/2002/12/policy\""\
- " xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\""\
- " xmlns:wsa=\"http://schemas.xmlsoap.org/ws/2004/03/addressing\""\
- " xmlns:wssc=\"http://schemas.xmlsoap.org/ws/2004/04/sc\""\
- " xmlns:wst=\"http://schemas.xmlsoap.org/ws/2004/04/trust\">"\
- "<Header>"\
- "<ps:AuthInfo"\
- " xmlns:ps=\"http://schemas.microsoft.com/Passport/SoapServices/PPCRL\""\
- " Id=\"PPAuthInfo\">"\
- "<ps:HostingApp>{7108E71A-9926-4FCB-BCC9-9A9D3F32E423}</ps:HostingApp>"\
- "<ps:BinaryVersion>4</ps:BinaryVersion>"\
- "<ps:UIVersion>1</ps:UIVersion>"\
- "<ps:Cookies></ps:Cookies>"\
- "<ps:RequestParams>AQAAAAIAAABsYwQAAAAxMDMz</ps:RequestParams>"\
- "</ps:AuthInfo>"\
- "<wsse:Security>"\
- "<wsse:UsernameToken Id=\"user\">"\
- "<wsse:Username>%s</wsse:Username>"\
- "<wsse:Password>%s</wsse:Password>"\
- "</wsse:UsernameToken>"\
- "</wsse:Security>"\
- "</Header>"\
- "<Body>"\
- "<ps:RequestMultipleSecurityTokens"\
- " xmlns:ps=\"http://schemas.microsoft.com/Passport/SoapServices/PPCRL\""\
- " Id=\"RSTS\">"\
- "<wst:RequestSecurityToken Id=\"RST0\">"\
- "<wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>"\
- "<wsp:AppliesTo>"\
- "<wsa:EndpointReference>"\
- "<wsa:Address>http://Passport.NET/tb</wsa:Address>"\
- "</wsa:EndpointReference>"\
- "</wsp:AppliesTo>"\
- "</wst:RequestSecurityToken>"\
- "%s" /* Other RSTn tokens */\
- "</ps:RequestMultipleSecurityTokens>"\
- "</Body>"\
-"</Envelope>"
-
-#define MSN_SSO_AUTHINFO_TEMPLATE \
-"<ps:AuthInfo xmlns:ps=\"http://schemas.microsoft.com/Passport/SoapServices/PPCRL\" Id=\"PPAuthInfo\">"\
- "<ps:HostingApp>{7108E71A-9926-4FCB-BCC9-9A9D3F32E423}</ps:HostingApp>"\
- "<ps:BinaryVersion>4</ps:BinaryVersion>"\
- "<ps:UIVersion>1</ps:UIVersion>"\
- "<ps:Cookies></ps:Cookies>"\
- "<ps:RequestParams>AQAAAAIAAABsYwQAAAA0MTA1</ps:RequestParams>"\
-"</ps:AuthInfo>"
-/* Not sure what's editable here, so I'll just hard-code the SHA1 hash */
-#define MSN_SSO_AUTHINFO_SHA1_BASE64 "d2IeTF4DAkPEa/tVETHznsivEpc="
-
-#define MSN_SSO_TIMESTAMP_TEMPLATE \
-"<wsu:Timestamp xmlns=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\" Id=\"Timestamp\">"\
- "<wsu:Created>%s</wsu:Created>"\
- "<wsu:Expires>%s</wsu:Expires>"\
-"</wsu:Timestamp>"
-
-#define MSN_SSO_SIGNEDINFO_TEMPLATE \
-"<SignedInfo xmlns=\"http://www.w3.org/2000/09/xmldsig#\">"\
- "<CanonicalizationMethod Algorithm=\"http://www.w3.org/2001/10/xml-exc-c14n#\"></CanonicalizationMethod>"\
- "<SignatureMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#hmac-sha1\"></SignatureMethod>"\
- "<Reference URI=\"#RST%d\">"\
- "<Transforms>"\
- "<Transform Algorithm=\"http://www.w3.org/2001/10/xml-exc-c14n#\"></Transform>"\
- "</Transforms>"\
- "<DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\"></DigestMethod>"\
- "<DigestValue>%s</DigestValue>"\
- "</Reference>"\
- "<Reference URI=\"#Timestamp\">"\
- "<Transforms>"\
- "<Transform Algorithm=\"http://www.w3.org/2001/10/xml-exc-c14n#\"></Transform>"\
- "</Transforms>"\
- "<DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\"></DigestMethod>"\
- "<DigestValue>%s</DigestValue>"\
- "</Reference>"\
- "<Reference URI=\"#PPAuthInfo\">"\
- "<Transforms>"\
- "<Transform Algorithm=\"http://www.w3.org/2001/10/xml-exc-c14n#\"></Transform>"\
- "</Transforms>"\
- "<DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\"></DigestMethod>"\
- "<DigestValue>" MSN_SSO_AUTHINFO_SHA1_BASE64 "</DigestValue>"\
- "</Reference>"\
-"</SignedInfo>"
-
-#define MSN_SSO_TOKEN_UPDATE_TEMPLATE "<?xml version=\"1.0\" encoding=\"utf-8\"?>"\
-"<Envelope"\
- " xmlns=\"http://schemas.xmlsoap.org/soap/envelope/\""\
- " xmlns:wsse=\"http://schemas.xmlsoap.org/ws/2003/06/secext\""\
- " xmlns:saml=\"urn:oasis:names:tc:SAML:1.0:assertion\""\
- " xmlns:wsp=\"http://schemas.xmlsoap.org/ws/2002/12/policy\""\
- " xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\""\
- " xmlns:wsa=\"http://schemas.xmlsoap.org/ws/2004/03/addressing\""\
- " xmlns:wssc=\"http://schemas.xmlsoap.org/ws/2004/04/sc\""\
- " xmlns:wst=\"http://schemas.xmlsoap.org/ws/2004/04/trust\">"\
- "<Header>"\
- MSN_SSO_AUTHINFO_TEMPLATE /* ps:AuthInfo */ \
- "<wsse:Security>"\
- "<EncryptedData xmlns=\"http://www.w3.org/2001/04/xmlenc#\" Id=\"BinaryDAToken0\" Type=\"http://www.w3.org/2001/04/xmlenc#Element\">"\
- "<EncryptionMethod Algorithm=\"http://www.w3.org/2001/04/xmlenc#tripledes-cbc\"></EncryptionMethod>"\
- "<ds:KeyInfo xmlns:ds=\"http://www.w3.org/2000/09/xmldsig#\">"\
- "<ds:KeyName>http://Passport.NET/STS</ds:KeyName>"\
- "</ds:KeyInfo>"\
- "<CipherData>"\
- "<CipherValue>%s</CipherValue>"\
- "</CipherData>"\
- "</EncryptedData>"\
- "<wssc:DerivedKeyToken Id=\"SignKey\">"\
- "<wsse:RequestedTokenReference>"\
- "<wsse:KeyIdentifier ValueType=\"http://docs.oasis-open.org/wss/2004/XX/oasis-2004XX-wss-saml-token-profile-1.0#SAMLAssertionID\" />"\
- "<wsse:Reference URI=\"#BinaryDAToken0\" />"\
- "</wsse:RequestedTokenReference>"\
- "<wssc:Nonce>%s</wssc:Nonce>"\
- "</wssc:DerivedKeyToken>"\
- "%s" /* wsu:Timestamp */\
- "<Signature xmlns=\"http://www.w3.org/2000/09/xmldsig#\">"\
- "%s" /* SignedInfo */\
- "<SignatureValue>%s</SignatureValue>"\
- "<KeyInfo>"\
- "<wsse:SecurityTokenReference>"\
- "<wsse:Reference URI=\"#SignKey\" />"\
- "</wsse:SecurityTokenReference>"\
- "</KeyInfo>"\
- "</Signature>"\
- "</wsse:Security>"\
- "</Header>"\
- "<Body>"\
- "%s" /* wst:RequestSecurityToken */ \
- "</Body>"\
-"</Envelope>"
-
-struct _MsnTicketToken {
- GHashTable *token;
- char *secret;
- time_t expiry;
- GSList *updates;
-};
-
-struct _MsnNexus
-{
- MsnSession *session;
-
- /* From server via USR command */
- char *policy;
- char *nonce;
-
- /* From server via SOAP stuff */
- char *cipher;
- char *secret;
- MsnTicketToken *tokens;
- gsize token_len;
-};
-
-void msn_nexus_connect(MsnNexus *nexus);
-MsnNexus *msn_nexus_new(MsnSession *session);
-void msn_nexus_destroy(MsnNexus *nexus);
-GHashTable *msn_nexus_get_token(MsnNexus *nexus, MsnAuthDomains id);
-const char *msn_nexus_get_token_str(MsnNexus *nexus, MsnAuthDomains id);
-void msn_nexus_update_token(MsnNexus *nexus, int id, GSourceFunc cb, gpointer data);
-
-#endif /* MSN_NEXUS_H */
diff --git a/libpurple/protocols/msn/notification.c b/libpurple/protocols/msn/notification.c
deleted file mode 100644
index 2b3f3348b6..0000000000
--- a/libpurple/protocols/msn/notification.c
+++ /dev/null
@@ -1,2480 +0,0 @@
-/**
- * @file notification.c Notification server functions
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-
-#include "internal.h"
-#include "cipher.h"
-#include "core.h"
-#include "debug.h"
-
-#include "notification.h"
-
-#include "contact.h"
-#include "error.h"
-#include "msnutils.h"
-#include "state.h"
-#include "userlist.h"
-
-static MsnTable *cbs_table;
-
-/**************************************************************************
- * Main
- **************************************************************************/
-
-static void
-destroy_cb(MsnServConn *servconn)
-{
- MsnNotification *notification;
-
- notification = servconn->cmdproc->data;
- g_return_if_fail(notification != NULL);
-
- msn_notification_destroy(notification);
-}
-
-MsnNotification *
-msn_notification_new(MsnSession *session)
-{
- MsnNotification *notification;
- MsnServConn *servconn;
-
- g_return_val_if_fail(session != NULL, NULL);
-
- notification = g_new0(MsnNotification, 1);
-
- notification->session = session;
- notification->servconn = servconn = msn_servconn_new(session, MSN_SERVCONN_NS);
- msn_servconn_set_destroy_cb(servconn, destroy_cb);
-
- notification->cmdproc = servconn->cmdproc;
- notification->cmdproc->data = notification;
- notification->cmdproc->cbs_table = cbs_table;
-
- return notification;
-}
-
-void
-msn_notification_destroy(MsnNotification *notification)
-{
- notification->cmdproc->data = NULL;
-
- msn_servconn_set_destroy_cb(notification->servconn, NULL);
-
- msn_servconn_destroy(notification->servconn);
-
- g_free(notification);
-}
-
-/**************************************************************************
- * Connect
- **************************************************************************/
-
-static void
-connect_cb(MsnServConn *servconn)
-{
- MsnCmdProc *cmdproc;
- MsnSession *session;
- MsnTransaction *trans;
- GString *vers;
- const char *ver_str;
- int i;
-
- g_return_if_fail(servconn != NULL);
-
- cmdproc = servconn->cmdproc;
- session = servconn->session;
-
- vers = g_string_new("");
-
- for (i = WLM_MAX_PROTOCOL; i >= WLM_MIN_PROTOCOL; i--)
- g_string_append_printf(vers, " MSNP%d", i);
-
- g_string_append(vers, " CVR0");
-
- if (session->login_step == MSN_LOGIN_STEP_START)
- msn_session_set_login_step(session, MSN_LOGIN_STEP_HANDSHAKE);
- else
- msn_session_set_login_step(session, MSN_LOGIN_STEP_HANDSHAKE2);
-
- /* Skip the initial space */
- ver_str = (vers->str + 1);
- trans = msn_transaction_new(cmdproc, "VER", "%s", ver_str);
- msn_cmdproc_send_trans(cmdproc, trans);
-
- g_string_free(vers, TRUE);
-}
-
-gboolean
-msn_notification_connect(MsnNotification *notification, const char *host, int port)
-{
- MsnServConn *servconn;
-
- g_return_val_if_fail(notification != NULL, FALSE);
-
- servconn = notification->servconn;
-
- msn_servconn_set_connect_cb(servconn, connect_cb);
- notification->in_use = msn_servconn_connect(servconn, host, port, TRUE);
-
- return notification->in_use;
-}
-
-void
-msn_notification_disconnect(MsnNotification *notification)
-{
- g_return_if_fail(notification != NULL);
- g_return_if_fail(notification->in_use);
-
- msn_servconn_disconnect(notification->servconn);
-
- notification->in_use = FALSE;
-}
-
-/**************************************************************************
- * Login
- **************************************************************************/
-
-void
-msn_got_login_params(MsnSession *session, const char *ticket, const char *response)
-{
- MsnCmdProc *cmdproc;
- MsnTransaction *trans;
-
- cmdproc = session->notification->cmdproc;
-
- msn_session_set_login_step(session, MSN_LOGIN_STEP_AUTH_END);
-
- trans = msn_transaction_new(cmdproc, "USR", "SSO S %s %s %s", ticket, response, session->guid);
-
- msn_cmdproc_send_trans(cmdproc, trans);
-}
-
-static void
-cvr_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
- PurpleAccount *account;
- MsnTransaction *trans;
-
- account = cmdproc->session->account;
-
- trans = msn_transaction_new(cmdproc, "USR", "SSO I %s", purple_account_get_username(account));
- msn_cmdproc_send_trans(cmdproc, trans);
-}
-
-static void
-usr_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
- MsnSession *session = cmdproc->session;
-
- if (!g_ascii_strcasecmp(cmd->params[1], "OK"))
- {
- /* authenticate OK */
- msn_session_set_login_step(session, MSN_LOGIN_STEP_SYN);
- }
- else if (!g_ascii_strcasecmp(cmd->params[1], "SSO"))
- {
- /* RPS authentication */
-
- if (session->nexus)
- msn_nexus_destroy(session->nexus);
-
- session->nexus = msn_nexus_new(session);
-
- session->nexus->policy = g_strdup(cmd->params[3]);
- session->nexus->nonce = g_strdup(cmd->params[4]);
-
- msn_session_set_login_step(session, MSN_LOGIN_STEP_AUTH_START);
-
- msn_nexus_connect(session->nexus);
- }
-}
-
-static void
-usr_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error)
-{
- MsnErrorType msnerr = 0;
-
- switch (error)
- {
- case 500:
- case 601:
- case 910:
- case 921:
- msnerr = MSN_ERROR_SERV_UNAVAILABLE;
- break;
- case 911:
- msnerr = MSN_ERROR_AUTH;
- break;
- default:
- return;
- break;
- }
-
- msn_session_set_error(cmdproc->session, msnerr, NULL);
-}
-
-static void
-ver_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
- MsnSession *session;
- MsnTransaction *trans;
- PurpleAccount *account;
- gboolean protocol_supported = FALSE;
- guint proto_ver;
- size_t i;
-
- session = cmdproc->session;
- account = session->account;
-
- session->protocol_ver = 0;
- for (i = 1; i < cmd->param_count; i++)
- {
- if (sscanf(cmd->params[i], "MSNP%d", &proto_ver) == 1) {
- if (proto_ver >= WLM_MIN_PROTOCOL
- && proto_ver <= WLM_MAX_PROTOCOL
- && proto_ver > session->protocol_ver) {
- protocol_supported = TRUE;
- session->protocol_ver = proto_ver;
- }
- }
- }
-
- if (!protocol_supported)
- {
- msn_session_set_error(session, MSN_ERROR_UNSUPPORTED_PROTOCOL,
- NULL);
- return;
- }
-
- purple_debug_info("msn", "Negotiated protocol version %d with the server.\n", session->protocol_ver);
-
- /*
- * Windows Live Messenger 8.5
- * Notice :CVR String discriminate!
- * reference of http://www.microsoft.com/globaldev/reference/oslocversion.mspx
- * to see the Local ID
- */
- trans = msn_transaction_new(cmdproc, "CVR",
- "0x0409 winnt 5.1 i386 MSNMSGR 8.5.1302 BC01 %s",
- purple_account_get_username(account));
- msn_cmdproc_send_trans(cmdproc, trans);
-}
-
-/**************************************************************************
- * Log out
- **************************************************************************/
-
-static void
-out_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
- if (cmd->param_count == 0)
- msn_session_set_error(cmdproc->session, -1, NULL);
- else if (!g_ascii_strcasecmp(cmd->params[0], "OTH"))
- msn_session_set_error(cmdproc->session, MSN_ERROR_SIGN_OTHER,
- NULL);
- else if (!g_ascii_strcasecmp(cmd->params[0], "SSD"))
- msn_session_set_error(cmdproc->session, MSN_ERROR_SERV_DOWN, NULL);
-}
-
-void
-msn_notification_close(MsnNotification *notification)
-{
- MsnTransaction *trans;
-
- g_return_if_fail(notification != NULL);
-
- if (!notification->in_use)
- return;
-
- trans = msn_transaction_new(notification->cmdproc, "OUT", NULL);
- msn_transaction_set_saveable(trans, FALSE);
- msn_cmdproc_send_trans(notification->cmdproc, trans);
-
- msn_notification_disconnect(notification);
-}
-
-/**************************************************************************
- * Messages
- **************************************************************************/
-
-static void
-msg_cmd_post(MsnCmdProc *cmdproc, MsnCommand *cmd, char *payload,
- size_t len)
-{
- MsnMessage *msg;
-
- msg = msn_message_new_from_cmd(cmdproc->session, cmd);
-
- msn_message_parse_payload(msg, payload, len, MSG_LINE_DEM, MSG_BODY_DEM);
- if (purple_debug_is_verbose())
- msn_message_show_readable(msg, "Notification", TRUE);
-
- msn_cmdproc_process_msg(cmdproc, msg);
-
- msn_message_unref(msg);
-}
-
-static void
-msg_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
- purple_debug_info("msn", "Processing MSG... \n");
-
- /* NOTE: cmd is not always cmdproc->last_cmd, sometimes cmd is a queued
- * command and we are processing it */
- if (cmd->payload == NULL) {
- cmdproc->last_cmd->payload_cb = msg_cmd_post;
- cmd->payload_len = atoi(cmd->params[2]);
- } else {
- g_return_if_fail(cmd->payload_cb != NULL);
-
-#if 0 /* glib on win32 doesn't correctly support precision modifiers for a string */
- purple_debug_info("msn", "MSG payload:{%.*s}\n", (guint)cmd->payload_len, cmd->payload);
-#endif
- cmd->payload_cb(cmdproc, cmd, cmd->payload, cmd->payload_len);
- }
-}
-
-/*send Message to Yahoo Messenger*/
-void
-msn_notification_send_uum(MsnSession *session, MsnMessage *msg)
-{
- MsnCmdProc *cmdproc;
- MsnTransaction *trans;
- char *payload;
- gsize payload_len;
- int type;
- MsnUser *user;
- int network;
-
- g_return_if_fail(msg != NULL);
-
- cmdproc = session->notification->cmdproc;
-
- payload = msn_message_gen_payload(msg, &payload_len);
- type = msg->type;
- user = msn_userlist_find_user(session->userlist, msg->remote_user);
- if (user)
- network = msn_user_get_network(user);
- else
- network = MSN_NETWORK_PASSPORT;
-
- purple_debug_info("msn",
- "send UUM, payload{%s}, strlen:%" G_GSIZE_FORMAT ", len:%" G_GSIZE_FORMAT "\n",
- payload, strlen(payload), payload_len);
-
- trans = msn_transaction_new(cmdproc, "UUM", "%s %d %d %" G_GSIZE_FORMAT,
- msg->remote_user, network, type, payload_len);
- msn_transaction_set_payload(trans, payload, strlen(payload));
- msn_cmdproc_send_trans(cmdproc, trans);
-}
-
-/*Yahoo msg process*/
-static void
-ubm_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
- purple_debug_info("msn", "Processing UBM... \n");
-
- /* NOTE: cmd is not always cmdproc->last_cmd, sometimes cmd is a queued
- * command and we are processing it */
- if (cmd->payload == NULL) {
- cmdproc->last_cmd->payload_cb = msg_cmd_post;
- cmd->payload_len = atoi(cmd->params[5]);
- } else {
- g_return_if_fail(cmd->payload_cb != NULL);
-
- purple_debug_info("msn", "UBM payload:{%.*s}\n", (guint)(cmd->payload_len), cmd->payload);
- msg_cmd_post(cmdproc, cmd, cmd->payload, cmd->payload_len);
- }
-}
-
-/**************************************************************************
- * Challenges
- * we use MD5 to caculate the Challenges
- **************************************************************************/
-static void
-chl_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
- MsnTransaction *trans;
- char buf[33];
-
- msn_handle_chl(cmd->params[1], buf);
- trans = msn_transaction_new(cmdproc, "QRY", "%s 32", MSNP15_WLM_PRODUCT_ID);
-
- msn_transaction_set_payload(trans, buf, 32);
-
- msn_cmdproc_send_trans(cmdproc, trans);
-}
-
-/**************************************************************************
- * Buddy Lists
- **************************************************************************/
-
-typedef struct MsnFqyCbData {
- MsnFqyCb cb;
- gpointer data;
-} MsnFqyCbData;
-
-/* add contact to xmlnode */
-static void
-msn_add_contact_xml(xmlnode *mlNode, const char *passport, MsnListOp list_op, MsnNetwork networkId)
-{
- xmlnode *d_node,*c_node;
- char **tokens;
- const char *email,*domain;
- char fmt_str[3];
-
- g_return_if_fail(passport != NULL);
-
- purple_debug_info("msn", "Passport: %s, type: %d\n", passport, networkId);
- tokens = g_strsplit(passport, "@", 2);
- email = tokens[0];
- domain = tokens[1];
-
- if (email == NULL || domain == NULL) {
- purple_debug_error("msn", "Invalid passport (%s) specified to add to contact xml.\n", passport);
- g_strfreev(tokens);
- g_return_if_reached();
- }
-
- /*find a domain Node*/
- for (d_node = xmlnode_get_child(mlNode, "d"); d_node;
- d_node = xmlnode_get_next_twin(d_node)) {
- const char *attr = xmlnode_get_attrib(d_node,"n");
- if (attr == NULL)
- continue;
- if (!strcmp(attr, domain))
- break;
- }
-
- if (d_node == NULL) {
- /*domain not found, create a new domain Node*/
- purple_debug_info("msn", "Didn't find existing domain node, adding one.\n");
- d_node = xmlnode_new("d");
- xmlnode_set_attrib(d_node, "n", domain);
- xmlnode_insert_child(mlNode, d_node);
- }
-
- /*create contact node*/
- c_node = xmlnode_new("c");
- xmlnode_set_attrib(c_node, "n", email);
-
- if (list_op != 0) {
- purple_debug_info("msn", "list_op: %d\n", list_op);
- g_snprintf(fmt_str, sizeof(fmt_str), "%d", list_op);
- xmlnode_set_attrib(c_node, "l", fmt_str);
- }
-
- if (networkId != MSN_NETWORK_UNKNOWN) {
- g_snprintf(fmt_str, sizeof(fmt_str), "%d", networkId);
- /*mobile*/
- /*type_str = g_strdup_printf("4");*/
- xmlnode_set_attrib(c_node, "t", fmt_str);
- }
-
- xmlnode_insert_child(d_node, c_node);
-
- g_strfreev(tokens);
-}
-
-static void
-msn_notification_post_adl(MsnCmdProc *cmdproc, const char *payload, int payload_len)
-{
- MsnTransaction *trans;
- purple_debug_info("msn", "Sending ADL with payload: %s\n", payload);
- trans = msn_transaction_new(cmdproc, "ADL", "%i", payload_len);
- msn_transaction_set_payload(trans, payload, payload_len);
- msn_cmdproc_send_trans(cmdproc, trans);
-}
-
-static void
-msn_notification_post_rml(MsnCmdProc *cmdproc, const char *payload, int payload_len)
-{
- MsnTransaction *trans;
- purple_debug_info("msn", "Sending RML with payload: %s\n", payload);
- trans = msn_transaction_new(cmdproc, "RML", "%i", payload_len);
- msn_transaction_set_payload(trans, payload, payload_len);
- msn_cmdproc_send_trans(cmdproc, trans);
-}
-
-void
-msn_notification_send_fqy(MsnSession *session,
- const char *payload, int payload_len,
- MsnFqyCb cb,
- gpointer cb_data)
-{
- MsnTransaction *trans;
- MsnCmdProc *cmdproc;
- MsnFqyCbData *data;
-
- cmdproc = session->notification->cmdproc;
-
- data = g_new(MsnFqyCbData, 1);
- data->cb = cb;
- data->data = cb_data;
-
- trans = msn_transaction_new(cmdproc, "FQY", "%d", payload_len);
- msn_transaction_set_payload(trans, payload, payload_len);
- msn_transaction_set_data(trans, data);
- msn_transaction_set_data_free(trans, g_free);
- msn_cmdproc_send_trans(cmdproc, trans);
-}
-
-static void
-update_contact_network(MsnSession *session, const char *passport, MsnNetwork network, gpointer unused)
-{
- MsnUser *user;
-
- if (network == MSN_NETWORK_UNKNOWN)
- {
- purple_debug_warning("msn",
- "Ignoring user %s about which server knows nothing.\n",
- passport);
- /* Decrement the count for unknown results so that we'll continue login.
- Also, need to finish the login process here as well, because ADL OK
- will not be called. */
- if (purple_debug_is_verbose())
- purple_debug_info("msn", "ADL/FQY count is %d\n", session->adl_fqy);
- if (--session->adl_fqy == 0)
- msn_session_finish_login(session);
- return;
- }
-
- /* TODO: Also figure out how to update membership lists */
- user = msn_userlist_find_user(session->userlist, passport);
- if (user) {
- xmlnode *adl_node;
- char *payload;
- int payload_len;
-
- msn_user_set_network(user, network);
-
- adl_node = xmlnode_new("ml");
- xmlnode_set_attrib(adl_node, "l", "1");
- msn_add_contact_xml(adl_node, passport,
- user->list_op & MSN_LIST_OP_MASK, network);
- payload = xmlnode_to_str(adl_node, &payload_len);
- msn_notification_post_adl(session->notification->cmdproc, payload, payload_len);
- g_free(payload);
- xmlnode_free(adl_node);
- } else {
- purple_debug_error("msn",
- "Got FQY update for unknown user %s on network %d.\n",
- passport, network);
- }
-}
-
-/*dump contact info to NS*/
-void
-msn_notification_dump_contact(MsnSession *session)
-{
- MsnUser *user;
- GList *l;
- xmlnode *adl_node;
- xmlnode *fqy_node;
- char *payload;
- int payload_len;
- int adl_count = 0;
- int fqy_count = 0;
- PurpleConnection *pc;
- const char *display_name;
-
- adl_node = xmlnode_new("ml");
- adl_node->child = NULL;
- xmlnode_set_attrib(adl_node, "l", "1");
- fqy_node = xmlnode_new("ml");
-
- /*get the userlist*/
- for (l = session->userlist->users; l != NULL; l = l->next) {
- user = l->data;
-
- /* skip RL & PL during initial dump */
- if (!(user->list_op & MSN_LIST_OP_MASK))
- continue;
-
- if (user->passport && !strcmp(user->passport, "messenger@microsoft.com"))
- continue;
-
- if ((user->list_op & MSN_LIST_OP_MASK & ~MSN_LIST_FL_OP)
- == (MSN_LIST_AL_OP | MSN_LIST_BL_OP)) {
- /* The server will complain if we send it a user on both the
- Allow and Block lists. So assume they're on the Block list
- and remove them from the Allow list in the membership lists to
- stop this from happening again. */
- purple_debug_warning("msn",
- "User %s is on both Allow and Block list; "
- "removing from Allow list.\n",
- user->passport);
- msn_user_unset_op(user, MSN_LIST_AL_OP);
- }
-
- if (user->networkid != MSN_NETWORK_UNKNOWN) {
- if ((user->list_op & (MSN_LIST_OP_MASK | MSN_LIST_PL_OP)) == MSN_LIST_FL_OP) {
- purple_debug_warning("msn",
- "User %s is on neither Allow nor Block list, "
- "and not Pending addition; "
- "adding to Allow list.\n",
- user->passport);
- msn_user_set_op(user, MSN_LIST_AL_OP);
- }
-
- msn_add_contact_xml(adl_node, user->passport,
- user->list_op & MSN_LIST_OP_MASK,
- user->networkid);
-
- /* each ADL command may contain up to 150 contacts */
- if (++adl_count % 150 == 0) {
- payload = xmlnode_to_str(adl_node, &payload_len);
-
- /* ADL's are returned all-together */
- session->adl_fqy++;
- if (purple_debug_is_verbose())
- purple_debug_info("msn", "Posting ADL, count is %d\n",
- session->adl_fqy);
-
- msn_notification_post_adl(session->notification->cmdproc,
- payload, payload_len);
-
- g_free(payload);
- xmlnode_free(adl_node);
-
- adl_node = xmlnode_new("ml");
- adl_node->child = NULL;
- xmlnode_set_attrib(adl_node, "l", "1");
- }
- } else {
- /* FQY's are returned one-at-a-time */
- session->adl_fqy++;
- if (purple_debug_is_verbose())
- purple_debug_info("msn", "Adding FQY address, count is %d\n",
- session->adl_fqy);
-
- msn_add_contact_xml(fqy_node, user->passport, 0, user->networkid);
-
- /* each FQY command may contain up to 150 contacts, probably */
- if (++fqy_count % 150 == 0) {
- payload = xmlnode_to_str(fqy_node, &payload_len);
-
- msn_notification_send_fqy(session, payload, payload_len,
- update_contact_network, NULL);
-
- g_free(payload);
- xmlnode_free(fqy_node);
- fqy_node = xmlnode_new("ml");
- }
- }
- }
-
- /* Send the rest, or just an empty one to let the server set us online */
- if (adl_count == 0 || adl_count % 150 != 0) {
- payload = xmlnode_to_str(adl_node, &payload_len);
-
- /* ADL's are returned all-together */
- session->adl_fqy++;
- if (purple_debug_is_verbose())
- purple_debug_info("msn", "Posting ADL, count is %d\n",
- session->adl_fqy);
-
- msn_notification_post_adl(session->notification->cmdproc, payload, payload_len);
-
- g_free(payload);
- }
-
- if (fqy_count % 150 != 0) {
- payload = xmlnode_to_str(fqy_node, &payload_len);
-
- msn_notification_send_fqy(session, payload, payload_len,
- update_contact_network, NULL);
-
- g_free(payload);
- }
-
- xmlnode_free(adl_node);
- xmlnode_free(fqy_node);
-
- msn_session_activate_login_timeout(session);
-
- pc = purple_account_get_connection(session->account);
- display_name = purple_connection_get_display_name(pc);
- if (display_name
- && strcmp(display_name,
- purple_account_get_username(session->account))) {
- msn_set_public_alias(pc, display_name, NULL, NULL);
- }
-
-}
-
-static void
-blp_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
-}
-
-static void
-adl_cmd_parse(MsnCmdProc *cmdproc, MsnCommand *cmd, char *payload,
- size_t len)
-{
- xmlnode *root, *domain_node;
-
- purple_debug_misc("msn", "Parsing received ADL XML data\n");
-
- g_return_if_fail(payload != NULL);
-
- root = xmlnode_from_str(payload, (gssize) len);
-
- if (root == NULL) {
- purple_debug_info("msn", "Invalid XML in ADL!\n");
- return;
- }
- for (domain_node = xmlnode_get_child(root, "d");
- domain_node;
- domain_node = xmlnode_get_next_twin(domain_node)) {
- xmlnode *contact_node = NULL;
-
- for (contact_node = xmlnode_get_child(domain_node, "c");
- contact_node;
- contact_node = xmlnode_get_next_twin(contact_node)) {
- const gchar *list;
- gint list_op = 0;
-
- list = xmlnode_get_attrib(contact_node, "l");
- if (list != NULL) {
- list_op = atoi(list);
- }
-
- if (list_op & MSN_LIST_RL_OP) {
- /* someone is adding us */
- msn_get_contact_list(cmdproc->session, MSN_PS_PENDING_LIST, NULL);
- }
- }
- }
-
- xmlnode_free(root);
-}
-
-static void
-adl_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
- MsnSession *session;
-
- g_return_if_fail(cmdproc != NULL);
- g_return_if_fail(cmdproc->session != NULL);
- g_return_if_fail(cmdproc->last_cmd != NULL);
- g_return_if_fail(cmd != NULL);
-
- session = cmdproc->session;
-
- if (!strcmp(cmd->params[1], "OK")) {
- /* ADL ack */
- if (purple_debug_is_verbose())
- purple_debug_info("msn", "ADL ACK, count is %d\n",
- session->adl_fqy);
- if (--session->adl_fqy == 0)
- msn_session_finish_login(session);
- } else {
- cmdproc->last_cmd->payload_cb = adl_cmd_parse;
- cmd->payload_len = atoi(cmd->params[1]);
- }
-
- return;
-}
-
-static void
-adl_error_parse(MsnCmdProc *cmdproc, MsnCommand *cmd, char *payload, size_t len)
-{
- MsnSession *session;
- PurpleAccount *account;
- PurpleConnection *gc;
- int error = GPOINTER_TO_INT(cmd->payload_cbdata);
-
- session = cmdproc->session;
- account = session->account;
- gc = purple_account_get_connection(account);
-
- if (error == 241) {
- /* khc: some googling suggests that error 241 means the buddy is somehow
- in the local list, but not the server list, and that we should add
- those buddies to the addressbook. For now I will just notify the user
- about the raw payload, because I am lazy */
- xmlnode *adl = xmlnode_from_str(payload, len);
- GString *emails = g_string_new(NULL);
-
- xmlnode *domain = xmlnode_get_child(adl, "d");
- while (domain) {
- const char *domain_str = xmlnode_get_attrib(domain, "n");
- xmlnode *contact = xmlnode_get_child(domain, "c");
- while (contact) {
- g_string_append_printf(emails, "%s@%s\n",
- xmlnode_get_attrib(contact, "n"), domain_str);
- contact = xmlnode_get_next_twin(contact);
- }
- domain = xmlnode_get_next_twin(domain);
- }
-
- purple_notify_error(gc, NULL,
- _("The following users are missing from your addressbook"),
- emails->str);
- g_string_free(emails, TRUE);
- xmlnode_free(adl);
- }
- else
- {
- char *adl = g_strndup(payload, len);
- char *reason = g_strdup_printf(_("Unknown error (%d): %s"),
- error, adl);
- g_free(adl);
-
- purple_notify_error(gc, NULL, _("Unable to add user"), reason);
- g_free(reason);
- }
-}
-
-static void
-adl_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error)
-{
- MsnSession *session;
- PurpleAccount *account;
- PurpleConnection *gc;
- MsnCommand *cmd = cmdproc->last_cmd;
-
- session = cmdproc->session;
- account = session->account;
- gc = purple_account_get_connection(account);
-
- purple_debug_error("msn", "ADL error\n");
- if (cmd->param_count > 1) {
- cmd->payload_cb = adl_error_parse;
- cmd->payload_len = atoi(cmd->params[1]);
- cmd->payload_cbdata = GINT_TO_POINTER(error);
- } else {
- char *reason = g_strdup_printf(_("Unknown error (%d)"), error);
- purple_notify_error(gc, NULL, _("Unable to add user"), reason);
- g_free(reason);
- }
-}
-
-static void
-rml_error_parse(MsnCmdProc *cmdproc, MsnCommand *cmd, char *payload, size_t len)
-{
- MsnSession *session;
- PurpleAccount *account;
- PurpleConnection *gc;
- char *adl, *reason;
- int error = GPOINTER_TO_INT(cmd->payload_cbdata);
-
- session = cmdproc->session;
- account = session->account;
- gc = purple_account_get_connection(account);
-
- adl = g_strndup(payload, len);
- reason = g_strdup_printf(_("Unknown error (%d): %s"),
- error, adl);
- g_free(adl);
-
- purple_notify_error(gc, NULL, _("Unable to remove user"), reason);
- g_free(reason);
-}
-
-static void
-rml_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error)
-{
- MsnSession *session;
- PurpleAccount *account;
- PurpleConnection *gc;
- MsnCommand *cmd = cmdproc->last_cmd;
-
- session = cmdproc->session;
- account = session->account;
- gc = purple_account_get_connection(account);
-
- purple_debug_error("msn", "RML error\n");
- if (cmd->param_count > 1) {
- cmd->payload_cb = rml_error_parse;
- cmd->payload_len = atoi(cmd->params[1]);
- cmd->payload_cbdata = GINT_TO_POINTER(error);
- } else {
- char *reason = g_strdup_printf(_("Unknown error (%d)"), error);
- purple_notify_error(gc, NULL, _("Unable to remove user"), reason);
- g_free(reason);
- }
-}
-
-static void
-fqy_cmd_post(MsnCmdProc *cmdproc, MsnCommand *cmd, char *payload,
- size_t len)
-{
- MsnSession *session;
- xmlnode *ml, *d, *c;
- const char *domain;
- const char *local;
- const char *type;
- char *passport;
- MsnNetwork network = MSN_NETWORK_PASSPORT;
-
- session = cmdproc->session;
-
- /* FQY response:
- <ml><d n="domain.com"><c n="local-node" t="network" /></d></ml> */
- ml = xmlnode_from_str(payload, len);
- for (d = xmlnode_get_child(ml, "d");
- d != NULL;
- d = xmlnode_get_next_twin(d)) {
- domain = xmlnode_get_attrib(d, "n");
- for (c = xmlnode_get_child(d, "c");
- c != NULL;
- c = xmlnode_get_next_twin(c)) {
- local = xmlnode_get_attrib(c, "n");
- type = xmlnode_get_attrib(c, "t");
-
- passport = g_strdup_printf("%s@%s", local, domain);
-
- if (g_ascii_isdigit(cmd->command[0]))
- network = MSN_NETWORK_UNKNOWN;
- else if (type != NULL)
- network = (MsnNetwork)strtoul(type, NULL, 10);
-
- purple_debug_info("msn", "FQY response says %s is from network %d\n",
- passport, network);
- if (cmd->trans->data) {
- MsnFqyCbData *fqy_data = cmd->trans->data;
- fqy_data->cb(session, passport, network, fqy_data->data);
- /* Don't free fqy_data yet since the server responds to FQY multiple times.
- It will be freed when cmd->trans is freed. */
- }
-
- g_free(passport);
- }
- }
-
- xmlnode_free(ml);
-}
-
-static void
-fqy_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error)
-{
- MsnCommand *cmd = cmdproc->last_cmd;
-
- purple_debug_warning("msn", "FQY error %d\n", error);
- if (cmd->param_count > 1) {
- cmd->payload_cb = fqy_cmd_post;
- cmd->payload_len = atoi(cmd->params[1]);
- cmd->payload_cbdata = GINT_TO_POINTER(error);
- }
-#if 0
- /* If the server didn't send us a corresponding email address for this
- FQY error, it's probably going to disconnect us. So it isn't necessary
- to tell the handler about it. */
- else if (trans->data)
- ((MsnFqyCb)trans->data)(session, NULL, MSN_NETWORK_UNKNOWN, NULL);
-#endif
-}
-
-static void
-fqy_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
- purple_debug_info("msn", "Process FQY\n");
- cmdproc->last_cmd->payload_cb = fqy_cmd_post;
- cmd->payload_len = atoi(cmd->params[1]);
-}
-
-static void
-rml_cmd_post(MsnCmdProc *cmdproc, MsnCommand *cmd, char *payload,
- size_t len)
-{
- if (payload != NULL)
- purple_debug_info("msn", "Received RML:\n%s\n", payload);
-}
-
-static void
-rml_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
- purple_debug_info("msn", "Process RML\n");
- cmd->payload_len = atoi(cmd->params[1]);
- cmdproc->last_cmd->payload_cb = rml_cmd_post;
-}
-
-static void
-qng_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
- /* TODO: Call PNG after the timeout specified. */
-}
-
-
-static void
-fln_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
- MsnUser *user;
- char *passport;
- int networkid;
-
- /* Tell libpurple that the user has signed off */
- msn_parse_user(cmd->params[0], &passport, &networkid);
- user = msn_userlist_find_user(cmdproc->session->userlist, passport);
- msn_user_set_state(user, NULL);
- msn_user_update(user);
-
- g_free(passport);
-}
-
-static void
-iln_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
- MsnSession *session;
- MsnUser *user;
- MsnObject *msnobj = NULL;
- unsigned long clientid, extcaps;
- char *extcap_str;
- int networkid = 0;
- const char *state, *passport;
- char *friendly;
-
- session = cmdproc->session;
-
- state = cmd->params[1];
- passport = cmd->params[2];
-
- user = msn_userlist_find_user(session->userlist, passport);
- if (user == NULL)
- /* Where'd this come from? */
- return;
-
- if (cmd->param_count == 8) {
- /* Yahoo! Buddy, looks like */
- networkid = atoi(cmd->params[3]);
- friendly = g_strdup(purple_url_decode(cmd->params[4]));
- clientid = strtoul(cmd->params[5], &extcap_str, 10);
- if (extcap_str && *extcap_str)
- extcaps = strtoul(extcap_str+1, NULL, 10);
- else
- extcaps = 0;
-
- /* cmd->params[7] seems to be a URL to a Yahoo! icon:
- https://sec.yimg.com/i/us/nt/b/purpley.1.0.png
- ... and it's purple, HAH!
- */
- } else if (cmd->param_count == 7) {
- /* MSNP14+ with Display Picture object */
- networkid = atoi(cmd->params[3]);
- friendly = g_strdup(purple_url_decode(cmd->params[4]));
- clientid = strtoul(cmd->params[5], &extcap_str, 10);
- if (extcap_str && *extcap_str)
- extcaps = strtoul(extcap_str+1, NULL, 10);
- else
- extcaps = 0;
- msnobj = msn_object_new_from_string(purple_url_decode(cmd->params[6]));
- } else if (cmd->param_count == 6) {
- /* Yes, this is 5. The friendly name could start with a number,
- but the display picture object can't... */
- if (isdigit(cmd->params[5][0])) {
- /* MSNP14 without Display Picture object */
- networkid = atoi(cmd->params[3]);
- friendly = g_strdup(purple_url_decode(cmd->params[4]));
- clientid = strtoul(cmd->params[5], &extcap_str, 10);
- if (extcap_str && *extcap_str)
- extcaps = strtoul(extcap_str+1, NULL, 10);
- else
- extcaps = 0;
- } else {
- /* MSNP8+ with Display Picture object */
- friendly = g_strdup(purple_url_decode(cmd->params[3]));
- clientid = strtoul(cmd->params[4], &extcap_str, 10);
- if (extcap_str && *extcap_str)
- extcaps = strtoul(extcap_str+1, NULL, 10);
- else
- extcaps = 0;
- msnobj = msn_object_new_from_string(purple_url_decode(cmd->params[5]));
- }
- } else if (cmd->param_count == 5) {
- /* MSNP8+ without Display Picture object */
- friendly = g_strdup(purple_url_decode(cmd->params[3]));
- clientid = strtoul(cmd->params[4], &extcap_str, 10);
- if (extcap_str && *extcap_str)
- extcaps = strtoul(extcap_str+1, NULL, 10);
- else
- extcaps = 0;
- } else {
- purple_debug_warning("msn", "Received ILN with unknown number of parameters.\n");
- return;
- }
-
- if (msn_user_set_friendly_name(user, friendly)) {
- msn_update_contact(session, passport, MSN_UPDATE_DISPLAY, friendly);
- }
- g_free(friendly);
-
- msn_user_set_object(user, msnobj);
-
- user->mobile = (clientid & MSN_CAP_MOBILE_ON) || (user->extinfo && user->extinfo->phone_mobile && user->extinfo->phone_mobile[0] == '+');
- msn_user_set_clientid(user, clientid);
- msn_user_set_extcaps(user, extcaps);
- msn_user_set_network(user, networkid);
-
- msn_user_set_state(user, state);
- msn_user_update(user);
-}
-
-static void
-ipg_cmd_post(MsnCmdProc *cmdproc, MsnCommand *cmd, char *payload, size_t len)
-{
- PurpleConnection *gc;
- MsnUserList *userlist;
- const char *who = NULL;
- char *text = NULL;
- const char *id = NULL;
- xmlnode *payloadNode, *from, *msg, *textNode;
-
- purple_debug_misc("msn", "Incoming Page: {%s}\n", payload);
-
- userlist = cmdproc->session->userlist;
- gc = purple_account_get_connection(cmdproc->session->account);
-
- /* payload looks like this:
- <?xml version="1.0"?>
- <NOTIFICATION id="0" siteid="111100400" siteurl="http://mobile.msn.com/">
- <TO name="passport@example.com">
- <VIA agent="mobile"/>
- </TO>
- <FROM name="tel:+XXXXXXXXXXX"/>
- <MSG pri="1" id="1">
- <CAT Id="110110001"/>
- <ACTION url="2wayIM.asp"/>
- <SUBSCR url="2wayIM.asp"/>
- <BODY lcid="1033">
- <TEXT>Message was here</TEXT>
- </BODY>
- </MSG>
- </NOTIFICATION>
- */
-
- /* This is the payload if your message was too long:
- <NOTIFICATION id="TrID" siteid="111100400" siteurl="http://mobile.msn.com/">
- <TO name="passport@example.com">
- <VIA agent="mobile"/>
- </TO>
- <FROM name="tel:+XXXXXXXXXXX"/>
- <MSG pri="1" id="407">
- <CAT Id="110110001"/>
- <ACTION url="2wayIM.asp"/>
- <SUBSCR url="2wayIM.asp"/>
- <BODY lcid="1033">
- <TEXT></TEXT>
- </BODY>
- </MSG>
- </NOTIFICATION>
- */
-
- payloadNode = xmlnode_from_str(payload, len);
- if (!payloadNode)
- return;
-
- if (!(from = xmlnode_get_child(payloadNode, "FROM")) ||
- !(msg = xmlnode_get_child(payloadNode, "MSG")) ||
- !(textNode = xmlnode_get_child(msg, "BODY/TEXT"))) {
- xmlnode_free(payloadNode);
- return;
- }
-
- who = xmlnode_get_attrib(from, "name");
- if (!who) return;
-
- text = xmlnode_get_data(textNode);
-
- /* Match number to user's mobile number, FROM is a phone number if the
- other side page you using your phone number */
- if (!strncmp(who, "tel:+", 5)) {
- MsnUser *user =
- msn_userlist_find_user_with_mobile_phone(userlist, who + 4);
-
- if (user && user->passport)
- who = user->passport;
- }
-
- id = xmlnode_get_attrib(msg, "id");
-
- if (id && strcmp(id, "1")) {
- PurpleConversation *conv
- = purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY,
- who, gc->account);
- if (conv != NULL) {
- const char *error;
- if (!strcmp(id, "407"))
- error = _("Mobile message was not sent because it was too long.");
- else
- error = _("Mobile message was not sent because an unknown error occurred.");
-
- purple_conversation_write(conv, NULL, error,
- PURPLE_MESSAGE_ERROR, time(NULL));
-
- if ((id = xmlnode_get_attrib(payloadNode, "id")) != NULL) {
- unsigned int trId = atol(id);
- MsnTransaction *trans;
-
- trans = msn_history_find(cmdproc->history, trId);
- if (trans) {
- MsnMessage *msg = (MsnMessage *)trans->data;
-
- if (msg) {
- char *body_str = msn_message_to_string(msg);
- char *body_enc = g_markup_escape_text(body_str, -1);
-
- purple_conversation_write(conv, NULL, body_enc,
- PURPLE_MESSAGE_RAW, time(NULL));
-
- g_free(body_str);
- g_free(body_enc);
- msn_message_unref(msg);
- trans->data = NULL;
- }
- }
- }
- }
- } else {
- serv_got_im(gc, who, text, 0, time(NULL));
- }
-
- g_free(text);
- xmlnode_free(payloadNode);
-}
-
-static void
-ipg_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
- cmd->payload_len = atoi(cmd->params[0]);
- cmdproc->last_cmd->payload_cb = ipg_cmd_post;
-}
-
-static void
-nln_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
- MsnSession *session;
- MsnUser *user;
- MsnObject *msnobj;
- unsigned long clientid, extcaps;
- char *extcap_str;
- char *passport;
- int networkid;
- const char *state, *friendly;
-
- session = cmdproc->session;
-
- state = cmd->params[0];
- msn_parse_user(cmd->params[1], &passport, &networkid);
- friendly = purple_url_decode(cmd->params[2]);
-
- user = msn_userlist_find_user(session->userlist, passport);
- if (user == NULL) return;
-
- if (msn_user_set_friendly_name(user, friendly) && user != session->user)
- {
- msn_update_contact(session, passport, MSN_UPDATE_DISPLAY, friendly);
- }
-
- if (cmd->param_count == 5)
- {
- msnobj = msn_object_new_from_string(purple_url_decode(cmd->params[4]));
- msn_user_set_object(user, msnobj);
- }
- else
- {
- msn_user_set_object(user, NULL);
- }
-
- clientid = strtoul(cmd->params[3], &extcap_str, 10);
- if (extcap_str && *extcap_str)
- extcaps = strtoul(extcap_str+1, NULL, 10);
- else
- extcaps = 0;
-
- user->mobile = (clientid & MSN_CAP_MOBILE_ON) || (user->extinfo && user->extinfo->phone_mobile && user->extinfo->phone_mobile[0] == '+');
-
- msn_user_set_clientid(user, clientid);
- msn_user_set_extcaps(user, extcaps);
- msn_user_set_network(user, networkid);
-
- msn_user_set_state(user, state);
- msn_user_update(user);
-
- g_free(passport);
-}
-
-#if 0
-static void
-chg_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
- char *state = cmd->params[1];
- int state_id = 0;
-
- if (!strcmp(state, "NLN"))
- state_id = MSN_ONLINE;
- else if (!strcmp(state, "BSY"))
- state_id = MSN_BUSY;
- else if (!strcmp(state, "IDL"))
- state_id = MSN_IDLE;
- else if (!strcmp(state, "BRB"))
- state_id = MSN_BRB;
- else if (!strcmp(state, "AWY"))
- state_id = MSN_AWAY;
- else if (!strcmp(state, "PHN"))
- state_id = MSN_PHONE;
- else if (!strcmp(state, "LUN"))
- state_id = MSN_LUNCH;
- else if (!strcmp(state, "HDN"))
- state_id = MSN_HIDDEN;
-
- cmdproc->session->state = state_id;
-}
-#endif
-
-
-static void
-not_cmd_post(MsnCmdProc *cmdproc, MsnCommand *cmd, char *payload, size_t len)
-{
-#if 0
- MSN_SET_PARAMS("NOT %d\r\n%s", cmdproc->servconn->payload, payload);
- purple_debug_misc("msn", "Notification: {%s}\n", payload);
-#endif
-}
-
-static void
-not_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
- cmd->payload_len = atoi(cmd->params[0]);
- cmdproc->last_cmd->payload_cb = not_cmd_post;
-}
-
-static void
-prp_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
- MsnSession *session = cmdproc->session;
- const char *type, *value;
-
- g_return_if_fail(cmd->param_count >= 3);
-
- type = cmd->params[2];
-
- if (cmd->param_count == 4)
- {
- value = cmd->params[3];
- if (!strcmp(type, "PHH"))
- msn_user_set_home_phone(session->user, purple_url_decode(value));
- else if (!strcmp(type, "PHW"))
- msn_user_set_work_phone(session->user, purple_url_decode(value));
- else if (!strcmp(type, "PHM"))
- msn_user_set_mobile_phone(session->user, purple_url_decode(value));
- }
- else
- {
- if (!strcmp(type, "PHH"))
- msn_user_set_home_phone(session->user, NULL);
- else if (!strcmp(type, "PHW"))
- msn_user_set_work_phone(session->user, NULL);
- else if (!strcmp(type, "PHM"))
- msn_user_set_mobile_phone(session->user, NULL);
- }
-}
-
-/**************************************************************************
- * Misc commands
- **************************************************************************/
-
-static void
-url_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
- MsnSession *session;
- PurpleConnection *gc;
- PurpleAccount *account;
- const char *rru;
- const char *url;
- PurpleCipherContext *cipher;
- gchar creds[33];
- char *buf;
-
- gulong tmp_timestamp;
-
- session = cmdproc->session;
- account = session->account;
- gc = account->gc;
-
- rru = cmd->params[1];
- url = cmd->params[2];
-
- session->passport_info.mail_timestamp = time(NULL);
- tmp_timestamp = session->passport_info.mail_timestamp - session->passport_info.sl;
-
- buf = g_strdup_printf("%s%lu%s",
- session->passport_info.mspauth ? session->passport_info.mspauth : "BOGUS",
- tmp_timestamp,
- purple_connection_get_password(gc));
-
- cipher = purple_cipher_context_new_by_name("md5", NULL);
- purple_cipher_context_append(cipher, (const guchar *)buf, strlen(buf));
- purple_cipher_context_digest_to_str(cipher, sizeof(creds), creds, NULL);
- purple_cipher_context_destroy(cipher);
- g_free(buf);
-
- g_free(session->passport_info.mail_url);
- session->passport_info.mail_url =
- g_strdup_printf("%s&auth=%s&creds=%s&sl=%ld&username=%s&mode=ttl&sid=%s&id=2&rru=%s&svc=mail&js=yes",
- url,
- session->passport_info.mspauth ? purple_url_encode(session->passport_info.mspauth) : "BOGUS",
- creds,
- tmp_timestamp,
- msn_user_get_passport(session->user),
- session->passport_info.sid,
- rru);
-
- /* The user wants to check his or her email */
- if (cmd->trans && cmd->trans->data)
- purple_notify_uri(purple_account_get_connection(account), session->passport_info.mail_url);
-}
-/**************************************************************************
- * Switchboards
- **************************************************************************/
-
-static void
-rng_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
- MsnSession *session;
- MsnSwitchBoard *swboard;
- const char *session_id;
- char *host;
- int port;
-
- session = cmdproc->session;
- session_id = cmd->params[0];
-
- msn_parse_socket(cmd->params[1], &host, &port);
-
- if (session->http_method)
- port = 80;
-
- swboard = msn_switchboard_new(session);
-
- msn_switchboard_set_invited(swboard, TRUE);
- msn_switchboard_set_session_id(swboard, session_id);
- msn_switchboard_set_auth_key(swboard, cmd->params[3]);
- swboard->im_user = g_strdup(cmd->params[4]);
- /* msn_switchboard_add_user(swboard, cmd->params[4]); */
-
- if (!msn_switchboard_connect(swboard, host, port))
- msn_switchboard_destroy(swboard);
-
- g_free(host);
-}
-
-static void
-xfr_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
- char *host;
- int port;
-
- if (strcmp(cmd->params[1], "SB") && strcmp(cmd->params[1], "NS"))
- {
- /* Maybe we can have a generic bad command error. */
- purple_debug_error("msn", "Bad XFR command (%s)\n", cmd->params[1]);
- return;
- }
-
- msn_parse_socket(cmd->params[2], &host, &port);
-
- if (!strcmp(cmd->params[1], "SB"))
- {
- purple_debug_error("msn", "This shouldn't be handled here.\n");
- }
- else if (!strcmp(cmd->params[1], "NS"))
- {
- MsnSession *session;
-
- session = cmdproc->session;
-
- msn_session_set_login_step(session, MSN_LOGIN_STEP_TRANSFER);
-
- msn_notification_connect(session->notification, host, port);
- }
-
- g_free(host);
-}
-
-static void
-gcf_cmd_post(MsnCmdProc *cmdproc, MsnCommand *cmd, char *payload,
- size_t len)
-{
-/* QuLogic: Disabled until confirmed correct. */
-#if 0
- xmlnode *root;
- xmlnode *policy;
-
- g_return_if_fail(cmd->payload != NULL);
-
- if ( (root = xmlnode_from_str(cmd->payload, cmd->payload_len)) == NULL)
- {
- purple_debug_error("msn", "Unable to parse GCF payload into a XML tree\n");
- return;
- }
-
-
- g_free(cmdproc->session->blocked_text);
- cmdproc->session->blocked_text = NULL;
-
- /* We need a get_child with attrib... */
- policy = xmlnode_get_child(root, "Policy");
- while (policy) {
- if (g_str_equal(xmlnode_get_attrib(policy, "type"), "SHIELDS"))
- break;
- policy = xmlnode_get_next_twin(policy);
- }
-
- if (policy) {
- GString *blocked = g_string_new(NULL);
- xmlnode *imtext = xmlnode_get_child(policy,
- "config/block/regexp/imtext");
- while (imtext) {
- const char *value = xmlnode_get_attrib(imtext, "value");
- g_string_append_printf(blocked, "%s<br/>\n",
- purple_base64_decode(value, NULL));
- imtext = xmlnode_get_next_twin(imtext);
- }
-
- cmdproc->session->blocked_text = g_string_free(blocked, FALSE);
- }
-
- xmlnode_free(root);
-#endif
-}
-
-static void
-gcf_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
- purple_debug_info("msn", "Processing GCF command\n");
-
- cmdproc->last_cmd->payload_cb = gcf_cmd_post;
- cmd->payload_len = atoi(cmd->params[1]);
-}
-
-static void
-sbs_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
- purple_debug_info("msn", "Processing SBS... \n");
- /*get the payload content*/
-}
-
-static void
-parse_user_endpoints(MsnUser *user, xmlnode *payloadNode)
-{
- MsnSession *session;
- xmlnode *epNode, *capsNode;
- MsnUserEndpoint data;
- const char *id;
- char *caps, *tmp;
- gboolean is_me;
-
- purple_debug_info("msn", "Get EndpointData\n");
-
- session = user->userlist->session;
- is_me = (user == session->user);
-
- msn_user_clear_endpoints(user);
- for (epNode = xmlnode_get_child(payloadNode, "EndpointData");
- epNode;
- epNode = xmlnode_get_next_twin(epNode)) {
- id = xmlnode_get_attrib(epNode, "id");
- capsNode = xmlnode_get_child(epNode, "Capabilities");
-
- /* Disconnect others, if MPOP is disabled */
- if (is_me
- && !session->enable_mpop
- && strncasecmp(id + 1, session->guid, 36) != 0) {
- purple_debug_info("msn", "Disconnecting Endpoint %s\n", id);
-
- tmp = g_strdup_printf("%s;%s", user->passport, id);
- msn_notification_send_uun(session, tmp, MSN_UNIFIED_NOTIFICATION_MPOP, "goawyplzthxbye");
- g_free(tmp);
- } else {
- if (capsNode != NULL) {
- caps = xmlnode_get_data(capsNode);
-
- data.clientid = strtoul(caps, &tmp, 10);
- if (tmp && *tmp)
- data.extcaps = strtoul(tmp + 1, NULL, 10);
- else
- data.extcaps = 0;
-
- g_free(caps);
- } else {
- data.clientid = 0;
- data.extcaps = 0;
- }
-
- msn_user_set_endpoint_data(user, id, &data);
- }
- }
-
- if (is_me && session->enable_mpop) {
- for (epNode = xmlnode_get_child(payloadNode, "PrivateEndpointData");
- epNode;
- epNode = xmlnode_get_next_twin(epNode)) {
- MsnUserEndpoint *ep;
- xmlnode *nameNode, *clientNode;
-
- /* <PrivateEndpointData id='{GUID}'>
- <EpName>Endpoint Name</EpName>
- <Idle>true/false</Idle>
- <ClientType>1</ClientType>
- <State>NLN</State>
- </PrivateEndpointData>
- */
- id = xmlnode_get_attrib(epNode, "id");
- ep = msn_user_get_endpoint_data(user, id);
-
- if (ep != NULL) {
- nameNode = xmlnode_get_child(epNode, "EpName");
- if (nameNode != NULL) {
- g_free(ep->name);
- ep->name = xmlnode_get_data(nameNode);
- }
-
- clientNode = xmlnode_get_child(epNode, "ClientType");
- if (clientNode != NULL) {
- tmp = xmlnode_get_data(clientNode);
- ep->type = strtoul(tmp, NULL, 10);
- g_free(tmp);
- }
- }
- }
- }
-}
-
-static void parse_currentmedia(MsnUser *user, const char *cmedia)
-{
- char **cmedia_array;
- int strings = 0;
-
- if (!cmedia || cmedia[0] == '\0') {
- purple_debug_info("msn", "No currentmedia string\n");
- return;
- }
-
- purple_debug_info("msn", "Parsing currentmedia string: \"%s\"\n", cmedia);
-
- cmedia_array = g_strsplit(cmedia, "\\0", 0);
-
- /*
- * 0: Application
- * 1: 'Music'/'Games'/'Office'
- * 2: '1' if enabled, '0' if not
- * 3: Format (eg. {0} by {1})
- * 4: Title
- * If 'Music':
- * 5: Artist
- * 6: Album
- * 7: ?
- */
- strings = g_strv_length(cmedia_array);
-
- if (strings >= 4 && !strcmp(cmedia_array[2], "1")) {
- if (user->extinfo == NULL)
- user->extinfo = g_new0(MsnUserExtendedInfo, 1);
- else {
- g_free(user->extinfo->media_album);
- g_free(user->extinfo->media_artist);
- g_free(user->extinfo->media_title);
- }
-
- if (!strcmp(cmedia_array[1], "Music"))
- user->extinfo->media_type = CURRENT_MEDIA_MUSIC;
- else if (!strcmp(cmedia_array[1], "Games"))
- user->extinfo->media_type = CURRENT_MEDIA_GAMES;
- else if (!strcmp(cmedia_array[1], "Office"))
- user->extinfo->media_type = CURRENT_MEDIA_OFFICE;
- else
- user->extinfo->media_type = CURRENT_MEDIA_UNKNOWN;
-
- user->extinfo->media_title = g_strdup(cmedia_array[strings == 4 ? 3 : 4]);
- user->extinfo->media_artist = strings > 5 ? g_strdup(cmedia_array[5]) : NULL;
- user->extinfo->media_album = strings > 6 ? g_strdup(cmedia_array[6]) : NULL;
- }
-
- g_strfreev(cmedia_array);
-}
-
-/*
- * Get the UBX's PSM info
- * Post it to the User status
- * Thanks for Chris <ukdrizzle@yahoo.co.uk>'s code
- */
-static void
-ubx_cmd_post(MsnCmdProc *cmdproc, MsnCommand *cmd, char *payload,
- size_t len)
-{
- MsnSession *session;
- MsnUser *user;
- char *passport;
- int network;
- xmlnode *payloadNode;
- char *psm_str, *str;
-
- session = cmdproc->session;
-
- msn_parse_user(cmd->params[0], &passport, &network);
- user = msn_userlist_find_user(session->userlist, passport);
-
- if (user == NULL) {
- str = g_strndup(payload, len);
- purple_debug_info("msn", "unknown user %s, payload is %s\n",
- passport, str);
- g_free(passport);
- g_free(str);
- return;
- }
-
- g_free(passport);
-
- /* Free any existing media info for this user */
- if (user->extinfo) {
- g_free(user->extinfo->media_album);
- g_free(user->extinfo->media_artist);
- g_free(user->extinfo->media_title);
- user->extinfo->media_album = NULL;
- user->extinfo->media_artist = NULL;
- user->extinfo->media_title = NULL;
- user->extinfo->media_type = CURRENT_MEDIA_UNKNOWN;
- }
-
- if (len != 0) {
- payloadNode = xmlnode_from_str(payload, len);
- if (!payloadNode) {
- purple_debug_error("msn", "UBX XML parse Error!\n");
-
- msn_user_set_statusline(user, NULL);
-
- msn_user_update(user);
- return;
- }
-
- psm_str = msn_get_psm(payloadNode);
- msn_user_set_statusline(user, psm_str);
- g_free(psm_str);
-
- str = msn_get_currentmedia(payloadNode);
- parse_currentmedia(user, str);
- g_free(str);
-
- parse_user_endpoints(user, payloadNode);
-
- xmlnode_free(payloadNode);
-
- } else {
- msn_user_set_statusline(user, NULL);
- }
-
- msn_user_update(user);
-}
-
-static void
-ubx_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
- purple_debug_misc("msn", "UBX received.\n");
- cmdproc->last_cmd->payload_cb = ubx_cmd_post;
- cmd->payload_len = atoi(cmd->params[1]);
-}
-
-static void
-uux_cmd_post(MsnCmdProc *cmdproc, MsnCommand *cmd, char *payload,
- size_t len)
-{
- /* Do Nothing, right now. */
- if (payload != NULL)
- purple_debug_info("msn", "UUX payload:\n%s\n", payload);
-}
-
-static void
-uux_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
- purple_debug_misc("msn", "UUX received.\n");
- cmdproc->last_cmd->payload_cb = uux_cmd_post;
- cmd->payload_len = atoi(cmd->params[1]);
-}
-
-void
-msn_notification_send_uux(MsnSession *session, const char *payload)
-{
- MsnTransaction *trans;
- MsnCmdProc *cmdproc;
- size_t len = strlen(payload);
-
- cmdproc = session->notification->cmdproc;
- purple_debug_misc("msn", "Sending UUX command with payload: %s\n", payload);
- trans = msn_transaction_new(cmdproc, "UUX", "%" G_GSIZE_FORMAT, len);
- msn_transaction_set_payload(trans, payload, len);
- msn_cmdproc_send_trans(cmdproc, trans);
-}
-
-void msn_notification_send_uux_endpointdata(MsnSession *session)
-{
- xmlnode *epDataNode;
- xmlnode *capNode;
- char *caps;
- char *payload;
- int length;
-
- epDataNode = xmlnode_new("EndpointData");
-
- capNode = xmlnode_new_child(epDataNode, "Capabilities");
- caps = g_strdup_printf("%d:%02d", MSN_CLIENT_ID_CAPABILITIES, MSN_CLIENT_ID_EXT_CAPS);
- xmlnode_insert_data(capNode, caps, -1);
- g_free(caps);
-
- payload = xmlnode_to_str(epDataNode, &length);
-
- msn_notification_send_uux(session, payload);
-
- xmlnode_free(epDataNode);
- g_free(payload);
-}
-
-void msn_notification_send_uux_private_endpointdata(MsnSession *session)
-{
- xmlnode *private;
- const char *name;
- xmlnode *epname;
- xmlnode *idle;
- GHashTable *ui_info;
- const gchar *ui_type;
- xmlnode *client_type;
- xmlnode *state;
- char *payload;
- int length;
-
- private = xmlnode_new("PrivateEndpointData");
-
- name = purple_account_get_string(session->account, "endpoint-name", NULL);
- epname = xmlnode_new_child(private, "EpName");
- xmlnode_insert_data(epname, name, -1);
-
- idle = xmlnode_new_child(private, "Idle");
- xmlnode_insert_data(idle, "false", -1);
-
- /* ClientType info (from amsn guys):
- 0: None
- 1: Computer
- 2: Website
- 3: Mobile / none
- 4: Xbox / phone /mobile
- 9: MsnGroup
- 32: Email member, currently Yahoo!
- */
- client_type = xmlnode_new_child(private, "ClientType");
- ui_info = purple_core_get_ui_info();
- ui_type = ui_info ? g_hash_table_lookup(ui_info, "client_type") : NULL;
- if (ui_type) {
- if (strcmp(ui_type, "pc") == 0)
- xmlnode_insert_data(client_type, "1", -1);
- else if (strcmp(ui_type, "web") == 0)
- xmlnode_insert_data(client_type, "2", -1);
- else if (strcmp(ui_type, "phone") == 0)
- xmlnode_insert_data(client_type, "3", -1);
- else if (strcmp(ui_type, "handheld") == 0)
- xmlnode_insert_data(client_type, "3", -1);
- else
- xmlnode_insert_data(client_type, "1", -1);
- }
- else
- xmlnode_insert_data(client_type, "1", -1);
-
- state = xmlnode_new_child(private, "State");
- xmlnode_insert_data(state, msn_state_get_text(msn_state_from_account(session->account)), -1);
-
- payload = xmlnode_to_str(private, &length);
-
- msn_notification_send_uux(session, payload);
-
- xmlnode_free(private);
- g_free(payload);
-}
-
-static void
-ubn_cmd_post(MsnCmdProc *cmdproc, MsnCommand *cmd, char *payload,
- size_t len)
-{
- /* Do Nothing, right now. */
- if (payload != NULL)
- purple_debug_info("msn", "UBN payload:\n%s\n", payload);
-}
-
-static void
-ubn_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
- purple_debug_misc("msn", "UBN received from %s.\n", cmd->params[0]);
- cmdproc->last_cmd->payload_cb = ubn_cmd_post;
- cmd->payload_len = atoi(cmd->params[2]);
-}
-
-static void
-uun_cmd_post(MsnCmdProc *cmdproc, MsnCommand *cmd, char *payload,
- size_t len)
-{
- /* Do Nothing, right now. */
- if (payload != NULL)
- purple_debug_info("msn", "UUN payload:\n%s\n", payload);
-}
-
-static void
-uun_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
- if (strcmp(cmd->params[1], "OK") != 0) {
- purple_debug_misc("msn", "UUN received.\n");
- cmdproc->last_cmd->payload_cb = uun_cmd_post;
- cmd->payload_len = atoi(cmd->params[1]);
- }
- else
- purple_debug_misc("msn", "UUN OK received.\n");
-}
-
-void
-msn_notification_send_uun(MsnSession *session, const char *user,
- MsnUnifiedNotificationType type, const char *payload)
-{
- MsnTransaction *trans;
- MsnCmdProc *cmdproc;
- size_t len = strlen(payload);
-
- cmdproc = session->notification->cmdproc;
- purple_debug_misc("msn", "Sending UUN command %d to %s with payload: %s\n",
- type, user, payload);
- trans = msn_transaction_new(cmdproc, "UUN", "%s %d %" G_GSIZE_FORMAT,
- user, type, len);
- msn_transaction_set_payload(trans, payload, len);
- msn_cmdproc_send_trans(cmdproc, trans);
-}
-
-void
-msn_notification_send_circle_auth(MsnSession *session, const char *ticket)
-{
- MsnTransaction *trans;
- MsnCmdProc *cmdproc;
- char *encoded;
-
- cmdproc = session->notification->cmdproc;
-
- encoded = purple_base64_encode((guchar *)ticket, strlen(ticket));
- trans = msn_transaction_new(cmdproc, "USR", "SHA A %s", encoded);
- msn_cmdproc_send_trans(cmdproc, trans);
-
- g_free(encoded);
-}
-
-/**************************************************************************
- * Message Types
- **************************************************************************/
-
-static void
-profile_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
-{
- MsnSession *session;
- const char *value;
-#ifdef MSN_PARTIAL_LISTS
- const char *clLastChange;
-#endif
-
- session = cmdproc->session;
-
- if (strcmp(msg->remote_user, "Hotmail"))
- /* This isn't an official message. */
- return;
-
- if ((value = msn_message_get_header_value(msg, "sid")) != NULL)
- {
- g_free(session->passport_info.sid);
- session->passport_info.sid = g_strdup(value);
- }
-
- if ((value = msn_message_get_header_value(msg, "MSPAuth")) != NULL)
- {
- g_free(session->passport_info.mspauth);
- session->passport_info.mspauth = g_strdup(value);
- }
-
- if ((value = msn_message_get_header_value(msg, "ClientIP")) != NULL)
- {
- g_free(session->passport_info.client_ip);
- session->passport_info.client_ip = g_strdup(value);
- }
-
- if ((value = msn_message_get_header_value(msg, "ClientPort")) != NULL)
- {
- session->passport_info.client_port = ntohs(atoi(value));
- }
-
- if ((value = msn_message_get_header_value(msg, "LoginTime")) != NULL)
- session->passport_info.sl = atol(value);
-
- if ((value = msn_message_get_header_value(msg, "EmailEnabled")) != NULL)
- session->passport_info.email_enabled = (gboolean)atol(value);
-
-#ifdef MSN_PARTIAL_LISTS
- /*starting retrieve the contact list*/
- clLastChange = purple_account_get_string(session->account, "CLLastChange", NULL);
- /* msn_userlist_load defeats all attempts at trying to detect blist sync issues */
- msn_userlist_load(session);
- msn_get_contact_list(session, MSN_PS_INITIAL, clLastChange);
-#else
- /* always get the full list? */
- msn_get_contact_list(session, MSN_PS_INITIAL, NULL);
-#endif
-}
-
-static void
-initial_email_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
-{
- MsnSession *session;
- PurpleConnection *gc;
- GHashTable *table;
- const char *unread;
-
- session = cmdproc->session;
- gc = session->account->gc;
-
- if (strcmp(msg->remote_user, "Hotmail"))
- /* This isn't an official message. */
- return;
-
- if (session->passport_info.mail_url == NULL)
- {
- MsnTransaction *trans;
- trans = msn_transaction_new(cmdproc, "URL", "%s", "INBOX");
- msn_transaction_queue_cmd(trans, msg->cmd);
-
- msn_cmdproc_send_trans(cmdproc, trans);
-
- return;
- }
-
- if (!purple_account_get_check_mail(session->account))
- return;
-
- table = msn_message_get_hashtable_from_body(msg);
-
- unread = g_hash_table_lookup(table, "Inbox-Unread");
-
- if (unread != NULL)
- {
- int count = atoi(unread);
-
- if (count > 0)
- {
- const char *passports[2] = { msn_user_get_passport(session->user) };
- const char *urls[2] = { session->passport_info.mail_url };
-
- purple_notify_emails(gc, count, FALSE, NULL, NULL,
- passports, urls, NULL, NULL);
- }
- }
-
- g_hash_table_destroy(table);
-}
-
-/*offline Message notification process*/
-static void
-initial_mdata_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
-{
- MsnSession *session;
- PurpleConnection *gc;
- GHashTable *table;
- const char *mdata, *unread;
-
- session = cmdproc->session;
- gc = session->account->gc;
-
- if (strcmp(msg->remote_user, "Hotmail"))
- /* This isn't an official message. */
- return;
-
- table = msn_message_get_hashtable_from_body(msg);
-
- mdata = g_hash_table_lookup(table, "Mail-Data");
-
- if (mdata != NULL)
- msn_parse_oim_msg(session->oim, mdata);
-
- if (g_hash_table_lookup(table, "Inbox-URL") == NULL)
- {
- g_hash_table_destroy(table);
- return;
- }
-
- if (session->passport_info.mail_url == NULL)
- {
- MsnTransaction *trans;
- trans = msn_transaction_new(cmdproc, "URL", "%s", "INBOX");
- msn_transaction_queue_cmd(trans, msg->cmd);
-
- msn_cmdproc_send_trans(cmdproc, trans);
-
- g_hash_table_destroy(table);
- return;
- }
-
- if (!purple_account_get_check_mail(session->account))
- {
- g_hash_table_destroy(table);
- return;
- }
-
- unread = g_hash_table_lookup(table, "Inbox-Unread");
-
- if (unread != NULL)
- {
- int count = atoi(unread);
-
- if (count > 0)
- {
- const char *passports[2] = { msn_user_get_passport(session->user) };
- const char *urls[2] = { session->passport_info.mail_url };
-
- purple_notify_emails(gc, count, FALSE, NULL, NULL,
- passports, urls, NULL, NULL);
- }
- }
-
- g_hash_table_destroy(table);
-}
-
-/*offline Message Notification*/
-static void
-delete_oim_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
-{
- purple_debug_misc("msn", "Delete OIM message.\n");
-}
-
-static void
-email_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
-{
- MsnSession *session;
- PurpleConnection *gc;
- GHashTable *table;
- char *from, *subject, *tmp;
-
- session = cmdproc->session;
- gc = session->account->gc;
-
- if (strcmp(msg->remote_user, "Hotmail"))
- /* This isn't an official message. */
- return;
-
- if (session->passport_info.mail_url == NULL)
- {
- MsnTransaction *trans;
- trans = msn_transaction_new(cmdproc, "URL", "%s", "INBOX");
- msn_transaction_queue_cmd(trans, msg->cmd);
-
- msn_cmdproc_send_trans(cmdproc, trans);
-
- return;
- }
-
- if (!purple_account_get_check_mail(session->account))
- return;
-
- table = msn_message_get_hashtable_from_body(msg);
-
- from = subject = NULL;
-
- tmp = g_hash_table_lookup(table, "From");
- if (tmp != NULL)
- from = purple_mime_decode_field(tmp);
-
- tmp = g_hash_table_lookup(table, "Subject");
- if (tmp != NULL)
- subject = purple_mime_decode_field(tmp);
-
- purple_notify_email(gc,
- (subject != NULL ? subject : ""),
- (from != NULL ? from : ""),
- msn_user_get_passport(session->user),
- session->passport_info.mail_url, NULL, NULL);
-
- g_free(from);
- g_free(subject);
-
- g_hash_table_destroy(table);
-}
-
-static void
-system_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
-{
- GHashTable *table;
- const char *type_s;
-
- if (strcmp(msg->remote_user, "Hotmail"))
- /* This isn't an official message. */
- return;
-
- table = msn_message_get_hashtable_from_body(msg);
-
- if ((type_s = g_hash_table_lookup(table, "Type")) != NULL)
- {
- int type = atoi(type_s);
- char buf[MSN_BUF_LEN] = "";
- int minutes;
-
- switch (type)
- {
- case 1:
- minutes = atoi(g_hash_table_lookup(table, "Arg1"));
- g_snprintf(buf, sizeof(buf), dngettext(PACKAGE,
- "The MSN server will shut down for maintenance "
- "in %d minute. You will automatically be "
- "signed out at that time. Please finish any "
- "conversations in progress.\n\nAfter the "
- "maintenance has been completed, you will be "
- "able to successfully sign in.",
- "The MSN server will shut down for maintenance "
- "in %d minutes. You will automatically be "
- "signed out at that time. Please finish any "
- "conversations in progress.\n\nAfter the "
- "maintenance has been completed, you will be "
- "able to successfully sign in.", minutes),
- minutes);
- default:
- break;
- }
-
- if (*buf != '\0')
- purple_notify_info(cmdproc->session->account->gc, NULL, buf, NULL);
- }
-
- g_hash_table_destroy(table);
-}
-
-/**************************************************************************
- * Dispatch server list management
- **************************************************************************/
-typedef struct MsnAddRemoveListData {
- MsnCmdProc *cmdproc;
- MsnUser *user;
- MsnListOp list_op;
- gboolean add;
-} MsnAddRemoveListData;
-
-static void
-modify_unknown_buddy_on_list(MsnSession *session, const char *passport,
- MsnNetwork network, gpointer data)
-{
- MsnAddRemoveListData *addrem = data;
- MsnCmdProc *cmdproc;
- xmlnode *node;
- char *payload;
- int payload_len;
-
- cmdproc = addrem->cmdproc;
-
- /* Update user first */
- msn_user_set_network(addrem->user, network);
-
- node = xmlnode_new("ml");
- node->child = NULL;
-
- msn_add_contact_xml(node, passport, addrem->list_op, network);
-
- payload = xmlnode_to_str(node, &payload_len);
- xmlnode_free(node);
-
- if (addrem->add)
- msn_notification_post_adl(cmdproc, payload, payload_len);
- else
- msn_notification_post_rml(cmdproc, payload, payload_len);
-
- g_free(payload);
- g_free(addrem);
-}
-
-void
-msn_notification_add_buddy_to_list(MsnNotification *notification, MsnListId list_id,
- MsnUser *user)
-{
- MsnAddRemoveListData *addrem;
- MsnCmdProc *cmdproc;
- MsnListOp list_op = 1 << list_id;
- xmlnode *adl_node;
- char *payload;
- int payload_len;
-
- cmdproc = notification->servconn->cmdproc;
-
- adl_node = xmlnode_new("ml");
- adl_node->child = NULL;
-
- msn_add_contact_xml(adl_node, user->passport, list_op, user->networkid);
-
- payload = xmlnode_to_str(adl_node, &payload_len);
- xmlnode_free(adl_node);
-
- if (user->networkid != MSN_NETWORK_UNKNOWN) {
- msn_notification_post_adl(cmdproc, payload, payload_len);
-
- } else {
- addrem = g_new(MsnAddRemoveListData, 1);
- addrem->cmdproc = cmdproc;
- addrem->user = user;
- addrem->list_op = list_op;
- addrem->add = TRUE;
-
- msn_notification_send_fqy(notification->session, payload, payload_len,
- modify_unknown_buddy_on_list, addrem);
- }
-
- g_free(payload);
-}
-
-void
-msn_notification_rem_buddy_from_list(MsnNotification *notification, MsnListId list_id,
- MsnUser *user)
-{
- MsnAddRemoveListData *addrem;
- MsnCmdProc *cmdproc;
- MsnListOp list_op = 1 << list_id;
- xmlnode *rml_node;
- char *payload;
- int payload_len;
-
- cmdproc = notification->servconn->cmdproc;
-
- rml_node = xmlnode_new("ml");
- rml_node->child = NULL;
-
- msn_add_contact_xml(rml_node, user->passport, list_op, user->networkid);
-
- payload = xmlnode_to_str(rml_node, &payload_len);
- xmlnode_free(rml_node);
-
- if (user->networkid != MSN_NETWORK_UNKNOWN) {
- msn_notification_post_rml(cmdproc, payload, payload_len);
-
- } else {
- addrem = g_new(MsnAddRemoveListData, 1);
- addrem->cmdproc = cmdproc;
- addrem->user = user;
- addrem->list_op = list_op;
- addrem->add = FALSE;
-
- msn_notification_send_fqy(notification->session, payload, payload_len,
- modify_unknown_buddy_on_list, addrem);
- }
-
- g_free(payload);
-}
-
-/**************************************************************************
- * Init
- **************************************************************************/
-void
-msn_notification_init(void)
-{
- cbs_table = msn_table_new();
-
- /* Synchronous */
- msn_table_add_cmd(cbs_table, "CHG", "CHG", NULL);
- msn_table_add_cmd(cbs_table, "CHG", "ILN", iln_cmd);
- msn_table_add_cmd(cbs_table, "ADL", "ILN", iln_cmd);
- msn_table_add_cmd(cbs_table, "USR", "USR", usr_cmd);
- msn_table_add_cmd(cbs_table, "USR", "XFR", xfr_cmd);
- msn_table_add_cmd(cbs_table, "USR", "GCF", gcf_cmd);
- msn_table_add_cmd(cbs_table, "CVR", "CVR", cvr_cmd);
- msn_table_add_cmd(cbs_table, "VER", "VER", ver_cmd);
- msn_table_add_cmd(cbs_table, "PRP", "PRP", prp_cmd);
- msn_table_add_cmd(cbs_table, "BLP", "BLP", blp_cmd);
- msn_table_add_cmd(cbs_table, "XFR", "XFR", xfr_cmd);
-
- /* Asynchronous */
- msn_table_add_cmd(cbs_table, NULL, "IPG", ipg_cmd);
- msn_table_add_cmd(cbs_table, NULL, "MSG", msg_cmd);
- msn_table_add_cmd(cbs_table, NULL, "UBM", ubm_cmd);
- msn_table_add_cmd(cbs_table, NULL, "GCF", gcf_cmd);
- msn_table_add_cmd(cbs_table, NULL, "SBS", sbs_cmd);
- msn_table_add_cmd(cbs_table, NULL, "NOT", not_cmd);
-
- msn_table_add_cmd(cbs_table, NULL, "CHL", chl_cmd);
- msn_table_add_cmd(cbs_table, NULL, "RML", rml_cmd);
- msn_table_add_cmd(cbs_table, NULL, "ADL", adl_cmd);
- msn_table_add_cmd(cbs_table, NULL, "FQY", fqy_cmd);
-
- msn_table_add_cmd(cbs_table, NULL, "QRY", NULL);
- msn_table_add_cmd(cbs_table, NULL, "QNG", qng_cmd);
- msn_table_add_cmd(cbs_table, NULL, "FLN", fln_cmd);
- msn_table_add_cmd(cbs_table, NULL, "NLN", nln_cmd);
- msn_table_add_cmd(cbs_table, NULL, "ILN", iln_cmd);
- msn_table_add_cmd(cbs_table, NULL, "OUT", out_cmd);
- msn_table_add_cmd(cbs_table, NULL, "RNG", rng_cmd);
-
- msn_table_add_cmd(cbs_table, NULL, "UBX", ubx_cmd);
- msn_table_add_cmd(cbs_table, NULL, "UUX", uux_cmd);
-
- msn_table_add_cmd(cbs_table, NULL, "UBN", ubn_cmd);
- msn_table_add_cmd(cbs_table, NULL, "UUN", uun_cmd);
-
- msn_table_add_cmd(cbs_table, NULL, "URL", url_cmd);
-
- msn_table_add_cmd(cbs_table, "fallback", "XFR", xfr_cmd);
-
- msn_table_add_error(cbs_table, "ADL", adl_error);
- msn_table_add_error(cbs_table, "RML", rml_error);
- msn_table_add_error(cbs_table, "FQY", fqy_error);
- msn_table_add_error(cbs_table, "USR", usr_error);
-
- msn_table_add_msg_type(cbs_table,
- "text/x-msmsgsprofile",
- profile_msg);
- /*initial OIM notification*/
- msn_table_add_msg_type(cbs_table,
- "text/x-msmsgsinitialmdatanotification",
- initial_mdata_msg);
- /*OIM notification when user online*/
- msn_table_add_msg_type(cbs_table,
- "text/x-msmsgsoimnotification",
- initial_mdata_msg);
- msn_table_add_msg_type(cbs_table,
- "text/x-msmsgsinitialemailnotification",
- initial_email_msg);
- msn_table_add_msg_type(cbs_table,
- "text/x-msmsgsemailnotification",
- email_msg);
- /*delete an offline Message notification*/
- msn_table_add_msg_type(cbs_table,
- "text/x-msmsgsactivemailnotification",
- delete_oim_msg);
- msn_table_add_msg_type(cbs_table,
- "application/x-msmsgssystemmessage",
- system_msg);
- /* generic message handlers */
- msn_table_add_msg_type(cbs_table, "text/plain",
- msn_plain_msg);
- msn_table_add_msg_type(cbs_table, "text/x-msmsgscontrol",
- msn_control_msg);
- msn_table_add_msg_type(cbs_table, "text/x-msnmsgr-datacast",
- msn_datacast_msg);
-}
-
-void
-msn_notification_end(void)
-{
- msn_table_destroy(cbs_table);
-}
-
diff --git a/libpurple/protocols/msn/notification.h b/libpurple/protocols/msn/notification.h
deleted file mode 100644
index 4e9798dc6b..0000000000
--- a/libpurple/protocols/msn/notification.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/**
- * @file notification.h Notification server functions
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-#ifndef MSN_NOTIFICATION_H
-#define MSN_NOTIFICATION_H
-
-typedef struct _MsnNotification MsnNotification;
-
-/* MSN protocol challenge info */
-
-/* MSNP18 challenge: WLM Version 2009 (Build 14.0.8089.726) */
-#define MSNP18_WLM_PRODUCT_KEY "C1BX{V4W}Q3*10SM"
-#define MSNP18_WLM_PRODUCT_ID "PROD0120PW!CCV9@"
-
-/* MSNP15 challenge: WLM 8.5.1288.816 */
-#define MSNP15_WLM_PRODUCT_KEY "ILTXC!4IXB5FB*PX"
-#define MSNP15_WLM_PRODUCT_ID "PROD0119GSJUC$18"
-
-/* MSNP13 challenge */
-#define MSNP13_WLM_PRODUCT_KEY "O4BG@C7BWLYQX?5G"
-#define MSNP13_WLM_PRODUCT_ID "PROD01065C%ZFN6F"
-
-#define MSNP10_PRODUCT_KEY "VT6PX?UQTM4WM%YR"
-#define MSNP10_PRODUCT_ID "PROD0038W!61ZTF9"
-
-#include "cmdproc.h"
-#include "msg.h"
-#include "session.h"
-#include "servconn.h"
-#include "state.h"
-#include "user.h"
-#include "userlist.h"
-
-struct _MsnNotification
-{
- MsnSession *session;
-
- /**
- * This is a convenience pointer that always points to
- * servconn->cmdproc
- */
- MsnCmdProc *cmdproc;
- MsnServConn *servconn;
-
- gboolean in_use;
-};
-
-typedef void (*MsnFqyCb)(MsnSession *session, const char *passport, MsnNetwork network, gpointer data);
-
-/* Type used for msn_notification_send_uun */
-typedef enum {
- MSN_UNIFIED_NOTIFICATION_SHARED_FOLDERS = 1,
- MSN_UNIFIED_NOTIFICATION_UNKNOWN1 = 2,
- MSN_UNIFIED_NOTIFICATION_P2P = 3,
- MSN_UNIFIED_NOTIFICATION_MPOP = 4
-
-} MsnUnifiedNotificationType;
-
-void msn_notification_end(void);
-void msn_notification_init(void);
-
-void msn_notification_add_buddy_to_list(MsnNotification *notification,
- MsnListId list_id, MsnUser *user);
-void msn_notification_rem_buddy_from_list(MsnNotification *notification,
- MsnListId list_id, MsnUser *user);
-
-void msn_notification_send_fqy(MsnSession *session,
- const char *payload, int payload_len,
- MsnFqyCb cb, gpointer cb_data);
-
-MsnNotification *msn_notification_new(MsnSession *session);
-void msn_notification_destroy(MsnNotification *notification);
-gboolean msn_notification_connect(MsnNotification *notification,
- const char *host, int port);
-void msn_notification_disconnect(MsnNotification *notification);
-void msn_notification_dump_contact(MsnSession *session);
-
-void msn_notification_send_uum(MsnSession *session, MsnMessage *msg);
-
-void msn_notification_send_uux(MsnSession *session, const char *payload);
-
-void msn_notification_send_uux_endpointdata(MsnSession *session);
-
-void msn_notification_send_uux_private_endpointdata(MsnSession *session);
-
-void msn_notification_send_uun(MsnSession *session,
- const char *user,
- MsnUnifiedNotificationType type,
- const char *payload);
-
-void msn_notification_send_circle_auth(MsnSession *session, const char *ticket);
-
-/**
- * Closes a notification.
- *
- * It's first closed, and then disconnected.
- *
- * @param notification The notification object to close.
- */
-void msn_notification_close(MsnNotification *notification);
-
-void msn_got_login_params(MsnSession *session, const char *ticket, const char *response);
-
-#endif /* MSN_NOTIFICATION_H */
diff --git a/libpurple/protocols/msn/object.c b/libpurple/protocols/msn/object.c
deleted file mode 100644
index bee264109a..0000000000
--- a/libpurple/protocols/msn/object.c
+++ /dev/null
@@ -1,459 +0,0 @@
-/**
- * @file object.c MSNObject API
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-
-#include "msn.h"
-#include "object.h"
-#include "debug.h"
-/* Sha1 stuff */
-#include "cipher.h"
-/* Base64 stuff */
-#include "util.h"
-
-#define GET_STRING_TAG(field, id) \
- if ((tag = strstr(str, id "=\"")) != NULL) \
- { \
- tag += strlen(id "=\""); \
- c = strchr(tag, '"'); \
- if (c != NULL) \
- { \
- if (obj->field != NULL) \
- g_free(obj->field); \
- obj->field = g_strndup(tag, c - tag); \
- } \
- }
-
-#define GET_INT_TAG(field, id) \
- if ((tag = strstr(str, id "=\"")) != NULL) \
- { \
- char buf[16]; \
- size_t offset; \
- tag += strlen(id "=\""); \
- c = strchr(tag, '"'); \
- if (c != NULL) \
- { \
- memset(buf, 0, sizeof(buf)); \
- offset = c - tag; \
- if (offset >= sizeof(buf)) \
- offset = sizeof(buf) - 1; \
- strncpy(buf, tag, offset); \
- obj->field = atoi(buf); \
- } \
- }
-
-static GList *local_objs;
-
-MsnObject *
-msn_object_new(void)
-{
- MsnObject *obj;
-
- obj = g_new0(MsnObject, 1);
-
- msn_object_set_type(obj, MSN_OBJECT_UNKNOWN);
- msn_object_set_friendly(obj, "AAA=");
-
- return obj;
-}
-
-MsnObject *
-msn_object_new_from_string(const char *str)
-{
- MsnObject *obj;
- char *tag, *c;
-
- g_return_val_if_fail(str != NULL, NULL);
-
- if (strncmp(str, "<msnobj ", 8))
- return NULL;
-
- obj = msn_object_new();
-
- GET_STRING_TAG(creator, "Creator");
- GET_INT_TAG(size, "Size");
- GET_INT_TAG(type, "Type");
- GET_STRING_TAG(location, "Location");
- GET_STRING_TAG(friendly, "Friendly");
- GET_STRING_TAG(sha1d, "SHA1D");
- GET_STRING_TAG(sha1c, "SHA1C");
- GET_STRING_TAG(url, "Url");
- GET_STRING_TAG(url1, "Url1");
-
- /* If we are missing any of the required elements then discard the object */
- if (obj->creator == NULL || obj->size == 0 || obj->type == 0
- || obj->sha1d == NULL) {
- purple_debug_error("msn", "Discarding invalid msnobj: '%s'\n", str);
- msn_object_destroy(obj);
- return NULL;
- }
-
- if (obj->location == NULL || obj->friendly == NULL) {
- /* Location/friendly are required for non-buddyicon objects */
- if (obj->type != MSN_OBJECT_USERTILE) {
- purple_debug_error("msn", "Discarding invalid msnobj: '%s'\n", str);
- msn_object_destroy(obj);
- return NULL;
- /* Buddy icon object can contain Url/Url1 instead */
- } else if (obj->url == NULL || obj->url1 == NULL) {
- purple_debug_error("msn", "Discarding invalid msnobj: '%s'\n", str);
- msn_object_destroy(obj);
- return NULL;
- }
- }
-
- return obj;
-}
-
-MsnObject*
-msn_object_new_from_image(PurpleStoredImage *img, const char *location,
- const char *creator, MsnObjectType type)
-{
- MsnObject *msnobj;
-
- PurpleCipherContext *ctx;
- char *buf;
- gconstpointer data;
- size_t size;
- char *base64;
- unsigned char digest[20];
-
- msnobj = NULL;
-
- if (img == NULL)
- return msnobj;
-
- size = purple_imgstore_get_size(img);
- data = purple_imgstore_get_data(img);
-
- /* New object */
- msnobj = msn_object_new();
- msn_object_set_local(msnobj);
- msn_object_set_type(msnobj, type);
- msn_object_set_location(msnobj, location);
- msn_object_set_creator(msnobj, creator);
-
- msn_object_set_image(msnobj, img);
-
- /* Compute the SHA1D field. */
- memset(digest, 0, sizeof(digest));
-
- ctx = purple_cipher_context_new_by_name("sha1", NULL);
- purple_cipher_context_append(ctx, data, size);
- purple_cipher_context_digest(ctx, sizeof(digest), digest, NULL);
-
- base64 = purple_base64_encode(digest, sizeof(digest));
- msn_object_set_sha1d(msnobj, base64);
- g_free(base64);
-
- msn_object_set_size(msnobj, size);
-
- /* Compute the SHA1C field. */
- buf = g_strdup_printf(
- "Creator%sSize%dType%dLocation%sFriendly%sSHA1D%s",
- msn_object_get_creator(msnobj),
- msn_object_get_size(msnobj),
- msn_object_get_type(msnobj),
- msn_object_get_location(msnobj),
- msn_object_get_friendly(msnobj),
- msn_object_get_sha1d(msnobj));
-
- memset(digest, 0, sizeof(digest));
-
- purple_cipher_context_reset(ctx, NULL);
- purple_cipher_context_append(ctx, (const guchar *)buf, strlen(buf));
- purple_cipher_context_digest(ctx, sizeof(digest), digest, NULL);
- purple_cipher_context_destroy(ctx);
- g_free(buf);
-
- base64 = purple_base64_encode(digest, sizeof(digest));
- msn_object_set_sha1c(msnobj, base64);
- g_free(base64);
-
- return msnobj;
-}
-
-void
-msn_object_destroy(MsnObject *obj)
-{
- g_return_if_fail(obj != NULL);
-
- g_free(obj->creator);
- g_free(obj->location);
- g_free(obj->friendly);
- g_free(obj->sha1d);
- g_free(obj->sha1c);
- g_free(obj->url);
- g_free(obj->url1);
-
- purple_imgstore_unref(obj->img);
-
- if (obj->local)
- local_objs = g_list_remove(local_objs, obj);
-
- g_free(obj);
-}
-
-char *
-msn_object_to_string(const MsnObject *obj)
-{
- char *str;
- const char *sha1c;
-
- g_return_val_if_fail(obj != NULL, NULL);
-
- sha1c = msn_object_get_sha1c(obj);
-
- str = g_strdup_printf("<msnobj Creator=\"%s\" Size=\"%d\" Type=\"%d\" "
- "Location=\"%s\" Friendly=\"%s\" SHA1D=\"%s\""
- "%s%s%s/>",
- msn_object_get_creator(obj),
- msn_object_get_size(obj),
- msn_object_get_type(obj),
- msn_object_get_location(obj),
- msn_object_get_friendly(obj),
- msn_object_get_sha1d(obj),
- sha1c ? " SHA1C=\"" : "",
- sha1c ? sha1c : "",
- sha1c ? "\"" : "");
-
- return str;
-}
-
-void
-msn_object_set_creator(MsnObject *obj, const char *creator)
-{
- g_return_if_fail(obj != NULL);
-
- g_free(obj->creator);
- obj->creator = g_strdup(creator);
-}
-
-void
-msn_object_set_size(MsnObject *obj, int size)
-{
- g_return_if_fail(obj != NULL);
-
- obj->size = size;
-}
-
-void
-msn_object_set_type(MsnObject *obj, MsnObjectType type)
-{
- g_return_if_fail(obj != NULL);
-
- obj->type = type;
-}
-
-void
-msn_object_set_location(MsnObject *obj, const char *location)
-{
- g_return_if_fail(obj != NULL);
-
- g_free(obj->location);
- obj->location = g_strdup(location);
-}
-
-void
-msn_object_set_friendly(MsnObject *obj, const char *friendly)
-{
- g_return_if_fail(obj != NULL);
-
- g_free(obj->friendly);
- obj->friendly = g_strdup(friendly);
-}
-
-void
-msn_object_set_sha1d(MsnObject *obj, const char *sha1d)
-{
- g_return_if_fail(obj != NULL);
-
- g_free(obj->sha1d);
- obj->sha1d = g_strdup(sha1d);
-}
-
-void
-msn_object_set_sha1c(MsnObject *obj, const char *sha1c)
-{
- g_return_if_fail(obj != NULL);
-
- g_free(obj->sha1c);
- obj->sha1c = g_strdup(sha1c);
-}
-
-void
-msn_object_set_url(MsnObject *obj, const char *url)
-{
- g_return_if_fail(obj != NULL);
-
- g_free(obj->url);
- obj->url = g_strdup(url);
-}
-
-void
-msn_object_set_url1(MsnObject *obj, const char *url)
-{
- g_return_if_fail(obj != NULL);
-
- g_free(obj->url1);
- obj->url1 = g_strdup(url);
-}
-
-const char *
-msn_object_get_creator(const MsnObject *obj)
-{
- g_return_val_if_fail(obj != NULL, NULL);
-
- return obj->creator;
-}
-
-int
-msn_object_get_size(const MsnObject *obj)
-{
- g_return_val_if_fail(obj != NULL, 0);
-
- return obj->size;
-}
-
-MsnObjectType
-msn_object_get_type(const MsnObject *obj)
-{
- g_return_val_if_fail(obj != NULL, MSN_OBJECT_UNKNOWN);
-
- return obj->type;
-}
-
-const char *
-msn_object_get_location(const MsnObject *obj)
-{
- g_return_val_if_fail(obj != NULL, NULL);
-
- return obj->location;
-}
-
-const char *
-msn_object_get_friendly(const MsnObject *obj)
-{
- g_return_val_if_fail(obj != NULL, NULL);
-
- return obj->friendly;
-}
-
-const char *
-msn_object_get_sha1d(const MsnObject *obj)
-{
- g_return_val_if_fail(obj != NULL, NULL);
-
- return obj->sha1d;
-}
-
-const char *
-msn_object_get_sha1c(const MsnObject *obj)
-{
- g_return_val_if_fail(obj != NULL, NULL);
-
- return obj->sha1c;
-}
-
-const char *
-msn_object_get_sha1(const MsnObject *obj)
-{
- g_return_val_if_fail(obj != NULL, NULL);
-
- if(obj->sha1c != NULL) {
- return obj->sha1c;
- } else {
- return obj->sha1d;
- }
-}
-
-const char *
-msn_object_get_url(const MsnObject *obj)
-{
- g_return_val_if_fail(obj != NULL, NULL);
-
- return obj->url;
-}
-
-const char *
-msn_object_get_url1(const MsnObject *obj)
-{
- g_return_val_if_fail(obj != NULL, NULL);
-
- return obj->url1;
-}
-
-MsnObject *
-msn_object_find_local(const char *sha1)
-{
- GList *l;
-
- g_return_val_if_fail(sha1 != NULL, NULL);
-
- for (l = local_objs; l != NULL; l = l->next)
- {
- MsnObject *local_obj = l->data;
-
- if (!strcmp(msn_object_get_sha1(local_obj), sha1))
- return local_obj;
- }
-
- return NULL;
-
-}
-
-void
-msn_object_set_local(MsnObject *obj)
-{
- g_return_if_fail(obj != NULL);
-
- obj->local = TRUE;
-
- local_objs = g_list_append(local_objs, obj);
-}
-
-void
-msn_object_set_image(MsnObject *obj, PurpleStoredImage *img)
-{
- g_return_if_fail(obj != NULL);
- g_return_if_fail(img != NULL);
-
- /* obj->local = TRUE; */
-
- purple_imgstore_unref(obj->img);
- obj->img = purple_imgstore_ref(img);
-}
-
-PurpleStoredImage *
-msn_object_get_image(const MsnObject *obj)
-{
- MsnObject *local_obj;
-
- g_return_val_if_fail(obj != NULL, NULL);
-
- local_obj = msn_object_find_local(msn_object_get_sha1(obj));
-
- if (local_obj != NULL)
- return local_obj->img;
-
- return NULL;
-}
diff --git a/libpurple/protocols/msn/object.h b/libpurple/protocols/msn/object.h
deleted file mode 100644
index 81572dc799..0000000000
--- a/libpurple/protocols/msn/object.h
+++ /dev/null
@@ -1,276 +0,0 @@
-/**
- * @file object.h MSNObject API
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-#ifndef MSN_OBJECT_H
-#define MSN_OBJECT_H
-
-typedef enum
-{
- MSN_OBJECT_UNKNOWN = -1, /**< Unknown object */
- MSN_OBJECT_RESERVED1 = 1, /**< Reserved */
- MSN_OBJECT_EMOTICON = 2, /**< Custom Emoticon */
- MSN_OBJECT_USERTILE = 3, /**< UserTile (buddy icon) */
- MSN_OBJECT_RESERVED2 = 4, /**< Reserved */
- MSN_OBJECT_BACKGROUND = 5 /**< Background */
-} MsnObjectType;
-
-#include "internal.h"
-
-#include "imgstore.h"
-
-typedef struct
-{
- gboolean local;
-
- char *creator;
- int size;
- MsnObjectType type;
- PurpleStoredImage *img;
- char *location;
- char *friendly;
- char *sha1d;
- char *sha1c;
- char *url;
- char *url1;
-} MsnObject;
-
-/**
- * Creates a MsnObject structure.
- *
- * @return A new MsnObject structure.
- */
-MsnObject *msn_object_new(void);
-
-/**
- * Creates a MsnObject structure from a string.
- *
- * @param str The string.
- *
- * @return The new MsnObject structure.
- */
-MsnObject *msn_object_new_from_string(const char *str);
-
-/**
- * Creates a MsnObject structure from a stored image
- *
- * @param img The image associated to object
- * @param location The object location as stored in MsnObject
- * @param creator The creator of the object
- * @param type The type of the object
- *
- * @return A new MsnObject structure
- */
-MsnObject *msn_object_new_from_image(PurpleStoredImage *img,
- const char *location, const char *creator, MsnObjectType type);
-
-/**
- * Destroys an MsnObject structure.
- *
- * @param obj The object structure.
- */
-void msn_object_destroy(MsnObject *obj);
-
-/**
- * Outputs a string representation of an MsnObject.
- *
- * @param obj The object.
- *
- * @return The string representation. This must be freed.
- */
-char *msn_object_to_string(const MsnObject *obj);
-
-/**
- * Sets the creator field in a MsnObject.
- *
- * @param creator The creator value.
- */
-void msn_object_set_creator(MsnObject *obj, const char *creator);
-
-/**
- * Sets the size field in a MsnObject.
- *
- * @param size The size value.
- */
-void msn_object_set_size(MsnObject *obj, int size);
-
-/**
- * Sets the type field in a MsnObject.
- *
- * @param type The type value.
- */
-void msn_object_set_type(MsnObject *obj, MsnObjectType type);
-
-/**
- * Sets the location field in a MsnObject.
- *
- * @param location The location value.
- */
-void msn_object_set_location(MsnObject *obj, const char *location);
-
-/**
- * Sets the friendly name field in a MsnObject.
- *
- * @param friendly The friendly name value.
- */
-void msn_object_set_friendly(MsnObject *obj, const char *friendly);
-
-/**
- * Sets the SHA1D field in a MsnObject.
- *
- * @param sha1d The sha1d value.
- */
-void msn_object_set_sha1d(MsnObject *obj, const char *sha1d);
-
-/**
- * Sets the SHA1C field in a MsnObject.
- *
- * @param sha1c The sha1c value.
- */
-void msn_object_set_sha1c(MsnObject *obj, const char *sha1c);
-
-/**
- * Associates an image with a MsnObject.
- *
- * @param obj The object.
- * @param img The image to associate.
- */
-void msn_object_set_image(MsnObject *obj, PurpleStoredImage *img);
-
-/**
- * Sets the url field in a MsnObject.
- *
- * @param url The url value.
- */
-void msn_object_set_url(MsnObject *obj, const char *url);
-
-/**
- * Sets the url1 field in a MsnObject.
- *
- * @param url1 The url1 value.
- */
-void msn_object_set_url1(MsnObject *obj, const char *url);
-
-/**
- * Returns a MsnObject's creator value.
- *
- * @param obj The object.
- *
- * @return The creator value.
- */
-const char *msn_object_get_creator(const MsnObject *obj);
-
-/**
- * Returns a MsnObject's size value.
- *
- * @param obj The object.
- *
- * @return The size value.
- */
-int msn_object_get_size(const MsnObject *obj);
-
-/**
- * Returns a MsnObject's type.
- *
- * @param obj The object.
- *
- * @return The object type.
- */
-MsnObjectType msn_object_get_type(const MsnObject *obj);
-
-/**
- * Returns a MsnObject's location value.
- *
- * @param obj The object.
- *
- * @return The location value.
- */
-const char *msn_object_get_location(const MsnObject *obj);
-
-/**
- * Returns a MsnObject's friendly name value.
- *
- * @param obj The object.
- *
- * @return The friendly name value.
- */
-const char *msn_object_get_friendly(const MsnObject *obj);
-
-/**
- * Returns a MsnObject's SHA1D value.
- *
- * @param obj The object.
- *
- * @return The SHA1D value.
- */
-const char *msn_object_get_sha1d(const MsnObject *obj);
-
-/**
- * Returns a MsnObject's SHA1C value.
- *
- * @param obj The object.
- *
- * @return The SHA1C value.
- */
-const char *msn_object_get_sha1c(const MsnObject *obj);
-
-/**
- * Returns a MsnObject's SHA1C value if it exists, otherwise SHA1D.
- *
- * @param obj The object.
- *
- * @return The SHA1C value.
- */
-const char *msn_object_get_sha1(const MsnObject *obj);
-
-/**
- * Returns the image associated with the MsnObject.
- *
- * @param obj The object.
- *
- * @return The associated image.
- */
-PurpleStoredImage *msn_object_get_image(const MsnObject *obj);
-
-/**
- * Returns a MsnObject's url value.
- *
- * @param obj The object.
- *
- * @return The url value.
- */
-const char *msn_object_get_url(const MsnObject *obj);
-
-/**
- * Returns a MsnObject's url1 value.
- *
- * @param obj The object.
- *
- * @return The url1 value.
- */
-const char *msn_object_get_url1(const MsnObject *obj);
-
-MsnObject * msn_object_find_local(const char *sha1);
-
-void msn_object_set_local(MsnObject *obj);
-
-#endif /* MSN_OBJECT_H */
diff --git a/libpurple/protocols/msn/oim.c b/libpurple/protocols/msn/oim.c
deleted file mode 100644
index 54b5a6648a..0000000000
--- a/libpurple/protocols/msn/oim.c
+++ /dev/null
@@ -1,886 +0,0 @@
-/**
- * @file oim.c
- * get and send MSN offline Instant Message via SOAP request
- * Author
- * MaYuan<mayuan2006@gmail.com>
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "internal.h"
-#include "debug.h"
-
-#include "soap.h"
-#include "oim.h"
-#include "msnutils.h"
-
-typedef struct _MsnOimSendReq {
- char *from_member;
- char *friendname;
- char *to_member;
- char *oim_msg;
-} MsnOimSendReq;
-
-typedef struct {
- MsnOim *oim;
- char *msg_id;
-} MsnOimRecvData;
-
-/*Local Function Prototype*/
-static void msn_parse_oim_xml(MsnOim *oim, xmlnode *node);
-static void msn_oim_free_send_req(MsnOimSendReq *req);
-static void msn_oim_recv_data_free(MsnOimRecvData *data);
-static void msn_oim_post_single_get_msg(MsnOim *oim, MsnOimRecvData *data);
-
-/*new a OIM object*/
-MsnOim *
-msn_oim_new(MsnSession *session)
-{
- MsnOim *oim;
-
- oim = g_new0(MsnOim, 1);
- oim->session = session;
- oim->oim_list = NULL;
- oim->run_id = rand_guid();
- oim->challenge = NULL;
- oim->send_queue = g_queue_new();
- oim->send_seq = 1;
- return oim;
-}
-
-/*destroy the oim object*/
-void
-msn_oim_destroy(MsnOim *oim)
-{
- MsnOimSendReq *request;
-
- purple_debug_info("msn", "destroy the OIM %p\n", oim);
- g_free(oim->run_id);
- g_free(oim->challenge);
-
- while ((request = g_queue_pop_head(oim->send_queue)) != NULL)
- msn_oim_free_send_req(request);
- g_queue_free(oim->send_queue);
-
- while (oim->oim_list != NULL)
- msn_oim_recv_data_free((MsnOimRecvData *)oim->oim_list->data);
-
- g_free(oim);
-}
-
-static MsnOimSendReq *
-msn_oim_new_send_req(const char *from_member, const char*friendname,
- const char* to_member, const char *msg)
-{
- MsnOimSendReq *request;
-
- request = g_new0(MsnOimSendReq, 1);
- request->from_member = g_strdup(from_member);
- request->friendname = g_strdup(friendname);
- request->to_member = g_strdup(to_member);
- request->oim_msg = g_strdup(msg);
- return request;
-}
-
-static void
-msn_oim_free_send_req(MsnOimSendReq *req)
-{
- g_return_if_fail(req != NULL);
-
- g_free(req->from_member);
- g_free(req->friendname);
- g_free(req->to_member);
- g_free(req->oim_msg);
-
- g_free(req);
-}
-
-static MsnOimRecvData *
-msn_oim_recv_data_new(MsnOim *oim, char *msg_id)
-{
- MsnOimRecvData *data;
-
- data = g_new0(MsnOimRecvData, 1);
- data->oim = oim;
- data->msg_id = msg_id;
-
- oim->oim_list = g_list_append(oim->oim_list, data);
-
- return data;
-}
-
-/* Probably only good for g_list_find_custom */
-static gint
-msn_recv_data_equal(MsnOimRecvData *a, const char *msg_id)
-{
- return strcmp(a->msg_id, msg_id);
-}
-
-static void
-msn_oim_recv_data_free(MsnOimRecvData *data)
-{
- data->oim->oim_list = g_list_remove(data->oim->oim_list, data);
- g_free(data->msg_id);
-
- g_free(data);
-}
-
-/****************************************
- * Manage OIM Tokens
- ****************************************/
-typedef struct _MsnOimRequestData {
- MsnOim *oim;
- gboolean send;
- const char *action;
- const char *host;
- const char *url;
- xmlnode *body;
- MsnSoapCallback cb;
- gpointer cb_data;
-} MsnOimRequestData;
-
-static gboolean msn_oim_request_helper(MsnOimRequestData *data);
-
-static void
-msn_oim_request_cb(MsnSoapMessage *request, MsnSoapMessage *response,
- gpointer req_data)
-{
- MsnOimRequestData *data = (MsnOimRequestData *)req_data;
- xmlnode *fault = NULL;
- xmlnode *faultcode = NULL;
-
- if (response != NULL)
- fault = xmlnode_get_child(response->xml, "Body/Fault");
-
- if (fault && (faultcode = xmlnode_get_child(fault, "faultcode"))) {
- gchar *faultcode_str = xmlnode_get_data(faultcode);
- gboolean need_token_update = FALSE;
-
- if (faultcode_str) {
- if (g_str_equal(faultcode_str, "q0:BadContextToken") ||
- g_str_equal(faultcode_str, "AuthenticationFailed") ||
- g_str_equal(faultcode_str, "s:AuthenticationFailed"))
- need_token_update = TRUE;
- else if (g_str_equal(faultcode_str, "q0:AuthenticationFailed") &&
- xmlnode_get_child(fault, "detail/RequiredAuthPolicy") != NULL)
- need_token_update = TRUE;
- }
-
- if (need_token_update) {
- purple_debug_warning("msn", "OIM Request Error, Updating token now.\n");
- msn_nexus_update_token(data->oim->session->nexus,
- data->send ? MSN_AUTH_LIVE_SECURE : MSN_AUTH_MESSENGER_WEB,
- (GSourceFunc)msn_oim_request_helper, data);
- g_free(faultcode_str);
- return;
-
- }
-
- g_free(faultcode_str);
- }
-
- if (data->cb)
- data->cb(request, response, data->cb_data);
- xmlnode_free(data->body);
- g_free(data);
-}
-
-static gboolean
-msn_oim_request_helper(MsnOimRequestData *data)
-{
- MsnSession *session = data->oim->session;
-
- if (data->send) {
- /* The Sending of OIM's uses a different token for some reason. */
- xmlnode *ticket;
- ticket = xmlnode_get_child(data->body, "Header/Ticket");
- xmlnode_set_attrib(ticket, "passport",
- msn_nexus_get_token_str(session->nexus, MSN_AUTH_LIVE_SECURE));
- }
- else
- {
- xmlnode *passport;
- xmlnode *xml_t;
- xmlnode *xml_p;
- GHashTable *token;
- const char *msn_t;
- const char *msn_p;
-
- token = msn_nexus_get_token(session->nexus, MSN_AUTH_MESSENGER_WEB);
- g_return_val_if_fail(token != NULL, FALSE);
-
- msn_t = g_hash_table_lookup(token, "t");
- msn_p = g_hash_table_lookup(token, "p");
-
- g_return_val_if_fail(msn_t != NULL, FALSE);
- g_return_val_if_fail(msn_p != NULL, FALSE);
-
- passport = xmlnode_get_child(data->body, "Header/PassportCookie");
- xml_t = xmlnode_get_child(passport, "t");
- xml_p = xmlnode_get_child(passport, "p");
-
- /* frees old token text, or the 'EMPTY' text if first time */
- xmlnode_free(xml_t->child);
- xmlnode_free(xml_p->child);
-
- xmlnode_insert_data(xml_t, msn_t, -1);
- xmlnode_insert_data(xml_p, msn_p, -1);
- }
-
- msn_soap_message_send(session,
- msn_soap_message_new(data->action, xmlnode_copy(data->body)),
- data->host, data->url, FALSE,
- msn_oim_request_cb, data);
-
- return FALSE;
-}
-
-
-static void
-msn_oim_make_request(MsnOim *oim, gboolean send, const char *action,
- const char *host, const char *url, xmlnode *body, MsnSoapCallback cb,
- gpointer cb_data)
-{
- MsnOimRequestData *data = g_new0(MsnOimRequestData, 1);
- data->oim = oim;
- data->send = send;
- data->action = action;
- data->host = host;
- data->url = url;
- data->body = body;
- data->cb = cb;
- data->cb_data = cb_data;
-
- msn_oim_request_helper(data);
-}
-
-/****************************************
- * OIM GetMetadata request
- * **************************************/
-static void
-msn_oim_get_metadata_cb(MsnSoapMessage *request, MsnSoapMessage *response,
- gpointer data)
-{
- MsnOim *oim = data;
-
- if (response) {
- msn_parse_oim_xml(oim,
- xmlnode_get_child(response->xml, "Body/GetMetadataResponse/MD"));
- }
-}
-
-/* Post to get the OIM Metadata */
-static void
-msn_oim_get_metadata(MsnOim *oim)
-{
- msn_oim_make_request(oim, FALSE, MSN_OIM_GET_METADATA_ACTION,
- MSN_OIM_RETRIEVE_HOST, MSN_OIM_RETRIEVE_URL,
- xmlnode_from_str(MSN_OIM_GET_METADATA_TEMPLATE, -1),
- msn_oim_get_metadata_cb, oim);
-}
-
-/****************************************
- * OIM send SOAP request
- * **************************************/
-/*encode the message to OIM Message Format*/
-static gchar *
-msn_oim_msg_to_str(MsnOim *oim, const char *body)
-{
- GString *oim_body;
- char *oim_base64;
- char *c;
- int len;
- size_t base64_len;
-
- purple_debug_info("msn", "Encoding OIM Message...\n");
- len = strlen(body);
- c = oim_base64 = purple_base64_encode((const guchar *)body, len);
- base64_len = strlen(oim_base64);
- purple_debug_info("msn", "Encoded base64 body:{%s}\n", oim_base64);
-
- oim_body = g_string_new(NULL);
- g_string_printf(oim_body, MSN_OIM_MSG_TEMPLATE,
- oim->run_id, oim->send_seq);
-
-#define OIM_LINE_LEN 76
- while (base64_len > OIM_LINE_LEN) {
- g_string_append_len(oim_body, c, OIM_LINE_LEN);
- g_string_append_c(oim_body, '\n');
- c += OIM_LINE_LEN;
- base64_len -= OIM_LINE_LEN;
- }
-#undef OIM_LINE_LEN
-
- g_string_append(oim_body, c);
-
- g_free(oim_base64);
-
- return g_string_free(oim_body, FALSE);
-}
-
-/*
- * Process the send return SOAP string
- * If got SOAP Fault,get the lock key,and resend it.
- */
-static void
-msn_oim_send_read_cb(MsnSoapMessage *request, MsnSoapMessage *response,
- gpointer data)
-{
- MsnOim *oim = data;
- MsnOimSendReq *msg = g_queue_pop_head(oim->send_queue);
-
- g_return_if_fail(msg != NULL);
-
- if (response == NULL) {
- purple_debug_info("msn", "cannot send OIM: %s\n", msg->oim_msg);
- } else {
- xmlnode *faultNode = xmlnode_get_child(response->xml, "Body/Fault");
-
- if (faultNode == NULL) {
- /*Send OK! return*/
- purple_debug_info("msn", "sent OIM: %s\n", msg->oim_msg);
- } else {
- xmlnode *faultcode = xmlnode_get_child(faultNode, "faultcode");
-
- if (faultcode) {
- char *faultcode_str = xmlnode_get_data(faultcode);
-
- if (faultcode_str && g_str_equal(faultcode_str, "q0:AuthenticationFailed")) {
- xmlnode *challengeNode = xmlnode_get_child(faultNode,
- "detail/LockKeyChallenge");
- char *challenge = NULL;
-
- if (challengeNode == NULL || (challenge = xmlnode_get_data(challengeNode)) == NULL) {
- if (oim->challenge) {
- g_free(oim->challenge);
- oim->challenge = NULL;
-
- purple_debug_info("msn", "Resending OIM: %s\n",
- msg->oim_msg);
- g_queue_push_head(oim->send_queue, msg);
- msn_oim_send_msg(oim);
- msg = NULL;
- } else {
- purple_debug_info("msn",
- "Can't find lock key for OIM: %s\n",
- msg->oim_msg);
- }
- } else {
- char buf[33];
-
- msn_handle_chl(challenge, buf);
-
- g_free(oim->challenge);
- oim->challenge = g_strndup(buf, sizeof(buf));
- g_free(challenge);
- purple_debug_info("msn", "Found lockkey:{%s}\n", oim->challenge);
-
- /*repost the send*/
- purple_debug_info("msn", "Resending OIM: %s\n", msg->oim_msg);
- g_queue_push_head(oim->send_queue, msg);
- msn_oim_send_msg(oim);
- msg = NULL;
- }
- } else {
- /* Report the error */
- const char *str_reason = NULL;
-
- if (faultcode_str) {
- if (g_str_equal(faultcode_str, "q0:SystemUnavailable")) {
- str_reason = _("Message was not sent because the system is "
- "unavailable. This normally happens when the "
- "user is blocked or does not exist.");
- } else if (g_str_equal(faultcode_str, "q0:SenderThrottleLimitExceeded")) {
- str_reason = _("Message was not sent because messages "
- "are being sent too quickly.");
- } else if (g_str_equal(faultcode_str, "q0:InvalidContent")) {
- str_reason = _("Message was not sent because an unknown "
- "encoding error occurred.");
- }
- }
-
- if (str_reason == NULL) {
- str_reason = _("Message was not sent because an unknown "
- "error occurred.");
- }
-
- msn_session_report_user(oim->session, msg->to_member,
- str_reason, PURPLE_MESSAGE_ERROR);
- msn_session_report_user(oim->session, msg->to_member,
- msg->oim_msg, PURPLE_MESSAGE_RAW);
- }
-
- g_free(faultcode_str);
- }
- }
- }
-
- if (msg)
- msn_oim_free_send_req(msg);
-}
-
-void
-msn_oim_prep_send_msg_info(MsnOim *oim, const char *membername,
- const char* friendname, const char *tomember,
- const char * msg)
-{
- g_return_if_fail(oim != NULL);
-
- g_queue_push_tail(oim->send_queue,
- msn_oim_new_send_req(membername, friendname, tomember, msg));
-}
-
-/*post send single message request to oim server*/
-void
-msn_oim_send_msg(MsnOim *oim)
-{
- MsnOimSendReq *oim_request;
- char *soap_body;
- char *msg_body;
-
- g_return_if_fail(oim != NULL);
- oim_request = g_queue_peek_head(oim->send_queue);
- g_return_if_fail(oim_request != NULL);
-
- purple_debug_info("msn", "Sending OIM: %s\n", oim_request->oim_msg);
-
- /* if we got the challenge lock key, we compute it
- * else we go for the SOAP fault and resend it.
- */
- if (oim->challenge == NULL){
- purple_debug_info("msn", "No lock key challenge, waiting for SOAP Fault and Resend\n");
- }
-
- msg_body = msn_oim_msg_to_str(oim, oim_request->oim_msg);
- soap_body = g_strdup_printf(MSN_OIM_SEND_TEMPLATE,
- oim_request->from_member,
- oim_request->friendname,
- oim_request->to_member,
- MSNP15_WLM_PRODUCT_ID,
- oim->challenge ? oim->challenge : "",
- oim->send_seq,
- msg_body);
-
- msn_oim_make_request(oim, TRUE, MSN_OIM_SEND_SOAP_ACTION, MSN_OIM_SEND_HOST,
- MSN_OIM_SEND_URL, xmlnode_from_str(soap_body, -1), msn_oim_send_read_cb,
- oim);
-
- /*increase the offline Sequence control*/
- if (oim->challenge != NULL) {
- oim->send_seq++;
- }
-
- g_free(msg_body);
- g_free(soap_body);
-}
-
-/****************************************
- * OIM delete SOAP request
- * **************************************/
-static void
-msn_oim_delete_read_cb(MsnSoapMessage *request, MsnSoapMessage *response,
- gpointer data)
-{
- MsnOimRecvData *rdata = data;
-
- if (response && xmlnode_get_child(response->xml, "Body/Fault") == NULL)
- purple_debug_info("msn", "Delete OIM success\n");
- else
- purple_debug_info("msn", "Delete OIM failed\n");
-
- msn_oim_recv_data_free(rdata);
-}
-
-/*Post to get the Offline Instant Message*/
-static void
-msn_oim_post_delete_msg(MsnOimRecvData *rdata)
-{
- MsnOim *oim = rdata->oim;
- char *msgid = rdata->msg_id;
- char *soap_body;
-
- purple_debug_info("msn", "Delete single OIM Message {%s}\n",msgid);
-
- soap_body = g_strdup_printf(MSN_OIM_DEL_TEMPLATE, msgid);
-
- msn_oim_make_request(oim, FALSE, MSN_OIM_DEL_SOAP_ACTION, MSN_OIM_RETRIEVE_HOST,
- MSN_OIM_RETRIEVE_URL, xmlnode_from_str(soap_body, -1), msn_oim_delete_read_cb, rdata);
-
- g_free(soap_body);
-}
-
-/****************************************
- * OIM get SOAP request
- * **************************************/
-/* like purple_str_to_time, but different. The format of the timestamp
- * is like this: 5 Sep 2007 21:42:12 -0700 */
-static time_t
-msn_oim_parse_timestamp(const char *timestamp)
-{
- char month_str[4], tz_str[6];
- char *tz_ptr = tz_str;
- static const char *months[] = {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL
- };
- time_t tval = 0;
- struct tm t;
- memset(&t, 0, sizeof(t));
-
- time(&tval);
- localtime_r(&tval, &t);
-
- if (sscanf(timestamp, "%02d %03s %04d %02d:%02d:%02d %05s",
- &t.tm_mday, month_str, &t.tm_year,
- &t.tm_hour, &t.tm_min, &t.tm_sec, tz_str) == 7) {
- gboolean offset_positive = TRUE;
- int tzhrs;
- int tzmins;
-
- for (t.tm_mon = 0;
- months[t.tm_mon] != NULL &&
- strcmp(months[t.tm_mon], month_str) != 0; t.tm_mon++);
- if (months[t.tm_mon] != NULL) {
- if (*tz_str == '-') {
- offset_positive = FALSE;
- tz_ptr++;
- } else if (*tz_str == '+') {
- tz_ptr++;
- }
-
- if (sscanf(tz_ptr, "%02d%02d", &tzhrs, &tzmins) == 2) {
- time_t tzoff = tzhrs * 60 * 60 + tzmins * 60;
-#ifdef _WIN32
- long sys_tzoff;
-#endif
-
- if (offset_positive)
- tzoff *= -1;
-
- t.tm_year -= 1900;
-
-#ifdef _WIN32
- if ((sys_tzoff = wpurple_get_tz_offset()) != -1)
- tzoff += sys_tzoff;
-#else
-#ifdef HAVE_TM_GMTOFF
- tzoff += t.tm_gmtoff;
-#else
-# ifdef HAVE_TIMEZONE
- tzset(); /* making sure */
- tzoff -= timezone;
-# endif
-#endif
-#endif /* _WIN32 */
-
- return mktime(&t) + tzoff;
- }
- }
- }
-
- purple_debug_info("msn", "Can't parse timestamp %s\n", timestamp);
- return tval;
-}
-
-/*Post the Offline Instant Message to User Conversation*/
-static void
-msn_oim_report_to_user(MsnOimRecvData *rdata, const char *msg_str)
-{
- MsnMessage *message;
- const char *date;
- const char *from;
- const char *boundary;
- char *decode_msg = NULL, *clean_msg = NULL;
- gsize body_len;
- char **tokens;
- char *passport = NULL;
- time_t stamp;
- const char *charset = NULL;
-
- message = msn_message_new(MSN_MSG_UNKNOWN);
-
- msn_message_parse_payload(message, msg_str, strlen(msg_str),
- MSG_OIM_LINE_DEM, MSG_OIM_BODY_DEM);
- purple_debug_info("msn", "oim body:{%s}\n", message->body);
-
- boundary = msn_message_get_header_value(message, "boundary");
-
- if (boundary != NULL) {
- char *bounds;
- char **part;
-
- bounds = g_strdup_printf("--%s" MSG_OIM_LINE_DEM, boundary);
- tokens = g_strsplit(message->body, bounds, 0);
-
- /* tokens+1 to skip the "This is a multipart message..." text */
- for (part = tokens+1; *part != NULL; part++) {
- MsnMessage *multipart;
- const char *type;
- multipart = msn_message_new(MSN_MSG_UNKNOWN);
- msn_message_parse_payload(multipart, *part, strlen(*part),
- MSG_OIM_LINE_DEM, MSG_OIM_BODY_DEM);
-
- type = msn_message_get_content_type(multipart);
- if (type && !strcmp(type, "text/plain")) {
- decode_msg = (char *)purple_base64_decode(multipart->body, &body_len);
- charset = msn_message_get_charset(multipart);
-
- msn_message_unref(multipart);
- break;
- }
- msn_message_unref(multipart);
- }
-
- g_strfreev(tokens);
- g_free(bounds);
-
- if (decode_msg == NULL) {
- purple_debug_error("msn", "Couldn't find text/plain OIM message.\n");
- msn_message_unref(message);
- return;
- }
- } else {
- decode_msg = (char *)purple_base64_decode(message->body, &body_len);
- charset = msn_message_get_charset(message);
- }
-
- if (charset && !((g_ascii_strncasecmp(charset, "UTF-8", 5) == 0) || (g_ascii_strncasecmp(charset, "UTF8", 4) == 0))) {
- clean_msg = g_convert(decode_msg, body_len, "UTF-8", charset, NULL, NULL, NULL);
-
- if (!clean_msg) {
- char *clean = purple_utf8_salvage(decode_msg);
-
- purple_debug_error("msn", "Failed to convert charset from %s to UTF-8 for OIM message: %s\n", charset, clean);
-
- clean_msg = g_strdup_printf(_("%s (There was an error receiving this message. "
- "Converting the encoding from %s to UTF-8 failed.)"),
- clean, charset);
- g_free(clean);
- }
-
- g_free(decode_msg);
-
- } else if (!g_utf8_validate(decode_msg, body_len, NULL)) {
- char *clean = purple_utf8_salvage(decode_msg);
-
- purple_debug_error("msn", "Received an OIM message that is not UTF-8,"
- " and no encoding specified: %s\n", clean);
-
- if (charset) {
- clean_msg = g_strdup_printf(_("%s (There was an error receiving this message."
- " The charset was %s, but it was not valid UTF-8.)"),
- clean, charset);
- } else {
- clean_msg = g_strdup_printf(_("%s (There was an error receiving this message."
- " The charset was missing, but it was not valid UTF-8.)"),
- clean);
- }
-
- g_free(clean);
- g_free(decode_msg);
-
- } else {
- clean_msg = decode_msg;
- }
-
- from = msn_message_get_header_value(message, "X-OIM-originatingSource");
-
- /* Match number to user's mobile number, FROM is a phone number
- if the other side pages you using your phone number */
- if (from && !strncmp(from, "tel:+", 5)) {
- MsnUser *user = msn_userlist_find_user_with_mobile_phone(
- rdata->oim->session->userlist, from + 4);
-
- if (user && user->passport)
- passport = g_strdup(user->passport);
- }
-
- if (passport == NULL) {
- char *start, *end;
-
- from = msn_message_get_header_value(message, "From");
-
- tokens = g_strsplit(from, " ", 2);
- if (tokens[1] != NULL)
- from = (const char *)tokens[1];
-
- start = strchr(from, '<');
- if (start != NULL) {
- start++;
- end = strchr(from, '>');
- if (end != NULL)
- passport = g_strndup(start, end - start);
- }
- if (passport == NULL)
- passport = g_strdup(_("Unknown"));
-
- g_strfreev(tokens);
- }
-
- date = msn_message_get_header_value(message, "Date");
- stamp = msn_oim_parse_timestamp(date);
- purple_debug_info("msn", "oim Date:{%s},passport{%s}\n",
- date, passport);
-
- serv_got_im(purple_account_get_connection(rdata->oim->session->account), passport, clean_msg, 0,
- stamp);
-
- /*Now get the oim message ID from the oim_list.
- * and append to read list to prepare for deleting the Offline Message when sign out
- */
- msn_oim_post_delete_msg(rdata);
-
- g_free(passport);
- g_free(clean_msg);
- msn_message_unref(message);
-}
-
-/* Parse the XML data,
- * prepare to report the OIM to user
- */
-static void
-msn_oim_get_read_cb(MsnSoapMessage *request, MsnSoapMessage *response,
- gpointer data)
-{
- MsnOimRecvData *rdata = data;
-
- if (response != NULL) {
- xmlnode *msg_node = xmlnode_get_child(response->xml,
- "Body/GetMessageResponse/GetMessageResult");
-
- if (msg_node) {
- char *msg_str = xmlnode_get_data(msg_node);
- msn_oim_report_to_user(rdata, msg_str);
- g_free(msg_str);
- } else {
- char *str = xmlnode_to_str(response->xml, NULL);
- purple_debug_info("msn", "Unknown OIM response: %s\n", str);
- g_free(str);
- msn_oim_recv_data_free(rdata);
- }
- } else {
- purple_debug_info("msn", "Failed to get OIM\n");
- msn_oim_recv_data_free(rdata);
- }
-
-}
-
-/* parse the oim XML data
- * and post it to the soap server to get the Offline Message
- * */
-void
-msn_parse_oim_msg(MsnOim *oim,const char *xmlmsg)
-{
- xmlnode *node;
-
- purple_debug_info("msn", "%s\n", xmlmsg);
-
- if (!strcmp(xmlmsg, "too-large")) {
- /* Too many OIM's to send via NS, so we need to request them via SOAP. */
- msn_oim_get_metadata(oim);
- } else {
- node = xmlnode_from_str(xmlmsg, -1);
- msn_parse_oim_xml(oim, node);
- xmlnode_free(node);
- }
-}
-
-static void
-msn_parse_oim_xml(MsnOim *oim, xmlnode *node)
-{
- xmlnode *mNode;
- xmlnode *iu_node;
- MsnSession *session = oim->session;
-
- g_return_if_fail(node != NULL);
-
- if (strcmp(node->name, "MD") != 0) {
- char *xmlmsg = xmlnode_to_str(node, NULL);
- purple_debug_info("msn", "WTF is this? %s\n", xmlmsg);
- g_free(xmlmsg);
- return;
- }
-
- iu_node = xmlnode_get_child(node, "E/IU");
-
- if (iu_node != NULL && purple_account_get_check_mail(session->account))
- {
- char *unread = xmlnode_get_data(iu_node);
- const char *passports[2] = { msn_user_get_passport(session->user) };
- const char *urls[2] = { session->passport_info.mail_url };
- int count;
-
- /* XXX/khc: pretty sure this is wrong */
- if (unread && (count = atoi(unread)) > 0)
- purple_notify_emails(session->account->gc, count, FALSE, NULL,
- NULL, passports, urls, NULL, NULL);
- g_free(unread);
- }
-
- for(mNode = xmlnode_get_child(node, "M"); mNode;
- mNode = xmlnode_get_next_twin(mNode)){
- char *passport, *msgid, *nickname, *rtime = NULL;
- xmlnode *e_node, *i_node, *n_node, *rt_node;
-
- e_node = xmlnode_get_child(mNode, "E");
- passport = xmlnode_get_data(e_node);
-
- i_node = xmlnode_get_child(mNode, "I");
- msgid = xmlnode_get_data(i_node);
-
- n_node = xmlnode_get_child(mNode, "N");
- nickname = xmlnode_get_data(n_node);
-
- rt_node = xmlnode_get_child(mNode, "RT");
- if (rt_node != NULL) {
- rtime = xmlnode_get_data(rt_node);
- }
-/* purple_debug_info("msn", "E:{%s},I:{%s},rTime:{%s}\n",passport,msgid,rTime); */
-
- if (!g_list_find_custom(oim->oim_list, msgid, (GCompareFunc)msn_recv_data_equal)) {
- MsnOimRecvData *data = msn_oim_recv_data_new(oim, msgid);
- msn_oim_post_single_get_msg(oim, data);
- msgid = NULL;
- }
-
- g_free(passport);
- g_free(msgid);
- g_free(rtime);
- g_free(nickname);
- }
-}
-
-/*Post to get the Offline Instant Message*/
-static void
-msn_oim_post_single_get_msg(MsnOim *oim, MsnOimRecvData *data)
-{
- char *soap_body;
-
- purple_debug_info("msn", "Get single OIM Message\n");
-
- soap_body = g_strdup_printf(MSN_OIM_GET_TEMPLATE, data->msg_id);
-
- msn_oim_make_request(oim, FALSE, MSN_OIM_GET_SOAP_ACTION, MSN_OIM_RETRIEVE_HOST,
- MSN_OIM_RETRIEVE_URL, xmlnode_from_str(soap_body, -1), msn_oim_get_read_cb,
- data);
-
- g_free(soap_body);
-}
-
diff --git a/libpurple/protocols/msn/oim.h b/libpurple/protocols/msn/oim.h
deleted file mode 100644
index 17751ea27b..0000000000
--- a/libpurple/protocols/msn/oim.h
+++ /dev/null
@@ -1,163 +0,0 @@
-/**
- * @file oim.h Header file for oim.c
- * Author
- * MaYuan<mayuan2006@gmail.com>
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-#ifndef MSN_OIM_H
-#define MSN_OIM_H
-
-typedef struct _MsnOim MsnOim;
-
-/* OIM Retrieval Info */
-#define MSN_OIM_RETRIEVE_HOST "rsi.hotmail.com"
-#define MSN_OIM_RETRIEVE_URL "/rsi/rsi.asmx"
-
-/* OIM GetMetadata SOAP Template */
-#define MSN_OIM_GET_METADATA_ACTION "http://www.hotmail.msn.com/ws/2004/09/oim/rsi/GetMetadata"
-
-#define MSN_OIM_GET_METADATA_TEMPLATE "<?xml version=\"1.0\" encoding=\"utf-8\"?>"\
-"<soap:Envelope"\
- " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""\
- " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\""\
- " xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"\
- "<soap:Header>"\
- "<PassportCookie xmlns=\"http://www.hotmail.msn.com/ws/2004/09/oim/rsi\">"\
- "<t>EMPTY</t>"\
- "<p>EMPTY</p>"\
- "</PassportCookie>"\
- "</soap:Header>"\
- "<soap:Body>"\
- "<GetMetadata xmlns=\"http://www.hotmail.msn.com/ws/2004/09/oim/rsi\" />"\
- "</soap:Body>"\
-"</soap:Envelope>"
-
-/*OIM GetMessage SOAP Template*/
-#define MSN_OIM_GET_SOAP_ACTION "http://www.hotmail.msn.com/ws/2004/09/oim/rsi/GetMessage"
-
-#define MSN_OIM_GET_TEMPLATE "<?xml version=\"1.0\" encoding=\"utf-8\"?>"\
-"<soap:Envelope"\
- " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""\
- " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\""\
- " xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"\
- "<soap:Header>"\
- "<PassportCookie xmlns=\"http://www.hotmail.msn.com/ws/2004/09/oim/rsi\">"\
- "<t>EMPTY</t>"\
- "<p>EMPTY</p>"\
- "</PassportCookie>"\
- "</soap:Header>"\
- "<soap:Body>"\
- "<GetMessage xmlns=\"http://www.hotmail.msn.com/ws/2004/09/oim/rsi\">"\
- "<messageId>%s</messageId>"\
- "<alsoMarkAsRead>false</alsoMarkAsRead>"\
- "</GetMessage>"\
- "</soap:Body>"\
-"</soap:Envelope>"
-
-/*OIM DeleteMessages SOAP Template*/
-#define MSN_OIM_DEL_SOAP_ACTION "http://www.hotmail.msn.com/ws/2004/09/oim/rsi/DeleteMessages"
-
-#define MSN_OIM_DEL_TEMPLATE "<?xml version=\"1.0\" encoding=\"utf-8\"?>"\
-"<soap:Envelope"\
- " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""\
- " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\""\
- " xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"\
- "<soap:Header>"\
- "<PassportCookie xmlns=\"http://www.hotmail.msn.com/ws/2004/09/oim/rsi\">"\
- "<t>EMPTY</t>"\
- "<p>EMPTY</p>"\
- "</PassportCookie>"\
- "</soap:Header>"\
- "<soap:Body>"\
- "<DeleteMessages xmlns=\"http://www.hotmail.msn.com/ws/2004/09/oim/rsi\">"\
- "<messageIds>"\
- "<messageId>%s</messageId>"\
- "</messageIds>"\
- "</DeleteMessages>"\
- "</soap:Body>"\
-"</soap:Envelope>"
-
-/*OIM Send SOAP Template*/
-#define MSN_OIM_MSG_TEMPLATE "MIME-Version: 1.0\n"\
- "Content-Type: text/plain; charset=UTF-8\n"\
- "Content-Transfer-Encoding: base64\n"\
- "X-OIM-Message-Type: OfflineMessage\n"\
- "X-OIM-Run-Id: {%s}\n"\
- "X-OIM-Sequence-Num: %d\n\n"
-
-#define MSN_OIM_SEND_HOST "ows.messenger.msn.com"
-#define MSN_OIM_SEND_URL "/OimWS/oim.asmx"
-#define MSN_OIM_SEND_SOAP_ACTION "http://messenger.live.com/ws/2006/09/oim/Store2"
-#define MSN_OIM_SEND_TEMPLATE "<?xml version=\"1.0\" encoding=\"utf-8\"?>"\
-"<soap:Envelope"\
- " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""\
- " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\""\
- " xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"\
- "<soap:Header>"\
- "<From"\
- " memberName=\"%s\""\
- " friendlyName=\"%s\""\
- " xml:lang=\"en-US\""\
- " proxy=\"MSNMSGR\""\
- " xmlns=\"http://messenger.msn.com/ws/2004/09/oim/\""\
- " msnpVer=\"MSNP15\""\
- " buildVer=\"8.5.1288\"/>"\
- "<To memberName=\"%s\" xmlns=\"http://messenger.msn.com/ws/2004/09/oim/\"/>"\
- "<Ticket passport=\"EMPTY\" appid=\"%s\" lockkey=\"%s\" xmlns=\"http://messenger.msn.com/ws/2004/09/oim/\"/>"\
- "<Sequence xmlns=\"http://schemas.xmlsoap.org/ws/2003/03/rm\">"\
- "<Identifier xmlns=\"http://schemas.xmlsoap.org/ws/2002/07/utility\">http://messenger.msn.com</Identifier>"\
- "<MessageNumber>%d</MessageNumber>"\
- "</Sequence>"\
- "</soap:Header>"\
- "<soap:Body>"\
- "<MessageType xmlns=\"http://messenger.msn.com/ws/2004/09/oim/\">text</MessageType>"\
- "<Content xmlns=\"http://messenger.msn.com/ws/2004/09/oim/\">%s</Content>"\
- "</soap:Body>"\
-"</soap:Envelope>"
-
-struct _MsnOim
-{
- MsnSession *session;
-
- GList * oim_list;
-
- char *challenge;
- char *run_id;
- gint send_seq;
- GQueue *send_queue;
-};
-
-/****************************************************
- * function prototype
- * **************************************************/
-MsnOim * msn_oim_new(MsnSession *session);
-void msn_oim_destroy(MsnOim *oim);
-
-void msn_parse_oim_msg(MsnOim *oim,const char *xmlmsg);
-
-/*Send OIM Message*/
-void msn_oim_prep_send_msg_info(MsnOim *oim, const char *membername,
- const char *friendname, const char *tomember,
- const char * msg);
-
-void msn_oim_send_msg(MsnOim *oim);
-
-#endif/* MSN_OIM_H*/
diff --git a/libpurple/protocols/msn/p2p.c b/libpurple/protocols/msn/p2p.c
deleted file mode 100644
index d39979edb1..0000000000
--- a/libpurple/protocols/msn/p2p.c
+++ /dev/null
@@ -1,872 +0,0 @@
-/**
- * @file p2p.c MSN P2P functions
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-
-#include "internal.h"
-#include "debug.h"
-
-#include "p2p.h"
-#include "tlv.h"
-#include "msnutils.h"
-
-MsnP2PInfo *
-msn_p2p_info_new(MsnP2PVersion version)
-{
- MsnP2PInfo *info = g_new0(MsnP2PInfo, 1);
- info->version = version;
-
- switch (version) {
- case MSN_P2P_VERSION_ONE:
- case MSN_P2P_VERSION_TWO:
- /* Nothing to do */
- break;
-
- default:
- purple_debug_error("msn", "Invalid P2P Info version: %d\n", version);
- g_free(info);
- info = NULL;
- }
-
- return info;
-}
-
-MsnP2PInfo *
-msn_p2p_info_dup(MsnP2PInfo *info)
-{
- MsnP2PInfo *new_info = g_new0(MsnP2PInfo, 1);
-
- new_info->version = info->version;
-
- switch (info->version) {
- case MSN_P2P_VERSION_ONE:
- *new_info = *info;
- break;
-
- case MSN_P2P_VERSION_TWO:
- *new_info = *info;
- new_info->header.v2.header_tlv = msn_tlvlist_copy(info->header.v2.header_tlv);
- new_info->header.v2.data_tlv = msn_tlvlist_copy(info->header.v2.data_tlv);
- break;
-
- default:
- purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
- g_free(new_info);
- new_info = NULL;
- }
-
- return new_info;
-}
-
-void
-msn_p2p_info_free(MsnP2PInfo *info)
-{
- switch (info->version) {
- case MSN_P2P_VERSION_ONE:
- /* Nothing to do! */
- break;
-
- case MSN_P2P_VERSION_TWO:
- msn_tlvlist_free(info->header.v2.header_tlv);
- msn_tlvlist_free(info->header.v2.data_tlv);
- break;
-
- default:
- purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
- }
-
- g_free(info);
-}
-
-size_t
-msn_p2p_header_from_wire(MsnP2PInfo *info, const char *wire, size_t max_len)
-{
- size_t len = 0;
-
- switch (info->version) {
- case MSN_P2P_VERSION_ONE: {
- MsnP2PHeader *header = &info->header.v1;
-
- if (max_len < P2P_PACKET_HEADER_SIZE) {
- /* Invalid packet length */
- len = 0;
- break;
- }
-
- header->session_id = msn_pop32le(wire);
- header->id = msn_pop32le(wire);
- header->offset = msn_pop64le(wire);
- header->total_size = msn_pop64le(wire);
- header->length = msn_pop32le(wire);
- header->flags = msn_pop32le(wire);
- header->ack_id = msn_pop32le(wire);
- header->ack_sub_id = msn_pop32le(wire);
- header->ack_size = msn_pop64le(wire);
-
- len = P2P_PACKET_HEADER_SIZE;
- break;
- }
-
- case MSN_P2P_VERSION_TWO: {
- MsnP2Pv2Header *header = &info->header.v2;
-
- header->header_len = msn_pop8(wire);
- header->opcode = msn_pop8(wire);
- header->message_len = msn_pop16be(wire);
- header->base_id = msn_pop32be(wire);
- if ((gsize)header->header_len + header->message_len +
- P2P_PACKET_FOOTER_SIZE > max_len)
- {
- /* Invalid header and data length */
- len = 0;
- break;
- }
-
- if (header->header_len > 8) {
- header->header_tlv = msn_tlvlist_read(wire, header->header_len - 8);
- wire += header->header_len - 8;
- }
-
- if (header->message_len > 0) {
- /* Parse Data packet */
-
- header->data_header_len = msn_pop8(wire);
- if (header->data_header_len > header->message_len) {
- /* Invalid data header length */
- len = 0;
- break;
- }
- header->data_tf = msn_pop8(wire);
- header->package_number = msn_pop16be(wire);
- header->session_id = msn_pop32be(wire);
-
- if (header->data_header_len > 8) {
- header->data_tlv = msn_tlvlist_read(wire, header->data_header_len - 8);
- wire += header->data_header_len - 8;
- }
- }
-
- len = header->header_len + header->message_len;
-
- break;
- }
-
- default:
- purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
- }
-
- return len;
-}
-
-char *
-msn_p2p_header_to_wire(MsnP2PInfo *info, size_t *len)
-{
- char *wire = NULL;
- char *tmp;
-
- switch (info->version) {
- case MSN_P2P_VERSION_ONE: {
- MsnP2PHeader *header = &info->header.v1;
- tmp = wire = g_new(char, P2P_PACKET_HEADER_SIZE);
-
- msn_push32le(tmp, header->session_id);
- msn_push32le(tmp, header->id);
- msn_push64le(tmp, header->offset);
- msn_push64le(tmp, header->total_size);
- msn_push32le(tmp, header->length);
- msn_push32le(tmp, header->flags);
- msn_push32le(tmp, header->ack_id);
- msn_push32le(tmp, header->ack_sub_id);
- msn_push64le(tmp, header->ack_size);
-
- if (len)
- *len = P2P_PACKET_HEADER_SIZE;
-
- break;
- }
-
- case MSN_P2P_VERSION_TWO: {
- MsnP2Pv2Header *header = &info->header.v2;
- char *header_wire = NULL;
- char *data_header_wire = NULL;
-
- if (header->header_tlv != NULL)
- header_wire = msn_tlvlist_write(header->header_tlv, &header->header_len);
- else
- header->header_len = 0;
-
- if (header->data_tlv != NULL)
- data_header_wire = msn_tlvlist_write(header->data_tlv, &header->data_header_len);
- else
- header->data_header_len = 0;
-
- tmp = wire = g_new(char, 16 + header->header_len + header->data_header_len);
-
- msn_push8(tmp, header->header_len + 8);
- msn_push8(tmp, header->opcode);
- msn_push16be(tmp, header->data_header_len + 8 + header->message_len);
- msn_push32be(tmp, header->base_id);
-
- if (header_wire != NULL) {
- memcpy(tmp, header_wire, header->header_len);
- tmp += header->header_len;
- }
-
- msn_push8(tmp, header->data_header_len + 8);
- msn_push8(tmp, header->data_tf);
- msn_push16be(tmp, header->package_number);
- msn_push32be(tmp, header->session_id);
-
- if (data_header_wire != NULL) {
- memcpy(tmp, data_header_wire, header->data_header_len);
- tmp += header->data_header_len;
- }
-
- if (len)
- *len = header->header_len + header->data_header_len + 16;
-
- break;
- }
-
- default:
- purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
- }
-
- return wire;
-}
-
-size_t
-msn_p2p_footer_from_wire(MsnP2PInfo *info, const char *wire)
-{
- MsnP2PFooter *footer;
-
- footer = &info->footer;
-
- footer->value = msn_pop32be(wire);
-
- return P2P_PACKET_FOOTER_SIZE;
-}
-
-char *
-msn_p2p_footer_to_wire(MsnP2PInfo *info, size_t *len)
-{
- MsnP2PFooter *footer;
- char *wire;
- char *tmp;
-
- footer = &info->footer;
- tmp = wire = g_new(char, P2P_PACKET_FOOTER_SIZE);
-
- msn_push32be(tmp, footer->value);
-
- if (len)
- *len = P2P_PACKET_FOOTER_SIZE;
-
- return wire;
-}
-
-void
-msn_p2p_info_to_string(MsnP2PInfo *info, GString *str)
-{
- switch (info->version) {
- case MSN_P2P_VERSION_ONE: {
- MsnP2PHeader *header = &info->header.v1;
- g_string_append_printf(str, "Session ID: %u\r\n", header->session_id);
- g_string_append_printf(str, "ID: %u\r\n", header->id);
- g_string_append_printf(str, "Offset: %" G_GUINT64_FORMAT "\r\n", header->offset);
- g_string_append_printf(str, "Total size: %" G_GUINT64_FORMAT "\r\n", header->total_size);
- g_string_append_printf(str, "Length: %u\r\n", header->length);
- g_string_append_printf(str, "Flags: 0x%x\r\n", header->flags);
- g_string_append_printf(str, "ACK ID: %u\r\n", header->ack_id);
- g_string_append_printf(str, "SUB ID: %u\r\n", header->ack_sub_id);
- g_string_append_printf(str, "ACK Size: %" G_GUINT64_FORMAT "\r\n", header->ack_size);
-
- break;
- }
-
- case MSN_P2P_VERSION_TWO:
- /* Nothing to do! */
- break;
-
- default:
- purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
- }
-
- g_string_append_printf(str, "Footer: 0x%08X\r\n", info->footer.value);
-}
-
-gboolean
-msn_p2p_msg_is_data(const MsnP2PInfo *info)
-{
- gboolean data = FALSE;
-
- switch (info->version) {
- case MSN_P2P_VERSION_ONE: {
- guint32 flags = info->header.v1.flags;
- data = (flags == P2P_MSN_OBJ_DATA ||
- flags == (P2P_WLM2009_COMP | P2P_MSN_OBJ_DATA) ||
- flags == P2P_FILE_DATA);
- break;
- }
-
- case MSN_P2P_VERSION_TWO:
- data = info->header.v2.message_len > 0;
- break;
-
- default:
- purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
- }
-
- return data;
-}
-
-gboolean
-msn_p2p_info_is_valid(MsnP2PInfo *info)
-{
- gboolean valid = FALSE;
-
- switch (info->version) {
- case MSN_P2P_VERSION_ONE:
- valid = info->header.v1.total_size >= info->header.v1.length;
- break;
-
- case MSN_P2P_VERSION_TWO:
- /* Nothing to do! */
- valid = TRUE;
- break;
-
- default:
- purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
- }
-
- return valid;
-}
-
-gboolean
-msn_p2p_info_is_first(MsnP2PInfo *info)
-{
- gboolean first = FALSE;
-
- switch (info->version) {
- case MSN_P2P_VERSION_ONE:
- first = info->header.v1.offset == 0;
- break;
-
- case MSN_P2P_VERSION_TWO:
- /* Nothing to do! */
- first = info->header.v2.data_tf & TF_FIRST;
- break;
-
- default:
- purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
- }
-
- return first;
-}
-
-gboolean
-msn_p2p_info_is_final(MsnP2PInfo *info)
-{
- gboolean final = FALSE;
-
- switch (info->version) {
- case MSN_P2P_VERSION_ONE:
- final = info->header.v1.offset + info->header.v1.length >= info->header.v1.total_size;
- break;
-
- case MSN_P2P_VERSION_TWO:
- final = msn_tlv_gettlv(info->header.v2.data_tlv, P2P_DATA_TLV_REMAINING, 1) == NULL;
- break;
-
- default:
- purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
- }
-
- return final;
-}
-
-void
-msn_p2p_info_create_ack(MsnP2PInfo *old_info, MsnP2PInfo *new_info)
-{
- switch (old_info->version) {
- case MSN_P2P_VERSION_ONE: {
- MsnP2PHeader *old = &old_info->header.v1;
- MsnP2PHeader *new = &new_info->header.v1;
-
- new->session_id = old->session_id;
- new->flags = P2P_ACK;
- new->ack_id = old->id;
- new->ack_sub_id = old->ack_id;
- new->ack_size = old->total_size;
- break;
- }
-
- case MSN_P2P_VERSION_TWO: {
- MsnP2Pv2Header *old = &old_info->header.v2;
- MsnP2Pv2Header *new = &new_info->header.v2;
-
- msn_tlvlist_add_32(&new->header_tlv, P2P_HEADER_TLV_TYPE_ACK, old->base_id + old->message_len);
- new->opcode = P2P_OPCODE_NONE;
-
- if (old->message_len > 0) {
- if (!msn_tlv_gettlv(old->header_tlv, P2P_HEADER_TLV_TYPE_ACK, 1)) {
- if (old->opcode & P2P_OPCODE_SYN) {
- msn_tlv_t *ack_tlv;
- new->opcode |= P2P_OPCODE_RAK;
-
- ack_tlv = msn_tlv_gettlv(old->header_tlv, P2P_HEADER_TLV_TYPE_PEER_INFO, 1);
- if (ack_tlv) {
- msn_tlvlist_add_tlv(&new->header_tlv, ack_tlv);
- new->opcode |= P2P_OPCODE_SYN;
- }
- }
- }
- }
- break;
- }
-
- default:
- purple_debug_error("msn", "Invalid P2P Info version: %d\n", old_info->version);
- }
-}
-
-gboolean
-msn_p2p_info_require_ack(MsnP2PInfo *info)
-{
- gboolean ret = FALSE;
-
- switch (info->version) {
- case MSN_P2P_VERSION_ONE: {
- guint32 flags = msn_p2p_info_get_flags(info);
-
- ret = flags == P2P_NO_FLAG || flags == P2P_WLM2009_COMP ||
- msn_p2p_msg_is_data(info);
- break;
- }
-
- case MSN_P2P_VERSION_TWO:
- ret = (info->header.v2.opcode & P2P_OPCODE_RAK) > 0;
- break;
-
- default:
- purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
- }
-
- return ret;
-}
-
-gboolean
-msn_p2p_info_is_ack(MsnP2PInfo *info)
-{
- gboolean ret = FALSE;
-
- switch (info->version) {
- case MSN_P2P_VERSION_ONE: {
- ret = msn_p2p_info_get_flags(info) == P2P_ACK;
- break;
- }
-
- case MSN_P2P_VERSION_TWO:
- ret = msn_tlv_gettlv(info->header.v2.header_tlv, P2P_HEADER_TLV_TYPE_ACK, 1) != NULL;
- break;
-
- default:
- purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
- }
-
- return ret;
-}
-
-void
-msn_p2p_info_init_first(MsnP2PInfo *info, MsnP2PInfo *old_info)
-{
- switch (info->version) {
- case MSN_P2P_VERSION_ONE:
- info->header.v1.session_id = old_info->header.v1.session_id;
- info->header.v1.flags = old_info->header.v1.flags;
- break;
-
- case MSN_P2P_VERSION_TWO:
- info->header.v2.data_tf = TF_FIRST;
- break;
-
- default:
- purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
- }
-}
-
-guint32
-msn_p2p_info_get_session_id(MsnP2PInfo *info)
-{
- guint32 session_id = 0;
-
- switch (info->version) {
- case MSN_P2P_VERSION_ONE:
- session_id = info->header.v1.session_id;
- break;
-
- case MSN_P2P_VERSION_TWO:
- session_id = info->header.v2.session_id;
- break;
-
- default:
- purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
- }
-
- return session_id;
-}
-
-guint32
-msn_p2p_info_get_id(MsnP2PInfo *info)
-{
- guint32 id = 0;
-
- switch (info->version) {
- case MSN_P2P_VERSION_ONE:
- id = info->header.v1.id;
- break;
-
- case MSN_P2P_VERSION_TWO:
- id = info->header.v2.base_id;
- break;
-
- default:
- purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
- }
-
- return id;
-}
-
-guint64
-msn_p2p_info_get_offset(MsnP2PInfo *info)
-{
- guint64 offset = 0;
-
- switch (info->version) {
- case MSN_P2P_VERSION_ONE:
- offset = info->header.v1.offset;
- break;
-
- case MSN_P2P_VERSION_TWO:
- /* Nothing to do! */
- break;
-
- default:
- purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
- }
-
- return offset;
-}
-
-guint64
-msn_p2p_info_get_total_size(MsnP2PInfo *info)
-{
- guint64 total_size = 0;
-
- switch (info->version) {
- case MSN_P2P_VERSION_ONE:
- total_size = info->header.v1.total_size;
- break;
-
- case MSN_P2P_VERSION_TWO:
- /* Nothing to do! */
- break;
-
- default:
- purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
- }
-
- return total_size;
-}
-
-guint32
-msn_p2p_info_get_length(MsnP2PInfo *info)
-{
- guint32 length = 0;
-
- switch (info->version) {
- case MSN_P2P_VERSION_ONE:
- length = info->header.v1.length;
- break;
-
- case MSN_P2P_VERSION_TWO:
- /* Nothing to do! */
- break;
-
- default:
- purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
- }
-
- return length;
-}
-
-guint32
-msn_p2p_info_get_flags(MsnP2PInfo *info)
-{
- guint32 flags = 0;
-
- switch (info->version) {
- case MSN_P2P_VERSION_ONE:
- flags = info->header.v1.flags;
- break;
-
- case MSN_P2P_VERSION_TWO:
- flags = info->header.v2.data_tf;
- break;
-
- default:
- purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
- }
-
- return flags;
-}
-
-guint32
-msn_p2p_info_get_ack_id(MsnP2PInfo *info)
-{
- guint32 ack_id = 0;
-
- switch (info->version) {
- case MSN_P2P_VERSION_ONE:
- ack_id = info->header.v1.ack_id;
- break;
-
- case MSN_P2P_VERSION_TWO:
- /* Nothing to do! */
- break;
-
- default:
- purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
- }
-
- return ack_id;
-}
-
-guint32
-msn_p2p_info_get_ack_sub_id(MsnP2PInfo *info)
-{
- guint32 ack_sub_id = 0;
-
- switch (info->version) {
- case MSN_P2P_VERSION_ONE:
- ack_sub_id = info->header.v1.ack_sub_id;
- break;
-
- case MSN_P2P_VERSION_TWO:
- /* Nothing to do! */
- break;
-
- default:
- purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
- }
-
- return ack_sub_id;
-}
-
-guint64
-msn_p2p_info_get_ack_size(MsnP2PInfo *info)
-{
- guint64 ack_size = 0;
-
- switch (info->version) {
- case MSN_P2P_VERSION_ONE:
- ack_size = info->header.v1.ack_size;
- break;
-
- case MSN_P2P_VERSION_TWO:
- /* Nothing to do! */
- break;
-
- default:
- purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
- }
-
- return ack_size;
-}
-
-guint32
-msn_p2p_info_get_app_id(MsnP2PInfo *info)
-{
- return info->footer.value;
-}
-
-void
-msn_p2p_info_set_session_id(MsnP2PInfo *info, guint32 session_id)
-{
- switch (info->version) {
- case MSN_P2P_VERSION_ONE:
- info->header.v1.session_id = session_id;
- break;
-
- case MSN_P2P_VERSION_TWO:
- info->header.v2.session_id = session_id;
- break;
-
- default:
- purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
- }
-
-}
-
-void
-msn_p2p_info_set_id(MsnP2PInfo *info, guint32 id)
-{
- switch (info->version) {
- case MSN_P2P_VERSION_ONE:
- info->header.v1.id = id;
- break;
-
- case MSN_P2P_VERSION_TWO:
- info->header.v2.base_id = id;
- break;
-
- default:
- purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
- }
-
-}
-
-void
-msn_p2p_info_set_offset(MsnP2PInfo *info, guint64 offset)
-{
- switch (info->version) {
- case MSN_P2P_VERSION_ONE:
- info->header.v1.offset = offset;
- break;
-
- case MSN_P2P_VERSION_TWO:
- /* Nothing to do! */
- break;
-
- default:
- purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
- }
-}
-
-void
-msn_p2p_info_set_total_size(MsnP2PInfo *info, guint64 total_size)
-{
- switch (info->version) {
- case MSN_P2P_VERSION_ONE:
- info->header.v1.total_size = total_size;
- break;
-
- case MSN_P2P_VERSION_TWO:
- /* Nothing to do! */
- break;
-
- default:
- purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
- }
-}
-
-void
-msn_p2p_info_set_length(MsnP2PInfo *info, guint32 length)
-{
- switch (info->version) {
- case MSN_P2P_VERSION_ONE:
- info->header.v1.length = length;
- break;
-
- case MSN_P2P_VERSION_TWO:
- /* Nothing to do! */
- break;
-
- default:
- purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
- }
-}
-
-void
-msn_p2p_info_set_flags(MsnP2PInfo *info, guint32 flags)
-{
- switch (info->version) {
- case MSN_P2P_VERSION_ONE:
- info->header.v1.flags = flags;
- break;
-
- case MSN_P2P_VERSION_TWO:
- info->header.v2.data_tf = flags;
- break;
-
- default:
- purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
- }
-}
-
-void
-msn_p2p_info_set_ack_id(MsnP2PInfo *info, guint32 ack_id)
-{
- switch (info->version) {
- case MSN_P2P_VERSION_ONE:
- info->header.v1.ack_id = ack_id;
- break;
-
- case MSN_P2P_VERSION_TWO:
- /* Nothing to do! */
- break;
-
- default:
- purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
- }
-}
-
-void
-msn_p2p_info_set_ack_sub_id(MsnP2PInfo *info, guint32 ack_sub_id)
-{
- switch (info->version) {
- case MSN_P2P_VERSION_ONE:
- info->header.v1.ack_sub_id = ack_sub_id;
- break;
-
- case MSN_P2P_VERSION_TWO:
- /* Nothing to do! */
- break;
-
- default:
- purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
- }
-}
-
-void
-msn_p2p_info_set_ack_size(MsnP2PInfo *info, guint64 ack_size)
-{
- switch (info->version) {
- case MSN_P2P_VERSION_ONE:
- info->header.v1.ack_size = ack_size;
- break;
-
- case MSN_P2P_VERSION_TWO:
- /* Nothing to do! */
- break;
-
- default:
- purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
- }
-}
-
-void
-msn_p2p_info_set_app_id(MsnP2PInfo *info, guint32 app_id)
-{
- info->footer.value = app_id;
-}
-
diff --git a/libpurple/protocols/msn/p2p.h b/libpurple/protocols/msn/p2p.h
deleted file mode 100644
index 89ac239486..0000000000
--- a/libpurple/protocols/msn/p2p.h
+++ /dev/null
@@ -1,264 +0,0 @@
-/**
- * @file p2p.h MSN P2P functions
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-
-#ifndef MSN_P2P_H
-#define MSN_P2P_H
-
-typedef struct {
- guint32 session_id;
- guint32 id;
- /**
- * In a MsnSlpMessage:
- * For outgoing messages this is the number of bytes from buffer that
- * have already been sent out. For incoming messages this is the
- * number of bytes that have been written to buffer.
- */
- guint64 offset;
- guint64 total_size;
- guint32 length;
- guint32 flags;
- guint32 ack_id;
- guint32 ack_sub_id;
- guint64 ack_size;
-/* guint8 body[1]; */
-} MsnP2PHeader;
-#define P2P_PACKET_HEADER_SIZE (6 * 4 + 3 * 8)
-
-typedef struct {
- guint8 header_len;
- guint8 opcode;
- guint16 message_len;
- guint32 base_id;
- GSList *header_tlv;
- guint8 data_header_len;
- guint8 data_tf;
- guint16 package_number;
- guint32 session_id;
- GSList *data_tlv;
-/* guint8 body[1]; */
-} MsnP2Pv2Header;
-
-typedef struct {
- guint16 protocol_version;
- guint16 implementation_id;
- guint16 version;
- guint16 reserved;
- guint32 caps;
-} P2PPeerInfo;
-
-typedef enum
-{
- TF_FIRST = 0x01, /**< The first package. */
- TF_MSNOBJ = 0x04, /**< Payload contains binary data for MsnObject. */
- TF_FILE = 0x06 /**< Payload contains binary data. */
-} TF;
-
-typedef enum
-{
- P2P_HEADER_TLV_TYPE_PEER_INFO = 0x01, /**< Client peer info */
- P2P_HEADER_TLV_TYPE_ACK = 0x02, /**< ACK */
- P2P_HEADER_TLV_TYPE_NAK = 0x03 /**< NAK */
-} P2PHeaderTLVType;
-
-typedef enum
-{
- P2P_DATA_TLV_REMAINING = 0x01, /**< Indicates the remaining data to transfer.*/
-} P2PDataTLVType;
-
-typedef enum
-{
- P2P_PI_PVER = 0x0200,
- P2P_PI_IMP_ID = 0,
- P2P_PI_VER = 0x0e00,
- P2P_PI_RES = 0,
- P2P_PI_CAPS = 0x0000010f
-} P2PPeerInfoVal;
-
-typedef struct
-{
- guint32 value;
-} MsnP2PFooter;
-#define P2P_PACKET_FOOTER_SIZE (1 * 4)
-
-typedef enum
-{
- MSN_P2P_VERSION_ONE = 0,
- MSN_P2P_VERSION_TWO = 1,
-} MsnP2PVersion;
-
-typedef struct {
- MsnP2PVersion version;
- union {
- MsnP2PHeader v1;
- MsnP2Pv2Header v2;
- } header;
- MsnP2PFooter footer;
-} MsnP2PInfo;
-
-typedef enum
-{
- P2P_NO_FLAG = 0x0, /**< No flags specified */
- P2P_OUT_OF_ORDER = 0x1, /**< Chunk out-of-order */
- P2P_ACK = 0x2, /**< Acknowledgement */
- P2P_PENDING_INVITE = 0x4, /**< There is a pending invite */
- P2P_BINARY_ERROR = 0x8, /**< Error on the binary level */
- P2P_FILE = 0x10, /**< File */
- P2P_MSN_OBJ_DATA = 0x20, /**< MsnObject data */
- P2P_CLOSE = 0x40, /**< Close session */
- P2P_TLP_ERROR = 0x80, /**< Error at transport layer protocol */
- P2P_DC_HANDSHAKE = 0x100, /**< Direct Handshake */
- P2P_WLM2009_COMP = 0x1000000, /**< Compatibility with WLM 2009 */
- P2P_FILE_DATA = 0x1000030 /**< File transfer data */
-} MsnP2PHeaderFlag;
-/* Info From:
- * http://msnpiki.msnfanatic.com/index.php/MSNC:P2Pv1_Headers#Flags
- * http://trac.kmess.org/changeset/ba04d0c825769d23370511031c47f6be75fe9b86
- * #7180
- */
-
-typedef enum
-{
- P2P_APPID_SESSION = 0x0, /**< Negotiating session */
- P2P_APPID_OBJ = 0x1, /**< MsnObject (Display or Emoticon) */
- P2P_APPID_FILE = 0x2, /**< File transfer */
- P2P_APPID_EMOTE = 0xB, /**< CustomEmoticon */
- P2P_APPID_DISPLAY = 0xC /**< Display Image */
-} MsnP2PAppId;
-
-typedef enum
-{
- P2P_OPCODE_NONE = 0x00,
- P2P_OPCODE_SYN = 0x01,
- P2P_OPCODE_RAK = 0x02
-} MsnP2Pv2OpCode;
-
-MsnP2PInfo *
-msn_p2p_info_new(MsnP2PVersion version);
-
-MsnP2PInfo *
-msn_p2p_info_dup(MsnP2PInfo *info);
-
-void
-msn_p2p_info_free(MsnP2PInfo *info);
-
-size_t
-msn_p2p_header_from_wire(MsnP2PInfo *info, const char *wire, size_t max_len);
-
-char *
-msn_p2p_header_to_wire(MsnP2PInfo *info, size_t *len);
-
-size_t
-msn_p2p_footer_from_wire(MsnP2PInfo *info, const char *wire);
-
-char *
-msn_p2p_footer_to_wire(MsnP2PInfo *info, size_t *len);
-
-void
-msn_p2p_info_to_string(MsnP2PInfo *info, GString *str);
-
-gboolean
-msn_p2p_msg_is_data(const MsnP2PInfo *info);
-
-gboolean
-msn_p2p_info_is_valid(MsnP2PInfo *info);
-
-gboolean
-msn_p2p_info_is_first(MsnP2PInfo *info);
-
-gboolean
-msn_p2p_info_is_final(MsnP2PInfo *info);
-
-void
-msn_p2p_info_create_ack(MsnP2PInfo *old_info, MsnP2PInfo *new_info);
-
-gboolean
-msn_p2p_info_require_ack(MsnP2PInfo *info);
-
-gboolean
-msn_p2p_info_is_ack(MsnP2PInfo *info);
-
-void
-msn_p2p_info_init_first(MsnP2PInfo *new_info, MsnP2PInfo *old_info);
-
-guint32
-msn_p2p_info_get_session_id(MsnP2PInfo *info);
-
-guint32
-msn_p2p_info_get_id(MsnP2PInfo *info);
-
-guint64
-msn_p2p_info_get_offset(MsnP2PInfo *info);
-
-guint64
-msn_p2p_info_get_total_size(MsnP2PInfo *info);
-
-guint32
-msn_p2p_info_get_length(MsnP2PInfo *info);
-
-guint32
-msn_p2p_info_get_flags(MsnP2PInfo *info);
-
-guint32
-msn_p2p_info_get_ack_id(MsnP2PInfo *info);
-
-guint32
-msn_p2p_info_get_ack_sub_id(MsnP2PInfo *info);
-
-guint64
-msn_p2p_info_get_ack_size(MsnP2PInfo *info);
-
-guint32
-msn_p2p_info_get_app_id(MsnP2PInfo *info);
-
-void
-msn_p2p_info_set_session_id(MsnP2PInfo *info, guint32 session_id);
-
-void
-msn_p2p_info_set_id(MsnP2PInfo *info, guint32 id);
-
-void
-msn_p2p_info_set_offset(MsnP2PInfo *info, guint64 offset);
-
-void
-msn_p2p_info_set_total_size(MsnP2PInfo *info, guint64 total_size);
-
-void
-msn_p2p_info_set_length(MsnP2PInfo *info, guint32 length);
-
-void
-msn_p2p_info_set_flags(MsnP2PInfo *info, guint32 flags);
-
-void
-msn_p2p_info_set_ack_id(MsnP2PInfo *info, guint32 ack_id);
-
-void
-msn_p2p_info_set_ack_sub_id(MsnP2PInfo *info, guint32 ack_sub_id);
-
-void
-msn_p2p_info_set_ack_size(MsnP2PInfo *info, guint64 ack_size);
-
-void
-msn_p2p_info_set_app_id(MsnP2PInfo *info, guint32 app_id);
-
-#endif /* MSN_P2P_H */
diff --git a/libpurple/protocols/msn/page.c b/libpurple/protocols/msn/page.c
deleted file mode 100644
index a357af4da7..0000000000
--- a/libpurple/protocols/msn/page.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/**
- * @file page.c Paging functions
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-#include "msn.h"
-#include "page.h"
-
-MsnPage *
-msn_page_new(void)
-{
- MsnPage *page;
-
- page = g_new0(MsnPage, 1);
-
- return page;
-}
-
-void
-msn_page_destroy(MsnPage *page)
-{
- g_return_if_fail(page != NULL);
-
- g_free(page->body);
- g_free(page->from_location);
- g_free(page->from_phone);
-
- g_free(page);
-}
-
-char *
-msn_page_gen_payload(const MsnPage *page, size_t *ret_size)
-{
- char *str;
- char *body;
-
- g_return_val_if_fail(page != NULL, NULL);
-
- body = g_markup_escape_text(msn_page_get_body(page), -1);
- str = g_strdup_printf(
- "<TEXT xml:space=\"preserve\" enc=\"utf-8\">%s</TEXT>",
- body);
- g_free(body);
-
- if (ret_size != NULL)
- *ret_size = strlen(str);
-
- return str;
-}
-
-void
-msn_page_set_body(MsnPage *page, const char *body)
-{
- g_return_if_fail(page != NULL);
- g_return_if_fail(body != NULL);
-
- g_free(page->body);
- page->body = g_strdup(body);
-}
-
-const char *
-msn_page_get_body(const MsnPage *page)
-{
- g_return_val_if_fail(page != NULL, NULL);
-
- return page->body;
-}
diff --git a/libpurple/protocols/msn/page.h b/libpurple/protocols/msn/page.h
deleted file mode 100644
index 4fb89f5380..0000000000
--- a/libpurple/protocols/msn/page.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/**
- * @file page.h Paging functions
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-#ifndef MSN_PAGE_H
-#define MSN_PAGE_H
-
-typedef struct _MsnPage MsnPage;
-
-#include "session.h"
-
-/**
- * A page.
- */
-struct _MsnPage
-{
- char *from_location;
- char *from_phone;
-
- char *body;
-};
-
-/**
- * Creates a new, empty page.
- *
- * @return A new page.
- */
-MsnPage *msn_page_new(void);
-
-/**
- * Destroys a page.
- */
-void msn_page_destroy(MsnPage *page);
-
-/**
- * Generates the payload data of a page.
- *
- * @param page The page.
- * @param ret_size The returned size of the payload.
- *
- * @return The payload data of a page.
- */
-char *msn_page_gen_payload(const MsnPage *page, size_t *ret_size);
-
-/**
- * Sets the body of a page.
- *
- * @param page The page.
- * @param body The body of the page.
- */
-void msn_page_set_body(MsnPage *page, const char *body);
-
-/**
- * Returns the body of the page.
- *
- * @param page The page.
- *
- * @return The body of the page.
- */
-const char *msn_page_get_body(const MsnPage *page);
-
-#endif /* MSN_PAGE_H */
diff --git a/libpurple/protocols/msn/sbconn.c b/libpurple/protocols/msn/sbconn.c
deleted file mode 100644
index a9a6288844..0000000000
--- a/libpurple/protocols/msn/sbconn.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/**
- * @file sbconn.c MSN Switchboard Connection
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-
-#include "internal.h"
-#include "debug.h"
-
-#include "msg.h"
-#include "sbconn.h"
-
-void msn_sbconn_send_part(MsnSlpLink *slplink, MsnSlpMessagePart *part)
-{
- MsnMessage *msg;
- const char *passport;
- char *data;
- size_t size;
-
- msg = msn_message_new_msnslp();
-
- passport = purple_normalize(slplink->session->account, slplink->remote_user);
- msn_message_set_header(msg, "P2P-Dest", passport);
-
- msg->part = msn_slpmsgpart_ref(part);
- data = msn_slpmsgpart_serialize(part, &size);
- msn_message_set_bin_data(msg, data, size);
- g_free(data);
-
- if (slplink->swboard == NULL)
- {
- slplink->swboard = msn_session_get_swboard(slplink->session,
- slplink->remote_user, MSN_SB_FLAG_FT);
-
- g_return_if_fail(slplink->swboard != NULL);
-
- /* If swboard is destroyed we will be too */
- slplink->swboard->slplinks = g_list_prepend(slplink->swboard->slplinks, slplink);
- }
-
- msn_switchboard_send_msg(slplink->swboard, msg, TRUE);
- msn_message_unref(msg);
-}
-
-/** Called when a message times out. */
-static void
-msg_timeout(MsnCmdProc *cmdproc, MsnTransaction *trans)
-{
- MsnMessage *msg;
-
- msg = trans->data;
-
- msg_error_helper(cmdproc, msg, MSN_MSG_ERROR_TIMEOUT);
-}
-
-static void
-release_msg(MsnSwitchBoard *swboard, MsnMessage *msg)
-{
- MsnCmdProc *cmdproc;
- MsnTransaction *trans;
- char *payload;
- gsize payload_len;
- char flag;
-
- g_return_if_fail(swboard != NULL);
- g_return_if_fail(msg != NULL);
-
- cmdproc = swboard->cmdproc;
-
- payload = msn_message_gen_payload(msg, &payload_len);
-
- if (purple_debug_is_verbose()) {
- purple_debug_info("msn", "SB length:{%" G_GSIZE_FORMAT "}\n", payload_len);
- msn_message_show_readable(msg, "SB SEND", FALSE);
- }
-
- flag = msn_message_get_flag(msg);
- trans = msn_transaction_new(cmdproc, "MSG", "%c %" G_GSIZE_FORMAT,
- flag, payload_len);
-
- /* Data for callbacks */
- msn_transaction_set_data(trans, msg);
-
- if (flag != 'U') {
- if (msg->type == MSN_MSG_TEXT)
- {
- msg->ack_ref = TRUE;
- msn_message_ref(msg);
- swboard->ack_list = g_list_append(swboard->ack_list, msg);
- msn_transaction_set_timeout_cb(trans, msg_timeout);
- }
- else if (msg->type == MSN_MSG_SLP)
- {
- msg->ack_ref = TRUE;
- msn_message_ref(msg);
- swboard->ack_list = g_list_append(swboard->ack_list, msg);
- msn_transaction_set_timeout_cb(trans, msg_timeout);
-#if 0
- if (msg->ack_cb != NULL)
- {
- msn_transaction_add_cb(trans, "ACK", msg_ack);
- msn_transaction_add_cb(trans, "NAK", msg_nak);
- }
-#endif
- }
- }
-
- trans->payload = payload;
- trans->payload_len = payload_len;
-
- msn_cmdproc_send_trans(cmdproc, trans);
-}
-
-static void
-queue_msg(MsnSwitchBoard *swboard, MsnMessage *msg)
-{
- g_return_if_fail(swboard != NULL);
- g_return_if_fail(msg != NULL);
-
- purple_debug_info("msn", "Appending message to queue.\n");
-
- g_queue_push_tail(swboard->msg_queue, msg);
-
- msn_message_ref(msg);
-}
-
-void
-msn_sbconn_process_queue(MsnSwitchBoard *swboard)
-{
- MsnMessage *msg;
-
- g_return_if_fail(swboard != NULL);
-
- purple_debug_info("msn", "Processing queue\n");
-
- while ((msg = g_queue_pop_head(swboard->msg_queue)) != NULL)
- {
- purple_debug_info("msn", "Sending message\n");
- release_msg(swboard, msg);
- msn_message_unref(msg);
- }
-}
-
-void
-msn_switchboard_send_msg(MsnSwitchBoard *swboard, MsnMessage *msg,
- gboolean queue)
-{
- g_return_if_fail(swboard != NULL);
- g_return_if_fail(msg != NULL);
-
- purple_debug_info("msn", "switchboard send msg..\n");
- if (msn_switchboard_can_send(swboard))
- release_msg(swboard, msg);
- else if (queue)
- queue_msg(swboard, msg);
-}
diff --git a/libpurple/protocols/msn/sbconn.h b/libpurple/protocols/msn/sbconn.h
deleted file mode 100644
index 3b59172ef5..0000000000
--- a/libpurple/protocols/msn/sbconn.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- * @file sbconn.h MSN Switchboard Connection
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-
-#ifndef MSN_SBCONN_H
-#define MSN_SBCONN_H
-
-#include "msg.h"
-#include "slplink.h"
-
-#define MSN_SBCONN_MAX_SIZE 1202
-
-void msn_sbconn_send_part(MsnSlpLink *slplink, MsnSlpMessagePart *part);
-
-void msn_switchboard_send_msg(MsnSwitchBoard *swboard, MsnMessage *msg,
- gboolean queue);
-
-void
-msn_sbconn_process_queue(MsnSwitchBoard *swboard);
-
-#endif /* MSN_SBCONN_H */
diff --git a/libpurple/protocols/msn/servconn.c b/libpurple/protocols/msn/servconn.c
deleted file mode 100644
index 2d8ea83587..0000000000
--- a/libpurple/protocols/msn/servconn.c
+++ /dev/null
@@ -1,608 +0,0 @@
-/**
- * @file servconn.c Server connection functions
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-#include "internal.h"
-#include "debug.h"
-
-#include "servconn.h"
-#include "error.h"
-
-static void read_cb(gpointer data, gint source, PurpleInputCondition cond);
-static void servconn_timeout_renew(MsnServConn *servconn);
-
-/**************************************************************************
- * 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 = purple_circ_buffer_new(MSN_BUF_LEN);
- servconn->tx_handler = 0;
- servconn->timeout_sec = 0;
- servconn->timeout_handle = 0;
-
- servconn->fd = -1;
-
- return servconn;
-}
-
-void
-msn_servconn_destroy(MsnServConn *servconn)
-{
- g_return_if_fail(servconn != NULL);
-
- if (servconn->processing)
- {
- servconn->wasted = TRUE;
- return;
- }
-
- 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);
-
- purple_circ_buffer_destroy(servconn->tx_buf);
- if (servconn->tx_handler > 0)
- purple_input_remove(servconn->tx_handler);
- if (servconn->timeout_handle > 0)
- purple_timeout_remove(servconn->timeout_handle);
-
- 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,
- const char *reason)
-{
- MsnSession *session = servconn->session;
- MsnServConnType type = servconn->type;
-
- const char *names[] = { "Notification", "Switchboard" };
- const char *name;
-
- name = names[type];
-
- if (reason == NULL) {
- 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;
- }
- }
-
- purple_debug_error("msn", "Connection error from %s server (%s): %s\n",
- name, servconn->host, reason);
-
- if (type == MSN_SERVCONN_SB)
- {
- MsnSwitchBoard *swboard;
- swboard = servconn->cmdproc->data;
- if (swboard != NULL)
- swboard->error = MSN_SB_ERROR_CONNECTION;
- }
-
- /* servconn->disconnect_cb may destroy servconn, so don't use it again */
- msn_servconn_disconnect(servconn);
-
- if (type == MSN_SERVCONN_NS)
- {
- char *tmp = g_strdup_printf(_("Connection error from %s server:\n%s"),
- name, reason);
- msn_session_set_error(session, MSN_ERROR_SERVCONN, tmp);
- g_free(tmp);
- }
-}
-
-/**************************************************************************
- * Connect
- **************************************************************************/
-
-static void
-connect_cb(gpointer data, gint source, const char *error_message)
-{
- MsnServConn *servconn;
-
- servconn = data;
- servconn->connect_data = NULL;
-
- servconn->fd = source;
-
- if (source >= 0)
- {
- servconn->connected = TRUE;
-
- /* Someone wants to know we connected. */
- servconn->connect_cb(servconn);
- servconn->inpa = purple_input_add(servconn->fd, PURPLE_INPUT_READ,
- read_cb, data);
- servconn_timeout_renew(servconn);
- }
- else
- {
- purple_debug_error("msn", "Connection error: %s\n", error_message);
- msn_servconn_got_error(servconn, MSN_SERVCONN_ERROR_CONNECT, error_message);
- }
-}
-
-gboolean
-msn_servconn_connect(MsnServConn *servconn, const char *host, int port, gboolean force)
-{
- MsnSession *session;
-
- 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);
-
- g_free(servconn->host);
- servconn->host = g_strdup(host);
-
- if (session->http_method)
- {
- /* HTTP Connection. */
-
- if (!servconn->httpconn->connected || force)
- if (!msn_httpconn_connect(servconn->httpconn, host, port))
- return FALSE;
-
- servconn->connected = TRUE;
- servconn->httpconn->virgin = TRUE;
- servconn_timeout_renew(servconn);
-
- /* Someone wants to know we connected. */
- servconn->connect_cb(servconn);
-
- return TRUE;
- }
-
- servconn->connect_data = purple_proxy_connect(NULL, session->account,
- host, port, connect_cb, servconn);
-
- return (servconn->connect_data != NULL);
-}
-
-void
-msn_servconn_disconnect(MsnServConn *servconn)
-{
- g_return_if_fail(servconn != NULL);
-
- if (servconn->connect_data != NULL)
- {
- purple_proxy_connect_cancel(servconn->connect_data);
- servconn->connect_data = 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)
- {
- purple_input_remove(servconn->inpa);
- servconn->inpa = 0;
- }
-
- if (servconn->timeout_handle > 0)
- {
- purple_timeout_remove(servconn->timeout_handle);
- servconn->timeout_handle = 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 gboolean
-servconn_idle_timeout_cb(MsnServConn *servconn)
-{
- servconn->timeout_handle = 0;
- msn_servconn_disconnect(servconn);
- return FALSE;
-}
-
-static void
-servconn_timeout_renew(MsnServConn *servconn)
-{
- if (servconn->timeout_handle) {
- purple_timeout_remove(servconn->timeout_handle);
- servconn->timeout_handle = 0;
- }
-
- if (servconn->connected && servconn->timeout_sec) {
- servconn->timeout_handle = purple_timeout_add_seconds(
- servconn->timeout_sec, (GSourceFunc)servconn_idle_timeout_cb, servconn);
- }
-}
-
-void
-msn_servconn_set_idle_timeout(MsnServConn *servconn, guint seconds)
-{
- servconn->timeout_sec = seconds;
- if (servconn->connected)
- servconn_timeout_renew(servconn);
-}
-
-static void
-servconn_write_cb(gpointer data, gint source, PurpleInputCondition cond)
-{
- MsnServConn *servconn = data;
- gssize ret;
- int writelen;
-
- writelen = purple_circ_buffer_get_max_read(servconn->tx_buf);
-
- if (writelen == 0) {
- purple_input_remove(servconn->tx_handler);
- servconn->tx_handler = 0;
- 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, NULL);
- return;
- }
-
- purple_circ_buffer_mark_read(servconn->tx_buf, ret);
- servconn_timeout_renew(servconn);
-}
-
-gssize
-msn_servconn_write(MsnServConn *servconn, const char *buf, size_t len)
-{
- gssize ret = 0;
-
- g_return_val_if_fail(servconn != NULL, 0);
-
- if (!servconn->session->http_method)
- {
- if (servconn->tx_handler == 0) {
- 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 >= 0 && (size_t)ret < len) {
- if (servconn->tx_handler == 0)
- servconn->tx_handler = purple_input_add(
- servconn->fd, PURPLE_INPUT_WRITE,
- servconn_write_cb, servconn);
- purple_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, NULL);
- }
-
- servconn_timeout_renew(servconn);
- return ret;
-}
-
-static void
-read_cb(gpointer data, gint source, PurpleInputCondition cond)
-{
- MsnServConn *servconn;
- char buf[MSN_BUF_LEN];
- gssize len;
-
- servconn = data;
-
- if (servconn->type == MSN_SERVCONN_NS)
- servconn->session->account->gc->last_received = time(NULL);
-
- len = read(servconn->fd, buf, sizeof(buf) - 1);
- if (len < 0 && errno == EAGAIN)
- return;
- if (len <= 0) {
- purple_debug_error("msn", "servconn %03d read error, "
- "len: %" G_GSSIZE_FORMAT ", errno: %d, error: %s\n",
- servconn->num, len, errno, g_strerror(errno));
- msn_servconn_got_error(servconn, MSN_SERVCONN_ERROR_READ, NULL);
-
- 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;
-
- servconn = msn_servconn_process_data(servconn);
- if (servconn)
- servconn_timeout_renew(servconn);
-}
-
-MsnServConn *msn_servconn_process_data(MsnServConn *servconn)
-{
- char *cur, *end, *old_rx_buf;
- int cur_len;
-
- end = old_rx_buf = servconn->rx_buf;
-
- servconn->processing = TRUE;
-
- do
- {
- cur = end;
-
- if (servconn->payload_len)
- {
- if (servconn->rx_len < 0
- || servconn->payload_len > (gsize)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);
- servconn = NULL;
- }
-
- g_free(old_rx_buf);
- return servconn;
-}
-
-#if 0
-static int
-create_listener(int port)
-{
- int fd;
- int flags;
- 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)
- {
- purple_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)
- {
- purple_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;
- }
-
- flags = fcntl(fd, F_GETFL);
- fcntl(fd, F_SETFL, flags | O_NONBLOCK);
-#ifndef _WIN32
- fcntl(fd, F_SETFD, FD_CLOEXEC);
-#endif
-
- return fd;
-}
-#endif
diff --git a/libpurple/protocols/msn/servconn.h b/libpurple/protocols/msn/servconn.h
deleted file mode 100644
index b075fd08f2..0000000000
--- a/libpurple/protocols/msn/servconn.h
+++ /dev/null
@@ -1,193 +0,0 @@
-/**
- * @file servconn.h Server connection functions
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-#ifndef MSN_SERVCONN_H
-#define MSN_SERVCONN_H
-
-typedef struct _MsnServConn MsnServConn;
-
-/**
- * Connection error types.
- */
-typedef enum
-{
- MSN_SERVCONN_ERROR_NONE,
- MSN_SERVCONN_ERROR_CONNECT,
- MSN_SERVCONN_ERROR_WRITE,
- MSN_SERVCONN_ERROR_READ
-} MsnServConnError;
-
-/**
- * Connection types.
- */
-typedef enum
-{
- MSN_SERVCONN_NS,
- MSN_SERVCONN_SB
-} MsnServConnType;
-
-#include "internal.h"
-#include "proxy.h"
-
-#include "cmdproc.h"
-#include "httpconn.h"
-#include "session.h"
-
-/**
- * A Connection.
- */
-struct _MsnServConn
-{
- MsnServConnType type; /**< The type of this connection. */
- MsnSession *session; /**< The MSN session of this connection. */
- MsnCmdProc *cmdproc; /**< The command processor of this connection. */
-
- PurpleProxyConnectData *connect_data;
-
- gboolean connected; /**< A flag that states if it's connected. */
- gboolean processing; /**< A flag that states if something is working
- with this connection. */
- gboolean wasted; /**< A flag that states if it should be destroyed. */
-
- char *host; /**< The host this connection is connected or should be
- connected to. */
- int num; /**< A number id of this connection. */
-
- MsnHttpConn *httpconn; /**< The HTTP connection this connection should use. */
-
- int fd; /**< The connection's file descriptor. */
- int inpa; /**< The connection's input handler. */
-
- char *rx_buf; /**< The receive buffer. */
- int rx_len; /**< The receive buffer lenght. */
-
- size_t payload_len; /**< The length of the payload.
- It's only set when we've received a command that
- has a payload. */
-
- PurpleCircBuffer *tx_buf;
- guint tx_handler;
- guint timeout_sec;
- guint timeout_handle;
-
- void (*connect_cb)(MsnServConn *); /**< The callback to call when connecting. */
- void (*disconnect_cb)(MsnServConn *); /**< The callback to call when disconnecting. */
- void (*destroy_cb)(MsnServConn *); /**< The callback to call when destroying. */
-};
-
-/**
- * Creates a new connection object.
- *
- * @param session The session.
- * @param type The type of the connection.
- */
-MsnServConn *msn_servconn_new(MsnSession *session, MsnServConnType type);
-
-/**
- * Destroys a connection object.
- *
- * @param servconn The connection.
- */
-void msn_servconn_destroy(MsnServConn *servconn);
-
-/**
- * Connects to a host.
- *
- * @param servconn The connection.
- * @param host The host.
- * @param port The port.
- * @param force Force this servconn to connect to a new server.
- */
-gboolean msn_servconn_connect(MsnServConn *servconn, const char *host, int port,
- gboolean force);
-
-/**
- * Disconnects.
- *
- * @param servconn The connection.
- */
-void msn_servconn_disconnect(MsnServConn *servconn);
-
-/**
- * Sets the connect callback.
- *
- * @param servconn The servconn.
- * @param connect_cb The connect callback.
- */
-void msn_servconn_set_connect_cb(MsnServConn *servconn,
- void (*connect_cb)(MsnServConn *));
-/**
- * Sets the disconnect callback.
- *
- * @param servconn The servconn.
- * @param disconnect_cb The disconnect callback.
- */
-void msn_servconn_set_disconnect_cb(MsnServConn *servconn,
- void (*disconnect_cb)(MsnServConn *));
-/**
- * Sets the destroy callback.
- *
- * @param servconn The servconn that's being destroyed.
- * @param destroy_cb The destroy callback.
- */
-void msn_servconn_set_destroy_cb(MsnServConn *servconn,
- void (*destroy_cb)(MsnServConn *));
-
-/**
- * Writes a chunck of data to the servconn.
- *
- * @param servconn The servconn.
- * @param buf The data to write.
- * @param size The size of the data.
- */
-gssize msn_servconn_write(MsnServConn *servconn, const char *buf,
- size_t size);
-
-/**
- * Function to call whenever an error related to a switchboard occurs.
- *
- * @param servconn The servconn.
- * @param error The error that happened.
- */
-void msn_servconn_got_error(MsnServConn *servconn, MsnServConnError error,
- const char *reason);
-
-/**
- * Process the data in servconn->rx_buf. This is called after reading
- * data from the socket.
- *
- * @param servconn The servconn.
- *
- * @return @c NULL if servconn was destroyed, 'servconn' otherwise.
- */
-MsnServConn *msn_servconn_process_data(MsnServConn *servconn);
-
-/**
- * Set a idle timeout fot this servconn
- *
- * @param servconn The servconn
- * @param seconds The idle timeout in seconds
- */
-void msn_servconn_set_idle_timeout(MsnServConn *servconn, guint seconds);
-
-#endif /* MSN_SERVCONN_H */
diff --git a/libpurple/protocols/msn/session.c b/libpurple/protocols/msn/session.c
deleted file mode 100644
index 371800ad89..0000000000
--- a/libpurple/protocols/msn/session.c
+++ /dev/null
@@ -1,500 +0,0 @@
-/**
- * @file session.c MSN session functions
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-
-#include "internal.h"
-#include "debug.h"
-
-#include "error.h"
-#include "msnutils.h"
-#include "session.h"
-#include "notification.h"
-#include "oim.h"
-
-MsnSession *
-msn_session_new(PurpleAccount *account)
-{
- MsnSession *session;
-
- g_return_val_if_fail(account != NULL, NULL);
-
- session = g_new0(MsnSession, 1);
-
- session->account = account;
- session->notification = msn_notification_new(session);
- session->userlist = msn_userlist_new(session);
-
- session->user = msn_user_new(session->userlist,
- purple_account_get_username(account), NULL);
- msn_userlist_add_user(session->userlist, session->user);
- session->oim = msn_oim_new(session);
-
- session->protocol_ver = 0;
- session->enable_mpop = TRUE; /* Default only */
-
- session->guid = rand_guid();
-
- return session;
-}
-
-void
-msn_session_destroy(MsnSession *session)
-{
- g_return_if_fail(session != NULL);
-
- session->destroying = TRUE;
-
- while (session->url_datas) {
- purple_util_fetch_url_cancel(session->url_datas->data);
- session->url_datas = g_slist_delete_link(session->url_datas, session->url_datas);
- }
-
- if (session->connected)
- msn_session_disconnect(session);
-
- if (session->soap_cleanup_handle)
- purple_timeout_remove(session->soap_cleanup_handle);
-
- if (session->soap_table != NULL)
- g_hash_table_destroy(session->soap_table);
-
- while (session->slplinks != NULL)
- msn_slplink_unref(session->slplinks->data);
-
- while (session->switches != NULL)
- msn_switchboard_destroy(session->switches->data);
-
- if (session->oim != NULL)
- msn_oim_destroy(session->oim);
-
- if (session->nexus != NULL)
- msn_nexus_destroy(session->nexus);
-
- if (session->user != NULL)
- msn_user_unref(session->user);
-
- if (session->notification != NULL)
- msn_notification_destroy(session->notification);
-
- msn_userlist_destroy(session->userlist);
-
- g_free(session->psm);
- g_free(session->guid);
- g_free(session->abch_cachekey);
-#if 0
- g_free(session->blocked_text);
-#endif
-
- g_free(session->passport_info.sid);
- g_free(session->passport_info.mspauth);
- g_free(session->passport_info.client_ip);
- g_free(session->passport_info.mail_url);
-
- g_free(session);
-}
-
-gboolean
-msn_session_connect(MsnSession *session, const char *host, int port,
- gboolean http_method)
-{
- g_return_val_if_fail(session != NULL, FALSE);
- g_return_val_if_fail(!session->connected, TRUE);
-
- session->connected = TRUE;
- session->http_method = http_method;
-
- if (session->notification == NULL)
- {
- purple_debug_error("msn", "This shouldn't happen\n");
- g_return_val_if_reached(FALSE);
- }
-
- return msn_notification_connect(session->notification, host, port);
-}
-
-void
-msn_session_disconnect(MsnSession *session)
-{
- g_return_if_fail(session != NULL);
-
- if (!session->connected)
- return;
-
- if (session->login_timeout) {
- purple_timeout_remove(session->login_timeout);
- session->login_timeout = 0;
- }
-
- session->connected = FALSE;
-
- while (session->switches != NULL)
- msn_switchboard_close(session->switches->data);
-
- if (session->notification != NULL)
- msn_notification_close(session->notification);
-}
-
-/* TODO: This must go away when conversation is redesigned */
-MsnSwitchBoard *
-msn_session_find_swboard(MsnSession *session, const char *username)
-{
- GList *l;
-
- g_return_val_if_fail(session != NULL, NULL);
- g_return_val_if_fail(username != NULL, NULL);
-
- for (l = session->switches; l != NULL; l = l->next)
- {
- MsnSwitchBoard *swboard;
-
- swboard = l->data;
-
- if ((swboard->im_user != NULL) && !strcmp(username, swboard->im_user))
- return swboard;
- }
-
- return NULL;
-}
-
-static PurpleConversation *
-msn_session_get_conv(MsnSession *session,const char *passport)
-{
- PurpleAccount *account;
- PurpleConversation * conv;
-
- g_return_val_if_fail(session != NULL, NULL);
- account = session->account;
-
- conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM,
- passport, account);
- if(conv == NULL){
- conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, passport);
- }
- return conv;
-}
-
-/* put Message to User Conversation
- *
- * passport - the one want to talk to you
- */
-void
-msn_session_report_user(MsnSession *session,const char *passport,const char *msg,PurpleMessageFlags flags)
-{
- PurpleConversation * conv;
-
- if ((conv = msn_session_get_conv(session,passport)) != NULL){
- purple_conversation_write(conv, NULL, msg, flags, time(NULL));
- }
-}
-
-MsnSwitchBoard *
-msn_session_find_swboard_with_conv(MsnSession *session, PurpleConversation *conv)
-{
- GList *l;
-
- g_return_val_if_fail(session != NULL, NULL);
- g_return_val_if_fail(conv != NULL, NULL);
-
- for (l = session->switches; l != NULL; l = l->next)
- {
- MsnSwitchBoard *swboard;
-
- swboard = l->data;
-
- if (swboard->conv == conv)
- return swboard;
- }
-
- return NULL;
-}
-
-MsnSwitchBoard *
-msn_session_find_swboard_with_id(const MsnSession *session, int chat_id)
-{
- GList *l;
-
- g_return_val_if_fail(session != NULL, NULL);
- g_return_val_if_fail(chat_id >= 0, NULL);
-
- for (l = session->switches; l != NULL; l = l->next)
- {
- MsnSwitchBoard *swboard;
-
- swboard = l->data;
-
- if (swboard->chat_id == chat_id)
- return swboard;
- }
-
- return NULL;
-}
-
-MsnSwitchBoard *
-msn_session_get_swboard(MsnSession *session, const char *username,
- MsnSBFlag flag)
-{
- MsnSwitchBoard *swboard;
-
- g_return_val_if_fail(session != NULL, NULL);
-
- swboard = msn_session_find_swboard(session, username);
-
- if (swboard == NULL)
- {
- swboard = msn_switchboard_new(session);
- swboard->im_user = g_strdup(username);
- if (msn_switchboard_request(swboard))
- msn_switchboard_request_add_user(swboard, username);
- else
- return NULL;
- }
-
- swboard->flag |= flag;
-
- return swboard;
-}
-
-static gboolean
-msn_login_timeout_cb(gpointer data)
-{
- MsnSession *session = data;
- /* This forces the login process to finish, even though we haven't heard
- a response for our FQY requests yet. We'll at least end up online to the
- people we've already added. The rest will follow later. */
- msn_session_finish_login(session);
- session->login_timeout = 0;
- return FALSE;
-}
-
-void
-msn_session_activate_login_timeout(MsnSession *session)
-{
- if (!session->logged_in && session->connected) {
- if (session->login_timeout)
- purple_timeout_remove(session->login_timeout);
- session->login_timeout =
- purple_timeout_add_seconds(MSN_LOGIN_FQY_TIMEOUT,
- msn_login_timeout_cb, session);
- }
-}
-
-static void
-msn_session_sync_users(MsnSession *session)
-{
- PurpleConnection *gc = purple_account_get_connection(session->account);
- GList *to_remove = NULL;
- GSList *buddies;
-
- g_return_if_fail(gc != NULL);
-
- /* The core used to use msn_add_buddy to add all buddies before
- * being logged in. This no longer happens, so we manually iterate
- * over the whole buddy list to identify sync issues.
- */
- for (buddies = purple_find_buddies(session->account, NULL); buddies;
- buddies = g_slist_delete_link(buddies, buddies)) {
- PurpleBuddy *buddy = buddies->data;
- const gchar *buddy_name = purple_buddy_get_name(buddy);
- const gchar *group_name = purple_group_get_name(purple_buddy_get_group(buddy));
- MsnUser *remote_user;
- gboolean found = FALSE;
-
- remote_user = msn_userlist_find_user(session->userlist, buddy_name);
- if (remote_user && remote_user->list_op & MSN_LIST_FL_OP) {
- GList *l;
- for (l = remote_user->group_ids; l; l = l->next) {
- const char *name = msn_userlist_find_group_name(remote_user->userlist, l->data);
- if (name && !g_ascii_strcasecmp(group_name, name)) {
- found = TRUE;
- break;
- }
- }
-
- /* We don't care if they're in a different group, as long as they're on the
- * list somewhere. If we check for the group, we cause pain, agony and
- * suffering for people who decide to re-arrange their buddy list elsewhere.
- */
- if (!found) {
- if ((remote_user == NULL) || !(remote_user->list_op & MSN_LIST_FL_OP)) {
- /* The user is not on the server list */
- msn_error_sync_issue(session, buddy_name, group_name);
- } else {
- /* The user is not in that group on the server list */
- to_remove = g_list_prepend(to_remove, buddy);
- }
- }
- }
- }
-
- if (to_remove != NULL) {
- g_list_foreach(to_remove, (GFunc)purple_blist_remove_buddy, NULL);
- g_list_free(to_remove);
- }
-}
-
-void
-msn_session_set_error(MsnSession *session, MsnErrorType error,
- const char *info)
-{
- PurpleConnection *gc;
- PurpleConnectionError reason;
- char *msg;
-
- if (session->destroying)
- return;
-
- gc = purple_account_get_connection(session->account);
-
- switch (error)
- {
- case MSN_ERROR_SERVCONN:
- reason = PURPLE_CONNECTION_ERROR_NETWORK_ERROR;
- msg = g_strdup(info);
- break;
- case MSN_ERROR_UNSUPPORTED_PROTOCOL:
- reason = PURPLE_CONNECTION_ERROR_NETWORK_ERROR;
- msg = g_strdup(_("Our protocol is not supported by the "
- "server"));
- break;
- case MSN_ERROR_HTTP_MALFORMED:
- reason = PURPLE_CONNECTION_ERROR_NETWORK_ERROR;
- msg = g_strdup(_("Error parsing HTTP"));
- break;
- case MSN_ERROR_SIGN_OTHER:
- reason = PURPLE_CONNECTION_ERROR_NAME_IN_USE;
- msg = g_strdup(_("You have signed on from another location"));
- if (!purple_account_get_remember_password(session->account))
- purple_account_set_password(session->account, NULL);
- break;
- case MSN_ERROR_SERV_UNAVAILABLE:
- reason = PURPLE_CONNECTION_ERROR_NETWORK_ERROR;
- msg = g_strdup(_("The MSN servers are temporarily "
- "unavailable. Please wait and try "
- "again."));
- break;
- case MSN_ERROR_SERV_DOWN:
- reason = PURPLE_CONNECTION_ERROR_NETWORK_ERROR;
- msg = g_strdup(_("The MSN servers are going down "
- "temporarily"));
- break;
- case MSN_ERROR_AUTH:
- reason = PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED;
- msg = g_strdup_printf(_("Unable to authenticate: %s"),
- (info == NULL ) ?
- _("Unknown error") : info);
- /* Clear the password if it isn't being saved */
- if (!purple_account_get_remember_password(session->account))
- purple_account_set_password(session->account, NULL);
- break;
- case MSN_ERROR_BAD_BLIST:
- reason = PURPLE_CONNECTION_ERROR_NETWORK_ERROR;
- msg = g_strdup_printf(_("Your MSN buddy list is temporarily "
- "unavailable: %s"),
- (info == NULL) ? _("Unknown error") : info);
- break;
- default:
- reason = PURPLE_CONNECTION_ERROR_NETWORK_ERROR;
- msg = g_strdup(_("Unknown error"));
- break;
- }
-
- msn_session_disconnect(session);
-
- purple_connection_error_reason(gc, reason, msg);
-
- g_free(msg);
-}
-
-static const char *
-get_login_step_text(MsnSession *session)
-{
- const char *steps_text[] = {
- _("Connecting"),
- _("Handshaking"),
- _("Transferring"),
- _("Handshaking"),
- _("Starting authentication"),
- _("Getting cookie"),
- _("Authenticating"),
- _("Sending cookie"),
- _("Retrieving buddy list")
- };
-
- return steps_text[session->login_step];
-}
-
-void
-msn_session_set_login_step(MsnSession *session, MsnLoginStep step)
-{
- PurpleConnection *gc;
-
- /* Prevent the connection progress going backwards, eg. if we get
- * transferred several times during login */
- if (session->login_step >= step)
- return;
-
- /* If we're already logged in, we're probably here because of a
- * mid-session XFR from the notification server, so we don't want to
- * popup the connection progress dialog */
- if (session->logged_in)
- return;
-
- gc = session->account->gc;
-
- session->login_step = step;
-
- purple_connection_update_progress(gc, get_login_step_text(session), step,
- MSN_LOGIN_STEPS);
-}
-
-void
-msn_session_finish_login(MsnSession *session)
-{
- PurpleAccount *account;
- PurpleConnection *gc;
- PurpleStoredImage *img;
-
- if (!session->logged_in) {
- account = session->account;
- gc = purple_account_get_connection(account);
-
- img = purple_buddy_icons_find_account_icon(session->account);
- /* TODO: Do we really want to call this if img is NULL? */
- msn_user_set_buddy_icon(session->user, img);
- if (img != NULL)
- purple_imgstore_unref(img);
-
- session->logged_in = TRUE;
- purple_connection_set_state(gc, PURPLE_CONNECTED);
-
- /* Sync users */
- msn_session_sync_users(session);
- }
-
- /* TODO: Send this when updating status instead? */
- msn_notification_send_uux_endpointdata(session);
- msn_notification_send_uux_private_endpointdata(session);
-
- msn_change_status(session);
-}
-
diff --git a/libpurple/protocols/msn/session.h b/libpurple/protocols/msn/session.h
deleted file mode 100644
index e94b3b73ac..0000000000
--- a/libpurple/protocols/msn/session.h
+++ /dev/null
@@ -1,245 +0,0 @@
-/**
- * @file session.h MSN session functions
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-#ifndef MSN_SESSION_H
-#define MSN_SESSION_H
-
-typedef struct _MsnSession MsnSession;
-
-/**
- * Types of errors.
- */
-typedef enum
-{
- MSN_ERROR_SERVCONN,
- MSN_ERROR_UNSUPPORTED_PROTOCOL,
- MSN_ERROR_HTTP_MALFORMED,
- MSN_ERROR_AUTH,
- MSN_ERROR_BAD_BLIST,
- MSN_ERROR_SIGN_OTHER,
- MSN_ERROR_SERV_DOWN,
- MSN_ERROR_SERV_UNAVAILABLE
-} MsnErrorType;
-
-/**
- * Login steps.
- */
-typedef enum
-{
- MSN_LOGIN_STEP_START,
- MSN_LOGIN_STEP_HANDSHAKE,
- MSN_LOGIN_STEP_TRANSFER,
- MSN_LOGIN_STEP_HANDSHAKE2,
- MSN_LOGIN_STEP_AUTH_START,
- MSN_LOGIN_STEP_GET_COOKIE,
- MSN_LOGIN_STEP_AUTH_END,
- MSN_LOGIN_STEP_SYN,
- MSN_LOGIN_STEP_END
-} MsnLoginStep;
-
-#define MSN_LOGIN_STEPS MSN_LOGIN_STEP_END
-
-#define MSN_LOGIN_FQY_TIMEOUT 30
-
-#define MSN_LOGIN_FQY_TIMEOUT 30
-
-#include "nexus.h"
-#include "notification.h"
-#include "oim.h"
-#include "switchboard.h"
-#include "user.h"
-#include "userlist.h"
-
-struct _MsnSession
-{
- PurpleAccount *account;
- MsnUser *user;
-
- guint protocol_ver;
-
- MsnLoginStep login_step; /**< The current step in the login process. */
-
- gboolean connected:1;
- gboolean logged_in:1; /**< A temporal flag to ignore local buddy list adds. */
- gboolean destroying:1; /**< A flag that states if the session is being destroyed. */
- gboolean http_method:1;
- gboolean enable_mpop:1; /**< Use Multiple Points of Presence? */
- int adl_fqy; /**< A count of ADL/FQY so status is only changed once. */
- guint login_timeout; /**< Timeout to force status change if ADL/FQY fail. */
-
- MsnNotification *notification;
- MsnNexus *nexus;
- MsnOim *oim;
- MsnUserList *userlist;
- char *abch_cachekey;
-
- int servconns_count; /**< The count of server connections. */
- GList *switches; /**< The list of all the switchboards. */
- GList *slplinks; /**< The list of all the slplinks. */
-
- /*psm info*/
- char *psm;
-
-#if 0
- char *blocked_text;
-#endif
-
- struct
- {
- char *sid;
- char *mspauth;
- unsigned long sl;
- char *client_ip;
- int client_port;
- char *mail_url;
- gulong mail_timestamp;
- gboolean email_enabled;
- } passport_info;
-
- GHashTable *soap_table;
- guint soap_cleanup_handle;
- char *guid;
-
- GSList *url_datas; /**< PurpleUtilFetchUrlData to be cancelled on exit */
-};
-
-/**
- * Creates an MSN session.
- *
- * @param account The account.
- *
- * @return The new MSN session.
- */
-MsnSession *msn_session_new(PurpleAccount *account);
-
-/**
- * Destroys an MSN session.
- *
- * @param session The MSN session to destroy.
- */
-void msn_session_destroy(MsnSession *session);
-
-/**
- * Connects to and initiates an MSN session.
- *
- * @param session The MSN session.
- * @param host The dispatch server host.
- * @param port The dispatch server port.
- * @param http_method Whether to use or not http_method.
- *
- * @return @c TRUE on success, @c FALSE on failure.
- */
-gboolean msn_session_connect(MsnSession *session,
- const char *host, int port,
- gboolean http_method);
-
-/**
- * Disconnects from an MSN session.
- *
- * @param session The MSN session.
- */
-void msn_session_disconnect(MsnSession *session);
-
- /**
- * Finds a switchboard with the given username.
- *
- * @param session The MSN session.
- * @param username The username to search for.
- *
- * @return The switchboard, if found.
- */
-MsnSwitchBoard *msn_session_find_swboard(MsnSession *session,
- const char *username);
-
- /**
- * Finds a switchboard with the given conversation.
- *
- * @param session The MSN session.
- * @param conv The conversation to search for.
- *
- * @return The switchboard, if found.
- */
-MsnSwitchBoard *msn_session_find_swboard_with_conv(MsnSession *session,
- PurpleConversation *conv);
-/**
- * Finds a switchboard with the given chat ID.
- *
- * @param session The MSN session.
- * @param chat_id The chat ID to search for.
- *
- * @return The switchboard, if found.
- */
-MsnSwitchBoard *msn_session_find_swboard_with_id(const MsnSession *session,
- int chat_id);
-
-/**
- * Returns a switchboard to communicate with certain username.
- *
- * @param session The MSN session.
- * @param username The username to search for.
- * @param flag The flag of the switchboard
- *
- * @return The switchboard.
- */
-MsnSwitchBoard *msn_session_get_swboard(MsnSession *session,
- const char *username, MsnSBFlag flag);
-
-/**
- * Sets an error for the MSN session.
- *
- * @param session The MSN session.
- * @param error The error.
- * @param info Extra information.
- */
-void msn_session_set_error(MsnSession *session, MsnErrorType error,
- const char *info);
-
-/**
- * Starts a timeout to initiate finishing login. Sometimes the server ignores
- * our FQY requests, so this forces ourselves online eventually.
- *
- * @param session The MSN session.
- */
-void
-msn_session_activate_login_timeout(MsnSession *session);
-
-/**
- * Sets the current step in the login process.
- *
- * @param session The MSN session.
- * @param step The current step.
- */
-void msn_session_set_login_step(MsnSession *session, MsnLoginStep step);
-
-/**
- * Finish the login proccess.
- *
- * @param session The MSN session.
- */
-void msn_session_finish_login(MsnSession *session);
-
-/*post message to User*/
-void msn_session_report_user(MsnSession *session,const char *passport,
- const char *msg,PurpleMessageFlags flags);
-
-#endif /* MSN_SESSION_H */
diff --git a/libpurple/protocols/msn/slp.c b/libpurple/protocols/msn/slp.c
deleted file mode 100644
index 85c78b260a..0000000000
--- a/libpurple/protocols/msn/slp.c
+++ /dev/null
@@ -1,396 +0,0 @@
-/**
- * @file msnslp.c MSNSLP support
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-
-#include "internal.h"
-#include "debug.h"
-
-#include "slp.h"
-#include "slpcall.h"
-#include "slpmsg.h"
-#include "msnutils.h"
-
-#include "object.h"
-#include "user.h"
-#include "sbconn.h"
-#include "directconn.h"
-#include "p2p.h"
-#include "xfer.h"
-
-/* seconds to delay between sending buddy icon requests to the server. */
-#define BUDDY_ICON_DELAY 20
-
-typedef struct {
- MsnSession *session;
- const char *remote_user;
- const char *sha1;
-} MsnFetchUserDisplayData;
-
-/**************************************************************************
- * SLP Control
- **************************************************************************/
-
-void
-msn_slp_send_ok(MsnSlpCall *slpcall, const char *branch,
- const char *type, const char *content)
-{
- MsnSlpLink *slplink;
- MsnSlpMessage *slpmsg;
-
- slplink = slpcall->slplink;
-
- /* 200 OK */
- slpmsg = msn_slpmsg_sip_new(slpcall, 1,
- "MSNSLP/1.0 200 OK",
- branch, type, content);
-
- slpmsg->info = "SLP 200 OK";
- slpmsg->text_body = TRUE;
-
- msn_slplink_queue_slpmsg(slplink, slpmsg);
-}
-
-void
-msn_slp_send_decline(MsnSlpCall *slpcall, const char *branch,
- const char *type, const char *content)
-{
- MsnSlpLink *slplink;
- MsnSlpMessage *slpmsg;
-
- slplink = slpcall->slplink;
-
- /* 603 Decline */
- slpmsg = msn_slpmsg_sip_new(slpcall, 1,
- "MSNSLP/1.0 603 Decline",
- branch, type, content);
-
- slpmsg->info = "SLP 603 Decline";
- slpmsg->text_body = TRUE;
-
- msn_slplink_queue_slpmsg(slplink, slpmsg);
-}
-
-/**************************************************************************
- * Msg Callbacks
- **************************************************************************/
-
-/*
- * Called on a timeout from end_user_display(). Frees a buddy icon window slow and dequeues the next
- * buddy icon request if there is one.
- */
-static gboolean
-msn_release_buddy_icon_request_timeout(gpointer data)
-{
- MsnUserList *userlist = (MsnUserList *)data;
-
- /* Free one window slot */
- userlist->buddy_icon_window++;
-
- /* Clear the tag for our former request timer */
- userlist->buddy_icon_request_timer = 0;
-
- msn_release_buddy_icon_request(userlist);
-
- return FALSE;
-}
-
-static void
-got_user_display(MsnSlpCall *slpcall,
- const guchar *data, gsize size)
-{
- const char *info;
- PurpleAccount *account;
-
- g_return_if_fail(slpcall != NULL);
-
- info = slpcall->data_info;
- if (purple_debug_is_verbose())
- purple_debug_info("msn", "Got User Display: %s\n", slpcall->slplink->remote_user);
-
- account = slpcall->slplink->session->account;
-
- purple_buddy_icons_set_for_user(account, slpcall->slplink->remote_user,
- g_memdup(data, size), size, info);
-}
-
-static void
-end_user_display(MsnSlpCall *slpcall, MsnSession *session)
-{
- MsnUserList *userlist;
-
- g_return_if_fail(session != NULL);
-
- if (purple_debug_is_verbose())
- purple_debug_info("msn", "End User Display\n");
-
- userlist = session->userlist;
-
- /* If the session is being destroyed we better stop doing anything. */
- if (session->destroying)
- return;
-
- /* Delay before freeing a buddy icon window slot and requesting the next icon, if appropriate.
- * If we don't delay, we'll rapidly hit the MSN equivalent of AIM's rate limiting; the server will
- * send us an error 800 like so:
- *
- * C: NS 000: XFR 21 SB
- * S: NS 000: 800 21
- */
- if (userlist->buddy_icon_request_timer) {
- /* Free the window slot used by this previous request */
- userlist->buddy_icon_window++;
-
- /* Clear our pending timeout */
- purple_timeout_remove(userlist->buddy_icon_request_timer);
- }
-
- /* Wait BUDDY_ICON_DELAY s before freeing our window slot and requesting the next icon. */
- userlist->buddy_icon_request_timer = purple_timeout_add_seconds(BUDDY_ICON_DELAY,
- msn_release_buddy_icon_request_timeout, userlist);
-}
-
-static void
-fetched_user_display(PurpleUtilFetchUrlData *url_data, gpointer user_data,
- const gchar *url_text, gsize len, const gchar *error_message)
-{
- MsnFetchUserDisplayData *data = user_data;
- MsnSession *session = data->session;
-
- session->url_datas = g_slist_remove(session->url_datas, url_data);
-
- if (url_text) {
- purple_buddy_icons_set_for_user(session->account, data->remote_user,
- g_memdup(url_text, len), len,
- data->sha1);
- }
-
- end_user_display(NULL, session);
-
- g_free(user_data);
-}
-
-static void
-request_own_user_display(MsnUser *user)
-{
- PurpleAccount *account;
- MsnSession *session;
- MsnObject *my_obj = NULL;
- gconstpointer data = NULL;
- const char *info = NULL;
- size_t len = 0;
-
- if (purple_debug_is_verbose())
- purple_debug_info("msn", "Requesting our own user display\n");
-
- session = user->userlist->session;
- account = session->account;
- my_obj = msn_user_get_object(user);
-
- if (my_obj != NULL) {
- PurpleStoredImage *img = msn_object_get_image(my_obj);
- data = purple_imgstore_get_data(img);
- len = purple_imgstore_get_size(img);
- info = msn_object_get_sha1(my_obj);
- }
-
- purple_buddy_icons_set_for_user(account, user->passport, g_memdup(data, len), len, info);
-
- /* Free one window slot */
- session->userlist->buddy_icon_window++;
-
- if (purple_debug_is_verbose())
- purple_debug_info("msn", "msn_request_user_display(): buddy_icon_window++ yields =%d\n",
- session->userlist->buddy_icon_window);
-
- msn_release_buddy_icon_request(session->userlist);
-}
-
-void
-msn_request_user_display(MsnUser *user)
-{
- PurpleAccount *account;
- MsnSession *session;
- MsnSlpLink *slplink;
- MsnObject *obj;
- const char *info;
-
- session = user->userlist->session;
- account = session->account;
-
- slplink = msn_session_get_slplink(session, user->passport);
-
- obj = msn_user_get_object(user);
-
- info = msn_object_get_sha1(obj);
-
- if (g_ascii_strcasecmp(user->passport,
- purple_account_get_username(account)))
- {
- const char *url = msn_object_get_url1(obj);
- if (url) {
- MsnFetchUserDisplayData *data = g_new0(MsnFetchUserDisplayData, 1);
- PurpleUtilFetchUrlData *url_data;
- data->session = session;
- data->remote_user = user->passport;
- data->sha1 = info;
- url_data = purple_util_fetch_url_len(url, TRUE, NULL, TRUE, 200*1024,
- fetched_user_display, data);
- session->url_datas = g_slist_prepend(session->url_datas, url_data);
- } else {
- msn_slplink_request_object(slplink, info, got_user_display,
- end_user_display, obj);
- }
- }
- else
- request_own_user_display(user);
-}
-
-static void
-send_file_cb(MsnSlpCall *slpcall)
-{
- MsnSlpMessage *slpmsg;
- PurpleXfer *xfer;
-
- xfer = (PurpleXfer *)slpcall->xfer;
- if (purple_xfer_get_status(xfer) >= PURPLE_XFER_STATUS_STARTED)
- return;
-
- purple_xfer_ref(xfer);
- purple_xfer_start(xfer, -1, NULL, 0);
- if (purple_xfer_get_status(xfer) != PURPLE_XFER_STATUS_STARTED) {
- purple_xfer_unref(xfer);
- return;
- }
- purple_xfer_unref(xfer);
-
- slpmsg = msn_slpmsg_file_new(slpcall, purple_xfer_get_size(xfer));
-
- msn_slplink_send_slpmsg(slpcall->slplink, slpmsg);
-}
-
-static gchar *
-gen_context(PurpleXfer *xfer, const char *file_name, const char *file_path)
-{
- gsize size = 0;
- MsnFileContext context;
- gchar *u8 = NULL;
- gchar *ret;
- gunichar2 *uni = NULL;
- glong currentChar = 0;
- glong len = 0;
- const char *preview;
- gsize preview_len;
-
- size = purple_xfer_get_size(xfer);
-
- purple_xfer_prepare_thumbnail(xfer, "png");
-
- if (!file_name) {
- gchar *basename = g_path_get_basename(file_path);
- u8 = purple_utf8_try_convert(basename);
- g_free(basename);
- file_name = u8;
- }
-
- uni = g_utf8_to_utf16(file_name, -1, NULL, &len, NULL);
-
- if (u8) {
- g_free(u8);
- file_name = NULL;
- u8 = NULL;
- }
-
- preview = purple_xfer_get_thumbnail(xfer, &preview_len);
-
- context.length = MSN_FILE_CONTEXT_SIZE;
- context.version = 2; /* V.3 contains additional unnecessary data */
- context.file_size = size;
- if (preview)
- context.type = 0;
- else
- context.type = 1;
-
- len = MIN(len, MAX_FILE_NAME_LEN);
- for (currentChar = 0; currentChar < len; currentChar++) {
- context.file_name[currentChar] = GUINT16_TO_LE(uni[currentChar]);
- }
- memset(&context.file_name[currentChar], 0x00, (MAX_FILE_NAME_LEN - currentChar) * 2);
-
- memset(&context.unknown1, 0, sizeof(context.unknown1));
- context.unknown2 = 0xffffffff;
-
- /* Mind the cast, as in, don't free it after! */
- context.preview = (char *)preview;
- context.preview_len = preview_len;
-
- u8 = msn_file_context_to_wire(&context);
- ret = purple_base64_encode((const guchar *)u8, MSN_FILE_CONTEXT_SIZE + preview_len);
-
- g_free(uni);
- g_free(u8);
-
- return ret;
-}
-
-void
-msn_request_ft(PurpleXfer *xfer)
-{
- MsnSlpCall *slpcall;
- MsnSlpLink *slplink;
- char *context;
- const char *fn;
- const char *fp;
-
- fn = purple_xfer_get_filename(xfer);
- fp = purple_xfer_get_local_filename(xfer);
-
- slplink = xfer->data;
-
- g_return_if_fail(slplink != NULL);
- g_return_if_fail(fp != NULL);
-
- slpcall = msn_slpcall_new(slplink);
- msn_slpcall_init(slpcall, MSN_SLPCALL_DC);
-
- slpcall->session_init_cb = send_file_cb;
- slpcall->end_cb = msn_xfer_end_cb;
- slpcall->cb = msn_xfer_completed_cb;
- slpcall->xfer = xfer;
- purple_xfer_ref(slpcall->xfer);
-
- slpcall->pending = TRUE;
-
- purple_xfer_set_cancel_send_fnc(xfer, msn_xfer_cancel);
- purple_xfer_set_read_fnc(xfer, msn_xfer_read);
- purple_xfer_set_write_fnc(xfer, msn_xfer_write);
-
- xfer->data = slpcall;
-
- context = gen_context(xfer, fn, fp);
-
- msn_slpcall_invite(slpcall, MSN_FT_GUID, P2P_APPID_FILE, context);
- msn_slplink_unref(slplink);
-
- g_free(context);
-}
-
diff --git a/libpurple/protocols/msn/slp.h b/libpurple/protocols/msn/slp.h
deleted file mode 100644
index 0be19f0358..0000000000
--- a/libpurple/protocols/msn/slp.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * @file slp.h MSNSLP support
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-#ifndef MSN_SLP_H
-#define MSN_SLP_H
-
-#include "internal.h"
-#include "ft.h"
-
-#include "session.h"
-#include "slpcall.h"
-#include "slplink.h"
-#include "user.h"
-
-void
-msn_slp_send_ok(MsnSlpCall *slpcall, const char *branch,
- const char *type, const char *content);
-
-void
-msn_slp_send_decline(MsnSlpCall *slpcall, const char *branch,
- const char *type, const char *content);
-
-
-void send_bye(MsnSlpCall *slpcall, const char *type);
-
-
-void msn_request_user_display(MsnUser *user);
-
-void msn_request_ft(PurpleXfer *xfer);
-
-#endif /* MSN_SLP_H */
diff --git a/libpurple/protocols/msn/slpcall.c b/libpurple/protocols/msn/slpcall.c
deleted file mode 100644
index 2f06124921..0000000000
--- a/libpurple/protocols/msn/slpcall.c
+++ /dev/null
@@ -1,1157 +0,0 @@
-/**
- * @file slpcall.c SLP Call Functions
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-
-#include "internal.h"
-#include "debug.h"
-#include "smiley.h"
-
-#include "msnutils.h"
-#include "slpcall.h"
-
-#include "slp.h"
-#include "p2p.h"
-#include "xfer.h"
-
-/**************************************************************************
- * Main
- **************************************************************************/
-
-static gboolean
-msn_slpcall_timeout(gpointer data)
-{
- MsnSlpCall *slpcall;
-
- slpcall = data;
-
- if (purple_debug_is_verbose())
- purple_debug_info("msn", "slpcall_timeout: slpcall(%p)\n", slpcall);
-
- if (!slpcall->pending && !slpcall->progress)
- {
- msn_slpcall_destroy(slpcall);
- return TRUE;
- }
-
- slpcall->progress = FALSE;
-
- return TRUE;
-}
-
-MsnSlpCall *
-msn_slpcall_new(MsnSlpLink *slplink)
-{
- MsnSlpCall *slpcall;
-
- g_return_val_if_fail(slplink != NULL, NULL);
-
- slpcall = g_new0(MsnSlpCall, 1);
-
- if (purple_debug_is_verbose())
- purple_debug_info("msn", "slpcall_new: slpcall(%p)\n", slpcall);
-
- slpcall->slplink = slplink;
-
- msn_slplink_add_slpcall(slplink, slpcall);
-
- slpcall->timer = purple_timeout_add_seconds(MSN_SLPCALL_TIMEOUT, msn_slpcall_timeout, slpcall);
-
- return slpcall;
-}
-
-void
-msn_slpcall_destroy(MsnSlpCall *slpcall)
-{
- GList *e;
-
- if (purple_debug_is_verbose())
- purple_debug_info("msn", "slpcall_destroy: slpcall(%p)\n", slpcall);
-
- g_return_if_fail(slpcall != NULL);
-
- if (slpcall->timer)
- purple_timeout_remove(slpcall->timer);
-
- for (e = slpcall->slplink->slp_msgs; e != NULL; )
- {
- MsnSlpMessage *slpmsg = e->data;
- e = e->next;
-
- if (purple_debug_is_verbose())
- purple_debug_info("msn", "slpcall_destroy: trying slpmsg(%p)\n",
- slpmsg);
-
- if (slpmsg->slpcall == slpcall)
- {
- msn_slpmsg_destroy(slpmsg);
- }
- }
-
- if (slpcall->end_cb != NULL)
- slpcall->end_cb(slpcall, slpcall->slplink->session);
-
- if (slpcall->xfer != NULL) {
- if (purple_xfer_get_type(slpcall->xfer) == PURPLE_XFER_RECEIVE)
- g_byte_array_free(slpcall->u.incoming_data, TRUE);
- slpcall->xfer->data = NULL;
- purple_xfer_unref(slpcall->xfer);
- }
-
-
- msn_slplink_remove_slpcall(slpcall->slplink, slpcall);
-
- g_free(slpcall->id);
- g_free(slpcall->branch);
- g_free(slpcall->data_info);
-
- g_free(slpcall);
-}
-
-void
-msn_slpcall_init(MsnSlpCall *slpcall, MsnSlpCallType type)
-{
- slpcall->session_id = rand() % 0xFFFFFF00 + 4;
- slpcall->id = rand_guid();
- slpcall->type = type;
-}
-
-void
-msn_slpcall_session_init(MsnSlpCall *slpcall)
-{
- if (slpcall->session_init_cb)
- slpcall->session_init_cb(slpcall);
-
- slpcall->started = TRUE;
-}
-
-void
-msn_slpcall_invite(MsnSlpCall *slpcall, const char *euf_guid,
- MsnP2PAppId app_id, const char *context)
-{
- MsnSlpLink *slplink;
- MsnSlpMessage *slpmsg;
- char *header;
- char *content;
-
- g_return_if_fail(slpcall != NULL);
- g_return_if_fail(context != NULL);
-
- slplink = slpcall->slplink;
-
- slpcall->branch = rand_guid();
-
- content = g_strdup_printf(
- "EUF-GUID: {%s}\r\n"
- "SessionID: %lu\r\n"
- "AppID: %d\r\n"
- "Context: %s\r\n\r\n",
- euf_guid,
- slpcall->session_id,
- app_id,
- context);
-
- header = g_strdup_printf("INVITE MSNMSGR:%s MSNSLP/1.0",
- slplink->remote_user);
-
- slpmsg = msn_slpmsg_sip_new(slpcall, 0, header, slpcall->branch,
- "application/x-msnmsgr-sessionreqbody", content);
-
- slpmsg->info = "SLP INVITE";
- slpmsg->text_body = TRUE;
-
- msn_slplink_send_slpmsg(slplink, slpmsg);
-
- g_free(header);
- g_free(content);
-}
-
-void
-msn_slpcall_close(MsnSlpCall *slpcall)
-{
- g_return_if_fail(slpcall != NULL);
- g_return_if_fail(slpcall->slplink != NULL);
-
- send_bye(slpcall, "application/x-msnmsgr-sessionclosebody");
- msn_slplink_send_queued_slpmsgs(slpcall->slplink);
- msn_slpcall_destroy(slpcall);
-}
-
-/*****************************************************************************
- * Parse received SLP messages
- ****************************************************************************/
-
-/**************************************************************************
- *** Util
- **************************************************************************/
-
-static char *
-get_token(const char *str, const char *start, const char *end)
-{
- const char *c, *c2;
-
- if ((c = strstr(str, start)) == NULL)
- return NULL;
-
- c += strlen(start);
-
- if (end != NULL)
- {
- if ((c2 = strstr(c, end)) == NULL)
- return NULL;
-
- return g_strndup(c, c2 - c);
- }
- else
- {
- /* This has to be changed */
- return g_strdup(c);
- }
-
-}
-
-/* XXX: this could be improved if we tracked custom smileys
- * per-protocol, per-account, per-session or (ideally) per-conversation
- */
-static PurpleStoredImage *
-find_valid_emoticon(PurpleAccount *account, const char *path)
-{
- GList *smileys;
-
- if (!purple_account_get_bool(account, "custom_smileys", TRUE))
- return NULL;
-
- smileys = purple_smileys_get_all();
-
- for (; smileys; smileys = g_list_delete_link(smileys, smileys)) {
- PurpleSmiley *smiley;
- PurpleStoredImage *img;
-
- smiley = smileys->data;
- img = purple_smiley_get_stored_image(smiley);
-
- if (purple_strequal(path, purple_imgstore_get_filename(img))) {
- g_list_free(smileys);
- return img;
- }
-
- purple_imgstore_unref(img);
- }
-
- purple_debug_error("msn", "Received illegal request for file %s\n", path);
- return NULL;
-}
-
-static char *
-parse_dc_nonce(const char *content, MsnDirectConnNonceType *ntype)
-{
- char *nonce;
-
- *ntype = DC_NONCE_UNKNOWN;
-
- nonce = get_token(content, "Hashed-Nonce: {", "}\r\n");
- if (nonce) {
- *ntype = DC_NONCE_SHA1;
- } else {
- guint32 n1, n6;
- guint16 n2, n3, n4, n5;
- nonce = get_token(content, "Nonce: {", "}\r\n");
- if (nonce
- && sscanf(nonce, "%08x-%04hx-%04hx-%04hx-%04hx%08x",
- &n1, &n2, &n3, &n4, &n5, &n6) == 6) {
- *ntype = DC_NONCE_PLAIN;
- g_free(nonce);
- nonce = g_malloc(16);
- *(guint32 *)(nonce + 0) = GUINT32_TO_LE(n1);
- *(guint16 *)(nonce + 4) = GUINT16_TO_LE(n2);
- *(guint16 *)(nonce + 6) = GUINT16_TO_LE(n3);
- *(guint16 *)(nonce + 8) = GUINT16_TO_BE(n4);
- *(guint16 *)(nonce + 10) = GUINT16_TO_BE(n5);
- *(guint32 *)(nonce + 12) = GUINT32_TO_BE(n6);
- } else {
- /* Invalid nonce, so ignore request */
- g_free(nonce);
- nonce = NULL;
- }
- }
-
- return nonce;
-}
-
-static void
-msn_slp_process_transresp(MsnSlpCall *slpcall, const char *content)
-{
- /* A direct connection negotiation response */
- char *bridge;
- char *nonce;
- char *listening;
- MsnDirectConn *dc = slpcall->slplink->dc;
- MsnDirectConnNonceType ntype;
-
- purple_debug_info("msn", "process_transresp\n");
-
- /* Direct connections are disabled. */
- if (!purple_account_get_bool(slpcall->slplink->session->account, "direct_connect", TRUE))
- return;
-
- g_return_if_fail(dc != NULL);
- g_return_if_fail(dc->state == DC_STATE_CLOSED);
-
- bridge = get_token(content, "Bridge: ", "\r\n");
- nonce = parse_dc_nonce(content, &ntype);
- listening = get_token(content, "Listening: ", "\r\n");
- if (listening && bridge && !strcmp(bridge, "TCPv1")) {
- /* Ok, the client supports direct TCP connection */
-
- /* We always need this. */
- if (ntype == DC_NONCE_SHA1) {
- strncpy(dc->remote_nonce, nonce, 36);
- dc->remote_nonce[36] = '\0';
- }
-
- if (!strcasecmp(listening, "false")) {
- if (dc->listen_data != NULL) {
- /*
- * We'll listen for incoming connections but
- * the listening socket isn't ready yet so we cannot
- * send the INVITE packet now. Put the slpcall into waiting mode
- * and let the callback send the invite.
- */
- slpcall->wait_for_socket = TRUE;
-
- } else if (dc->listenfd != -1) {
- /* The listening socket is ready. Send the INVITE here. */
- msn_dc_send_invite(dc);
-
- } else {
- /* We weren't able to create a listener either. Use SB. */
- msn_dc_fallback_to_sb(dc);
- }
-
- } else {
- /*
- * We should connect to the client so parse
- * IP/port from response.
- */
- char *ip, *port_str;
- int port = 0;
-
- if (ntype == DC_NONCE_PLAIN) {
- /* Only needed for listening side. */
- memcpy(dc->nonce, nonce, 16);
- }
-
- /* Cancel any listen attempts because we don't need them. */
- if (dc->listenfd_handle != 0) {
- purple_input_remove(dc->listenfd_handle);
- dc->listenfd_handle = 0;
- }
- if (dc->connect_timeout_handle != 0) {
- purple_timeout_remove(dc->connect_timeout_handle);
- dc->connect_timeout_handle = 0;
- }
- if (dc->listenfd != -1) {
- purple_network_remove_port_mapping(dc->listenfd);
- close(dc->listenfd);
- dc->listenfd = -1;
- }
- if (dc->listen_data != NULL) {
- purple_network_listen_cancel(dc->listen_data);
- dc->listen_data = NULL;
- }
-
- /* Save external IP/port for later use. We'll try local connection first. */
- dc->ext_ip = get_token(content, "IPv4External-Addrs: ", "\r\n");
- port_str = get_token(content, "IPv4External-Port: ", "\r\n");
- if (port_str) {
- dc->ext_port = atoi(port_str);
- g_free(port_str);
- }
-
- ip = get_token(content, "IPv4Internal-Addrs: ", "\r\n");
- port_str = get_token(content, "IPv4Internal-Port: ", "\r\n");
- if (port_str) {
- port = atoi(port_str);
- g_free(port_str);
- }
-
- if (ip && port) {
- /* Try internal address first */
- dc->connect_data = purple_proxy_connect(
- NULL,
- slpcall->slplink->session->account,
- ip,
- port,
- msn_dc_connected_to_peer_cb,
- dc
- );
-
- if (dc->connect_data) {
- /* Add connect timeout handle */
- dc->connect_timeout_handle = purple_timeout_add_seconds(
- DC_OUTGOING_TIMEOUT,
- msn_dc_outgoing_connection_timeout_cb,
- dc
- );
- } else {
- /*
- * Connection failed
- * Try external IP/port (if specified)
- */
- msn_dc_outgoing_connection_timeout_cb(dc);
- }
-
- } else {
- /*
- * Omitted or invalid internal IP address / port
- * Try external IP/port (if specified)
- */
- msn_dc_outgoing_connection_timeout_cb(dc);
- }
-
- g_free(ip);
- }
-
- } else {
- /*
- * Invalid direct connect invitation or
- * TCP connection is not supported
- */
- }
-
- g_free(listening);
- g_free(nonce);
- g_free(bridge);
-
- return;
-}
-
-static void
-got_sessionreq(MsnSlpCall *slpcall, const char *branch,
- const char *euf_guid, const char *context)
-{
- gboolean accepted = FALSE;
-
- if (!strcmp(euf_guid, MSN_OBJ_GUID))
- {
- /* Emoticon or UserDisplay */
- char *content;
- gsize len;
- MsnSlpLink *slplink;
- MsnSlpMessage *slpmsg;
- MsnObject *obj;
- char *msnobj_data;
- PurpleStoredImage *img = NULL;
- int type;
-
- /* Send Ok */
- content = g_strdup_printf("SessionID: %lu\r\n\r\n",
- slpcall->session_id);
-
- msn_slp_send_ok(slpcall, branch, "application/x-msnmsgr-sessionreqbody",
- content);
-
- g_free(content);
-
- slplink = slpcall->slplink;
-
- msnobj_data = (char *)purple_base64_decode(context, &len);
- obj = msn_object_new_from_string(msnobj_data);
- type = msn_object_get_type(obj);
- g_free(msnobj_data);
- if (type == MSN_OBJECT_EMOTICON) {
- img = find_valid_emoticon(slplink->session->account, obj->location);
- } else if (type == MSN_OBJECT_USERTILE) {
- img = msn_object_get_image(obj);
- if (img)
- purple_imgstore_ref(img);
- }
- msn_object_destroy(obj);
-
- if (img != NULL) {
- /* DATA PREP */
- slpmsg = msn_slpmsg_dataprep_new(slpcall);
- msn_slplink_queue_slpmsg(slplink, slpmsg);
-
- /* DATA */
- slpmsg = msn_slpmsg_obj_new(slpcall, img);
- msn_slplink_queue_slpmsg(slplink, slpmsg);
- purple_imgstore_unref(img);
-
- accepted = TRUE;
-
- } else {
- purple_debug_error("msn", "Wrong object.\n");
- }
- }
-
- else if (!strcmp(euf_guid, MSN_FT_GUID))
- {
- /* File Transfer */
- PurpleAccount *account;
- PurpleXfer *xfer;
- MsnFileContext *file_context;
- char *buf;
- gsize bin_len;
- guint32 file_size;
- char *file_name;
-
- account = slpcall->slplink->session->account;
-
- slpcall->end_cb = msn_xfer_end_cb;
- slpcall->branch = g_strdup(branch);
-
- slpcall->pending = TRUE;
-
- xfer = purple_xfer_new(account, PURPLE_XFER_RECEIVE,
- slpcall->slplink->remote_user);
-
- buf = (char *)purple_base64_decode(context, &bin_len);
- file_context = msn_file_context_from_wire(buf, bin_len);
-
- if (file_context != NULL) {
- file_size = file_context->file_size;
-
- file_name = g_convert((const gchar *)&file_context->file_name,
- MAX_FILE_NAME_LEN * 2,
- "UTF-8", "UTF-16LE",
- NULL, NULL, NULL);
-
- purple_xfer_set_filename(xfer, file_name ? file_name : "");
- g_free(file_name);
- purple_xfer_set_size(xfer, file_size);
- purple_xfer_set_init_fnc(xfer, msn_xfer_init);
- purple_xfer_set_request_denied_fnc(xfer, msn_xfer_cancel);
- purple_xfer_set_cancel_recv_fnc(xfer, msn_xfer_cancel);
- purple_xfer_set_read_fnc(xfer, msn_xfer_read);
- purple_xfer_set_write_fnc(xfer, msn_xfer_write);
-
- slpcall->u.incoming_data = g_byte_array_new();
-
- slpcall->xfer = xfer;
- purple_xfer_ref(slpcall->xfer);
-
- xfer->data = slpcall;
-
- if (file_context->preview) {
- purple_xfer_set_thumbnail(xfer, file_context->preview,
- file_context->preview_len,
- "image/png");
- g_free(file_context->preview);
- }
-
- purple_xfer_request(xfer);
- }
- g_free(file_context);
- g_free(buf);
-
- accepted = TRUE;
-
- } else if (!strcmp(euf_guid, MSN_CAM_REQUEST_GUID)) {
- purple_debug_info("msn", "Cam request.\n");
- if (slpcall->slplink && slpcall->slplink->session) {
- PurpleConversation *conv;
- gchar *from = slpcall->slplink->remote_user;
- conv = purple_find_conversation_with_account(
- PURPLE_CONV_TYPE_IM, from,
- slpcall->slplink->session->account);
- if (conv) {
- char *buf;
- buf = g_strdup_printf(
- _("%s requests to view your "
- "webcam, but this request is "
- "not yet supported."), from);
- purple_conversation_write(conv, NULL, buf,
- PURPLE_MESSAGE_SYSTEM |
- PURPLE_MESSAGE_NOTIFY,
- time(NULL));
- g_free(buf);
- }
- }
-
- } else if (!strcmp(euf_guid, MSN_CAM_GUID)) {
- purple_debug_info("msn", "Cam invite.\n");
- if (slpcall->slplink && slpcall->slplink->session) {
- PurpleConversation *conv;
- gchar *from = slpcall->slplink->remote_user;
- conv = purple_find_conversation_with_account(
- PURPLE_CONV_TYPE_IM, from,
- slpcall->slplink->session->account);
- if (conv) {
- char *buf;
- buf = g_strdup_printf(
- _("%s invited you to view his/her webcam, but "
- "this is not yet supported."), from);
- purple_conversation_write(conv, NULL, buf,
- PURPLE_MESSAGE_SYSTEM |
- PURPLE_MESSAGE_NOTIFY,
- time(NULL));
- g_free(buf);
- }
- }
-
- } else
- purple_debug_warning("msn", "SLP SessionReq with unknown EUF-GUID: %s\n", euf_guid);
-
- if (!accepted) {
- char *content = g_strdup_printf("SessionID: %lu\r\n\r\n",
- slpcall->session_id);
- msn_slp_send_decline(slpcall, branch, "application/x-msnmsgr-sessionreqbody", content);
- g_free(content);
- }
-}
-
-void
-send_bye(MsnSlpCall *slpcall, const char *type)
-{
- MsnSlpLink *slplink;
- PurpleAccount *account;
- MsnSlpMessage *slpmsg;
- char *header;
-
- slplink = slpcall->slplink;
-
- g_return_if_fail(slplink != NULL);
-
- account = slplink->session->account;
-
- header = g_strdup_printf("BYE MSNMSGR:%s MSNSLP/1.0",
- purple_account_get_username(account));
-
- slpmsg = msn_slpmsg_sip_new(slpcall, 0, header,
- "A0D624A6-6C0C-4283-A9E0-BC97B4B46D32",
- type,
- "\r\n");
- g_free(header);
-
- slpmsg->info = "SLP BYE";
- slpmsg->text_body = TRUE;
-
- msn_slplink_queue_slpmsg(slplink, slpmsg);
-}
-
-static void
-got_invite(MsnSlpCall *slpcall,
- const char *branch, const char *type, const char *content)
-{
- MsnSlpLink *slplink;
-
- slplink = slpcall->slplink;
-
- if (!strcmp(type, "application/x-msnmsgr-sessionreqbody"))
- {
- char *euf_guid, *context;
- char *temp;
-
- euf_guid = get_token(content, "EUF-GUID: {", "}\r\n");
-
- temp = get_token(content, "SessionID: ", "\r\n");
- if (temp != NULL)
- slpcall->session_id = atoi(temp);
- g_free(temp);
-
- temp = get_token(content, "AppID: ", "\r\n");
- if (temp != NULL)
- slpcall->app_id = atoi(temp);
- g_free(temp);
-
- context = get_token(content, "Context: ", "\r\n");
-
- if (context != NULL)
- got_sessionreq(slpcall, branch, euf_guid, context);
-
- g_free(context);
- g_free(euf_guid);
- }
- else if (!strcmp(type, "application/x-msnmsgr-transreqbody"))
- {
- /* A direct connection negotiation request */
- char *bridges;
- char *nonce;
- MsnDirectConnNonceType ntype;
-
- purple_debug_info("msn", "got_invite: transreqbody received\n");
-
- /* Direct connections may be disabled. */
- if (!purple_account_get_bool(slplink->session->account, "direct_connect", TRUE)) {
- msn_slp_send_ok(slpcall, branch,
- "application/x-msnmsgr-transrespbody",
- "Bridge: TCPv1\r\n"
- "Listening: false\r\n"
- "Nonce: {00000000-0000-0000-0000-000000000000}\r\n"
- "\r\n");
- msn_slpcall_session_init(slpcall);
-
- return;
- }
-
- /* Don't do anything if we already have a direct connection */
- if (slplink->dc != NULL)
- return;
-
- bridges = get_token(content, "Bridges: ", "\r\n");
- nonce = parse_dc_nonce(content, &ntype);
- if (bridges && strstr(bridges, "TCPv1") != NULL) {
- /*
- * Ok, the client supports direct TCP connection
- * Try to create a listening port
- */
- MsnDirectConn *dc;
-
- dc = msn_dc_new(slpcall);
- if (ntype == DC_NONCE_PLAIN) {
- /* There is only one nonce for plain auth. */
- dc->nonce_type = ntype;
- memcpy(dc->nonce, nonce, 16);
- } else if (ntype == DC_NONCE_SHA1) {
- /* Each side has a nonce in SHA1 auth. */
- dc->nonce_type = ntype;
- strncpy(dc->remote_nonce, nonce, 36);
- dc->remote_nonce[36] = '\0';
- }
-
- dc->listen_data = purple_network_listen_range(
- 0, 0,
- SOCK_STREAM,
- msn_dc_listen_socket_created_cb,
- dc
- );
-
- if (dc->listen_data == NULL) {
- /* Listen socket creation failed */
-
- purple_debug_info("msn", "got_invite: listening failed\n");
-
- if (dc->nonce_type != DC_NONCE_PLAIN)
- msn_slp_send_ok(slpcall, branch,
- "application/x-msnmsgr-transrespbody",
- "Bridge: TCPv1\r\n"
- "Listening: false\r\n"
- "Hashed-Nonce: {00000000-0000-0000-0000-000000000000}\r\n"
- "\r\n");
- else
- msn_slp_send_ok(slpcall, branch,
- "application/x-msnmsgr-transrespbody",
- "Bridge: TCPv1\r\n"
- "Listening: false\r\n"
- "Nonce: {00000000-0000-0000-0000-000000000000}\r\n"
- "\r\n");
-
- } else {
- /*
- * Listen socket created successfully.
- * Don't send anything here because we don't know the parameters
- * of the created socket yet. msn_dc_send_ok will be called from
- * the callback function: dc_listen_socket_created_cb
- */
- purple_debug_info("msn", "got_invite: listening socket created\n");
-
- dc->send_connection_info_msg_cb = msn_dc_send_ok;
- slpcall->wait_for_socket = TRUE;
- }
-
- } else {
- /*
- * Invalid direct connect invitation or
- * TCP connection is not supported.
- */
- }
-
- g_free(nonce);
- g_free(bridges);
- }
- else if (!strcmp(type, "application/x-msnmsgr-transrespbody"))
- {
- /* A direct connection negotiation response */
- msn_slp_process_transresp(slpcall, content);
- }
-}
-
-static void
-got_ok(MsnSlpCall *slpcall,
- const char *type, const char *content)
-{
- g_return_if_fail(slpcall != NULL);
- g_return_if_fail(type != NULL);
-
- if (!strcmp(type, "application/x-msnmsgr-sessionreqbody"))
- {
- char *content;
- char *header;
- char *nonce = NULL;
- MsnSession *session = slpcall->slplink->session;
- MsnSlpMessage *msg;
- MsnDirectConn *dc;
- MsnUser *user;
-
- if (!purple_account_get_bool(session->account, "direct_connect", TRUE)) {
- /* Don't attempt a direct connection if disabled. */
- msn_slpcall_session_init(slpcall);
- return;
- }
-
- if (slpcall->slplink->dc != NULL) {
- /* If we already have an established direct connection
- * then just start the transfer.
- */
- msn_slpcall_session_init(slpcall);
- return;
- }
-
- user = msn_userlist_find_user(session->userlist,
- slpcall->slplink->remote_user);
- if (!user || !(user->clientid & 0xF0000000)) {
- /* Just start a normal SB transfer. */
- msn_slpcall_session_init(slpcall);
- return;
- }
-
- /* Try direct file transfer by sending a second INVITE */
- dc = msn_dc_new(slpcall);
- g_free(slpcall->branch);
- slpcall->branch = rand_guid();
-
- dc->listen_data = purple_network_listen_range(
- 0, 0,
- SOCK_STREAM,
- msn_dc_listen_socket_created_cb,
- dc
- );
-
- header = g_strdup_printf(
- "INVITE MSNMSGR:%s MSNSLP/1.0",
- slpcall->slplink->remote_user
- );
-
- if (dc->nonce_type == DC_NONCE_SHA1)
- nonce = g_strdup_printf("Hashed-Nonce: {%s}\r\n", dc->nonce_hash);
-
- if (dc->listen_data == NULL) {
- /* Listen socket creation failed */
- purple_debug_info("msn", "got_ok: listening failed\n");
-
- content = g_strdup_printf(
- "Bridges: TCPv1\r\n"
- "NetID: %u\r\n"
- "Conn-Type: IP-Restrict-NAT\r\n"
- "UPnPNat: false\r\n"
- "ICF: false\r\n"
- "%s"
- "\r\n",
-
- rand() % G_MAXUINT32,
- nonce ? nonce : ""
- );
-
- } else {
- /* Listen socket created successfully. */
- purple_debug_info("msn", "got_ok: listening socket created\n");
-
- content = g_strdup_printf(
- "Bridges: TCPv1\r\n"
- "NetID: 0\r\n"
- "Conn-Type: Direct-Connect\r\n"
- "UPnPNat: false\r\n"
- "ICF: false\r\n"
- "%s"
- "\r\n",
-
- nonce ? nonce : ""
- );
- }
-
- msg = msn_slpmsg_sip_new(
- slpcall,
- 0,
- header,
- slpcall->branch,
- "application/x-msnmsgr-transreqbody",
- content
- );
- msg->info = "DC INVITE";
- msg->text_body = TRUE;
- g_free(nonce);
- g_free(header);
- g_free(content);
-
- msn_slplink_queue_slpmsg(slpcall->slplink, msg);
- }
- else if (!strcmp(type, "application/x-msnmsgr-transreqbody"))
- {
- /* Do we get this? */
- purple_debug_info("msn", "OK with transreqbody\n");
- }
- else if (!strcmp(type, "application/x-msnmsgr-transrespbody"))
- {
- msn_slp_process_transresp(slpcall, content);
- }
-}
-
-static void
-got_error(MsnSlpCall *slpcall,
- const char *error, const char *type, const char *content)
-{
- /* It's not valid. Kill this off. */
- purple_debug_error("msn", "Received non-OK result: %s\n",
- error ? error : "Unknown");
-
- if (type && !strcmp(type, "application/x-msnmsgr-transreqbody")) {
- MsnDirectConn *dc = slpcall->slplink->dc;
- if (dc) {
- msn_dc_fallback_to_sb(dc);
- return;
- }
- }
-
- slpcall->wasted = TRUE;
-}
-
-static MsnSlpCall *
-msn_slp_sip_recv(MsnSlpLink *slplink, const char *body)
-{
- MsnSlpCall *slpcall;
-
- if (body == NULL)
- {
- purple_debug_warning("msn", "received bogus message\n");
- return NULL;
- }
-
- if (!strncmp(body, "INVITE", strlen("INVITE")))
- {
- /* This is an INVITE request */
- char *branch;
- char *call_id;
- char *content;
- char *content_type;
-
- /* From: <msnmsgr:buddy@hotmail.com> */
-#if 0
- slpcall->remote_user = get_token(body, "From: <msnmsgr:", ">\r\n");
-#endif
-
- branch = get_token(body, ";branch={", "}");
-
- call_id = get_token(body, "Call-ID: {", "}");
-
-#if 0
- long content_len = -1;
-
- temp = get_token(body, "Content-Length: ", "\r\n");
- if (temp != NULL)
- content_len = atoi(temp);
- g_free(temp);
-#endif
- content_type = get_token(body, "Content-Type: ", "\r\n");
-
- content = get_token(body, "\r\n\r\n", NULL);
-
- slpcall = NULL;
- if (branch && call_id)
- {
- slpcall = msn_slplink_find_slp_call(slplink, call_id);
- if (slpcall)
- {
- g_free(slpcall->branch);
- slpcall->branch = g_strdup(branch);
- got_invite(slpcall, branch, content_type, content);
- }
- else if (content_type && content)
- {
- slpcall = msn_slpcall_new(slplink);
- slpcall->id = g_strdup(call_id);
- got_invite(slpcall, branch, content_type, content);
- }
- }
-
- g_free(call_id);
- g_free(branch);
- g_free(content_type);
- g_free(content);
- }
- else if (!strncmp(body, "MSNSLP/1.0 ", strlen("MSNSLP/1.0 ")))
- {
- /* This is a response */
- char *content;
- char *content_type;
- /* Make sure this is "OK" */
- const char *status = body + strlen("MSNSLP/1.0 ");
- char *call_id;
-
- call_id = get_token(body, "Call-ID: {", "}");
- slpcall = msn_slplink_find_slp_call(slplink, call_id);
- g_free(call_id);
-
- g_return_val_if_fail(slpcall != NULL, NULL);
-
- content_type = get_token(body, "Content-Type: ", "\r\n");
-
- content = get_token(body, "\r\n\r\n", NULL);
-
- if (strncmp(status, "200 OK", 6))
- {
- char *error = NULL;
- const char *c;
-
- /* Eww */
- if ((c = strchr(status, '\r')) || (c = strchr(status, '\n')) ||
- (c = strchr(status, '\0')))
- {
- size_t len = c - status;
- error = g_strndup(status, len);
- }
-
- got_error(slpcall, error, content_type, content);
- g_free(error);
-
- } else {
- /* Everything's just dandy */
- got_ok(slpcall, content_type, content);
- }
-
- g_free(content_type);
- g_free(content);
- }
- else if (!strncmp(body, "BYE", strlen("BYE")))
- {
- /* This is a BYE request */
- char *call_id;
-
- call_id = get_token(body, "Call-ID: {", "}");
- slpcall = msn_slplink_find_slp_call(slplink, call_id);
- g_free(call_id);
-
- if (slpcall != NULL)
- slpcall->wasted = TRUE;
-
- /* msn_slpcall_destroy(slpcall); */
- }
- else
- slpcall = NULL;
-
- return slpcall;
-}
-
-MsnSlpCall *
-msn_slp_process_msg(MsnSlpLink *slplink, MsnSlpMessage *slpmsg)
-{
- MsnSlpCall *slpcall;
- const guchar *body;
- gsize body_len;
- guint32 session_id;
- guint32 flags;
-
- slpcall = NULL;
- body = slpmsg->buffer;
- body_len = msn_p2p_info_get_offset(slpmsg->p2p_info);
-
- session_id = msn_p2p_info_get_session_id(slpmsg->p2p_info);
- flags = msn_p2p_info_get_flags(slpmsg->p2p_info);
-
- if (flags == P2P_NO_FLAG || flags == P2P_WLM2009_COMP)
- {
- char *body_str;
-
- if (session_id == 64)
- {
- /* This is for handwritten messages (Ink) */
- GError *error = NULL;
- gsize bytes_read, bytes_written;
-
- body_str = g_convert((const gchar *)body, body_len / 2,
- "UTF-8", "UTF-16LE",
- &bytes_read, &bytes_written, &error);
- body_len -= bytes_read + 2;
- body += bytes_read + 2;
- if (body_str == NULL
- || body_len <= 0
- || strstr(body_str, "image/gif") == NULL)
- {
- if (error != NULL) {
- purple_debug_error("msn",
- "Unable to convert Ink header from UTF-16 to UTF-8: %s\n",
- error->message);
- g_error_free(error);
- }
- else
- purple_debug_error("msn",
- "Received Ink in unknown format\n");
- g_free(body_str);
- return NULL;
- }
- g_free(body_str);
-
- body_str = g_convert((const gchar *)body, body_len / 2,
- "UTF-8", "UTF-16LE",
- &bytes_read, &bytes_written, &error);
- if (!body_str)
- {
- if (error != NULL) {
- purple_debug_error("msn",
- "Unable to convert Ink body from UTF-16 to UTF-8: %s\n",
- error->message);
- g_error_free(error);
- }
- else
- purple_debug_error("msn",
- "Received Ink in unknown format\n");
- return NULL;
- }
-
- msn_switchboard_show_ink(slpmsg->slplink->swboard,
- slplink->remote_user,
- body_str);
- }
- else
- {
- body_str = g_strndup((const char *)body, body_len);
- slpcall = msn_slp_sip_recv(slplink, body_str);
- }
- g_free(body_str);
- }
- else if (msn_p2p_msg_is_data(slpmsg->p2p_info))
- {
- slpcall = msn_slplink_find_slp_call_with_session_id(slplink, session_id);
-
- if (slpcall != NULL)
- {
- if (slpcall->timer) {
- purple_timeout_remove(slpcall->timer);
- slpcall->timer = 0;
- }
-
- if (slpcall->cb)
- slpcall->cb(slpcall, body, body_len);
-
- slpcall->wasted = TRUE;
- }
- }
- else if (msn_p2p_info_is_ack(slpmsg->p2p_info))
- {
- /* Acknowledgement of previous message. Don't do anything currently. */
- }
- else
- purple_debug_warning("msn", "Unprocessed SLP message with flags 0x%04x\n",
- flags);
-
- return slpcall;
-}
diff --git a/libpurple/protocols/msn/slpcall.h b/libpurple/protocols/msn/slpcall.h
deleted file mode 100644
index 3cfacf0473..0000000000
--- a/libpurple/protocols/msn/slpcall.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/**
- * @file slpcall.h SLP Call functions
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-#ifndef MSN_SLPCALL_H
-#define MSN_SLPCALL_H
-
-typedef struct _MsnSlpCall MsnSlpCall;
-
-typedef enum
-{
- MSN_SLPCALL_ANY,
- MSN_SLPCALL_DC
-} MsnSlpCallType;
-
-#include "internal.h"
-
-#include "slplink.h"
-
-/* The official client seems to timeout slp calls after 5 minutes */
-#define MSN_SLPCALL_TIMEOUT 300
-
-struct _MsnSlpCall
-{
- /* Our parent slplink */
- MsnSlpLink *slplink;
-
- MsnSlpCallType type;
-
- /* Call-ID */
- char *id;
- char *branch;
-
- long session_id;
- long app_id;
-
- gboolean pending; /**< A flag that states if we should wait for this
- slpcall to start and do not time out. */
- gboolean progress; /**< A flag that states if there has been progress since
- the last time out. */
- gboolean wasted; /**< A flag that states if this slpcall is going to be
- destroyed. */
- gboolean started; /**< A flag that states if this slpcall's session has
- been initiated. */
-
- gboolean wait_for_socket;
-
- void (*progress_cb)(MsnSlpCall *slpcall,
- gsize total_length, gsize len);
- void (*session_init_cb)(MsnSlpCall *slpcall);
-
- /* Can be checksum, or smile */
- char *data_info;
-
- PurpleXfer *xfer;
- union {
- GByteArray *incoming_data;
- struct {
- gsize len;
- const guchar *data;
- } outgoing;
- } u;
- MsnSlpMessage *xfer_msg; /* A dirty hack */
-
- MsnSlpCb cb;
- void (*end_cb)(MsnSlpCall *slpcall, MsnSession *session);
-
- guint timer;
-};
-
-MsnSlpCall *msn_slpcall_new(MsnSlpLink *slplink);
-void msn_slpcall_init(MsnSlpCall *slpcall, MsnSlpCallType type);
-void msn_slpcall_session_init(MsnSlpCall *slpcall);
-void msn_slpcall_destroy(MsnSlpCall *slpcall);
-void msn_slpcall_invite(MsnSlpCall *slpcall, const char *euf_guid,
- MsnP2PAppId app_id, const char *context);
-void msn_slpcall_close(MsnSlpCall *slpcall);
-
-#endif /* MSN_SLPCALL_H */
diff --git a/libpurple/protocols/msn/slplink.c b/libpurple/protocols/msn/slplink.c
deleted file mode 100644
index c2b5453f46..0000000000
--- a/libpurple/protocols/msn/slplink.c
+++ /dev/null
@@ -1,646 +0,0 @@
-/**
- * @file slplink.c MSNSLP Link support
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-
-#include "internal.h"
-#include "debug.h"
-
-#include "msn.h"
-#include "slplink.h"
-#include "slpmsg_part.h"
-
-#include "sbconn.h"
-#include "switchboard.h"
-#include "slp.h"
-#include "p2p.h"
-
-#ifdef MSN_DEBUG_SLP_FILES
-static int m_sc = 0;
-static int m_rc = 0;
-
-static void
-debug_part_to_file(MsnSlpMessage *msg, gboolean send)
-{
- char *tmp;
- char *dir;
- char *data;
- int c;
- gsize data_size;
-
- dir = send ? "send" : "recv";
- c = send ? m_sc++ : m_rc++;
- tmp = g_strdup_printf("%s/msntest/%s/%03d", purple_user_dir(), dir, c);
- data = msn_slpmsg_serialize(msg, &data_size);
- if (!purple_util_write_data_to_file_absolute(tmp, data, data_size))
- {
- purple_debug_error("msn", "could not save debug file\n");
- }
- g_free(tmp);
-}
-#endif
-
-/**************************************************************************
- * Main
- **************************************************************************/
-
-static MsnSlpLink *
-msn_slplink_new(MsnSession *session, const char *username)
-{
- MsnSlpLink *slplink;
-
- g_return_val_if_fail(session != NULL, NULL);
-
- slplink = g_new0(MsnSlpLink, 1);
-
- if (purple_debug_is_verbose())
- purple_debug_info("msn", "slplink_new: slplink(%p)\n", slplink);
-
- slplink->session = session;
- slplink->slp_seq_id = rand() % 0xFFFFFF00 + 4;
-
- slplink->remote_user = g_strdup(username);
- slplink->p2p_version = MSN_P2P_VERSION_ONE;
-
- slplink->slp_msg_queue = g_queue_new();
-
- session->slplinks =
- g_list_append(session->slplinks, slplink);
-
- return msn_slplink_ref(slplink);
-}
-
-static void
-msn_slplink_destroy(MsnSlpLink *slplink)
-{
- MsnSession *session;
-
- if (purple_debug_is_verbose())
- purple_debug_info("msn", "slplink_destroy: slplink(%p)\n", slplink);
-
- if (slplink->swboard != NULL) {
- slplink->swboard->slplinks = g_list_remove(slplink->swboard->slplinks, slplink);
- slplink->swboard = NULL;
- }
-
- session = slplink->session;
-
- if (slplink->dc != NULL) {
- slplink->dc->slplink = NULL;
- msn_dc_destroy(slplink->dc);
- slplink->dc = NULL;
- }
-
- while (slplink->slp_calls != NULL)
- msn_slpcall_destroy(slplink->slp_calls->data);
-
- g_queue_free(slplink->slp_msg_queue);
-
- session->slplinks =
- g_list_remove(session->slplinks, slplink);
-
- g_free(slplink->remote_user);
-
- g_free(slplink);
-}
-
-MsnSlpLink *
-msn_slplink_ref(MsnSlpLink *slplink)
-{
- g_return_val_if_fail(slplink != NULL, NULL);
-
- slplink->refs++;
- if (purple_debug_is_verbose())
- purple_debug_info("msn", "slplink ref (%p)[%d]\n", slplink, slplink->refs);
-
- return slplink;
-}
-
-void
-msn_slplink_unref(MsnSlpLink *slplink)
-{
- g_return_if_fail(slplink != NULL);
-
- slplink->refs--;
- if (purple_debug_is_verbose())
- purple_debug_info("msn", "slplink unref (%p)[%d]\n", slplink, slplink->refs);
-
- if (slplink->refs == 0)
- msn_slplink_destroy(slplink);
-}
-
-MsnSlpLink *
-msn_session_find_slplink(MsnSession *session, const char *who)
-{
- GList *l;
-
- for (l = session->slplinks; l != NULL; l = l->next)
- {
- MsnSlpLink *slplink;
-
- slplink = l->data;
-
- if (!strcmp(slplink->remote_user, who))
- return slplink;
- }
-
- return NULL;
-}
-
-MsnSlpLink *
-msn_session_get_slplink(MsnSession *session, const char *username)
-{
- MsnSlpLink *slplink;
-
- g_return_val_if_fail(session != NULL, NULL);
- g_return_val_if_fail(username != NULL, NULL);
-
- slplink = msn_session_find_slplink(session, username);
-
- if (slplink == NULL)
- slplink = msn_slplink_new(session, username);
-
- return slplink;
-}
-
-void
-msn_slplink_add_slpcall(MsnSlpLink *slplink, MsnSlpCall *slpcall)
-{
- if (slplink->swboard != NULL)
- slplink->swboard->flag |= MSN_SB_FLAG_FT;
-
- slplink->slp_calls = g_list_append(slplink->slp_calls, slpcall);
-
- /*
- if (slplink->dc != NULL && slplink->dc->state == DC_STATE_ESTABLISHED)
- msn_dc_ref(slplink->dc);
- */
-}
-
-void
-msn_slplink_remove_slpcall(MsnSlpLink *slplink, MsnSlpCall *slpcall)
-{
- /*
- if (slplink->dc != NULL && slplink->dc->state == DC_STATE_ESTABLISHED)
- msn_dc_unref(slplink->dc);
- */
-
- slplink->slp_calls = g_list_remove(slplink->slp_calls, slpcall);
-
- /* The slplink has no slpcalls in it, release it from MSN_SB_FLAG_FT.
- * If nothing else is using it then this might cause swboard to be
- * destroyed. */
- if (slplink->slp_calls == NULL && slplink->swboard != NULL) {
- slplink->swboard->slplinks = g_list_remove(slplink->swboard->slplinks, slplink);
- msn_switchboard_release(slplink->swboard, MSN_SB_FLAG_FT);
- slplink->swboard = NULL;
- }
-
- if (slplink->dc != NULL) {
- if ((slplink->dc->state != DC_STATE_ESTABLISHED && slplink->dc->slpcall == slpcall)
- || (slplink->slp_calls == NULL)) {
- /* The DC is not established and its corresponding slpcall is dead,
- * or the slplink has no slpcalls in it and no longer needs the DC.
- */
- slplink->dc->slplink = NULL;
- msn_dc_destroy(slplink->dc);
- slplink->dc = NULL;
- }
- }
-}
-
-MsnSlpCall *
-msn_slplink_find_slp_call(MsnSlpLink *slplink, const char *id)
-{
- GList *l;
- MsnSlpCall *slpcall;
-
- if (!id)
- return NULL;
-
- for (l = slplink->slp_calls; l != NULL; l = l->next)
- {
- slpcall = l->data;
-
- if (slpcall->id && !strcmp(slpcall->id, id))
- return slpcall;
- }
-
- return NULL;
-}
-
-MsnSlpCall *
-msn_slplink_find_slp_call_with_session_id(MsnSlpLink *slplink, long id)
-{
- GList *l;
- MsnSlpCall *slpcall;
-
- for (l = slplink->slp_calls; l != NULL; l = l->next)
- {
- slpcall = l->data;
-
- if (slpcall->session_id == id)
- return slpcall;
- }
-
- return NULL;
-}
-
-MsnP2PVersion
-msn_slplink_get_p2p_version(MsnSlpLink *slplink)
-{
- return slplink->p2p_version;
-}
-
-static void
-msn_slplink_send_part(MsnSlpLink *slplink, MsnSlpMessagePart *part)
-{
- if (slplink->dc != NULL && slplink->dc->state == DC_STATE_ESTABLISHED)
- {
- msn_dc_enqueue_part(slplink->dc, part);
- }
- else
- {
- msn_sbconn_send_part(slplink, part);
- }
-}
-
-void
-msn_slplink_send_msgpart(MsnSlpLink *slplink, MsnSlpMessage *slpmsg)
-{
- MsnSlpMessagePart *part;
- MsnP2PInfo *info;
- gsize real_size;
- size_t len = 0;
- guint64 offset;
-
- /* Maybe we will want to create a new msg for this slpmsg instead of
- * reusing the same one all the time. */
- info = slpmsg->p2p_info;
- part = msn_slpmsgpart_new(msn_p2p_info_dup(info));
- part->ack_data = slpmsg;
-
- real_size = msn_p2p_info_is_ack(info) ? 0 : slpmsg->size;
-
- offset = msn_p2p_info_get_offset(info);
- if (offset < real_size)
- {
- if (slpmsg->slpcall && slpmsg->slpcall->xfer && purple_xfer_get_type(slpmsg->slpcall->xfer) == PURPLE_XFER_SEND &&
- purple_xfer_get_status(slpmsg->slpcall->xfer) == PURPLE_XFER_STATUS_STARTED)
- {
- len = MIN(MSN_SBCONN_MAX_SIZE, slpmsg->slpcall->u.outgoing.len);
- msn_slpmsgpart_set_bin_data(part, slpmsg->slpcall->u.outgoing.data, len);
- }
- else
- {
- len = slpmsg->size - offset;
-
- if (len > MSN_SBCONN_MAX_SIZE)
- len = MSN_SBCONN_MAX_SIZE;
-
- msn_slpmsgpart_set_bin_data(part, slpmsg->buffer + offset, len);
- }
-
- msn_p2p_info_set_length(slpmsg->p2p_info, len);
- }
-
-#if 0
- /* TODO: port this function to SlpMessageParts */
- if (purple_debug_is_verbose())
- msn_message_show_readable(msg, slpmsg->info, slpmsg->text_body);
-#endif
-
-#ifdef MSN_DEBUG_SLP_FILES
- debug_part_to_file(slpmsg, TRUE);
-#endif
-
- slpmsg->parts = g_list_append(slpmsg->parts, part);
- msn_slplink_send_part(slplink, part);
-
-
- if (msn_p2p_msg_is_data(info) && slpmsg->slpcall != NULL)
- {
- slpmsg->slpcall->progress = TRUE;
-
- if (slpmsg->slpcall->progress_cb != NULL)
- {
- slpmsg->slpcall->progress_cb(slpmsg->slpcall, slpmsg->size,
- len);
- }
- }
-
- /* slpmsg->offset += len; */
-}
-
-static void
-msn_slplink_release_slpmsg(MsnSlpLink *slplink, MsnSlpMessage *slpmsg)
-{
- MsnP2PInfo *info;
- guint32 flags;
-
- info = slpmsg->p2p_info;
-
- flags = msn_p2p_info_get_flags(info);
- if (flags == P2P_NO_FLAG)
- {
- msn_p2p_info_set_ack_id(info, rand() % 0xFFFFFF00);
- }
- else if (msn_p2p_msg_is_data(info))
- {
- MsnSlpCall *slpcall;
- slpcall = slpmsg->slpcall;
-
- g_return_if_fail(slpcall != NULL);
- msn_p2p_info_set_session_id(info, slpcall->session_id);
- msn_p2p_info_set_app_id(info, slpcall->app_id);
- msn_p2p_info_set_ack_id(info, rand() % 0xFFFFFF00);
- }
-
- msn_p2p_info_set_id(info, slpmsg->id);
-
- msn_p2p_info_set_total_size(info, slpmsg->size);
-
- msn_slplink_send_msgpart(slplink, slpmsg);
-}
-
-void
-msn_slplink_queue_slpmsg(MsnSlpLink *slplink, MsnSlpMessage *slpmsg)
-{
- g_return_if_fail(slpmsg != NULL);
-
- slpmsg->id = slplink->slp_seq_id++;
-
- g_queue_push_tail(slplink->slp_msg_queue, slpmsg);
-}
-
-void
-msn_slplink_send_slpmsg(MsnSlpLink *slplink, MsnSlpMessage *slpmsg)
-{
- slpmsg->id = slplink->slp_seq_id++;
-
- msn_slplink_release_slpmsg(slplink, slpmsg);
-}
-
-void
-msn_slplink_send_queued_slpmsgs(MsnSlpLink *slplink)
-{
- MsnSlpMessage *slpmsg;
-
- /* Send the queued msgs in the order they were created */
- while ((slpmsg = g_queue_pop_head(slplink->slp_msg_queue)) != NULL)
- {
- msn_slplink_release_slpmsg(slplink, slpmsg);
- }
-}
-
-static void
-msn_slplink_send_ack(MsnSlpLink *slplink, MsnP2PInfo *info)
-{
- MsnSlpMessage *slpmsg = msn_slpmsg_ack_new(slplink, info);
-
- msn_slplink_send_slpmsg(slplink, slpmsg);
- msn_slpmsg_destroy(slpmsg);
-}
-
-static MsnSlpMessage *
-msn_slplink_message_find(MsnSlpLink *slplink, guint32 session_id, long id)
-{
- GList *e;
-
- for (e = slplink->slp_msgs; e != NULL; e = e->next)
- {
- MsnSlpMessage *slpmsg = e->data;
-
- if ((msn_p2p_info_get_session_id(slpmsg->p2p_info) == session_id) && (slpmsg->id == id))
- return slpmsg;
- }
-
- return NULL;
-}
-
-static MsnSlpMessage *
-init_first_msg(MsnSlpLink *slplink, MsnP2PInfo *info)
-{
- MsnSlpMessage *slpmsg;
- guint32 session_id;
-
- slpmsg = msn_slpmsg_new(slplink, NULL);
- slpmsg->id = msn_p2p_info_get_id(info);
- session_id = msn_p2p_info_get_session_id(info);
- slpmsg->size = msn_p2p_info_get_total_size(info);
- msn_p2p_info_init_first(slpmsg->p2p_info, info);
-
- if (session_id)
- {
- slpmsg->slpcall = msn_slplink_find_slp_call_with_session_id(slplink, session_id);
- if (slpmsg->slpcall != NULL)
- {
- if (msn_p2p_msg_is_data(info))
- {
- PurpleXfer *xfer = slpmsg->slpcall->xfer;
- if (xfer != NULL)
- {
- slpmsg->ft = TRUE;
- slpmsg->slpcall->xfer_msg = slpmsg;
-
- purple_xfer_ref(xfer);
- purple_xfer_start(xfer, -1, NULL, 0);
-
- if (xfer->data == NULL) {
- purple_xfer_unref(xfer);
- msn_slpmsg_destroy(slpmsg);
- g_return_val_if_reached(NULL);
- } else {
- purple_xfer_unref(xfer);
- }
- }
- }
- }
- }
- if (!slpmsg->ft && slpmsg->size)
- {
- slpmsg->buffer = g_try_malloc(slpmsg->size);
- if (slpmsg->buffer == NULL)
- {
- purple_debug_error("msn", "Failed to allocate buffer for slpmsg\n");
- msn_slpmsg_destroy(slpmsg);
- return NULL;
- }
- }
-
- return slpmsg;
-}
-
-static void
-process_complete_msg(MsnSlpLink *slplink, MsnSlpMessage *slpmsg, MsnP2PInfo *info)
-{
- MsnSlpCall *slpcall;
-
- slpcall = msn_slp_process_msg(slplink, slpmsg);
-
- if (slpcall == NULL) {
- msn_slpmsg_destroy(slpmsg);
- return;
- }
-
- purple_debug_info("msn", "msn_slplink_process_msg: slpmsg complete\n");
-
- if (msn_p2p_info_require_ack(slpmsg->p2p_info))
- {
- /* Release all the messages and send the ACK */
-
- if (slpcall->wait_for_socket) {
- /*
- * Save ack for later because we have to send
- * a 200 OK message to the previous direct connect
- * invitation before ACK but the listening socket isn't
- * created yet.
- */
- purple_debug_info("msn", "msn_slplink_process_msg: save ACK\n");
-
- slpcall->slplink->dc->prev_ack = msn_slpmsg_ack_new(slplink, info);
- } else if (!slpcall->wasted) {
- purple_debug_info("msn", "msn_slplink_process_msg: send ACK\n");
-
- msn_slplink_send_ack(slplink, info);
- msn_slplink_send_queued_slpmsgs(slplink);
- }
- }
-
- msn_slpmsg_destroy(slpmsg);
-
- if (!slpcall->wait_for_socket && slpcall->wasted)
- msn_slpcall_destroy(slpcall);
-}
-
-static void
-slpmsg_add_part(MsnSlpMessage *slpmsg, MsnSlpMessagePart *part)
-{
- if (slpmsg->ft) {
- slpmsg->slpcall->u.incoming_data =
- g_byte_array_append(slpmsg->slpcall->u.incoming_data, (const guchar *)part->buffer, part->size);
- purple_xfer_prpl_ready(slpmsg->slpcall->xfer);
- }
- else if (slpmsg->size && slpmsg->buffer) {
- guint64 offset = msn_p2p_info_get_offset(part->info);
- if (G_MAXSIZE - part->size < offset
- || (offset + part->size) > slpmsg->size
- || msn_p2p_info_get_offset(slpmsg->p2p_info) != offset) {
- purple_debug_error("msn",
- "Oversized slpmsg - msgsize=%" G_GSIZE_FORMAT " offset=%" G_GUINT64_FORMAT " len=%" G_GSIZE_FORMAT "\n",
- (gsize)slpmsg->size, offset, (gsize)part->size);
- g_return_if_reached();
- } else {
- memcpy(slpmsg->buffer + offset, part->buffer, part->size);
- msn_p2p_info_set_offset(slpmsg->p2p_info, offset + part->size);
- }
- }
-}
-
-void
-msn_slplink_process_msg(MsnSlpLink *slplink, MsnSlpMessagePart *part)
-{
- MsnSlpMessage *slpmsg;
- MsnP2PInfo *info;
-
- info = part->info;
-
- if (!msn_p2p_info_is_valid(info))
- {
- /* We seem to have received a bad header */
- purple_debug_warning("msn", "Total size listed in SLP binary header "
- "was less than length of this particular message. This "
- "should not happen. Dropping message.\n");
- return;
- }
-
- if (msn_p2p_info_is_first(info))
- slpmsg = init_first_msg(slplink, info);
- else {
- guint32 session_id, id;
- session_id = msn_p2p_info_get_session_id(info);
- id = msn_p2p_info_get_id(info);
- slpmsg = msn_slplink_message_find(slplink, session_id, id);
- if (slpmsg == NULL)
- {
- /* Probably the transfer was cancelled */
- purple_debug_error("msn", "Couldn't find slpmsg\n");
- return;
- }
- }
-
- slpmsg_add_part(slpmsg, part);
-
- if (msn_p2p_msg_is_data(slpmsg->p2p_info) && slpmsg->slpcall != NULL)
- {
- slpmsg->slpcall->progress = TRUE;
-
- if (slpmsg->slpcall->progress_cb != NULL)
- {
- slpmsg->slpcall->progress_cb(slpmsg->slpcall, slpmsg->size,
- part->size);
- }
- }
-
-#if 0
- if (slpmsg->buffer == NULL)
- return;
-#endif
-
- /* All the pieces of the slpmsg have been received */
- if (msn_p2p_info_is_final(info))
- process_complete_msg(slplink, slpmsg, info);
-
- /* NOTE: The slpmsg will be destroyed in process_complete_msg or left in
- the slplink until fully received. Don't free it here!
- */
-}
-
-void
-msn_slplink_request_object(MsnSlpLink *slplink,
- const char *info,
- MsnSlpCb cb,
- MsnSlpEndCb end_cb,
- const MsnObject *obj)
-{
- MsnSlpCall *slpcall;
- char *msnobj_data;
- char *msnobj_base64;
-
- g_return_if_fail(slplink != NULL);
- g_return_if_fail(obj != NULL);
-
- msnobj_data = msn_object_to_string(obj);
- msnobj_base64 = purple_base64_encode((const guchar *)msnobj_data, strlen(msnobj_data));
- g_free(msnobj_data);
-
- slpcall = msn_slpcall_new(slplink);
- msn_slpcall_init(slpcall, MSN_SLPCALL_ANY);
-
- slpcall->data_info = g_strdup(info);
- slpcall->cb = cb;
- slpcall->end_cb = end_cb;
-
- msn_slpcall_invite(slpcall, MSN_OBJ_GUID, P2P_APPID_OBJ, msnobj_base64);
-
- g_free(msnobj_base64);
-}
diff --git a/libpurple/protocols/msn/slplink.h b/libpurple/protocols/msn/slplink.h
deleted file mode 100644
index 2ce34e1032..0000000000
--- a/libpurple/protocols/msn/slplink.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/**
- * @file slplink.h MSNSLP Link support
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-#ifndef MSN_SLPLINK_H
-#define MSN_SLPLINK_H
-
-typedef struct _MsnSlpLink MsnSlpLink;
-
-#include "directconn.h"
-#include "session.h"
-#include "slpcall.h"
-#include "slpmsg.h"
-#include "switchboard.h"
-
-typedef void (*MsnSlpCb)(MsnSlpCall *slpcall,
- const guchar *data, gsize size);
-typedef void (*MsnSlpEndCb)(MsnSlpCall *slpcall, MsnSession *session);
-
-struct _MsnSlpLink
-{
- MsnSession *session;
- MsnSwitchBoard *swboard;
- MsnDirectConn *dc;
-
- guint refs;
-
- char *remote_user;
- MsnP2PVersion p2p_version;
-
- int slp_seq_id;
-
- GList *slp_calls;
- GList *slp_msgs;
-
- GQueue *slp_msg_queue;
-};
-
-MsnSlpLink *msn_slplink_ref(MsnSlpLink *slplink);
-void msn_slplink_unref(MsnSlpLink *slplink);
-
-/**
- * @return An MsnSlpLink for the given user, or NULL if there is no
- * existing MsnSlpLink.
- */
-MsnSlpLink *msn_session_find_slplink(MsnSession *session,
- const char *who);
-
-/**
- * @return An MsnSlpLink for the given user. One will be created if
- * it does not already exist.
- */
-MsnSlpLink *msn_session_get_slplink(MsnSession *session, const char *username);
-
-void msn_slplink_add_slpcall(MsnSlpLink *slplink, MsnSlpCall *slpcall);
-void msn_slplink_remove_slpcall(MsnSlpLink *slplink, MsnSlpCall *slpcall);
-MsnSlpCall *msn_slplink_find_slp_call(MsnSlpLink *slplink,
- const char *id);
-MsnSlpCall *msn_slplink_find_slp_call_with_session_id(MsnSlpLink *slplink, long id);
-MsnP2PVersion msn_slplink_get_p2p_version(MsnSlpLink *slplink);
-
-void msn_slplink_queue_slpmsg(MsnSlpLink *slplink, MsnSlpMessage *slpmsg);
-void msn_slplink_send_slpmsg(MsnSlpLink *slplink,
- MsnSlpMessage *slpmsg);
-void msn_slplink_send_queued_slpmsgs(MsnSlpLink *slplink);
-void msn_slplink_process_msg(MsnSlpLink *slplink, MsnSlpMessagePart *part);
-
-/* Only exported for msn_xfer_write */
-void msn_slplink_send_msgpart(MsnSlpLink *slplink, MsnSlpMessage *slpmsg);
-
-void msn_slplink_request_object(MsnSlpLink *slplink,
- const char *info,
- MsnSlpCb cb,
- MsnSlpEndCb end_cb,
- const MsnObject *obj);
-
-MsnSlpCall *msn_slp_process_msg(MsnSlpLink *slplink, MsnSlpMessage *slpmsg);
-
-#endif /* MSN_SLPLINK_H */
diff --git a/libpurple/protocols/msn/slpmsg.c b/libpurple/protocols/msn/slpmsg.c
deleted file mode 100644
index 4a75e3abc9..0000000000
--- a/libpurple/protocols/msn/slpmsg.c
+++ /dev/null
@@ -1,309 +0,0 @@
-/**
- * @file slpmsg.c SLP Message functions
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-
-#include "internal.h"
-#include "debug.h"
-
-#include "slpmsg.h"
-#include "slpmsg_part.h"
-#include "slplink.h"
-
-/**************************************************************************
- * SLP Message
- **************************************************************************/
-
-MsnSlpMessage *
-msn_slpmsg_new(MsnSlpLink *slplink, MsnSlpCall *slpcall)
-{
- MsnSlpMessage *slpmsg;
- MsnP2PVersion p2p;
-
- g_return_val_if_fail(slplink != NULL, NULL);
-
- slpmsg = g_new0(MsnSlpMessage, 1);
-
- if (purple_debug_is_verbose())
- purple_debug_info("msn", "slpmsg new (%p)\n", slpmsg);
-
- msn_slpmsg_set_slplink(slpmsg, slplink);
- slpmsg->slpcall = slpcall;
-
- p2p = msn_slplink_get_p2p_version(slplink);
- slpmsg->p2p_info = msn_p2p_info_new(p2p);
-
- return slpmsg;
-}
-
-void
-msn_slpmsg_destroy(MsnSlpMessage *slpmsg)
-{
- MsnSlpLink *slplink;
- GList *cur;
-
- g_return_if_fail(slpmsg != NULL);
-
- if (purple_debug_is_verbose())
- purple_debug_info("msn", "slpmsg destroy (%p)\n", slpmsg);
-
- slplink = slpmsg->slplink;
-
- purple_imgstore_unref(slpmsg->img);
-
- /* We don't want to free the data of the PurpleStoredImage,
- * but to avoid code duplication, it's sharing buffer. */
- if (slpmsg->img == NULL)
- g_free(slpmsg->buffer);
-
- for (cur = slpmsg->parts; cur != NULL; cur = g_list_delete_link(cur, cur))
- {
- /* Something is pointing to this slpmsg, so we should remove that
- * pointer to prevent a crash. */
- /* Ex: a user goes offline and after that we receive an ACK */
-
- MsnSlpMessagePart *part = cur->data;
-
- part->ack_cb = NULL;
- part->nak_cb = NULL;
- part->ack_data = NULL;
- msn_slpmsgpart_unref(part);
- }
-
- slplink->slp_msgs = g_list_remove(slplink->slp_msgs, slpmsg);
-
- msn_p2p_info_free(slpmsg->p2p_info);
-
- g_free(slpmsg);
-}
-
-void
-msn_slpmsg_set_slplink(MsnSlpMessage *slpmsg, MsnSlpLink *slplink)
-{
- g_return_if_fail(slplink != NULL);
-
- slpmsg->slplink = slplink;
-
- slplink->slp_msgs =
- g_list_append(slplink->slp_msgs, slpmsg);
-}
-
-void
-msn_slpmsg_set_body(MsnSlpMessage *slpmsg, const char *body,
- long long size)
-{
- /* We can only have one data source at a time. */
- g_return_if_fail(slpmsg->buffer == NULL);
- g_return_if_fail(slpmsg->img == NULL);
- g_return_if_fail(slpmsg->ft == FALSE);
-
- if (body != NULL)
- slpmsg->buffer = g_memdup(body, size);
- else
- slpmsg->buffer = g_new0(guchar, size);
-
- slpmsg->size = size;
-}
-
-void
-msn_slpmsg_set_image(MsnSlpMessage *slpmsg, PurpleStoredImage *img)
-{
- /* We can only have one data source at a time. */
- g_return_if_fail(slpmsg->buffer == NULL);
- g_return_if_fail(slpmsg->img == NULL);
- g_return_if_fail(slpmsg->ft == FALSE);
-
- slpmsg->img = purple_imgstore_ref(img);
- slpmsg->buffer = (guchar *)purple_imgstore_get_data(img);
- slpmsg->size = purple_imgstore_get_size(img);
-}
-
-
-MsnSlpMessage *
-msn_slpmsg_sip_new(MsnSlpCall *slpcall, int cseq,
- const char *header, const char *branch,
- const char *content_type, const char *content)
-{
- MsnSlpLink *slplink;
- PurpleAccount *account;
- MsnSlpMessage *slpmsg;
- char *body;
- gsize body_len;
- gsize content_len;
-
- g_return_val_if_fail(slpcall != NULL, NULL);
- g_return_val_if_fail(header != NULL, NULL);
-
- slplink = slpcall->slplink;
- account = slplink->session->account;
-
- /* Let's remember that "content" should end with a 0x00 */
-
- content_len = (content != NULL) ? strlen(content) + 1 : 0;
-
- body = g_strdup_printf(
- "%s\r\n"
- "To: <msnmsgr:%s>\r\n"
- "From: <msnmsgr:%s>\r\n"
- "Via: MSNSLP/1.0/TLP ;branch={%s}\r\n"
- "CSeq: %d\r\n"
- "Call-ID: {%s}\r\n"
- "Max-Forwards: 0\r\n"
- "Content-Type: %s\r\n"
- "Content-Length: %" G_GSIZE_FORMAT "\r\n"
- "\r\n",
- header,
- slplink->remote_user,
- purple_account_get_username(account),
- branch,
- cseq,
- slpcall->id,
- content_type,
- content_len);
-
- body_len = strlen(body);
-
- if (content_len > 0)
- {
- body_len += content_len;
- body = g_realloc(body, body_len);
- g_strlcat(body, content, body_len);
- }
-
- slpmsg = msn_slpmsg_new(slplink, slpcall);
- msn_slpmsg_set_body(slpmsg, body, body_len);
-
- g_free(body);
-
- return slpmsg;
-}
-
-MsnSlpMessage *msn_slpmsg_ack_new(MsnSlpLink *slplink, MsnP2PInfo *ack_info)
-{
- MsnSlpMessage *slpmsg;
- MsnP2PInfo *new_info;
-
- slpmsg = msn_slpmsg_new(slplink, NULL);
-
- new_info = slpmsg->p2p_info;
- msn_p2p_info_create_ack(ack_info, new_info);
- slpmsg->size = msn_p2p_info_get_total_size(ack_info);
- slpmsg->info = "SLP ACK";
-
- return slpmsg;
-}
-
-MsnSlpMessage *msn_slpmsg_obj_new(MsnSlpCall *slpcall, PurpleStoredImage *img)
-{
- MsnSlpMessage *slpmsg;
-
- slpmsg = msn_slpmsg_new(slpcall->slplink, slpcall);
- msn_p2p_info_set_flags(slpmsg->p2p_info, P2P_MSN_OBJ_DATA);
- slpmsg->info = "SLP DATA";
-
- msn_slpmsg_set_image(slpmsg, img);
-
- return slpmsg;
-}
-
-MsnSlpMessage *msn_slpmsg_dataprep_new(MsnSlpCall *slpcall)
-{
- MsnSlpMessage *slpmsg;
-
- slpmsg = msn_slpmsg_new(slpcall->slplink, slpcall);
-
- msn_p2p_info_set_session_id(slpmsg->p2p_info, slpcall->session_id);
- msn_slpmsg_set_body(slpmsg, NULL, 4);
- slpmsg->info = "SLP DATA PREP";
-
- return slpmsg;
-
-}
-
-MsnSlpMessage *msn_slpmsg_file_new(MsnSlpCall *slpcall, size_t size)
-{
- MsnSlpMessage *slpmsg;
-
- slpmsg = msn_slpmsg_new(slpcall->slplink, slpcall);
-
- msn_p2p_info_set_flags(slpmsg->p2p_info, P2P_FILE_DATA);
- slpmsg->info = "SLP FILE";
- slpmsg->size = size;
-
- return slpmsg;
-}
-
-char *msn_slpmsg_serialize(MsnSlpMessage *slpmsg, size_t *ret_size)
-{
- char *header;
- char *footer;
- char *base;
- char *tmp;
- size_t header_size, footer_size;
-
- header = msn_p2p_header_to_wire(slpmsg->p2p_info, &header_size);
- footer = msn_p2p_footer_to_wire(slpmsg->p2p_info, &footer_size);
-
- base = g_malloc(header_size + slpmsg->size + footer_size);
- tmp = base;
-
- /* Copy header */
- memcpy(tmp, header, header_size);
- tmp += header_size;
-
- /* Copy body */
- memcpy(tmp, slpmsg->buffer, slpmsg->size);
- tmp += slpmsg->size;
-
- /* Copy footer */
- memcpy(tmp, footer, footer_size);
- tmp += footer_size;
-
- *ret_size = tmp - base;
-
- g_free(header);
- g_free(footer);
-
- return base;
-}
-
-void msn_slpmsg_show_readable(MsnSlpMessage *slpmsg)
-{
- GString *str;
-
- str = g_string_new(NULL);
-
- msn_p2p_info_to_string(slpmsg->p2p_info, str);
-
- if (purple_debug_is_verbose() && slpmsg->buffer != NULL) {
- g_string_append_len(str, (gchar*)slpmsg->buffer, slpmsg->size);
-
- if (slpmsg->buffer[slpmsg->size - 1] == '\0') {
- str->len--;
- g_string_append(str, " 0x00");
- }
- g_string_append(str, "\r\n");
-
- }
-
- purple_debug_info("msn", "SlpMessage %s:\n{%s}\n", slpmsg->info, str->str);
-}
diff --git a/libpurple/protocols/msn/slpmsg.h b/libpurple/protocols/msn/slpmsg.h
deleted file mode 100644
index 45c755ebc5..0000000000
--- a/libpurple/protocols/msn/slpmsg.h
+++ /dev/null
@@ -1,150 +0,0 @@
-/**
- * @file slpmsg.h SLP Message functions
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-#ifndef _MSN_SLPMSG_H_
-#define _MSN_SLPMSG_H_
-
-typedef struct _MsnSlpMessage MsnSlpMessage;
-
-#include "imgstore.h"
-
-#include "slpcall.h"
-#include "slplink.h"
-#include "session.h"
-#include "p2p.h"
-
-#include "slp.h"
-
-/**
- * A SLP Message This contains everything that we will need to send a SLP
- * Message even if has to be sent in several parts.
- */
-struct _MsnSlpMessage
-{
- MsnSlpCall *slpcall; /**< The slpcall to which this slp message belongs (if applicable). */
- MsnSlpLink *slplink; /**< The slplink through which this slp message is being sent. */
- MsnSession *session;
-
- MsnP2PInfo *p2p_info;
-
- long id;
-
- gboolean ft;
- PurpleStoredImage *img;
- guchar *buffer;
-
- /**
- * This is the size of buffer, unless this is an outgoing file transfer,
- * in which case this is the size of the file.
- */
- gsize size;
-
- GList *parts; /**< A list with the SlpMsgParts */
-
- const char *info;
- gboolean text_body;
-};
-
-/**
- * Creates a new slp message
- *
- * @param slplink The slplink through which this slp message will be sent.
- * If it's set to NULL, it is a temporary SlpMessage.
- * @return The created slp message.
- */
-MsnSlpMessage *msn_slpmsg_new(MsnSlpLink *slplink, MsnSlpCall *slpcall);
-
-/**
- * Destroys a slp message
- *
- * @param slpmsg The slp message to destory.
- */
-void msn_slpmsg_destroy(MsnSlpMessage *slpmsg);
-
-/**
- * Relate this SlpMessage with an existing SlpLink
- *
- * @param slplink The SlpLink that will send this message.
- */
-void msn_slpmsg_set_slplink(MsnSlpMessage *slpmsg, MsnSlpLink *slplink);
-
-void msn_slpmsg_set_body(MsnSlpMessage *slpmsg, const char *body,
- long long size);
-void msn_slpmsg_set_image(MsnSlpMessage *slpmsg, PurpleStoredImage *img);
-MsnSlpMessage * msn_slpmsg_sip_new(MsnSlpCall *slpcall, int cseq,
- const char *header,
- const char *branch,
- const char *content_type,
- const char *content);
-
-/**
- * Create a new SLP Ack message
- *
- * @param header the value of the header in this slpmsg.
- *
- * @return A new SlpMessage with ACK headers
- */
-MsnSlpMessage *msn_slpmsg_ack_new(MsnSlpLink *slplink, MsnP2PInfo *info);
-
-/**
- * Create a new SLP message for MsnObject data.
- *
- * @param slpcall The slpcall that manages this message.
- * @param img The image to be sent in this message.
- *
- * @return A new SlpMessage with MsnObject info.
- */
-MsnSlpMessage *msn_slpmsg_obj_new(MsnSlpCall *slpcall, PurpleStoredImage *img);
-
-/**
- * Create a new SLP message for data preparation.
- *
- * @param slpcall The slpcall that manages this message.
- *
- * @return A new SlpMessage with data preparation info.
- */
-MsnSlpMessage *msn_slpmsg_dataprep_new(MsnSlpCall *slpcall);
-
-/**
- * Create a new SLP message for File transfer.
- *
- * @param slpcall The slpcall that manages this message.
- * @param size The size of the file being transsmited.
- *
- * @return A new SlpMessage with the file transfer info.
- */
-MsnSlpMessage *msn_slpmsg_file_new(MsnSlpCall *slpcall, size_t size);
-
-/**
- * Serialize the MsnSlpMessage in a way it can be used to be transmited
- *
- * @param slpmsg The MsnSlpMessage.
- * @param ret_size The size of the buffer cointaining the message.
- *
- * @return a buffer with the serialized data.
- */
-char *msn_slpmsg_serialize(MsnSlpMessage *slpmsg, size_t *ret_size);
-
-void msn_slpmsg_show_readable(MsnSlpMessage *slpmsg);
-
-#endif /* _MSN_SLPMSG_H_ */
diff --git a/libpurple/protocols/msn/slpmsg_part.c b/libpurple/protocols/msn/slpmsg_part.c
deleted file mode 100644
index add959a73a..0000000000
--- a/libpurple/protocols/msn/slpmsg_part.c
+++ /dev/null
@@ -1,232 +0,0 @@
-/**
- * @file slpmsg_part.c MSNSLP Parts
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-
-#include "internal.h"
-#include "debug.h"
-
-#include "slpmsg.h"
-#include "slpmsg_part.h"
-
-MsnSlpMessagePart *msn_slpmsgpart_new(MsnP2PInfo *info)
-{
- MsnSlpMessagePart *part;
-
- part = g_new0(MsnSlpMessagePart, 1);
-
- part->info = info;
-
- part->ack_cb = msn_slpmsgpart_ack;
- part->nak_cb = msn_slpmsgpart_nak;
-
- return msn_slpmsgpart_ref(part);
-}
-
-MsnSlpMessagePart *
-msn_slpmsgpart_new_from_data(MsnP2PVersion p2p, const char *data, size_t data_len)
-{
- MsnSlpMessagePart *part;
- MsnP2PInfo *info;
- size_t len;
- int body_len;
-
- info = msn_p2p_info_new(p2p);
-
- /* Extract the binary SLP header */
- len = msn_p2p_header_from_wire(info, data, data_len);
- if (len == 0) {
- msn_p2p_info_free(info);
- return NULL;
- }
- data += len;
- part = msn_slpmsgpart_new(info);
-
- /* Extract the body */
- body_len = data_len - len - P2P_PACKET_FOOTER_SIZE;
- /* msg->body_len = msg->msnslp_header.length; */
-
- if (body_len > 0) {
- part->size = body_len;
- part->buffer = g_malloc(body_len);
- memcpy(part->buffer, data, body_len);
- data += body_len;
- }
-
- /* Extract the footer */
- if (body_len >= 0)
- msn_p2p_footer_from_wire(part->info, data);
-
- return part;
-}
-
-static void msn_slpmsgpart_destroy(MsnSlpMessagePart *part)
-{
- g_free(part->info);
- g_free(part->buffer);
-
- g_free(part);
-
-}
-
-MsnSlpMessagePart *msn_slpmsgpart_ref(MsnSlpMessagePart *part)
-{
- g_return_val_if_fail(part != NULL, NULL);
- part->ref_count++;
-
- if (purple_debug_is_verbose())
- purple_debug_info("msn", "part ref (%p)[%u]\n", part, part->ref_count);
-
- return part;
-}
-
-void msn_slpmsgpart_unref(MsnSlpMessagePart *part)
-{
- g_return_if_fail(part != NULL);
- g_return_if_fail(part->ref_count > 0);
-
- part->ref_count--;
-
- if (purple_debug_is_verbose())
- purple_debug_info("msn", "part unref (%p)[%u]\n", part, part->ref_count);
-
- if (part->ref_count == 0) {
- msn_slpmsgpart_destroy(part);
- }
-}
-
-void msn_slpmsgpart_set_bin_data(MsnSlpMessagePart *part, const void *data, size_t len)
-{
- g_return_if_fail(part != NULL);
-
- g_free(part->buffer);
-
- if (data != NULL && len > 0) {
- part->buffer = g_malloc(len + 1);
- memcpy(part->buffer, data, len);
- part->buffer[len] = '\0';
- part->size = len;
- } else {
- part->buffer = NULL;
- part->size = 0;
- }
-
-}
-
-char *msn_slpmsgpart_serialize(MsnSlpMessagePart *part, size_t *ret_size)
-{
- char *header;
- char *footer;
- char *base;
- char *tmp;
- size_t header_size, footer_size;
-
- header = msn_p2p_header_to_wire(part->info, &header_size);
- footer = msn_p2p_footer_to_wire(part->info, &footer_size);
-
- base = g_malloc(header_size + part->size + footer_size);
- tmp = base;
-
- /* Copy header */
- memcpy(tmp, header, header_size);
- tmp += header_size;
-
- /* Copy body */
- memcpy(tmp, part->buffer, part->size);
- tmp += part->size;
-
- /* Copy footer */
- memcpy(tmp, footer, footer_size);
- tmp += footer_size;
-
- *ret_size = tmp - base;
-
- g_free(header);
- g_free(footer);
-
- return base;
-}
-
-/* We have received the message ack */
-void
-msn_slpmsgpart_ack(MsnSlpMessagePart *part, void *data)
-{
- MsnSlpMessage *slpmsg;
- guint64 offset;
- gsize real_size;
-
- slpmsg = data;
-
- real_size = msn_p2p_info_is_ack(slpmsg->p2p_info) ? 0 : slpmsg->size;
-
- offset = msn_p2p_info_get_offset(slpmsg->p2p_info);
- offset += msn_p2p_info_get_length(part->info);
- msn_p2p_info_set_offset(slpmsg->p2p_info, offset);
-
- slpmsg->parts = g_list_remove(slpmsg->parts, part);
- msn_slpmsgpart_unref(part);
-
- if (offset < real_size)
- {
- if (slpmsg->slpcall->xfer && purple_xfer_get_status(slpmsg->slpcall->xfer) == PURPLE_XFER_STATUS_STARTED)
- {
- slpmsg->slpcall->xfer_msg = slpmsg;
- purple_xfer_prpl_ready(slpmsg->slpcall->xfer);
- }
- else
- msn_slplink_send_msgpart(slpmsg->slplink, slpmsg);
- }
- else
- {
- /* The whole message has been sent */
- if (msn_p2p_msg_is_data(slpmsg->p2p_info))
- {
- if (slpmsg->slpcall != NULL)
- {
- if (slpmsg->slpcall->cb)
- slpmsg->slpcall->cb(slpmsg->slpcall,
- NULL, 0);
- }
- }
- }
-}
-
-/* We have received the message nak. */
-void
-msn_slpmsgpart_nak(MsnSlpMessagePart *part, void *data)
-{
- MsnSlpMessage *slpmsg;
-
- slpmsg = data;
-
- msn_slplink_send_msgpart(slpmsg->slplink, slpmsg);
-
- slpmsg->parts = g_list_remove(slpmsg->parts, part);
- msn_slpmsgpart_unref(part);
-}
-
-void
-msn_slpmsgpart_to_string(MsnSlpMessagePart *part, GString *str)
-{
- msn_p2p_info_to_string(part->info, str);
-}
-
diff --git a/libpurple/protocols/msn/slpmsg_part.h b/libpurple/protocols/msn/slpmsg_part.h
deleted file mode 100644
index 460eaa6986..0000000000
--- a/libpurple/protocols/msn/slpmsg_part.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/**
- * @file slpmsg_part.h MSNSLP Parts
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-
-#ifndef MSN_SLPMSG_PART_H
-#define MSN_SLPMSG_PART_H
-
-#include "p2p.h"
-
-typedef struct _MsnSlpMessagePart MsnSlpMessagePart;
-typedef void (*MsnSlpPartCb)(MsnSlpMessagePart *part, void *data);
-
-struct _MsnSlpMessagePart
-{
- guint ref_count;
-
- MsnP2PInfo *info;
-
- MsnSlpPartCb ack_cb;
- MsnSlpPartCb nak_cb;
- void *ack_data;
-
- guchar *buffer;
- size_t size;
-};
-
-MsnSlpMessagePart *msn_slpmsgpart_new(MsnP2PInfo *info);
-
-MsnSlpMessagePart *msn_slpmsgpart_new_from_data(MsnP2PVersion p2p, const char *data, size_t data_len);
-
-MsnSlpMessagePart *msn_slpmsgpart_ref(MsnSlpMessagePart *part);
-
-void msn_slpmsgpart_unref(MsnSlpMessagePart *part);
-
-void msn_slpmsgpart_set_bin_data(MsnSlpMessagePart *part, const void *data, size_t len);
-
-char *msn_slpmsgpart_serialize(MsnSlpMessagePart *part, size_t *ret_size);
-
-void msn_slpmsgpart_ack(MsnSlpMessagePart *part, void *data);
-
-void msn_slpmsgpart_nak(MsnSlpMessagePart *part, void *data);
-
-void msn_slpmsgpart_to_string(MsnSlpMessagePart *part, GString *str);
-
-#endif /* MSN_SLPMSG_PART_H */
-
diff --git a/libpurple/protocols/msn/soap.c b/libpurple/protocols/msn/soap.c
deleted file mode 100644
index 4cb571e51f..0000000000
--- a/libpurple/protocols/msn/soap.c
+++ /dev/null
@@ -1,688 +0,0 @@
-/**
- * @file soap.c
- * Functions relating to SOAP connections.
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "internal.h"
-
-#include "soap.h"
-
-#include "session.h"
-
-#include "debug.h"
-#include "xmlnode.h"
-
-#include <glib.h>
-#if !defined(_WIN32) || !defined(_WINERROR_)
-#include <error.h>
-#endif
-
-#define SOAP_TIMEOUT (5 * 60)
-
-typedef struct _MsnSoapRequest {
- char *path;
- MsnSoapMessage *message;
- gboolean secure;
- MsnSoapCallback cb;
- gpointer cb_data;
-} MsnSoapRequest;
-
-typedef struct _MsnSoapConnection {
- MsnSession *session;
- char *host;
-
- time_t last_used;
- PurpleSslConnection *ssl;
- gboolean connected;
-
- guint event_handle;
- guint run_timer;
- GString *buf;
- gsize handled_len;
- gsize body_len;
- int response_code;
- gboolean headers_done;
- gboolean close_when_done;
-
- MsnSoapMessage *message;
-
- GQueue *queue;
- MsnSoapRequest *current_request;
-} MsnSoapConnection;
-
-static gboolean msn_soap_connection_run(gpointer data);
-
-static MsnSoapConnection *
-msn_soap_connection_new(MsnSession *session, const char *host)
-{
- MsnSoapConnection *conn = g_new0(MsnSoapConnection, 1);
- conn->session = session;
- conn->host = g_strdup(host);
- conn->queue = g_queue_new();
- return conn;
-}
-
-static void
-msn_soap_message_destroy(MsnSoapMessage *message)
-{
- g_slist_foreach(message->headers, (GFunc)g_free, NULL);
- g_slist_free(message->headers);
- g_free(message->action);
- if (message->xml)
- xmlnode_free(message->xml);
- g_free(message);
-}
-
-static void
-msn_soap_request_destroy(MsnSoapRequest *req, gboolean keep_message)
-{
- g_free(req->path);
- if (!keep_message)
- msn_soap_message_destroy(req->message);
- g_free(req);
-}
-
-static void
-msn_soap_connection_sanitize(MsnSoapConnection *conn, gboolean disconnect)
-{
- if (conn->event_handle) {
- purple_input_remove(conn->event_handle);
- conn->event_handle = 0;
- }
-
- if (conn->run_timer) {
- purple_timeout_remove(conn->run_timer);
- conn->run_timer = 0;
- }
-
- if (conn->message) {
- msn_soap_message_destroy(conn->message);
- conn->message = NULL;
- }
-
- if (conn->buf) {
- g_string_free(conn->buf, TRUE);
- conn->buf = NULL;
- }
-
- if (conn->ssl && (disconnect || conn->close_when_done)) {
- purple_ssl_close(conn->ssl);
- conn->ssl = NULL;
- }
-
- if (conn->current_request) {
- msn_soap_request_destroy(conn->current_request, FALSE);
- conn->current_request = NULL;
- }
-}
-
-static void
-msn_soap_connection_destroy_foreach_cb(gpointer item, gpointer data)
-{
- MsnSoapRequest *req = item;
-
- req->cb(req->message, NULL, req->cb_data);
-
- msn_soap_request_destroy(req, FALSE);
-}
-
-static void
-msn_soap_connection_destroy(MsnSoapConnection *conn)
-{
- if (conn->current_request) {
- MsnSoapRequest *req = conn->current_request;
- conn->current_request = NULL;
- msn_soap_connection_destroy_foreach_cb(req, conn);
- }
-
- msn_soap_connection_sanitize(conn, TRUE);
- g_queue_foreach(conn->queue, msn_soap_connection_destroy_foreach_cb, conn);
- g_queue_free(conn->queue);
-
- g_free(conn->host);
- g_free(conn);
-}
-
-static gboolean
-msn_soap_cleanup_each(gpointer key, gpointer value, gpointer data)
-{
- MsnSoapConnection *conn = value;
- time_t *t = data;
-
- if ((*t - conn->last_used) > SOAP_TIMEOUT * 2) {
- purple_debug_info("soap", "cleaning up soap conn %p\n", conn);
- return TRUE;
- }
-
- return FALSE;
-}
-
-static gboolean
-msn_soap_cleanup_for_session(gpointer data)
-{
- MsnSession *sess = data;
- time_t t = time(NULL);
-
- purple_debug_info("soap", "session cleanup timeout\n");
-
- if (sess->soap_table) {
- g_hash_table_foreach_remove(sess->soap_table, msn_soap_cleanup_each,
- &t);
-
- if (g_hash_table_size(sess->soap_table) != 0)
- return TRUE;
- }
-
- sess->soap_cleanup_handle = 0;
- return FALSE;
-}
-
-static MsnSoapConnection *
-msn_soap_get_connection(MsnSession *session, const char *host)
-{
- MsnSoapConnection *conn = NULL;
-
- if (session->soap_table) {
- conn = g_hash_table_lookup(session->soap_table, host);
- } else {
- session->soap_table = g_hash_table_new_full(g_str_hash, g_str_equal,
- NULL, (GDestroyNotify)msn_soap_connection_destroy);
- }
-
- if (session->soap_cleanup_handle == 0)
- session->soap_cleanup_handle = purple_timeout_add_seconds(SOAP_TIMEOUT,
- msn_soap_cleanup_for_session, session);
-
- if (conn == NULL) {
- conn = msn_soap_connection_new(session, host);
- g_hash_table_insert(session->soap_table, conn->host, conn);
- }
-
- conn->last_used = time(NULL);
-
- return conn;
-}
-
-static void
-msn_soap_connection_handle_next(MsnSoapConnection *conn)
-{
- msn_soap_connection_sanitize(conn, FALSE);
-
- conn->run_timer = purple_timeout_add(0, msn_soap_connection_run, conn);
-}
-
-static void
-msn_soap_message_send_internal(MsnSession *session, MsnSoapMessage *message,
- const char *host, const char *path, gboolean secure,
- MsnSoapCallback cb, gpointer cb_data, gboolean first)
-{
- MsnSoapConnection *conn = msn_soap_get_connection(session, host);
- MsnSoapRequest *req = g_new0(MsnSoapRequest, 1);
-
- req->path = g_strdup(path);
- req->message = message;
- req->secure = secure;
- req->cb = cb;
- req->cb_data = cb_data;
-
- if (first) {
- g_queue_push_head(conn->queue, req);
- } else {
- g_queue_push_tail(conn->queue, req);
- }
-
- if (conn->run_timer == 0)
- conn->run_timer = purple_timeout_add(0, msn_soap_connection_run,
- conn);
-}
-
-void
-msn_soap_message_send(MsnSession *session, MsnSoapMessage *message,
- const char *host, const char *path, gboolean secure,
- MsnSoapCallback cb, gpointer cb_data)
-{
- g_return_if_fail(message != NULL);
- g_return_if_fail(cb != NULL);
-
- msn_soap_message_send_internal(session, message, host, path, secure,
- cb, cb_data, FALSE);
-}
-
-static gboolean
-msn_soap_handle_redirect(MsnSoapConnection *conn, const char *url)
-{
- char *host;
- char *path;
-
- if (purple_url_parse(url, &host, NULL, &path, NULL, NULL)) {
- MsnSoapRequest *req = conn->current_request;
- conn->current_request = NULL;
-
- msn_soap_message_send_internal(conn->session, req->message, host, path,
- req->secure, req->cb, req->cb_data, TRUE);
-
- msn_soap_request_destroy(req, TRUE);
-
- g_free(host);
- g_free(path);
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-static gboolean
-msn_soap_handle_body(MsnSoapConnection *conn, MsnSoapMessage *response)
-{
- xmlnode *body = xmlnode_get_child(response->xml, "Body");
- xmlnode *fault = xmlnode_get_child(response->xml, "Fault");
-
- if (fault) {
- xmlnode *faultcode = xmlnode_get_child(fault, "faultcode");
-
- if (faultcode != NULL) {
- char *faultdata = xmlnode_get_data(faultcode);
-
- if (faultdata && g_str_equal(faultdata, "psf:Redirect")) {
- xmlnode *url = xmlnode_get_child(fault, "redirectUrl");
-
- if (url) {
- char *urldata = xmlnode_get_data(url);
- if (urldata)
- msn_soap_handle_redirect(conn, urldata);
- g_free(urldata);
- }
-
- g_free(faultdata);
- msn_soap_message_destroy(response);
- return TRUE;
- } else if (faultdata && g_str_equal(faultdata, "wsse:FailedAuthentication")) {
- xmlnode *reason = xmlnode_get_child(fault, "faultstring");
- char *reasondata = NULL;
-
- if (reason)
- reasondata = xmlnode_get_data(reason);
-
- msn_soap_connection_sanitize(conn, TRUE);
- msn_session_set_error(conn->session, MSN_ERROR_AUTH,
- reasondata);
-
- g_free(reasondata);
- g_free(faultdata);
- msn_soap_message_destroy(response);
- return FALSE;
- }
-
- g_free(faultdata);
- }
- }
-
- if (fault || body) {
- if (conn->current_request) {
- MsnSoapRequest *request = conn->current_request;
- conn->current_request = NULL;
- request->cb(request->message, response,
- request->cb_data);
- msn_soap_request_destroy(request, FALSE);
- }
- msn_soap_message_destroy(response);
- }
-
- return TRUE;
-}
-
-static void
-msn_soap_message_add_header(MsnSoapMessage *message,
- const char *name, const char *value)
-{
- char *header = g_strdup_printf("%s: %s\r\n", name, value);
-
- message->headers = g_slist_prepend(message->headers, header);
-}
-
-static void
-msn_soap_process(MsnSoapConnection *conn)
-{
- gboolean handled = FALSE;
- char *cursor;
- char *linebreak;
-
- cursor = conn->buf->str + conn->handled_len;
-
- if (!conn->headers_done) {
- while ((linebreak = strstr(cursor, "\r\n")) != NULL) {
- conn->handled_len = linebreak - conn->buf->str + 2;
-
- if (conn->response_code == 0) {
- if (sscanf(cursor, "HTTP/1.1 %d", &conn->response_code) != 1) {
- /* something horribly wrong */
- purple_ssl_close(conn->ssl);
- conn->ssl = NULL;
- handled = TRUE;
- break;
- } else if (conn->response_code == 503 && conn->session->login_step < MSN_LOGIN_STEP_END) {
- msn_soap_connection_sanitize(conn, TRUE);
- msn_session_set_error(conn->session, MSN_ERROR_SERV_UNAVAILABLE, NULL);
- return;
- }
- } else if (cursor == linebreak) {
- /* blank line */
- conn->headers_done = TRUE;
- cursor = conn->buf->str + conn->handled_len;
- break;
- } else {
- char *line = g_strndup(cursor, linebreak - cursor);
- char *sep = strstr(line, ": ");
- char *key = line;
- char *value;
-
- if (sep == NULL) {
- purple_debug_info("soap", "ignoring malformed line: %s\n", line);
- g_free(line);
- goto loop_end;
- }
-
- value = sep + 2;
- *sep = '\0';
- msn_soap_message_add_header(conn->message, key, value);
-
- if ((conn->response_code == 301 || conn->response_code == 300)
- && strcmp(key, "Location") == 0) {
-
- msn_soap_handle_redirect(conn, value);
-
- handled = TRUE;
- g_free(line);
- break;
- } else if (conn->response_code == 401 &&
- strcmp(key, "WWW-Authenticate") == 0) {
- char *error = strstr(value, "cbtxt=");
-
- if (error) {
- error += strlen("cbtxt=");
- }
-
- msn_soap_connection_sanitize(conn, TRUE);
- msn_session_set_error(conn->session, MSN_ERROR_AUTH,
- error ? purple_url_decode(error) : NULL);
-
- g_free(line);
- return;
- } else if (strcmp(key, "Content-Length") == 0) {
- if (sscanf(value, "%" G_GSIZE_FORMAT, &(conn->body_len)) != 1)
- purple_debug_error("soap", "Unable to parse Content-Length\n");
- } else if (strcmp(key, "Connection") == 0) {
- if (strcmp(value, "close") == 0) {
- conn->close_when_done = TRUE;
- }
- }
- g_free(line);
- }
-
- loop_end:
- cursor = conn->buf->str + conn->handled_len;
- }
- }
-
- if (!handled && conn->headers_done) {
- if (conn->buf->len - conn->handled_len >=
- conn->body_len) {
- xmlnode *node = xmlnode_from_str(cursor, conn->body_len);
-
- if (node == NULL) {
- purple_debug_info("soap", "Malformed SOAP response: %s\n",
- cursor);
- } else {
- MsnSoapMessage *message = conn->message;
- conn->message = NULL;
- message->xml = node;
-
- if (!msn_soap_handle_body(conn, message)) {
- return;
- }
- }
-
- msn_soap_connection_handle_next(conn);
- }
-
- return;
- }
-
- if (handled) {
- msn_soap_connection_handle_next(conn);
- }
-}
-
-static void
-msn_soap_read_cb(gpointer data, gint fd, PurpleInputCondition cond)
-{
- MsnSoapConnection *conn = data;
- int count = 0, cnt, perrno;
- /* This buffer needs to be larger than any packets received from
- login.live.com or Adium will fail to receive the packet
- (something weird with the login.live.com server). With NSS it works
- fine, so I believe it's some bug with OS X */
- char buf[16 * 1024];
- gsize cursor;
-
- if (conn->message == NULL) {
- conn->message = msn_soap_message_new(NULL, NULL);
- }
-
- if (conn->buf == NULL) {
- conn->buf = g_string_new_len(buf, 0);
- }
-
- cursor = conn->buf->len;
- while ((cnt = purple_ssl_read(conn->ssl, buf, sizeof(buf))) > 0) {
- purple_debug_info("soap", "read %d bytes\n", cnt);
- count += cnt;
- g_string_append_len(conn->buf, buf, cnt);
- }
-
- perrno = errno;
- if (cnt < 0 && perrno != EAGAIN)
- purple_debug_info("soap", "read: %s\n", g_strerror(perrno));
-
- if (conn->current_request && conn->current_request->secure &&
- !purple_debug_is_unsafe())
- purple_debug_misc("soap", "Received secure request.\n");
- else if (count != 0)
- purple_debug_misc("soap", "current %s\n", conn->buf->str + cursor);
-
- /* && count is necessary for Adium, on OS X the last read always
- return an error, so we want to proceed anyway. See #5212 for
- discussion on this and the above buffer size issues */
- if(cnt < 0 && errno == EAGAIN && count == 0)
- return;
-
- /* msn_soap_process could alter errno */
- msn_soap_process(conn);
-
- if ((cnt < 0 && perrno != EAGAIN) || cnt == 0) {
- /* It's possible msn_soap_process closed the ssl connection */
- if (conn->ssl) {
- purple_ssl_close(conn->ssl);
- conn->ssl = NULL;
- msn_soap_connection_handle_next(conn);
- }
- }
-}
-
-static gboolean
-msn_soap_write_cb_internal(gpointer data, gint fd, PurpleInputCondition cond,
- gboolean initial)
-{
- MsnSoapConnection *conn = data;
- int written;
-
- if (cond != PURPLE_INPUT_WRITE)
- return TRUE;
-
- written = purple_ssl_write(conn->ssl, conn->buf->str + conn->handled_len,
- conn->buf->len - conn->handled_len);
-
- if (written < 0 && errno == EAGAIN)
- return TRUE;
- else if (written <= 0) {
- purple_ssl_close(conn->ssl);
- conn->ssl = NULL;
- if (!initial)
- msn_soap_connection_handle_next(conn);
- return FALSE;
- }
-
- conn->handled_len += written;
-
- if (conn->handled_len < conn->buf->len)
- return TRUE;
-
- /* we are done! */
- g_string_free(conn->buf, TRUE);
- conn->buf = NULL;
- conn->handled_len = 0;
- conn->body_len = 0;
- conn->response_code = 0;
- conn->headers_done = FALSE;
- conn->close_when_done = FALSE;
-
- purple_input_remove(conn->event_handle);
- conn->event_handle = purple_input_add(conn->ssl->fd, PURPLE_INPUT_READ,
- msn_soap_read_cb, conn);
- return TRUE;
-}
-
-static void
-msn_soap_write_cb(gpointer data, gint fd, PurpleInputCondition cond)
-{
- msn_soap_write_cb_internal(data, fd, cond, FALSE);
-}
-
-static void
-msn_soap_error_cb(PurpleSslConnection *ssl, PurpleSslErrorType error,
- gpointer data)
-{
- MsnSoapConnection *conn = data;
-
- /* sslconn already frees the connection in case of error */
- conn->ssl = NULL;
-
- g_hash_table_remove(conn->session->soap_table, conn->host);
-}
-
-static void
-msn_soap_connected_cb(gpointer data, PurpleSslConnection *ssl,
- PurpleInputCondition cond)
-{
- MsnSoapConnection *conn = data;
-
- conn->connected = TRUE;
-
- if (conn->run_timer == 0)
- conn->run_timer = purple_timeout_add(0, msn_soap_connection_run, conn);
-}
-
-MsnSoapMessage *
-msn_soap_message_new(const char *action, xmlnode *xml)
-{
- MsnSoapMessage *message = g_new0(MsnSoapMessage, 1);
-
- message->action = g_strdup(action);
- message->xml = xml;
-
- return message;
-}
-
-static gboolean
-msn_soap_connection_run(gpointer data)
-{
- MsnSoapConnection *conn = data;
- MsnSoapRequest *req = g_queue_peek_head(conn->queue);
-
- conn->run_timer = 0;
-
- if (req) {
- if (conn->ssl == NULL) {
- conn->ssl = purple_ssl_connect(conn->session->account, conn->host,
- 443, msn_soap_connected_cb, msn_soap_error_cb, conn);
- } else if (conn->connected) {
- int len = -1;
- char *body = xmlnode_to_str(req->message->xml, &len);
- GSList *iter;
-
- g_queue_pop_head(conn->queue);
-
- conn->buf = g_string_new("");
-
- g_string_append_printf(conn->buf,
- "POST /%s HTTP/1.1\r\n"
- "SOAPAction: %s\r\n"
- "Content-Type:text/xml; charset=utf-8\r\n"
- "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\r\n"
- "Accept: */*\r\n"
- "Host: %s\r\n"
- "Content-Length: %d\r\n"
- "Connection: Keep-Alive\r\n"
- "Cache-Control: no-cache\r\n",
- req->path, req->message->action ? req->message->action : "",
- conn->host, len);
-
- for (iter = req->message->headers; iter; iter = iter->next) {
- g_string_append(conn->buf, (char *)iter->data);
- g_string_append(conn->buf, "\r\n");
- }
-
- g_string_append(conn->buf, "\r\n");
- g_string_append(conn->buf, body);
-
- if (req->secure && !purple_debug_is_unsafe())
- purple_debug_misc("soap", "Sending secure request.\n");
- else
- purple_debug_misc("soap", "%s\n", conn->buf->str);
-
- conn->handled_len = 0;
- conn->current_request = req;
-
- if (conn->event_handle)
- purple_input_remove(conn->event_handle);
- conn->event_handle = purple_input_add(conn->ssl->fd,
- PURPLE_INPUT_WRITE, msn_soap_write_cb, conn);
- if (!msn_soap_write_cb_internal(conn, conn->ssl->fd, PURPLE_INPUT_WRITE, TRUE)) {
- /* Not connected => reconnect and retry */
- purple_debug_info("soap", "not connected, reconnecting\n");
-
- conn->connected = FALSE;
- conn->current_request = NULL;
- msn_soap_connection_sanitize(conn, FALSE);
-
- g_queue_push_head(conn->queue, req);
- conn->run_timer = purple_timeout_add(0, msn_soap_connection_run, conn);
- }
-
- g_free(body);
- }
- }
-
- return FALSE;
-}
diff --git a/libpurple/protocols/msn/soap.h b/libpurple/protocols/msn/soap.h
deleted file mode 100644
index de4d50e3dd..0000000000
--- a/libpurple/protocols/msn/soap.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * @file soap.h
- * header file for SOAP connection related process
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-#ifndef MSN_SOAP_H
-#define MSN_SOAP_H
-
-typedef struct _MsnSoapMessage MsnSoapMessage;
-
-#include <glib.h>
-
-#include "xmlnode.h"
-
-#include "session.h"
-#include "sslconn.h"
-
-typedef void (*MsnSoapCallback)(MsnSoapMessage *request,
- MsnSoapMessage *response, gpointer cb_data);
-
-struct _MsnSoapMessage {
- char *action;
- xmlnode *xml;
- GSList *headers;
-};
-
-MsnSoapMessage *msn_soap_message_new(const char *action, xmlnode *xml);
-
-void msn_soap_message_send(MsnSession *session, MsnSoapMessage *message,
- const char *host, const char *path, gboolean secure,
- MsnSoapCallback cb, gpointer cb_data);
-
-#endif /* MSN_SOAP_H */
diff --git a/libpurple/protocols/msn/state.c b/libpurple/protocols/msn/state.c
deleted file mode 100644
index 7157cfcd13..0000000000
--- a/libpurple/protocols/msn/state.c
+++ /dev/null
@@ -1,315 +0,0 @@
-/**
- * @file state.c State functions and definitions
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-
-#include "internal.h"
-#include "debug.h"
-
-#include "core.h"
-
-#include "notification.h"
-#include "state.h"
-
-static const char *away_text[] =
-{
- N_("Available"),
- N_("Available"),
- N_("Busy"),
- N_("Idle"),
- N_("Be Right Back"),
- N_("Away From Computer"),
- N_("On The Phone"),
- N_("Out To Lunch"),
- N_("Available"),
- N_("Available")
-};
-
-/*
- * WLM media PSM info build prcedure
- *
- * Result can like:
- * <CurrentMedia>\0Music\01\0{0} - {1}\0Song Title\0Song Artist\0Song Album\0\0</CurrentMedia>\
- * <CurrentMedia>\0Games\01\0Playing {0}\0Game Name\0</CurrentMedia>\
- * <CurrentMedia>\0Office\01\0Office Message\0Office App Name\0</CurrentMedia>"
- */
-static char *
-msn_build_psm(const char *psmstr,const char *mediastr, const char *guidstr, guint protocol_ver)
-{
- xmlnode *dataNode,*psmNode,*mediaNode,*guidNode;
- char *result;
- int length;
-
- dataNode = xmlnode_new("Data");
-
- psmNode = xmlnode_new("PSM");
- if(psmstr != NULL){
- xmlnode_insert_data(psmNode, psmstr, -1);
- }
- xmlnode_insert_child(dataNode, psmNode);
-
- mediaNode = xmlnode_new("CurrentMedia");
- if(mediastr != NULL){
- xmlnode_insert_data(mediaNode, mediastr, -1);
- }
- xmlnode_insert_child(dataNode, mediaNode);
-
- guidNode = xmlnode_new("MachineGuid");
- if(guidstr != NULL){
- xmlnode_insert_data(guidNode, guidstr, -1);
- }
- xmlnode_insert_child(dataNode, guidNode);
-
- if (protocol_ver >= 16) {
- /* TODO: What is this for? */
- xmlnode *ddpNode = xmlnode_new("DDP");
- xmlnode_insert_child(dataNode, ddpNode);
- }
-
- result = xmlnode_to_str(dataNode, &length);
- xmlnode_free(dataNode);
- return result;
-}
-
-/* get the CurrentMedia info from the XML node */
-char *
-msn_get_currentmedia(xmlnode *payloadNode)
-{
- xmlnode *currentmediaNode;
- char *currentmedia;
-
- purple_debug_info("msn", "Get CurrentMedia\n");
- currentmediaNode = xmlnode_get_child(payloadNode, "CurrentMedia");
- if (currentmediaNode == NULL) {
- purple_debug_info("msn", "No CurrentMedia Node\n");
- return NULL;
- }
- currentmedia = xmlnode_get_data(currentmediaNode);
-
- return currentmedia;
-}
-
-/* Get the PSM info from the XML node */
-char *
-msn_get_psm(xmlnode *payloadNode)
-{
- xmlnode *psmNode;
- char *psm;
-
- purple_debug_info("msn", "msn get PSM\n");
- psmNode = xmlnode_get_child(payloadNode, "PSM");
- if (psmNode == NULL) {
- purple_debug_info("msn", "No PSM status Node\n");
- return NULL;
- }
- psm = xmlnode_get_data(psmNode);
-
- return psm;
-}
-
-static char *
-create_media_string(PurplePresence *presence)
-{
- const char *title, *game, *office;
- char *ret;
- PurpleStatus *status = purple_presence_get_status(presence, "tune");
- if (!status || !purple_status_is_active(status))
- return NULL;
-
- title = purple_status_get_attr_string(status, PURPLE_TUNE_TITLE);
- game = purple_status_get_attr_string(status, "game");
- office = purple_status_get_attr_string(status, "office");
-
- if (title && *title) {
- const char *artist = purple_status_get_attr_string(status, PURPLE_TUNE_ARTIST);
- const char *album = purple_status_get_attr_string(status, PURPLE_TUNE_ALBUM);
- ret = g_strdup_printf("WMP\\0Music\\01\\0{0}%s%s\\0%s\\0%s\\0%s\\0",
- artist ? " - {1}" : "",
- album ? " ({2})" : "",
- title,
- artist ? artist : "",
- album ? album : "");
- }
- else if (game && *game)
- ret = g_strdup_printf("\\0Games\\01\\0Playing {0}\\0%s\\0", game);
- else if (office && *office)
- ret = g_strdup_printf("\\0Office\\01\\0Editing {0}\\0%s\\0", office);
- else
- ret = NULL;
-
- return ret;
-}
-
-/* set the MSN's PSM info,Currently Read from the status Line
- * Thanks for Cris Code
- */
-static void
-msn_set_psm(MsnSession *session)
-{
- PurpleAccount *account;
- PurplePresence *presence;
- PurpleStatus *status;
- char *payload;
- const char *statusline;
- gchar *statusline_stripped, *media = NULL;
-
- g_return_if_fail(session != NULL);
- g_return_if_fail(session->notification != NULL);
-
- account = session->account;
-
- /* Get the PSM string from Purple's Status Line */
- presence = purple_account_get_presence(account);
- status = purple_presence_get_active_status(presence);
- statusline = purple_status_get_attr_string(status, "message");
-
- /* MSN expects plain text, not HTML */
- statusline_stripped = purple_markup_strip_html(statusline);
- media = create_media_string(presence);
- g_free(session->psm);
- session->psm = msn_build_psm(statusline_stripped, media, session->guid, session->protocol_ver);
-
- payload = session->psm;
-
- msn_notification_send_uux(session, payload);
-
- g_free(statusline_stripped);
- g_free(media);
-}
-
-void
-msn_change_status(MsnSession *session)
-{
- PurpleAccount *account;
- MsnCmdProc *cmdproc;
- MsnTransaction *trans;
- MsnUser *user;
- MsnObject *msnobj;
- const char *state_text;
- GHashTable *ui_info = purple_core_get_ui_info();
- MsnClientCaps caps = MSN_CLIENT_ID;
-
- g_return_if_fail(session != NULL);
- g_return_if_fail(session->notification != NULL);
-
- /* set client caps based on what the UI tells us it is... */
- if (ui_info) {
- const gchar *client_type = g_hash_table_lookup(ui_info, "client_type");
- if (client_type) {
- if (strcmp(client_type, "phone") == 0 ||
- strcmp(client_type, "handheld") == 0) {
- caps |= MSN_CAP_VIA_MOBILE;
- } else if (strcmp(client_type, "web") == 0) {
- caps |= MSN_CAP_VIA_WEBIM;
- } else if (strcmp(client_type, "bot") == 0) {
- caps |= MSN_CAP_BOT;
- }
- /* MSN doesn't a "console" type...
- What, they have no ncurses UI? :-) */
- }
- }
-
- account = session->account;
- cmdproc = session->notification->cmdproc;
- user = session->user;
- state_text = msn_state_get_text(msn_state_from_account(account));
-
- /* If we're not logged in yet, don't send the status to the server,
- * it will be sent when login completes
- */
- if (!session->logged_in)
- return;
-
- msn_set_psm(session);
-
- msnobj = msn_user_get_object(user);
-
- if (msnobj == NULL)
- {
- trans = msn_transaction_new(cmdproc, "CHG", "%s %u:%02u 0", state_text,
- caps, MSN_CLIENT_ID_EXT_CAPS);
- }
- else
- {
- char *msnobj_str;
-
- msnobj_str = msn_object_to_string(msnobj);
-
- trans = msn_transaction_new(cmdproc, "CHG", "%s %u:%02u %s", state_text,
- caps, MSN_CLIENT_ID_EXT_CAPS,
- purple_url_encode(msnobj_str));
-
- g_free(msnobj_str);
- }
-
- msn_cmdproc_send_trans(cmdproc, trans);
-}
-
-const char *
-msn_away_get_text(MsnAwayType type)
-{
- g_return_val_if_fail(type <= MSN_HIDDEN, NULL);
-
- return _(away_text[type]);
-}
-
-const char *
-msn_state_get_text(MsnAwayType state)
-{
- static char *status_text[] =
- { "NLN", "NLN", "BSY", "IDL", "BRB", "AWY", "PHN", "LUN", "HDN", "HDN" };
-
- return status_text[state];
-}
-
-MsnAwayType
-msn_state_from_account(PurpleAccount *account)
-{
- MsnAwayType msnstatus;
- PurplePresence *presence;
- PurpleStatus *status;
- const char *status_id;
-
- presence = purple_account_get_presence(account);
- status = purple_presence_get_active_status(presence);
- status_id = purple_status_get_id(status);
-
- if (!strcmp(status_id, "away"))
- msnstatus = MSN_AWAY;
- else if (!strcmp(status_id, "brb"))
- msnstatus = MSN_BRB;
- else if (!strcmp(status_id, "busy"))
- msnstatus = MSN_BUSY;
- else if (!strcmp(status_id, "phone"))
- msnstatus = MSN_PHONE;
- else if (!strcmp(status_id, "lunch"))
- msnstatus = MSN_LUNCH;
- else if (!strcmp(status_id, "invisible"))
- msnstatus = MSN_HIDDEN;
- else
- msnstatus = MSN_ONLINE;
-
- if ((msnstatus == MSN_ONLINE) && purple_presence_is_idle(presence))
- msnstatus = MSN_IDLE;
-
- return msnstatus;
-}
diff --git a/libpurple/protocols/msn/state.h b/libpurple/protocols/msn/state.h
deleted file mode 100644
index eca877729c..0000000000
--- a/libpurple/protocols/msn/state.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/**
- * @file state.h State functions and definitions
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-#ifndef MSN_STATE_H
-#define MSN_STATE_H
-
-/**
- * Away types.
- */
-typedef enum
-{
- MSN_ONLINE = 1,
- MSN_BUSY = 2,
- MSN_IDLE = 3,
- MSN_BRB = 4,
- MSN_AWAY = 5,
- MSN_PHONE = 6,
- MSN_LUNCH = 7,
- MSN_OFFLINE = 8,
- MSN_HIDDEN = 9
-} MsnAwayType;
-
-/**
- * Changes the status of the user.
- *
- * @param session The MSN session.
- */
-void msn_change_status(MsnSession *session);
-
-/**
- * Returns the string representation of an away type.
- *
- * @param type The away type.
- *
- * @return The string representation of the away type.
- */
-const char *msn_away_get_text(MsnAwayType type);
-
-const char *msn_state_get_text(MsnAwayType state);
-
-/* Get the CurrentMedia info from the XML node */
-char *msn_get_currentmedia(xmlnode *payloadNode);
-
-/* Get the PSM info from the XML node */
-char *msn_get_psm(xmlnode *payloadNode);
-
-MsnAwayType msn_state_from_account(PurpleAccount *account);
-
-#endif /* MSN_STATE_H */
diff --git a/libpurple/protocols/msn/switchboard.c b/libpurple/protocols/msn/switchboard.c
deleted file mode 100644
index cc4ef75b5a..0000000000
--- a/libpurple/protocols/msn/switchboard.c
+++ /dev/null
@@ -1,1197 +0,0 @@
-/**
- * @file switchboard.c MSN switchboard functions
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-
-#include "internal.h"
-#include "debug.h"
-
-#include "msnutils.h"
-#include "switchboard.h"
-#include "sbconn.h"
-#include "slplink.h"
-#include "user.h"
-#include "userlist.h"
-
-static MsnTable *cbs_table;
-
-/**************************************************************************
- * Main
- **************************************************************************/
-
-MsnSwitchBoard *
-msn_switchboard_new(MsnSession *session)
-{
- MsnSwitchBoard *swboard;
-
- g_return_val_if_fail(session != NULL, NULL);
-
- swboard = g_new0(MsnSwitchBoard, 1);
-
- swboard->session = session;
- swboard->servconn = msn_servconn_new(session, MSN_SERVCONN_SB);
- msn_servconn_set_idle_timeout(swboard->servconn, 60);
- swboard->cmdproc = swboard->servconn->cmdproc;
-
- swboard->msg_queue = g_queue_new();
- swboard->empty = TRUE;
-
- swboard->cmdproc->data = swboard;
- swboard->cmdproc->cbs_table = cbs_table;
-
- session->switches = g_list_prepend(session->switches, swboard);
-
- if (purple_debug_is_verbose())
- purple_debug_info("msn", "switchboard new: swboard(%p)\n", swboard);
-
- return swboard;
-}
-
-void
-msn_switchboard_destroy(MsnSwitchBoard *swboard)
-{
- MsnSession *session;
- MsnMessage *msg;
- GList *l;
-
- if (purple_debug_is_verbose())
- purple_debug_info("msn", "switchboard destroy: swboard(%p)\n", swboard);
-
- g_return_if_fail(swboard != NULL);
-
- if (swboard->destroying)
- return;
-
- swboard->destroying = TRUE;
-
- if (swboard->reconn_timeout_h > 0)
- purple_timeout_remove(swboard->reconn_timeout_h);
-
- /* If it linked us is because its looking for trouble */
- while (swboard->slplinks != NULL) {
- MsnSlpLink *slplink = swboard->slplinks->data;
-
- swboard->slplinks = g_list_remove(swboard->slplinks, slplink);
-
- /* Destroy only those slplinks which use the switchboard */
- if (slplink->dc == NULL)
- msn_slplink_unref(slplink);
- else {
- swboard->slplinks = g_list_remove(swboard->slplinks, slplink);
- slplink->swboard = NULL;
- }
- }
-
- /* Destroy the message queue */
- while ((msg = g_queue_pop_head(swboard->msg_queue)) != NULL)
- {
- if (swboard->error != MSN_SB_ERROR_NONE)
- {
- /* The messages could not be sent due to a switchboard error */
- msg_error_helper(swboard->cmdproc, msg,
- MSN_MSG_ERROR_SB);
- }
- msn_message_unref(msg);
- }
-
- g_queue_free(swboard->msg_queue);
-
- /* msg_error_helper will both remove the msg from ack_list and
- unref it, so we don't need to do either here */
- while ((l = swboard->ack_list) != NULL)
- msg_error_helper(swboard->cmdproc, l->data, MSN_MSG_ERROR_SB);
-
- g_free(swboard->im_user);
- g_free(swboard->auth_key);
- g_free(swboard->session_id);
-
- for (; swboard->users; swboard->users = g_list_delete_link(swboard->users, swboard->users))
- msn_user_unref(swboard->users->data);
-
- session = swboard->session;
- session->switches = g_list_remove(session->switches, swboard);
-
- for (l = session->slplinks; l; l = l->next) {
- MsnSlpLink *slplink = l->data;
- if (slplink->swboard == swboard) slplink->swboard = NULL;
- }
-
-#if 0
- /* This should never happen or we are in trouble. */
- if (swboard->servconn != NULL)
- msn_servconn_destroy(swboard->servconn);
-#endif
-
- swboard->cmdproc->data = NULL;
-
- msn_servconn_set_disconnect_cb(swboard->servconn, NULL);
-
- msn_servconn_destroy(swboard->servconn);
-
- g_free(swboard);
-}
-
-void
-msn_switchboard_set_auth_key(MsnSwitchBoard *swboard, const char *key)
-{
- g_return_if_fail(swboard != NULL);
- g_return_if_fail(key != NULL);
-
- swboard->auth_key = g_strdup(key);
-}
-
-const char *
-msn_switchboard_get_auth_key(MsnSwitchBoard *swboard)
-{
- g_return_val_if_fail(swboard != NULL, NULL);
-
- return swboard->auth_key;
-}
-
-void
-msn_switchboard_set_session_id(MsnSwitchBoard *swboard, const char *id)
-{
- g_return_if_fail(swboard != NULL);
- g_return_if_fail(id != NULL);
-
- g_free(swboard->session_id);
- swboard->session_id = g_strdup(id);
-}
-
-const char *
-msn_switchboard_get_session_id(MsnSwitchBoard *swboard)
-{
- g_return_val_if_fail(swboard != NULL, NULL);
-
- return swboard->session_id;
-}
-
-int
-msn_switchboard_get_chat_id(void)
-{
- static int chat_id = 1;
-
- return chat_id++;
-}
-
-void
-msn_switchboard_set_invited(MsnSwitchBoard *swboard, gboolean invited)
-{
- g_return_if_fail(swboard != NULL);
-
- swboard->invited = invited;
-}
-
-gboolean
-msn_switchboard_is_invited(MsnSwitchBoard *swboard)
-{
- g_return_val_if_fail(swboard != NULL, FALSE);
-
- return swboard->invited;
-}
-
-/**************************************************************************
- * Utility
- **************************************************************************/
-
-static void
-send_clientcaps(MsnSwitchBoard *swboard)
-{
- MsnMessage *msg;
-
- msg = msn_message_new(MSN_MSG_CAPS);
- msn_message_set_content_type(msg, "text/x-clientcaps");
- msn_message_set_flag(msg, 'U');
- msn_message_set_bin_data(msg, MSN_CLIENTINFO, strlen(MSN_CLIENTINFO));
-
- msn_switchboard_send_msg(swboard, msg, TRUE);
-
- msn_message_unref(msg);
-}
-
-static void
-msn_switchboard_add_user(MsnSwitchBoard *swboard, const char *user)
-{
- MsnCmdProc *cmdproc;
- PurpleAccount *account;
- MsnUserList *userlist;
- MsnUser *msnuser;
- char *semicolon;
- char *passport;
-
- g_return_if_fail(swboard != NULL);
-
- cmdproc = swboard->cmdproc;
- account = cmdproc->session->account;
-
- semicolon = strchr(user, ';');
- /* We don't really care about the machine ID. */
- if (semicolon)
- passport = g_strndup(user, semicolon - user);
- else
- passport = g_strdup(user);
-
- userlist = swboard->session->userlist;
- msnuser = msn_userlist_find_user(userlist, passport);
-
- /* Don't add multiple endpoints to the conversation. */
- if (g_list_find_custom(swboard->users, passport, (GCompareFunc)msn_user_passport_cmp)) {
- g_free(passport);
- return;
- }
-
- /* Don't add ourselves either... */
- if (g_str_equal(passport, purple_account_get_username(account))) {
- g_free(passport);
- return;
- }
-
- if (!msnuser) {
- purple_debug_info("msn","User %s is not on our list.\n", passport);
- msnuser = msn_user_new(userlist, passport, NULL);
- } else
- msn_user_ref(msnuser);
-
- g_free(passport);
-
- swboard->users = g_list_prepend(swboard->users, msnuser);
- swboard->current_users++;
- swboard->empty = FALSE;
-
- if (purple_debug_is_verbose())
- purple_debug_info("msn", "user=[%s], total=%d\n",
- user, swboard->current_users);
-
- if (!(swboard->flag & MSN_SB_FLAG_IM) && (swboard->conv != NULL))
- {
- /* This is a helper switchboard. */
- purple_debug_error("msn", "switchboard_add_user: conv != NULL\n");
- return;
- }
-
- if ((swboard->conv != NULL) &&
- (purple_conversation_get_type(swboard->conv) == PURPLE_CONV_TYPE_CHAT))
- {
- purple_conv_chat_add_user(PURPLE_CONV_CHAT(swboard->conv), msnuser->passport, NULL,
- PURPLE_CBFLAGS_NONE, TRUE);
- msn_servconn_set_idle_timeout(swboard->servconn, 0);
- }
- else if (swboard->current_users > 1)
- {
- msn_servconn_set_idle_timeout(swboard->servconn, 0);
- if (swboard->conv == NULL ||
- purple_conversation_get_type(swboard->conv) != PURPLE_CONV_TYPE_CHAT)
- {
- GList *l;
-
-#if 0
- /* this is bad - it causes msn_switchboard_close to be called on the
- * switchboard we're in the middle of using :( */
- if (swboard->conv != NULL)
- purple_conversation_destroy(swboard->conv);
-#endif
-
- swboard->chat_id = msn_switchboard_get_chat_id();
- swboard->flag |= MSN_SB_FLAG_IM;
- swboard->conv = serv_got_joined_chat(account->gc,
- swboard->chat_id,
- "MSN Chat");
-
- for (l = swboard->users; l != NULL; l = l->next)
- {
- const char *tmp_user;
-
- tmp_user = ((MsnUser*)l->data)->passport;
-
- purple_conv_chat_add_user(PURPLE_CONV_CHAT(swboard->conv),
- tmp_user, NULL, PURPLE_CBFLAGS_NONE, TRUE);
- }
-
- purple_conv_chat_add_user(PURPLE_CONV_CHAT(swboard->conv),
- purple_account_get_username(account),
- NULL, PURPLE_CBFLAGS_NONE, TRUE);
-
- g_free(swboard->im_user);
- swboard->im_user = NULL;
- }
- }
- else if (swboard->conv == NULL)
- {
- swboard->conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM,
- msnuser->passport, account);
- }
- else
- {
- purple_debug_warning("msn", "switchboard_add_user: This should not happen!\n");
- }
-}
-
-static PurpleConversation *
-msn_switchboard_get_conv(MsnSwitchBoard *swboard)
-{
- PurpleAccount *account;
-
- g_return_val_if_fail(swboard != NULL, NULL);
-
- if (swboard->conv != NULL)
- return swboard->conv;
-
- purple_debug_error("msn", "Switchboard with unassigned conversation\n");
-
- account = swboard->session->account;
-
- return (swboard->conv = purple_conversation_new(PURPLE_CONV_TYPE_IM,
- account, swboard->im_user));
-}
-
-static void
-msn_switchboard_report_user(MsnSwitchBoard *swboard, PurpleMessageFlags flags, const char *msg)
-{
- PurpleConversation *conv;
-
- g_return_if_fail(swboard != NULL);
- g_return_if_fail(msg != NULL);
-
- if ((conv = msn_switchboard_get_conv(swboard)) != NULL)
- {
- purple_conversation_write(conv, NULL, msg, flags, time(NULL));
- }
-}
-
-static void
-swboard_error_helper(MsnSwitchBoard *swboard, int reason, const char *passport)
-{
- g_return_if_fail(swboard != NULL);
-
- purple_debug_warning("msn", "Error: Unable to call the user %s for reason %i\n",
- passport ? passport : "(null)", reason);
-
- /* TODO: if current_users > 0, this is probably a chat and an invite failed,
- * we should report that in the chat or something */
- if (swboard->current_users == 0)
- {
- swboard->error = reason;
- msn_switchboard_close(swboard);
- }
-}
-
-static void
-cal_error_helper(MsnTransaction *trans, int reason)
-{
- MsnSwitchBoard *swboard;
- const char *passport;
- char **params;
-
- params = g_strsplit(trans->params, " ", 0);
-
- passport = params[0];
-
- swboard = trans->data;
-
- purple_debug_warning("msn", "cal_error_helper: command %s failed for reason %i\n",trans->command,reason);
-
- swboard_error_helper(swboard, reason, passport);
-
- g_strfreev(params);
-}
-
-static gboolean
-msg_resend_cb(gpointer data)
-{
- MsnSwitchBoard *swboard = data;
-
- purple_debug_info("msn", "unqueuing unsent message to %s\n", swboard->im_user);
-
- if (msn_switchboard_request(swboard)) {
- msn_switchboard_request_add_user(swboard, swboard->im_user);
- swboard->reconn_timeout_h = 0;
- }
- return FALSE;
-}
-
-void
-msg_error_helper(MsnCmdProc *cmdproc, MsnMessage *msg, MsnMsgErrorType error)
-{
- MsnSwitchBoard *swboard;
-
- g_return_if_fail(cmdproc != NULL);
- g_return_if_fail(msg != NULL);
-
- if ((error != MSN_MSG_ERROR_SB) && (msg->nak_cb != NULL))
- msg->nak_cb(msg, msg->ack_data);
-
- swboard = cmdproc->data;
-
- /* This is not good, and should be fixed somewhere else. */
- g_return_if_fail(swboard != NULL);
-
- if (msg->type == MSN_MSG_TEXT)
- {
- const char *format, *str_reason;
- char *body_str, *body_enc, *pre, *post;
-
-#if 0
- if (swboard->conv == NULL)
- {
- if (msg->ack_ref)
- msn_message_unref(msg);
-
- return;
- }
-#endif
-
- if (error == MSN_MSG_ERROR_TIMEOUT)
- {
- str_reason = _("Message may have not been sent "
- "because a timeout occurred:");
- }
- else if (error == MSN_MSG_ERROR_SB)
- {
- MsnSession *session = swboard->session;
-
- if (!session->destroying && msg->retries && swboard->im_user &&
- (swboard->error == MSN_SB_ERROR_CONNECTION ||
- swboard->error == MSN_SB_ERROR_UNKNOWN)) {
- MsnSwitchBoard *new_sw = msn_session_find_swboard(session,
- swboard->im_user);
-
- if (new_sw == NULL || new_sw->reconn_timeout_h == 0) {
- new_sw = msn_switchboard_new(session);
- new_sw->im_user = g_strdup(swboard->im_user);
- new_sw->reconn_timeout_h = purple_timeout_add_seconds(3, msg_resend_cb, new_sw);
- new_sw->flag |= MSN_SB_FLAG_IM;
- }
-
- body_str = msn_message_to_string(msg);
- body_enc = g_markup_escape_text(body_str, -1);
- g_free(body_str);
-
- purple_debug_info("msn", "queuing unsent message to %s: %s\n",
- swboard->im_user, body_enc);
- g_free(body_enc);
- msn_send_im_message(session, msg);
- msg->retries--;
-
- return;
- }
-
- switch (swboard->error)
- {
- case MSN_SB_ERROR_OFFLINE:
- str_reason = _("Message could not be sent, "
- "not allowed while invisible:");
- break;
- case MSN_SB_ERROR_USER_OFFLINE:
- str_reason = _("Message could not be sent "
- "because the user is offline:");
- break;
- case MSN_SB_ERROR_CONNECTION:
- str_reason = _("Message could not be sent "
- "because a connection error occurred:");
- break;
- case MSN_SB_ERROR_TOO_FAST:
- str_reason = _("Message could not be sent "
- "because we are sending too quickly:");
- break;
- case MSN_SB_ERROR_AUTHFAILED:
- str_reason = _("Message could not be sent "
- "because we were unable to establish a "
- "session with the server. This is "
- "likely a server problem, try again in "
- "a few minutes:");
- break;
- default:
- str_reason = _("Message could not be sent "
- "because an error with "
- "the switchboard occurred:");
- break;
- }
- }
- else
- {
- str_reason = _("Message may have not been sent "
- "because an unknown error occurred:");
- }
-
- body_str = msn_message_to_string(msg);
- body_enc = g_markup_escape_text(body_str, -1);
- g_free(body_str);
-
- format = msn_message_get_header_value(msg, "X-MMS-IM-Format");
- msn_parse_format(format, &pre, &post);
- body_str = g_strdup_printf("%s%s%s", pre ? pre : "",
- body_enc ? body_enc : "", post ? post : "");
- g_free(body_enc);
- g_free(pre);
- g_free(post);
-
- msn_switchboard_report_user(swboard, PURPLE_MESSAGE_ERROR,
- str_reason);
- msn_switchboard_report_user(swboard, PURPLE_MESSAGE_RAW,
- body_str);
-
- g_free(body_str);
- }
-
- /* If a timeout occures we will want the msg around just in case we
- * receive the ACK after the timeout. */
- if (msg->ack_ref && error != MSN_MSG_ERROR_TIMEOUT)
- {
- swboard->ack_list = g_list_remove(swboard->ack_list, msg);
- msn_message_unref(msg);
- }
-}
-
-/**************************************************************************
- * Message Stuff
- **************************************************************************/
-
-/** Called when we receive an error of a message. */
-static void
-msg_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error)
-{
- msg_error_helper(cmdproc, trans->data, MSN_MSG_ERROR_UNKNOWN);
-}
-
-gboolean
-msn_switchboard_can_send(MsnSwitchBoard *swboard)
-{
- g_return_val_if_fail(swboard != NULL, FALSE);
-
- if (swboard->empty || !g_queue_is_empty(swboard->msg_queue))
- return FALSE;
-
- return TRUE;
-}
-
-/**************************************************************************
- * Switchboard Commands
- **************************************************************************/
-
-static void
-ans_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
- MsnSwitchBoard *swboard;
-
- swboard = cmdproc->data;
- swboard->ready = TRUE;
-}
-
-static void
-bye_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
- MsnSwitchBoard *swboard;
- const char *user;
-
- swboard = cmdproc->data;
- user = cmd->params[0];
-
- /* cmdproc->data is set to NULL when the switchboard is destroyed;
- * we may get a bye shortly thereafter. */
- g_return_if_fail(swboard != NULL);
-
- if (!(swboard->flag & MSN_SB_FLAG_IM) && (swboard->conv != NULL))
- purple_debug_error("msn", "bye_cmd: helper bug\n");
-
- if (swboard->conv == NULL)
- {
- /* This is a helper switchboard */
- msn_switchboard_destroy(swboard);
- }
- else if ((swboard->current_users > 1) ||
- (purple_conversation_get_type(swboard->conv) == PURPLE_CONV_TYPE_CHAT))
- {
- GList *passport;
- /* This is a switchboard used for a chat */
- purple_conv_chat_remove_user(PURPLE_CONV_CHAT(swboard->conv), user, NULL);
-
- passport = g_list_find_custom(swboard->users, user, (GCompareFunc)strcmp);
- if (passport)
- g_free(passport->data);
- else
- purple_debug_warning("msn", "Can't find user %s in the switchboard\n", user);
- swboard->users = g_list_delete_link(swboard->users, passport);
- swboard->current_users--;
- if (swboard->current_users == 0)
- msn_switchboard_destroy(swboard);
- }
- else
- {
- /* This is a switchboard used for a im session */
- msn_switchboard_destroy(swboard);
- }
-}
-
-static void
-iro_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
- MsnSwitchBoard *swboard;
-
- swboard = cmdproc->data;
-
- swboard->total_users = atoi(cmd->params[2]);
-
- msn_switchboard_add_user(swboard, cmd->params[3]);
-}
-
-static void
-joi_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
- MsnSession *session;
- MsnSwitchBoard *swboard;
- const char *passport;
-
- passport = cmd->params[0];
-
- session = cmdproc->session;
- swboard = cmdproc->data;
-
- msn_switchboard_add_user(swboard, passport);
-
- msn_sbconn_process_queue(swboard);
-
- if (!session->http_method)
- send_clientcaps(swboard);
-
- if (swboard->closed)
- msn_switchboard_close(swboard);
-}
-
-static void
-msg_cmd_post(MsnCmdProc *cmdproc, MsnCommand *cmd, char *payload, size_t len)
-{
- MsnMessage *msg;
-
- msg = msn_message_new_from_cmd(cmdproc->session, cmd);
-
- msn_message_parse_payload(msg, payload, len,
- MSG_LINE_DEM,MSG_BODY_DEM);
- if (purple_debug_is_verbose())
- msn_message_show_readable(msg, "SB RECV", FALSE);
-
- g_free (msg->remote_user);
- msg->remote_user = g_strdup(cmd->params[0]);
-
- msn_cmdproc_process_msg(cmdproc, msg);
-
- msn_message_unref(msg);
-}
-
-static void
-msg_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
- cmd->payload_len = atoi(cmd->params[2]);
- cmdproc->last_cmd->payload_cb = msg_cmd_post;
-}
-
-static void
-ubm_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
- purple_debug_misc("msn", "get UBM...\n");
- cmd->payload_len = atoi(cmd->params[5]);
- cmdproc->last_cmd->payload_cb = msg_cmd_post;
-}
-
-static void
-nak_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
- MsnMessage *msg;
-
- msg = cmd->trans->data;
- g_return_if_fail(msg != NULL);
-
- msg_error_helper(cmdproc, msg, MSN_MSG_ERROR_NAK);
- cmd->trans->data = NULL;
-}
-
-static void
-ack_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
- MsnSwitchBoard *swboard;
- MsnMessage *msg;
-
- msg = cmd->trans->data;
-
- if (msg->part && msg->part->ack_cb != NULL)
- msg->part->ack_cb(msg->part, msg->part->ack_data);
-
- swboard = cmdproc->data;
- if (swboard)
- swboard->ack_list = g_list_remove(swboard->ack_list, msg);
- msn_message_unref(msg);
- cmd->trans->data = NULL;
-}
-
-static void
-out_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
- PurpleConnection *gc;
- MsnSwitchBoard *swboard;
-
- gc = cmdproc->session->account->gc;
- swboard = cmdproc->data;
-
- if (swboard->current_users > 1)
- serv_got_chat_left(gc, swboard->chat_id);
-
- msn_switchboard_disconnect(swboard);
-}
-
-static void
-usr_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
- MsnSwitchBoard *swboard;
-
- swboard = cmdproc->data;
-
-#if 0
- GList *l;
-
- for (l = swboard->users; l != NULL; l = l->next)
- {
- const char *user;
- user = l->data;
-
- msn_cmdproc_send(cmdproc, "CAL", "%s", user);
- }
-#endif
-
- swboard->ready = TRUE;
- msn_cmdproc_process_queue(cmdproc);
-}
-
-/**************************************************************************
- * Message Handlers
- **************************************************************************/
-static void
-clientcaps_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
-{
-#if 0
- MsnSession *session;
- MsnSwitchBoard *swboard;
- MsnUser *user;
- GHashTable *clientcaps;
- const char *value;
-
- char *passport = msg->sender;
-
- session = cmdproc->session;
- swboard = cmdproc->servconn->swboard;
-
- clientcaps = msn_message_get_hashtable_from_body(msg);
-#endif
-}
-
-void
-msn_switchboard_show_ink(MsnSwitchBoard *swboard, const char *passport,
- const char *data)
-{
- PurpleConnection *gc;
- guchar *image_data;
- size_t image_len;
- int imgid;
- char *image_msg;
-
- if (!purple_str_has_prefix(data, "base64:"))
- {
- purple_debug_error("msn", "Ignoring Ink not in Base64 format.\n");
- return;
- }
-
- gc = purple_account_get_connection(swboard->session->account);
-
- data += sizeof("base64:") - 1;
- image_data = purple_base64_decode(data, &image_len);
- if (!image_data || !image_len)
- {
- purple_debug_error("msn", "Unable to decode Ink from Base64 format.\n");
- return;
- }
-
- imgid = purple_imgstore_add_with_id(image_data, image_len, NULL);
- image_msg = g_strdup_printf("<IMG ID='%d'>", imgid);
-
- if (swboard->current_users > 1 ||
- ((swboard->conv != NULL) &&
- purple_conversation_get_type(swboard->conv) == PURPLE_CONV_TYPE_CHAT))
- serv_got_chat_in(gc, swboard->chat_id, passport, 0, image_msg,
- time(NULL));
- else
- serv_got_im(gc, passport, image_msg, 0, time(NULL));
-
- purple_imgstore_unref_by_id(imgid);
- g_free(image_msg);
-}
-
-/**************************************************************************
- * Connect stuff
- **************************************************************************/
-static void
-ans_usr_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error);
-
-static void
-connect_cb(MsnServConn *servconn)
-{
- MsnSwitchBoard *swboard;
- MsnTransaction *trans;
- MsnCmdProc *cmdproc;
- PurpleAccount *account;
- char *username;
-
- cmdproc = servconn->cmdproc;
- g_return_if_fail(cmdproc != NULL);
-
- account = cmdproc->session->account;
- swboard = cmdproc->data;
- g_return_if_fail(swboard != NULL);
-
- username = g_strdup_printf("%s;{%s}",
- purple_account_get_username(account),
- servconn->session->guid);
-
- if (msn_switchboard_is_invited(swboard))
- {
- swboard->empty = FALSE;
-
- trans = msn_transaction_new(cmdproc, "ANS", "%s %s %s",
- username,
- swboard->auth_key, swboard->session_id);
- }
- else
- {
- trans = msn_transaction_new(cmdproc, "USR", "%s %s",
- username,
- swboard->auth_key);
- }
-
- msn_transaction_set_error_cb(trans, ans_usr_error);
- msn_transaction_set_data(trans, swboard);
- msn_cmdproc_send_trans(cmdproc, trans);
-
- g_free(username);
-}
-
-static void
-ans_usr_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error)
-{
- MsnSwitchBoard *swboard;
- char **params;
- char *passport;
- int reason = MSN_SB_ERROR_UNKNOWN;
-
- if (error == 911)
- {
- reason = MSN_SB_ERROR_AUTHFAILED;
- }
-
- purple_debug_warning("msn", "ans_usr_error: command %s gave error %i\n", trans->command, error);
-
- params = g_strsplit(trans->params, " ", 0);
- passport = params[0];
- swboard = trans->data;
-
- swboard_error_helper(swboard, reason, passport);
-
- g_strfreev(params);
-}
-
-static void
-disconnect_cb(MsnServConn *servconn)
-{
- MsnSwitchBoard *swboard;
-
- swboard = servconn->cmdproc->data;
- g_return_if_fail(swboard != NULL);
-
- msn_servconn_set_disconnect_cb(swboard->servconn, NULL);
-
- msn_switchboard_destroy(swboard);
-}
-
-gboolean
-msn_switchboard_connect(MsnSwitchBoard *swboard, const char *host, int port)
-{
- g_return_val_if_fail(swboard != NULL, FALSE);
-
- msn_servconn_set_connect_cb(swboard->servconn, connect_cb);
- msn_servconn_set_disconnect_cb(swboard->servconn, disconnect_cb);
-
- return msn_servconn_connect(swboard->servconn, host, port, FALSE);
-}
-
-void
-msn_switchboard_disconnect(MsnSwitchBoard *swboard)
-{
- g_return_if_fail(swboard != NULL);
-
- msn_servconn_disconnect(swboard->servconn);
-}
-
-/**************************************************************************
- * Call stuff
- **************************************************************************/
-static void
-got_cal(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
-#if 0
- MsnSwitchBoard *swboard;
- const char *user;
-
- swboard = cmdproc->data;
-
- user = cmd->params[0];
-
- msn_switchboard_add_user(swboard, user);
-#endif
-}
-
-static void
-cal_timeout(MsnCmdProc *cmdproc, MsnTransaction *trans)
-{
- purple_debug_warning("msn", "cal_timeout: command %s timed out\n", trans->command);
-
- cal_error_helper(trans, MSN_SB_ERROR_UNKNOWN);
-}
-
-static void
-cal_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error)
-{
- int reason = MSN_SB_ERROR_UNKNOWN;
- MsnMessage *msg;
- MsnSwitchBoard *swboard = trans->data;
-
- if (error == 215)
- {
- purple_debug_info("msn", "Invited user already in switchboard\n");
- return;
- }
- else if (error == 217)
- {
- reason = MSN_SB_ERROR_USER_OFFLINE;
- }
-
- purple_debug_warning("msn", "cal_error: command %s gave error %i\n", trans->command, error);
-
- while ((msg = g_queue_pop_head(swboard->msg_queue)) != NULL){
- purple_debug_warning("msn", "Unable to send msg: {%s}\n", msg->body);
- /* The messages could not be sent due to a switchboard error */
- swboard->error = MSN_SB_ERROR_USER_OFFLINE;
- msg_error_helper(swboard->cmdproc, msg,
- MSN_MSG_ERROR_SB);
- }
- cal_error_helper(trans, reason);
-}
-
-void
-msn_switchboard_request_add_user(MsnSwitchBoard *swboard, const char *user)
-{
- MsnTransaction *trans;
- MsnCmdProc *cmdproc;
-
- g_return_if_fail(swboard != NULL);
-
- cmdproc = swboard->cmdproc;
-
- trans = msn_transaction_new(cmdproc, "CAL", "%s", user);
- /* this doesn't do anything, but users seem to think that
- * 'Unhandled command' is some kind of error, so we don't report it */
- msn_transaction_add_cb(trans, "CAL", got_cal);
-
- msn_transaction_set_data(trans, swboard);
- msn_transaction_set_timeout_cb(trans, cal_timeout);
-
- if (swboard->ready)
- msn_cmdproc_send_trans(cmdproc, trans);
- else
- msn_cmdproc_queue_trans(cmdproc, trans);
-}
-
-/**************************************************************************
- * Create & Transfer stuff
- **************************************************************************/
-
-static void
-got_swboard(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
- MsnSwitchBoard *swboard;
- char *host;
- int port;
- swboard = cmd->trans->data;
-
- if (g_list_find(cmdproc->session->switches, swboard) == NULL)
- /* The conversation window was closed. */
- return;
-
- purple_debug_info("msn", "Switchboard:auth:{%s} socket:{%s}\n", cmd->params[4], cmd->params[2]);
- msn_switchboard_set_auth_key(swboard, cmd->params[4]);
-
- msn_parse_socket(cmd->params[2], &host, &port);
-
- if (!msn_switchboard_connect(swboard, host, port))
- msn_switchboard_destroy(swboard);
-
- g_free(host);
-}
-
-static void
-xfr_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error)
-{
- MsnSwitchBoard *swboard;
- int reason = MSN_SB_ERROR_UNKNOWN;
-
- if (error == 913)
- reason = MSN_SB_ERROR_OFFLINE;
- else if (error == 800)
- reason = MSN_SB_ERROR_TOO_FAST;
-
- swboard = trans->data;
-
- purple_debug_info("msn",
- "xfr_error %i for %s: trans %p, command %s, reason %i\n",
- error, (swboard->im_user ? swboard->im_user : "(null)"), trans,
- (trans->command ? trans->command : "(null)"), reason);
-
- swboard_error_helper(swboard, reason, swboard->im_user);
-}
-
-gboolean
-msn_switchboard_request(MsnSwitchBoard *swboard)
-{
- MsnCmdProc *cmdproc;
- MsnTransaction *trans;
-
- g_return_val_if_fail(swboard != NULL, FALSE);
-
- cmdproc = swboard->session->notification->cmdproc;
-
- trans = msn_transaction_new(cmdproc, "XFR", "%s", "SB");
- msn_transaction_add_cb(trans, "XFR", got_swboard);
-
- msn_transaction_set_data(trans, swboard);
- msn_transaction_set_error_cb(trans, xfr_error);
-
- return msn_cmdproc_send_trans(cmdproc, trans);
-}
-
-void
-msn_switchboard_close(MsnSwitchBoard *swboard)
-{
- g_return_if_fail(swboard != NULL);
-
- if (swboard->error != MSN_SB_ERROR_NONE)
- {
- msn_switchboard_destroy(swboard);
- }
- else if (g_queue_is_empty(swboard->msg_queue) ||
- !swboard->session->connected)
- {
- MsnCmdProc *cmdproc;
- MsnTransaction *trans;
- cmdproc = swboard->cmdproc;
- trans = msn_transaction_new(cmdproc, "OUT", NULL);
- msn_transaction_set_saveable(trans, FALSE);
- msn_cmdproc_send_trans(cmdproc, trans);
-
- msn_switchboard_destroy(swboard);
- }
- else
- {
- swboard->closed = TRUE;
- }
-}
-
-void
-msn_switchboard_release(MsnSwitchBoard *swboard, MsnSBFlag flag)
-{
- g_return_if_fail(swboard != NULL);
-
- swboard->flag &= ~flag;
-
- if (flag == MSN_SB_FLAG_IM)
- /* Forget any conversation that used to be associated with this
- * swboard. */
- swboard->conv = NULL;
-
- if (swboard->flag == 0)
- /* Nothing else is using this switchboard, so close it */
- msn_switchboard_close(swboard);
-}
-
-/**************************************************************************
- * Init stuff
- **************************************************************************/
-
-void
-msn_switchboard_init(void)
-{
- cbs_table = msn_table_new();
-
- msn_table_add_cmd(cbs_table, "ANS", "ANS", ans_cmd);
- msn_table_add_cmd(cbs_table, "ANS", "IRO", iro_cmd);
-
- msn_table_add_cmd(cbs_table, "MSG", "ACK", ack_cmd);
- msn_table_add_cmd(cbs_table, "MSG", "NAK", nak_cmd);
-
- msn_table_add_cmd(cbs_table, "USR", "USR", usr_cmd);
-
- msn_table_add_cmd(cbs_table, NULL, "MSG", msg_cmd);
- msn_table_add_cmd(cbs_table, NULL, "UBM", ubm_cmd);
- msn_table_add_cmd(cbs_table, NULL, "JOI", joi_cmd);
- msn_table_add_cmd(cbs_table, NULL, "BYE", bye_cmd);
- msn_table_add_cmd(cbs_table, NULL, "OUT", out_cmd);
-
-#if 0
- /* They might skip the history */
- msn_table_add_cmd(cbs_table, NULL, "ACK", NULL);
-#endif
-
- msn_table_add_error(cbs_table, "MSG", msg_error);
- msn_table_add_error(cbs_table, "CAL", cal_error);
-
- /* Register the message type callbacks. */
- msn_table_add_msg_type(cbs_table, "text/plain",
- msn_plain_msg);
- msn_table_add_msg_type(cbs_table, "text/x-msmsgscontrol",
- msn_control_msg);
- msn_table_add_msg_type(cbs_table, "text/x-clientcaps",
- clientcaps_msg);
- msn_table_add_msg_type(cbs_table, "text/x-clientinfo",
- clientcaps_msg);
- msn_table_add_msg_type(cbs_table, "application/x-msnmsgrp2p",
- msn_p2p_msg);
- msn_table_add_msg_type(cbs_table, "text/x-mms-emoticon",
- msn_emoticon_msg);
- msn_table_add_msg_type(cbs_table, "text/x-mms-animemoticon",
- msn_emoticon_msg);
- msn_table_add_msg_type(cbs_table, "text/x-msnmsgr-datacast",
- msn_datacast_msg);
- msn_table_add_msg_type(cbs_table, "text/x-msmsgsinvite",
- msn_invite_msg);
- msn_table_add_msg_type(cbs_table, "image/gif",
- msn_handwritten_msg);
-}
-
-void
-msn_switchboard_end(void)
-{
- msn_table_destroy(cbs_table);
-}
diff --git a/libpurple/protocols/msn/switchboard.h b/libpurple/protocols/msn/switchboard.h
deleted file mode 100644
index 5a125384dd..0000000000
--- a/libpurple/protocols/msn/switchboard.h
+++ /dev/null
@@ -1,266 +0,0 @@
-/**
- * @file switchboard.h MSN switchboard functions
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-#ifndef MSN_SWITCHBOARD_H
-#define MSN_SWITCHBOARD_H
-
-typedef struct _MsnSwitchBoard MsnSwitchBoard;
-
-/**
- * A switchboard error.
- */
-typedef enum
-{
- MSN_SB_ERROR_NONE, /**< No error. */
- MSN_SB_ERROR_CAL, /**< The user could not join (answer the call). */
- MSN_SB_ERROR_OFFLINE, /**< The account is offline. */
- MSN_SB_ERROR_USER_OFFLINE, /**< The user to call is offline. */
- MSN_SB_ERROR_CONNECTION, /**< There was a connection error. */
- MSN_SB_ERROR_TOO_FAST, /**< We are sending too fast */
- MSN_SB_ERROR_AUTHFAILED, /**< Authentication failed joining the switchboard session */
- MSN_SB_ERROR_UNKNOWN /**< An unknown error occurred. */
-} MsnSBErrorType;
-
-/**
- * A switchboard flag.
- */
-typedef enum
-{
- MSN_SB_FLAG_IM = 0x01, /**< This switchboard is being used for a conversation. */
- MSN_SB_FLAG_FT = 0x02 /**< This switchboard is being used for file transfer. */
-} MsnSBFlag;
-
-#include "cmdproc.h"
-#include "msg.h"
-#include "servconn.h"
-#include "session.h"
-
-/**
- * A switchboard.
- *
- * A place where a bunch of users send messages to the rest of the users.
- */
-struct _MsnSwitchBoard
-{
- MsnSession *session; /**< Our parent session. */
- MsnServConn *servconn; /**< The physical connection for this switchboard. */
- MsnCmdProc *cmdproc; /**< Convenience variable for servconn->cmdproc. */
- char *im_user;
-
- MsnSBFlag flag;
- char *auth_key;
- char *session_id;
-
- PurpleConversation *conv; /**< The conversation that displays the
- messages of this switchboard, or @c NULL if
- this is a helper switchboard. */
-
- gboolean empty; /**< A flag that states if the swithcboard has no
- users in it. */
- gboolean invited; /**< A flag that states if we were invited to the
- switchboard. */
- gboolean ready; /**< A flag that states if this switchboard is
- ready to be used. */
- gboolean closed; /**< A flag that states if the switchboard has
- been closed by the user. */
- gboolean destroying; /**< A flag that states if the switchboard is
- alredy on the process of destruction. */
-
- int current_users;
- int total_users;
- GList *users;
-
- int chat_id;
-
- GQueue *msg_queue; /**< Queue of messages to send. */
- GList *ack_list; /**< List of messages waiting for an ack. */
-
- MsnSBErrorType error; /**< The error that occurred in this switchboard
- (if applicable). */
- GList *slplinks; /**< The list of slplinks that are using this switchboard. */
- guint reconn_timeout_h;
-};
-
-/**
- * Initialize the variables for switchboard creation.
- */
-void msn_switchboard_init(void);
-
-/**
- * Destroy the variables for switchboard creation.
- */
-void msn_switchboard_end(void);
-
-/**
- * Creates a new switchboard.
- *
- * @param session The MSN session.
- *
- * @return The new switchboard.
- */
-MsnSwitchBoard *msn_switchboard_new(MsnSession *session);
-
-/**
- * Destroys a switchboard.
- *
- * @param swboard The switchboard to destroy.
- */
-void msn_switchboard_destroy(MsnSwitchBoard *swboard);
-
-/**
- * Sets the auth key the switchboard must use when connecting.
- *
- * @param swboard The switchboard.
- * @param key The auth key.
- */
-void msn_switchboard_set_auth_key(MsnSwitchBoard *swboard, const char *key);
-
-/**
- * Returns the auth key the switchboard must use when connecting.
- *
- * @param swboard The switchboard.
- *
- * @return The auth key.
- */
-const char *msn_switchboard_get_auth_key(MsnSwitchBoard *swboard);
-
-/**
- * Sets the session ID the switchboard must use when connecting.
- *
- * @param swboard The switchboard.
- * @param id The session ID.
- */
-void msn_switchboard_set_session_id(MsnSwitchBoard *swboard, const char *id);
-
-/**
- * Returns the session ID the switchboard must use when connecting.
- *
- * @param swboard The switchboard.
- *
- * @return The session ID.
- */
-const char *msn_switchboard_get_session_id(MsnSwitchBoard *swboard);
-
-/**
- * Returns the next chat ID for use by a switchboard.
- *
- * @return The chat ID.
- */
-int msn_switchboard_get_chat_id(void);
-
-/**
- * Sets whether or not we were invited to this switchboard.
- *
- * @param swboard The switchboard.
- * @param invite @c TRUE if invited, @c FALSE otherwise.
- */
-void msn_switchboard_set_invited(MsnSwitchBoard *swboard, gboolean invited);
-
-/**
- * Returns whether or not we were invited to this switchboard.
- *
- * @param swboard The switchboard.
- *
- * @return @c TRUE if invited, @c FALSE otherwise.
- */
-gboolean msn_switchboard_is_invited(MsnSwitchBoard *swboard);
-
-/**
- * Connects to a switchboard.
- *
- * @param swboard The switchboard.
- * @param host The switchboard server host.
- * @param port The switcbharod server port.
- *
- * @return @c TRUE if able to connect, or @c FALSE otherwise.
- */
-gboolean msn_switchboard_connect(MsnSwitchBoard *swboard,
- const char *host, int port);
-
-/**
- * Disconnects from a switchboard.
- *
- * @param swboard The switchboard to disconnect from.
- */
-void msn_switchboard_disconnect(MsnSwitchBoard *swboard);
-
-/**
- * Closes the switchboard.
- *
- * Called when a conversation is closed.
- *
- * @param swboard The switchboard to close.
- */
-void msn_switchboard_close(MsnSwitchBoard *swboard);
-
-/**
- * Release a switchboard from a certain function.
- *
- * @param swboard The switchboard to release.
- * @param flag The flag that states the function.
- */
-void msn_switchboard_release(MsnSwitchBoard *swboard, MsnSBFlag flag);
-
-/**
- * Returns whether or not we currently can send a message through this
- * switchboard.
- *
- * @param swboard The switchboard.
- *
- * @return @c TRUE if a message can be sent, @c FALSE otherwise.
- */
-gboolean msn_switchboard_can_send(MsnSwitchBoard *swboard);
-
-/**
- * Sends a message through this switchboard.
- *
- * @param swboard The switchboard.
- * @param msg The message.
- * @param queue A flag that states if we want this message to be queued (in
- * the case it cannot currently be sent).
- *
- * @return @c TRUE if a message can be sent, @c FALSE otherwise.
- */
-void msn_switchboard_send_msg(MsnSwitchBoard *swboard, MsnMessage *msg,
- gboolean queue);
-
-void
-msg_error_helper(MsnCmdProc *cmdproc, MsnMessage *msg, MsnMsgErrorType error);
-
-gboolean msn_switchboard_chat_leave(MsnSwitchBoard *swboard);
-gboolean msn_switchboard_chat_invite(MsnSwitchBoard *swboard, const char *who);
-
-gboolean msn_switchboard_request(MsnSwitchBoard *swboard);
-void msn_switchboard_request_add_user(MsnSwitchBoard *swboard, const char *user);
-
-/**
- * Shows an ink message from this switchboard.
- *
- * @param swboard The switchboard.
- * @param passport The user that sent the ink.
- * @param data The ink data.
- */
-void msn_switchboard_show_ink(MsnSwitchBoard *swboard, const char *passport,
- const char *data);
-
-#endif /* MSN_SWITCHBOARD_H */
diff --git a/libpurple/protocols/msn/table.c b/libpurple/protocols/msn/table.c
deleted file mode 100644
index c0642c7f28..0000000000
--- a/libpurple/protocols/msn/table.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/**
- * @file table.c MSN helper structure
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-#include "msn.h"
-#include "table.h"
-
-static void
-null_cmd_cb(MsnCmdProc *cmdproc, MsnCommand *cmd)
-{
-}
-
-static void
-null_error_cb(MsnCmdProc *cmdproc, MsnTransaction *trans, int error)
-{
-}
-
-MsnTable *
-msn_table_new()
-{
- MsnTable *table;
-
- table = g_new0(MsnTable, 1);
-
- table->cmds = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, (GDestroyNotify)g_hash_table_destroy);
- table->msgs = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL);
- table->errors = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL);
-
- table->async = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL);
- table->fallback = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL);
-
- return table;
-}
-
-void
-msn_table_destroy(MsnTable *table)
-{
- g_return_if_fail(table != NULL);
-
- g_hash_table_destroy(table->cmds);
- g_hash_table_destroy(table->msgs);
- g_hash_table_destroy(table->errors);
-
- g_hash_table_destroy(table->async);
- g_hash_table_destroy(table->fallback);
-
- g_free(table);
-}
-
-void
-msn_table_add_cmd(MsnTable *table,
- char *command, char *answer, MsnTransCb cb)
-{
- GHashTable *cbs;
-
- g_return_if_fail(table != NULL);
- g_return_if_fail(answer != NULL);
-
- cbs = NULL;
-
- if (command == NULL)
- {
- cbs = table->async;
- }
- else if (strcmp(command, "fallback") == 0)
- {
- cbs = table->fallback;
- }
- else
- {
- cbs = g_hash_table_lookup(table->cmds, command);
-
- if (cbs == NULL)
- {
- cbs = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL);
- g_hash_table_insert(table->cmds, command, cbs);
- }
- }
-
- if (cb == NULL)
- cb = null_cmd_cb;
-
- g_hash_table_insert(cbs, answer, cb);
-}
-
-void
-msn_table_add_error(MsnTable *table,
- char *answer, MsnErrorCb cb)
-{
- g_return_if_fail(table != NULL);
- g_return_if_fail(answer != NULL);
-
- if (cb == NULL)
- cb = null_error_cb;
-
- g_hash_table_insert(table->errors, answer, cb);
-}
-
-void
-msn_table_add_msg_type(MsnTable *table,
- char *type, MsnMsgTypeCb cb)
-{
- g_return_if_fail(table != NULL);
- g_return_if_fail(type != NULL);
- g_return_if_fail(cb != NULL);
-
-#if 0
- if (cb == NULL)
- cb = null_msg_cb;
-#endif
-
- g_hash_table_insert(table->msgs, type, cb);
-}
diff --git a/libpurple/protocols/msn/table.h b/libpurple/protocols/msn/table.h
deleted file mode 100644
index 83d9954d13..0000000000
--- a/libpurple/protocols/msn/table.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/**
- * @file table.h MSN helper structure
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-#ifndef MSN_TABLE_H
-#define MSN_TABLE_H
-
-typedef struct _MsnTable MsnTable;
-
-#include "cmdproc.h"
-#include "transaction.h"
-#include "msg.h"
-
-typedef void (*MsnMsgTypeCb)(MsnCmdProc *cmdproc, MsnMessage *msg);
-
-struct _MsnTable
-{
- GHashTable *cmds; /**< Callbacks that manage command response. */
- GHashTable *msgs; /**< Callbacks that manage incoming messages. */
- GHashTable *errors; /**< Callbacks that manage command errors. */
-
- GHashTable *async; /**< Callbacks that manage incoming asyncronous messages. */
- /* TODO: Does this one is really needed? */
- GHashTable *fallback; /**< Fallback callback. */
-};
-
-/**
- * Create a new instance of a MsnTable which map commands, errors and messages
- * with callbacks that will handle it.
- *
- * @return A new MsnTable.
- */
-MsnTable *msn_table_new(void);
-
-/**
- * Destroy a MsnTable.
- *
- * @param table The MsnTable to be destroyed.
- */
-void msn_table_destroy(MsnTable *table);
-
-/**
- * Relate an incomming command from server with a callback able to handle
- * the event.
- *
- * @param table The MsnTable.
- * @param command If NULL this add an incoming asyncronous command set in answer.
- * Else, the command sent.
- * @param answer The server answer to 'command'. If 'command' is NULL,
- * the asyncronous command sent by the server.
- * @param cb Callback to handle this event.
- */
-void msn_table_add_cmd(MsnTable *table, char *command, char *answer,
- MsnTransCb cb);
-
-/**
- * Set a callback to handle incoming command errors.
- *
- * @param table The MsnTable.
- * @param answer Incoming command with error.
- * @param cb Callback to handle this error.
- */
-void msn_table_add_error(MsnTable *table, char *answer, MsnErrorCb cb);
-
-/**
- * Relate a message Content-type with a callback able to handle it.
- *
- * @param table The MsnTable.
- * @param type The Message Content-Type.
- * @param cb Callback to handle this Content-type.
- */
-void msn_table_add_msg_type(MsnTable *table, char *type, MsnMsgTypeCb cb);
-
-#endif /* MSN_TABLE_H */
diff --git a/libpurple/protocols/msn/tlv.c b/libpurple/protocols/msn/tlv.c
deleted file mode 100644
index d05cf4b9e2..0000000000
--- a/libpurple/protocols/msn/tlv.c
+++ /dev/null
@@ -1,458 +0,0 @@
-/**
- * @file tlv.c MSN TLV functions
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-
-#include "tlv.h"
-#include "msnutils.h"
-
-static msn_tlv_t *
-createtlv(guint8 type, guint8 length, guint8 *value)
-{
- msn_tlv_t *ret;
-
- ret = g_new(msn_tlv_t, 1);
- ret->type = type;
- ret->length = length;
- ret->value = value;
-
- return ret;
-}
-
-static void
-freetlv(msn_tlv_t *oldtlv)
-{
- g_free(oldtlv->value);
- g_free(oldtlv);
-}
-
-GSList *
-msn_tlvlist_read(const char *bs, size_t bs_len)
-{
- GSList *list = NULL;
-
- while (bs_len > 0) {
- guint8 type, length;
- msn_tlv_t *tlv;
-
- if (bs_len == 3 && *bs == 0) {
- /* Padding to multiple of 4 */
- break;
- } else if (bs_len == 2 && *bs == 0) {
- /* Padding to multiple of 4 */
- break;
- } else if (bs_len == 1) {
- if (*bs == 0) {
- /* Padding to multiple of 4 */
- break;
- } else {
- /* TLV is not small enough to fit here */
- msn_tlvlist_free(list);
- return NULL;
- }
- }
-
- type = msn_pop8(bs);
- length = msn_pop8(bs);
- bs_len -= 2;
-
- if (length > bs_len) {
- msn_tlvlist_free(list);
- return NULL;
- }
-
- tlv = createtlv(type, length, NULL);
- if (length > 0) {
- tlv->value = g_memdup(bs, length);
- if (!tlv->value) {
- freetlv(tlv);
- msn_tlvlist_free(list);
- return NULL;
- }
- }
-
- bs_len -= length;
- bs += length;
-
- list = g_slist_prepend(list, tlv);
- }
-
- return g_slist_reverse(list);
-}
-
-GSList *
-msn_tlvlist_copy(GSList *orig)
-{
- GSList *new = NULL;
- msn_tlv_t *tlv;
-
- while (orig != NULL) {
- tlv = orig->data;
- msn_tlvlist_add_raw(&new, tlv->type, tlv->length, (const char *)tlv->value);
- orig = orig->next;
- }
-
- return new;
-}
-
-gboolean
-msn_tlvlist_equal(GSList *one, GSList *two)
-{
- while (one && two) {
- msn_tlv_t *a = one->data;
- msn_tlv_t *b = two->data;
-
- if (a->type != b->type)
- return FALSE;
- else if (a->length != b->length)
- return FALSE;
- else if (!a->value && b->value)
- return FALSE;
- else if (a->value && !b->value)
- return FALSE;
- else if (a->value && b->value && memcmp(a->value, b->value, a->length) != 0)
- return FALSE;
-
- one = one->next;
- two = two->next;
- }
-
- return one == two;
-}
-
-void
-msn_tlvlist_free(GSList *list)
-{
- while (list != NULL) {
- freetlv(list->data);
- list = g_slist_delete_link(list, list);
- }
-}
-
-int
-msn_tlvlist_count(GSList *list)
-{
- return g_slist_length(list);
-}
-
-size_t
-msn_tlvlist_size(GSList *list)
-{
- int size;
-
- if (list == NULL)
- return 0;
-
- for (size = 0; list; list = list->next)
- size += (2 + ((msn_tlv_t *)list->data)->length);
-
- return size;
-}
-
-int
-msn_tlvlist_add_raw(GSList **list, const guint8 type, const guint8 length, const char *value)
-{
- msn_tlv_t *tlv;
-
- if (list == NULL)
- return 0;
-
- tlv = createtlv(type, length, NULL);
- if (length > 0)
- tlv->value = g_memdup(value, length);
-
- *list = g_slist_append(*list, tlv);
-
- return tlv->length;
-}
-
-int
-msn_tlvlist_add_8(GSList **list, const guint8 type, const guint8 value)
-{
- char v8[1];
-
- msn_write8(v8, value);
-
- return msn_tlvlist_add_raw(list, type, 1, v8);
-}
-
-int
-msn_tlvlist_add_16(GSList **list, const guint8 type, const guint16 value)
-{
- char v16[2];
-
- msn_write16be(v16, value);
-
- return msn_tlvlist_add_raw(list, type, 2, v16);
-}
-
-int
-msn_tlvlist_add_32(GSList **list, const guint8 type, const guint32 value)
-{
- char v32[4];
-
- msn_write32be(v32, value);
-
- return msn_tlvlist_add_raw(list, type, 4, v32);
-}
-
-int
-msn_tlvlist_add_str(GSList **list, const guint8 type, const char *value)
-{
- return msn_tlvlist_add_raw(list, type, strlen(value), value);
-}
-
-int
-msn_tlvlist_add_empty(GSList **list, const guint8 type)
-{
- return msn_tlvlist_add_raw(list, type, 0, NULL);
-}
-
-int
-msn_tlvlist_add_tlv(GSList **list, const msn_tlv_t *tlv)
-{
- return msn_tlvlist_add_raw(list, tlv->type, tlv->length, (const char *)tlv->value);
-}
-
-int
-msn_tlvlist_replace_raw(GSList **list, const guint8 type, const guint8 length, const char *value)
-{
- GSList *cur;
- msn_tlv_t *tlv;
-
- if (list == NULL)
- return 0;
-
- for (cur = *list; cur != NULL; cur = cur->next) {
- tlv = cur->data;
- if (tlv->type == type)
- break;
- }
-
- if (cur == NULL)
- /* TLV does not exist, so add a new one */
- return msn_tlvlist_add_raw(list, type, length, value);
-
- g_free(tlv->value);
- tlv->length = length;
- if (length > 0) {
- tlv->value = g_memdup(value, length);
- } else
- tlv->value = NULL;
-
- return length;
-}
-
-int
-msn_tlvlist_replace_str(GSList **list, const guint8 type, const char *str)
-{
- return msn_tlvlist_replace_raw(list, type, strlen(str), str);
-}
-
-int
-msn_tlvlist_replace_empty(GSList **list, const guint8 type)
-{
- return msn_tlvlist_replace_raw(list, type, 0, NULL);
-}
-
-int
-msn_tlvlist_replace_8(GSList **list, const guint8 type, const guint8 value)
-{
- char v8[1];
-
- msn_write8(v8, value);
-
- return msn_tlvlist_replace_raw(list, type, 1, v8);
-}
-
-int
-msn_tlvlist_replace_32(GSList **list, const guint8 type, const guint32 value)
-{
- char v32[4];
-
- msn_write32be(v32, value);
-
- return msn_tlvlist_replace_raw(list, type, 4, v32);
-}
-
-int
-msn_tlvlist_replace_tlv(GSList **list, const msn_tlv_t *tlv)
-{
- return msn_tlvlist_replace_raw(list, tlv->type, tlv->length, (const char *)tlv->value);
-}
-
-void
-msn_tlvlist_remove(GSList **list, const guint8 type)
-{
- GSList *cur, *next;
- msn_tlv_t *tlv;
-
- if (list == NULL || *list == NULL)
- return;
-
- cur = *list;
- while (cur != NULL) {
- tlv = cur->data;
- next = cur->next;
-
- if (tlv->type == type) {
- /* Delete this TLV */
- *list = g_slist_delete_link(*list, cur);
- g_free(tlv->value);
- g_free(tlv);
- }
-
- cur = next;
- }
-}
-
-char *
-msn_tlvlist_write(GSList *list, guint8 *out_len)
-{
- char *buf;
- char *tmp;
- size_t bytes_left;
- size_t total_len;
-
- tmp = buf = g_malloc(256);
- bytes_left = total_len = 256;
-
- for (; list; list = g_slist_next(list)) {
- msn_tlv_t *tlv = (msn_tlv_t *)list->data;
-
- if (G_UNLIKELY((gsize)tlv->length + 2 > bytes_left)) {
- buf = g_realloc(buf, total_len + 256);
- bytes_left += 256;
- total_len += 256;
- tmp = buf + (total_len - bytes_left);
- }
-
- msn_push8(tmp, tlv->type);
- msn_push8(tmp, tlv->length);
- memcpy(tmp, tlv->value, tlv->length);
- tmp += tlv->length;
-
- bytes_left -= (tlv->length + 2);
- }
-
- /* Align length to multiple of 4 */
- total_len = total_len - bytes_left;
- bytes_left = 4 - total_len % 4;
- if (bytes_left != 4)
- memset(tmp, 0, bytes_left);
- else
- bytes_left = 0;
-
- *out_len = total_len + bytes_left;
-
- return buf;
-}
-
-msn_tlv_t *
-msn_tlv_gettlv(GSList *list, const guint8 type, const int nth)
-{
- msn_tlv_t *tlv;
- int i;
-
- for (i = 0; list != NULL; list = list->next) {
- tlv = list->data;
- if (tlv->type == type)
- i++;
- if (i >= nth)
- return tlv;
- }
-
- return NULL;
-}
-
-int
-msn_tlv_getlength(GSList *list, const guint8 type, const int nth)
-{
- msn_tlv_t *tlv;
-
- tlv = msn_tlv_gettlv(list, type, nth);
- if (tlv == NULL)
- return -1;
-
- return tlv->length;
-}
-
-char *
-msn_tlv_getvalue_as_string(msn_tlv_t *tlv)
-{
- char *ret;
-
- ret = g_malloc(tlv->length + 1);
- memcpy(ret, tlv->value, tlv->length);
- ret[tlv->length] = '\0';
-
- return ret;
-}
-
-char *
-msn_tlv_getstr(GSList *list, const guint8 type, const int nth)
-{
- msn_tlv_t *tlv;
-
- tlv = msn_tlv_gettlv(list, type, nth);
- if (tlv == NULL)
- return NULL;
-
- return msn_tlv_getvalue_as_string(tlv);
-}
-
-guint8
-msn_tlv_get8(GSList *list, const guint8 type, const int nth)
-{
- msn_tlv_t *tlv;
-
- tlv = msn_tlv_gettlv(list, type, nth);
- if (tlv == NULL)
- return 0; /* erm */
-
- return msn_read8((const char *)tlv->value);
-}
-
-guint16
-msn_tlv_get16(GSList *list, const guint8 type, const int nth)
-{
- msn_tlv_t *tlv;
-
- tlv = msn_tlv_gettlv(list, type, nth);
- if (tlv == NULL)
- return 0; /* erm */
-
- return msn_read16be((const char *)tlv->value);
-}
-
-guint32
-msn_tlv_get32(GSList *list, const guint8 type, const int nth)
-{
- msn_tlv_t *tlv;
-
- tlv = msn_tlv_gettlv(list, type, nth);
- if (tlv == NULL)
- return 0; /* erm */
-
- return msn_read32be((const char *)tlv->value);
-}
-
diff --git a/libpurple/protocols/msn/tlv.h b/libpurple/protocols/msn/tlv.h
deleted file mode 100644
index 065dee3388..0000000000
--- a/libpurple/protocols/msn/tlv.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/**
- * @file tlv.h MSN TLV functions
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-
-#ifndef MSN_TLV_H
-#define MSN_TLV_H
-
-#include "msn.h"
-
-/* TLV structure */
-typedef struct msn_tlv_s
-{
- guint8 type;
- guint8 length;
- guint8 *value;
-} msn_tlv_t;
-
-/* TLV handling functions */
-char *msn_tlv_getvalue_as_string(msn_tlv_t *tlv);
-
-msn_tlv_t *msn_tlv_gettlv(GSList *list, const guint8 type, const int nth);
-int msn_tlv_getlength(GSList *list, const guint8 type, const int nth);
-char *msn_tlv_getstr(GSList *list, const guint8 type, const int nth);
-guint8 msn_tlv_get8(GSList *list, const guint8 type, const int nth);
-guint16 msn_tlv_get16(GSList *list, const guint8 type, const int nth);
-guint32 msn_tlv_get32(GSList *list, const guint8 type, const int nth);
-
-/* TLV list handling functions */
-GSList *msn_tlvlist_read(const char *bs, size_t bs_len);
-GSList *msn_tlvlist_copy(GSList *orig);
-
-int msn_tlvlist_count(GSList *list);
-size_t msn_tlvlist_size(GSList *list);
-gboolean msn_tlvlist_equal(GSList *one, GSList *two);
-char *msn_tlvlist_write(GSList *list, guint8 *out_len);
-void msn_tlvlist_free(GSList *list);
-
-int msn_tlvlist_add_raw(GSList **list, const guint8 type, const guint8 length, const char *value);
-int msn_tlvlist_add_empty(GSList **list, const guint8 type);
-int msn_tlvlist_add_8(GSList **list, const guint8 type, const guint8 value);
-int msn_tlvlist_add_16(GSList **list, const guint8 type, const guint16 value);
-int msn_tlvlist_add_32(GSList **list, const guint8 type, const guint32 value);
-int msn_tlvlist_add_str(GSList **list, const guint8 type, const char *value);
-int msn_tlvlist_add_tlv(GSList **list, const msn_tlv_t *tlv);
-
-int msn_tlvlist_replace_raw(GSList **list, const guint8 type, const guint8 lenth, const char *value);
-int msn_tlvlist_replace_str(GSList **list, const guint8 type, const char *str);
-int msn_tlvlist_replace_empty(GSList **list, const guint8 type);
-int msn_tlvlist_replace_8(GSList **list, const guint8 type, const guint8 value);
-int msn_tlvlist_replace_16(GSList **list, const guint8 type, const guint16 value);
-int msn_tlvlist_replace_32(GSList **list, const guint8 type, const guint32 value);
-int msn_tlvlist_replace_tlv(GSList **list, const msn_tlv_t *tlv);
-
-void msn_tlvlist_remove(GSList **list, const guint8 type);
-
-#endif /* MSN_TLV_H */
-
diff --git a/libpurple/protocols/msn/transaction.c b/libpurple/protocols/msn/transaction.c
deleted file mode 100644
index 57f3464553..0000000000
--- a/libpurple/protocols/msn/transaction.c
+++ /dev/null
@@ -1,247 +0,0 @@
-/**
- * @file transaction.c MSN transaction functions
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-
-#include "internal.h"
-#include "debug.h"
-
-#include "msn.h"
-#include "transaction.h"
-
-MsnTransaction *
-msn_transaction_new(MsnCmdProc *cmdproc, const char *command,
- const char *format, ...)
-{
- MsnTransaction *trans;
- va_list arg;
-
- g_return_val_if_fail(command != NULL, NULL);
-
- trans = g_new0(MsnTransaction, 1);
-
- trans->cmdproc = cmdproc;
- trans->command = g_strdup(command);
- trans->saveable = TRUE;
-
- if (format != NULL)
- {
- va_start(arg, format);
- trans->params = g_strdup_vprintf(format, arg);
- va_end(arg);
- }
-
- /* trans->queue = g_queue_new(); */
-
- return trans;
-}
-
-void
-msn_transaction_destroy(MsnTransaction *trans)
-{
- g_return_if_fail(trans != NULL);
-
- g_free(trans->command);
- g_free(trans->params);
- g_free(trans->payload);
-
- if (trans->data_free)
- trans->data_free(trans->data);
-
-#if 0
- if (trans->pendent_cmd != NULL)
- msn_message_unref(trans->pendent_msg);
-#endif
-
-#if 0
- MsnTransaction *elem;
- if (trans->queue != NULL)
- {
- while ((elem = g_queue_pop_head(trans->queue)) != NULL)
- msn_transaction_destroy(elem);
-
- g_queue_free(trans->queue);
- }
-#endif
-
- if (trans->callbacks != NULL && trans->has_custom_callbacks)
- g_hash_table_destroy(trans->callbacks);
-
- if (trans->timer)
- purple_timeout_remove(trans->timer);
-
- g_free(trans);
-}
-
-char *
-msn_transaction_to_string(MsnTransaction *trans)
-{
- char *str;
-
- g_return_val_if_fail(trans != NULL, FALSE);
-
- if (trans->params != NULL)
- str = g_strdup_printf("%s %u %s\r\n", trans->command, trans->trId, trans->params);
- else if (trans->saveable)
- str = g_strdup_printf("%s %u\r\n", trans->command, trans->trId);
- else
- str = g_strdup_printf("%s\r\n", trans->command);
-
- return str;
-}
-
-void
-msn_transaction_queue_cmd(MsnTransaction *trans, MsnCommand *cmd)
-{
- purple_debug_info("msn", "queueing command.\n");
- trans->pendent_cmd = cmd;
- msn_command_ref(cmd);
-}
-
-void
-msn_transaction_unqueue_cmd(MsnTransaction *trans, MsnCmdProc *cmdproc)
-{
- MsnCommand *cmd;
-
- if (!cmdproc->servconn->connected)
- return;
-
- purple_debug_info("msn", "unqueueing command.\n");
- cmd = trans->pendent_cmd;
-
- g_return_if_fail(cmd != NULL);
-
- msn_cmdproc_process_cmd(cmdproc, cmd);
- msn_command_unref(cmd);
-
- trans->pendent_cmd = NULL;
-}
-
-#if 0
-void
-msn_transaction_queue(MsnTransaction *trans, MsnTransaction *elem)
-{
- if (trans->queue == NULL)
- trans->queue = g_queue_new();
-
- g_queue_push_tail(trans->queue, elem);
-}
-
-void
-msn_transaction_unqueue(MsnTransaction *trans, MsnCmdProc *cmdproc)
-{
- MsnTransaction *elem;
-
- while ((elem = g_queue_pop_head(trans->queue)) != NULL)
- msn_cmdproc_send_trans(cmdproc, elem);
-}
-#endif
-
-void
-msn_transaction_set_payload(MsnTransaction *trans,
- const char *payload, gsize payload_len)
-{
- g_return_if_fail(trans != NULL);
- g_return_if_fail(payload != NULL);
-
- trans->payload = g_strdup(payload);
- trans->payload_len = payload_len ? payload_len : strlen(trans->payload);
-}
-
-void
-msn_transaction_set_data(MsnTransaction *trans, void *data)
-{
- g_return_if_fail(trans != NULL);
-
- trans->data = data;
-}
-
-void msn_transaction_set_data_free(MsnTransaction *trans, GDestroyNotify fn)
-{
- g_return_if_fail(trans != NULL);
- trans->data_free = fn;
-}
-
-void
-msn_transaction_set_saveable(MsnTransaction *trans, gboolean saveable)
-{
- g_return_if_fail(trans != NULL);
-
- trans->saveable = saveable;
-}
-
-void
-msn_transaction_add_cb(MsnTransaction *trans, char *answer,
- MsnTransCb cb)
-{
- g_return_if_fail(trans != NULL);
- g_return_if_fail(answer != NULL);
-
- if (trans->callbacks == NULL)
- {
- trans->has_custom_callbacks = TRUE;
- trans->callbacks = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
- NULL);
- }
- else if (trans->has_custom_callbacks != TRUE)
- g_return_if_reached ();
-
- g_hash_table_insert(trans->callbacks, answer, cb);
-}
-
-static gboolean
-transaction_timeout(gpointer data)
-{
- MsnTransaction *trans;
-
- trans = data;
- g_return_val_if_fail(trans != NULL, FALSE);
-
-#if 0
- purple_debug_info("msn", "timed out: %s %d %s\n", trans->command, trans->trId, trans->params);
-#endif
-
- trans->timer = 0;
-
- if (trans->timeout_cb != NULL)
- trans->timeout_cb(trans->cmdproc, trans);
-
- return FALSE;
-}
-
-void
-msn_transaction_set_timeout_cb(MsnTransaction *trans, MsnTimeoutCb cb)
-{
- if (trans->timer)
- {
- purple_debug_error("msn", "This shouldn't be happening\n");
- purple_timeout_remove(trans->timer);
- }
- trans->timeout_cb = cb;
- trans->timer = purple_timeout_add_seconds(60, transaction_timeout, trans);
-}
-
-void
-msn_transaction_set_error_cb(MsnTransaction *trans, MsnErrorCb cb)
-{
- trans->error_cb = cb;
-}
diff --git a/libpurple/protocols/msn/transaction.h b/libpurple/protocols/msn/transaction.h
deleted file mode 100644
index 10fe8fc0c3..0000000000
--- a/libpurple/protocols/msn/transaction.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/**
- * @file transaction.h MSN transaction functions
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-#ifndef MSN_TRANSACTION_H
-#define MSN_TRANSACTION_H
-
-#include "internal.h"
-
-typedef struct _MsnTransaction MsnTransaction;
-
-#include "cmdproc.h"
-#include "command.h"
-
-typedef void (*MsnTransCb)(MsnCmdProc *cmdproc, MsnCommand *cmd);
-typedef void (*MsnTimeoutCb)(MsnCmdProc *cmdproc, MsnTransaction *trans);
-typedef void (*MsnErrorCb)(MsnCmdProc *cmdproc, MsnTransaction *trans,
- int error);
-
-/**
- * A transaction. A sending command that will initiate the transaction.
- */
-struct _MsnTransaction
-{
- MsnCmdProc *cmdproc;
-
- gboolean saveable; /**< Whether to save this transaction in the history */
- unsigned int trId; /**< The ID of this transaction, if it's being saved */
-
- char *command;
- char *params;
-
- guint timer;
-
- void *data; /**< The data to be used on the different callbacks. */
- GDestroyNotify data_free; /**< The function to free 'data', or @c NULL */
-
- GHashTable *callbacks;
- gboolean has_custom_callbacks;
- MsnErrorCb error_cb;
- MsnTimeoutCb timeout_cb;
-
- char *payload;
- size_t payload_len;
-
- GQueue *queue;
- MsnCommand *pendent_cmd; /**< The command that is waiting for the result of
- this transaction. */
-};
-
-MsnTransaction *msn_transaction_new(MsnCmdProc *cmdproc, const char *command,
- const char *format, ...) G_GNUC_PRINTF(3, 4);
-void msn_transaction_destroy(MsnTransaction *trans);
-
-char *msn_transaction_to_string(MsnTransaction *trans);
-void msn_transaction_queue_cmd(MsnTransaction *trans, MsnCommand *cmd);
-void msn_transaction_unqueue_cmd(MsnTransaction *trans, MsnCmdProc *cmdproc);
-void msn_transaction_set_payload(MsnTransaction *trans,
- const char *payload, gsize payload_len);
-void msn_transaction_set_data(MsnTransaction *trans, void *data);
-void msn_transaction_set_data_free(MsnTransaction *trans, GDestroyNotify fn);
-void msn_transaction_set_saveable(MsnTransaction *trans, gboolean saveable);
-void msn_transaction_add_cb(MsnTransaction *trans, char *answer,
- MsnTransCb cb);
-void msn_transaction_set_error_cb(MsnTransaction *trans, MsnErrorCb cb);
-void msn_transaction_set_timeout_cb(MsnTransaction *trans, MsnTimeoutCb cb);
-
-#endif /* MSN_TRANSACTION_H */
diff --git a/libpurple/protocols/msn/user.c b/libpurple/protocols/msn/user.c
deleted file mode 100644
index a9565be27c..0000000000
--- a/libpurple/protocols/msn/user.c
+++ /dev/null
@@ -1,801 +0,0 @@
-/**
- * @file user.c User functions
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-
-#include "internal.h"
-#include "debug.h"
-#include "util.h"
-
-#include "user.h"
-#include "slp.h"
-
-static void free_user_endpoint(MsnUserEndpoint *data)
-{
- g_free(data->id);
- g_free(data->name);
- g_free(data);
-}
-
-/*new a user object*/
-MsnUser *
-msn_user_new(MsnUserList *userlist, const char *passport,
- const char *friendly_name)
-{
- MsnUser *user;
-
- user = g_new0(MsnUser, 1);
-
- user->userlist = userlist;
-
- msn_user_set_passport(user, passport);
- msn_user_set_friendly_name(user, friendly_name);
-
- return msn_user_ref(user);
-}
-
-/*destroy a user object*/
-static void
-msn_user_destroy(MsnUser *user)
-{
- while (user->endpoints != NULL) {
- free_user_endpoint(user->endpoints->data);
- user->endpoints = g_slist_delete_link(user->endpoints, user->endpoints);
- }
-
- if (user->clientcaps != NULL)
- g_hash_table_destroy(user->clientcaps);
-
- if (user->group_ids != NULL)
- {
- GList *l;
- for (l = user->group_ids; l != NULL; l = l->next)
- {
- g_free(l->data);
- }
- g_list_free(user->group_ids);
- }
-
- if (user->msnobj != NULL)
- msn_object_destroy(user->msnobj);
-
- g_free(user->passport);
- g_free(user->friendly_name);
- g_free(user->uid);
- if (user->extinfo) {
- g_free(user->extinfo->media_album);
- g_free(user->extinfo->media_artist);
- g_free(user->extinfo->media_title);
- g_free(user->extinfo->phone_home);
- g_free(user->extinfo->phone_mobile);
- g_free(user->extinfo->phone_work);
- g_free(user->extinfo);
- }
- g_free(user->statusline);
- g_free(user->invite_message);
-
- g_free(user);
-}
-
-MsnUser *
-msn_user_ref(MsnUser *user)
-{
- g_return_val_if_fail(user != NULL, NULL);
-
- user->refcount++;
-
- return user;
-}
-
-void
-msn_user_unref(MsnUser *user)
-{
- g_return_if_fail(user != NULL);
-
- user->refcount--;
-
- if(user->refcount == 0)
- msn_user_destroy(user);
-}
-
-void
-msn_user_update(MsnUser *user)
-{
- PurpleAccount *account;
- gboolean offline;
-
- g_return_if_fail(user != NULL);
-
- account = user->userlist->session->account;
-
- offline = (user->status == NULL);
-
- if (!offline) {
- purple_prpl_got_user_status(account, user->passport, user->status,
- "message", user->statusline, NULL);
- } else {
- if (user->mobile) {
- purple_prpl_got_user_status(account, user->passport, "mobile", NULL);
- purple_prpl_got_user_status(account, user->passport, "available", NULL);
- } else {
- purple_prpl_got_user_status(account, user->passport, "offline", NULL);
- }
- }
-
- if (!offline || !user->mobile) {
- purple_prpl_got_user_status_deactive(account, user->passport, "mobile");
- }
-
- if (!offline && user->extinfo && user->extinfo->media_type != CURRENT_MEDIA_UNKNOWN) {
- if (user->extinfo->media_type == CURRENT_MEDIA_MUSIC) {
- purple_prpl_got_user_status(account, user->passport, "tune",
- PURPLE_TUNE_ARTIST, user->extinfo->media_artist,
- PURPLE_TUNE_ALBUM, user->extinfo->media_album,
- PURPLE_TUNE_TITLE, user->extinfo->media_title,
- NULL);
- } else if (user->extinfo->media_type == CURRENT_MEDIA_GAMES) {
- purple_prpl_got_user_status(account, user->passport, "tune",
- "game", user->extinfo->media_title,
- NULL);
- } else if (user->extinfo->media_type == CURRENT_MEDIA_OFFICE) {
- purple_prpl_got_user_status(account, user->passport, "tune",
- "office", user->extinfo->media_title,
- NULL);
- } else {
- purple_debug_warning("msn", "Got CurrentMedia with unknown type %d.\n",
- user->extinfo->media_type);
- }
- } else {
- purple_prpl_got_user_status_deactive(account, user->passport, "tune");
- }
-
- if (user->idle)
- purple_prpl_got_user_idle(account, user->passport, TRUE, -1);
- else
- purple_prpl_got_user_idle(account, user->passport, FALSE, 0);
-}
-
-void
-msn_user_set_state(MsnUser *user, const char *state)
-{
- const char *status;
-
- g_return_if_fail(user != NULL);
-
- if (state == NULL) {
- user->status = NULL;
- return;
- }
-
- if (!g_ascii_strcasecmp(state, "BSY"))
- status = "busy";
- else if (!g_ascii_strcasecmp(state, "BRB"))
- status = "brb";
- else if (!g_ascii_strcasecmp(state, "AWY"))
- status = "away";
- else if (!g_ascii_strcasecmp(state, "PHN"))
- status = "phone";
- else if (!g_ascii_strcasecmp(state, "LUN"))
- status = "lunch";
- else if (!g_ascii_strcasecmp(state, "HDN"))
- status = NULL;
- else
- status = "available";
-
- if (!g_ascii_strcasecmp(state, "IDL"))
- user->idle = TRUE;
- else
- user->idle = FALSE;
-
- user->status = status;
-}
-
-void
-msn_user_set_passport(MsnUser *user, const char *passport)
-{
- g_return_if_fail(user != NULL);
-
- g_free(user->passport);
- user->passport = g_strdup(passport);
-}
-
-gboolean
-msn_user_set_friendly_name(MsnUser *user, const char *name)
-{
- g_return_val_if_fail(user != NULL, FALSE);
-
- if (!name)
- return FALSE;
-
- if (user->friendly_name && (!strcmp(user->friendly_name, name) ||
- !strcmp(user->passport, name)))
- return FALSE;
-
- g_free(user->friendly_name);
- user->friendly_name = g_strdup(name);
-
- serv_got_alias(purple_account_get_connection(user->userlist->session->account),
- user->passport, name);
- return TRUE;
-}
-
-void
-msn_user_set_statusline(MsnUser *user, const char *statusline)
-{
- g_return_if_fail(user != NULL);
-
- g_free(user->statusline);
- user->statusline = g_strdup(statusline);
-}
-
-void
-msn_user_set_uid(MsnUser *user, const char *uid)
-{
- g_return_if_fail(user != NULL);
-
- g_free(user->uid);
- user->uid = g_strdup(uid);
-}
-
-void
-msn_user_set_endpoint_data(MsnUser *user, const char *input, MsnUserEndpoint *newep)
-{
- MsnUserEndpoint *ep;
- char *endpoint;
- GSList *l;
-
- g_return_if_fail(user != NULL);
- g_return_if_fail(input != NULL);
-
- endpoint = g_ascii_strdown(input, -1);
-
- for (l = user->endpoints; l; l = l->next) {
- ep = l->data;
- if (g_str_equal(ep->id, endpoint)) {
- /* We have info about this endpoint! */
-
- g_free(endpoint);
-
- if (newep == NULL) {
- /* Delete it and exit */
- user->endpoints = g_slist_delete_link(user->endpoints, l);
- free_user_endpoint(ep);
- return;
- }
-
- /* Break out of our loop and update it */
- break;
- }
- }
- if (l == NULL) {
- /* Need to add a new endpoint */
- ep = g_new0(MsnUserEndpoint, 1);
- ep->id = endpoint;
- user->endpoints = g_slist_prepend(user->endpoints, ep);
- }
-
- ep->clientid = newep->clientid;
- ep->extcaps = newep->extcaps;
-}
-
-void
-msn_user_clear_endpoints(MsnUser *user)
-{
- MsnUserEndpoint *ep;
- GSList *l;
-
- g_return_if_fail(user != NULL);
-
- for (l = user->endpoints; l; l = g_slist_delete_link(l, l)) {
- ep = l->data;
- free_user_endpoint(ep);
- }
-
- user->endpoints = NULL;
-}
-
-void
-msn_user_set_op(MsnUser *user, MsnListOp list_op)
-{
- g_return_if_fail(user != NULL);
-
- user->list_op |= list_op;
-}
-
-void
-msn_user_unset_op(MsnUser *user, MsnListOp list_op)
-{
- g_return_if_fail(user != NULL);
-
- user->list_op &= ~list_op;
-}
-
-void
-msn_user_set_buddy_icon(MsnUser *user, PurpleStoredImage *img)
-{
- MsnObject *msnobj;
-
- g_return_if_fail(user != NULL);
-
- msnobj = msn_object_new_from_image(img, "TFR2C2.tmp",
- user->passport, MSN_OBJECT_USERTILE);
-
- if (!msnobj)
- purple_debug_error("msn", "Unable to open buddy icon from %s!\n", user->passport);
-
- msn_user_set_object(user, msnobj);
-}
-
-/*add group id to User object*/
-void
-msn_user_add_group_id(MsnUser *user, const char* group_id)
-{
- MsnUserList *userlist;
- PurpleAccount *account;
- PurpleBuddy *b;
- PurpleGroup *g;
- const char *passport;
- const char *group_name;
-
- g_return_if_fail(user != NULL);
- g_return_if_fail(group_id != NULL);
-
- user->group_ids = g_list_append(user->group_ids, g_strdup(group_id));
-
- userlist = user->userlist;
- account = userlist->session->account;
- passport = msn_user_get_passport(user);
-
- group_name = msn_userlist_find_group_name(userlist, group_id);
-
- purple_debug_info("msn", "User: group id:%s,name:%s,user:%s\n", group_id, group_name, passport);
-
- g = purple_find_group(group_name);
-
- if ((group_id == NULL) && (g == NULL))
- {
- g = purple_group_new(group_name);
- purple_blist_add_group(g, NULL);
- }
-
- b = purple_find_buddy_in_group(account, passport, g);
- if (b == NULL)
- {
- b = purple_buddy_new(account, passport, NULL);
- purple_blist_add_buddy(b, NULL, g, NULL);
- }
- purple_buddy_set_protocol_data(b, user);
- /*Update the blist Node info*/
-}
-
-/*check if the msn user is online*/
-gboolean
-msn_user_is_online(PurpleAccount *account, const char *name)
-{
- PurpleBuddy *buddy;
-
- buddy = purple_find_buddy(account, name);
- return PURPLE_BUDDY_IS_ONLINE(buddy);
-}
-
-gboolean
-msn_user_is_yahoo(PurpleAccount *account, const char *name)
-{
- MsnSession *session = NULL;
- MsnUser *user;
- PurpleConnection *gc;
-
- gc = purple_account_get_connection(account);
- if (gc != NULL)
- session = gc->proto_data;
-
- if ((session != NULL) && (user = msn_userlist_find_user(session->userlist, name)) != NULL)
- {
- return (user->networkid == MSN_NETWORK_YAHOO);
- }
- return (strstr(name,"@yahoo.") != NULL);
-}
-
-void
-msn_user_remove_group_id(MsnUser *user, const char *id)
-{
- GList *l;
-
- g_return_if_fail(user != NULL);
- g_return_if_fail(id != NULL);
-
- l = g_list_find_custom(user->group_ids, id, (GCompareFunc)strcmp);
-
- if (l == NULL)
- return;
-
- g_free(l->data);
- user->group_ids = g_list_delete_link(user->group_ids, l);
-}
-
-void
-msn_user_set_pending_group(MsnUser *user, const char *group)
-{
- user->pending_group = g_strdup(group);
-}
-
-char *
-msn_user_remove_pending_group(MsnUser *user)
-{
- char *group = user->pending_group;
- user->pending_group = NULL;
- return group;
-}
-
-void
-msn_user_set_home_phone(MsnUser *user, const char *number)
-{
- g_return_if_fail(user != NULL);
-
- if (!number && !user->extinfo)
- return;
-
- if (user->extinfo)
- g_free(user->extinfo->phone_home);
- else
- user->extinfo = g_new0(MsnUserExtendedInfo, 1);
-
- user->extinfo->phone_home = g_strdup(number);
-}
-
-void
-msn_user_set_work_phone(MsnUser *user, const char *number)
-{
- g_return_if_fail(user != NULL);
-
- if (!number && !user->extinfo)
- return;
-
- if (user->extinfo)
- g_free(user->extinfo->phone_work);
- else
- user->extinfo = g_new0(MsnUserExtendedInfo, 1);
-
- user->extinfo->phone_work = g_strdup(number);
-}
-
-void
-msn_user_set_mobile_phone(MsnUser *user, const char *number)
-{
- g_return_if_fail(user != NULL);
-
- if (!number && !user->extinfo)
- return;
-
- if (user->extinfo)
- g_free(user->extinfo->phone_mobile);
- else
- user->extinfo = g_new0(MsnUserExtendedInfo, 1);
-
- user->extinfo->phone_mobile = g_strdup(number);
-}
-
-void
-msn_user_set_clientid(MsnUser *user, guint clientid)
-{
- g_return_if_fail(user != NULL);
-
- user->clientid = clientid;
-}
-
-void
-msn_user_set_extcaps(MsnUser *user, guint extcaps)
-{
- g_return_if_fail(user != NULL);
-
- user->extcaps = extcaps;
-}
-
-void
-msn_user_set_network(MsnUser *user, MsnNetwork network)
-{
- g_return_if_fail(user != NULL);
-
- user->networkid = network;
-}
-
-static gboolean
-buddy_icon_cached(PurpleConnection *gc, MsnObject *obj)
-{
- PurpleAccount *account;
- PurpleBuddy *buddy;
- const char *old;
- const char *new;
-
- g_return_val_if_fail(obj != NULL, FALSE);
-
- account = purple_connection_get_account(gc);
-
- buddy = purple_find_buddy(account, msn_object_get_creator(obj));
- if (buddy == NULL)
- return FALSE;
-
- old = purple_buddy_icons_get_checksum_for_user(buddy);
- new = msn_object_get_sha1(obj);
-
- if (new == NULL)
- return FALSE;
-
- /* If the old and new checksums are the same, and the file actually exists,
- * then return TRUE */
- if (old != NULL && !strcmp(old, new))
- return TRUE;
-
- return FALSE;
-}
-
-static void
-queue_buddy_icon_request(MsnUser *user)
-{
- PurpleAccount *account;
- MsnObject *obj;
- GQueue *queue;
-
- g_return_if_fail(user != NULL);
-
- account = user->userlist->session->account;
-
- obj = msn_user_get_object(user);
-
- if (obj == NULL) {
- purple_buddy_icons_set_for_user(account, user->passport, NULL, 0, NULL);
- return;
- }
-
- if (!buddy_icon_cached(account->gc, obj)) {
- MsnUserList *userlist;
-
- userlist = user->userlist;
- queue = userlist->buddy_icon_requests;
-
- if (purple_debug_is_verbose())
- purple_debug_info("msn", "Queueing buddy icon request for %s (buddy_icon_window = %i)\n",
- user->passport, userlist->buddy_icon_window);
-
- g_queue_push_tail(queue, user);
-
- if (userlist->buddy_icon_window > 0)
- msn_release_buddy_icon_request(userlist);
- }
-}
-
-void
-msn_user_set_object(MsnUser *user, MsnObject *obj)
-{
- g_return_if_fail(user != NULL);
-
- if (user->msnobj != NULL && !msn_object_find_local(msn_object_get_sha1(obj)))
- msn_object_destroy(user->msnobj);
-
- user->msnobj = obj;
-
- if (user->list_op & MSN_LIST_FL_OP)
- queue_buddy_icon_request(user);
-}
-
-void
-msn_user_set_client_caps(MsnUser *user, GHashTable *info)
-{
- g_return_if_fail(user != NULL);
- g_return_if_fail(info != NULL);
-
- if (user->clientcaps != NULL)
- g_hash_table_destroy(user->clientcaps);
-
- user->clientcaps = info;
-}
-
-void
-msn_user_set_invite_message(MsnUser *user, const char *message)
-{
- g_return_if_fail(user != NULL);
-
- g_free(user->invite_message);
- user->invite_message = g_strdup(message);
-}
-
-const char *
-msn_user_get_passport(const MsnUser *user)
-{
- g_return_val_if_fail(user != NULL, NULL);
-
- return user->passport;
-}
-
-const char *
-msn_user_get_friendly_name(const MsnUser *user)
-{
- g_return_val_if_fail(user != NULL, NULL);
-
- return user->friendly_name;
-}
-
-const char *
-msn_user_get_home_phone(const MsnUser *user)
-{
- g_return_val_if_fail(user != NULL, NULL);
-
- return user->extinfo ? user->extinfo->phone_home : NULL;
-}
-
-const char *
-msn_user_get_work_phone(const MsnUser *user)
-{
- g_return_val_if_fail(user != NULL, NULL);
-
- return user->extinfo ? user->extinfo->phone_work : NULL;
-}
-
-const char *
-msn_user_get_mobile_phone(const MsnUser *user)
-{
- g_return_val_if_fail(user != NULL, NULL);
-
- return user->extinfo ? user->extinfo->phone_mobile : NULL;
-}
-
-guint
-msn_user_get_clientid(const MsnUser *user)
-{
- g_return_val_if_fail(user != NULL, 0);
-
- return user->clientid;
-}
-
-guint
-msn_user_get_extcaps(const MsnUser *user)
-{
- g_return_val_if_fail(user != NULL, 0);
-
- return user->extcaps;
-}
-
-MsnUserEndpoint *
-msn_user_get_endpoint_data(MsnUser *user, const char *input)
-{
- char *endpoint;
- GSList *l;
- MsnUserEndpoint *ep;
-
- g_return_val_if_fail(user != NULL, NULL);
- g_return_val_if_fail(input != NULL, NULL);
-
- endpoint = g_ascii_strdown(input, -1);
-
- for (l = user->endpoints; l; l = l->next) {
- ep = l->data;
- if (g_str_equal(ep->id, endpoint)) {
- g_free(endpoint);
- return ep;
- }
- }
-
- g_free(endpoint);
-
- return NULL;
-}
-
-MsnNetwork
-msn_user_get_network(const MsnUser *user)
-{
- g_return_val_if_fail(user != NULL, MSN_NETWORK_UNKNOWN);
-
- return user->networkid;
-}
-
-MsnObject *
-msn_user_get_object(const MsnUser *user)
-{
- g_return_val_if_fail(user != NULL, NULL);
-
- return user->msnobj;
-}
-
-GHashTable *
-msn_user_get_client_caps(const MsnUser *user)
-{
- g_return_val_if_fail(user != NULL, NULL);
-
- return user->clientcaps;
-}
-
-const char *
-msn_user_get_invite_message(const MsnUser *user)
-{
- g_return_val_if_fail(user != NULL, NULL);
-
- return user->invite_message;
-}
-
-gboolean
-msn_user_is_capable(MsnUser *user, char *endpoint, guint capability, guint extcap)
-{
- g_return_val_if_fail(user != NULL, FALSE);
-
- if (endpoint != NULL) {
- MsnUserEndpoint *ep = msn_user_get_endpoint_data(user, endpoint);
- if (ep != NULL)
- return (ep->clientid & capability) && (ep->extcaps & extcap);
- else
- return FALSE;
- }
-
- return (user->clientid & capability) && (user->extcaps & extcap);
-}
-
-/**************************************************************************
- * Utility functions
- **************************************************************************/
-
-int
-msn_user_passport_cmp(MsnUser *user, const char *passport)
-{
- const char *str;
- char *pass;
- int result;
-
- str = purple_normalize_nocase(NULL, msn_user_get_passport(user));
- pass = g_strdup(str);
-
-#if GLIB_CHECK_VERSION(2,16,0)
- result = g_strcmp0(pass, purple_normalize_nocase(NULL, passport));
-#else
- str = purple_normalize_nocase(NULL, passport);
- if (!pass)
- result = -(pass != str);
- else if (!str)
- result = pass != str;
- else
- result = strcmp(pass, str);
-#endif /* GLIB < 2.16.0 */
-
- g_free(pass);
-
- return result;
-}
-
-gboolean
-msn_user_is_in_group(MsnUser *user, const char * group_id)
-{
- if (user == NULL)
- return FALSE;
-
- if (group_id == NULL)
- return FALSE;
-
- return (g_list_find_custom(user->group_ids, group_id, (GCompareFunc)strcmp)) != NULL;
-}
-
-gboolean
-msn_user_is_in_list(MsnUser *user, MsnListId list_id)
-{
- if (user == NULL)
- return FALSE;
-
- return (user->list_op & (1 << list_id));
-}
-
diff --git a/libpurple/protocols/msn/user.h b/libpurple/protocols/msn/user.h
deleted file mode 100644
index 727c717a8f..0000000000
--- a/libpurple/protocols/msn/user.h
+++ /dev/null
@@ -1,533 +0,0 @@
-/**
- * @file user.h User functions
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-#ifndef MSN_USER_H
-#define MSN_USER_H
-
-typedef struct _MsnUser MsnUser;
-
-typedef enum
-{
- MSN_NETWORK_UNKNOWN = 0,
- MSN_NETWORK_PASSPORT = 1,
- MSN_NETWORK_COMMUNICATOR = 2,
- MSN_NETWORK_MOBILE = 4,
- MSN_NETWORK_MNI = 8,
- MSN_NETWORK_CIRCLE = 9,
- MSN_NETWORK_TEMP_GROUP = 10,
- MSN_NETWORK_CID = 11,
- MSN_NETWORK_CONNECT = 13,
- MSN_NETWORK_REMOTE = 14,
- MSN_NETWORK_SMTP = 16,
- MSN_NETWORK_YAHOO = 32
-} MsnNetwork;
-
-/**
- * Current media.
- */
-typedef enum
-{
- CURRENT_MEDIA_UNKNOWN,
- CURRENT_MEDIA_MUSIC,
- CURRENT_MEDIA_GAMES,
- CURRENT_MEDIA_OFFICE
-} CurrentMediaType;
-
-#include "object.h"
-#include "session.h"
-#include "userlist.h"
-
-/**
- * Contains optional info about a user that is fairly uncommon. We
- * put this info in in a separate struct to save memory because we
- * allocate an MsnUser struct for each buddy, but we generally only
- * need this information for a small percentage of our buddies
- * (usually less than 1%). Putting it in a separate struct makes
- * MsnUser smaller by the size of a few pointers.
- */
-typedef struct _MsnUserExtendedInfo
-{
- CurrentMediaType media_type; /**< Type of the user's current media. */
- char *media_title; /**< Title of the user's current media. */
- char *media_artist; /**< Artist of the user's current media. */
- char *media_album; /**< Album of the user's current media. */
-
- char *phone_home; /**< E.T. uses this. */
- char *phone_work; /**< Work phone number. */
- char *phone_mobile; /**< Mobile phone number. */
-} MsnUserExtendedInfo;
-
-/**
- * A user.
- */
-struct _MsnUser
-{
- MsnUserList *userlist;
-
- guint8 refcount; /**< The reference count of this object */
-
- char *passport; /**< The passport account. */
- char *friendly_name; /**< The friendly name. */
-
- char *uid; /*< User ID */
- GSList *endpoints; /*< Endpoint-specific data */
-
- const char *status; /**< The state of the user. */
- char *statusline; /**< The state of the user. */
-
- gboolean idle; /**< The idle state of the user. */
-
- MsnUserExtendedInfo *extinfo; /**< Extended info for the user. */
-
- gboolean authorized; /**< Authorized to add this user. */
- gboolean mobile; /**< Signed up with MSN Mobile. */
-
- GList *group_ids; /**< The group IDs. */
- char *pending_group; /**< A pending group to add. */
-
- MsnObject *msnobj; /**< The user's MSN Object. */
-
- GHashTable *clientcaps; /**< The client's capabilities. */
-
- guint clientid; /**< The client's ID */
- guint extcaps; /**< The client's extended capabilities */
-
- MsnNetwork networkid; /**< The user's network */
-
- MsnListOp list_op; /**< Which lists the user is in */
-
- /**
- * The membershipId for this buddy on our pending list. Sent by
- * the contact's server
- */
- guint member_id_on_pending_list;
-
- char *invite_message; /**< Invite message of user request */
-};
-
-/**
- * A specific user endpoint.
- */
-typedef struct MsnUserEndpoint {
- char *id; /**< The client's endpoint ID */
- char *name; /**< The client's endpoint's name */
- int type; /**< The client's endpoint type */
- guint clientid; /**< The client's ID */
- guint extcaps; /**< The client's extended capabilites */
-
-} MsnUserEndpoint;
-
-/**************************************************************************
- ** @name User API *
- **************************************************************************/
-/*@{*/
-
-/**
- * Creates a new user structure.
- *
- * @param session The MSN session.
- * @param passport The initial passport.
- * @param stored_name The initial stored name.
- *
- * @return A new user structure. It will have a reference count of 1.
- */
-MsnUser *msn_user_new(MsnUserList *userlist, const char *passport,
- const char *friendly_name);
-
-/**
- * Increment the reference count.
- *
- * @param user The user.
- *
- * @return user.
- */
-MsnUser *msn_user_ref(MsnUser *user);
-
-/**
- * Decrement the reference count. When the count reaches 0 the object is
- * automatically freed.
- *
- * @param user The user
- */
-void msn_user_unref(MsnUser *user);
-
-/**
- * Updates the user.
- *
- * Communicates with the core to update the ui, etc.
- *
- * @param user The user to update.
- */
-void msn_user_update(MsnUser *user);
-
- /**
- * Sets the new statusline of user.
- *
- * @param user The user.
- * @param state The statusline string.
- */
-void msn_user_set_statusline(MsnUser *user, const char *statusline);
-
-/**
- * Sets the new state of user.
- *
- * @param user The user.
- * @param state The state string.
- */
-void msn_user_set_state(MsnUser *user, const char *state);
-
-/**
- * Sets the passport account for a user.
- *
- * @param user The user.
- * @param passport The passport account.
- */
-void msn_user_set_passport(MsnUser *user, const char *passport);
-
-/**
- * Sets the friendly name for a user.
- *
- * @param user The user.
- * @param name The friendly name.
- *
- * @returns TRUE is name actually changed, FALSE otherwise.
- */
-gboolean msn_user_set_friendly_name(MsnUser *user, const char *name);
-
-/**
- * Sets the buddy icon for a local user.
- *
- * @param user The user.
- * @param img The buddy icon image
- */
-void msn_user_set_buddy_icon(MsnUser *user, PurpleStoredImage *img);
-
-/**
- * Sets the group ID list for a user.
- *
- * @param user The user.
- * @param ids The group ID list.
- */
-void msn_user_set_group_ids(MsnUser *user, GList *ids);
-
-/**
- * Adds the group ID for a user.
- *
- * @param user The user.
- * @param id The group ID.
- */
-void msn_user_add_group_id(MsnUser *user, const char * id);
-
-/**
- * Removes the group ID from a user.
- *
- * @param user The user.
- * @param id The group ID.
- */
-void msn_user_remove_group_id(MsnUser *user, const char * id);
-
-/**
- * Sets the pending group for a user.
- *
- * @param user The user.
- * @param group The group name.
- */
-void msn_user_set_pending_group(MsnUser *user, const char *group);
-
-/**
- * Removes the pending group from a user.
- *
- * @param user The user.
- *
- * @return Returns the pending group name.
- */
-char *msn_user_remove_pending_group(MsnUser *user);
-
-/**
- * Sets the home phone number for a user.
- *
- * @param user The user.
- * @param number The home phone number.
- */
-void msn_user_set_home_phone(MsnUser *user, const char *number);
-
-/**
- * Sets the work phone number for a user.
- *
- * @param user The user.
- * @param number The work phone number.
- */
-void msn_user_set_work_phone(MsnUser *user, const char *number);
-
-void msn_user_set_uid(MsnUser *user, const char *uid);
-
-/**
- * Sets endpoint data for a user.
- *
- * @param user The user.
- * @param endpoint The endpoint.
- * @param data The endpoint data.
- */
-void
-msn_user_set_endpoint_data(MsnUser *user, const char *endpoint, MsnUserEndpoint *data);
-
-/**
- * Clears all endpoint data for a user.
- *
- * @param user The user.
- */
-void
-msn_user_clear_endpoints(MsnUser *user);
-
-/**
- * Sets the client id for a user.
- *
- * @param user The user.
- * @param clientid The client id.
- */
-void msn_user_set_clientid(MsnUser *user, guint clientid);
-
-/**
- * Sets the client id for a user.
- *
- * @param user The user.
- * @param extcaps The client's extended capabilities.
- */
-void msn_user_set_extcaps(MsnUser *user, guint extcaps);
-
-/**
- * Sets the network id for a user.
- *
- * @param user The user.
- * @param network The network id.
- */
-void msn_user_set_network(MsnUser *user, MsnNetwork network);
-
-/**
- * Sets the mobile phone number for a user.
- *
- * @param user The user.
- * @param number The mobile phone number.
- */
-void msn_user_set_mobile_phone(MsnUser *user, const char *number);
-
-/**
- * Sets the MSNObject for a user.
- *
- * @param user The user.
- * @param obj The MSNObject.
- */
-void msn_user_set_object(MsnUser *user, MsnObject *obj);
-
-/**
- * Sets the client information for a user.
- *
- * @param user The user.
- * @param info The client information.
- */
-void msn_user_set_client_caps(MsnUser *user, GHashTable *info);
-
-/**
- * Sets the invite message for a user.
- *
- * @param user The user.
- * @param message The invite message for a user.
- */
-void msn_user_set_invite_message(MsnUser *user, const char *message);
-
-
-/**
- * Returns the passport account for a user.
- *
- * @param user The user.
- *
- * @return The passport account.
- */
-const char *msn_user_get_passport(const MsnUser *user);
-
-/**
- * Returns the friendly name for a user.
- *
- * @param user The user.
- *
- * @return The friendly name.
- */
-const char *msn_user_get_friendly_name(const MsnUser *user);
-
-/**
- * Returns the home phone number for a user.
- *
- * @param user The user.
- *
- * @return The user's home phone number.
- */
-const char *msn_user_get_home_phone(const MsnUser *user);
-
-/**
- * Returns the work phone number for a user.
- *
- * @param user The user.
- *
- * @return The user's work phone number.
- */
-const char *msn_user_get_work_phone(const MsnUser *user);
-
-/**
- * Returns the mobile phone number for a user.
- *
- * @param user The user.
- *
- * @return The user's mobile phone number.
- */
-const char *msn_user_get_mobile_phone(const MsnUser *user);
-
-/**
- * Gets endpoint data for a user.
- *
- * @param user The user.
- * @param endpoint The endpoint.
- *
- * @return The user's endpoint data.
- */
-MsnUserEndpoint *
-msn_user_get_endpoint_data(MsnUser *user, const char *endpoint);
-
-/**
- * Returns the client id for a user.
- *
- * @param user The user.
- *
- * @return The user's client id.
- */
-guint msn_user_get_clientid(const MsnUser *user);
-
-/**
- * Returns the extended capabilities for a user.
- *
- * @param user The user.
- *
- * @return The user's extended capabilities.
- */
-guint msn_user_get_extcaps(const MsnUser *user);
-
-/**************************************************************************
- * Utility functions
- **************************************************************************/
-
-
-/**
- * Check if the user is part of the group.
- *
- * @param user The user we are asking group membership.
- * @param group_id The group where the user may be in.
- *
- * @return TRUE if user is part of the group. Otherwise, FALSE.
- */
-gboolean msn_user_is_in_group(MsnUser *user, const char * group_id);
-
-/**
- * Check if user is on list.
- *
- * @param user The user we are asking list membership.
- * @param list_id The list where the user may be in.
- *
- * @return TRUE if the user is on the list, else FALSE.
- */
-gboolean msn_user_is_in_list(MsnUser *user, MsnListId list_id);
-/**
- * Returns the network id for a user.
- *
- * @param user The user.
- *
- * @return The user's network id.
- */
-MsnNetwork msn_user_get_network(const MsnUser *user);
-
-/**
- * Returns the MSNObject for a user.
- *
- * @param user The user.
- *
- * @return The MSNObject.
- */
-MsnObject *msn_user_get_object(const MsnUser *user);
-
-/**
- * Returns the client information for a user.
- *
- * @param user The user.
- *
- * @return The client information.
- */
-GHashTable *msn_user_get_client_caps(const MsnUser *user);
-
-/**
- * Returns the invite message for a user.
- *
- * @param user The user.
- *
- * @return The user's invite message.
- */
-const char *msn_user_get_invite_message(const MsnUser *user);
-
-/**
- * check to see if user is online
- */
-gboolean msn_user_is_online(PurpleAccount *account, const char *name);
-
-/**
- * check to see if user is Yahoo User
- */
-gboolean msn_user_is_yahoo(PurpleAccount *account, const char *name);
-
-void msn_user_set_op(MsnUser *user, MsnListOp list_op);
-void msn_user_unset_op(MsnUser *user, MsnListOp list_op);
-
-/**
- * Compare the given passport with the one of the user
- *
- * @param user User to compare.
- * @oaran passport Passport to compare.
- *
- * @return Zero if the passport match with the one of the user, otherwise
- * a positive integer if the user passport is greather than the one given
- * and a negative integer if it is less.
- */
-int msn_user_passport_cmp(MsnUser *user, const char *passport);
-
-/**
- * Checks whether a user is capable of some task.
- *
- * @param user The user.
- * @param endpoint The endpoint. Can be @NULL to check overall capabilities.
- * @param capability The capability (including client version).
- * @param extcap The extended capability.
- *
- * @return Whether the user supports the capability.
- */
-gboolean
-msn_user_is_capable(MsnUser *user, char *endpoint, guint capability, guint extcap);
-
-/*@}*/
-
-#endif /* MSN_USER_H */
diff --git a/libpurple/protocols/msn/userlist.c b/libpurple/protocols/msn/userlist.c
deleted file mode 100644
index 8ad73813ff..0000000000
--- a/libpurple/protocols/msn/userlist.c
+++ /dev/null
@@ -1,759 +0,0 @@
-/**
- * @file userlist.c MSN user list support
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-
-#include "internal.h"
-#include "debug.h"
-#include "request.h"
-
-#include "msn.h"
-#include "msnutils.h"
-#include "userlist.h"
-
-#include "contact.h"
-
-const char *lists[] = { "FL", "AL", "BL", "RL" };
-
-typedef struct
-{
- PurpleConnection *gc;
- char *who;
- char *friendly;
-
-} MsnPermitAdd;
-
-/**************************************************************************
- * Callbacks
- **************************************************************************/
-static void
-msn_accept_add_cb(gpointer data)
-{
- MsnPermitAdd *pa = data;
-
- purple_debug_misc("msn", "Accepted the new buddy: %s\n", pa->who);
-
- if (PURPLE_CONNECTION_IS_VALID(pa->gc))
- {
- MsnSession *session = pa->gc->proto_data;
- MsnUserList *userlist = session->userlist;
- PurpleAccount *account = purple_connection_get_account(pa->gc);
-
- msn_userlist_add_buddy_to_list(userlist, pa->who, MSN_LIST_AL);
- purple_privacy_deny_remove(account, pa->who, TRUE);
- purple_privacy_permit_add(account, pa->who, TRUE);
-
- msn_del_contact_from_list(session, NULL, pa->who, MSN_LIST_PL);
- }
-
- g_free(pa->who);
- g_free(pa->friendly);
- g_free(pa);
-}
-
-static void
-msn_cancel_add_cb(gpointer data)
-{
- MsnPermitAdd *pa = data;
-
- purple_debug_misc("msn", "Denied the new buddy: %s\n", pa->who);
-
- if (PURPLE_CONNECTION_IS_VALID(pa->gc))
- {
- MsnSession *session = pa->gc->proto_data;
- MsnUserList *userlist = session->userlist;
- MsnCallbackState *state = msn_callback_state_new(session);
-
- msn_callback_state_set_action(state, MSN_DENIED_BUDDY);
-
- msn_userlist_add_buddy_to_list(userlist, pa->who, MSN_LIST_BL);
- msn_del_contact_from_list(session, state, pa->who, MSN_LIST_PL);
- }
-
- g_free(pa->who);
- g_free(pa->friendly);
- g_free(pa);
-}
-
-static void
-got_new_entry(PurpleConnection *gc, const char *passport, const char *friendly, const char *message)
-{
- PurpleAccount *acct;
- MsnPermitAdd *pa;
-
- pa = g_new0(MsnPermitAdd, 1);
- pa->who = g_strdup(passport);
- pa->friendly = g_strdup(friendly);
- pa->gc = gc;
-
- acct = purple_connection_get_account(gc);
- purple_account_request_authorization(acct, passport, NULL, friendly, message,
- purple_find_buddy(acct, passport) != NULL,
- msn_accept_add_cb, msn_cancel_add_cb, pa);
-
-}
-
-/**************************************************************************
- * Server functions
- **************************************************************************/
-
-void
-msn_got_lst_user(MsnSession *session, MsnUser *user,
- MsnListOp list_op, GSList *group_ids)
-{
- PurpleConnection *gc;
- PurpleAccount *account;
- const char *passport;
- const char *store;
- const char *message;
-
- account = session->account;
- gc = purple_account_get_connection(account);
-
- passport = msn_user_get_passport(user);
- store = msn_user_get_friendly_name(user);
- message = msn_user_get_invite_message(user);
-
- msn_user_set_op(user, list_op);
-
- if (list_op & MSN_LIST_FL_OP)
- {
- GSList *c;
- for (c = group_ids; c != NULL; c = g_slist_next(c))
- {
- char *group_id = c->data;
- msn_user_add_group_id(user, group_id);
- }
-
- /* FIXME: It might be a real alias */
- /* Umm, what? This might fix bug #1385130 */
- serv_got_alias(gc, passport, store);
- }
-
- if (list_op & MSN_LIST_AL_OP)
- {
- /* These are users who are allowed to see our status. */
- purple_privacy_deny_remove(account, passport, TRUE);
- purple_privacy_permit_add(account, passport, TRUE);
- }
-
- if (list_op & MSN_LIST_BL_OP)
- {
- /* These are users who are not allowed to see our status. */
- purple_privacy_permit_remove(account, passport, TRUE);
- purple_privacy_deny_add(account, passport, TRUE);
- }
-
- if (list_op & MSN_LIST_RL_OP)
- {
- /* These are users who have us on their buddy list. */
- /*
- * TODO: What is store name set to when this happens?
- * For one of my accounts "something@hotmail.com"
- * the store name was "something." Maybe we
- * should use the friendly name, instead? --KingAnt
- */
-
- if (!(list_op & (MSN_LIST_AL_OP | MSN_LIST_BL_OP)))
- {
-/* got_new_entry(gc, passport, store, NULL); */
- }
- }
-
- if (list_op & MSN_LIST_PL_OP)
- {
- user->authorized = TRUE;
- got_new_entry(gc, passport, store, message);
- }
-}
-
-/**************************************************************************
- * UserList functions
- **************************************************************************/
-
-MsnUserList*
-msn_userlist_new(MsnSession *session)
-{
- MsnUserList *userlist;
-
- userlist = g_new0(MsnUserList, 1);
-
- userlist->session = session;
- userlist->buddy_icon_requests = g_queue_new();
-
- /* buddy_icon_window is the number of allowed simultaneous buddy icon requests.
- * XXX With smarter rate limiting code, we could allow more at once... 5 was the limit set when
- * we weren't retrieiving any more than 5 per MSN session. */
- userlist->buddy_icon_window = 1;
-
- return userlist;
-}
-
-void
-msn_userlist_destroy(MsnUserList *userlist)
-{
- GList *l;
-
- /*destroy userlist*/
- for (l = userlist->users; l != NULL; l = l->next)
- {
- msn_user_unref(l->data);
- }
- g_list_free(userlist->users);
-
- /*destroy group list*/
- for (l = userlist->groups; l != NULL; l = l->next)
- {
- msn_group_destroy(l->data);
- }
- g_list_free(userlist->groups);
-
- g_queue_free(userlist->buddy_icon_requests);
-
- if (userlist->buddy_icon_request_timer)
- purple_timeout_remove(userlist->buddy_icon_request_timer);
-
- g_free(userlist);
-}
-
-MsnUser *
-msn_userlist_find_add_user(MsnUserList *userlist, const char *passport, const char *friendly_name)
-{
- MsnUser *user;
-
- user = msn_userlist_find_user(userlist, passport);
- if (user == NULL)
- {
- user = msn_user_new(userlist, passport, friendly_name);
- msn_userlist_add_user(userlist, user);
- msn_user_unref(user);
- } else {
- msn_user_set_friendly_name(user, friendly_name);
- }
- return user;
-}
-
-void
-msn_userlist_add_user(MsnUserList *userlist, MsnUser *user)
-{
- msn_user_ref(user);
- userlist->users = g_list_prepend(userlist->users, user);
-}
-
-void
-msn_userlist_remove_user(MsnUserList *userlist, MsnUser *user)
-{
- userlist->users = g_list_remove(userlist->users, user);
- g_queue_remove(userlist->buddy_icon_requests, user);
- msn_user_unref(user);
-}
-
-MsnUser *
-msn_userlist_find_user(MsnUserList *userlist, const char *passport)
-{
- GList *l;
-
- g_return_val_if_fail(passport != NULL, NULL);
-
- for (l = userlist->users; l != NULL; l = l->next)
- {
- MsnUser *user = (MsnUser *)l->data;
-
- g_return_val_if_fail(user->passport != NULL, NULL);
-
- if (!g_ascii_strcasecmp(passport, user->passport)){
- return user;
- }
- }
-
- return NULL;
-}
-
-MsnUser *
-msn_userlist_find_user_with_id(MsnUserList *userlist, const char *uid)
-{
- GList *l;
-
- g_return_val_if_fail(uid != NULL, NULL);
-
- for (l = userlist->users; l != NULL; l = l->next) {
- MsnUser *user = (MsnUser *)l->data;
-
- if (user->uid == NULL) {
- continue;
- }
-
- if ( !g_ascii_strcasecmp(uid, user->uid) ) {
- return user;
- }
- }
-
- return NULL;
-}
-
-MsnUser *
-msn_userlist_find_user_with_mobile_phone(MsnUserList *userlist, const char *number)
-{
- GList *l;
-
- g_return_val_if_fail(number != NULL, NULL);
-
- for (l = userlist->users; l != NULL; l = l->next) {
- MsnUser *user = (MsnUser *)l->data;
- const char *user_number = msn_user_get_mobile_phone(user);
-
- if (user_number && !g_ascii_strcasecmp(number, user_number))
- return user;
- }
-
- return NULL;
-}
-
-void
-msn_userlist_add_group(MsnUserList *userlist, MsnGroup *group)
-{
- userlist->groups = g_list_append(userlist->groups, group);
-}
-
-void
-msn_userlist_remove_group(MsnUserList *userlist, MsnGroup *group)
-{
- userlist->groups = g_list_remove(userlist->groups, group);
-}
-
-MsnGroup *
-msn_userlist_find_group_with_id(MsnUserList *userlist, const char * id)
-{
- GList *l;
-
- g_return_val_if_fail(userlist != NULL, NULL);
- g_return_val_if_fail(id != NULL, NULL);
-
- for (l = userlist->groups; l != NULL; l = l->next)
- {
- MsnGroup *group = l->data;
-
- if (!g_ascii_strcasecmp(group->id,id))
- return group;
- }
-
- return NULL;
-}
-
-MsnGroup *
-msn_userlist_find_group_with_name(MsnUserList *userlist, const char *name)
-{
- GList *l;
-
- g_return_val_if_fail(userlist != NULL, NULL);
- g_return_val_if_fail(name != NULL, NULL);
-
- for (l = userlist->groups; l != NULL; l = l->next)
- {
- MsnGroup *group = l->data;
-
- if ((group->name != NULL) && !g_ascii_strcasecmp(name, group->name))
- return group;
- }
-
- return NULL;
-}
-
-const char *
-msn_userlist_find_group_id(MsnUserList *userlist, const char *group_name)
-{
- MsnGroup *group;
-
- group = msn_userlist_find_group_with_name(userlist, group_name);
-
- if (group != NULL)
- return msn_group_get_id(group);
- else
- return NULL;
-}
-
-const char *
-msn_userlist_find_group_name(MsnUserList *userlist, const char * group_id)
-{
- MsnGroup *group;
-
- group = msn_userlist_find_group_with_id(userlist, group_id);
-
- if (group != NULL)
- return msn_group_get_name(group);
- else
- return NULL;
-}
-
-void
-msn_userlist_rename_group_id(MsnUserList *userlist, const char * group_id,
- const char *new_name)
-{
- MsnGroup *group;
-
- group = msn_userlist_find_group_with_id(userlist, group_id);
-
- if (group != NULL)
- msn_group_set_name(group, new_name);
-}
-
-void
-msn_userlist_remove_group_id(MsnUserList *userlist, const char * group_id)
-{
- MsnGroup *group;
-
- group = msn_userlist_find_group_with_id(userlist, group_id);
-
- if (group != NULL)
- {
- msn_userlist_remove_group(userlist, group);
- msn_group_destroy(group);
- }
-}
-
-typedef struct {
- MsnSession *session;
- char *uid;
-} MsnUserlistABData;
-
-static void
-userlist_ab_delete_cb(void *data, int choice)
-{
- MsnUserlistABData *ab = (MsnUserlistABData *)data;
-
- /* msn_delete_contact(ab->session, ab->uid, (gboolean)choice); */
-
- g_free(ab->uid);
- g_free(ab);
-}
-
-void
-msn_userlist_rem_buddy(MsnUserList *userlist, const char *who)
-{
- MsnUser *user = NULL;
-
- g_return_if_fail(userlist != NULL);
- g_return_if_fail(userlist->session != NULL);
- g_return_if_fail(who != NULL);
-
- user = msn_userlist_find_user(userlist, who);
-
- msn_userlist_rem_buddy_from_list(userlist, who, MSN_LIST_FL);
-
- /* delete the contact from address book via soap action */
- if (user != NULL) {
- if (0 /*not ready yet*/ && userlist->session->passport_info.email_enabled) {
- MsnUserlistABData *ab = g_new0(MsnUserlistABData, 1);
- ab->session = userlist->session;
- ab->uid = g_strdup(user->uid); /* Not necessary? */
- purple_request_yes_no(userlist->session->account,
- _("Delete Buddy from Address Book?"),
- _("Do you want to delete this buddy from your address book as well?"),
- user->passport, 0, userlist->session->account, user->passport,
- NULL, ab,
- G_CALLBACK(userlist_ab_delete_cb), G_CALLBACK(userlist_ab_delete_cb));
- } else
- msn_delete_contact(userlist->session, user);
- }
-}
-
-void
-msn_userlist_rem_buddy_from_list(MsnUserList *userlist, const char *who,
- MsnListId list_id)
-{
- MsnUser *user;
- const gchar *list;
- MsnListOp list_op = 1 << list_id;
-
- user = msn_userlist_find_user(userlist, who);
-
- g_return_if_fail(user != NULL);
-
- if ( !msn_user_is_in_list(user, list_id)) {
- list = lists[list_id];
- purple_debug_info("msn", "User %s is not in list %s, not removing.\n", who, list);
- return;
- }
-
- msn_user_unset_op(user, list_op);
-
- msn_notification_rem_buddy_from_list(userlist->session->notification, list_id, user);
-}
-
-/*add buddy*/
-void
-msn_userlist_add_buddy(MsnUserList *userlist, const char *who, const char *group_name)
-{
- MsnUser *user;
- MsnCallbackState *state = NULL;
- const char *group_id = NULL, *new_group_name;
-
- new_group_name = group_name == NULL ? MSN_INDIVIDUALS_GROUP_NAME : group_name;
-
- g_return_if_fail(userlist != NULL);
- g_return_if_fail(userlist->session != NULL);
-
- purple_debug_info("msn", "Add user: %s to group: %s\n", who, new_group_name);
-
- if (!msn_email_is_valid(who))
- {
- /* only notify the user about problems adding to the friends list
- * maybe we should do something else for other lists, but it probably
- * won't cause too many problems if we just ignore it */
-
- char *str = g_strdup_printf(_("Unable to add \"%s\"."), who);
-
- purple_notify_error(NULL, NULL, str,
- _("The username specified is invalid."));
- g_free(str);
-
- return;
- }
-
- state = msn_callback_state_new(userlist->session);
- msn_callback_state_set_who(state, who);
- msn_callback_state_set_new_group_name(state, new_group_name);
-
- group_id = msn_userlist_find_group_id(userlist, new_group_name);
-
- if (group_id == NULL)
- {
- /* Whoa, we must add that group first. */
- purple_debug_info("msn", "Adding user %s to a new group, creating group %s first\n", who, new_group_name);
-
- msn_callback_state_set_action(state, MSN_ADD_BUDDY);
-
- msn_add_group(userlist->session, state, new_group_name);
- return;
- } else {
- msn_callback_state_set_guid(state, group_id);
- }
-
- /* XXX: adding user here may not be correct (should add them in the
- * ACK to the ADL command), but for now we need to make sure they exist
- * early enough that the ILN command doesn't screw us up */
-
- user = msn_userlist_find_add_user(userlist, who, who);
-
- if ( msn_user_is_in_list(user, MSN_LIST_FL) ) {
-
- purple_debug_info("msn", "User %s already exists\n", who);
-
- msn_userlist_rem_buddy_from_list(userlist, who, MSN_LIST_BL);
-
- if (msn_user_is_in_group(user, group_id)) {
- purple_debug_info("msn", "User %s is already in group %s, returning\n", who, new_group_name);
- msn_callback_state_free(state);
- return;
- }
- }
-
- purple_debug_info("msn", "Adding user: %s to group id: %s\n", who, group_id);
-
- msn_callback_state_set_action(state, MSN_ADD_BUDDY);
-
- /* Add contact in the Contact server with a SOAP request and if
- successful, send ADL with MSN_LIST_AL and MSN_LIST_FL and a FQY */
- msn_add_contact_to_group(userlist->session, state, who, group_id);
-}
-
-void
-msn_userlist_add_buddy_to_list(MsnUserList *userlist, const char *who,
- MsnListId list_id)
-{
- MsnUser *user = NULL;
- const gchar *list;
- MsnListOp list_op = 1 << list_id;
-
- g_return_if_fail(userlist != NULL);
-
- user = msn_userlist_find_add_user(userlist, who, who);
-
- /* First we're going to check if it's already there. */
- if (msn_user_is_in_list(user, list_id))
- {
- list = lists[list_id];
- purple_debug_info("msn", "User '%s' is already in list: %s\n", who, list);
- return;
- }
-
- /* XXX: see XXX above, this should really be done when we get the response from
- the server */
-
- msn_user_set_op(user, list_op);
-
- msn_notification_add_buddy_to_list(userlist->session->notification, list_id, user);
-}
-
-gboolean
-msn_userlist_add_buddy_to_group(MsnUserList *userlist, const char *who,
- const char *group_name)
-{
- MsnUser *user;
- gchar * group_id;
-
- g_return_val_if_fail(userlist != NULL, FALSE);
- g_return_val_if_fail(group_name != NULL, FALSE);
- g_return_val_if_fail(who != NULL, FALSE);
-
- purple_debug_info("msn", "Adding buddy with passport %s to group %s\n", who, group_name);
-
- if ( (group_id = (gchar *)msn_userlist_find_group_id(userlist, group_name)) == NULL) {
- purple_debug_error("msn", "Group %s has no guid!\n", group_name);
- return FALSE;
- }
-
- if ( (user = msn_userlist_find_user(userlist, who)) == NULL) {
- purple_debug_error("msn", "User %s not found!\n", who);
- return FALSE;
- }
-
- msn_user_add_group_id(user, group_id);
-
- return TRUE;
-}
-
-
-gboolean
-msn_userlist_rem_buddy_from_group(MsnUserList *userlist, const char *who,
- const char *group_name)
-{
- const gchar * group_id;
- MsnUser *user;
-
- g_return_val_if_fail(userlist != NULL, FALSE);
- g_return_val_if_fail(group_name != NULL, FALSE);
- g_return_val_if_fail(who != NULL, FALSE);
-
- purple_debug_info("msn", "Removing buddy with passport %s from group %s\n", who, group_name);
-
- if ( (group_id = msn_userlist_find_group_id(userlist, group_name)) == NULL) {
- purple_debug_error("msn", "Group %s has no guid!\n", group_name);
- return FALSE;
- }
-
- if ( (user = msn_userlist_find_user(userlist, who)) == NULL) {
- purple_debug_error("msn", "User %s not found!\n", who);
- return FALSE;
- }
-
- msn_user_remove_group_id(user, group_id);
-
- return TRUE;
-}
-
-void
-msn_userlist_move_buddy(MsnUserList *userlist, const char *who,
- const char *old_group_name, const char *new_group_name)
-{
- const char *new_group_id;
- MsnCallbackState *state;
-
- g_return_if_fail(userlist != NULL);
- g_return_if_fail(userlist->session != NULL);
-
- state = msn_callback_state_new(userlist->session);
- msn_callback_state_set_who(state, who);
- msn_callback_state_set_action(state, MSN_MOVE_BUDDY);
- msn_callback_state_set_old_group_name(state, old_group_name);
- msn_callback_state_set_new_group_name(state, new_group_name);
-
- new_group_id = msn_userlist_find_group_id(userlist, new_group_name);
-
- if (new_group_id == NULL)
- {
- msn_add_group(userlist->session, state, new_group_name);
- return;
- }
-
- /* add the contact to the new group, and remove it from the old one in
- * the callback
- */
- msn_add_contact_to_group(userlist->session, state, who, new_group_id);
-}
-
-void
-msn_release_buddy_icon_request(MsnUserList *userlist)
-{
- MsnUser *user;
-
- g_return_if_fail(userlist != NULL);
-
- if (purple_debug_is_verbose())
- purple_debug_info("msn", "Releasing buddy icon request\n");
-
- if (userlist->buddy_icon_window > 0) {
- GQueue *queue;
-
- queue = userlist->buddy_icon_requests;
-
- if (g_queue_is_empty(userlist->buddy_icon_requests))
- return;
-
- user = g_queue_pop_head(queue);
-
- userlist->buddy_icon_window--;
-
- msn_request_user_display(user);
-
- if (purple_debug_is_verbose())
- purple_debug_info("msn",
- "msn_release_buddy_icon_request(): buddy_icon_window-- yields =%d\n",
- userlist->buddy_icon_window);
- }
-}
-
-/*load userlist from the Blist file cache*/
-void
-msn_userlist_load(MsnSession *session)
-{
- PurpleAccount *account = session->account;
- PurpleConnection *gc = purple_account_get_connection(account);
- GSList *l;
- MsnUser * user;
-
- g_return_if_fail(gc != NULL);
-
- for (l = purple_find_buddies(account, NULL); l != NULL;
- l = g_slist_delete_link(l, l)) {
- PurpleBuddy *buddy = l->data;
-
- user = msn_userlist_find_add_user(session->userlist,
- purple_buddy_get_name(buddy), NULL);
- purple_buddy_set_protocol_data(buddy, user);
- msn_user_set_op(user, MSN_LIST_FL_OP);
- }
- for (l = session->account->permit; l != NULL; l = l->next)
- {
- user = msn_userlist_find_add_user(session->userlist,
- (char *)l->data,NULL);
- msn_user_set_op(user, MSN_LIST_AL_OP);
- }
- for (l = session->account->deny; l != NULL; l = l->next)
- {
- user = msn_userlist_find_add_user(session->userlist,
- (char *)l->data,NULL);
- msn_user_set_op(user, MSN_LIST_BL_OP);
- }
-
-}
-
diff --git a/libpurple/protocols/msn/userlist.h b/libpurple/protocols/msn/userlist.h
deleted file mode 100644
index 4e9582a756..0000000000
--- a/libpurple/protocols/msn/userlist.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/**
- * @file userlist.h MSN user list support
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-#ifndef MSN_USERLIST_H
-#define MSN_USERLIST_H
-
-typedef struct _MsnUserList MsnUserList;
-
-typedef enum
-{
- MSN_LIST_FL, /**< Forward list */
- MSN_LIST_AL, /**< Allow list */
- MSN_LIST_BL, /**< Block list */
- MSN_LIST_RL, /**< Reverse list */
- MSN_LIST_PL /**< Pending list */
-} MsnListId;
-
-typedef enum
-{
- MSN_LIST_FL_OP = 0x01,
- MSN_LIST_AL_OP = 0x02,
- MSN_LIST_BL_OP = 0x04,
- MSN_LIST_RL_OP = 0x08,
- MSN_LIST_PL_OP = 0x10
-} MsnListOp;
-#define MSN_LIST_OP_MASK 0x07
-
-#include "group.h"
-#include "msn.h"
-#include "user.h"
-
-struct _MsnUserList
-{
- MsnSession *session;
-
- GList *users; /* Contains MsnUsers */
- GList *groups; /* Contains MsnGroups */
-
- GQueue *buddy_icon_requests;
- int buddy_icon_window;
- guint buddy_icon_request_timer;
-
-};
-
-void msn_got_lst_user(MsnSession *session, MsnUser *user,
- MsnListOp list_op, GSList *group_ids);
-
-MsnUserList *msn_userlist_new(MsnSession *session);
-void msn_userlist_destroy(MsnUserList *userlist);
-
-void msn_userlist_add_user(MsnUserList *userlist, MsnUser *user);
-void msn_userlist_remove_user(MsnUserList *userlist, MsnUser *user);
-
-MsnUser * msn_userlist_find_user(MsnUserList *userlist, const char *passport);
-MsnUser * msn_userlist_find_add_user(MsnUserList *userlist,
- const char *passport, const char *friendly_name);
-MsnUser * msn_userlist_find_user_with_id(MsnUserList *userlist, const char *uid);
-MsnUser * msn_userlist_find_user_with_mobile_phone(MsnUserList *userlist, const char *number);
-
-void msn_userlist_add_group(MsnUserList *userlist, MsnGroup *group);
-void msn_userlist_remove_group(MsnUserList *userlist, MsnGroup *group);
-MsnGroup *msn_userlist_find_group_with_id(MsnUserList *userlist, const char *id);
-MsnGroup *msn_userlist_find_group_with_name(MsnUserList *userlist, const char *name);
-const char * msn_userlist_find_group_id(MsnUserList *userlist,
- const char *group_name);
-const char *msn_userlist_find_group_name(MsnUserList *userlist, const char *group_id);
-void msn_userlist_rename_group_id(MsnUserList *userlist, const char *group_id,
- const char *new_name);
-void msn_userlist_remove_group_id(MsnUserList *userlist, const char *group_id);
-
-void msn_userlist_rem_buddy(MsnUserList *userlist, const char *who);
-void msn_userlist_add_buddy(MsnUserList *userlist,
- const char *who, const char *group_name);
-void msn_userlist_move_buddy(MsnUserList *userlist, const char *who,
- const char *old_group_name,
- const char *new_group_name);
-
-gboolean msn_userlist_add_buddy_to_group(MsnUserList *userlist, const char *who,
- const char *group_name);
-gboolean msn_userlist_rem_buddy_from_group(MsnUserList *userlist,
- const char *who,
- const char *group_name);
-
-void msn_userlist_add_buddy_to_list(MsnUserList *userlist, const char *who,
- MsnListId list_id);
-void msn_userlist_rem_buddy_from_list(MsnUserList *userlist, const char *who,
- MsnListId list_id);
-void msn_release_buddy_icon_request(MsnUserList *userlist);
-
-void msn_userlist_load(MsnSession *session);
-
-#endif /* MSN_USERLIST_H */
diff --git a/libpurple/protocols/msn/xfer.c b/libpurple/protocols/msn/xfer.c
deleted file mode 100644
index 4da276dacd..0000000000
--- a/libpurple/protocols/msn/xfer.c
+++ /dev/null
@@ -1,235 +0,0 @@
-/**
- * @file xfer.c MSN File Transfer functions
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-
-#include "internal.h"
-#include "debug.h"
-
-#include "msnutils.h"
-#include "sbconn.h"
-#include "xfer.h"
-
-/**************************************************************************
- * Xfer
- **************************************************************************/
-
-void
-msn_xfer_init(PurpleXfer *xfer)
-{
- MsnSlpCall *slpcall;
- /* MsnSlpLink *slplink; */
- char *content;
-
- purple_debug_info("msn", "xfer_init\n");
-
- slpcall = xfer->data;
-
- /* Send Ok */
- content = g_strdup_printf("SessionID: %lu\r\n\r\n",
- slpcall->session_id);
-
- msn_slp_send_ok(slpcall, slpcall->branch, "application/x-msnmsgr-sessionreqbody",
- content);
-
- g_free(content);
- msn_slplink_send_queued_slpmsgs(slpcall->slplink);
-}
-
-void
-msn_xfer_cancel(PurpleXfer *xfer)
-{
- MsnSlpCall *slpcall;
- char *content;
-
- g_return_if_fail(xfer != NULL);
- g_return_if_fail(xfer->data != NULL);
-
- slpcall = xfer->data;
-
- if (purple_xfer_get_status(xfer) == PURPLE_XFER_STATUS_CANCEL_LOCAL)
- {
- if (slpcall->started)
- {
- msn_slpcall_close(slpcall);
- }
- else
- {
- content = g_strdup_printf("SessionID: %lu\r\n\r\n",
- slpcall->session_id);
-
- msn_slp_send_decline(slpcall, slpcall->branch, "application/x-msnmsgr-sessionreqbody",
- content);
-
- g_free(content);
- msn_slplink_send_queued_slpmsgs(slpcall->slplink);
-
- if (purple_xfer_get_type(xfer) == PURPLE_XFER_SEND)
- slpcall->wasted = TRUE;
- else
- msn_slpcall_destroy(slpcall);
- }
- }
-}
-
-gssize
-msn_xfer_write(const guchar *data, gsize len, PurpleXfer *xfer)
-{
- MsnSlpCall *slpcall;
-
- g_return_val_if_fail(xfer != NULL, -1);
- g_return_val_if_fail(data != NULL, -1);
- g_return_val_if_fail(len > 0, -1);
-
- g_return_val_if_fail(purple_xfer_get_type(xfer) == PURPLE_XFER_SEND, -1);
-
- slpcall = xfer->data;
- /* Not sure I trust it'll be there */
- g_return_val_if_fail(slpcall != NULL, -1);
-
- g_return_val_if_fail(slpcall->xfer_msg != NULL, -1);
-
- slpcall->u.outgoing.len = len;
- slpcall->u.outgoing.data = data;
- msn_slplink_send_msgpart(slpcall->slplink, slpcall->xfer_msg);
-
- return MIN(MSN_SBCONN_MAX_SIZE, len);
-}
-
-gssize
-msn_xfer_read(guchar **data, PurpleXfer *xfer)
-{
- MsnSlpCall *slpcall;
- gsize len;
-
- g_return_val_if_fail(xfer != NULL, -1);
- g_return_val_if_fail(data != NULL, -1);
-
- g_return_val_if_fail(purple_xfer_get_type(xfer) == PURPLE_XFER_RECEIVE, -1);
-
- slpcall = xfer->data;
- /* Not sure I trust it'll be there */
- g_return_val_if_fail(slpcall != NULL, -1);
-
- /* Just pass up the whole GByteArray. We'll make another. */
- *data = slpcall->u.incoming_data->data;
- len = slpcall->u.incoming_data->len;
-
- g_byte_array_free(slpcall->u.incoming_data, FALSE);
- slpcall->u.incoming_data = g_byte_array_new();
-
- return len;
-}
-
-void
-msn_xfer_end_cb(MsnSlpCall *slpcall, MsnSession *session)
-{
- if ((purple_xfer_get_status(slpcall->xfer) != PURPLE_XFER_STATUS_DONE) &&
- (purple_xfer_get_status(slpcall->xfer) != PURPLE_XFER_STATUS_CANCEL_REMOTE) &&
- (purple_xfer_get_status(slpcall->xfer) != PURPLE_XFER_STATUS_CANCEL_LOCAL))
- {
- purple_xfer_cancel_remote(slpcall->xfer);
- }
-}
-
-void
-msn_xfer_completed_cb(MsnSlpCall *slpcall, const guchar *body,
- gsize size)
-{
- PurpleXfer *xfer = slpcall->xfer;
-
- purple_xfer_set_completed(xfer, TRUE);
- purple_xfer_end(xfer);
-}
-
-gchar *
-msn_file_context_to_wire(MsnFileContext *context)
-{
- gchar *ret, *tmp;
-
- tmp = ret = g_new(gchar, MSN_FILE_CONTEXT_SIZE + context->preview_len + 1);
-
- msn_push32le(tmp, context->length);
- msn_push32le(tmp, context->version);
- msn_push64le(tmp, context->file_size);
- msn_push32le(tmp, context->type);
- memcpy(tmp, context->file_name, MAX_FILE_NAME_LEN * 2);
- tmp += MAX_FILE_NAME_LEN * 2;
- memcpy(tmp, context->unknown1, sizeof(context->unknown1));
- tmp += sizeof(context->unknown1);
- msn_push32le(tmp, context->unknown2);
- if (context->preview) {
- memcpy(tmp, context->preview, context->preview_len);
- }
- tmp[context->preview_len] = '\0';
-
- return ret;
-}
-
-MsnFileContext *
-msn_file_context_from_wire(const char *buf, gsize len)
-{
- MsnFileContext *context;
-
- if (!buf || len < MSN_FILE_CONTEXT_SIZE)
- return NULL;
-
- context = g_new(MsnFileContext, 1);
-
- context->length = msn_pop32le(buf);
- context->version = msn_pop32le(buf);
- if (context->version == 2) {
- /* The length field is broken for this version. No check. */
- context->length = MSN_FILE_CONTEXT_SIZE;
- } else if (context->version == 3) {
- if (context->length != MSN_FILE_CONTEXT_SIZE + 63) {
- g_free(context);
- return NULL;
- } else if (len < MSN_FILE_CONTEXT_SIZE + 63) {
- g_free(context);
- return NULL;
- }
- } else {
- purple_debug_warning("msn", "Received MsnFileContext with unknown version: %d\n", context->version);
- g_free(context);
- return NULL;
- }
-
- context->file_size = msn_pop64le(buf);
- context->type = msn_pop32le(buf);
- memcpy(context->file_name, buf, MAX_FILE_NAME_LEN * 2);
- buf += MAX_FILE_NAME_LEN * 2;
- memcpy(context->unknown1, buf, sizeof(context->unknown1));
- buf += sizeof(context->unknown1);
- context->unknown2 = msn_pop32le(buf);
-
- if (context->type == 0 && len > context->length) {
- context->preview_len = len - context->length;
- context->preview = g_memdup(buf, context->preview_len);
- } else {
- context->preview_len = 0;
- context->preview = NULL;
- }
-
- return context;
-}
-
diff --git a/libpurple/protocols/msn/xfer.h b/libpurple/protocols/msn/xfer.h
deleted file mode 100644
index 23e19f37c3..0000000000
--- a/libpurple/protocols/msn/xfer.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
- * @file xfer.h MSN File Transfer functions
- *
- * purple
- *
- * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-
-#ifndef MSN_XFER_H
-#define MSN_XFER_H
-
-#include "slpcall.h"
-
-#define MAX_FILE_NAME_LEN 260 /* MAX_PATH in Windows */
-
-/**
- * The context data for a file transfer request
- */
-typedef struct
-{
- guint32 length; /*< Length of header */
- guint32 version; /*< MSN version */
- guint64 file_size; /*< Size of file */
- guint32 type; /*< Transfer type */
- gunichar2 file_name[MAX_FILE_NAME_LEN]; /*< Self-explanatory */
- gchar unknown1[30]; /*< Used somehow for background sharing */
- guint32 unknown2; /*< Possibly for background sharing as well */
- gchar *preview; /*< File preview data, 96x96 PNG */
- gsize preview_len;
-} MsnFileContext;
-
-#define MSN_FILE_CONTEXT_SIZE (4*4 + 1*8 + 2*MAX_FILE_NAME_LEN + 30)
-
-void msn_xfer_init(PurpleXfer *xfer);
-void msn_xfer_cancel(PurpleXfer *xfer);
-
-gssize msn_xfer_write(const guchar *data, gsize len, PurpleXfer *xfer);
-gssize msn_xfer_read(guchar **data, PurpleXfer *xfer);
-
-void msn_xfer_completed_cb(MsnSlpCall *slpcall,
- const guchar *body, gsize size);
-void msn_xfer_end_cb(MsnSlpCall *slpcall, MsnSession *session);
-
-gchar *
-msn_file_context_to_wire(MsnFileContext *context);
-
-MsnFileContext *
-msn_file_context_from_wire(const char *buf, gsize len);
-
-#endif /* MSN_XFER_H */
-
diff --git a/pidgin/win32/nsis/pidgin-installer.nsi b/pidgin/win32/nsis/pidgin-installer.nsi
index d09ec0c34d..ee2be32da4 100644
--- a/pidgin/win32/nsis/pidgin-installer.nsi
+++ b/pidgin/win32/nsis/pidgin-installer.nsi
@@ -564,7 +564,6 @@ Section Uninstall
Delete "$INSTDIR\plugins\libgg.dll"
Delete "$INSTDIR\plugins\libicq.dll"
Delete "$INSTDIR\plugins\libirc.dll"
- Delete "$INSTDIR\plugins\libmsn.dll"
Delete "$INSTDIR\plugins\libmyspace.dll"
Delete "$INSTDIR\plugins\libnapster.dll"
Delete "$INSTDIR\plugins\libnovell.dll"
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 6b4673eb7d..5e93928af2 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -107,21 +107,6 @@ libpurple/protocols/jabber/si.c
libpurple/protocols/jabber/usermood.c
libpurple/protocols/jabber/usernick.c
libpurple/protocols/jabber/xdata.c
-libpurple/protocols/msn/contact.c
-libpurple/protocols/msn/error.c
-libpurple/protocols/msn/group.h
-libpurple/protocols/msn/msg.c
-libpurple/protocols/msn/msn.c
-libpurple/protocols/msn/nexus.c
-libpurple/protocols/msn/notification.c
-libpurple/protocols/msn/oim.c
-libpurple/protocols/msn/servconn.c
-libpurple/protocols/msn/session.c
-libpurple/protocols/msn/slp.c
-libpurple/protocols/msn/slpcall.c
-libpurple/protocols/msn/state.c
-libpurple/protocols/msn/switchboard.c
-libpurple/protocols/msn/userlist.c
libpurple/protocols/myspace/myspace.c
libpurple/protocols/myspace/user.c
libpurple/protocols/myspace/zap.c