changeset 22502:1eadbca855f0

merge of '662b18e22ed66890ffcb81db34c948405b31f4c7' and 'c75212a9281c1a006eb33e70196e493431421b89'
author Etan Reisner <pidgin@unreliablesource.net>
date Wed, 27 Feb 2008 22:41:34 +0000
parents b8774519bda0 (diff) cf596f8b7c48 (current diff)
children e62b3625cc54
files
diffstat 13 files changed, 110 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Wed Feb 27 00:24:57 2008 +0000
+++ b/ChangeLog	Wed Feb 27 22:41:34 2008 +0000
@@ -2,6 +2,8 @@
 
 version 2.4.0 (??/??/2008):
 	libpurple:
+	* Added support for offline messages for AIM accounts (thanks to
+	  Matthew Goldstein)
 	* Fixed various problems with loss of status messages when going
 	  or returning from idle on MySpaceIM.
 	* Eliminated unmaintained Howl backend implementation for the
--- a/ChangeLog.API	Wed Feb 27 00:24:57 2008 +0000
+++ b/ChangeLog.API	Wed Feb 27 22:41:34 2008 +0000
@@ -44,6 +44,8 @@
 			* purple_connection_get_prpl
 			* purple_xfer_get_start_time
 			* purple_xfer_get_end_time
+		* purple_serv_got_private_alias for prpls to call after receiving a
+		  private alias from the server.
 
 	Pidgin:
 		Added:
--- a/libpurple/protocols/msn/notification.c	Wed Feb 27 00:24:57 2008 +0000
+++ b/libpurple/protocols/msn/notification.c	Wed Feb 27 22:41:34 2008 +0000
@@ -1091,7 +1091,7 @@
 	PurpleConnection *gc;
 	MsnUser *user;
 	MsnObject *msnobj;
-	int clientid;
+	unsigned long clientid;
 	int wlmclient;
 	const char *state, *passport, *friendly, *old_friendly;
 
@@ -1126,7 +1126,7 @@
 		}
 	}
 
-	clientid = atoi(cmd->params[4]);
+	clientid = strtoul(cmd->params[4], NULL, 10);
 	user->mobile = (clientid & MSN_CLIENT_CAP_MSNMOBILE);
 
 	msn_user_set_state(user, state);
--- a/libpurple/protocols/oscar/family_icbm.c	Wed Feb 27 00:24:57 2008 +0000
+++ b/libpurple/protocols/oscar/family_icbm.c	Wed Feb 27 22:41:34 2008 +0000
@@ -221,7 +221,7 @@
 	params.maxrecverwarn = byte_stream_get16(bs);
 	params.minmsginterval = byte_stream_get32(bs);
 
-	params.flags = 0x0000000b;
+	params.flags = 0x0000000b | AIM_IMPARAM_FLAG_SUPPORT_OFFLINEMSGS;
 	params.maxmsglen = 8000;
 	params.minmsginterval = 0;
 
@@ -1626,7 +1626,10 @@
 
 		} else if (type == 0x0006) { /* Message was received offline. */
 
-			/* XXX - not sure if this actually gets sent. */
+			/*
+			 * This flag is set on incoming offline messages for both
+			 * AIM and ICQ accounts.
+			 */
 			args.icbmflags |= AIM_IMFLAGS_OFFLINE;
 
 		} else if (type == 0x0008) { /* I-HAVE-A-REALLY-PURTY-ICON Flag */
@@ -1657,6 +1660,14 @@
 
 			args.icbmflags |= AIM_IMFLAGS_TYPINGNOT;
 
+		} else if (type == 0x0016) {
+
+			/*
+			 * UTC timestamp for when the message was sent.  Only
+			 * provided for offline messages.
+			 */
+			args.timestamp = byte_stream_get32(bs);
+
 		} else if (type == 0x0017) {
 
 			if (length > byte_stream_empty(bs))
@@ -2589,6 +2600,30 @@
 }
 
 /*
+ * Subtype 0x0010 - Request any offline messages that are waiting for
+ * us.  This is the "new" way of handling offline messages which is
+ * used for both AIM and ICQ.  The old way is to use the ugly
+ * aim_icq_reqofflinemsgs() function, but that is no longer necessary.
+ *
+ * We set the 0x00000100 flag on the ICBM message parameters, which
+ * tells the oscar servers that we support offline messages.  When we
+ * set that flag the servers do not automatically send us offline
+ * messages.  Instead we must request them using this function.  This
+ * should happen after sending the 0x0001/0x0002 "client online" SNAC.
+ */
+int aim_im_reqofflinemsgs(OscarData *od)
+{
+	FlapConnection *conn;
+
+	if (!od || !(conn = flap_connection_findbygroup(od, 0x0002)))
+		return -EINVAL;
+
+	aim_genericreq_n(od, conn, 0x0004, 0x0010);
+
+	return 0;
+}
+
+/*
  * Subtype 0x0014 - Send a mini typing notification (mtn) packet.
  *
  * This is supported by winaim5 and newer, MacAIM bleh and newer, iChat bleh and newer,
--- a/libpurple/protocols/oscar/family_icq.c	Wed Feb 27 00:24:57 2008 +0000
+++ b/libpurple/protocols/oscar/family_icq.c	Wed Feb 27 22:41:34 2008 +0000
@@ -25,6 +25,7 @@
 
 #include "oscar.h"
 
+#ifdef OLDSTYLE_ICQ_OFFLINEMSGS
 int aim_icq_reqofflinemsgs(OscarData *od)
 {
 	FlapConnection *conn;
@@ -86,6 +87,7 @@
 
 	return 0;
 }
+#endif /* OLDSTYLE_ICQ_OFFLINEMSGS */
 
 int
 aim_icq_setsecurity(OscarData *od, gboolean auth_required, gboolean webaware)
@@ -559,6 +561,7 @@
 	purple_debug_misc("oscar", "icq response: %d bytes, %ld, 0x%04x, 0x%04x\n", cmdlen, ouruin, cmd, reqid);
 
 	if (cmd == 0x0041) { /* offline message */
+#ifdef OLDSTYLE_ICQ_OFFLINEMSGS
 		struct aim_icq_offlinemsg msg;
 		aim_rxcallback_t userfunc;
 
@@ -585,6 +588,7 @@
 
 		if ((userfunc = aim_callhandler(od, SNAC_FAMILY_ICQ, SNAC_SUBTYPE_ICQ_OFFLINEMSGCOMPLETE)))
 			ret = userfunc(od, conn, frame);
+#endif /* OLDSTYLE_ICQ_OFFLINEMSGS */
 
 	} else if (cmd == 0x07da) { /* information */
 		guint16 subtype;
--- a/libpurple/protocols/oscar/oscar.c	Wed Feb 27 00:24:57 2008 +0000
+++ b/libpurple/protocols/oscar/oscar.c	Wed Feb 27 22:41:34 2008 +0000
@@ -180,8 +180,10 @@
 static int purple_parse_genericerr (OscarData *, FlapConnection *, FlapFrame *, ...);
 static int purple_memrequest       (OscarData *, FlapConnection *, FlapFrame *, ...);
 static int purple_selfinfo         (OscarData *, FlapConnection *, FlapFrame *, ...);
+#ifdef OLDSTYLE_ICQ_OFFLINEMSGS
 static int purple_offlinemsg       (OscarData *, FlapConnection *, FlapFrame *, ...);
 static int purple_offlinemsgdone   (OscarData *, FlapConnection *, FlapFrame *, ...);
+#endif /* OLDSTYLE_ICQ_OFFLINEMSGS */
 static int purple_icqalias         (OscarData *, FlapConnection *, FlapFrame *, ...);
 static int purple_icqinfo          (OscarData *, FlapConnection *, FlapFrame *, ...);
 static int purple_popup            (OscarData *, FlapConnection *, FlapFrame *, ...);
@@ -1275,8 +1277,10 @@
 	oscar_data_addhandler(od, SNAC_FAMILY_ICBM, SNAC_SUBTYPE_ICBM_ERROR, purple_parse_msgerr, 0);
 	oscar_data_addhandler(od, SNAC_FAMILY_ICBM, SNAC_SUBTYPE_ICBM_MTN, purple_parse_mtn, 0);
 	oscar_data_addhandler(od, SNAC_FAMILY_ICBM, SNAC_SUBTYPE_ICBM_ACK, purple_parse_msgack, 0);
+#ifdef OLDSTYLE_ICQ_OFFLINEMSGS
 	oscar_data_addhandler(od, SNAC_FAMILY_ICQ, SNAC_SUBTYPE_ICQ_OFFLINEMSG, purple_offlinemsg, 0);
 	oscar_data_addhandler(od, SNAC_FAMILY_ICQ, SNAC_SUBTYPE_ICQ_OFFLINEMSGCOMPLETE, purple_offlinemsgdone, 0);
+#endif /* OLDSTYLE_ICQ_OFFLINEMSGS */
 	oscar_data_addhandler(od, SNAC_FAMILY_ICQ, SNAC_SUBTYPE_ICQ_ALIAS, purple_icqalias, 0);
 	oscar_data_addhandler(od, SNAC_FAMILY_ICQ, SNAC_SUBTYPE_ICQ_INFO, purple_icqinfo, 0);
 	oscar_data_addhandler(od, SNAC_FAMILY_LOCATE, SNAC_SUBTYPE_LOCATE_RIGHTSINFO, purple_parse_locaterights, 0);
@@ -2079,7 +2083,8 @@
 		g_datalist_clear(&attribs);
 	}
 
-	serv_got_im(gc, userinfo->sn, tmp, flags, time(NULL));
+	serv_got_im(gc, userinfo->sn, tmp, flags,
+			(args->icbmflags & AIM_IMFLAGS_OFFLINE) ? args->timestamp : time(NULL));
 	g_free(tmp);
 
 	return 1;
@@ -2264,6 +2269,8 @@
 			}
 		}
 	}
+
+	oscar_free_name_data(data);
 }
 
 static void
@@ -3639,8 +3646,13 @@
 	presence = purple_status_get_presence(status);
 	aim_srv_setidle(od, !purple_presence_is_idle(presence) ? 0 : time(NULL) - purple_presence_get_idle_time(presence));
 
+	/* Request offline messages for AIM and ICQ */
+	aim_im_reqofflinemsgs(od);
+
 	if (od->icq) {
+#ifdef OLDSTYLE_ICQ_OFFLINEMSGS
 		aim_icq_reqofflinemsgs(od);
+#endif
 		oscar_set_extendedstatus(gc);
 		aim_icq_setsecurity(od,
 			purple_account_get_bool(account, "authorization", OSCAR_DEFAULT_AUTHORIZATION),
@@ -3664,6 +3676,7 @@
 	return 1;
 }
 
+#ifdef OLDSTYLE_ICQ_OFFLINEMSGS
 static int purple_offlinemsg(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) {
 	va_list ap;
 	struct aim_icq_offlinemsg *msg;
@@ -3692,6 +3705,7 @@
 	aim_icq_ackofflinemsgs(od);
 	return 1;
 }
+#endif /* OLDSTYLE_ICQ_OFFLINEMSGS */
 
 static int purple_icqinfo(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...)
 {
@@ -4258,7 +4272,7 @@
 			g_hash_table_insert(od->buddyinfo, g_strdup(purple_normalize(account, name)), bi);
 		}
 
-		args.flags = AIM_IMFLAGS_ACK | AIM_IMFLAGS_CUSTOMFEATURES;
+		args.flags = AIM_IMFLAGS_ACK | AIM_IMFLAGS_CUSTOMFEATURES | AIM_IMFLAGS_OFFLINE;
 		if (od->icq) {
 			/* We have to present different "features" (whose meaning
 			   is unclear and are merely a result of protocol inspection)
@@ -4275,7 +4289,6 @@
 				args.features = features_icq_offline;
 				args.featureslen = sizeof(features_icq_offline);
 			}
-			args.flags |= AIM_IMFLAGS_OFFLINE;
 		} else {
 			args.features = features_aim;
 			args.featureslen = sizeof(features_aim);
--- a/libpurple/protocols/oscar/oscar.h	Wed Feb 27 00:24:57 2008 +0000
+++ b/libpurple/protocols/oscar/oscar.h	Wed Feb 27 22:41:34 2008 +0000
@@ -679,8 +679,9 @@
 #define AIM_TRANSFER_DENY_DECLINE	0x0001
 #define AIM_TRANSFER_DENY_NOTACCEPTING	0x0002
 
-#define AIM_IMPARAM_FLAG_CHANMSGS_ALLOWED	0x00000001
-#define AIM_IMPARAM_FLAG_MISSEDCALLS_ENABLED	0x00000002
+#define AIM_IMPARAM_FLAG_CHANMSGS_ALLOWED       0x00000001
+#define AIM_IMPARAM_FLAG_MISSEDCALLS_ENABLED    0x00000002
+#define AIM_IMPARAM_FLAG_SUPPORT_OFFLINEMSGS    0x00000100
 
 /* This is what the server will give you if you don't set them yourself. */
 #define AIM_IMPARAM_DEFAULTS { \
@@ -844,6 +845,7 @@
 	/* Always provided */
 	aim_mpmsg_t mpmsg;
 	guint32 icbmflags; /* some flags apply only to ->msg, not all mpmsg */
+	time_t timestamp; /* Only set for offline messages */
 
 	/* Only provided if message has a human-readable section */
 	gchar *msg;
@@ -948,6 +950,7 @@
 /* 0x0006 */ int aim_im_sendch4(OscarData *od, const char *sn, guint16 type, const char *message);
 /* 0x0008 */ int aim_im_warn(OscarData *od, FlapConnection *conn, const char *destsn, guint32 flags);
 /* 0x000b */ int aim_im_denytransfer(OscarData *od, const char *sn, const guchar *cookie, guint16 code);
+/* 0x0010 */ int aim_im_reqofflinemsgs(OscarData *od);
 /* 0x0014 */ int aim_im_sendmtn(OscarData *od, guint16 type1, const char *sn, guint16 type2);
 void aim_icbm_makecookie(guchar* cookie);
 gchar *oscar_encoding_extract(const char *encoding);
@@ -1256,6 +1259,7 @@
 #define AIM_ICQ_INFO_UNKNOWN	0x100
 #define AIM_ICQ_INFO_HAVEALL	0x1ff
 
+#ifdef OLDSTYLE_ICQ_OFFLINEMSGS
 struct aim_icq_offlinemsg
 {
 	guint32 sender;
@@ -1266,6 +1270,7 @@
 	char *msg;
 	int msglen;
 };
+#endif /* OLDSTYLE_ICQ_OFFLINEMSGS */
 
 struct aim_icq_info
 {
@@ -1330,8 +1335,10 @@
 	char *status_note_title;
 };
 
+#ifdef OLDSTYLE_ICQ_OFFLINEMSGS
 int aim_icq_reqofflinemsgs(OscarData *od);
 int aim_icq_ackofflinemsgs(OscarData *od);
+#endif
 int aim_icq_setsecurity(OscarData *od, gboolean auth_required, gboolean webaware);
 int aim_icq_changepasswd(OscarData *od, const char *passwd);
 int aim_icq_getsimpleinfo(OscarData *od, const char *uin);
--- a/libpurple/server.c	Wed Feb 27 00:24:57 2008 +0000
+++ b/libpurple/server.c	Wed Feb 27 22:41:34 2008 +0000
@@ -274,6 +274,29 @@
 	}
 }
 
+void
+purple_serv_got_private_alias(PurpleConnection *gc, const char *who, const char *alias)
+{
+	PurpleAccount *account = NULL;
+	GSList *buddies = NULL;
+	PurpleBuddy *b = NULL;
+
+	account = purple_connection_get_account(gc);
+	buddies = purple_find_buddies(account, who);
+
+	while(buddies != NULL) {
+		b = buddies->data;
+
+		buddies = g_slist_delete_link(buddies, buddies);
+
+		if((!b->alias && !alias) || (b->alias && alias && !strcmp(b->alias, alias)))
+			continue;
+
+		purple_blist_alias_buddy(b, alias);
+	}
+}
+
+
 PurpleAttentionType *purple_get_attention_type_from_code(PurpleAccount *account, guint type_code)
 {
 	PurplePlugin *prpl;
--- a/libpurple/server.h	Wed Feb 27 00:24:57 2008 +0000
+++ b/libpurple/server.h	Wed Feb 27 22:41:34 2008 +0000
@@ -98,6 +98,17 @@
 void serv_alias_buddy(PurpleBuddy *);
 void serv_got_alias(PurpleConnection *gc, const char *who, const char *alias);
 
+/**
+ * A protocol plugin should call this when it retrieves a private alias from
+ * the server.  Private aliases are the aliases the user sets, while public
+ * aliases are the aliases or display names that buddies set for themselves.
+ *
+ * @param gc The connection on which the alias was received.
+ * @param who The screen name of the buddy whose alias was received.
+ * @param alias The alias that was received.
+ */
+void purple_serv_got_private_alias(PurpleConnection *gc, const char *who, const char *alias);
+
 
 /**
  * Receive a typing message from a remote user.  Either PURPLE_TYPING
--- a/libpurple/tests/Makefile.am	Wed Feb 27 00:24:57 2008 +0000
+++ b/libpurple/tests/Makefile.am	Wed Feb 27 22:41:34 2008 +0000
@@ -19,6 +19,7 @@
 		$(GLIB_CFLAGS) \
 		$(DEBUG_CFLAGS) \
 		-I.. \
+		-I$(top_srcdir)/libpurple \
 		-DBUILDDIR=\"$(top_builddir)\"
 
 check_libpurple_LDADD=\
--- a/pidgin/gtkdialogs.c	Wed Feb 27 00:24:57 2008 +0000
+++ b/pidgin/gtkdialogs.c	Wed Feb 27 22:41:34 2008 +0000
@@ -97,6 +97,7 @@
 
 /* Order: Alphabetical by Last Name */
 static const struct developer patch_writers[] = {
+	{"Felipe 'shx' Contreras",		NULL,	NULL},
 	{"Dennis 'EvilDennisR' Ristuccia",	N_("Senior Contributor/QA"),	NULL},
 	{"Peter 'Fmoo' Ruibal",		NULL,	NULL},
 	{"Elliott 'QuLogic' Sales de Andrade",	NULL,	NULL},
@@ -121,7 +122,6 @@
 
 /* Order: Alphabetical by Last Name */
 static const struct developer retired_patch_writers[] = {
-	{"Felipe 'shx' Contreras",		NULL,	NULL},
 	{"Decklin Foster",				NULL,	NULL},
 	{"Peter 'Bleeter' Lawler",      NULL,   NULL},
 	{"Robert 'Robot101' McQueen",	NULL,	NULL},
--- a/pidgin/gtkmain.c	Wed Feb 27 00:24:57 2008 +0000
+++ b/pidgin/gtkmain.c	Wed Feb 27 22:41:34 2008 +0000
@@ -301,6 +301,8 @@
 static void
 pidgin_ui_init(void)
 {
+	pidgin_stock_init();
+
 	/* Set the UI operation structures. */
 	purple_accounts_set_ui_ops(pidgin_accounts_get_ui_ops());
 	purple_xfers_set_ui_ops(pidgin_xfers_get_ui_ops());
@@ -315,7 +317,6 @@
 	purple_idle_set_ui_ops(pidgin_idle_get_ui_ops());
 #endif
 
-	pidgin_stock_init();
 	pidgin_account_init();
 	pidgin_connection_init();
 	pidgin_blist_init();
Binary file pidgin/pixmaps/logo.png has changed