source: irc_commands.c @ 07054a5

Last change on this file since 07054a5 was 3611717, checked in by Wilmer van der Gaast <wilmer@…>, at 2008-08-31T15:00:35Z

Added auto_join code.

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