source: irc_commands.c @ 5a673f3

Last change on this file since 5a673f3 was 47fae0f, checked in by Wilmer van der Gaast <wilmer@…>, at 2010-05-09T12:05:50Z

No. Run the part handler from the IRC /PART command, not from irc_channel.c.
This was causing troubles with Twitter at disconnect time.

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