From: <fac...@us...> - 2006-05-01 01:22:31
|
Revision: 16110 Author: faceprint Date: 2006-04-30 18:22:18 -0700 (Sun, 30 Apr 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16110&view=rev Log Message: ----------- support for JEP-0085 (chat state notifications) Basically, this gains us the ability to send/receive the fact that a user has typed, and then stopped. This has passed the WorksForMe(TM) test suite...lemme know if you notice anything weird. Modified Paths: -------------- trunk/src/protocols/jabber/buddy.h trunk/src/protocols/jabber/message.c trunk/src/protocols/jabber/message.h Modified: trunk/src/protocols/jabber/buddy.h =================================================================== --- trunk/src/protocols/jabber/buddy.h 2006-04-30 11:49:42 UTC (rev 16109) +++ trunk/src/protocols/jabber/buddy.h 2006-05-01 01:22:18 UTC (rev 16110) @@ -61,6 +61,16 @@ char *status; JabberCapabilities capabilities; char *thread_id; + enum { + JABBER_CHAT_STATES_UNKNOWN, + JABBER_CHAT_STATES_UNSUPPORTED, + JABBER_CHAT_STATES_SUPPORTED + } chat_states; + struct { + char *version; + char *name; + char *os; + } client; } JabberBuddyResource; void jabber_buddy_free(JabberBuddy *jb); Modified: trunk/src/protocols/jabber/message.c =================================================================== --- trunk/src/protocols/jabber/message.c 2006-04-30 11:49:42 UTC (rev 16109) +++ trunk/src/protocols/jabber/message.c 2006-05-01 01:22:18 UTC (rev 16110) @@ -30,8 +30,6 @@ #include "message.h" #include "xmlnode.h" -#define JABBER_TYPING_NOTIFY_INT 15 - void jabber_message_free(JabberMessage *jm) { g_free(jm->from); @@ -79,14 +77,24 @@ } if(!jm->xhtml && !jm->body) { - if(jm->events & JABBER_MESSAGE_EVENT_COMPOSING) + if(JM_STATE_COMPOSING == jm->chat_state) serv_got_typing(jm->js->gc, from, 0, GAIM_TYPING); + else if(JM_STATE_PAUSED == jm->chat_state) + serv_got_typing(jm->js->gc, from, 0, GAIM_TYPED); else serv_got_typing_stopped(jm->js->gc, from); } else { if(jbr) { - if(jm->events & JABBER_MESSAGE_EVENT_COMPOSING) + if(JM_TS_JEP_0085 == (jm->typing_style & JM_TS_JEP_0085)) { + jbr->chat_states = JABBER_CHAT_STATES_SUPPORTED; + } else { + jbr->chat_states = JABBER_CHAT_STATES_UNSUPPORTED; + } + + if(JM_TS_JEP_0022 == (jm->typing_style & JM_TS_JEP_0022)) { jbr->capabilities |= JABBER_CAP_COMPOSING; + } + if(jbr->thread_id) g_free(jbr->thread_id); jbr->thread_id = g_strdup(jbr->thread_id); @@ -95,6 +103,7 @@ jm->sent); } + g_free(from); jabber_id_free(jid); } @@ -286,6 +295,21 @@ } else if(!strcmp(child->name, "html")) { if(!jm->xhtml && xmlnode_get_child(child, "body")) jm->xhtml = xmlnode_to_str(child, NULL); + } else if(!strcmp(child->name, "active")) { + jm->chat_state = JM_STATE_ACTIVE; + jm->typing_style |= JM_TS_JEP_0085; + } else if(!strcmp(child->name, "composing")) { + jm->chat_state = JM_STATE_COMPOSING; + jm->typing_style |= JM_TS_JEP_0085; + } else if(!strcmp(child->name, "paused")) { + jm->chat_state = JM_STATE_PAUSED; + jm->typing_style |= JM_TS_JEP_0085; + } else if(!strcmp(child->name, "inactive")) { + jm->chat_state = JM_STATE_INACTIVE; + jm->typing_style |= JM_TS_JEP_0085; + } else if(!strcmp(child->name, "gone")) { + jm->chat_state = JM_STATE_GONE; + jm->typing_style |= JM_TS_JEP_0085; } else if(!strcmp(child->name, "error")) { const char *code = xmlnode_get_attrib(child, "code"); char *code_txt = NULL; @@ -303,8 +327,11 @@ } else if(!strcmp(child->name, "x")) { const char *xmlns = xmlnode_get_attrib(child, "xmlns"); if(xmlns && !strcmp(xmlns, "jabber:x:event")) { - if(xmlnode_get_child(child, "composing")) - jm->events |= JABBER_MESSAGE_EVENT_COMPOSING; + if(xmlnode_get_child(child, "composing")) { + if(jm->chat_state == JM_STATE_ACTIVE) + jm->chat_state = JM_STATE_COMPOSING; + jm->typing_style |= JM_TS_JEP_0022; + } } else if(xmlns && !strcmp(xmlns, "jabber:x:delay")) { const char *timestamp = xmlnode_get_attrib(child, "stamp"); jm->delayed = TRUE; @@ -411,13 +438,37 @@ xmlnode_insert_data(child, jm->thread_id, -1); } - if(jm->events || (!jm->body && !jm->xhtml && !jm->subject)) { + if(JM_TS_JEP_0022 == (jm->typing_style & JM_TS_JEP_0022)) { child = xmlnode_new_child(message, "x"); xmlnode_set_attrib(child, "xmlns", "jabber:x:event"); - if(jm->events & JABBER_MESSAGE_EVENT_COMPOSING) + if(jm->chat_state == JM_STATE_COMPOSING || jm->body) xmlnode_new_child(child, "composing"); } + if(JM_TS_JEP_0085 == (jm->typing_style & JM_TS_JEP_0085)) { + child = NULL; + switch(jm->chat_state) + { + case JM_STATE_ACTIVE: + child = xmlnode_new_child(message, "active"); + break; + case JM_STATE_COMPOSING: + child = xmlnode_new_child(message, "composing"); + break; + case JM_STATE_PAUSED: + child = xmlnode_new_child(message, "paused"); + break; + case JM_STATE_INACTIVE: + child = xmlnode_new_child(message, "inactive"); + break; + case JM_STATE_GONE: + child = xmlnode_new_child(message, "gone"); + break; + } + if(child) + xmlnode_set_attrib(child, "xmlns", "http://jabber.org/protocol/chatstates"); + } + if(jm->subject) { child = xmlnode_new_child(message, "subject"); xmlnode_insert_data(child, jm->subject, -1); @@ -467,12 +518,25 @@ jm = g_new0(JabberMessage, 1); jm->js = gc->proto_data; jm->type = JABBER_MESSAGE_CHAT; - jm->events = JABBER_MESSAGE_EVENT_COMPOSING; + jm->chat_state = JM_STATE_ACTIVE; jm->to = g_strdup(who); jm->id = jabber_get_next_id(jm->js); - if(jbr && jbr->thread_id) - jm->thread_id = jbr->thread_id; + jm->chat_state = JM_STATE_ACTIVE; + if(jbr) { + if(jbr->thread_id) + jm->thread_id = jbr->thread_id; + + if(jbr->chat_states != JABBER_CHAT_STATES_UNSUPPORTED) { + jm->typing_style |= JM_TS_JEP_0085; + /* if(JABBER_CHAT_STATES_UNKNOWN == jbr->chat_states) + jbr->chat_states = JABBER_CHAT_STATES_UNSUPPORTED; */ + } + + if(jbr->chat_states != JABBER_CHAT_STATES_SUPPORTED) + jm->typing_style |= JM_TS_JEP_0022; + } + buf = g_strdup_printf("<html xmlns='http://jabber.org/protocol/xhtml-im'><body xmlns='http://www.w3.org/1999/xhtml'>%s</body></html>", msg); gaim_markup_html_to_xhtml(buf, &xhtml, &jm->body); @@ -537,21 +601,35 @@ g_free(resource); - if(!jbr || !(jbr->capabilities & JABBER_CAP_COMPOSING)) + if(!jbr || !((jbr->capabilities & JABBER_CAP_COMPOSING) || (jbr->chat_states != JABBER_CHAT_STATES_UNSUPPORTED))) return 0; + /* TODO: figure out threading */ jm = g_new0(JabberMessage, 1); jm->js = gc->proto_data; jm->type = JABBER_MESSAGE_CHAT; jm->to = g_strdup(who); jm->id = jabber_get_next_id(jm->js); - if(typing == GAIM_TYPING) - jm->events = JABBER_MESSAGE_EVENT_COMPOSING; + if(GAIM_TYPING == typing) + jm->chat_state = JM_STATE_COMPOSING; + else if(GAIM_TYPED == typing) + jm->chat_state = JM_STATE_PAUSED; + else + jm->chat_state = JM_STATE_ACTIVE; + if(jbr->chat_states != JABBER_CHAT_STATES_UNSUPPORTED) { + jm->typing_style |= JM_TS_JEP_0085; + /* if(JABBER_CHAT_STATES_UNKNOWN == jbr->chat_states) + jbr->chat_states = JABBER_CHAT_STATES_UNSUPPORTED; */ + } + + if(jbr->chat_states != JABBER_CHAT_STATES_SUPPORTED) + jm->typing_style |= JM_TS_JEP_0022; + jabber_message_send(jm); jabber_message_free(jm); - return JABBER_TYPING_NOTIFY_INT; + return 0; } Modified: trunk/src/protocols/jabber/message.h =================================================================== --- trunk/src/protocols/jabber/message.h 2006-04-30 11:49:42 UTC (rev 16109) +++ trunk/src/protocols/jabber/message.h 2006-05-01 01:22:18 UTC (rev 16110) @@ -48,8 +48,17 @@ char *error; char *thread_id; enum { - JABBER_MESSAGE_EVENT_COMPOSING = 1 << 1 - } events; + JM_TS_NONE = 0, + JM_TS_JEP_0022 = 0x1, + JM_TS_JEP_0085 = 0x2 + } typing_style; + enum { + JM_STATE_ACTIVE, + JM_STATE_COMPOSING, + JM_STATE_PAUSED, + JM_STATE_INACTIVE, + JM_STATE_GONE + } chat_state; GList *etc; } JabberMessage; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fac...@us...> - 2006-05-30 01:30:25
|
Revision: 16204 Author: faceprint Date: 2006-05-29 18:30:18 -0700 (Mon, 29 May 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16204&view=rev Log Message: ----------- jabber get info now fetches and displays idle time and version info this is based largely on the work of Andrew Sayman. He submitted a patch back in 2004, and I hacked it all to hell, changed how some things were done. If it works, credit him. If it breaks, blame me. Modified Paths: -------------- trunk/src/protocols/jabber/buddy.c trunk/src/protocols/jabber/iq.c trunk/src/protocols/jabber/iq.h Modified: trunk/src/protocols/jabber/buddy.c =================================================================== --- trunk/src/protocols/jabber/buddy.c 2006-05-29 23:27:30 UTC (rev 16203) +++ trunk/src/protocols/jabber/buddy.c 2006-05-30 01:30:18 UTC (rev 16204) @@ -35,6 +35,21 @@ #include "presence.h" #include "xdata.h" +typedef struct { + long idle_seconds; +} JabberBuddyInfoResource; + +typedef struct { + JabberStream *js; + JabberBuddy *jb; + char *jid; + GSList *ids; + GHashTable *resources; + int timeout_handle; + char *vcard_text; + GSList *vcard_imgids; +} JabberBuddyInfo; + void jabber_buddy_free(JabberBuddy *jb) { g_return_if_fail(jb != NULL); @@ -125,10 +140,11 @@ jbr->jb->resources = g_list_remove(jbr->jb->resources, jbr); g_free(jbr->name); - if(jbr->status) - g_free(jbr->status); - if(jbr->thread_id) - g_free(jbr->thread_id); + g_free(jbr->status); + g_free(jbr->thread_id); + g_free(jbr->client.name); + g_free(jbr->client.version); + g_free(jbr->client.os); g_free(jbr); } @@ -587,39 +603,24 @@ * end of that ancient crap that needs to die ******/ - -static void jabber_vcard_parse(JabberStream *js, xmlnode *packet, gpointer data) +static void jabber_buddy_info_show_if_ready(JabberBuddyInfo *jbi) { - GList *resources; - const char *from = xmlnode_get_attrib(packet, "from"); - JabberBuddy *jb; - JabberBuddyResource *jbr; GString *info_text; char *resource_name; - char *bare_jid; - char *text; - xmlnode *vcard; - GaimBuddy *b; - GSList *imgids = NULL; + JabberBuddyResource *jbr; + JabberBuddyInfoResource *jbir; + GList *resources; - if(!from) + /* not yet */ + if(jbi->ids) return; - if(!(jb = jabber_buddy_find(js, from, TRUE))) - return; - - /* XXX: handle the error case */ - - resource_name = jabber_get_resource(from); - bare_jid = jabber_get_bare_jid(from); - - b = gaim_find_buddy(js->gc->account, bare_jid); - - info_text = g_string_new(""); + resource_name = jabber_get_resource(jbi->jid); if(resource_name) { - jbr = jabber_buddy_find_resource(jb, resource_name); + jbr = jabber_buddy_find_resource(jbi->jb, resource_name); + jbir = g_hash_table_lookup(jbi->resources, resource_name); if(jbr) { char *purdy = NULL; if(jbr->status) @@ -634,25 +635,127 @@ g_string_append_printf(info_text, "<b>%s:</b> %s<br/>", _("Status"), _("Unknown")); } + if(jbir) { + if(jbir->idle_seconds > 0) { + g_string_append_printf(info_text, "<b>%s:</b> %s<br/>", + _("Idle"), gaim_str_seconds_to_string(jbir->idle_seconds)); + } + } + if(jbr && jbr->client.name) { + g_string_append_printf(info_text, "<b>%s:</b> %s %s<br/>", + _("Client:"), jbr->client.name, + jbr->client.version ? jbr->client.version : ""); + if(jbr->client.os) { + g_string_append_printf(info_text, "<b>%s:</b> %s<br/>", + _("Operating System"), jbr->client.os); + } + } } else { - for(resources = jb->resources; resources; resources = resources->next) { + for(resources = jbi->jb->resources; resources; resources = resources->next) { char *purdy = NULL; jbr = resources->data; if(jbr->status) purdy = gaim_strdup_withhtml(jbr->status); g_string_append_printf(info_text, "<b>%s:</b> %s<br/>", _("Resource"), jbr->name); - g_string_append_printf(info_text, "<b>%s:</b> %s%s%s<br/><br/>", + g_string_append_printf(info_text, "<b>%s:</b> %s%s%s<br/>", _("Status"), jabber_buddy_state_get_name(jbr->state), purdy ? ": " : "", purdy ? purdy : ""); if(purdy) g_free(purdy); + + jbir = g_hash_table_lookup(jbi->resources, jbr->name); + if(jbir) { + if(jbir->idle_seconds > 0) { + g_string_append_printf(info_text, "<b>%s:</b> %s<br/>", + _("Idle"), gaim_str_seconds_to_string(jbir->idle_seconds)); + } + } + if(jbr->client.name) { + g_string_append_printf(info_text, "<b>%s:</b> %s %s<br/>", + _("Client:"), jbr->client.name, + jbr->client.version ? jbr->client.version : ""); + if(jbr->client.os) { + g_string_append_printf(info_text, "<b>%s:</b> %s<br/>", + _("Operating System"), jbr->client.os); + } + } + + g_string_append_printf(info_text, "<br/>"); } } g_free(resource_name); + info_text = g_string_append(info_text, jbi->vcard_text); + + gaim_notify_userinfo(jbi->js->gc, jbi->jid, info_text->str, NULL, NULL); + + while(jbi->vcard_imgids) { + gaim_imgstore_unref(GPOINTER_TO_INT(jbi->vcard_imgids->data)); + jbi->vcard_imgids = g_slist_delete_link(jbi->vcard_imgids, jbi->vcard_imgids); + } + + g_string_free(info_text, TRUE); + + gaim_timeout_remove(jbi->timeout_handle); + g_free(jbi->jid); + g_hash_table_destroy(jbi->resources); + g_free(jbi->vcard_text); + g_free(jbi); +} + +static void jabber_buddy_info_remove_id(JabberBuddyInfo *jbi, const char *id) +{ + GSList *l = jbi->ids; + + if(!id) + return; + + while(l) { + if(!strcmp(id, l->data)) { + jbi->ids = g_slist_remove(jbi->ids, l->data); + return; + } + l = l->next; + } +} + +static void jabber_vcard_parse(JabberStream *js, xmlnode *packet, gpointer data) +{ + const char *type, *id, *from; + JabberBuddy *jb; + GString *info_text; + char *bare_jid; + char *text; + xmlnode *vcard; + GaimBuddy *b; + JabberBuddyInfo *jbi = data; + + from = xmlnode_get_attrib(packet, "from"); + type = xmlnode_get_attrib(packet, "type"); + id = xmlnode_get_attrib(packet, "id"); + + jabber_buddy_info_remove_id(jbi, id); + + if(!jbi) + return; + + if(!from) + return; + + if(!(jb = jabber_buddy_find(js, from, TRUE))) + return; + + /* XXX: handle the error case */ + + bare_jid = jabber_get_bare_jid(from); + + b = gaim_find_buddy(js->gc->account, bare_jid); + + info_text = g_string_new(""); + if((vcard = xmlnode_get_child(packet, "vCard")) || (vcard = xmlnode_get_child_with_namespace(packet, "query", "vcard-temp"))) { xmlnode *child; @@ -838,11 +941,11 @@ data = gaim_base64_decode(bintext, &size); - imgids = g_slist_prepend(imgids, GINT_TO_POINTER(gaim_imgstore_add(data, size, "logo.png"))); + jbi->vcard_imgids = g_slist_prepend(jbi->vcard_imgids, GINT_TO_POINTER(gaim_imgstore_add(data, size, "logo.png"))); g_string_append_printf(info_text, "<b>%s:</b> <img id='%d'><br/>", photo ? _("Photo") : _("Logo"), - GPOINTER_TO_INT(imgids->data)); + GPOINTER_TO_INT(jbi->vcard_imgids->data)); gaim_buddy_icons_set_for_user(js->gc->account, bare_jid, data, size); @@ -862,33 +965,187 @@ } } - text = gaim_strdup_withhtml(info_text->str); + jbi->vcard_text = gaim_strdup_withhtml(info_text->str); + g_string_free(info_text, TRUE); + g_free(bare_jid); - gaim_notify_userinfo(js->gc, from, text, NULL, NULL); + jabber_buddy_info_show_if_ready(jbi); +} - while(imgids) { - gaim_imgstore_unref(GPOINTER_TO_INT(imgids->data)); - imgids = g_slist_delete_link(imgids, imgids); + +static void jabber_buddy_info_resource_free(gpointer data) +{ + JabberBuddyInfoResource *jbri = data; + g_free(jbri); +} + +static void jabber_version_parse(JabberStream *js, xmlnode *packet, gpointer data) +{ + JabberBuddyInfo *jbi = data; + const char *type, *id, *from; + xmlnode *query; + char *resource_name; + + g_return_if_fail(jbi != NULL); + + type = xmlnode_get_attrib(packet, "type"); + id = xmlnode_get_attrib(packet, "id"); + from = xmlnode_get_attrib(packet, "from"); + + jabber_buddy_info_remove_id(jbi, id); + + if(!from) + return; + + resource_name = jabber_get_resource(from); + + if(resource_name) { + if(type && !strcmp(type, "result")) { + if((query = xmlnode_get_child(packet, "query"))) { + JabberBuddyResource *jbr = jabber_buddy_find_resource(jbi->jb, resource_name); + if(jbr) { + xmlnode *node; + if((node = xmlnode_get_child(query, "name"))) { + jbr->client.name = xmlnode_get_data(node); + } + if((node = xmlnode_get_child(query, "version"))) { + jbr->client.version = xmlnode_get_data(node); + } + if((node = xmlnode_get_child(query, "os"))) { + jbr->client.os = xmlnode_get_data(node); + } + } + } + } + g_free(resource_name); } - g_string_free(info_text, TRUE); - g_free(text); - g_free(bare_jid); + + jabber_buddy_info_show_if_ready(jbi); } -static void jabber_buddy_get_info_for_jid(JabberStream *js, const char *full_jid) +static void jabber_last_parse(JabberStream *js, xmlnode *packet, gpointer data) { + JabberBuddyInfo *jbi = data; + xmlnode *query; + char *resource_name; + const char *type, *id, *from, *seconds; + + g_return_if_fail(jbi != NULL); + + type = xmlnode_get_attrib(packet, "type"); + id = xmlnode_get_attrib(packet, "id"); + from = xmlnode_get_attrib(packet, "from"); + + jabber_buddy_info_remove_id(jbi, id); + + if(!from) + return; + + resource_name = jabber_get_resource(from); + + if(resource_name) { + if(type && !strcmp(type, "result")) { + if((query = xmlnode_get_child(packet, "query"))) { + seconds = xmlnode_get_attrib(query, "seconds"); + if(seconds) { + char *end = NULL; + long sec = strtol(seconds, &end, 10); + if(end != seconds) { + JabberBuddyInfoResource *jbir = g_hash_table_lookup(jbi->resources, resource_name); + if(jbir) { + jbir->idle_seconds = sec; + } + } + } + } + } + g_free(resource_name); + } + + jabber_buddy_info_show_if_ready(jbi); +} + +static gboolean jabber_buddy_get_info_timeout(gpointer data) +{ + JabberBuddyInfo *jbi = data; + + /* remove the pending callbacks */ + while(jbi->ids) { + char *id = jbi->ids->data; + jabber_iq_remove_callback_by_id(jbi->js, id); + g_free(id); + jbi->ids = g_slist_remove(jbi->ids, id); + } + + jbi->timeout_handle = 0; + + jabber_buddy_info_show_if_ready(jbi); + + return FALSE; +} + +static void jabber_buddy_get_info_for_jid(JabberStream *js, const char *jid) +{ JabberIq *iq; xmlnode *vcard; + GList *resources; + JabberBuddy *jb; + JabberBuddyInfo *jbi; + jb = jabber_buddy_find(js, jid, TRUE); + + /* invalid JID */ + if(!jb) + return; + + jbi = g_new0(JabberBuddyInfo, 1); + jbi->jid = g_strdup(jid); + jbi->js = js; + jbi->jb = jb; + jbi->resources = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, jabber_buddy_info_resource_free); + iq = jabber_iq_new(js, JABBER_IQ_GET); - xmlnode_set_attrib(iq->node, "to", full_jid); + xmlnode_set_attrib(iq->node, "to", jid); vcard = xmlnode_new_child(iq->node, "vCard"); xmlnode_set_attrib(vcard, "xmlns", "vcard-temp"); - jabber_iq_set_callback(iq, jabber_vcard_parse, NULL); + jabber_iq_set_callback(iq, jabber_vcard_parse, jbi); + jbi->ids = g_slist_prepend(jbi->ids, g_strdup(iq->id)); jabber_iq_send(iq); + + for(resources = jb->resources; resources; resources = resources->next) + { + JabberBuddyResource *jbr = resources->data; + JabberBuddyInfoResource *jbir = g_new0(JabberBuddyInfoResource, 1); + char *full_jid; + if(strrchr(jid, '/')) { + full_jid = g_strdup(jid); + } else { + full_jid = g_strdup_printf("%s/%s", jid, jbr->name); + } + + g_hash_table_insert(jbi->resources, g_strdup(jbr->name), jbir); + + if(!jbr->client.name) { + iq = jabber_iq_new_query(js, JABBER_IQ_GET, "jabber:iq:version"); + xmlnode_set_attrib(iq->node, "to", full_jid); + jabber_iq_set_callback(iq, jabber_version_parse, jbi); + jbi->ids = g_slist_prepend(jbi->ids, g_strdup(iq->id)); + jabber_iq_send(iq); + } + + iq = jabber_iq_new_query(js, JABBER_IQ_GET, "jabber:iq:last"); + xmlnode_set_attrib(iq->node, "to", full_jid); + jabber_iq_set_callback(iq, jabber_last_parse, jbi); + jbi->ids = g_slist_prepend(jbi->ids, g_strdup(iq->id)); + jabber_iq_send(iq); + + g_free(full_jid); + } + + jbi->timeout_handle = gaim_timeout_add(30000, jabber_buddy_get_info_timeout, jbi); } void jabber_buddy_get_info(GaimConnection *gc, const char *who) @@ -1383,7 +1640,7 @@ if(!(type = xmlnode_get_attrib(packet, "type")) || !strcmp(type, "error")) { char *msg = jabber_parse_error(js, packet); - + if(!msg) msg = g_strdup(_("Unknown error")); @@ -1417,16 +1674,16 @@ if((instnode = xmlnode_get_child(query, "instructions"))) { char *tmp = xmlnode_get_data(instnode); - + if(tmp) { - /* Try to translate the message (see static message + /* Try to translate the message (see static message list in jabber_user_dir_comments[]) */ instructions = g_strdup_printf(_("Server Instructions: %s"), _(tmp)); g_free(tmp); } } - + if(!instructions) { instructions = g_strdup(_("Fill in one or more fields to search " @@ -1497,3 +1754,6 @@ _("Search Directory"), GAIM_CALLBACK(jabber_user_search_ok), _("Cancel"), NULL, js); } + + + Modified: trunk/src/protocols/jabber/iq.c =================================================================== --- trunk/src/protocols/jabber/iq.c 2006-05-29 23:27:30 UTC (rev 16203) +++ trunk/src/protocols/jabber/iq.c 2006-05-30 01:30:18 UTC (rev 16204) @@ -239,6 +239,11 @@ } } +void jabber_iq_remove_callback_by_id(JabberStream *js, const char *id) +{ + g_hash_table_remove(js->iq_callbacks, id); +} + void jabber_iq_parse(JabberStream *js, xmlnode *packet) { JabberCallbackData *jcd; @@ -256,7 +261,7 @@ if(type && (!strcmp(type, "result") || !strcmp(type, "error"))) { if(id && *id && (jcd = g_hash_table_lookup(js->iq_callbacks, id))) { jcd->callback(js, packet, jcd->data); - g_hash_table_remove(js->iq_callbacks, id); + jabber_iq_remove_callback_by_id(js, id); return; } } Modified: trunk/src/protocols/jabber/iq.h =================================================================== --- trunk/src/protocols/jabber/iq.h 2006-05-29 23:27:30 UTC (rev 16203) +++ trunk/src/protocols/jabber/iq.h 2006-05-30 01:30:18 UTC (rev 16204) @@ -53,6 +53,7 @@ void jabber_iq_parse(JabberStream *js, xmlnode *packet); +void jabber_iq_remove_callback_by_id(JabberStream *js, const char *id); void jabber_iq_set_callback(JabberIq *iq, JabberIqCallback *cb, gpointer data); void jabber_iq_set_id(JabberIq *iq, const char *id); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <the...@us...> - 2006-08-14 07:19:00
|
Revision: 16747 Author: thekingant Date: 2006-08-14 00:18:58 -0700 (Mon, 14 Aug 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16747&view=rev Log Message: ----------- Jabber is done. Also, I have a feeling JabberSIXfer->streamhosts is leaking, if anyone wants to fix it. Wink wink. Nudge Nudge. Karate chop. Modified Paths: -------------- trunk/src/protocols/jabber/jabber.c trunk/src/protocols/jabber/jabber.h trunk/src/protocols/jabber/si.c Modified: trunk/src/protocols/jabber/jabber.c =================================================================== --- trunk/src/protocols/jabber/jabber.c 2006-08-14 07:00:26 UTC (rev 16746) +++ trunk/src/protocols/jabber/jabber.c 2006-08-14 07:18:58 UTC (rev 16747) @@ -30,6 +30,7 @@ #include "message.h" #include "notify.h" #include "pluginpref.h" +#include "proxy.h" #include "prpl.h" #include "request.h" #include "server.h" @@ -421,21 +422,18 @@ static void -jabber_login_callback(gpointer data, gint source) +jabber_login_callback(gpointer data, gint source, const gchar *error) { GaimConnection *gc = data; JabberStream *js = gc->proto_data; + js->connect_info = NULL; + if (source < 0) { gaim_connection_error(gc, _("Couldn't connect to host")); return; } - if(!g_list_find(gaim_connections_get_all(), gc)) { - close(source); - return; - } - js->fd = source; if(js->state == JABBER_STREAM_CONNECTING) @@ -474,12 +472,10 @@ static void jabber_login_connect(JabberStream *js, const char *server, int port) { - GaimProxyConnectInfo *connect_info; - - connect_info = gaim_proxy_connect(js->gc->account, server, + js->connect_info = gaim_proxy_connect(js->gc->account, server, port, jabber_login_callback, js->gc); - if (connect_info == NULL) + if (js->connect_info == NULL) gaim_connection_error(js->gc, _("Unable to create socket")); } @@ -862,7 +858,6 @@ const char *connect_server = gaim_account_get_string(account, "connect_server", ""); const char *server; - GaimProxyConnectInfo *connect_info; js = gc->proto_data = g_new0(JabberStream, 1); js->gc = gc; @@ -912,11 +907,11 @@ } if(!js->gsc) { - connect_info = gaim_proxy_connect(account, server, + js->connect_info = gaim_proxy_connect(account, server, gaim_account_get_int(account, "port", 5222), jabber_login_callback, gc); - if (connect_info == NULL) + if (js->connect_info == NULL) gaim_connection_error(gc, _("Unable to create socket")); } } @@ -932,6 +927,9 @@ if (!gc->disconnect_timeout) jabber_send_raw(js, "</stream:stream>", -1); + if (js->connect_info) + gaim_proxy_connect_cancel(js->connect_info); + if(js->gsc) { #ifdef HAVE_OPENSSL if (!gc->disconnect_timeout) Modified: trunk/src/protocols/jabber/jabber.h =================================================================== --- trunk/src/protocols/jabber/jabber.h 2006-08-14 07:00:26 UTC (rev 16746) +++ trunk/src/protocols/jabber/jabber.h 2006-08-14 07:18:58 UTC (rev 16747) @@ -67,6 +67,8 @@ { int fd; + GaimProxyConnectInfo *connect_info; + #ifdef HAVE_LIBXML xmlParserCtxt *context; #else Modified: trunk/src/protocols/jabber/si.c =================================================================== --- trunk/src/protocols/jabber/si.c 2006-08-14 07:00:26 UTC (rev 16746) +++ trunk/src/protocols/jabber/si.c 2006-08-14 07:18:58 UTC (rev 16747) @@ -46,6 +46,8 @@ typedef struct _JabberSIXfer { JabberStream *js; + GaimProxyConnectInfo *connect_info; + gboolean accepted; char *stream_id; @@ -88,7 +90,8 @@ static void jabber_si_bytestreams_attempt_connect(GaimXfer *xfer); -static void jabber_si_bytestreams_connect_cb(gpointer data, gint source) +static void +jabber_si_bytestreams_connect_cb(gpointer data, gint source, const gchar *error_message) { GaimXfer *xfer = data; JabberSIXfer *jsx = xfer->data; @@ -97,6 +100,7 @@ struct bytestreams_streamhost *streamhost = jsx->streamhosts->data; gaim_proxy_info_destroy(jsx->gpi); + jsx->connect_info = NULL; if(source < 0) { jsx->streamhosts = g_list_remove(jsx->streamhosts, streamhost); @@ -167,8 +171,18 @@ for(i=0; i<20; i++, p+=2) snprintf(p, 3, "%02x", hashval[i]); - gaim_proxy_connect_socks5(jsx->gpi, dstaddr, 0, jabber_si_bytestreams_connect_cb, xfer); + jsx->connect_info = gaim_proxy_connect_socks5(jsx->gpi, dstaddr, 0, + jabber_si_bytestreams_connect_cb, xfer); g_free(dstaddr); + + if (jsx->connect_info == NULL) + { + jsx->streamhosts = g_list_remove(jsx->streamhosts, streamhost); + g_free(streamhost->jid); + g_free(streamhost->host); + g_free(streamhost); + jabber_si_bytestreams_attempt_connect(xfer); + } } void jabber_bytestreams_parse(JabberStream *js, xmlnode *packet) @@ -682,6 +696,9 @@ js->file_transfers = g_list_remove(js->file_transfers, xfer); + if (jsx->connect_info != NULL) + gaim_proxy_connect_cancel(jsx->connect_info); + g_free(jsx->stream_id); g_free(jsx->iq_id); /* XXX: free other stuff */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |