changeset 18259:c5c265dff90c

support replying to XEP-0202 queries
author Nathan Walp <nwalp@pidgin.im>
date Sun, 24 Jun 2007 04:53:36 +0000
parents 70747b33f1bd
children 7992f408a94d dfe4d0a0a00e
files libpurple/protocols/jabber/disco.c libpurple/protocols/jabber/iq.c libpurple/util.c libpurple/util.h
diffstat 4 files changed, 51 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- 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")
--- 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);
--- 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;
--- 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