# HG changeset patch # User Jim Seymour # Date 1026052317 0 # Node ID dd34e0b40fed4d10cac8954956bd0594eba10748 # Parent d651e743ac641e141df9d26d288c397361173c12 [gaim-migrate @ 3367] Support for server-side synchronization on group rename. (Thanks, Mark Doliner) committer: Tailor Script diff -r d651e743ac64 -r dd34e0b40fed src/dialogs.c --- 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); diff -r d651e743ac64 -r dd34e0b40fed src/gaim.h --- 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 *); diff -r d651e743ac64 -r dd34e0b40fed src/protocols/oscar/aim.h --- 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); diff -r d651e743ac64 -r dd34e0b40fed src/protocols/oscar/oscar.c --- 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; diff -r d651e743ac64 -r dd34e0b40fed src/protocols/oscar/ssi.c --- 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) diff -r d651e743ac64 -r dd34e0b40fed src/prpl.h --- 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. */ diff -r d651e743ac64 -r dd34e0b40fed src/server.c --- 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)