ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/branches/ircd-hybrid-newconf/src/conf/shared.c
Revision: 1027
Committed: Sun Nov 8 13:01:13 2009 UTC (16 years, 9 months ago) by michael
Content type: text/x-csrc
File size: 8269 byte(s)
Log Message:
- Move old 7.3 sources to branches/ircd-hybrid-newconf

File Contents

# Content
1 /*
2 * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 * shared.c: Defines the shared{} and cluster{} blocks of ircd.conf.
4 *
5 * Copyright (C) 2006 by the 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20 * USA
21 *
22 * $Id$
23 */
24
25 #include "stdinc.h"
26 #include "conf/conf.h"
27 #include "client.h"
28 #include "numeric.h"
29 #include "send.h"
30 #include "server.h"
31
32 dlink_list cluster_confs = {0};
33 dlink_list shared_confs = {0};
34
35 static dlink_node *hreset;
36 static char *tmpserver = NULL;
37 static char tmpuser[USERLEN + 1];
38 static char tmphost[HOSTLEN + 1];
39 static int tmpflags;
40
41 FlagMap shared_flag_map =
42 {
43 {'K', "kline", SHARED_KLINE},
44 {'k', "tkline", SHARED_TKLINE},
45 {'U', "unkline", SHARED_UNKLINE},
46 {'X', "xline", SHARED_XLINE},
47 {'x', "txline", SHARED_TXLINE},
48 {'Y', "unxline", SHARED_UNXLINE},
49 {'Q', "resv", SHARED_RESV},
50 {'q', "tresv", SHARED_TRESV},
51 {'R', "unresv", SHARED_UNRESV},
52 {'L', "locops", SHARED_LOCOPS},
53 {0, NULL, 0}
54 };
55
56 /*
57 * shared_type_as_string()
58 *
59 * Translates an integer type value to a string representation.
60 *
61 * inputs:
62 * type - bitfield
63 * str - where to put the result
64 * output: none
65 */
66 static void
67 shared_type_as_string(int type, char *str)
68 {
69 const struct FlagMapping *m;
70
71 for (m = shared_flag_map; m->letter; m++)
72 if ((type & m->flag) != 0)
73 *str++ = m->letter;
74
75 *str = 0;
76 }
77
78 /*
79 * reset_shared()
80 *
81 * Frees all shared/cluster blocks before a rehash.
82 *
83 * inputs: none
84 * output: none
85 */
86 static void *
87 reset_shared(va_list args)
88 {
89 struct SharedConf *shared;
90 struct ClusterConf *cluster;
91
92 while (shared_confs.head)
93 {
94 shared = shared_confs.head->data;
95 dlinkDelete(&shared->node, &shared_confs);
96
97 MyFree(shared->server);
98 MyFree(shared->user);
99 MyFree(shared->host);
100 MyFree(shared);
101 }
102
103 while (cluster_confs.head)
104 {
105 cluster = cluster_confs.head->data;
106 dlinkDelete(&cluster->node, &cluster_confs);
107
108 MyFree(cluster->server);
109 MyFree(cluster);
110 }
111
112 return pass_callback(hreset);
113 }
114
115 /*
116 * clear_temp()
117 *
118 * Clears temporary storage before and after parsing a single shared/cluster block.
119 *
120 * inputs: none
121 * output: none
122 */
123 static void
124 clear_temp(void)
125 {
126 MyFree(tmpserver);
127 tmpserver = NULL;
128 tmpuser[0] = tmphost[0] = 0;
129 tmpflags = 0;
130 }
131
132 /*
133 * parse_user()
134 *
135 * Parses the "user=" field.
136 *
137 * inputs: user@host mask
138 * output: none
139 */
140 static void
141 parse_user(void *value, void *unused)
142 {
143 struct split_nuh_item uh;
144
145 uh.nuhmask = value;
146 uh.nickptr = NULL;
147 uh.userptr = tmpuser;
148 uh.hostptr = tmphost;
149
150 uh.nicksize = 0;
151 uh.usersize = sizeof(tmpuser);
152 uh.hostsize = sizeof(tmphost);
153
154 split_nuh(&uh);
155 }
156
157 /*
158 * parse_type()
159 *
160 * Parses the "type=" field.
161 *
162 * inputs: pointer to a dlink list of string
163 * output: none
164 */
165 static void
166 parse_type(void *list, void *unused)
167 {
168 const struct FlagMapping *p;
169 int errors = NO;
170 dlink_node *ptr;
171
172 tmpflags = 0;
173
174 DLINK_FOREACH(ptr, ((dlink_list *)list)->head)
175 {
176 const char *str = ptr->data;
177 int found = NO, all = !irccmp(str, "all");
178
179 for (p = shared_flag_map; p->name; ++p)
180 if (all || !irccmp(str, p->name))
181 {
182 found = YES;
183 tmpflags |= p->flag;
184 if (!all)
185 break;
186 }
187
188 if (!found)
189 errors = YES;
190 }
191
192 if (errors)
193 parse_error("Invalid type specifier, check your syntax");
194 }
195
196 /*
197 * after_shared()
198 *
199 * Configures a single shared{} block.
200 *
201 * inputs: none
202 * output: none
203 */
204 static void
205 after_shared(void)
206 {
207 struct SharedConf *conf;
208 int bits;
209
210 if (!tmpflags)
211 {
212 MyFree(tmpserver);
213 return;
214 }
215
216 conf = MyMalloc(sizeof(*conf));
217
218 if (tmpserver)
219 conf->server = tmpserver;
220 else
221 DupString(conf->server, "*");
222 tmpserver = NULL;
223
224 DupString(conf->user, tmpuser[0] ? tmpuser : "*");
225 DupString(conf->host, tmphost[0] ? tmphost : "*");
226 if (parse_netmask(conf->host, &conf->ip, &bits) != HM_HOST)
227 conf->ip.ss_port = bits;
228 conf->type = tmpflags;
229
230 dlinkAddTail(conf, &conf->node, &shared_confs);
231 }
232
233 /*
234 * after_cluster()
235 *
236 * Configures a single cluster{} block.
237 *
238 * inputs: none
239 * output: none
240 */
241 static void
242 after_cluster(void)
243 {
244 struct ClusterConf *conf;
245
246 if (!tmpflags)
247 return;
248
249 conf = MyMalloc(sizeof(*conf));
250 if (tmpserver)
251 conf->server = tmpserver;
252 else
253 DupString(conf->server, "*");
254 tmpserver = NULL;
255
256 conf->type = tmpflags;
257 dlinkAddTail(conf, &conf->node, &cluster_confs);
258 }
259
260 /*
261 * find_shared()
262 *
263 * Looks for a shared{} entry.
264 *
265 * inputs:
266 * serv - server that is trying to feed us
267 * user - username of the oper
268 * host - hostname of the oper
269 * addr - IP address of the oper
270 * type - operation type, e.g. SHARED_KLINE
271 * output: pointer to a shared conf or NULL
272 */
273 struct SharedConf *
274 find_shared(const char *serv, const char *user, const char *host,
275 const char *addr, int type)
276 {
277 dlink_node *ptr;
278 struct SharedConf *conf;
279 struct addrinfo hints = {0}, *res;
280 struct irc_ssaddr ip;
281
282 ip.ss.sin_family = AF_UNSPEC;
283 if (EmptyString(addr))
284 addr = host;
285
286 hints.ai_family = AF_UNSPEC;
287 hints.ai_socktype = SOCK_STREAM;
288 hints.ai_flags = AI_NUMERICHOST;
289
290 if (!irc_getaddrinfo(addr, NULL, &hints, &res))
291 {
292 memcpy(&ip, res->ai_addr, res->ai_addrlen);
293 ip.ss.sin_family = res->ai_family;
294 ip.ss_len = res->ai_addrlen;
295 irc_freeaddrinfo(res);
296 }
297
298 DLINK_FOREACH(ptr, shared_confs.head)
299 {
300 conf = ptr->data;
301 if (!(conf->type & type) || (serv && !match(conf->server, serv)) ||
302 (user && !match(conf->user, user)))
303 continue;
304
305 if (ip.ss.sin_family != AF_UNSPEC &&
306 conf->ip.ss.sin_family != AF_UNSPEC && (
307 #ifdef IPV6
308 (conf->ip.ss.sin_family == AF_INET6) ? match_ipv6 :
309 #endif
310 match_ipv4)(&ip, &conf->ip, conf->ip.ss_port))
311 return conf;
312 if (host && match(conf->host, host))
313 return conf;
314 }
315
316 return NULL;
317 }
318
319 /*
320 * report_shared()
321 *
322 * Sends a /stats U reply to the given client.
323 *
324 * inputs: client pointer
325 * output: none
326 */
327 void
328 report_shared(struct Client *to)
329 {
330 dlink_node *ptr;
331 struct SharedConf *conf;
332 struct ClusterConf *conf2;
333 char buffer[32];
334
335 DLINK_FOREACH(ptr, shared_confs.head)
336 {
337 conf = ptr->data;
338 buffer[0] = 'c';
339 shared_type_as_string(conf->type, buffer + 1);
340 sendto_one(to, form_str(RPL_STATSULINE), ID_or_name(&me, to->from),
341 ID_or_name(to, to->from), conf->server ? conf->server : "*",
342 conf->user ? conf->user : "*", conf->host ? conf->host : "*",
343 buffer);
344 }
345
346 DLINK_FOREACH(ptr, cluster_confs.head)
347 {
348 conf2 = ptr->data;
349 buffer[0] = 'C';
350 shared_type_as_string(conf->type, buffer + 1);
351 sendto_one(to, form_str(RPL_STATSULINE), ID_or_name(&me, to->from),
352 ID_or_name(to, to->from), conf->server ? conf->server : "*",
353 "*", "*", buffer);
354 }
355 }
356
357 /*
358 * init_shared()
359 *
360 * Defines the shared{} and cluster{} conf sections.
361 *
362 * inputs: none
363 * output: none
364 */
365 void
366 init_shared(void)
367 {
368 struct ConfSection *s = add_conf_section("shared", 2);
369 struct ConfSection *s2 = add_conf_section("cluster", 2);
370
371 hreset = install_hook(reset_conf, reset_shared);
372
373 s->before = s2->before = clear_temp;
374
375 add_conf_field(s, "name", CT_STRING, NULL, &tmpserver);
376 add_conf_field(s2, "name", CT_STRING, NULL, &tmpserver);
377 add_conf_field(s, "user", CT_STRING, parse_user, NULL);
378 add_conf_field(s, "type", CT_LIST, parse_type, NULL);
379 add_conf_field(s2, "type", CT_LIST, parse_type, NULL);
380
381 s->after = after_shared;
382 s2->after = after_cluster;
383 }

Properties

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