aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/xmltree.c15
-rw-r--r--lib/xmltree.h1
-rw-r--r--protocols/jabber/jabber.h3
-rw-r--r--protocols/jabber/jabber_util.c30
4 files changed, 38 insertions, 11 deletions
diff --git a/lib/xmltree.c b/lib/xmltree.c
index 0726d387..9d84fb7c 100644
--- a/lib/xmltree.c
+++ b/lib/xmltree.c
@@ -523,6 +523,21 @@ char *xt_find_attr( struct xt_node *node, const char *key )
return node->attr[i].value;
}
+struct xt_node *xt_find_node_by_attr( struct xt_node *xt, const char *tag, const char *key, const char *value ) {
+ struct xt_node *c;
+ char *s;
+
+ for( c = xt; ( c = xt_find_node( c, tag ) ); c = c->next )
+ {
+ if( ( s = xt_find_attr( c, key ) ) && strcmp( s, value ) == 0 )
+ {
+ return c;
+ }
+ }
+ return NULL;
+}
+
+
/* Strip a few non-printable characters that aren't allowed in XML streams
(and upset some XMPP servers for example). */
void xt_strip_text( char *in )
diff --git a/lib/xmltree.h b/lib/xmltree.h
index a41cbac1..aaf49cea 100644
--- a/lib/xmltree.h
+++ b/lib/xmltree.h
@@ -91,6 +91,7 @@ void xt_free( struct xt_parser *xt );
struct xt_node *xt_find_node( struct xt_node *node, const char *name );
struct xt_node *xt_find_path( struct xt_node *node, const char *name );
char *xt_find_attr( struct xt_node *node, const char *key );
+struct xt_node *xt_find_node_by_attr( struct xt_node *xt, const char *tag, const char *key, const char *value );
struct xt_node *xt_new_node( char *name, const char *text, struct xt_node *children );
void xt_add_child( struct xt_node *parent, struct xt_node *child );
diff --git a/protocols/jabber/jabber.h b/protocols/jabber/jabber.h
index e6aa3ba3..eb99f9ca 100644
--- a/protocols/jabber/jabber.h
+++ b/protocols/jabber/jabber.h
@@ -228,7 +228,8 @@ struct jabber_transfer
#define XMLNS_PING "urn:xmpp:ping" /* XEP-0199 */
#define XMLNS_RECEIPTS "urn:xmpp:receipts" /* XEP-0184 */
#define XMLNS_VCARD "vcard-temp" /* XEP-0054 */
-#define XMLNS_DELAY "jabber:x:delay" /* XEP-0091 */
+#define XMLNS_DELAY_OLD "jabber:x:delay" /* XEP-0091 */
+#define XMLNS_DELAY "urn:xmpp:delay" /* XEP-0203 */
#define XMLNS_XDATA "jabber:x:data" /* XEP-0004 */
#define XMLNS_CHATSTATES "http://jabber.org/protocol/chatstates" /* XEP-0085 */
#define XMLNS_DISCO_INFO "http://jabber.org/protocol/disco#info" /* XEP-0030 */
diff --git a/protocols/jabber/jabber_util.c b/protocols/jabber/jabber_util.c
index 0fcc8338..fb68c33d 100644
--- a/protocols/jabber/jabber_util.c
+++ b/protocols/jabber/jabber_util.c
@@ -725,19 +725,29 @@ time_t jabber_get_timestamp( struct xt_node *xt )
struct xt_node *c;
char *s = NULL;
struct tm tp;
-
- for( c = xt->children; ( c = xt_find_node( c, "x" ) ); c = c->next )
- {
- if( ( s = xt_find_attr( c, "xmlns" ) ) && strcmp( s, XMLNS_DELAY ) == 0 )
- break;
+ gboolean is_old = TRUE;
+ const char *format;
+
+ /* XEP-0091 has <x> */
+ c = xt_find_node_by_attr( xt->children, "x", "xmlns", XMLNS_DELAY_OLD );
+
+ if( !c || !( s = xt_find_attr( c, "stamp" ) ) ) {
+ is_old = FALSE;
+
+ /* XEP-0203 has <delay> */
+ c = xt_find_node_by_attr( xt->children, "delay", "xmlns", XMLNS_DELAY );
+ if( !c || !( s = xt_find_attr( c, "stamp" ) ) ) {
+ return 0;
+ }
}
- if( !c || !( s = xt_find_attr( c, "stamp" ) ) )
- return 0;
-
memset( &tp, 0, sizeof( tp ) );
- if( sscanf( s, "%4d%2d%2dT%2d:%2d:%2d", &tp.tm_year, &tp.tm_mon, &tp.tm_mday,
- &tp.tm_hour, &tp.tm_min, &tp.tm_sec ) != 6 )
+
+ /* The other main difference between XEPs is the timestamp format */
+ format = (is_old) ? "%4d%2d%2dT%2d:%2d:%2d" : "%4d-%2d-%2dT%2d:%2d:%2dZ";
+
+ if( sscanf( s, format, &tp.tm_year, &tp.tm_mon, &tp.tm_mday,
+ &tp.tm_hour, &tp.tm_min, &tp.tm_sec ) != 6 )
return 0;
tp.tm_year -= 1900;