source: irc_commands.c @ b919363

Last change on this file since b919363 was b919363, checked in by Wilmer van der Gaast <wilmer@…>, at 2010-03-27T14:31:03Z

Mode stuff. Also disallow unsetting +R umode which was possible so far
(and shouldn't be).

  • Property mode set to 100644
File size: 17.6 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->nick )
76        {
77                irc_send_num( irc, 438, ":The hand of the deity is upon thee, thy nick may not change" );
78        }
79        else if( irc_user_find( irc, cmd[1] ) )
80        {
81                irc_send_num( irc, 433, ":This nick is already in use" );
82        }
83        else if( !nick_ok( cmd[1] ) )
84        {
85                /* [SH] Invalid characters. */
86                irc_send_num( irc, 432, ":This nick contains invalid characters" );
87        }
88        else
89        {
90                irc->user->nick = g_strdup( cmd[1] );
91               
92                irc_check_login( irc );
93        }
94}
95
96static void irc_cmd_quit( irc_t *irc, char **cmd )
97{
98        if( cmd[1] && *cmd[1] )
99                irc_abort( irc, 0, "Quit: %s", cmd[1] );
100        else
101                irc_abort( irc, 0, "Leaving..." );
102}
103
104static void irc_cmd_ping( irc_t *irc, char **cmd )
105{
106        irc_write( irc, ":%s PONG %s :%s", irc->root->host,
107                   irc->root->host, cmd[1]?cmd[1]:irc->root->host );
108}
109
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
159static void irc_cmd_whois( irc_t *irc, char **cmd )
160{
161        char *nick = cmd[1];
162        irc_user_t *iu = irc_user_find( irc, nick );
163       
164        if( iu )
165                irc_send_whois( iu );
166        else
167                irc_send_num( irc, 401, "%s :Nick does not exist", nick );
168}
169
170static void irc_cmd_whowas( irc_t *irc, char **cmd )
171{
172        /* For some reason irssi tries a whowas when whois fails. We can
173           ignore this, but then the user never gets a "user not found"
174           message from irssi which is a bit annoying. So just respond
175           with not-found and irssi users will get better error messages */
176       
177        irc_send_num( irc, 406, "%s :Nick does not exist", cmd[1] );
178        irc_send_num( irc, 369, "%s :End of WHOWAS", cmd[1] );
179}
180
181static void irc_cmd_motd( irc_t *irc, char **cmd )
182{
183        irc_send_motd( irc );
184}
185
186static void irc_cmd_mode( irc_t *irc, char **cmd )
187{
188        if( irc_channel_name_ok( cmd[1] ) )
189        {
190                irc_channel_t *ic;
191               
192                if( ( ic = irc_channel_by_name( irc, cmd[1] ) ) == NULL )
193                        irc_send_num( irc, 403, "%s :No such channel", cmd[1] );
194                else if( cmd[2] )
195                {
196                        if( *cmd[2] == '+' || *cmd[2] == '-' )
197                                irc_send_num( irc, 477, "%s :Can't change channel modes", cmd[1] );
198                        else if( *cmd[2] == 'b' )
199                                irc_send_num( irc, 368, "%s :No bans possible", cmd[1] );
200                }
201                else
202                        irc_send_num( irc, 324, "%s +%s", cmd[1], ic->mode );
203        }
204        else
205        {
206                if( nick_cmp( cmd[1], irc->user->nick ) == 0 )
207                {
208                        if( cmd[2] )
209                                irc_umode_set( irc, cmd[2], 0 );
210                        else
211                                irc_send_num( irc, 221, "+%s", irc->umode );
212                }
213                else
214                        irc_send_num( irc, 502, ":Don't touch their modes" );
215        }
216}
217
218#if 0
219//#if 0
220static void irc_cmd_oper( irc_t *irc, char **cmd )
221{
222        if( global.conf->oper_pass &&
223            ( strncmp( global.conf->oper_pass, "md5:", 4 ) == 0 ?
224                md5_verify_password( cmd[2], global.conf->oper_pass + 4 ) == 0 :
225                strcmp( cmd[2], global.conf->oper_pass ) == 0 ) )
226        {
227                irc_umode_set( irc, "+o", 1 );
228                irc_send_num( irc, 381, ":Password accepted" );
229        }
230        else
231        {
232                irc_send_num( irc, 432, ":Incorrect password" );
233        }
234}
235
236static void irc_cmd_invite( irc_t *irc, char **cmd )
237{
238        char *nick = cmd[1], *channel = cmd[2];
239        struct groupchat *c = irc_chat_by_channel( irc, channel );
240        user_t *u = user_find( irc, nick );
241       
242        if( u && c && ( u->ic == c->ic ) )
243                if( c->ic && c->ic->acc->prpl->chat_invite )
244                {
245                        c->ic->acc->prpl->chat_invite( c, u->handle, NULL );
246                        irc_send_num( irc, 341, "%s %s", nick, channel );
247                        return;
248                }
249       
250        irc_send_num( irc, 482, "%s :Invite impossible; User/Channel non-existent or incompatible", channel );
251}
252
253static void irc_cmd_privmsg( irc_t *irc, char **cmd )
254{
255        if( !cmd[2] )
256        {
257                irc_send_num( irc, 412, ":No text to send" );
258        }
259        else if( irc->nick && g_strcasecmp( cmd[1], irc->nick ) == 0 )
260        {
261                irc_write( irc, ":%s!%s@%s %s %s :%s", irc->nick, irc->user, irc->host, cmd[0], cmd[1], cmd[2] );
262        }
263        else
264        {
265                if( g_strcasecmp( cmd[1], irc->channel ) == 0 )
266                {
267                        unsigned int i;
268                        char *t = set_getstr( &irc->set, "default_target" );
269                       
270                        if( g_strcasecmp( t, "last" ) == 0 && irc->last_target )
271                                cmd[1] = irc->last_target;
272                        else if( g_strcasecmp( t, "root" ) == 0 )
273                                cmd[1] = irc->mynick;
274                       
275                        for( i = 0; i < strlen( cmd[2] ); i ++ )
276                        {
277                                if( cmd[2][i] == ' ' ) break;
278                                if( cmd[2][i] == ':' || cmd[2][i] == ',' )
279                                {
280                                        cmd[1] = cmd[2];
281                                        cmd[2] += i;
282                                        *cmd[2] = 0;
283                                        while( *(++cmd[2]) == ' ' );
284                                        break;
285                                }
286                        }
287                       
288                        irc->is_private = 0;
289                       
290                        if( cmd[1] != irc->last_target )
291                        {
292                                g_free( irc->last_target );
293                                irc->last_target = g_strdup( cmd[1] );
294                        }
295                }
296                else
297                {
298                        irc->is_private = 1;
299                }
300                irc_send( irc, cmd[1], cmd[2], ( g_strcasecmp( cmd[0], "NOTICE" ) == 0 ) ? OPT_AWAY : 0 );
301        }
302}
303
304static void irc_cmd_who( irc_t *irc, char **cmd )
305{
306        char *channel = cmd[1];
307        user_t *u = irc->users;
308        struct groupchat *c;
309        GList *l;
310       
311        if( !channel || *channel == '0' || *channel == '*' || !*channel )
312                while( u )
313                {
314                        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 );
315                        u = u->next;
316                }
317        else if( g_strcasecmp( channel, irc->channel ) == 0 )
318                while( u )
319                {
320                        if( u->online )
321                                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 );
322                        u = u->next;
323                }
324        else if( ( c = irc_chat_by_channel( irc, channel ) ) )
325                for( l = c->in_room; l; l = l->next )
326                {
327                        if( ( u = user_findhandle( c->ic, l->data ) ) )
328                                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 );
329                }
330        else if( ( u = user_find( irc, channel ) ) )
331                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 );
332       
333        irc_send_num( irc, 315, "%s :End of /WHO list", channel?channel:"**" );
334}
335
336static void irc_cmd_userhost( irc_t *irc, char **cmd )
337{
338        user_t *u;
339        int i;
340       
341        /* [TV] Usable USERHOST-implementation according to
342                RFC1459. Without this, mIRC shows an error
343                while connecting, and the used way of rejecting
344                breaks standards.
345        */
346       
347        for( i = 1; cmd[i]; i ++ )
348                if( ( u = user_find( irc, cmd[i] ) ) )
349                {
350                        if( u->online && u->away )
351                                irc_send_num( irc, 302, ":%s=-%s@%s", u->nick, u->user, u->host );
352                        else
353                                irc_send_num( irc, 302, ":%s=+%s@%s", u->nick, u->user, u->host );
354                }
355}
356
357static void irc_cmd_ison( irc_t *irc, char **cmd )
358{
359        user_t *u;
360        char buff[IRC_MAX_LINE];
361        int lenleft, i;
362       
363        buff[0] = '\0';
364       
365        /* [SH] Leave room for : and \0 */
366        lenleft = IRC_MAX_LINE - 2;
367       
368        for( i = 1; cmd[i]; i ++ )
369        {
370                char *this, *next;
371               
372                this = cmd[i];
373                while( *this )
374                {
375                        if( ( next = strchr( this, ' ' ) ) )
376                                *next = 0;
377                       
378                        if( ( u = user_find( irc, this ) ) && u->online )
379                        {
380                                lenleft -= strlen( u->nick ) + 1;
381                               
382                                if( lenleft < 0 )
383                                        break;
384                               
385                                strcat( buff, u->nick );
386                                strcat( buff, " " );
387                        }
388                       
389                        if( next )
390                        {
391                                *next = ' ';
392                                this = next + 1;
393                        }
394                        else
395                        {
396                                break;
397                        }   
398                }
399               
400                /* *sigh* */
401                if( lenleft < 0 )
402                        break;
403        }
404       
405        if( strlen( buff ) > 0 )
406                buff[strlen(buff)-1] = '\0';
407       
408        irc_send_num( irc, 303, ":%s", buff );
409}
410
411static void irc_cmd_watch( irc_t *irc, char **cmd )
412{
413        int i;
414       
415        /* Obviously we could also mark a user structure as being
416           watched, but what if the WATCH command is sent right
417           after connecting? The user won't exist yet then... */
418        for( i = 1; cmd[i]; i ++ )
419        {
420                char *nick;
421                user_t *u;
422               
423                if( !cmd[i][0] || !cmd[i][1] )
424                        break;
425               
426                nick = g_strdup( cmd[i] + 1 );
427                nick_lc( nick );
428               
429                u = user_find( irc, nick );
430               
431                if( cmd[i][0] == '+' )
432                {
433                        if( !g_hash_table_lookup( irc->watches, nick ) )
434                                g_hash_table_insert( irc->watches, nick, nick );
435                       
436                        if( u && u->online )
437                                irc_send_num( irc, 604, "%s %s %s %d :%s", u->nick, u->user, u->host, (int) time( NULL ), "is online" );
438                        else
439                                irc_send_num( irc, 605, "%s %s %s %d :%s", nick, "*", "*", (int) time( NULL ), "is offline" );
440                }
441                else if( cmd[i][0] == '-' )
442                {
443                        gpointer okey, ovalue;
444                       
445                        if( g_hash_table_lookup_extended( irc->watches, nick, &okey, &ovalue ) )
446                        {
447                                g_hash_table_remove( irc->watches, okey );
448                                g_free( okey );
449                               
450                                irc_send_num( irc, 602, "%s %s %s %d :%s", nick, "*", "*", 0, "Stopped watching" );
451                        }
452                }
453        }
454}
455
456static void irc_cmd_topic( irc_t *irc, char **cmd )
457{
458        char *channel = cmd[1];
459        char *topic = cmd[2];
460       
461        if( topic )
462        {
463                /* Send the topic */
464                struct groupchat *c = irc_chat_by_channel( irc, channel );
465                if( c && c->ic && c->ic->acc->prpl->chat_topic )
466                        c->ic->acc->prpl->chat_topic( c, topic );
467        }
468        else
469        {
470                /* Get the topic */
471                irc_topic( irc, channel );
472        }
473}
474
475static void irc_cmd_away( irc_t *irc, char **cmd )
476{
477        user_t *u = user_find( irc, irc->nick );
478        char *away = cmd[1];
479       
480        if( !u ) return;
481       
482        if( away && *away )
483        {
484                int i, j;
485               
486                /* Copy away string, but skip control chars. Mainly because
487                   Jabber really doesn't like them. */
488                u->away = g_malloc( strlen( away ) + 1 );
489                for( i = j = 0; away[i]; i ++ )
490                        if( ( u->away[j] = away[i] ) >= ' ' )
491                                j ++;
492                u->away[j] = 0;
493               
494                irc_send_num( irc, 306, ":You're now away: %s", u->away );
495                /* irc_umode_set( irc, irc->myhost, "+a" ); */
496        }
497        else
498        {
499                if( u->away ) g_free( u->away );
500                u->away = NULL;
501                /* irc_umode_set( irc, irc->myhost, "-a" ); */
502                irc_send_num( irc, 305, ":Welcome back" );
503        }
504       
505        set_setstr( &irc->set, "away", u->away );
506}
507
508static void irc_cmd_nickserv( irc_t *irc, char **cmd )
509{
510        /* [SH] This aliases the NickServ command to PRIVMSG root */
511        /* [TV] This aliases the NS command to PRIVMSG root as well */
512        root_command( irc, cmd + 1 );
513}
514
515static void irc_cmd_pong( irc_t *irc, char **cmd )
516{
517        /* We could check the value we get back from the user, but in
518           fact we don't care, we're just happy he's still alive. */
519        irc->last_pong = gettime();
520        irc->pinging = 0;
521}
522
523static void irc_cmd_version( irc_t *irc, char **cmd )
524{
525        irc_send_num( irc, 351, "bitlbee-%s. %s :%s/%s ", BITLBEE_VERSION, irc->myhost, ARCH, CPU );
526}
527
528static void irc_cmd_completions( irc_t *irc, char **cmd )
529{
530        user_t *u = user_find( irc, irc->mynick );
531        help_t *h;
532        set_t *s;
533        int i;
534       
535        irc_privmsg( irc, u, "NOTICE", irc->nick, "COMPLETIONS ", "OK" );
536       
537        for( i = 0; commands[i].command; i ++ )
538                irc_privmsg( irc, u, "NOTICE", irc->nick, "COMPLETIONS ", commands[i].command );
539       
540        for( h = global.help; h; h = h->next )
541                irc_privmsg( irc, u, "NOTICE", irc->nick, "COMPLETIONS help ", h->title );
542       
543        for( s = irc->set; s; s = s->next )
544                irc_privmsg( irc, u, "NOTICE", irc->nick, "COMPLETIONS set ", s->key );
545       
546        irc_privmsg( irc, u, "NOTICE", irc->nick, "COMPLETIONS ", "END" );
547}
548
549static void irc_cmd_rehash( irc_t *irc, char **cmd )
550{
551        if( global.conf->runmode == RUNMODE_INETD )
552                ipc_master_cmd_rehash( NULL, NULL );
553        else
554                ipc_to_master( cmd );
555       
556        irc_send_num( irc, 382, "%s :Rehashing", global.conf_file );
557}
558#endif
559
560static const command_t irc_commands[] = {
561        { "pass",        1, irc_cmd_pass,        0 },
562        { "user",        4, irc_cmd_user,        IRC_CMD_PRE_LOGIN },
563        { "nick",        1, irc_cmd_nick,        0 },
564        { "quit",        0, irc_cmd_quit,        0 },
565        { "ping",        0, irc_cmd_ping,        0 },
566        { "join",        1, irc_cmd_join,        IRC_CMD_LOGGED_IN },
567        { "names",       1, irc_cmd_names,       IRC_CMD_LOGGED_IN },
568        { "part",        1, irc_cmd_part,        IRC_CMD_LOGGED_IN },
569        { "whois",       1, irc_cmd_whois,       IRC_CMD_LOGGED_IN },
570        { "whowas",      1, irc_cmd_whowas,      IRC_CMD_LOGGED_IN },
571        { "motd",        0, irc_cmd_motd,        IRC_CMD_LOGGED_IN },
572        { "mode",        1, irc_cmd_mode,        IRC_CMD_LOGGED_IN },
573#if 0
574        { "oper",        2, irc_cmd_oper,        IRC_CMD_LOGGED_IN },
575        { "invite",      2, irc_cmd_invite,      IRC_CMD_LOGGED_IN },
576        { "privmsg",     1, irc_cmd_privmsg,     IRC_CMD_LOGGED_IN },
577        { "notice",      1, irc_cmd_privmsg,     IRC_CMD_LOGGED_IN },
578        { "who",         0, irc_cmd_who,         IRC_CMD_LOGGED_IN },
579        { "userhost",    1, irc_cmd_userhost,    IRC_CMD_LOGGED_IN },
580        { "ison",        1, irc_cmd_ison,        IRC_CMD_LOGGED_IN },
581        { "watch",       1, irc_cmd_watch,       IRC_CMD_LOGGED_IN },
582        { "topic",       1, irc_cmd_topic,       IRC_CMD_LOGGED_IN },
583        { "away",        0, irc_cmd_away,        IRC_CMD_LOGGED_IN },
584        { "nickserv",    1, irc_cmd_nickserv,    IRC_CMD_LOGGED_IN },
585        { "ns",          1, irc_cmd_nickserv,    IRC_CMD_LOGGED_IN },
586        { "pong",        0, irc_cmd_pong,        IRC_CMD_LOGGED_IN },
587        { "version",     0, irc_cmd_version,     IRC_CMD_LOGGED_IN },
588        { "completions", 0, irc_cmd_completions, IRC_CMD_LOGGED_IN },
589        { "die",         0, NULL,                IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER },
590        { "deaf",        0, NULL,                IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER },
591        { "wallops",     1, NULL,                IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER },
592        { "wall",        1, NULL,                IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER },
593        { "rehash",      0, irc_cmd_rehash,      IRC_CMD_OPER_ONLY },
594        { "restart",     0, NULL,                IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER },
595        { "kill",        2, NULL,                IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER },
596#endif
597        { NULL }
598};
599
600void irc_exec( irc_t *irc, char *cmd[] )
601{       
602        int i, n_arg;
603       
604        if( !cmd[0] )
605                return;
606       
607        for( i = 0; irc_commands[i].command; i++ )
608                if( g_strcasecmp( irc_commands[i].command, cmd[0] ) == 0 )
609                {
610                        /* There should be no typo in the next line: */
611                        for( n_arg = 0; cmd[n_arg]; n_arg ++ ); n_arg --;
612                       
613                        if( irc_commands[i].flags & IRC_CMD_PRE_LOGIN && irc->status & USTATUS_LOGGED_IN )
614                        {
615                                irc_send_num( irc, 462, ":Only allowed before logging in" );
616                        }
617                        else if( irc_commands[i].flags & IRC_CMD_LOGGED_IN && !( irc->status & USTATUS_LOGGED_IN ) )
618                        {
619                                irc_send_num( irc, 451, ":Register first" );
620                        }
621                        else if( irc_commands[i].flags & IRC_CMD_OPER_ONLY && !strchr( irc->umode, 'o' ) )
622                        {
623                                irc_send_num( irc, 481, ":Permission denied - You're not an IRC operator" );
624                        }
625                        else if( n_arg < irc_commands[i].required_parameters )
626                        {
627                                irc_send_num( irc, 461, "%s :Need more parameters", cmd[0] );
628                        }
629                        else if( irc_commands[i].flags & IRC_CMD_TO_MASTER )
630                        {
631                                /* IPC doesn't make sense in inetd mode,
632                                    but the function will catch that. */
633                                ipc_to_master( cmd );
634                        }
635                        else
636                        {
637                                irc_commands[i].execute( irc, cmd );
638                        }
639                       
640                        return;
641                }
642       
643        if( irc->status >= USTATUS_LOGGED_IN )
644                irc_send_num( irc, 421, "%s :Unknown command", cmd[0] );
645}
Note: See TracBrowser for help on using the repository browser.