source: irc_commands.c @ 63a520b

Last change on this file since 63a520b was b9e020a, checked in by Wilmer van der Gaast <wilmer@…>, at 2010-03-27T03:04:35Z

Added JOIN, NAMES and PART commands.

  • Property mode set to 100644
File size: 18.1 KB
RevLine 
[0298d11]1  /********************************************************************\
2  * BitlBee -- An IRC to other IM-networks gateway                     *
3  *                                                                    *
[3ddb7477]4  * Copyright 2002-2010 Wilmer van der Gaast and others                *
[0298d11]5  \********************************************************************/
6
7/* IRC commands                                                         */
8
9/*
10  This program is free software; you can redistribute it and/or modify
11  it under the terms of the GNU General Public License as published by
12  the Free Software Foundation; either version 2 of the License, or
13  (at your option) any later version.
14
15  This program is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  GNU General Public License for more details.
19
20  You should have received a copy of the GNU General Public License with
21  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
22  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
23  Suite 330, Boston, MA  02111-1307  USA
24*/
25
26#define BITLBEE_CORE
27#include "bitlbee.h"
[0431ea1]28#include "ipc.h"
[b75acf6]29#include "chat.h"
[0298d11]30
[f73b969]31static void irc_cmd_pass( irc_t *irc, char **cmd )
[0298d11]32{
[a199d33]33        if( irc->status & USTATUS_LOGGED_IN )
34        {
35                char *send_cmd[] = { "identify", cmd[1], NULL };
36               
37                /* We're already logged in, this client seems to send the PASS
38                   command last. (Possibly it won't send it at all if it turns
39                   out we don't require it, which will break this feature.)
40                   Try to identify using the given password. */
[3ddb7477]41                /*return root_command( irc, send_cmd );*/
[a199d33]42        }
43        /* Handling in pre-logged-in state, first see if this server is
44           password-protected: */
45        else if( global.conf->auth_pass &&
[c029350]46            ( strncmp( global.conf->auth_pass, "md5:", 4 ) == 0 ?
47                md5_verify_password( cmd[1], global.conf->auth_pass + 4 ) == 0 :
48                strcmp( cmd[1], global.conf->auth_pass ) == 0 ) )
[0298d11]49        {
[79e826a]50                irc->status |= USTATUS_AUTHORIZED;
[de3e100]51                irc_check_login( irc );
[0298d11]52        }
[a199d33]53        else if( global.conf->auth_pass )
[0298d11]54        {
[3ddb7477]55                irc_send_num( irc, 464, ":Incorrect password" );
[0298d11]56        }
[a199d33]57        else
58        {
59                /* Remember the password and try to identify after USER/NICK. */
[3ddb7477]60                /*irc_setpass( irc, cmd[1] ); */
[a199d33]61                irc_check_login( irc );
62        }
[0298d11]63}
64
[f73b969]65static void irc_cmd_user( irc_t *irc, char **cmd )
[0298d11]66{
[3ddb7477]67        irc->user->user = g_strdup( cmd[1] );
68        irc->user->fullname = g_strdup( cmd[4] );
[edf9657]69       
70        irc_check_login( irc );
[0298d11]71}
72
[f73b969]73static void irc_cmd_nick( irc_t *irc, char **cmd )
[0298d11]74{
[3ddb7477]75        if( irc->user->nick )
[0298d11]76        {
[3ddb7477]77                irc_send_num( irc, 438, ":The hand of the deity is upon thee, thy nick may not change" );
[0298d11]78        }
[3ddb7477]79        else if( irc_user_find( irc, cmd[1] ) )
[0298d11]80        {
[3ddb7477]81                irc_send_num( irc, 433, ":This nick is already in use" );
[0298d11]82        }
83        else if( !nick_ok( cmd[1] ) )
84        {
85                /* [SH] Invalid characters. */
[3ddb7477]86                irc_send_num( irc, 432, ":This nick contains invalid characters" );
[0298d11]87        }
88        else
89        {
[3ddb7477]90                irc->user->nick = g_strdup( cmd[1] );
[edf9657]91               
92                irc_check_login( irc );
[0298d11]93        }
94}
95
[f73b969]96static void irc_cmd_quit( irc_t *irc, char **cmd )
[0298d11]97{
[f73b969]98        if( cmd[1] && *cmd[1] )
99                irc_abort( irc, 0, "Quit: %s", cmd[1] );
100        else
101                irc_abort( irc, 0, "Leaving..." );
[0298d11]102}
103
[f73b969]104static void irc_cmd_ping( irc_t *irc, char **cmd )
[0298d11]105{
[ebaebfe]106        irc_write( irc, ":%s PONG %s :%s", irc->root->host,
107                   irc->root->host, cmd[1]?cmd[1]:irc->root->host );
[0298d11]108}
109
[b9e020a]110static void irc_cmd_join( irc_t *irc, char **cmd )
111{
112        irc_channel_t *ic;
113       
114        if( ( ic = irc_channel_by_name( irc, cmd[1] ) ) == NULL )
115                ic = irc_channel_new( irc, cmd[1] );
116       
117        if( ic == NULL )
118                irc_send_num( irc, 479, "%s :Invalid channel name", cmd[1] );
119       
120        if( ic->flags & IRC_CHANNEL_JOINED )
121                return; /* Dude, you're already there...
122                           RFC doesn't have any reply for that though? */
123       
124        irc_channel_add_user( ic, irc->user );
125}
126
127static void irc_cmd_names( irc_t *irc, char **cmd )
128{
129        irc_channel_t *ic;
130       
131        if( cmd[1] && ( ic = irc_channel_by_name( irc, cmd[1] ) ) )
132                irc_send_names( ic );
133        /* With no args, we should show /names of all chans. Make the code
134           below work well if necessary.
135        else
136        {
137                GSList *l;
138               
139                for( l = irc->channels; l; l = l->next )
140                        irc_send_names( l->data );
141        }
142        */
143}
144
145static void irc_cmd_part( irc_t *irc, char **cmd )
146{
147        irc_channel_t *ic;
148       
149        if( ( ic = irc_channel_by_name( irc, cmd[1] ) ) == NULL )
150        {
151                irc_send_num( irc, 403, "%s :No such channel", cmd[1] );
152        }
153        else if( !irc_channel_del_user( ic, irc->user ) )
154        {
155                irc_send_num( irc, 442, "%s :You're not on that channel", cmd[1] );
156        }
157}
158
[ebaebfe]159#if 0
[b9e020a]160//#if 0
[f73b969]161static void irc_cmd_oper( irc_t *irc, char **cmd )
[0298d11]162{
[ec0355f]163        if( global.conf->oper_pass &&
[c029350]164            ( strncmp( global.conf->oper_pass, "md5:", 4 ) == 0 ?
165                md5_verify_password( cmd[2], global.conf->oper_pass + 4 ) == 0 :
166                strcmp( cmd[2], global.conf->oper_pass ) == 0 ) )
[b23c5c7]167        {
[0298d11]168                irc_umode_set( irc, "+o", 1 );
[3ddb7477]169                irc_send_num( irc, 381, ":Password accepted" );
[b23c5c7]170        }
171        else
172        {
[3ddb7477]173                irc_send_num( irc, 432, ":Incorrect password" );
[b23c5c7]174        }
[0298d11]175}
176
[f73b969]177static void irc_cmd_mode( irc_t *irc, char **cmd )
[0298d11]178{
[39f93f0]179        if( strchr( CTYPES, *cmd[1] ) )
[0298d11]180        {
181                if( cmd[2] )
182                {
183                        if( *cmd[2] == '+' || *cmd[2] == '-' )
[3ddb7477]184                                irc_send_num( irc, 477, "%s :Can't change channel modes", cmd[1] );
[0298d11]185                        else if( *cmd[2] == 'b' )
[3ddb7477]186                                irc_send_num( irc, 368, "%s :No bans possible", cmd[1] );
[0298d11]187                }
188                else
[3ddb7477]189                        irc_send_num( irc, 324, "%s +%s", cmd[1], CMODE );
[0298d11]190        }
191        else
192        {
193                if( nick_cmp( cmd[1], irc->nick ) == 0 )
194                {
195                        if( cmd[2] )
196                                irc_umode_set( irc, cmd[2], 0 );
[2f13222]197                        else
[3ddb7477]198                                irc_send_num( irc, 221, "+%s", irc->umode );
[0298d11]199                }
200                else
[3ddb7477]201                        irc_send_num( irc, 502, ":Don't touch their modes" );
[0298d11]202        }
203}
204
[f73b969]205static void irc_cmd_invite( irc_t *irc, char **cmd )
[0298d11]206{
207        char *nick = cmd[1], *channel = cmd[2];
[0e7ab64]208        struct groupchat *c = irc_chat_by_channel( irc, channel );
[0298d11]209        user_t *u = user_find( irc, nick );
210       
[0da65d5]211        if( u && c && ( u->ic == c->ic ) )
212                if( c->ic && c->ic->acc->prpl->chat_invite )
[0298d11]213                {
[c058ff9]214                        c->ic->acc->prpl->chat_invite( c, u->handle, NULL );
[3ddb7477]215                        irc_send_num( irc, 341, "%s %s", nick, channel );
[f73b969]216                        return;
[0298d11]217                }
218       
[3ddb7477]219        irc_send_num( irc, 482, "%s :Invite impossible; User/Channel non-existent or incompatible", channel );
[0298d11]220}
221
[f73b969]222static void irc_cmd_privmsg( irc_t *irc, char **cmd )
[0298d11]223{
224        if ( !cmd[2] )
225        {
[3ddb7477]226                irc_send_num( irc, 412, ":No text to send" );
[0298d11]227        }
228        else if ( irc->nick && g_strcasecmp( cmd[1], irc->nick ) == 0 )
229        {
230                irc_write( irc, ":%s!%s@%s %s %s :%s", irc->nick, irc->user, irc->host, cmd[0], cmd[1], cmd[2] );
231        }
232        else
233        {
234                if( g_strcasecmp( cmd[1], irc->channel ) == 0 )
235                {
236                        unsigned int i;
[5c9512f]237                        char *t = set_getstr( &irc->set, "default_target" );
[0298d11]238                       
239                        if( g_strcasecmp( t, "last" ) == 0 && irc->last_target )
240                                cmd[1] = irc->last_target;
241                        else if( g_strcasecmp( t, "root" ) == 0 )
242                                cmd[1] = irc->mynick;
243                       
244                        for( i = 0; i < strlen( cmd[2] ); i ++ )
245                        {
246                                if( cmd[2][i] == ' ' ) break;
247                                if( cmd[2][i] == ':' || cmd[2][i] == ',' )
248                                {
249                                        cmd[1] = cmd[2];
250                                        cmd[2] += i;
251                                        *cmd[2] = 0;
252                                        while( *(++cmd[2]) == ' ' );
253                                        break;
254                                }
255                        }
256                       
257                        irc->is_private = 0;
258                       
259                        if( cmd[1] != irc->last_target )
260                        {
[f9756bd]261                                g_free( irc->last_target );
[0298d11]262                                irc->last_target = g_strdup( cmd[1] );
263                        }
264                }
265                else
266                {
267                        irc->is_private = 1;
268                }
[6bbb939]269                irc_send( irc, cmd[1], cmd[2], ( g_strcasecmp( cmd[0], "NOTICE" ) == 0 ) ? OPT_AWAY : 0 );
[0298d11]270        }
271}
272
[f73b969]273static void irc_cmd_who( irc_t *irc, char **cmd )
[0298d11]274{
275        char *channel = cmd[1];
276        user_t *u = irc->users;
[0da65d5]277        struct groupchat *c;
[0298d11]278        GList *l;
279       
280        if( !channel || *channel == '0' || *channel == '*' || !*channel )
281                while( u )
282                {
[3ddb7477]283                        irc_send_num( 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 );
[0298d11]284                        u = u->next;
285                }
286        else if( g_strcasecmp( channel, irc->channel ) == 0 )
287                while( u )
288                {
289                        if( u->online )
[3ddb7477]290                                irc_send_num( 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 );
[0298d11]291                        u = u->next;
292                }
[0e7ab64]293        else if( ( c = irc_chat_by_channel( irc, channel ) ) )
[0298d11]294                for( l = c->in_room; l; l = l->next )
295                {
[0da65d5]296                        if( ( u = user_findhandle( c->ic, l->data ) ) )
[3ddb7477]297                                irc_send_num( 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 );
[0298d11]298                }
299        else if( ( u = user_find( irc, channel ) ) )
[3ddb7477]300                irc_send_num( 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 );
[0298d11]301       
[3ddb7477]302        irc_send_num( irc, 315, "%s :End of /WHO list", channel?channel:"**" );
[0298d11]303}
304
[f73b969]305static void irc_cmd_userhost( irc_t *irc, char **cmd )
[0298d11]306{
307        user_t *u;
308        int i;
309       
310        /* [TV] Usable USERHOST-implementation according to
311                RFC1459. Without this, mIRC shows an error
312                while connecting, and the used way of rejecting
313                breaks standards.
314        */
315       
316        for( i = 1; cmd[i]; i ++ )
317                if( ( u = user_find( irc, cmd[i] ) ) )
318                {
319                        if( u->online && u->away )
[3ddb7477]320                                irc_send_num( irc, 302, ":%s=-%s@%s", u->nick, u->user, u->host );
[0298d11]321                        else
[3ddb7477]322                                irc_send_num( irc, 302, ":%s=+%s@%s", u->nick, u->user, u->host );
[0298d11]323                }
324}
325
[f73b969]326static void irc_cmd_ison( irc_t *irc, char **cmd )
[0298d11]327{
328        user_t *u;
[b4e4b95]329        char buff[IRC_MAX_LINE];
[0298d11]330        int lenleft, i;
331       
332        buff[0] = '\0';
333       
334        /* [SH] Leave room for : and \0 */
335        lenleft = IRC_MAX_LINE - 2;
336       
337        for( i = 1; cmd[i]; i ++ )
338        {
[42616d1]339                char *this, *next;
340               
341                this = cmd[i];
342                while( *this )
[0298d11]343                {
[42616d1]344                        if( ( next = strchr( this, ' ' ) ) )
345                                *next = 0;
[0298d11]346                       
[42616d1]347                        if( ( u = user_find( irc, this ) ) && u->online )
[0298d11]348                        {
[42616d1]349                                lenleft -= strlen( u->nick ) + 1;
350                               
351                                if( lenleft < 0 )
352                                        break;
353                               
354                                strcat( buff, u->nick );
355                                strcat( buff, " " );
[0298d11]356                        }
357                       
[42616d1]358                        if( next )
359                        {
360                                *next = ' ';
361                                this = next + 1;
362                        }
363                        else
364                        {
365                                break;
366                        }   
[0298d11]367                }
[42616d1]368               
369                /* *sigh* */
370                if( lenleft < 0 )
371                        break;
[0298d11]372        }
373       
374        if( strlen( buff ) > 0 )
375                buff[strlen(buff)-1] = '\0';
376       
[3ddb7477]377        irc_send_num( irc, 303, ":%s", buff );
[0298d11]378}
379
[f73b969]380static void irc_cmd_watch( irc_t *irc, char **cmd )
[0298d11]381{
382        int i;
383       
384        /* Obviously we could also mark a user structure as being
385           watched, but what if the WATCH command is sent right
386           after connecting? The user won't exist yet then... */
387        for( i = 1; cmd[i]; i ++ )
388        {
389                char *nick;
390                user_t *u;
391               
392                if( !cmd[i][0] || !cmd[i][1] )
393                        break;
394               
395                nick = g_strdup( cmd[i] + 1 );
396                nick_lc( nick );
397               
398                u = user_find( irc, nick );
399               
400                if( cmd[i][0] == '+' )
401                {
402                        if( !g_hash_table_lookup( irc->watches, nick ) )
403                                g_hash_table_insert( irc->watches, nick, nick );
404                       
405                        if( u && u->online )
[3ddb7477]406                                irc_send_num( irc, 604, "%s %s %s %d :%s", u->nick, u->user, u->host, (int) time( NULL ), "is online" );
[0298d11]407                        else
[3ddb7477]408                                irc_send_num( irc, 605, "%s %s %s %d :%s", nick, "*", "*", (int) time( NULL ), "is offline" );
[0298d11]409                }
410                else if( cmd[i][0] == '-' )
411                {
412                        gpointer okey, ovalue;
413                       
414                        if( g_hash_table_lookup_extended( irc->watches, nick, &okey, &ovalue ) )
415                        {
416                                g_hash_table_remove( irc->watches, okey );
[e59b4f6]417                                g_free( okey );
[0298d11]418                               
[3ddb7477]419                                irc_send_num( irc, 602, "%s %s %s %d :%s", nick, "*", "*", 0, "Stopped watching" );
[0298d11]420                        }
421                }
422        }
423}
424
[f73b969]425static void irc_cmd_topic( irc_t *irc, char **cmd )
[0298d11]426{
[50e1776]427        char *channel = cmd[1];
428        char *topic = cmd[2];
429       
430        if( topic )
431        {
432                /* Send the topic */
433                struct groupchat *c = irc_chat_by_channel( irc, channel );
434                if( c && c->ic && c->ic->acc->prpl->chat_topic )
435                        c->ic->acc->prpl->chat_topic( c, topic );
436        }
[0298d11]437        else
[50e1776]438        {
439                /* Get the topic */
440                irc_topic( irc, channel );
441        }
[0298d11]442}
443
[f73b969]444static void irc_cmd_away( irc_t *irc, char **cmd )
[0298d11]445{
446        user_t *u = user_find( irc, irc->nick );
447        char *away = cmd[1];
448       
[f73b969]449        if( !u ) return;
[0298d11]450       
451        if( away && *away )
452        {
453                int i, j;
454               
455                /* Copy away string, but skip control chars. Mainly because
456                   Jabber really doesn't like them. */
457                u->away = g_malloc( strlen( away ) + 1 );
458                for( i = j = 0; away[i]; i ++ )
459                        if( ( u->away[j] = away[i] ) >= ' ' )
460                                j ++;
461                u->away[j] = 0;
462               
[3ddb7477]463                irc_send_num( irc, 306, ":You're now away: %s", u->away );
[0298d11]464                /* irc_umode_set( irc, irc->myhost, "+a" ); */
465        }
466        else
467        {
468                if( u->away ) g_free( u->away );
469                u->away = NULL;
470                /* irc_umode_set( irc, irc->myhost, "-a" ); */
[3ddb7477]471                irc_send_num( irc, 305, ":Welcome back" );
[0298d11]472        }
473       
[58adb7e]474        set_setstr( &irc->set, "away", u->away );
[0298d11]475}
476
[f73b969]477static void irc_cmd_whois( irc_t *irc, char **cmd )
[0298d11]478{
479        char *nick = cmd[1];
480        user_t *u = user_find( irc, nick );
481       
482        if( u )
483        {
[3ddb7477]484                irc_send_num( irc, 311, "%s %s %s * :%s", u->nick, u->user, u->host, u->realname );
[0298d11]485               
[0da65d5]486                if( u->ic )
[3ddb7477]487                        irc_send_num( irc, 312, "%s %s.%s :%s network", u->nick, u->ic->acc->user,
[0da65d5]488                                   u->ic->acc->server && *u->ic->acc->server ? u->ic->acc->server : "",
489                                   u->ic->acc->prpl->name );
[0298d11]490                else
[3ddb7477]491                        irc_send_num( irc, 312, "%s %s :%s", u->nick, irc->myhost, IRCD_INFO );
[0298d11]492               
493                if( !u->online )
[3ddb7477]494                        irc_send_num( irc, 301, "%s :%s", u->nick, "User is offline" );
[0298d11]495                else if( u->away )
[3ddb7477]496                        irc_send_num( irc, 301, "%s :%s", u->nick, u->away );
[449a51d]497                if( u->status_msg )
[3ddb7477]498                        irc_send_num( irc, 333, "%s :Status: %s", u->nick, u->status_msg );
[0298d11]499               
[3ddb7477]500                irc_send_num( irc, 318, "%s :End of /WHOIS list", nick );
[0298d11]501        }
502        else
503        {
[3ddb7477]504                irc_send_num( irc, 401, "%s :Nick does not exist", nick );
[0298d11]505        }
506}
507
[f73b969]508static void irc_cmd_whowas( irc_t *irc, char **cmd )
[0298d11]509{
510        /* For some reason irssi tries a whowas when whois fails. We can
511           ignore this, but then the user never gets a "user not found"
512           message from irssi which is a bit annoying. So just respond
513           with not-found and irssi users will get better error messages */
514       
[3ddb7477]515        irc_send_num( irc, 406, "%s :Nick does not exist", cmd[1] );
516        irc_send_num( irc, 369, "%s :End of WHOWAS", cmd[1] );
[0298d11]517}
518
[f73b969]519static void irc_cmd_nickserv( irc_t *irc, char **cmd )
[0298d11]520{
521        /* [SH] This aliases the NickServ command to PRIVMSG root */
522        /* [TV] This aliases the NS command to PRIVMSG root as well */
523        root_command( irc, cmd + 1 );
524}
525
[f73b969]526static void irc_cmd_motd( irc_t *irc, char **cmd )
[0298d11]527{
528        irc_motd( irc );
529}
530
[f73b969]531static void irc_cmd_pong( irc_t *irc, char **cmd )
[0298d11]532{
533        /* We could check the value we get back from the user, but in
534           fact we don't care, we're just happy he's still alive. */
535        irc->last_pong = gettime();
536        irc->pinging = 0;
537}
538
[82898af]539static void irc_cmd_version( irc_t *irc, char **cmd )
540{
[3ddb7477]541        irc_send_num( irc, 351, "bitlbee-%s. %s :%s/%s ", BITLBEE_VERSION, irc->myhost, ARCH, CPU );
[82898af]542}
543
[f73b969]544static void irc_cmd_completions( irc_t *irc, char **cmd )
[0298d11]545{
546        user_t *u = user_find( irc, irc->mynick );
547        help_t *h;
548        set_t *s;
549        int i;
550       
551        irc_privmsg( irc, u, "NOTICE", irc->nick, "COMPLETIONS ", "OK" );
552       
553        for( i = 0; commands[i].command; i ++ )
554                irc_privmsg( irc, u, "NOTICE", irc->nick, "COMPLETIONS ", commands[i].command );
555       
556        for( h = global.help; h; h = h->next )
[0fbda193]557                irc_privmsg( irc, u, "NOTICE", irc->nick, "COMPLETIONS help ", h->title );
[0298d11]558       
559        for( s = irc->set; s; s = s->next )
560                irc_privmsg( irc, u, "NOTICE", irc->nick, "COMPLETIONS set ", s->key );
561       
562        irc_privmsg( irc, u, "NOTICE", irc->nick, "COMPLETIONS ", "END" );
563}
564
[f73b969]565static void irc_cmd_rehash( irc_t *irc, char **cmd )
[f4a5940]566{
[5424c76]567        if( global.conf->runmode == RUNMODE_INETD )
568                ipc_master_cmd_rehash( NULL, NULL );
569        else
570                ipc_to_master( cmd );
[f4a5940]571       
[3ddb7477]572        irc_send_num( irc, 382, "%s :Rehashing", global.conf_file );
[f4a5940]573}
[3ddb7477]574#endif
[f4a5940]575
[0298d11]576static const command_t irc_commands[] = {
[a199d33]577        { "pass",        1, irc_cmd_pass,        0 },
[0298d11]578        { "user",        4, irc_cmd_user,        IRC_CMD_PRE_LOGIN },
579        { "nick",        1, irc_cmd_nick,        0 },
580        { "quit",        0, irc_cmd_quit,        0 },
581        { "ping",        0, irc_cmd_ping,        0 },
[b9e020a]582        { "join",        1, irc_cmd_join,        IRC_CMD_LOGGED_IN },
583        { "names",       1, irc_cmd_names,       IRC_CMD_LOGGED_IN },
584        { "part",        1, irc_cmd_part,        IRC_CMD_LOGGED_IN },
[ebaebfe]585#if 0
[0298d11]586        { "oper",        2, irc_cmd_oper,        IRC_CMD_LOGGED_IN },
587        { "mode",        1, irc_cmd_mode,        IRC_CMD_LOGGED_IN },
588        { "invite",      2, irc_cmd_invite,      IRC_CMD_LOGGED_IN },
589        { "privmsg",     1, irc_cmd_privmsg,     IRC_CMD_LOGGED_IN },
590        { "notice",      1, irc_cmd_privmsg,     IRC_CMD_LOGGED_IN },
591        { "who",         0, irc_cmd_who,         IRC_CMD_LOGGED_IN },
592        { "userhost",    1, irc_cmd_userhost,    IRC_CMD_LOGGED_IN },
593        { "ison",        1, irc_cmd_ison,        IRC_CMD_LOGGED_IN },
594        { "watch",       1, irc_cmd_watch,       IRC_CMD_LOGGED_IN },
595        { "topic",       1, irc_cmd_topic,       IRC_CMD_LOGGED_IN },
596        { "away",        0, irc_cmd_away,        IRC_CMD_LOGGED_IN },
597        { "whois",       1, irc_cmd_whois,       IRC_CMD_LOGGED_IN },
598        { "whowas",      1, irc_cmd_whowas,      IRC_CMD_LOGGED_IN },
599        { "nickserv",    1, irc_cmd_nickserv,    IRC_CMD_LOGGED_IN },
600        { "ns",          1, irc_cmd_nickserv,    IRC_CMD_LOGGED_IN },
601        { "motd",        0, irc_cmd_motd,        IRC_CMD_LOGGED_IN },
602        { "pong",        0, irc_cmd_pong,        IRC_CMD_LOGGED_IN },
[82898af]603        { "version",     0, irc_cmd_version,     IRC_CMD_LOGGED_IN },
[0298d11]604        { "completions", 0, irc_cmd_completions, IRC_CMD_LOGGED_IN },
[0431ea1]605        { "die",         0, NULL,                IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER },
[565a1ea]606        { "deaf",        0, NULL,                IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER },
[48721c3]607        { "wallops",     1, NULL,                IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER },
[dfc8a46]608        { "wall",        1, NULL,                IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER },
[f4a5940]609        { "rehash",      0, irc_cmd_rehash,      IRC_CMD_OPER_ONLY },
[54879ab]610        { "restart",     0, NULL,                IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER },
[48721c3]611        { "kill",        2, NULL,                IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER },
[3ddb7477]612#endif
[0298d11]613        { NULL }
614};
615
[f73b969]616void irc_exec( irc_t *irc, char *cmd[] )
[0298d11]617{       
[f1d38f2]618        int i, n_arg;
[0298d11]619       
620        if( !cmd[0] )
[f73b969]621                return;
[0298d11]622       
623        for( i = 0; irc_commands[i].command; i++ )
624                if( g_strcasecmp( irc_commands[i].command, cmd[0] ) == 0 )
625                {
[f1d38f2]626                        /* There should be no typo in the next line: */
627                        for( n_arg = 0; cmd[n_arg]; n_arg ++ ); n_arg --;
628                       
[79e826a]629                        if( irc_commands[i].flags & IRC_CMD_PRE_LOGIN && irc->status & USTATUS_LOGGED_IN )
[edf9657]630                        {
[3ddb7477]631                                irc_send_num( irc, 462, ":Only allowed before logging in" );
[edf9657]632                        }
[3af70b0]633                        else if( irc_commands[i].flags & IRC_CMD_LOGGED_IN && !( irc->status & USTATUS_LOGGED_IN ) )
[edf9657]634                        {
[3ddb7477]635                                irc_send_num( irc, 451, ":Register first" );
[edf9657]636                        }
[f73b969]637                        else if( irc_commands[i].flags & IRC_CMD_OPER_ONLY && !strchr( irc->umode, 'o' ) )
[edf9657]638                        {
[3ddb7477]639                                irc_send_num( irc, 481, ":Permission denied - You're not an IRC operator" );
[edf9657]640                        }
[f1d38f2]641                        else if( n_arg < irc_commands[i].required_parameters )
[f73b969]642                        {
[3ddb7477]643                                irc_send_num( irc, 461, "%s :Need more parameters", cmd[0] );
[f73b969]644                        }
645                        else if( irc_commands[i].flags & IRC_CMD_TO_MASTER )
646                        {
[5424c76]647                                /* IPC doesn't make sense in inetd mode,
648                                    but the function will catch that. */
[0431ea1]649                                ipc_to_master( cmd );
[f73b969]650                        }
[0431ea1]651                        else
[f73b969]652                        {
653                                irc_commands[i].execute( irc, cmd );
654                        }
655                       
[2f13222]656                        return;
[0298d11]657                }
[2f13222]658       
659        if( irc->status >= USTATUS_LOGGED_IN )
[3ddb7477]660                irc_send_num( irc, 421, "%s :Unknown command", cmd[0] );
[0298d11]661}
Note: See TracBrowser for help on using the repository browser.