# HG changeset patch # User Mark Doliner # Date 1185864689 0 # Node ID 84d53c3c699d06e3da5bf4abe312d953e337a6ab # Parent 66df5d93cdf4458a5d08056fe548cdc1d9d5df66 Some changes from Matthew Goldstein and I to not automatically remove empty groups from the oscar server-stored buddy list. There's this thing called AIM WIMZI that relies on having a certain group in your buddy list so that it can add buddies to it automatically, and it wasn't working if you used Pidgin because the group didn't exist. See http://wimzi.aim.com/ Also try to fix allowing buddies to be in multiple groups. diff -r 66df5d93cdf4 -r 84d53c3c699d COPYRIGHT --- a/COPYRIGHT Tue Jul 31 06:09:45 2007 +0000 +++ b/COPYRIGHT Tue Jul 31 06:51:29 2007 +0000 @@ -144,6 +144,7 @@ Gustavo Giráldez Richard Gobeille Ian Goldberg +Matthew Goldstein Michael Golden Charlie Gordon Ryan C. Gordon diff -r 66df5d93cdf4 -r 84d53c3c699d libpurple/protocols/oscar/family_feedbag.c --- a/libpurple/protocols/oscar/family_feedbag.c Tue Jul 31 06:09:45 2007 +0000 +++ b/libpurple/protocols/oscar/family_feedbag.c Tue Jul 31 06:51:29 2007 +0000 @@ -695,18 +695,6 @@ cur = cur->next; } - /* Check if there are empty groups and delete them */ - cur = od->ssi.local; - while (cur) { - next = cur->next; - if (cur->type == AIM_SSI_TYPE_GROUP) { - aim_tlv_t *tlv = aim_tlv_gettlv(cur->data, 0x00c8, 1); - if (!tlv || !tlv->length) - aim_ssi_itemlist_del(&od->ssi.local, cur); - } - cur = next; - } - /* Check if the master group is empty */ if ((cur = aim_ssi_itemlist_find(od->ssi.local, 0x0000, 0x0000)) && (!cur->data)) aim_ssi_itemlist_del(&od->ssi.local, cur); @@ -841,18 +829,39 @@ /* Modify the parent group */ aim_ssi_itemlist_rebuildgroup(od->ssi.local, group); - /* Check if we should delete the parent group */ - if ((del = aim_ssi_itemlist_finditem(od->ssi.local, group, NULL, AIM_SSI_TYPE_GROUP)) && (!del->data)) { - aim_ssi_itemlist_del(&od->ssi.local, del); + /* Sync our local list with the server list */ + return aim_ssi_sync(od); +} + +/** + * Deletes a group from the list. + * + * @param od The oscar odion. + * @param group The name of the group. + * @return Return 0 if no errors, otherwise return the error number. + */ +int aim_ssi_delgroup(OscarData *od, const char *group) +{ + struct aim_ssi_item *del; + aim_tlv_t *tlv; - /* Modify the parent group */ - aim_ssi_itemlist_rebuildgroup(od->ssi.local, NULL); + if (!od) + return -EINVAL; + + /* Find the group */ + if (!(del = aim_ssi_itemlist_finditem(od->ssi.local, group, NULL, AIM_SSI_TYPE_GROUP))) + return -EINVAL; - /* Check if we should delete the parent's parent (the master group) */ - if ((del = aim_ssi_itemlist_find(od->ssi.local, 0x0000, 0x0000)) && (!del->data)) { - aim_ssi_itemlist_del(&od->ssi.local, del); - } - } + /* Don't delete the group if it's not empty */ + tlv = aim_tlv_gettlv(del->data, 0x00c8, 1); + if (tlv && tlv->length > 0) + return -EINVAL; + + /* Remove the item from the list */ + aim_ssi_itemlist_del(&od->ssi.local, del); + + /* Modify the parent group */ + aim_ssi_itemlist_rebuildgroup(od->ssi.local, group); /* Sync our local list with the server list */ return aim_ssi_sync(od); diff -r 66df5d93cdf4 -r 84d53c3c699d libpurple/protocols/oscar/libaim.c --- a/libpurple/protocols/oscar/libaim.c Tue Jul 31 06:09:45 2007 +0000 +++ b/libpurple/protocols/oscar/libaim.c Tue Jul 31 06:51:29 2007 +0000 @@ -78,7 +78,7 @@ oscar_convo_closed, /* convo_closed */ oscar_normalize, /* normalize */ oscar_set_icon, /* set_buddy_icon */ - NULL, /* remove_group */ + oscar_remove_group, /* remove_group */ NULL, /* get_cb_real_name */ NULL, /* set_chat_topic */ NULL, /* find_blist_chat */ diff -r 66df5d93cdf4 -r 84d53c3c699d libpurple/protocols/oscar/libicq.c --- a/libpurple/protocols/oscar/libicq.c Tue Jul 31 06:09:45 2007 +0000 +++ b/libpurple/protocols/oscar/libicq.c Tue Jul 31 06:51:29 2007 +0000 @@ -78,7 +78,7 @@ oscar_convo_closed, /* convo_closed */ oscar_normalize, /* normalize */ oscar_set_icon, /* set_buddy_icon */ - NULL, /* remove_group */ + oscar_remove_group, /* remove_group */ NULL, /* get_cb_real_name */ NULL, /* set_chat_topic */ NULL, /* find_blist_chat */ diff -r 66df5d93cdf4 -r 84d53c3c699d libpurple/protocols/oscar/oscar.c --- a/libpurple/protocols/oscar/oscar.c Tue Jul 31 06:09:45 2007 +0000 +++ b/libpurple/protocols/oscar/oscar.c Tue Jul 31 06:51:29 2007 +0000 @@ -4709,6 +4709,11 @@ } } +void oscar_remove_group(PurpleConnection *gc, PurpleGroup *group) +{ + aim_ssi_delgroup(gc->proto_data, group->name); +} + static gboolean purple_ssi_rerequestdata(gpointer data) { OscarData *od = data; @@ -4902,29 +4907,34 @@ /* Add from server list to local list */ for (curitem=od->ssi.local; curitem; curitem=curitem->next) { - if ((curitem->name == NULL) || (g_utf8_validate(curitem->name, -1, NULL))) + if ((curitem->name == NULL) || (g_utf8_validate(curitem->name, -1, NULL))) switch (curitem->type) { case 0x0000: { /* Buddy */ if (curitem->name) { - char *gname = aim_ssi_itemlist_findparentname(od->ssi.local, curitem->name); + struct aim_ssi_item *groupitem = aim_ssi_itemlist_find(od->ssi.local, curitem->gid, 0x0000); + char *gname = groupitem ? groupitem->name : NULL; char *gname_utf8 = gname ? oscar_utf8_try_convert(gc->account, gname) : NULL; char *alias = aim_ssi_getalias(od->ssi.local, gname, curitem->name); char *alias_utf8; + g = purple_find_group(gname_utf8 ? gname_utf8 : _("Orphans")); + if (g == NULL) { + g = purple_group_new(gname_utf8 ? gname_utf8 : _("Orphans")); + purple_blist_add_group(g, NULL); + } + if (alias != NULL) { if (g_utf8_validate(alias, -1, NULL)) alias_utf8 = g_strdup(alias); else alias_utf8 = oscar_utf8_try_convert(account, alias); + g_free(alias); } else alias_utf8 = NULL; - b = purple_find_buddy(gc->account, curitem->name); - /* Should gname be freed here? -- elb */ - /* Not with the current code, but that might be cleaner -- med */ - g_free(alias); + b = purple_find_buddy_in_group(gc->account, curitem->name, g); if (b) { /* Get server stored alias */ if (alias_utf8) { @@ -4934,13 +4944,8 @@ } else { b = purple_buddy_new(gc->account, curitem->name, alias_utf8); - if (!(g = purple_find_group(gname_utf8 ? gname_utf8 : _("Orphans")))) { - g = purple_group_new(gname_utf8 ? gname_utf8 : _("Orphans")); - purple_blist_add_group(g, NULL); - } - purple_debug_info("oscar", - "ssi: adding buddy %s to group %s to local list\n", curitem->name, gname_utf8 ? gname_utf8 : _("Orphans")); + "ssi: adding buddy %s to group %s to local list\n", curitem->name, g->name); purple_blist_add_buddy(b, NULL, g, NULL); } if (!aim_sncmp(curitem->name, account->username)) { @@ -4957,7 +4962,12 @@ } break; case 0x0001: { /* Group */ - /* Shouldn't add empty groups */ + char *gname = curitem->name; + char *gname_utf8 = gname ? oscar_utf8_try_convert(gc->account, gname) : NULL; + if (gname_utf8 != NULL) { + g = purple_group_new(gname_utf8); + purple_blist_add_group(g, NULL); + } } break; case 0x0002: { /* Permit buddy */ diff -r 66df5d93cdf4 -r 84d53c3c699d libpurple/protocols/oscar/oscar.h --- a/libpurple/protocols/oscar/oscar.h Tue Jul 31 06:09:45 2007 +0000 +++ b/libpurple/protocols/oscar/oscar.h Tue Jul 31 06:51:29 2007 +0000 @@ -1211,6 +1211,7 @@ int aim_ssi_addpermit(OscarData *od, const char *name); int aim_ssi_adddeny(OscarData *od, const char *name); int aim_ssi_delbuddy(OscarData *od, const char *name, const char *group); +int aim_ssi_delgroup(OscarData *od, const char *group); int aim_ssi_delpermit(OscarData *od, const char *name); int aim_ssi_deldeny(OscarData *od, const char *name); int aim_ssi_movebuddy(OscarData *od, const char *oldgn, const char *newgn, const char *sn); diff -r 66df5d93cdf4 -r 84d53c3c699d libpurple/protocols/oscar/oscarcommon.h --- a/libpurple/protocols/oscar/oscarcommon.h Tue Jul 31 06:09:45 2007 +0000 +++ b/libpurple/protocols/oscar/oscarcommon.h Tue Jul 31 06:51:29 2007 +0000 @@ -82,6 +82,7 @@ void oscar_convo_closed(PurpleConnection *gc, const char *who); const char *oscar_normalize(const PurpleAccount *account, const char *str); void oscar_set_icon(PurpleConnection *gc, PurpleStoredImage *img); +void oscar_remove_group(PurpleConnection *gc, PurpleGroup *group); gboolean oscar_can_receive_file(PurpleConnection *gc, const char *who); void oscar_send_file(PurpleConnection *gc, const char *who, const char *file); PurpleXfer *oscar_new_xfer(PurpleConnection *gc, const char *who); diff -r 66df5d93cdf4 -r 84d53c3c699d libpurple/stringref.h --- a/libpurple/stringref.h Tue Jul 31 06:09:45 2007 +0000 +++ b/libpurple/stringref.h Tue Jul 31 06:51:29 2007 +0000 @@ -1,3 +1,5 @@ +/* TODO: Can we just replace this whole thing with a GCache */ + /** * @file stringref.h Reference-counted immutable strings * @ingroup core