source: irc_commands.c @ 7a6ba50

Last change on this file since 7a6ba50 was 58646d9, checked in by Wilmer van der Gaast <wilmer@…>, at 2010-06-28T09:37:11Z

Allow joining multiple channels at once. Although BitlBee doesn't advertise
support for this, irssi tries to do this anyway.

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