Changes in protocols/nogaim.c [7e83e8e4:839189b]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
protocols/nogaim.c
r7e83e8e4 r839189b 38 38 #include "chat.h" 39 39 40 static int remove_chat_buddy_silent( struct groupchat *b, const char *handle ); 41 static char *format_timestamp( irc_t *irc, time_t msg_ts ); 42 40 43 GSList *connections; 41 44 … … 89 92 } 90 93 #endif 94 95 /* nogaim.c */ 91 96 92 97 GList *protocols = NULL; … … 121 126 } 122 127 128 /* nogaim.c */ 123 129 void nogaim_init() 124 130 { … … 156 162 GSList *get_connections() { return connections; } 157 163 164 /* multi.c */ 165 158 166 struct im_connection *imcb_new( account_t *acc ) 159 167 { … … 162 170 ic = g_new0( struct im_connection, 1 ); 163 171 164 ic-> bee = acc->bee;172 ic->irc = acc->irc; 165 173 ic->acc = acc; 166 174 acc->ic = ic; … … 176 184 177 185 /* Destroy the pointer to this connection from the account list */ 178 for( a = ic-> bee->accounts; a; a = a->next )186 for( a = ic->irc->accounts; a; a = a->next ) 179 187 if( a->ic == ic ) 180 188 { … … 197 205 va_end( params ); 198 206 199 if( ( g_strcasecmp( set_getstr( &ic-> bee->set, "strip_html" ), "always" ) == 0 ) ||200 ( ( ic->flags & OPT_DOES_HTML ) && set_getbool( &ic-> bee->set, "strip_html" ) ) )207 if( ( g_strcasecmp( set_getstr( &ic->irc->set, "strip_html" ), "always" ) == 0 ) || 208 ( ( ic->flags & OPT_DOES_HTML ) && set_getbool( &ic->irc->set, "strip_html" ) ) ) 201 209 strip_html( text ); 202 210 203 211 /* Try to find a different connection on the same protocol. */ 204 for( a = ic-> bee->accounts; a; a = a->next )212 for( a = ic->irc->accounts; a; a = a->next ) 205 213 if( a->prpl == ic->acc->prpl && a->ic != ic ) 206 214 break; … … 208 216 /* If we found one, include the screenname in the message. */ 209 217 if( a ) 210 /* FIXME(wilmer): ui_log callback or so */ 211 irc_usermsg( ic->bee->ui_data, "%s(%s) - %s", ic->acc->prpl->name, ic->acc->user, text ); 218 irc_usermsg( ic->irc, "%s(%s) - %s", ic->acc->prpl->name, ic->acc->user, text ); 212 219 else 213 irc_usermsg( ic-> bee->ui_data, "%s - %s", ic->acc->prpl->name, text );220 irc_usermsg( ic->irc, "%s - %s", ic->acc->prpl->name, text ); 214 221 215 222 g_free( text ); … … 262 269 void imcb_connected( struct im_connection *ic ) 263 270 { 271 irc_t *irc = ic->irc; 272 struct chat *c; 273 user_t *u; 274 264 275 /* MSN servers sometimes redirect you to a different server and do 265 276 the whole login sequence again, so these "late" calls to this … … 268 279 return; 269 280 281 u = user_find( ic->irc, ic->irc->nick ); 282 270 283 imcb_log( ic, "Logged in" ); 271 284 … … 280 293 ic->acc->auto_reconnect_delay = 0; 281 294 282 /*283 295 for( c = irc->chatrooms; c; c = c->next ) 284 296 { … … 289 301 chat_join( irc, c, NULL ); 290 302 } 291 */292 303 } 293 304 … … 297 308 298 309 a->reconnect = 0; 299 account_on( a-> bee, a );310 account_on( a->irc, a ); 300 311 301 312 return( FALSE ); /* Only have to run the timeout once */ … … 310 321 void imc_logout( struct im_connection *ic, int allow_reconnect ) 311 322 { 312 bee_t *bee = ic->bee; 323 irc_t *irc = ic->irc; 324 user_t *t, *u; 313 325 account_t *a; 314 GSList *l;315 326 int delay; 316 327 … … 332 343 ic->away = NULL; 333 344 334 for( l = bee->users; l; ) 335 { 336 bee_user_t *bu = l->data; 337 GSList *next = l->next; 338 339 if( bu->ic == ic ) 340 bee_user_free( bee, bu ); 341 342 l = next; 343 } 344 345 query_del_by_conn( (irc_t*) ic->bee->ui_data, ic ); 346 347 for( a = bee->accounts; a; a = a->next ) 345 u = irc->users; 346 while( u ) 347 { 348 if( u->ic == ic ) 349 { 350 t = u->next; 351 user_del( irc, u->nick ); 352 u = t; 353 } 354 else 355 u = u->next; 356 } 357 358 query_del_by_conn( ic->irc, ic ); 359 360 for( a = irc->accounts; a; a = a->next ) 348 361 if( a->ic == ic ) 349 362 break; … … 353 366 /* Uhm... This is very sick. */ 354 367 } 355 else if( allow_reconnect && set_getbool( & bee->set, "auto_reconnect" ) &&368 else if( allow_reconnect && set_getbool( &irc->set, "auto_reconnect" ) && 356 369 set_getbool( &a->set, "auto_reconnect" ) && 357 370 ( delay = account_reconnect_delay( a ) ) > 0 ) … … 364 377 } 365 378 379 380 /* dialogs.c */ 381 366 382 void imcb_ask( struct im_connection *ic, char *msg, void *data, 367 383 query_callback doit, query_callback dont ) 368 384 { 369 query_add( (irc_t *) ic->bee->ui_data, ic, msg, doit, dont, data ); 370 } 385 query_add( ic->irc, ic, msg, doit, dont, data ); 386 } 387 388 389 /* list.c */ 371 390 372 391 void imcb_add_buddy( struct im_connection *ic, const char *handle, const char *group ) 373 392 { 374 bee_user_t *bu; 375 bee_t *bee = ic->bee; 376 377 if( !( bu = bee_user_by_handle( bee, ic, handle ) ) ) 378 bu = bee_user_new( bee, ic, handle, 0 ); 379 380 bu->group = bee_group_by_name( bee, group, TRUE ); 381 382 if( bee->ui->user_group ) 383 bee->ui->user_group( bee, bu ); 384 } 385 386 void imcb_rename_buddy( struct im_connection *ic, const char *handle, const char *fullname ) 387 { 388 bee_t *bee = ic->bee; 389 bee_user_t *bu = bee_user_by_handle( bee, ic, handle ); 390 391 if( !bu || !fullname ) return; 392 393 if( !bu->fullname || strcmp( bu->fullname, fullname ) != 0 ) 394 { 395 g_free( bu->fullname ); 396 bu->fullname = g_strdup( fullname ); 397 398 if( bee->ui->user_fullname ) 399 bee->ui->user_fullname( bee, bu ); 393 user_t *u; 394 char nick[MAX_NICK_LENGTH+1], *s; 395 irc_t *irc = ic->irc; 396 397 if( user_findhandle( ic, handle ) ) 398 { 399 if( set_getbool( &irc->set, "debug" ) ) 400 imcb_log( ic, "User already exists, ignoring add request: %s", handle ); 401 402 return; 403 404 /* Buddy seems to exist already. Let's ignore this request then... 405 Eventually subsequent calls to this function *should* be possible 406 when a buddy is in multiple groups. But for now BitlBee doesn't 407 even support groups so let's silently ignore this for now. */ 408 } 409 410 memset( nick, 0, MAX_NICK_LENGTH + 1 ); 411 strcpy( nick, nick_get( ic->acc, handle ) ); 412 413 u = user_add( ic->irc, nick ); 414 415 // if( !realname || !*realname ) realname = nick; 416 // u->realname = g_strdup( realname ); 417 418 if( ( s = strchr( handle, '@' ) ) ) 419 { 420 u->host = g_strdup( s + 1 ); 421 u->user = g_strndup( handle, s - handle ); 422 } 423 else if( ic->acc->server ) 424 { 425 u->host = g_strdup( ic->acc->server ); 426 u->user = g_strdup( handle ); 427 428 /* s/ /_/ ... important for AOL screennames */ 429 for( s = u->user; *s; s ++ ) 430 if( *s == ' ' ) 431 *s = '_'; 432 } 433 else 434 { 435 u->host = g_strdup( ic->acc->prpl->name ); 436 u->user = g_strdup( handle ); 437 } 438 439 u->ic = ic; 440 u->handle = g_strdup( handle ); 441 if( group ) u->group = g_strdup( group ); 442 u->send_handler = buddy_send_handler; 443 u->last_typing_notice = 0; 444 } 445 446 struct buddy *imcb_find_buddy( struct im_connection *ic, char *handle ) 447 { 448 static struct buddy b[1]; 449 user_t *u; 450 451 u = user_findhandle( ic, handle ); 452 453 if( !u ) 454 return( NULL ); 455 456 memset( b, 0, sizeof( b ) ); 457 strncpy( b->name, handle, 80 ); 458 strncpy( b->show, u->realname, BUDDY_ALIAS_MAXLEN ); 459 b->present = u->online; 460 b->ic = u->ic; 461 462 return( b ); 463 } 464 465 void imcb_rename_buddy( struct im_connection *ic, const char *handle, const char *realname ) 466 { 467 user_t *u = user_findhandle( ic, handle ); 468 char *set; 469 470 if( !u || !realname ) return; 471 472 if( g_strcasecmp( u->realname, realname ) != 0 ) 473 { 474 if( u->realname != u->nick ) g_free( u->realname ); 475 476 u->realname = g_strdup( realname ); 477 478 if( ( ic->flags & OPT_LOGGED_IN ) && set_getbool( &ic->irc->set, "display_namechanges" ) ) 479 imcb_log( ic, "User `%s' changed name to `%s'", u->nick, u->realname ); 480 } 481 482 set = set_getstr( &ic->acc->set, "nick_source" ); 483 if( strcmp( set, "handle" ) != 0 ) 484 { 485 char *name = g_strdup( realname ); 486 487 if( strcmp( set, "first_name" ) == 0 ) 488 { 489 int i; 490 for( i = 0; name[i] && !isspace( name[i] ); i ++ ) {} 491 name[i] = '\0'; 492 } 493 494 imcb_buddy_nick_hint( ic, handle, name ); 495 496 g_free( name ); 400 497 } 401 498 } … … 403 500 void imcb_remove_buddy( struct im_connection *ic, const char *handle, char *group ) 404 501 { 405 bee_user_free( ic->bee, bee_user_by_handle( ic->bee, ic, handle ) ); 502 user_t *u; 503 504 if( ( u = user_findhandle( ic, handle ) ) ) 505 user_del( ic->irc, u->nick ); 406 506 } 407 507 … … 410 510 void imcb_buddy_nick_hint( struct im_connection *ic, const char *handle, const char *nick ) 411 511 { 412 #if 0413 512 user_t *u = user_findhandle( ic, handle ); 414 513 char newnick[MAX_NICK_LENGTH+1], *orig_nick; … … 425 524 /* Some processing to make sure this string is a valid IRC nickname. */ 426 525 nick_strip( newnick ); 427 if( set_getbool( &ic-> bee->set, "lcnicks" ) )526 if( set_getbool( &ic->irc->set, "lcnicks" ) ) 428 527 nick_lc( newnick ); 429 528 … … 442 541 } 443 542 } 444 #endif445 543 } 446 544 … … 487 585 data->ic = ic; 488 586 data->handle = g_strdup( handle ); 489 query_add( (irc_t *) ic->bee->ui_data, ic, s, 490 imcb_ask_auth_cb_yes, imcb_ask_auth_cb_no, data ); 587 query_add( ic->irc, ic, s, imcb_ask_auth_cb_yes, imcb_ask_auth_cb_no, data ); 491 588 } 492 589 … … 513 610 514 611 /* TODO: Make a setting for this! */ 515 if( bee_user_by_handle( ic->bee,ic, handle ) != NULL )612 if( user_findhandle( ic, handle ) != NULL ) 516 613 return; 517 614 … … 520 617 data->ic = ic; 521 618 data->handle = g_strdup( handle ); 522 query_add( (irc_t *) ic->bee->ui_data, ic, s, 523 imcb_ask_add_cb_yes, imcb_ask_add_cb_no, data ); 524 } 525 526 struct bee_user *imcb_buddy_by_handle( struct im_connection *ic, const char *handle ) 527 { 528 return bee_user_by_handle( ic->bee, ic, handle ); 619 query_add( ic->irc, ic, s, imcb_ask_add_cb_yes, imcb_ask_add_cb_no, data ); 620 } 621 622 623 /* server.c */ 624 625 void imcb_buddy_status( struct im_connection *ic, const char *handle, int flags, const char *state, const char *message ) 626 { 627 user_t *u; 628 int oa, oo; 629 630 u = user_findhandle( ic, (char*) handle ); 631 632 if( !u ) 633 { 634 if( g_strcasecmp( set_getstr( &ic->irc->set, "handle_unknown" ), "add" ) == 0 ) 635 { 636 imcb_add_buddy( ic, (char*) handle, NULL ); 637 u = user_findhandle( ic, (char*) handle ); 638 } 639 else 640 { 641 if( set_getbool( &ic->irc->set, "debug" ) || g_strcasecmp( set_getstr( &ic->irc->set, "handle_unknown" ), "ignore" ) != 0 ) 642 { 643 imcb_log( ic, "imcb_buddy_status() for unknown handle %s:", handle ); 644 imcb_log( ic, "flags = %d, state = %s, message = %s", flags, 645 state ? state : "NULL", message ? message : "NULL" ); 646 } 647 648 return; 649 } 650 } 651 652 oa = u->away != NULL; 653 oo = u->online; 654 655 g_free( u->away ); 656 g_free( u->status_msg ); 657 u->away = u->status_msg = NULL; 658 659 if( set_getbool( &ic->irc->set, "show_offline" ) && !u->online ) 660 { 661 /* always set users as online */ 662 irc_spawn( ic->irc, u ); 663 u->online = 1; 664 if( !( flags & OPT_LOGGED_IN ) ) 665 { 666 /* set away message if user isn't really online */ 667 u->away = g_strdup( "User is offline" ); 668 } 669 } 670 else if( ( flags & OPT_LOGGED_IN ) && !u->online ) 671 { 672 irc_spawn( ic->irc, u ); 673 u->online = 1; 674 } 675 else if( !( flags & OPT_LOGGED_IN ) && u->online ) 676 { 677 struct groupchat *c; 678 679 if( set_getbool( &ic->irc->set, "show_offline" ) ) 680 { 681 /* keep offline users in channel and set away message to "offline" */ 682 u->away = g_strdup( "User is offline" ); 683 684 /* Keep showing him/her in the control channel but not in groupchats. */ 685 for( c = ic->groupchats; c; c = c->next ) 686 { 687 if( remove_chat_buddy_silent( c, handle ) && c->joined ) 688 irc_part( c->ic->irc, u, c->channel ); 689 } 690 } 691 else 692 { 693 /* kill offline users */ 694 irc_kill( ic->irc, u ); 695 u->online = 0; 696 697 /* Remove him/her from the groupchats to prevent PART messages after he/she QUIT already */ 698 for( c = ic->groupchats; c; c = c->next ) 699 remove_chat_buddy_silent( c, handle ); 700 } 701 } 702 703 if( flags & OPT_AWAY ) 704 { 705 if( state && message ) 706 { 707 u->away = g_strdup_printf( "%s (%s)", state, message ); 708 } 709 else if( state ) 710 { 711 u->away = g_strdup( state ); 712 } 713 else if( message ) 714 { 715 u->away = g_strdup( message ); 716 } 717 else 718 { 719 u->away = g_strdup( "Away" ); 720 } 721 } 722 else 723 { 724 u->status_msg = g_strdup( message ); 725 } 726 727 /* early if-clause for show_offline even if there is some redundant code here because this isn't LISP but C ;) */ 728 if( set_getbool( &ic->irc->set, "show_offline" ) && set_getbool( &ic->irc->set, "away_devoice" ) ) 729 { 730 char *from; 731 732 if( set_getbool( &ic->irc->set, "simulate_netsplit" ) ) 733 { 734 from = g_strdup( ic->irc->myhost ); 735 } 736 else 737 { 738 from = g_strdup_printf( "%s!%s@%s", ic->irc->mynick, ic->irc->mynick, 739 ic->irc->myhost ); 740 } 741 742 /* if we use show_offline, we op online users, voice away users, and devoice/deop offline users */ 743 if( flags & OPT_LOGGED_IN ) 744 { 745 /* user is "online" (either really online or away) */ 746 irc_write( ic->irc, ":%s MODE %s %cv%co %s %s", from, ic->irc->channel, 747 u->away?'+':'-', u->away?'-':'+', u->nick, u->nick ); 748 } 749 else 750 { 751 /* user is offline */ 752 irc_write( ic->irc, ":%s MODE %s -vo %s %s", from, ic->irc->channel, u->nick, u->nick ); 753 } 754 } 755 else 756 { 757 /* LISPy... */ 758 if( ( set_getbool( &ic->irc->set, "away_devoice" ) ) && /* Don't do a thing when user doesn't want it */ 759 ( u->online ) && /* Don't touch offline people */ 760 ( ( ( u->online != oo ) && !u->away ) || /* Voice joining people */ 761 ( ( u->online == oo ) && ( oa == !u->away ) ) ) ) /* (De)voice people changing state */ 762 { 763 char *from; 764 765 if( set_getbool( &ic->irc->set, "simulate_netsplit" ) ) 766 { 767 from = g_strdup( ic->irc->myhost ); 768 } 769 else 770 { 771 from = g_strdup_printf( "%s!%s@%s", ic->irc->mynick, ic->irc->mynick, 772 ic->irc->myhost ); 773 } 774 irc_write( ic->irc, ":%s MODE %s %cv %s", from, ic->irc->channel, 775 u->away?'-':'+', u->nick ); 776 g_free( from ); 777 } 778 } 779 } 780 781 void imcb_buddy_msg( struct im_connection *ic, const char *handle, char *msg, uint32_t flags, time_t sent_at ) 782 { 783 irc_t *irc = ic->irc; 784 char *wrapped, *ts = NULL; 785 user_t *u; 786 787 u = user_findhandle( ic, handle ); 788 789 if( !u ) 790 { 791 char *h = set_getstr( &irc->set, "handle_unknown" ); 792 793 if( g_strcasecmp( h, "ignore" ) == 0 ) 794 { 795 if( set_getbool( &irc->set, "debug" ) ) 796 imcb_log( ic, "Ignoring message from unknown handle %s", handle ); 797 798 return; 799 } 800 else if( g_strncasecmp( h, "add", 3 ) == 0 ) 801 { 802 int private = set_getbool( &irc->set, "private" ); 803 804 if( h[3] ) 805 { 806 if( g_strcasecmp( h + 3, "_private" ) == 0 ) 807 private = 1; 808 else if( g_strcasecmp( h + 3, "_channel" ) == 0 ) 809 private = 0; 810 } 811 812 imcb_add_buddy( ic, handle, NULL ); 813 u = user_findhandle( ic, handle ); 814 u->is_private = private; 815 } 816 else 817 { 818 imcb_log( ic, "Message from unknown handle %s:", handle ); 819 u = user_find( irc, irc->mynick ); 820 } 821 } 822 823 if( ( g_strcasecmp( set_getstr( &ic->irc->set, "strip_html" ), "always" ) == 0 ) || 824 ( ( ic->flags & OPT_DOES_HTML ) && set_getbool( &ic->irc->set, "strip_html" ) ) ) 825 strip_html( msg ); 826 827 if( set_getbool( &ic->irc->set, "display_timestamps" ) && 828 ( ts = format_timestamp( irc, sent_at ) ) ) 829 { 830 char *new = g_strconcat( ts, msg, NULL ); 831 g_free( ts ); 832 ts = msg = new; 833 } 834 835 wrapped = word_wrap( msg, 425 ); 836 irc_msgfrom( irc, u->nick, wrapped ); 837 g_free( wrapped ); 838 g_free( ts ); 839 } 840 841 void imcb_buddy_typing( struct im_connection *ic, char *handle, uint32_t flags ) 842 { 843 user_t *u; 844 845 if( !set_getbool( &ic->irc->set, "typing_notice" ) ) 846 return; 847 848 if( ( u = user_findhandle( ic, handle ) ) ) 849 { 850 char buf[256]; 851 852 g_snprintf( buf, 256, "\1TYPING %d\1", ( flags >> 8 ) & 3 ); 853 irc_privmsg( ic->irc, u, "PRIVMSG", ic->irc->nick, NULL, buf ); 854 } 855 } 856 857 struct groupchat *imcb_chat_new( struct im_connection *ic, const char *handle ) 858 { 859 struct groupchat *c; 860 861 /* This one just creates the conversation structure, user won't see anything yet */ 862 863 if( ic->groupchats ) 864 { 865 for( c = ic->groupchats; c->next; c = c->next ); 866 c = c->next = g_new0( struct groupchat, 1 ); 867 } 868 else 869 ic->groupchats = c = g_new0( struct groupchat, 1 ); 870 871 c->ic = ic; 872 c->title = g_strdup( handle ); 873 c->channel = g_strdup_printf( "&chat_%03d", ic->irc->c_id++ ); 874 c->topic = g_strdup_printf( "BitlBee groupchat: \"%s\". Please keep in mind that root-commands won't work here. Have fun!", c->title ); 875 876 if( set_getbool( &ic->irc->set, "debug" ) ) 877 imcb_log( ic, "Creating new conversation: (id=%p,handle=%s)", c, handle ); 878 879 return c; 880 } 881 882 void imcb_chat_name_hint( struct groupchat *c, const char *name ) 883 { 884 if( !c->joined ) 885 { 886 struct im_connection *ic = c->ic; 887 char stripped[MAX_NICK_LENGTH+1], *full_name; 888 889 strncpy( stripped, name, MAX_NICK_LENGTH ); 890 stripped[MAX_NICK_LENGTH] = '\0'; 891 nick_strip( stripped ); 892 if( set_getbool( &ic->irc->set, "lcnicks" ) ) 893 nick_lc( stripped ); 894 895 full_name = g_strdup_printf( "&%s", stripped ); 896 897 if( stripped[0] && 898 nick_cmp( stripped, ic->irc->channel + 1 ) != 0 && 899 irc_chat_by_channel( ic->irc, full_name ) == NULL ) 900 { 901 g_free( c->channel ); 902 c->channel = full_name; 903 } 904 else 905 { 906 g_free( full_name ); 907 } 908 } 909 } 910 911 void imcb_chat_free( struct groupchat *c ) 912 { 913 struct im_connection *ic = c->ic; 914 struct groupchat *l; 915 GList *ir; 916 917 if( set_getbool( &ic->irc->set, "debug" ) ) 918 imcb_log( ic, "You were removed from conversation %p", c ); 919 920 if( c ) 921 { 922 if( c->joined ) 923 { 924 user_t *u, *r; 925 926 r = user_find( ic->irc, ic->irc->mynick ); 927 irc_privmsg( ic->irc, r, "PRIVMSG", c->channel, "", "Cleaning up channel, bye!" ); 928 929 u = user_find( ic->irc, ic->irc->nick ); 930 irc_kick( ic->irc, u, c->channel, r ); 931 /* irc_part( ic->irc, u, c->channel ); */ 932 } 933 934 /* Find the previous chat in the linked list. */ 935 for( l = ic->groupchats; l && l->next != c; l = l->next ); 936 937 if( l ) 938 l->next = c->next; 939 else 940 ic->groupchats = c->next; 941 942 for( ir = c->in_room; ir; ir = ir->next ) 943 g_free( ir->data ); 944 g_list_free( c->in_room ); 945 g_free( c->channel ); 946 g_free( c->title ); 947 g_free( c->topic ); 948 g_free( c ); 949 } 950 } 951 952 void imcb_chat_msg( struct groupchat *c, const char *who, char *msg, uint32_t flags, time_t sent_at ) 953 { 954 struct im_connection *ic = c->ic; 955 char *wrapped; 956 user_t *u; 957 958 /* Gaim sends own messages through this too. IRC doesn't want this, so kill them */ 959 if( g_strcasecmp( who, ic->acc->user ) == 0 ) 960 return; 961 962 u = user_findhandle( ic, who ); 963 964 if( ( g_strcasecmp( set_getstr( &ic->irc->set, "strip_html" ), "always" ) == 0 ) || 965 ( ( ic->flags & OPT_DOES_HTML ) && set_getbool( &ic->irc->set, "strip_html" ) ) ) 966 strip_html( msg ); 967 968 wrapped = word_wrap( msg, 425 ); 969 if( c && u ) 970 { 971 char *ts = NULL; 972 if( set_getbool( &ic->irc->set, "display_timestamps" ) ) 973 ts = format_timestamp( ic->irc, sent_at ); 974 irc_privmsg( ic->irc, u, "PRIVMSG", c->channel, ts ? : "", wrapped ); 975 g_free( ts ); 976 } 977 else 978 { 979 imcb_log( ic, "Message from/to conversation %s@%p (unknown conv/user): %s", who, c, wrapped ); 980 } 981 g_free( wrapped ); 982 } 983 984 void imcb_chat_log( struct groupchat *c, char *format, ... ) 985 { 986 irc_t *irc = c->ic->irc; 987 va_list params; 988 char *text; 989 user_t *u; 990 991 va_start( params, format ); 992 text = g_strdup_vprintf( format, params ); 993 va_end( params ); 994 995 u = user_find( irc, irc->mynick ); 996 997 irc_privmsg( irc, u, "PRIVMSG", c->channel, "System message: ", text ); 998 999 g_free( text ); 1000 } 1001 1002 void imcb_chat_topic( struct groupchat *c, char *who, char *topic, time_t set_at ) 1003 { 1004 struct im_connection *ic = c->ic; 1005 user_t *u = NULL; 1006 1007 if( who == NULL) 1008 u = user_find( ic->irc, ic->irc->mynick ); 1009 else if( g_strcasecmp( who, ic->acc->user ) == 0 ) 1010 u = user_find( ic->irc, ic->irc->nick ); 1011 else 1012 u = user_findhandle( ic, who ); 1013 1014 if( ( g_strcasecmp( set_getstr( &ic->irc->set, "strip_html" ), "always" ) == 0 ) || 1015 ( ( ic->flags & OPT_DOES_HTML ) && set_getbool( &ic->irc->set, "strip_html" ) ) ) 1016 strip_html( topic ); 1017 1018 g_free( c->topic ); 1019 c->topic = g_strdup( topic ); 1020 1021 if( c->joined && u ) 1022 irc_write( ic->irc, ":%s!%s@%s TOPIC %s :%s", u->nick, u->user, u->host, c->channel, topic ); 1023 } 1024 1025 1026 /* buddy_chat.c */ 1027 1028 void imcb_chat_add_buddy( struct groupchat *b, const char *handle ) 1029 { 1030 user_t *u = user_findhandle( b->ic, handle ); 1031 int me = 0; 1032 1033 if( set_getbool( &b->ic->irc->set, "debug" ) ) 1034 imcb_log( b->ic, "User %s added to conversation %p", handle, b ); 1035 1036 /* It might be yourself! */ 1037 if( b->ic->acc->prpl->handle_cmp( handle, b->ic->acc->user ) == 0 ) 1038 { 1039 u = user_find( b->ic->irc, b->ic->irc->nick ); 1040 if( !b->joined ) 1041 irc_join( b->ic->irc, u, b->channel ); 1042 b->joined = me = 1; 1043 } 1044 1045 /* Most protocols allow people to join, even when they're not in 1046 your contact list. Try to handle that here */ 1047 if( !u ) 1048 { 1049 imcb_add_buddy( b->ic, handle, NULL ); 1050 u = user_findhandle( b->ic, handle ); 1051 } 1052 1053 /* Add the handle to the room userlist, if it's not 'me' */ 1054 if( !me ) 1055 { 1056 if( b->joined ) 1057 irc_join( b->ic->irc, u, b->channel ); 1058 b->in_room = g_list_append( b->in_room, g_strdup( handle ) ); 1059 } 1060 } 1061 1062 /* This function is one BIG hack... :-( EREWRITE */ 1063 void imcb_chat_remove_buddy( struct groupchat *b, const char *handle, const char *reason ) 1064 { 1065 user_t *u; 1066 int me = 0; 1067 1068 if( set_getbool( &b->ic->irc->set, "debug" ) ) 1069 imcb_log( b->ic, "User %s removed from conversation %p (%s)", handle, b, reason ? reason : "" ); 1070 1071 /* It might be yourself! */ 1072 if( g_strcasecmp( handle, b->ic->acc->user ) == 0 ) 1073 { 1074 if( b->joined == 0 ) 1075 return; 1076 1077 u = user_find( b->ic->irc, b->ic->irc->nick ); 1078 b->joined = 0; 1079 me = 1; 1080 } 1081 else 1082 { 1083 u = user_findhandle( b->ic, handle ); 1084 } 1085 1086 if( me || ( remove_chat_buddy_silent( b, handle ) && b->joined && u ) ) 1087 irc_part( b->ic->irc, u, b->channel ); 1088 } 1089 1090 static int remove_chat_buddy_silent( struct groupchat *b, const char *handle ) 1091 { 1092 GList *i; 1093 1094 /* Find the handle in the room userlist and shoot it */ 1095 i = b->in_room; 1096 while( i ) 1097 { 1098 if( g_strcasecmp( handle, i->data ) == 0 ) 1099 { 1100 g_free( i->data ); 1101 b->in_room = g_list_remove( b->in_room, i->data ); 1102 return( 1 ); 1103 } 1104 1105 i = i->next; 1106 } 1107 1108 return( 0 ); 529 1109 } 530 1110 531 1111 532 1112 /* Misc. BitlBee stuff which shouldn't really be here */ 533 #if 0 1113 534 1114 char *set_eval_away_devoice( set_t *set, char *value ) 535 1115 { … … 544 1124 /* Horror.... */ 545 1125 546 if( st != set_getbool( &irc-> b->set, "away_devoice" ) )1126 if( st != set_getbool( &irc->set, "away_devoice" ) ) 547 1127 { 548 1128 char list[80] = ""; … … 586 1166 return value; 587 1167 } 588 #endif 1168 1169 char *set_eval_timezone( set_t *set, char *value ) 1170 { 1171 char *s; 1172 1173 if( strcmp( value, "local" ) == 0 || 1174 strcmp( value, "gmt" ) == 0 || strcmp( value, "utc" ) == 0 ) 1175 return value; 1176 1177 /* Otherwise: +/- at the beginning optional, then one or more numbers, 1178 possibly followed by a colon and more numbers. Don't bother bound- 1179 checking them since users are free to shoot themselves in the foot. */ 1180 s = value; 1181 if( *s == '+' || *s == '-' ) 1182 s ++; 1183 1184 /* \d+ */ 1185 if( !isdigit( *s ) ) 1186 return SET_INVALID; 1187 while( *s && isdigit( *s ) ) s ++; 1188 1189 /* EOS? */ 1190 if( *s == '\0' ) 1191 return value; 1192 1193 /* Otherwise, colon */ 1194 if( *s != ':' ) 1195 return SET_INVALID; 1196 s ++; 1197 1198 /* \d+ */ 1199 if( !isdigit( *s ) ) 1200 return SET_INVALID; 1201 while( *s && isdigit( *s ) ) s ++; 1202 1203 /* EOS */ 1204 return *s == '\0' ? value : SET_INVALID; 1205 } 1206 1207 static char *format_timestamp( irc_t *irc, time_t msg_ts ) 1208 { 1209 time_t now_ts = time( NULL ); 1210 struct tm now, msg; 1211 char *set; 1212 1213 /* If the timestamp is <= 0 or less than a minute ago, discard it as 1214 it doesn't seem to add to much useful info and/or might be noise. */ 1215 if( msg_ts <= 0 || msg_ts > now_ts - 60 ) 1216 return NULL; 1217 1218 set = set_getstr( &irc->set, "timezone" ); 1219 if( strcmp( set, "local" ) == 0 ) 1220 { 1221 localtime_r( &now_ts, &now ); 1222 localtime_r( &msg_ts, &msg ); 1223 } 1224 else 1225 { 1226 int hr, min = 0, sign = 60; 1227 1228 if( set[0] == '-' ) 1229 { 1230 sign *= -1; 1231 set ++; 1232 } 1233 else if( set[0] == '+' ) 1234 { 1235 set ++; 1236 } 1237 1238 if( sscanf( set, "%d:%d", &hr, &min ) >= 1 ) 1239 { 1240 msg_ts += sign * ( hr * 60 + min ); 1241 now_ts += sign * ( hr * 60 + min ); 1242 } 1243 1244 gmtime_r( &now_ts, &now ); 1245 gmtime_r( &msg_ts, &msg ); 1246 } 1247 1248 if( msg.tm_year == now.tm_year && msg.tm_yday == now.tm_yday ) 1249 return g_strdup_printf( "\x02[\x02\x02\x02%02d:%02d:%02d\x02]\x02 ", 1250 msg.tm_hour, msg.tm_min, msg.tm_sec ); 1251 else 1252 return g_strdup_printf( "\x02[\x02\x02\x02%04d-%02d-%02d " 1253 "%02d:%02d:%02d\x02]\x02 ", 1254 msg.tm_year + 1900, msg.tm_mon + 1, msg.tm_mday, 1255 msg.tm_hour, msg.tm_min, msg.tm_sec ); 1256 } 589 1257 590 1258 /* The plan is to not allow straight calls to prpl functions anymore, but do 591 1259 them all from some wrappers. We'll start to define some down here: */ 1260 1261 int imc_buddy_msg( struct im_connection *ic, char *handle, char *msg, int flags ) 1262 { 1263 char *buf = NULL; 1264 int st; 1265 1266 if( ( ic->flags & OPT_DOES_HTML ) && ( g_strncasecmp( msg, "<html>", 6 ) != 0 ) ) 1267 { 1268 buf = escape_html( msg ); 1269 msg = buf; 1270 } 1271 1272 st = ic->acc->prpl->buddy_msg( ic, handle, msg, flags ); 1273 g_free( buf ); 1274 1275 return st; 1276 } 592 1277 593 1278 int imc_chat_msg( struct groupchat *c, char *msg, int flags ) … … 618 1303 619 1304 away = set_getstr( &ic->acc->set, "away" ) ? 620 : set_getstr( &ic-> bee->set, "away" );1305 : set_getstr( &ic->irc->set, "away" ); 621 1306 if( away && *away ) 622 1307 { … … 629 1314 away = NULL; 630 1315 msg = set_getstr( &ic->acc->set, "status" ) ? 631 : set_getstr( &ic-> bee->set, "status" );1316 : set_getstr( &ic->irc->set, "status" ); 632 1317 } 633 1318
Note: See TracChangeset
for help on using the changeset viewer.