Mercurial > pidgin
diff libpurple/protocols/oscar/family_icq.c @ 21993:bb1190d6961c
Partial support for reading ICQ 6 status notes. The status note will
show up next to the person's name in the buddy list, but only if they
don't have another status message set.
This is from Collin from ComBOTS GmbH. Fixes #3208.
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Sat, 05 Jan 2008 07:33:13 +0000 |
parents | 44b4e8bd759b |
children | a8c025929245 |
line wrap: on
line diff
--- a/libpurple/protocols/oscar/family_icq.c Sat Jan 05 02:16:30 2008 +0000 +++ b/libpurple/protocols/oscar/family_icq.c Sat Jan 05 07:33:13 2008 +0000 @@ -435,6 +435,65 @@ return 0; } +/* + * getstatusnote may be a misleading name because the response + * contains a lot of different information but currently it's only + * used to get that. + */ +int aim_icq_getstatusnote(OscarData *od, const char *uin, guint8 *note_hash, guint16 note_hash_len) +{ + FlapConnection *conn; + FlapFrame *frame; + aim_snacid_t snacid; + int bslen; + + purple_debug_misc("oscar", "aim_icq_getstatusnote: requesting status note for %s.\n", uin); + + if (!od || !(conn = flap_connection_findbygroup(od, 0x0015))) + { + purple_debug_misc("oscar", "aim_icq_getstatusnote: no connection.\n"); + return -EINVAL; + } + + bslen = 2 + 4 + 2 + 2 + 2 + 2 + 58 + strlen(uin); + + frame = flap_frame_new(od, 0x02, 10 + 4 + bslen); + + snacid = aim_cachesnac(od, 0x0015, 0x0002, 0x0000, NULL, 0); + aim_putsnac(&frame->data, 0x0015, 0x0002, 0x0000, snacid); + + /* For simplicity, don't bother using a tlvlist */ + byte_stream_put16(&frame->data, 0x0001); + byte_stream_put16(&frame->data, bslen); + + byte_stream_putle16(&frame->data, bslen - 2); + byte_stream_putle32(&frame->data, atoi(od->sn)); + byte_stream_putle16(&frame->data, 0x07d0); /* I command thee. */ + byte_stream_putle16(&frame->data, snacid); /* eh. */ + byte_stream_putle16(&frame->data, 0x0fa0); /* shrug. */ + byte_stream_putle16(&frame->data, 58 + strlen(uin)); + + byte_stream_put32(&frame->data, 0x05b90002); /* don't ask */ + byte_stream_put32(&frame->data, 0x80000000); + byte_stream_put32(&frame->data, 0x00000006); + byte_stream_put32(&frame->data, 0x00010002); + byte_stream_put32(&frame->data, 0x00020000); + byte_stream_put32(&frame->data, 0x04e30000); + byte_stream_put32(&frame->data, 0x00020002); + byte_stream_put32(&frame->data, 0x00000001); + + byte_stream_put16(&frame->data, 24 + strlen(uin)); + byte_stream_put32(&frame->data, 0x003c0010); + byte_stream_putraw(&frame->data, note_hash, 16); /* status note hash */ + byte_stream_put16(&frame->data, 0x0032); /* buddy uin */ + byte_stream_put16(&frame->data, strlen(uin)); + byte_stream_putstr(&frame->data, uin); + + flap_connection_send(conn, frame); + + return 0; +} + static void aim_icq_freeinfo(struct aim_icq_info *info) { int i; @@ -467,6 +526,7 @@ g_free(info->workposition); g_free(info->workwebpage); g_free(info->info); + g_free(info->status_note_title); g_free(info); } @@ -641,6 +701,178 @@ info->email = byte_stream_getstr(&qbs, byte_stream_getle16(&qbs)); /* Then 0x00 02 00 00 00 00 00 */ } break; + + /* status note title and send request for status note text */ + case 0x0fb4: { + GSList *tlvlist; + aim_tlv_t *tlv; + FlapConnection *conn; + char *uin = NULL; + char *status_note_title = NULL; + + conn = flap_connection_findbygroup(od, 0x0004); + if (conn == NULL) + { + purple_debug_misc("oscar", "icq/0x0fb4: flap connection was not found.\n"); + break; + } + + byte_stream_advance(&qbs, 0x02); /* length */ + byte_stream_advance(&qbs, 0x2f); /* unknown stuff */ + + tlvlist = aim_tlvlist_read(&qbs); + + tlv = aim_tlv_gettlv(tlvlist, 0x0032, 1); + if (tlv != NULL) + /* Get user number */ + uin = aim_tlv_getvalue_as_string(tlv); + + tlv = aim_tlv_gettlv(tlvlist, 0x0226, 1); + if (tlv != NULL) + /* Get status note title */ + status_note_title = aim_tlv_getvalue_as_string(tlv); + + aim_tlvlist_free(tlvlist); + + if (uin == NULL || status_note_title == NULL) + { + purple_debug_misc("oscar", "icq/0x0fb4: uin or " + "status_note_title was not found\n"); + g_free(uin); + g_free(status_note_title); + break; + } + + if (status_note_title[0] == '\0') + { + PurpleAccount *account; + PurpleBuddy *buddy; + PurplePresence *presence; + PurpleStatus *status; + + account = purple_connection_get_account(od->gc); + buddy = purple_find_buddy(account, uin); + presence = purple_buddy_get_presence(buddy); + status = purple_presence_get_active_status(presence); + + purple_prpl_got_user_status(account, uin, + purple_status_get_id(status), + "message", NULL, NULL); + + g_free(status_note_title); + } + else + { + struct aim_icq_info *info; + guint32 data_len; + FlapFrame *frame; + aim_snacid_t snacid; + guchar cookie[8]; + + info = g_new0(struct aim_icq_info, 1); + + if (info == NULL) + { + g_free(uin); + g_free(status_note_title); + + break; + } + + data_len = 13 + strlen(uin) + 30 + 6 + 4 + 55 + 85 + 4; + frame = flap_frame_new(od, 0x0002, 10 + 4 + data_len); + snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, NULL, 0); + + aim_putsnac(&frame->data, 0x0004, 0x0006, 0x0000, snacid); + + aim_icbm_makecookie(cookie); + + byte_stream_putraw(&frame->data, cookie, 8); /* ICBM cookie */ + byte_stream_put16(&frame->data, 0x0002); /* message channel */ + byte_stream_put8(&frame->data, strlen(uin)); /* uin */ + byte_stream_putstr(&frame->data, uin); + + byte_stream_put16(&frame->data, 0x0005); /* rendez vous data */ + byte_stream_put16(&frame->data, 0x00b2); + byte_stream_put16(&frame->data, 0x0000); /* request */ + byte_stream_putraw(&frame->data, cookie, 8); /* ICBM cookie */ + byte_stream_put32(&frame->data, 0x09461349); /* ICQ server relaying */ + byte_stream_put16(&frame->data, 0x4c7f); + byte_stream_put16(&frame->data, 0x11d1); + byte_stream_put32(&frame->data, 0x82224445); + byte_stream_put32(&frame->data, 0x53540000); + + byte_stream_put16(&frame->data, 0x000a); /* unknown TLV */ + byte_stream_put16(&frame->data, 0x0002); + byte_stream_put16(&frame->data, 0x0001); + + byte_stream_put16(&frame->data, 0x000f); /* unknown TLV */ + byte_stream_put16(&frame->data, 0x0000); + + byte_stream_put16(&frame->data, 0x2711); /* extended data */ + byte_stream_put16(&frame->data, 0x008a); + byte_stream_putle16(&frame->data, 0x001b); /* length */ + byte_stream_putle16(&frame->data, 0x0009); /* version */ + byte_stream_putle32(&frame->data, 0x00000000); /* plugin: none */ + byte_stream_putle32(&frame->data, 0x00000000); + byte_stream_putle32(&frame->data, 0x00000000); + byte_stream_putle32(&frame->data, 0x00000000); + byte_stream_putle16(&frame->data, 0x0000); /* unknown */ + byte_stream_putle32(&frame->data, 0x00000000); /* client capabilities flags */ + byte_stream_put8(&frame->data, 0x00); /* unknown */ + byte_stream_putle16(&frame->data, 0x0064); /* downcounter? */ + byte_stream_putle16(&frame->data, 0x000e); /* length */ + byte_stream_putle16(&frame->data, 0x0064); /* downcounter? */ + byte_stream_putle32(&frame->data, 0x00000000); /* unknown */ + byte_stream_putle32(&frame->data, 0x00000000); + byte_stream_putle32(&frame->data, 0x00000000); + byte_stream_put8(&frame->data, 0x1a); /* message type: plugin message descibed by text string */ + byte_stream_put8(&frame->data, 0x00); /* message flags */ + byte_stream_putle16(&frame->data, 0x0000); /* status code */ + byte_stream_putle16(&frame->data, 0x0001); /* priority code */ + byte_stream_putle16(&frame->data, 0x0000); /* text length */ + + byte_stream_put8(&frame->data, 0x3a); /* message dump */ + byte_stream_put32(&frame->data, 0x00811a18); + byte_stream_put32(&frame->data, 0xbc0e6c18); + byte_stream_put32(&frame->data, 0x47a5916f); + byte_stream_put32(&frame->data, 0x18dcc76f); + byte_stream_put32(&frame->data, 0x1a010013); + byte_stream_put32(&frame->data, 0x00000041); + byte_stream_put32(&frame->data, 0x77617920); + byte_stream_put32(&frame->data, 0x53746174); + byte_stream_put32(&frame->data, 0x7573204d); + byte_stream_put32(&frame->data, 0x65737361); + byte_stream_put32(&frame->data, 0x67650100); + byte_stream_put32(&frame->data, 0x00000000); + byte_stream_put32(&frame->data, 0x00000000); + byte_stream_put32(&frame->data, 0x00000000); + byte_stream_put32(&frame->data, 0x00000015); + byte_stream_put32(&frame->data, 0x00000000); + byte_stream_put32(&frame->data, 0x0000000d); + byte_stream_put32(&frame->data, 0x00000074); + byte_stream_put32(&frame->data, 0x6578742f); + byte_stream_put32(&frame->data, 0x782d616f); + byte_stream_put32(&frame->data, 0x6c727466); + + byte_stream_put16(&frame->data, 0x0003); /* server ACK requested */ + byte_stream_put16(&frame->data, 0x0000); + + info->uin = atoi(uin); + info->status_note_title = status_note_title; + + memcpy(&info->icbm_cookie, cookie, 8); + + info->next = od->icq_info; + od->icq_info = info; + + flap_connection_send(conn, frame); + } + + g_free(uin); + + } break; + } /* End switch statement */ if (!(snac->flags & 0x0001)) {