ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/extban.c
Revision: 9292
Committed: Sun Feb 23 10:37:06 2020 UTC (5 years, 6 months ago) by michael
Content type: text/x-csrc
File size: 5557 byte(s)
Log Message:
- Extban $n of type 'acting' has been implemented. This extban prevents matching users from changing their
  nick while in the channel. Users with voice or above are not affected.
- Channel mode +N has been changed so channel members with +v can change nick names, too

File Contents

# User Rev Content
1 michael 9234 /*
2     * ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3     *
4     * Copyright (c) 2015-2016 plexus development team
5     * Copyright (c) 2019-2020 ircd-hybrid development team
6     *
7     * This program is free software; you can redistribute it and/or modify
8     * it under the terms of the GNU General Public License as published by
9     * the Free Software Foundation; either version 2 of the License, or
10     * (at your option) any later version.
11     *
12     * This program is distributed in the hope that it will be useful,
13     * but WITHOUT ANY WARRANTY; without even the implied warranty of
14     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15     * GNU General Public License for more details.
16     *
17     * You should have received a copy of the GNU General Public License
18     * along with this program; if not, write to the Free Software
19     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
20     * USA
21     */
22    
23     /*! \file extban.c
24     * \brief Implements extended channel bans.
25 michael 9238 * \version $Id$
26 michael 9234 */
27    
28     #include "stdinc.h"
29     #include "ircd_defs.h"
30     #include "list.h"
31     #include "irc_string.h"
32     #include "user.h"
33     #include "isupport.h"
34     #include "extban.h"
35    
36    
37     static dlink_list extban_list;
38     static unsigned int matching_mask, acting_mask;
39    
40    
41     static unsigned int
42     extban_find_mask(void)
43     {
44     dlink_node *node;
45     unsigned int used = 0;
46     unsigned int i;
47    
48     DLINK_FOREACH(node, extban_list.head)
49     {
50     const struct Extban *extban = node->data;
51     used |= extban->flag;
52     }
53    
54     for (i = 1; (i < EXTBAN_MASK) && (used & i); i <<= 1)
55     ;
56    
57     return i;
58     }
59    
60     void
61     extban_init(void)
62     {
63     extban_add(&extban_account);
64     extban_add(&extban_channel);
65     extban_add(&extban_fingerprint);
66     extban_add(&extban_gecos);
67     extban_add(&extban_join);
68     extban_add(&extban_mute);
69 michael 9292 extban_add(&extban_nick);
70 michael 9234 extban_add(&extban_operclass);
71     extban_add(&extban_server);
72     extban_add(&extban_usermode);
73    
74     const char *ptr = extban_get_isupport();
75     if (ptr)
76     isupport_add("EXTBAN", ptr, -1);
77     }
78    
79     void
80     extban_add(struct Extban *extban)
81     {
82     unsigned int mask = extban_find_mask();
83    
84     if (mask == 0)
85     return;
86    
87     extban->flag = mask;
88     dlinkAdd(extban, &extban->node, &extban_list);
89    
90     if (extban->type & EXTBAN_MATCHING)
91     matching_mask |= mask;
92     if (extban->type & EXTBAN_ACTING)
93     acting_mask |= mask;
94     }
95    
96     void
97     extban_del(struct Extban *extban)
98     {
99     if (extban->flag == 0)
100     return;
101    
102     dlinkDelete(&extban->node, &extban_list);
103    
104     matching_mask &= ~extban->flag;
105     acting_mask &= ~extban->flag;
106     }
107    
108     struct Extban *
109     extban_find(unsigned char c)
110     {
111     dlink_node *node;
112    
113     DLINK_FOREACH(node, extban_list.head)
114     {
115     struct Extban *extban = node->data;
116    
117     if (extban->character == c)
118     return extban;
119     }
120    
121     return NULL;
122     }
123    
124     struct Extban *
125     extban_find_flag(unsigned int flag)
126     {
127     dlink_node *node;
128    
129     DLINK_FOREACH(node, extban_list.head)
130     {
131     struct Extban *extban = node->data;
132    
133     if (extban->flag == flag)
134     return extban;
135     }
136    
137     return NULL;
138     }
139    
140     enum extban_type
141     extban_parse(const char *mask, unsigned int *input_extbans, unsigned int *offset)
142     {
143     *input_extbans = 0;
144     *offset = 0;
145    
146     if (*mask == '$' && IsAlpha(*(mask + 1)) && *(mask + 2) == ':')
147     {
148     struct Extban *extban = extban_find(*(mask + 1));
149     if (extban == NULL)
150     return EXTBAN_INVALID;
151    
152     *input_extbans |= extban->flag;
153     *offset += 3;
154     mask += 3;
155    
156     /* Matching extbans take a special parameter, so stop reading */
157     if (extban->type == EXTBAN_MATCHING)
158     return EXTBAN_MATCHING;
159    
160     if (IsAlpha(*mask) && *(mask + 1) == ':')
161     {
162     extban = extban_find(*mask);
163     if (extban == NULL)
164     return EXTBAN_INVALID;
165    
166     /* Two acting extbans make no sense */
167     if (extban->type == EXTBAN_ACTING)
168     return EXTBAN_INVALID;
169    
170     /* Check parameter */
171     if (extban->is_valid && extban->is_valid(mask) == EXTBAN_INVALID)
172     return EXTBAN_INVALID;
173    
174     *input_extbans |= extban->flag;
175     *offset += 2;
176     mask += 2;
177    
178     return EXTBAN_MATCHING;
179     }
180    
181     return EXTBAN_ACTING;
182     }
183    
184     return EXTBAN_NONE;
185     }
186    
187     unsigned int
188     extban_format(unsigned int e, char *buf)
189     {
190     dlink_node *node;
191     unsigned int written = 0;
192    
193     DLINK_FOREACH(node, extban_list.head)
194     {
195     struct Extban *extban = node->data;
196    
197     if (extban->type != EXTBAN_ACTING)
198     continue;
199    
200     if (extban->flag & e)
201     {
202     if (written == 0)
203     {
204     written++;
205     *buf++ = '$';
206     }
207    
208     *buf++ = extban->character;
209     *buf++ = ':';
210 michael 9262 written += 2;
211 michael 9234
212 michael 9262 break;
213 michael 9234 }
214     }
215    
216     DLINK_FOREACH(node, extban_list.head)
217     {
218     struct Extban *extban = node->data;
219    
220     if (extban->type != EXTBAN_MATCHING)
221     continue;
222    
223     if (extban->flag & e)
224     {
225     if (written == 0)
226     {
227     written++;
228     *buf++ = '$';
229     }
230    
231     *buf++ = extban->character;
232     *buf++ = ':';
233     written += 2;
234 michael 9262
235     break;
236 michael 9234 }
237     }
238    
239     return written;
240     }
241    
242     unsigned int
243     extban_matching_mask(void)
244     {
245     return matching_mask;
246     }
247    
248     unsigned int
249     extban_acting_mask(void)
250     {
251     return acting_mask;
252     }
253    
254     const char *
255     extban_get_isupport(void)
256     {
257     dlink_node *node;
258     char extban_chars[256] = { 0 };
259     static char buf[sizeof(extban_chars) + 3 /* +3 = $,\0 */ ];
260    
261     if (dlink_list_length(&extban_list) == 0)
262     return NULL;
263    
264     DLINK_FOREACH(node, extban_list.head)
265     {
266     struct Extban *extban = node->data;
267 michael 9242 extban_chars[extban->character] = extban->character;
268 michael 9234 }
269    
270     char *p = buf + strlcpy(buf, "$,", sizeof(buf));
271    
272     for (unsigned int i = 0; i < 256; ++i)
273     if (extban_chars[i])
274     *p++ = extban_chars[i];
275     *p++ = '\0';
276    
277     return buf;
278     }
279    

Properties

Name Value
svn:eol-style native
svn:keywords Id