ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/releases/8.2.36/src/extban.c
Revision: 9784
Committed: Fri Dec 4 13:30:16 2020 UTC (5 years, 10 months ago) by michael
Content type: text/x-csrc
File size: 5588 byte(s)
Log Message:
RELEASE TAG 8.2.36

File Contents

# Content
1 /*
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 * \version $Id$
26 */
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 extban_add(&extban_nick);
70 extban_add(&extban_operclass);
71 extban_add(&extban_server);
72 extban_add(&extban_tlsinfo);
73 extban_add(&extban_usermode);
74
75 const char *ptr = extban_get_isupport();
76 if (ptr)
77 isupport_add("EXTBAN", ptr, -1);
78 }
79
80 void
81 extban_add(struct Extban *extban)
82 {
83 unsigned int mask = extban_find_mask();
84
85 if (mask == 0)
86 return;
87
88 extban->flag = mask;
89 dlinkAdd(extban, &extban->node, &extban_list);
90
91 if (extban->type & EXTBAN_MATCHING)
92 matching_mask |= mask;
93 if (extban->type & EXTBAN_ACTING)
94 acting_mask |= mask;
95 }
96
97 void
98 extban_del(struct Extban *extban)
99 {
100 if (extban->flag == 0)
101 return;
102
103 dlinkDelete(&extban->node, &extban_list);
104
105 matching_mask &= ~extban->flag;
106 acting_mask &= ~extban->flag;
107 }
108
109 struct Extban *
110 extban_find(unsigned char c)
111 {
112 dlink_node *node;
113
114 DLINK_FOREACH(node, extban_list.head)
115 {
116 struct Extban *extban = node->data;
117
118 if (extban->character == c)
119 return extban;
120 }
121
122 return NULL;
123 }
124
125 struct Extban *
126 extban_find_flag(unsigned int flag)
127 {
128 dlink_node *node;
129
130 DLINK_FOREACH(node, extban_list.head)
131 {
132 struct Extban *extban = node->data;
133
134 if (extban->flag == flag)
135 return extban;
136 }
137
138 return NULL;
139 }
140
141 enum extban_type
142 extban_parse(const char *mask, unsigned int *input_extbans, unsigned int *offset)
143 {
144 *input_extbans = 0;
145 *offset = 0;
146
147 if (*mask == '$' && IsAlpha(*(mask + 1)) && *(mask + 2) == ':')
148 {
149 struct Extban *extban = extban_find(*(mask + 1));
150 if (extban == NULL)
151 return EXTBAN_INVALID;
152
153 *input_extbans |= extban->flag;
154 *offset += 3;
155 mask += 3;
156
157 /* Matching extbans take a special parameter, so stop reading */
158 if (extban->type == EXTBAN_MATCHING)
159 return EXTBAN_MATCHING;
160
161 if (IsAlpha(*mask) && *(mask + 1) == ':')
162 {
163 extban = extban_find(*mask);
164 if (extban == NULL)
165 return EXTBAN_INVALID;
166
167 /* Two acting extbans make no sense */
168 if (extban->type == EXTBAN_ACTING)
169 return EXTBAN_INVALID;
170
171 /* Check parameter */
172 if (extban->is_valid && extban->is_valid(mask) == EXTBAN_INVALID)
173 return EXTBAN_INVALID;
174
175 *input_extbans |= extban->flag;
176 *offset += 2;
177 mask += 2;
178
179 return EXTBAN_MATCHING;
180 }
181
182 return EXTBAN_ACTING;
183 }
184
185 return EXTBAN_NONE;
186 }
187
188 unsigned int
189 extban_format(unsigned int e, char *buf)
190 {
191 dlink_node *node;
192 unsigned int written = 0;
193
194 DLINK_FOREACH(node, extban_list.head)
195 {
196 struct Extban *extban = node->data;
197
198 if (extban->type != EXTBAN_ACTING)
199 continue;
200
201 if (extban->flag & e)
202 {
203 if (written == 0)
204 {
205 written++;
206 *buf++ = '$';
207 }
208
209 *buf++ = extban->character;
210 *buf++ = ':';
211 written += 2;
212
213 break;
214 }
215 }
216
217 DLINK_FOREACH(node, extban_list.head)
218 {
219 struct Extban *extban = node->data;
220
221 if (extban->type != EXTBAN_MATCHING)
222 continue;
223
224 if (extban->flag & e)
225 {
226 if (written == 0)
227 {
228 written++;
229 *buf++ = '$';
230 }
231
232 *buf++ = extban->character;
233 *buf++ = ':';
234 written += 2;
235
236 break;
237 }
238 }
239
240 return written;
241 }
242
243 unsigned int
244 extban_matching_mask(void)
245 {
246 return matching_mask;
247 }
248
249 unsigned int
250 extban_acting_mask(void)
251 {
252 return acting_mask;
253 }
254
255 const char *
256 extban_get_isupport(void)
257 {
258 dlink_node *node;
259 char extban_chars[256] = { 0 };
260 static char buf[sizeof(extban_chars) + 3 /* +3 = $,\0 */ ];
261
262 if (dlink_list_length(&extban_list) == 0)
263 return NULL;
264
265 DLINK_FOREACH(node, extban_list.head)
266 {
267 struct Extban *extban = node->data;
268 extban_chars[extban->character] = extban->character;
269 }
270
271 char *p = buf + strlcpy(buf, "$,", sizeof(buf));
272
273 for (unsigned int i = 0; i < 256; ++i)
274 if (extban_chars[i])
275 *p++ = extban_chars[i];
276 *p++ = '\0';
277
278 return buf;
279 }
280

Properties

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