changeset 3348:dd34e0b40fed

[gaim-migrate @ 3367] Support for server-side synchronization on group rename. (Thanks, Mark Doliner) committer: Tailor Script <tailor@pidgin.im>
author Jim Seymour <jseymour>
date Sun, 07 Jul 2002 14:31:57 +0000
parents d651e743ac64
children 000546860da7
files src/dialogs.c src/gaim.h src/protocols/oscar/aim.h src/protocols/oscar/oscar.c src/protocols/oscar/ssi.c src/prpl.h src/server.c
diffstat 7 files changed, 105 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/src/dialogs.c	Fri Jul 05 22:27:40 2002 +0000
+++ b/src/dialogs.c	Sun Jul 07 14:31:57 2002 +0000
@@ -3946,16 +3946,20 @@
 	if (new_name && (strlen(new_name) != 0) && strcmp(new_name, g->name)) {
 		char *prevname;
 		gc = g->gc;
+
 		if ((orig = find_group(g->gc, new_name)) != NULL && g_strcasecmp(new_name, g->name)) {
 			orig->members = g_slist_concat(orig->members, g->members);
 			handle_group_rename(orig, g->name);
 			g->gc->groups = g_slist_remove(g->gc->groups, g);
 			/* FIXME, i don't like calling this. it's sloppy. */ build_edit_tree();
+			serv_rename_group(gc, g, new_name);
 			g_free(g);
 		} else {
 			prevname = g_strdup(g->name);
+			serv_rename_group(gc, g, new_name);
 			g_snprintf(g->name, sizeof(g->name), "%s", new_name);
 			handle_group_rename(g, prevname);
+			/* FIXME, i don't like calling this. it's sloppy. */ build_edit_tree();
 			g_free(prevname);
 		}
 		do_export(gc);
--- a/src/gaim.h	Fri Jul 05 22:27:40 2002 +0000
+++ b/src/gaim.h	Sun Jul 07 14:31:57 2002 +0000
@@ -409,6 +409,7 @@
 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 *);
+extern void serv_rename_group(struct gaim_connection *, struct group *, char *);
 
 /* Functions in util.c */
 extern char *normalize(const char *);
--- a/src/protocols/oscar/aim.h	Fri Jul 05 22:27:40 2002 +0000
+++ b/src/protocols/oscar/aim.h	Sun Jul 07 14:31:57 2002 +0000
@@ -1049,6 +1049,7 @@
 faim_export int aim_ssi_addgroups(aim_session_t *sess, aim_conn_t *conn, char **gn, unsigned int num);
 faim_export int aim_ssi_addpord(aim_session_t *sess, aim_conn_t *conn, char **sn, unsigned int num, fu16_t type);
 faim_export int aim_ssi_movebuddy(aim_session_t *sess, aim_conn_t *conn, char *oldgn, char *newgn, char *sn);
+faim_export int aim_ssi_rename_group(aim_session_t *sess, aim_conn_t *conn, char *oldgn, char *newgn);
 faim_export int aim_ssi_delbuddies(aim_session_t *sess, aim_conn_t *conn, char *gn, char **sn, unsigned int num);
 faim_export int aim_ssi_delmastergroup(aim_session_t *sess, aim_conn_t *conn);
 faim_export int aim_ssi_delgroups(aim_session_t *sess, aim_conn_t *conn, char **gn, unsigned int num);
--- a/src/protocols/oscar/oscar.c	Fri Jul 05 22:27:40 2002 +0000
+++ b/src/protocols/oscar/oscar.c	Sun Jul 07 14:31:57 2002 +0000
@@ -3007,6 +3007,21 @@
 	}
 }
 
+static void oscar_rename_group(struct gaim_connection *g, char *old_group, char *new_group, GList *members) {
+	struct oscar_data *odata = (struct oscar_data *)g->proto_data;
+	if (!odata->icq)
+		if (odata->sess->ssi.received_data) {
+			if (aim_ssi_itemlist_finditem(odata->sess->ssi.items, NULL, new_group, 0x0001)) {
+				oscar_remove_buddies(g, members, old_group);
+				oscar_add_buddies(g, members);
+				debug_printf("ssi: moved all buddies from group %s to %s\n", old_group, new_group);
+			} else {
+				aim_ssi_rename_group(odata->sess, odata->conn, old_group, new_group);
+				debug_printf("ssi: renamed group %s to %s\n", old_group, new_group);
+			}
+		}
+}
+
 static int gaim_ssi_parserights(aim_session_t *sess, aim_frame_t *fr, ...) {
 /*	XXX - Fix parsing of the ssi rights packet and pass us the data
 	fu16_t maxbuddies, maxgroups, maxpermits, maxdenies;
@@ -3892,6 +3907,7 @@
 	ret->add_buddy = oscar_add_buddy;
 	ret->add_buddies = oscar_add_buddies;
 	ret->group_buddy = oscar_move_buddy;
+	ret->rename_group = oscar_rename_group;
 	ret->remove_buddy = oscar_remove_buddy;
 	ret->remove_buddies = oscar_remove_buddies;
 	ret->add_permit = oscar_add_permit;
--- a/src/protocols/oscar/ssi.c	Fri Jul 05 22:27:40 2002 +0000
+++ b/src/protocols/oscar/ssi.c	Sun Jul 07 14:31:57 2002 +0000
@@ -94,7 +94,7 @@
  */
 static int aim_ssi_itemlist_rebuildgroup(struct aim_ssi_item **list, struct aim_ssi_item *parentgroup)
 {
-	int newlen, i;
+	int newlen;
 	struct aim_ssi_item *cur;
 
 	/* Free the old additional data */
@@ -517,7 +517,7 @@
 		}
 
 	/* Send the add item SNAC */
-	if (i = aim_ssi_addmoddel(sess, conn, newitems, num, AIM_CB_SSI_ADD)) {
+	if ((i = aim_ssi_addmoddel(sess, conn, newitems, num, AIM_CB_SSI_ADD))) {
 		free(newitems);
 		return -i;
 	}
@@ -526,11 +526,11 @@
 	free(newitems);
 
 	/* Rebuild the additional data in the parent group */
-	if (i = aim_ssi_itemlist_rebuildgroup(&sess->ssi.items, parentgroup))
+	if ((i = aim_ssi_itemlist_rebuildgroup(&sess->ssi.items, parentgroup)))
 		return i;
 
 	/* Send the mod item SNAC */
-	if (i = aim_ssi_addmoddel(sess, conn, &parentgroup, 1, AIM_CB_SSI_MOD))
+	if ((i = aim_ssi_addmoddel(sess, conn, &parentgroup, 1, AIM_CB_SSI_MOD)))
 		return i;
 
 	/* Begin sending SSI SNACs */
@@ -608,7 +608,7 @@
 		}
 
 	/* Send the add item SNAC */
-	if (i = aim_ssi_addmoddel(sess, conn, newitems, num, AIM_CB_SSI_ADD)) {
+	if ((i = aim_ssi_addmoddel(sess, conn, newitems, num, AIM_CB_SSI_ADD))) {
 		free(newitems);
 		return -i;
 	}
@@ -617,11 +617,11 @@
 	free(newitems);
 
 	/* Rebuild the additional data in the parent group */
-	if (i = aim_ssi_itemlist_rebuildgroup(&sess->ssi.items, parentgroup))
+	if ((i = aim_ssi_itemlist_rebuildgroup(&sess->ssi.items, parentgroup)))
 		return i;
 
 	/* Send the mod item SNAC */
-	if (i = aim_ssi_addmoddel(sess, conn, &parentgroup, 1, AIM_CB_SSI_MOD))
+	if ((i = aim_ssi_addmoddel(sess, conn, &parentgroup, 1, AIM_CB_SSI_MOD)))
 		return i;
 
 	/* Begin sending SSI SNACs */
@@ -664,7 +664,7 @@
 		}
 
 	/* Send the add item SNAC */
-	if (i = aim_ssi_addmoddel(sess, conn, newitems, num, AIM_CB_SSI_ADD)) {
+	if ((i = aim_ssi_addmoddel(sess, conn, newitems, num, AIM_CB_SSI_ADD))) {
 		free(newitems);
 		return -i;
 	}
@@ -714,8 +714,11 @@
 
 	/* Look up the new parent group */
 	if (!(groups[1] = aim_ssi_itemlist_finditem(sess->ssi.items, NULL, newgn, AIM_SSI_TYPE_GROUP))) {
-		free(groups);
-		return -ENOMEM;
+		aim_ssi_addgroups(sess, conn, &newgn, 1);
+		if (!(groups[1] = aim_ssi_itemlist_finditem(sess->ssi.items, NULL, newgn, AIM_SSI_TYPE_GROUP))) {
+			free(groups);
+			return -ENOMEM;
+		}
 	}
 
 	/* Send the delete item SNAC */
@@ -753,6 +756,46 @@
 }
 
 /**
+ * Rename a group.  I really like how this is done.  It turns me on.
+ *
+ * Did I say that out loud?...
+ *
+ * @param sess The oscar session.
+ * @param conn The bos connection for this session.
+ * @param oldgn The old group name.
+ * @param newgn The new group name.
+ * @return Return 0 if no errors, otherwise return the error number.
+ */
+faim_export int aim_ssi_rename_group(aim_session_t *sess, aim_conn_t *conn, char *oldgn, char *newgn)
+{
+	struct aim_ssi_item *group;
+
+	if (!sess || !conn || !oldgn || !newgn)
+		return -EINVAL;
+
+	/* Look up the group */
+	if (!(group = aim_ssi_itemlist_finditem(sess->ssi.items, NULL, oldgn, AIM_SSI_TYPE_GROUP)))
+		return -ENOMEM;
+
+	/* Free the old group name and copy the new one in its place. */
+	if (group->name)
+		free(group->name);
+	if (!(group->name = (char *)malloc((strlen(newgn)+1)*sizeof(char)))) {
+		group->name = NULL;
+		return -ENOMEM;
+	}
+	strcpy(group->name, newgn);
+
+	/* Send the mod item SNAC */
+	aim_ssi_addmoddel(sess, conn, &group, 1, AIM_CB_SSI_MOD);
+
+	/* Begin sending SSI SNACs */
+	aim_ssi_dispatch(sess, conn);
+
+	return 0;
+}
+
+/**
  * Delete an array of screen names from the given group.
  *
  * @param sess The oscar session.
@@ -1012,8 +1055,7 @@
  * @return Return 0 if no errors, otherwise return the error number.
  */
 faim_export int aim_ssi_setpermdeny(aim_session_t *sess, aim_conn_t *conn, fu8_t permdeny, fu32_t vismask) {
-	struct aim_ssi_item *cur, *tmp;
-	fu16_t j;
+	struct aim_ssi_item *cur;
 	aim_tlv_t *tlv;
 
 	if (!sess || !conn)
@@ -1077,8 +1119,7 @@
  * @return Return 0 if no errors, otherwise return the error number.
  */
 faim_export int aim_ssi_setpresence(aim_session_t *sess, aim_conn_t *conn, fu32_t presence) {
-	struct aim_ssi_item *cur, *tmp;
-	fu16_t j;
+	struct aim_ssi_item *cur;
 	aim_tlv_t *tlv;
 
 	if (!sess || !conn)
--- a/src/prpl.h	Fri Jul 05 22:27:40 2002 +0000
+++ b/src/prpl.h	Sun Jul 07 14:31:57 2002 +0000
@@ -168,6 +168,9 @@
 	/* change a buddy's group on a server list/roster */
 	void (* group_buddy)	(struct gaim_connection *, char *who, char *old_group, char *new_group);
 
+	/* rename a group on a server list/roster */
+	void (* rename_group)	(struct gaim_connection *, char *old_group, char *new_group, GList *members);
+
 	void (* buddy_free)	(struct buddy *);
 
 	/* this is really bad. */
--- a/src/server.c	Fri Jul 05 22:27:40 2002 +0000
+++ b/src/server.c	Sun Jul 07 14:31:57 2002 +0000
@@ -315,6 +315,31 @@
 	}
 }
 
+/*
+ * Rename a group on server roster/list.
+ */
+void serv_rename_group(struct gaim_connection *g, struct group *old_group, char *new_name)
+{
+	if (g && g->prpl && old_group && new_name) {
+		GList *tobemoved = NULL;
+		GSList *original;
+
+		for (original=old_group->members; original; original=g_slist_next(original))
+			tobemoved = g_list_append(tobemoved, ((struct buddy *)original->data)->name);
+
+		if (g->prpl->rename_group) {
+			/* prpl's might need to check if the group already 
+			 * exists or not, and handle that differently */
+			g->prpl->rename_group(g, old_group->name, new_name, tobemoved);
+		} else {
+			serv_remove_buddies(g, tobemoved, old_group->name);
+			serv_add_buddies(g, tobemoved);
+		}
+
+		g_list_free(tobemoved);
+	}
+}
+
 void serv_add_permit(struct gaim_connection *g, char *name)
 {
 	if (g && g_slist_find(connections, g) && g->prpl && g->prpl->add_permit)