summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Aurich <darkrain42@pidgin.im>2009-02-05 00:59:58 +0000
committerPaul Aurich <darkrain42@pidgin.im>2009-02-05 00:59:58 +0000
commit606373d166f3b5e279d928805591430fec2cc93d (patch)
tree37dc85ef4ed98c83ed9b71f8b8c7dfa082846f12
parent71ad3f45a71fc7ba782f9e6dce44be2a153a0d51 (diff)
parent8d286b8a775d41299d34d7fc7a17ab4f94f7475d (diff)
downloadpidgin-606373d166f3b5e279d928805591430fec2cc93d.tar.gz
propagate from branch 'im.pidgin.pidgin' (head 9cec90116395a424243dc04f682da4a41cb0dbdd)
to branch 'im.pidgin.cpw.darkrain42.xmpp.iq-handlers' (head 00f750a7f902204f295eb2586bf83d9fc20206e7)
-rw-r--r--libpurple/protocols/jabber/disco.c2
-rw-r--r--libpurple/protocols/jabber/iq.c121
-rw-r--r--libpurple/protocols/jabber/jabber.c29
-rw-r--r--libpurple/protocols/jabber/ping.c50
-rw-r--r--libpurple/protocols/jabber/ping.h10
5 files changed, 101 insertions, 111 deletions
diff --git a/libpurple/protocols/jabber/disco.c b/libpurple/protocols/jabber/disco.c
index 71f87cffa6..f76772a730 100644
--- a/libpurple/protocols/jabber/disco.c
+++ b/libpurple/protocols/jabber/disco.c
@@ -126,7 +126,7 @@ void jabber_disco_info_parse(JabberStream *js, xmlnode *packet) {
SUPPORT_FEATURE("jabber:iq:last")
SUPPORT_FEATURE("jabber:iq:oob")
SUPPORT_FEATURE("jabber:iq:time")
- SUPPORT_FEATURE("xmpp:urn:time")
+ SUPPORT_FEATURE("urn:xmpp:time")
SUPPORT_FEATURE("jabber:iq:version")
SUPPORT_FEATURE("jabber:x:conference")
SUPPORT_FEATURE("http://jabber.org/protocol/bytestreams")
diff --git a/libpurple/protocols/jabber/iq.c b/libpurple/protocols/jabber/iq.c
index 11442ed5a5..0e5ecb25aa 100644
--- a/libpurple/protocols/jabber/iq.c
+++ b/libpurple/protocols/jabber/iq.c
@@ -174,7 +174,7 @@ static void jabber_iq_time_parse(JabberStream *js, xmlnode *packet)
{
const char *type, *from, *id, *xmlns;
JabberIq *iq;
- xmlnode *query;
+ xmlnode *child;
time_t now_t;
struct tm *now;
@@ -185,61 +185,44 @@ static void jabber_iq_time_parse(JabberStream *js, xmlnode *packet)
from = xmlnode_get_attrib(packet, "from");
id = xmlnode_get_attrib(packet, "id");
- /* we're gonna throw this away in a moment, but we need it
- * to get the xmlns, so we can figure out if this is
- * jabber:iq:time or urn:xmpp:time */
- query = xmlnode_get_child(packet, "query");
- xmlns = xmlnode_get_namespace(query);
+ if ((child = xmlnode_get_child(packet, "query"))) {
+ xmlns = "jabber:iq:time";
+ } else if ((child = xmlnode_get_child(packet, "time"))) {
+ xmlns = "urn:xmpp:time";
+ } else {
+ purple_debug_warning("jabber", "Malformed IQ time packet\n");
+ return;
+ }
if(type && !strcmp(type, "get")) {
xmlnode *utc;
- const char *date;
+ const char *date, *tz, *display;
- iq = jabber_iq_new_query(js, JABBER_IQ_RESULT, xmlns);
+ iq = jabber_iq_new(js, JABBER_IQ_RESULT);
jabber_iq_set_id(iq, id);
xmlnode_set_attrib(iq->node, "to", from);
- query = xmlnode_get_child(iq->node, "query");
-
- date = purple_utf8_strftime("%Y%m%dT%T", now);
- utc = xmlnode_new_child(query, "utc");
- xmlnode_insert_data(utc, date, -1);
+ child = xmlnode_new_child(iq->node, child->name);
+ utc = xmlnode_new_child(child, "utc");
if(!strcmp("urn:xmpp:time", xmlns)) {
- xmlnode_insert_data(utc, "Z", 1); /* of COURSE the thing that is the same is different */
+ tz = purple_get_tzoff_str(now, TRUE);
+ xmlnode_insert_data(xmlnode_new_child(child, "tzo"), tz, -1);
- date = purple_get_tzoff_str(now, TRUE);
- xmlnode_insert_data(xmlnode_new_child(query, "tzo"), date, -1);
+ date = purple_utf8_strftime("%FT%TZ", now);
+ xmlnode_insert_data(utc, date, -1);
} else { /* jabber:iq:time */
- date = purple_utf8_strftime("%Z", now);
- xmlnode_insert_data(xmlnode_new_child(query, "tz"), date, -1);
-
- date = purple_utf8_strftime("%d %b %Y %T", now);
- xmlnode_insert_data(xmlnode_new_child(query, "display"), date, -1);
- }
+ tz = purple_utf8_strftime("%Z", now);
+ xmlnode_insert_data(xmlnode_new_child(child, "tz"), tz, -1);
- jabber_iq_send(iq);
- }
-}
+ date = purple_utf8_strftime("%Y%m%dT%T", now);
+ xmlnode_insert_data(utc, date, -1);
-static void urn_xmpp_ping_parse(JabberStream *js, xmlnode *packet)
-{
- const char *type, *id, *from;
- JabberIq *iq;
-
- type = xmlnode_get_attrib(packet, "type");
- from = xmlnode_get_attrib(packet, "from");
- id = xmlnode_get_attrib(packet, "id");
-
- if(type && !strcmp(type, "get")) {
- iq = jabber_iq_new_query(js, JABBER_IQ_RESULT, "urn:xmpp:ping");
-
- jabber_iq_set_id(iq, id);
- xmlnode_set_attrib(iq->node, "to", from);
+ display = purple_utf8_strftime("%d %b %Y %T", now);
+ xmlnode_insert_data(xmlnode_new_child(child, "display"), display, -1);
+ }
jabber_iq_send(iq);
- } else {
- /* XXX: error */
}
}
@@ -309,12 +292,23 @@ void jabber_iq_remove_callback_by_id(JabberStream *js, const char *id)
void jabber_iq_parse(JabberStream *js, xmlnode *packet)
{
JabberCallbackData *jcd;
- xmlnode *query, *error, *x;
+ xmlnode *child, *error, *x;
const char *xmlns;
const char *type, *id, *from;
JabberIqHandler *jih;
- query = xmlnode_get_child(packet, "query");
+ /*
+ * child will be either the first tag child or NULL if there is no child.
+ * Historically, we used just the 'query' subchild, but newer XEPs use
+ * differently named children. Grabbing the first child is (for the time
+ * being) sufficient.
+ */
+ for (child = packet->child; child; child = child->next) {
+ if (child->type != XMLNODE_TYPE_TAG)
+ continue;
+ break;
+ }
+
type = xmlnode_get_attrib(packet, "type");
from = xmlnode_get_attrib(packet, "from");
id = xmlnode_get_attrib(packet, "id");
@@ -353,7 +347,6 @@ void jabber_iq_parse(JabberStream *js, xmlnode *packet)
}
/* First, lets see if a special callback got registered */
-
if(!strcmp(type, "result") || !strcmp(type, "error")) {
if(id && *id && (jcd = g_hash_table_lookup(js->iq_callbacks, id))) {
jcd->callback(js, packet, jcd->data);
@@ -363,36 +356,15 @@ void jabber_iq_parse(JabberStream *js, xmlnode *packet)
}
/* Apparently not, so lets see if we have a pre-defined handler */
-
- if(query && (xmlns = xmlnode_get_namespace(query))) {
+ if(child && (xmlns = xmlnode_get_namespace(child))) {
if((jih = g_hash_table_lookup(iq_handlers, xmlns))) {
jih(js, packet);
return;
}
}
- if(xmlnode_get_child_with_namespace(packet, "si", "http://jabber.org/protocol/si")) {
- jabber_si_parse(js, packet);
- return;
- }
-
- if(xmlnode_get_child_with_namespace(packet, "new-mail", "google:mail:notify")) {
- jabber_gmail_poke(js, packet);
- return;
- }
-
purple_debug_info("jabber", "jabber_iq_parse\n");
- if(xmlnode_get_child_with_namespace(packet, "ping", "urn:xmpp:ping")) {
- jabber_ping_parse(js, packet);
- return;
- }
-
- if (xmlnode_get_child_with_namespace(packet, "data", XEP_0231_NAMESPACE)) {
- jabber_data_parse(js, packet);
- return;
- }
-
/* If we get here, send the default error reply mandated by XMPP-CORE */
if(!strcmp(type, "set") || !strcmp(type, "get")) {
JabberIq *iq = jabber_iq_new(js, JABBER_IQ_ERROR);
@@ -421,17 +393,20 @@ void jabber_iq_init(void)
{
iq_handlers = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
- jabber_iq_register_handler("jabber:iq:roster", jabber_roster_parse);
- jabber_iq_register_handler("jabber:iq:oob", jabber_oob_parse);
+ jabber_iq_register_handler("google:mail:notify", jabber_gmail_poke);
jabber_iq_register_handler("http://jabber.org/protocol/bytestreams", jabber_bytestreams_parse);
- jabber_iq_register_handler("jabber:iq:last", jabber_iq_last_parse);
- jabber_iq_register_handler("jabber:iq:time", jabber_iq_time_parse);
- jabber_iq_register_handler("urn:xmpp:time", jabber_iq_time_parse);
- jabber_iq_register_handler("jabber:iq:version", jabber_iq_version_parse);
jabber_iq_register_handler("http://jabber.org/protocol/disco#info", jabber_disco_info_parse);
jabber_iq_register_handler("http://jabber.org/protocol/disco#items", jabber_disco_items_parse);
+ jabber_iq_register_handler("http://jabber.org/protocol/si", jabber_si_parse);
+ jabber_iq_register_handler("jabber:iq:last", jabber_iq_last_parse);
+ jabber_iq_register_handler("jabber:iq:oob", jabber_oob_parse);
jabber_iq_register_handler("jabber:iq:register", jabber_register_parse);
- jabber_iq_register_handler("urn:xmpp:ping", urn_xmpp_ping_parse);
+ jabber_iq_register_handler("jabber:iq:roster", jabber_roster_parse);
+ jabber_iq_register_handler("jabber:iq:time", jabber_iq_time_parse);
+ jabber_iq_register_handler("jabber:iq:version", jabber_iq_version_parse);
+ jabber_iq_register_handler(XEP_0231_NAMESPACE, jabber_data_parse);
+ jabber_iq_register_handler("urn:xmpp:ping", jabber_ping_parse);
+ jabber_iq_register_handler("urn:xmpp:time", jabber_iq_time_parse);
}
void jabber_iq_uninit(void)
diff --git a/libpurple/protocols/jabber/jabber.c b/libpurple/protocols/jabber/jabber.c
index a105b93a00..7efc96b69e 100644
--- a/libpurple/protocols/jabber/jabber.c
+++ b/libpurple/protocols/jabber/jabber.c
@@ -439,17 +439,11 @@ void jabber_send(JabberStream *js, xmlnode *packet)
g_free(txt);
}
-static void jabber_pong_cb(JabberStream *js, xmlnode *packet, gpointer unused)
-{
- purple_timeout_remove(js->keepalive_timeout);
- js->keepalive_timeout = -1;
-}
-
-static gboolean jabber_pong_timeout(PurpleConnection *gc)
+static gboolean jabber_keepalive_timeout(PurpleConnection *gc)
{
JabberStream *js = gc->proto_data;
purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
- _("Ping timeout"));
+ _("Ping timeout"));
js->keepalive_timeout = -1;
return FALSE;
}
@@ -459,14 +453,9 @@ void jabber_keepalive(PurpleConnection *gc)
JabberStream *js = gc->proto_data;
if (js->keepalive_timeout == -1) {
- JabberIq *iq = jabber_iq_new(js, JABBER_IQ_GET);
-
- xmlnode *ping = xmlnode_new_child(iq->node, "ping");
- xmlnode_set_namespace(ping, "urn:xmpp:ping");
-
- js->keepalive_timeout = purple_timeout_add_seconds(120, (GSourceFunc)(jabber_pong_timeout), gc);
- jabber_iq_set_callback(iq, jabber_pong_cb, NULL);
- jabber_iq_send(iq);
+ jabber_ping_jid(js, NULL);
+ js->keepalive_timeout = purple_timeout_add_seconds(120,
+ (GSourceFunc)(jabber_keepalive_timeout), gc);
}
}
@@ -2421,10 +2410,16 @@ static PurpleCmdRet jabber_cmd_chat_msg(PurpleConversation *conv,
static PurpleCmdRet jabber_cmd_ping(PurpleConversation *conv,
const char *cmd, char **args, char **error, void *data)
{
+ PurpleAccount *account;
+ PurpleConnection *pc;
+
if(!args || !args[0])
return PURPLE_CMD_RET_FAILED;
- if(!jabber_ping_jid(conv, args[0])) {
+ account = purple_conversation_get_account(conv);
+ pc = purple_account_get_connection(account);
+
+ if(!jabber_ping_jid(pc->proto_data, args[0])) {
*error = g_strdup_printf(_("Unable to ping user %s"), args[0]);
return PURPLE_CMD_RET_FAILED;
}
diff --git a/libpurple/protocols/jabber/ping.c b/libpurple/protocols/jabber/ping.c
index 4339c27dd1..5826a6a7ff 100644
--- a/libpurple/protocols/jabber/ping.c
+++ b/libpurple/protocols/jabber/ping.c
@@ -23,34 +23,59 @@
#include "internal.h"
#include "debug.h"
-#include "xmlnode.h"
#include "jabber.h"
#include "ping.h"
#include "iq.h"
+static void jabber_keepalive_pong_cb(JabberStream *js)
+{
+ purple_timeout_remove(js->keepalive_timeout);
+ js->keepalive_timeout = -1;
+}
+
void
jabber_ping_parse(JabberStream *js, xmlnode *packet)
{
- JabberIq *iq;
+ const char *type, *id, *from;
- purple_debug_info("jabber", "jabber_ping_parse\n");
+ type = xmlnode_get_attrib(packet, "type");
+ from = xmlnode_get_attrib(packet, "from");
+ id = xmlnode_get_attrib(packet, "id");
- iq = jabber_iq_new(js, JABBER_IQ_RESULT);
+ if (!type) {
+ purple_debug_warning("jabber", "jabber_ping with no type\n");
+ return;
+ }
+
+ purple_debug_info("jabber", "jabber_ping_parse\n");
- xmlnode_set_attrib(iq->node, "to", xmlnode_get_attrib(packet, "from") );
+ if (!strcmp(type, "get")) {
+ JabberIq *iq = jabber_iq_new(js, JABBER_IQ_RESULT);
- jabber_iq_set_id(iq, xmlnode_get_attrib(packet, "id"));
+ xmlnode_set_attrib(iq->node, "to", from);
+ xmlnode_set_attrib(iq->node, "id", id);
- jabber_iq_send(iq);
+ jabber_iq_send(iq);
+ } else if (!strcmp(type, "set")) {
+ /* XXX: error */
+ }
}
static void jabber_ping_result_cb(JabberStream *js, xmlnode *packet,
- gpointer data)
+ gpointer data)
{
const char *type = xmlnode_get_attrib(packet, "type");
+ const char *from = xmlnode_get_attrib(packet, "from");
purple_debug_info("jabber", "jabber_ping_result_cb\n");
+
+ if (!from || !strcmp(from, js->user->domain)) {
+ /* If the pong is from our server, treat it as a return from the
+ * keepalive functions */
+ jabber_keepalive_pong_cb(js);
+ }
+
if(type && !strcmp(type, "result")) {
purple_debug_info("jabber", "PONG!\n");
} else {
@@ -58,15 +83,16 @@ static void jabber_ping_result_cb(JabberStream *js, xmlnode *packet,
}
}
-gboolean jabber_ping_jid(PurpleConversation *conv, const char *jid)
+gboolean jabber_ping_jid(JabberStream *js, const char *jid)
{
JabberIq *iq;
xmlnode *ping;
purple_debug_info("jabber", "jabber_ping_jid\n");
- iq = jabber_iq_new(conv->account->gc->proto_data, JABBER_IQ_GET);
- xmlnode_set_attrib(iq->node, "to", jid);
+ iq = jabber_iq_new(js, JABBER_IQ_GET);
+ if (jid)
+ xmlnode_set_attrib(iq->node, "to", jid);
ping = xmlnode_new_child(iq->node, "ping");
xmlnode_set_namespace(ping, "urn:xmpp:ping");
@@ -74,7 +100,5 @@ gboolean jabber_ping_jid(PurpleConversation *conv, const char *jid)
jabber_iq_set_callback(iq, jabber_ping_result_cb, NULL);
jabber_iq_send(iq);
-
-
return TRUE;
}
diff --git a/libpurple/protocols/jabber/ping.h b/libpurple/protocols/jabber/ping.h
index 377452f56c..65ebe47e04 100644
--- a/libpurple/protocols/jabber/ping.h
+++ b/libpurple/protocols/jabber/ping.h
@@ -23,13 +23,9 @@
#define _PURPLE_JABBER_PING_H_
#include "jabber.h"
-#include "conversation.h"
-
-void jabber_ping_parse(JabberStream *js,
- xmlnode *packet);
-
-
-gboolean jabber_ping_jid(PurpleConversation *conv, const char *jid);
+#include "xmlnode.h"
+void jabber_ping_parse(JabberStream *js, xmlnode *packet);
+gboolean jabber_ping_jid(JabberStream *js, const char *jid);
#endif /* _PURPLE_JABBER_PING_H_ */