diff options
author | Wilmer van der Gaast <wilmer@gaast.net> | 2006-10-01 11:31:41 +0200 |
---|---|---|
committer | Wilmer van der Gaast <wilmer@gaast.net> | 2006-10-01 11:31:41 +0200 |
commit | 6baca2a2910d0b6663b54ef302820d9ffbbf5eee (patch) | |
tree | cf0d5c1b95f5401d7e3d2a3eae136c4d242bb74f /protocols/jabber/iq.c | |
parent | 022df46b52683f49a1a48e15a440d1f6b81adfdd (diff) |
Some initial hooks/stuff for privacy lists, and fixed a crash bug on
connecting to Google Talk.
Diffstat (limited to 'protocols/jabber/iq.c')
-rw-r--r-- | protocols/jabber/iq.c | 119 |
1 files changed, 114 insertions, 5 deletions
diff --git a/protocols/jabber/iq.c b/protocols/jabber/iq.c index a7783fcb..0411d4ad 100644 --- a/protocols/jabber/iq.c +++ b/protocols/jabber/iq.c @@ -27,7 +27,7 @@ xt_status jabber_pkt_iq( struct xt_node *node, gpointer data ) { struct gaim_connection *gc = data; struct jabber_data *jd = gc->proto_data; - struct xt_node *query, *reply = NULL, *orig = NULL; + struct xt_node *query, *reply = NULL, *orig = NULL, *c; char *s, *type, *xmlns; int st; @@ -108,10 +108,45 @@ xt_status jabber_pkt_iq( struct xt_node *node, gpointer data ) account_online( gc ); } + if( strcmp( type, "result" ) == 0 && xmlns && strcmp( xmlns, "jabber:iq:privacy" ) == 0 ) + { + struct xt_node *node; + + /* When receiving a list of lists: */ + if( ( node = xt_find_node( query->children, "active" ) ) ) + { + if( ( s = xt_find_attr( node, "name" ) ) ) + { + set_t *set; + + g_free( jd->privacy_active ); + jd->privacy_active = g_strdup( s ); + + /* Save it so the user can see it. */ + if( ( set = set_find( &gc->acc->set, "privacy_list" ) ) ) + { + g_free( set->value ); + set->value = g_strdup( s ); + } + + if( !jabber_get_privacy( gc ) ) + return XT_ABORT; + } + } + /* When receiving an actual list: */ + else if( ( node = xt_find_node( query->children, "list" ) ) ) + { + xt_free_node( jd->privacy_list ); + jd->privacy_list = xt_dup( node ); + } + else if( query->children == NULL ) + { + /* What to do here if there is no privacy list defined yet... */ + } + } else if( strcmp( type, "result" ) == 0 && orig ) { struct xt_node *c; - if( !( jd->flags & JFLAG_AUTHENTICATED ) && ( c = xt_find_node( orig->children, "query" ) ) && ( c = xt_find_node( c->children, "username" ) ) && @@ -120,7 +155,7 @@ xt_status jabber_pkt_iq( struct xt_node *node, gpointer data ) /* This happens when we just successfully authenticated the old (non-SASL) way. */ jd->flags |= JFLAG_AUTHENTICATED; - if( !jabber_get_roster( gc ) ) + if( !jabber_get_roster( gc ) || !jabber_get_privacy( gc ) ) return XT_ABORT; } /* Tricky: Look for <bind> in the reply, because the server @@ -144,19 +179,39 @@ xt_status jabber_pkt_iq( struct xt_node *node, gpointer data ) if( ( jd->flags & ( JFLAG_WAIT_BIND | JFLAG_WAIT_SESSION ) ) == 0 ) { - if( !jabber_get_roster( gc ) ) + if( !jabber_get_roster( gc ) || !jabber_get_privacy( gc ) ) return XT_ABORT; } } + else if( ( c = xt_find_node( orig->children, "query" ) ) && + ( c = xt_find_node( c->children, "active" ) ) ) + { + /* We just successfully activated a (different) + privacy list. Fetch it now. */ + g_free( jd->privacy_active ); + jd->privacy_active = g_strdup( xt_find_attr( c, "name" ) ); + + if( !jabber_get_privacy( gc ) ) + return XT_ABORT; + } } else if( strcmp( type, "error" ) == 0 ) { - if( !( jd->flags & JFLAG_AUTHENTICATED ) ) + if( !( jd->flags & JFLAG_AUTHENTICATED ) && + ( c = xt_find_node( orig->children, "query" ) ) && + ( c = xt_find_node( c->children, "username" ) ) && + c->text_len ) { hide_login_progress( gc, "Authentication failure" ); signoff( gc ); return XT_ABORT; } + else if( orig && + ( c = xt_find_node( orig->children, "query" ) ) && + ( c = xt_find_node( c->children, "active" ) ) ) + { + serv_got_crap( gc, "Error while activating privacy list, maybe it doesn't exist" ); + } } return XT_HANDLED; @@ -237,3 +292,57 @@ int jabber_remove_from_roster( struct gaim_connection *gc, char *handle ) xt_free_node( node ); return st; } + +/* Request the privacy list from the server. We need this, because every + time we remove/add something we have to send the whole new list to the + server again... If no privacy list is specified yet, this function will + first ask for the list of lists (XMPP supports multiple "privacy lists", + don't ask me why), later we can then fetch the list we want to use. */ +int jabber_get_privacy( struct gaim_connection *gc ) +{ + struct jabber_data *jd = gc->proto_data; + struct xt_node *node = NULL; + char *name; + int st; + + if( jd->privacy_active ) + { + /* If we know what is the active list right now, fetch it. */ + node = xt_new_node( "list", NULL, NULL ); + xt_add_attr( node, "name", jd->privacy_active ); + } + /* Okay, we don't know yet. If the user set a specific list, we'll + activate that one. Otherwise, we should figure out which list is + currently active. */ + else if( ( name = set_getstr( &gc->acc->set, "privacy_list" ) ) ) + { + return jabber_set_privacy( gc, name ); + } + /* else: sending this packet without a <list/> element will give + a list of available lists and information about the currently + active list. */ + + node = xt_new_node( "query", NULL, node ); + xt_add_attr( node, "xmlns", "jabber:iq:privacy" ); + node = jabber_make_packet( "iq", "get", NULL, node ); + + st = jabber_write_packet( gc, node ); + + xt_free_node( node ); + return st; +} + +int jabber_set_privacy( struct gaim_connection *gc, char *name ) +{ + struct xt_node *node; + + node = xt_new_node( "active", NULL, NULL ); + xt_add_attr( node, "name", name ); + node = xt_new_node( "query", NULL, node ); + xt_add_attr( node, "xmlns", "jabber:iq:privacy" ); + + node = jabber_make_packet( "iq", "set", NULL, node ); + jabber_cache_packet( gc, node ); + + return jabber_write_packet( gc, node ); +} |