From f774e01cdb34e339455671f51413ecdc6de3208d Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Wed, 30 Jan 2008 23:05:52 +0000 Subject: Fixed handling of OSCAR multi-part messages... They're not arrays, they're linked lists! --- protocols/oscar/oscar.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'protocols') diff --git a/protocols/oscar/oscar.c b/protocols/oscar/oscar.c index 30ad4b68..9e5de70a 100644 --- a/protocols/oscar/oscar.c +++ b/protocols/oscar/oscar.c @@ -1065,12 +1065,14 @@ static int incomingim_chan1(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_ } else if (args->mpmsg.numparts == 0) { g_snprintf(tmp, BUF_LONG, "%s", args->msg); } else { - int i; + aim_mpmsg_section_t *part; *tmp = 0; - for (i = 0; i < args->mpmsg.numparts; i ++) { - g_strlcat(tmp, (char*) args->mpmsg.parts[i].data, BUF_LONG); - g_strlcat(tmp, "\n", BUF_LONG); + for (part = args->mpmsg.parts; part; part = part->next) { + if (part->data) { + g_strlcat(tmp, (char*) part->data, BUF_LONG); + g_strlcat(tmp, "\n", BUF_LONG); + } } } -- cgit v1.2.3 From 979cfb448cc233e29ceb6cd43f99fb4104728be6 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 3 Feb 2008 13:54:19 +0000 Subject: Saner garbage collection of cached packets in the Jabber module. Now cached packets are removed after about ten minues instead of something between one and two minutes. Closes one issue in #354. --- protocols/jabber/jabber.h | 5 +++++ protocols/jabber/jabber_util.c | 16 ++++++---------- 2 files changed, 11 insertions(+), 10 deletions(-) (limited to 'protocols') diff --git a/protocols/jabber/jabber.h b/protocols/jabber/jabber.h index cf0f8e6a..5132d45f 100644 --- a/protocols/jabber/jabber.h +++ b/protocols/jabber/jabber.h @@ -94,6 +94,7 @@ typedef xt_status (*jabber_cache_event) ( struct im_connection *ic, struct xt_no struct jabber_cache_entry { + time_t saved_at; struct xt_node *node; jabber_cache_event func; }; @@ -140,6 +141,10 @@ struct jabber_chat #define JABBER_PACKET_ID "BeeP" #define JABBER_CACHED_ID "BeeC" +/* The number of seconds to keep cached packets before garbage collecting + them. This gc is done on every keepalive (every minute). */ +#define JABBER_CACHE_MAX_AGE 600 + /* RFC 392[01] stuff */ #define XMLNS_TLS "urn:ietf:params:xml:ns:xmpp-tls" #define XMLNS_SASL "urn:ietf:params:xml:ns:xmpp-sasl" diff --git a/protocols/jabber/jabber_util.c b/protocols/jabber/jabber_util.c index 794a1040..6e872040 100644 --- a/protocols/jabber/jabber_util.c +++ b/protocols/jabber/jabber_util.c @@ -141,6 +141,7 @@ void jabber_cache_add( struct im_connection *ic, struct xt_node *node, jabber_ca entry->node = node; entry->func = func; + entry->saved_at = time( NULL ); g_hash_table_insert( jd->node_cache, xt_find_attr( node, "id" ), entry ); } @@ -162,22 +163,17 @@ gboolean jabber_cache_clean_entry( gpointer key, gpointer entry, gpointer nullpo void jabber_cache_clean( struct im_connection *ic ) { struct jabber_data *jd = ic->proto_data; + time_t threshold = time( NULL ) - JABBER_CACHE_MAX_AGE; - g_hash_table_foreach_remove( jd->node_cache, jabber_cache_clean_entry, NULL ); + g_hash_table_foreach_remove( jd->node_cache, jabber_cache_clean_entry, &threshold ); } -gboolean jabber_cache_clean_entry( gpointer key, gpointer entry_, gpointer nullpointer ) +gboolean jabber_cache_clean_entry( gpointer key, gpointer entry_, gpointer threshold_ ) { struct jabber_cache_entry *entry = entry_; - struct xt_node *node = entry->node; + time_t *threshold = threshold_; - if( node->flags & XT_SEEN ) - return TRUE; - else - { - node->flags |= XT_SEEN; - return FALSE; - } + return entry->saved_at < *threshold; } xt_status jabber_cache_handle_packet( struct im_connection *ic, struct xt_node *node ) -- cgit v1.2.3 From 8c1eb8025f493ce22b4cc58da1ecfd4afa416816 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 3 Feb 2008 16:59:39 +0000 Subject: Implemented XEP-0115. This adds some info to the tags so clients interested in capabilities can cache discovery info, so they don't have to ask about it every time you/they log in. --- protocols/jabber/iq.c | 3 ++- protocols/jabber/jabber.h | 1 + protocols/jabber/presence.c | 34 ++++++++++++++++++++++++++++++++-- 3 files changed, 35 insertions(+), 3 deletions(-) (limited to 'protocols') diff --git a/protocols/jabber/iq.c b/protocols/jabber/iq.c index e1bab29e..c88bc0b0 100644 --- a/protocols/jabber/iq.c +++ b/protocols/jabber/iq.c @@ -91,7 +91,8 @@ xt_status jabber_pkt_iq( struct xt_node *node, gpointer data ) } else if( strcmp( s, XMLNS_DISCOVER ) == 0 ) { - const char *features[] = { XMLNS_VERSION, + const char *features[] = { XMLNS_DISCOVER, + XMLNS_VERSION, XMLNS_TIME, XMLNS_CHATSTATES, XMLNS_MUC, diff --git a/protocols/jabber/jabber.h b/protocols/jabber/jabber.h index 5132d45f..44655409 100644 --- a/protocols/jabber/jabber.h +++ b/protocols/jabber/jabber.h @@ -165,6 +165,7 @@ struct jabber_chat #define XMLNS_DISCOVER "http://jabber.org/protocol/disco#info" /* 0030 */ #define XMLNS_MUC "http://jabber.org/protocol/muc" /* XEP-0045 */ #define XMLNS_MUC_USER "http://jabber.org/protocol/muc#user"/* XEP-0045 */ +#define XMLNS_CAPS "http://jabber.org/protocol/caps" /* XEP-0115 */ /* iq.c */ xt_status jabber_pkt_iq( struct xt_node *node, gpointer data ); diff --git a/protocols/jabber/presence.c b/protocols/jabber/presence.c index 2c49b800..6fc360b7 100644 --- a/protocols/jabber/presence.c +++ b/protocols/jabber/presence.c @@ -28,7 +28,7 @@ xt_status jabber_pkt_presence( struct xt_node *node, gpointer data ) struct im_connection *ic = data; char *from = xt_find_attr( node, "from" ); char *type = xt_find_attr( node, "type" ); /* NULL should mean the person is online. */ - struct xt_node *c; + struct xt_node *c, *cap; struct jabber_buddy *bud, *send_presence = NULL; int is_chat = 0; char *s; @@ -76,6 +76,26 @@ xt_status jabber_pkt_presence( struct xt_node *node, gpointer data ) else bud->priority = 0; + if( bud && ( cap = xt_find_node( node->children, "c" ) ) && + ( s = xt_find_attr( cap, "xmlns" ) ) && strcmp( s, XMLNS_CAPS ) == 0 ) + { + /* This stanza includes an XEP-0115 + capabilities part. Not too interesting, but we can + see if it has an ext= attribute. */ + s = xt_find_attr( cap, "ext" ); + if( s && ( strstr( s, "cstates" ) || strstr( s, "chatstate" ) ) ) + bud->flags |= JBFLAG_DOES_XEP85; + + /* This field can contain more information like xhtml + support, but we don't support that ourselves. + Officially the ext= tag was deprecated, but enough + clients do send it. + + (I'm aware that this is not the right way to use + this field.) See for an explanation of ext=: + http://www.xmpp.org/extensions/attic/xep-0115-1.3.html*/ + } + if( is_chat ) jabber_chat_pkt_presence( ic, bud, node ); else @@ -185,7 +205,7 @@ xt_status jabber_pkt_presence( struct xt_node *node, gpointer data ) int presence_send_update( struct im_connection *ic ) { struct jabber_data *jd = ic->proto_data; - struct xt_node *node; + struct xt_node *node, *cap; char *show = jd->away_state->code; char *status = jd->away_message; struct groupchat *c; @@ -198,6 +218,16 @@ int presence_send_update( struct im_connection *ic ) if( status ) xt_add_child( node, xt_new_node( "status", status, NULL ) ); + /* This makes the packet slightly bigger, but clients interested in + capabilities can now cache the discovery info. This reduces the + usual post-login iq-flood. See XEP-0115. At least libpurple and + Trillian seem to do this right. */ + cap = xt_new_node( "c", NULL, NULL ); + xt_add_attr( cap, "xmlns", XMLNS_CAPS ); + xt_add_attr( cap, "node", "http://bitlbee.org/xmpp/caps" ); + xt_add_attr( cap, "ver", BITLBEE_VERSION ); /* The XEP wants this hashed, but nobody's doing that. */ + xt_add_child( node, cap ); + st = jabber_write_packet( ic, node ); /* Have to send this update to all groupchats too, the server won't -- cgit v1.2.3 From 8ff0a61e7389db201ff4534f267225af6f66736b Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 3 Feb 2008 17:11:15 +0000 Subject: Disabling "Unknown command" warnings since they're very noisy and pretty pointless. --- protocols/msn/ns.c | 2 +- protocols/msn/sb.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'protocols') diff --git a/protocols/msn/ns.c b/protocols/msn/ns.c index 3735aad6..0bb84a74 100644 --- a/protocols/msn/ns.c +++ b/protocols/msn/ns.c @@ -583,7 +583,7 @@ static int msn_ns_command( gpointer data, char **cmd, int num_parts ) } else { - debug( "Received unknown command from main server: %s", cmd[0] ); + /* debug( "Received unknown command from main server: %s", cmd[0] ); */ } return( 1 ); diff --git a/protocols/msn/sb.c b/protocols/msn/sb.c index cdf2e8ad..18c41ef5 100644 --- a/protocols/msn/sb.c +++ b/protocols/msn/sb.c @@ -593,7 +593,7 @@ static int msn_sb_command( gpointer data, char **cmd, int num_parts ) } else { - debug( "Received unknown command from switchboard server: %s", cmd[0] ); + /* debug( "Received unknown command from switchboard server: %s", cmd[0] ); */ } return( 1 ); -- cgit v1.2.3 From 63075d7345355dde6e490ad00a886a1b165dbe17 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 3 Feb 2008 23:33:18 +0000 Subject: Messages from the user are also included in backlogs when joining a Jabber chatroom. Until now they were ignored, which might make backlogs a little bit confusing. --- protocols/jabber/conference.c | 9 ++++++--- protocols/jabber/jabber.h | 14 ++++++++++---- 2 files changed, 16 insertions(+), 7 deletions(-) (limited to 'protocols') diff --git a/protocols/jabber/conference.c b/protocols/jabber/conference.c index 515194fc..f206e084 100644 --- a/protocols/jabber/conference.c +++ b/protocols/jabber/conference.c @@ -122,6 +122,8 @@ int jabber_chat_msg( struct groupchat *c, char *message, int flags ) struct jabber_chat *jc = c->data; struct xt_node *node; + jc->flags |= JCFLAG_MESSAGE_SENT; + node = xt_new_node( "body", message, NULL ); node = jabber_make_packet( "message", "groupchat", jc->name, node ); @@ -294,10 +296,11 @@ void jabber_chat_pkt_message( struct im_connection *ic, struct jabber_buddy *bud { struct xt_node *subject = xt_find_node( node->children, "subject" ); struct xt_node *body = xt_find_node( node->children, "body" ); - struct groupchat *chat = NULL; + struct groupchat *chat = bud ? jabber_chat_by_jid( ic, bud->bare_jid ) : NULL; + struct jabber_chat *jc = chat ? chat->data : NULL; char *s; - if( bud == NULL ) + if( bud == NULL || ( jc && ~jc->flags & JCFLAG_MESSAGE_SENT && bud == jc->me ) ) { char *nick; @@ -345,7 +348,7 @@ void jabber_chat_pkt_message( struct im_connection *ic, struct jabber_buddy *bud return; } - else if( ( chat = jabber_chat_by_jid( ic, bud->bare_jid ) ) == NULL ) + else if( chat == NULL ) { /* How could this happen?? We could do kill( self, 11 ) now or just wait for the OS to do it. :-) */ diff --git a/protocols/jabber/jabber.h b/protocols/jabber/jabber.h index 44655409..1ff0e8dd 100644 --- a/protocols/jabber/jabber.h +++ b/protocols/jabber/jabber.h @@ -48,16 +48,22 @@ typedef enum typedef enum { - JBFLAG_PROBED_XEP85 = 1, /* Set this when we sent our probe packet to make + JBFLAG_PROBED_XEP85 = 1, /* Set this when we sent our probe packet to make sure it gets sent only once. */ - JBFLAG_DOES_XEP85 = 2, /* Set this when the resource seems to support + JBFLAG_DOES_XEP85 = 2, /* Set this when the resource seems to support XEP85 (typing notification shite). */ - JBFLAG_IS_CHATROOM = 4, /* It's convenient to use this JID thingy for + JBFLAG_IS_CHATROOM = 4, /* It's convenient to use this JID thingy for groupchat state info too. */ - JBFLAG_IS_ANONYMOUS = 8, /* For anonymous chatrooms, when we don't have + JBFLAG_IS_ANONYMOUS = 8, /* For anonymous chatrooms, when we don't have have a real JID. */ } jabber_buddy_flags_t; +typedef enum +{ + JCFLAG_MESSAGE_SENT = 1, /* Set this after sending the first message, so + we can detect echoes/backlogs. */ +} jabber_chat_flags_t; + struct jabber_data { struct im_connection *ic; -- cgit v1.2.3 From 3038e476a93b2be057581b831749eac931a06559 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 10 Feb 2008 17:11:06 +0000 Subject: Added support for password-protected Jabber chatrooms. --- protocols/jabber/conference.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'protocols') diff --git a/protocols/jabber/conference.c b/protocols/jabber/conference.c index f206e084..79fdd053 100644 --- a/protocols/jabber/conference.c +++ b/protocols/jabber/conference.c @@ -36,6 +36,8 @@ struct groupchat *jabber_chat_join( struct im_connection *ic, char *room, char * node = xt_new_node( "x", NULL, NULL ); xt_add_attr( node, "xmlns", XMLNS_MUC ); node = jabber_make_packet( "presence", NULL, roomjid, node ); + if( password ) + xt_add_child( node, xt_new_node( "password", password, NULL ) ); jabber_cache_add( ic, node, jabber_chat_join_failed ); if( !jabber_write_packet( ic, node ) ) -- cgit v1.2.3 From af97b234ad86fb9d69aa744af426591e4b1eaf97 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sat, 16 Feb 2008 13:17:52 +0000 Subject: Improved sasl_get_part() to deal with whitespace in challenge strings, as described in RFC 2831 secion 7.1 (the #rule description). Closes bug #362. --- protocols/jabber/sasl.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) (limited to 'protocols') diff --git a/protocols/jabber/sasl.c b/protocols/jabber/sasl.c index 87059051..53248ef3 100644 --- a/protocols/jabber/sasl.c +++ b/protocols/jabber/sasl.c @@ -21,6 +21,8 @@ * * \***************************************************************************/ +#include + #include "jabber.h" #include "base64.h" @@ -106,12 +108,17 @@ xt_status sasl_pkt_mechanisms( struct xt_node *node, gpointer data ) return XT_HANDLED; } -static char *sasl_get_part( char *data, char *field ) +/* Non-static function, but not mentioned in jabber.h because it's for internal + use, just that the unittest should be able to reach it... */ +char *sasl_get_part( char *data, char *field ) { int i, len; len = strlen( field ); + while( isspace( *data ) || *data == ',' ) + data ++; + if( g_strncasecmp( data, field, len ) == 0 && data[len] == '=' ) { i = strlen( field ) + 1; @@ -128,13 +135,19 @@ static char *sasl_get_part( char *data, char *field ) i ++; } - /* If we got a comma, we got a new field. Check it. */ - if( data[i] == ',' && - g_strncasecmp( data + i + 1, field, len ) == 0 && - data[i+len+1] == '=' ) + /* If we got a comma, we got a new field. Check it, + find the next key after it. */ + if( data[i] == ',' ) { - i += len + 2; - break; + while( isspace( data[i] ) || data[i] == ',' ) + i ++; + + if( g_strncasecmp( data + i, field, len ) == 0 && + data[i+len] == '=' ) + { + i += len + 1; + break; + } } } } -- cgit v1.2.3 From fc5cf88448d4337d1a5fde418df1c6206a9b0ea2 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 16 Feb 2008 16:45:12 +0100 Subject: Fix lcov dependencies. --- protocols/Makefile | 2 +- protocols/jabber/Makefile | 2 +- protocols/msn/Makefile | 2 +- protocols/oscar/Makefile | 2 +- protocols/yahoo/Makefile | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) (limited to 'protocols') diff --git a/protocols/Makefile b/protocols/Makefile index f7d76e0f..18d79e8d 100644 --- a/protocols/Makefile +++ b/protocols/Makefile @@ -26,7 +26,7 @@ LFLAGS += -r # [SH] Phony targets all: protocols.o check: all -lcov: +lcov: check gcov: gcov *.c diff --git a/protocols/jabber/Makefile b/protocols/jabber/Makefile index e042f812..3ce78127 100644 --- a/protocols/jabber/Makefile +++ b/protocols/jabber/Makefile @@ -17,7 +17,7 @@ LFLAGS += -r # [SH] Phony targets all: jabber_mod.o check: all -lcov: +lcov: check gcov: gcov *.c diff --git a/protocols/msn/Makefile b/protocols/msn/Makefile index 3440658d..6a588613 100644 --- a/protocols/msn/Makefile +++ b/protocols/msn/Makefile @@ -17,7 +17,7 @@ LFLAGS += -r # [SH] Phony targets all: msn_mod.o check: all -lcov: +lcov: check gcov: gcov *.c diff --git a/protocols/oscar/Makefile b/protocols/oscar/Makefile index 95e85ec2..2792f22a 100644 --- a/protocols/oscar/Makefile +++ b/protocols/oscar/Makefile @@ -17,7 +17,7 @@ LFLAGS += -r # [SH] Phony targets all: oscar_mod.o check: all -lcov: +lcov: check gcov: gcov *.c diff --git a/protocols/yahoo/Makefile b/protocols/yahoo/Makefile index 2cfd147b..b4fe56e2 100644 --- a/protocols/yahoo/Makefile +++ b/protocols/yahoo/Makefile @@ -17,7 +17,7 @@ LFLAGS += -r # [SH] Phony targets all: yahoo_mod.o check: all -lcov: +lcov: check gcov: gcov *.c -- cgit v1.2.3