Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • irc_commands.c

    r70f69ecc r228fc18  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2010 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2006 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    5353        else if( global.conf->auth_pass )
    5454        {
    55                 irc_send_num( irc, 464, ":Incorrect password" );
     55                irc_reply( irc, 464, ":Incorrect password" );
    5656        }
    5757        else
     
    6565static void irc_cmd_user( irc_t *irc, char **cmd )
    6666{
    67         irc->user->user = g_strdup( cmd[1] );
    68         irc->user->fullname = g_strdup( cmd[4] );
     67        irc->user = g_strdup( cmd[1] );
     68        irc->realname = g_strdup( cmd[4] );
    6969       
    7070        irc_check_login( irc );
     
    7373static void irc_cmd_nick( irc_t *irc, char **cmd )
    7474{
    75         if( irc_user_by_name( irc, cmd[1] ) )
    76         {
    77                 irc_send_num( irc, 433, ":This nick is already in use" );
     75        if( irc->status & USTATUS_IDENTIFIED && irc->nick )
     76        {
     77                irc_reply( irc, 438, "%s %s :You can only change your nick if you're not "
     78                           "logged in (i.e. pre-identify)", irc->nick, cmd[1] );
     79        }
     80        /* This is not clean, but for now it'll have to be like this... */
     81        else if( ( nick_cmp( cmd[1], irc->mynick ) == 0 ) || ( nick_cmp( cmd[1], NS_NICK ) == 0 ) || ( user_find( irc, cmd[1] ) != NULL ) )
     82        {
     83                irc_reply( irc, 433, "%s :This nick is already in use", cmd[1] );
    7884        }
    7985        else if( !nick_ok( cmd[1] ) )
    8086        {
    8187                /* [SH] Invalid characters. */
    82                 irc_send_num( irc, 432, ":This nick contains invalid characters" );
    83         }
    84         else if( irc->user->nick )
    85         {
    86                 if( irc->status & USTATUS_IDENTIFIED )
    87                 {
    88                         irc_setpass( irc, NULL );
    89                         irc->status &= ~USTATUS_IDENTIFIED;
    90                         irc_umode_set( irc, "-R", 1 );
    91                         irc_usermsg( irc, "Changing nicks resets your identify status. "
    92                                      "Re-identify or register a new account if you want "
    93                                      "your configuration to be saved. See \x02help "
    94                                      "nick_changes\x02." );
    95                 }
    96                
    97                 irc_user_set_nick( irc->user, cmd[1] );
    98         }
    99         else
    100         {
    101                 irc->user->nick = g_strdup( cmd[1] );
     88                irc_reply( irc, 432, "%s :This nick contains invalid characters", cmd[1] );
     89        }
     90        else if(irc->nick)
     91        {
     92                if( user_find( irc, irc->nick ) )
     93                        user_rename(irc, irc->nick, cmd[1]);
     94
     95                irc_write( irc, ":%s!%s@%s NICK %s", irc->nick, irc->user, irc->host, cmd[1] );
     96                g_free(irc->nick);
     97                irc->nick = g_strdup( cmd[1] );
     98        }
     99        else
     100        {
     101                irc->nick = g_strdup( cmd[1] );
    102102               
    103103                irc_check_login( irc );
     
    115115static void irc_cmd_ping( irc_t *irc, char **cmd )
    116116{
    117         irc_write( irc, ":%s PONG %s :%s", irc->root->host,
    118                    irc->root->host, cmd[1]?cmd[1]:irc->root->host );
    119 }
    120 
    121 static void irc_cmd_pong( irc_t *irc, char **cmd )
    122 {
    123         /* We could check the value we get back from the user, but in
    124            fact we don't care, we're just happy s/he's still alive. */
    125         irc->last_pong = gettime();
    126         irc->pinging = 0;
    127 }
    128 
    129 static void irc_cmd_join( irc_t *irc, char **cmd )
    130 {
    131         irc_channel_t *ic;
    132        
    133         if( ( ic = irc_channel_by_name( irc, cmd[1] ) ) == NULL )
    134                 ic = irc_channel_new( irc, cmd[1] );
    135        
    136         if( ic == NULL )
    137         {
    138                 irc_send_num( irc, 479, "%s :Invalid channel name", cmd[1] );
    139                 return;
    140         }
    141        
    142         if( ic->flags & IRC_CHANNEL_JOINED )
    143                 return; /* Dude, you're already there...
    144                            RFC doesn't have any reply for that though? */
    145        
    146         if( ic->f->join && !ic->f->join( ic ) )
    147                 /* The story is: FALSE either means the handler showed an error
    148                    message, or is doing some work before the join should be
    149                    confirmed. (In the latter case, the caller should take care
    150                    of that confirmation.)
    151                    TRUE means all's good, let the user join the channel right away. */
    152                 return;
    153        
    154         irc_channel_add_user( ic, irc->user );
    155 }
    156 
    157 static void irc_cmd_names( irc_t *irc, char **cmd )
    158 {
    159         irc_channel_t *ic;
    160        
    161         if( cmd[1] && ( ic = irc_channel_by_name( irc, cmd[1] ) ) )
    162                 irc_send_names( ic );
    163         /* With no args, we should show /names of all chans. Make the code
    164            below work well if necessary.
    165         else
    166         {
    167                 GSList *l;
    168                
    169                 for( l = irc->channels; l; l = l->next )
    170                         irc_send_names( l->data );
    171         }
    172         */
    173 }
    174 
    175 static void irc_cmd_part( irc_t *irc, char **cmd )
    176 {
    177         irc_channel_t *ic;
    178        
    179         if( ( ic = irc_channel_by_name( irc, cmd[1] ) ) == NULL )
    180         {
    181                 irc_send_num( irc, 403, "%s :No such channel", cmd[1] );
    182         }
    183         else if( irc_channel_del_user( ic, irc->user, FALSE, cmd[2] ) )
    184         {
    185                 if( ic->f->part )
    186                         ic->f->part( ic, NULL );
    187         }
    188         else
    189         {
    190                 irc_send_num( irc, 442, "%s :You're not on that channel", cmd[1] );
    191         }
    192 }
    193 
    194 static void irc_cmd_whois( irc_t *irc, char **cmd )
    195 {
    196         char *nick = cmd[1];
    197         irc_user_t *iu = irc_user_by_name( irc, nick );
    198        
    199         if( iu )
    200                 irc_send_whois( iu );
    201         else
    202                 irc_send_num( irc, 401, "%s :Nick does not exist", nick );
    203 }
    204 
    205 static void irc_cmd_whowas( irc_t *irc, char **cmd )
    206 {
    207         /* For some reason irssi tries a whowas when whois fails. We can
    208            ignore this, but then the user never gets a "user not found"
    209            message from irssi which is a bit annoying. So just respond
    210            with not-found and irssi users will get better error messages */
    211        
    212         irc_send_num( irc, 406, "%s :Nick does not exist", cmd[1] );
    213         irc_send_num( irc, 369, "%s :End of WHOWAS", cmd[1] );
    214 }
    215 
    216 static void irc_cmd_motd( irc_t *irc, char **cmd )
    217 {
    218         irc_send_motd( irc );
     117        irc_write( irc, ":%s PONG %s :%s", irc->myhost, irc->myhost, cmd[1]?cmd[1]:irc->myhost );
     118}
     119
     120static void irc_cmd_oper( irc_t *irc, char **cmd )
     121{
     122        if( global.conf->oper_pass &&
     123            ( strncmp( global.conf->oper_pass, "md5:", 4 ) == 0 ?
     124                md5_verify_password( cmd[2], global.conf->oper_pass + 4 ) == 0 :
     125                strcmp( cmd[2], global.conf->oper_pass ) == 0 ) )
     126        {
     127                irc_umode_set( irc, "+o", 1 );
     128                irc_reply( irc, 381, ":Password accepted" );
     129        }
     130        else
     131        {
     132                irc_reply( irc, 432, ":Incorrect password" );
     133        }
    219134}
    220135
    221136static void irc_cmd_mode( irc_t *irc, char **cmd )
    222137{
    223         if( irc_channel_name_ok( cmd[1] ) )
    224         {
    225                 irc_channel_t *ic;
    226                
    227                 if( ( ic = irc_channel_by_name( irc, cmd[1] ) ) == NULL )
    228                         irc_send_num( irc, 403, "%s :No such channel", cmd[1] );
    229                 else if( cmd[2] )
     138        if( strchr( CTYPES, *cmd[1] ) )
     139        {
     140                if( cmd[2] )
    230141                {
    231142                        if( *cmd[2] == '+' || *cmd[2] == '-' )
    232                                 irc_send_num( irc, 477, "%s :Can't change channel modes", cmd[1] );
     143                                irc_reply( irc, 477, "%s :Can't change channel modes", cmd[1] );
    233144                        else if( *cmd[2] == 'b' )
    234                                 irc_send_num( irc, 368, "%s :No bans possible", cmd[1] );
     145                                irc_reply( irc, 368, "%s :No bans possible", cmd[1] );
    235146                }
    236147                else
    237                         irc_send_num( irc, 324, "%s +%s", cmd[1], ic->mode );
    238         }
    239         else
    240         {
    241                 if( nick_cmp( cmd[1], irc->user->nick ) == 0 )
     148                        irc_reply( irc, 324, "%s +%s", cmd[1], CMODE );
     149        }
     150        else
     151        {
     152                if( nick_cmp( cmd[1], irc->nick ) == 0 )
    242153                {
    243154                        if( cmd[2] )
    244155                                irc_umode_set( irc, cmd[2], 0 );
    245156                        else
    246                                 irc_send_num( irc, 221, "+%s", irc->umode );
     157                                irc_reply( irc, 221, "+%s", irc->umode );
    247158                }
    248159                else
    249                         irc_send_num( irc, 502, ":Don't touch their modes" );
    250         }
    251 }
    252 
    253 static void irc_cmd_who( irc_t *irc, char **cmd )
    254 {
    255         char *channel = cmd[1];
    256         irc_channel_t *ic;
    257        
    258         if( !channel || *channel == '0' || *channel == '*' || !*channel )
    259                 irc_send_who( irc, irc->users, "**" );
    260         else if( ( ic = irc_channel_by_name( irc, channel ) ) )
    261                 irc_send_who( irc, ic->users, channel );
    262         else
    263                 irc_send_num( irc, 403, "%s :No such channel", channel );
     160                        irc_reply( irc, 502, ":Don't touch their modes" );
     161        }
     162}
     163
     164static void irc_cmd_names( irc_t *irc, char **cmd )
     165{
     166        irc_names( irc, cmd[1]?cmd[1]:irc->channel );
     167}
     168
     169static void irc_cmd_part( irc_t *irc, char **cmd )
     170{
     171        struct groupchat *c;
     172       
     173        if( g_strcasecmp( cmd[1], irc->channel ) == 0 )
     174        {
     175                user_t *u = user_find( irc, irc->nick );
     176               
     177                /* Not allowed to leave control channel */
     178                irc_part( irc, u, irc->channel );
     179                irc_join( irc, u, irc->channel );
     180        }
     181        else if( ( c = irc_chat_by_channel( irc, cmd[1] ) ) )
     182        {
     183                user_t *u = user_find( irc, irc->nick );
     184               
     185                irc_part( irc, u, c->channel );
     186               
     187                if( c->ic )
     188                {
     189                        c->joined = 0;
     190                        c->ic->acc->prpl->chat_leave( c );
     191                }
     192        }
     193        else
     194        {
     195                irc_reply( irc, 403, "%s :No such channel", cmd[1] );
     196        }
     197}
     198
     199static void irc_cmd_join( irc_t *irc, char **cmd )
     200{
     201        if( g_strcasecmp( cmd[1], irc->channel ) == 0 )
     202                ; /* Dude, you're already there...
     203                     RFC doesn't have any reply for that though? */
     204        else if( cmd[1] )
     205        {
     206                struct chat *c;
     207               
     208                if( strchr( CTYPES, cmd[1][0] ) == NULL || cmd[1][1] == 0 )
     209                        irc_reply( irc, 479, "%s :Invalid channel name", cmd[1] );
     210                else if( ( c = chat_bychannel( irc, cmd[1] ) ) && c->acc && c->acc->ic )
     211                        chat_join( irc, c, cmd[2] );
     212                else
     213                        irc_reply( irc, 403, "%s :No such channel", cmd[1] );
     214        }
     215}
     216
     217static void irc_cmd_invite( irc_t *irc, char **cmd )
     218{
     219        char *nick = cmd[1], *channel = cmd[2];
     220        struct groupchat *c = irc_chat_by_channel( irc, channel );
     221        user_t *u = user_find( irc, nick );
     222       
     223        if( u && c && ( u->ic == c->ic ) )
     224                if( c->ic && c->ic->acc->prpl->chat_invite )
     225                {
     226                        c->ic->acc->prpl->chat_invite( c, u->handle, NULL );
     227                        irc_reply( irc, 341, "%s %s", nick, channel );
     228                        return;
     229                }
     230       
     231        irc_reply( irc, 482, "%s :Invite impossible; User/Channel non-existent or incompatible", channel );
    264232}
    265233
    266234static void irc_cmd_privmsg( irc_t *irc, char **cmd )
    267235{
    268         irc_channel_t *ic;
    269         irc_user_t *iu;
    270        
    271         if( !cmd[2] )
    272         {
    273                 irc_send_num( irc, 412, ":No text to send" );
    274                 return;
    275         }
    276        
    277         /* Don't treat CTCP actions as real CTCPs, just convert them right now. */
    278         if( g_strncasecmp( cmd[2], "\001ACTION", 7 ) == 0 )
    279         {
    280                 cmd[2] += 4;
    281                 strcpy( cmd[2], "/me" );
    282                 if( cmd[2][strlen(cmd[2])-1] == '\001' )
    283                         cmd[2][strlen(cmd[2])-1] = '\0';
    284         }
    285        
    286         if( irc_channel_name_ok( cmd[1] ) &&
    287             ( ic = irc_channel_by_name( irc, cmd[1] ) ) )
    288         {
    289                 if( ic->f->privmsg )
    290                         ic->f->privmsg( ic, cmd[2] );
    291         }
    292         else if( ( iu = irc_user_by_name( irc, cmd[1] ) ) )
    293         {
    294                 if( cmd[2][0] == '\001' )
    295                 {
    296                         char **ctcp;
    297                        
    298                         if( iu->f->ctcp == NULL )
    299                                 return;
    300                         if( cmd[2][strlen(cmd[2])-1] == '\001' )
    301                                 cmd[2][strlen(cmd[2])-1] = '\0';
    302                        
    303                         ctcp = split_command_parts( cmd[2] + 1 );
    304                         iu->f->ctcp( iu, ctcp );
    305                 }
    306                 else if( iu->f->privmsg )
    307                 {
    308                         iu->flags |= IRC_USER_PRIVATE;
    309                         iu->f->privmsg( iu, cmd[2] );
    310                 }
    311         }
    312         else
    313         {
    314                 irc_send_num( irc, 401, "%s :No such nick/channel", cmd[1] );
    315         }
    316 
    317 
    318 #if 0
    319         else if( irc->nick && g_strcasecmp( cmd[1], irc->nick ) == 0 )
    320         {
     236        if ( !cmd[2] )
     237        {
     238                irc_reply( irc, 412, ":No text to send" );
     239        }
     240        else if ( irc->nick && g_strcasecmp( cmd[1], irc->nick ) == 0 )
     241        {
     242                irc_write( irc, ":%s!%s@%s %s %s :%s", irc->nick, irc->user, irc->host, cmd[0], cmd[1], cmd[2] );
    321243        }
    322244        else
     
    359281                irc_send( irc, cmd[1], cmd[2], ( g_strcasecmp( cmd[0], "NOTICE" ) == 0 ) ? OPT_AWAY : 0 );
    360282        }
    361 #endif
    362 }
    363 
    364 static void irc_cmd_nickserv( irc_t *irc, char **cmd )
    365 {
    366         /* [SH] This aliases the NickServ command to PRIVMSG root */
    367         /* [TV] This aliases the NS command to PRIVMSG root as well */
    368         root_command( irc, cmd + 1 );
    369 }
    370 
    371 
    372 
    373 static void irc_cmd_oper( irc_t *irc, char **cmd )
    374 {
    375         if( global.conf->oper_pass &&
    376             ( strncmp( global.conf->oper_pass, "md5:", 4 ) == 0 ?
    377                 md5_verify_password( cmd[2], global.conf->oper_pass + 4 ) == 0 :
    378                 strcmp( cmd[2], global.conf->oper_pass ) == 0 ) )
    379         {
    380                 irc_umode_set( irc, "+o", 1 );
    381                 irc_send_num( irc, 381, ":Password accepted" );
    382         }
    383         else
    384         {
    385                 irc_send_num( irc, 432, ":Incorrect password" );
    386         }
    387 }
    388 
    389 static void irc_cmd_invite( irc_t *irc, char **cmd )
    390 {
    391         irc_channel_t *ic;
    392         irc_user_t *iu;
    393        
    394         if( ( iu = irc_user_by_name( irc, cmd[1] ) ) == NULL )
    395         {
    396                 irc_send_num( irc, 401, "%s :No such nick", cmd[1] );
    397                 return;
    398         }
    399         else if( ( ic = irc_channel_by_name( irc, cmd[2] ) ) == NULL )
    400         {
    401                 irc_send_num( irc, 403, "%s :No such channel", cmd[2] );
    402                 return;
    403         }
    404        
    405         if( !ic->f->invite || !ic->f->invite( ic, iu ) )
    406                 irc_send_num( irc, 482, "%s :Can't invite people here", cmd[2] );
     283}
     284
     285static void irc_cmd_who( irc_t *irc, char **cmd )
     286{
     287        char *channel = cmd[1];
     288        user_t *u = irc->users;
     289        struct groupchat *c;
     290        GList *l;
     291       
     292        if( !channel || *channel == '0' || *channel == '*' || !*channel )
     293                while( u )
     294                {
     295                        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 );
     296                        u = u->next;
     297                }
     298        else if( g_strcasecmp( channel, irc->channel ) == 0 )
     299                while( u )
     300                {
     301                        if( u->online )
     302                                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 );
     303                        u = u->next;
     304                }
     305        else if( ( c = irc_chat_by_channel( irc, channel ) ) )
     306                for( l = c->in_room; l; l = l->next )
     307                {
     308                        if( ( u = user_findhandle( c->ic, l->data ) ) )
     309                                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 );
     310                }
     311        else if( ( u = user_find( irc, channel ) ) )
     312                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 );
     313       
     314        irc_reply( irc, 315, "%s :End of /WHO list", channel?channel:"**" );
    407315}
    408316
    409317static void irc_cmd_userhost( irc_t *irc, char **cmd )
    410318{
     319        user_t *u;
    411320        int i;
    412321       
     
    418327       
    419328        for( i = 1; cmd[i]; i ++ )
    420         {
    421                 irc_user_t *iu = irc_user_by_name( irc, cmd[i] );
    422                
    423                 if( iu )
    424                         irc_send_num( irc, 302, ":%s=%c%s@%s", iu->nick,
    425                                       irc_user_get_away( iu ) ? '-' : '+',
    426                                       iu->user, iu->host );
    427         }
     329                if( ( u = user_find( irc, cmd[i] ) ) )
     330                {
     331                        if( u->online && u->away )
     332                                irc_reply( irc, 302, ":%s=-%s@%s", u->nick, u->user, u->host );
     333                        else
     334                                irc_reply( irc, 302, ":%s=+%s@%s", u->nick, u->user, u->host );
     335                }
    428336}
    429337
    430338static void irc_cmd_ison( irc_t *irc, char **cmd )
    431339{
     340        user_t *u;
    432341        char buff[IRC_MAX_LINE];
    433342        int lenleft, i;
     
    445354                while( *this )
    446355                {
    447                         irc_user_t *iu;
    448                        
    449356                        if( ( next = strchr( this, ' ' ) ) )
    450357                                *next = 0;
    451358                       
    452                         if( ( iu = irc_user_by_name( irc, this ) ) &&
    453                             iu->bu && iu->bu->flags & BEE_USER_ONLINE )
    454                         {
    455                                 lenleft -= strlen( iu->nick ) + 1;
     359                        if( ( u = user_find( irc, this ) ) && u->online )
     360                        {
     361                                lenleft -= strlen( u->nick ) + 1;
    456362                               
    457363                                if( lenleft < 0 )
    458364                                        break;
    459365                               
    460                                 strcat( buff, iu->nick );
     366                                strcat( buff, u->nick );
    461367                                strcat( buff, " " );
    462368                        }
     
    481387                buff[strlen(buff)-1] = '\0';
    482388       
    483         irc_send_num( irc, 303, ":%s", buff );
     389        irc_reply( irc, 303, ":%s", buff );
    484390}
    485391
     
    494400        {
    495401                char *nick;
    496                 irc_user_t *iu;
     402                user_t *u;
    497403               
    498404                if( !cmd[i][0] || !cmd[i][1] )
     
    502408                nick_lc( nick );
    503409               
    504                 iu = irc_user_by_name( irc, nick );
     410                u = user_find( irc, nick );
    505411               
    506412                if( cmd[i][0] == '+' )
     
    509415                                g_hash_table_insert( irc->watches, nick, nick );
    510416                       
    511                         if( iu && iu->bu && iu->bu->flags & BEE_USER_ONLINE )
    512                                 irc_send_num( irc, 604, "%s %s %s %d :%s", iu->nick, iu->user,
    513                                               iu->host, (int) time( NULL ), "is online" );
     417                        if( u && u->online )
     418                                irc_reply( irc, 604, "%s %s %s %d :%s", u->nick, u->user, u->host, (int) time( NULL ), "is online" );
    514419                        else
    515                                 irc_send_num( irc, 605, "%s %s %s %d :%s", nick, "*", "*",
    516                                               (int) time( NULL ), "is offline" );
     420                                irc_reply( irc, 605, "%s %s %s %d :%s", nick, "*", "*", (int) time( NULL ), "is offline" );
    517421                }
    518422                else if( cmd[i][0] == '-' )
     
    525429                                g_free( okey );
    526430                               
    527                                 irc_send_num( irc, 602, "%s %s %s %d :%s", nick, "*", "*", 0, "Stopped watching" );
     431                                irc_reply( irc, 602, "%s %s %s %d :%s", nick, "*", "*", 0, "Stopped watching" );
    528432                        }
    529433                }
     
    533437static void irc_cmd_topic( irc_t *irc, char **cmd )
    534438{
    535         irc_channel_t *ic = irc_channel_by_name( irc, cmd[1] );
    536         const char *new = cmd[2];
    537        
    538         if( ic == NULL )
    539         {
    540                 irc_send_num( irc, 403, "%s :No such channel", cmd[1] );
    541         }
    542         else if( new )
    543         {
    544                 if( ic->f->topic == NULL )
    545                         irc_send_num( irc, 482, "%s :Can't change this channel's topic", ic->name );
    546                 else if( ic->f->topic( ic, new ) )
    547                         irc_send_topic( ic, TRUE );
    548         }
    549         else
    550         {
    551                 irc_send_topic( ic, FALSE );
     439        char *channel = cmd[1];
     440        char *topic = cmd[2];
     441       
     442        if( topic )
     443        {
     444                /* Send the topic */
     445                struct groupchat *c = irc_chat_by_channel( irc, channel );
     446                if( c && c->ic && c->ic->acc->prpl->chat_topic )
     447                        c->ic->acc->prpl->chat_topic( c, topic );
     448        }
     449        else
     450        {
     451                /* Get the topic */
     452                irc_topic( irc, channel );
    552453        }
    553454}
     
    555456static void irc_cmd_away( irc_t *irc, char **cmd )
    556457{
    557         if( cmd[1] && *cmd[1] )
    558         {
    559                 char away[strlen(cmd[1])+1];
     458        user_t *u = user_find( irc, irc->nick );
     459        char *away = cmd[1];
     460       
     461        if( !u ) return;
     462       
     463        if( away && *away )
     464        {
    560465                int i, j;
    561466               
    562467                /* Copy away string, but skip control chars. Mainly because
    563468                   Jabber really doesn't like them. */
    564                 for( i = j = 0; cmd[1][i]; i ++ )
    565                         if( ( away[j] = cmd[1][i] ) >= ' ' )
     469                u->away = g_malloc( strlen( away ) + 1 );
     470                for( i = j = 0; away[i]; i ++ )
     471                        if( ( u->away[j] = away[i] ) >= ' ' )
    566472                                j ++;
    567                 away[j] = '\0';
    568                
    569                 irc_send_num( irc, 306, ":You're now away: %s", away );
    570                 set_setstr( &irc->b->set, "away", away );
    571         }
    572         else
    573         {
    574                 irc_send_num( irc, 305, ":Welcome back" );
    575                 set_setstr( &irc->b->set, "away", NULL );
    576         }
     473                u->away[j] = 0;
     474               
     475                irc_reply( irc, 306, ":You're now away: %s", u->away );
     476                /* irc_umode_set( irc, irc->myhost, "+a" ); */
     477        }
     478        else
     479        {
     480                if( u->away ) g_free( u->away );
     481                u->away = NULL;
     482                /* irc_umode_set( irc, irc->myhost, "-a" ); */
     483                irc_reply( irc, 305, ":Welcome back" );
     484        }
     485       
     486        set_setstr( &irc->set, "away", u->away );
     487}
     488
     489static void irc_cmd_whois( irc_t *irc, char **cmd )
     490{
     491        char *nick = cmd[1];
     492        user_t *u = user_find( irc, nick );
     493       
     494        if( u )
     495        {
     496                irc_reply( irc, 311, "%s %s %s * :%s", u->nick, u->user, u->host, u->realname );
     497               
     498                if( u->ic )
     499                        irc_reply( irc, 312, "%s %s.%s :%s network", u->nick, u->ic->acc->user,
     500                                   u->ic->acc->server && *u->ic->acc->server ? u->ic->acc->server : "",
     501                                   u->ic->acc->prpl->name );
     502                else
     503                        irc_reply( irc, 312, "%s %s :%s", u->nick, irc->myhost, IRCD_INFO );
     504               
     505                if( !u->online )
     506                        irc_reply( irc, 301, "%s :%s", u->nick, "User is offline" );
     507                else if( u->away )
     508                        irc_reply( irc, 301, "%s :%s", u->nick, u->away );
     509                if( u->status_msg )
     510                        irc_reply( irc, 320, "%s :%s", u->nick, u->status_msg );
     511               
     512                irc_reply( irc, 318, "%s :End of /WHOIS list", nick );
     513        }
     514        else
     515        {
     516                irc_reply( irc, 401, "%s :Nick does not exist", nick );
     517        }
     518}
     519
     520static void irc_cmd_whowas( irc_t *irc, char **cmd )
     521{
     522        /* For some reason irssi tries a whowas when whois fails. We can
     523           ignore this, but then the user never gets a "user not found"
     524           message from irssi which is a bit annoying. So just respond
     525           with not-found and irssi users will get better error messages */
     526       
     527        irc_reply( irc, 406, "%s :Nick does not exist", cmd[1] );
     528        irc_reply( irc, 369, "%s :End of WHOWAS", cmd[1] );
     529}
     530
     531static void irc_cmd_nickserv( irc_t *irc, char **cmd )
     532{
     533        /* [SH] This aliases the NickServ command to PRIVMSG root */
     534        /* [TV] This aliases the NS command to PRIVMSG root as well */
     535        root_command( irc, cmd + 1 );
     536}
     537
     538static void irc_cmd_motd( irc_t *irc, char **cmd )
     539{
     540        irc_motd( irc );
     541}
     542
     543static void irc_cmd_pong( irc_t *irc, char **cmd )
     544{
     545        /* We could check the value we get back from the user, but in
     546           fact we don't care, we're just happy he's still alive. */
     547        irc->last_pong = gettime();
     548        irc->pinging = 0;
    577549}
    578550
    579551static void irc_cmd_version( irc_t *irc, char **cmd )
    580552{
    581         irc_send_num( irc, 351, "bitlbee-%s. %s :%s/%s ",
    582                       BITLBEE_VERSION, irc->root->host, ARCH, CPU );
     553        irc_reply( irc, 351, "bitlbee-%s. %s :%s/%s ", BITLBEE_VERSION, irc->myhost, ARCH, CPU );
    583554}
    584555
    585556static void irc_cmd_completions( irc_t *irc, char **cmd )
    586557{
     558        user_t *u = user_find( irc, irc->mynick );
    587559        help_t *h;
    588560        set_t *s;
    589561        int i;
    590562       
    591         irc_send_msg_raw( irc->root, "NOTICE", irc->user->nick, "COMPLETIONS OK" );
     563        irc_privmsg( irc, u, "NOTICE", irc->nick, "COMPLETIONS ", "OK" );
    592564       
    593565        for( i = 0; commands[i].command; i ++ )
    594                 irc_send_msg_f( irc->root, "NOTICE", irc->user->nick, "COMPLETIONS %s", commands[i].command );
     566                irc_privmsg( irc, u, "NOTICE", irc->nick, "COMPLETIONS ", commands[i].command );
    595567       
    596568        for( h = global.help; h; h = h->next )
    597                 irc_send_msg_f( irc->root, "NOTICE", irc->user->nick, "COMPLETIONS help %s", h->title );
    598        
    599         for( s = irc->b->set; s; s = s->next )
    600                 irc_send_msg_f( irc->root, "NOTICE", irc->user->nick, "COMPLETIONS set %s", s->key );
    601        
    602         irc_send_msg_raw( irc->root, "NOTICE", irc->user->nick, "COMPLETIONS END" );
     569                irc_privmsg( irc, u, "NOTICE", irc->nick, "COMPLETIONS help ", h->title );
     570       
     571        for( s = irc->set; s; s = s->next )
     572                irc_privmsg( irc, u, "NOTICE", irc->nick, "COMPLETIONS set ", s->key );
     573       
     574        irc_privmsg( irc, u, "NOTICE", irc->nick, "COMPLETIONS ", "END" );
    603575}
    604576
     
    610582                ipc_to_master( cmd );
    611583       
    612         irc_send_num( irc, 382, "%s :Rehashing", global.conf_file );
     584        irc_reply( irc, 382, "%s :Rehashing", global.conf_file );
    613585}
    614586
     
    619591        { "quit",        0, irc_cmd_quit,        0 },
    620592        { "ping",        0, irc_cmd_ping,        0 },
    621         { "pong",        0, irc_cmd_pong,        IRC_CMD_LOGGED_IN },
     593        { "oper",        2, irc_cmd_oper,        IRC_CMD_LOGGED_IN },
     594        { "mode",        1, irc_cmd_mode,        IRC_CMD_LOGGED_IN },
     595        { "names",       0, irc_cmd_names,       IRC_CMD_LOGGED_IN },
     596        { "part",        1, irc_cmd_part,        IRC_CMD_LOGGED_IN },
    622597        { "join",        1, irc_cmd_join,        IRC_CMD_LOGGED_IN },
    623         { "names",       1, irc_cmd_names,       IRC_CMD_LOGGED_IN },
    624         { "part",        1, irc_cmd_part,        IRC_CMD_LOGGED_IN },
    625         { "whois",       1, irc_cmd_whois,       IRC_CMD_LOGGED_IN },
    626         { "whowas",      1, irc_cmd_whowas,      IRC_CMD_LOGGED_IN },
    627         { "motd",        0, irc_cmd_motd,        IRC_CMD_LOGGED_IN },
    628         { "mode",        1, irc_cmd_mode,        IRC_CMD_LOGGED_IN },
     598        { "invite",      2, irc_cmd_invite,      IRC_CMD_LOGGED_IN },
     599        { "privmsg",     1, irc_cmd_privmsg,     IRC_CMD_LOGGED_IN },
     600        { "notice",      1, irc_cmd_privmsg,     IRC_CMD_LOGGED_IN },
    629601        { "who",         0, irc_cmd_who,         IRC_CMD_LOGGED_IN },
    630         { "privmsg",     1, irc_cmd_privmsg,     IRC_CMD_LOGGED_IN },
    631         { "nickserv",    1, irc_cmd_nickserv,    IRC_CMD_LOGGED_IN },
    632         { "ns",          1, irc_cmd_nickserv,    IRC_CMD_LOGGED_IN },
    633         { "away",        0, irc_cmd_away,        IRC_CMD_LOGGED_IN },
    634         { "version",     0, irc_cmd_version,     IRC_CMD_LOGGED_IN },
    635         { "completions", 0, irc_cmd_completions, IRC_CMD_LOGGED_IN },
    636602        { "userhost",    1, irc_cmd_userhost,    IRC_CMD_LOGGED_IN },
    637603        { "ison",        1, irc_cmd_ison,        IRC_CMD_LOGGED_IN },
    638604        { "watch",       1, irc_cmd_watch,       IRC_CMD_LOGGED_IN },
    639         { "invite",      2, irc_cmd_invite,      IRC_CMD_LOGGED_IN },
    640 #if 0
    641         { "notice",      1, irc_cmd_privmsg,     IRC_CMD_LOGGED_IN },
    642 #endif
    643605        { "topic",       1, irc_cmd_topic,       IRC_CMD_LOGGED_IN },
    644         { "oper",        2, irc_cmd_oper,        IRC_CMD_LOGGED_IN },
     606        { "away",        0, irc_cmd_away,        IRC_CMD_LOGGED_IN },
     607        { "whois",       1, irc_cmd_whois,       IRC_CMD_LOGGED_IN },
     608        { "whowas",      1, irc_cmd_whowas,      IRC_CMD_LOGGED_IN },
     609        { "nickserv",    1, irc_cmd_nickserv,    IRC_CMD_LOGGED_IN },
     610        { "ns",          1, irc_cmd_nickserv,    IRC_CMD_LOGGED_IN },
     611        { "motd",        0, irc_cmd_motd,        IRC_CMD_LOGGED_IN },
     612        { "pong",        0, irc_cmd_pong,        IRC_CMD_LOGGED_IN },
     613        { "version",     0, irc_cmd_version,     IRC_CMD_LOGGED_IN },
     614        { "completions", 0, irc_cmd_completions, IRC_CMD_LOGGED_IN },
    645615        { "die",         0, NULL,                IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER },
    646616        { "deaf",        0, NULL,                IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER },
     
    668638                        if( irc_commands[i].flags & IRC_CMD_PRE_LOGIN && irc->status & USTATUS_LOGGED_IN )
    669639                        {
    670                                 irc_send_num( irc, 462, ":Only allowed before logging in" );
     640                                irc_reply( irc, 462, ":Only allowed before logging in" );
    671641                        }
    672642                        else if( irc_commands[i].flags & IRC_CMD_LOGGED_IN && !( irc->status & USTATUS_LOGGED_IN ) )
    673643                        {
    674                                 irc_send_num( irc, 451, ":Register first" );
     644                                irc_reply( irc, 451, ":Register first" );
    675645                        }
    676646                        else if( irc_commands[i].flags & IRC_CMD_OPER_ONLY && !strchr( irc->umode, 'o' ) )
    677647                        {
    678                                 irc_send_num( irc, 481, ":Permission denied - You're not an IRC operator" );
     648                                irc_reply( irc, 481, ":Permission denied - You're not an IRC operator" );
    679649                        }
    680650                        else if( n_arg < irc_commands[i].required_parameters )
    681651                        {
    682                                 irc_send_num( irc, 461, "%s :Need more parameters", cmd[0] );
     652                                irc_reply( irc, 461, "%s :Need more parameters", cmd[0] );
    683653                        }
    684654                        else if( irc_commands[i].flags & IRC_CMD_TO_MASTER )
     
    697667       
    698668        if( irc->status >= USTATUS_LOGGED_IN )
    699                 irc_send_num( irc, 421, "%s :Unknown command", cmd[0] );
    700 }
     669                irc_reply( irc, 421, "%s :Unknown command", cmd[0] );
     670}
Note: See TracChangeset for help on using the changeset viewer.