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
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
159#if 0
160//#if 0
161static void irc_cmd_oper( irc_t *irc, char **cmd )
162{
163        if( global.conf->oper_pass &&
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 ) )
167        {
168                irc_umode_set( irc, "+o", 1 );
169                irc_send_num( irc, 381, ":Password accepted" );
170        }
171        else
172        {
173                irc_send_num( irc, 432, ":Incorrect password" );
174        }
175}
176
177static void irc_cmd_mode( irc_t *irc, char **cmd )
178{
179        if( strchr( CTYPES, *cmd[1] ) )
180        {
181                if( cmd[2] )
182                {
183                        if( *cmd[2] == '+' || *cmd[2] == '-' )
184                                irc_send_num( irc, 477, "%s :Can't change channel modes", cmd[1] );
185                        else if( *cmd[2] == 'b' )
186                                irc_send_num( irc, 368, "%s :No bans possible", cmd[1] );
187                }
188                else
189                        irc_send_num( irc, 324, "%s +%s", cmd[1], CMODE );
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 );
197                        else
198                                irc_send_num( irc, 221, "+%s", irc->umode );
199                }
200                else
201                        irc_send_num( irc, 502, ":Don't touch their modes" );
202        }
203}
204
205static void irc_cmd_invite( irc_t *irc, char **cmd )
206{
207        char *nick = cmd[1], *channel = cmd[2];
208        struct groupchat *c = irc_chat_by_channel( irc, channel );
209        user_t *u = user_find( irc, nick );
210       
211        if( u && c && ( u->ic == c->ic ) )
212                if( c->ic && c->ic->acc->prpl->chat_invite )
213                {
214                        c->ic->acc->prpl->chat_invite( c, u->handle, NULL );
215                        irc_send_num( irc, 341, "%s %s", nick, channel );
216                        return;
217                }
218       
219        irc_send_num( irc, 482, "%s :Invite impossible; User/Channel non-existent or incompatible", channel );
220}
221
222static void irc_cmd_privmsg( irc_t *irc, char **cmd )
223{
224        if ( !cmd[2] )
225        {
226                irc_send_num( irc, 412, ":No text to send" );
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;
237                        char *t = set_getstr( &irc->set, "default_target" );
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                        {
261                                g_free( irc->last_target );
262                                irc->last_target = g_strdup( cmd[1] );
263                        }
264                }
265                else
266                {
267                        irc->is_private = 1;
268                }
269                irc_send( irc, cmd[1], cmd[2], ( g_strcasecmp( cmd[0], "NOTICE" ) == 0 ) ? OPT_AWAY : 0 );
270        }
271}
272
273static void irc_cmd_who( irc_t *irc, char **cmd )
274{
275        char *channel = cmd[1];
276        user_t *u = irc->users;
277        struct groupchat *c;
278        GList *l;
279       
280        if( !channel || *channel == '0' || *channel == '*' || !*channel )
281                while( u )
282                {
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 );
284                        u = u->next;
285                }
286        else if( g_strcasecmp( channel, irc->channel ) == 0 )
287                while( u )
288                {
289                        if( u->online )
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 );
291                        u = u->next;
292                }
293        else if( ( c = irc_chat_by_channel( irc, channel ) ) )
294                for( l = c->in_room; l; l = l->next )
295                {
296                        if( ( u = user_findhandle( c->ic, l->data ) ) )
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 );
298                }
299        else if( ( u = user_find( irc, channel ) ) )
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 );
301       
302        irc_send_num( irc, 315, "%s :End of /WHO list", channel?channel:"**" );
303}
304
305static void irc_cmd_userhost( irc_t *irc, char **cmd )
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 )
320                                irc_send_num( irc, 302, ":%s=-%s@%s", u->nick, u->user, u->host );
321                        else
322                                irc_send_num( irc, 302, ":%s=+%s@%s", u->nick, u->user, u->host );
323                }
324}
325
326static void irc_cmd_ison( irc_t *irc, char **cmd )
327{
328        user_t *u;
329        char buff[IRC_MAX_LINE];
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        {
339                char *this, *next;
340               
341                this = cmd[i];
342                while( *this )
343                {
344                        if( ( next = strchr( this, ' ' ) ) )
345                                *next = 0;
346                       
347                        if( ( u = user_find( irc, this ) ) && u->online )
348                        {
349                                lenleft -= strlen( u->nick ) + 1;
350                               
351                                if( lenleft < 0 )
352                                        break;
353                               
354                                strcat( buff, u->nick );
355                                strcat( buff, " " );
356                        }
357                       
358                        if( next )
359                        {
360                                *next = ' ';
361                                this = next + 1;
362                        }
363                        else
364                        {
365                                break;
366                        }   
367                }
368               
369                /* *sigh* */
370                if( lenleft < 0 )
371                        break;
372        }
373       
374        if( strlen( buff ) > 0 )
375                buff[strlen(buff)-1] = '\0';
376       
377        irc_send_num( irc, 303, ":%s", buff );
378}
379
380static void irc_cmd_watch( irc_t *irc, char **cmd )
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 )
406                                irc_send_num( irc, 604, "%s %s %s %d :%s", u->nick, u->user, u->host, (int) time( NULL ), "is online" );
407                        else
408                                irc_send_num( irc, 605, "%s %s %s %d :%s", nick, "*", "*", (int) time( NULL ), "is offline" );
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 );
417                                g_free( okey );
418                               
419                                irc_send_num( irc, 602, "%s %s %s %d :%s", nick, "*", "*", 0, "Stopped watching" );
420                        }
421                }
422        }
423}
424
425static void irc_cmd_topic( irc_t *irc, char **cmd )
426{
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        }
437        else
438        {
439                /* Get the topic */
440                irc_topic( irc, channel );
441        }
442}
443
444static void irc_cmd_away( irc_t *irc, char **cmd )
445{
446        user_t *u = user_find( irc, irc->nick );
447        char *away = cmd[1];
448       
449        if( !u ) return;
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               
463                irc_send_num( irc, 306, ":You're now away: %s", u->away );
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" ); */
471                irc_send_num( irc, 305, ":Welcome back" );
472        }
473       
474        set_setstr( &irc->set, "away", u->away );
475}
476
477static void irc_cmd_whois( irc_t *irc, char **cmd )
478{
479        char *nick = cmd[1];
480        user_t *u = user_find( irc, nick );
481       
482        if( u )
483        {
484                irc_send_num( irc, 311, "%s %s %s * :%s", u->nick, u->user, u->host, u->realname );
485               
486                if( u->ic )
487                        irc_send_num( irc, 312, "%s %s.%s :%s network", u->nick, u->ic->acc->user,
488                                   u->ic->acc->server && *u->ic->acc->server ? u->ic->acc->server : "",
489                                   u->ic->acc->prpl->name );
490                else
491                        irc_send_num( irc, 312, "%s %s :%s", u->nick, irc->myhost, IRCD_INFO );
492               
493                if( !u->online )
494                        irc_send_num( irc, 301, "%s :%s", u->nick, "User is offline" );
495                else if( u->away )
496                        irc_send_num( irc, 301, "%s :%s", u->nick, u->away );
497                if( u->status_msg )
498                        irc_send_num( irc, 333, "%s :Status: %s", u->nick, u->status_msg );
499               
500                irc_send_num( irc, 318, "%s :End of /WHOIS list", nick );
501        }
502        else
503        {
504                irc_send_num( irc, 401, "%s :Nick does not exist", nick );
505        }
506}
507
508static void irc_cmd_whowas( irc_t *irc, char **cmd )
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       
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] );
517}
518
519static void irc_cmd_nickserv( irc_t *irc, char **cmd )
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
526static void irc_cmd_motd( irc_t *irc, char **cmd )
527{
528        irc_motd( irc );
529}
530
531static void irc_cmd_pong( irc_t *irc, char **cmd )
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
539static void irc_cmd_version( irc_t *irc, char **cmd )
540{
541        irc_send_num( irc, 351, "bitlbee-%s. %s :%s/%s ", BITLBEE_VERSION, irc->myhost, ARCH, CPU );
542}
543
544static void irc_cmd_completions( irc_t *irc, char **cmd )
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 )
557                irc_privmsg( irc, u, "NOTICE", irc->nick, "COMPLETIONS help ", h->title );
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
565static void irc_cmd_rehash( irc_t *irc, char **cmd )
566{
567        if( global.conf->runmode == RUNMODE_INETD )
568                ipc_master_cmd_rehash( NULL, NULL );
569        else
570                ipc_to_master( cmd );
571       
572        irc_send_num( irc, 382, "%s :Rehashing", global.conf_file );
573}
574#endif
575
576static const command_t irc_commands[] = {
577        { "pass",        1, irc_cmd_pass,        0 },
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 },
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 },
585#if 0
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 },
603        { "version",     0, irc_cmd_version,     IRC_CMD_LOGGED_IN },
604        { "completions", 0, irc_cmd_completions, IRC_CMD_LOGGED_IN },
605        { "die",         0, NULL,                IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER },
606        { "deaf",        0, NULL,                IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER },
607        { "wallops",     1, NULL,                IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER },
608        { "wall",        1, NULL,                IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER },
609        { "rehash",      0, irc_cmd_rehash,      IRC_CMD_OPER_ONLY },
610        { "restart",     0, NULL,                IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER },
611        { "kill",        2, NULL,                IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER },
612#endif
613        { NULL }
614};
615
616void irc_exec( irc_t *irc, char *cmd[] )
617{       
618        int i, n_arg;
619       
620        if( !cmd[0] )
621                return;
622       
623        for( i = 0; irc_commands[i].command; i++ )
624                if( g_strcasecmp( irc_commands[i].command, cmd[0] ) == 0 )
625                {
626                        /* There should be no typo in the next line: */
627                        for( n_arg = 0; cmd[n_arg]; n_arg ++ ); n_arg --;
628                       
629                        if( irc_commands[i].flags & IRC_CMD_PRE_LOGIN && irc->status & USTATUS_LOGGED_IN )
630                        {
631                                irc_send_num( irc, 462, ":Only allowed before logging in" );
632                        }
633                        else if( irc_commands[i].flags & IRC_CMD_LOGGED_IN && !( irc->status & USTATUS_LOGGED_IN ) )
634                        {
635                                irc_send_num( irc, 451, ":Register first" );
636                        }
637                        else if( irc_commands[i].flags & IRC_CMD_OPER_ONLY && !strchr( irc->umode, 'o' ) )
638                        {
639                                irc_send_num( irc, 481, ":Permission denied - You're not an IRC operator" );
640                        }
641                        else if( n_arg < irc_commands[i].required_parameters )
642                        {
643                                irc_send_num( irc, 461, "%s :Need more parameters", cmd[0] );
644                        }
645                        else if( irc_commands[i].flags & IRC_CMD_TO_MASTER )
646                        {
647                                /* IPC doesn't make sense in inetd mode,
648                                    but the function will catch that. */
649                                ipc_to_master( cmd );
650                        }
651                        else
652                        {
653                                irc_commands[i].execute( irc, cmd );
654                        }
655                       
656                        return;
657                }
658       
659        if( irc->status >= USTATUS_LOGGED_IN )
660                irc_send_num( irc, 421, "%s :Unknown command", cmd[0] );
661}
Note: See TracBrowser for help on using the repository browser.