changeset 3136:1bd472b7f7a2

[gaim-migrate @ 3151] Jabber sync. fixen committer: Tailor Script <tailor@pidgin.im>
author Rob Flynn <gaim@robflynn.com>
date Fri, 12 Apr 2002 02:15:24 +0000
parents 1838f48a5f72
children b7fce1bf6b87
files ChangeLog src/buddy.c src/core.h src/dialogs.c src/gaim.h src/list.c src/protocols/jabber/jabber.c src/protocols/msn/msn.c src/prpl.h src/server.c
diffstat 10 files changed, 114 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Fri Apr 12 02:13:13 2002 +0000
+++ b/ChangeLog	Fri Apr 12 02:15:24 2002 +0000
@@ -7,7 +7,8 @@
 	* libjabber upgraded to most recent stable version
 	* Buddylist looks a little better
 	* Fixed MSN privacy settings
-	* Group deletion fix
+	* Group deletion fix (Thanks Mark Doliner)
+	* Alias/Group syncronization for Jabber (Thanks JSeymour)
 	
 version 0.55 (03/29/2002):
 	* Jabber improvements (Thanks Jim Seymour)
--- a/src/buddy.c	Fri Apr 12 02:13:13 2002 +0000
+++ b/src/buddy.c	Fri Apr 12 02:15:24 2002 +0000
@@ -754,6 +754,7 @@
 	GtkCTreeNode *node = gtk_ctree_find_by_row_data(GTK_CTREE(edittree), NULL, b);
 	g_snprintf(b->show, sizeof(b->show), "%s", b->name);
 	gtk_ctree_node_set_text(GTK_CTREE(edittree), node, 0, b->name);
+	serv_alias_buddy(b);
 	if (gs)
 		bs = find_buddy_show(gs, b->name);
 	if (bs)
@@ -1094,9 +1095,15 @@
 		} else
 			new_g->members = g_slist_append(new_g->members, buddy);
 
-		/* we do the add after it's added locally so that prpls can find it if necessary */
-		if (add)
+		/*
+		 * we do the add after it's added locally so that prpls can find it if necessary
+		 * JFIXME: Er, shouldn't the buddy be removed from the old server, as well?
+		 */
+		if (add) {
 			serv_add_buddy(new_g->gc, buddy->name);
+		} else {
+			serv_move_buddy(buddy, old_g, new_g);
+		}
 
 		do_export(buddy->gc);
 		if (buddy->gc != new_g->gc) {
--- a/src/core.h	Fri Apr 12 02:13:13 2002 +0000
+++ b/src/core.h	Fri Apr 12 02:15:24 2002 +0000
@@ -110,10 +110,12 @@
 
 #endif
 
+#define BUDDY_ALIAS_MAXLEN 388	/* because MSN names can be 387 characters */
+
 struct buddy {
 	int edittype; /* XXX CUI: this is really a GUI function and we need to put this in ui.h */
 	char name[80];
-	char show[388]; /* because MSN names can be 387 characters */
+	char show[BUDDY_ALIAS_MAXLEN];
         int present;
 	int evil;
 	time_t signon;
--- a/src/dialogs.c	Fri Apr 12 02:13:13 2002 +0000
+++ b/src/dialogs.c	Fri Apr 12 02:15:24 2002 +0000
@@ -3382,6 +3382,7 @@
 	char *al = gtk_entry_get_text(GTK_ENTRY(aliasname));
 	g_snprintf(b->show, sizeof(b->show), "%s", (al && strlen(al)) ? al : b->name);
 	handle_buddy_rename(b, b->name);
+	serv_alias_buddy(b);
 	destroy_dialog(aliasdlg, aliasdlg);
 }
 
--- a/src/gaim.h	Fri Apr 12 02:13:13 2002 +0000
+++ b/src/gaim.h	Fri Apr 12 02:15:24 2002 +0000
@@ -396,6 +396,8 @@
 extern int  serv_chat_send(struct gaim_connection *, int, char *);
 extern void serv_got_popup(char *, char *, int, int);
 extern void serv_get_away(struct gaim_connection *, char *);
+extern void serv_alias_buddy(struct buddy *);
+extern void serv_move_buddy(struct buddy *, struct group *, struct group *);
 
 /* Functions in util.c */
 extern char *normalize(const char *);
--- a/src/list.c	Fri Apr 12 02:13:13 2002 +0000
+++ b/src/list.c	Fri Apr 12 02:15:24 2002 +0000
@@ -366,7 +366,7 @@
 					how_many++;
 				}
 			} else if (*c == 'b' && !find_buddy(gc, c + 2)) {
-				char nm[80], sw[388], *tmp = c + 2;
+				char nm[80], sw[BUDDY_ALIAS_MAXLEN], *tmp = c + 2;
 				int i = 0;
 				while (*tmp != ':' && *tmp && i < sizeof(nm) - 1)
 					nm[i++] = *tmp++;
--- a/src/protocols/jabber/jabber.c	Fri Apr 12 02:13:13 2002 +0000
+++ b/src/protocols/jabber/jabber.c	Fri Apr 12 02:15:24 2002 +0000
@@ -1025,15 +1025,27 @@
 {
 	xmlnode g;
 	char *Jid = xmlnode_get_attrib(p->x, "from");
-	char *ask = xmlnode_get_attrib(p->x, "type");
+	char *type = xmlnode_get_attrib(p->x, "type");
 
 	g = xmlnode_new_tag("presence");
 	xmlnode_put_attrib(g, "to", Jid);
-	if (!strcmp(ask, "subscribe"))
+	if (!strcmp(type, "subscribe"))
 		xmlnode_put_attrib(g, "type", "subscribed");
-	else if (!strcmp(ask, "unsubscribe"))
+	else if (!strcmp(type, "unsubscribe"))
 		xmlnode_put_attrib(g, "type", "unsubscribed");
 	else {
+		if (!strcmp(type, "unsubscribed")) {
+			xmlnode y;
+			char *status;
+			if((y = xmlnode_get_tag(p->x, "status")) && (status = xmlnode_get_data(y)) &&
+					!strcmp(status, "Not Found")) {
+				char *msg = g_strdup_printf("%s: \"%s\"", _("No such user"), 
+					xmlnode_get_attrib(p->x, "from"));
+				do_error_dialog(msg, _("Jabber Error"));
+				g_free(msg);
+			}
+		}
+
 		xmlnode_free(g);
 		return;
 	}
@@ -1078,7 +1090,7 @@
 	char *Jid, *name, *sub, *ask;
 	jid who;
 	struct buddy *b = NULL;
-	char *buddyname, *groupname;
+	char *buddyname, *groupname = NULL;
 
 	Jid = xmlnode_get_attrib(x, "jid");
 	name = xmlnode_get_attrib(x, "name");
@@ -1099,20 +1111,44 @@
 
 	buddyname = g_strdup_printf("%s@%s", who->user, who->server);
 
-	if((g = xmlnode_get_tag(x, "group")) == NULL || (groupname = xmlnode_get_data(g)) == NULL) {
-		groupname = _("Buddies");
+	if((g = xmlnode_get_tag(x, "group")) != NULL && xmlnode_get_datasz(g) > 0) {
+		groupname = xmlnode_get_data(g);
 	}
 
-
 	/*
-	 * Add or remove a buddy?
+	 * Add or remove a buddy?  Change buddy's alias or group?
 	 */
 	if (BUD_SUB_TO_PEND(sub, ask) || BUD_SUBD_TO(sub, ask)) {
 		if ((b = find_buddy(GJ_GC(gjc), buddyname)) == NULL) {
 			debug_printf("adding buddy [4]: %s\n", buddyname);
-			b = add_buddy(GJ_GC(gjc), groupname, buddyname,
+			b = add_buddy(GJ_GC(gjc), groupname ? groupname : _("Buddies"), buddyname,
 				name ? name : buddyname);
 			do_export(GJ_GC(gjc));
+		} else {
+			struct group *c_grp = find_group_by_buddy(GJ_GC(gjc), buddyname);
+
+			/* 
+			 * If the buddy's in a new group or his/her alias is changed...
+			 */
+			if(groupname && c_grp && strcmp(c_grp->name, groupname)) {
+				int present = b->present;	/* save presence state */
+				int uc = b->uc;			/* and away state (?) */
+
+				/*
+				 * seems rude, but it seems to be the only way...
+				 */
+				remove_buddy(GJ_GC(gjc), c_grp, b);
+				b = add_buddy(GJ_GC(gjc), groupname, buddyname,
+					name ? name : buddyname);
+				do_export(GJ_GC(gjc));
+				if(present) {
+					serv_got_update(GJ_GC(gjc), buddyname, 1, 0, 0, 0, uc, 0);
+				}
+			} else if(name != NULL && strcmp(b->show, name)) {
+				strncpy(b->show, name, BUDDY_ALIAS_MAXLEN);
+				b->show[BUDDY_ALIAS_MAXLEN - 1] = '\0';	/* cheap safety feature */
+				handle_buddy_rename(b, buddyname);
+			}
 		}
 	}  else if (BUD_USUB_TO_PEND(sub, ask) || BUD_USUBD_TO(sub, ask) || !strcasecmp(sub, "remove")) {
 		if ((b = find_buddy(GJ_GC(gjc), buddyname)) != NULL) {
@@ -1399,7 +1435,6 @@
 		}
 
 		break;
-
 	case JPACKET_S10N:
 		jabber_handles10n(gjc, p);
 		break;
@@ -1587,7 +1622,7 @@
 		 * and it doesn't match his JID, add the "name" attribute.
 		 */
 		if((buddy = find_buddy(gc, realwho)) != NULL &&
-			buddy->show != NULL && strcmp(realwho, buddy->show)) {
+			buddy->show != NULL && buddy->show[0] != '\0' && strcmp(realwho, buddy->show)) {
 
 			xmlnode_put_attrib(y, "name", buddy->show);
 		}
@@ -1609,13 +1644,21 @@
 	}
 }
 
+/*
+ * Change buddy's group on server roster
+ */
+static void jabber_group_change(struct gaim_connection *gc, char *name, char *old_group, char *new_group)
+{
+	if(strcmp(old_group, new_group)) {
+		jabber_roster_update(gc, name);
+	}
+}
+
 static void jabber_add_buddy(struct gaim_connection *gc, char *name)
 {
-	xmlnode x, y;
+	xmlnode x;
 	char *realwho;
 	gjconn gjc = ((struct jabber_data *)gc->proto_data)->gjc;
-	struct buddy *buddy = NULL;
-	struct group *buddy_group = NULL;
 
 	if (!((struct jabber_data *)gc->proto_data)->did_import)
 		return;
@@ -2993,6 +3036,8 @@
 	ret->normalize = jabber_normalize;
 	ret->buddy_free = jabber_buddy_free;
 	ret->register_user = jabber_register_user;
+	ret->alias_buddy = jabber_roster_update;
+	ret->group_buddy = jabber_group_change;
 
 	my_protocol = ret;
 }
--- a/src/protocols/msn/msn.c	Fri Apr 12 02:13:13 2002 +0000
+++ b/src/protocols/msn/msn.c	Fri Apr 12 02:15:24 2002 +0000
@@ -1884,7 +1884,7 @@
 	struct msn_data *md = gc->proto_data;
 	char buf[MSN_BUF_LEN];
 
-	if (strlen(url_encode(entry)) > 387) {
+	if (strlen(url_encode(entry)) >= BUDDY_ALIAS_MAXLEN) {
 		do_error_dialog("Friendly name too long.", "MSN Error");
 		return;
 	}
--- a/src/prpl.h	Fri Apr 12 02:13:13 2002 +0000
+++ b/src/prpl.h	Fri Apr 12 02:15:24 2002 +0000
@@ -161,6 +161,12 @@
 	void (* get_cb_info)	(struct gaim_connection *, int, char *who);
 	void (* get_cb_away)	(struct gaim_connection *, int, char *who);
 
+	/* save/store buddy's alias on server list/roster */
+	void (* alias_buddy)	(struct gaim_connection *, char *who);
+
+	/* change a buddy's group on a server list/roster */
+	void (* group_buddy)	(struct gaim_connection *, char *who, char *old_group, char *new_group);
+
 	void (* buddy_free)	(struct buddy *);
 
 	/* this is really bad. */
--- a/src/server.c	Fri Apr 12 02:13:13 2002 +0000
+++ b/src/server.c	Fri Apr 12 02:15:24 2002 +0000
@@ -285,6 +285,36 @@
 	}
 }
 
+/*
+ * Set buddy's alias on server roster/list
+ */
+void serv_alias_buddy(struct buddy *b)
+{
+	if(b && b->gc && b->gc->prpl && b->gc->prpl->alias_buddy) {
+		b->gc->prpl->alias_buddy(b->gc, b->name);
+	}
+}
+
+/*
+ * Move a buddy from one group to another on server.
+ *
+ * Note: For now we'll not deal with changing gc's at the same time, but
+ * it should be possible.  Probably needs to be done, someday.
+ */
+void serv_move_buddy(struct buddy *b, struct group *og, struct group *ng)
+{
+	if(b && b->gc && og && og->gc && ng && ng->gc) {
+		/*
+		 * If there are no connection changes...
+		 */
+		if(b->gc == og->gc && b->gc == ng->gc && ng->gc == og->gc) {
+			if(b->gc->prpl && b->gc->prpl->group_buddy) {
+				b->gc->prpl->group_buddy(b->gc, b->name, og->name, ng->name);
+			}
+		}
+	}
+}
+
 void serv_add_permit(struct gaim_connection *g, char *name)
 {
 	if (g && g_slist_find(connections, g) && g->prpl && g->prpl->add_permit)