# HG changeset patch # User Mark Doliner # Date 1123958440 0 # Node ID 1b1d63602d771ef9fe098a2b14c8ea7f9b9b2d0e # Parent ce3b9969b3994407dfc56078cbed3f8f3d888c33 [gaim-migrate @ 13429] sf patch #1247984, from Ilya Konstantinov Retrieve ICQ away messages with i18n support committer: Tailor Script diff -r ce3b9969b399 -r 1b1d63602d77 COPYRIGHT --- a/COPYRIGHT Sat Aug 13 15:53:29 2005 +0000 +++ b/COPYRIGHT Sat Aug 13 18:40:40 2005 +0000 @@ -104,6 +104,7 @@ Henry Jen Benjamin Kahn Akuke Kok +Ilya Konstantinov Cole Kowalski Gary Kramlich Patrik Kullman diff -r ce3b9969b399 -r 1b1d63602d77 src/protocols/oscar/im.c --- a/src/protocols/oscar/im.c Sat Aug 13 15:53:29 2005 +0000 +++ b/src/protocols/oscar/im.c Sat Aug 13 18:40:40 2005 +0000 @@ -972,10 +972,10 @@ aimbs_put16(&fr->data, 0x0036); { /* V */ aimbs_putle16(&fr->data, 0x001b); /* L */ - aimbs_putle16(&fr->data, 0x0008); /* XXX - Protocol version */ + aimbs_putle16(&fr->data, 0x0009); /* Protocol version */ aim_putcap(&fr->data, AIM_CAPS_EMPTY); aimbs_putle16(&fr->data, 0x0000); /* Unknown */ - aimbs_putle16(&fr->data, 0x0003); /* Client features? */ + aimbs_putle16(&fr->data, 0x0001); /* Client features? */ aimbs_putle16(&fr->data, 0x0000); /* Unknown */ aimbs_putle8(&fr->data, 0x00); /* Unkizown */ aimbs_putle16(&fr->data, 0xffff); /* Sequence number? XXX - This should decrement by 1 with each request */ @@ -988,15 +988,19 @@ /* The type of status message being requested */ if (type & AIM_ICQ_STATE_CHAT) - aimbs_putle16(&fr->data, 0x03ec); + aimbs_putle8(&fr->data, 0xec); else if(type & AIM_ICQ_STATE_DND) - aimbs_putle16(&fr->data, 0x03eb); + aimbs_putle8(&fr->data, 0xeb); else if(type & AIM_ICQ_STATE_OUT) - aimbs_putle16(&fr->data, 0x03ea); + aimbs_putle8(&fr->data, 0xea); else if(type & AIM_ICQ_STATE_BUSY) - aimbs_putle16(&fr->data, 0x03e9); + aimbs_putle8(&fr->data, 0xe9); else if(type & AIM_ICQ_STATE_AWAY) - aimbs_putle16(&fr->data, 0x03e8); + aimbs_putle8(&fr->data, 0xe8); + else + /* This should not happen */ + aimbs_putle8(&fr->data, 0x00); + aimbs_putle8(&fr->data, 0x03); /* Message Flags */ aimbs_putle16(&fr->data, 0x0000); /* Status? */ aimbs_putle16(&fr->data, 0x0001); /* Priority of this message? */ @@ -2194,11 +2198,106 @@ sn = aimbs_getstr(bs, snlen); reason = aimbs_get16(bs); - if (channel == 0x0002) { /* File transfer declined */ - aimbs_get16(bs); /* Unknown */ - aimbs_get16(bs); /* Unknown */ - if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) - ret = userfunc(sess, rx, channel, sn, reason, ck); + if (channel == 0x0002) { + switch (reason) { + case 0x0003: { + /* This is exactly like the Extended Data TLV (2711) */ + fu16_t len; + fu16_t version; + fu8_t plugin_uuid[16]; + + len = aimbs_getle16(bs); /* Usually 0x001b */ + version = aimbs_getle16(bs); + aimbs_getrawbuf(bs, plugin_uuid, sizeof(plugin_uuid)); + aim_bstream_advance(bs, len - sizeof(version) - sizeof(plugin_uuid)); /* Rest is unknown */ + + len = aimbs_getle16(bs); /* Usually 0x000e */ + aim_bstream_advance(bs, len); /* Unknown */ + + if (plugin_uuid[0] == 0 && + plugin_uuid[1] == 0 && + plugin_uuid[2] == 0 && + plugin_uuid[3] == 0 && + plugin_uuid[4] == 0 && + plugin_uuid[5] == 0 && + plugin_uuid[6] == 0 && + plugin_uuid[7] == 0 && + plugin_uuid[8] == 0 && + plugin_uuid[9] == 0 && + plugin_uuid[10] == 0 && + plugin_uuid[11] == 0 && + plugin_uuid[12] == 0 && + plugin_uuid[13] == 0 && + plugin_uuid[14] == 0 && + plugin_uuid[15] == 0) + { + fu8_t msg_type, msg_flags, *msg; + fu16_t status_code, priority_code, msg_length; + fu32_t state; + + msg_type = aimbs_getle8(bs); + switch (msg_type) { + case 0xe8: + state = AIM_ICQ_STATE_AWAY; + break; + case 0xe9: + state = AIM_ICQ_STATE_AWAY | AIM_ICQ_STATE_BUSY; + break; + case 0xea: + state = AIM_ICQ_STATE_AWAY | AIM_ICQ_STATE_OUT; + break; + case 0xeb: + state = AIM_ICQ_STATE_AWAY | AIM_ICQ_STATE_DND | AIM_ICQ_STATE_BUSY; + break; + case 0xec: + state = AIM_ICQ_STATE_CHAT; + break; + default: + state = 0; + break; + } + msg_flags = aimbs_getle8(bs); /* would usually have 0x03 == auto msg */ + status_code = aimbs_getle16(bs); + priority_code = aimbs_getle16(bs); + + msg_length = aimbs_getle16(bs); + msg = aimbs_getraw(bs, msg_length); + + if (state & AIM_ICQ_STATE_AWAY) + { + aim_userinfo_t *userinfo = aim_locate_finduserinfo(sess, sn); + free(userinfo->away); + free(userinfo->away_encoding); + if (msg_length > 0) + { + userinfo->away = (char *)malloc(msg_length); + memcpy(userinfo->away, msg, msg_length); + } + else + { + userinfo->away = NULL; + } + userinfo->away_len = msg_length - 1; /* msg_length includes a terminating '\0' */ + userinfo->away_encoding = strdup("text/x-aolrtf; charset=\"utf-8\""); + } + + if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) + ret = userfunc(sess, rx, channel, sn, reason, state, msg); + } + else + { + if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) + ret = userfunc(sess, rx, channel, sn, reason, ck); + } + break; + } + + default: { + /* File transfer declined? */ + if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) + ret = userfunc(sess, rx, channel, sn, reason, ck); + } + } } else if (channel == 0x0004) { /* ICQ message */ switch (reason) { case 0x0003: { /* ICQ status message. Maybe other stuff too, you never know with these people. */ diff -r ce3b9969b399 -r 1b1d63602d77 src/protocols/oscar/locate.c --- a/src/protocols/oscar/locate.c Sat Aug 13 15:53:29 2005 +0000 +++ b/src/protocols/oscar/locate.c Sat Aug 13 18:40:40 2005 +0000 @@ -67,8 +67,8 @@ 0x82, 0x22, 0x44, 0x45, 0x45, 0x53, 0x54, 0x00}}, /* - * Not really sure about this one. In an email from - * 26 Sep 2003, Matthew Sachs suggested that, "this + * Not really sure about this one. In an email from + * 26 Sep 2003, Matthew Sachs suggested that, "this * is probably the capability for the SMS features." */ {AIM_CAPS_SMS, @@ -124,9 +124,9 @@ 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, /* - * Indeed, there are two of these. The former appears to be correct, - * but in some versions of winaim, the second one is set. Either they - * forgot to fix endianness, or they made a typo. It really doesn't + * Indeed, there are two of these. The former appears to be correct, + * but in some versions of winaim, the second one is set. Either they + * forgot to fix endianness, or they made a typo. It really doesn't * matter which. */ {AIM_CAPS_GAMES, @@ -141,12 +141,12 @@ 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}, /* - * Setting this lets AIM users receive messages from ICQ users, and ICQ - * users receive messages from AIM users. It also lets ICQ users show - * up in buddy lists for AIM users, and AIM users show up in buddy lists - * for ICQ users. And ICQ privacy/invisibility acts like AIM privacy, - * in that if you add a user to your deny list, you will not be able to - * see them as online (previous you could still see them, but they + * Setting this lets AIM users receive messages from ICQ users, and ICQ + * users receive messages from AIM users. It also lets ICQ users show + * up in buddy lists for AIM users, and AIM users show up in buddy lists + * for ICQ users. And ICQ privacy/invisibility acts like AIM privacy, + * in that if you add a user to your deny list, you will not be able to + * see them as online (previous you could still see them, but they * couldn't see you. */ {AIM_CAPS_INTEROPERATE, @@ -183,7 +183,7 @@ {0x97, 0xb1, 0x27, 0x51, 0x24, 0x3c, 0x43, 0x34, 0xad, 0x22, 0xd6, 0xab, 0xf7, 0x3f, 0x14, 0x09}}, - {AIM_CAPS_APINFO, + {AIM_CAPS_APINFO, {0xaa, 0x4a, 0x32, 0xb5, 0xf8, 0x84, 0x48, 0xc6, 0xa3, 0xd7, 0x8c, 0x50, 0x97, 0x19, 0xfd, 0x5b}}, @@ -199,7 +199,7 @@ }; /* - * Add the userinfo to our linked list. If we already have userinfo + * Add the userinfo to our linked list. If we already have userinfo * for this buddy, then just overwrite parts of the old data. * * @param userinfo Contains the new information for the buddy. @@ -295,12 +295,12 @@ } /** - * Remove this screen name from our queue. If this info was requested + * Remove this screen name from our queue. If this info was requested * by our info request queue, then pop the next element off of the queue. * * @param sess The aim session. * @param sn Screen name of the info we just received. - * @return True if the request was explicit (client requested the info), + * @return True if the request was explicit (client requested the info), * false if the request was implicit (libfaim request the info). */ static int aim_locate_gotuserinfo(aim_session_t *sess, const char *sn) { @@ -497,7 +497,7 @@ } /* - * AIM is fairly regular about providing user info. This is a generic + * AIM is fairly regular about providing user info. This is a generic * routine to extract it in its standard form. */ faim_internal int aim_info_extract(aim_session_t *sess, aim_bstream_t *bs, aim_userinfo_t *outinfo) @@ -512,7 +512,7 @@ memset(outinfo, 0x00, sizeof(aim_userinfo_t)); /* - * Screen name. Stored as an unterminated string prepended with a + * Screen name. Stored as an unterminated string prepended with a * byte containing its length. */ snlen = aimbs_get8(bs); @@ -524,12 +524,12 @@ outinfo->warnlevel = aimbs_get16(bs); /* - * TLV Count. Unsigned short representing the number of + * TLV Count. Unsigned short representing the number of * Type-Length-Value triples that follow. */ tlvcnt = aimbs_get16(bs); - /* + /* * Parse out the Type-Length-Value triples as they're found. */ for (curtlv = 0; curtlv < tlvcnt; curtlv++) { @@ -1135,6 +1135,19 @@ userinfo->away = (char *)malloc(tlv->length); memcpy(userinfo->away, tlv->value, tlv->length); userinfo->away_len = tlv->length; + /* + * ICQ cannot be trusted with non-Latin-1 away messages + * delivered in 0x02,0x06; see SF issue 1175975. + * Therefore, we try to get its Away information + * in an alternative fashion -- same as used + * by the official client. + */ + if (((userinfo->icqinfo.status & AIM_ICQ_STATE_AWAY) || + (userinfo->icqinfo.status & AIM_ICQ_STATE_CHAT)) && + (userinfo->sn != NULL) && aim_sn_is_icq(userinfo->sn)) + { + aim_im_sendch2_geticqaway(sess, userinfo->sn, userinfo->icqinfo.status); + } } /* Caps will be 5 */ @@ -1152,8 +1165,8 @@ free(userinfo); /* - * Remove this screen name from our queue. If the client requested - * this buddy's info explicitly, then notify them that we have info + * Remove this screen name from our queue. If the client requested + * this buddy's info explicitly, then notify them that we have info * for this buddy. */ was_explicit = aim_locate_gotuserinfo(sess, userinfo2->sn); @@ -1164,14 +1177,14 @@ return ret; } -/* +/* * Subtype 0x0009 - Set directory profile data. * * This is not the same as aim_location_setprofile! * privacy: 1 to allow searching, 0 to disallow. * */ -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) +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) { aim_conn_t *conn; aim_frame_t *fr; @@ -1237,7 +1250,7 @@ return -ENOMEM; snacid = aim_cachesnac(sess, 0x0002, 0x000b, 0x0000, NULL, 0); - + aim_putsnac(&fr->data, 0x0002, 0x000b, 0x0000, snacid); aimbs_put8(&fr->data, strlen(sn)); aimbs_putstr(&fr->data, sn); @@ -1249,7 +1262,7 @@ /* * Subtype 0x000f - * + * * XXX pass these in better * */ @@ -1292,7 +1305,7 @@ } /* - * Subtype 0x0015 - Request the info a user using the short method. This is + * Subtype 0x0015 - Request the info a user using the short method. This is * what iChat uses. It normally is VERY leniently rate limited. * * @param sn The screen name whose info you wish to request.