source: irc_commands.c @ ebaebfe

Last change on this file since ebaebfe was ebaebfe, checked in by Wilmer van der Gaast <wilmer@…>, at 2010-03-27T01:57:00Z

PING and QUIT work now, and adding some files that weren't checked in so
far.

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