summaryrefslogtreecommitdiff
path: root/libpurple/protocols/oscar/family_icbm.c
diff options
context:
space:
mode:
Diffstat (limited to 'libpurple/protocols/oscar/family_icbm.c')
-rw-r--r--libpurple/protocols/oscar/family_icbm.c241
1 files changed, 233 insertions, 8 deletions
diff --git a/libpurple/protocols/oscar/family_icbm.c b/libpurple/protocols/oscar/family_icbm.c
index d3bdc70e53..a01a6e56f1 100644
--- a/libpurple/protocols/oscar/family_icbm.c
+++ b/libpurple/protocols/oscar/family_icbm.c
@@ -2624,6 +2624,15 @@ static int clientautoresp(OscarData *od, FlapConnection *conn, aim_module_t *mod
char *bn;
guchar *cookie;
guint8 bnlen;
+ char *xml = NULL;
+ int hdrlen;
+ int curpos;
+ int num1,num2;
+ char *desc, *title, *temp;
+ PurpleAccount *account;
+ PurpleBuddy *buddy;
+ PurplePresence *presence;
+ PurpleStatus *status;
cookie = byte_stream_getraw(bs, 8);
channel = byte_stream_get16(bs);
@@ -2633,14 +2642,54 @@ static int clientautoresp(OscarData *od, FlapConnection *conn, aim_module_t *mod
if (channel == 0x0002)
{
- if (reason == 0x0003) /* channel-specific */
- /* parse status note text */
- parse_status_note_text(od, cookie, bn, bs);
-
- byte_stream_get16(bs); /* Unknown */
- byte_stream_get16(bs); /* Unknown */
- if ((userfunc = aim_callhandler(od, snac->family, snac->subtype)))
- ret = userfunc(od, conn, frame, channel, bn, reason, cookie);
+ hdrlen = byte_stream_getle16(bs);
+ if ( ((hdrlen == 27 ) && (bs->len > (27 + 51)))) {
+ byte_stream_advance(bs, 51);
+ num1 = byte_stream_getle16(bs);
+ num2 = byte_stream_getle16(bs);
+ purple_debug_misc("oscar", "X-Status: Num1 %i, num2 %i\n",num1, num2);
+
+ if(((num1 == 0x4f00)&&(num2 == 0x3b00))) {
+ byte_stream_advance(bs, 86);
+ curpos = byte_stream_curpos(bs);
+ xml = byte_stream_getstr(bs, bs->len - curpos);
+ purple_debug_misc("oscar", "X-Status: Received XML reply\n");
+ if(xml) {
+ /* purple_debug_misc("oscar", "X-Status: XML reply: %s\n", (const char*) xml); */
+ if ((desc=strstr(xml,"<desc>")) != NULL) {
+ temp=strstr(xml,"</desc>");
+ temp[0]=0;
+ desc=desc+12;
+ }
+ if ((title=strstr(xml,"<title>")) != NULL) {
+ temp=strstr(xml,"</title>");
+ temp[0]=0;
+ title=title+13;
+ } else {
+ title="";
+ }
+ strcpy(xml,title);
+ if (desc) {
+ strcat(xml, " - ");
+ strcat(xml, desc);
+ }
+ purple_debug_misc("oscar", "X-Status reply: %s\n", (const char*)xml);
+ account = purple_connection_get_account(od->gc);
+ buddy = purple_find_buddy(account, bn);
+ presence = purple_buddy_get_presence(buddy);
+ status = purple_presence_get_active_status(presence);
+ purple_prpl_got_user_status(account, bn,
+ purple_status_get_id(status), "message", xml, NULL);
+ } else {
+ purple_debug_misc("oscar", "X-Status: Can't get XML reply string\n");
+ }
+ } else {
+ purple_debug_misc("oscar", "X-Status: 0x0004, 0x000b not an xstatus reply\n" );
+ /* if ((userfunc = aim_callhandler(od, snac->family, snac->subtype)))
+ ret = userfunc(od, conn, frame, channel, sn, reason); */
+ }
+
+ }
} else if (channel == 0x0004) { /* ICQ message */
switch (reason) {
@@ -2699,6 +2748,7 @@ static int clientautoresp(OscarData *od, FlapConnection *conn, aim_module_t *mod
g_free(cookie);
g_free(bn);
+ g_free(xml);
return ret;
}
@@ -2807,6 +2857,181 @@ int aim_im_sendmtn(OscarData *od, guint16 channel, const char *bn, guint16 event
}
/*
+ * Subtype 0x0006 - Send eXtra Status request
+ */
+int icq_im_xstatus_request(OscarData *od, const char *sn)
+{
+ FlapConnection *conn;
+ aim_snacid_t snacid;
+ guchar cookie[8];
+ GSList *outer_tlvlist = NULL, *inner_tlvlist = NULL;
+ ByteStream bs, header, plugindata;
+ PurpleAccount *account;
+ const char *fmt;
+ char *statxml;
+ int xmllen;
+
+ static const guint8 pluginid[] =
+ {
+ 0x09, 0x46, 0x13, 0x49, 0x4C, 0x7F, 0x11, 0xD1,
+ 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00
+ };
+
+ static const guint8 c_plugindata[] =
+ {
+ 0x1B, 0x00, 0x0A,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0xF9, 0xD1, 0x0E, 0x00, 0xF9, 0xD1, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x01, 0x00, 0x00, 0x4F, 0x00, 0x3B, 0x60, 0xB3, 0xEF, 0xD8, 0x2A, 0x6C, 0x45, 0xA4, 0xE0, 0x9C,
+ 0x5A, 0x5E, 0x67, 0xE8, 0x65, 0x08, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x53, 0x63, 0x72, 0x69, 0x70,
+ 0x74, 0x20, 0x50, 0x6C, 0x75, 0x67, 0x2D, 0x69, 0x6E, 0x3A, 0x20, 0x52, 0x65, 0x6D, 0x6F, 0x74,
+ 0x65, 0x20, 0x4E, 0x6F, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41,
+ 0x72, 0x72, 0x69, 0x76, 0x65, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x14, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00
+ };
+
+ if (!od || !(conn = flap_connection_findbygroup(od, 0x0004)))
+ return -EINVAL;
+
+ if (!sn)
+ return -EINVAL;
+
+ fmt = "<N><QUERY>&lt;Q&gt;&lt;PluginID&gt;srvMng&lt;/PluginID&gt;&lt;/Q&gt;</QUERY><NOTIFY>&lt;srv&gt;&lt;id&gt;cAwaySrv&lt;/id&gt;&lt;req&gt;&lt;id&gt;AwayStat&lt;/id&gt;&lt;trans&gt;2&lt;/trans&gt;&lt;senderId&gt;%s&lt;/senderId&gt;&lt;/req&gt;&lt;/srv&gt;</NOTIFY></N>\r\n";
+
+ account = purple_connection_get_account(od->gc);
+ xmllen = strlen(fmt) - 2 + strlen(account->username);
+
+ statxml = (char*) g_malloc(xmllen);
+ snprintf(statxml, xmllen, fmt, account->username);
+
+ aim_icbm_makecookie(cookie);
+
+ byte_stream_new(&bs, 10 + 8 + 2 + 1 + strlen(sn) + 2
+ + 2 + 2 + 8 + 16 + 2 + 2 + 2 + 2 + 2
+ + 2 + 2 + sizeof(c_plugindata) + xmllen
+ + 2 + 2);
+
+ snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, NULL, 0);
+ aim_im_puticbm(&bs, cookie, 0x0002, sn);
+
+ byte_stream_new(&header, (7*2) + 16 + 8 + 2 + sizeof(c_plugindata) + xmllen); /* TLV 0x0005 Stream + Size */
+ byte_stream_new(&plugindata, (sizeof(c_plugindata) + xmllen));
+
+ byte_stream_put16(&header, 0x0000); /* Message Type: Request */
+ byte_stream_putraw(&header, cookie, sizeof(cookie)); /* Message ID */
+ byte_stream_putraw(&header, pluginid, sizeof(pluginid)); /* Plugin ID */
+
+ aim_tlvlist_add_16(&inner_tlvlist, 0x000a, 0x0001);
+ aim_tlvlist_add_noval(&inner_tlvlist, 0x000f);
+
+ /* Add Plugin Specific Data */
+ byte_stream_putraw(&plugindata, c_plugindata, sizeof(c_plugindata)); /* Content of TLV 0x2711 */
+ byte_stream_putstr(&plugindata, statxml);
+
+ aim_tlvlist_add_raw(&inner_tlvlist, 0x2711, (sizeof(c_plugindata) + xmllen), plugindata.data);
+
+ aim_tlvlist_write(&header, &inner_tlvlist);
+
+
+ aim_tlvlist_add_raw(&outer_tlvlist, 0x0005, byte_stream_curpos(&header), header.data);
+ aim_tlvlist_add_noval(&outer_tlvlist, 0x0003); /* Empty TLV 0x0003 */
+
+ aim_tlvlist_write(&bs, &outer_tlvlist);
+
+ purple_debug_misc("oscar", "X-Status Request\n");
+ flap_connection_send_snac_with_priority(od, conn, 0x0004, 0x0006, 0x0000, snacid, &bs, TRUE);
+
+ aim_tlvlist_free(inner_tlvlist);
+ aim_tlvlist_free(outer_tlvlist);
+ byte_stream_destroy(&header);
+ byte_stream_destroy(&plugindata);
+ byte_stream_destroy(&bs);
+ g_free(statxml);
+
+ return 0;
+}
+
+int icq_relay_xstatus(OscarData *od, const char *sn, const guchar *cookie)
+{
+ FlapConnection *conn;
+ ByteStream bs;
+ aim_snacid_t snacid;
+ PurpleAccount *account;
+ PurpleStatus *status;
+ const char *fmt;
+ const char *formatted_msg;
+ char *msg;
+ char *statxml;
+ const char *title;
+ int len;
+
+ static const guint8 plugindata[] = {
+ 0x1B, 0x00,
+ 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0xF9, 0xD1, 0x0E, 0x00, 0xF9, 0xD1,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x4F,
+ 0x00, 0x3B, 0x60, 0xB3, 0xEF, 0xD8, 0x2A, 0x6C, 0x45, 0xA4, 0xE0,
+ 0x9C, 0x5A, 0x5E, 0x67, 0xE8, 0x65, 0x08, 0x00, 0x2A, 0x00, 0x00,
+ 0x00, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, 0x50, 0x6C, 0x75,
+ 0x67, 0x2D, 0x69, 0x6E, 0x3A, 0x20, 0x52, 0x65, 0x6D, 0x6F, 0x74,
+ 0x65, 0x20, 0x4E, 0x6F, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
+ 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x72, 0x72, 0x69, 0x76, 0x65, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xF3, 0x01, 0x00, 0x00, 0xEF, 0x01, 0x00, 0x00
+ };
+
+ fmt = "<NR><RES>&lt;ret event='OnRemoteNotification'&gt;&lt;srv&gt;&lt;id&gt;cAwaySrv&lt;/id&gt;&lt;val srv_id='cAwaySrv'&gt;&lt;Root&gt;&lt;CASXtraSetAwayMessage&gt;&lt;/CASXtraSetAwayMessage&gt;&l t;uin&gt;%s&lt;/uin&gt;&lt;index&gt;1&lt;/index&gt;&lt;title&gt;%s&lt;/title&gt;&lt;desc&gt;%s&lt;/desc&gt;&lt;/Root&gt;&lt;/val&gt;&lt;/srv&gt;&lt;srv&gt;&lt;id&gt;cRandomizerSrv&lt;/id&gt;&lt;val srv_id='cRandomizerSrv'&gt;undefined&lt;/val&gt;&lt;/srv&gt;&lt;/ret&gt;</RES></NR>\r\n";
+
+
+ if (!od || !(conn = flap_connection_findbygroup(od, 0x0002)))
+ return -EINVAL;
+
+ if (!sn)
+ return -EINVAL;
+
+ account = purple_connection_get_account(od->gc);
+ if(!account) return -EINVAL;
+
+/* if (!strcmp(account->username, sn))
+ icq_im_xstatus_request(od, sn); */
+
+ status = purple_presence_get_active_status(account->presence);
+ if (!status) return -EINVAL;
+ title = purple_status_get_name(status);
+ if (!title) return -EINVAL;
+ formatted_msg = purple_status_get_attr_string(status, "message");
+ if (!formatted_msg) return -EINVAL;
+ msg = purple_markup_strip_html(formatted_msg);
+ if (!msg) return -EINVAL;
+ len = strlen(fmt)-6+strlen(account->username)+strlen(title)+strlen(msg);
+ statxml = (char*) g_malloc(len);
+
+ snprintf(statxml, len, fmt,
+ account->username, title, msg);
+
+ purple_debug_misc("oscar", "X-Status AutoReply: %s, %s\n", formatted_msg, msg);
+
+ byte_stream_new(&bs, 10 + 8 + 2 + 1 + strlen(sn) + 2 + sizeof(plugindata) + strlen(statxml)); /* 16 extra */
+
+ snacid = aim_cachesnac(od, 0x0004, 0x000b, 0x0000, NULL, 0);
+ aim_im_puticbm(&bs, cookie, 0x0002, sn);
+ byte_stream_put16(&bs, 0x0003);
+ byte_stream_putraw(&bs, plugindata, sizeof(plugindata));
+ byte_stream_putraw(&bs, (const guint8*)statxml, strlen(statxml));
+
+ flap_connection_send_snac_with_priority(od, conn, 0x0004, 0x000b, 0x0000, snacid, &bs, TRUE);
+
+ g_free(statxml);
+ g_free(msg);
+ byte_stream_destroy(&bs);
+
+ return 0;
+}
+
+/*
* Subtype 0x0014 - Receive a mini typing notification (mtn) packet.
*
* This is supported by winaim5 and newer, MacAIM bleh and newer, iChat bleh and newer,