Changes in / [a87e6ba:3ab1d31]


Ignore:
Files:
6 added
12 deleted
27 edited

Legend:

Unmodified
Added
Removed
  • Makefile

    ra87e6ba r3ab1d31  
    1010
    1111# Program variables
    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)
    13 objects = 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)
     12objects = 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
    1413headers = 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
    1514subdirs = lib protocols
  • bitlbee.h

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

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

    ra87e6ba r3ab1d31  
    6161unsigned int receivedchunks=0, receiveddata=0;
    6262
    63 void dcc_finish( file_transfer_t *file );
    64 void dcc_close( file_transfer_t *file );
     63static void dcc_finish( file_transfer_t *file );
     64static void 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, irc_user_t *iu, struct sockaddr_storage *saddr );
     66int dccs_send_request( struct dcc_file_transfer *df, char *user_nick, struct sockaddr_storage *saddr );
     67gboolean dccs_recv_start( file_transfer_t *ft );
    6768gboolean dccs_recv_proto( gpointer data, gint fd, b_input_condition cond);
    6869gboolean dccs_recv_write_request( file_transfer_t *ft );
     
    7071gboolean dcc_abort( dcc_file_transfer_t *df, char *reason, ... );
    7172
    72 dcc_file_transfer_t *dcc_alloc_transfer( const char *file_name, size_t file_size, struct im_connection *ic )
     73/* As defined in ft.h */
     74file_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 */
     86void 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 */
     95gboolean imcb_file_recv_start( file_transfer_t *ft )
     96{
     97        return dccs_recv_start( ft );
     98}
     99
     100/* As defined in ft.h */
     101void 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
     111dcc_file_transfer_t *dcc_alloc_transfer( char *file_name, size_t file_size, struct im_connection *ic )
    73112{
    74113        file_transfer_t *file = g_new0( file_transfer_t, 1 );
     
    85124
    86125/* This is where the sending magic starts... */
    87 file_transfer_t *dccs_send_start( struct im_connection *ic, irc_user_t *iu, const char *file_name, size_t file_size )
     126file_transfer_t *dccs_send_start( struct im_connection *ic, char *user_nick, char *file_name, size_t file_size )
    88127{
    89128        file_transfer_t *file;
    90129        dcc_file_transfer_t *df;
    91         irc_t *irc = (irc_t *) ic->bee->ui_data;
    92130        struct sockaddr_storage saddr;
    93131        char *errmsg;
     
    112150        file->status = FT_STATUS_LISTENING;
    113151
    114         if( !dccs_send_request( df, iu, &saddr ) )
     152        if( !dccs_send_request( df, user_nick, &saddr ) )
    115153                return NULL;
    116154
     
    118156        df->watch_in = b_input_add( df->fd, GAIM_INPUT_READ, dccs_send_proto, df );
    119157
    120         irc->file_transfers = g_slist_prepend( irc->file_transfers, file );
     158        df->ic->irc->file_transfers = g_slist_prepend( df->ic->irc->file_transfers, file );
    121159
    122160        df->progress_timeout = b_timeout_add( DCC_MAX_STALL * 1000, dcc_progress, df );
     
    125163                      "Accept the file transfer if you'd like the file. If you don't, "
    126164                      "issue the 'transfers reject' command.",
    127                       iu->nick, file_name, file_size / 1024 );
     165                      user_nick, file_name, file_size / 1024 );
    128166
    129167        return file;
     
    178216
    179217/* Creates the "DCC SEND" line and sends it to the server */
    180 int dccs_send_request( struct dcc_file_transfer *df, irc_user_t *iu, struct sockaddr_storage *saddr )
     218int dccs_send_request( struct dcc_file_transfer *df, char *user_nick, struct sockaddr_storage *saddr )
    181219{
    182220        char ipaddr[INET6_ADDRSTRLEN];
     
    212250                                df->ft->file_name, ipaddr, port, df->ft->file_size );
    213251       
    214         irc_send_msg_raw( iu, "PRIVMSG", iu->irc->user->nick, cmd );
     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 );
    215254
    216255        g_free( cmd );
     
    457496 * Cleans up after a transfer.
    458497 */
    459 void dcc_close( file_transfer_t *file )
     498static void dcc_close( file_transfer_t *file )
    460499{
    461500        dcc_file_transfer_t *df = file->priv;
    462         irc_t *irc = (irc_t *) df->ic->bee->ui_data;
    463501
    464502        if( file->free )
     
    476514                b_event_remove( df->progress_timeout );
    477515       
    478         irc->file_transfers = g_slist_remove( irc->file_transfers, file );
     516        df->ic->irc->file_transfers = g_slist_remove( df->ic->irc->file_transfers, file );
    479517       
    480518        g_free( df );
     
    506544file_transfer_t *dcc_request( struct im_connection *ic, char *line )
    507545{
    508         irc_t *irc = (irc_t *) ic->bee->ui_data;
    509546        char *pattern = "SEND"
    510547                " (([^\"][^ ]*)|\"(([^\"]|\\\")*)\")"
     
    590627                g_free( input );
    591628
    592                 irc->file_transfers = g_slist_prepend( irc->file_transfers, ft );
     629                df->ic->irc->file_transfers = g_slist_prepend( df->ic->irc->file_transfers, ft );
    593630
    594631                return ft;
  • dcc.h

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

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

    ra87e6ba r3ab1d31  
    55  \********************************************************************/
    66
    7 /* The IRC-based UI (for now the only one)                              */
     7/* The big hairy IRCd part of the project                               */
    88
    99/*
     
    2424*/
    2525
     26#define BITLBEE_CORE
    2627#include "bitlbee.h"
     28#include "sock.h"
    2729#include "ipc.h"
    28 
    29 GSList *irc_connection_list;
    30 
    31 static gboolean irc_userping( gpointer _irc, gint fd, b_input_condition cond );
    32 static char *set_eval_charset( set_t *set, char *value );
     30#include "dcc.h"
     31
     32static gboolean irc_userping( gpointer _irc, int fd, b_input_condition cond );
     33
     34GSList *irc_connection_list = NULL;
     35
     36static 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
     51static 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
     80static 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}
    3398
    3499irc_t *irc_new( int fd )
     
    37102        struct sockaddr_storage sock;
    38103        socklen_t socklen = sizeof( sock );
    39         char *host = NULL, *myhost = NULL;
    40         irc_user_t *iu;
    41104        set_t *s;
    42         bee_t *b;
    43105       
    44106        irc = g_new0( irc_t, 1 );
     
    52114        irc->last_pong = gettime();
    53115       
    54         irc->nick_user_hash = g_hash_table_new( g_str_hash, g_str_equal );
     116        irc->userhash = g_hash_table_new( g_str_hash, g_str_equal );
    55117        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 );
    56122       
    57123        irc->iconv = (GIConv) -1;
     
    60126        if( global.conf->hostname )
    61127        {
    62                 myhost = g_strdup( global.conf->hostname );
     128                irc->myhost = g_strdup( global.conf->hostname );
    63129        }
    64130        else if( getsockname( irc->fd, (struct sockaddr*) &sock, &socklen ) == 0 )
     
    69135                                 NI_MAXHOST, NULL, 0, 0 ) == 0 )
    70136                {
    71                         myhost = g_strdup( ipv6_unwrap( buf ) );
     137                        irc->myhost = g_strdup( ipv6_unwrap( buf ) );
    72138                }
    73139        }
     
    80146                                 NI_MAXHOST, NULL, 0, 0 ) == 0 )
    81147                {
    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" );
     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" );
    90156       
    91157        if( global.conf->ping_interval > 0 && global.conf->ping_timeout > 0 )
    92158                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" );
    93161
    94162        irc_connection_list = g_slist_append( irc_connection_list, irc );
    95163       
    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 );
     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 );
    129192       
    130193        conf_loaddefaults( irc );
    131194       
    132195        /* Evaluator sets the iconv/oconv structures. */
    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;
     196        set_eval_charset( set_find( &irc->set, "charset" ), set_getstr( &irc->set, "charset" ) );
     197       
     198        return( irc );
    141199}
    142200
     
    159217               
    160218                ipc_to_master_str( "OPERMSG :Client exiting: %s@%s [%s]\r\n",
    161                                    irc->user->nick ? irc->user->nick : "(NONE)", irc->root->host, reason );
     219                                   irc->nick ? irc->nick : "(NONE)", irc->host, reason );
    162220               
    163221                g_free( reason );
     
    169227               
    170228                ipc_to_master_str( "OPERMSG :Client exiting: %s@%s [%s]\r\n",
    171                                    irc->user->nick ? irc->user->nick : "(NONE)", irc->root->host, "No reason given" );
     229                                   irc->nick ? irc->nick : "(NONE)", irc->host, "No reason given" );
    172230        }
    173231       
     
    190248}
    191249
    192 static gboolean irc_free_hashkey( gpointer key, gpointer value, gpointer data );
    193 
     250static 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 */
    194258void irc_free( irc_t * irc )
    195259{
     260        user_t *user, *usertmp;
     261       
    196262        log_message( LOGLVL_INFO, "Destroying connection with fd %d", irc->fd );
    197263       
    198         /*
    199         if( irc->status & USTATUS_IDENTIFIED && set_getbool( &irc->b->set, "save_on_quit" ) )
     264        if( irc->status & USTATUS_IDENTIFIED && set_getbool( &irc->set, "save_on_quit" ) )
    200265                if( storage_save( irc, NULL, TRUE ) != STORAGE_OK )
    201266                        irc_usermsg( irc, "Error while saving settings!" );
    202         */
    203267       
    204268        irc_connection_list = g_slist_remove( irc_connection_list, irc );
    205269       
    206         /*
     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       
    207285        while( irc->queries != NULL )
    208286                query_del( irc, irc->queries );
    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 );
     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        }
    219309       
    220310        if( irc->ping_source_id > 0 )
     
    228318        irc->fd = -1;
    229319       
    230         g_hash_table_foreach_remove( irc->nick_user_hash, irc_free_hashkey, NULL );
    231         g_hash_table_destroy( irc->nick_user_hash );
     320        g_hash_table_foreach_remove( irc->userhash, irc_free_hashkey, NULL );
     321        g_hash_table_destroy( irc->userhash );
    232322       
    233323        g_hash_table_foreach_remove( irc->watches, irc_free_hashkey, NULL );
     
    242332        g_free( irc->readbuffer );
    243333       
     334        g_free( irc->nick );
     335        g_free( irc->user );
     336        g_free( irc->host );
     337        g_free( irc->realname );
    244338        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 );
    245346       
    246347        g_free( irc );
     
    254355}
    255356
    256 static gboolean irc_free_hashkey( gpointer key, gpointer value, gpointer data )
    257 {
    258         g_free( key );
    259        
    260         return( TRUE );
    261 }
    262 
    263357/* USE WITH CAUTION!
    264358   Sets pass without checking */
    265 void irc_setpass (irc_t *irc, const char *pass)
     359void irc_setpass (irc_t *irc, const char *pass) 
    266360{
    267361        g_free (irc->password);
     
    274368}
    275369
    276 static char **irc_splitlines( char *buffer );
    277 
    278370void irc_process( irc_t *irc )
    279371{
     
    283375        if( irc->readbuffer != NULL )
    284376        {
    285                 lines = irc_splitlines( irc->readbuffer );
     377                lines = irc_tokenize( irc->readbuffer );
    286378               
    287379                for( i = 0; *lines[i] != '\0'; i ++ )
     
    320412                                                                  "`help set charset' for more information. Your "
    321413                                                                  "message was ignored.",
    322                                                                   set_getstr( &irc->b->set, "charset" ) );
     414                                                                  set_getstr( &irc->set, "charset" ) );
    323415                                               
    324416                                                g_free( conv );
     
    327419                                        else
    328420                                        {
    329                                                 irc_write( irc, ":%s NOTICE AUTH :%s", irc->root->host,
     421                                                irc_write( irc, ":%s NOTICE AUTH :%s", irc->myhost,
    330422                                                           "Warning: invalid characters received at login time." );
    331423                                               
     
    365457}
    366458
    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.) */
    371 static char **irc_splitlines( char *buffer )
     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. */
     461char **irc_tokenize( char *buffer )
    372462{
    373463        int i, j, n = 3;
     
    500590}
    501591
     592void 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
     605int 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
    502622void irc_write( irc_t *irc, char *format, ... )
    503623{
     
    510630        return;
    511631}
    512 
    513 void 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 }
    541632
    542633void irc_vawrite( irc_t *irc, char *format, va_list params )
     
    595686}
    596687
     688void 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
     717void 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 )
     732                        {
     733                                irc_reply( irc, 353, "= %s :%s", channel, namelist );
     734                                *namelist = 0;
     735                        }
     736                       
     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
    597775int irc_check_login( irc_t *irc )
    598776{
    599         if( irc->user->user && irc->user->nick )
     777        if( irc->user && irc->nick )
    600778        {
    601779                if( global.conf->authmode == AUTHMODE_CLOSED && !( irc->status & USTATUS_AUTHORIZED ) )
    602780                {
    603                         irc_send_num( irc, 464, ":This server is password-protected." );
     781                        irc_reply( irc, 464, ":This server is password-protected." );
    604782                        return 0;
    605783                }
    606784                else
    607785                {
    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 )
    626                         {
    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] );
    632                         }
    633                        
    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                        
     786                        irc_login( irc );
    645787                        return 1;
    646788                }
     
    653795}
    654796
    655 void irc_umode_set( irc_t *irc, const char *s, gboolean allow_priv )
     797void 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
     857void 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
     909void 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
     921void irc_umode_set( irc_t *irc, char *s, int allow_priv )
    656922{
    657923        /* allow_priv: Set to 0 if s contains user input, 1 if you want
    658924           to set a "privileged" mode (+o, +R, etc). */
    659         char m[128], st = 1;
    660         const char *t;
     925        char m[256], st = 1, *t;
    661926        int i;
    662927        char changes[512], *p, st2 = 2;
     
    666931       
    667932        for( t = irc->umode; *t; t ++ )
    668                 if( *t < sizeof( m ) )
    669                         m[(int)*t] = 1;
    670        
     933                m[(int)*t] = 1;
     934
    671935        p = changes;
    672936        for( t = s; *t; t ++ )
     
    674938                if( *t == '+' || *t == '-' )
    675939                        st = *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 ) ) )
     940                else if( st == 0 || ( strchr( UMODES, *t ) || ( allow_priv && strchr( UMODES_PRIV, *t ) ) ) )
    679941                {
    680942                        if( m[(int)*t] != st)
     
    693955        memset( irc->umode, 0, sizeof( irc->umode ) );
    694956       
    695         for( i = 'A'; i <= 'z' && strlen( irc->umode ) < ( sizeof( irc->umode ) - 1 ); i ++ )
     957        for( i = 0; i < 256 && strlen( irc->umode ) < ( sizeof( irc->umode ) - 1 ); i ++ )
    696958                if( m[i] )
    697959                        irc->umode[strlen(irc->umode)] = i;
    698960       
    699961        if( badflag )
    700                 irc_send_num( irc, 501, ":Unknown MODE flag" );
     962                irc_reply( irc, 501, ":Unknown MODE flag" );
     963        /* Deliberately no !user@host on the prefix here */
    701964        if( *changes )
    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 
     965                irc_write( irc, ":%s MODE %s %s", irc->nick, irc->nick, changes );
     966}
     967
     968void irc_spawn( irc_t *irc, user_t *u )
     969{
     970        irc_join( irc, u, irc->channel );
     971}
     972
     973void 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
     996void 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
     1001void 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
     1006void 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
     1043int 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
     1154static 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
     1174void 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
     1219int 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
     1258int 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
     1281int 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}
    7071290
    7081291/* Returns 0 if everything seems to be okay, a number >0 when there was a
     
    7421325}
    7431326
    744 
    745 static 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 }
     1327struct 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}
  • irc.h

    ra87e6ba r3ab1d31  
    55  \********************************************************************/
    66
    7 /* The IRC-based UI (for now the only one)                              */
     7/* The big hairy IRCd part of the project                               */
    88
    99/*
     
    3333#define IRC_PING_STRING "PinglBee"
    3434
    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 */
     35#define UMODES "abisw"
     36#define UMODES_PRIV "Ro"
     37#define CMODES "nt"
     38#define CMODE "t"
     39#define UMODE "s"
     40#define CTYPES "&#"
    4341
    4442typedef enum
     
    5048        USTATUS_SHUTDOWN = 8
    5149} irc_status_t;
    52 
    53 struct irc_user;
    5450
    5551typedef struct irc
     
    6359        GIConv iconv, oconv;
    6460
    65         struct irc_user *root;
    66         struct irc_user *user;
    67        
    68         char *last_root_cmd;
     61        int sentbytes;
     62        time_t oldtime;
    6963
     64        char *nick;
     65        char *user;
     66        char *host;
     67        char *realname;
    7068        char *password; /* HACK: Used to save the user's password, but before
    7169                           logging in, this may contain a password we should
     
    7472        char umode[8];
    7573       
     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       
    7683        struct query *queries;
     84        struct account *accounts;
    7785        GSList *file_transfers;
     86        struct chat *chatrooms;
    7887       
    79         GSList *users, *channels;
    80         GHashTable *nick_user_hash;
     88        struct __USER *users;
     89        GHashTable *userhash;
    8190        GHashTable *watches;
     91        struct __NICK *nicks;
     92        struct set *set;
    8293
    8394        gint r_watch_source_id;
    8495        gint w_watch_source_id;
    8596        gint ping_source_id;
    86        
    87         struct bee *b;
    8897} irc_t;
    8998
    90 typedef enum
    91 {
    92         IRC_USER_PRIVATE = 1,
    93 } irc_user_flags_t;
     99#include "user.h"
    94100
    95 typedef struct irc_user
    96 {
    97         irc_t *irc;
    98        
    99         char *nick;
    100         char *user;
    101         char *host;
    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 
    119 struct irc_user_funcs
    120 {
    121         gboolean (*privmsg)( irc_user_t *iu, const char *msg );
    122 };
    123 
    124 extern const struct irc_user_funcs irc_user_root_funcs;
    125 extern const struct irc_user_funcs irc_user_self_funcs;
    126 
    127 typedef enum
    128 {
    129         IRC_CHANNEL_JOINED = 1,
    130 } irc_channel_flags_t;
    131 
    132 typedef 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;
    144         struct set *set;
    145        
    146         const struct irc_channel_funcs *f;
    147 } irc_channel_t;
    148 
    149 struct irc_channel_funcs
    150 {
    151         gboolean (*privmsg)( irc_channel_t *iu, const char *msg );
    152 };
    153 
    154 extern const struct bee_ui_funcs irc_ui_funcs;
    155 
    156 /* irc.c */
    157101extern GSList *irc_connection_list;
    158102
     
    160104void irc_abort( irc_t *irc, int immed, char *format, ... ) G_GNUC_PRINTF( 3, 4 );
    161105void irc_free( irc_t *irc );
    162 void irc_setpass (irc_t *irc, const char *pass);
    163106
     107void irc_exec( irc_t *irc, char **cmd );
    164108void irc_process( irc_t *irc );
    165109char **irc_parse_line( char *line );
    166110char *irc_build_line( char **cmd );
    167111
     112void irc_vawrite( irc_t *irc, char *format, va_list params );
    168113void irc_write( irc_t *irc, char *format, ... ) G_GNUC_PRINTF( 2, 3 );
    169114void irc_write_all( int now, char *format, ... ) G_GNUC_PRINTF( 2, 3 );
    170 void irc_vawrite( irc_t *irc, char *format, va_list params );
     115void irc_reply( irc_t *irc, int code, char *format, ... ) G_GNUC_PRINTF( 3, 4 );
     116G_MODULE_EXPORT int irc_usermsg( irc_t *irc, char *format, ... ) G_GNUC_PRINTF( 2, 3 );
     117char **irc_tokenize( char *buffer );
    171118
     119void irc_login( irc_t *irc );
    172120int irc_check_login( irc_t *irc );
     121void irc_motd( irc_t *irc );
     122void irc_names( irc_t *irc, char *channel );
     123void irc_topic( irc_t *irc, char *channel );
     124void irc_umode_set( irc_t *irc, char *s, int allow_priv );
     125void irc_who( irc_t *irc, char *channel );
     126void irc_spawn( irc_t *irc, user_t *u );
     127void irc_join( irc_t *irc, user_t *u, char *channel );
     128void irc_part( irc_t *irc, user_t *u, char *channel );
     129void irc_kick( irc_t *irc, user_t *u, char *channel, user_t *kicker );
     130void irc_kill( irc_t *irc, user_t *u );
     131void irc_invite( irc_t *irc, char *nick, char *channel );
     132void irc_whois( irc_t *irc, char *nick );
     133void irc_setpass( irc_t *irc, const char *pass ); /* USE WITH CAUTION! */
    173134
    174 void irc_umode_set( irc_t *irc, const char *s, gboolean allow_priv );
     135int irc_send( irc_t *irc, char *nick, char *s, int flags );
     136int irc_privmsg( irc_t *irc, user_t *u, char *type, char *to, char *prefix, char *msg );
     137int irc_msgfrom( irc_t *irc, char *nick, char *msg );
     138int irc_noticefrom( irc_t *irc, char *nick, char *msg );
    175139
    176 /* irc_channel.c */
    177 irc_channel_t *irc_channel_new( irc_t *irc, const char *name );
    178 irc_channel_t *irc_channel_by_name( irc_t *irc, const char *name );
    179 int irc_channel_free( irc_channel_t *ic );
    180 int irc_channel_add_user( irc_channel_t *ic, irc_user_t *iu );
    181 int irc_channel_del_user( irc_channel_t *ic, irc_user_t *iu );
    182 gboolean irc_channel_has_user( irc_channel_t *ic, irc_user_t *iu );
    183 int irc_channel_set_topic( irc_channel_t *ic, const char *topic, const irc_user_t *who );
    184 gboolean irc_channel_name_ok( const char *name );
    185 
    186 /* irc_commands.c */
    187 void irc_exec( irc_t *irc, char **cmd );
    188 
    189 /* irc_send.c */
    190 void irc_send_num( irc_t *irc, int code, char *format, ... ) G_GNUC_PRINTF( 3, 4 );
    191 void irc_send_login( irc_t *irc );
    192 void irc_send_motd( irc_t *irc );
    193 void irc_usermsg( irc_t *irc, char *format, ... );
    194 void irc_send_join( irc_channel_t *ic, irc_user_t *iu );
    195 void irc_send_part( irc_channel_t *ic, irc_user_t *iu, const char *reason );
    196 void irc_send_names( irc_channel_t *ic );
    197 void irc_send_topic( irc_channel_t *ic, gboolean topic_change );
    198 void irc_send_whois( irc_user_t *iu );
    199 void irc_send_who( irc_t *irc, GSList *l, const char *channel );
    200 void irc_send_msg( irc_user_t *iu, const char *type, const char *dst, const char *msg, const char *prefix );
    201 void irc_send_msg_raw( irc_user_t *iu, const char *type, const char *dst, const char *msg );
    202 void irc_send_nick( irc_user_t *iu, const char *new );
    203 
    204 /* irc_user.c */
    205 irc_user_t *irc_user_new( irc_t *irc, const char *nick );
    206 int irc_user_free( irc_t *irc, const char *nick );
    207 irc_user_t *irc_user_by_name( irc_t *irc, const char *nick );
    208 int irc_user_set_nick( irc_user_t *iu, const char *new );
    209 gint irc_user_cmp( gconstpointer a_, gconstpointer b_ );
     140void buddy_send_handler( irc_t *irc, user_t *u, char *msg, int flags );
     141struct groupchat *irc_chat_by_channel( irc_t *irc, char *channel );
    210142
    211143#endif
  • irc_commands.c

    ra87e6ba r3ab1d31  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2010 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2006 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    5353        else if( global.conf->auth_pass )
    5454        {
    55                 irc_send_num( irc, 464, ":Incorrect password" );
     55                irc_reply( 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->user = g_strdup( cmd[1] );
    68         irc->user->fullname = g_strdup( cmd[4] );
     67        irc->user = g_strdup( cmd[1] );
     68        irc->realname = g_strdup( cmd[4] );
    6969       
    7070        irc_check_login( irc );
     
    7373static void irc_cmd_nick( irc_t *irc, char **cmd )
    7474{
    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" );
     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" );
    8283        }
    8384        else if( !nick_ok( cmd[1] ) )
    8485        {
    8586                /* [SH] Invalid characters. */
    86                 irc_send_num( irc, 432, ":This nick contains invalid characters" );
    87         }
    88         else
    89         {
    90                 irc->user->nick = g_strdup( cmd[1] );
     87                irc_reply( irc, 432, ":This nick contains invalid characters" );
     88        }
     89        else
     90        {
     91                irc->nick = g_strdup( cmd[1] );
    9192               
    9293                irc_check_login( irc );
     
    104105static void irc_cmd_ping( irc_t *irc, char **cmd )
    105106{
    106         irc_write( irc, ":%s PONG %s :%s", irc->root->host,
    107                    irc->root->host, cmd[1]?cmd[1]:irc->root->host );
    108 }
    109 
    110 static 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 
    118 static 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 
    135 static 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 
    153 static 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 
    167 static 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 
    178 static 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 
    189 static void irc_cmd_motd( irc_t *irc, char **cmd )
    190 {
    191         irc_send_motd( irc );
     107        irc_write( irc, ":%s PONG %s :%s", irc->myhost, irc->myhost, cmd[1]?cmd[1]:irc->myhost );
     108}
     109
     110static 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        }
    192124}
    193125
    194126static void irc_cmd_mode( irc_t *irc, char **cmd )
    195127{
    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] )
     128        if( strchr( CTYPES, *cmd[1] ) )
     129        {
     130                if( cmd[2] )
    203131                {
    204132                        if( *cmd[2] == '+' || *cmd[2] == '-' )
    205                                 irc_send_num( irc, 477, "%s :Can't change channel modes", cmd[1] );
     133                                irc_reply( irc, 477, "%s :Can't change channel modes", cmd[1] );
    206134                        else if( *cmd[2] == 'b' )
    207                                 irc_send_num( irc, 368, "%s :No bans possible", cmd[1] );
     135                                irc_reply( irc, 368, "%s :No bans possible", cmd[1] );
    208136                }
    209137                else
    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 )
     138                        irc_reply( irc, 324, "%s +%s", cmd[1], CMODE );
     139        }
     140        else
     141        {
     142                if( nick_cmp( cmd[1], irc->nick ) == 0 )
    215143                {
    216144                        if( cmd[2] )
    217145                                irc_umode_set( irc, cmd[2], 0 );
    218146                        else
    219                                 irc_send_num( irc, 221, "+%s", irc->umode );
     147                                irc_reply( irc, 221, "+%s", irc->umode );
    220148                }
    221149                else
    222                         irc_send_num( irc, 502, ":Don't touch their modes" );
    223         }
    224 }
    225 
    226 static 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 );
     150                        irc_reply( irc, 502, ":Don't touch their modes" );
     151        }
     152}
     153
     154static void irc_cmd_names( irc_t *irc, char **cmd )
     155{
     156        irc_names( irc, cmd[1]?cmd[1]:irc->channel );
     157}
     158
     159static 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
     189static 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
     207static 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 );
    237222}
    238223
    239224static void irc_cmd_privmsg( irc_t *irc, char **cmd )
    240225{
    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         {
     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] );
    268233        }
    269234        else
     
    306271                irc_send( irc, cmd[1], cmd[2], ( g_strcasecmp( cmd[0], "NOTICE" ) == 0 ) ? OPT_AWAY : 0 );
    307272        }
    308 #endif
    309 }
    310 
    311 static 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
    322 static 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 
    338 static 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 );
     273}
     274
     275static 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:"**" );
    353305}
    354306
     
    368320                {
    369321                        if( u->online && u->away )
    370                                 irc_send_num( irc, 302, ":%s=-%s@%s", u->nick, u->user, u->host );
     322                                irc_reply( irc, 302, ":%s=-%s@%s", u->nick, u->user, u->host );
    371323                        else
    372                                 irc_send_num( irc, 302, ":%s=+%s@%s", u->nick, u->user, u->host );
     324                                irc_reply( irc, 302, ":%s=+%s@%s", u->nick, u->user, u->host );
    373325                }
    374326}
     
    425377                buff[strlen(buff)-1] = '\0';
    426378       
    427         irc_send_num( irc, 303, ":%s", buff );
     379        irc_reply( irc, 303, ":%s", buff );
    428380}
    429381
     
    454406                       
    455407                        if( u && u->online )
    456                                 irc_send_num( irc, 604, "%s %s %s %d :%s", u->nick, u->user, u->host, (int) time( NULL ), "is online" );
     408                                irc_reply( irc, 604, "%s %s %s %d :%s", u->nick, u->user, u->host, (int) time( NULL ), "is online" );
    457409                        else
    458                                 irc_send_num( irc, 605, "%s %s %s %d :%s", nick, "*", "*", (int) time( NULL ), "is offline" );
     410                                irc_reply( irc, 605, "%s %s %s %d :%s", nick, "*", "*", (int) time( NULL ), "is offline" );
    459411                }
    460412                else if( cmd[i][0] == '-' )
     
    467419                                g_free( okey );
    468420                               
    469                                 irc_send_num( irc, 602, "%s %s %s %d :%s", nick, "*", "*", 0, "Stopped watching" );
     421                                irc_reply( irc, 602, "%s %s %s %d :%s", nick, "*", "*", 0, "Stopped watching" );
    470422                        }
    471423                }
     
    511463                u->away[j] = 0;
    512464               
    513                 irc_send_num( irc, 306, ":You're now away: %s", u->away );
     465                irc_reply( irc, 306, ":You're now away: %s", u->away );
    514466                /* irc_umode_set( irc, irc->myhost, "+a" ); */
    515467        }
     
    519471                u->away = NULL;
    520472                /* irc_umode_set( irc, irc->myhost, "-a" ); */
    521                 irc_send_num( irc, 305, ":Welcome back" );
     473                irc_reply( irc, 305, ":Welcome back" );
    522474        }
    523475       
     
    525477}
    526478
     479static 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
     510static 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
     521static 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
     528static void irc_cmd_motd( irc_t *irc, char **cmd )
     529{
     530        irc_motd( irc );
     531}
     532
     533static 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
    527541static void irc_cmd_version( irc_t *irc, char **cmd )
    528542{
    529         irc_send_num( irc, 351, "bitlbee-%s. %s :%s/%s ", BITLBEE_VERSION, irc->myhost, ARCH, CPU );
     543        irc_reply( irc, 351, "bitlbee-%s. %s :%s/%s ", BITLBEE_VERSION, irc->myhost, ARCH, CPU );
    530544}
    531545
     
    558572                ipc_to_master( cmd );
    559573       
    560         irc_send_num( irc, 382, "%s :Rehashing", global.conf_file );
    561 }
    562 #endif
     574        irc_reply( irc, 382, "%s :Rehashing", global.conf_file );
     575}
    563576
    564577static const command_t irc_commands[] = {
     
    568581        { "quit",        0, irc_cmd_quit,        0 },
    569582        { "ping",        0, irc_cmd_ping,        0 },
    570         { "pong",        0, irc_cmd_pong,        IRC_CMD_LOGGED_IN },
     583        { "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 },
    571587        { "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 },
     588        { "invite",      2, irc_cmd_invite,      IRC_CMD_LOGGED_IN },
     589        { "privmsg",     1, irc_cmd_privmsg,     IRC_CMD_LOGGED_IN },
     590        { "notice",      1, irc_cmd_privmsg,     IRC_CMD_LOGGED_IN },
    578591        { "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
    583         { "oper",        2, irc_cmd_oper,        IRC_CMD_LOGGED_IN },
    584         { "invite",      2, irc_cmd_invite,      IRC_CMD_LOGGED_IN },
    585         { "notice",      1, irc_cmd_privmsg,     IRC_CMD_LOGGED_IN },
    586592        { "userhost",    1, irc_cmd_userhost,    IRC_CMD_LOGGED_IN },
    587593        { "ison",        1, irc_cmd_ison,        IRC_CMD_LOGGED_IN },
     
    589595        { "topic",       1, irc_cmd_topic,       IRC_CMD_LOGGED_IN },
    590596        { "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 },
    591603        { "version",     0, irc_cmd_version,     IRC_CMD_LOGGED_IN },
    592604        { "completions", 0, irc_cmd_completions, IRC_CMD_LOGGED_IN },
     
    598610        { "restart",     0, NULL,                IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER },
    599611        { "kill",        2, NULL,                IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER },
    600 #endif
    601612        { NULL }
    602613};
     
    617628                        if( irc_commands[i].flags & IRC_CMD_PRE_LOGIN && irc->status & USTATUS_LOGGED_IN )
    618629                        {
    619                                 irc_send_num( irc, 462, ":Only allowed before logging in" );
     630                                irc_reply( irc, 462, ":Only allowed before logging in" );
    620631                        }
    621632                        else if( irc_commands[i].flags & IRC_CMD_LOGGED_IN && !( irc->status & USTATUS_LOGGED_IN ) )
    622633                        {
    623                                 irc_send_num( irc, 451, ":Register first" );
     634                                irc_reply( irc, 451, ":Register first" );
    624635                        }
    625636                        else if( irc_commands[i].flags & IRC_CMD_OPER_ONLY && !strchr( irc->umode, 'o' ) )
    626637                        {
    627                                 irc_send_num( irc, 481, ":Permission denied - You're not an IRC operator" );
     638                                irc_reply( irc, 481, ":Permission denied - You're not an IRC operator" );
    628639                        }
    629640                        else if( n_arg < irc_commands[i].required_parameters )
    630641                        {
    631                                 irc_send_num( irc, 461, "%s :Need more parameters", cmd[0] );
     642                                irc_reply( irc, 461, "%s :Need more parameters", cmd[0] );
    632643                        }
    633644                        else if( irc_commands[i].flags & IRC_CMD_TO_MASTER )
     
    646657       
    647658        if( irc->status >= USTATUS_LOGGED_IN )
    648                 irc_send_num( irc, 421, "%s :Unknown command", cmd[0] );
    649 }
     659                irc_reply( irc, 421, "%s :Unknown command", cmd[0] );
     660}
  • nick.c

    ra87e6ba r3ab1d31  
    7878               
    7979                nick_strip( nick );
    80                 if( set_getbool( &acc->bee->set, "lcnicks" ) )
     80                if( set_getbool( &acc->irc->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;
    9594        int inf_protection = 256;
    9695       
    9796        /* Now, find out if the nick is already in use at the moment, and make
    9897           subtle changes to make it unique. */
    99         while( !nick_ok( nick ) || irc_user_by_name( irc, nick ) )
     98        while( !nick_ok( nick ) || user_find( acc->irc, nick ) )
    10099        {
    101100                if( strlen( nick ) < ( MAX_NICK_LENGTH - 1 ) )
     
    113112                        int i;
    114113                       
    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 );
     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 );
    122121                        for( i = 0; i < MAX_NICK_LENGTH; i ++ )
    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" );
     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" );
    128127                       
    129128                        g_snprintf( nick, MAX_NICK_LENGTH + 1, "xx%x", rand() );
  • protocols/Makefile

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

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

    ra87e6ba r3ab1d31  
    392392                        if( ( strcmp( sub, "both" ) == 0 || strcmp( sub, "to" ) == 0 ) )
    393393                        {
    394                                 if( initial || bee_user_by_handle( ic->bee, ic, jid ) == NULL )
     394                                if( initial || imcb_find_buddy( 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( bee_user_by_handle( ic->bee, ic, jid ) == NULL )
     592                if( imcb_find_buddy( ic, jid ) == NULL )
    593593                        imcb_add_buddy( ic, jid, NULL );
    594594        }
  • protocols/jabber/jabber.c

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

    ra87e6ba r3ab1d31  
    279279        presence_send_request( bla->ic, bla->handle, "subscribed" );
    280280       
    281         imcb_ask_add( bla->ic, bla->handle, NULL );
     281        if( imcb_find_buddy( bla->ic, bla->handle ) == NULL )
     282                imcb_ask_add( bla->ic, bla->handle, NULL );
    282283       
    283284        g_free( bla->handle );
     
    461462               
    462463                if( bud == NULL && ( flags & GET_BUDDY_CREAT ) &&
    463                     ( bare_exists || bee_user_by_handle( ic->bee, ic, jid ) ) )
     464                    ( bare_exists || imcb_find_buddy( ic, jid ) ) )
    464465                {
    465466                        *s = '/';
     
    482483                if( bud == NULL )
    483484                        /* No match. Create it now? */
    484                         return ( ( flags & GET_BUDDY_CREAT ) &&
    485                                  bee_user_by_handle( ic->bee, ic, jid_ ) ) ?
     485                        return ( ( flags & GET_BUDDY_CREAT ) && imcb_find_buddy( ic, jid_ ) ) ?
    486486                                   jabber_buddy_add( ic, jid_ ) : NULL;
    487487                else if( bud->resource && ( flags & GET_BUDDY_EXACT ) )
  • protocols/jabber/s5bytestream.c

    ra87e6ba r3ab1d31  
    567567        xt_free_node( reply );
    568568
    569         imcb_file_canceled( tf->ic, tf->ft, "couldn't connect to any streamhosts" );
     569        imcb_file_canceled( 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->ic, tf->ft, "Error transmitting bytestream response" );
     606                imcb_file_canceled( 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->ic, tf->ft );
     646                imcb_file_finished( tf->ft );
    647647
    648648        tf->ft->write( tf->ft, tf->ft->buffer, ret );   
     
    660660        if( tf->watch_in )
    661661        {
    662                 imcb_file_canceled( tf->ic, ft, "BUG in jabber file transfer: write_request called when already watching for input" );
     662                imcb_file_canceled( 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( tf->ic, ft );
     708                imcb_file_finished( 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->ic, tf->ft, "Error transmitting bytestream request" );
     1008                imcb_file_canceled( 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->ic, tf->ft, error );
     1023                imcb_file_canceled( tf->ft, error );
    10241024
    10251025        /* MUST always return FALSE! */
  • protocols/jabber/si.c

    ra87e6ba r3ab1d31  
    9191
    9292        if( !foundft )
    93                 imcb_file_canceled( tf->ic, tf->ft, "Buddy's client doesn't feature file transfers" );
     93                imcb_file_canceled( tf->ft, "Buddy's client doesn't feature file transfers" );
    9494        else if( !foundbt )
    95                 imcb_file_canceled( tf->ic, tf->ft, "Buddy's client doesn't feature byte streams (required)" );
     95                imcb_file_canceled( tf->ft, "Buddy's client doesn't feature byte streams (required)" );
    9696        else if( !foundsi )
    97                 imcb_file_canceled( tf->ic, tf->ft, "Buddy's client doesn't feature stream initiation (required)" );
     97                imcb_file_canceled( 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->ic, tf->ft );
     111        imcb_file_recv_start( tf->ft );
    112112
    113113}
     
    156156        if( bud == NULL )
    157157        {
    158                 imcb_file_canceled( ic, ft, "Couldn't find buddy (BUG?)" );
     158                imcb_file_canceled( ft, "Couldn't find buddy (BUG?)" );
    159159                return;
    160160        }
  • protocols/msn/Makefile

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

    ra87e6ba r3ab1d31  
    8181        if( md )
    8282        {
    83                 /** Disabling MSN ft support for now.
    8483                while( md->filetransfers ) {
    8584                        imcb_file_canceled( md->filetransfers->data, "Closing connection" );
    8685                }
    87                 */
    8886               
    8987                if( md->fd >= 0 )
     
    346344        ret->send_typing = msn_send_typing;
    347345        ret->handle_cmp = g_strcasecmp;
    348         //ret->transfer_request = msn_ftp_transfer_request;
     346        ret->transfer_request = msn_ftp_transfer_request;
    349347
    350348        register_protocol(ret);
  • protocols/msn/msn_util.c

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

    ra87e6ba r3ab1d31  
    691691                        }
    692692                }
    693 #if 0
    694                 // Disable MSN ft support for now.
    695693                else if( g_strncasecmp( ct, "text/x-msmsgsinvite", 19 ) == 0 )
    696694                {
     
    725723                        g_free( command );
    726724                }
    727 #endif
    728725                else if( g_strncasecmp( ct, "application/x-msnmsgrp2p", 24 ) == 0 )
    729726                {
  • protocols/nogaim.c

    ra87e6ba r3ab1d31  
    3838#include "chat.h"
    3939
     40static int remove_chat_buddy_silent( struct groupchat *b, const char *handle );
     41
    4042GSList *connections;
    4143
     
    8991}
    9092#endif
     93
     94/* nogaim.c */
    9195
    9296GList *protocols = NULL;
     
    121125}
    122126
     127/* nogaim.c */
    123128void nogaim_init()
    124129{
     
    151156GSList *get_connections() { return connections; }
    152157
     158/* multi.c */
     159
    153160struct im_connection *imcb_new( account_t *acc )
    154161{
     
    157164        ic = g_new0( struct im_connection, 1 );
    158165       
    159         ic->bee = acc->bee;
     166        ic->irc = acc->irc;
    160167        ic->acc = acc;
    161168        acc->ic = ic;
     
    171178       
    172179        /* Destroy the pointer to this connection from the account list */
    173         for( a = ic->bee->accounts; a; a = a->next )
     180        for( a = ic->irc->accounts; a; a = a->next )
    174181                if( a->ic == ic )
    175182                {
     
    192199        va_end( params );
    193200
    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" ) ) )
     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" ) ) )
    196203                strip_html( text );
    197204       
    198205        /* Try to find a different connection on the same protocol. */
    199         for( a = ic->bee->accounts; a; a = a->next )
     206        for( a = ic->irc->accounts; a; a = a->next )
    200207                if( a->prpl == ic->acc->prpl && a->ic != ic )
    201208                        break;
     
    203210        /* If we found one, include the screenname in the message. */
    204211        if( a )
    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 );
     212                irc_usermsg( ic->irc, "%s(%s) - %s", ic->acc->prpl->name, ic->acc->user, text );
    207213        else
    208                 irc_usermsg( ic->bee->ui_data, "%s - %s", ic->acc->prpl->name, text );
     214                irc_usermsg( ic->irc, "%s - %s", ic->acc->prpl->name, text );
    209215       
    210216        g_free( text );
     
    257263void imcb_connected( struct im_connection *ic )
    258264{
     265        irc_t *irc = ic->irc;
     266        struct chat *c;
     267        user_t *u;
     268       
    259269        /* MSN servers sometimes redirect you to a different server and do
    260270           the whole login sequence again, so these "late" calls to this
     
    263273                return;
    264274       
     275        u = user_find( ic->irc, ic->irc->nick );
     276       
    265277        imcb_log( ic, "Logged in" );
    266278       
     
    275287        ic->acc->auto_reconnect_delay = 0;
    276288       
    277         /*
    278289        for( c = irc->chatrooms; c; c = c->next )
    279290        {
     
    284295                        chat_join( irc, c, NULL );
    285296        }
    286         */
    287297}
    288298
     
    292302       
    293303        a->reconnect = 0;
    294         account_on( a->bee, a );
     304        account_on( a->irc, a );
    295305       
    296306        return( FALSE );        /* Only have to run the timeout once */
     
    305315void imc_logout( struct im_connection *ic, int allow_reconnect )
    306316{
    307         bee_t *bee = ic->bee;
     317        irc_t *irc = ic->irc;
     318        user_t *t, *u;
    308319        account_t *a;
    309         GSList *l;
    310320        int delay;
    311321       
     
    327337        ic->away = NULL;
    328338       
    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 )
     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 )
    340355                if( a->ic == ic )
    341356                        break;
     
    345360                /* Uhm... This is very sick. */
    346361        }
    347         else if( allow_reconnect && set_getbool( &bee->set, "auto_reconnect" ) &&
     362        else if( allow_reconnect && set_getbool( &irc->set, "auto_reconnect" ) &&
    348363                 set_getbool( &a->set, "auto_reconnect" ) &&
    349364                 ( delay = account_reconnect_delay( a ) ) > 0 )
     
    356371}
    357372
     373
     374/* dialogs.c */
     375
    358376void imcb_ask( struct im_connection *ic, char *msg, void *data,
    359377               query_callback doit, query_callback dont )
    360378{
    361         //query_add( ic->irc, ic, msg, doit, dont, data );
    362 }
     379        query_add( ic->irc, ic, msg, doit, dont, data );
     380}
     381
     382
     383/* list.c */
    363384
    364385void imcb_add_buddy( struct im_connection *ic, const char *handle, const char *group )
    365386{
    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" ) )
     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" ) )
    372394                        imcb_log( ic, "User already exists, ignoring add request: %s", handle );
    373395               
     
    380402        }
    381403       
    382         bu = bee_user_new( bee, ic, handle );
    383         bu->group = g_strdup( group );
    384 }
    385 
    386 void imcb_rename_buddy( struct im_connection *ic, const char *handle, const char *fullname )
    387 {
    388         bee_t *bee = ic->bee;
    389         bee_user_t *bu = bee_user_by_handle( bee, ic, handle );
    390        
    391         if( !bu || !fullname ) return;
    392        
    393         if( !bu->fullname || strcmp( bu->fullname, fullname ) != 0 )
    394         {
    395                 g_free( bu->fullname );
    396                 bu->fullname = g_strdup( fullname );
    397                
    398                 if( bee->ui->user_fullname )
    399                         bee->ui->user_fullname( bee, bu );
     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
     440struct 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
     459void 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 );
    400491        }
    401492}
     
    403494void imcb_remove_buddy( struct im_connection *ic, const char *handle, char *group )
    404495{
    405         bee_user_free( ic->bee, ic, handle );
     496        user_t *u;
     497       
     498        if( ( u = user_findhandle( ic, handle ) ) )
     499                user_del( ic->irc, u->nick );
    406500}
    407501
     
    410504void imcb_buddy_nick_hint( struct im_connection *ic, const char *handle, const char *nick )
    411505{
    412 #if 0
    413506        user_t *u = user_findhandle( ic, handle );
    414507        char newnick[MAX_NICK_LENGTH+1], *orig_nick;
     
    425518                /* Some processing to make sure this string is a valid IRC nickname. */
    426519                nick_strip( newnick );
    427                 if( set_getbool( &ic->bee->set, "lcnicks" ) )
     520                if( set_getbool( &ic->irc->set, "lcnicks" ) )
    428521                        nick_lc( newnick );
    429522               
     
    442535                }
    443536        }
    444 #endif
    445537}
    446538
     
    452544};
    453545
    454 #if 0
    455546static void imcb_ask_auth_cb_no( void *data )
    456547{
     
    472563        g_free( cbd );
    473564}
    474 #endif
    475565
    476566void imcb_ask_auth( struct im_connection *ic, const char *handle, const char *realname )
    477567{
    478 #if 0
    479568        struct imcb_ask_cb_data *data = g_new0( struct imcb_ask_cb_data, 1 );
    480569        char *s, *realname_ = NULL;
     
    491580        data->handle = g_strdup( handle );
    492581        query_add( ic->irc, ic, s, imcb_ask_auth_cb_yes, imcb_ask_auth_cb_no, data );
    493 #endif
    494 }
    495 
    496 
    497 #if 0
     582}
     583
     584
    498585static void imcb_ask_add_cb_no( void *data )
    499586{
     
    510597        return imcb_ask_add_cb_no( data );
    511598}
    512 #endif
    513599
    514600void imcb_ask_add( struct im_connection *ic, const char *handle, const char *realname )
    515601{
    516 #if 0
    517602        struct imcb_ask_cb_data *data = g_new0( struct imcb_ask_cb_data, 1 );
    518603        char *s;
     
    527612        data->handle = g_strdup( handle );
    528613        query_add( ic->irc, ic, s, imcb_ask_add_cb_yes, imcb_ask_add_cb_no, data );
    529 #endif
     614}
     615
     616
     617/* server.c */                   
     618
     619void imcb_buddy_status( struct im_connection *ic, const char *handle, int flags, const char *state, const char *message )
     620{
     621        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
     717void 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 );
    530766}
    531767
    532768void imcb_buddy_typing( struct im_connection *ic, char *handle, uint32_t flags )
    533769{
    534 #if 0
    535770        user_t *u;
    536771       
    537         if( !set_getbool( &ic->bee->set, "typing_notice" ) )
     772        if( !set_getbool( &ic->irc->set, "typing_notice" ) )
    538773                return;
    539774       
     
    545780                irc_privmsg( ic->irc, u, "PRIVMSG", ic->irc->nick, NULL, buf );
    546781        }
    547 #endif
    548 }
    549 
    550 struct bee_user *imcb_buddy_by_handle( struct im_connection *ic, const char *handle )
    551 {
    552         return bee_user_by_handle( ic->bee, ic, handle );
    553782}
    554783
    555784struct groupchat *imcb_chat_new( struct im_connection *ic, const char *handle )
    556785{
    557 #if 0
    558786        struct groupchat *c;
    559787       
     
    573801        c->topic = g_strdup_printf( "BitlBee groupchat: \"%s\". Please keep in mind that root-commands won't work here. Have fun!", c->title );
    574802       
    575         if( set_getbool( &ic->bee->set, "debug" ) )
     803        if( set_getbool( &ic->irc->set, "debug" ) )
    576804                imcb_log( ic, "Creating new conversation: (id=%p,handle=%s)", c, handle );
    577805       
    578806        return c;
    579 #endif
    580         return NULL;
    581807}
    582808
    583809void imcb_chat_free( struct groupchat *c )
    584810{
    585 #if 0
    586811        struct im_connection *ic = c->ic;
    587812        struct groupchat *l;
    588813        GList *ir;
    589814       
    590         if( set_getbool( &ic->bee->set, "debug" ) )
     815        if( set_getbool( &ic->irc->set, "debug" ) )
    591816                imcb_log( ic, "You were removed from conversation %p", c );
    592817       
     
    621846                g_free( c );
    622847        }
    623 #endif
    624848}
    625849
    626850void imcb_chat_msg( struct groupchat *c, const char *who, char *msg, uint32_t flags, time_t sent_at )
    627851{
    628 #if 0
    629852        struct im_connection *ic = c->ic;
    630853        char *wrapped;
     
    637860        u = user_findhandle( ic, who );
    638861       
    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" ) ) )
     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" ) ) )
    641864                strip_html( msg );
    642865       
     
    651874        }
    652875        g_free( wrapped );
    653 #endif
    654876}
    655877
    656878void imcb_chat_log( struct groupchat *c, char *format, ... )
    657879{
    658 #if 0
    659880        irc_t *irc = c->ic->irc;
    660881        va_list params;
     
    671892       
    672893        g_free( text );
    673 #endif
    674894}
    675895
    676896void imcb_chat_topic( struct groupchat *c, char *who, char *topic, time_t set_at )
    677897{
    678 #if 0
    679898        struct im_connection *ic = c->ic;
    680899        user_t *u = NULL;
     
    687906                u = user_findhandle( ic, who );
    688907       
    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" ) ) )
     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" ) ) )
    691910                strip_html( topic );
    692911       
     
    696915        if( c->joined && u )
    697916                irc_write( ic->irc, ":%s!%s@%s TOPIC %s :%s", u->nick, u->user, u->host, c->channel, topic );
    698 #endif
    699 }
     917}
     918
     919
     920/* buddy_chat.c */
    700921
    701922void imcb_chat_add_buddy( struct groupchat *b, const char *handle )
    702923{
    703 #if 0
    704924        user_t *u = user_findhandle( b->ic, handle );
    705925        int me = 0;
    706926       
    707         if( set_getbool( &b->ic->bee->set, "debug" ) )
     927        if( set_getbool( &b->ic->irc->set, "debug" ) )
    708928                imcb_log( b->ic, "User %s added to conversation %p", handle, b );
    709929       
     
    732952                b->in_room = g_list_append( b->in_room, g_strdup( handle ) );
    733953        }
    734 #endif
    735954}
    736955
     
    738957void imcb_chat_remove_buddy( struct groupchat *b, const char *handle, const char *reason )
    739958{
    740 #if 0
    741959        user_t *u;
    742960        int me = 0;
    743961       
    744         if( set_getbool( &b->ic->bee->set, "debug" ) )
     962        if( set_getbool( &b->ic->irc->set, "debug" ) )
    745963                imcb_log( b->ic, "User %s removed from conversation %p (%s)", handle, b, reason ? reason : "" );
    746964       
     
    762980        if( me || ( remove_chat_buddy_silent( b, handle ) && b->joined && u ) )
    763981                irc_part( b->ic->irc, u, b->channel );
    764 #endif
    765 }
    766 
    767 #if 0
     982}
     983
    768984static int remove_chat_buddy_silent( struct groupchat *b, const char *handle )
    769985{
     
    7841000        }
    7851001       
    786         return 0;
    787 }
    788 #endif
     1002        return( 0 );
     1003}
    7891004
    7901005
    7911006/* Misc. BitlBee stuff which shouldn't really be here */
    792 #if 0
     1007
    7931008char *set_eval_away_devoice( set_t *set, char *value )
    7941009{
     
    8031018        /* Horror.... */
    8041019       
    805         if( st != set_getbool( &irc->b->set, "away_devoice" ) )
     1020        if( st != set_getbool( &irc->set, "away_devoice" ) )
    8061021        {
    8071022                char list[80] = "";
     
    8451060        return value;
    8461061}
    847 #endif
     1062
    8481063
    8491064
     
    8521067   them all from some wrappers. We'll start to define some down here: */
    8531068
    854 int imc_chat_msg( struct groupchat *c, char *msg, int flags )
     1069int imc_buddy_msg( struct im_connection *ic, char *handle, char *msg, int flags )
    8551070{
    8561071        char *buf = NULL;
    857        
    858         if( ( c->ic->flags & OPT_DOES_HTML ) && ( g_strncasecmp( msg, "<html>", 6 ) != 0 ) )
     1072        int st;
     1073       
     1074        if( ( ic->flags & OPT_DOES_HTML ) && ( g_strncasecmp( msg, "<html>", 6 ) != 0 ) )
    8591075        {
    8601076                buf = escape_html( msg );
     
    8621078        }
    8631079       
     1080        st = ic->acc->prpl->buddy_msg( ic, handle, msg, flags );
     1081        g_free( buf );
     1082       
     1083        return st;
     1084}
     1085
     1086int 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       
    8641096        c->ic->acc->prpl->chat_msg( c, msg, flags );
    8651097        g_free( buf );
     
    8751107       
    8761108        away = set_getstr( &ic->acc->set, "away" ) ?
    877              : set_getstr( &ic->bee->set, "away" );
     1109             : set_getstr( &ic->irc->set, "away" );
    8781110        if( away && *away )
    8791111        {
     
    8861118                away = NULL;
    8871119                msg = set_getstr( &ic->acc->set, "status" ) ?
    888                     : set_getstr( &ic->bee->set, "status" );
     1120                    : set_getstr( &ic->irc->set, "status" );
    8891121        }
    8901122       
  • protocols/nogaim.h

    ra87e6ba r3ab1d31  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2010 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2004 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    8787       
    8888        /* BitlBee */
    89         bee_t *bee;
     89        irc_t *irc;
    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 */
     293G_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. */
     296G_MODULE_EXPORT void imcb_buddy_msg( struct im_connection *ic, const char *handle, char *msg, uint32_t flags, time_t sent_at );
    288297G_MODULE_EXPORT void imcb_buddy_typing( struct im_connection *ic, char *handle, uint32_t flags );
    289 G_MODULE_EXPORT struct bee_user *imcb_buddy_by_handle( struct im_connection *ic, const char *handle );
    290298G_MODULE_EXPORT void imcb_clean_handle( struct im_connection *ic, char *handle );
    291299
     
    312320/* Actions, or whatever. */
    313321int imc_away_send_update( struct im_connection *ic );
     322int imc_buddy_msg( struct im_connection *ic, char *handle, char *msg, int flags );
    314323int imc_chat_msg( struct groupchat *c, char *msg, int flags );
    315324
  • protocols/oscar/oscar.c

    ra87e6ba r3ab1d31  
    11901190        aim_ssi_auth_reply(od->sess, od->conn, uin, 1, "");
    11911191        // aim_send_im_ch4(od->sess, uin, AIM_ICQMSG_AUTHGRANTED, &message);
    1192         imcb_ask_add(data->ic, uin, NULL);
     1192        if(imcb_find_buddy(data->ic, uin) == NULL)
     1193                imcb_ask_add(data->ic, uin, NULL);
    11931194       
    11941195        g_free(uin);
     
    19511952        struct oscar_data *odata = (struct oscar_data *)g->proto_data;
    19521953        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                 */
    19601959        } else
    19611960                aim_getinfo(odata->sess, odata->conn, who, AIM_GETINFO_AWAYMESSAGE);
     
    20952094                switch (curitem->type) {
    20962095                        case 0x0000: /* Buddy */
    2097                                 if ((curitem->name) && (!imcb_buddy_by_handle(ic, nrm))) {
     2096                                if ((curitem->name) && (!imcb_find_buddy(ic, nrm))) {
    20982097                                        char *realname = NULL;
    20992098
  • root_commands.c

    ra87e6ba r3ab1d31  
    3232#include <string.h>
    3333
    34 void root_command_string( irc_t *irc, char *command )
     34void root_command_string( irc_t *irc, user_t *u, char *command, int flags )
    3535{
    3636        char *cmd[IRC_MAX_ARGS];
     
    161161                irc->status |= USTATUS_IDENTIFIED;
    162162                irc_umode_set( irc, "+R", 1 );
    163                 if( set_getbool( &irc->b->set, "auto_connect" ) )
     163                if( set_getbool( &irc->set, "auto_connect" ) )
    164164                        cmd_account( irc, account_on );
    165165                break;
     
    201201        storage_status_t status;
    202202       
    203         status = storage_remove (irc->user->nick, cmd[1]);
     203        status = storage_remove (irc->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->user->nick );
     215                irc_usermsg( irc, "Account `%s' removed", irc->nick );
    216216                break;
    217217        default:
     
    221221}
    222222
    223 static 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 
    233223struct cmd_account_del_data
    234224{
     
    242232        account_t *a;
    243233       
    244         for( a = cad->irc->b->accounts; a && a != cad->a; a = a->next );
     234        for( a = cad->irc->accounts; a && a != cad->a; a = a->next );
    245235       
    246236        if( a == NULL )
     
    254244        else
    255245        {
    256                 account_del( cad->irc->b, a );
     246                account_del( cad->irc, a );
    257247                irc_usermsg( cad->irc, "Account deleted" );
    258248        }
     
    295285                set_name = set_full;
    296286               
    297                 head = &irc->b->set;
     287                head = &irc->set;
    298288        }
    299289        else
     
    366356        account_t *a;
    367357       
    368         if( ( a = account_get( irc->b, id ) ) )
     358        if( ( a = account_get( irc, id ) ) )
    369359                return &a->set;
    370360        else
     
    414404                }
    415405
    416                 a = account_add( irc->b, prpl, cmd[3], cmd[4] );
     406                a = account_add( irc, prpl, cmd[3], cmd[4] );
    417407                if( cmd[5] )
    418408                {
     
    428418                MIN_ARGS( 2 );
    429419
    430                 if( !( a = account_get( irc->b, cmd[2] ) ) )
     420                if( !( a = account_get( irc, cmd[2] ) ) )
    431421                {
    432422                        irc_usermsg( irc, "Invalid account" );
     
    450440                                               "set' command. Are you sure you want to delete this "
    451441                                               "account?", a->prpl->name, a->user );
    452                         //query_add( irc, NULL, msg, cmd_account_del_yes, cmd_account_del_no, cad );
     442                        query_add( irc, NULL, msg, cmd_account_del_yes, cmd_account_del_no, cad );
    453443                        g_free( msg );
    454444                }
     
    461451                        irc_usermsg( irc, "Account list:" );
    462452               
    463                 for( a = irc->b->accounts; a; a = a->next )
     453                for( a = irc->accounts; a; a = a->next )
    464454                {
    465455                        char *con;
     
    484474                if( cmd[2] )
    485475                {
    486                         if( ( a = account_get( irc->b, cmd[2] ) ) )
     476                        if( ( a = account_get( irc, cmd[2] ) ) )
    487477                        {
    488478                                if( a->ic )
     
    493483                                else
    494484                                {
    495                                         account_on( irc->b, a );
     485                                        account_on( irc, a );
    496486                                }
    497487                        }
     
    504494                else
    505495                {
    506                         if ( irc->b->accounts )
    507                         {
     496                        if ( irc->accounts ) {
    508497                                irc_usermsg( irc, "Trying to get all accounts connected..." );
    509498                       
    510                                 for( a = irc->b->accounts; a; a = a->next )
     499                                for( a = irc->accounts; a; a = a->next )
    511500                                        if( !a->ic && a->auto_connect )
    512                                                 account_on( irc->b, a );
     501                                                account_on( irc, a );
    513502                        }
    514503                        else
     
    524513                        irc_usermsg( irc, "Deactivating all active (re)connections..." );
    525514                       
    526                         for( a = irc->b->accounts; a; a = a->next )
     515                        for( a = irc->accounts; a; a = a->next )
    527516                        {
    528517                                if( a->ic )
    529                                         account_off( irc->b, a );
     518                                        account_off( irc, a );
    530519                                else if( a->reconnect )
    531520                                        cancel_auto_reconnect( a );
    532521                        }
    533522                }
    534                 else if( ( a = account_get( irc->b, cmd[2] ) ) )
     523                else if( ( a = account_get( irc, cmd[2] ) ) )
    535524                {
    536525                        if( a->ic )
    537526                        {
    538                                 account_off( irc->b, a );
     527                                account_off( irc, a );
    539528                        }
    540529                        else if( a->reconnect )
     
    567556}
    568557
    569 #if 0
    570558static void cmd_add( irc_t *irc, char **cmd )
    571559{
     
    656644        }
    657645}
    658 #endif
    659646
    660647static void cmd_rename( irc_t *irc, char **cmd )
    661648{
    662         irc_user_t *iu;
    663        
    664         iu = irc_user_by_name( irc, cmd[1] );
    665        
    666         if( iu == NULL )
     649        user_t *u;
     650       
     651        if( g_strcasecmp( cmd[1], irc->nick ) == 0 )
     652        {
     653                irc_usermsg( irc, "Nick `%s' can't be changed", cmd[1] );
     654        }
     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 ) )
     671        {
     672                irc_usermsg( irc, "Nick `%s' already exists", cmd[2] );
     673        }
     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] ) ) )
    667679        {
    668680                irc_usermsg( irc, "Nick `%s' does not exist", cmd[1] );
    669681        }
    670         else if( iu == irc->user )
    671         {
    672                 irc_usermsg( irc, "Nick `%s' can't be changed", cmd[1] );
    673         }
    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] ) )
    679         {
    680                 irc_usermsg( irc, "Nick `%s' already exists", cmd[2] );
    681         }
    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                 {
     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                       
    692691                        /* If we're called internally (user did "set root_nick"),
    693692                           let's not go O(INF). :-) */
    694693                        if( strcmp( cmd[0], "set_rename" ) != 0 )
    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] );
     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] );
    700699                }
    701700               
     
    704703}
    705704
    706 #if 0
    707705char *set_eval_root_nick( set_t *set, char *new_nick )
    708706{
     
    915913{
    916914        cmd_set_real( irc, cmd, NULL, NULL );
     915}
     916
     917static 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!" );
    917925}
    918926
     
    982990}
    983991
     992static 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
    9841020static void cmd_qlist( irc_t *irc, char **cmd )
    9851021{
     
    10001036                else
    10011037                        irc_usermsg( irc, "%d, BitlBee: %s", num, q->question );
     1038}
     1039
     1040static 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." );
    10021044}
    10031045
     
    11751217        }
    11761218}
    1177 #endif
    11781219
    11791220const command_t commands[] = {
    11801221        { "help",           0, cmd_help,           0 },
    1181         { "account",        1, cmd_account,        0 },
    11821222        { "identify",       1, cmd_identify,       0 },
    11831223        { "register",       1, cmd_register,       0 },
    11841224        { "drop",           1, cmd_drop,           0 },
    1185         { "save",           0, cmd_save,           0 },
    1186 #if 0
     1225        { "account",        1, cmd_account,        0 },
    11871226        { "add",            2, cmd_add,            0 },
    11881227        { "info",           1, cmd_info,           0 },
    1189 #endif
    11901228        { "rename",         2, cmd_rename,         0 },
    1191 #if 0
    11921229        { "remove",         1, cmd_remove,         0 },
    11931230        { "block",          1, cmd_block,          0 },
    11941231        { "allow",          1, cmd_allow,          0 },
     1232        { "save",           0, cmd_save,           0 },
    11951233        { "set",            0, cmd_set,            0 },
    11961234        { "yes",            0, cmd_yesno,          0 },
     
    12021240        { "chat",           1, cmd_chat,           0 },
    12031241        { "transfer",       0, cmd_transfer,       0 },
    1204 #endif
    12051242        { NULL }
    12061243};
  • set.c

    ra87e6ba r3ab1d31  
    225225}
    226226
    227 /*
    228227char *set_eval_ops( set_t *set, char *value )
    229228{
     
    247246        return value;
    248247}
    249 */
  • storage_xml.c

    ra87e6ba r3ab1d31  
    147147                                         arc_decode( pass_cr, pass_len, &password, xd->given_pass ) )
    148148                {
    149                         xd->current_account = account_add( irc->b, prpl, handle, password );
     149                        xd->current_account = account_add( irc, 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->b->set;
     183                                xd->current_set_head = &xd->irc->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->user->nick, password, XML_PASS_UNKNOWN );
     355        return xml_load_real( irc, irc->nick, password, XML_PASS_UNKNOWN );
    356356}
    357357
     
    396396        md5_state_t md5_state;
    397397       
    398         path2 = g_strdup( irc->user->nick );
     398        path2 = g_strdup( irc->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->user->nick, pass_buf, XML_FORMAT_VERSION ) )
     424        if( !xml_printf( fd, 0, "<user nick=\"%s\" password=\"%s\" version=\"%d\">\n", irc->nick, pass_buf, XML_FORMAT_VERSION ) )
    425425                goto write_error;
    426426       
    427427        g_free( pass_buf );
    428428       
    429         for( set = irc->b->set; set; set = set->next )
     429        for( set = irc->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->b->accounts; acc; acc = acc->next )
     434        for( acc = irc->accounts; acc; acc = acc->next )
    435435        {
    436436                unsigned char *pass_cr;
     
    470470                        goto write_error;
    471471               
    472 #if 0
    473472                for( c = irc->chatrooms; c; c = c->next )
    474473                {
     
    489488                                goto write_error;
    490489                }
    491 #endif
    492490               
    493491                if( !xml_printf( fd, 1, "</account>\n" ) )
Note: See TracChangeset for help on using the changeset viewer.