Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • irc.c

    rde3e100 r5c577bd  
    293293int irc_process( irc_t *irc )
    294294{
    295         char **lines, *temp, **cmd;
     295        char **lines, *temp;   
    296296        int i;
    297297
    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                         {
     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 ) {
    306302                                temp = g_strdup( lines[i] );
    307303                                g_free( irc->readbuffer );
    308304                                irc->readbuffer = temp;
    309                                 i ++;
     305                                i++;
    310306                                break;
    311307                        }                       
    312                        
    313                         if( ( cmd = irc_parse_line( irc, lines[i] ) ) == NULL )
    314                                 continue;
    315                         if( !irc_exec( irc, cmd ) )
    316                         {
    317                                 g_free( cmd );
     308                        if (!irc_process_line(irc, lines[i])) {
    318309                                g_free( lines );
    319310                                return 0;
    320311                        }
    321                        
    322                         g_free( cmd );
    323                 }
    324                
    325                 if( lines[i] != NULL )
    326                 {
    327                         g_free( irc->readbuffer );
    328                         irc->readbuffer = NULL;
    329                 }
    330                
     312                }
     313                if(lines[i]!=NULL) {
     314                        g_free(irc->readbuffer);
     315                        irc->readbuffer=NULL;   
     316                }
    331317                g_free( lines );
    332318        }
    333        
    334319        return 1;       
    335320}
     
    341326
    342327        /* Count the number of elements we're gonna need. */
    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 ++;
     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++;
    348332        }
    349333       
    350334        /* Allocate j+1 elements. */
    351         lines = g_new( char *, j + 1 );
     335        lines=g_new (char *, j+1);
    352336       
    353337        /* NULL terminate our list. */
    354         lines[j] = NULL;
    355        
    356         lines[0] = buffer;
     338        lines[j]=NULL;
     339       
     340        lines[0]=buffer;
    357341       
    358342        /* Split the buffer in several strings, using \r\n as our seperator, where \r is optional.
    359343         * Although this is not in the RFC, some braindead ircds (newnet's) use this, so some clients might too.
    360344         */
    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 
    377 char **irc_parse_line( irc_t *irc, 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 )
    378364{
    379365        int i, j;
     
    381367       
    382368        /* Move the line pointer to the start of the command, skipping spaces and the optional prefix. */
    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        
     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
    391376        /* If we're already at the end of the line, return. If not, we're going to need at least one element. */
    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 ++;
     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                }
    402390                       
    403                         if( line[i+1] == ':' )
    404                                 break;
    405                 }
    406391        }       
    407392
    408393        /* Allocate the space we need. */
    409         cmd = g_new( char *, j + 1 );
    410         cmd[j] = NULL;
     394        cmd=g_new(char *, j+1);
     395        cmd[j]=NULL;
    411396       
    412397        /* Do the actual line splitting, format is:
     
    415400         */
    416401
    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;
     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 );
    424565                       
    425                         if( line[i+1] == ':' )
    426                         {
    427                                 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] )
    428767                                break;
    429                         }
    430                 }
    431         }
    432        
    433         return cmd;
     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( g_strcasecmp( cmd[0], "DIE" ) == 0 )
     877        {
     878                printf( "%d %d\n", global.listen_socket, write( global.listen_socket, "DIE\r\n", 5 ) );
     879        }
     880        else if( set_getint( irc, "debug" ) )
     881        {
     882                irc_usermsg( irc, "\002--- Unknown command:" );
     883                for( i = 0; cmd[i]; i ++ ) irc_usermsg( irc, "%s", cmd[i] );
     884                irc_usermsg( irc, "\002--------------------" );
     885        }
     886       
     887        return( 1 );
    434888}
    435889
     
    491945        if( irc->sendbuffer != NULL ) {
    492946                size = strlen( irc->sendbuffer ) + strlen( line );
     947#ifdef FLOOD_SEND
     948                if( size > FLOOD_SEND_MAXBUFFER ) {
     949                        /* Die flooder, die! >:) */
     950
     951                        g_free(irc->sendbuffer);
     952                       
     953                        /* We need the \r\n at the start because else we might append our string to a half
     954                         * sent line. A bit hackish, but it works.
     955                         */
     956                        irc->sendbuffer = g_strdup( "\r\nERROR :Sendq Exceeded\r\n" );
     957                        irc->quit = 1;
     958                       
     959                        return;
     960                }
     961#endif
    493962                irc->sendbuffer = g_renew ( char, irc->sendbuffer, size + 1 );
    494963                strcpy( ( irc->sendbuffer + strlen( irc->sendbuffer ) ), line );
     
    5901059}
    5911060
    592 int irc_check_login( irc_t *irc )
    593 {
    594         if( irc->user && irc->nick )
    595         {
    596                 if( global.conf->authmode == AUTHMODE_CLOSED && irc->status < USTATUS_AUTHORIZED )
    597                 {
    598                         irc_reply( irc, 464, ":This server is password-protected." );
    599                         return 0;
    600                 }
    601                 else
    602                 {
    603                         irc_login( irc );
    604                         return 1;
    605                 }
    606         }
    607         else
    608         {
    609                 /* More information needed. */
    610                 return 0;
    611         }
     1061void irc_who( irc_t *irc, char *channel )
     1062{
     1063        user_t *u = irc->users;
     1064        struct conversation *c;
     1065        GList *l;
     1066       
     1067        if( !channel || *channel == '0' || *channel == '*' || !*channel )
     1068                while( u )
     1069                {
     1070                        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 );
     1071                        u = u->next;
     1072                }
     1073        else if( g_strcasecmp( channel, irc->channel ) == 0 )
     1074                while( u )
     1075                {
     1076                        if( u->online )
     1077                                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 );
     1078                        u = u->next;
     1079                }
     1080        else if( ( c = conv_findchannel( channel ) ) )
     1081                for( l = c->in_room; l; l = l->next )
     1082                {
     1083                        if( ( u = user_findhandle( c->gc, l->data ) ) )
     1084                                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 );
     1085                }
     1086        else if( ( u = user_find( irc, channel ) ) )
     1087                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 );
     1088       
     1089        irc_reply( irc, 315, "%s :End of /WHO list.", channel?channel:"**" );
    6121090}
    6131091
     
    7211199}
    7221200
     1201void irc_whois( irc_t *irc, char *nick )
     1202{
     1203        user_t *u = user_find( irc, nick );
     1204       
     1205        if( u )
     1206        {
     1207                irc_reply( irc, 311, "%s %s %s * :%s", u->nick, u->user, u->host, u->realname );
     1208               
     1209                if( u->gc )
     1210                        irc_reply( irc, 312, "%s %s.%s :%s network", u->nick, u->gc->user->username,
     1211                                   *u->gc->user->proto_opt[0] ? u->gc->user->proto_opt[0] : "", u->gc->prpl->name );
     1212                else
     1213                        irc_reply( irc, 312, "%s %s :%s", u->nick, irc->myhost, IRCD_INFO );
     1214               
     1215                if( !u->online )
     1216                        irc_reply( irc, 301, "%s :%s", u->nick, "User is offline" );
     1217                else if( u->away )
     1218                        irc_reply( irc, 301, "%s :%s", u->nick, u->away );
     1219               
     1220                irc_reply( irc, 318, "%s :End of /WHOIS list", nick );
     1221        }
     1222        else
     1223        {
     1224                irc_reply( irc, 401, "%s :Nick does not exist", nick );
     1225        }
     1226}
     1227
     1228
    7231229void irc_umode_set( irc_t *irc, char *s, int allow_priv )
    7241230{
     
    7501256}
    7511257
     1258int irc_away( irc_t *irc, char *away )
     1259{
     1260        user_t *u = user_find( irc, irc->nick );
     1261        GSList *c = get_connections();
     1262       
     1263        if( !u ) return( 0 );
     1264       
     1265        if( away && *away )
     1266        {
     1267                int i, j;
     1268               
     1269                /* Copy away string, but skip control chars. Mainly because
     1270                   Jabber really doesn't like them. */
     1271                u->away = g_malloc( strlen( away ) + 1 );
     1272                for( i = j = 0; away[i]; i ++ )
     1273                        if( ( u->away[j] = away[i] ) >= ' ' )
     1274                                j ++;
     1275                u->away[j] = 0;
     1276               
     1277                irc_reply( irc, 306, ":You're now away: %s", u->away );
     1278                /* irc_umode_set( irc, irc->myhost, "+a" ); */
     1279        }
     1280        else
     1281        {
     1282                if( u->away ) g_free( u->away );
     1283                u->away = NULL;
     1284                /* irc_umode_set( irc, irc->myhost, "-a" ); */
     1285                irc_reply( irc, 305, ":Welcome back" );
     1286        }
     1287       
     1288        while( c )
     1289        {
     1290                if( ((struct gaim_connection *)c->data)->flags & OPT_LOGGED_IN )
     1291                        proto_away( c->data, u->away );
     1292               
     1293                c = c->next;
     1294        }
     1295       
     1296        return( 1 );
     1297}
     1298
    7521299void irc_spawn( irc_t *irc, user_t *u )
    7531300{
     
    8011348        }
    8021349        g_free( nick );
     1350}
     1351
     1352void irc_invite( irc_t *irc, char *nick, char *channel )
     1353{
     1354        struct conversation *c = conv_findchannel( channel );
     1355        user_t *u = user_find( irc, nick );
     1356       
     1357        if( u && c && ( u->gc == c->gc ) )
     1358                if( c->gc && c->gc->prpl && c->gc->prpl->chat_invite )
     1359                {
     1360                        c->gc->prpl->chat_invite( c->gc, c->id, "", u->handle );
     1361                        irc_reply( irc, 341, "%s %s", nick, channel );
     1362                        return;
     1363                }
     1364       
     1365        irc_reply( irc, 482, "%s :Invite impossible; User/Channel non-existent or incompatible", channel );
    8031366}
    8041367
Note: See TracChangeset for help on using the changeset viewer.