Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • protocols/nogaim.c

    r839189b r6ef9065  
    3838#include "chat.h"
    3939
    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 
    4340GSList *connections;
    4441
     
    9289}
    9390#endif
    94 
    95 /* nogaim.c */
    9691
    9792GList *protocols = NULL;
     
    117112{
    118113        GList *gl;
    119         for (gl = protocols; gl; gl = gl->next)
     114       
     115        for( gl = protocols; gl; gl = gl->next )
    120116        {
    121117                struct prpl *proto = gl->data;
    122                 if(!g_strcasecmp(proto->name, name))
     118               
     119                if( g_strcasecmp( proto->name, name ) == 0 )
    123120                        return proto;
    124121        }
     122       
    125123        return NULL;
    126124}
    127125
    128 /* nogaim.c */
    129126void nogaim_init()
    130127{
     
    134131        extern void jabber_initmodule();
    135132        extern void twitter_initmodule();
     133        extern void purple_initmodule();
    136134
    137135#ifdef WITH_MSN
     
    155153#endif
    156154
     155#ifdef WITH_PURPLE
     156        purple_initmodule();
     157#endif
     158
    157159#ifdef WITH_PLUGINS
    158160        load_plugins();
     
    162164GSList *get_connections() { return connections; }
    163165
    164 /* multi.c */
    165 
    166166struct im_connection *imcb_new( account_t *acc )
    167167{
     
    170170        ic = g_new0( struct im_connection, 1 );
    171171       
    172         ic->irc = acc->irc;
     172        ic->bee = acc->bee;
    173173        ic->acc = acc;
    174174        acc->ic = ic;
     
    184184       
    185185        /* Destroy the pointer to this connection from the account list */
    186         for( a = ic->irc->accounts; a; a = a->next )
     186        for( a = ic->bee->accounts; a; a = a->next )
    187187                if( a->ic == ic )
    188188                {
     
    205205        va_end( params );
    206206
    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" ) ) )
     207        if( ( g_strcasecmp( set_getstr( &ic->bee->set, "strip_html" ), "always" ) == 0 ) ||
     208            ( ( ic->flags & OPT_DOES_HTML ) && set_getbool( &ic->bee->set, "strip_html" ) ) )
    209209                strip_html( text );
    210210       
    211211        /* Try to find a different connection on the same protocol. */
    212         for( a = ic->irc->accounts; a; a = a->next )
     212        for( a = ic->bee->accounts; a; a = a->next )
    213213                if( a->prpl == ic->acc->prpl && a->ic != ic )
    214214                        break;
     
    216216        /* If we found one, include the screenname in the message. */
    217217        if( a )
    218                 irc_usermsg( ic->irc, "%s(%s) - %s", ic->acc->prpl->name, ic->acc->user, text );
     218                /* FIXME(wilmer): ui_log callback or so */
     219                irc_usermsg( ic->bee->ui_data, "%s(%s) - %s", ic->acc->prpl->name, ic->acc->user, text );
    219220        else
    220                 irc_usermsg( ic->irc, "%s - %s", ic->acc->prpl->name, text );
     221                irc_usermsg( ic->bee->ui_data, "%s - %s", ic->acc->prpl->name, text );
    221222       
    222223        g_free( text );
     
    269270void imcb_connected( struct im_connection *ic )
    270271{
    271         irc_t *irc = ic->irc;
    272         struct chat *c;
    273         user_t *u;
    274        
    275272        /* MSN servers sometimes redirect you to a different server and do
    276273           the whole login sequence again, so these "late" calls to this
     
    279276                return;
    280277       
    281         u = user_find( ic->irc, ic->irc->nick );
    282        
    283278        imcb_log( ic, "Logged in" );
    284279       
     
    293288        ic->acc->auto_reconnect_delay = 0;
    294289       
     290        /*
    295291        for( c = irc->chatrooms; c; c = c->next )
    296292        {
     
    301297                        chat_join( irc, c, NULL );
    302298        }
     299        */
    303300}
    304301
     
    308305       
    309306        a->reconnect = 0;
    310         account_on( a->irc, a );
     307        account_on( a->bee, a );
    311308       
    312309        return( FALSE );        /* Only have to run the timeout once */
     
    321318void imc_logout( struct im_connection *ic, int allow_reconnect )
    322319{
    323         irc_t *irc = ic->irc;
    324         user_t *t, *u;
     320        bee_t *bee = ic->bee;
    325321        account_t *a;
     322        GSList *l;
    326323        int delay;
    327324       
     
    343340        ic->away = NULL;
    344341       
    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 )
     342        for( l = bee->users; l; )
     343        {
     344                bee_user_t *bu = l->data;
     345                GSList *next = l->next;
     346               
     347                if( bu->ic == ic )
     348                        bee_user_free( bee, bu );
     349               
     350                l = next;
     351        }
     352       
     353        query_del_by_conn( (irc_t*) ic->bee->ui_data, ic );
     354       
     355        for( a = bee->accounts; a; a = a->next )
    361356                if( a->ic == ic )
    362357                        break;
     
    366361                /* Uhm... This is very sick. */
    367362        }
    368         else if( allow_reconnect && set_getbool( &irc->set, "auto_reconnect" ) &&
     363        else if( allow_reconnect && set_getbool( &bee->set, "auto_reconnect" ) &&
    369364                 set_getbool( &a->set, "auto_reconnect" ) &&
    370365                 ( delay = account_reconnect_delay( a ) ) > 0 )
     
    377372}
    378373
    379 
    380 /* dialogs.c */
    381 
    382374void imcb_ask( struct im_connection *ic, char *msg, void *data,
    383375               query_callback doit, query_callback dont )
    384376{
    385         query_add( ic->irc, ic, msg, doit, dont, data );
    386 }
    387 
    388 
    389 /* list.c */
     377        query_add( (irc_t *) ic->bee->ui_data, ic, msg, doit, dont, data );
     378}
    390379
    391380void imcb_add_buddy( struct im_connection *ic, const char *handle, const char *group )
    392381{
    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 );
     382        bee_user_t *bu;
     383        bee_t *bee = ic->bee;
     384       
     385        if( !( bu = bee_user_by_handle( bee, ic, handle ) ) )
     386                bu = bee_user_new( bee, ic, handle, 0 );
     387       
     388        bu->group = bee_group_by_name( bee, group, TRUE );
     389       
     390        if( bee->ui->user_group )
     391                bee->ui->user_group( bee, bu );
     392}
     393
     394void imcb_rename_buddy( struct im_connection *ic, const char *handle, const char *fullname )
     395{
     396        bee_t *bee = ic->bee;
     397        bee_user_t *bu = bee_user_by_handle( bee, ic, handle );
     398       
     399        if( !bu || !fullname ) return;
     400       
     401        if( !bu->fullname || strcmp( bu->fullname, fullname ) != 0 )
     402        {
     403                g_free( bu->fullname );
     404                bu->fullname = g_strdup( fullname );
    401405               
    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 );
     406                if( bee->ui->user_fullname )
     407                        bee->ui->user_fullname( bee, bu );
    497408        }
    498409}
     
    500411void imcb_remove_buddy( struct im_connection *ic, const char *handle, char *group )
    501412{
    502         user_t *u;
    503        
    504         if( ( u = user_findhandle( ic, handle ) ) )
    505                 user_del( ic->irc, u->nick );
     413        bee_user_free( ic->bee, bee_user_by_handle( ic->bee, ic, handle ) );
    506414}
    507415
     
    510418void imcb_buddy_nick_hint( struct im_connection *ic, const char *handle, const char *nick )
    511419{
    512         user_t *u = user_findhandle( ic, handle );
    513         char newnick[MAX_NICK_LENGTH+1], *orig_nick;
    514        
    515         if( u && !u->online && !nick_saved( ic->acc, handle ) )
    516         {
    517                 /* Only do this if the person isn't online yet (which should
    518                    be the case if we just added it) and if the user hasn't
    519                    assigned a nickname to this buddy already. */
    520                
    521                 strncpy( newnick, nick, MAX_NICK_LENGTH );
    522                 newnick[MAX_NICK_LENGTH] = 0;
    523                
    524                 /* Some processing to make sure this string is a valid IRC nickname. */
    525                 nick_strip( newnick );
    526                 if( set_getbool( &ic->irc->set, "lcnicks" ) )
    527                         nick_lc( newnick );
    528                
    529                 if( strcmp( u->nick, newnick ) != 0 )
    530                 {
    531                         /* Only do this if newnick is different from the current one.
    532                            If rejoining a channel, maybe we got this nick already
    533                            (and dedupe would only add an underscore. */
    534                         nick_dedupe( ic->acc, handle, newnick );
    535                        
    536                         /* u->nick will be freed halfway the process, so it can't be
    537                            passed as an argument. */
    538                         orig_nick = g_strdup( u->nick );
    539                         user_rename( ic->irc, orig_nick, newnick );
    540                         g_free( orig_nick );
    541                 }
    542         }
     420        bee_t *bee = ic->bee;
     421        bee_user_t *bu = bee_user_by_handle( bee, ic, handle );
     422       
     423        if( !bu || !nick ) return;
     424       
     425        if( bee->ui->user_nick_hint )
     426                bee->ui->user_nick_hint( bee, bu, nick );
    543427}
    544428
     
    585469        data->ic = ic;
    586470        data->handle = g_strdup( handle );
    587         query_add( ic->irc, ic, s, imcb_ask_auth_cb_yes, imcb_ask_auth_cb_no, data );
     471        query_add( (irc_t *) ic->bee->ui_data, ic, s,
     472                   imcb_ask_auth_cb_yes, imcb_ask_auth_cb_no, data );
    588473}
    589474
     
    610495       
    611496        /* TODO: Make a setting for this! */
    612         if( user_findhandle( ic, handle ) != NULL )
     497        if( bee_user_by_handle( ic->bee, ic, handle ) != NULL )
    613498                return;
    614499       
     
    617502        data->ic = ic;
    618503        data->handle = g_strdup( 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 );
    1109 }
    1110 
    1111 
    1112 /* Misc. BitlBee stuff which shouldn't really be here */
    1113 
    1114 char *set_eval_away_devoice( set_t *set, char *value )
    1115 {
    1116         irc_t *irc = set->data;
    1117         int st;
    1118        
    1119         if( !is_bool( value ) )
    1120                 return SET_INVALID;
    1121        
    1122         st = bool2int( value );
    1123        
    1124         /* Horror.... */
    1125        
    1126         if( st != set_getbool( &irc->set, "away_devoice" ) )
    1127         {
    1128                 char list[80] = "";
    1129                 user_t *u = irc->users;
    1130                 int i = 0, count = 0;
    1131                 char pm;
    1132                 char v[80];
    1133                
    1134                 if( st )
    1135                         pm = '+';
    1136                 else
    1137                         pm = '-';
    1138                
    1139                 while( u )
    1140                 {
    1141                         if( u->ic && u->online && !u->away )
    1142                         {
    1143                                 if( ( strlen( list ) + strlen( u->nick ) ) >= 79 )
    1144                                 {
    1145                                         for( i = 0; i < count; v[i++] = 'v' ); v[i] = 0;
    1146                                         irc_write( irc, ":%s MODE %s %c%s%s",
    1147                                                    irc->myhost,
    1148                                                    irc->channel, pm, v, list );
    1149                                        
    1150                                         *list = 0;
    1151                                         count = 0;
    1152                                 }
    1153                                
    1154                                 sprintf( list + strlen( list ), " %s", u->nick );
    1155                                 count ++;
    1156                         }
    1157                         u = u->next;
    1158                 }
    1159                
    1160                 /* $v = 'v' x $i */
    1161                 for( i = 0; i < count; v[i++] = 'v' ); v[i] = 0;
    1162                 irc_write( irc, ":%s MODE %s %c%s%s", irc->myhost,
    1163                                                             irc->channel, pm, v, list );
    1164         }
    1165        
    1166         return value;
    1167 }
    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 );
     504        query_add( (irc_t *) ic->bee->ui_data, ic, s,
     505                   imcb_ask_add_cb_yes, imcb_ask_add_cb_no, data );
     506}
     507
     508struct bee_user *imcb_buddy_by_handle( struct im_connection *ic, const char *handle )
     509{
     510        return bee_user_by_handle( ic->bee, ic, handle );
    1256511}
    1257512
    1258513/* The plan is to not allow straight calls to prpl functions anymore, but do
    1259514   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 }
    1277515
    1278516int imc_chat_msg( struct groupchat *c, char *msg, int flags )
     
    1303541       
    1304542        away = set_getstr( &ic->acc->set, "away" ) ?
    1305              : set_getstr( &ic->irc->set, "away" );
     543             : set_getstr( &ic->bee->set, "away" );
    1306544        if( away && *away )
    1307545        {
     
    1314552                away = NULL;
    1315553                msg = set_getstr( &ic->acc->set, "status" ) ?
    1316                     : set_getstr( &ic->irc->set, "status" );
     554                    : set_getstr( &ic->bee->set, "status" );
    1317555        }
    1318556       
Note: See TracChangeset for help on using the changeset viewer.