Changeset 1ba7e8f for protocols/jabber
- Timestamp:
- 2008-02-15T17:38:57Z (17 years ago)
- Branches:
- master
- Children:
- 506e61b
- Parents:
- 0fbd3a6d (diff), eeb85a8 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- protocols/jabber
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
protocols/jabber/conference.c
r0fbd3a6d r1ba7e8f 37 37 xt_add_attr( node, "xmlns", XMLNS_MUC ); 38 38 node = jabber_make_packet( "presence", NULL, roomjid, node ); 39 if( password ) 40 xt_add_child( node, xt_new_node( "password", password, NULL ) ); 39 41 jabber_cache_add( ic, node, jabber_chat_join_failed ); 40 42 … … 73 75 74 76 room = xt_find_attr( orig, "to" ); 75 if( ( bud = jabber_buddy_by_jid( ic, room, 0 ) ) ) 76 jabber_chat_free( jabber_chat_by_jid( ic, bud->bare_jid ) ); 77 77 bud = jabber_buddy_by_jid( ic, room, 0 ); 78 78 err = jabber_error_parse( xt_find_node( node->children, "error" ), XMLNS_STANZA_ERROR ); 79 79 if( err ) 80 80 { 81 imcb_error( ic, "Error joining groupchat %s: %s%s%s", 82 bud->bare_jid, err->code, err->text ? ": " : "", 83 err->text ? err->text : "" ); 81 imcb_error( ic, "Error joining groupchat %s: %s%s%s", room, err->code, 82 err->text ? ": " : "", err->text ? err->text : "" ); 84 83 jabber_error_free( err ); 85 84 } 85 if( bud ) 86 jabber_chat_free( jabber_chat_by_jid( ic, bud->bare_jid ) ); 86 87 87 88 return XT_HANDLED; … … 123 124 struct jabber_chat *jc = c->data; 124 125 struct xt_node *node; 126 127 jc->flags |= JCFLAG_MESSAGE_SENT; 125 128 126 129 node = xt_new_node( "body", message, NULL ); … … 296 299 struct xt_node *subject = xt_find_node( node->children, "subject" ); 297 300 struct xt_node *body = xt_find_node( node->children, "body" ); 298 struct groupchat *chat; 301 struct groupchat *chat = bud ? jabber_chat_by_jid( ic, bud->bare_jid ) : NULL; 302 struct jabber_chat *jc = chat ? chat->data : NULL; 299 303 char *s; 300 304 301 if( bud == NULL ) 302 { 305 if( bud == NULL || ( jc && ~jc->flags & JCFLAG_MESSAGE_SENT && bud == jc->me ) ) 306 { 307 char *nick; 308 309 if( body == NULL || body->text_len == 0 ) 310 /* Meh. Empty messages aren't very interesting, no matter 311 how much some servers love to send them. */ 312 return; 313 303 314 s = xt_find_attr( node, "from" ); /* pkt_message() already NULL-checked this one. */ 304 if( strchr( s, '/' ) == NULL ) 315 nick = strchr( s, '/' ); 316 if( nick ) 317 { 318 /* If this message included a resource/nick we don't know, 319 we might still know the groupchat itself. */ 320 *nick = 0; 321 chat = jabber_chat_by_jid( ic, s ); 322 *nick = '/'; 323 324 nick ++; 325 } 326 else 327 { 328 /* message.c uses the EXACT_JID option, so bud should 329 always be NULL here for bare JIDs. */ 330 chat = jabber_chat_by_jid( ic, s ); 331 } 332 333 if( nick == NULL ) 334 { 305 335 /* This is fine, the groupchat itself isn't in jd->buddies. */ 306 imcb_log( ic, "System message from groupchat %s: %s", s, body? body->text : "NULL" ); 336 if( chat ) 337 imcb_chat_log( chat, "From conference server: %s", body->text ); 338 else 339 imcb_log( ic, "System message from unknown groupchat %s: %s", s, body->text ); 340 } 307 341 else 308 /* This, however, isn't fine! */ 309 imcb_log( ic, "Groupchat message from unknown participant %s: %s", s, body ? body->text : "NULL" ); 342 { 343 /* This can happen too, at least when receiving a backlog when 344 just joining a channel. */ 345 if( chat ) 346 imcb_chat_log( chat, "Message from unknown participant %s: %s", nick, body->text ); 347 else 348 imcb_log( ic, "Groupchat message from unknown JID %s: %s", s, body->text ); 349 } 310 350 311 351 return; 312 352 } 313 else if( ( chat = jabber_chat_by_jid( ic, bud->bare_jid ) )== NULL )353 else if( chat == NULL ) 314 354 { 315 355 /* How could this happen?? We could do kill( self, 11 ) -
protocols/jabber/io.c
r0fbd3a6d r1ba7e8f 249 249 struct im_connection *ic = data; 250 250 251 if( g_slist_find( jabber_connections, ic ) == NULL ) 252 return FALSE; 253 251 254 if( source == -1 ) 252 255 { … … 264 267 { 265 268 struct im_connection *ic = data; 266 struct jabber_data *jd = ic->proto_data; 269 struct jabber_data *jd; 270 271 if( g_slist_find( jabber_connections, ic ) == NULL ) 272 return FALSE; 273 274 jd = ic->proto_data; 267 275 268 276 if( source == NULL ) -
protocols/jabber/iq.c
r0fbd3a6d r1ba7e8f 54 54 !( s = xt_find_attr( c, "xmlns" ) ) ) 55 55 { 56 imcb_log( ic, "W ARNING: Received incomplete IQ-%s packet", type );56 imcb_log( ic, "Warning: Received incomplete IQ-%s packet", type ); 57 57 return XT_HANDLED; 58 58 } … … 92 92 else if( strcmp( s, XMLNS_DISCO_INFO ) == 0 ) 93 93 { 94 const char *features[] = { XMLNS_VERSION, 94 const char *features[] = { XMLNS_DISCO_INFO, 95 XMLNS_VERSION, 95 96 XMLNS_TIME, 96 97 XMLNS_CHATSTATES, … … 132 133 !( s = xt_find_attr( c, "xmlns" ) ) ) 133 134 { 134 imcb_log( ic, "W ARNING: Received incomplete IQ-%s packet", type );135 imcb_log( ic, "Warning: Received incomplete IQ-%s packet", type ); 135 136 return XT_HANDLED; 136 137 } else if( strcmp( s, XMLNS_ROSTER ) == 0 ) … … 152 153 else 153 154 { 154 imcb_log( ic, "W ARNING: %s tried to fake a roster push!", s ? s : "(unknown)" );155 imcb_log( ic, "Warning: %s tried to fake a roster push!", s ? s : "(unknown)" ); 155 156 156 157 xt_free_node( reply ); … … 220 221 if( !( query = xt_find_node( node->children, "query" ) ) ) 221 222 { 222 imcb_log( ic, "W ARNING: Received incomplete IQ packet while authenticating" );223 imcb_log( ic, "Warning: Received incomplete IQ packet while authenticating" ); 223 224 imc_logout( ic, FALSE ); 224 225 return XT_HANDLED; … … 278 279 if( !( type = xt_find_attr( node, "type" ) ) ) 279 280 { 280 imcb_log( ic, "W ARNING: Received incomplete IQ packet while authenticating" );281 imcb_log( ic, "Warning: Received incomplete IQ packet while authenticating" ); 281 282 imc_logout( ic, FALSE ); 282 283 return XT_HANDLED; … … 354 355 if( !( query = xt_find_node( node->children, "query" ) ) ) 355 356 { 356 imcb_log( ic, "W ARNING: Received NULL roster packet" );357 imcb_log( ic, "Warning: Received NULL roster packet" ); 357 358 return XT_HANDLED; 358 359 } -
protocols/jabber/jabber.c
r0fbd3a6d r1ba7e8f 35 35 #include "base64.h" 36 36 37 GSList *jabber_connections; 38 37 39 static void jabber_init( account_t *acc ) 38 40 { … … 70 72 struct ns_srv_reply *srv = NULL; 71 73 char *connect_to, *s; 74 75 /* For now this is needed in the _connected() handlers if using 76 GLib event handling, to make sure we're not handling events 77 on dead connections. */ 78 jabber_connections = g_slist_prepend( jabber_connections, ic ); 72 79 73 80 jd->ic = ic; … … 197 204 imcb_error( ic, "Could not connect to server" ); 198 205 imc_logout( ic, TRUE ); 206 207 return; 199 208 } 200 209 … … 261 270 g_free( jd->username ); 262 271 g_free( jd ); 272 273 jabber_connections = g_slist_remove( jabber_connections, ic ); 263 274 } 264 275 -
protocols/jabber/jabber.h
r0fbd3a6d r1ba7e8f 29 29 #include "xmltree.h" 30 30 #include "bitlbee.h" 31 32 extern GSList *jabber_connections; 31 33 32 34 typedef enum … … 47 49 typedef enum 48 50 { 49 JBFLAG_PROBED_XEP85 = 1, 51 JBFLAG_PROBED_XEP85 = 1, /* Set this when we sent our probe packet to make 50 52 sure it gets sent only once. */ 51 JBFLAG_DOES_XEP85 = 2, 53 JBFLAG_DOES_XEP85 = 2, /* Set this when the resource seems to support 52 54 XEP85 (typing notification shite). */ 53 JBFLAG_IS_CHATROOM = 4, 55 JBFLAG_IS_CHATROOM = 4, /* It's convenient to use this JID thingy for 54 56 groupchat state info too. */ 55 JBFLAG_IS_ANONYMOUS = 8, 57 JBFLAG_IS_ANONYMOUS = 8, /* For anonymous chatrooms, when we don't have 56 58 have a real JID. */ 57 59 } jabber_buddy_flags_t; … … 64 66 char port[6]; 65 67 } jabber_streamhost_t; 68 69 typedef enum 70 { 71 JCFLAG_MESSAGE_SENT = 1, /* Set this after sending the first message, so 72 we can detect echoes/backlogs. */ 73 } jabber_chat_flags_t; 66 74 67 75 struct jabber_data … … 105 113 struct jabber_cache_entry 106 114 { 115 time_t saved_at; 107 116 struct xt_node *node; 108 117 jabber_cache_event func; … … 175 184 #define JABBER_PACKET_ID "BeeP" 176 185 #define JABBER_CACHED_ID "BeeC" 186 187 /* The number of seconds to keep cached packets before garbage collecting 188 them. This gc is done on every keepalive (every minute). */ 189 #define JABBER_CACHE_MAX_AGE 600 177 190 178 191 /* RFC 392[01] stuff */ … … 198 211 #define XMLNS_MUC "http://jabber.org/protocol/muc" /* XEP-0045 */ 199 212 #define XMLNS_MUC_USER "http://jabber.org/protocol/muc#user" /* XEP-0045 */ 213 #define XMLNS_CAPS "http://jabber.org/protocol/caps" /* XEP-0115 */ 200 214 #define XMLNS_FEATURE "http://jabber.org/protocol/feature-neg" /* XEP-0020 */ 201 215 #define XMLNS_SI "http://jabber.org/protocol/si" /* XEP-0095 */ -
protocols/jabber/jabber_util.c
r0fbd3a6d r1ba7e8f 146 146 entry->node = node; 147 147 entry->func = func; 148 entry->saved_at = time( NULL ); 148 149 g_hash_table_insert( jd->node_cache, xt_find_attr( node, "id" ), entry ); 149 150 } … … 167 168 { 168 169 struct jabber_data *jd = ic->proto_data; 169 170 g_hash_table_foreach_remove( jd->node_cache, jabber_cache_clean_entry, NULL ); 171 } 172 173 gboolean jabber_cache_clean_entry( gpointer key, gpointer entry_, gpointer nullpointer ) 170 time_t threshold = time( NULL ) - JABBER_CACHE_MAX_AGE; 171 172 g_hash_table_foreach_remove( jd->node_cache, jabber_cache_clean_entry, &threshold ); 173 } 174 175 gboolean jabber_cache_clean_entry( gpointer key, gpointer entry_, gpointer threshold_ ) 174 176 { 175 177 struct jabber_cache_entry *entry = entry_; 176 struct xt_node *node = entry->node; 177 178 if( node->flags & XT_SEEN ) 179 return TRUE; 180 else 181 { 182 node->flags |= XT_SEEN; 183 return FALSE; 184 } 178 time_t *threshold = threshold_; 179 180 return entry->saved_at < *threshold; 185 181 } 186 182 … … 204 200 if( entry == NULL ) 205 201 { 206 imcb_log( ic, "W ARNING: Received %s-%s packet with unknown/expired ID %s!",202 imcb_log( ic, "Warning: Received %s-%s packet with unknown/expired ID %s!", 207 203 node->name, xt_find_attr( node, "type" ) ? : "(no type)", s ); 208 204 } … … 403 399 if( ( bud = g_hash_table_lookup( jd->buddies, jid ) ) ) 404 400 { 401 /* Just return the first one for this bare JID. */ 402 if( flags & GET_BUDDY_FIRST ) 403 { 404 *s = '/'; 405 g_free( jid ); 406 return bud; 407 } 408 405 409 /* Is this one of those no-resource buddies? */ 406 410 if( bud->resource == NULL ) 407 411 { 412 *s = '/'; 408 413 g_free( jid ); 409 414 return NULL; 410 415 } 411 else 412 { 413 /* See if there's an exact match. */ 414 for( ; bud; bud = bud->next ) 415 if( g_strcasecmp( bud->resource, s + 1 ) == 0 ) 416 break; 417 } 416 417 /* See if there's an exact match. */ 418 for( ; bud; bud = bud->next ) 419 if( g_strcasecmp( bud->resource, s + 1 ) == 0 ) 420 break; 418 421 } 419 422 else … … 424 427 is done to handle conferences properly. */ 425 428 none_found = 1; 429 /* TODO(wilmer): Find out what I was thinking when I 430 wrote this??? And then fix it. This makes me sad... */ 426 431 } 427 432 … … 453 458 else if( ( bud->resource == NULL || bud->next == NULL ) ) 454 459 /* No need for selection if there's only one option. */ 460 return bud; 461 else if( flags & GET_BUDDY_FIRST ) 462 /* Looks like the caller doesn't care about details. */ 455 463 return bud; 456 464 -
protocols/jabber/presence.c
r0fbd3a6d r1ba7e8f 29 29 char *from = xt_find_attr( node, "from" ); 30 30 char *type = xt_find_attr( node, "type" ); /* NULL should mean the person is online. */ 31 struct xt_node *c ;32 struct jabber_buddy *bud ;33 int is_chat = 0 , is_away = 0;31 struct xt_node *c, *cap; 32 struct jabber_buddy *bud, *send_presence = NULL; 33 int is_chat = 0; 34 34 char *s; 35 35 … … 50 50 { 51 51 if( set_getbool( &ic->irc->set, "debug" ) ) 52 imcb_log( ic, "W ARNING: Could not handle presence information from JID: %s", from );52 imcb_log( ic, "Warning: Could not handle presence information from JID: %s", from ); 53 53 return XT_HANDLED; 54 54 } … … 63 63 { 64 64 bud->away_state = (void*) jabber_away_state_by_code( c->text ); 65 if( strcmp( c->text, "chat" ) != 0 )66 is_away = OPT_AWAY;67 65 } 68 66 else … … 79 77 bud->priority = 0; 80 78 79 if( bud && ( cap = xt_find_node( node->children, "c" ) ) && 80 ( s = xt_find_attr( cap, "xmlns" ) ) && strcmp( s, XMLNS_CAPS ) == 0 ) 81 { 82 /* This <presence> stanza includes an XEP-0115 83 capabilities part. Not too interesting, but we can 84 see if it has an ext= attribute. */ 85 s = xt_find_attr( cap, "ext" ); 86 if( s && ( strstr( s, "cstates" ) || strstr( s, "chatstate" ) ) ) 87 bud->flags |= JBFLAG_DOES_XEP85; 88 89 /* This field can contain more information like xhtml 90 support, but we don't support that ourselves. 91 Officially the ext= tag was deprecated, but enough 92 clients do send it. 93 94 (I'm aware that this is not the right way to use 95 this field.) See for an explanation of ext=: 96 http://www.xmpp.org/extensions/attic/xep-0115-1.3.html*/ 97 } 98 81 99 if( is_chat ) 82 100 jabber_chat_pkt_presence( ic, bud, node ); 83 else if( bud == jabber_buddy_by_jid( ic, bud->bare_jid, 0 ) ) 84 imcb_buddy_status( ic, bud->bare_jid, OPT_LOGGED_IN | is_away, 85 ( is_away && bud->away_state ) ? bud->away_state->full_name : NULL, 86 bud->away_message ); 101 else 102 send_presence = jabber_buddy_by_jid( ic, bud->bare_jid, 0 ); 87 103 } 88 104 else if( strcmp( type, "unavailable" ) == 0 ) … … 91 107 { 92 108 if( set_getbool( &ic->irc->set, "debug" ) ) 93 imcb_log( ic, "W ARNING: Received presence information from unknown JID: %s", from );109 imcb_log( ic, "Warning: Received presence information from unknown JID: %s", from ); 94 110 return XT_HANDLED; 95 111 } … … 119 135 /* If another resource is still available, send its presence 120 136 information. */ 121 if( ( bud = jabber_buddy_by_jid( ic, from, 0 ) ) ) 122 { 123 if( bud->away_state && ( *bud->away_state->code == 0 || 124 strcmp( bud->away_state->code, "chat" ) == 0 ) ) 125 is_away = OPT_AWAY; 126 127 imcb_buddy_status( ic, bud->bare_jid, OPT_LOGGED_IN | is_away, 128 ( is_away && bud->away_state ) ? bud->away_state->full_name : NULL, 129 bud->away_message ); 130 } 131 else 137 if( ( send_presence = jabber_buddy_by_jid( ic, from, 0 ) ) == NULL ) 132 138 { 133 139 /* Otherwise, count him/her as offline now. */ … … 177 183 } */ 178 184 } 185 186 if( send_presence ) 187 { 188 int is_away = 0; 189 190 if( send_presence->away_state && !( *send_presence->away_state->code == 0 || 191 strcmp( send_presence->away_state->code, "chat" ) == 0 ) ) 192 is_away = OPT_AWAY; 193 194 imcb_buddy_status( ic, send_presence->bare_jid, OPT_LOGGED_IN | is_away, 195 ( is_away && send_presence->away_state ) ? 196 send_presence->away_state->full_name : NULL, 197 send_presence->away_message ); 198 } 179 199 180 200 return XT_HANDLED; … … 186 206 { 187 207 struct jabber_data *jd = ic->proto_data; 188 struct xt_node *node ;208 struct xt_node *node, *cap; 189 209 char *show = jd->away_state->code; 190 210 char *status = jd->away_message; … … 199 219 xt_add_child( node, xt_new_node( "status", status, NULL ) ); 200 220 221 /* This makes the packet slightly bigger, but clients interested in 222 capabilities can now cache the discovery info. This reduces the 223 usual post-login iq-flood. See XEP-0115. At least libpurple and 224 Trillian seem to do this right. */ 225 cap = xt_new_node( "c", NULL, NULL ); 226 xt_add_attr( cap, "xmlns", XMLNS_CAPS ); 227 xt_add_attr( cap, "node", "http://bitlbee.org/xmpp/caps" ); 228 xt_add_attr( cap, "ver", BITLBEE_VERSION ); /* The XEP wants this hashed, but nobody's doing that. */ 229 xt_add_child( node, cap ); 230 201 231 st = jabber_write_packet( ic, node ); 202 232
Note: See TracChangeset
for help on using the changeset viewer.