1 /*
2  *  ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3  *
4  *  Copyright (c) 2019-2021 ircd-hybrid development team
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
19  *  USA
20  */
21 
22 /*! \file extban_usermode.c
23  * \brief Implements usermode based extended channel bans.
24  * \version $Id: extban_usermode.c 9959 2021-05-29 12:18:46Z michael $
25  */
26 
27 #include "stdinc.h"
28 #include "list.h"
29 #include "channel.h"
30 #include "channel_mode.h"
31 #include "client.h"
32 #include "extban.h"
33 #include "user.h"
34 
35 
36 static enum extban_match
extban_usermode_matches(struct Client * client,struct Channel * channel,struct Ban * ban)37 extban_usermode_matches(struct Client *client, struct Channel *channel, struct Ban *ban)
38 {
39   int what = MODE_ADD;
40   unsigned int modes_del = 0, modes_add = 0;
41 
42   for (const char *m = ban->host; *m; ++m)
43   {
44     switch (*m)
45     {
46       case '+':
47         what = MODE_ADD;
48         break;
49       case '-':
50         what = MODE_DEL;
51         break;
52       default:
53       {
54         const struct user_modes *tab = umode_map[(unsigned char)*m];
55 
56         switch (what)
57         {
58           case MODE_DEL:
59             if (tab)
60               modes_del |= tab->flag;
61             break;
62           case MODE_ADD:
63             if (tab)
64               modes_add |= tab->flag;
65             break;
66         }
67       }
68     }
69   }
70 
71   if ((client->umodes & modes_add) == modes_add &&
72       (client->umodes & modes_del) == 0)
73     return EXTBAN_MATCH;
74 
75   return EXTBAN_NO_MATCH;
76 }
77 
78 struct Extban extban_usermode =
79 {
80   .character = 'u',
81   .type = EXTBAN_MATCHING,
82   .types = CHFL_BAN | CHFL_EXCEPTION | CHFL_INVEX,
83   .matches = extban_usermode_matches
84 };
85