Changes in / [19a8088:e900442]
- Files:
-
- 1 added
- 23 edited
Legend:
- Unmodified
- Added
- Removed
-
bitlbee.c
r19a8088 re900442 70 70 #ifdef IPV6 71 71 memset( &listen_addr6, 0, sizeof( listen_addr6 ) ); 72 memset( &listen_addr, 0, sizeof( listen_addr ) ); 72 73 listen_addr6.sin6_family = AF_INET6; 73 74 listen_addr6.sin6_port = htons( global.conf->port ); … … 77 78 use_ipv6 = 0; 78 79 #endif 79 memset( &listen_addr, 0, sizeof( listen_addr ) );80 80 listen_addr.sin_family = AF_INET; 81 81 listen_addr.sin_port = htons( global.conf->port ); … … 125 125 exit( 0 ); 126 126 127 chdir( "/" );127 // chdir( "/" ); 128 128 129 129 /* Sometimes std* are already closed (for example when we're in a RESTARTed -
irc.c
r19a8088 re900442 658 658 } 659 659 } 660 else if( ( c = chat_by_channel(channel ) ) )660 else if( ( c = irc_chat_by_channel( irc, channel ) ) ) 661 661 { 662 662 GList *l; … … 811 811 else 812 812 { 813 struct groupchat *c = chat_by_channel(channel );813 struct groupchat *c = irc_chat_by_channel( irc, channel ); 814 814 815 815 if( c ) … … 949 949 if( *nick == '#' || *nick == '&' ) 950 950 { 951 if( !( c = chat_by_channel(nick ) ) )951 if( !( c = irc_chat_by_channel( irc, nick ) ) ) 952 952 { 953 953 irc_reply( irc, 403, "%s :Channel does not exist", nick ); … … 1215 1215 return TRUE; 1216 1216 } 1217 1218 struct groupchat *irc_chat_by_channel( irc_t *irc, char *channel ) 1219 { 1220 struct groupchat *c; 1221 account_t *a; 1222 1223 /* This finds the connection which has a conversation which belongs to this channel */ 1224 for( a = irc->accounts; a; a = a->next ) 1225 { 1226 if( a->ic == NULL ) 1227 continue; 1228 1229 c = a->ic->groupchats; 1230 while( c ) 1231 { 1232 if( c->channel && g_strcasecmp( c->channel, channel ) == 0 ) 1233 return c; 1234 1235 c = c->next; 1236 } 1237 } 1238 1239 return NULL; 1240 } -
irc.h
r19a8088 re900442 140 140 141 141 void buddy_send_handler( irc_t *irc, user_t *u, char *msg, int flags ); 142 struct groupchat *irc_chat_by_channel( irc_t *irc, char *channel ); 142 143 143 144 #endif -
irc_commands.c
r19a8088 re900442 144 144 irc_join( irc, u, irc->channel ); 145 145 } 146 else if( ( c = chat_by_channel(cmd[1] ) ) )146 else if( ( c = irc_chat_by_channel( irc, cmd[1] ) ) ) 147 147 { 148 148 user_t *u = user_find( irc, irc->nick ); … … 201 201 { 202 202 char *nick = cmd[1], *channel = cmd[2]; 203 struct groupchat *c = chat_by_channel(channel );203 struct groupchat *c = irc_chat_by_channel( irc, channel ); 204 204 user_t *u = user_find( irc, nick ); 205 205 … … 287 287 u = u->next; 288 288 } 289 else if( ( c = chat_by_channel(channel ) ) )289 else if( ( c = irc_chat_by_channel( irc, channel ) ) ) 290 290 for( l = c->in_room; l; l = l->next ) 291 291 { -
nick.c
r19a8088 re900442 57 57 static char nick[MAX_NICK_LENGTH+1]; 58 58 char *store_handle, *found_nick; 59 int inf_protection = 256;60 59 61 60 memset( nick, 0, MAX_NICK_LENGTH + 1 ); … … 82 81 } 83 82 g_free( store_handle ); 83 84 /* Make sure the nick doesn't collide with an existing one by adding 85 underscores and that kind of stuff, if necessary. */ 86 nick_dedupe( acc, handle, nick ); 87 88 return nick; 89 } 90 91 void nick_dedupe( account_t *acc, const char *handle, char nick[MAX_NICK_LENGTH+1] ) 92 { 93 int inf_protection = 256; 84 94 85 95 /* Now, find out if the nick is already in use at the moment, and make … … 120 130 } 121 131 } 122 123 return nick;124 132 } 125 133 -
nick.h
r19a8088 re900442 26 26 void nick_set( account_t *acc, const char *handle, const char *nick ); 27 27 char *nick_get( account_t *acc, const char *handle ); 28 void nick_dedupe( account_t *acc, const char *handle, char nick[MAX_NICK_LENGTH+1] ); 28 29 int nick_saved( account_t *acc, const char *handle ); 29 30 void nick_del( account_t *acc, const char *handle ); -
protocols/jabber/Makefile
r19a8088 re900442 10 10 11 11 # [SH] Program variables 12 objects = io.o iq.o jabber.o jabber_util.o message.o presence.o sasl.o xmltree.o12 objects = conference.o io.o iq.o jabber.o jabber_util.o message.o presence.o sasl.o xmltree.o 13 13 14 14 CFLAGS += -Wall -
protocols/jabber/io.c
r19a8088 re900442 44 44 struct jabber_data *jd = ic->proto_data; 45 45 gboolean ret; 46 47 if( jd->flags & JFLAG_XMLCONSOLE ) 48 { 49 char *msg; 50 51 msg = g_strdup_printf( "TX: %s", buf ); 52 imcb_buddy_msg( ic, JABBER_XMLCONSOLE_HANDLE, msg, 0, 0 ); 53 g_free( msg ); 54 } 46 55 47 56 if( jd->tx_len == 0 ) … … 484 493 } 485 494 495 static xt_status jabber_xmlconsole( struct xt_node *node, gpointer data ) 496 { 497 struct im_connection *ic = data; 498 struct jabber_data *jd = ic->proto_data; 499 500 if( jd->flags & JFLAG_XMLCONSOLE ) 501 { 502 char *msg, *pkt; 503 504 pkt = xt_to_string( node ); 505 msg = g_strdup_printf( "RX: %s", pkt ); 506 imcb_buddy_msg( ic, JABBER_XMLCONSOLE_HANDLE, msg, 0, 0 ); 507 g_free( msg ); 508 g_free( pkt ); 509 } 510 511 return XT_NEXT; 512 } 513 486 514 static const struct xt_handler_entry jabber_handlers[] = { 515 { NULL, "stream:stream", jabber_xmlconsole }, 487 516 { "stream:stream", "<root>", jabber_end_of_stream }, 488 517 { "message", "stream:stream", jabber_pkt_message }, -
protocols/jabber/iq.c
r19a8088 re900442 99 99 else if( strcmp( s, XMLNS_DISCOVER ) == 0 ) 100 100 { 101 const char *features[] = { XMLNS_VERSION, 102 XMLNS_TIME, 103 XMLNS_CHATSTATES, 104 XMLNS_MUC, 105 NULL }; 106 const char **f; 107 101 108 c = xt_new_node( "identity", NULL, NULL ); 102 109 xt_add_attr( c, "category", "client" ); … … 105 112 xt_add_child( reply, c ); 106 113 107 c = xt_new_node( "feature", NULL, NULL ); 108 xt_add_attr( c, "var", XMLNS_VERSION ); 109 xt_add_child( reply, c ); 110 111 c = xt_new_node( "feature", NULL, NULL ); 112 xt_add_attr( c, "var", XMLNS_TIME ); 113 xt_add_child( reply, c ); 114 115 c = xt_new_node( "feature", NULL, NULL ); 116 xt_add_attr( c, "var", XMLNS_CHATSTATES ); 117 xt_add_child( reply, c ); 118 119 /* Later this can be useful to announce things like 120 MUC support. */ 114 for( f = features; *f; f ++ ) 115 { 116 c = xt_new_node( "feature", NULL, NULL ); 117 xt_add_attr( c, "var", *f ); 118 xt_add_child( reply, c ); 119 } 121 120 } 122 121 else … … 373 372 group->text : NULL ); 374 373 375 imcb_rename_buddy( ic, jid, name ); 374 if( name ) 375 imcb_rename_buddy( ic, jid, name ); 376 376 } 377 377 else if( strcmp( sub, "remove" ) == 0 ) 378 378 { 379 /* Don't have any API call for this yet! So let's380 just try to handle this as well as we can. */381 379 jabber_buddy_remove_bare( ic, jid ); 382 imcb_buddy_status( ic, jid, 0, NULL, NULL ); 383 /* FIXME! */ 380 imcb_remove_buddy( ic, jid, NULL ); 384 381 } 385 382 } -
protocols/jabber/jabber.c
r19a8088 re900442 197 197 jabber_end_stream( ic ); 198 198 199 while( ic->groupchats ) 200 jabber_chat_free( ic->groupchats ); 201 199 202 if( jd->r_inpa >= 0 ) 200 203 b_event_remove( jd->r_inpa ); … … 224 227 struct jabber_buddy *bud; 225 228 struct xt_node *node; 229 char *s; 226 230 int st; 227 231 228 bud = jabber_buddy_by_jid( ic, who, 0 ); 232 if( g_strcasecmp( who, JABBER_XMLCONSOLE_HANDLE ) == 0 ) 233 return jabber_write( ic, message, strlen( message ) ); 234 235 if( ( s = strchr( who, '=' ) ) && jabber_chat_by_name( ic, s + 1 ) ) 236 bud = jabber_buddy_by_ext_jid( ic, who, 0 ); 237 else 238 bud = jabber_buddy_by_jid( ic, who, 0 ); 229 239 230 240 node = xt_new_node( "body", message, NULL ); … … 311 321 static void jabber_add_buddy( struct im_connection *ic, char *who, char *group ) 312 322 { 323 struct jabber_data *jd = ic->proto_data; 324 325 if( g_strcasecmp( who, JABBER_XMLCONSOLE_HANDLE ) == 0 ) 326 { 327 jd->flags |= JFLAG_XMLCONSOLE; 328 imcb_add_buddy( ic, JABBER_XMLCONSOLE_HANDLE, NULL ); 329 return; 330 } 331 313 332 if( jabber_add_to_roster( ic, who, NULL ) ) 314 333 presence_send_request( ic, who, "subscribe" ); … … 317 336 static void jabber_remove_buddy( struct im_connection *ic, char *who, char *group ) 318 337 { 338 struct jabber_data *jd = ic->proto_data; 339 340 if( g_strcasecmp( who, JABBER_XMLCONSOLE_HANDLE ) == 0 ) 341 { 342 jd->flags &= ~JFLAG_XMLCONSOLE; 343 /* Not necessary for now. And for now the code isn't too 344 happy if the buddy is completely gone right after calling 345 this function already. 346 imcb_remove_buddy( ic, JABBER_XMLCONSOLE_HANDLE, NULL ); 347 */ 348 return; 349 } 350 319 351 /* We should always do this part. Clean up our administration a little bit. */ 320 352 jabber_buddy_remove_bare( ic, who ); … … 322 354 if( jabber_remove_from_roster( ic, who ) ) 323 355 presence_send_request( ic, who, "unsubscribe" ); 356 } 357 358 static struct groupchat *jabber_chat_join_( struct im_connection *ic, char *room, char *nick, char *password ) 359 { 360 if( strchr( room, '@' ) == NULL ) 361 imcb_error( ic, "Invalid room name: %s", room ); 362 else if( jabber_chat_by_name( ic, room ) ) 363 imcb_error( ic, "Already present in chat `%s'", room ); 364 else 365 return jabber_chat_join( ic, room, nick, password ); 366 367 return NULL; 368 } 369 370 static void jabber_chat_msg_( struct groupchat *c, char *message, int flags ) 371 { 372 if( c && message ) 373 jabber_chat_msg( c, message, flags ); 374 } 375 376 static void jabber_chat_leave_( struct groupchat *c ) 377 { 378 if( c ) 379 jabber_chat_leave( c, NULL ); 324 380 } 325 381 … … 388 444 ret->buddy_msg = jabber_buddy_msg; 389 445 ret->away_states = jabber_away_states; 390 // ret->get_status_string = jabber_get_status_string;391 446 ret->set_away = jabber_set_away; 392 447 // ret->set_info = jabber_set_info; … … 394 449 ret->add_buddy = jabber_add_buddy; 395 450 ret->remove_buddy = jabber_remove_buddy; 396 // ret->chat_msg = jabber_chat_msg;451 ret->chat_msg = jabber_chat_msg_; 397 452 // ret->chat_invite = jabber_chat_invite; 398 // ret->chat_leave = jabber_chat_leave;399 // ret->chat_open = jabber_chat_open;453 ret->chat_leave = jabber_chat_leave_; 454 ret->chat_join = jabber_chat_join_; 400 455 ret->keepalive = jabber_keepalive; 401 456 ret->send_typing = jabber_send_typing; -
protocols/jabber/jabber.h
r19a8088 re900442 32 32 typedef enum 33 33 { 34 JFLAG_STREAM_STARTED = 1, 34 JFLAG_STREAM_STARTED = 1, /* Set when we detected the beginning of the stream 35 35 and want to do auth. */ 36 JFLAG_AUTHENTICATED = 2, 37 JFLAG_STREAM_RESTART = 4, 36 JFLAG_AUTHENTICATED = 2, /* Set when we're successfully authenticatd. */ 37 JFLAG_STREAM_RESTART = 4, /* Set when we want to restart the stream (after 38 38 SASL or TLS). */ 39 JFLAG_WAIT_SESSION = 8, 39 JFLAG_WAIT_SESSION = 8, /* Set if we sent a <session> tag and need a reply 40 40 before we continue. */ 41 JFLAG_WAIT_BIND = 16, 42 JFLAG_WANT_TYPING = 32, 41 JFLAG_WAIT_BIND = 16, /* ... for <bind> tag. */ 42 JFLAG_WANT_TYPING = 32, /* Set if we ever sent a typing notification, this 43 43 activates all XEP-85 related code. */ 44 JFLAG_XMLCONSOLE = 64, /* If the user added an xmlconsole buddy. */ 44 45 } jabber_flags_t; 45 46 … … 50 51 JBFLAG_DOES_XEP85 = 2, /* Set this when the resource seems to support 51 52 XEP85 (typing notification shite). */ 53 JBFLAG_IS_CHATROOM = 4, /* It's convenient to use this JID thingy for 54 groupchat state info too. */ 55 JBFLAG_IS_ANONYMOUS = 8, /* For anonymous chatrooms, when we don't have 56 have a real JID. */ 52 57 } jabber_buddy_flags_t; 53 54 #define JABBER_PORT_DEFAULT "5222"55 #define JABBER_PORT_MIN 522056 #define JABBER_PORT_MAX 522957 58 58 59 struct jabber_data … … 101 102 char *resource; 102 103 104 char *ext_jid; /* The JID to use in BitlBee. The real JID if possible, */ 105 /* otherwise something similar to the conference JID. */ 106 103 107 int priority; 104 108 struct jabber_away_state *away_state; … … 110 114 struct jabber_buddy *next; 111 115 }; 116 117 struct jabber_chat 118 { 119 int flags; 120 char *name; 121 char *my_full_jid; /* Separate copy because of case sensitivity. */ 122 struct jabber_buddy *me; 123 }; 124 125 #define JABBER_XMLCONSOLE_HANDLE "xmlconsole" 126 127 #define JABBER_PORT_DEFAULT "5222" 128 #define JABBER_PORT_MIN 5220 129 #define JABBER_PORT_MAX 5229 112 130 113 131 /* Prefixes to use for packet IDs (mainly for IQ packets ATM). Usually the … … 132 150 #define XMLNS_TIME "jabber:iq:time" /* XEP-0090 */ 133 151 #define XMLNS_VCARD "vcard-temp" /* XEP-0054 */ 152 #define XMLNS_DELAY "jabber:x:delay" /* XEP-0091 */ 134 153 #define XMLNS_CHATSTATES "http://jabber.org/protocol/chatstates" /* 0085 */ 135 154 #define XMLNS_DISCOVER "http://jabber.org/protocol/disco#info" /* 0030 */ 155 #define XMLNS_MUC "http://jabber.org/protocol/muc" /* XEP-0045 */ 156 #define XMLNS_MUC_USER "http://jabber.org/protocol/muc#user"/* XEP-0045 */ 136 157 137 158 /* iq.c */ … … 164 185 const struct jabber_away_state *jabber_away_state_by_name( char *name ); 165 186 void jabber_buddy_ask( struct im_connection *ic, char *handle ); 166 char *jabber_normalize( c har *orig );187 char *jabber_normalize( const char *orig ); 167 188 168 189 typedef enum 169 190 { 170 191 GET_BUDDY_CREAT = 1, /* Try to create it, if necessary. */ 171 GET_BUDDY_EXACT = 2, /* Get an exact message (only makes sense with bare JIDs). */ 192 GET_BUDDY_EXACT = 2, /* Get an exact match (only makes sense with bare JIDs). */ 193 GET_BUDDY_FIRST = 4, /* No selection, simply get the first resource for this JID. */ 172 194 } get_buddy_flags_t; 173 195 174 196 struct jabber_buddy *jabber_buddy_add( struct im_connection *ic, char *full_jid ); 175 197 struct jabber_buddy *jabber_buddy_by_jid( struct im_connection *ic, char *jid, get_buddy_flags_t flags ); 198 struct jabber_buddy *jabber_buddy_by_ext_jid( struct im_connection *ic, char *jid, get_buddy_flags_t flags ); 176 199 int jabber_buddy_remove( struct im_connection *ic, char *full_jid ); 177 200 int jabber_buddy_remove_bare( struct im_connection *ic, char *bare_jid ); 201 struct groupchat *jabber_chat_by_name( struct im_connection *ic, const char *name ); 202 time_t jabber_get_timestamp( struct xt_node *xt ); 178 203 179 204 extern const struct jabber_away_state jabber_away_state_list[]; … … 193 218 gboolean sasl_supported( struct im_connection *ic ); 194 219 220 /* conference.c */ 221 struct groupchat *jabber_chat_join( struct im_connection *ic, char *room, char *nick, char *password ); 222 void jabber_chat_free( struct groupchat *c ); 223 int jabber_chat_msg( struct groupchat *ic, char *message, int flags ); 224 int jabber_chat_leave( struct groupchat *c, const char *reason ); 225 void jabber_chat_pkt_presence( struct im_connection *ic, struct jabber_buddy *bud, struct xt_node *node ); 226 void jabber_chat_pkt_message( struct im_connection *ic, struct jabber_buddy *bud, struct xt_node *node ); 227 195 228 #endif -
protocols/jabber/jabber_util.c
r19a8088 re900442 48 48 call p_s_u() now to send the new prio setting, it would 49 49 send the old setting because the set->value gets changed 50 when theeval returns a non-NULL value.50 after the (this) eval returns a non-NULL value. 51 51 52 52 So now I can choose between implementing post-set … … 129 129 /* Cache a node/packet for later use. Mainly useful for IQ packets if you need 130 130 them when you receive the response. Use this BEFORE sending the packet so 131 it'll get a new id= tag, and do NOT free() the packet after writing it! */131 it'll get a new id= tag, and do NOT free() the packet after sending it! */ 132 132 void jabber_cache_add( struct im_connection *ic, struct xt_node *node, jabber_cache_event func ) 133 133 { … … 252 252 253 253 /* Returns a new string. Don't leak it! */ 254 char *jabber_normalize( c har *orig )254 char *jabber_normalize( const char *orig ) 255 255 { 256 256 int len, i; … … 320 320 else 321 321 { 322 /* Keep in mind that full_jid currently isn't really 323 a full JID... */ 322 324 new->bare_jid = g_strdup( full_jid ); 323 325 g_hash_table_insert( jd->buddies, new->bare_jid, new ); … … 333 335 { 334 336 /* Let's waste some more bytes of RAM instead of to make 335 memory management a total disaster here.. */ 337 memory management a total disaster here. And it saves 338 me one g_free() call in this function. :-P */ 336 339 new->full_jid = full_jid; 337 340 } … … 353 356 if( ( s = strchr( jid, '/' ) ) ) 354 357 { 358 int none_found = 0; 359 355 360 *s = 0; 356 361 if( ( bud = g_hash_table_lookup( jd->buddies, jid ) ) ) … … 370 375 } 371 376 } 372 373 if( bud == NULL && ( flags & GET_BUDDY_CREAT ) && imcb_find_buddy( ic, jid ) ) 377 else 378 { 379 /* This hack is there to make sure that O_CREAT will 380 work if there's already another resouce present 381 for this JID, even if it's an unknown buddy. This 382 is done to handle conferences properly. */ 383 none_found = 1; 384 } 385 386 if( bud == NULL && ( flags & GET_BUDDY_CREAT ) && ( imcb_find_buddy( ic, jid ) || !none_found ) ) 374 387 { 375 388 *s = '/'; … … 418 431 } 419 432 433 /* I'm keeping a separate ext_jid attribute to save a JID that makes sense 434 to export to BitlBee. This is mainly for groupchats right now. It's 435 a bit of a hack, but I just think having the user nickname in the hostname 436 part of the hostmask doesn't look nice on IRC. Normally you can convert 437 a normal JID to ext_jid by swapping the part before and after the / and 438 replacing the / with a =. But there should be some stripping (@s are 439 allowed in Jabber nicks...). */ 440 struct jabber_buddy *jabber_buddy_by_ext_jid( struct im_connection *ic, char *jid_, get_buddy_flags_t flags ) 441 { 442 struct jabber_buddy *bud; 443 char *s, *jid; 444 445 jid = jabber_normalize( jid_ ); 446 447 if( ( s = strchr( jid, '=' ) ) == NULL ) 448 return NULL; 449 450 for( bud = jabber_buddy_by_jid( ic, s + 1, GET_BUDDY_FIRST ); bud; bud = bud->next ) 451 { 452 /* Hmmm, could happen if not all people in the chat are anonymized? */ 453 if( bud->ext_jid == NULL ) 454 continue; 455 456 if( strcmp( bud->ext_jid, jid ) == 0 ) 457 break; 458 } 459 460 g_free( jid ); 461 462 return bud; 463 } 464 420 465 /* Remove one specific full JID from our list. Use this when a buddy goes 421 466 off-line (because (s)he can still be online from a different location. … … 441 486 g_hash_table_remove( jd->buddies, bud->bare_jid ); 442 487 g_free( bud->bare_jid ); 488 g_free( bud->ext_jid ); 443 489 g_free( bud->full_jid ); 444 490 g_free( bud->away_message ); … … 473 519 g_hash_table_replace( jd->buddies, bi->bare_jid, bi->next ); 474 520 521 g_free( bi->ext_jid ); 475 522 g_free( bi->full_jid ); 476 523 g_free( bi->away_message ); … … 495 542 specified bare JID. Use this when removing someone from the contact 496 543 list, for example. */ 497 int jabber_buddy_remove_bare( struct im_connection *ic, char *bare_jid _)544 int jabber_buddy_remove_bare( struct im_connection *ic, char *bare_jid ) 498 545 { 499 546 struct jabber_data *jd = ic->proto_data; 500 547 struct jabber_buddy *bud, *next; 501 char *bare_jid; 502 503 if( strchr( bare_jid_, '/' ) ) 548 549 if( strchr( bare_jid, '/' ) ) 504 550 return 0; 505 551 506 bare_jid = jabber_normalize( bare_jid_ ); 507 508 if( ( bud = g_hash_table_lookup( jd->buddies, bare_jid ) ) ) 552 if( ( bud = jabber_buddy_by_jid( ic, bare_jid, GET_BUDDY_FIRST ) ) ) 509 553 { 510 554 /* Most important: Remove the hash reference. We don't know 511 555 this buddy anymore. */ 512 556 g_hash_table_remove( jd->buddies, bud->bare_jid ); 557 g_free( bud->bare_jid ); 513 558 514 559 /* Deallocate the linked list of resources. */ 515 560 while( bud ) 516 561 { 562 /* ext_jid && anonymous means that this buddy is 563 specific to one groupchat (the one we're 564 currently cleaning up) so it can be deleted 565 completely. */ 566 if( bud->ext_jid && bud->flags & JBFLAG_IS_ANONYMOUS ) 567 imcb_remove_buddy( ic, bud->ext_jid, NULL ); 568 517 569 next = bud->next; 570 g_free( bud->ext_jid ); 518 571 g_free( bud->full_jid ); 519 572 g_free( bud->away_message ); … … 522 575 } 523 576 524 g_free( bare_jid );525 577 return 1; 526 578 } 527 579 else 528 580 { 529 g_free( bare_jid );530 581 return 0; 531 582 } 532 583 } 584 585 struct groupchat *jabber_chat_by_name( struct im_connection *ic, const char *name ) 586 { 587 char *normalized = jabber_normalize( name ); 588 struct groupchat *ret; 589 struct jabber_chat *jc; 590 591 for( ret = ic->groupchats; ret; ret = ret->next ) 592 { 593 jc = ret->data; 594 if( strcmp( normalized, jc->name ) == 0 ) 595 break; 596 } 597 g_free( normalized ); 598 599 return ret; 600 } 601 602 time_t jabber_get_timestamp( struct xt_node *xt ) 603 { 604 struct tm tp, utc; 605 struct xt_node *c; 606 time_t res, tres; 607 char *s = NULL; 608 609 for( c = xt->children; ( c = xt_find_node( c, "x" ) ); c = c->next ) 610 { 611 if( ( s = xt_find_attr( c, "xmlns" ) ) && strcmp( s, XMLNS_DELAY ) == 0 ) 612 break; 613 } 614 615 if( !c || !( s = xt_find_attr( c, "stamp" ) ) ) 616 return 0; 617 618 memset( &tp, 0, sizeof( tp ) ); 619 if( sscanf( s, "%4d%2d%2dT%2d:%2d:%2d", &tp.tm_year, &tp.tm_mon, &tp.tm_mday, 620 &tp.tm_hour, &tp.tm_min, &tp.tm_sec ) != 6 ) 621 return 0; 622 623 tp.tm_year -= 1900; 624 tp.tm_mon --; 625 tp.tm_isdst = -1; /* GRRRRRRRRRRR */ 626 627 res = mktime( &tp ); 628 /* Problem is, mktime() just gave us the GMT timestamp for the 629 given local time... While the given time WAS NOT local. So 630 we should fix this now. 631 632 Now I could choose between messing with environment variables 633 (kludgy) or using timegm() (not portable)... Or doing the 634 following, which I actually prefer... */ 635 gmtime_r( &res, &utc ); 636 utc.tm_isdst = -1; /* Once more: GRRRRRRRRRRRRRRRRRR!!! */ 637 if( utc.tm_hour == tp.tm_hour && utc.tm_min == tp.tm_min ) 638 /* Sweet! We're in UTC right now... */ 639 return res; 640 641 tres = mktime( &utc ); 642 res += res - tres; 643 644 /* Yes, this is a hack. And it will go wrong around DST changes. 645 BUT this is more likely to be threadsafe than messing with 646 environment variables, and possibly more portable... */ 647 648 return res; 649 } -
protocols/jabber/message.c
r19a8088 re900442 30 30 char *type = xt_find_attr( node, "type" ); 31 31 struct xt_node *body = xt_find_node( node->children, "body" ), *c; 32 struct jabber_buddy *bud = NULL; 32 33 char *s; 34 35 if( !from ) 36 return XT_HANDLED; /* Consider this packet corrupted. */ 37 38 bud = jabber_buddy_by_jid( ic, from, GET_BUDDY_EXACT ); 33 39 34 40 if( type && strcmp( type, "error" ) == 0 ) … … 36 42 /* Handle type=error packet. */ 37 43 } 38 else if( type && strcmp( type, "groupchat" ) == 0 )44 else if( type && from && strcmp( type, "groupchat" ) == 0 ) 39 45 { 40 /* TODO! */46 jabber_chat_pkt_message( ic, bud, node ); 41 47 } 42 48 else /* "chat", "normal", "headline", no-type or whatever. Should all be pretty similar. */ 43 49 { 44 struct jabber_buddy *bud = NULL;45 50 GString *fullmsg = g_string_new( "" ); 46 51 47 52 if( ( s = strchr( from, '/' ) ) ) 48 53 { 49 if( ( bud = jabber_buddy_by_jid( ic, from, GET_BUDDY_EXACT ) ) ) 54 if( bud ) 55 { 50 56 bud->last_act = time( NULL ); 57 from = bud->ext_jid ? : bud->bare_jid; 58 } 51 59 else 52 60 *s = 0; /* We need to generate a bare JID now. */ … … 76 84 77 85 if( fullmsg->len > 0 ) 78 imcb_buddy_msg( ic, bud ? bud->bare_jid : from, fullmsg->str, 0, 0 ); 86 imcb_buddy_msg( ic, from, fullmsg->str, 87 0, jabber_get_timestamp( node ) ); 79 88 80 89 g_string_free( fullmsg, TRUE ); … … 84 93 { 85 94 bud->flags |= JBFLAG_DOES_XEP85; 86 imcb_buddy_typing( ic, bud ? bud->bare_jid :from, OPT_TYPING );95 imcb_buddy_typing( ic, from, OPT_TYPING ); 87 96 } 88 97 /* No need to send a "stopped typing" signal when there's a message. */ … … 90 99 { 91 100 bud->flags |= JBFLAG_DOES_XEP85; 92 imcb_buddy_typing( ic, bud ? bud->bare_jid :from, 0 );101 imcb_buddy_typing( ic, from, 0 ); 93 102 } 94 103 else if( xt_find_node( node->children, "paused" ) ) 95 104 { 96 105 bud->flags |= JBFLAG_DOES_XEP85; 97 imcb_buddy_typing( ic, bud ? bud->bare_jid :from, OPT_THINKING );106 imcb_buddy_typing( ic, from, OPT_THINKING ); 98 107 } 99 108 -
protocols/jabber/presence.c
r19a8088 re900442 31 31 struct xt_node *c; 32 32 struct jabber_buddy *bud; 33 int is_chat = 0, is_away = 0; 33 34 char *s; 34 35 … … 36 37 return XT_HANDLED; 37 38 39 if( ( s = strchr( from, '/' ) ) ) 40 { 41 *s = 0; 42 if( jabber_chat_by_name( ic, from ) ) 43 is_chat = 1; 44 *s = '/'; 45 } 46 38 47 if( type == NULL ) 39 48 { 40 int is_away = 0;41 42 49 if( !( bud = jabber_buddy_by_jid( ic, from, GET_BUDDY_EXACT | GET_BUDDY_CREAT ) ) ) 43 50 { … … 72 79 bud->priority = 0; 73 80 74 if( bud == jabber_buddy_by_jid( ic, bud->bare_jid, 0 ) ) 81 if( is_chat ) 82 jabber_chat_pkt_presence( ic, bud, node ); 83 else if( bud == jabber_buddy_by_jid( ic, bud->bare_jid, 0 ) ) 75 84 imcb_buddy_status( ic, bud->bare_jid, OPT_LOGGED_IN | is_away, 76 85 ( is_away && bud->away_state ) ? bud->away_state->full_name : NULL, … … 79 88 else if( strcmp( type, "unavailable" ) == 0 ) 80 89 { 81 if( jabber_buddy_by_jid( ic, from, GET_BUDDY_EXACT) == NULL )90 if( ( bud = jabber_buddy_by_jid( ic, from, GET_BUDDY_EXACT ) ) == NULL ) 82 91 { 83 92 if( set_getbool( &ic->irc->set, "debug" ) ) … … 86 95 } 87 96 97 /* Handle this before we delete the JID. */ 98 if( is_chat ) 99 { 100 jabber_chat_pkt_presence( ic, bud, node ); 101 } 102 88 103 jabber_buddy_remove( ic, from ); 89 104 90 if( ( s = strchr( from, '/' ) ) ) 105 if( is_chat ) 106 { 107 /* Nothing else to do for now? */ 108 } 109 else if( ( s = strchr( from, '/' ) ) ) 91 110 { 92 111 *s = 0; 93 112 94 /* Only count this as offline if there's no other resource 95 available anymore. */ 96 if( jabber_buddy_by_jid( ic, from, 0 ) == NULL ) 113 /* If another resource is still available, send its presence 114 information. */ 115 if( ( bud = jabber_buddy_by_jid( ic, from, 0 ) ) ) 116 { 117 if( bud->away_state && ( *bud->away_state->code == 0 || 118 strcmp( bud->away_state->code, "chat" ) == 0 ) ) 119 is_away = OPT_AWAY; 120 121 imcb_buddy_status( ic, bud->bare_jid, OPT_LOGGED_IN | is_away, 122 ( is_away && bud->away_state ) ? bud->away_state->full_name : NULL, 123 bud->away_message ); 124 } 125 else 126 { 127 /* Otherwise, count him/her as offline now. */ 97 128 imcb_buddy_status( ic, from, 0, NULL, NULL ); 129 } 98 130 99 131 *s = '/'; … … 145 177 char *show = jd->away_state->code; 146 178 char *status = jd->away_message; 179 struct groupchat *c; 147 180 int st; 148 181 … … 156 189 st = jabber_write_packet( ic, node ); 157 190 191 /* Have to send this update to all groupchats too, the server won't 192 do this automatically. */ 193 for( c = ic->groupchats; c && st; c = c->next ) 194 { 195 struct jabber_chat *jc = c->data; 196 197 xt_add_attr( node, "to", jc->my_full_jid ); 198 st = jabber_write_packet( ic, node ); 199 } 200 158 201 xt_free_node( node ); 159 202 return st; -
protocols/jabber/xmltree.c
r19a8088 re900442 442 442 list, not the node itself! The reason you have to do this by hand: So 443 443 that you can also use this function as a find-next. */ 444 struct xt_node *xt_find_node( struct xt_node *node, c har *name )444 struct xt_node *xt_find_node( struct xt_node *node, const char *name ) 445 445 { 446 446 while( node ) … … 455 455 } 456 456 457 char *xt_find_attr( struct xt_node *node, c har *key )457 char *xt_find_attr( struct xt_node *node, const char *key ) 458 458 { 459 459 int i; … … 524 524 } 525 525 526 void xt_add_attr( struct xt_node *node, c har *key,char *value )526 void xt_add_attr( struct xt_node *node, const char *key, const char *value ) 527 527 { 528 528 int i; … … 551 551 } 552 552 553 int xt_remove_attr( struct xt_node *node, c har *key )553 int xt_remove_attr( struct xt_node *node, const char *key ) 554 554 { 555 555 int i, last; -
protocols/jabber/xmltree.h
r19a8088 re900442 87 87 void xt_free_node( struct xt_node *node ); 88 88 void xt_free( struct xt_parser *xt ); 89 struct xt_node *xt_find_node( struct xt_node *node, c har *name );90 char *xt_find_attr( struct xt_node *node, c har *key );89 struct xt_node *xt_find_node( struct xt_node *node, const char *name ); 90 char *xt_find_attr( struct xt_node *node, const char *key ); 91 91 92 92 struct xt_node *xt_new_node( char *name, char *text, struct xt_node *children ); 93 93 void xt_add_child( struct xt_node *parent, struct xt_node *child ); 94 void xt_add_attr( struct xt_node *node, c har *key,char *value );95 int xt_remove_attr( struct xt_node *node, c har *key );94 void xt_add_attr( struct xt_node *node, const char *key, const char *value ); 95 int xt_remove_attr( struct xt_node *node, const char *key ); 96 96 97 97 #endif -
protocols/msn/sb.c
r19a8088 re900442 232 232 if( sb->chat ) 233 233 { 234 imcb_chat_ removed( sb->chat );234 imcb_chat_free( sb->chat ); 235 235 } 236 236 -
protocols/nogaim.c
r19a8088 re900442 428 428 { 429 429 user_t *u = user_findhandle( ic, handle ); 430 char *s, newnick[MAX_NICK_LENGTH+1];431 430 432 431 if( !u || !realname ) return; … … 440 439 if( ( ic->flags & OPT_LOGGED_IN ) && set_getbool( &ic->irc->set, "display_namechanges" ) ) 441 440 imcb_log( ic, "User `%s' changed name to `%s'", u->nick, u->realname ); 442 443 if( !u->online && !nick_saved( ic->acc, handle ) ) 444 { 445 /* Detect numeric handles: */ 446 for( s = u->user; isdigit( *s ); s++ ); 441 } 442 } 443 444 void imcb_remove_buddy( struct im_connection *ic, char *handle, char *group ) 445 { 446 user_t *u; 447 448 if( ( u = user_findhandle( ic, handle ) ) ) 449 user_del( ic->irc, u->nick ); 450 } 451 452 /* Mainly meant for ICQ (and now also for Jabber conferences) to allow IM 453 modules to suggest a nickname for a handle. */ 454 void imcb_buddy_nick_hint( struct im_connection *ic, char *handle, char *nick ) 455 { 456 user_t *u = user_findhandle( ic, handle ); 457 char newnick[MAX_NICK_LENGTH+1], *orig_nick; 458 459 if( u && !u->online && !nick_saved( ic->acc, handle ) ) 460 { 461 /* Only do this if the person isn't online yet (which should 462 be the case if we just added it) and if the user hasn't 463 assigned a nickname to this buddy already. */ 464 465 strncpy( newnick, nick, MAX_NICK_LENGTH ); 466 newnick[MAX_NICK_LENGTH] = 0; 467 468 /* Some processing to make sure this string is a valid IRC nickname. */ 469 nick_strip( newnick ); 470 if( set_getbool( &ic->irc->set, "lcnicks" ) ) 471 nick_lc( newnick ); 472 473 if( strcmp( u->nick, newnick ) != 0 ) 474 { 475 /* Only do this if newnick is different from the current one. 476 If rejoining a channel, maybe we got this nick already 477 (and dedupe would only add an underscore. */ 478 nick_dedupe( ic->acc, handle, newnick ); 447 479 448 if( *s == 0 ) 449 { 450 /* If we reached the end of the string, it only contained numbers. 451 Seems to be an ICQ# then, so hopefully realname contains 452 something more useful. */ 453 strcpy( newnick, realname ); 454 455 /* Some processing to make sure this string is a valid IRC nickname. */ 456 nick_strip( newnick ); 457 if( set_getbool( &ic->irc->set, "lcnicks" ) ) 458 nick_lc( newnick ); 459 460 u->nick = g_strdup( newnick ); 461 } 462 } 463 } 464 } 465 480 /* u->nick will be freed halfway the process, so it can't be 481 passed as an argument. */ 482 orig_nick = g_strdup( u->nick ); 483 user_rename( ic->irc, orig_nick, newnick ); 484 g_free( orig_nick ); 485 } 486 } 487 } 466 488 467 489 /* prpl.c */ … … 554 576 u->online = 0; 555 577 556 /* Remove him/her from the conversations to prevent PART messages after he/she QUIT already */557 for( c = ic-> conversations; c; c = c->next )578 /* Remove him/her from the groupchats to prevent PART messages after he/she QUIT already */ 579 for( c = ic->groupchats; c; c = c->next ) 558 580 remove_chat_buddy_silent( c, (char*) handle ); 559 581 } … … 685 707 } 686 708 687 void imcb_chat_ removed( struct groupchat *c )709 void imcb_chat_free( struct groupchat *c ) 688 710 { 689 711 struct im_connection *ic = c->ic; 690 struct groupchat *l = NULL;712 struct groupchat *l; 691 713 GList *ir; 692 714 … … 708 730 } 709 731 732 /* Find the previous chat in the linked list. */ 733 for( l = ic->groupchats; l && l->next != c; l = l->next ); 734 710 735 if( l ) 711 736 l->next = c->next; 712 737 else 713 ic-> conversations = c->next;738 ic->groupchats = c->next; 714 739 715 740 for( ir = c->in_room; ir; ir = ir->next ) … … 749 774 /* This one just creates the conversation structure, user won't see anything yet */ 750 775 751 if( ic-> conversations )752 { 753 for( c = ic-> conversations; c->next; c = c->next );776 if( ic->groupchats ) 777 { 778 for( c = ic->groupchats; c->next; c = c->next ); 754 779 c = c->next = g_new0( struct groupchat, 1 ); 755 780 } 756 781 else 757 ic-> conversations = c = g_new0( struct groupchat, 1 );782 ic->groupchats = c = g_new0( struct groupchat, 1 ); 758 783 759 784 c->ic = ic; … … 804 829 } 805 830 831 /* This function is one BIG hack... :-( EREWRITE */ 806 832 void imcb_chat_remove_buddy( struct groupchat *b, char *handle, char *reason ) 807 833 { … … 815 841 if( g_strcasecmp( handle, b->ic->acc->user ) == 0 ) 816 842 { 843 if( b->joined == 0 ) 844 return; 845 817 846 u = user_find( b->ic->irc, b->ic->irc->nick ); 818 847 b->joined = 0; … … 824 853 } 825 854 826 if( remove_chat_buddy_silent( b, handle ) ) 827 if( ( b->joined || me ) && u ) 828 irc_part( b->ic->irc, u, b->channel ); 855 if( me || ( remove_chat_buddy_silent( b, handle ) && b->joined && u ) ) 856 irc_part( b->ic->irc, u, b->channel ); 829 857 } 830 858 … … 852 880 853 881 /* Misc. BitlBee stuff which shouldn't really be here */ 854 855 struct groupchat *chat_by_channel( char *channel )856 {857 struct im_connection *ic;858 struct groupchat *c;859 GSList *l;860 861 /* This finds the connection which has a conversation which belongs to this channel */862 for( l = connections; l; l = l->next )863 {864 ic = l->data;865 for( c = ic->conversations; c && g_strcasecmp( c->channel, channel ) != 0; c = c->next );866 if( c )867 return c;868 }869 870 return NULL;871 }872 882 873 883 char *set_eval_away_devoice( set_t *set, char *value ) -
protocols/nogaim.h
r19a8088 re900442 61 61 #define OPT_AWAY 0x00000004 62 62 #define OPT_DOES_HTML 0x00000010 63 #define OPT_LOCALBUDDY 0x00000020 /* For nicks local to one groupchat */ 63 64 #define OPT_TYPING 0x00000100 /* Some pieces of code make assumptions */ 64 65 #define OPT_THINKING 0x00000200 /* about these values... Stupid me! */ … … 91 92 irc_t *irc; 92 93 93 struct groupchat * conversations;94 struct groupchat *groupchats; 94 95 }; 95 96 … … 97 98 struct im_connection *ic; 98 99 99 /* stuff used just for chat */100 100 GList *in_room; 101 101 GList *ignored; 102 102 103 /* BitlBee */104 103 struct groupchat *next; 105 104 char *channel; … … 195 194 G_MODULE_EXPORT struct buddy *imcb_find_buddy( struct im_connection *ic, char *handle ); 196 195 G_MODULE_EXPORT void imcb_rename_buddy( struct im_connection *ic, char *handle, char *realname ); 196 G_MODULE_EXPORT void imcb_buddy_nick_hint( struct im_connection *ic, char *handle, char *nick ); 197 197 198 198 /* Buddy activity */ … … 208 208 G_MODULE_EXPORT void imcb_chat_remove_buddy( struct groupchat *b, char *handle, char *reason ); 209 209 G_MODULE_EXPORT void imcb_chat_msg( struct groupchat *c, char *who, char *msg, u_int32_t flags, time_t sent_at ); 210 G_MODULE_EXPORT void imcb_chat_removed( struct groupchat *c ); 211 struct groupchat *chat_by_channel( char *channel ); 210 G_MODULE_EXPORT void imcb_chat_free( struct groupchat *c ); 212 211 213 212 /* Actions, or whatever. */ -
protocols/oscar/oscar.c
r19a8088 re900442 2022 2022 2023 2023 if (realname) { 2024 imcb_buddy_nick_hint(ic, curitem->name, realname); 2024 2025 imcb_rename_buddy(ic, curitem->name, realname); 2025 2026 g_free(realname); … … 2514 2515 2515 2516 /* Notify the conversation window that we've left the chat */ 2516 imcb_chat_ removed(cc->cnv);2517 imcb_chat_free(cc->cnv); 2517 2518 2518 2519 /* Destroy the chat_connection */ -
protocols/yahoo/yahoo.c
r19a8088 re900442 145 145 GSList *l; 146 146 147 while( ic-> conversations )148 imcb_chat_ removed( ic->conversations );147 while( ic->groupchats ) 148 imcb_chat_free( ic->groupchats ); 149 149 150 150 for( l = yd->buddygroups; l; l = l->next ) … … 318 318 319 319 yahoo_conference_logoff( yd->y2_id, NULL, c->data, c->title ); 320 imcb_chat_ removed( c );320 imcb_chat_free( c ); 321 321 } 322 322 … … 798 798 { 799 799 yahoo_conference_decline( inv->yid, NULL, inv->members, inv->name, "User rejected groupchat" ); 800 imcb_chat_ removed( inv->c );800 imcb_chat_free( inv->c ); 801 801 g_free( inv->name ); 802 802 g_free( inv ); … … 841 841 struct groupchat *c; 842 842 843 for( c = ic-> conversations; c && strcmp( c->title, room ) != 0; c = c->next );843 for( c = ic->groupchats; c && strcmp( c->title, room ) != 0; c = c->next ); 844 844 845 845 if( c ) … … 853 853 struct groupchat *c; 854 854 855 for( c = ic-> conversations; c && strcmp( c->title, room ) != 0; c = c->next );855 for( c = ic->groupchats; c && strcmp( c->title, room ) != 0; c = c->next ); 856 856 857 857 if( c ) … … 865 865 struct groupchat *c; 866 866 867 for( c = ic-> conversations; c && strcmp( c->title, room ) != 0; c = c->next );867 for( c = ic->groupchats; c && strcmp( c->title, room ) != 0; c = c->next ); 868 868 869 869 if( c ) -
root_commands.c
r19a8088 re900442 912 912 if( cmd[3] ) 913 913 { 914 channel = g_strdup( cmd[3] ); 914 if( cmd[3][0] != '#' && cmd[3][0] != '&' ) 915 channel = g_strdup_printf( "&%s", cmd[3] ); 916 else 917 channel = g_strdup( cmd[3] ); 915 918 } 916 919 else … … 918 921 char *s; 919 922 920 channel = g_strdup (chat );923 channel = g_strdup_printf( "&%s", chat ); 921 924 if( ( s = strchr( channel, '@' ) ) ) 922 925 *s = 0; … … 924 927 if( cmd[3] && cmd[4] ) 925 928 nick = cmd[4]; 929 else 930 nick = irc->nick; 926 931 if( cmd[3] && cmd[4] && cmd[5] ) 927 932 password = cmd[5]; 928 933 929 c = a->prpl->chat_join( ic, chat, nick, password ); 930 931 g_free( channel ); 934 if( !nick_ok( channel + 1 ) ) 935 { 936 irc_usermsg( irc, "Invalid channel name: %s", channel ); 937 g_free( channel ); 938 return; 939 } 940 else if( g_strcasecmp( channel, irc->channel ) == 0 || irc_chat_by_channel( irc, channel ) ) 941 { 942 irc_usermsg( irc, "Channel already exists: %s", channel ); 943 g_free( channel ); 944 return; 945 } 946 947 if( ( c = a->prpl->chat_join( ic, chat, nick, password ) ) ) 948 { 949 g_free( c->channel ); 950 c->channel = channel; 951 } 952 else 953 { 954 irc_usermsg( irc, "Tried to join chat, not sure if this was successful" ); 955 g_free( channel ); 956 } 932 957 } 933 958 -
user.c
r19a8088 re900442 161 161 } 162 162 163 /* DO NOT PASS u->nick FOR oldnick !!! */ 163 164 void user_rename( irc_t *irc, char *oldnick, char *newnick ) 164 165 {
Note: See TracChangeset
for help on using the changeset viewer.