Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • irc.c

    rc1826c6 r74c119d  
    151151}
    152152
    153 void irc_abort( irc_t *irc )
    154 {
    155         irc->status = USTATUS_SHUTDOWN;
    156         if( irc->sendbuffer )
    157         {
    158                 g_source_remove( irc->r_watch_source_id );
    159                 irc->r_watch_source_id = g_timeout_add_full( G_PRIORITY_HIGH, 1000, (GSourceFunc) irc_free, irc, NULL );
    160         }
    161         else
    162         {
    163                 irc_free( irc );
    164         }
    165 }
    166 
    167153static gboolean irc_free_userhash( gpointer key, gpointer value, gpointer data )
    168154{
     
    173159
    174160/* Because we have no garbage collection, this is quite annoying */
    175 void irc_free( irc_t * irc )
     161void irc_free(irc_t * irc)
    176162{
    177163        account_t *account, *accounttmp;
     
    307293int irc_process( irc_t *irc )
    308294{
    309         char **lines, *temp;   
     295        char **lines, *temp, **cmd;
    310296        int i;
    311297
    312         if( irc->readbuffer != NULL ) {
    313                 lines = irc_tokenize(irc->readbuffer );
    314                 for( i = 0; *lines[i] != '\0'; i++ ) {
    315                         if( lines[i+1] == NULL ) {
     298        if( irc->readbuffer != NULL )
     299        {
     300                lines = irc_tokenize( irc->readbuffer );
     301               
     302                for( i = 0; *lines[i] != '\0'; i ++ )
     303                {
     304                        if( lines[i+1] == NULL )
     305                        {
    316306                                temp = g_strdup( lines[i] );
    317307                                g_free( irc->readbuffer );
    318308                                irc->readbuffer = temp;
    319                                 i++;
     309                                i ++;
    320310                                break;
    321311                        }                       
    322                         if (!irc_process_line(irc, lines[i])) {
     312                       
     313                        if( ( cmd = irc_parse_line( lines[i] ) ) == NULL )
     314                                continue;
     315                        if( !irc_exec( irc, cmd ) )
     316                        {
     317                                g_free( cmd );
    323318                                g_free( lines );
    324319                                return 0;
    325320                        }
    326                 }
    327                 if(lines[i]!=NULL) {
    328                         g_free(irc->readbuffer);
    329                         irc->readbuffer=NULL;   
    330                 }
     321                       
     322                        g_free( cmd );
     323                }
     324               
     325                if( lines[i] != NULL )
     326                {
     327                        g_free( irc->readbuffer );
     328                        irc->readbuffer = NULL;
     329                }
     330               
    331331                g_free( lines );
    332332        }
     333       
    333334        return 1;       
    334335}
     
    340341
    341342        /* Count the number of elements we're gonna need. */
    342         for(i=0, j=1; buffer[i]!='\0'; i++ ) {
    343                 if(buffer[i]=='\n' )
    344                         if(buffer[i+1]!='\r' && buffer[i+1]!='\n')
    345                                 j++;
     343        for( i = 0, j = 1; buffer[i] != '\0'; i ++ )
     344        {
     345                if( buffer[i] == '\n' )
     346                        if( buffer[i+1] != '\r' && buffer[i+1] != '\n' )
     347                                j ++;
    346348        }
    347349       
    348350        /* Allocate j+1 elements. */
    349         lines=g_new (char *, j+1);
     351        lines = g_new( char *, j + 1 );
    350352       
    351353        /* NULL terminate our list. */
    352         lines[j]=NULL;
    353        
    354         lines[0]=buffer;
     354        lines[j] = NULL;
     355       
     356        lines[0] = buffer;
    355357       
    356358        /* Split the buffer in several strings, using \r\n as our seperator, where \r is optional.
    357359         * Although this is not in the RFC, some braindead ircds (newnet's) use this, so some clients might too.
    358360         */
    359         for( i=0, j=0; buffer[i]!='\0'; i++) {
    360                 if(buffer[i]=='\n') {
    361                         buffer[i]='\0';
    362 
    363                         /* We dont want to read 1 byte before our buffer
    364                          * and (in rare cases) generate a SIGSEGV.
    365                          */
    366                         if(i!=0)
    367                                 if(buffer[i-1]=='\r')
    368                                         buffer[i-1]='\0';
    369                         if(buffer[i+1]!='\r'&&buffer[i+1]!='\n')
    370                                 lines[++j]=buffer+i+1;
    371                 }
    372         }
    373 
    374         return(lines);
    375 }
    376 
    377 int irc_process_line( irc_t *irc, char *line )
     361        for( i = 0, j = 0; buffer[i] != '\0'; i ++)
     362        {
     363                if( buffer[i] == '\n' )
     364                {
     365                        buffer[i] = '\0';
     366                       
     367                        if( i > 0 && buffer[i-1] == '\r' )
     368                                buffer[i-1] = '\0';
     369                        if( buffer[i+1] != '\r' && buffer[i+1] != '\n' )
     370                                lines[++j] = buffer + i + 1;
     371                }
     372        }
     373       
     374        return( lines );
     375}
     376
     377char **irc_parse_line( char *line )
    378378{
    379379        int i, j;
     
    381381       
    382382        /* Move the line pointer to the start of the command, skipping spaces and the optional prefix. */
    383         if(line[0]==':') {
    384                 for(i=0; line[i]!=32; i++);
    385                 line=line+i;
    386         }
    387         for(i=0; line[i]==32; i++);
    388         line=line+i;
    389 
     383        if( line[0] == ':' )
     384        {
     385                for( i = 0; line[i] != ' '; i ++ );
     386                line = line + i;
     387        }
     388        for( i = 0; line[i] == ' '; i ++ );
     389        line = line + i;
     390       
    390391        /* If we're already at the end of the line, return. If not, we're going to need at least one element. */
    391         if(line[0]=='\0')
    392                 return 1;
    393         else
    394                 j=1;   
    395        
    396         /* Count the number of char **cmd elements we're going to need. */     
    397         for(i=0; line[i]!='\0'; i++) {
    398                 if((line[i]==32) && (line[i+1]!=32) && (line[i+1]!='\0') && (line[i+1]!=':'))           
    399                         j++;
    400                 else if((line[i]==':') && (line[i+1]!='\0') && (line[i-1]==32)) {
    401                         j++;
    402                         break;
    403                 }
     392        if( line[0] == '\0')
     393                return NULL;
     394       
     395        /* Count the number of char **cmd elements we're going to need. */
     396        j = 1;
     397        for( i = 0; line[i] != '\0'; i ++ )
     398        {
     399                if( line[i] == ' ' )
     400                {
     401                        j ++;
    404402                       
     403                        if( line[i+1] == ':' )
     404                                break;
     405                }
    405406        }       
    406407
    407408        /* Allocate the space we need. */
    408         cmd=g_new(char *, j+1);
    409         cmd[j]=NULL;
     409        cmd = g_new( char *, j + 1 );
     410        cmd[j] = NULL;
    410411       
    411412        /* Do the actual line splitting, format is:
     
    414415         */
    415416
    416         cmd[0]=line;
    417         for(i=0, j=0; line[i]!='\0'; i++) {
    418                 if((line[i]==32)) {
    419                         line[i]='\0';
    420                         if((line[i+1]!=32) && (line[i+1]!='\0') && (line[i+1]!=':'))           
    421                                 cmd[++j]=line+i+1;
    422                 }
    423                 else if((line[i]==':') && (line[i+1]!='\0') && (line[i-1]=='\0')) {
    424                         cmd[++j]=line+i+1;
    425                         break;
    426                 }
    427         }
    428        
    429         i=irc_exec(irc, cmd);
    430         g_free(cmd);
    431 
    432         return(i);     
    433 }
    434 
    435 int irc_exec( irc_t *irc, char **cmd )
    436 {       
    437         int i;
    438 
    439         if( (global.conf)->authmode == AUTHMODE_CLOSED && irc->status < USTATUS_AUTHORIZED )
    440         {
    441                 if( g_strcasecmp( cmd[0], "PASS" ) == 0 )
    442                 {
    443                         if( !cmd[1] )
     417        cmd[0] = line;
     418        for( i = 0, j = 0; line[i] != '\0'; i ++ )
     419        {
     420                if( line[i] == ' ' )
     421                {
     422                        line[i] = '\0';
     423                        cmd[++j] = line + i + 1;
     424                       
     425                        if( line[i+1] == ':' )
    444426                        {
    445                                 irc_reply( irc, 461, "%s :Need more parameters", cmd[0] );
     427                                cmd[j] ++;
     428                                break;
    446429                        }
    447                         else if( strcmp( cmd[1], (global.conf)->auth_pass ) == 0 )
    448                         {
    449                                 irc->status = USTATUS_AUTHORIZED;
    450                         }
    451                         else
    452                         {
    453                                 irc_reply( irc, 464, ":Nope, maybe you should try it again..." );
    454                         }
    455                 }
    456                 else
    457                 {
    458                         irc_reply( irc, 464, ":Uhh, fine, but I want the password first." );
    459                 }
    460                
    461                 return( 1 );
    462         }
    463        
    464         if( g_strcasecmp( cmd[0], "USER" ) == 0 )
    465         {
    466                 if( !( cmd[1] && cmd[2] && cmd[3] && cmd[4] ) )
    467                 {
    468                         irc_reply( irc, 461, "%s :Need more parameters", cmd[0] );
    469                 }
    470                 else if( irc->user )
    471                 {
    472                         irc_reply( irc, 462, ":You can't change your nick/userinfo" );
    473                 }
    474                 else
    475                 {
    476                         irc->user = g_strdup( cmd[1] );
    477                         irc->realname = g_strdup( cmd[4] );
    478                         if( irc->nick ) irc_login( irc );
    479                 }
    480                 return( 1 );
    481         }
    482         else if( g_strcasecmp( cmd[0], "NICK" ) == 0 )
    483         {
    484                 if( !cmd[1] )
    485                 {
    486                         irc_reply( irc, 461, "%s :Need more parameters", cmd[0] );
    487                 }
    488                 else if( irc->nick )
    489                 {
    490                         irc_reply( irc, 438, ":The hand of the deity is upon thee, thy nick may not change" );
    491                 }
    492                 /* This is not clean, but for now it'll have to be like this... */
    493                 else if( ( nick_cmp( cmd[1], irc->mynick ) == 0 ) || ( nick_cmp( cmd[1], NS_NICK ) == 0 ) )
    494                 {
    495                         irc_reply( irc, 433, ":This nick is already in use" );
    496                 }
    497                 else if( !nick_ok( cmd[1] ) )
    498                 {
    499                         /* [SH] Invalid characters. */
    500                         irc_reply( irc, 432, ":This nick contains invalid characters" );
    501                 }
    502                 else
    503                 {
    504                         irc->nick = g_strdup( cmd[1] );
    505                         if( irc->user ) irc_login( irc );
    506                 }
    507                 return( 1 );
    508         }
    509         else if( g_strcasecmp( cmd[0], "QUIT" ) == 0 )
    510         {
    511                 irc_write( irc, "ERROR :%s%s", cmd[1]?"Quit: ":"", cmd[1]?cmd[1]:"Client Quit" );
    512                 /* g_io_channel_close( irc->io_channel ); */
    513                 return( 0 );
    514         }
    515        
    516         if( !irc->user || !irc->nick )
    517         {
    518                 irc_reply( irc, 451, ":Register first" );
    519                 return( 1 );
    520         }
    521        
    522         if( g_strcasecmp( cmd[0], "PING" ) == 0 )
    523         {
    524                 irc_write( irc, ":%s PONG %s :%s", irc->myhost, irc->myhost, cmd[1]?cmd[1]:irc->myhost );
    525         }
    526         else if( g_strcasecmp( cmd[0], "OPER" ) == 0 )
    527         {
    528                 if( !cmd[2] )
    529                         irc_reply( irc, 461, "%s :Need more parameters", cmd[0] );
    530                 else if( strcmp( cmd[2], global.conf->oper_pass ) == 0 )
    531                         irc_umode_set( irc, "+o", 1 );
    532                 // else
    533                         /* FIXME/TODO: Find out which reply to send now. */
    534         }
    535         else if( g_strcasecmp( cmd[0], "MODE" ) == 0 )
    536         {
    537                 if( !cmd[1] )
    538                 {
    539                         irc_reply( irc, 461, "%s :Need more parameters", cmd[0] );
    540                 }
    541                 else if( *cmd[1] == '#' || *cmd[1] == '&' )
    542                 {
    543                         if( cmd[2] )
    544                         {
    545                                 if( *cmd[2] == '+' || *cmd[2] == '-' )
    546                                         irc_reply( irc, 477, "%s :Can't change channel modes", cmd[1] );
    547                                 else if( *cmd[2] == 'b' )
    548                                         irc_reply( irc, 368, "%s :No bans possible", cmd[1] );
    549                         }
    550                         else
    551                                 irc_reply( irc, 324, "%s +%s", cmd[1], CMODE );
    552                 }
    553                 else
    554                 {
    555                         if( nick_cmp( cmd[1], irc->nick ) == 0 )
    556                         {
    557                                 if( cmd[2] )
    558                                         irc_umode_set( irc, cmd[2], 0 );
    559                         }
    560                         else
    561                                 irc_reply( irc, 502, ":Don't touch their modes" );
    562                 }
    563         }
    564         else if( g_strcasecmp( cmd[0], "NAMES" ) == 0 )
    565         {
    566                 irc_names( irc, cmd[1]?cmd[1]:irc->channel );
    567         }
    568         else if( g_strcasecmp( cmd[0], "PART" ) == 0 )
    569         {
    570                 struct conversation *c;
    571                
    572                 if( !cmd[1] )
    573                 {
    574                         irc_reply( irc, 461, "%s :Need more parameters", cmd[0] );
    575                 }
    576                 else if( g_strcasecmp( cmd[1], irc->channel ) == 0 )
    577                 {
    578                         user_t *u = user_find( irc, irc->nick );
    579                        
    580                         /* Not allowed to leave control channel */
    581                         irc_part( irc, u, irc->channel );
    582                         irc_join( irc, u, irc->channel );
    583                 }
    584                 else if( ( c = conv_findchannel( cmd[1] ) ) )
    585                 {
    586                         user_t *u = user_find( irc, irc->nick );
    587                        
    588                         irc_part( irc, u, c->channel );
    589                        
    590                         if( c->gc && c->gc->prpl )
    591                         {
    592                                 c->joined = 0;
    593                                 c->gc->prpl->chat_leave( c->gc, c->id );
    594                         }
    595                 }
    596                 else
    597                 {
    598                         irc_reply( irc, 403, "%s :No such channel", cmd[1] );
    599                 }
    600         }
    601         else if( g_strcasecmp( cmd[0], "JOIN" ) == 0 )
    602         {
    603                 if( !cmd[1] )
    604                 {
    605                         irc_reply( irc, 461, "%s :Need more parameters", cmd[0] );
    606                 }
    607                 else if( g_strcasecmp( cmd[1], irc->channel ) == 0 )
    608                         ; /* Dude, you're already there...
    609                              RFC doesn't have any reply for that though? */
    610                 else if( cmd[1] )
    611                 {
    612                         if( ( cmd[1][0] == '#' || cmd[1][0] == '&' ) && cmd[1][1] )
    613                         {
    614                                 user_t *u = user_find( irc, cmd[1] + 1 );
    615                                
    616                                 if( u && u->gc && u->gc->prpl && u->gc->prpl->chat_open )
    617                                 {
    618                                         irc_reply( irc, 403, "%s :Initializing groupchat in a different channel", cmd[1] );
    619                                        
    620                                         if( !u->gc->prpl->chat_open( u->gc, u->handle ) )
    621                                         {
    622                                                 irc_usermsg( irc, "Could not open a groupchat with %s, maybe you don't have a connection to him/her yet?", u->nick );
    623                                         }
    624                                 }
    625                                 else
    626                                 {
    627                                         irc_reply( irc, 403, "%s :Groupchats are not possible with %s", cmd[1], cmd[1]+1 );
    628                                 }
    629                         }
    630                         else
    631                         {
    632                                 irc_reply( irc, 403, "%s :No such channel", cmd[1] );
    633                         }
    634                 }
    635         }
    636         else if( g_strcasecmp( cmd[0], "INVITE" ) == 0 )
    637         {
    638                 if( cmd[1] && cmd[2] )
    639                         irc_invite( irc, cmd[1], cmd[2] );
    640                 else
    641                         irc_reply( irc, 461, "%s :Need more parameters", cmd[0] );
    642         }
    643         else if( g_strcasecmp( cmd[0], "PRIVMSG" ) == 0 || g_strcasecmp( cmd[0], "NOTICE" ) == 0 )
    644         {
    645                 if( !cmd[1] )
    646                 {
    647                         irc_reply( irc, 461, "%s :Need more parameters", cmd[0] );
    648                 }
    649                 else if ( !cmd[2] )
    650                 {
    651                         irc_reply( irc, 412, ":No text to send" );
    652                 }
    653                 else if ( irc->nick && g_strcasecmp( cmd[1], irc->nick ) == 0 )
    654                 {
    655                         irc_write( irc, ":%s!%s@%s %s %s :%s", irc->nick, irc->user, irc->host, cmd[0], cmd[1], cmd[2] );
    656                 }
    657                 else
    658                 {
    659                         if( g_strcasecmp( cmd[1], irc->channel ) == 0 )
    660                         {
    661                                 unsigned int i;
    662                                 char *t = set_getstr( irc, "default_target" );
    663                                
    664                                 if( g_strcasecmp( t, "last" ) == 0 && irc->last_target )
    665                                         cmd[1] = irc->last_target;
    666                                 else if( g_strcasecmp( t, "root" ) == 0 )
    667                                         cmd[1] = irc->mynick;
    668                                
    669                                 for( i = 0; i < strlen( cmd[2] ); i ++ )
    670                                 {
    671                                         if( cmd[2][i] == ' ' ) break;
    672                                         if( cmd[2][i] == ':' || cmd[2][i] == ',' )
    673                                         {
    674                                                 cmd[1] = cmd[2];
    675                                                 cmd[2] += i;
    676                                                 *cmd[2] = 0;
    677                                                 while( *(++cmd[2]) == ' ' );
    678                                                 break;
    679                                         }
    680                                 }
    681                                
    682                                 irc->is_private = 0;
    683                                
    684                                 if( cmd[1] != irc->last_target )
    685                                 {
    686                                         if( irc->last_target )
    687                                                 g_free( irc->last_target );
    688                                         irc->last_target = g_strdup( cmd[1] );
    689                                 }
    690                         }
    691                         else
    692                         {
    693                                 irc->is_private = 1;
    694                         }
    695                         irc_send( irc, cmd[1], cmd[2], ( g_strcasecmp( cmd[0], "NOTICE" ) == 0 ) ? IM_FLAG_AWAY : 0 );
    696                 }
    697         }
    698         else if( g_strcasecmp( cmd[0], "WHO" ) == 0 )
    699         {
    700                 irc_who( irc, cmd[1] );
    701         }
    702         else if( g_strcasecmp( cmd[0], "USERHOST" ) == 0 )
    703         {
    704                 user_t *u;
    705                
    706                 if( !cmd[1] )
    707                 {
    708                         irc_reply( irc, 461, "%s :Need more parameters", cmd[0] );
    709                 }
    710                 /* [TV] Usable USERHOST-implementation according to
    711                         RFC1459. Without this, mIRC shows an error
    712                         while connecting, and the used way of rejecting
    713                         breaks standards.
    714                 */
    715                
    716                 for( i = 1; cmd[i]; i ++ )
    717                         if( ( u = user_find( irc, cmd[i] ) ) )
    718                         {
    719                                 if( u->online && u->away )
    720                                         irc_reply( irc, 302, ":%s=-%s@%s", u->nick, u->user, u->host );
    721                                 else
    722                                         irc_reply( irc, 302, ":%s=+%s@%s", u->nick, u->user, u->host );
    723                         }
    724         }
    725         else if( g_strcasecmp( cmd[0], "ISON" ) == 0 )
    726         {
    727                 user_t *u;
    728                 char buff[IRC_MAX_LINE];
    729                 int lenleft;
    730                
    731                 buff[0] = '\0';
    732                
    733                 /* [SH] Leave room for : and \0 */
    734                 lenleft = IRC_MAX_LINE - 2;
    735                
    736                 for( i = 1; cmd[i]; i ++ )
    737                 {
    738                         if( ( u = user_find( irc, cmd[i] ) ) && u->online )
    739                         {
    740                                 /* [SH] Make sure we don't use too much buffer space. */
    741                                 lenleft -= strlen( u->nick ) + 1;
    742                                
    743                                 if( lenleft < 0 )
    744                                 {
    745                                         break;
    746                                 }
    747                                
    748                                 /* [SH] Add the nick to the buffer. Note
    749                                  * that an extra space is always added. Even
    750                                  * if it's the last nick in the list. Who
    751                                  * cares?
    752                                  */
    753                                
    754                                 strcat( buff, u->nick );
    755                                 strcat( buff, " " );
    756                         }
    757                 }
    758                
    759                 /* [WvG] Well, maybe someone cares, so why not remove it? */
    760                 if( strlen( buff ) > 0 )
    761                         buff[strlen(buff)-1] = '\0';
    762                
    763                 /* [SH] By the way, that really *was* WvG talking. */
    764                 /* [WvG] Really? */
    765                 /* [SH] Yeah... But *this* is WvG talking too. ;-P */
    766                 /* [WvG] *sigh* */
    767                
    768                 irc_reply( irc, 303, ":%s", buff );
    769         }
    770         else if( g_strcasecmp( cmd[0], "WATCH" ) == 0 )
    771         {
    772                 /* Obviously we could also mark a user structure as being
    773                    watched, but what if the WATCH command is sent right
    774                    after connecting? The user won't exist yet then... */
    775                 for( i = 1; cmd[i]; i ++ )
    776                 {
    777                         char *nick;
    778                         user_t *u;
    779                        
    780                         if( !cmd[i][0] || !cmd[i][1] )
    781                                 break;
    782                        
    783                         nick = g_strdup( cmd[i] + 1 );
    784                         nick_lc( nick );
    785                        
    786                         u = user_find( irc, nick );
    787                        
    788                         if( cmd[i][0] == '+' )
    789                         {
    790                                 if( !g_hash_table_lookup( irc->watches, nick ) )
    791                                         g_hash_table_insert( irc->watches, nick, nick );
    792                                
    793                                 if( u && u->online )
    794                                         irc_reply( irc, 604, "%s %s %s %d :%s", u->nick, u->user, u->host, time( NULL ), "is online" );
    795                                 else
    796                                         irc_reply( irc, 605, "%s %s %s %d :%s", nick, "*", "*", time( NULL ), "is offline" );
    797                         }
    798                         else if( cmd[i][0] == '-' )
    799                         {
    800                                 gpointer okey, ovalue;
    801                                
    802                                 if( g_hash_table_lookup_extended( irc->watches, nick, &okey, &ovalue ) )
    803                                 {
    804                                         g_free( okey );
    805                                         g_hash_table_remove( irc->watches, okey );
    806                                        
    807                                         irc_reply( irc, 602, "%s %s %s %d :%s", nick, "*", "*", 0, "Stopped watching" );
    808                                 }
    809                         }
    810                 }
    811         }
    812         else if( g_strcasecmp( cmd[0], "TOPIC" ) == 0 )
    813         {
    814                 if( cmd[1] && cmd[2] )
    815                         irc_reply( irc, 482, "%s :Cannot change topic", cmd[1] );
    816                 else if( cmd[1] )
    817                         irc_topic( irc, cmd[1] );
    818                 else
    819                         irc_reply( irc, 461, "%s :Need more parameters", cmd[0] );
    820         }
    821         else if( g_strcasecmp( cmd[0], "AWAY" ) == 0 )
    822         {
    823                 irc_away( irc, cmd[1] );
    824         }
    825         else if( g_strcasecmp( cmd[0], "WHOIS" ) == 0 )
    826         {
    827                 if( cmd[1] )
    828                 {
    829                         irc_whois( irc, cmd[1] );
    830                 }
    831                 else
    832                 {
    833                         irc_reply( irc, 461, "%s :Need more parameters", cmd[0] );
    834                 }
    835         }
    836         else if( g_strcasecmp( cmd[0], "WHOWAS" ) == 0 )
    837         {
    838                 /* For some reason irssi tries a whowas when whois fails. We can
    839                    ignore this, but then the user never gets a "user not found"
    840                    message from irssi which is a bit annoying. So just respond
    841                    with not-found and irssi users will get better error messages */
    842                
    843                 if( cmd[1] )
    844                 {
    845                         irc_reply( irc, 406, "%s :Nick does not exist", cmd[1] );
    846                         irc_reply( irc, 369, "%s :End of WHOWAS", cmd[1] );
    847                 }
    848                 else
    849                 {
    850                         irc_reply( irc, 461, "%s :Need more parameters", cmd[0] );
    851                 }
    852         }
    853         else if( ( g_strcasecmp( cmd[0], "NICKSERV" ) == 0 ) || ( g_strcasecmp( cmd[0], "NS" ) == 0 ) )
    854         {
    855                 /* [SH] This aliases the NickServ command to PRIVMSG root */
    856                 /* [TV] This aliases the NS command to PRIVMSG root as well */
    857                 root_command( irc, cmd + 1 );
    858         }
    859         else if( g_strcasecmp( cmd[0], "MOTD" ) == 0 )
    860         {
    861                 irc_motd( irc );
    862         }
    863         else if( g_strcasecmp( cmd[0], "PONG" ) == 0 )
    864         {
    865                 /* We could check the value we get back from the user, but in
    866                    fact we don't care, we're just happy he's still alive. */
    867                 irc->last_pong = gettime();
    868                 irc->pinging = 0;
    869         }
    870         else if( g_strcasecmp( cmd[0], "COMPLETIONS" ) == 0 )
    871         {
    872                 user_t *u = user_find( irc, irc->mynick );
    873                 help_t *h;
    874                 set_t *s;
    875                 int i;
    876                
    877                 irc_privmsg( irc, u, "NOTICE", irc->nick, "COMPLETIONS ", "OK" );
    878                
    879                 for( i = 0; commands[i].command; i ++ )
    880                         irc_privmsg( irc, u, "NOTICE", irc->nick, "COMPLETIONS ", commands[i].command );
    881                
    882                 for( h = global.help; h; h = h->next )
    883                         irc_privmsg( irc, u, "NOTICE", irc->nick, "COMPLETIONS help ", h->string );
    884                
    885                 for( s = irc->set; s; s = s->next )
    886                         irc_privmsg( irc, u, "NOTICE", irc->nick, "COMPLETIONS set ", s->key );
    887                
    888                 irc_privmsg( irc, u, "NOTICE", irc->nick, "COMPLETIONS ", "END" );
    889         }
    890         else if( set_getint( irc, "debug" ) )
    891         {
    892                 irc_usermsg( irc, "\002--- Unknown command:" );
    893                 for( i = 0; cmd[i]; i ++ ) irc_usermsg( irc, "%s", cmd[i] );
    894                 irc_usermsg( irc, "\002--------------------" );
    895         }
    896        
    897         return( 1 );
     430                }
     431        }
     432       
     433        return cmd;
     434}
     435
     436char *irc_build_line( char **cmd )
     437{
     438        int i, len;
     439        char *s;
     440       
     441        if( cmd[0] == NULL )
     442                return NULL;
     443       
     444        len = 1;
     445        for( i = 0; cmd[i]; i ++ )
     446                len += strlen( cmd[i] ) + 1;
     447       
     448        if( strchr( cmd[i-1], ' ' ) != NULL )
     449                len ++;
     450       
     451        s = g_new0( char, len + 1 );
     452        for( i = 0; cmd[i]; i ++ )
     453        {
     454                if( cmd[i+1] == NULL && strchr( cmd[i], ' ' ) != NULL )
     455                        strcat( s, ":" );
     456               
     457                strcat( s, cmd[i] );
     458               
     459                if( cmd[i+1] )
     460                        strcat( s, " " );
     461        }
     462        strcat( s, "\r\n" );
     463       
     464        return s;
    898465}
    899466
     
    1054621}
    1055622
    1056 void irc_who( irc_t *irc, char *channel )
    1057 {
    1058         user_t *u = irc->users;
    1059         struct conversation *c;
    1060         GList *l;
    1061        
    1062         if( !channel || *channel == '0' || *channel == '*' || !*channel )
    1063                 while( u )
    1064                 {
    1065                         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 );
    1066                         u = u->next;
    1067                 }
    1068         else if( g_strcasecmp( channel, irc->channel ) == 0 )
    1069                 while( u )
    1070                 {
    1071                         if( u->online )
    1072                                 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 );
    1073                         u = u->next;
    1074                 }
    1075         else if( ( c = conv_findchannel( channel ) ) )
    1076                 for( l = c->in_room; l; l = l->next )
    1077                 {
    1078                         if( ( u = user_findhandle( c->gc, l->data ) ) )
    1079                                 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 );
    1080                 }
    1081         else if( ( u = user_find( irc, channel ) ) )
    1082                 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 );
    1083        
    1084         irc_reply( irc, 315, "%s :End of /WHO list.", channel?channel:"**" );
     623int irc_check_login( irc_t *irc )
     624{
     625        if( irc->user && irc->nick )
     626        {
     627                if( global.conf->authmode == AUTHMODE_CLOSED && irc->status < USTATUS_AUTHORIZED )
     628                {
     629                        irc_reply( irc, 464, ":This server is password-protected." );
     630                        return 0;
     631                }
     632                else
     633                {
     634                        irc_login( irc );
     635                        return 1;
     636                }
     637        }
     638        else
     639        {
     640                /* More information needed. */
     641                return 0;
     642        }
    1085643}
    1086644
     
    1194752}
    1195753
    1196 void irc_whois( irc_t *irc, char *nick )
    1197 {
    1198         user_t *u = user_find( irc, nick );
    1199        
    1200         if( u )
    1201         {
    1202                 irc_reply( irc, 311, "%s %s %s * :%s", u->nick, u->user, u->host, u->realname );
    1203                
    1204                 if( u->gc )
    1205                         irc_reply( irc, 312, "%s %s.%s :%s network", u->nick, u->gc->user->username,
    1206                                    *u->gc->user->proto_opt[0] ? u->gc->user->proto_opt[0] : "", u->gc->prpl->name );
    1207                 else
    1208                         irc_reply( irc, 312, "%s %s :%s", u->nick, irc->myhost, IRCD_INFO );
    1209                
    1210                 if( !u->online )
    1211                         irc_reply( irc, 301, "%s :%s", u->nick, "User is offline" );
    1212                 else if( u->away )
    1213                         irc_reply( irc, 301, "%s :%s", u->nick, u->away );
    1214                
    1215                 irc_reply( irc, 318, "%s :End of /WHOIS list", nick );
    1216         }
    1217         else
    1218         {
    1219                 irc_reply( irc, 401, "%s :Nick does not exist", nick );
    1220         }
    1221 }
    1222 
    1223 
    1224754void irc_umode_set( irc_t *irc, char *s, int allow_priv )
    1225755{
     
    1251781}
    1252782
    1253 int irc_away( irc_t *irc, char *away )
    1254 {
    1255         user_t *u = user_find( irc, irc->nick );
    1256         GSList *c = get_connections();
    1257        
    1258         if( !u ) return( 0 );
    1259        
    1260         if( away && *away )
    1261         {
    1262                 int i, j;
    1263                
    1264                 /* Copy away string, but skip control chars. Mainly because
    1265                    Jabber really doesn't like them. */
    1266                 u->away = g_malloc( strlen( away ) + 1 );
    1267                 for( i = j = 0; away[i]; i ++ )
    1268                         if( ( u->away[j] = away[i] ) >= ' ' )
    1269                                 j ++;
    1270                 u->away[j] = 0;
    1271                
    1272                 irc_reply( irc, 306, ":You're now away: %s", u->away );
    1273                 /* irc_umode_set( irc, irc->myhost, "+a" ); */
    1274         }
    1275         else
    1276         {
    1277                 if( u->away ) g_free( u->away );
    1278                 u->away = NULL;
    1279                 /* irc_umode_set( irc, irc->myhost, "-a" ); */
    1280                 irc_reply( irc, 305, ":Welcome back" );
    1281         }
    1282        
    1283         while( c )
    1284         {
    1285                 if( ((struct gaim_connection *)c->data)->flags & OPT_LOGGED_IN )
    1286                         proto_away( c->data, u->away );
    1287                
    1288                 c = c->next;
    1289         }
    1290        
    1291         return( 1 );
    1292 }
    1293 
    1294783void irc_spawn( irc_t *irc, user_t *u )
    1295784{
     
    1343832        }
    1344833        g_free( nick );
    1345 }
    1346 
    1347 void irc_invite( irc_t *irc, char *nick, char *channel )
    1348 {
    1349         struct conversation *c = conv_findchannel( channel );
    1350         user_t *u = user_find( irc, nick );
    1351        
    1352         if( u && c && ( u->gc == c->gc ) )
    1353                 if( c->gc && c->gc->prpl && c->gc->prpl->chat_invite )
    1354                 {
    1355                         c->gc->prpl->chat_invite( c->gc, c->id, "", u->handle );
    1356                         irc_reply( irc, 341, "%s %s", nick, channel );
    1357                         return;
    1358                 }
    1359        
    1360         irc_reply( irc, 482, "%s :Invite impossible; User/Channel non-existent or incompatible", channel );
    1361834}
    1362835
Note: See TracChangeset for help on using the changeset viewer.