Changes in / [3ab1d31:a87e6ba]


Ignore:
Files:
12 added
6 deleted
27 edited

Legend:

Unmodified
Added
Removed
  • Makefile

    r3ab1d31 ra87e6ba  
    1010
    1111# Program variables
    12 objects = account.o bitlbee.o chat.o dcc.o help.o ipc.o irc.o irc_commands.o nick.o query.o root_commands.o set.o storage.o $(STORAGE_OBJS) user.o
     12#objects = bitlbee.o chat.o dcc.o help.o ipc.o irc.o irc_commands.o nick.o query.o root_commands.o set.o storage.o $(STORAGE_OBJS)
     13objects = bitlbee.o dcc.o help.o ipc.o irc.o irc_im.o irc_channel.o irc_commands.o irc_send.o irc_user.o nick.o root_commands.o set.o storage.o $(STORAGE_OBJS)
    1314headers = account.h bitlbee.h commands.h conf.h config.h help.h ipc.h irc.h log.h nick.h query.h set.h sock.h storage.h user.h lib/events.h lib/ftutil.h lib/http_client.h lib/ini.h lib/md5.h lib/misc.h lib/proxy.h lib/sha1.h lib/ssl_client.h lib/url.h protocols/ft.h protocols/nogaim.h
    1415subdirs = lib protocols
  • bitlbee.h

    r3ab1d31 ra87e6ba  
    124124#define CONF_FILE_DEF ETCDIR "bitlbee.conf"
    125125
     126#include "bee.h"
    126127#include "irc.h"
    127128#include "storage.h"
     
    158159gboolean bitlbee_io_current_client_write( gpointer data, gint source, b_input_condition cond );
    159160
    160 void root_command_string( irc_t *irc, user_t *u, char *command, int flags );
     161void root_command_string( irc_t *irc, char *command );
    161162void root_command( irc_t *irc, char *command[] );
    162163gboolean bitlbee_shutdown( gpointer data, gint fd, b_input_condition cond );
  • conf.c

    r3ab1d31 ra87e6ba  
    369369                if( g_strcasecmp( ini->section, "defaults" ) == 0 )
    370370                {
    371                         set_t *s = set_find( &irc->set, ini->key );
     371                        set_t *s = set_find( &irc->b->set, ini->key );
    372372                       
    373373                        if( s )
  • dcc.c

    r3ab1d31 ra87e6ba  
    6161unsigned int receivedchunks=0, receiveddata=0;
    6262
    63 static void dcc_finish( file_transfer_t *file );
    64 static void dcc_close( file_transfer_t *file );
     63void dcc_finish( file_transfer_t *file );
     64void dcc_close( file_transfer_t *file );
    6565gboolean dccs_send_proto( gpointer data, gint fd, b_input_condition cond );
    66 int dccs_send_request( struct dcc_file_transfer *df, char *user_nick, struct sockaddr_storage *saddr );
    67 gboolean dccs_recv_start( file_transfer_t *ft );
     66int dccs_send_request( struct dcc_file_transfer *df, irc_user_t *iu, struct sockaddr_storage *saddr );
    6867gboolean dccs_recv_proto( gpointer data, gint fd, b_input_condition cond);
    6968gboolean dccs_recv_write_request( file_transfer_t *ft );
     
    7170gboolean dcc_abort( dcc_file_transfer_t *df, char *reason, ... );
    7271
    73 /* As defined in ft.h */
    74 file_transfer_t *imcb_file_send_start( struct im_connection *ic, char *handle, char *file_name, size_t file_size )
    75 {
    76         user_t *u = user_findhandle( ic, handle );
    77         /* one could handle this more intelligent like imcb_buddy_msg.
    78          * can't call it directly though cause it does some wrapping.
    79          * Maybe give imcb_buddy_msg a parameter NO_WRAPPING? */
    80         if (!u) return NULL;
    81 
    82         return dccs_send_start( ic, u->nick, file_name, file_size );
    83 };
    84 
    85 /* As defined in ft.h */
    86 void imcb_file_canceled( file_transfer_t *file, char *reason )
    87 {
    88         if( file->canceled )
    89                 file->canceled( file, reason );
    90 
    91         dcc_close( file );
    92 }
    93 
    94 /* As defined in ft.h */
    95 gboolean imcb_file_recv_start( file_transfer_t *ft )
    96 {
    97         return dccs_recv_start( ft );
    98 }
    99 
    100 /* As defined in ft.h */
    101 void imcb_file_finished( file_transfer_t *file )
    102 {
    103         dcc_file_transfer_t *df = file->priv;
    104 
    105         if( file->bytes_transferred >= file->file_size )
    106                 dcc_finish( file );
    107         else
    108                 df->proto_finished = TRUE;
    109 }
    110 
    111 dcc_file_transfer_t *dcc_alloc_transfer( char *file_name, size_t file_size, struct im_connection *ic )
     72dcc_file_transfer_t *dcc_alloc_transfer( const char *file_name, size_t file_size, struct im_connection *ic )
    11273{
    11374        file_transfer_t *file = g_new0( file_transfer_t, 1 );
     
    12485
    12586/* This is where the sending magic starts... */
    126 file_transfer_t *dccs_send_start( struct im_connection *ic, char *user_nick, char *file_name, size_t file_size )
     87file_transfer_t *dccs_send_start( struct im_connection *ic, irc_user_t *iu, const char *file_name, size_t file_size )
    12788{
    12889        file_transfer_t *file;
    12990        dcc_file_transfer_t *df;
     91        irc_t *irc = (irc_t *) ic->bee->ui_data;
    13092        struct sockaddr_storage saddr;
    13193        char *errmsg;
     
    150112        file->status = FT_STATUS_LISTENING;
    151113
    152         if( !dccs_send_request( df, user_nick, &saddr ) )
     114        if( !dccs_send_request( df, iu, &saddr ) )
    153115                return NULL;
    154116
     
    156118        df->watch_in = b_input_add( df->fd, GAIM_INPUT_READ, dccs_send_proto, df );
    157119
    158         df->ic->irc->file_transfers = g_slist_prepend( df->ic->irc->file_transfers, file );
     120        irc->file_transfers = g_slist_prepend( irc->file_transfers, file );
    159121
    160122        df->progress_timeout = b_timeout_add( DCC_MAX_STALL * 1000, dcc_progress, df );
     
    163125                      "Accept the file transfer if you'd like the file. If you don't, "
    164126                      "issue the 'transfers reject' command.",
    165                       user_nick, file_name, file_size / 1024 );
     127                      iu->nick, file_name, file_size / 1024 );
    166128
    167129        return file;
     
    216178
    217179/* Creates the "DCC SEND" line and sends it to the server */
    218 int dccs_send_request( struct dcc_file_transfer *df, char *user_nick, struct sockaddr_storage *saddr )
     180int dccs_send_request( struct dcc_file_transfer *df, irc_user_t *iu, struct sockaddr_storage *saddr )
    219181{
    220182        char ipaddr[INET6_ADDRSTRLEN];
     
    250212                                df->ft->file_name, ipaddr, port, df->ft->file_size );
    251213       
    252         if ( !irc_msgfrom( df->ic->irc, user_nick, cmd ) )
    253                 return dcc_abort( df, "Couldn't send `DCC SEND' message to %s.", user_nick );
     214        irc_send_msg_raw( iu, "PRIVMSG", iu->irc->user->nick, cmd );
    254215
    255216        g_free( cmd );
     
    496457 * Cleans up after a transfer.
    497458 */
    498 static void dcc_close( file_transfer_t *file )
     459void dcc_close( file_transfer_t *file )
    499460{
    500461        dcc_file_transfer_t *df = file->priv;
     462        irc_t *irc = (irc_t *) df->ic->bee->ui_data;
    501463
    502464        if( file->free )
     
    514476                b_event_remove( df->progress_timeout );
    515477       
    516         df->ic->irc->file_transfers = g_slist_remove( df->ic->irc->file_transfers, file );
     478        irc->file_transfers = g_slist_remove( irc->file_transfers, file );
    517479       
    518480        g_free( df );
     
    544506file_transfer_t *dcc_request( struct im_connection *ic, char *line )
    545507{
     508        irc_t *irc = (irc_t *) ic->bee->ui_data;
    546509        char *pattern = "SEND"
    547510                " (([^\"][^ ]*)|\"(([^\"]|\\\")*)\")"
     
    627590                g_free( input );
    628591
    629                 df->ic->irc->file_transfers = g_slist_prepend( df->ic->irc->file_transfers, ft );
     592                irc->file_transfers = g_slist_prepend( irc->file_transfers, ft );
    630593
    631594                return ft;
  • dcc.h

    r3ab1d31 ra87e6ba  
    9595} dcc_file_transfer_t;
    9696
    97 file_transfer_t *dccs_send_start( struct im_connection *ic, char *user_nick, char *file_name, size_t file_size );
     97file_transfer_t *dccs_send_start( struct im_connection *ic, irc_user_t *iu, const char *file_name, size_t file_size );
     98void dcc_canceled( file_transfer_t *file, char *reason );
     99gboolean dccs_send_write( file_transfer_t *file, char *data, unsigned int data_size );
     100file_transfer_t *dcc_request( struct im_connection *ic, char *line );
     101void dcc_finish( file_transfer_t *file );
     102void dcc_close( file_transfer_t *file );
     103gboolean dccs_recv_start( file_transfer_t *ft );
    98104
    99 void dcc_canceled( file_transfer_t *file, char *reason );
    100 
    101 gboolean dccs_send_write( file_transfer_t *file, char *data, unsigned int data_size );
    102 
    103 file_transfer_t *dcc_request( struct im_connection *ic, char *line );
    104105#endif
  • ipc.c

    r3ab1d31 ra87e6ba  
    138138       
    139139        if( strchr( irc->umode, 'w' ) )
    140                 irc_write( irc, ":%s WALLOPS :%s", irc->myhost, cmd[1] );
     140                irc_write( irc, ":%s WALLOPS :%s", irc->root->host, cmd[1] );
    141141}
    142142
     
    147147       
    148148        if( strchr( irc->umode, 's' ) )
    149                 irc_write( irc, ":%s NOTICE %s :%s", irc->myhost, irc->nick, cmd[1] );
     149                irc_write( irc, ":%s NOTICE %s :%s", irc->root->host, irc->user->nick, cmd[1] );
    150150}
    151151
     
    156156       
    157157        if( strchr( irc->umode, 'o' ) )
    158                 irc_write( irc, ":%s NOTICE %s :*** OperMsg *** %s", irc->myhost, irc->nick, cmd[1] );
     158                irc_write( irc, ":%s NOTICE %s :*** OperMsg *** %s", irc->root->host, irc->user->nick, cmd[1] );
    159159}
    160160
     
    176176                return;
    177177       
    178         if( nick_cmp( cmd[1], irc->nick ) != 0 )
     178        if( nick_cmp( cmd[1], irc->user->nick ) != 0 )
    179179                return;         /* It's not for us. */
    180180       
    181         irc_write( irc, ":%s!%s@%s KILL %s :%s", irc->mynick, irc->mynick, irc->myhost, irc->nick, cmd[2] );
     181        irc_write( irc, ":%s!%s@%s KILL %s :%s", irc->root->nick, irc->root->nick, irc->root->host, irc->user->nick, cmd[2] );
    182182        irc_abort( irc, 0, "Killed by operator: %s", cmd[2] );
    183183}
     
    188188                ipc_to_master_str( "HELLO\r\n" );
    189189        else
    190                 ipc_to_master_str( "HELLO %s %s :%s\r\n", irc->host, irc->nick, irc->realname );
     190                ipc_to_master_str( "HELLO %s %s :%s\r\n", irc->user->host, irc->user->nick, irc->user->fullname );
    191191}
    192192
  • irc.c

    r3ab1d31 ra87e6ba  
    55  \********************************************************************/
    66
    7 /* The big hairy IRCd part of the project                               */
     7/* The IRC-based UI (for now the only one)                              */
    88
    99/*
     
    2424*/
    2525
    26 #define BITLBEE_CORE
    2726#include "bitlbee.h"
    28 #include "sock.h"
    2927#include "ipc.h"
    30 #include "dcc.h"
    31 
    32 static gboolean irc_userping( gpointer _irc, int fd, b_input_condition cond );
    33 
    34 GSList *irc_connection_list = NULL;
    35 
    36 static char *set_eval_password( set_t *set, char *value )
    37 {
    38         irc_t *irc = set->data;
    39        
    40         if( irc->status & USTATUS_IDENTIFIED && value )
    41         {
    42                 irc_setpass( irc, value );
    43                 return NULL;
    44         }
    45         else
    46         {
    47                 return SET_INVALID;
    48         }
    49 }
    50 
    51 static char *set_eval_charset( set_t *set, char *value )
    52 {
    53         irc_t *irc = set->data;
    54         GIConv ic, oc;
    55 
    56         if( g_strcasecmp( value, "none" ) == 0 )
    57                 value = g_strdup( "utf-8" );
    58 
    59         if( ( ic = g_iconv_open( "utf-8", value ) ) == (GIConv) -1 )
    60         {
    61                 return NULL;
    62         }
    63         if( ( oc = g_iconv_open( value, "utf-8" ) ) == (GIConv) -1 )
    64         {
    65                 g_iconv_close( ic );
    66                 return NULL;
    67         }
    68        
    69         if( irc->iconv != (GIConv) -1 )
    70                 g_iconv_close( irc->iconv );
    71         if( irc->oconv != (GIConv) -1 )
    72                 g_iconv_close( irc->oconv );
    73        
    74         irc->iconv = ic;
    75         irc->oconv = oc;
    76 
    77         return value;
    78 }
    79 
    80 static char *set_eval_away_status( set_t *set, char *value )
    81 {
    82         irc_t *irc = set->data;
    83         account_t *a;
    84        
    85         g_free( set->value );
    86         set->value = g_strdup( value );
    87        
    88         for( a = irc->accounts; a; a = a->next )
    89         {
    90                 struct im_connection *ic = a->ic;
    91                
    92                 if( ic && ic->flags & OPT_LOGGED_IN )
    93                         imc_away_send_update( ic );
    94         }
    95        
    96         return value;
    97 }
     28
     29GSList *irc_connection_list;
     30
     31static gboolean irc_userping( gpointer _irc, gint fd, b_input_condition cond );
     32static char *set_eval_charset( set_t *set, char *value );
    9833
    9934irc_t *irc_new( int fd )
     
    10237        struct sockaddr_storage sock;
    10338        socklen_t socklen = sizeof( sock );
     39        char *host = NULL, *myhost = NULL;
     40        irc_user_t *iu;
    10441        set_t *s;
     42        bee_t *b;
    10543       
    10644        irc = g_new0( irc_t, 1 );
     
    11452        irc->last_pong = gettime();
    11553       
    116         irc->userhash = g_hash_table_new( g_str_hash, g_str_equal );
     54        irc->nick_user_hash = g_hash_table_new( g_str_hash, g_str_equal );
    11755        irc->watches = g_hash_table_new( g_str_hash, g_str_equal );
    118        
    119         strcpy( irc->umode, UMODE );
    120         irc->mynick = g_strdup( ROOT_NICK );
    121         irc->channel = g_strdup( ROOT_CHAN );
    12256       
    12357        irc->iconv = (GIConv) -1;
     
    12660        if( global.conf->hostname )
    12761        {
    128                 irc->myhost = g_strdup( global.conf->hostname );
     62                myhost = g_strdup( global.conf->hostname );
    12963        }
    13064        else if( getsockname( irc->fd, (struct sockaddr*) &sock, &socklen ) == 0 )
     
    13569                                 NI_MAXHOST, NULL, 0, 0 ) == 0 )
    13670                {
    137                         irc->myhost = g_strdup( ipv6_unwrap( buf ) );
     71                        myhost = g_strdup( ipv6_unwrap( buf ) );
    13872                }
    13973        }
     
    14680                                 NI_MAXHOST, NULL, 0, 0 ) == 0 )
    14781                {
    148                         irc->host = g_strdup( ipv6_unwrap( buf ) );
    149                 }
    150         }
    151        
    152         if( irc->host == NULL )
    153                 irc->host = g_strdup( "localhost.localdomain" );
    154         if( irc->myhost == NULL )
    155                 irc->myhost = g_strdup( "localhost.localdomain" );
     82                        host = g_strdup( ipv6_unwrap( buf ) );
     83                }
     84        }
     85       
     86        if( host == NULL )
     87                host = g_strdup( "localhost.localdomain" );
     88        if( myhost == NULL )
     89                myhost = g_strdup( "localhost.localdomain" );
    15690       
    15791        if( global.conf->ping_interval > 0 && global.conf->ping_timeout > 0 )
    15892                irc->ping_source_id = b_timeout_add( global.conf->ping_interval * 1000, irc_userping, irc );
    159        
    160         irc_write( irc, ":%s NOTICE AUTH :%s", irc->myhost, "BitlBee-IRCd initialized, please go on" );
    16193
    16294        irc_connection_list = g_slist_append( irc_connection_list, irc );
    16395       
    164         s = set_add( &irc->set, "away", NULL,  set_eval_away_status, irc );
    165         s->flags |= SET_NULL_OK;
    166         s = set_add( &irc->set, "away_devoice", "true",  set_eval_away_devoice, irc );
    167         s = set_add( &irc->set, "auto_connect", "true", set_eval_bool, irc );
    168         s = set_add( &irc->set, "auto_reconnect", "true", set_eval_bool, irc );
    169         s = set_add( &irc->set, "auto_reconnect_delay", "5*3<900", set_eval_account_reconnect_delay, irc );
    170         s = set_add( &irc->set, "buddy_sendbuffer", "false", set_eval_bool, irc );
    171         s = set_add( &irc->set, "buddy_sendbuffer_delay", "200", set_eval_int, irc );
    172         s = set_add( &irc->set, "charset", "utf-8", set_eval_charset, irc );
    173         s = set_add( &irc->set, "control_channel", irc->channel, set_eval_control_channel, irc );
    174         s = set_add( &irc->set, "debug", "false", set_eval_bool, irc );
    175         s = set_add( &irc->set, "default_target", "root", NULL, irc );
    176         s = set_add( &irc->set, "display_namechanges", "false", set_eval_bool, irc );
    177         s = set_add( &irc->set, "handle_unknown", "root", NULL, irc );
    178         s = set_add( &irc->set, "lcnicks", "true", set_eval_bool, irc );
    179         s = set_add( &irc->set, "ops", "both", set_eval_ops, irc );
    180         s = set_add( &irc->set, "password", NULL, set_eval_password, irc );
    181         s->flags |= SET_NULL_OK;
    182         s = set_add( &irc->set, "private", "true", set_eval_bool, irc );
    183         s = set_add( &irc->set, "query_order", "lifo", NULL, irc );
    184         s = set_add( &irc->set, "root_nick", irc->mynick, set_eval_root_nick, irc );
    185         s = set_add( &irc->set, "save_on_quit", "true", set_eval_bool, irc );
    186         s = set_add( &irc->set, "simulate_netsplit", "true", set_eval_bool, irc );
    187         s = set_add( &irc->set, "status", NULL,  set_eval_away_status, irc );
    188         s->flags |= SET_NULL_OK;
    189         s = set_add( &irc->set, "strip_html", "true", NULL, irc );
    190         s = set_add( &irc->set, "to_char", ": ", set_eval_to_char, irc );
    191         s = set_add( &irc->set, "typing_notice", "false", set_eval_bool, irc );
     96        b = irc->b = bee_new();
     97        b->ui_data = irc;
     98        b->ui = &irc_ui_funcs;
     99       
     100        s = set_add( &b->set, "away_devoice", "true", NULL/*set_eval_away_devoice*/, irc );
     101        s = set_add( &b->set, "buddy_sendbuffer", "false", set_eval_bool, irc );
     102        s = set_add( &b->set, "buddy_sendbuffer_delay", "200", set_eval_int, irc );
     103        s = set_add( &b->set, "charset", "utf-8", set_eval_charset, irc );
     104        //s = set_add( &b->set, "control_channel", irc->channel, NULL/*set_eval_control_channel*/, irc );
     105        s = set_add( &b->set, "default_target", "root", NULL, irc );
     106        s = set_add( &b->set, "display_namechanges", "false", set_eval_bool, irc );
     107        s = set_add( &b->set, "handle_unknown", "root", NULL, irc );
     108        s = set_add( &b->set, "lcnicks", "true", set_eval_bool, irc );
     109        s = set_add( &b->set, "ops", "both", NULL/*set_eval_ops*/, irc );
     110        s = set_add( &b->set, "private", "true", set_eval_bool, irc );
     111        s = set_add( &b->set, "query_order", "lifo", NULL, irc );
     112        s = set_add( &b->set, "root_nick", ROOT_NICK, NULL/*set_eval_root_nick*/, irc );
     113        s = set_add( &b->set, "simulate_netsplit", "true", set_eval_bool, irc );
     114        s = set_add( &b->set, "to_char", ": ", set_eval_to_char, irc );
     115        s = set_add( &b->set, "typing_notice", "false", set_eval_bool, irc );
     116
     117        irc->root = iu = irc_user_new( irc, ROOT_NICK );
     118        iu->host = g_strdup( myhost );
     119        iu->fullname = g_strdup( ROOT_FN );
     120        iu->f = &irc_user_root_funcs;
     121       
     122        iu = irc_user_new( irc, NS_NICK );
     123        iu->host = g_strdup( myhost );
     124        iu->fullname = g_strdup( ROOT_FN );
     125        iu->f = &irc_user_root_funcs;
     126       
     127        irc->user = g_new0( irc_user_t, 1 );
     128        irc->user->host = g_strdup( host );
    192129       
    193130        conf_loaddefaults( irc );
    194131       
    195132        /* Evaluator sets the iconv/oconv structures. */
    196         set_eval_charset( set_find( &irc->set, "charset" ), set_getstr( &irc->set, "charset" ) );
    197        
    198         return( irc );
     133        set_eval_charset( set_find( &b->set, "charset" ), set_getstr( &b->set, "charset" ) );
     134       
     135        irc_write( irc, ":%s NOTICE AUTH :%s", irc->root->host, "BitlBee-IRCd initialized, please go on" );
     136       
     137        g_free( myhost );
     138        g_free( host );
     139       
     140        return irc;
    199141}
    200142
     
    217159               
    218160                ipc_to_master_str( "OPERMSG :Client exiting: %s@%s [%s]\r\n",
    219                                    irc->nick ? irc->nick : "(NONE)", irc->host, reason );
     161                                   irc->user->nick ? irc->user->nick : "(NONE)", irc->root->host, reason );
    220162               
    221163                g_free( reason );
     
    227169               
    228170                ipc_to_master_str( "OPERMSG :Client exiting: %s@%s [%s]\r\n",
    229                                    irc->nick ? irc->nick : "(NONE)", irc->host, "No reason given" );
     171                                   irc->user->nick ? irc->user->nick : "(NONE)", irc->root->host, "No reason given" );
    230172        }
    231173       
     
    248190}
    249191
    250 static gboolean irc_free_hashkey( gpointer key, gpointer value, gpointer data )
    251 {
    252         g_free( key );
    253        
    254         return( TRUE );
    255 }
    256 
    257 /* Because we have no garbage collection, this is quite annoying */
     192static gboolean irc_free_hashkey( gpointer key, gpointer value, gpointer data );
     193
    258194void irc_free( irc_t * irc )
    259195{
    260         user_t *user, *usertmp;
    261        
    262196        log_message( LOGLVL_INFO, "Destroying connection with fd %d", irc->fd );
    263197       
    264         if( irc->status & USTATUS_IDENTIFIED && set_getbool( &irc->set, "save_on_quit" ) )
     198        /*
     199        if( irc->status & USTATUS_IDENTIFIED && set_getbool( &irc->b->set, "save_on_quit" ) )
    265200                if( storage_save( irc, NULL, TRUE ) != STORAGE_OK )
    266201                        irc_usermsg( irc, "Error while saving settings!" );
     202        */
    267203       
    268204        irc_connection_list = g_slist_remove( irc_connection_list, irc );
    269205       
    270         while( irc->accounts )
    271         {
    272                 if( irc->accounts->ic )
    273                         imc_logout( irc->accounts->ic, FALSE );
    274                 else if( irc->accounts->reconnect )
    275                         cancel_auto_reconnect( irc->accounts );
    276                
    277                 if( irc->accounts->ic == NULL )
    278                         account_del( irc, irc->accounts );
    279                 else
    280                         /* Nasty hack, but account_del() doesn't work in this
    281                            case and we don't want infinite loops, do we? ;-) */
    282                         irc->accounts = irc->accounts->next;
    283         }
    284        
     206        /*
    285207        while( irc->queries != NULL )
    286208                query_del( irc, irc->queries );
    287        
    288         while( irc->set )
    289                 set_del( &irc->set, irc->set->key );
    290        
    291         if (irc->users != NULL)
    292         {
    293                 user = irc->users;
    294                 while( user != NULL )
    295                 {
    296                         g_free( user->nick );
    297                         g_free( user->away );
    298                         g_free( user->handle );
    299                         if( user->user != user->nick ) g_free( user->user );
    300                         if( user->host != user->nick ) g_free( user->host );
    301                         if( user->realname != user->nick ) g_free( user->realname );
    302                         b_event_remove( user->sendbuf_timer );
    303                                        
    304                         usertmp = user;
    305                         user = user->next;
    306                         g_free( usertmp );
    307                 }
    308         }
     209        */
     210       
     211        while( irc->users )
     212        {
     213                irc_user_t *iu = irc->users->data;
     214                irc_user_free( irc, iu->nick );
     215        }
     216       
     217        while( irc->channels )
     218                irc_channel_free( irc->channels->data );
    309219       
    310220        if( irc->ping_source_id > 0 )
     
    318228        irc->fd = -1;
    319229       
    320         g_hash_table_foreach_remove( irc->userhash, irc_free_hashkey, NULL );
    321         g_hash_table_destroy( irc->userhash );
     230        g_hash_table_foreach_remove( irc->nick_user_hash, irc_free_hashkey, NULL );
     231        g_hash_table_destroy( irc->nick_user_hash );
    322232       
    323233        g_hash_table_foreach_remove( irc->watches, irc_free_hashkey, NULL );
     
    332242        g_free( irc->readbuffer );
    333243       
    334         g_free( irc->nick );
    335         g_free( irc->user );
    336         g_free( irc->host );
    337         g_free( irc->realname );
    338244        g_free( irc->password );
    339        
    340         g_free( irc->myhost );
    341         g_free( irc->mynick );
    342        
    343         g_free( irc->channel );
    344        
    345         g_free( irc->last_target );
    346245       
    347246        g_free( irc );
     
    355254}
    356255
     256static gboolean irc_free_hashkey( gpointer key, gpointer value, gpointer data )
     257{
     258        g_free( key );
     259       
     260        return( TRUE );
     261}
     262
    357263/* USE WITH CAUTION!
    358264   Sets pass without checking */
    359 void irc_setpass (irc_t *irc, const char *pass) 
     265void irc_setpass (irc_t *irc, const char *pass)
    360266{
    361267        g_free (irc->password);
     
    368274}
    369275
     276static char **irc_splitlines( char *buffer );
     277
    370278void irc_process( irc_t *irc )
    371279{
     
    375283        if( irc->readbuffer != NULL )
    376284        {
    377                 lines = irc_tokenize( irc->readbuffer );
     285                lines = irc_splitlines( irc->readbuffer );
    378286               
    379287                for( i = 0; *lines[i] != '\0'; i ++ )
     
    412320                                                                  "`help set charset' for more information. Your "
    413321                                                                  "message was ignored.",
    414                                                                   set_getstr( &irc->set, "charset" ) );
     322                                                                  set_getstr( &irc->b->set, "charset" ) );
    415323                                               
    416324                                                g_free( conv );
     
    419327                                        else
    420328                                        {
    421                                                 irc_write( irc, ":%s NOTICE AUTH :%s", irc->myhost,
     329                                                irc_write( irc, ":%s NOTICE AUTH :%s", irc->root->host,
    422330                                                           "Warning: invalid characters received at login time." );
    423331                                               
     
    457365}
    458366
    459 /* Splits a long string into separate lines. The array is NULL-terminated and, unless the string
    460    contains an incomplete line at the end, ends with an empty string. */
    461 char **irc_tokenize( char *buffer )
     367/* Splits a long string into separate lines. The array is NULL-terminated
     368   and, unless the string contains an incomplete line at the end, ends with
     369   an empty string. Could use g_strsplit() but this one does it in-place.
     370   (So yes, it's destructive.) */
     371static char **irc_splitlines( char *buffer )
    462372{
    463373        int i, j, n = 3;
     
    590500}
    591501
    592 void irc_reply( irc_t *irc, int code, char *format, ... )
    593 {
    594         char text[IRC_MAX_LINE];
    595         va_list params;
    596        
    597         va_start( params, format );
    598         g_vsnprintf( text, IRC_MAX_LINE, format, params );
    599         va_end( params );
    600         irc_write( irc, ":%s %03d %s %s", irc->myhost, code, irc->nick?irc->nick:"*", text );
    601        
    602         return;
    603 }
    604 
    605 int irc_usermsg( irc_t *irc, char *format, ... )
    606 {
    607         char text[1024];
    608         va_list params;
    609         char is_private = 0;
    610         user_t *u;
    611        
    612         u = user_find( irc, irc->mynick );
    613         is_private = u->is_private;
    614        
    615         va_start( params, format );
    616         g_vsnprintf( text, sizeof( text ), format, params );
    617         va_end( params );
    618        
    619         return( irc_msgfrom( irc, u->nick, text ) );
    620 }
    621 
    622502void irc_write( irc_t *irc, char *format, ... )
    623503{
     
    630510        return;
    631511}
     512
     513void irc_write_all( int now, char *format, ... )
     514{
     515        va_list params;
     516        GSList *temp;   
     517       
     518        va_start( params, format );
     519       
     520        temp = irc_connection_list;
     521        while( temp != NULL )
     522        {
     523                irc_t *irc = temp->data;
     524               
     525                if( now )
     526                {
     527                        g_free( irc->sendbuffer );
     528                        irc->sendbuffer = g_strdup( "\r\n" );
     529                }
     530                irc_vawrite( temp->data, format, params );
     531                if( now )
     532                {
     533                        bitlbee_io_current_client_write( irc, irc->fd, GAIM_INPUT_WRITE );
     534                }
     535                temp = temp->next;
     536        }
     537       
     538        va_end( params );
     539        return;
     540}
    632541
    633542void irc_vawrite( irc_t *irc, char *format, va_list params )
     
    686595}
    687596
    688 void irc_write_all( int now, char *format, ... )
    689 {
    690         va_list params;
    691         GSList *temp;   
    692        
    693         va_start( params, format );
    694        
    695         temp = irc_connection_list;
    696         while( temp != NULL )
    697         {
    698                 irc_t *irc = temp->data;
    699                
    700                 if( now )
    701                 {
    702                         g_free( irc->sendbuffer );
    703                         irc->sendbuffer = g_strdup( "\r\n" );
    704                 }
    705                 irc_vawrite( temp->data, format, params );
    706                 if( now )
    707                 {
    708                         bitlbee_io_current_client_write( irc, irc->fd, GAIM_INPUT_WRITE );
    709                 }
    710                 temp = temp->next;
    711         }
    712        
    713         va_end( params );
    714         return;
    715 }
    716 
    717 void irc_names( irc_t *irc, char *channel )
    718 {
    719         user_t *u;
    720         char namelist[385] = "";
    721         struct groupchat *c = NULL;
    722         char *ops = set_getstr( &irc->set, "ops" );
    723        
    724         /* RFCs say there is no error reply allowed on NAMES, so when the
    725            channel is invalid, just give an empty reply. */
    726        
    727         if( g_strcasecmp( channel, irc->channel ) == 0 )
    728         {
    729                 for( u = irc->users; u; u = u->next ) if( u->online )
    730                 {
    731                         if( strlen( namelist ) + strlen( u->nick ) > sizeof( namelist ) - 4 )
     597int irc_check_login( irc_t *irc )
     598{
     599        if( irc->user->user && irc->user->nick )
     600        {
     601                if( global.conf->authmode == AUTHMODE_CLOSED && !( irc->status & USTATUS_AUTHORIZED ) )
     602                {
     603                        irc_send_num( irc, 464, ":This server is password-protected." );
     604                        return 0;
     605                }
     606                else
     607                {
     608                        irc_channel_t *ic;
     609                        irc_user_t *iu = irc->user;
     610                       
     611                        irc->user = irc_user_new( irc, iu->nick );
     612                        irc->user->user = iu->user;
     613                        irc->user->host = iu->host;
     614                        irc->user->fullname = iu->fullname;
     615                        irc->user->f = &irc_user_self_funcs;
     616                        g_free( iu->nick );
     617                        g_free( iu );
     618                       
     619                        if( global.conf->runmode == RUNMODE_FORKDAEMON || global.conf->runmode == RUNMODE_DAEMON )
     620                                ipc_to_master_str( "CLIENT %s %s :%s\r\n", irc->user->host, irc->user->nick, irc->user->fullname );
     621                       
     622                        irc->status |= USTATUS_LOGGED_IN;
     623                       
     624                        /* This is for bug #209 (use PASS to identify to NickServ). */
     625                        if( irc->password != NULL )
    732626                        {
    733                                 irc_reply( irc, 353, "= %s :%s", channel, namelist );
    734                                 *namelist = 0;
     627                                char *send_cmd[] = { "identify", g_strdup( irc->password ), NULL };
     628                               
     629                                /*irc_setpass( irc, NULL );*/
     630                                /*root_command( irc, send_cmd );*/
     631                                g_free( send_cmd[1] );
    735632                        }
    736633                       
    737                         if( u->ic && !u->away && set_getbool( &irc->set, "away_devoice" ) )
    738                                 strcat( namelist, "+" );
    739                         else if( ( strcmp( u->nick, irc->mynick ) == 0 && ( strcmp( ops, "root" ) == 0 || strcmp( ops, "both" ) == 0 ) ) ||
    740                                  ( strcmp( u->nick, irc->nick ) == 0 && ( strcmp( ops, "user" ) == 0 || strcmp( ops, "both" ) == 0 ) ) )
    741                                 strcat( namelist, "@" );
    742                        
    743                         strcat( namelist, u->nick );
    744                         strcat( namelist, " " );
    745                 }
    746         }
    747         else if( ( c = irc_chat_by_channel( irc, channel ) ) )
    748         {
    749                 GList *l;
    750                
    751                 /* root and the user aren't in the channel userlist but should
    752                    show up in /NAMES, so list them first: */
    753                 sprintf( namelist, "%s%s %s%s ", strcmp( ops, "root" ) == 0 || strcmp( ops, "both" ) ? "@" : "", irc->mynick,
    754                                                  strcmp( ops, "user" ) == 0 || strcmp( ops, "both" ) ? "@" : "", irc->nick );
    755                
    756                 for( l = c->in_room; l; l = l->next ) if( ( u = user_findhandle( c->ic, l->data ) ) )
    757                 {
    758                         if( strlen( namelist ) + strlen( u->nick ) > sizeof( namelist ) - 4 )
    759                         {
    760                                 irc_reply( irc, 353, "= %s :%s", channel, namelist );
    761                                 *namelist = 0;
    762                         }
    763                        
    764                         strcat( namelist, u->nick );
    765                         strcat( namelist, " " );
    766                 }
    767         }
    768        
    769         if( *namelist )
    770                 irc_reply( irc, 353, "= %s :%s", channel, namelist );
    771        
    772         irc_reply( irc, 366, "%s :End of /NAMES list", channel );
    773 }
    774 
    775 int irc_check_login( irc_t *irc )
    776 {
    777         if( irc->user && irc->nick )
    778         {
    779                 if( global.conf->authmode == AUTHMODE_CLOSED && !( irc->status & USTATUS_AUTHORIZED ) )
    780                 {
    781                         irc_reply( irc, 464, ":This server is password-protected." );
    782                         return 0;
    783                 }
    784                 else
    785                 {
    786                         irc_login( irc );
     634                        irc_send_login( irc );
     635                       
     636                        irc->umode[0] = '\0';
     637                        irc_umode_set( irc, "+" UMODE, TRUE );
     638                       
     639                        ic = irc_channel_new( irc, ROOT_CHAN );
     640                        irc_channel_set_topic( ic, CONTROL_TOPIC, irc->root );
     641                        irc_channel_add_user( ic, irc->user );
     642                       
     643                        irc->last_root_cmd = g_strdup( ROOT_CHAN );
     644                       
    787645                        return 1;
    788646                }
     
    795653}
    796654
    797 void irc_login( irc_t *irc )
    798 {
    799         user_t *u;
    800        
    801         irc_reply( irc,   1, ":Welcome to the BitlBee gateway, %s", irc->nick );
    802         irc_reply( irc,   2, ":Host %s is running BitlBee " BITLBEE_VERSION " " ARCH "/" CPU ".", irc->myhost );
    803         irc_reply( irc,   3, ":%s", IRCD_INFO );
    804         irc_reply( irc,   4, "%s %s %s %s", irc->myhost, BITLBEE_VERSION, UMODES UMODES_PRIV, CMODES );
    805         irc_reply( irc,   5, "PREFIX=(ov)@+ CHANTYPES=%s CHANMODES=,,,%s NICKLEN=%d NETWORK=BitlBee "
    806                              "CASEMAPPING=rfc1459 MAXTARGETS=1 WATCH=128 :are supported by this server",
    807                              CTYPES, CMODES, MAX_NICK_LENGTH - 1 );
    808         irc_motd( irc );
    809         irc->umode[0] = '\0';
    810         irc_umode_set( irc, "+" UMODE, 1 );
    811 
    812         u = user_add( irc, irc->mynick );
    813         u->host = g_strdup( irc->myhost );
    814         u->realname = g_strdup( ROOT_FN );
    815         u->online = 1;
    816         u->send_handler = root_command_string;
    817         u->is_private = 0; /* [SH] The channel is root's personal playground. */
    818         irc_spawn( irc, u );
    819        
    820         u = user_add( irc, NS_NICK );
    821         u->host = g_strdup( irc->myhost );
    822         u->realname = g_strdup( ROOT_FN );
    823         u->online = 0;
    824         u->send_handler = root_command_string;
    825         u->is_private = 1; /* [SH] NickServ is not in the channel, so should always /query. */
    826        
    827         u = user_add( irc, irc->nick );
    828         u->user = g_strdup( irc->user );
    829         u->host = g_strdup( irc->host );
    830         u->realname = g_strdup( irc->realname );
    831         u->online = 1;
    832         irc_spawn( irc, u );
    833        
    834         irc_usermsg( irc, "Welcome to the BitlBee gateway!\n\n"
    835                           "If you've never used BitlBee before, please do read the help "
    836                           "information using the \x02help\x02 command. Lots of FAQs are "
    837                           "answered there.\n"
    838                           "If you already have an account on this server, just use the "
    839                           "\x02identify\x02 command to identify yourself." );
    840        
    841         if( global.conf->runmode == RUNMODE_FORKDAEMON || global.conf->runmode == RUNMODE_DAEMON )
    842                 ipc_to_master_str( "CLIENT %s %s :%s\r\n", irc->host, irc->nick, irc->realname );
    843        
    844         irc->status |= USTATUS_LOGGED_IN;
    845        
    846         /* This is for bug #209 (use PASS to identify to NickServ). */
    847         if( irc->password != NULL )
    848         {
    849                 char *send_cmd[] = { "identify", g_strdup( irc->password ), NULL };
    850                
    851                 irc_setpass( irc, NULL );
    852                 root_command( irc, send_cmd );
    853                 g_free( send_cmd[1] );
    854         }
    855 }
    856 
    857 void irc_motd( irc_t *irc )
    858 {
    859         int fd;
    860        
    861         fd = open( global.conf->motdfile, O_RDONLY );
    862         if( fd == -1 )
    863         {
    864                 irc_reply( irc, 422, ":We don't need MOTDs." );
    865         }
    866         else
    867         {
    868                 char linebuf[80];       /* Max. line length for MOTD's is 79 chars. It's what most IRC networks seem to do. */
    869                 char *add, max;
    870                 int len;
    871                
    872                 linebuf[79] = len = 0;
    873                 max = sizeof( linebuf ) - 1;
    874                
    875                 irc_reply( irc, 375, ":- %s Message Of The Day - ", irc->myhost );
    876                 while( read( fd, linebuf + len, 1 ) == 1 )
    877                 {
    878                         if( linebuf[len] == '\n' || len == max )
    879                         {
    880                                 linebuf[len] = 0;
    881                                 irc_reply( irc, 372, ":- %s", linebuf );
    882                                 len = 0;
    883                         }
    884                         else if( linebuf[len] == '%' )
    885                         {
    886                                 read( fd, linebuf + len, 1 );
    887                                 if( linebuf[len] == 'h' )
    888                                         add = irc->myhost;
    889                                 else if( linebuf[len] == 'v' )
    890                                         add = BITLBEE_VERSION;
    891                                 else if( linebuf[len] == 'n' )
    892                                         add = irc->nick;
    893                                 else
    894                                         add = "%";
    895                                
    896                                 strncpy( linebuf + len, add, max - len );
    897                                 while( linebuf[++len] );
    898                         }
    899                         else if( len < max )
    900                         {
    901                                 len ++;
    902                         }
    903                 }
    904                 irc_reply( irc, 376, ":End of MOTD" );
    905                 close( fd );
    906         }
    907 }
    908 
    909 void irc_topic( irc_t *irc, char *channel )
    910 {
    911         struct groupchat *c = irc_chat_by_channel( irc, channel );
    912        
    913         if( c && c->topic )
    914                 irc_reply( irc, 332, "%s :%s", channel, c->topic );
    915         else if( g_strcasecmp( channel, irc->channel ) == 0 )
    916                 irc_reply( irc, 332, "%s :%s", channel, CONTROL_TOPIC );
    917         else
    918                 irc_reply( irc, 331, "%s :No topic for this channel", channel );
    919 }
    920 
    921 void irc_umode_set( irc_t *irc, char *s, int allow_priv )
     655void irc_umode_set( irc_t *irc, const char *s, gboolean allow_priv )
    922656{
    923657        /* allow_priv: Set to 0 if s contains user input, 1 if you want
    924658           to set a "privileged" mode (+o, +R, etc). */
    925         char m[256], st = 1, *t;
     659        char m[128], st = 1;
     660        const char *t;
    926661        int i;
    927662        char changes[512], *p, st2 = 2;
     
    931666       
    932667        for( t = irc->umode; *t; t ++ )
    933                 m[(int)*t] = 1;
    934 
     668                if( *t < sizeof( m ) )
     669                        m[(int)*t] = 1;
     670       
    935671        p = changes;
    936672        for( t = s; *t; t ++ )
     
    938674                if( *t == '+' || *t == '-' )
    939675                        st = *t == '+';
    940                 else if( st == 0 || ( strchr( UMODES, *t ) || ( allow_priv && strchr( UMODES_PRIV, *t ) ) ) )
     676                else if( ( st == 0 && ( !strchr( UMODES_KEEP, *t ) || allow_priv ) ) ||
     677                         ( st == 1 && strchr( UMODES, *t ) ) ||
     678                         ( st == 1 && allow_priv && strchr( UMODES_PRIV, *t ) ) )
    941679                {
    942680                        if( m[(int)*t] != st)
     
    955693        memset( irc->umode, 0, sizeof( irc->umode ) );
    956694       
    957         for( i = 0; i < 256 && strlen( irc->umode ) < ( sizeof( irc->umode ) - 1 ); i ++ )
     695        for( i = 'A'; i <= 'z' && strlen( irc->umode ) < ( sizeof( irc->umode ) - 1 ); i ++ )
    958696                if( m[i] )
    959697                        irc->umode[strlen(irc->umode)] = i;
    960698       
    961699        if( badflag )
    962                 irc_reply( irc, 501, ":Unknown MODE flag" );
    963         /* Deliberately no !user@host on the prefix here */
     700                irc_send_num( irc, 501, ":Unknown MODE flag" );
    964701        if( *changes )
    965                 irc_write( irc, ":%s MODE %s %s", irc->nick, irc->nick, changes );
    966 }
    967 
    968 void irc_spawn( irc_t *irc, user_t *u )
    969 {
    970         irc_join( irc, u, irc->channel );
    971 }
    972 
    973 void irc_join( irc_t *irc, user_t *u, char *channel )
    974 {
    975         char *nick;
    976        
    977         if( ( g_strcasecmp( channel, irc->channel ) != 0 ) || user_find( irc, irc->nick ) )
    978                 irc_write( irc, ":%s!%s@%s JOIN :%s", u->nick, u->user, u->host, channel );
    979        
    980         if( nick_cmp( u->nick, irc->nick ) == 0 )
    981         {
    982                 irc_write( irc, ":%s MODE %s +%s", irc->myhost, channel, CMODE );
    983                 irc_names( irc, channel );
    984                 irc_topic( irc, channel );
    985         }
    986        
    987         nick = g_strdup( u->nick );
    988         nick_lc( nick );
    989         if( g_hash_table_lookup( irc->watches, nick ) )
    990         {
    991                 irc_reply( irc, 600, "%s %s %s %d :%s", u->nick, u->user, u->host, (int) time( NULL ), "logged online" );
    992         }
    993         g_free( nick );
    994 }
    995 
    996 void irc_part( irc_t *irc, user_t *u, char *channel )
    997 {
    998         irc_write( irc, ":%s!%s@%s PART %s :%s", u->nick, u->user, u->host, channel, "" );
    999 }
    1000 
    1001 void irc_kick( irc_t *irc, user_t *u, char *channel, user_t *kicker )
    1002 {
    1003         irc_write( irc, ":%s!%s@%s KICK %s %s :%s", kicker->nick, kicker->user, kicker->host, channel, u->nick, "" );
    1004 }
    1005 
    1006 void irc_kill( irc_t *irc, user_t *u )
    1007 {
    1008         char *nick, *s;
    1009         char reason[128];
    1010        
    1011         if( u->ic && u->ic->flags & OPT_LOGGING_OUT && set_getbool( &irc->set, "simulate_netsplit" ) )
    1012         {
    1013                 if( u->ic->acc->server )
    1014                         g_snprintf( reason, sizeof( reason ), "%s %s", irc->myhost,
    1015                                     u->ic->acc->server );
    1016                 else if( ( s = strchr( u->ic->acc->user, '@' ) ) )
    1017                         g_snprintf( reason, sizeof( reason ), "%s %s", irc->myhost,
    1018                                     s + 1 );
    1019                 else
    1020                         g_snprintf( reason, sizeof( reason ), "%s %s.%s", irc->myhost,
    1021                                     u->ic->acc->prpl->name, irc->myhost );
    1022                
    1023                 /* proto_opt might contain garbage after the : */
    1024                 if( ( s = strchr( reason, ':' ) ) )
    1025                         *s = 0;
    1026         }
    1027         else
    1028         {
    1029                 strcpy( reason, "Leaving..." );
    1030         }
    1031        
    1032         irc_write( irc, ":%s!%s@%s QUIT :%s", u->nick, u->user, u->host, reason );
    1033        
    1034         nick = g_strdup( u->nick );
    1035         nick_lc( nick );
    1036         if( g_hash_table_lookup( irc->watches, nick ) )
    1037         {
    1038                 irc_reply( irc, 601, "%s %s %s %d :%s", u->nick, u->user, u->host, (int) time( NULL ), "logged offline" );
    1039         }
    1040         g_free( nick );
    1041 }
    1042 
    1043 int irc_send( irc_t *irc, char *nick, char *s, int flags )
    1044 {
    1045         struct groupchat *c = NULL;
    1046         user_t *u = NULL;
    1047        
    1048         if( strchr( CTYPES, *nick ) )
    1049         {
    1050                 if( !( c = irc_chat_by_channel( irc, nick ) ) )
    1051                 {
    1052                         irc_reply( irc, 403, "%s :Channel does not exist", nick );
    1053                         return( 0 );
    1054                 }
    1055         }
    1056         else
    1057         {
    1058                 u = user_find( irc, nick );
    1059                
    1060                 if( !u )
    1061                 {
    1062                         if( irc->is_private )
    1063                                 irc_reply( irc, 401, "%s :Nick does not exist", nick );
    1064                         else
    1065                                 irc_usermsg( irc, "Nick `%s' does not exist!", nick );
    1066                         return( 0 );
    1067                 }
    1068         }
    1069        
    1070         if( *s == 1 && s[strlen(s)-1] == 1 )
    1071         {
    1072                 if( g_strncasecmp( s + 1, "ACTION", 6 ) == 0 )
    1073                 {
    1074                         if( s[7] == ' ' ) s ++;
    1075                         s += 3;
    1076                         *(s++) = '/';
    1077                         *(s++) = 'm';
    1078                         *(s++) = 'e';
    1079                         *(s++) = ' ';
    1080                         s -= 4;
    1081                         s[strlen(s)-1] = 0;
    1082                 }
    1083                 else if( g_strncasecmp( s + 1, "VERSION", 7 ) == 0 )
    1084                 {
    1085                         u = user_find( irc, irc->mynick );
    1086                         irc_privmsg( irc, u, "NOTICE", irc->nick, "", "\001VERSION BitlBee " BITLBEE_VERSION " " ARCH "/" CPU "\001" );
    1087                         return( 1 );
    1088                 }
    1089                 else if( g_strncasecmp( s + 1, "PING", 4 ) == 0 )
    1090                 {
    1091                         u = user_find( irc, irc->mynick );
    1092                         irc_privmsg( irc, u, "NOTICE", irc->nick, "", s );
    1093                         return( 1 );
    1094                 }
    1095                 else if( g_strncasecmp( s + 1, "TYPING", 6 ) == 0 )
    1096                 {
    1097                         if( u && u->ic && u->ic->acc->prpl->send_typing && strlen( s ) >= 10 )
    1098                         {
    1099                                 time_t current_typing_notice = time( NULL );
    1100                                
    1101                                 if( current_typing_notice - u->last_typing_notice >= 5 )
    1102                                 {
    1103                                         u->ic->acc->prpl->send_typing( u->ic, u->handle, ( s[8] - '0' ) << 8 );
    1104                                         u->last_typing_notice = current_typing_notice;
    1105                                 }
    1106                         }
    1107                         return( 1 );
    1108                 }
    1109                 else if( g_strncasecmp( s + 1, "DCC", 3 ) == 0 )
    1110                 {
    1111                         if( u && u->ic && u->ic->acc->prpl->transfer_request )
    1112                         {
    1113                                 file_transfer_t *ft = dcc_request( u->ic, s + 5 );
    1114                                 if ( ft )
    1115                                         u->ic->acc->prpl->transfer_request( u->ic, ft, u->handle );
    1116                         }
    1117                         return( 1 );
    1118                 }               
    1119                 else
    1120                 {
    1121                         irc_usermsg( irc, "Supported CTCPs are ACTION, VERSION, PING, TYPING, DCC" );
    1122                         return( 0 );
    1123                 }
    1124         }
    1125        
    1126         if( u )
    1127         {
    1128                 /* For the next message, we probably do have to send new notices... */
    1129                 u->last_typing_notice = 0;
    1130                 u->is_private = irc->is_private;
    1131                
    1132                 if( u->is_private )
    1133                 {
    1134                         if( !u->online )
    1135                                 irc_reply( irc, 301, "%s :%s", u->nick, "User is offline" );
    1136                         else if( u->away )
    1137                                 irc_reply( irc, 301, "%s :%s", u->nick, u->away );
    1138                 }
    1139                
    1140                 if( u->send_handler )
    1141                 {
    1142                         u->send_handler( irc, u, s, flags );
    1143                         return 1;
    1144                 }
    1145         }
    1146         else if( c && c->ic && c->ic->acc && c->ic->acc->prpl )
    1147         {
    1148                 return( imc_chat_msg( c, s, 0 ) );
    1149         }
    1150        
    1151         return( 0 );
    1152 }
    1153 
    1154 static gboolean buddy_send_handler_delayed( gpointer data, gint fd, b_input_condition cond )
    1155 {
    1156         user_t *u = data;
    1157        
    1158         /* Shouldn't happen, but just to be sure. */
    1159         if( u->sendbuf_len < 2 )
    1160                 return FALSE;
    1161        
    1162         u->sendbuf[u->sendbuf_len-2] = 0; /* Cut off the last newline */
    1163         imc_buddy_msg( u->ic, u->handle, u->sendbuf, u->sendbuf_flags );
    1164        
    1165         g_free( u->sendbuf );
    1166         u->sendbuf = NULL;
    1167         u->sendbuf_len = 0;
    1168         u->sendbuf_timer = 0;
    1169         u->sendbuf_flags = 0;
    1170        
    1171         return FALSE;
    1172 }
    1173 
    1174 void buddy_send_handler( irc_t *irc, user_t *u, char *msg, int flags )
    1175 {
    1176         if( !u || !u->ic ) return;
    1177        
    1178         if( set_getbool( &irc->set, "buddy_sendbuffer" ) && set_getint( &irc->set, "buddy_sendbuffer_delay" ) > 0 )
    1179         {
    1180                 int delay;
    1181                
    1182                 if( u->sendbuf_len > 0 && u->sendbuf_flags != flags)
    1183                 {
    1184                         /* Flush the buffer */
    1185                         b_event_remove( u->sendbuf_timer );
    1186                         buddy_send_handler_delayed( u, -1, 0 );
    1187                 }
    1188 
    1189                 if( u->sendbuf_len == 0 )
    1190                 {
    1191                         u->sendbuf_len = strlen( msg ) + 2;
    1192                         u->sendbuf = g_new( char, u->sendbuf_len );
    1193                         u->sendbuf[0] = 0;
    1194                         u->sendbuf_flags = flags;
    1195                 }
    1196                 else
    1197                 {
    1198                         u->sendbuf_len += strlen( msg ) + 1;
    1199                         u->sendbuf = g_renew( char, u->sendbuf, u->sendbuf_len );
    1200                 }
    1201                
    1202                 strcat( u->sendbuf, msg );
    1203                 strcat( u->sendbuf, "\n" );
    1204                
    1205                 delay = set_getint( &irc->set, "buddy_sendbuffer_delay" );
    1206                 if( delay <= 5 )
    1207                         delay *= 1000;
    1208                
    1209                 if( u->sendbuf_timer > 0 )
    1210                         b_event_remove( u->sendbuf_timer );
    1211                 u->sendbuf_timer = b_timeout_add( delay, buddy_send_handler_delayed, u );
    1212         }
    1213         else
    1214         {
    1215                 imc_buddy_msg( u->ic, u->handle, msg, flags );
    1216         }
    1217 }
    1218 
    1219 int irc_privmsg( irc_t *irc, user_t *u, char *type, char *to, char *prefix, char *msg )
    1220 {
    1221         char last = 0;
    1222         char *s = msg, *line = msg;
    1223        
    1224         /* The almighty linesplitter .. woohoo!! */
    1225         while( !last )
    1226         {
    1227                 if( *s == '\r' && *(s+1) == '\n' )
    1228                         *(s++) = 0;
    1229                 if( *s == '\n' )
    1230                 {
    1231                         last = s[1] == 0;
    1232                         *s = 0;
    1233                 }
    1234                 else
    1235                 {
    1236                         last = s[0] == 0;
    1237                 }
    1238                 if( *s == 0 )
    1239                 {
    1240                         if( g_strncasecmp( line, "/me ", 4 ) == 0 && ( !prefix || !*prefix ) && g_strcasecmp( type, "PRIVMSG" ) == 0 )
    1241                         {
    1242                                 irc_write( irc, ":%s!%s@%s %s %s :\001ACTION %s\001", u->nick, u->user, u->host,
    1243                                            type, to, line + 4 );
    1244                         }
    1245                         else
    1246                         {
    1247                                 irc_write( irc, ":%s!%s@%s %s %s :%s%s", u->nick, u->user, u->host,
    1248                                            type, to, prefix ? prefix : "", line );
    1249                         }
    1250                         line = s + 1;
    1251                 }
    1252                 s ++;
    1253         }
    1254        
    1255         return( 1 );
    1256 }
    1257 
    1258 int irc_msgfrom( irc_t *irc, char *nick, char *msg )
    1259 {
    1260         user_t *u = user_find( irc, nick );
    1261         static char *prefix = NULL;
    1262        
    1263         if( !u ) return( 0 );
    1264         if( prefix && *prefix ) g_free( prefix );
    1265        
    1266         if( !u->is_private && nick_cmp( u->nick, irc->mynick ) != 0 )
    1267         {
    1268                 int len = strlen( irc->nick) + 3;
    1269                 prefix = g_new (char, len );
    1270                 g_snprintf( prefix, len, "%s%s", irc->nick, set_getstr( &irc->set, "to_char" ) );
    1271                 prefix[len-1] = 0;
    1272         }
    1273         else
    1274         {
    1275                 prefix = "";
    1276         }
    1277        
    1278         return( irc_privmsg( irc, u, "PRIVMSG", u->is_private ? irc->nick : irc->channel, prefix, msg ) );
    1279 }
    1280 
    1281 int irc_noticefrom( irc_t *irc, char *nick, char *msg )
    1282 {
    1283         user_t *u = user_find( irc, nick );
    1284        
    1285         if( u )
    1286                 return( irc_privmsg( irc, u, "NOTICE", irc->nick, "", msg ) );
    1287         else
    1288                 return( 0 );
    1289 }
     702                irc_write( irc, ":%s!%s@%s MODE %s :%s", irc->user->nick,
     703                           irc->user->user, irc->user->host, irc->user->nick,
     704                           changes );
     705}
     706
    1290707
    1291708/* Returns 0 if everything seems to be okay, a number >0 when there was a
     
    1325742}
    1326743
    1327 struct groupchat *irc_chat_by_channel( irc_t *irc, char *channel )
    1328 {
    1329         struct groupchat *c;
    1330         account_t *a;
    1331        
    1332         /* This finds the connection which has a conversation which belongs to this channel */
    1333         for( a = irc->accounts; a; a = a->next )
    1334         {
    1335                 if( a->ic == NULL )
    1336                         continue;
    1337                
    1338                 c = a->ic->groupchats;
    1339                 while( c )
    1340                 {
    1341                         if( c->channel && g_strcasecmp( c->channel, channel ) == 0 )
    1342                                 return c;
    1343                        
    1344                         c = c->next;
    1345                 }
    1346         }
    1347        
    1348         return NULL;
    1349 }
     744
     745static char *set_eval_charset( set_t *set, char *value )
     746{
     747        irc_t *irc = set->data;
     748        GIConv ic, oc;
     749
     750        if( g_strcasecmp( value, "none" ) == 0 )
     751                value = g_strdup( "utf-8" );
     752
     753        if( ( ic = g_iconv_open( "utf-8", value ) ) == (GIConv) -1 )
     754        {
     755                return NULL;
     756        }
     757        if( ( oc = g_iconv_open( value, "utf-8" ) ) == (GIConv) -1 )
     758        {
     759                g_iconv_close( ic );
     760                return NULL;
     761        }
     762       
     763        if( irc->iconv != (GIConv) -1 )
     764                g_iconv_close( irc->iconv );
     765        if( irc->oconv != (GIConv) -1 )
     766                g_iconv_close( irc->oconv );
     767       
     768        irc->iconv = ic;
     769        irc->oconv = oc;
     770
     771        return value;
     772}
  • irc.h

    r3ab1d31 ra87e6ba  
    55  \********************************************************************/
    66
    7 /* The big hairy IRCd part of the project                               */
     7/* The IRC-based UI (for now the only one)                              */
    88
    99/*
     
    3333#define IRC_PING_STRING "PinglBee"
    3434
    35 #define UMODES "abisw"
    36 #define UMODES_PRIV "Ro"
    37 #define CMODES "nt"
    38 #define CMODE "t"
    39 #define UMODE "s"
    40 #define CTYPES "&#"
     35#define UMODES "abisw"     /* Allowed umodes (although they mostly do nothing) */
     36#define UMODES_PRIV "Ro"   /* Allowed, but not by user directly */
     37#define UMODES_KEEP "R"    /* Don't allow unsetting using /MODE */
     38#define CMODES "nt"        /* Allowed modes */
     39#define CMODE "t"          /* Default mode */
     40#define UMODE "s"          /* Default mode */
     41
     42#define CTYPES "&#"        /* Valid channel name prefixes */
    4143
    4244typedef enum
     
    4850        USTATUS_SHUTDOWN = 8
    4951} irc_status_t;
     52
     53struct irc_user;
    5054
    5155typedef struct irc
     
    5963        GIConv iconv, oconv;
    6064
    61         int sentbytes;
    62         time_t oldtime;
    63 
     65        struct irc_user *root;
     66        struct irc_user *user;
     67       
     68        char *last_root_cmd;
     69
     70        char *password; /* HACK: Used to save the user's password, but before
     71                           logging in, this may contain a password we should
     72                           send to identify after USER/NICK are received. */
     73
     74        char umode[8];
     75       
     76        struct query *queries;
     77        GSList *file_transfers;
     78       
     79        GSList *users, *channels;
     80        GHashTable *nick_user_hash;
     81        GHashTable *watches;
     82
     83        gint r_watch_source_id;
     84        gint w_watch_source_id;
     85        gint ping_source_id;
     86       
     87        struct bee *b;
     88} irc_t;
     89
     90typedef enum
     91{
     92        IRC_USER_PRIVATE = 1,
     93} irc_user_flags_t;
     94
     95typedef struct irc_user
     96{
     97        irc_t *irc;
     98       
    6499        char *nick;
    65100        char *user;
    66101        char *host;
    67         char *realname;
    68         char *password; /* HACK: Used to save the user's password, but before
    69                            logging in, this may contain a password we should
    70                            send to identify after USER/NICK are received. */
    71 
    72         char umode[8];
    73        
    74         char *myhost;
    75         char *mynick;
    76 
    77         char *channel;
    78         int c_id;
    79 
    80         char is_private;                /* Not too nice... */
    81         char *last_target;
    82        
    83         struct query *queries;
    84         struct account *accounts;
    85         GSList *file_transfers;
    86         struct chat *chatrooms;
    87        
    88         struct __USER *users;
    89         GHashTable *userhash;
    90         GHashTable *watches;
    91         struct __NICK *nicks;
     102        char *fullname;
     103       
     104        /* Nickname in lowercase for case sensitive searches */
     105        char *key;
     106       
     107        irc_user_flags_t flags;
     108       
     109        char *sendbuf;
     110        int sendbuf_len;
     111        guint sendbuf_timer;
     112        //int sendbuf_flags;
     113       
     114        struct bee_user *bu;
     115       
     116        const struct irc_user_funcs *f;
     117} irc_user_t;
     118
     119struct irc_user_funcs
     120{
     121        gboolean (*privmsg)( irc_user_t *iu, const char *msg );
     122};
     123
     124extern const struct irc_user_funcs irc_user_root_funcs;
     125extern const struct irc_user_funcs irc_user_self_funcs;
     126
     127typedef enum
     128{
     129        IRC_CHANNEL_JOINED = 1,
     130} irc_channel_flags_t;
     131
     132typedef struct irc_channel
     133{
     134        irc_t *irc;
     135        char *name;
     136        char mode[8];
     137        int flags;
     138       
     139        char *topic;
     140        char *topic_who;
     141        time_t topic_time;
     142       
     143        GSList *users;
    92144        struct set *set;
    93 
    94         gint r_watch_source_id;
    95         gint w_watch_source_id;
    96         gint ping_source_id;
    97 } irc_t;
    98 
    99 #include "user.h"
    100 
     145       
     146        const struct irc_channel_funcs *f;
     147} irc_channel_t;
     148
     149struct irc_channel_funcs
     150{
     151        gboolean (*privmsg)( irc_channel_t *iu, const char *msg );
     152};
     153
     154extern const struct bee_ui_funcs irc_ui_funcs;
     155
     156/* irc.c */
    101157extern GSList *irc_connection_list;
    102158
     
    104160void irc_abort( irc_t *irc, int immed, char *format, ... ) G_GNUC_PRINTF( 3, 4 );
    105161void irc_free( irc_t *irc );
    106 
    107 void irc_exec( irc_t *irc, char **cmd );
     162void irc_setpass (irc_t *irc, const char *pass);
     163
    108164void irc_process( irc_t *irc );
    109165char **irc_parse_line( char *line );
    110166char *irc_build_line( char **cmd );
    111167
    112 void irc_vawrite( irc_t *irc, char *format, va_list params );
    113168void irc_write( irc_t *irc, char *format, ... ) G_GNUC_PRINTF( 2, 3 );
    114169void irc_write_all( int now, char *format, ... ) G_GNUC_PRINTF( 2, 3 );
    115 void irc_reply( irc_t *irc, int code, char *format, ... ) G_GNUC_PRINTF( 3, 4 );
    116 G_MODULE_EXPORT int irc_usermsg( irc_t *irc, char *format, ... ) G_GNUC_PRINTF( 2, 3 );
    117 char **irc_tokenize( char *buffer );
    118 
    119 void irc_login( irc_t *irc );
     170void irc_vawrite( irc_t *irc, char *format, va_list params );
     171
    120172int irc_check_login( irc_t *irc );
    121 void irc_motd( irc_t *irc );
    122 void irc_names( irc_t *irc, char *channel );
    123 void irc_topic( irc_t *irc, char *channel );
    124 void irc_umode_set( irc_t *irc, char *s, int allow_priv );
    125 void irc_who( irc_t *irc, char *channel );
    126 void irc_spawn( irc_t *irc, user_t *u );
    127 void irc_join( irc_t *irc, user_t *u, char *channel );
    128 void irc_part( irc_t *irc, user_t *u, char *channel );
    129 void irc_kick( irc_t *irc, user_t *u, char *channel, user_t *kicker );
    130 void irc_kill( irc_t *irc, user_t *u );
    131 void irc_invite( irc_t *irc, char *nick, char *channel );
    132 void irc_whois( irc_t *irc, char *nick );
    133 void irc_setpass( irc_t *irc, const char *pass ); /* USE WITH CAUTION! */
    134 
    135 int irc_send( irc_t *irc, char *nick, char *s, int flags );
    136 int irc_privmsg( irc_t *irc, user_t *u, char *type, char *to, char *prefix, char *msg );
    137 int irc_msgfrom( irc_t *irc, char *nick, char *msg );
    138 int irc_noticefrom( irc_t *irc, char *nick, char *msg );
    139 
    140 void buddy_send_handler( irc_t *irc, user_t *u, char *msg, int flags );
    141 struct groupchat *irc_chat_by_channel( irc_t *irc, char *channel );
     173
     174void irc_umode_set( irc_t *irc, const char *s, gboolean allow_priv );
     175
     176/* irc_channel.c */
     177irc_channel_t *irc_channel_new( irc_t *irc, const char *name );
     178irc_channel_t *irc_channel_by_name( irc_t *irc, const char *name );
     179int irc_channel_free( irc_channel_t *ic );
     180int irc_channel_add_user( irc_channel_t *ic, irc_user_t *iu );
     181int irc_channel_del_user( irc_channel_t *ic, irc_user_t *iu );
     182gboolean irc_channel_has_user( irc_channel_t *ic, irc_user_t *iu );
     183int irc_channel_set_topic( irc_channel_t *ic, const char *topic, const irc_user_t *who );
     184gboolean irc_channel_name_ok( const char *name );
     185
     186/* irc_commands.c */
     187void irc_exec( irc_t *irc, char **cmd );
     188
     189/* irc_send.c */
     190void irc_send_num( irc_t *irc, int code, char *format, ... ) G_GNUC_PRINTF( 3, 4 );
     191void irc_send_login( irc_t *irc );
     192void irc_send_motd( irc_t *irc );
     193void irc_usermsg( irc_t *irc, char *format, ... );
     194void irc_send_join( irc_channel_t *ic, irc_user_t *iu );
     195void irc_send_part( irc_channel_t *ic, irc_user_t *iu, const char *reason );
     196void irc_send_names( irc_channel_t *ic );
     197void irc_send_topic( irc_channel_t *ic, gboolean topic_change );
     198void irc_send_whois( irc_user_t *iu );
     199void irc_send_who( irc_t *irc, GSList *l, const char *channel );
     200void irc_send_msg( irc_user_t *iu, const char *type, const char *dst, const char *msg, const char *prefix );
     201void irc_send_msg_raw( irc_user_t *iu, const char *type, const char *dst, const char *msg );
     202void irc_send_nick( irc_user_t *iu, const char *new );
     203
     204/* irc_user.c */
     205irc_user_t *irc_user_new( irc_t *irc, const char *nick );
     206int irc_user_free( irc_t *irc, const char *nick );
     207irc_user_t *irc_user_by_name( irc_t *irc, const char *nick );
     208int irc_user_set_nick( irc_user_t *iu, const char *new );
     209gint irc_user_cmp( gconstpointer a_, gconstpointer b_ );
    142210
    143211#endif
  • irc_commands.c

    r3ab1d31 ra87e6ba  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2006 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2010 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    5353        else if( global.conf->auth_pass )
    5454        {
    55                 irc_reply( irc, 464, ":Incorrect password" );
     55                irc_send_num( irc, 464, ":Incorrect password" );
    5656        }
    5757        else
    5858        {
    5959                /* Remember the password and try to identify after USER/NICK. */
    60                 irc_setpass( irc, cmd[1] );
     60                /*irc_setpass( irc, cmd[1] ); */
    6161                irc_check_login( irc );
    6262        }
     
    6565static void irc_cmd_user( irc_t *irc, char **cmd )
    6666{
    67         irc->user = g_strdup( cmd[1] );
    68         irc->realname = g_strdup( cmd[4] );
     67        irc->user->user = g_strdup( cmd[1] );
     68        irc->user->fullname = g_strdup( cmd[4] );
    6969       
    7070        irc_check_login( irc );
     
    7373static void irc_cmd_nick( irc_t *irc, char **cmd )
    7474{
    75         if( irc->nick )
    76         {
    77                 irc_reply( irc, 438, ":The hand of the deity is upon thee, thy nick may not change" );
    78         }
    79         /* This is not clean, but for now it'll have to be like this... */
    80         else if( ( nick_cmp( cmd[1], irc->mynick ) == 0 ) || ( nick_cmp( cmd[1], NS_NICK ) == 0 ) )
    81         {
    82                 irc_reply( irc, 433, ":This nick is already in use" );
     75        if( irc->user->nick )
     76        {
     77                irc_send_num( irc, 438, ":The hand of the deity is upon thee, thy nick may not change" );
     78        }
     79        else if( irc_user_by_name( irc, cmd[1] ) )
     80        {
     81                irc_send_num( irc, 433, ":This nick is already in use" );
    8382        }
    8483        else if( !nick_ok( cmd[1] ) )
    8584        {
    8685                /* [SH] Invalid characters. */
    87                 irc_reply( irc, 432, ":This nick contains invalid characters" );
    88         }
    89         else
    90         {
    91                 irc->nick = g_strdup( cmd[1] );
     86                irc_send_num( irc, 432, ":This nick contains invalid characters" );
     87        }
     88        else
     89        {
     90                irc->user->nick = g_strdup( cmd[1] );
    9291               
    9392                irc_check_login( irc );
     
    105104static void irc_cmd_ping( irc_t *irc, char **cmd )
    106105{
    107         irc_write( irc, ":%s PONG %s :%s", irc->myhost, irc->myhost, cmd[1]?cmd[1]:irc->myhost );
    108 }
    109 
    110 static void irc_cmd_oper( irc_t *irc, char **cmd )
    111 {
    112         if( global.conf->oper_pass &&
    113             ( strncmp( global.conf->oper_pass, "md5:", 4 ) == 0 ?
    114                 md5_verify_password( cmd[2], global.conf->oper_pass + 4 ) == 0 :
    115                 strcmp( cmd[2], global.conf->oper_pass ) == 0 ) )
    116         {
    117                 irc_umode_set( irc, "+o", 1 );
    118                 irc_reply( irc, 381, ":Password accepted" );
    119         }
    120         else
    121         {
    122                 irc_reply( irc, 432, ":Incorrect password" );
    123         }
     106        irc_write( irc, ":%s PONG %s :%s", irc->root->host,
     107                   irc->root->host, cmd[1]?cmd[1]:irc->root->host );
     108}
     109
     110static void irc_cmd_pong( irc_t *irc, char **cmd )
     111{
     112        /* We could check the value we get back from the user, but in
     113           fact we don't care, we're just happy s/he's still alive. */
     114        irc->last_pong = gettime();
     115        irc->pinging = 0;
     116}
     117
     118static void irc_cmd_join( irc_t *irc, char **cmd )
     119{
     120        irc_channel_t *ic;
     121       
     122        if( ( ic = irc_channel_by_name( irc, cmd[1] ) ) == NULL )
     123                ic = irc_channel_new( irc, cmd[1] );
     124       
     125        if( ic == NULL )
     126                irc_send_num( irc, 479, "%s :Invalid channel name", cmd[1] );
     127       
     128        if( ic->flags & IRC_CHANNEL_JOINED )
     129                return; /* Dude, you're already there...
     130                           RFC doesn't have any reply for that though? */
     131       
     132        irc_channel_add_user( ic, irc->user );
     133}
     134
     135static void irc_cmd_names( irc_t *irc, char **cmd )
     136{
     137        irc_channel_t *ic;
     138       
     139        if( cmd[1] && ( ic = irc_channel_by_name( irc, cmd[1] ) ) )
     140                irc_send_names( ic );
     141        /* With no args, we should show /names of all chans. Make the code
     142           below work well if necessary.
     143        else
     144        {
     145                GSList *l;
     146               
     147                for( l = irc->channels; l; l = l->next )
     148                        irc_send_names( l->data );
     149        }
     150        */
     151}
     152
     153static void irc_cmd_part( irc_t *irc, char **cmd )
     154{
     155        irc_channel_t *ic;
     156       
     157        if( ( ic = irc_channel_by_name( irc, cmd[1] ) ) == NULL )
     158        {
     159                irc_send_num( irc, 403, "%s :No such channel", cmd[1] );
     160        }
     161        else if( !irc_channel_del_user( ic, irc->user ) )
     162        {
     163                irc_send_num( irc, 442, "%s :You're not on that channel", cmd[1] );
     164        }
     165}
     166
     167static void irc_cmd_whois( irc_t *irc, char **cmd )
     168{
     169        char *nick = cmd[1];
     170        irc_user_t *iu = irc_user_by_name( irc, nick );
     171       
     172        if( iu )
     173                irc_send_whois( iu );
     174        else
     175                irc_send_num( irc, 401, "%s :Nick does not exist", nick );
     176}
     177
     178static void irc_cmd_whowas( irc_t *irc, char **cmd )
     179{
     180        /* For some reason irssi tries a whowas when whois fails. We can
     181           ignore this, but then the user never gets a "user not found"
     182           message from irssi which is a bit annoying. So just respond
     183           with not-found and irssi users will get better error messages */
     184       
     185        irc_send_num( irc, 406, "%s :Nick does not exist", cmd[1] );
     186        irc_send_num( irc, 369, "%s :End of WHOWAS", cmd[1] );
     187}
     188
     189static void irc_cmd_motd( irc_t *irc, char **cmd )
     190{
     191        irc_send_motd( irc );
    124192}
    125193
    126194static void irc_cmd_mode( irc_t *irc, char **cmd )
    127195{
    128         if( strchr( CTYPES, *cmd[1] ) )
    129         {
    130                 if( cmd[2] )
     196        if( irc_channel_name_ok( cmd[1] ) )
     197        {
     198                irc_channel_t *ic;
     199               
     200                if( ( ic = irc_channel_by_name( irc, cmd[1] ) ) == NULL )
     201                        irc_send_num( irc, 403, "%s :No such channel", cmd[1] );
     202                else if( cmd[2] )
    131203                {
    132204                        if( *cmd[2] == '+' || *cmd[2] == '-' )
    133                                 irc_reply( irc, 477, "%s :Can't change channel modes", cmd[1] );
     205                                irc_send_num( irc, 477, "%s :Can't change channel modes", cmd[1] );
    134206                        else if( *cmd[2] == 'b' )
    135                                 irc_reply( irc, 368, "%s :No bans possible", cmd[1] );
     207                                irc_send_num( irc, 368, "%s :No bans possible", cmd[1] );
    136208                }
    137209                else
    138                         irc_reply( irc, 324, "%s +%s", cmd[1], CMODE );
    139         }
    140         else
    141         {
    142                 if( nick_cmp( cmd[1], irc->nick ) == 0 )
     210                        irc_send_num( irc, 324, "%s +%s", cmd[1], ic->mode );
     211        }
     212        else
     213        {
     214                if( nick_cmp( cmd[1], irc->user->nick ) == 0 )
    143215                {
    144216                        if( cmd[2] )
    145217                                irc_umode_set( irc, cmd[2], 0 );
    146218                        else
    147                                 irc_reply( irc, 221, "+%s", irc->umode );
     219                                irc_send_num( irc, 221, "+%s", irc->umode );
    148220                }
    149221                else
    150                         irc_reply( irc, 502, ":Don't touch their modes" );
    151         }
    152 }
    153 
    154 static void irc_cmd_names( irc_t *irc, char **cmd )
    155 {
    156         irc_names( irc, cmd[1]?cmd[1]:irc->channel );
    157 }
    158 
    159 static void irc_cmd_part( irc_t *irc, char **cmd )
    160 {
    161         struct groupchat *c;
    162        
    163         if( g_strcasecmp( cmd[1], irc->channel ) == 0 )
    164         {
    165                 user_t *u = user_find( irc, irc->nick );
    166                
    167                 /* Not allowed to leave control channel */
    168                 irc_part( irc, u, irc->channel );
    169                 irc_join( irc, u, irc->channel );
    170         }
    171         else if( ( c = irc_chat_by_channel( irc, cmd[1] ) ) )
    172         {
    173                 user_t *u = user_find( irc, irc->nick );
    174                
    175                 irc_part( irc, u, c->channel );
    176                
    177                 if( c->ic )
    178                 {
    179                         c->joined = 0;
    180                         c->ic->acc->prpl->chat_leave( c );
    181                 }
    182         }
    183         else
    184         {
    185                 irc_reply( irc, 403, "%s :No such channel", cmd[1] );
    186         }
    187 }
    188 
    189 static void irc_cmd_join( irc_t *irc, char **cmd )
    190 {
    191         if( g_strcasecmp( cmd[1], irc->channel ) == 0 )
    192                 ; /* Dude, you're already there...
    193                      RFC doesn't have any reply for that though? */
    194         else if( cmd[1] )
    195         {
    196                 struct chat *c;
    197                
    198                 if( strchr( CTYPES, cmd[1][0] ) == NULL || cmd[1][1] == 0 )
    199                         irc_reply( irc, 479, "%s :Invalid channel name", cmd[1] );
    200                 else if( ( c = chat_bychannel( irc, cmd[1] ) ) && c->acc && c->acc->ic )
    201                         chat_join( irc, c, cmd[2] );
    202                 else
    203                         irc_reply( irc, 403, "%s :No such channel", cmd[1] );
    204         }
    205 }
    206 
    207 static void irc_cmd_invite( irc_t *irc, char **cmd )
    208 {
    209         char *nick = cmd[1], *channel = cmd[2];
    210         struct groupchat *c = irc_chat_by_channel( irc, channel );
    211         user_t *u = user_find( irc, nick );
    212        
    213         if( u && c && ( u->ic == c->ic ) )
    214                 if( c->ic && c->ic->acc->prpl->chat_invite )
    215                 {
    216                         c->ic->acc->prpl->chat_invite( c, u->handle, NULL );
    217                         irc_reply( irc, 341, "%s %s", nick, channel );
    218                         return;
    219                 }
    220        
    221         irc_reply( irc, 482, "%s :Invite impossible; User/Channel non-existent or incompatible", channel );
     222                        irc_send_num( irc, 502, ":Don't touch their modes" );
     223        }
     224}
     225
     226static void irc_cmd_who( irc_t *irc, char **cmd )
     227{
     228        char *channel = cmd[1];
     229        irc_channel_t *ic;
     230       
     231        if( !channel || *channel == '0' || *channel == '*' || !*channel )
     232                irc_send_who( irc, irc->users, "**" );
     233        else if( ( ic = irc_channel_by_name( irc, channel ) ) )
     234                irc_send_who( irc, ic->users, channel );
     235        else
     236                irc_send_num( irc, 403, "%s :No such channel", channel );
    222237}
    223238
    224239static void irc_cmd_privmsg( irc_t *irc, char **cmd )
    225240{
    226         if ( !cmd[2] )
    227         {
    228                 irc_reply( irc, 412, ":No text to send" );
    229         }
    230         else if ( irc->nick && g_strcasecmp( cmd[1], irc->nick ) == 0 )
    231         {
    232                 irc_write( irc, ":%s!%s@%s %s %s :%s", irc->nick, irc->user, irc->host, cmd[0], cmd[1], cmd[2] );
     241        irc_channel_t *ic;
     242        irc_user_t *iu;
     243       
     244        if( !cmd[2] )
     245        {
     246                irc_send_num( irc, 412, ":No text to send" );
     247        }
     248        else if( irc_channel_name_ok( cmd[1] ) &&
     249                 ( ic = irc_channel_by_name( irc, cmd[1] ) ) )
     250        {
     251                if( ic->f->privmsg )
     252                        ic->f->privmsg( ic, cmd[2] );
     253        }
     254        else if( ( iu = irc_user_by_name( irc, cmd[1] ) ) )
     255        {
     256                if( iu->f->privmsg )
     257                        iu->f->privmsg( iu, cmd[2] );
     258        }
     259        else
     260        {
     261                irc_send_num( irc, 401, "%s :No such nick/channel", cmd[1] );
     262        }
     263
     264
     265#if 0
     266        else if( irc->nick && g_strcasecmp( cmd[1], irc->nick ) == 0 )
     267        {
    233268        }
    234269        else
     
    271306                irc_send( irc, cmd[1], cmd[2], ( g_strcasecmp( cmd[0], "NOTICE" ) == 0 ) ? OPT_AWAY : 0 );
    272307        }
    273 }
    274 
    275 static void irc_cmd_who( irc_t *irc, char **cmd )
    276 {
    277         char *channel = cmd[1];
    278         user_t *u = irc->users;
    279         struct groupchat *c;
    280         GList *l;
    281        
    282         if( !channel || *channel == '0' || *channel == '*' || !*channel )
    283                 while( u )
    284                 {
    285                         irc_reply( irc, 352, "%s %s %s %s %s %c :0 %s", u->online ? irc->channel : "*", u->user, u->host, irc->myhost, u->nick, u->online ? ( u->away ? 'G' : 'H' ) : 'G', u->realname );
    286                         u = u->next;
    287                 }
    288         else if( g_strcasecmp( channel, irc->channel ) == 0 )
    289                 while( u )
    290                 {
    291                         if( u->online )
    292                                 irc_reply( irc, 352, "%s %s %s %s %s %c :0 %s", channel, u->user, u->host, irc->myhost, u->nick, u->away ? 'G' : 'H', u->realname );
    293                         u = u->next;
    294                 }
    295         else if( ( c = irc_chat_by_channel( irc, channel ) ) )
    296                 for( l = c->in_room; l; l = l->next )
    297                 {
    298                         if( ( u = user_findhandle( c->ic, l->data ) ) )
    299                                 irc_reply( irc, 352, "%s %s %s %s %s %c :0 %s", channel, u->user, u->host, irc->myhost, u->nick, u->away ? 'G' : 'H', u->realname );
    300                 }
    301         else if( ( u = user_find( irc, channel ) ) )
    302                 irc_reply( irc, 352, "%s %s %s %s %s %c :0 %s", channel, u->user, u->host, irc->myhost, u->nick, u->online ? ( u->away ? 'G' : 'H' ) : 'G', u->realname );
    303        
    304         irc_reply( irc, 315, "%s :End of /WHO list", channel?channel:"**" );
     308#endif
     309}
     310
     311static void irc_cmd_nickserv( irc_t *irc, char **cmd )
     312{
     313        /* [SH] This aliases the NickServ command to PRIVMSG root */
     314        /* [TV] This aliases the NS command to PRIVMSG root as well */
     315        root_command( irc, cmd + 1 );
     316}
     317
     318
     319
     320#if 0
     321//#if 0
     322static void irc_cmd_oper( irc_t *irc, char **cmd )
     323{
     324        if( global.conf->oper_pass &&
     325            ( strncmp( global.conf->oper_pass, "md5:", 4 ) == 0 ?
     326                md5_verify_password( cmd[2], global.conf->oper_pass + 4 ) == 0 :
     327                strcmp( cmd[2], global.conf->oper_pass ) == 0 ) )
     328        {
     329                irc_umode_set( irc, "+o", 1 );
     330                irc_send_num( irc, 381, ":Password accepted" );
     331        }
     332        else
     333        {
     334                irc_send_num( irc, 432, ":Incorrect password" );
     335        }
     336}
     337
     338static void irc_cmd_invite( irc_t *irc, char **cmd )
     339{
     340        char *nick = cmd[1], *channel = cmd[2];
     341        struct groupchat *c = irc_chat_by_channel( irc, channel );
     342        user_t *u = user_find( irc, nick );
     343       
     344        if( u && c && ( u->ic == c->ic ) )
     345                if( c->ic && c->ic->acc->prpl->chat_invite )
     346                {
     347                        c->ic->acc->prpl->chat_invite( c, u->handle, NULL );
     348                        irc_send_num( irc, 341, "%s %s", nick, channel );
     349                        return;
     350                }
     351       
     352        irc_send_num( irc, 482, "%s :Invite impossible; User/Channel non-existent or incompatible", channel );
    305353}
    306354
     
    320368                {
    321369                        if( u->online && u->away )
    322                                 irc_reply( irc, 302, ":%s=-%s@%s", u->nick, u->user, u->host );
     370                                irc_send_num( irc, 302, ":%s=-%s@%s", u->nick, u->user, u->host );
    323371                        else
    324                                 irc_reply( irc, 302, ":%s=+%s@%s", u->nick, u->user, u->host );
     372                                irc_send_num( irc, 302, ":%s=+%s@%s", u->nick, u->user, u->host );
    325373                }
    326374}
     
    377425                buff[strlen(buff)-1] = '\0';
    378426       
    379         irc_reply( irc, 303, ":%s", buff );
     427        irc_send_num( irc, 303, ":%s", buff );
    380428}
    381429
     
    406454                       
    407455                        if( u && u->online )
    408                                 irc_reply( irc, 604, "%s %s %s %d :%s", u->nick, u->user, u->host, (int) time( NULL ), "is online" );
     456                                irc_send_num( irc, 604, "%s %s %s %d :%s", u->nick, u->user, u->host, (int) time( NULL ), "is online" );
    409457                        else
    410                                 irc_reply( irc, 605, "%s %s %s %d :%s", nick, "*", "*", (int) time( NULL ), "is offline" );
     458                                irc_send_num( irc, 605, "%s %s %s %d :%s", nick, "*", "*", (int) time( NULL ), "is offline" );
    411459                }
    412460                else if( cmd[i][0] == '-' )
     
    419467                                g_free( okey );
    420468                               
    421                                 irc_reply( irc, 602, "%s %s %s %d :%s", nick, "*", "*", 0, "Stopped watching" );
     469                                irc_send_num( irc, 602, "%s %s %s %d :%s", nick, "*", "*", 0, "Stopped watching" );
    422470                        }
    423471                }
     
    463511                u->away[j] = 0;
    464512               
    465                 irc_reply( irc, 306, ":You're now away: %s", u->away );
     513                irc_send_num( irc, 306, ":You're now away: %s", u->away );
    466514                /* irc_umode_set( irc, irc->myhost, "+a" ); */
    467515        }
     
    471519                u->away = NULL;
    472520                /* irc_umode_set( irc, irc->myhost, "-a" ); */
    473                 irc_reply( irc, 305, ":Welcome back" );
     521                irc_send_num( irc, 305, ":Welcome back" );
    474522        }
    475523       
     
    477525}
    478526
    479 static void irc_cmd_whois( irc_t *irc, char **cmd )
    480 {
    481         char *nick = cmd[1];
    482         user_t *u = user_find( irc, nick );
    483        
    484         if( u )
    485         {
    486                 irc_reply( irc, 311, "%s %s %s * :%s", u->nick, u->user, u->host, u->realname );
    487                
    488                 if( u->ic )
    489                         irc_reply( irc, 312, "%s %s.%s :%s network", u->nick, u->ic->acc->user,
    490                                    u->ic->acc->server && *u->ic->acc->server ? u->ic->acc->server : "",
    491                                    u->ic->acc->prpl->name );
    492                 else
    493                         irc_reply( irc, 312, "%s %s :%s", u->nick, irc->myhost, IRCD_INFO );
    494                
    495                 if( !u->online )
    496                         irc_reply( irc, 301, "%s :%s", u->nick, "User is offline" );
    497                 else if( u->away )
    498                         irc_reply( irc, 301, "%s :%s", u->nick, u->away );
    499                 if( u->status_msg )
    500                         irc_reply( irc, 333, "%s :Status: %s", u->nick, u->status_msg );
    501                
    502                 irc_reply( irc, 318, "%s :End of /WHOIS list", nick );
    503         }
    504         else
    505         {
    506                 irc_reply( irc, 401, "%s :Nick does not exist", nick );
    507         }
    508 }
    509 
    510 static void irc_cmd_whowas( irc_t *irc, char **cmd )
    511 {
    512         /* For some reason irssi tries a whowas when whois fails. We can
    513            ignore this, but then the user never gets a "user not found"
    514            message from irssi which is a bit annoying. So just respond
    515            with not-found and irssi users will get better error messages */
    516        
    517         irc_reply( irc, 406, "%s :Nick does not exist", cmd[1] );
    518         irc_reply( irc, 369, "%s :End of WHOWAS", cmd[1] );
    519 }
    520 
    521 static void irc_cmd_nickserv( irc_t *irc, char **cmd )
    522 {
    523         /* [SH] This aliases the NickServ command to PRIVMSG root */
    524         /* [TV] This aliases the NS command to PRIVMSG root as well */
    525         root_command( irc, cmd + 1 );
    526 }
    527 
    528 static void irc_cmd_motd( irc_t *irc, char **cmd )
    529 {
    530         irc_motd( irc );
    531 }
    532 
    533 static void irc_cmd_pong( irc_t *irc, char **cmd )
    534 {
    535         /* We could check the value we get back from the user, but in
    536            fact we don't care, we're just happy he's still alive. */
    537         irc->last_pong = gettime();
    538         irc->pinging = 0;
    539 }
    540 
    541527static void irc_cmd_version( irc_t *irc, char **cmd )
    542528{
    543         irc_reply( irc, 351, "bitlbee-%s. %s :%s/%s ", BITLBEE_VERSION, irc->myhost, ARCH, CPU );
     529        irc_send_num( irc, 351, "bitlbee-%s. %s :%s/%s ", BITLBEE_VERSION, irc->myhost, ARCH, CPU );
    544530}
    545531
     
    572558                ipc_to_master( cmd );
    573559       
    574         irc_reply( irc, 382, "%s :Rehashing", global.conf_file );
    575 }
     560        irc_send_num( irc, 382, "%s :Rehashing", global.conf_file );
     561}
     562#endif
    576563
    577564static const command_t irc_commands[] = {
     
    581568        { "quit",        0, irc_cmd_quit,        0 },
    582569        { "ping",        0, irc_cmd_ping,        0 },
     570        { "pong",        0, irc_cmd_pong,        IRC_CMD_LOGGED_IN },
     571        { "join",        1, irc_cmd_join,        IRC_CMD_LOGGED_IN },
     572        { "names",       1, irc_cmd_names,       IRC_CMD_LOGGED_IN },
     573        { "part",        1, irc_cmd_part,        IRC_CMD_LOGGED_IN },
     574        { "whois",       1, irc_cmd_whois,       IRC_CMD_LOGGED_IN },
     575        { "whowas",      1, irc_cmd_whowas,      IRC_CMD_LOGGED_IN },
     576        { "motd",        0, irc_cmd_motd,        IRC_CMD_LOGGED_IN },
     577        { "mode",        1, irc_cmd_mode,        IRC_CMD_LOGGED_IN },
     578        { "who",         0, irc_cmd_who,         IRC_CMD_LOGGED_IN },
     579        { "privmsg",     1, irc_cmd_privmsg,     IRC_CMD_LOGGED_IN },
     580        { "nickserv",    1, irc_cmd_nickserv,    IRC_CMD_LOGGED_IN },
     581        { "ns",          1, irc_cmd_nickserv,    IRC_CMD_LOGGED_IN },
     582#if 0
    583583        { "oper",        2, irc_cmd_oper,        IRC_CMD_LOGGED_IN },
    584         { "mode",        1, irc_cmd_mode,        IRC_CMD_LOGGED_IN },
    585         { "names",       0, irc_cmd_names,       IRC_CMD_LOGGED_IN },
    586         { "part",        1, irc_cmd_part,        IRC_CMD_LOGGED_IN },
    587         { "join",        1, irc_cmd_join,        IRC_CMD_LOGGED_IN },
    588584        { "invite",      2, irc_cmd_invite,      IRC_CMD_LOGGED_IN },
    589         { "privmsg",     1, irc_cmd_privmsg,     IRC_CMD_LOGGED_IN },
    590585        { "notice",      1, irc_cmd_privmsg,     IRC_CMD_LOGGED_IN },
    591         { "who",         0, irc_cmd_who,         IRC_CMD_LOGGED_IN },
    592586        { "userhost",    1, irc_cmd_userhost,    IRC_CMD_LOGGED_IN },
    593587        { "ison",        1, irc_cmd_ison,        IRC_CMD_LOGGED_IN },
     
    595589        { "topic",       1, irc_cmd_topic,       IRC_CMD_LOGGED_IN },
    596590        { "away",        0, irc_cmd_away,        IRC_CMD_LOGGED_IN },
    597         { "whois",       1, irc_cmd_whois,       IRC_CMD_LOGGED_IN },
    598         { "whowas",      1, irc_cmd_whowas,      IRC_CMD_LOGGED_IN },
    599         { "nickserv",    1, irc_cmd_nickserv,    IRC_CMD_LOGGED_IN },
    600         { "ns",          1, irc_cmd_nickserv,    IRC_CMD_LOGGED_IN },
    601         { "motd",        0, irc_cmd_motd,        IRC_CMD_LOGGED_IN },
    602         { "pong",        0, irc_cmd_pong,        IRC_CMD_LOGGED_IN },
    603591        { "version",     0, irc_cmd_version,     IRC_CMD_LOGGED_IN },
    604592        { "completions", 0, irc_cmd_completions, IRC_CMD_LOGGED_IN },
     
    610598        { "restart",     0, NULL,                IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER },
    611599        { "kill",        2, NULL,                IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER },
     600#endif
    612601        { NULL }
    613602};
     
    628617                        if( irc_commands[i].flags & IRC_CMD_PRE_LOGIN && irc->status & USTATUS_LOGGED_IN )
    629618                        {
    630                                 irc_reply( irc, 462, ":Only allowed before logging in" );
     619                                irc_send_num( irc, 462, ":Only allowed before logging in" );
    631620                        }
    632621                        else if( irc_commands[i].flags & IRC_CMD_LOGGED_IN && !( irc->status & USTATUS_LOGGED_IN ) )
    633622                        {
    634                                 irc_reply( irc, 451, ":Register first" );
     623                                irc_send_num( irc, 451, ":Register first" );
    635624                        }
    636625                        else if( irc_commands[i].flags & IRC_CMD_OPER_ONLY && !strchr( irc->umode, 'o' ) )
    637626                        {
    638                                 irc_reply( irc, 481, ":Permission denied - You're not an IRC operator" );
     627                                irc_send_num( irc, 481, ":Permission denied - You're not an IRC operator" );
    639628                        }
    640629                        else if( n_arg < irc_commands[i].required_parameters )
    641630                        {
    642                                 irc_reply( irc, 461, "%s :Need more parameters", cmd[0] );
     631                                irc_send_num( irc, 461, "%s :Need more parameters", cmd[0] );
    643632                        }
    644633                        else if( irc_commands[i].flags & IRC_CMD_TO_MASTER )
     
    657646       
    658647        if( irc->status >= USTATUS_LOGGED_IN )
    659                 irc_reply( irc, 421, "%s :Unknown command", cmd[0] );
    660 }
     648                irc_send_num( irc, 421, "%s :Unknown command", cmd[0] );
     649}
  • nick.c

    r3ab1d31 ra87e6ba  
    7878               
    7979                nick_strip( nick );
    80                 if( set_getbool( &acc->irc->set, "lcnicks" ) )
     80                if( set_getbool( &acc->bee->set, "lcnicks" ) )
    8181                        nick_lc( nick );
    8282        }
     
    9292void nick_dedupe( account_t *acc, const char *handle, char nick[MAX_NICK_LENGTH+1] )
    9393{
     94        irc_t *irc = (irc_t*) acc->bee->ui_data;
    9495        int inf_protection = 256;
    9596       
    9697        /* Now, find out if the nick is already in use at the moment, and make
    9798           subtle changes to make it unique. */
    98         while( !nick_ok( nick ) || user_find( acc->irc, nick ) )
     99        while( !nick_ok( nick ) || irc_user_by_name( irc, nick ) )
    99100        {
    100101                if( strlen( nick ) < ( MAX_NICK_LENGTH - 1 ) )
     
    112113                        int i;
    113114                       
    114                         irc_usermsg( acc->irc, "Warning: Almost had an infinite loop in nick_get()! "
    115                                                "This used to be a fatal BitlBee bug, but we tried to fix it. "
    116                                                "This message should *never* appear anymore. "
    117                                                "If it does, please *do* send us a bug report! "
    118                                                "Please send all the following lines in your report:" );
    119                        
    120                         irc_usermsg( acc->irc, "Trying to get a sane nick for handle %s", handle );
     115                        irc_usermsg( irc, "Warning: Almost had an infinite loop in nick_get()! "
     116                                          "This used to be a fatal BitlBee bug, but we tried to fix it. "
     117                                          "This message should *never* appear anymore. "
     118                                          "If it does, please *do* send us a bug report! "
     119                                          "Please send all the following lines in your report:" );
     120                       
     121                        irc_usermsg( irc, "Trying to get a sane nick for handle %s", handle );
    121122                        for( i = 0; i < MAX_NICK_LENGTH; i ++ )
    122                                 irc_usermsg( acc->irc, "Char %d: %c/%d", i, nick[i], nick[i] );
    123                        
    124                         irc_usermsg( acc->irc, "FAILED. Returning an insane nick now. Things might break. "
    125                                                "Good luck, and please don't forget to paste the lines up here "
    126                                                "in #bitlbee on OFTC or in a mail to wilmer@gaast.net" );
     123                                irc_usermsg( irc, "Char %d: %c/%d", i, nick[i], nick[i] );
     124                       
     125                        irc_usermsg( irc, "FAILED. Returning an insane nick now. Things might break. "
     126                                          "Good luck, and please don't forget to paste the lines up here "
     127                                          "in #bitlbee on OFTC or in a mail to wilmer@gaast.net" );
    127128                       
    128129                        g_snprintf( nick, MAX_NICK_LENGTH + 1, "xx%x", rand() );
  • protocols/Makefile

    r3ab1d31 ra87e6ba  
    1010
    1111# [SH] Program variables
    12 objects = nogaim.o
     12objects = account.o bee.o bee_ft.o bee_user.o nogaim.o
     13
    1314
    1415# [SH] The next two lines should contain the directory name (in $(subdirs))
  • protocols/ft.h

    r3ab1d31 ra87e6ba  
    168168 * the canceled() and free() callbacks given in file will be called by this function.
    169169 */
    170 void imcb_file_canceled( file_transfer_t *file, char *reason );
     170void imcb_file_canceled( struct im_connection *ic, file_transfer_t *file, char *reason );
    171171
    172 gboolean imcb_file_recv_start( file_transfer_t *ft );
     172gboolean imcb_file_recv_start( struct im_connection *ic, file_transfer_t *ft );
    173173
    174 void imcb_file_finished( file_transfer_t *file );
     174void imcb_file_finished( struct im_connection *ic, file_transfer_t *file );
    175175#endif
  • protocols/jabber/iq.c

    r3ab1d31 ra87e6ba  
    392392                        if( ( strcmp( sub, "both" ) == 0 || strcmp( sub, "to" ) == 0 ) )
    393393                        {
    394                                 if( initial || imcb_find_buddy( ic, jid ) == NULL )
     394                                if( initial || bee_user_by_handle( ic->bee, ic, jid ) == NULL )
    395395                                        imcb_add_buddy( ic, jid, ( group && group->text_len ) ?
    396396                                                                   group->text : NULL );
     
    590590            strcmp( s, "result" ) == 0 )
    591591        {
    592                 if( imcb_find_buddy( ic, jid ) == NULL )
     592                if( bee_user_by_handle( ic->bee, ic, jid ) == NULL )
    593593                        imcb_add_buddy( ic, jid, NULL );
    594594        }
  • protocols/jabber/jabber.c

    r3ab1d31 ra87e6ba  
    267267       
    268268        while( jd->filetransfers )
    269                 imcb_file_canceled( ( ( struct jabber_transfer *) jd->filetransfers->data )->ft, "Logging out" );
     269                imcb_file_canceled( ic, ( ( struct jabber_transfer *) jd->filetransfers->data )->ft, "Logging out" );
    270270
    271271        while( jd->streamhosts )
  • protocols/jabber/jabber_util.c

    r3ab1d31 ra87e6ba  
    279279        presence_send_request( bla->ic, bla->handle, "subscribed" );
    280280       
    281         if( imcb_find_buddy( bla->ic, bla->handle ) == NULL )
    282                 imcb_ask_add( bla->ic, bla->handle, NULL );
     281        imcb_ask_add( bla->ic, bla->handle, NULL );
    283282       
    284283        g_free( bla->handle );
     
    462461               
    463462                if( bud == NULL && ( flags & GET_BUDDY_CREAT ) &&
    464                     ( bare_exists || imcb_find_buddy( ic, jid ) ) )
     463                    ( bare_exists || bee_user_by_handle( ic->bee, ic, jid ) ) )
    465464                {
    466465                        *s = '/';
     
    483482                if( bud == NULL )
    484483                        /* No match. Create it now? */
    485                         return ( ( flags & GET_BUDDY_CREAT ) && imcb_find_buddy( ic, jid_ ) ) ?
     484                        return ( ( flags & GET_BUDDY_CREAT ) &&
     485                                 bee_user_by_handle( ic->bee, ic, jid_ ) ) ?
    486486                                   jabber_buddy_add( ic, jid_ ) : NULL;
    487487                else if( bud->resource && ( flags & GET_BUDDY_EXACT ) )
  • protocols/jabber/s5bytestream.c

    r3ab1d31 ra87e6ba  
    567567        xt_free_node( reply );
    568568
    569         imcb_file_canceled( tf->ft, "couldn't connect to any streamhosts" );
     569        imcb_file_canceled( tf->ic, tf->ft, "couldn't connect to any streamhosts" );
    570570
    571571        bt->tf->watch_in = 0;
     
    604604               
    605605        if( !jabber_write_packet( tf->ic, reply ) )
    606                 imcb_file_canceled( tf->ft, "Error transmitting bytestream response" );
     606                imcb_file_canceled( tf->ic, tf->ft, "Error transmitting bytestream response" );
    607607        xt_free_node( reply );
    608608}
     
    644644
    645645        if( tf->bytesread >= tf->ft->file_size )
    646                 imcb_file_finished( tf->ft );
     646                imcb_file_finished( tf->ic, tf->ft );
    647647
    648648        tf->ft->write( tf->ft, tf->ft->buffer, ret );   
     
    660660        if( tf->watch_in )
    661661        {
    662                 imcb_file_canceled( ft, "BUG in jabber file transfer: write_request called when already watching for input" );
     662                imcb_file_canceled( tf->ic, ft, "BUG in jabber file transfer: write_request called when already watching for input" );
    663663                return FALSE;
    664664        }
     
    706706
    707707        if( tf->byteswritten >= ft->file_size )
    708                 imcb_file_finished( ft );
     708                imcb_file_finished( tf->ic, ft );
    709709        else
    710710                bt->tf->watch_out = b_input_add( tf->fd, GAIM_INPUT_WRITE, jabber_bs_send_can_write, bt );
     
    10061006
    10071007        if( !jabber_write_packet( tf->ic, iq ) )
    1008                 imcb_file_canceled( tf->ft, "Error transmitting bytestream request" );
     1008                imcb_file_canceled( tf->ic, tf->ft, "Error transmitting bytestream request" );
    10091009        return TRUE;
    10101010}
     
    10211021
    10221022        if( jd->streamhosts==NULL ) /* we're done here unless we have a proxy to try */
    1023                 imcb_file_canceled( tf->ft, error );
     1023                imcb_file_canceled( tf->ic, tf->ft, error );
    10241024
    10251025        /* MUST always return FALSE! */
  • protocols/jabber/si.c

    r3ab1d31 ra87e6ba  
    9191
    9292        if( !foundft )
    93                 imcb_file_canceled( tf->ft, "Buddy's client doesn't feature file transfers" );
     93                imcb_file_canceled( tf->ic, tf->ft, "Buddy's client doesn't feature file transfers" );
    9494        else if( !foundbt )
    95                 imcb_file_canceled( tf->ft, "Buddy's client doesn't feature byte streams (required)" );
     95                imcb_file_canceled( tf->ic, tf->ft, "Buddy's client doesn't feature byte streams (required)" );
    9696        else if( !foundsi )
    97                 imcb_file_canceled( tf->ft, "Buddy's client doesn't feature stream initiation (required)" );
     97                imcb_file_canceled( tf->ic, tf->ft, "Buddy's client doesn't feature stream initiation (required)" );
    9898               
    9999        return foundft && foundbt && foundsi;
     
    109109
    110110        /* and start the receive logic */
    111         imcb_file_recv_start( tf->ft );
     111        imcb_file_recv_start( tf->ic, tf->ft );
    112112
    113113}
     
    156156        if( bud == NULL )
    157157        {
    158                 imcb_file_canceled( ft, "Couldn't find buddy (BUG?)" );
     158                imcb_file_canceled( ic, ft, "Couldn't find buddy (BUG?)" );
    159159                return;
    160160        }
  • protocols/msn/Makefile

    r3ab1d31 ra87e6ba  
    1010
    1111# [SH] Program variables
    12 objects = invitation.o msn.o msn_util.o ns.o passport.o sb.o tables.o
     12objects = msn.o msn_util.o ns.o passport.o sb.o tables.o
    1313
    1414CFLAGS += -Wall
  • protocols/msn/msn.c

    r3ab1d31 ra87e6ba  
    8181        if( md )
    8282        {
     83                /** Disabling MSN ft support for now.
    8384                while( md->filetransfers ) {
    8485                        imcb_file_canceled( md->filetransfers->data, "Closing connection" );
    8586                }
     87                */
    8688               
    8789                if( md->fd >= 0 )
     
    344346        ret->send_typing = msn_send_typing;
    345347        ret->handle_cmp = g_strcasecmp;
    346         ret->transfer_request = msn_ftp_transfer_request;
     348        //ret->transfer_request = msn_ftp_transfer_request;
    347349
    348350        register_protocol(ret);
  • protocols/msn/msn_util.c

    r3ab1d31 ra87e6ba  
    9696        msn_buddy_list_add( bla->ic, "AL", bla->handle, bla->realname );
    9797       
    98         if( imcb_find_buddy( bla->ic, bla->handle ) == NULL )
    99                 imcb_ask_add( bla->ic, bla->handle, NULL );
     98        imcb_ask_add( bla->ic, bla->handle, NULL );
    10099       
    101100        g_free( bla->handle );
  • protocols/msn/sb.c

    r3ab1d31 ra87e6ba  
    691691                        }
    692692                }
     693#if 0
     694                // Disable MSN ft support for now.
    693695                else if( g_strncasecmp( ct, "text/x-msmsgsinvite", 19 ) == 0 )
    694696                {
     
    723725                        g_free( command );
    724726                }
     727#endif
    725728                else if( g_strncasecmp( ct, "application/x-msnmsgrp2p", 24 ) == 0 )
    726729                {
  • protocols/nogaim.c

    r3ab1d31 ra87e6ba  
    3838#include "chat.h"
    3939
    40 static int remove_chat_buddy_silent( struct groupchat *b, const char *handle );
    41 
    4240GSList *connections;
    4341
     
    9189}
    9290#endif
    93 
    94 /* nogaim.c */
    9591
    9692GList *protocols = NULL;
     
    125121}
    126122
    127 /* nogaim.c */
    128123void nogaim_init()
    129124{
     
    156151GSList *get_connections() { return connections; }
    157152
    158 /* multi.c */
    159 
    160153struct im_connection *imcb_new( account_t *acc )
    161154{
     
    164157        ic = g_new0( struct im_connection, 1 );
    165158       
    166         ic->irc = acc->irc;
     159        ic->bee = acc->bee;
    167160        ic->acc = acc;
    168161        acc->ic = ic;
     
    178171       
    179172        /* Destroy the pointer to this connection from the account list */
    180         for( a = ic->irc->accounts; a; a = a->next )
     173        for( a = ic->bee->accounts; a; a = a->next )
    181174                if( a->ic == ic )
    182175                {
     
    199192        va_end( params );
    200193
    201         if( ( g_strcasecmp( set_getstr( &ic->irc->set, "strip_html" ), "always" ) == 0 ) ||
    202             ( ( ic->flags & OPT_DOES_HTML ) && set_getbool( &ic->irc->set, "strip_html" ) ) )
     194        if( ( g_strcasecmp( set_getstr( &ic->bee->set, "strip_html" ), "always" ) == 0 ) ||
     195            ( ( ic->flags & OPT_DOES_HTML ) && set_getbool( &ic->bee->set, "strip_html" ) ) )
    203196                strip_html( text );
    204197       
    205198        /* Try to find a different connection on the same protocol. */
    206         for( a = ic->irc->accounts; a; a = a->next )
     199        for( a = ic->bee->accounts; a; a = a->next )
    207200                if( a->prpl == ic->acc->prpl && a->ic != ic )
    208201                        break;
     
    210203        /* If we found one, include the screenname in the message. */
    211204        if( a )
    212                 irc_usermsg( ic->irc, "%s(%s) - %s", ic->acc->prpl->name, ic->acc->user, text );
     205                /* FIXME(wilmer): ui_log callback or so */
     206                irc_usermsg( ic->bee->ui_data, "%s(%s) - %s", ic->acc->prpl->name, ic->acc->user, text );
    213207        else
    214                 irc_usermsg( ic->irc, "%s - %s", ic->acc->prpl->name, text );
     208                irc_usermsg( ic->bee->ui_data, "%s - %s", ic->acc->prpl->name, text );
    215209       
    216210        g_free( text );
     
    263257void imcb_connected( struct im_connection *ic )
    264258{
    265         irc_t *irc = ic->irc;
    266         struct chat *c;
    267         user_t *u;
    268        
    269259        /* MSN servers sometimes redirect you to a different server and do
    270260           the whole login sequence again, so these "late" calls to this
     
    273263                return;
    274264       
    275         u = user_find( ic->irc, ic->irc->nick );
    276        
    277265        imcb_log( ic, "Logged in" );
    278266       
     
    287275        ic->acc->auto_reconnect_delay = 0;
    288276       
     277        /*
    289278        for( c = irc->chatrooms; c; c = c->next )
    290279        {
     
    295284                        chat_join( irc, c, NULL );
    296285        }
     286        */
    297287}
    298288
     
    302292       
    303293        a->reconnect = 0;
    304         account_on( a->irc, a );
     294        account_on( a->bee, a );
    305295       
    306296        return( FALSE );        /* Only have to run the timeout once */
     
    315305void imc_logout( struct im_connection *ic, int allow_reconnect )
    316306{
    317         irc_t *irc = ic->irc;
    318         user_t *t, *u;
     307        bee_t *bee = ic->bee;
    319308        account_t *a;
     309        GSList *l;
    320310        int delay;
    321311       
     
    337327        ic->away = NULL;
    338328       
    339         u = irc->users;
    340         while( u )
    341         {
    342                 if( u->ic == ic )
    343                 {
    344                         t = u->next;
    345                         user_del( irc, u->nick );
    346                         u = t;
    347                 }
    348                 else
    349                         u = u->next;
    350         }
    351        
    352         query_del_by_conn( ic->irc, ic );
    353        
    354         for( a = irc->accounts; a; a = a->next )
     329        for( l = bee->users; l; l = l->next )
     330        {
     331                bee_user_t *bu = l->data;
     332               
     333                if( bu->ic == ic )
     334                        bee_user_free( bee, ic, bu->handle );
     335        }
     336       
     337        //query_del_by_conn( ic->irc, ic );
     338       
     339        for( a = bee->accounts; a; a = a->next )
    355340                if( a->ic == ic )
    356341                        break;
     
    360345                /* Uhm... This is very sick. */
    361346        }
    362         else if( allow_reconnect && set_getbool( &irc->set, "auto_reconnect" ) &&
     347        else if( allow_reconnect && set_getbool( &bee->set, "auto_reconnect" ) &&
    363348                 set_getbool( &a->set, "auto_reconnect" ) &&
    364349                 ( delay = account_reconnect_delay( a ) ) > 0 )
     
    371356}
    372357
    373 
    374 /* dialogs.c */
    375 
    376358void imcb_ask( struct im_connection *ic, char *msg, void *data,
    377359               query_callback doit, query_callback dont )
    378360{
    379         query_add( ic->irc, ic, msg, doit, dont, data );
    380 }
    381 
    382 
    383 /* list.c */
     361        //query_add( ic->irc, ic, msg, doit, dont, data );
     362}
    384363
    385364void imcb_add_buddy( struct im_connection *ic, const char *handle, const char *group )
    386365{
    387         user_t *u;
    388         char nick[MAX_NICK_LENGTH+1], *s;
    389         irc_t *irc = ic->irc;
    390        
    391         if( user_findhandle( ic, handle ) )
    392         {
    393                 if( set_getbool( &irc->set, "debug" ) )
     366        bee_user_t *bu;
     367        bee_t *bee = ic->bee;
     368       
     369        if( bee_user_by_handle( bee, ic, handle ) )
     370        {
     371                if( set_getbool( &bee->set, "debug" ) )
    394372                        imcb_log( ic, "User already exists, ignoring add request: %s", handle );
    395373               
     
    402380        }
    403381       
    404         memset( nick, 0, MAX_NICK_LENGTH + 1 );
    405         strcpy( nick, nick_get( ic->acc, handle ) );
    406        
    407         u = user_add( ic->irc, nick );
    408        
    409 //      if( !realname || !*realname ) realname = nick;
    410 //      u->realname = g_strdup( realname );
    411        
    412         if( ( s = strchr( handle, '@' ) ) )
    413         {
    414                 u->host = g_strdup( s + 1 );
    415                 u->user = g_strndup( handle, s - handle );
    416         }
    417         else if( ic->acc->server )
    418         {
    419                 u->host = g_strdup( ic->acc->server );
    420                 u->user = g_strdup( handle );
    421                
    422                 /* s/ /_/ ... important for AOL screennames */
    423                 for( s = u->user; *s; s ++ )
    424                         if( *s == ' ' )
    425                                 *s = '_';
    426         }
    427         else
    428         {
    429                 u->host = g_strdup( ic->acc->prpl->name );
    430                 u->user = g_strdup( handle );
    431         }
    432        
    433         u->ic = ic;
    434         u->handle = g_strdup( handle );
    435         if( group ) u->group = g_strdup( group );
    436         u->send_handler = buddy_send_handler;
    437         u->last_typing_notice = 0;
    438 }
    439 
    440 struct buddy *imcb_find_buddy( struct im_connection *ic, char *handle )
    441 {
    442         static struct buddy b[1];
    443         user_t *u;
    444        
    445         u = user_findhandle( ic, handle );
    446        
    447         if( !u )
    448                 return( NULL );
    449        
    450         memset( b, 0, sizeof( b ) );
    451         strncpy( b->name, handle, 80 );
    452         strncpy( b->show, u->realname, BUDDY_ALIAS_MAXLEN );
    453         b->present = u->online;
    454         b->ic = u->ic;
    455        
    456         return( b );
    457 }
    458 
    459 void imcb_rename_buddy( struct im_connection *ic, const char *handle, const char *realname )
    460 {
    461         user_t *u = user_findhandle( ic, handle );
    462         char *set;
    463        
    464         if( !u || !realname ) return;
    465        
    466         if( g_strcasecmp( u->realname, realname ) != 0 )
    467         {
    468                 if( u->realname != u->nick ) g_free( u->realname );
    469                
    470                 u->realname = g_strdup( realname );
    471                
    472                 if( ( ic->flags & OPT_LOGGED_IN ) && set_getbool( &ic->irc->set, "display_namechanges" ) )
    473                         imcb_log( ic, "User `%s' changed name to `%s'", u->nick, u->realname );
    474         }
    475        
    476         set = set_getstr( &ic->acc->set, "nick_source" );
    477         if( strcmp( set, "handle" ) != 0 )
    478         {
    479                 char *name = g_strdup( realname );
    480                
    481                 if( strcmp( set, "first_name" ) == 0 )
    482                 {
    483                         int i;
    484                         for( i = 0; name[i] && !isspace( name[i] ); i ++ ) {}
    485                         name[i] = '\0';
    486                 }
    487                
    488                 imcb_buddy_nick_hint( ic, handle, name );
    489                
    490                 g_free( name );
     382        bu = bee_user_new( bee, ic, handle );
     383        bu->group = g_strdup( group );
     384}
     385
     386void 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 );
    491400        }
    492401}
     
    494403void imcb_remove_buddy( struct im_connection *ic, const char *handle, char *group )
    495404{
    496         user_t *u;
    497        
    498         if( ( u = user_findhandle( ic, handle ) ) )
    499                 user_del( ic->irc, u->nick );
     405        bee_user_free( ic->bee, ic, handle );
    500406}
    501407
     
    504410void imcb_buddy_nick_hint( struct im_connection *ic, const char *handle, const char *nick )
    505411{
     412#if 0
    506413        user_t *u = user_findhandle( ic, handle );
    507414        char newnick[MAX_NICK_LENGTH+1], *orig_nick;
     
    518425                /* Some processing to make sure this string is a valid IRC nickname. */
    519426                nick_strip( newnick );
    520                 if( set_getbool( &ic->irc->set, "lcnicks" ) )
     427                if( set_getbool( &ic->bee->set, "lcnicks" ) )
    521428                        nick_lc( newnick );
    522429               
     
    535442                }
    536443        }
     444#endif
    537445}
    538446
     
    544452};
    545453
     454#if 0
    546455static void imcb_ask_auth_cb_no( void *data )
    547456{
     
    563472        g_free( cbd );
    564473}
     474#endif
    565475
    566476void imcb_ask_auth( struct im_connection *ic, const char *handle, const char *realname )
    567477{
     478#if 0
    568479        struct imcb_ask_cb_data *data = g_new0( struct imcb_ask_cb_data, 1 );
    569480        char *s, *realname_ = NULL;
     
    580491        data->handle = g_strdup( handle );
    581492        query_add( ic->irc, ic, s, imcb_ask_auth_cb_yes, imcb_ask_auth_cb_no, data );
    582 }
    583 
    584 
     493#endif
     494}
     495
     496
     497#if 0
    585498static void imcb_ask_add_cb_no( void *data )
    586499{
     
    597510        return imcb_ask_add_cb_no( data );
    598511}
     512#endif
    599513
    600514void imcb_ask_add( struct im_connection *ic, const char *handle, const char *realname )
    601515{
     516#if 0
    602517        struct imcb_ask_cb_data *data = g_new0( struct imcb_ask_cb_data, 1 );
    603518        char *s;
     
    612527        data->handle = g_strdup( handle );
    613528        query_add( ic->irc, ic, s, imcb_ask_add_cb_yes, imcb_ask_add_cb_no, data );
    614 }
    615 
    616 
    617 /* server.c */                   
    618 
    619 void imcb_buddy_status( struct im_connection *ic, const char *handle, int flags, const char *state, const char *message )
    620 {
     529#endif
     530}
     531
     532void imcb_buddy_typing( struct im_connection *ic, char *handle, uint32_t flags )
     533{
     534#if 0
    621535        user_t *u;
    622         int oa, oo;
    623        
    624         u = user_findhandle( ic, (char*) handle );
    625        
    626         if( !u )
    627         {
    628                 if( g_strcasecmp( set_getstr( &ic->irc->set, "handle_unknown" ), "add" ) == 0 )
    629                 {
    630                         imcb_add_buddy( ic, (char*) handle, NULL );
    631                         u = user_findhandle( ic, (char*) handle );
    632                 }
    633                 else
    634                 {
    635                         if( set_getbool( &ic->irc->set, "debug" ) || g_strcasecmp( set_getstr( &ic->irc->set, "handle_unknown" ), "ignore" ) != 0 )
    636                         {
    637                                 imcb_log( ic, "imcb_buddy_status() for unknown handle %s:", handle );
    638                                 imcb_log( ic, "flags = %d, state = %s, message = %s", flags,
    639                                           state ? state : "NULL", message ? message : "NULL" );
    640                         }
    641                        
    642                         return;
    643                 }
    644         }
    645        
    646         oa = u->away != NULL;
    647         oo = u->online;
    648        
    649         g_free( u->away );
    650         g_free( u->status_msg );
    651         u->away = u->status_msg = NULL;
    652        
    653         if( ( flags & OPT_LOGGED_IN ) && !u->online )
    654         {
    655                 irc_spawn( ic->irc, u );
    656                 u->online = 1;
    657         }
    658         else if( !( flags & OPT_LOGGED_IN ) && u->online )
    659         {
    660                 struct groupchat *c;
    661                
    662                 irc_kill( ic->irc, u );
    663                 u->online = 0;
    664                
    665                 /* Remove him/her from the groupchats to prevent PART messages after he/she QUIT already */
    666                 for( c = ic->groupchats; c; c = c->next )
    667                         remove_chat_buddy_silent( c, handle );
    668         }
    669        
    670         if( flags & OPT_AWAY )
    671         {
    672                 if( state && message )
    673                 {
    674                         u->away = g_strdup_printf( "%s (%s)", state, message );
    675                 }
    676                 else if( state )
    677                 {
    678                         u->away = g_strdup( state );
    679                 }
    680                 else if( message )
    681                 {
    682                         u->away = g_strdup( message );
    683                 }
    684                 else
    685                 {
    686                         u->away = g_strdup( "Away" );
    687                 }
    688         }
    689         else
    690         {
    691                 u->status_msg = g_strdup( message );
    692         }
    693        
    694         /* LISPy... */
    695         if( ( set_getbool( &ic->irc->set, "away_devoice" ) ) &&         /* Don't do a thing when user doesn't want it */
    696             ( u->online ) &&                                            /* Don't touch offline people */
    697             ( ( ( u->online != oo ) && !u->away ) ||                    /* Voice joining people */
    698               ( ( u->online == oo ) && ( oa == !u->away ) ) ) )         /* (De)voice people changing state */
    699         {
    700                 char *from;
    701                
    702                 if( set_getbool( &ic->irc->set, "simulate_netsplit" ) )
    703                 {
    704                         from = g_strdup( ic->irc->myhost );
    705                 }
    706                 else
    707                 {
    708                         from = g_strdup_printf( "%s!%s@%s", ic->irc->mynick, ic->irc->mynick,
    709                                                             ic->irc->myhost );
    710                 }
    711                 irc_write( ic->irc, ":%s MODE %s %cv %s", from, ic->irc->channel,
    712                                                           u->away?'-':'+', u->nick );
    713                 g_free( from );
    714         }
    715 }
    716 
    717 void imcb_buddy_msg( struct im_connection *ic, const char *handle, char *msg, uint32_t flags, time_t sent_at )
    718 {
    719         irc_t *irc = ic->irc;
    720         char *wrapped;
    721         user_t *u;
    722        
    723         u = user_findhandle( ic, handle );
    724        
    725         if( !u )
    726         {
    727                 char *h = set_getstr( &irc->set, "handle_unknown" );
    728                
    729                 if( g_strcasecmp( h, "ignore" ) == 0 )
    730                 {
    731                         if( set_getbool( &irc->set, "debug" ) )
    732                                 imcb_log( ic, "Ignoring message from unknown handle %s", handle );
    733                        
    734                         return;
    735                 }
    736                 else if( g_strncasecmp( h, "add", 3 ) == 0 )
    737                 {
    738                         int private = set_getbool( &irc->set, "private" );
    739                        
    740                         if( h[3] )
    741                         {
    742                                 if( g_strcasecmp( h + 3, "_private" ) == 0 )
    743                                         private = 1;
    744                                 else if( g_strcasecmp( h + 3, "_channel" ) == 0 )
    745                                         private = 0;
    746                         }
    747                        
    748                         imcb_add_buddy( ic, handle, NULL );
    749                         u = user_findhandle( ic, handle );
    750                         u->is_private = private;
    751                 }
    752                 else
    753                 {
    754                         imcb_log( ic, "Message from unknown handle %s:", handle );
    755                         u = user_find( irc, irc->mynick );
    756                 }
    757         }
    758        
    759         if( ( g_strcasecmp( set_getstr( &ic->irc->set, "strip_html" ), "always" ) == 0 ) ||
    760             ( ( ic->flags & OPT_DOES_HTML ) && set_getbool( &ic->irc->set, "strip_html" ) ) )
    761                 strip_html( msg );
    762 
    763         wrapped = word_wrap( msg, 425 );
    764         irc_msgfrom( irc, u->nick, wrapped );
    765         g_free( wrapped );
    766 }
    767 
    768 void imcb_buddy_typing( struct im_connection *ic, char *handle, uint32_t flags )
    769 {
    770         user_t *u;
    771        
    772         if( !set_getbool( &ic->irc->set, "typing_notice" ) )
     536       
     537        if( !set_getbool( &ic->bee->set, "typing_notice" ) )
    773538                return;
    774539       
     
    780545                irc_privmsg( ic->irc, u, "PRIVMSG", ic->irc->nick, NULL, buf );
    781546        }
     547#endif
     548}
     549
     550struct bee_user *imcb_buddy_by_handle( struct im_connection *ic, const char *handle )
     551{
     552        return bee_user_by_handle( ic->bee, ic, handle );
    782553}
    783554
    784555struct groupchat *imcb_chat_new( struct im_connection *ic, const char *handle )
    785556{
     557#if 0
    786558        struct groupchat *c;
    787559       
     
    801573        c->topic = g_strdup_printf( "BitlBee groupchat: \"%s\". Please keep in mind that root-commands won't work here. Have fun!", c->title );
    802574       
    803         if( set_getbool( &ic->irc->set, "debug" ) )
     575        if( set_getbool( &ic->bee->set, "debug" ) )
    804576                imcb_log( ic, "Creating new conversation: (id=%p,handle=%s)", c, handle );
    805577       
    806578        return c;
     579#endif
     580        return NULL;
    807581}
    808582
    809583void imcb_chat_free( struct groupchat *c )
    810584{
     585#if 0
    811586        struct im_connection *ic = c->ic;
    812587        struct groupchat *l;
    813588        GList *ir;
    814589       
    815         if( set_getbool( &ic->irc->set, "debug" ) )
     590        if( set_getbool( &ic->bee->set, "debug" ) )
    816591                imcb_log( ic, "You were removed from conversation %p", c );
    817592       
     
    846621                g_free( c );
    847622        }
     623#endif
    848624}
    849625
    850626void imcb_chat_msg( struct groupchat *c, const char *who, char *msg, uint32_t flags, time_t sent_at )
    851627{
     628#if 0
    852629        struct im_connection *ic = c->ic;
    853630        char *wrapped;
     
    860637        u = user_findhandle( ic, who );
    861638       
    862         if( ( g_strcasecmp( set_getstr( &ic->irc->set, "strip_html" ), "always" ) == 0 ) ||
    863             ( ( ic->flags & OPT_DOES_HTML ) && set_getbool( &ic->irc->set, "strip_html" ) ) )
     639        if( ( g_strcasecmp( set_getstr( &ic->bee->set, "strip_html" ), "always" ) == 0 ) ||
     640            ( ( ic->flags & OPT_DOES_HTML ) && set_getbool( &ic->bee->set, "strip_html" ) ) )
    864641                strip_html( msg );
    865642       
     
    874651        }
    875652        g_free( wrapped );
     653#endif
    876654}
    877655
    878656void imcb_chat_log( struct groupchat *c, char *format, ... )
    879657{
     658#if 0
    880659        irc_t *irc = c->ic->irc;
    881660        va_list params;
     
    892671       
    893672        g_free( text );
     673#endif
    894674}
    895675
    896676void imcb_chat_topic( struct groupchat *c, char *who, char *topic, time_t set_at )
    897677{
     678#if 0
    898679        struct im_connection *ic = c->ic;
    899680        user_t *u = NULL;
     
    906687                u = user_findhandle( ic, who );
    907688       
    908         if( ( g_strcasecmp( set_getstr( &ic->irc->set, "strip_html" ), "always" ) == 0 ) ||
    909             ( ( ic->flags & OPT_DOES_HTML ) && set_getbool( &ic->irc->set, "strip_html" ) ) )
     689        if( ( g_strcasecmp( set_getstr( &ic->bee->set, "strip_html" ), "always" ) == 0 ) ||
     690            ( ( ic->flags & OPT_DOES_HTML ) && set_getbool( &ic->bee->set, "strip_html" ) ) )
    910691                strip_html( topic );
    911692       
     
    915696        if( c->joined && u )
    916697                irc_write( ic->irc, ":%s!%s@%s TOPIC %s :%s", u->nick, u->user, u->host, c->channel, topic );
    917 }
    918 
    919 
    920 /* buddy_chat.c */
     698#endif
     699}
    921700
    922701void imcb_chat_add_buddy( struct groupchat *b, const char *handle )
    923702{
     703#if 0
    924704        user_t *u = user_findhandle( b->ic, handle );
    925705        int me = 0;
    926706       
    927         if( set_getbool( &b->ic->irc->set, "debug" ) )
     707        if( set_getbool( &b->ic->bee->set, "debug" ) )
    928708                imcb_log( b->ic, "User %s added to conversation %p", handle, b );
    929709       
     
    952732                b->in_room = g_list_append( b->in_room, g_strdup( handle ) );
    953733        }
     734#endif
    954735}
    955736
     
    957738void imcb_chat_remove_buddy( struct groupchat *b, const char *handle, const char *reason )
    958739{
     740#if 0
    959741        user_t *u;
    960742        int me = 0;
    961743       
    962         if( set_getbool( &b->ic->irc->set, "debug" ) )
     744        if( set_getbool( &b->ic->bee->set, "debug" ) )
    963745                imcb_log( b->ic, "User %s removed from conversation %p (%s)", handle, b, reason ? reason : "" );
    964746       
     
    980762        if( me || ( remove_chat_buddy_silent( b, handle ) && b->joined && u ) )
    981763                irc_part( b->ic->irc, u, b->channel );
    982 }
    983 
     764#endif
     765}
     766
     767#if 0
    984768static int remove_chat_buddy_silent( struct groupchat *b, const char *handle )
    985769{
     
    1000784        }
    1001785       
    1002         return( 0 );
    1003 }
     786        return 0;
     787}
     788#endif
    1004789
    1005790
    1006791/* Misc. BitlBee stuff which shouldn't really be here */
    1007 
     792#if 0
    1008793char *set_eval_away_devoice( set_t *set, char *value )
    1009794{
     
    1018803        /* Horror.... */
    1019804       
    1020         if( st != set_getbool( &irc->set, "away_devoice" ) )
     805        if( st != set_getbool( &irc->b->set, "away_devoice" ) )
    1021806        {
    1022807                char list[80] = "";
     
    1060845        return value;
    1061846}
    1062 
     847#endif
    1063848
    1064849
     
    1067852   them all from some wrappers. We'll start to define some down here: */
    1068853
    1069 int imc_buddy_msg( struct im_connection *ic, char *handle, char *msg, int flags )
     854int imc_chat_msg( struct groupchat *c, char *msg, int flags )
    1070855{
    1071856        char *buf = NULL;
    1072         int st;
    1073        
    1074         if( ( ic->flags & OPT_DOES_HTML ) && ( g_strncasecmp( msg, "<html>", 6 ) != 0 ) )
     857       
     858        if( ( c->ic->flags & OPT_DOES_HTML ) && ( g_strncasecmp( msg, "<html>", 6 ) != 0 ) )
    1075859        {
    1076860                buf = escape_html( msg );
     
    1078862        }
    1079863       
    1080         st = ic->acc->prpl->buddy_msg( ic, handle, msg, flags );
    1081         g_free( buf );
    1082        
    1083         return st;
    1084 }
    1085 
    1086 int imc_chat_msg( struct groupchat *c, char *msg, int flags )
    1087 {
    1088         char *buf = NULL;
    1089        
    1090         if( ( c->ic->flags & OPT_DOES_HTML ) && ( g_strncasecmp( msg, "<html>", 6 ) != 0 ) )
    1091         {
    1092                 buf = escape_html( msg );
    1093                 msg = buf;
    1094         }
    1095        
    1096864        c->ic->acc->prpl->chat_msg( c, msg, flags );
    1097865        g_free( buf );
     
    1107875       
    1108876        away = set_getstr( &ic->acc->set, "away" ) ?
    1109              : set_getstr( &ic->irc->set, "away" );
     877             : set_getstr( &ic->bee->set, "away" );
    1110878        if( away && *away )
    1111879        {
     
    1118886                away = NULL;
    1119887                msg = set_getstr( &ic->acc->set, "status" ) ?
    1120                     : set_getstr( &ic->irc->set, "status" );
     888                    : set_getstr( &ic->bee->set, "status" );
    1121889        }
    1122890       
  • protocols/nogaim.h

    r3ab1d31 ra87e6ba  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2004 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2010 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    8787       
    8888        /* BitlBee */
    89         irc_t *irc;
     89        bee_t *bee;
    9090       
    9191        struct groupchat *groupchats;
     
    286286G_MODULE_EXPORT void imcb_buddy_nick_hint( struct im_connection *ic, const char *handle, const char *nick );
    287287
    288 /* Buddy activity */
    289 /* To manipulate the status of a handle.
    290  * - flags can be |='d with OPT_* constants. You will need at least:
    291  *   OPT_LOGGED_IN and OPT_AWAY.
    292  * - 'state' and 'message' can be NULL */
    293 G_MODULE_EXPORT void imcb_buddy_status( struct im_connection *ic, const char *handle, int flags, const char *state, const char *message );
    294 /* Not implemented yet! */ G_MODULE_EXPORT void imcb_buddy_times( struct im_connection *ic, const char *handle, time_t login, time_t idle );
    295 /* Call when a handle says something. 'flags' and 'sent_at may be just 0. */
    296 G_MODULE_EXPORT void imcb_buddy_msg( struct im_connection *ic, const char *handle, char *msg, uint32_t flags, time_t sent_at );
    297288G_MODULE_EXPORT void imcb_buddy_typing( struct im_connection *ic, char *handle, uint32_t flags );
     289G_MODULE_EXPORT struct bee_user *imcb_buddy_by_handle( struct im_connection *ic, const char *handle );
    298290G_MODULE_EXPORT void imcb_clean_handle( struct im_connection *ic, char *handle );
    299291
     
    320312/* Actions, or whatever. */
    321313int imc_away_send_update( struct im_connection *ic );
    322 int imc_buddy_msg( struct im_connection *ic, char *handle, char *msg, int flags );
    323314int imc_chat_msg( struct groupchat *c, char *msg, int flags );
    324315
  • protocols/oscar/oscar.c

    r3ab1d31 ra87e6ba  
    11901190        aim_ssi_auth_reply(od->sess, od->conn, uin, 1, "");
    11911191        // aim_send_im_ch4(od->sess, uin, AIM_ICQMSG_AUTHGRANTED, &message);
    1192         if(imcb_find_buddy(data->ic, uin) == NULL)
    1193                 imcb_ask_add(data->ic, uin, NULL);
     1192        imcb_ask_add(data->ic, uin, NULL);
    11941193       
    11951194        g_free(uin);
     
    19521951        struct oscar_data *odata = (struct oscar_data *)g->proto_data;
    19531952        if (odata->icq) {
     1953                /** FIXME(wilmer): Hmm, lost the ability to get away msgs here, do we care to get that back?
    19541954                struct buddy *budlight = imcb_find_buddy(g, who);
    19551955                if (budlight)
     
    19571957                                if (budlight->caps & AIM_CAPS_ICQSERVERRELAY)
    19581958                                        aim_send_im_ch2_geticqmessage(odata->sess, who, (budlight->uc & 0xff80) >> 7);
     1959                */
    19591960        } else
    19601961                aim_getinfo(odata->sess, odata->conn, who, AIM_GETINFO_AWAYMESSAGE);
     
    20942095                switch (curitem->type) {
    20952096                        case 0x0000: /* Buddy */
    2096                                 if ((curitem->name) && (!imcb_find_buddy(ic, nrm))) {
     2097                                if ((curitem->name) && (!imcb_buddy_by_handle(ic, nrm))) {
    20972098                                        char *realname = NULL;
    20982099
  • root_commands.c

    r3ab1d31 ra87e6ba  
    3232#include <string.h>
    3333
    34 void root_command_string( irc_t *irc, user_t *u, char *command, int flags )
     34void root_command_string( irc_t *irc, char *command )
    3535{
    3636        char *cmd[IRC_MAX_ARGS];
     
    161161                irc->status |= USTATUS_IDENTIFIED;
    162162                irc_umode_set( irc, "+R", 1 );
    163                 if( set_getbool( &irc->set, "auto_connect" ) )
     163                if( set_getbool( &irc->b->set, "auto_connect" ) )
    164164                        cmd_account( irc, account_on );
    165165                break;
     
    201201        storage_status_t status;
    202202       
    203         status = storage_remove (irc->nick, cmd[1]);
     203        status = storage_remove (irc->user->nick, cmd[1]);
    204204        switch (status) {
    205205        case STORAGE_NO_SUCH_USER:
     
    213213                irc->status &= ~USTATUS_IDENTIFIED;
    214214                irc_umode_set( irc, "-R", 1 );
    215                 irc_usermsg( irc, "Account `%s' removed", irc->nick );
     215                irc_usermsg( irc, "Account `%s' removed", irc->user->nick );
    216216                break;
    217217        default:
     
    221221}
    222222
     223static void cmd_save( irc_t *irc, char **cmd )
     224{
     225        if( ( irc->status & USTATUS_IDENTIFIED ) == 0 )
     226                irc_usermsg( irc, "Please create an account first" );
     227        else if( storage_save( irc, NULL, TRUE ) == STORAGE_OK )
     228                irc_usermsg( irc, "Configuration saved" );
     229        else
     230                irc_usermsg( irc, "Configuration could not be saved!" );
     231}
     232
    223233struct cmd_account_del_data
    224234{
     
    232242        account_t *a;
    233243       
    234         for( a = cad->irc->accounts; a && a != cad->a; a = a->next );
     244        for( a = cad->irc->b->accounts; a && a != cad->a; a = a->next );
    235245       
    236246        if( a == NULL )
     
    244254        else
    245255        {
    246                 account_del( cad->irc, a );
     256                account_del( cad->irc->b, a );
    247257                irc_usermsg( cad->irc, "Account deleted" );
    248258        }
     
    285295                set_name = set_full;
    286296               
    287                 head = &irc->set;
     297                head = &irc->b->set;
    288298        }
    289299        else
     
    356366        account_t *a;
    357367       
    358         if( ( a = account_get( irc, id ) ) )
     368        if( ( a = account_get( irc->b, id ) ) )
    359369                return &a->set;
    360370        else
     
    404414                }
    405415
    406                 a = account_add( irc, prpl, cmd[3], cmd[4] );
     416                a = account_add( irc->b, prpl, cmd[3], cmd[4] );
    407417                if( cmd[5] )
    408418                {
     
    418428                MIN_ARGS( 2 );
    419429
    420                 if( !( a = account_get( irc, cmd[2] ) ) )
     430                if( !( a = account_get( irc->b, cmd[2] ) ) )
    421431                {
    422432                        irc_usermsg( irc, "Invalid account" );
     
    440450                                               "set' command. Are you sure you want to delete this "
    441451                                               "account?", a->prpl->name, a->user );
    442                         query_add( irc, NULL, msg, cmd_account_del_yes, cmd_account_del_no, cad );
     452                        //query_add( irc, NULL, msg, cmd_account_del_yes, cmd_account_del_no, cad );
    443453                        g_free( msg );
    444454                }
     
    451461                        irc_usermsg( irc, "Account list:" );
    452462               
    453                 for( a = irc->accounts; a; a = a->next )
     463                for( a = irc->b->accounts; a; a = a->next )
    454464                {
    455465                        char *con;
     
    474484                if( cmd[2] )
    475485                {
    476                         if( ( a = account_get( irc, cmd[2] ) ) )
     486                        if( ( a = account_get( irc->b, cmd[2] ) ) )
    477487                        {
    478488                                if( a->ic )
     
    483493                                else
    484494                                {
    485                                         account_on( irc, a );
     495                                        account_on( irc->b, a );
    486496                                }
    487497                        }
     
    494504                else
    495505                {
    496                         if ( irc->accounts ) {
     506                        if ( irc->b->accounts )
     507                        {
    497508                                irc_usermsg( irc, "Trying to get all accounts connected..." );
    498509                       
    499                                 for( a = irc->accounts; a; a = a->next )
     510                                for( a = irc->b->accounts; a; a = a->next )
    500511                                        if( !a->ic && a->auto_connect )
    501                                                 account_on( irc, a );
     512                                                account_on( irc->b, a );
    502513                        }
    503514                        else
     
    513524                        irc_usermsg( irc, "Deactivating all active (re)connections..." );
    514525                       
    515                         for( a = irc->accounts; a; a = a->next )
     526                        for( a = irc->b->accounts; a; a = a->next )
    516527                        {
    517528                                if( a->ic )
    518                                         account_off( irc, a );
     529                                        account_off( irc->b, a );
    519530                                else if( a->reconnect )
    520531                                        cancel_auto_reconnect( a );
    521532                        }
    522533                }
    523                 else if( ( a = account_get( irc, cmd[2] ) ) )
     534                else if( ( a = account_get( irc->b, cmd[2] ) ) )
    524535                {
    525536                        if( a->ic )
    526537                        {
    527                                 account_off( irc, a );
     538                                account_off( irc->b, a );
    528539                        }
    529540                        else if( a->reconnect )
     
    556567}
    557568
     569#if 0
    558570static void cmd_add( irc_t *irc, char **cmd )
    559571{
     
    644656        }
    645657}
     658#endif
    646659
    647660static void cmd_rename( irc_t *irc, char **cmd )
    648661{
    649         user_t *u;
    650        
    651         if( g_strcasecmp( cmd[1], irc->nick ) == 0 )
     662        irc_user_t *iu;
     663       
     664        iu = irc_user_by_name( irc, cmd[1] );
     665       
     666        if( iu == NULL )
     667        {
     668                irc_usermsg( irc, "Nick `%s' does not exist", cmd[1] );
     669        }
     670        else if( iu == irc->user )
    652671        {
    653672                irc_usermsg( irc, "Nick `%s' can't be changed", cmd[1] );
    654673        }
    655         else if( g_strcasecmp( cmd[1], irc->channel ) == 0 )
    656         {
    657                 if( strchr( CTYPES, cmd[2][0] ) && nick_ok( cmd[2] + 1 ) )
    658                 {
    659                         u = user_find( irc, irc->nick );
    660                        
    661                         irc_part( irc, u, irc->channel );
    662                         g_free( irc->channel );
    663                         irc->channel = g_strdup( cmd[2] );
    664                         irc_join( irc, u, irc->channel );
    665                        
    666                         if( strcmp( cmd[0], "set_rename" ) != 0 )
    667                                 set_setstr( &irc->set, "control_channel", cmd[2] );
    668                 }
    669         }
    670         else if( user_find( irc, cmd[2] ) && ( nick_cmp( cmd[1], cmd[2] ) != 0 ) )
     674        else if( !nick_ok( cmd[2] ) )
     675        {
     676                irc_usermsg( irc, "Nick `%s' is invalid", cmd[2] );
     677        }
     678        else if( irc_user_by_name( irc, cmd[2] ) )
    671679        {
    672680                irc_usermsg( irc, "Nick `%s' already exists", cmd[2] );
    673681        }
    674         else if( !nick_ok( cmd[2] ) )
    675         {
    676                 irc_usermsg( irc, "Nick `%s' is invalid", cmd[2] );
    677         }
    678         else if( !( u = user_find( irc, cmd[1] ) ) )
    679         {
    680                 irc_usermsg( irc, "Nick `%s' does not exist", cmd[1] );
    681         }
    682         else
    683         {
    684                 user_rename( irc, cmd[1], cmd[2] );
    685                 irc_write( irc, ":%s!%s@%s NICK %s", cmd[1], u->user, u->host, cmd[2] );
    686                 if( g_strcasecmp( cmd[1], irc->mynick ) == 0 )
    687                 {
    688                         g_free( irc->mynick );
    689                         irc->mynick = g_strdup( cmd[2] );
    690                        
     682        else
     683        {
     684                if( !irc_user_set_nick( iu, cmd[2] ) )
     685                {
     686                        irc_usermsg( irc, "Error while changing nick" );
     687                        return;
     688                }
     689               
     690                if( iu == irc->root )
     691                {
    691692                        /* If we're called internally (user did "set root_nick"),
    692693                           let's not go O(INF). :-) */
    693694                        if( strcmp( cmd[0], "set_rename" ) != 0 )
    694                                 set_setstr( &irc->set, "root_nick", cmd[2] );
    695                 }
    696                 else if( u->send_handler == buddy_send_handler )
    697                 {
    698                         nick_set( u->ic->acc, u->handle, cmd[2] );
     695                                set_setstr( &irc->b->set, "root_nick", cmd[2] );
     696                }
     697                else if( iu->bu )
     698                {
     699                        nick_set( iu->bu->ic->acc, iu->bu->handle, cmd[2] );
    699700                }
    700701               
     
    703704}
    704705
     706#if 0
    705707char *set_eval_root_nick( set_t *set, char *new_nick )
    706708{
     
    913915{
    914916        cmd_set_real( irc, cmd, NULL, NULL );
    915 }
    916 
    917 static void cmd_save( irc_t *irc, char **cmd )
    918 {
    919         if( ( irc->status & USTATUS_IDENTIFIED ) == 0 )
    920                 irc_usermsg( irc, "Please create an account first" );
    921         else if( storage_save( irc, NULL, TRUE ) == STORAGE_OK )
    922                 irc_usermsg( irc, "Configuration saved" );
    923         else
    924                 irc_usermsg( irc, "Configuration could not be saved!" );
    925917}
    926918
     
    990982}
    991983
    992 static void cmd_nick( irc_t *irc, char **cmd )
    993 {
    994         account_t *a;
    995 
    996         if( !cmd[1] || !( a = account_get( irc, cmd[1] ) ) )
    997         {
    998                 irc_usermsg( irc, "Invalid account");
    999         }
    1000         else if( !( a->ic && ( a->ic->flags & OPT_LOGGED_IN ) ) )
    1001         {
    1002                 irc_usermsg( irc, "That account is not on-line" );
    1003         }
    1004         else if ( !cmd[2] )
    1005         {
    1006                 irc_usermsg( irc, "Your name is `%s'" , a->ic->displayname ? a->ic->displayname : "NULL" );
    1007         }
    1008         else if ( !a->prpl->set_my_name )
    1009         {
    1010                 irc_usermsg( irc, "Command `%s' not supported by this protocol", cmd[0] );
    1011         }
    1012         else
    1013         {
    1014                 irc_usermsg( irc, "Setting your name to `%s'", cmd[2] );
    1015                
    1016                 a->prpl->set_my_name( a->ic, cmd[2] );
    1017         }
    1018 }
    1019 
    1020984static void cmd_qlist( irc_t *irc, char **cmd )
    1021985{
     
    10361000                else
    10371001                        irc_usermsg( irc, "%d, BitlBee: %s", num, q->question );
    1038 }
    1039 
    1040 static void cmd_join_chat( irc_t *irc, char **cmd )
    1041 {
    1042         irc_usermsg( irc, "This command is now obsolete. "
    1043                           "Please try the `chat' command instead." );
    10441002}
    10451003
     
    12171175        }
    12181176}
     1177#endif
    12191178
    12201179const command_t commands[] = {
    12211180        { "help",           0, cmd_help,           0 },
     1181        { "account",        1, cmd_account,        0 },
    12221182        { "identify",       1, cmd_identify,       0 },
    12231183        { "register",       1, cmd_register,       0 },
    12241184        { "drop",           1, cmd_drop,           0 },
    1225         { "account",        1, cmd_account,        0 },
     1185        { "save",           0, cmd_save,           0 },
     1186#if 0
    12261187        { "add",            2, cmd_add,            0 },
    12271188        { "info",           1, cmd_info,           0 },
     1189#endif
    12281190        { "rename",         2, cmd_rename,         0 },
     1191#if 0
    12291192        { "remove",         1, cmd_remove,         0 },
    12301193        { "block",          1, cmd_block,          0 },
    12311194        { "allow",          1, cmd_allow,          0 },
    1232         { "save",           0, cmd_save,           0 },
    12331195        { "set",            0, cmd_set,            0 },
    12341196        { "yes",            0, cmd_yesno,          0 },
     
    12401202        { "chat",           1, cmd_chat,           0 },
    12411203        { "transfer",       0, cmd_transfer,       0 },
     1204#endif
    12421205        { NULL }
    12431206};
  • set.c

    r3ab1d31 ra87e6ba  
    225225}
    226226
     227/*
    227228char *set_eval_ops( set_t *set, char *value )
    228229{
     
    246247        return value;
    247248}
     249*/
  • storage_xml.c

    r3ab1d31 ra87e6ba  
    147147                                         arc_decode( pass_cr, pass_len, &password, xd->given_pass ) )
    148148                {
    149                         xd->current_account = account_add( irc, prpl, handle, password );
     149                        xd->current_account = account_add( irc->b, prpl, handle, password );
    150150                        if( server )
    151151                                set_setstr( &xd->current_account->set, "server", server );
     
    181181                                xd->current_set_head = &xd->current_account->set;
    182182                        else
    183                                 xd->current_set_head = &xd->irc->set;
     183                                xd->current_set_head = &xd->irc->b->set;
    184184                       
    185185                        xd->current_setting = g_strdup( setting );
     
    215215                if( xd->current_account && handle && channel )
    216216                {
    217                         xd->current_chat = chat_add( xd->irc, xd->current_account, handle, channel );
     217                        //xd->current_chat = chat_add( xd->irc, xd->current_account, handle, channel );
    218218                }
    219219                else
     
    353353static storage_status_t xml_load( irc_t *irc, const char *password )
    354354{
    355         return xml_load_real( irc, irc->nick, password, XML_PASS_UNKNOWN );
     355        return xml_load_real( irc, irc->user->nick, password, XML_PASS_UNKNOWN );
    356356}
    357357
     
    396396        md5_state_t md5_state;
    397397       
    398         path2 = g_strdup( irc->nick );
     398        path2 = g_strdup( irc->user->nick );
    399399        nick_lc( path2 );
    400400        g_snprintf( path, sizeof( path ) - 2, "%s%s%s", global.conf->configdir, path2, ".xml" );
     
    422422        pass_buf = base64_encode( pass_md5, 21 );
    423423       
    424         if( !xml_printf( fd, 0, "<user nick=\"%s\" password=\"%s\" version=\"%d\">\n", irc->nick, pass_buf, XML_FORMAT_VERSION ) )
     424        if( !xml_printf( fd, 0, "<user nick=\"%s\" password=\"%s\" version=\"%d\">\n", irc->user->nick, pass_buf, XML_FORMAT_VERSION ) )
    425425                goto write_error;
    426426       
    427427        g_free( pass_buf );
    428428       
    429         for( set = irc->set; set; set = set->next )
     429        for( set = irc->b->set; set; set = set->next )
    430430                if( set->value )
    431431                        if( !xml_printf( fd, 1, "<setting name=\"%s\">%s</setting>\n", set->key, set->value ) )
    432432                                goto write_error;
    433433       
    434         for( acc = irc->accounts; acc; acc = acc->next )
     434        for( acc = irc->b->accounts; acc; acc = acc->next )
    435435        {
    436436                unsigned char *pass_cr;
     
    470470                        goto write_error;
    471471               
     472#if 0
    472473                for( c = irc->chatrooms; c; c = c->next )
    473474                {
     
    488489                                goto write_error;
    489490                }
     491#endif
    490492               
    491493                if( !xml_printf( fd, 1, "</account>\n" ) )
Note: See TracChangeset for help on using the changeset viewer.