Changes in / [a4dc9f7:8e419cb]


Ignore:
Files:
2 added
5 deleted
24 edited

Legend:

Unmodified
Added
Removed
  • Makefile

    ra4dc9f7 r8e419cb  
    1010
    1111# Program variables
    12 objects = account.o bitlbee.o crypting.o help.o ini.o ipc.o irc.o irc_commands.o nick.o query.o root_commands.o set.o storage.o storage_text.o url.o user.o util.o
     12objects = account.o bitlbee.o commands.o crypting.o help.o ini.o irc.o nick.o query.o set.o storage.o storage_text.o url.o user.o util.o
    1313subdirs = protocols
    1414
  • bitlbee.c

    ra4dc9f7 r8e419cb  
    2929#include "protocols/nogaim.h"
    3030#include "help.h"
    31 #include "ipc.h"
    3231#include <signal.h>
    3332#include <stdio.h>
    3433#include <errno.h>
    3534
    36 gboolean bitlbee_io_new_client( GIOChannel *source, GIOCondition condition, gpointer data );
     35gboolean bitlbee_io_new_client( GIOChannel *source, GIOCondition condition, gpointer data )
     36{
     37        size_t size = sizeof( struct sockaddr_in );
     38        struct sockaddr_in conn_info;
     39        int new_socket = accept( global.listen_socket, (struct sockaddr *) &conn_info, &size );
     40        pid_t client_pid = 0;
     41       
     42        if( global.conf->runmode == RUNMODE_FORKDAEMON )
     43                client_pid = fork();
     44       
     45        if( client_pid == 0 )
     46        {
     47                log_message( LOGLVL_INFO, "Creating new connection with fd %d.", new_socket );
     48                irc_new( new_socket );
     49               
     50                if( global.conf->runmode == RUNMODE_FORKDAEMON )
     51                {
     52                        /* Close the listening socket, we're a client. */
     53                        close( global.listen_socket );
     54                        g_source_remove( global.listen_watch_source_id );
     55                }
     56        }
     57        else
     58        {
     59                /* We don't need this one, only the client does. */
     60                close( new_socket );
     61               
     62                /* Or maybe we didn't even get a child process... */
     63                if( client_pid == -1 )
     64                        log_message( LOGLVL_ERROR, "Failed to fork() subprocess for client: %s", strerror( errno ) );
     65        }
     66       
     67        return TRUE;
     68}
     69 
     70
    3771
    3872int bitlbee_daemon_init()
     
    4579        int i;
    4680        GIOChannel *ch;
    47         FILE *fp;
    4881       
    4982        log_link( LOGLVL_ERROR, LOGOUTPUT_SYSLOG );
     
    5689                return( -1 );
    5790        }
    58        
    59         /* TIME_WAIT (?) sucks.. */
    60         i = 1;
    61         setsockopt( global.listen_socket, SOL_SOCKET, SO_REUSEADDR, &i, sizeof( i ) );
    6291       
    6392#ifdef IPV6
     
    105134                else if( i != 0 )
    106135                        exit( 0 );
    107                
     136                close( 0 );
     137                close( 1 );
     138                close( 2 );
    108139                chdir( "/" );
    109                
    110                 /* Sometimes std* are already closed (for example when we're in a RESTARTed
    111                    BitlBee process. So let's only close TTY-fds. */
    112                 if( isatty( 0 ) ) close( 0 );
    113                 if( isatty( 0 ) ) close( 1 );
    114                 if( isatty( 0 ) ) close( 2 );
    115140        }
    116141#endif
    117        
    118         if( global.conf->runmode == RUNMODE_FORKDAEMON )
    119                 ipc_master_load_state();
    120 
    121         if( global.conf->runmode == RUNMODE_DAEMON ||
    122                 global.conf->runmode == RUNMODE_FORKDAEMON )
    123                 ipc_master_listen_socket();
    124        
    125         if( ( fp = fopen( global.conf->pidfile, "w" ) ) )
    126         {
    127                 fprintf( fp, "%d\n", (int) getpid() );
    128                 fclose( fp );
    129         }
    130         else
    131         {
    132                 log_message( LOGLVL_WARNING, "Warning: Couldn't write PID to `%s'", global.conf->pidfile );
    133         }
    134142       
    135143        return( 0 );
     
    152160        if( condition & G_IO_ERR || condition & G_IO_HUP )
    153161        {
    154                 irc_abort( irc, 1, "Read error" );
     162                irc_free( irc );
    155163                return FALSE;
    156164        }
     
    159167        if( st == 0 )
    160168        {
    161                 irc_abort( irc, 1, "Connection reset by peer" );
     169                irc_free( irc );
    162170                return FALSE;
    163171        }
     
    170178                else
    171179                {
    172                         irc_abort( irc, 1, "Read error: %s", strerror( errno ) );
     180                        irc_free( irc );
    173181                        return FALSE;
    174182                }
     
    186194        }
    187195       
    188         irc_process( irc );
    189        
    190         /* Normally, irc_process() shouldn't call irc_free() but irc_abort(). Just in case: */
    191         if( !g_slist_find( irc_connection_list, irc ) )
    192         {
    193                 log_message( LOGLVL_WARNING, "Abnormal termination of connection with fd %d.", irc->fd );
     196        if( !irc_process( irc ) )
     197        {
     198                log_message( LOGLVL_INFO, "Destroying connection with fd %d.", irc->fd );
     199                irc_free( irc );
    194200                return FALSE;
    195201        }
     
    198204        if( irc->readbuffer && ( strlen( irc->readbuffer ) > 1024 ) )
    199205        {
    200                 irc_abort( irc, 0, "Maximum line length exceeded" );
     206                log_message( LOGLVL_ERROR, "Maximum line length exceeded." );
     207                irc_free( irc );
    201208                return FALSE;
    202209        }
     
    217224        st = write( irc->fd, irc->sendbuffer, size );
    218225       
    219         if( st == 0 || ( st < 0 && !sockerr_again() ) )
    220         {
    221                 irc_abort( irc, 1, "Write error: %s", strerror( errno ) );
    222                 return FALSE;
    223         }
    224         else if( st < 0 ) /* && sockerr_again() */
    225         {
    226                 return TRUE;
     226        if( st <= 0 )
     227        {
     228                if( sockerr_again() )
     229                {
     230                        return TRUE;
     231                }
     232                else
     233                {
     234                        irc_free( irc );
     235                        return FALSE;
     236                }
    227237        }
    228238       
     
    231241                g_free( irc->sendbuffer );
    232242                irc->sendbuffer = NULL;
     243               
    233244                irc->w_watch_source_id = 0;
    234                
    235                 if( irc->status == USTATUS_SHUTDOWN )
    236                         irc_free( irc );
    237                
    238245                return( FALSE );
    239246        }
     
    248255}
    249256
    250 gboolean bitlbee_io_new_client( GIOChannel *source, GIOCondition condition, gpointer data )
    251 {
    252         size_t size = sizeof( struct sockaddr_in );
    253         struct sockaddr_in conn_info;
    254         int new_socket = accept( global.listen_socket, (struct sockaddr *) &conn_info, &size );
    255         pid_t client_pid = 0;
    256        
    257         if( new_socket == -1 )
    258         {
    259                 log_message( LOGLVL_WARNING, "Could not accept new connection: %s", strerror( errno ) );
    260                 return TRUE;
    261         }
    262        
    263         if( global.conf->runmode == RUNMODE_FORKDAEMON )
    264         {
    265                 int fds[2];
    266                
    267                 if( socketpair( AF_UNIX, SOCK_STREAM, 0, fds ) == -1 )
    268                 {
    269                         log_message( LOGLVL_WARNING, "Could not create IPC socket for client: %s", strerror( errno ) );
    270                         fds[0] = fds[1] = -1;
    271                 }
    272                
    273                 sock_make_nonblocking( fds[0] );
    274                 sock_make_nonblocking( fds[1] );
    275                
    276                 client_pid = fork();
    277                
    278                 if( client_pid > 0 && fds[0] != -1 )
    279                 {
    280                         struct bitlbee_child *child;
    281                        
    282                         child = g_new0( struct bitlbee_child, 1 );
    283                         child->pid = client_pid;
    284                         child->ipc_fd = fds[0];
    285                         child->ipc_inpa = gaim_input_add( child->ipc_fd, GAIM_INPUT_READ, ipc_master_read, child );
    286                         child_list = g_slist_append( child_list, child );
    287                        
    288                         log_message( LOGLVL_INFO, "Creating new subprocess with pid %d.", client_pid );
    289                        
    290                         /* Close some things we don't need in the parent process. */
    291                         close( new_socket );
    292                         close( fds[1] );
    293                 }
    294                 else if( client_pid == 0 )
    295                 {
    296                         irc_t *irc;
    297                        
    298                         /* Close the listening socket, we're a client. */
    299                         close( global.listen_socket );
    300                         g_source_remove( global.listen_watch_source_id );
    301                        
    302                         /* Make the connection. */
    303                         irc = irc_new( new_socket );
    304                        
    305                         /* We can store the IPC fd there now. */
    306                         global.listen_socket = fds[1];
    307                         global.listen_watch_source_id = gaim_input_add( fds[1], GAIM_INPUT_READ, ipc_child_read, irc );
    308                        
    309                         close( fds[0] );
    310                        
    311                         ipc_master_free_all();
    312                 }
    313         }
    314         else
    315         {
    316                 log_message( LOGLVL_INFO, "Creating new connection with fd %d.", new_socket );
    317                 irc_new( new_socket );
    318         }
    319        
    320         return TRUE;
    321 }
    322 
    323257void bitlbee_shutdown( gpointer data )
    324258{
  • bitlbee.h

    ra4dc9f7 r8e419cb  
    109109#include "sock.h"
    110110
    111 typedef struct global {
    112         /* In forked mode, child processes store the fd of the IPC socket here. */
     111typedef struct global_t {
    113112        int listen_socket;
    114113        gint listen_watch_source_id;
     
    118117        char *helpfile;
    119118        GMainLoop *loop;
    120         int restart;
    121119} global_t;
    122120
     
    127125gboolean bitlbee_io_current_client_write( GIOChannel *source, GIOCondition condition, gpointer data );
    128126
    129 void root_command_string( irc_t *irc, user_t *u, char *command, int flags );
    130 void root_command( irc_t *irc, char *command[] );
     127int root_command_string( irc_t *irc, user_t *u, char *command, int flags );
     128int root_command( irc_t *irc, char *command[] );
    131129void bitlbee_shutdown( gpointer data );
    132130double gettime( void );
  • commands.h

    ra4dc9f7 r8e419cb  
    2929#include "bitlbee.h"
    3030
    31 typedef struct command
     31typedef struct command_t
    3232{
    3333        char *command;
    3434        int required_parameters;
    35         void (*execute)(irc_t *, char **args);
    36         int flags;
     35        int (*execute)(irc_t *, char **args);
    3736} command_t;
     37
     38int cmd_account( irc_t *irc, char **cmd );
     39int cmd_help( irc_t *irc, char **args);
     40int cmd_info( irc_t *irc, char **args);
     41int cmd_add( irc_t *irc, char **args) ;
     42int cmd_rename( irc_t *irc, char **args );
     43int cmd_remove( irc_t *irc, char **args );
     44int cmd_block( irc_t *irc, char **args );
     45int cmd_allow( irc_t *irc, char **args );
     46int cmd_save( irc_t *irc, char **args );
     47int cmd_set( irc_t *irc, char **args );
     48int cmd_yesno( irc_t *irc, char **args );
     49int cmd_identify( irc_t *irc, char **args );
     50int cmd_register( irc_t *irc, char **args );
     51int cmd_drop( irc_t *irc, char **args );
     52int cmd_blist( irc_t *irc, char **cmd );
     53int cmd_nick( irc_t *irc, char **cmd );
     54int cmd_qlist( irc_t *irc, char **cmd );
     55int cmd_import_buddies( irc_t *irc, char **cmd );
     56int cmd_dump( irc_t *irc, char **cmd );
    3857
    3958extern const command_t commands[];
    4059
    41 #define IRC_CMD_PRE_LOGIN       1
    42 #define IRC_CMD_LOGGED_IN       2
    43 #define IRC_CMD_OPER_ONLY       4
    44 #define IRC_CMD_TO_MASTER       8
    45 
    46 #define IPC_CMD_TO_CHILDREN     1
    47 
    4860#endif
  • conf.c

    ra4dc9f7 r8e419cb  
    3232#include "ini.h"
    3333#include "url.h"
    34 #include "ipc.h"
    3534
    3635#include "protocols/proxy.h"
     
    6261        conf->configdir = g_strdup( CONFIG );
    6362        conf->plugindir = g_strdup( PLUGINDIR );
    64         conf->pidfile = g_strdup( "/var/run/bitlbee.pid" );
    6563        conf->motdfile = g_strdup( ETCDIR "/motd.txt" );
    6664        conf->ping_interval = 180;
    6765        conf->ping_timeout = 300;
    68         proxytype = 0;
    6966       
    7067        i = conf_loadini( conf, CONF_FILE );
     
    7976        }
    8077       
    81         while( argc > 0 && ( opt = getopt( argc, argv, "i:p:P:nvIDFc:d:hR:" ) ) >= 0 )
    82         /*     ^^^^ Just to make sure we skip this step from the REHASH handler. */
     78        while( ( opt = getopt( argc, argv, "i:p:nvIDFc:d:h" ) ) >= 0 )
    8379        {
    8480                if( opt == 'i' )
     
    9591                        conf->port = i;
    9692                }
    97                 else if( opt == 'p' )
    98                 {
    99                         g_free( conf->pidfile );
    100                         conf->pidfile = g_strdup( optarg );
    101                 }
    10293                else if( opt == 'n' )
    103                         conf->nofork = 1;
     94                        conf->nofork=1;
    10495                else if( opt == 'v' )
    105                         conf->verbose = 1;
     96                        conf->verbose=1;
    10697                else if( opt == 'I' )
    107                         conf->runmode = RUNMODE_INETD;
     98                        conf->runmode=RUNMODE_INETD;
    10899                else if( opt == 'D' )
    109                         conf->runmode = RUNMODE_DAEMON;
     100                        conf->runmode=RUNMODE_DAEMON;
    110101                else if( opt == 'F' )
    111                         conf->runmode = RUNMODE_FORKDAEMON;
     102                        conf->runmode=RUNMODE_FORKDAEMON;
    112103                else if( opt == 'c' )
    113104                {
     
    117108                                CONF_FILE = g_strdup( optarg );
    118109                                g_free( conf );
    119                                 /* Re-evaluate arguments. Don't use this option twice,
    120                                    you'll end up in an infinite loop! Hope this trick
    121                                    works with all libcs BTW.. */
    122                                 optind = 1;
    123110                                return( conf_load( argc, argv ) );
    124111                        }
     
    139126                                "  -D  Daemon mode. (Still EXPERIMENTAL!)\n"
    140127                                "  -F  Forking daemon. (one process per client)\n"
    141                                 "  -P  Specify PID-file (not for inetd mode)\n"
    142128                                "  -i  Specify the interface (by IP address) to listen on.\n"
    143129                                "      (Default: 0.0.0.0 (any interface))\n"
     
    150136                        return( NULL );
    151137                }
    152                 else if( opt == 'R' )
    153                 {
    154                         /* We can't load the statefile yet (and should make very sure we do this
    155                            only once), so set the filename here and load the state information
    156                            when initializing ForkDaemon. (This option only makes sense in that
    157                            mode anyway!) */
    158                         ipc_master_set_statefile( optarg );
    159                 }
    160138        }
    161139       
     
    191169                                else
    192170                                        conf->runmode = RUNMODE_INETD;
    193                         }
    194                         else if( g_strcasecmp( ini->key, "pidfile" ) == 0 )
    195                         {
    196                                 g_free( conf->pidfile );
    197                                 conf->pidfile = g_strdup( ini->value );
    198171                        }
    199172                        else if( g_strcasecmp( ini->key, "daemoninterface" ) == 0 )
  • conf.h

    ra4dc9f7 r8e419cb  
    4343        char *configdir;
    4444        char *plugindir;
    45         char *pidfile;
    4645        char *motdfile;
    4746        char *primary_storage;
  • configure

    ra4dc9f7 r8e419cb  
    1414datadir='$prefix/share/bitlbee/'
    1515config='/var/lib/bitlbee/'
    16 pidfile='/var/run/bitlbee.pid'
    17 ipcsocket='/var/run/bitlbee'
    1816plugindir='$prefix/lib/bitlbee'
    1917
     
    4846--datadir=...                                           $datadir
    4947--plugindir=...                                         $plugindir
    50 --pidfile=...                                           $pidfile
    5148--config=...                                            $config
    52 --ipcsocket=...                                         $ipcsocket
    5349
    5450--msn=0/1       Disable/enable MSN part                 $msn
     
    7874config=`eval echo "$config/" | sed 's/\/\{1,\}/\//g'`
    7975plugindir=`eval echo "$plugindir/" | sed 's/\/\{1,\}/\//g'`
    80 pidfile=`eval echo "$pidfile" | sed 's/\/\{1,\}/\//g'`
    81 ipcsocket=`eval echo "$ipcsocket" | sed 's/\/\{1,\}/\//g'`
    8276
    8377cat<<EOF>Makefile.settings
     
    9084PLUGINDIR=$plugindir
    9185CONFIG=$config
    92 IPCSOCKET=$ipcsocket
    9386
    9487ARCH=$arch
     
    111104#define VARDIR "$datadir"
    112105#define PLUGINDIR "$plugindir"
    113 #define PIDFILE "$pidfile"
    114 #define IPCSOCKET "$ipcsocket"
    115106#define ARCH "$arch"
    116107#define CPU "$cpu"
  • doc/README

    ra4dc9f7 r8e419cb  
    5050
    5151These days, MSN Messenger clients have to connect to the MS Passport servers
    52 through HTTPS. BitlBee can use several SSL libraries for this: GnuTLS, NSS
     52through HTTPS. BitlBee can use serveral SSL libraries for this: GnuTLS, NSS
    5353(which comes with Mozilla) and OpenSSL. OpenSSL is not GPL-compatible in some
    5454situations, so using GnuTLS or NSS is preferred. However, especially on *BSD,
  • irc.c

    ra4dc9f7 r8e419cb  
    2727#include "bitlbee.h"
    2828#include "crypting.h"
    29 #include "ipc.h"
    3029
    3130static gboolean irc_userping( gpointer _irc );
     
    152151}
    153152
    154 /* immed=1 makes this function pretty much equal to irc_free(), except that
    155    this one will "log". In case the connection is already broken and we
    156    shouldn't try to write to it. */
    157 void irc_abort( irc_t *irc, int immed, char *format, ... )
    158 {
    159         if( format != NULL )
    160         {
    161                 va_list params;
    162                 char *reason;
    163                
    164                 va_start( params, format );
    165                 reason = g_strdup_vprintf( format, params );
    166                 va_end( params );
    167                
    168                 if( !immed )
    169                         irc_write( irc, "ERROR :Closing link: %s", reason );
    170                
    171                 ipc_to_master_str( "OPERMSG :Client exiting: %s@%s [%s]\r\n",
    172                                    irc->nick ? irc->nick : "(NONE)", irc->host, reason );
    173                
    174                 g_free( reason );
    175         }
    176         else
    177         {
    178                 if( !immed )
    179                         irc_write( irc, "ERROR :Closing link" );
    180                
    181                 ipc_to_master_str( "OPERMSG :Client exiting: %s@%s [%s]\r\n",
    182                                    irc->nick ? irc->nick : "(NONE)", irc->host, "No reason given" );
    183         }
    184        
    185         irc->status = USTATUS_SHUTDOWN;
    186         if( irc->sendbuffer && !immed )
    187         {
    188                 /* We won't read from this socket anymore. Instead, we'll connect a timer
    189                    to it that should shut down the connection in a second, just in case
    190                    bitlbee_.._write doesn't do it first. */
    191                
    192                 g_source_remove( irc->r_watch_source_id );
    193                 irc->r_watch_source_id = g_timeout_add_full( G_PRIORITY_HIGH, 1000, (GSourceFunc) irc_free, irc, NULL );
    194         }
    195         else
    196         {
    197                 irc_free( irc );
    198         }
    199 }
    200 
    201153static gboolean irc_free_userhash( gpointer key, gpointer value, gpointer data )
    202154{
     
    220172                if( storage_save( irc, TRUE ) != STORAGE_OK )
    221173                        irc_usermsg( irc, "Error while saving settings!" );
    222        
    223         closesocket( irc->fd );
    224174       
    225175        if( irc->ping_source_id > 0 )
     
    341291}
    342292
    343 void irc_process( irc_t *irc )
    344 {
    345         char **lines, *temp, **cmd;
     293int irc_process( irc_t *irc )
     294{
     295        char **lines, *temp;   
    346296        int i;
    347297
    348         if( irc->readbuffer != NULL )
    349         {
    350                 lines = irc_tokenize( irc->readbuffer );
    351                
    352                 for( i = 0; *lines[i] != '\0'; i ++ )
    353                 {
    354                         if( lines[i+1] == NULL )
    355                         {
     298        if( irc->readbuffer != NULL ) {
     299                lines = irc_tokenize(irc->readbuffer );
     300                for( i = 0; *lines[i] != '\0'; i++ ) {
     301                        if( lines[i+1] == NULL ) {
    356302                                temp = g_strdup( lines[i] );
    357303                                g_free( irc->readbuffer );
    358304                                irc->readbuffer = temp;
    359                                 i ++;
     305                                i++;
    360306                                break;
    361307                        }                       
    362                        
    363                         if( ( cmd = irc_parse_line( lines[i] ) ) == NULL )
    364                                 continue;
    365                         irc_exec( irc, cmd );
    366                        
    367                         g_free( cmd );
    368                        
    369                         /* Shouldn't really happen, but just in case... */
    370                         if( !g_slist_find( irc_connection_list, irc ) )
    371                         {
     308                        if (!irc_process_line(irc, lines[i])) {
    372309                                g_free( lines );
    373                                 return;
    374                         }
    375                 }
    376                
    377                 if( lines[i] != NULL )
    378                 {
    379                         g_free( irc->readbuffer );
    380                         irc->readbuffer = NULL;
    381                 }
    382                
     310                                return 0;
     311                        }
     312                }
     313                if(lines[i]!=NULL) {
     314                        g_free(irc->readbuffer);
     315                        irc->readbuffer=NULL;   
     316                }
    383317                g_free( lines );
    384318        }
     319        return 1;       
    385320}
    386321
     
    391326
    392327        /* Count the number of elements we're gonna need. */
    393         for( i = 0, j = 1; buffer[i] != '\0'; i ++ )
    394         {
    395                 if( buffer[i] == '\n' )
    396                         if( buffer[i+1] != '\r' && buffer[i+1] != '\n' )
    397                                 j ++;
     328        for(i=0, j=1; buffer[i]!='\0'; i++ ) {
     329                if(buffer[i]=='\n' )
     330                        if(buffer[i+1]!='\r' && buffer[i+1]!='\n')
     331                                j++;
    398332        }
    399333       
    400334        /* Allocate j+1 elements. */
    401         lines = g_new( char *, j + 1 );
     335        lines=g_new (char *, j+1);
    402336       
    403337        /* NULL terminate our list. */
    404         lines[j] = NULL;
    405        
    406         lines[0] = buffer;
     338        lines[j]=NULL;
     339       
     340        lines[0]=buffer;
    407341       
    408342        /* Split the buffer in several strings, using \r\n as our seperator, where \r is optional.
    409343         * Although this is not in the RFC, some braindead ircds (newnet's) use this, so some clients might too.
    410344         */
    411         for( i = 0, j = 0; buffer[i] != '\0'; i ++)
    412         {
    413                 if( buffer[i] == '\n' )
    414                 {
    415                         buffer[i] = '\0';
    416                        
    417                         if( i > 0 && buffer[i-1] == '\r' )
    418                                 buffer[i-1] = '\0';
    419                         if( buffer[i+1] != '\r' && buffer[i+1] != '\n' )
    420                                 lines[++j] = buffer + i + 1;
    421                 }
    422         }
    423        
    424         return( lines );
    425 }
    426 
    427 char **irc_parse_line( char *line )
     345        for( i=0, j=0; buffer[i]!='\0'; i++) {
     346                if(buffer[i]=='\n') {
     347                        buffer[i]='\0';
     348
     349                        /* We dont want to read 1 byte before our buffer
     350                         * and (in rare cases) generate a SIGSEGV.
     351                         */
     352                        if(i!=0)
     353                                if(buffer[i-1]=='\r')
     354                                        buffer[i-1]='\0';
     355                        if(buffer[i+1]!='\r'&&buffer[i+1]!='\n')
     356                                lines[++j]=buffer+i+1;
     357                }
     358        }
     359
     360        return(lines);
     361}
     362
     363int irc_process_line( irc_t *irc, char *line )
    428364{
    429365        int i, j;
     
    431367       
    432368        /* Move the line pointer to the start of the command, skipping spaces and the optional prefix. */
    433         if( line[0] == ':' )
    434         {
    435                 for( i = 0; line[i] != ' '; i ++ );
    436                 line = line + i;
    437         }
    438         for( i = 0; line[i] == ' '; i ++ );
    439         line = line + i;
    440        
     369        if(line[0]==':') {
     370                for(i=0; line[i]!=32; i++);
     371                line=line+i;
     372        }
     373        for(i=0; line[i]==32; i++);
     374        line=line+i;
     375
    441376        /* If we're already at the end of the line, return. If not, we're going to need at least one element. */
    442         if( line[0] == '\0')
    443                 return NULL;
    444        
    445         /* Count the number of char **cmd elements we're going to need. */
    446         j = 1;
    447         for( i = 0; line[i] != '\0'; i ++ )
    448         {
    449                 if( line[i] == ' ' )
    450                 {
    451                         j ++;
     377        if(line[0]=='\0')
     378                return 1;
     379        else
     380                j=1;   
     381       
     382        /* Count the number of char **cmd elements we're going to need. */     
     383        for(i=0; line[i]!='\0'; i++) {
     384                if((line[i]==32) && (line[i+1]!=32) && (line[i+1]!='\0') && (line[i+1]!=':'))           
     385                        j++;
     386                else if((line[i]==':') && (line[i+1]!='\0') && (line[i-1]==32)) {
     387                        j++;
     388                        break;
     389                }
    452390                       
    453                         if( line[i+1] == ':' )
    454                                 break;
    455                 }
    456391        }       
    457392
    458393        /* Allocate the space we need. */
    459         cmd = g_new( char *, j + 1 );
    460         cmd[j] = NULL;
     394        cmd=g_new(char *, j+1);
     395        cmd[j]=NULL;
    461396       
    462397        /* Do the actual line splitting, format is:
     
    465400         */
    466401
    467         cmd[0] = line;
    468         for( i = 0, j = 0; line[i] != '\0'; i ++ )
    469         {
    470                 if( line[i] == ' ' )
    471                 {
    472                         line[i] = '\0';
    473                         cmd[++j] = line + i + 1;
     402        cmd[0]=line;
     403        for(i=0, j=0; line[i]!='\0'; i++) {
     404                if((line[i]==32)) {
     405                        line[i]='\0';
     406                        if((line[i+1]!=32) && (line[i+1]!='\0') && (line[i+1]!=':'))           
     407                                cmd[++j]=line+i+1;
     408                }
     409                else if((line[i]==':') && (line[i+1]!='\0') && (line[i-1]=='\0')) {
     410                        cmd[++j]=line+i+1;
     411                        break;
     412                }
     413        }
     414       
     415        i=irc_exec(irc, cmd);
     416        g_free(cmd);
     417
     418        return(i);     
     419}
     420
     421int irc_exec( irc_t *irc, char **cmd )
     422{       
     423        int i;
     424
     425        if( (global.conf)->authmode == AUTHMODE_CLOSED && irc->status < USTATUS_AUTHORIZED )
     426        {
     427                if( g_strcasecmp( cmd[0], "PASS" ) == 0 )
     428                {
     429                        if( !cmd[1] )
     430                        {
     431                                irc_reply( irc, 461, "%s :Need more parameters", cmd[0] );
     432                        }
     433                        else if( strcmp( cmd[1], (global.conf)->auth_pass ) == 0 )
     434                        {
     435                                irc->status = USTATUS_AUTHORIZED;
     436                        }
     437                        else
     438                        {
     439                                irc_reply( irc, 464, ":Nope, maybe you should try it again..." );
     440                        }
     441                }
     442                else
     443                {
     444                        irc_reply( irc, 464, ":Uhh, fine, but I want the password first." );
     445                }
     446               
     447                return( 1 );
     448        }
     449       
     450        if( g_strcasecmp( cmd[0], "USER" ) == 0 )
     451        {
     452                if( !( cmd[1] && cmd[2] && cmd[3] && cmd[4] ) )
     453                {
     454                        irc_reply( irc, 461, "%s :Need more parameters", cmd[0] );
     455                }
     456                else if( irc->user )
     457                {
     458                        irc_reply( irc, 462, ":You can't change your nick/userinfo" );
     459                }
     460                else
     461                {
     462                        irc->user = g_strdup( cmd[1] );
     463                        irc->realname = g_strdup( cmd[4] );
     464                        if( irc->nick ) irc_login( irc );
     465                }
     466                return( 1 );
     467        }
     468        else if( g_strcasecmp( cmd[0], "NICK" ) == 0 )
     469        {
     470                if( !cmd[1] )
     471                {
     472                        irc_reply( irc, 461, "%s :Need more parameters", cmd[0] );
     473                }
     474                else if( irc->nick )
     475                {
     476                        irc_reply( irc, 438, ":The hand of the deity is upon thee, thy nick may not change" );
     477                }
     478                /* This is not clean, but for now it'll have to be like this... */
     479                else if( ( nick_cmp( cmd[1], irc->mynick ) == 0 ) || ( nick_cmp( cmd[1], NS_NICK ) == 0 ) )
     480                {
     481                        irc_reply( irc, 433, ":This nick is already in use" );
     482                }
     483                else if( !nick_ok( cmd[1] ) )
     484                {
     485                        /* [SH] Invalid characters. */
     486                        irc_reply( irc, 432, ":This nick contains invalid characters" );
     487                }
     488                else
     489                {
     490                        irc->nick = g_strdup( cmd[1] );
     491                        if( irc->user ) irc_login( irc );
     492                }
     493                return( 1 );
     494        }
     495        else if( g_strcasecmp( cmd[0], "QUIT" ) == 0 )
     496        {
     497                irc_write( irc, "ERROR :%s%s", cmd[1]?"Quit: ":"", cmd[1]?cmd[1]:"Client Quit" );
     498                g_io_channel_close( irc->io_channel );
     499                return( 0 );
     500        }
     501       
     502        if( !irc->user || !irc->nick )
     503        {
     504                irc_reply( irc, 451, ":Register first" );
     505                return( 1 );
     506        }
     507       
     508        if( g_strcasecmp( cmd[0], "PING" ) == 0 )
     509        {
     510                irc_write( irc, ":%s PONG %s :%s", irc->myhost, irc->myhost, cmd[1]?cmd[1]:irc->myhost );
     511        }
     512        else if( g_strcasecmp( cmd[0], "OPER" ) == 0 )
     513        {
     514                if( !cmd[2] )
     515                        irc_reply( irc, 461, "%s :Need more parameters", cmd[0] );
     516                else if( strcmp( cmd[2], global.conf->oper_pass ) == 0 )
     517                        irc_umode_set( irc, "+o", 1 );
     518                // else
     519                        /* FIXME/TODO: Find out which reply to send now. */
     520        }
     521        else if( g_strcasecmp( cmd[0], "MODE" ) == 0 )
     522        {
     523                if( !cmd[1] )
     524                {
     525                        irc_reply( irc, 461, "%s :Need more parameters", cmd[0] );
     526                }
     527                else if( *cmd[1] == '#' || *cmd[1] == '&' )
     528                {
     529                        if( cmd[2] )
     530                        {
     531                                if( *cmd[2] == '+' || *cmd[2] == '-' )
     532                                        irc_reply( irc, 477, "%s :Can't change channel modes", cmd[1] );
     533                                else if( *cmd[2] == 'b' )
     534                                        irc_reply( irc, 368, "%s :No bans possible", cmd[1] );
     535                        }
     536                        else
     537                                irc_reply( irc, 324, "%s +%s", cmd[1], CMODE );
     538                }
     539                else
     540                {
     541                        if( nick_cmp( cmd[1], irc->nick ) == 0 )
     542                        {
     543                                if( cmd[2] )
     544                                        irc_umode_set( irc, cmd[2], 0 );
     545                        }
     546                        else
     547                                irc_reply( irc, 502, ":Don't touch their modes" );
     548                }
     549        }
     550        else if( g_strcasecmp( cmd[0], "NAMES" ) == 0 )
     551        {
     552                irc_names( irc, cmd[1]?cmd[1]:irc->channel );
     553        }
     554        else if( g_strcasecmp( cmd[0], "PART" ) == 0 )
     555        {
     556                struct conversation *c;
     557               
     558                if( !cmd[1] )
     559                {
     560                        irc_reply( irc, 461, "%s :Need more parameters", cmd[0] );
     561                }
     562                else if( g_strcasecmp( cmd[1], irc->channel ) == 0 )
     563                {
     564                        user_t *u = user_find( irc, irc->nick );
    474565                       
    475                         if( line[i+1] == ':' )
    476                         {
    477                                 cmd[j] ++;
     566                        /* Not allowed to leave control channel */
     567                        irc_part( irc, u, irc->channel );
     568                        irc_join( irc, u, irc->channel );
     569                }
     570                else if( ( c = conv_findchannel( cmd[1] ) ) )
     571                {
     572                        user_t *u = user_find( irc, irc->nick );
     573                       
     574                        irc_part( irc, u, c->channel );
     575                       
     576                        if( c->gc && c->gc->prpl )
     577                        {
     578                                c->joined = 0;
     579                                c->gc->prpl->chat_leave( c->gc, c->id );
     580                        }
     581                }
     582                else
     583                {
     584                        irc_reply( irc, 403, "%s :No such channel", cmd[1] );
     585                }
     586        }
     587        else if( g_strcasecmp( cmd[0], "JOIN" ) == 0 )
     588        {
     589                if( !cmd[1] )
     590                {
     591                        irc_reply( irc, 461, "%s :Need more parameters", cmd[0] );
     592                }
     593                else if( g_strcasecmp( cmd[1], irc->channel ) == 0 )
     594                        ; /* Dude, you're already there...
     595                             RFC doesn't have any reply for that though? */
     596                else if( cmd[1] )
     597                {
     598                        if( ( cmd[1][0] == '#' || cmd[1][0] == '&' ) && cmd[1][1] )
     599                        {
     600                                user_t *u = user_find( irc, cmd[1] + 1 );
     601                               
     602                                if( u && u->gc && u->gc->prpl && u->gc->prpl->chat_open )
     603                                {
     604                                        irc_reply( irc, 403, "%s :Initializing groupchat in a different channel", cmd[1] );
     605                                       
     606                                        if( !u->gc->prpl->chat_open( u->gc, u->handle ) )
     607                                        {
     608                                                irc_usermsg( irc, "Could not open a groupchat with %s, maybe you don't have a connection to him/her yet?", u->nick );
     609                                        }
     610                                }
     611                                else
     612                                {
     613                                        irc_reply( irc, 403, "%s :Groupchats are not possible with %s", cmd[1], cmd[1]+1 );
     614                                }
     615                        }
     616                        else
     617                        {
     618                                irc_reply( irc, 403, "%s :No such channel", cmd[1] );
     619                        }
     620                }
     621        }
     622        else if( g_strcasecmp( cmd[0], "INVITE" ) == 0 )
     623        {
     624                if( cmd[1] && cmd[2] )
     625                        irc_invite( irc, cmd[1], cmd[2] );
     626                else
     627                        irc_reply( irc, 461, "%s :Need more parameters", cmd[0] );
     628        }
     629        else if( g_strcasecmp( cmd[0], "PRIVMSG" ) == 0 || g_strcasecmp( cmd[0], "NOTICE" ) == 0 )
     630        {
     631                if( !cmd[1] )
     632                {
     633                        irc_reply( irc, 461, "%s :Need more parameters", cmd[0] );
     634                }
     635                else if ( !cmd[2] )
     636                {
     637                        irc_reply( irc, 412, ":No text to send" );
     638                }
     639                else if ( irc->nick && g_strcasecmp( cmd[1], irc->nick ) == 0 )
     640                {
     641                        irc_write( irc, ":%s!%s@%s %s %s :%s", irc->nick, irc->user, irc->host, cmd[0], cmd[1], cmd[2] );
     642                }
     643                else
     644                {
     645                        if( g_strcasecmp( cmd[1], irc->channel ) == 0 )
     646                        {
     647                                unsigned int i;
     648                                char *t = set_getstr( irc, "default_target" );
     649                               
     650                                if( g_strcasecmp( t, "last" ) == 0 && irc->last_target )
     651                                        cmd[1] = irc->last_target;
     652                                else if( g_strcasecmp( t, "root" ) == 0 )
     653                                        cmd[1] = irc->mynick;
     654                               
     655                                for( i = 0; i < strlen( cmd[2] ); i ++ )
     656                                {
     657                                        if( cmd[2][i] == ' ' ) break;
     658                                        if( cmd[2][i] == ':' || cmd[2][i] == ',' )
     659                                        {
     660                                                cmd[1] = cmd[2];
     661                                                cmd[2] += i;
     662                                                *cmd[2] = 0;
     663                                                while( *(++cmd[2]) == ' ' );
     664                                                break;
     665                                        }
     666                                }
     667                               
     668                                irc->is_private = 0;
     669                               
     670                                if( cmd[1] != irc->last_target )
     671                                {
     672                                        if( irc->last_target )
     673                                                g_free( irc->last_target );
     674                                        irc->last_target = g_strdup( cmd[1] );
     675                                }
     676                        }
     677                        else
     678                        {
     679                                irc->is_private = 1;
     680                        }
     681                        irc_send( irc, cmd[1], cmd[2], ( g_strcasecmp( cmd[0], "NOTICE" ) == 0 ) ? IM_FLAG_AWAY : 0 );
     682                }
     683        }
     684        else if( g_strcasecmp( cmd[0], "WHO" ) == 0 )
     685        {
     686                irc_who( irc, cmd[1] );
     687        }
     688        else if( g_strcasecmp( cmd[0], "USERHOST" ) == 0 )
     689        {
     690                user_t *u;
     691               
     692                if( !cmd[1] )
     693                {
     694                        irc_reply( irc, 461, "%s :Need more parameters", cmd[0] );
     695                }
     696                /* [TV] Usable USERHOST-implementation according to
     697                        RFC1459. Without this, mIRC shows an error
     698                        while connecting, and the used way of rejecting
     699                        breaks standards.
     700                */
     701               
     702                for( i = 1; cmd[i]; i ++ )
     703                        if( ( u = user_find( irc, cmd[i] ) ) )
     704                        {
     705                                if( u->online && u->away )
     706                                        irc_reply( irc, 302, ":%s=-%s@%s", u->nick, u->user, u->host );
     707                                else
     708                                        irc_reply( irc, 302, ":%s=+%s@%s", u->nick, u->user, u->host );
     709                        }
     710        }
     711        else if( g_strcasecmp( cmd[0], "ISON" ) == 0 )
     712        {
     713                user_t *u;
     714                char buff[IRC_MAX_LINE];
     715                int lenleft;
     716               
     717                buff[0] = '\0';
     718               
     719                /* [SH] Leave room for : and \0 */
     720                lenleft = IRC_MAX_LINE - 2;
     721               
     722                for( i = 1; cmd[i]; i ++ )
     723                {
     724                        if( ( u = user_find( irc, cmd[i] ) ) && u->online )
     725                        {
     726                                /* [SH] Make sure we don't use too much buffer space. */
     727                                lenleft -= strlen( u->nick ) + 1;
     728                               
     729                                if( lenleft < 0 )
     730                                {
     731                                        break;
     732                                }
     733                               
     734                                /* [SH] Add the nick to the buffer. Note
     735                                 * that an extra space is always added. Even
     736                                 * if it's the last nick in the list. Who
     737                                 * cares?
     738                                 */
     739                               
     740                                strcat( buff, u->nick );
     741                                strcat( buff, " " );
     742                        }
     743                }
     744               
     745                /* [WvG] Well, maybe someone cares, so why not remove it? */
     746                if( strlen( buff ) > 0 )
     747                        buff[strlen(buff)-1] = '\0';
     748               
     749                /* [SH] By the way, that really *was* WvG talking. */
     750                /* [WvG] Really? */
     751                /* [SH] Yeah... But *this* is WvG talking too. ;-P */
     752                /* [WvG] *sigh* */
     753               
     754                irc_reply( irc, 303, ":%s", buff );
     755        }
     756        else if( g_strcasecmp( cmd[0], "WATCH" ) == 0 )
     757        {
     758                /* Obviously we could also mark a user structure as being
     759                   watched, but what if the WATCH command is sent right
     760                   after connecting? The user won't exist yet then... */
     761                for( i = 1; cmd[i]; i ++ )
     762                {
     763                        char *nick;
     764                        user_t *u;
     765                       
     766                        if( !cmd[i][0] || !cmd[i][1] )
    478767                                break;
    479                         }
    480                 }
    481         }
    482        
    483         return cmd;
    484 }
    485 
    486 char *irc_build_line( char **cmd )
    487 {
    488         int i, len;
    489         char *s;
    490        
    491         if( cmd[0] == NULL )
    492                 return NULL;
    493        
    494         len = 1;
    495         for( i = 0; cmd[i]; i ++ )
    496                 len += strlen( cmd[i] ) + 1;
    497        
    498         if( strchr( cmd[i-1], ' ' ) != NULL )
    499                 len ++;
    500        
    501         s = g_new0( char, len + 1 );
    502         for( i = 0; cmd[i]; i ++ )
    503         {
    504                 if( cmd[i+1] == NULL && strchr( cmd[i], ' ' ) != NULL )
    505                         strcat( s, ":" );
    506                
    507                 strcat( s, cmd[i] );
    508                
    509                 if( cmd[i+1] )
    510                         strcat( s, " " );
    511         }
    512         strcat( s, "\r\n" );
    513        
    514         return s;
     768                       
     769                        nick = g_strdup( cmd[i] + 1 );
     770                        nick_lc( nick );
     771                       
     772                        u = user_find( irc, nick );
     773                       
     774                        if( cmd[i][0] == '+' )
     775                        {
     776                                if( !g_hash_table_lookup( irc->watches, nick ) )
     777                                        g_hash_table_insert( irc->watches, nick, nick );
     778                               
     779                                if( u && u->online )
     780                                        irc_reply( irc, 604, "%s %s %s %d :%s", u->nick, u->user, u->host, time( NULL ), "is online" );
     781                                else
     782                                        irc_reply( irc, 605, "%s %s %s %d :%s", nick, "*", "*", time( NULL ), "is offline" );
     783                        }
     784                        else if( cmd[i][0] == '-' )
     785                        {
     786                                gpointer okey, ovalue;
     787                               
     788                                if( g_hash_table_lookup_extended( irc->watches, nick, &okey, &ovalue ) )
     789                                {
     790                                        g_free( okey );
     791                                        g_hash_table_remove( irc->watches, okey );
     792                                       
     793                                        irc_reply( irc, 602, "%s %s %s %d :%s", nick, "*", "*", 0, "Stopped watching" );
     794                                }
     795                        }
     796                }
     797        }
     798        else if( g_strcasecmp( cmd[0], "TOPIC" ) == 0 )
     799        {
     800                if( cmd[1] && cmd[2] )
     801                        irc_reply( irc, 482, "%s :Cannot change topic", cmd[1] );
     802                else if( cmd[1] )
     803                        irc_topic( irc, cmd[1] );
     804                else
     805                        irc_reply( irc, 461, "%s :Need more parameters", cmd[0] );
     806        }
     807        else if( g_strcasecmp( cmd[0], "AWAY" ) == 0 )
     808        {
     809                irc_away( irc, cmd[1] );
     810        }
     811        else if( g_strcasecmp( cmd[0], "WHOIS" ) == 0 )
     812        {
     813                if( cmd[1] )
     814                {
     815                        irc_whois( irc, cmd[1] );
     816                }
     817                else
     818                {
     819                        irc_reply( irc, 461, "%s :Need more parameters", cmd[0] );
     820                }
     821        }
     822        else if( g_strcasecmp( cmd[0], "WHOWAS" ) == 0 )
     823        {
     824                /* For some reason irssi tries a whowas when whois fails. We can
     825                   ignore this, but then the user never gets a "user not found"
     826                   message from irssi which is a bit annoying. So just respond
     827                   with not-found and irssi users will get better error messages */
     828               
     829                if( cmd[1] )
     830                {
     831                        irc_reply( irc, 406, "%s :Nick does not exist", cmd[1] );
     832                        irc_reply( irc, 369, "%s :End of WHOWAS", cmd[1] );
     833                }
     834                else
     835                {
     836                        irc_reply( irc, 461, "%s :Need more parameters", cmd[0] );
     837                }
     838        }
     839        else if( ( g_strcasecmp( cmd[0], "NICKSERV" ) == 0 ) || ( g_strcasecmp( cmd[0], "NS" ) == 0 ) )
     840        {
     841                /* [SH] This aliases the NickServ command to PRIVMSG root */
     842                /* [TV] This aliases the NS command to PRIVMSG root as well */
     843                root_command( irc, cmd + 1 );
     844        }
     845        else if( g_strcasecmp( cmd[0], "MOTD" ) == 0 )
     846        {
     847                irc_motd( irc );
     848        }
     849        else if( g_strcasecmp( cmd[0], "PONG" ) == 0 )
     850        {
     851                /* We could check the value we get back from the user, but in
     852                   fact we don't care, we're just happy he's still alive. */
     853                irc->last_pong = gettime();
     854                irc->pinging = 0;
     855        }
     856        else if( g_strcasecmp( cmd[0], "COMPLETIONS" ) == 0 )
     857        {
     858                user_t *u = user_find( irc, irc->mynick );
     859                help_t *h;
     860                set_t *s;
     861                int i;
     862               
     863                irc_privmsg( irc, u, "NOTICE", irc->nick, "COMPLETIONS ", "OK" );
     864               
     865                for( i = 0; commands[i].command; i ++ )
     866                        irc_privmsg( irc, u, "NOTICE", irc->nick, "COMPLETIONS ", commands[i].command );
     867               
     868                for( h = global.help; h; h = h->next )
     869                        irc_privmsg( irc, u, "NOTICE", irc->nick, "COMPLETIONS help ", h->string );
     870               
     871                for( s = irc->set; s; s = s->next )
     872                        irc_privmsg( irc, u, "NOTICE", irc->nick, "COMPLETIONS set ", s->key );
     873               
     874                irc_privmsg( irc, u, "NOTICE", irc->nick, "COMPLETIONS ", "END" );
     875        }
     876        else if( set_getint( irc, "debug" ) )
     877        {
     878                irc_usermsg( irc, "\002--- Unknown command:" );
     879                for( i = 0; cmd[i]; i ++ ) irc_usermsg( irc, "%s", cmd[i] );
     880                irc_usermsg( irc, "\002--------------------" );
     881        }
     882       
     883        return( 1 );
    515884}
    516885
     
    6711040}
    6721041
    673 int irc_check_login( irc_t *irc )
    674 {
    675         if( irc->user && irc->nick )
    676         {
    677                 if( global.conf->authmode == AUTHMODE_CLOSED && irc->status < USTATUS_AUTHORIZED )
    678                 {
    679                         irc_reply( irc, 464, ":This server is password-protected." );
    680                         return 0;
    681                 }
    682                 else
    683                 {
    684                         irc_login( irc );
    685                         return 1;
    686                 }
    687         }
    688         else
    689         {
    690                 /* More information needed. */
    691                 return 0;
    692         }
     1042void irc_who( irc_t *irc, char *channel )
     1043{
     1044        user_t *u = irc->users;
     1045        struct conversation *c;
     1046        GList *l;
     1047       
     1048        if( !channel || *channel == '0' || *channel == '*' || !*channel )
     1049                while( u )
     1050                {
     1051                        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 );
     1052                        u = u->next;
     1053                }
     1054        else if( g_strcasecmp( channel, irc->channel ) == 0 )
     1055                while( u )
     1056                {
     1057                        if( u->online )
     1058                                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 );
     1059                        u = u->next;
     1060                }
     1061        else if( ( c = conv_findchannel( channel ) ) )
     1062                for( l = c->in_room; l; l = l->next )
     1063                {
     1064                        if( ( u = user_findhandle( c->gc, l->data ) ) )
     1065                                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 );
     1066                }
     1067        else if( ( u = user_find( irc, channel ) ) )
     1068                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 );
     1069       
     1070        irc_reply( irc, 315, "%s :End of /WHO list.", channel?channel:"**" );
    6931071}
    6941072
     
    7251103        u->realname = g_strdup( irc->realname );
    7261104        u->online = 1;
     1105//      u->send_handler = msg_echo;
    7271106        irc_spawn( irc, u );
    7281107       
    7291108        irc_usermsg( irc, "Welcome to the BitlBee gateway!\n\nIf you've never used BitlBee before, please do read the help information using the \x02help\x02 command. Lots of FAQ's are answered there." );
    730        
    731         if( global.conf->runmode == RUNMODE_FORKDAEMON || global.conf->runmode == RUNMODE_DAEMON )
    732                 ipc_to_master_str( "CLIENT %s %s :%s\r\n", irc->host, irc->nick, irc->realname );
    7331109       
    7341110        irc->status = USTATUS_LOGGED_IN;
     
    7831159                }
    7841160                irc_reply( irc, 376, ":End of MOTD" );
    785                 close( fd );
     1161                closesocket( fd );
    7861162        }
    7871163}
     
    8041180}
    8051181
     1182void irc_whois( irc_t *irc, char *nick )
     1183{
     1184        user_t *u = user_find( irc, nick );
     1185       
     1186        if( u )
     1187        {
     1188                irc_reply( irc, 311, "%s %s %s * :%s", u->nick, u->user, u->host, u->realname );
     1189               
     1190                if( u->gc )
     1191                        irc_reply( irc, 312, "%s %s.%s :%s network", u->nick, u->gc->user->username,
     1192                                   *u->gc->user->proto_opt[0] ? u->gc->user->proto_opt[0] : "", u->gc->prpl->name );
     1193                else
     1194                        irc_reply( irc, 312, "%s %s :%s", u->nick, irc->myhost, IRCD_INFO );
     1195               
     1196                if( !u->online )
     1197                        irc_reply( irc, 301, "%s :%s", u->nick, "User is offline" );
     1198                else if( u->away )
     1199                        irc_reply( irc, 301, "%s :%s", u->nick, u->away );
     1200               
     1201                irc_reply( irc, 318, "%s :End of /WHOIS list", nick );
     1202        }
     1203        else
     1204        {
     1205                irc_reply( irc, 401, "%s :Nick does not exist", nick );
     1206        }
     1207}
     1208
     1209
    8061210void irc_umode_set( irc_t *irc, char *s, int allow_priv )
    8071211{
     
    8331237}
    8341238
     1239int irc_away( irc_t *irc, char *away )
     1240{
     1241        user_t *u = user_find( irc, irc->nick );
     1242        GSList *c = get_connections();
     1243       
     1244        if( !u ) return( 0 );
     1245       
     1246        if( away && *away )
     1247        {
     1248                int i, j;
     1249               
     1250                /* Copy away string, but skip control chars. Mainly because
     1251                   Jabber really doesn't like them. */
     1252                u->away = g_malloc( strlen( away ) + 1 );
     1253                for( i = j = 0; away[i]; i ++ )
     1254                        if( ( u->away[j] = away[i] ) >= ' ' )
     1255                                j ++;
     1256                u->away[j] = 0;
     1257               
     1258                irc_reply( irc, 306, ":You're now away: %s", u->away );
     1259                /* irc_umode_set( irc, irc->myhost, "+a" ); */
     1260        }
     1261        else
     1262        {
     1263                if( u->away ) g_free( u->away );
     1264                u->away = NULL;
     1265                /* irc_umode_set( irc, irc->myhost, "-a" ); */
     1266                irc_reply( irc, 305, ":Welcome back" );
     1267        }
     1268       
     1269        while( c )
     1270        {
     1271                if( ((struct gaim_connection *)c->data)->flags & OPT_LOGGED_IN )
     1272                        proto_away( c->data, u->away );
     1273               
     1274                c = c->next;
     1275        }
     1276       
     1277        return( 1 );
     1278}
     1279
    8351280void irc_spawn( irc_t *irc, user_t *u )
    8361281{
     
    8841329        }
    8851330        g_free( nick );
     1331}
     1332
     1333void irc_invite( irc_t *irc, char *nick, char *channel )
     1334{
     1335        struct conversation *c = conv_findchannel( channel );
     1336        user_t *u = user_find( irc, nick );
     1337       
     1338        if( u && c && ( u->gc == c->gc ) )
     1339                if( c->gc && c->gc->prpl && c->gc->prpl->chat_invite )
     1340                {
     1341                        c->gc->prpl->chat_invite( c->gc, c->id, "", u->handle );
     1342                        irc_reply( irc, 341, "%s %s", nick, channel );
     1343                        return;
     1344                }
     1345       
     1346        irc_reply( irc, 482, "%s :Invite impossible; User/Channel non-existent or incompatible", channel );
    8861347}
    8871348
     
    9741435               
    9751436                if( u->send_handler )
    976                 {
    977                         u->send_handler( irc, u, s, flags );
    978                         return 1;
    979                 }
     1437                        return( u->send_handler( irc, u, s, flags ) );
    9801438        }
    9811439        else if( c && c->gc && c->gc->prpl )
     
    10031461}
    10041462
    1005 void buddy_send_handler( irc_t *irc, user_t *u, char *msg, int flags )
    1006 {
    1007         if( !u || !u->gc ) return;
     1463int buddy_send_handler( irc_t *irc, user_t *u, char *msg, int flags )
     1464{
     1465        if( !u || !u->gc ) return( 0 );
    10081466       
    10091467        if( set_getint( irc, "buddy_sendbuffer" ) && set_getint( irc, "buddy_sendbuffer_delay" ) > 0 )
     
    10411499                        g_source_remove( u->sendbuf_timer );
    10421500                u->sendbuf_timer = g_timeout_add( delay, buddy_send_handler_delayed, u );
     1501               
     1502                return( 1 );
    10431503        }
    10441504        else
    10451505        {
    1046                 serv_send_im( irc, u, msg, flags );
     1506                return( serv_send_im( irc, u, msg, flags ) );
    10471507        }
    10481508}
     
    11491609        if( rv > 0 )
    11501610        {
    1151                 irc_abort( irc, 0, "Ping Timeout: %d seconds", rv );
     1611                irc_write( irc, "ERROR :Closing Link: Ping Timeout: %d seconds", rv );
     1612                irc_free( irc );
    11521613                return FALSE;
    11531614        }
  • irc.h

    ra4dc9f7 r8e419cb  
    3333#define IRC_PING_STRING "PinglBee"
    3434
    35 #define UMODES "iasw"
     35#define UMODES "ias"
    3636#define UMODES_PRIV "Ro"
    3737#define CMODES "nt"
     
    4141typedef enum
    4242{
    43         USTATUS_OFFLINE = 0,
     43        USTATUS_OFFLINE,
    4444        USTATUS_AUTHORIZED,
    4545        USTATUS_LOGGED_IN,
    46         USTATUS_IDENTIFIED,
    47         USTATUS_SHUTDOWN = -1
     46        USTATUS_IDENTIFIED
    4847} irc_status_t;
    4948
     
    105104
    106105irc_t *irc_new( int fd );
    107 void irc_abort( irc_t *irc, int immed, char *format, ... );
    108106void irc_free( irc_t *irc );
    109107
    110 void irc_exec( irc_t *irc, char **cmd );
    111 void irc_process( irc_t *irc );
    112 char **irc_parse_line( char *line );
    113 char *irc_build_line( char **cmd );
     108int irc_exec( irc_t *irc, char **cmd );
     109int irc_process( irc_t *irc );
     110int irc_process_line( irc_t *irc, char *line );
    114111
    115112void irc_vawrite( irc_t *irc, char *format, va_list params );
     
    121118
    122119void irc_login( irc_t *irc );
    123 int irc_check_login( irc_t *irc );
    124120void irc_motd( irc_t *irc );
    125121void irc_names( irc_t *irc, char *channel );
     
    134130void irc_invite( irc_t *irc, char *nick, char *channel );
    135131void irc_whois( irc_t *irc, char *nick );
     132int irc_away( irc_t *irc, char *away );
    136133void irc_setpass( irc_t *irc, const char *pass ); /* USE WITH CAUTION! */
    137134
     
    141138int irc_noticefrom( irc_t *irc, char *nick, char *msg );
    142139
    143 void buddy_send_handler( irc_t *irc, user_t *u, char *msg, int flags );
     140int buddy_send_handler( irc_t *irc, user_t *u, char *msg, int flags );
    144141
    145142#endif
  • log.c

    ra4dc9f7 r8e419cb  
    3838        openlog("bitlbee", LOG_PID, LOG_DAEMON);       
    3939
    40         logoutput.informational = &log_null;
    41         logoutput.warning = &log_null;
    42         logoutput.error = &log_null;
     40        logoutput.informational=&log_null;
     41        logoutput.warning=&log_null;
     42        logoutput.error=&log_null;
    4343#ifdef DEBUG
    44         logoutput.debug = &log_null;
     44        logoutput.debug=&log_null;
    4545#endif
    4646
     
    5151        /* I know it's ugly, but it works and I didn't feel like messing with pointer to function pointers */
    5252
    53         if(level == LOGLVL_INFO) {
    54                 if(output == LOGOUTPUT_NULL)
    55                         logoutput.informational = &log_null;   
    56                 else if(output == LOGOUTPUT_IRC)
    57                         logoutput.informational = &log_irc;     
    58                 else if(output == LOGOUTPUT_SYSLOG)
    59                         logoutput.informational = &log_syslog; 
    60                 else if(output == LOGOUTPUT_CONSOLE)
    61                         logoutput.informational = &log_console;
     53        if(level==LOGLVL_INFO) {
     54                if(output==LOGOUTPUT_NULL)
     55                        logoutput.informational=&log_null;     
     56                else if(output==LOGOUTPUT_IRC)
     57                        logoutput.informational=&log_irc;       
     58                else if(output==LOGOUTPUT_SYSLOG)
     59                        logoutput.informational=&log_syslog;   
     60                else if(output==LOGOUTPUT_CONSOLE)
     61                        logoutput.informational=&log_console;   
    6262        }
    63         else if(level == LOGLVL_WARNING) {
    64                 if(output == LOGOUTPUT_NULL)
    65                         logoutput.warning = &log_null;
    66                 else if(output == LOGOUTPUT_IRC)
    67                         logoutput.warning = &log_irc;
    68                 else if(output == LOGOUTPUT_SYSLOG)
    69                         logoutput.warning = &log_syslog;
    70                 else if(output == LOGOUTPUT_CONSOLE)
    71                         logoutput.warning = &log_console;
     63        else if(level==LOGLVL_WARNING) {
     64                if(output==LOGOUTPUT_NULL)
     65                        logoutput.warning=&log_null;
     66                else if(output==LOGOUTPUT_IRC)
     67                        logoutput.warning=&log_irc;
     68                else if(output==LOGOUTPUT_SYSLOG)
     69                        logoutput.warning=&log_syslog;
     70                else if(output==LOGOUTPUT_CONSOLE)
     71                        logoutput.warning=&log_console;
    7272        }
    73         else if(level == LOGLVL_ERROR) {
    74                 if(output == LOGOUTPUT_NULL)
    75                         logoutput.error = &log_null;
    76                 else if(output == LOGOUTPUT_IRC)
    77                         logoutput.error = &log_irc;
    78                 else if(output == LOGOUTPUT_SYSLOG)
    79                         logoutput.error = &log_syslog;
    80                 else if(output == LOGOUTPUT_CONSOLE)
    81                         logoutput.error = &log_console;
     73        else if(level==LOGLVL_ERROR) {
     74                if(output==LOGOUTPUT_NULL)
     75                        logoutput.error=&log_null;
     76                else if(output==LOGOUTPUT_IRC)
     77                        logoutput.error=&log_irc;
     78                else if(output==LOGOUTPUT_SYSLOG)
     79                        logoutput.error=&log_syslog;
     80                else if(output==LOGOUTPUT_CONSOLE)
     81                        logoutput.error=&log_console;
    8282        }
    8383#ifdef DEBUG
    84         else if(level == LOGLVL_DEBUG) {
    85                 if(output == LOGOUTPUT_NULL)
    86                         logoutput.debug = &log_null;
    87                 else if(output == LOGOUTPUT_IRC)
    88                         logoutput.debug = &log_irc;
    89                 else if(output == LOGOUTPUT_SYSLOG)
    90                         logoutput.debug = &log_syslog;
    91                 else if(output == LOGOUTPUT_CONSOLE)
    92                         logoutput.debug = &log_console;
     84        else if(level==LOGLVL_DEBUG) {
     85                if(output==LOGOUTPUT_NULL)
     86                        logoutput.debug=&log_null;
     87                else if(output==LOGOUTPUT_IRC)
     88                        logoutput.debug=&log_irc;
     89                else if(output==LOGOUTPUT_SYSLOG)
     90                        logoutput.debug=&log_syslog;
     91                else if(output==LOGOUTPUT_CONSOLE)
     92                        logoutput.debug=&log_console;
    9393        }
    9494#endif
     
    106106        va_end(ap);
    107107
    108         if(level == LOGLVL_INFO)
     108        if(level==LOGLVL_INFO)
    109109                (*(logoutput.informational))(level, msgstring);
    110         if(level == LOGLVL_WARNING)
     110        if(level==LOGLVL_WARNING)
    111111                (*(logoutput.warning))(level, msgstring);
    112         if(level == LOGLVL_ERROR)
     112        if(level==LOGLVL_ERROR)
    113113                (*(logoutput.error))(level, msgstring);
    114114#ifdef DEBUG
    115         if(level == LOGLVL_DEBUG)
     115        if(level==LOGLVL_DEBUG)
    116116                (*(logoutput.debug))(level, msgstring);
    117117#endif
     
    133133
    134134static void log_irc(int level, char *message) {
    135         if(level == LOGLVL_ERROR)
     135        if(level==LOGLVL_ERROR)
    136136                irc_write_all(1, "ERROR :Error: %s", message);
    137         if(level == LOGLVL_WARNING)
     137        if(level==LOGLVL_WARNING)
    138138                irc_write_all(0, "ERROR :Warning: %s", message);
    139         if(level == LOGLVL_INFO)
     139        if(level==LOGLVL_INFO)
    140140                irc_write_all(0, "ERROR :Informational: %s", message); 
    141141#ifdef DEBUG
    142         if(level == LOGLVL_DEBUG)
     142        if(level==LOGLVL_DEBUG)
    143143                irc_write_all(0, "ERROR :Debug: %s", message); 
    144144#endif 
     
    148148
    149149static void log_syslog(int level, char *message) {
    150         if(level == LOGLVL_ERROR)
     150        if(level==LOGLVL_ERROR)
    151151                syslog(LOG_ERR, "%s", message);
    152         if(level == LOGLVL_WARNING)
     152        if(level==LOGLVL_WARNING)
    153153                syslog(LOG_WARNING, "%s", message);
    154         if(level == LOGLVL_INFO)
     154        if(level==LOGLVL_INFO)
    155155                syslog(LOG_INFO, "%s", message);
    156156#ifdef DEBUG
    157         if(level == LOGLVL_DEBUG)
     157        if(level==LOGLVL_DEBUG)
    158158                syslog(LOG_DEBUG, "%s", message);
    159159#endif
     
    162162
    163163static void log_console(int level, char *message) {
    164         if(level == LOGLVL_ERROR)
     164        if(level==LOGLVL_ERROR)
    165165                fprintf(stderr, "Error: %s\n", message);
    166         if(level == LOGLVL_WARNING)
     166        if(level==LOGLVL_WARNING)
    167167                fprintf(stderr, "Warning: %s\n", message);
    168         if(level == LOGLVL_INFO)
     168        if(level==LOGLVL_INFO)
    169169                fprintf(stdout, "Informational: %s\n", message);
    170170#ifdef DEBUG
    171         if(level == LOGLVL_DEBUG)
     171        if(level==LOGLVL_DEBUG)
    172172                fprintf(stdout, "Debug: %s\n", message);
    173173#endif
  • protocols/jabber/jabber.c

    ra4dc9f7 r8e419cb  
    413413                if (jd->die)
    414414                        signoff(GJ_GC(gjc));
    415         } else if (len == 0 || (len < 0 && (!sockerr_again() || gjc->ssl))) {
     415        } else if (len < 0 || errno != EAGAIN) {
    416416                STATE_EVT(JCONN_STATE_OFF)
    417417        }
  • protocols/msn/msn.c

    ra4dc9f7 r8e419cb  
    8484                {
    8585                        m = l->data;
    86                
    87                         serv_got_crap( gc, "Warning: Closing down MSN connection with unsent message to %s, you'll have to resend it.", m->who );
    8886                        g_free( m->who );
    8987                        g_free( m->text );
     
    9189                }
    9290                g_slist_free( md->msgq );
     91               
     92                serv_got_crap( gc, "Warning: Closing down MSN connection with unsent message(s), you'll have to resend them." );
    9393        }
    9494       
  • protocols/msn/sb.c

    ra4dc9f7 r8e419cb  
    213213                {
    214214                        m = l->data;
    215 
    216215                        g_free( m->who );
    217216                        g_free( m->text );
     
    220219                g_slist_free( sb->msgq );
    221220               
    222                 serv_got_crap( gc, "Warning: Closing down MSN switchboard connection with "
    223                                    "unsent message to %s, you'll have to resend it.",
    224                                    m->who ? m->who : "(unknown)" );
     221                serv_got_crap( gc, "Warning: Closing down MSN switchboard connection with unsent message(s), you'll have to resend them." );
    225222        }
    226223       
  • protocols/oscar/oscar.c

    ra4dc9f7 r8e419cb  
    608608                return;
    609609        }
    610         /* [WvG] Wheeeee! Who needs error checking anyway? ;-) */
    611610        read(pos->fd, m, 16);
    612611        m[16] = '\0';
  • protocols/oscar/rxqueue.c

    ra4dc9f7 r8e419cb  
    353353                return -1; /* its a aim_conn_close()'d connection */
    354354
    355         /* KIDS, THIS IS WHAT HAPPENS IF YOU USE CODE WRITTEN FOR GUIS IN A DAEMON!
    356            
    357            And wouldn't it make sense to return something that prevents this function
    358            from being called again IMMEDIATELY (and making the program suck up all
    359            CPU time)?...
    360            
    361         if (conn->fd < 3)
     355        if (conn->fd < 3)  /* can happen when people abuse the interface */
    362356                return 0;
    363         */
    364357
    365358        if (conn->status & AIM_CONN_STATUS_INPROGRESS)
  • protocols/oscar/service.c

    ra4dc9f7 r8e419cb  
    736736
    737737        tlvlen = aim_addtlvtochain32(&tl, 0x0006, data);
     738
     739        printf("%d\n", tlvlen);
    738740
    739741        if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 8)))
  • protocols/ssl_openssl.c

    ra4dc9f7 r8e419cb  
    55  \********************************************************************/
    66
    7 /* SSL module - OpenTLS version                                          */
     7/* SSL module - GnuTLS version                                          */
    88
    99/*
     
    4141struct scd
    4242{
    43         SslInputFunction func;
     43        ssl_input_function func;
    4444        gpointer data;
    4545        int fd;
    4646        gboolean established;
    4747       
     48        int inpa;
     49        int lasterr;            /* Necessary for SSL_get_error */
    4850        SSL *ssl;
    4951        SSL_CTX *ssl_ctx;
     
    5456
    5557
    56 void *ssl_connect( char *host, int port, SslInputFunction func, gpointer data )
     58void *ssl_connect( char *host, int port, ssl_input_function func, gpointer data )
    5759{
    5860        struct scd *conn = g_new0( struct scd, 1 );
     
    9395}
    9496
     97static void ssl_handshake( gpointer data, gint source, GaimInputCondition cond );
     98
    9599static void ssl_connected( gpointer data, gint source, GaimInputCondition cond )
    96100{
     
    98102       
    99103        if( source == -1 )
    100                 goto ssl_connected_failure;
    101        
     104                return ssl_handshake( data, -1, cond );
     105       
     106        /* Make it non-blocking at least during the handshake... */
     107        sock_make_nonblocking( conn->fd );
    102108        SSL_set_fd( conn->ssl, conn->fd );
    103109       
    104         if( SSL_connect( conn->ssl ) < 0 )
    105                 goto ssl_connected_failure;
     110        return ssl_handshake( data, source, cond );
     111}       
     112
     113static void ssl_handshake( gpointer data, gint source, GaimInputCondition cond )
     114{
     115        struct scd *conn = data;
     116        int st;
     117       
     118        if( conn->inpa != -1 )
     119        {
     120                gaim_input_remove( conn->inpa );
     121                conn->inpa = -1;
     122        }
     123       
     124        if( ( st = SSL_connect( conn->ssl ) ) < 0 )
     125        {
     126                conn->lasterr = SSL_get_error( conn->ssl, st );
     127                if( conn->lasterr != SSL_ERROR_WANT_READ && conn->lasterr != SSL_ERROR_WANT_WRITE )
     128                        goto ssl_connected_failure;
     129               
     130                conn->inpa = gaim_input_add( conn->fd, ssl_getdirection( conn ), ssl_handshake, data );
     131                return;
     132        }
    106133       
    107134        conn->established = TRUE;
     135        sock_make_blocking( conn->fd );         /* For now... */
    108136        conn->func( conn->data, conn, cond );
    109137        return;
     
    127155int ssl_read( void *conn, char *buf, int len )
    128156{
     157        int st;
     158       
    129159        if( !((struct scd*)conn)->established )
    130                 return( 0 );
    131        
    132         return( SSL_read( ((struct scd*)conn)->ssl, buf, len ) );
     160        {
     161                ssl_errno = SSL_NOHANDSHAKE;
     162                return -1;
     163        }
     164       
     165        st = SSL_read( ((struct scd*)conn)->ssl, buf, len );
     166       
     167        ssl_errno = SSL_OK;
     168        if( st <= 0 )
     169        {
     170                ((struct scd*)conn)->lasterr = SSL_get_error( ((struct scd*)conn)->ssl, st );
     171                if( ((struct scd*)conn)->lasterr == SSL_ERROR_WANT_READ || ((struct scd*)conn)->lasterr == SSL_ERROR_WANT_WRITE )
     172                        ssl_errno = SSL_AGAIN;
     173        }
     174       
     175        return st;
    133176}
    134177
    135178int ssl_write( void *conn, const char *buf, int len )
    136179{
     180        int st;
     181       
    137182        if( !((struct scd*)conn)->established )
    138                 return( 0 );
    139        
    140         return( SSL_write( ((struct scd*)conn)->ssl, buf, len ) );
     183        {
     184                ssl_errno = SSL_NOHANDSHAKE;
     185                return -1;
     186        }
     187       
     188        st = SSL_write( ((struct scd*)conn)->ssl, buf, len );
     189       
     190        ssl_errno = SSL_OK;
     191        if( st <= 0 )
     192        {
     193                ((struct scd*)conn)->lasterr = SSL_get_error( ((struct scd*)conn)->ssl, st );
     194                if( ((struct scd*)conn)->lasterr == SSL_ERROR_WANT_READ || ((struct scd*)conn)->lasterr == SSL_ERROR_WANT_WRITE )
     195                        ssl_errno = SSL_AGAIN;
     196        }
     197       
     198        return st;
    141199}
    142200
     
    144202{
    145203        struct scd *conn = conn_;
     204       
     205        if( conn->inpa != -1 )
     206                gaim_input_remove( conn->inpa );
    146207       
    147208        if( conn->established )
     
    159220        return( ((struct scd*)conn)->fd );
    160221}
     222
     223GaimInputCondition ssl_getdirection( void *conn )
     224{
     225        return( ((struct scd*)conn)->lasterr == SSL_ERROR_WANT_WRITE ? GAIM_INPUT_WRITE : GAIM_INPUT_READ );
     226}
  • protocols/yahoo/Makefile

    ra4dc9f7 r8e419cb  
    1010
    1111# [SH] Program variables
    12 objects = yahoo.o crypt.o libyahoo2.o yahoo_fn.o yahoo_httplib.o yahoo_util.o
     12objects = yahoo.o crypt.o libyahoo2.o yahoo_fn.o yahoo_httplib.o yahoo_list.o yahoo_util.o
    1313
    1414CFLAGS += -Wall -DSTDC_HEADERS -DHAVE_STRING_H -DHAVE_STRCHR -DHAVE_MEMCPY -DHAVE_GLIB
  • protocols/yahoo/yahoo.c

    ra4dc9f7 r8e419cb  
    189189{
    190190        struct byahoo_data *yd = (struct byahoo_data *) gc->proto_data;
    191        
     191
    192192        gc->away = NULL;
    193        
    194         if( msg )
     193
     194        if (msg)
    195195        {
    196196                yd->current_status = YAHOO_STATUS_CUSTOM;
    197197                gc->away = "";
    198198        }
    199         if( state )
     199        else if (state)
    200200        {
    201201                gc->away = "";
    202                 if( g_strcasecmp( state, "Available" ) == 0 )
     202                if( g_strcasecmp(state, "Available" ) == 0 )
    203203                {
    204204                        yd->current_status = YAHOO_STATUS_AVAILABLE;
     
    235235                }
    236236        }
    237         else if( gc->is_idle )
     237        else if ( gc->is_idle )
    238238                yd->current_status = YAHOO_STATUS_IDLE;
    239239        else
    240240                yd->current_status = YAHOO_STATUS_AVAILABLE;
    241241       
    242         if( yd->current_status == YAHOO_STATUS_INVISIBLE )
    243                 yahoo_set_away( yd->y2_id, yd->current_status, NULL, gc->away != NULL );
    244         else
    245                 yahoo_set_away( yd->y2_id, yd->current_status, msg, gc->away != NULL );
     242        yahoo_set_away( yd->y2_id, yd->current_status, msg, gc->away != NULL );
    246243}
    247244
  • protocols/yahoo/yahoo_list.h

    ra4dc9f7 r8e419cb  
    2121 */
    2222
     23/*
     24 * This is a replacement for the GList.  It only provides functions that
     25 * we use in Ayttm.  Thanks to Meredyyd from everybuddy dev for doing
     26 * most of it.
     27 */
     28
    2329#ifndef __YLIST_H__
    2430#define __YLIST_H__
    2531
    26 /* GLib has linked list already, so I don't see why libyahoo2 has to copy this... */
     32#ifdef __cplusplus
     33extern "C" {
     34#endif
    2735
    28 typedef GList YList;
     36typedef struct _YList {
     37        struct _YList *next;
     38        struct _YList *prev;
     39        void *data;
     40} YList;
    2941
    30 #define y_list_append g_list_append
    31 #define y_list_concat g_list_concat
    32 #define y_list_copy g_list_copy
    33 #define y_list_empty g_list_empty
    34 #define y_list_find g_list_find
    35 #define y_list_find_custom g_list_find_custom
    36 #define y_list_foreach g_list_foreach
    37 #define y_list_free g_list_free
    38 #define y_list_free_1 g_list_free_1
    39 #define y_list_insert_sorted g_list_insert_sorted
    40 #define y_list_length g_list_length
    41 #define y_list_next g_list_next
    42 #define y_list_nth g_list_nth
    43 #define y_list_prepend g_list_prepend
    44 #define y_list_remove g_list_remove
    45 #define y_list_remove_link g_list_remove_link
    46 #define y_list_singleton g_list_singleton
     42typedef int (*YListCompFunc) (const void *, const void *);
     43typedef void (*YListFunc) (void *, void *);
    4744
     45YList *y_list_append(YList * list, void *data);
     46YList *y_list_prepend(YList * list, void *data);
     47YList *y_list_remove_link(YList * list, const YList * link);
     48YList *y_list_remove(YList * list, void *data);
     49
     50YList *y_list_insert_sorted(YList * list, void * data, YListCompFunc comp);
     51
     52YList *y_list_copy(YList * list);
     53
     54YList *y_list_concat(YList * list, YList * add);
     55
     56YList *y_list_find(YList * list, const void *data);
     57YList *y_list_find_custom(YList * list, const void *data, YListCompFunc comp);
     58
     59YList *y_list_nth(YList * list, int n);
     60
     61void y_list_foreach(YList * list, YListFunc fn, void *user_data);
     62
     63void y_list_free_1(YList * list);
     64void y_list_free(YList * list);
     65int  y_list_length(const YList * list);
     66int  y_list_empty(const YList * list);
     67int  y_list_singleton(const YList * list);
     68
     69#define y_list_next(list)       list->next
     70
     71#ifdef __cplusplus
     72}
    4873#endif
     74#endif
  • unix.c

    ra4dc9f7 r8e419cb  
    2929#include "protocols/nogaim.h"
    3030#include "help.h"
    31 #include "ipc.h"
    3231#include <signal.h>
    3332#include <unistd.h>
     
    3938static void sighandler( int signal );
    4039
    41 int main( int argc, char *argv[], char **envp )
     40int main( int argc, char *argv[] )
    4241{
    4342        int i = 0;
    44         char *old_cwd = NULL;
    4543        struct sigaction sig, old;
    4644       
     
    8179        else if( global.conf->runmode == RUNMODE_FORKDAEMON )
    8280        {
    83                 /* In case the operator requests a restart, we need this. */
    84                 old_cwd = g_malloc( 256 );
    85                 if( getcwd( old_cwd, 255 ) == NULL )
    86                 {
    87                         log_message( LOGLVL_WARNING, "Could not save current directory: %s", strerror( errno ) );
    88                         g_free( old_cwd );
    89                         old_cwd = NULL;
    90                 }
    91                
    9281                i = bitlbee_daemon_init();
    9382                log_message( LOGLVL_INFO, "Bitlbee %s starting in forking daemon mode.", BITLBEE_VERSION );
     
    124113       
    125114        g_main_run( global.loop );
    126        
    127         if( global.restart )
    128         {
    129                 char *fn = ipc_master_save_state();
    130                 char **args;
    131                 int n, i;
    132                
    133                 chdir( old_cwd );
    134                
    135                 n = 0;
    136                 args = g_new0( char *, argc + 3 );
    137                 args[n++] = argv[0];
    138                 if( fn )
    139                 {
    140                         args[n++] = "-R";
    141                         args[n++] = fn;
    142                 }
    143                 for( i = 1; argv[i] && i < argc; i ++ )
    144                 {
    145                         if( strcmp( argv[i], "-R" ) == 0 )
    146                                 i += 2;
    147                        
    148                         args[n++] = argv[i];
    149                 }
    150                
    151                 close( global.listen_socket );
    152                
    153                 execve( args[0], args, envp );
    154         }
    155115       
    156116        return( 0 );
  • url.c

    ra4dc9f7 r8e419cb  
    4040        else
    4141        {
    42                 if( g_strncasecmp( set_url, "http", i - set_url ) == 0 )
     42                if( g_strncasecmp( set_url, "https", i - set_url ) == 0 )
     43                        url->proto = PROTO_HTTPS;
     44                else if( g_strncasecmp( set_url, "http", i - set_url ) == 0 )
    4345                        url->proto = PROTO_HTTP;
    44                 else if( g_strncasecmp( set_url, "https", i - set_url ) == 0 )
    45                         url->proto = PROTO_HTTPS;
    4646                else if( g_strncasecmp( set_url, "socks4", i - set_url ) == 0 )
    4747                        url->proto = PROTO_SOCKS4;
  • user.h

    ra4dc9f7 r8e419cb  
    4545        int sendbuf_flags;
    4646       
    47         void (*send_handler) ( irc_t *irc, struct __USER *u, char *msg, int flags );
     47        int (*send_handler) ( irc_t *irc, struct __USER *u, char *msg, int flags );
    4848       
    4949        struct __USER *next;
Note: See TracChangeset for help on using the changeset viewer.