~registry/ngircd/testing

« back to all changes in this revision

Viewing changes to src/ngircd/channel.c

  • Committer: DNS
  • Date: 2013-08-27 14:48:36 UTC
  • mfrom: (2671.5.8)
  • Revision ID: git-v1:bdb2850b399a7fac6a70fe24bd1f58dbd78cc307
Merge branch 'master' into testing

· Remove Conf_PreventLocalChans and Conf_PreventMLChans, obsolete now
· Remove RPL_HELP_MSG

Fixed conflicts with:
        doc/sample-ngircd.conf.tmpl
        man/ngircd.conf.5.tmpl
        src/ngircd/conf.c
        src/ngircd/irc-channel.c
        src/ngircd/irc-info.c
        src/ngircd/messages.h

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * ngIRCd -- The Next Generation IRC Daemon
3
 
 * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
 
3
 * Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors.
4
4
 *
5
5
 * This program is free software; you can redistribute it and/or modify
6
6
 * it under the terms of the GNU General Public License as published by
223
223
 
224
224
        /* Check that the channel name is valid */
225
225
        if (! Channel_IsValidName(Name)) {
226
 
                IRC_WriteStrClient(Client, ERR_NOSUCHCHANNEL_MSG,
 
226
                IRC_WriteErrClient(Client, ERR_NOSUCHCHANNEL_MSG,
227
227
                                   Client_ID(Client), Name);
228
228
                return false;
229
229
        }
268
268
        /* Check that specified channel exists */
269
269
        chan = Channel_Search(Name);
270
270
        if (!chan) {
271
 
                IRC_WriteStrClient(Client, ERR_NOSUCHCHANNEL_MSG,
 
271
                IRC_WriteErrClient(Client, ERR_NOSUCHCHANNEL_MSG,
272
272
                                   Client_ID(Client), Name);
273
273
                return false;
274
274
        }
275
275
 
276
276
        /* Check that the client is in the channel */
277
277
        if (!Get_Cl2Chan(chan, Client)) {
278
 
                IRC_WriteStrClient(Client, ERR_NOTONCHANNEL_MSG,
 
278
                IRC_WriteErrClient(Client, ERR_NOTONCHANNEL_MSG,
279
279
                                   Client_ID(Client), Name);
280
280
                return false;
281
281
        }
299
299
             const char *Reason )
300
300
{
301
301
        CHANNEL *chan;
302
 
        char *ptr, *target_modes;
303
302
        bool can_kick = false;
304
303
 
305
304
        assert(Peer != NULL);
310
309
 
311
310
        /* Check that channel exists */
312
311
        chan = Channel_Search( Name );
313
 
        if( ! chan )
314
 
        {
315
 
                IRC_WriteStrClient( Origin, ERR_NOSUCHCHANNEL_MSG, Client_ID( Origin ), Name );
 
312
        if (!chan) {
 
313
                IRC_WriteErrClient(Origin, ERR_NOSUCHCHANNEL_MSG,
 
314
                                   Client_ID(Origin), Name);
316
315
                return;
317
316
        }
318
317
 
320
319
            Client_Type(Origin) != CLIENT_SERVICE) {
321
320
                /* Check that user is on the specified channel */
322
321
                if (!Channel_IsMemberOf(chan, Origin)) {
323
 
                        IRC_WriteStrClient( Origin, ERR_NOTONCHANNEL_MSG,
324
 
                                            Client_ID(Origin), Name);
 
322
                        IRC_WriteErrClient(Origin, ERR_NOTONCHANNEL_MSG,
 
323
                                           Client_ID(Origin), Name);
325
324
                        return;
326
325
                }
327
326
        }
328
327
 
329
328
        /* Check that the client to be kicked is on the specified channel */
330
329
        if (!Channel_IsMemberOf(chan, Target)) {
331
 
                IRC_WriteStrClient(Origin, ERR_USERNOTINCHANNEL_MSG,
 
330
                IRC_WriteErrClient(Origin, ERR_USERNOTINCHANNEL_MSG,
332
331
                                   Client_ID(Origin), Client_ID(Target), Name );
333
332
                return;
334
333
        }
336
335
        if(Client_Type(Peer) == CLIENT_USER) {
337
336
                /* Channel mode 'Q' and user mode 'q' on target: nobody but
338
337
                 * IRC Operators and servers can kick the target user */
339
 
                if ((strchr(Channel_Modes(chan), 'Q')
 
338
                if ((Channel_HasMode(chan, 'Q')
340
339
                     || Client_HasMode(Target, 'q')
341
340
                     || Client_Type(Target) == CLIENT_SERVICE)
342
341
                    && !Client_HasMode(Origin, 'o')) {
343
 
                        IRC_WriteStrClient(Origin, ERR_KICKDENY_MSG,
 
342
                        IRC_WriteErrClient(Origin, ERR_KICKDENY_MSG,
344
343
                                           Client_ID(Origin), Name,
345
344
                                           Client_ID(Target));
346
345
                        return;
347
346
                }
348
347
 
349
348
                /* Check if client has the rights to kick target */
350
 
                ptr = Channel_UserModes(chan, Peer);
351
 
                target_modes = Channel_UserModes(chan, Target);
352
 
                while(*ptr) {
353
 
                        /* Owner can kick everyone */
354
 
                        if ( *ptr == 'q') {
355
 
                                can_kick = true;
356
 
                                break;
357
 
                        }
358
 
                        /* Admin can't kick owner */
359
 
                        if ( *ptr == 'a' ) {
360
 
                                if (!strchr(target_modes, 'q')) {
361
 
                                        can_kick = true;
362
 
                                        break;
363
 
                                }
364
 
                        }
365
 
                        /* Op can't kick owner | admin */
366
 
                        if ( *ptr == 'o' ) {
367
 
                                if (!strchr(target_modes, 'q') &&
368
 
                                    !strchr(target_modes, 'a')) {
369
 
                                        can_kick = true;
370
 
                                        break;
371
 
                                }
372
 
                        }
373
 
                        /* Half Op can't kick owner | admin | op */ 
374
 
                        if ( *ptr == 'h' ) {
375
 
                                if (!strchr(target_modes, 'q') &&
376
 
                                    !strchr(target_modes, 'a') &&
377
 
                                    !strchr(target_modes, 'o')) {
378
 
                                        can_kick = true;
379
 
                                        break;
380
 
                                }
381
 
                        }
382
 
                        ptr++;
383
 
                }
 
349
 
 
350
                /* Owner can kick everyone */
 
351
                if (Channel_UserHasMode(chan, Peer, 'q'))
 
352
                        can_kick = true;
 
353
 
 
354
                /* Admin can't kick owner */
 
355
                else if (Channel_UserHasMode(chan, Peer, 'a') &&
 
356
                    !Channel_UserHasMode(chan, Target, 'q'))
 
357
                        can_kick = true;
 
358
 
 
359
                /* Op can't kick owner | admin */
 
360
                else if (Channel_UserHasMode(chan, Peer, 'o') &&
 
361
                    !Channel_UserHasMode(chan, Target, 'q') &&
 
362
                    !Channel_UserHasMode(chan, Target, 'a'))
 
363
                        can_kick = true;
 
364
                        
 
365
                /* Half Op can't kick owner | admin | op */ 
 
366
                else if (Channel_UserHasMode(chan, Peer, 'h') &&
 
367
                    !Channel_UserHasMode(chan, Target, 'q') &&
 
368
                    !Channel_UserHasMode(chan, Target, 'a') &&
 
369
                    !Channel_UserHasMode(chan, Target, 'o'))
 
370
                        can_kick = true;
384
371
 
385
372
                if(!can_kick) {
386
 
                        IRC_WriteStrClient(Origin, ERR_CHANOPPRIVTOOLOW_MSG,
387
 
                                Client_ID(Origin), Name);
 
373
                        IRC_WriteErrClient(Origin, ERR_CHANOPPRIVTOOLOW_MSG,
 
374
                                           Client_ID(Origin), Name);
388
375
                        return;
389
376
                }
390
377
        }
433
420
        c = My_Channels;
434
421
        while(c) {
435
422
                if (Client) {
436
 
                        if (!strchr(Channel_Modes(c), 's')
 
423
                        if (!Channel_HasMode(c, 's')
437
424
                            || Channel_IsMemberOf(c, Client))
438
425
                                count++;
439
426
                } else
499
486
} /* Channel_Modes */
500
487
 
501
488
 
 
489
GLOBAL bool
 
490
Channel_HasMode( CHANNEL *Chan, char Mode )
 
491
{
 
492
        assert( Chan != NULL );
 
493
        return strchr( Chan->modes, Mode ) != NULL;
 
494
} /* Channel_HasMode */
 
495
 
 
496
 
502
497
GLOBAL char *
503
498
Channel_Key( CHANNEL *Chan )
504
499
{
636
631
        assert( Chan != NULL );
637
632
 
638
633
        x[0] = Mode; x[1] = '\0';
639
 
        if( ! strchr( Chan->modes, x[0] ))
 
634
        if( ! Channel_HasMode( Chan, x[0] ))
640
635
        {
641
636
                /* Channel does not have this mode yet, set it */
642
637
                strlcat( Chan->modes, x, sizeof( Chan->modes ));
746
741
 
747
742
 
748
743
GLOBAL bool
 
744
Channel_UserHasMode( CHANNEL *Chan, CLIENT *Client, char Mode )
 
745
{
 
746
        return strchr(Channel_UserModes(Chan, Client), Mode) != NULL;
 
747
} /* Channel_UserHasMode */
 
748
 
 
749
 
 
750
GLOBAL bool
749
751
Channel_IsMemberOf( CHANNEL *Chan, CLIENT *Client )
750
752
{
751
753
        /* Test if Client is on Channel Chan */
873
875
 
874
876
        if (Channel_IsMemberOf(Chan, From)) {
875
877
                is_member = true;
876
 
                if (strchr(Channel_UserModes(Chan, From), 'v'))
 
878
                if (Channel_UserHasMode(Chan, From, 'v'))
877
879
                        has_voice = true;
878
 
                if (strchr(Channel_UserModes(Chan, From), 'h'))
 
880
                if (Channel_UserHasMode(Chan, From, 'h'))
879
881
                        is_halfop = true;
880
 
                if (strchr(Channel_UserModes(Chan, From), 'o'))
 
882
                if (Channel_UserHasMode(Chan, From, 'o'))
881
883
                        is_op = true;
882
 
                if (strchr(Channel_UserModes(Chan, From), 'a'))
 
884
                if (Channel_UserHasMode(Chan, From, 'a'))
883
885
                        is_chanadmin = true;
884
 
                if (strchr(Channel_UserModes(Chan, From), 'q'))
 
886
                if (Channel_UserHasMode(Chan, From, 'q'))
885
887
                        is_owner = true;
886
888
        }
887
889
 
891
893
         * If channel mode n set: non-members cannot send to channel.
892
894
         * If channel mode m set: need voice.
893
895
         */
894
 
        if (strchr(Channel_Modes(Chan), 'n') && !is_member)
 
896
        if (Channel_HasMode(Chan, 'n') && !is_member)
895
897
                return false;
896
898
 
897
 
        if (strchr(Channel_Modes(Chan), 'M') && !Client_HasMode(From, 'R')
 
899
        if (Channel_HasMode(Chan, 'M') && !Client_HasMode(From, 'R')
898
900
            && !Client_HasMode(From, 'o'))
899
901
                return false;
900
902
 
901
903
        if (has_voice || is_halfop || is_op || is_chanadmin || is_owner)
902
904
                return true;
903
905
 
904
 
        if (strchr(Channel_Modes(Chan), 'm'))
 
906
        if (Channel_HasMode(Chan, 'm'))
905
907
                return false;
906
908
 
907
909
        if (Lists_Check(&Chan->list_excepts, From))
918
920
        if (!Can_Send_To_Channel(Chan, From)) {
919
921
                if (! SendErrors)
920
922
                        return CONNECTED;       /* no error, see RFC 2812 */
921
 
                if (strchr(Channel_Modes(Chan), 'M'))
922
 
                        return IRC_WriteStrClient(From, ERR_NEEDREGGEDNICK_MSG,
 
923
                if (Channel_HasMode(Chan, 'M'))
 
924
                        return IRC_WriteErrClient(From, ERR_NEEDREGGEDNICK_MSG,
923
925
                                                  Client_ID(From), Channel_Name(Chan));
924
926
                else
925
 
                        return IRC_WriteStrClient(From, ERR_CANNOTSENDTOCHAN_MSG,
 
927
                        return IRC_WriteErrClient(From, ERR_CANNOTSENDTOCHAN_MSG,
926
928
                                          Client_ID(From), Channel_Name(Chan));
927
929
        }
928
930
 
929
931
        if (Client_Conn(From) > NONE)
930
932
                Conn_UpdateIdle(Client_Conn(From));
931
933
 
932
 
        return IRC_WriteStrChannelPrefix(Client, Chan, From, true,
933
 
                        "%s %s :%s", Command, Channel_Name(Chan), Text);
 
934
        IRC_WriteStrChannelPrefix(Client, Chan, From, true, "%s %s :%s",
 
935
                                  Command, Channel_Name(Chan), Text);
 
936
        return CONNECTED;
934
937
}
935
938
 
936
939
 
1089
1092
        }
1090
1093
 
1091
1094
        /* When channel is empty and is not pre-defined, delete */
1092
 
        if( ! strchr( Channel_Modes( Chan ), 'P' ))
 
1095
        if( ! Channel_HasMode( Chan, 'P' ))
1093
1096
        {
1094
1097
                if( ! Get_First_Cl2Chan( NULL, Chan )) Delete_Channel( Chan );
1095
1098
        }
1217
1220
        assert(Client != NULL);
1218
1221
        assert(Key != NULL);
1219
1222
 
1220
 
        if (!strchr(Chan->modes, 'k'))
 
1223
        if (!Channel_HasMode(Chan, 'k'))
1221
1224
                return true;
1222
1225
        if (*Key == '\0')
1223
1226
                return false;