changeset 19645:5c92f70f8b0c

merge of '13a4e3e02e0fa91a6083954093807fa58bab04e8' and 'aa651fe1eac8c4bd79a37a2fdfb5e528dc759b07'
author Sadrul Habib Chowdhury <imadil@gmail.com>
date Tue, 04 Sep 2007 18:19:39 +0000
parents 1481ea6bb805 (current diff) ec7b92cbf49f (diff)
children 55d3f1622cf7
files
diffstat 11 files changed, 146 insertions(+), 94 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/network.c	Tue Sep 04 18:17:33 2007 +0000
+++ b/libpurple/network.c	Tue Sep 04 18:19:39 2007 +0000
@@ -351,6 +351,7 @@
 	listen_data->retry = TRUE;
 	listen_data->cb = cb;
 	listen_data->cb_data = cb_data;
+	listen_data->socket_type = socket_type;
 
 	/* Attempt a NAT-PMP Mapping, which will return immediately */
 	if (purple_pmp_create_map(((socket_type == SOCK_STREAM) ? PURPLE_PMP_TYPE_TCP : PURPLE_PMP_TYPE_UDP),
--- a/libpurple/protocols/myspace/myspace.c	Tue Sep 04 18:17:33 2007 +0000
+++ b/libpurple/protocols/myspace/myspace.c	Tue Sep 04 18:19:39 2007 +0000
@@ -1775,15 +1775,23 @@
 	purple_debug_info("msim", "msim_error (sesskey=%d): %s\n", 
 			session->sesskey, full_errmsg);
 
-	purple_notify_error(session->account, g_strdup(_("MySpaceIM Error")), 
-			full_errmsg, NULL);
-
 	/* Destroy session if fatal. */
 	if (msim_msg_get(msg, "fatal")) {
 		purple_debug_info("msim", "fatal error, closing\n");
+		if (err == 260) {
+			/* Incorrect password */
+			session->gc->wants_to_die = TRUE;
+			if (!purple_account_get_remember_password(session->account))
+				purple_account_set_password(session->account, NULL);
+		}
 		purple_connection_error(session->gc, full_errmsg);
+	} else {
+		purple_notify_error(session->account, g_strdup(_("MySpaceIM Error")), 
+				full_errmsg, NULL);
 	}
 
+	g_free(full_errmsg);
+
 	return TRUE;
 }
 
--- a/libpurple/protocols/oscar/family_auth.c	Tue Sep 04 18:17:33 2007 +0000
+++ b/libpurple/protocols/oscar/family_auth.c	Tue Sep 04 18:19:39 2007 +0000
@@ -211,7 +211,7 @@
 
 #ifdef USE_XOR_FOR_ICQ
 	/* If we're signing on an ICQ account then use the older, XOR login method */
-	if (aim_sn_is_icq(sn))
+	if (aim_snvalid_icq(sn))
 		return goddamnicq2(od, conn, sn, password, ci);
 #endif
 
@@ -224,7 +224,7 @@
 
 	/* Truncate ICQ and AOL passwords, if necessary */
 	password_len = strlen(password);
-	if (aim_sn_is_icq(sn) && (password_len > MAXICQPASSLEN))
+	if (aim_snvalid_icq(sn) && (password_len > MAXICQPASSLEN))
 		password_len = MAXICQPASSLEN;
 	else if (truncate_pass && password_len > 8)
 		password_len = 8;
@@ -477,7 +477,7 @@
 		return -EINVAL;
 
 #ifdef USE_XOR_FOR_ICQ
-	if (aim_sn_is_icq(sn))
+	if (aim_snvalid_icq(sn))
 		return goddamnicq(od, conn, sn);
 #endif
 
--- a/libpurple/protocols/oscar/family_icbm.c	Tue Sep 04 18:17:33 2007 +0000
+++ b/libpurple/protocols/oscar/family_icbm.c	Tue Sep 04 18:19:39 2007 +0000
@@ -2101,7 +2101,11 @@
 	args.uin = byte_stream_getle32(&meat);
 	args.type = byte_stream_getle8(&meat);
 	args.flags = byte_stream_getle8(&meat);
-	args.msglen = byte_stream_getle16(&meat);
+	if (args.type == 0x1a)
+		/* There seems to be a problem with the length in SMS msgs from server, this fixed it */
+		args.msglen = block->length - 6;
+	else
+		args.msglen = byte_stream_getle16(&meat);
 	args.msg = (gchar *)byte_stream_getraw(&meat, args.msglen);
 
 	if ((userfunc = aim_callhandler(od, snac->family, snac->subtype)))
--- a/libpurple/protocols/oscar/family_icq.c	Tue Sep 04 18:17:33 2007 +0000
+++ b/libpurple/protocols/oscar/family_icq.c	Tue Sep 04 18:19:39 2007 +0000
@@ -340,7 +340,6 @@
 }
 #endif
 
-#if 0
 /*
  * Send an SMS message.  This is the non-US way.  The US-way is to IM
  * their cell phone number (+19195551234).
@@ -369,6 +368,7 @@
 	const char *timestr;
 	time_t t;
 	struct tm *tm;
+	gchar *stripped;
 
 	if (!od || !(conn = flap_connection_findbygroup(od, 0x0015)))
 		return -EINVAL;
@@ -380,22 +380,24 @@
 	tm = gmtime(&t);
 	timestr = purple_utf8_strftime("%a, %d %b %Y %T %Z", tm);
 
+	stripped = purple_markup_strip_html(msg);
+
 	/* The length of xml included the null terminating character */
-	xmllen = 225 + strlen(name) + strlen(msg) + strlen(od->sn) + strlen(alias) + strlen(timestr) + 1;
+	xmllen = 209 + strlen(name) + strlen(stripped) + strlen(od->sn) + strlen(alias) + strlen(timestr) + 1;
 
 	xml = g_new(char, xmllen);
-	snprintf(xml, xmllen, "<icq_sms_message>\n"
-		"\t<destination>%s</destination>\n"
-		"\t<text>%s</text>\n"
-		"\t<codepage>1252</codepage>\n"
-		"\t<senders_UIN>%s</senders_UIN>\n"
-		"\t<senders_name>%s</senders_name>\n"
-		"\t<delivery_receipt>Yes</delivery_receipt>\n"
-		"\t<time>%s</time>\n"
-		"</icq_sms_message>\n",
-		name, msg, od->sn, alias, timestr);
+	snprintf(xml, xmllen, "<icq_sms_message>"
+		"<destination>%s</destination>"
+		"<text>%s</text>"
+		"<codepage>1252</codepage>"
+		"<senders_UIN>%s</senders_UIN>"
+		"<senders_name>%s</senders_name>"
+		"<delivery_receipt>Yes</delivery_receipt>"
+		"<time>%s</time>"
+		"</icq_sms_message>",
+		name, stripped, od->sn, alias, timestr);
 
-	bslen = 37 + xmllen;
+	bslen = 36 + xmllen;
 
 	frame = flap_frame_new(od, 0x02, 10 + 4 + bslen);
 
@@ -412,7 +414,7 @@
 	byte_stream_putle16(&frame->data, snacid); /* eh. */
 
 	/* From libicq200-0.3.2/src/SNAC-SRV.cpp */
-	byte_stream_putle16(&frame->data, 0x8214);
+	byte_stream_putle16(&frame->data, 0x1482);
 	byte_stream_put16(&frame->data, 0x0001);
 	byte_stream_put16(&frame->data, 0x0016);
 	byte_stream_put32(&frame->data, 0x00000000);
@@ -423,14 +425,15 @@
 	byte_stream_put16(&frame->data, 0x0000);
 	byte_stream_put16(&frame->data, xmllen);
 	byte_stream_putstr(&frame->data, xml);
+	byte_stream_put8(&frame->data, 0x00);
 
 	flap_connection_send(conn, frame);
 
 	g_free(xml);
+	g_free(stripped);
 
 	return 0;
 }
-#endif
 
 static void aim_icq_freeinfo(struct aim_icq_info *info) {
 	int i;
--- a/libpurple/protocols/oscar/oscar.c	Tue Sep 04 18:17:33 2007 +0000
+++ b/libpurple/protocols/oscar/oscar.c	Tue Sep 04 18:19:39 2007 +0000
@@ -358,7 +358,7 @@
 	const char *charset = NULL;
 	char *ret = NULL;
 
-	if(aim_sn_is_icq(purple_account_get_username(account)))
+	if(aim_snvalid_icq(purple_account_get_username(account)))
 		charset = purple_account_get_string(account, "encoding", NULL);
 
 	if(charset && *charset)
@@ -424,7 +424,7 @@
 		charsetstr1 = "UCS-2BE";
 		charsetstr2 = "UTF-8";
 	} else if (charset == AIM_CHARSET_CUSTOM) {
-		if ((sourcesn != NULL) && aim_sn_is_icq(sourcesn))
+		if ((sourcesn != NULL) && aim_snvalid_icq(sourcesn))
 			charsetstr1 = purple_account_get_string(account, "encoding", OSCAR_DEFAULT_CUSTOM_ENCODING);
 		else
 			charsetstr1 = "ISO-8859-1";
@@ -495,7 +495,7 @@
 	 * capability, and they are online, then attempt to send
 	 * as UCS-2BE.
 	 */
-	if ((destsn != NULL) && aim_sn_is_icq(destsn))
+	if ((destsn != NULL) && aim_snvalid_icq(destsn))
 		userinfo = aim_locate_finduserinfo(od, destsn);
 
 	if ((userinfo != NULL) && (userinfo->capabilities & OSCAR_CAPABILITY_UNICODE))
@@ -520,7 +520,7 @@
 	 * ICQ then attempt to send as the user specified character encoding.
 	 */
 	charsetstr = "ISO-8859-1";
-	if ((destsn != NULL) && aim_sn_is_icq(destsn))
+	if ((destsn != NULL) && aim_snvalid_icq(destsn))
 		charsetstr = purple_account_get_string(account, "encoding", OSCAR_DEFAULT_CUSTOM_ENCODING);
 
 	/*
@@ -815,7 +815,7 @@
 
 	if (b != NULL) {
 		if (purple_presence_is_online(presence)) {
-			if (aim_sn_is_icq(b->name)) {
+			if (aim_snvalid_icq(b->name)) {
 				PurpleStatus *status = purple_presence_get_active_status(presence);
 				oscar_user_info_add_pair(user_info, _("Status"),	purple_status_get_name(status));
 			}
@@ -1019,7 +1019,7 @@
 			PURPLE_INPUT_READ, flap_connection_recv_cb, conn);
 	if (conn->cookie == NULL)
 	{
-		if (!aim_sn_is_icq(purple_account_get_username(account)))
+		if (!aim_snvalid_icq(purple_account_get_username(account)))
 			/*
 			 * We don't send this when authenticating an ICQ account
 			 * because for some reason ICQ is still using the
@@ -1261,7 +1261,7 @@
 		g_free(buf);
 	}
 
-	if (aim_sn_is_icq((purple_account_get_username(account)))) {
+	if (aim_snvalid_icq((purple_account_get_username(account)))) {
 		od->icq = TRUE;
 	} else {
 		gc->flags |= PURPLE_CONNECTION_HTML;
@@ -1752,7 +1752,7 @@
 		}
 	}
 
-	if (aim_sn_is_icq(info->sn)) {
+	if (aim_snvalid_icq(info->sn)) {
 		if (type & AIM_ICQ_STATE_CHAT)
 			status_id = OSCAR_STATUS_ID_FREE4CHAT;
 		else if (type & AIM_ICQ_STATE_DND)
@@ -1987,7 +1987,7 @@
 	 * Note: There *may* be some clients which send messages as HTML formatted -
 	 *       they need to be special-cased somehow.
 	 */
-	if (aim_sn_is_icq(purple_account_get_username(account)) && aim_sn_is_icq(userinfo->sn)) {
+	if (aim_snvalid_icq(purple_account_get_username(account)) && aim_snvalid_icq(userinfo->sn)) {
 		/* being recevied by ICQ from ICQ - escape HTML so it is displayed as sent */
 		gchar *tmp2 = g_markup_escape_text(tmp, -1);
 		g_free(tmp);
@@ -2486,8 +2486,48 @@
 			}
 		} break;
 
-		case 0x1a: { /* Someone has sent you a greeting card or requested buddies? */
-			/* This is boring and silly. */
+		case 0x1a: { /* Handle SMS or someone has sent you a greeting card or requested buddies? */
+			ByteStream qbs;
+			int smstype, taglen, smslen;
+			char *tagstr = NULL, *smsmsg = NULL;
+			xmlnode *xmlroot = NULL, *xmltmp = NULL;
+			gchar *uin = NULL, *message = NULL;
+
+			/* From libicq2000-0.3.2/src/ICQ.cpp */
+			byte_stream_init(&qbs, (guint8 *)args->msg, args->msglen);
+			byte_stream_advance(&qbs, 21);
+			smstype = byte_stream_getle16(&qbs);
+			taglen = byte_stream_getle32(&qbs);
+			tagstr = byte_stream_getstr(&qbs, taglen);
+			byte_stream_advance(&qbs, 3);
+			byte_stream_advance(&qbs, 4);
+			smslen = byte_stream_getle32(&qbs);
+			smsmsg = byte_stream_getstr(&qbs, smslen);
+
+			/* Check if this is an SMS being sent from server */
+			if ((smstype == 0) && (!strcmp(tagstr, "ICQSMS")) && (smsmsg != NULL))
+			{
+				xmlroot = xmlnode_from_str(smsmsg, -1);
+				if (xmlroot != NULL)
+				{
+					xmltmp = xmlnode_get_child(xmlroot, "sender");
+					if (xmltmp != NULL)
+						uin = xmlnode_get_data(xmltmp);
+
+					xmltmp = xmlnode_get_child(xmlroot, "text");
+					if (xmltmp != NULL)
+						message = xmlnode_get_data(xmltmp);
+
+					if ((uin != NULL) && (message != NULL))
+							serv_got_im(gc, uin, message, 0, time(NULL));
+
+					g_free(uin);
+					g_free(message);
+					xmlnode_free(xmlroot);
+				}
+			}
+			g_free(tagstr);
+			g_free(smsmsg);
 		} break;
 
 		default: {
@@ -2963,7 +3003,7 @@
 	if (b == NULL)
 		return 1;
 
-	if (!aim_sn_is_icq(userinfo->sn))
+	if (!aim_snvalid_icq(userinfo->sn))
 	{
 		if (strcmp(purple_buddy_get_name(b), userinfo->sn))
 			serv_got_alias(gc, purple_buddy_get_name(b), userinfo->sn);
@@ -4154,6 +4194,17 @@
 	account = purple_connection_get_account(gc);
 	ret = 0;
 
+	if (od->icq && aim_snvalid_sms(name)) {
+		/*
+		 * We're sending to a phone number and this is ICQ,
+		 * so send the message as an SMS using aim_icq_sendsms()
+		 */
+		int ret;
+		purple_debug_info("oscar", "Sending SMS to %s.\n", name);
+		ret = aim_icq_sendsms(od, name, message, purple_account_get_username(account));
+		return (ret >= 0 ? 1 : ret);
+	}
+
 	if (imflags & PURPLE_MESSAGE_AUTO_RESP)
 		tmp1 = purple_str_sub_away_formatters(message, name);
 	else
@@ -4254,12 +4305,12 @@
 		/*
 		 * If we're IMing an SMS user or an ICQ user from an ICQ account, then strip HTML.
 		 */
-		if (aim_sn_is_sms(name)) {
+		if (aim_snvalid_sms(name)) {
 			/* Messaging an SMS (mobile) user */
 			tmp2 = purple_markup_strip_html(tmp1);
 			is_html = FALSE;
-		} else if (aim_sn_is_icq(purple_account_get_username(account))) {
-			if (aim_sn_is_icq(name)) {
+		} else if (aim_snvalid_icq(purple_account_get_username(account))) {
+			if (aim_snvalid_icq(name)) {
 				/* From ICQ to ICQ */
 				tmp2 = purple_markup_strip_html(tmp1);
 				is_html = FALSE;
@@ -4321,7 +4372,7 @@
 void oscar_get_info(PurpleConnection *gc, const char *name) {
 	OscarData *od = (OscarData *)gc->proto_data;
 
-	if (od->icq && aim_sn_is_icq(name))
+	if (od->icq && aim_snvalid_icq(name))
 		aim_icq_getallinfo(od, name);
 	else
 		aim_locate_getinfoshort(od, name, 0x00000003);
@@ -4566,7 +4617,7 @@
 	oscar_set_info_and_status(account, FALSE, NULL, TRUE, status);
 
 	/* Set the ICQ status for ICQ accounts only */
-	if (aim_sn_is_icq(purple_account_get_username(account)))
+	if (aim_snvalid_icq(purple_account_get_username(account)))
 		oscar_set_status_icq(account, status);
 }
 
@@ -5405,30 +5456,30 @@
 
 const char *oscar_list_icon_icq(PurpleAccount *a, PurpleBuddy *b)
 {
-	if ((b == NULL) || (b->name == NULL) || aim_sn_is_sms(b->name))
+	if ((b == NULL) || (b->name == NULL) || aim_snvalid_sms(b->name))
 	{
-		if (a == NULL || aim_sn_is_icq(purple_account_get_username(a)))
+		if (a == NULL || aim_snvalid_icq(purple_account_get_username(a)))
 			return "icq";
 		else
 			return "aim";
 	}
 
-	if (aim_sn_is_icq(b->name))
+	if (aim_snvalid_icq(b->name))
 		return "icq";
 	return "aim";
 }
 
 const char *oscar_list_icon_aim(PurpleAccount *a, PurpleBuddy *b)
 {
-	if ((b == NULL) || (b->name == NULL) || aim_sn_is_sms(b->name))
+	if ((b == NULL) || (b->name == NULL) || aim_snvalid_sms(b->name))
 	{
-		if (a != NULL && aim_sn_is_icq(purple_account_get_username(a)))
+		if (a != NULL && aim_snvalid_icq(purple_account_get_username(a)))
 			return "icq";
 		else
 			return "aim";
 	}
 
-	if (aim_sn_is_icq(b->name))
+	if (aim_snvalid_icq(b->name))
 		return "icq";
 	return "aim";
 }
@@ -5712,7 +5763,7 @@
 	g_return_val_if_fail(account != NULL, NULL);
 
 	/* Used to flag some statuses as "user settable" or not */
-	is_icq = aim_sn_is_icq(purple_account_get_username(account));
+	is_icq = aim_snvalid_icq(purple_account_get_username(account));
 
 	/* Common status types */
 	/* Really the available message should only be settable for AIM accounts */
@@ -5920,7 +5971,7 @@
 	userinfo = aim_locate_finduserinfo(od, buddy->name);
 	menu = NULL;
 
-	if (od->icq && aim_sn_is_icq(purple_buddy_get_name(buddy)))
+	if (od->icq && aim_snvalid_icq(purple_buddy_get_name(buddy)))
 	{
 		act = purple_menu_action_new(_("Get AIM Info"),
 								   PURPLE_CALLBACK(oscar_get_aim_info_cb),
@@ -6515,7 +6566,7 @@
 			od = (OscarData *)gc->proto_data;
 	}
 
-	return (od != NULL && od->icq && aim_sn_is_icq(purple_account_get_username(account)));
+	return (od != NULL && od->icq && aim_snvalid_icq(purple_account_get_username(account)));
 }
 
 /* TODO: Find somewhere to put this instead of including it in a bunch of places.
--- a/libpurple/protocols/oscar/oscar.h	Tue Sep 04 18:17:33 2007 +0000
+++ b/libpurple/protocols/oscar/oscar.h	Tue Sep 04 18:19:39 2007 +0000
@@ -1320,6 +1320,7 @@
 int aim_icq_getsimpleinfo(OscarData *od, const char *uin);
 int aim_icq_getalias(OscarData *od, const char *uin);
 int aim_icq_getallinfo(OscarData *od, const char *uin);
+int aim_icq_sendsms(OscarData *od, const char *name, const char *msg, const char *alias);
 
 
 
@@ -1458,8 +1459,8 @@
 char *aimutil_itemindex(char *toSearch, int theindex, char dl);
 
 gboolean aim_snvalid(const char *sn);
-gboolean aim_sn_is_icq(const char *sn);
-gboolean aim_sn_is_sms(const char *sn);
+gboolean aim_snvalid_icq(const char *sn);
+gboolean aim_snvalid_sms(const char *sn);
 int aim_snlen(const char *sn);
 int aim_sncmp(const char *sn1, const char *sn2);
 
--- a/libpurple/protocols/oscar/util.c	Tue Sep 04 18:17:33 2007 +0000
+++ b/libpurple/protocols/oscar/util.c	Tue Sep 04 18:19:39 2007 +0000
@@ -171,7 +171,7 @@
  *
  * @return TRUE if the screen name is valid, FALSE if not.
  */
-static gboolean
+gboolean
 aim_snvalid_icq(const char *sn)
 {
 	int i;
@@ -190,7 +190,7 @@
  *
  * @return TRUE if the screen name is valid, FALSE if not.
  */
-static gboolean
+gboolean
 aim_snvalid_sms(const char *sn)
 {
 	int i;
@@ -221,34 +221,6 @@
 }
 
 /**
- * Determine if a given screen name is an ICQ screen name
- * (i.e. it is composed of only numbers).
- *
- * @param sn A valid AIM or ICQ screen name.
- * @return TRUE if the screen name is an ICQ screen name.  Otherwise
- *         FALSE is returned.
- */
-gboolean
-aim_sn_is_icq(const char *sn)
-{
-	return aim_snvalid_icq(sn);
-}
-
-/**
- * Determine if a given screen name is an SMS number
- * (i.e. it begins with a +).
- *
- * @param sn A valid AIM or ICQ screen name.
- * @return TRUE if the screen name is an SMS number.  Otherwise
- *         FALSE is returned.
- */
-gboolean
-aim_sn_is_sms(const char *sn)
-{
-	return (sn[0] == '+');
-}
-
-/**
  * This takes two screen names and compares them using the rules
  * on screen names for AIM/AOL.  Mainly, this means case and space
  * insensitivity (all case differences and spacing differences are
--- a/libpurple/protocols/qq/header_info.c	Tue Sep 04 18:17:33 2007 +0000
+++ b/libpurple/protocols/qq/header_info.c	Tue Sep 04 18:19:39 2007 +0000
@@ -35,6 +35,7 @@
 #define QQ_CLIENT_0B35 0x0b35	/* GB QQ2003iii build 0304 (offical release) */
 #define QQ_CLIENT_0B37 0x0b37	/* GB QQ2003iii build 0304 (April 05 updates) */
 #define QQ_CLIENT_0E1B 0x0e1b	/* QQ2005? QQ2006? */
+#define QQ_CLIENT_0E35 0x0e35	/* EN QQ2005 V05.0.200.020 */
 #define QQ_CLIENT_0F15 0x0f15	/* QQ2006 Spring Festival build */
 #define QQ_CLIENT_0F5F 0x0f5f	/* QQ2006 final build */
 
@@ -115,6 +116,8 @@
 		return "GB QQ2003iii build 0304 (April 5 update)";
 	case QQ_CLIENT_0E1B:
 		return "QQ2005 or QQ2006";
+	case QQ_CLIENT_0E35:
+		return "En QQ2005 V05.0.200.020";
 	case QQ_CLIENT_0F15:
 		return "QQ2006 Spring Festival build";
 	case QQ_CLIENT_0F5F:
--- a/libpurple/protocols/qq/login_logout.c	Tue Sep 04 18:17:33 2007 +0000
+++ b/libpurple/protocols/qq/login_logout.c	Tue Sep 04 18:19:39 2007 +0000
@@ -380,33 +380,33 @@
 
 void qq_process_request_login_token_reply(guint8 *buf, gint buf_len, PurpleConnection *gc)
 {
-        qq_data *qd;
+	qq_data *qd;
 	gchar *hex_dump;
 
-        g_return_if_fail(buf != NULL && buf_len != 0);
+	g_return_if_fail(buf != NULL && buf_len != 0);
 
-        qd = (qq_data *) gc->proto_data;
+	qd = (qq_data *) gc->proto_data;
 
 	if (buf[0] == QQ_REQUEST_LOGIN_TOKEN_REPLY_OK) {
 		if (buf[1] != buf_len-2) {
-			purple_debug(PURPLE_DEBUG_INFO, "QQ", 
+			purple_debug(PURPLE_DEBUG_INFO, "QQ",
 					"Malformed login token reply packet. Packet specifies length of %d, actual length is %d\n", buf[1], buf_len-2);
 			purple_debug(PURPLE_DEBUG_INFO, "QQ",
 					"Attempting to proceed with the actual packet length.\n");
 		}
 		hex_dump = hex_dump_to_str(buf+2, buf_len-2);
 		purple_debug(PURPLE_DEBUG_INFO, "QQ",
-                                   "<<< got a token with %d bytes -> [default] decrypt and dump\n%s", buf_len-2, hex_dump);
+				"<<< got a token with %d bytes -> [default] decrypt and dump\n%s", buf_len-2, hex_dump);
 		qq_send_packet_login(gc, buf_len-2, buf+2);
 	} else {
 		purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Unknown request login token reply code : %d\n", buf[0]);
 		hex_dump = hex_dump_to_str(buf, buf_len);
-                purple_debug(PURPLE_DEBUG_WARNING, "QQ",
-           		           ">>> %d bytes -> [default] decrypt and dump\n%s",
-	                           buf_len, hex_dump);
-               		try_dump_as_gbk(buf, buf_len);
+		purple_debug(PURPLE_DEBUG_WARNING, "QQ",
+				">>> %d bytes -> [default] decrypt and dump\n%s",
+				buf_len, hex_dump);
+		try_dump_as_gbk(buf, buf_len);
 		purple_connection_error(gc, _("Error requesting login token"));
-	}		
+	}
 	g_free(hex_dump);
 }
 
@@ -463,11 +463,11 @@
 			default:
 				purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Unknown reply code: %d\n", data[0]);
 				hex_dump = hex_dump_to_str(data, len);
-		                purple_debug(PURPLE_DEBUG_WARNING, "QQ",
-                		           ">>> %d bytes -> [default] decrypt and dump\n%s",
-		                           buf_len, hex_dump);
+				purple_debug(PURPLE_DEBUG_WARNING, "QQ",
+						">>> %d bytes -> [default] decrypt and dump\n%s",
+						buf_len, hex_dump);
 				g_free(hex_dump);
-                		try_dump_as_gbk(data, len);
+				try_dump_as_gbk(data, len);
 
 				ret = QQ_LOGIN_REPLY_MISC_ERROR;
 			}
--- a/libpurple/xmlnode.c	Tue Sep 04 18:17:33 2007 +0000
+++ b/libpurple/xmlnode.c	Tue Sep 04 18:19:39 2007 +0000
@@ -549,7 +549,16 @@
 xmlnode_parser_error_libxml(void *user_data, const char *msg, ...)
 {
 	struct _xmlnode_parser_data *xpd = user_data;
+	char errmsg[2048];
+	va_list args;
+
 	xpd->error = TRUE;
+
+	va_start(args, msg);
+	vsnprintf(errmsg, sizeof(errmsg), msg, args);
+	va_end(args);
+
+	purple_debug_error("xmlnode", "Error parsing xml file: %s\n", errmsg);
 }
 
 static xmlSAXHandler xmlnode_parser_libxml = {