aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilmer van der Gaast <wilmer@gaast.net>2007-07-30 20:12:06 +0100
committerWilmer van der Gaast <wilmer@gaast.net>2007-07-30 20:12:06 +0100
commit1baaef858136cd3a4799b3ccf1d9961534e0017c (patch)
treed2292c3ede3b6813229cda8fa32b989f25e66da4
parent85023c65b697d2dab932acbda31258ae5270dbe6 (diff)
Added jabber_error_parse() and using it for both stream- and stanza
(only presence so far) errors.
-rw-r--r--protocols/jabber/io.c31
-rw-r--r--protocols/jabber/jabber.h7
-rw-r--r--protocols/jabber/jabber_util.c35
-rw-r--r--protocols/jabber/presence.c12
4 files changed, 61 insertions, 24 deletions
diff --git a/protocols/jabber/io.c b/protocols/jabber/io.c
index edde5a8d..cf71ff87 100644
--- a/protocols/jabber/io.c
+++ b/protocols/jabber/io.c
@@ -435,50 +435,35 @@ static xt_status jabber_pkt_proceed_tls( struct xt_node *node, gpointer data )
static xt_status jabber_pkt_stream_error( struct xt_node *node, gpointer data )
{
struct im_connection *ic = data;
- struct xt_node *c;
- char *s, *type = NULL, *text = NULL;
int allow_reconnect = TRUE;
+ struct jabber_error *err;
- for( c = node->children; c; c = c->next )
- {
- if( !( s = xt_find_attr( c, "xmlns" ) ) ||
- strcmp( s, XMLNS_STREAM_ERROR ) != 0 )
- continue;
-
- if( strcmp( c->name, "text" ) != 0 )
- {
- type = c->name;
- }
- /* Only use the text if it doesn't have an xml:lang attribute,
- if it's empty or if it's set to something English. */
- else if( !( s = xt_find_attr( c, "xml:lang" ) ) ||
- !*s || strncmp( s, "en", 2 ) == 0 )
- {
- text = c->text;
- }
- }
+ err = jabber_error_parse( node, XMLNS_STREAM_ERROR );
/* Tssk... */
- if( type == NULL )
+ if( err->code == NULL )
{
imcb_error( ic, "Unknown stream error reported by server" );
imc_logout( ic, allow_reconnect );
+ jabber_error_free( err );
return XT_ABORT;
}
/* We know that this is a fatal error. If it's a "conflict" error, we
should turn off auto-reconnect to make sure we won't get some nasty
infinite loop! */
- if( strcmp( type, "conflict" ) == 0 )
+ if( strcmp( err->code, "conflict" ) == 0 )
{
imcb_error( ic, "Account and resource used from a different location" );
allow_reconnect = FALSE;
}
else
{
- imcb_error( ic, "Stream error: %s%s%s", type, text ? ": " : "", text ? text : "" );
+ imcb_error( ic, "Stream error: %s%s%s", err->code, err->text ? ": " : "",
+ err->text ? err->text : "" );
}
+ jabber_error_free( err );
imc_logout( ic, allow_reconnect );
return XT_ABORT;
diff --git a/protocols/jabber/jabber.h b/protocols/jabber/jabber.h
index 90c1e9f6..7af7f98e 100644
--- a/protocols/jabber/jabber.h
+++ b/protocols/jabber/jabber.h
@@ -193,6 +193,11 @@ typedef enum
GET_BUDDY_FIRST = 4, /* No selection, simply get the first resource for this JID. */
} get_buddy_flags_t;
+struct jabber_error
+{
+ char *code, *text, *type;
+};
+
struct jabber_buddy *jabber_buddy_add( struct im_connection *ic, char *full_jid );
struct jabber_buddy *jabber_buddy_by_jid( struct im_connection *ic, char *jid, get_buddy_flags_t flags );
struct jabber_buddy *jabber_buddy_by_ext_jid( struct im_connection *ic, char *jid, get_buddy_flags_t flags );
@@ -200,6 +205,8 @@ int jabber_buddy_remove( struct im_connection *ic, char *full_jid );
int jabber_buddy_remove_bare( struct im_connection *ic, char *bare_jid );
struct groupchat *jabber_chat_by_name( struct im_connection *ic, const char *name );
time_t jabber_get_timestamp( struct xt_node *xt );
+struct jabber_error *jabber_error_parse( struct xt_node *node, char *xmlns );
+void jabber_error_free( struct jabber_error *err );
extern const struct jabber_away_state jabber_away_state_list[];
diff --git a/protocols/jabber/jabber_util.c b/protocols/jabber/jabber_util.c
index 5b91c5ed..56491c4f 100644
--- a/protocols/jabber/jabber_util.c
+++ b/protocols/jabber/jabber_util.c
@@ -647,3 +647,38 @@ time_t jabber_get_timestamp( struct xt_node *xt )
return res;
}
+
+struct jabber_error *jabber_error_parse( struct xt_node *node, char *xmlns )
+{
+ struct jabber_error *err = g_new0( struct jabber_error, 1 );
+ struct xt_node *c;
+ char *s;
+
+ err->type = xt_find_attr( node, "type" );
+
+ for( c = node->children; c; c = c->next )
+ {
+ if( !( s = xt_find_attr( c, "xmlns" ) ) ||
+ strcmp( s, xmlns ) != 0 )
+ continue;
+
+ if( strcmp( c->name, "text" ) != 0 )
+ {
+ err->code = c->name;
+ }
+ /* Only use the text if it doesn't have an xml:lang attribute,
+ if it's empty or if it's set to something English. */
+ else if( !( s = xt_find_attr( c, "xml:lang" ) ) ||
+ !*s || strncmp( s, "en", 2 ) == 0 )
+ {
+ err->text = c->text;
+ }
+ }
+
+ return err;
+}
+
+void jabber_error_free( struct jabber_error *err )
+{
+ g_free( err );
+}
diff --git a/protocols/jabber/presence.c b/protocols/jabber/presence.c
index e53978ea..cbfcedae 100644
--- a/protocols/jabber/presence.c
+++ b/protocols/jabber/presence.c
@@ -157,7 +157,17 @@ xt_status jabber_pkt_presence( struct xt_node *node, gpointer data )
}
else if( strcmp( type, "error" ) == 0 )
{
- /* What to do with it? */
+ struct jabber_error *err;
+
+ if( ( c = xt_find_node( node->children, "error" ) ) )
+ {
+ err = jabber_error_parse( c, XMLNS_STANZA_ERROR );
+ imcb_error( ic, "Stanza (%s) error: %s%s%s", node->name,
+ err->code, err->text ? ": " : "",
+ err->text ? err->text : "" );
+ jabber_error_free( err );
+ }
+ /* What else to do with it? */
}
else
{