# HG changeset patch # User Mark Doliner # Date 1067153716 0 # Node ID 83e8faa7f6d57a6b9891e5479613bf636b3b8a45 # Parent 6338cb1768eabf9fb74a3aaa0b84b4e493a8cb3e [gaim-migrate @ 7922] Add the ability to view users with secure IM enabled on AIM. They have a lock icon overlay. Also some other small changes and minor bandwidth usage reduction. I'm Brian Fellows! committer: Tailor Script diff -r 6338cb1768ea -r 83e8faa7f6d5 src/protocols/oscar/aim.h --- a/src/protocols/oscar/aim.h Sun Oct 26 06:55:27 2003 +0000 +++ b/src/protocols/oscar/aim.h Sun Oct 26 07:35:16 2003 +0000 @@ -1070,7 +1070,8 @@ faim_export aim_userinfo_t *aim_locate_finduserinfo(aim_session_t *sess, const char *sn); /* 0x0002 */ faim_export int aim_locate_reqrights(aim_session_t *sess); -/* 0x0004 */ faim_export int aim_locate_setprofile(aim_session_t *sess, const char *profile_encoding, const char *profile, const int profile_len, const char *awaymsg_encoding, const char *awaymsg, const int awaymsg_len, fu32_t caps); +/* 0x0004 */ faim_export int aim_locate_setprofile(aim_session_t *sess, const char *profile_encoding, const char *profile, const int profile_len, const char *awaymsg_encoding, const char *awaymsg, const int awaymsg_len); +/* 0x0004 */ faim_export int aim_locate_setcaps(aim_session_t *sess, fu32_t caps); /* 0x0005 */ faim_export int aim_locate_getinfo(aim_session_t *sess, const char *, fu16_t); /* 0x0009 */ faim_export int aim_locate_setdirinfo(aim_session_t *sess, const char *first, const char *middle, const char *last, const char *maiden, const char *nickname, const char *street, const char *city, const char *state, const char *zip, int country, fu16_t privacy); /* 0x000b */ faim_export int aim_locate_000b(aim_session_t *sess, const char *sn); diff -r 6338cb1768ea -r 83e8faa7f6d5 src/protocols/oscar/aim_internal.h --- a/src/protocols/oscar/aim_internal.h Sun Oct 26 06:55:27 2003 +0000 +++ b/src/protocols/oscar/aim_internal.h Sun Oct 26 07:35:16 2003 +0000 @@ -198,7 +198,8 @@ /* 0x0002 - locate.c */ faim_internal void aim_locate_requestuserinfo(aim_session_t *sess, const char *sn); -faim_internal fu32_t aim_getcap(aim_session_t *sess, aim_bstream_t *bs, int len); +faim_internal fu32_t aim_locate_getcaps(aim_session_t *sess, aim_bstream_t *bs, int len); +faim_internal fu32_t aim_locate_getcaps_short(aim_session_t *sess, aim_bstream_t *bs, int len); faim_internal int aim_putcap(aim_bstream_t *bs, fu32_t caps); faim_internal void aim_info_free(aim_userinfo_t *); faim_internal int aim_info_extract(aim_session_t *sess, aim_bstream_t *bs, aim_userinfo_t *); diff -r 6338cb1768ea -r 83e8faa7f6d5 src/protocols/oscar/im.c --- a/src/protocols/oscar/im.c Sun Oct 26 06:55:27 2003 +0000 +++ b/src/protocols/oscar/im.c Sun Oct 26 07:35:16 2003 +0000 @@ -1676,7 +1676,7 @@ * The next 16bytes are a capability block so we can * identify what type of rendezvous this is. */ - args.reqclass = aim_getcap(sess, &bbs, 0x10); + args.reqclass = aim_locate_getcaps(sess, &bbs, 0x10); /* * What follows may be TLVs or nothing, depending on the diff -r 6338cb1768ea -r 83e8faa7f6d5 src/protocols/oscar/locate.c --- a/src/protocols/oscar/locate.c Sun Oct 26 06:55:27 2003 +0000 +++ b/src/protocols/oscar/locate.c Sun Oct 26 07:35:16 2003 +0000 @@ -323,11 +323,7 @@ return NULL; } -/* - * This still takes a length parameter even with a bstream because capabilities - * are not naturally bounded. - */ -faim_internal fu32_t aim_getcap(aim_session_t *sess, aim_bstream_t *bs, int len) +faim_internal fu32_t aim_locate_getcaps(aim_session_t *sess, aim_bstream_t *bs, int len) { fu32_t flags = 0; int offset; @@ -339,16 +335,14 @@ cap = aimbs_getraw(bs, 0x10); for (i = 0, identified = 0; !(aim_caps[i].flag & AIM_CAPS_LAST); i++) { - if (memcmp(&aim_caps[i].data, cap, 0x10) == 0) { flags |= aim_caps[i].flag; identified++; break; /* should only match once... */ - } } - if (!identified) { + if (!identified) faimdprintf(sess, 0, "unknown capability: {%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n", cap[0], cap[1], cap[2], cap[3], cap[4], cap[5], @@ -356,8 +350,35 @@ cap[8], cap[9], cap[10], cap[11], cap[12], cap[13], cap[14], cap[15]); + + free(cap); + } + + return flags; +} + +faim_internal fu32_t aim_locate_getcaps_short(aim_session_t *sess, aim_bstream_t *bs, int len) +{ + fu32_t flags = 0; + int offset; + + for (offset = 0; aim_bstream_empty(bs) && (offset < len); offset += 0x02) { + fu8_t *cap; + int i, identified; + + cap = aimbs_getraw(bs, 0x02); + + for (i = 0, identified = 0; !(aim_caps[i].flag & AIM_CAPS_LAST); i++) { + if (memcmp(&aim_caps[i].data[2], cap, 0x02) == 0) { + flags |= aim_caps[i].flag; + identified++; + break; /* should only match once... */ + } } + if (!identified) + faimdprintf(sess, 0, "unknown short capability: {%02x%02x}\n", cap[0], cap[1]); + free(cap); } @@ -585,7 +606,7 @@ * OSCAR Capability information. * */ - outinfo->capabilities = aim_getcap(sess, bs, length); + outinfo->capabilities |= aim_locate_getcaps(sess, bs, length); outinfo->present |= AIM_USERINFO_PRESENT_CAPABILITIES; } else if (type == 0x000e) { @@ -618,6 +639,8 @@ * OSCAR short capability information. A shortened * form of the normal capabilities. */ + outinfo->capabilities |= aim_locate_getcaps_short(sess, bs, length); + outinfo->present |= AIM_USERINFO_PRESENT_CAPABILITIES; } else if (type == 0x001b) { /* @@ -896,8 +919,7 @@ */ faim_export int aim_locate_setprofile(aim_session_t *sess, const char *profile_encoding, const char *profile, const int profile_len, - const char *awaymsg_encoding, const char *awaymsg, const int awaymsg_len, - fu32_t caps) + const char *awaymsg_encoding, const char *awaymsg, const int awaymsg_len) { aim_conn_t *conn; aim_frame_t *fr; @@ -948,8 +970,34 @@ aim_tlvlist_add_noval(&tl, 0x0004); } - if (caps != 0x00000000) - aim_tlvlist_add_caps(&tl, 0x0005, caps); + if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + aim_tlvlist_size(&tl)))) + return -ENOMEM; + + snacid = aim_cachesnac(sess, 0x0002, 0x0004, 0x0000, NULL, 0); + aim_putsnac(&fr->data, 0x0002, 0x004, 0x0000, snacid); + + aim_tlvlist_write(&fr->data, &tl); + aim_tlvlist_free(&tl); + + aim_tx_enqueue(sess, fr); + + return 0; +} + +/* + * Subtype 0x0004 - Set your client's capabilities. + */ +faim_export int aim_locate_setcaps(aim_session_t *sess, fu32_t caps) +{ + aim_conn_t *conn; + aim_frame_t *fr; + aim_snacid_t snacid; + aim_tlvlist_t *tl = NULL; + + if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_LOC))) + return -EINVAL; + + aim_tlvlist_add_caps(&tl, 0x0005, caps); if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + aim_tlvlist_size(&tl)))) return -ENOMEM; @@ -1032,7 +1080,7 @@ if ((tlv = aim_tlv_gettlv(tlvlist, 0x0005, 1))) { aim_bstream_t cbs; aim_bstream_init(&cbs, tlv->value, tlv->length); - userinfo->capabilities = aim_getcap(sess, &cbs, tlv->length); + userinfo->capabilities = aim_locate_getcaps(sess, &cbs, tlv->length); userinfo->present = AIM_USERINFO_PRESENT_CAPABILITIES; } aim_tlvlist_free(&tlvlist); diff -r 6338cb1768ea -r 83e8faa7f6d5 src/protocols/oscar/oscar.c --- a/src/protocols/oscar/oscar.c Sun Oct 26 06:55:27 2003 +0000 +++ b/src/protocols/oscar/oscar.c Sun Oct 26 07:35:16 2003 +0000 @@ -59,8 +59,8 @@ static GaimPlugin *my_protocol = NULL; -static int caps_aim = AIM_CAPS_CHAT | AIM_CAPS_BUDDYICON | AIM_CAPS_DIRECTIM | AIM_CAPS_SENDFILE | AIM_CAPS_INTEROPERATE; -static int caps_icq = AIM_CAPS_BUDDYICON | AIM_CAPS_DIRECTIM | AIM_CAPS_SENDFILE | AIM_CAPS_ICQUTF8 | AIM_CAPS_INTEROPERATE; +static int caps_aim = AIM_CAPS_CHAT | AIM_CAPS_BUDDYICON | AIM_CAPS_DIRECTIM | AIM_CAPS_SENDFILE | AIM_CAPS_INTEROPERATE | AIM_CAPS_ICHAT; +static int caps_icq = AIM_CAPS_BUDDYICON | AIM_CAPS_DIRECTIM | AIM_CAPS_SENDFILE | AIM_CAPS_ICQUTF8 | AIM_CAPS_INTEROPERATE | AIM_CAPS_ICHAT; static fu8_t features_aim[] = {0x01, 0x01, 0x01, 0x02}; static fu8_t features_icq[] = {0x01, 0x06}; @@ -3122,7 +3122,7 @@ tmp = _("Hiptop"); break; case AIM_CAPS_SECUREIM: - tmp = _("Secure IM"); + tmp = _("Security Enabled"); break; default: tmp = NULL; @@ -3678,7 +3678,7 @@ aim_reqpersonalinfo(sess, fr->conn); #ifndef NOSSI - gaim_debug(GAIM_DEBUG_INFO, "oscar", "ssi: requesting ssi list\n"); + gaim_debug(GAIM_DEBUG_INFO, "oscar", "ssi: requesting rights and list\n"); aim_ssi_reqrights(sess); aim_ssi_reqdata(sess); #endif @@ -3686,9 +3686,11 @@ aim_locate_reqrights(sess); aim_buddylist_reqrights(sess, fr->conn); aim_im_reqparams(sess); - aim_bos_reqrights(sess, fr->conn); /* XXX - Don't call this with ssi? */ + aim_bos_reqrights(sess, fr->conn); /* XXX - Don't call this with ssi */ #ifdef NOSSI + gaim_debug(GAIM_DEBUG_INFO, "oscar", "bos: requesting rights\n"); + aim_bos_reqrights(sess, fr->conn); aim_bos_setgroupperm(sess, fr->conn, AIM_FLAG_ALLUSERS); aim_bos_setprivacyflags(sess, fr->conn, AIM_PRIVFLAGS_ALLOWIDLE | AIM_PRIVFLAGS_ALLOWMEMBERSINCE); #endif @@ -3789,9 +3791,10 @@ od->rights.maxsiglen = od->rights.maxawaymsglen = (guint)maxsiglen; if (od->icq) - aim_locate_setprofile(sess, NULL, NULL, 0, NULL, NULL, 0, caps_icq); + aim_locate_setcaps(od->sess, caps_icq); else - oscar_set_info(gc, gc->account->user_info); + aim_locate_setcaps(od->sess, caps_aim); + oscar_set_info(gc, gc->account->user_info); return 1; } @@ -3817,10 +3820,10 @@ } static int gaim_bosrights(aim_session_t *sess, aim_frame_t *fr, ...) { - fu16_t maxpermits, maxdenies; - va_list ap; GaimConnection *gc = sess->aux_data; OscarData *od = (OscarData *)gc->proto_data; + va_list ap; + fu16_t maxpermits, maxdenies; va_start(ap, fr); maxpermits = (fu16_t) va_arg(ap, unsigned int); @@ -4415,43 +4418,38 @@ "Your profile remains unset; try setting it " "again when you are fully connected.")); - if (od->icq) - aim_locate_setprofile(od->sess, NULL, NULL, 0, NULL, NULL, 0, caps_icq); - else { - if (!text) { - aim_locate_setprofile(od->sess, NULL, NULL, 0, NULL, NULL, 0, caps_aim); - return; - } + if (!text) { + aim_locate_setprofile(od->sess, NULL, "", 0, NULL, NULL, 0); + return; + } - text_html = gaim_strdup_withhtml(text); - flags = oscar_encoding_check(text_html); - if (flags & AIM_IMFLAGS_UNICODE) { - msg = g_convert(text_html, strlen(text_html), "UCS-2BE", "UTF-8", NULL, &msglen, NULL); - aim_locate_setprofile(od->sess, "unicode-2-0", msg, (msglen > od->rights.maxsiglen ? od->rights.maxsiglen : msglen), NULL, NULL, 0, caps_aim); - g_free(msg); - } else if (flags & AIM_IMFLAGS_ISO_8859_1) { - msg = g_convert(text_html, strlen(text_html), "ISO-8859-1", "UTF-8", NULL, &msglen, NULL); - aim_locate_setprofile(od->sess, "iso-8859-1", msg, (msglen > od->rights.maxsiglen ? od->rights.maxsiglen : msglen), NULL, NULL, 0, caps_aim); - g_free(msg); - } else { - msglen = strlen(text_html); - aim_locate_setprofile(od->sess, "us-ascii", text_html, (msglen > od->rights.maxsiglen ? od->rights.maxsiglen : msglen), NULL, NULL, 0, caps_aim); - } - - if (msglen > od->rights.maxsiglen) { - gchar *errstr; - errstr = g_strdup_printf(ngettext("The maximum profile length of %d byte " - "has been exceeded. Gaim has truncated it for you.", - "The maximum profile length of %d bytes " - "has been exceeded. Gaim has truncated it for you.", - od->rights.maxsiglen), od->rights.maxsiglen); - gaim_notify_warning(gc, NULL, _("Profile too long."), errstr); - g_free(errstr); - } - - g_free(text_html); - - } + text_html = gaim_strdup_withhtml(text); + flags = oscar_encoding_check(text_html); + if (flags & AIM_IMFLAGS_UNICODE) { + msg = g_convert(text_html, strlen(text_html), "UCS-2BE", "UTF-8", NULL, &msglen, NULL); + aim_locate_setprofile(od->sess, "unicode-2-0", msg, (msglen > od->rights.maxsiglen ? od->rights.maxsiglen : msglen), NULL, NULL, 0); + g_free(msg); + } else if (flags & AIM_IMFLAGS_ISO_8859_1) { + msg = g_convert(text_html, strlen(text_html), "ISO-8859-1", "UTF-8", NULL, &msglen, NULL); + aim_locate_setprofile(od->sess, "iso-8859-1", msg, (msglen > od->rights.maxsiglen ? od->rights.maxsiglen : msglen), NULL, NULL, 0); + g_free(msg); + } else { + msglen = strlen(text_html); + aim_locate_setprofile(od->sess, "us-ascii", text_html, (msglen > od->rights.maxsiglen ? od->rights.maxsiglen : msglen), NULL, NULL, 0); + } + + if (msglen > od->rights.maxsiglen) { + gchar *errstr; + errstr = g_strdup_printf(ngettext("The maximum profile length of %d byte " + "has been exceeded. Gaim has truncated it for you.", + "The maximum profile length of %d bytes " + "has been exceeded. Gaim has truncated it for you.", + od->rights.maxsiglen), od->rights.maxsiglen); + gaim_notify_warning(gc, NULL, _("Profile too long."), errstr); + g_free(errstr); + } + + g_free(text_html); return; } @@ -4477,7 +4475,7 @@ } if (!text) { - aim_locate_setprofile(od->sess, NULL, NULL, 0, NULL, "", 0, caps_aim); + aim_locate_setprofile(od->sess, NULL, NULL, 0, NULL, "", 0); return; } @@ -4486,19 +4484,19 @@ if (flags & AIM_IMFLAGS_UNICODE) { msg = g_convert(text_html, strlen(text_html), "UCS-2BE", "UTF-8", NULL, &msglen, NULL); aim_locate_setprofile(od->sess, NULL, NULL, 0, "unicode-2-0", msg, - (msglen > od->rights.maxawaymsglen ? od->rights.maxawaymsglen : msglen), caps_aim); + (msglen > od->rights.maxawaymsglen ? od->rights.maxawaymsglen : msglen)); g_free(msg); gc->away = g_strndup(text, od->rights.maxawaymsglen/2); } else if (flags & AIM_IMFLAGS_ISO_8859_1) { msg = g_convert(text_html, strlen(text_html), "ISO-8859-1", "UTF-8", NULL, &msglen, NULL); aim_locate_setprofile(od->sess, NULL, NULL, 0, "iso-8859-1", msg, - (msglen > od->rights.maxawaymsglen ? od->rights.maxawaymsglen : msglen), caps_aim); + (msglen > od->rights.maxawaymsglen ? od->rights.maxawaymsglen : msglen)); g_free(msg); gc->away = g_strndup(text_html, od->rights.maxawaymsglen); } else { msglen = strlen(text_html); aim_locate_setprofile(od->sess, NULL, NULL, 0, "us-ascii", text_html, - (msglen > od->rights.maxawaymsglen ? od->rights.maxawaymsglen : msglen), caps_aim); + (msglen > od->rights.maxawaymsglen ? od->rights.maxawaymsglen : msglen)); gc->away = g_strndup(text_html, od->rights.maxawaymsglen); } @@ -4628,13 +4626,7 @@ #else if (od->sess->ssi.received_data) { while (buddies) { - GaimBuddy *buddy = gaim_find_buddy(gc->account, (const char *)buddies->data); - GaimGroup *group = gaim_find_buddys_group(buddy); - if (buddy && group) { - gaim_debug(GAIM_DEBUG_INFO, "oscar", - "ssi: adding buddy %s to group %s\n", (const char *)buddies->data, group->name); - aim_ssi_addbuddy(od->sess, buddy->name, group->name, gaim_get_buddy_alias_only(buddy), NULL, NULL, 0); - } + oscar_add_buddy(gc, (const char *)buddies->data, NULL); buddies = buddies->next; } } @@ -5323,16 +5315,23 @@ static void oscar_list_emblems(GaimBuddy *b, char **se, char **sw, char **nw, char **ne) { + GaimAccount *account = NULL; + GaimConnection *gc = NULL; + OscarData *od = NULL; char *emblems[4] = {NULL,NULL,NULL,NULL}; int i = 0; + aim_userinfo_t *userinfo = NULL; + + if (b != NULL) + account = b->account; + if (account != NULL) + gc = account->gc; + if (gc != NULL) + od = gc->proto_data; if (!GAIM_BUDDY_IS_ONLINE(b)) { - GaimAccount *account; - GaimConnection *gc; - OscarData *od; char *gname; - if ((b->name) && (account = b->account) && (gc = account->gc) && - (od = gc->proto_data) && (od->sess->ssi.received_data) && + if ((b->name) && (od) && (od->sess->ssi.received_data) && (gname = aim_ssi_itemlist_findparentname(od->sess->ssi.local, b->name)) && (aim_ssi_waitingforauth(od->sess->ssi.local, gname, b->name))) { emblems[i++] = "notauthorized"; @@ -5371,6 +5370,13 @@ emblems[i++] = "hiptop"; /* if (b->uc & UC_UNCONFIRMED && i < 4) emblems[i++] = "unconfirmed"; */ + + if ((i < 4) && (od != NULL)) { + userinfo = aim_locate_finduserinfo(od->sess, b->name); + if ((userinfo != NULL) && (userinfo->capabilities & AIM_CAPS_SECUREIM)) + emblems[i++] = "secure"; + } + *se = emblems[0]; *sw = emblems[1]; *nw = emblems[2]; @@ -5501,6 +5507,7 @@ fu8_t flags = 0, length = 0; char *md5 = NULL; + va_start(ap, fr); type = va_arg(ap, int); @@ -6343,7 +6350,7 @@ static void oscar_setavailmsg(GaimConnection *gc, char *text) { OscarData *od = (OscarData *)gc->proto_data; - aim_locate_setprofile(od->sess, NULL, NULL, 0, NULL, "", 0, 0); + aim_locate_setprofile(od->sess, NULL, NULL, 0, NULL, "", 0); aim_srv_setavailmsg(od->sess, text); }