- Timestamp:
- 2006-11-12T23:06:08Z (18 years ago)
- Branches:
- master
- Children:
- 16b5f86
- Parents:
- 47d3ac4
- Location:
- protocols/jabber
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
protocols/jabber/jabber.c
r47d3ac4 r0d3f30f 217 217 int st; 218 218 219 bud = jabber_buddy_by_jid( gc, who );219 bud = jabber_buddy_by_jid( gc, who, 0 ); 220 220 221 221 node = xt_new_node( "body", message, NULL ); 222 222 node = jabber_make_packet( "message", "chat", bud ? bud->full_jid : who, node ); 223 223 224 if( ( jd->flags & JFLAG_WANT_TYPING ) && bud&&224 if( bud && ( jd->flags & JFLAG_WANT_TYPING ) && 225 225 ( ( bud->flags & JBFLAG_DOES_XEP85 ) || 226 226 !( bud->flags & JBFLAG_PROBED_XEP85 ) ) ) … … 266 266 267 267 if( strchr( who, '/' ) ) 268 bud = jabber_buddy_by_jid( gc, who );268 bud = jabber_buddy_by_jid( gc, who, 0 ); 269 269 else 270 bud = g_hash_table_lookup( jd->buddies, who ); 270 { 271 char *s = jabber_normalize( who ); 272 bud = g_hash_table_lookup( jd->buddies, s ); 273 g_free( s ); 274 } 271 275 272 276 while( bud ) 273 277 { 274 serv_got_crap( gc, "Buddy %s /%s(%d) information:\nAway state: %s\nAway message: %s",275 bud-> handle, bud->resource, bud->priority,278 serv_got_crap( gc, "Buddy %s (%d) information:\nAway state: %s\nAway message: %s", 279 bud->full_jid, bud->priority, 276 280 bud->away_state ? bud->away_state->full_name : "(none)", 277 281 bud->away_message ? : "(none)" ); … … 279 283 } 280 284 281 jabber_get_vcard( gc, bud ? bud-> handle: who );285 jabber_get_vcard( gc, bud ? bud->full_jid : who ); 282 286 } 283 287 … … 329 333 jd->flags |= JFLAG_WANT_TYPING; 330 334 331 if( ( bud = jabber_buddy_by_jid( gc, who ) ) == NULL )335 if( ( bud = jabber_buddy_by_jid( gc, who, 0 ) ) == NULL ) 332 336 { 333 337 /* Sending typing notifications to unknown buddies is -
protocols/jabber/jabber.h
r47d3ac4 r0d3f30f 50 50 JBFLAG_DOES_XEP85 = 2, /* Set this when the resource seems to support 51 51 XEP85 (typing notification shite). */ 52 } jabber_buddy_flag _t;52 } jabber_buddy_flags_t; 53 53 54 54 struct jabber_data … … 93 93 struct jabber_buddy 94 94 { 95 char * handle;95 char *bare_jid; 96 96 char *full_jid; 97 97 char *resource; … … 102 102 103 103 time_t last_act; 104 jabber_buddy_flag _t flags;104 jabber_buddy_flags_t flags; 105 105 106 106 struct jabber_buddy *next; … … 160 160 const struct jabber_away_state *jabber_away_state_by_name( char *name ); 161 161 void jabber_buddy_ask( struct gaim_connection *gc, char *handle ); 162 char *jabber_normalize( char *orig ); 163 164 typedef enum 165 { 166 GET_BUDDY_CREAT = 1, /* Try to create it, if necessary. */ 167 GET_BUDDY_EXACT = 2, /* Get an exact message (only makes sense with bare JIDs). */ 168 } get_buddy_flags_t; 169 162 170 struct jabber_buddy *jabber_buddy_add( struct gaim_connection *gc, char *full_jid ); 163 struct jabber_buddy *jabber_buddy_by_jid( struct gaim_connection *gc, char *jid );171 struct jabber_buddy *jabber_buddy_by_jid( struct gaim_connection *gc, char *jid, get_buddy_flags_t flags ); 164 172 int jabber_buddy_remove( struct gaim_connection *gc, char *full_jid ); 165 173 int jabber_buddy_remove_bare( struct gaim_connection *gc, char *bare_jid ); -
protocols/jabber/jabber_util.c
r47d3ac4 r0d3f30f 251 251 } 252 252 253 /* Returns a new string. Don't leak it! */ 254 char *jabber_normalize( char *orig ) 255 { 256 int len, i; 257 char *new; 258 259 len = strlen( orig ); 260 new = g_new( char, len + 1 ); 261 for( i = 0; i < len; i ++ ) 262 new[i] = tolower( orig[i] ); 263 264 new[i] = 0; 265 return new; 266 } 267 253 268 /* Adds a buddy/resource to our list. Returns NULL if full_jid is not really a 254 FULL jid or if we already have this buddy/resource. */ 255 struct jabber_buddy *jabber_buddy_add( struct gaim_connection *gc, char *full_jid ) 269 FULL jid or if we already have this buddy/resource. XXX: No, great, actually 270 buddies from transports don't (usually) have resources. So we'll really have 271 to deal with that properly. Set their ->resource property to NULL. Do *NOT* 272 allow to mix this stuff, though... */ 273 struct jabber_buddy *jabber_buddy_add( struct gaim_connection *gc, char *full_jid_ ) 256 274 { 257 275 struct jabber_data *jd = gc->proto_data; 258 276 struct jabber_buddy *bud, *new, *bi; 259 char *s; 260 261 if( !( s = strchr( full_jid, '/' ) ) ) 262 return NULL; 277 char *s, *full_jid; 278 279 full_jid = jabber_normalize( full_jid_ ); 280 281 if( ( s = strchr( full_jid, '/' ) ) ) 282 *s = 0; 263 283 264 284 new = g_new0( struct jabber_buddy, 1 ); 265 285 266 *s = 0;267 286 if( ( bud = g_hash_table_lookup( jd->buddies, full_jid ) ) ) 268 287 { 269 new->handle = bud->handle; 288 /* If this is a transport buddy or whatever, it can't have more 289 than one instance, so this is always wrong: */ 290 if( s == NULL || bud->resource == NULL ) 291 { 292 if( s ) *s = '/'; 293 g_free( new ); 294 g_free( full_jid ); 295 return NULL; 296 } 297 298 new->bare_jid = bud->bare_jid; 270 299 271 300 /* We already have another resource for this buddy, add the … … 273 302 for( bi = bud; bi; bi = bi->next ) 274 303 { 275 /* Check for dupes. Resource seem to be case sensitive.*/276 if( strcmp( bi->resource, s + 1 ) == 0 )304 /* Check for dupes. */ 305 if( g_strcasecmp( bi->resource, s + 1 ) == 0 ) 277 306 { 278 307 *s = '/'; 279 308 g_free( new ); 309 g_free( full_jid ); 280 310 return NULL; 281 311 } … … 290 320 else 291 321 { 292 new->handle = g_strdup( full_jid ); 293 g_hash_table_insert( jd->buddies, new->handle, new ); 294 } 295 296 *s = '/'; 297 new->full_jid = g_strdup( full_jid ); 298 new->resource = strchr( new->full_jid, '/' ) + 1; 322 new->bare_jid = g_strdup( full_jid ); 323 g_hash_table_insert( jd->buddies, new->bare_jid, new ); 324 } 325 326 if( s ) 327 { 328 *s = '/'; 329 new->full_jid = full_jid; 330 new->resource = strchr( new->full_jid, '/' ) + 1; 331 } 332 else 333 { 334 /* Let's waste some more bytes of RAM instead of to make 335 memory management a total disaster here.. */ 336 new->full_jid = full_jid; 337 } 299 338 300 339 return new; … … 304 343 asked for a bare JID, it uses the "resource_select" setting to see which 305 344 resource to pick. */ 306 struct jabber_buddy *jabber_buddy_by_jid( struct gaim_connection *gc, char *jid )345 struct jabber_buddy *jabber_buddy_by_jid( struct gaim_connection *gc, char *jid_, get_buddy_flags_t flags ) 307 346 { 308 347 struct jabber_data *jd = gc->proto_data; 309 348 struct jabber_buddy *bud; 310 char *s; 349 char *s, *jid; 350 351 jid = jabber_normalize( jid_ ); 311 352 312 353 if( ( s = strchr( jid, '/' ) ) ) … … 314 355 *s = 0; 315 356 if( ( bud = g_hash_table_lookup( jd->buddies, jid ) ) ) 316 for( ; bud; bud = bud->next ) 317 if( strcmp( bud->resource, s + 1 ) == 0 ) 318 break; 357 { 358 /* Is this one of those no-resource buddies? */ 359 if( bud->resource == NULL ) 360 { 361 bud = NULL; 362 } 363 else 364 { 365 /* See if there's an exact match. */ 366 for( ; bud; bud = bud->next ) 367 if( g_strcasecmp( bud->resource, s + 1 ) == 0 ) 368 break; 369 } 370 } 371 372 *s = '/'; 373 if( bud == NULL && ( flags & GET_BUDDY_CREAT ) ) 374 bud = jabber_buddy_add( gc, jid ); 375 376 g_free( jid ); 377 return bud; 319 378 } 320 379 else … … 323 382 char *set; 324 383 325 best_prio = best_time = bud = g_hash_table_lookup( jd->buddies, jid ); 384 bud = g_hash_table_lookup( jd->buddies, jid ); 385 386 g_free( jid ); 387 388 /* An exact match, or only one option. */ 389 if( bud == NULL ) 390 return ( flags & GET_BUDDY_CREAT ) ? jabber_buddy_add( gc, jid ) : NULL; 391 else if( ( bud->resource == NULL || bud->next == NULL ) ) 392 return bud; 393 394 best_prio = best_time = bud; 326 395 for( ; bud; bud = bud->next ) 327 396 { … … 339 408 return best_prio; 340 409 } 341 342 *s = '/';343 return bud;344 410 } 345 411 346 412 /* Remove one specific full JID from our list. Use this when a buddy goes 347 off-line (because (s)he can still be online from a different location. */ 348 int jabber_buddy_remove( struct gaim_connection *gc, char *full_jid ) 413 off-line (because (s)he can still be online from a different location. 414 XXX: See above, we should accept bare JIDs too... */ 415 int jabber_buddy_remove( struct gaim_connection *gc, char *full_jid_ ) 349 416 { 350 417 struct jabber_data *jd = gc->proto_data; 351 418 struct jabber_buddy *bud, *prev, *bi; 352 char *s; 353 354 if( !( s = strchr( full_jid, '/' ) ) ) 355 return 0; 356 357 *s = 0; 419 char *s, *full_jid; 420 421 full_jid = jabber_normalize( full_jid_ ); 422 423 if( ( s = strchr( full_jid, '/' ) ) ) 424 *s = 0; 425 358 426 if( ( bud = g_hash_table_lookup( jd->buddies, full_jid ) ) ) 359 427 { … … 361 429 matches), removing it is simple. (And the hash reference 362 430 should be removed too!) */ 363 if( bud->next == NULL && strcmp( bud->resource, s + 1 ) == 0)364 { 365 g_hash_table_remove( jd->buddies, bud-> handle);366 g_free( bud-> handle);431 if( bud->next == NULL && ( ( s == NULL || bud->resource == NULL ) || g_strcasecmp( bud->resource, s + 1 ) == 0 ) ) 432 { 433 g_hash_table_remove( jd->buddies, bud->bare_jid ); 434 g_free( bud->bare_jid ); 367 435 g_free( bud->full_jid ); 368 436 g_free( bud->away_message ); 369 437 g_free( bud ); 438 439 g_free( full_jid ); 440 441 return 1; 442 } 443 else if( s == NULL || bud->resource == NULL ) 444 { 445 /* Tried to remove a bare JID while this JID does seem 446 to have resources... (Or the opposite.) *sigh* */ 447 g_free( full_jid ); 448 return 0; 370 449 } 371 450 else 372 451 { 373 452 for( bi = bud, prev = NULL; bi; bi = (prev=bi)->next ) 374 if( strcmp( bi->resource, s + 1 ) == 0 )453 if( g_strcasecmp( bi->resource, s + 1 ) == 0 ) 375 454 break; 455 456 g_free( full_jid ); 376 457 377 458 if( bi ) … … 382 463 /* The hash table should point at the second 383 464 item, because we're removing the first. */ 384 g_hash_table_replace( jd->buddies, bi-> handle, bi->next );465 g_hash_table_replace( jd->buddies, bi->bare_jid, bi->next ); 385 466 386 467 g_free( bi->full_jid ); 387 468 g_free( bi->away_message ); 388 469 g_free( bi ); 470 471 return 1; 389 472 } 390 473 else 391 474 { 392 *s = '/';393 475 return 0; 394 476 } 395 477 } 396 397 *s = '/'; 398 return 1; 399 } 400 else 401 { 402 *s = '/'; 478 } 479 else 480 { 481 g_free( full_jid ); 403 482 return 0; 404 483 } … … 408 487 specified bare JID. Use this when removing someone from the contact 409 488 list, for example. */ 410 int jabber_buddy_remove_bare( struct gaim_connection *gc, char *bare_jid )489 int jabber_buddy_remove_bare( struct gaim_connection *gc, char *bare_jid_ ) 411 490 { 412 491 struct jabber_data *jd = gc->proto_data; 413 492 struct jabber_buddy *bud, *next; 414 415 if( strchr( bare_jid, '/' ) ) 493 char *bare_jid; 494 495 if( strchr( bare_jid_, '/' ) ) 416 496 return 0; 497 498 bare_jid = jabber_normalize( bare_jid_ ); 417 499 418 500 if( ( bud = g_hash_table_lookup( jd->buddies, bare_jid ) ) ) … … 420 502 /* Most important: Remove the hash reference. We don't know 421 503 this buddy anymore. */ 422 g_hash_table_remove( jd->buddies, bud-> handle);504 g_hash_table_remove( jd->buddies, bud->bare_jid ); 423 505 424 506 /* Deallocate the linked list of resources. */ … … 432 514 } 433 515 516 g_free( bare_jid ); 434 517 return 1; 435 518 } 436 519 else 437 520 { 521 g_free( bare_jid ); 438 522 return 0; 439 523 } -
protocols/jabber/message.c
r47d3ac4 r0d3f30f 47 47 if( ( s = strchr( from, '/' ) ) ) 48 48 { 49 if( ( bud = jabber_buddy_by_jid( gc, from ) ) )49 if( ( bud = jabber_buddy_by_jid( gc, from, GET_BUDDY_EXACT ) ) ) 50 50 bud->last_act = time( NULL ); 51 51 else … … 76 76 77 77 if( fullmsg->len > 0 ) 78 serv_got_im( gc, bud ? bud-> handle: from, fullmsg->str, 0, 0, fullmsg->len );78 serv_got_im( gc, bud ? bud->bare_jid : from, fullmsg->str, 0, 0, fullmsg->len ); 79 79 80 80 g_string_free( fullmsg, TRUE ); … … 84 84 { 85 85 bud->flags |= JBFLAG_DOES_XEP85; 86 serv_got_typing( gc, bud ? bud-> handle: from, 0, 1 );86 serv_got_typing( gc, bud ? bud->bare_jid : from, 0, 1 ); 87 87 } 88 88 /* No need to send a "stopped typing" signal when there's a message. */ … … 90 90 { 91 91 bud->flags |= JBFLAG_DOES_XEP85; 92 serv_got_typing( gc, bud ? bud-> handle: from, 0, 0 );92 serv_got_typing( gc, bud ? bud->bare_jid : from, 0, 0 ); 93 93 } 94 94 else if( xt_find_node( node->children, "paused" ) ) 95 95 { 96 96 bud->flags |= JBFLAG_DOES_XEP85; 97 serv_got_typing( gc, bud ? bud-> handle: from, 0, 2 );97 serv_got_typing( gc, bud ? bud->bare_jid : from, 0, 2 ); 98 98 } 99 99 -
protocols/jabber/presence.c
r47d3ac4 r0d3f30f 38 38 if( type == NULL ) 39 39 { 40 if( ( s = strchr( from, '/' ) ) == NULL)40 if( !( bud = jabber_buddy_by_jid( gc, from, GET_BUDDY_EXACT | GET_BUDDY_CREAT ) ) ) 41 41 { 42 char *s = xt_to_string( node ); 43 serv_got_crap( gc, "WARNING: Ignoring presence tag with bare JID: %s", s ); 44 g_free( s ); 42 serv_got_crap( gc, "WARNING: Could not handle presence information from JID: %s", from ); 45 43 return XT_HANDLED; 46 }47 48 if( !( bud = jabber_buddy_by_jid( gc, from ) ) )49 {50 /* FOR NOW, s still contains the location of the /.51 Keep this in mind when changing things here. :-) */52 53 /* We check if the buddy is in the contact list,54 because Jabber servers seem to like to send55 presence information of buddies we removed56 from our list sometimes, for example... */57 58 *s = 0;59 if( find_buddy( gc, from ) == NULL )60 {61 *s = '/';62 serv_got_crap( gc, "WARNING: Ignoring presence information from unknown JID: %s", from );63 return XT_HANDLED;64 }65 *s = '/';66 67 bud = jabber_buddy_add( gc, from );68 44 } 69 45 … … 89 65 bud->priority = 0; 90 66 91 serv_got_update( gc, bud-> handle, 1, 0, 0, 0,67 serv_got_update( gc, bud->bare_jid, 1, 0, 0, 0, 92 68 bud->away_state ? UC_UNAVAILABLE : 0, 0 ); 93 69 } 94 70 else if( strcmp( type, "unavailable" ) == 0 ) 95 71 { 96 char *s; 97 98 if( ( s = strchr( from, '/' ) ) == NULL ) 99 { 100 char *s = xt_to_string( node ); 101 serv_got_crap( gc, "WARNING: Ignoring presence tag with bare JID: %s\n", s ); 102 g_free( s ); 103 return XT_HANDLED; 104 } 105 106 if( jabber_buddy_by_jid( gc, from ) == NULL ) 72 if( jabber_buddy_by_jid( gc, from, GET_BUDDY_EXACT ) == NULL ) 107 73 { 108 74 serv_got_crap( gc, "WARNING: Received presence information from unknown JID: %s", from ); … … 111 77 112 78 jabber_buddy_remove( gc, from ); 113 *s = 0;114 79 115 /* Only count this as offline if there's no other resource 116 available anymore. */ 117 if( jabber_buddy_by_jid( gc, from ) == NULL ) 80 if( ( s = strchr( from, '/' ) ) ) 81 { 82 *s = 0; 83 84 /* Only count this as offline if there's no other resource 85 available anymore. */ 86 if( jabber_buddy_by_jid( gc, from, 0 ) == NULL ) 87 serv_got_update( gc, from, 0, 0, 0, 0, 0, 0 ); 88 89 *s = '/'; 90 } 91 else 92 { 118 93 serv_got_update( gc, from, 0, 0, 0, 0, 0, 0 ); 119 120 *s = '/'; 94 } 121 95 } 122 96 else if( strcmp( type, "subscribe" ) == 0 ) … … 126 100 else if( strcmp( type, "subscribed" ) == 0 ) 127 101 { 102 /* Not sure about this one, actually... */ 128 103 serv_got_crap( gc, "%s just accepted your authorization request", from ); 129 104 }
Note: See TracChangeset
for help on using the changeset viewer.