# HG changeset patch # User ivan.komarov@soc.pidgin.im # Date 1276869354 0 # Node ID 05c634403678387e7cde8b9cbee85bcc6a878eef # Parent 457b9739aca98d9a3f36b615baf3f170a94432ed Start using the real ICQ block list (SSI type 0xe) for allowing/blocking users. The deny list (SSI type 0x3) that is used in AIM is actually a "permanently invisible" list for ICQ. Also, the "vismask" parameter in aim_ssi_setpermdeny() was removed, since it wasn't being used anyway. diff -r 457b9739aca9 -r 05c634403678 libpurple/protocols/oscar/family_feedbag.c --- a/libpurple/protocols/oscar/family_feedbag.c Thu Jun 17 11:10:27 2010 +0000 +++ b/libpurple/protocols/oscar/family_feedbag.c Fri Jun 18 13:55:54 2010 +0000 @@ -781,16 +781,16 @@ */ int aim_ssi_adddeny(OscarData *od, const char *name) { - + guint16 deny_entry_type = aim_ssi_getdenyentrytype(od); if (!od || !name || !od->ssi.received_data) return -EINVAL; /* Make sure the master group exists */ if (aim_ssi_itemlist_find(od->ssi.local, 0x0000, 0x0000) == NULL) - aim_ssi_itemlist_add(&od->ssi.local, NULL, 0x0000, 0x0000, AIM_SSI_TYPE_GROUP, NULL); + aim_ssi_itemlist_add(&od->ssi.local, NULL, 0x0000, 0x0000, deny_entry_type, NULL); /* Add that bad boy */ - aim_ssi_itemlist_add(&od->ssi.local, name, 0x0000, 0xFFFF, AIM_SSI_TYPE_DENY, NULL); + aim_ssi_itemlist_add(&od->ssi.local, name, 0x0000, 0xFFFF, deny_entry_type, NULL); /* Sync our local list with the server list */ return aim_ssi_sync(od); @@ -893,13 +893,14 @@ */ int aim_ssi_deldeny(OscarData *od, const char *name) { + guint16 deny_entry_type = aim_ssi_getdenyentrytype(od); struct aim_ssi_item *del; if (!od) return -EINVAL; /* Find the item */ - if (!(del = aim_ssi_itemlist_finditem(od->ssi.local, NULL, name, AIM_SSI_TYPE_DENY))) + if (!(del = aim_ssi_itemlist_finditem(od->ssi.local, NULL, name, deny_entry_type))) return -EINVAL; /* Remove the item from the list */ @@ -1030,17 +1031,16 @@ * Stores your permit/deny setting on the server, and starts using it. * * @param od The oscar odion. - * @param permdeny Your permit/deny setting. Can be one of the following: + * @param permdeny Your permit/deny setting. For ICQ accounts, it actually affects your visibility + * and has nothing to do with blocking. Can be one of the following: * 1 - Allow all users * 2 - Block all users * 3 - Allow only the users below * 4 - Block only the users below * 5 - Allow only users on my buddy list - * @param vismask A bitmask of the class of users to whom you want to be - * visible. See the AIM_FLAG_BLEH #defines in oscar.h * @return Return 0 if no errors, otherwise return the error number. */ -int aim_ssi_setpermdeny(OscarData *od, guint8 permdeny, guint32 vismask) +int aim_ssi_setpermdeny(OscarData *od, guint8 permdeny) { struct aim_ssi_item *tmp; @@ -1059,9 +1059,6 @@ /* Need to add the 0x00ca TLV to the TLV chain */ aim_tlvlist_replace_8(&tmp->data, 0x00ca, permdeny); - /* Need to add the 0x00cb TLV to the TLV chain */ - aim_tlvlist_replace_32(&tmp->data, 0x00cb, vismask); - /* Sync our local list with the server list */ return aim_ssi_sync(od); } @@ -1935,6 +1932,16 @@ return ret; } +/* + * If we're on ICQ, then AIM_SSI_TYPE_DENY is used for the "permanently invisible" list. + * AIM_SSI_TYPE_ICQDENY is used for blocking users instead. + */ +guint16 +aim_ssi_getdenyentrytype(OscarData* od) +{ + return od->icq ? AIM_SSI_TYPE_ICQDENY : AIM_SSI_TYPE_DENY; +} + static int snachandler(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs) { diff -r 457b9739aca9 -r 05c634403678 libpurple/protocols/oscar/libicq.c --- a/libpurple/protocols/oscar/libicq.c Thu Jun 17 11:10:27 2010 +0000 +++ b/libpurple/protocols/oscar/libicq.c Fri Jun 18 13:55:54 2010 +0000 @@ -63,11 +63,11 @@ NULL, /* add_buddies */ oscar_remove_buddy, /* remove_buddy */ NULL, /* remove_buddies */ - oscar_add_permit, /* add_permit */ + NULL, /* add_permit */ oscar_add_deny, /* add_deny */ - oscar_rem_permit, /* rem_permit */ + NULL, /* rem_permit */ oscar_rem_deny, /* rem_deny */ - oscar_set_permit_deny, /* set_permit_deny */ + NULL, /* set_permit_deny */ oscar_join_chat, /* join_chat */ NULL, /* reject_chat */ oscar_get_chat_name, /* get_chat_name */ diff -r 457b9739aca9 -r 05c634403678 libpurple/protocols/oscar/oscar.c --- a/libpurple/protocols/oscar/oscar.c Thu Jun 17 11:10:27 2010 +0000 +++ b/libpurple/protocols/oscar/oscar.c Fri Jun 18 13:55:54 2010 +0000 @@ -4028,9 +4028,17 @@ oscar_set_status_icq(PurpleAccount *account) { PurpleConnection *gc = purple_account_get_connection(account); - - /* Our permit/deny setting affects our invisibility */ - oscar_set_permit_deny(gc); + OscarData *od = purple_connection_get_protocol_data(gc); + gboolean invisible = purple_account_is_status_active(account, OSCAR_STATUS_ID_INVISIBLE); + + /* + * For ICQ the permit/deny setting controls who can see you + * online. Mimicking the official client's behavior, we use PURPLE_PRIVACY_ALLOW_USERS + * when our status is "invisible" and PURPLE_PRIVACY_DENY_USERS otherwise. + * In the former case, we are visible only to buddies on our "permanently visible" list. + * In the latter, we are invisible only to buddies on our "permanentnly invisible" list. + */ + aim_ssi_setpermdeny(od, invisible ? PURPLE_PRIVACY_ALLOW_USERS : PURPLE_PRIVACY_DENY_USERS); /* * TODO: I guess we should probably wait and do this after we get @@ -4284,6 +4292,7 @@ va_list ap; guint16 fmtver, numitems; guint32 timestamp; + guint16 deny_entry_type = aim_ssi_getdenyentrytype(od); gc = od->gc; od = purple_connection_get_protocol_data(gc); @@ -4352,8 +4361,8 @@ purple_blist_remove_buddy(b); } - /* Permit list */ - if (account->permit) { + /* Permit list (ICQ doesn't have one) */ + if (!od->icq && account->permit) { next = account->permit; while (next != NULL) { cur = next; @@ -4372,7 +4381,7 @@ while (next != NULL) { cur = next; next = next->next; - if (!aim_ssi_itemlist_finditem(od->ssi.local, NULL, cur->data, AIM_SSI_TYPE_DENY)) { + if (!aim_ssi_itemlist_finditem(od->ssi.local, NULL, cur->data, deny_entry_type)) { purple_debug_info("oscar", "ssi: removing deny %s from local list\n", (const char *)cur->data); purple_privacy_deny_remove(account, cur->data, TRUE); @@ -4487,8 +4496,8 @@ g_free(gname_utf8); } break; - case AIM_SSI_TYPE_PERMIT: { /* Permit buddy */ - if (curitem->name) { + case AIM_SSI_TYPE_PERMIT: { /* Permit buddy (unless we're on ICQ) */ + if (!od->icq && curitem->name) { /* if (!find_permdeny_by_name(gc->permit, curitem->name)) { AAA */ GSList *list; for (list=account->permit; (list && oscar_util_name_compare(curitem->name, list->data)); list=list->next); @@ -4500,8 +4509,9 @@ } } break; + case AIM_SSI_TYPE_ICQDENY: case AIM_SSI_TYPE_DENY: { /* Deny buddy */ - if (curitem->name) { + if (curitem->type == deny_entry_type && curitem->name) { GSList *list; for (list=account->deny; (list && oscar_util_name_compare(curitem->name, list->data)); list=list->next); if (!list) { @@ -5172,28 +5182,6 @@ void oscar_set_permit_deny(PurpleConnection *gc) { PurpleAccount *account = purple_connection_get_account(gc); OscarData *od = purple_connection_get_protocol_data(gc); - PurplePrivacyType perm_deny; - - /* - * For ICQ the permit/deny setting controls who you can see you - * online when you set your status to "invisible." If we're ICQ - * and we're invisible then we need to use one of - * PURPLE_PRIVACY_ALLOW_USERS or PURPLE_PRIVACY_ALLOW_BUDDYLIST or - * PURPLE_PRIVACY_DENY_USERS if we actually want to be invisible - * to anyone. - * - * These three permit/deny settings correspond to: - * 1. Invisible to everyone except the people on my "permit" list - * 2. Invisible to everyone except the people on my buddy list - * 3. Invisible only to the people on my "deny" list - * - * It would be nice to allow cases 2 and 3, but our UI doesn't have - * a nice way to do it. For now we just force case 1. - */ - if (od->icq && purple_account_is_status_active(account, OSCAR_STATUS_ID_INVISIBLE)) - perm_deny = PURPLE_PRIVACY_ALLOW_USERS; - else - perm_deny = account->perm_deny; if (od->ssi.received_data) /* @@ -5201,7 +5189,7 @@ * values of libpurple's PurplePrivacyType and the values used * by the oscar protocol. */ - aim_ssi_setpermdeny(od, perm_deny, 0xffffffff); + aim_ssi_setpermdeny(od, account->perm_deny); } void oscar_add_permit(PurpleConnection *gc, const char *who) { diff -r 457b9739aca9 -r 05c634403678 libpurple/protocols/oscar/oscar.h --- a/libpurple/protocols/oscar/oscar.h Thu Jun 17 11:10:27 2010 +0000 +++ b/libpurple/protocols/oscar/oscar.h Fri Jun 18 13:55:54 2010 +0000 @@ -1272,6 +1272,7 @@ #define AIM_SSI_TYPE_DENY 0x0003 #define AIM_SSI_TYPE_PDINFO 0x0004 #define AIM_SSI_TYPE_PRESENCEPREFS 0x0005 +#define AIM_SSI_TYPE_ICQDENY 0x000e #define AIM_SSI_TYPE_ICONINFO 0x0014 #define AIM_SSI_ACK_SUCCESS 0x0000 @@ -1340,12 +1341,12 @@ int aim_ssi_rename_group(OscarData *od, const char *oldgn, const char *newgn); int aim_ssi_cleanlist(OscarData *od); int aim_ssi_deletelist(OscarData *od); -int aim_ssi_setpermdeny(OscarData *od, guint8 permdeny, guint32 vismask); +int aim_ssi_setpermdeny(OscarData *od, guint8 permdeny); int aim_ssi_setpresence(OscarData *od, guint32 presence); int aim_ssi_seticon(OscarData *od, const guint8 *iconsum, guint8 iconsumlen); int aim_ssi_delicon(OscarData *od); - +guint16 aim_ssi_getdenyentrytype(OscarData* od); /* 0x0015 - family_icq.c */ #define AIM_ICQ_INFO_SIMPLE 0x001