Changeset a4dc9f7 for irc.c


Ignore:
Timestamp:
2006-03-01T22:48:37Z (18 years ago)
Author:
Jelmer Vernooij <jelmer@…>
Branches:
master
Children:
46ad029
Parents:
8e419cb (diff), 9a1555d (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

[merge] Wilmer

File:
1 edited

Legend:

Unmodified
Added
Removed
  • irc.c

    r8e419cb ra4dc9f7  
    2727#include "bitlbee.h"
    2828#include "crypting.h"
     29#include "ipc.h"
    2930
    3031static gboolean irc_userping( gpointer _irc );
     
    151152}
    152153
     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. */
     157void 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
    153201static gboolean irc_free_userhash( gpointer key, gpointer value, gpointer data )
    154202{
     
    172220                if( storage_save( irc, TRUE ) != STORAGE_OK )
    173221                        irc_usermsg( irc, "Error while saving settings!" );
     222       
     223        closesocket( irc->fd );
    174224       
    175225        if( irc->ping_source_id > 0 )
     
    291341}
    292342
    293 int irc_process( irc_t *irc )
    294 {
    295         char **lines, *temp;   
     343void irc_process( irc_t *irc )
     344{
     345        char **lines, *temp, **cmd;
    296346        int i;
    297347
    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 ) {
     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                        {
    302356                                temp = g_strdup( lines[i] );
    303357                                g_free( irc->readbuffer );
    304358                                irc->readbuffer = temp;
    305                                 i++;
     359                                i ++;
    306360                                break;
    307361                        }                       
    308                         if (!irc_process_line(irc, lines[i])) {
     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                        {
    309372                                g_free( lines );
    310                                 return 0;
     373                                return;
    311374                        }
    312375                }
    313                 if(lines[i]!=NULL) {
    314                         g_free(irc->readbuffer);
    315                         irc->readbuffer=NULL;   
    316                 }
     376               
     377                if( lines[i] != NULL )
     378                {
     379                        g_free( irc->readbuffer );
     380                        irc->readbuffer = NULL;
     381                }
     382               
    317383                g_free( lines );
    318384        }
    319         return 1;       
    320385}
    321386
     
    326391
    327392        /* Count the number of elements we're gonna need. */
    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++;
     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 ++;
    332398        }
    333399       
    334400        /* Allocate j+1 elements. */
    335         lines=g_new (char *, j+1);
     401        lines = g_new( char *, j + 1 );
    336402       
    337403        /* NULL terminate our list. */
    338         lines[j]=NULL;
    339        
    340         lines[0]=buffer;
     404        lines[j] = NULL;
     405       
     406        lines[0] = buffer;
    341407       
    342408        /* Split the buffer in several strings, using \r\n as our seperator, where \r is optional.
    343409         * Although this is not in the RFC, some braindead ircds (newnet's) use this, so some clients might too.
    344410         */
    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 
    363 int irc_process_line( irc_t *irc, char *line )
     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
     427char **irc_parse_line( char *line )
    364428{
    365429        int i, j;
     
    367431       
    368432        /* Move the line pointer to the start of the command, skipping spaces and the optional prefix. */
    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 
     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       
    376441        /* If we're already at the end of the line, return. If not, we're going to need at least one element. */
    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                 }
     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 ++;
    390452                       
     453                        if( line[i+1] == ':' )
     454                                break;
     455                }
    391456        }       
    392457
    393458        /* Allocate the space we need. */
    394         cmd=g_new(char *, j+1);
    395         cmd[j]=NULL;
     459        cmd = g_new( char *, j + 1 );
     460        cmd[j] = NULL;
    396461       
    397462        /* Do the actual line splitting, format is:
     
    400465         */
    401466
    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 
    421 int 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] )
     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;
     474                       
     475                        if( line[i+1] == ':' )
    430476                        {
    431                                 irc_reply( irc, 461, "%s :Need more parameters", cmd[0] );
     477                                cmd[j] ++;
     478                                break;
    432479                        }
    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 );
    565                        
    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] )
    767                                 break;
    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 );
     480                }
     481        }
     482       
     483        return cmd;
     484}
     485
     486char *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;
    884515}
    885516
     
    1040671}
    1041672
    1042 void 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:"**" );
     673int 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        }
    1071693}
    1072694
     
    1103725        u->realname = g_strdup( irc->realname );
    1104726        u->online = 1;
    1105 //      u->send_handler = msg_echo;
    1106727        irc_spawn( irc, u );
    1107728       
    1108729        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 );
    1109733       
    1110734        irc->status = USTATUS_LOGGED_IN;
     
    1159783                }
    1160784                irc_reply( irc, 376, ":End of MOTD" );
    1161                 closesocket( fd );
     785                close( fd );
    1162786        }
    1163787}
     
    1180804}
    1181805
    1182 void 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 
    1210806void irc_umode_set( irc_t *irc, char *s, int allow_priv )
    1211807{
     
    1237833}
    1238834
    1239 int 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 
    1280835void irc_spawn( irc_t *irc, user_t *u )
    1281836{
     
    1329884        }
    1330885        g_free( nick );
    1331 }
    1332 
    1333 void 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 );
    1347886}
    1348887
     
    1435974               
    1436975                if( u->send_handler )
    1437                         return( u->send_handler( irc, u, s, flags ) );
     976                {
     977                        u->send_handler( irc, u, s, flags );
     978                        return 1;
     979                }
    1438980        }
    1439981        else if( c && c->gc && c->gc->prpl )
     
    14611003}
    14621004
    1463 int buddy_send_handler( irc_t *irc, user_t *u, char *msg, int flags )
    1464 {
    1465         if( !u || !u->gc ) return( 0 );
     1005void buddy_send_handler( irc_t *irc, user_t *u, char *msg, int flags )
     1006{
     1007        if( !u || !u->gc ) return;
    14661008       
    14671009        if( set_getint( irc, "buddy_sendbuffer" ) && set_getint( irc, "buddy_sendbuffer_delay" ) > 0 )
     
    14991041                        g_source_remove( u->sendbuf_timer );
    15001042                u->sendbuf_timer = g_timeout_add( delay, buddy_send_handler_delayed, u );
    1501                
    1502                 return( 1 );
    15031043        }
    15041044        else
    15051045        {
    1506                 return( serv_send_im( irc, u, msg, flags ) );
     1046                serv_send_im( irc, u, msg, flags );
    15071047        }
    15081048}
     
    16091149        if( rv > 0 )
    16101150        {
    1611                 irc_write( irc, "ERROR :Closing Link: Ping Timeout: %d seconds", rv );
    1612                 irc_free( irc );
     1151                irc_abort( irc, 0, "Ping Timeout: %d seconds", rv );
    16131152                return FALSE;
    16141153        }
Note: See TracChangeset for help on using the changeset viewer.