# HG changeset patch # User Nathan Walp # Date 1182660816 0 # Node ID c5c265dff90cc5014b81c3263f3f3dc7858991fe # Parent 70747b33f1bd9643c9594cc15b6207bb8aca549e support replying to XEP-0202 queries diff -r 70747b33f1bd -r c5c265dff90c libpurple/protocols/jabber/disco.c --- a/libpurple/protocols/jabber/disco.c Sun Jun 24 04:51:41 2007 +0000 +++ b/libpurple/protocols/jabber/disco.c Sun Jun 24 04:53:36 2007 +0000 @@ -83,6 +83,7 @@ SUPPORT_FEATURE("jabber:iq:last") SUPPORT_FEATURE("jabber:iq:oob") SUPPORT_FEATURE("jabber:iq:time") + SUPPORT_FEATURE("xmpp:urn:time") SUPPORT_FEATURE("jabber:iq:version") SUPPORT_FEATURE("jabber:x:conference") SUPPORT_FEATURE("http://jabber.org/protocol/bytestreams") diff -r 70747b33f1bd -r c5c265dff90c libpurple/protocols/jabber/iq.c --- a/libpurple/protocols/jabber/iq.c Sun Jun 24 04:51:41 2007 +0000 +++ b/libpurple/protocols/jabber/iq.c Sun Jun 24 04:53:36 2007 +0000 @@ -169,7 +169,7 @@ static void jabber_iq_time_parse(JabberStream *js, xmlnode *packet) { - const char *type, *from, *id; + const char *type, *from, *id, *xmlns; JabberIq *iq; xmlnode *query; time_t now_t; @@ -182,27 +182,40 @@ 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(type && !strcmp(type, "get")) { + xmlnode *utc; const char *date; - iq = jabber_iq_new_query(js, JABBER_IQ_RESULT, "jabber:iq:time"); + iq = jabber_iq_new_query(js, JABBER_IQ_RESULT, xmlns); 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); - xmlnode_insert_data(xmlnode_new_child(query, "utc"), date, -1); + utc = xmlnode_new_child(query, "utc"); + xmlnode_insert_data(utc, date, -1); + + if(!strcmp("urn:xmpp:time", xmlns)) { + xmlnode_insert_data(utc, "Z", 1); /* of COURSE the thing that is the same is different */ - date = purple_utf8_strftime("%Z", now); - xmlnode_insert_data(xmlnode_new_child(query, "tz"), date, -1); + date = purple_get_tzoff_str(now, TRUE); + xmlnode_insert_data(xmlnode_new_child(query, "tzo"), 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); + date = purple_utf8_strftime("%d %b %Y %T", now); + xmlnode_insert_data(xmlnode_new_child(query, "display"), date, -1); + } jabber_iq_send(iq); - } else { - /* XXX: error */ } } @@ -347,6 +360,7 @@ 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); diff -r 70747b33f1bd -r c5c265dff90c libpurple/util.c --- a/libpurple/util.c Sun Jun 24 04:51:41 2007 +0000 +++ b/libpurple/util.c Sun Jun 24 04:53:36 2007 +0000 @@ -531,10 +531,9 @@ } #endif -#ifndef HAVE_STRFTIME_Z_FORMAT -static const char *get_tmoff(const struct tm *tm) +const char *purple_get_tzoff_str(const struct tm *tm, gboolean iso) { - static char buf[6]; + static char buf[7]; long off; gint8 min; gint8 hrs; @@ -554,7 +553,7 @@ # else # ifdef HAVE_TIMEZONE tzset(); - off = -timezone; + off = -1 * timezone; # endif /* HAVE_TIMEZONE */ # endif /* !HAVE_TM_GMTOFF */ #endif /* _WIN32 */ @@ -562,12 +561,22 @@ min = (off / 60) % 60; hrs = ((off / 60) - min) / 60; - if (g_snprintf(buf, sizeof(buf), "%+03d%02d", hrs, ABS(min)) > 5) - g_return_val_if_reached(""); + if(iso) { + if (0 == off) { + strcpy(buf, "Z"); + } else { + /* please leave the colons...they're optional for iso, but jabber + * wants them */ + if(g_snprintf(buf, sizeof(buf), "%+03d:%02d", hrs, ABS(min)) > 6) + g_return_val_if_reached(""); + } + } else { + if (g_snprintf(buf, sizeof(buf), "%+03d%02d", hrs, ABS(min)) > 5) + g_return_val_if_reached(""); + } return buf; } -#endif /* Windows doesn't HAVE_STRFTIME_Z_FORMAT, but this seems clearer. -- rlaager */ #if !defined(HAVE_STRFTIME_Z_FORMAT) || defined(_WIN32) @@ -600,7 +609,7 @@ fmt ? fmt : "", c - start - 1, start, - get_tmoff(tm)); + purple_get_tzoff_str(tm, FALSE)); g_free(fmt); fmt = tmp; start = c + 1; diff -r 70747b33f1bd -r c5c265dff90c libpurple/util.h --- a/libpurple/util.h Sun Jun 24 04:51:41 2007 +0000 +++ b/libpurple/util.h Sun Jun 24 04:53:36 2007 +0000 @@ -257,6 +257,16 @@ const char *purple_utf8_strftime(const char *format, const struct tm *tm); /** + * Gets a string representation of the local timezone offset + * + * @param tm The time to get the timezone for + * @param iso TRUE to format the offset according to ISO-8601, FALSE to + * not substitute 'Z' for 0 offset, and to not separate + * hours and minutes with a colon. + */ +const char *purple_get_tzoff_str(const struct tm *tm, gboolean iso); + +/** * Formats a time into the user's preferred short date format. * * The returned string is stored in a static buffer, so the result