ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/branches/8.2.x/src/conf.c
(Generate patch)

Comparing:
ircd-hybrid-7.2/src/s_conf.c (file contents), Revision 896 by michael, Sat Nov 3 08:54:09 2007 UTC vs.
ircd-hybrid/trunk/src/conf.c (file contents), Revision 1825 by michael, Sun Apr 14 19:54:48 2013 UTC

# Line 1 | Line 1
1   /*
2   *  ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 < *  s_conf.c: Configuration file functions.
3 > *  conf.c: Configuration file functions.
4   *
5   *  Copyright (C) 2002 by the past and present ircd coders, and others.
6   *
# Line 23 | Line 23
23   */
24  
25   #include "stdinc.h"
26 + #include "list.h"
27   #include "ircd_defs.h"
28 < #include "tools.h"
28 < #include "s_conf.h"
28 > #include "conf.h"
29   #include "s_serv.h"
30   #include "resv.h"
31   #include "channel.h"
32   #include "client.h"
33 #include "common.h"
33   #include "event.h"
35 #include "hash.h"
34   #include "hook.h"
35   #include "irc_string.h"
38 #include "sprintf_irc.h"
36   #include "s_bsd.h"
40 #include "irc_getaddrinfo.h"
37   #include "ircd.h"
42 #include "list.h"
38   #include "listener.h"
39   #include "hostmask.h"
40   #include "modules.h"
41   #include "numeric.h"
42   #include "fdlist.h"
43 < #include "s_log.h"
43 > #include "log.h"
44   #include "send.h"
45   #include "s_gline.h"
51 #include "fileio.h"
46   #include "memory.h"
47 + #include "mempool.h"
48   #include "irc_res.h"
49   #include "userhost.h"
50   #include "s_user.h"
51   #include "channel_mode.h"
52 + #include "parse.h"
53 + #include "s_misc.h"
54 + #include "conf_db.h"
55 + #include "conf_class.h"
56  
58 struct Callback *client_check_cb = NULL;
57   struct config_server_hide ConfigServerHide;
58  
59   /* general conf items link list root, other than k lines etc. */
60 + dlink_list service_items = { NULL, NULL, 0 };
61   dlink_list server_items  = { NULL, NULL, 0 };
62   dlink_list cluster_items = { NULL, NULL, 0 };
64 dlink_list hub_items     = { NULL, NULL, 0 };
65 dlink_list leaf_items    = { NULL, NULL, 0 };
63   dlink_list oconf_items   = { NULL, NULL, 0 };
64   dlink_list uconf_items   = { NULL, NULL, 0 };
65   dlink_list xconf_items   = { NULL, NULL, 0 };
66   dlink_list rxconf_items  = { NULL, NULL, 0 };
67   dlink_list rkconf_items  = { NULL, NULL, 0 };
68   dlink_list nresv_items   = { NULL, NULL, 0 };
72 dlink_list class_items   = { NULL, NULL, 0 };
73 dlink_list gdeny_items   = { NULL, NULL, 0 };
74
75 dlink_list temporary_klines  = { NULL, NULL, 0 };
76 dlink_list temporary_dlines  = { NULL, NULL, 0 };
77 dlink_list temporary_xlines  = { NULL, NULL, 0 };
78 dlink_list temporary_rklines = { NULL, NULL, 0 };
79 dlink_list temporary_glines  = { NULL, NULL, 0 };
80 dlink_list temporary_rxlines = { NULL, NULL, 0 };
69   dlink_list temporary_resv = { NULL, NULL, 0 };
70  
71   extern unsigned int lineno;
72   extern char linebuf[];
73   extern char conffilebuf[IRCD_BUFSIZE];
86 extern char yytext[];
74   extern int yyparse(); /* defined in y.tab.c */
75 < int ypass = 1; /* used by yyparse()      */
75 >
76 > struct conf_parser_context conf_parser_ctx = { 0, 0, NULL };
77  
78   /* internally defined functions */
79 < static void lookup_confhost(struct ConfItem *);
92 < static void set_default_conf(void);
93 < static void validate_conf(void);
94 < static void read_conf(FBFILE *);
79 > static void read_conf(FILE *);
80   static void clear_out_old_conf(void);
96 static void flush_deleted_I_P(void);
81   static void expire_tklines(dlink_list *);
82   static void garbage_collect_ip_entries(void);
83   static int hash_ip(struct irc_ssaddr *);
84 < static int verify_access(struct Client *, const char *);
85 < static int attach_iline(struct Client *, struct ConfItem *);
84 > static int verify_access(struct Client *);
85 > static int attach_iline(struct Client *, struct MaskItem *);
86   static struct ip_entry *find_or_add_ip(struct irc_ssaddr *);
87 < static void parse_conf_file(int, int);
88 < static dlink_list *map_to_list(ConfType);
105 < static struct AccessItem *find_regexp_kline(const char *[]);
87 > static dlink_list *map_to_list(enum maskitem_type);
88 > static struct MaskItem *find_regexp_kline(const char *[]);
89   static int find_user_host(struct Client *, char *, char *, char *, unsigned int);
90  
108 /*
109 * bit_len
110 */
111 static int cidr_limit_reached(int, struct irc_ssaddr *, struct ClassItem *);
112 static void remove_from_cidr_check(struct irc_ssaddr *, struct ClassItem *);
113 static void destroy_cidr_class(struct ClassItem *);
114
115 static void flags_to_ascii(unsigned int, const unsigned int[], char *, int);
116
117 FBFILE *conf_fbfile_in = NULL;
118
119 /* address of default class conf */
120 static struct ConfItem *class_default;
91  
92   /* usually, with hash tables, you use a prime number...
93   * but in this case I am dealing with ip addresses,
# Line 128 | Line 98 | static struct ConfItem *class_default;
98   struct ip_entry
99   {
100    struct irc_ssaddr ip;
101 <  int count;
101 >  unsigned int count;
102    time_t last_attempt;
103    struct ip_entry *next;
104   };
105  
106   static struct ip_entry *ip_hash_table[IP_HASH_SIZE];
107 < static BlockHeap *ip_entry_heap = NULL;
107 > static mp_pool_t *ip_entry_pool = NULL;
108   static int ip_entries_count = 0;
109  
110  
141 inline void *
142 map_to_conf(struct ConfItem *aconf)
143 {
144  void *conf;
145  conf = (void *)((unsigned long)aconf +
146                  (unsigned long)sizeof(struct ConfItem));
147  return(conf);
148 }
149
150 inline struct ConfItem *
151 unmap_conf_item(void *aconf)
152 {
153  struct ConfItem *conf;
154
155  conf = (struct ConfItem *)((unsigned long)aconf -
156                             (unsigned long)sizeof(struct ConfItem));
157  return(conf);
158 }
159
111   /* conf_dns_callback()
112   *
113 < * inputs       - pointer to struct AccessItem
113 > * inputs       - pointer to struct MaskItem
114   *              - pointer to DNSReply reply
115   * output       - none
116   * side effects - called when resolver query finishes
# Line 168 | Line 119 | unmap_conf_item(void *aconf)
119   * if successful save hp in the conf item it was called with
120   */
121   static void
122 < conf_dns_callback(void *vptr, struct DNSReply *reply)
122 > conf_dns_callback(void *vptr, const struct irc_ssaddr *addr, const char *name)
123   {
124 <  struct AccessItem *aconf = (struct AccessItem *)vptr;
174 <  struct ConfItem *conf;
124 >  struct MaskItem *conf = vptr;
125  
126 <  MyFree(aconf->dns_query);
177 <  aconf->dns_query = NULL;
126 >  conf->dns_pending = 0;
127  
128 <  if (reply != NULL)
129 <    memcpy(&aconf->ipnum, &reply->addr, sizeof(reply->addr));
130 <  else {
131 <    ilog(L_NOTICE, "Host not found: %s, ignoring connect{} block",
183 <         aconf->host);
184 <    conf = unmap_conf_item(aconf);
185 <    sendto_realops_flags(UMODE_ALL, L_ALL,
186 <                         "Ignoring connect{} block for %s - host not found",
187 <                         conf->name);
188 <    delete_conf_item(conf);
189 <  }
128 >  if (addr != NULL)
129 >    memcpy(&conf->addr, addr, sizeof(conf->addr));
130 >  else
131 >    conf->dns_failed = 1;
132   }
133  
134   /* conf_dns_lookup()
# Line 196 | Line 138 | conf_dns_callback(void *vptr, struct DNS
138   * allocate a dns_query and start ns lookup.
139   */
140   static void
141 < conf_dns_lookup(struct AccessItem *aconf)
141 > conf_dns_lookup(struct MaskItem *conf)
142   {
143 <  if (aconf->dns_query == NULL)
143 >  if (!conf->dns_pending)
144    {
145 <    aconf->dns_query = MyMalloc(sizeof(struct DNSQuery));
146 <    aconf->dns_query->ptr = aconf;
205 <    aconf->dns_query->callback = conf_dns_callback;
206 <    gethost_byname(aconf->host, aconf->dns_query);
145 >    conf->dns_pending = 1;
146 >    gethost_byname(conf_dns_callback, conf, conf->host);
147    }
148   }
149  
150 < /* make_conf_item()
151 < *
212 < * inputs       - type of item
213 < * output       - pointer to new conf entry
214 < * side effects - none
215 < */
216 < struct ConfItem *
217 < make_conf_item(ConfType type)
150 > struct MaskItem *
151 > conf_make(enum maskitem_type type)
152   {
153 <  struct ConfItem *conf = NULL;
154 <  struct AccessItem *aconf = NULL;
221 <  struct ClassItem *aclass = NULL;
222 <  int status = 0;
223 <
224 <  switch (type)
225 <  {
226 <  case DLINE_TYPE:
227 <  case EXEMPTDLINE_TYPE:
228 <  case GLINE_TYPE:
229 <  case KLINE_TYPE:
230 <  case CLIENT_TYPE:
231 <  case OPER_TYPE:
232 <  case SERVER_TYPE:
233 <    conf = MyMalloc(sizeof(struct ConfItem) +
234 <                    sizeof(struct AccessItem));
235 <    aconf = map_to_conf(conf);
236 <    aconf->aftype = AF_INET;
237 <
238 <    /* Yes, sigh. switch on type again */
239 <    switch (type)
240 <    {
241 <    case EXEMPTDLINE_TYPE:
242 <      status = CONF_EXEMPTDLINE;
243 <      break;
244 <
245 <    case DLINE_TYPE:
246 <      status = CONF_DLINE;
247 <      break;
248 <
249 <    case KLINE_TYPE:
250 <      status = CONF_KLINE;
251 <      break;
252 <
253 <    case GLINE_TYPE:
254 <      status = CONF_GLINE;
255 <      break;
256 <
257 <    case CLIENT_TYPE:
258 <      status = CONF_CLIENT;
259 <      break;
260 <
261 <    case OPER_TYPE:
262 <      status = CONF_OPERATOR;
263 <      dlinkAdd(conf, &conf->node, &oconf_items);
264 <      break;
265 <
266 <    case SERVER_TYPE:
267 <      status = CONF_SERVER;
268 <      dlinkAdd(conf, &conf->node, &server_items);
269 <      break;
270 <
271 <    default:
272 <      break;
273 <    }
274 <    aconf->status = status;
275 <    break;
276 <
277 <  case LEAF_TYPE:
278 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
279 <                                       sizeof(struct MatchItem));
280 <    dlinkAdd(conf, &conf->node, &leaf_items);
281 <    break;
282 <
283 <  case HUB_TYPE:
284 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
285 <                                       sizeof(struct MatchItem));
286 <    dlinkAdd(conf, &conf->node, &hub_items);
287 <    break;
288 <
289 <  case ULINE_TYPE:
290 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
291 <                                       sizeof(struct MatchItem));
292 <    dlinkAdd(conf, &conf->node, &uconf_items);
293 <    break;
294 <
295 <  case GDENY_TYPE:
296 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
297 <                                       sizeof(struct AccessItem));
298 <    dlinkAdd(conf, &conf->node, &gdeny_items);
299 <    break;
300 <
301 <  case XLINE_TYPE:
302 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
303 <                                       sizeof(struct MatchItem));
304 <    dlinkAdd(conf, &conf->node, &xconf_items);
305 <    break;
306 <
307 <  case RXLINE_TYPE:
308 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
309 <                                       sizeof(struct MatchItem));
310 <    dlinkAdd(conf, &conf->node, &rxconf_items);
311 <    break;
312 <
313 <  case RKLINE_TYPE:
314 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
315 <                                       sizeof(struct AccessItem));
316 <    aconf = map_to_conf(conf);
317 <    aconf->status = CONF_KLINE;
318 <    dlinkAdd(conf, &conf->node, &rkconf_items);
319 <    break;
320 <
321 <  case CLUSTER_TYPE:
322 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem));
323 <    dlinkAdd(conf, &conf->node, &cluster_items);
324 <    break;
325 <
326 <  case CRESV_TYPE:
327 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
328 <                                       sizeof(struct ResvChannel));
329 <    break;
330 <
331 <  case NRESV_TYPE:
332 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
333 <                                       sizeof(struct MatchItem));
334 <    dlinkAdd(conf, &conf->node, &nresv_items);
335 <    break;
336 <
337 <  case CLASS_TYPE:
338 <    conf = MyMalloc(sizeof(struct ConfItem) +
339 <                           sizeof(struct ClassItem));
340 <    dlinkAdd(conf, &conf->node, &class_items);
341 <
342 <    aclass = map_to_conf(conf);
343 <    aclass->active = 1;
344 <    ConFreq(aclass) = DEFAULT_CONNECTFREQUENCY;
345 <    PingFreq(aclass) = DEFAULT_PINGFREQUENCY;
346 <    MaxTotal(aclass) = MAXIMUM_LINKS_DEFAULT;
347 <    MaxSendq(aclass) = DEFAULT_SENDQ;
348 <
349 <    break;
350 <
351 <  default:
352 <    conf = NULL;
353 <    break;
354 <  }
153 >  struct MaskItem *conf = MyMalloc(sizeof(*conf));
154 >  dlink_list *list = NULL;
155  
156 <  /* XXX Yes, this will core if default is hit. I want it to for now - db */
157 <  conf->type = type;
156 >  conf->type   = type;
157 >  conf->active = 1;
158 >  conf->aftype = AF_INET;
159  
160 +  if ((list = map_to_list(type)))
161 +    dlinkAdd(conf, &conf->node, list);
162    return conf;
163   }
164  
165   void
166 < delete_conf_item(struct ConfItem *conf)
166 > conf_free(struct MaskItem *conf)
167   {
168 <  dlink_node *m = NULL;
169 <  struct MatchItem *match_item;
170 <  struct AccessItem *aconf;
171 <  ConfType type = conf->type;
168 >  dlink_node *ptr = NULL, *ptr_next = NULL;
169 >  dlink_list *list = NULL;
170 >
171 >  if (conf->node.next)
172 >    if ((list = map_to_list(conf->type)))
173 >      dlinkDelete(&conf->node, list);
174  
175    MyFree(conf->name);
371  conf->name = NULL;
176  
177 <  switch(type)
178 <  {
179 <  case DLINE_TYPE:
180 <  case EXEMPTDLINE_TYPE:
181 <  case GLINE_TYPE:
182 <  case KLINE_TYPE:
183 <  case CLIENT_TYPE:
184 <  case OPER_TYPE:
185 <  case SERVER_TYPE:
186 <    aconf = map_to_conf(conf);
187 <
188 <    if (aconf->dns_query != NULL)
189 <    {
190 <      delete_resolver_queries(aconf->dns_query);
191 <      MyFree(aconf->dns_query);
192 <    }
389 <    if (aconf->passwd != NULL)
390 <      memset(aconf->passwd, 0, strlen(aconf->passwd));
391 <    if (aconf->spasswd != NULL)
392 <      memset(aconf->spasswd, 0, strlen(aconf->spasswd));
393 <    aconf->class_ptr = NULL;
394 <
395 <    MyFree(aconf->passwd);
396 <    MyFree(aconf->spasswd);
397 <    MyFree(aconf->reason);
398 <    MyFree(aconf->oper_reason);
399 <    MyFree(aconf->user);
400 <    MyFree(aconf->host);
401 <    MyFree(aconf->fakename);
177 >  if (conf->dns_pending)
178 >    delete_resolver_queries(conf);
179 >  if (conf->passwd != NULL)
180 >    memset(conf->passwd, 0, strlen(conf->passwd));
181 >  if (conf->spasswd != NULL)
182 >    memset(conf->spasswd, 0, strlen(conf->spasswd));
183 >
184 >  conf->class = NULL;
185 >
186 >  MyFree(conf->passwd);
187 >  MyFree(conf->spasswd);
188 >  MyFree(conf->reason);
189 >  MyFree(conf->user);
190 >  MyFree(conf->host);
191 >  MyFree(conf->regexuser);
192 >  MyFree(conf->regexhost);
193   #ifdef HAVE_LIBCRYPTO
194 <    if (aconf->rsa_public_key)
404 <      RSA_free(aconf->rsa_public_key);
405 <    MyFree(aconf->rsa_public_key_file);
406 < #endif
194 >  MyFree(conf->cipher_list);
195  
196 <    /* Yes, sigh. switch on type again */
197 <    switch(type)
198 <    {
199 <    case EXEMPTDLINE_TYPE:
200 <    case DLINE_TYPE:
201 <    case GLINE_TYPE:
202 <    case KLINE_TYPE:
415 <    case CLIENT_TYPE:
416 <      MyFree(conf);
417 <      break;
418 <
419 <    case OPER_TYPE:
420 <      aconf = map_to_conf(conf);
421 <      if (!IsConfIllegal(aconf))
422 <        dlinkDelete(&conf->node, &oconf_items);
423 <      MyFree(conf);
424 <      break;
425 <
426 <    case SERVER_TYPE:
427 <      aconf = map_to_conf(conf);
428 <      if (!IsConfIllegal(aconf))
429 <        dlinkDelete(&conf->node, &server_items);
430 <      MyFree(conf);
431 <      break;
432 <
433 <    default:
434 <      break;
435 <    }
436 <    break;
437 <
438 <  case HUB_TYPE:
439 <    match_item = map_to_conf(conf);
440 <    MyFree(match_item->user);
441 <    MyFree(match_item->host);
442 <    MyFree(match_item->reason);
443 <    MyFree(match_item->oper_reason);
444 <    /* If marked illegal, its already been pulled off of the hub_items list */
445 <    if (!match_item->illegal)
446 <      dlinkDelete(&conf->node, &hub_items);
447 <    MyFree(conf);
448 <    break;
449 <
450 <  case LEAF_TYPE:
451 <    match_item = map_to_conf(conf);
452 <    MyFree(match_item->user);
453 <    MyFree(match_item->host);
454 <    MyFree(match_item->reason);
455 <    MyFree(match_item->oper_reason);
456 <    /* If marked illegal, its already been pulled off of the leaf_items list */
457 <    if (!match_item->illegal)
458 <      dlinkDelete(&conf->node, &leaf_items);
459 <    MyFree(conf);
460 <    break;
461 <
462 <  case ULINE_TYPE:
463 <    match_item = map_to_conf(conf);
464 <    MyFree(match_item->user);
465 <    MyFree(match_item->host);
466 <    MyFree(match_item->reason);
467 <    MyFree(match_item->oper_reason);
468 <    dlinkDelete(&conf->node, &uconf_items);
469 <    MyFree(conf);
470 <    break;
471 <
472 <  case XLINE_TYPE:
473 <    match_item = map_to_conf(conf);
474 <    MyFree(match_item->user);
475 <    MyFree(match_item->host);
476 <    MyFree(match_item->reason);
477 <    MyFree(match_item->oper_reason);
478 <    dlinkDelete(&conf->node, &xconf_items);
479 <    MyFree(conf);
480 <    break;
481 <
482 <  case RKLINE_TYPE:
483 <    aconf = map_to_conf(conf);
484 <    MyFree(aconf->regexuser);
485 <    MyFree(aconf->regexhost);
486 <    MyFree(aconf->user);
487 <    MyFree(aconf->host);
488 <    MyFree(aconf->reason);
489 <    MyFree(aconf->oper_reason);
490 <    dlinkDelete(&conf->node, &rkconf_items);
491 <    MyFree(conf);
492 <    break;
493 <
494 <  case RXLINE_TYPE:
495 <    MyFree(conf->regexpname);
496 <    match_item = map_to_conf(conf);
497 <    MyFree(match_item->user);
498 <    MyFree(match_item->host);
499 <    MyFree(match_item->reason);
500 <    MyFree(match_item->oper_reason);
501 <    dlinkDelete(&conf->node, &rxconf_items);
502 <    MyFree(conf);
503 <    break;
504 <
505 <  case NRESV_TYPE:
506 <    match_item = map_to_conf(conf);
507 <    MyFree(match_item->user);
508 <    MyFree(match_item->host);
509 <    MyFree(match_item->reason);
510 <    MyFree(match_item->oper_reason);
511 <    dlinkDelete(&conf->node, &nresv_items);
512 <
513 <    if (conf->flags & CONF_FLAGS_TEMPORARY)
514 <      if ((m = dlinkFindDelete(&temporary_resv, conf)) != NULL)
515 <        free_dlink_node(m);
516 <
517 <    MyFree(conf);
518 <    break;
519 <
520 <  case GDENY_TYPE:
521 <    aconf = map_to_conf(conf);
522 <    MyFree(aconf->user);
523 <    MyFree(aconf->host);
524 <    dlinkDelete(&conf->node, &gdeny_items);
525 <    MyFree(conf);
526 <    break;
527 <
528 <  case CLUSTER_TYPE:
529 <    dlinkDelete(&conf->node, &cluster_items);
530 <    MyFree(conf);
531 <    break;
532 <
533 <  case CRESV_TYPE:
534 <    if (conf->flags & CONF_FLAGS_TEMPORARY)
535 <      if ((m = dlinkFindDelete(&temporary_resv, conf)) != NULL)
536 <        free_dlink_node(m);
537 <
538 <    MyFree(conf);
539 <    break;
540 <
541 <  case CLASS_TYPE:
542 <    dlinkDelete(&conf->node, &class_items);
543 <    MyFree(conf);
544 <    break;
545 <
546 <  default:
547 <    break;
196 >  if (conf->rsa_public_key)
197 >    RSA_free(conf->rsa_public_key);
198 > #endif
199 >  DLINK_FOREACH_SAFE(ptr, ptr_next, conf->hub_list.head)
200 >  {
201 >    MyFree(ptr->data);
202 >    free_dlink_node(ptr);
203    }
549 }
204  
205 < /* free_access_item()
206 < *
207 < * inputs       - pointer to conf to free
208 < * output       - none
209 < * side effects - crucial password fields are zeroed, conf is freed
556 < */
557 < void
558 < free_access_item(struct AccessItem *aconf)
559 < {
560 <  struct ConfItem *conf;
205 >  DLINK_FOREACH_SAFE(ptr, ptr_next, conf->leaf_list.head)
206 >  {
207 >    MyFree(ptr->data);
208 >    free_dlink_node(ptr);
209 >  }
210  
211 <  if (aconf == NULL)
563 <    return;
564 <  conf = unmap_conf_item(aconf);
565 <  delete_conf_item(conf);
211 >  MyFree(conf);
212   }
213  
214 < static const unsigned int shared_bit_table[] =
215 <  { 'K', 'k', 'U', 'X', 'x', 'Y', 'Q', 'q', 'R', 'L', 0};
214 > static const struct shared_flags
215 > {
216 >  const unsigned int type;
217 >  const unsigned char letter;
218 > } flag_table[] = {
219 >  { SHARED_KLINE,   'K' },
220 >  { SHARED_UNKLINE, 'U' },
221 >  { SHARED_XLINE,   'X' },
222 >  { SHARED_UNXLINE, 'Y' },
223 >  { SHARED_RESV,    'Q' },
224 >  { SHARED_UNRESV,  'R' },
225 >  { SHARED_LOCOPS,  'L' },
226 >  { SHARED_DLINE,   'D' },
227 >  { SHARED_UNDLINE, 'E' },
228 >  { 0, '\0' }
229 > };
230  
231 < /* report_confitem_types()
572 < *
231 > /*
232   * inputs       - pointer to client requesting confitem report
233   *              - ConfType to report
234   * output       - none
235   * side effects -
236   */
237   void
238 < report_confitem_types(struct Client *source_p, ConfType type, int temp)
238 > report_confitem_types(struct Client *source_p, enum maskitem_type type)
239   {
240 <  dlink_node *ptr = NULL;
241 <  struct ConfItem *conf = NULL;
242 <  struct AccessItem *aconf = NULL;
243 <  struct MatchItem *matchitem = NULL;
585 <  struct ClassItem *classitem = NULL;
240 >  dlink_node *ptr = NULL, *dptr = NULL;
241 >  struct MaskItem *conf = NULL;
242 >  const struct ClassItem *class = NULL;
243 >  const struct shared_flags *shared = NULL;
244    char buf[12];
245    char *p = NULL;
588  const char *pfx = NULL;
246  
247    switch (type)
248    {
249 <  case GDENY_TYPE:
593 <    DLINK_FOREACH(ptr, gdeny_items.head)
594 <    {
595 <      conf = ptr->data;
596 <      aconf = map_to_conf(conf);
597 <
598 <      p = buf;
599 <
600 <      if (aconf->flags & GDENY_BLOCK)
601 <        *p++ = 'B';
602 <      else
603 <        *p++ = 'b';
604 <
605 <      if (aconf->flags & GDENY_REJECT)
606 <        *p++ = 'R';
607 <      else
608 <        *p++ = 'r';
609 <
610 <      *p = '\0';
611 <
612 <      sendto_one(source_p, ":%s %d %s V %s@%s %s %s",
613 <                 me.name, RPL_STATSDEBUG, source_p->name,
614 <                 aconf->user, aconf->host, conf->name, buf);
615 <    }
616 <    break;
617 <
618 <  case XLINE_TYPE:
249 >  case CONF_XLINE:
250      DLINK_FOREACH(ptr, xconf_items.head)
251      {
252        conf = ptr->data;
622      matchitem = map_to_conf(conf);
253  
254        sendto_one(source_p, form_str(RPL_STATSXLINE),
255                   me.name, source_p->name,
256 <                 matchitem->hold ? "x": "X", matchitem->count,
257 <                 conf->name, matchitem->reason);
256 >                 conf->until ? "x": "X", conf->count,
257 >                 conf->name, conf->reason);
258      }
259      break;
260  
261 <  case RXLINE_TYPE:
261 > #ifdef HAVE_LIBPCRE
262 >  case CONF_RXLINE:
263      DLINK_FOREACH(ptr, rxconf_items.head)
264      {
265        conf = ptr->data;
635      matchitem = map_to_conf(conf);
266  
267        sendto_one(source_p, form_str(RPL_STATSXLINE),
268                   me.name, source_p->name,
269 <                 matchitem->hold ? "xR": "XR", matchitem->count,
270 <                 conf->name, matchitem->reason);
269 >                 "XR", conf->count,
270 >                 conf->name, conf->reason);
271      }
272      break;
273  
274 <  case RKLINE_TYPE:
645 <    pfx = temp ? "kR" : "KR";
646 <
274 >  case CONF_RKLINE:
275      DLINK_FOREACH(ptr, rkconf_items.head)
276      {
277 <      aconf = map_to_conf((conf = ptr->data));
650 <
651 <      if (temp && !(conf->flags & CONF_FLAGS_TEMPORARY))
652 <        continue;
277 >      conf = ptr->data;
278  
279        sendto_one(source_p, form_str(RPL_STATSKLINE), me.name,
280 <                 source_p->name, pfx, aconf->host, aconf->user,
281 <                 aconf->reason, aconf->oper_reason ? aconf->oper_reason : "");
280 >                 source_p->name, "KR", conf->host, conf->user,
281 >                 conf->reason);
282      }
283      break;
284 + #endif
285  
286 <  case ULINE_TYPE:
286 >  case CONF_ULINE:
287 >    shared = flag_table;
288      DLINK_FOREACH(ptr, uconf_items.head)
289      {
290        conf = ptr->data;
664      matchitem = map_to_conf(conf);
291  
292        p = buf;
293  
668      /* some of these are redundant for the sake of
669       * consistency with cluster{} flags
670       */
294        *p++ = 'c';
295 <      flags_to_ascii(matchitem->action, shared_bit_table, p, 0);
295 >      for (; shared->type; ++shared)
296 >        if (shared->type & conf->flags)
297 >          *p++ = shared->letter;
298 >        else
299 >          *p++ = ToLower(shared->letter);
300  
301        sendto_one(source_p, form_str(RPL_STATSULINE),
302                   me.name, source_p->name, conf->name,
303 <                 matchitem->user?matchitem->user: "*",
304 <                 matchitem->host?matchitem->host: "*", buf);
303 >                 conf->user?conf->user: "*",
304 >                 conf->host?conf->host: "*", buf);
305      }
306  
307 +    shared = flag_table;
308      DLINK_FOREACH(ptr, cluster_items.head)
309      {
310        conf = ptr->data;
# Line 684 | Line 312 | report_confitem_types(struct Client *sou
312        p = buf;
313  
314        *p++ = 'C';
315 <      flags_to_ascii(conf->flags, shared_bit_table, p, 0);
315 >      for (; shared->type; ++shared)
316 >        if (shared->type & conf->flags)
317 >          *p++ = shared->letter;
318 >        else
319 >          *p++ = ToLower(shared->letter);
320  
321        sendto_one(source_p, form_str(RPL_STATSULINE),
322                   me.name, source_p->name, conf->name,
# Line 693 | Line 325 | report_confitem_types(struct Client *sou
325  
326      break;
327  
328 <  case OPER_TYPE:
328 >  case CONF_OPER:
329      DLINK_FOREACH(ptr, oconf_items.head)
330      {
331        conf = ptr->data;
700      aconf = map_to_conf(conf);
332  
333        /* Don't allow non opers to see oper privs */
334 <      if (IsOper(source_p))
334 >      if (HasUMode(source_p, UMODE_OPER))
335          sendto_one(source_p, form_str(RPL_STATSOLINE),
336 <                   me.name, source_p->name, 'O', aconf->user, aconf->host,
337 <                   conf->name, oper_privs_as_string(aconf->port),
338 <                   aconf->class_ptr ? aconf->class_ptr->name : "<default>");
336 >                   me.name, source_p->name, 'O', conf->user, conf->host,
337 >                   conf->name, oper_privs_as_string(conf->port),
338 >                   conf->class ? conf->class->name : "<default>");
339        else
340          sendto_one(source_p, form_str(RPL_STATSOLINE),
341 <                   me.name, source_p->name, 'O', aconf->user, aconf->host,
341 >                   me.name, source_p->name, 'O', conf->user, conf->host,
342                     conf->name, "0",
343 <                   aconf->class_ptr ? aconf->class_ptr->name : "<default>");
343 >                   conf->class ? conf->class->name : "<default>");
344      }
345      break;
346  
347 <  case CLASS_TYPE:
348 <    DLINK_FOREACH(ptr, class_items.head)
347 >  case CONF_CLASS:
348 >    DLINK_FOREACH(ptr, class_get_list()->head)
349      {
350 <      conf = ptr->data;
720 <      classitem = map_to_conf(conf);
350 >      class = ptr->data;
351        sendto_one(source_p, form_str(RPL_STATSYLINE),
352                   me.name, source_p->name, 'Y',
353 <                 conf->name, PingFreq(classitem),
354 <                 ConFreq(classitem),
355 <                 MaxTotal(classitem), MaxSendq(classitem),
356 <                 CurrUserCount(classitem),
357 <                 classitem->active ? "active" : "disabled");
353 >                 class->name, class->ping_freq,
354 >                 class->con_freq,
355 >                 class->max_total, class->max_sendq,
356 >                 class->max_recvq,
357 >                 class->ref_count,
358 >                 class->number_per_cidr, class->cidr_bitlen_ipv4,
359 >                 class->number_per_cidr, class->cidr_bitlen_ipv6,
360 >                 class->active ? "active" : "disabled");
361      }
362      break;
363  
364 <  case CONF_TYPE:
365 <  case CLIENT_TYPE:
364 >  case CONF_SERVICE:
365 >    DLINK_FOREACH(ptr, service_items.head)
366 >    {
367 >      conf = ptr->data;
368 >      sendto_one(source_p, form_str(RPL_STATSSERVICE),
369 >                 me.name, source_p->name, 'S', "*", conf->name, 0, 0);
370 >    }
371      break;
372  
373 <  case SERVER_TYPE:
373 >  case CONF_SERVER:
374      DLINK_FOREACH(ptr, server_items.head)
375      {
376        p = buf;
739
377        conf = ptr->data;
741      aconf = map_to_conf(conf);
378  
379        buf[0] = '\0';
380  
381 <      if (IsConfAllowAutoConn(aconf))
381 >      if (IsConfAllowAutoConn(conf))
382          *p++ = 'A';
383 <      if (IsConfCryptLink(aconf))
384 <        *p++ = 'C';
749 <      if (aconf->fakename)
750 <        *p++ = 'M';
751 <      if (IsConfTopicBurst(aconf))
752 <        *p++ = 'T';
753 <      if (IsConfCompressed(aconf))
754 <        *p++ = 'Z';
383 >      if (IsConfSSL(conf))
384 >        *p++ = 'S';
385        if (buf[0] == '\0')
386          *p++ = '*';
387  
# Line 760 | Line 390 | report_confitem_types(struct Client *sou
390        /*
391         * Allow admins to see actual ips unless hide_server_ips is enabled
392         */
393 <      if (!ConfigServerHide.hide_server_ips && IsAdmin(source_p))
393 >      if (!ConfigServerHide.hide_server_ips && HasUMode(source_p, UMODE_ADMIN))
394          sendto_one(source_p, form_str(RPL_STATSCLINE),
395 <                   me.name, source_p->name, 'C', aconf->host,
396 <                   buf, conf->name, aconf->port,
397 <                   aconf->class_ptr ? aconf->class_ptr->name : "<default>");
395 >                   me.name, source_p->name, 'C', conf->host,
396 >                   buf, conf->name, conf->port,
397 >                   conf->class ? conf->class->name : "<default>");
398          else
399            sendto_one(source_p, form_str(RPL_STATSCLINE),
400                       me.name, source_p->name, 'C',
401 <                     "*@127.0.0.1", buf, conf->name, aconf->port,
402 <                     aconf->class_ptr ? aconf->class_ptr->name : "<default>");
401 >                     "*@127.0.0.1", buf, conf->name, conf->port,
402 >                     conf->class ? conf->class->name : "<default>");
403      }
404      break;
405  
406 <  case HUB_TYPE:
407 <    DLINK_FOREACH(ptr, hub_items.head)
406 >  case CONF_HUB:
407 >    DLINK_FOREACH(ptr, server_items.head)
408      {
409        conf = ptr->data;
410 <      matchitem = map_to_conf(conf);
411 <      sendto_one(source_p, form_str(RPL_STATSHLINE), me.name,
412 <                 source_p->name, 'H', matchitem->host, conf->name, 0, "*");
410 >
411 >      DLINK_FOREACH(dptr, conf->hub_list.head)
412 >        sendto_one(source_p, form_str(RPL_STATSHLINE), me.name,
413 >                   source_p->name, 'H', dptr->data, conf->name, 0, "*");
414      }
784    break;
415  
416 <  case LEAF_TYPE:
787 <    DLINK_FOREACH(ptr, leaf_items.head)
416 >    DLINK_FOREACH(ptr, server_items.head)
417      {
418        conf = ptr->data;
419 <      matchitem = map_to_conf(conf);
420 <      sendto_one(source_p, form_str(RPL_STATSLLINE), me.name,
421 <                 source_p->name, 'L', matchitem->host, conf->name, 0, "*");
419 >
420 >      DLINK_FOREACH(dptr, conf->leaf_list.head)
421 >        sendto_one(source_p, form_str(RPL_STATSLLINE), me.name,
422 >                   source_p->name, 'L', dptr->data, conf->name, 0, "*");
423      }
424 +
425      break;
426  
427 <  case GLINE_TYPE:
797 <  case KLINE_TYPE:
798 <  case DLINE_TYPE:
799 <  case EXEMPTDLINE_TYPE:
800 <  case CRESV_TYPE:
801 <  case NRESV_TYPE:
802 <  case CLUSTER_TYPE:
427 >  default:
428      break;
429    }
430   }
# Line 817 | Line 442 | report_confitem_types(struct Client *sou
442   *                Look for conf lines which have the same
443   *                status as the flags passed.
444   */
445 < static void *
446 < check_client(va_list args)
445 > int
446 > check_client(struct Client *source_p)
447   {
823  struct Client *source_p = va_arg(args, struct Client *);
824  const char *username = va_arg(args, const char *);
448    int i;
449  
450 <  /* I'm already in big trouble if source_p->localClient is NULL -db */
451 <  if ((i = verify_access(source_p, username)))
829 <    ilog(L_INFO, "Access denied: %s[%s]",
450 >  if ((i = verify_access(source_p)))
451 >    ilog(LOG_TYPE_IRCD, "Access denied: %s[%s]",
452           source_p->name, source_p->sockhost);
453  
454    switch (i)
455    {
456      case TOO_MANY:
457 <      sendto_realops_flags(UMODE_FULL, L_ALL,
457 >      sendto_realops_flags(UMODE_FULL, L_ALL, SEND_NOTICE,
458                             "Too many on IP for %s (%s).",
459                             get_client_name(source_p, SHOW_IP),
460                             source_p->sockhost);
461 <      ilog(L_INFO,"Too many connections on IP from %s.",
461 >      ilog(LOG_TYPE_IRCD, "Too many connections on IP from %s.",
462             get_client_name(source_p, SHOW_IP));
463        ++ServerStats.is_ref;
464        exit_client(source_p, &me, "No more connections allowed on that IP");
465        break;
466  
467      case I_LINE_FULL:
468 <      sendto_realops_flags(UMODE_FULL, L_ALL,
469 <                           "I-line is full for %s (%s).",
468 >      sendto_realops_flags(UMODE_FULL, L_ALL, SEND_NOTICE,
469 >                           "auth{} block is full for %s (%s).",
470                             get_client_name(source_p, SHOW_IP),
471                             source_p->sockhost);
472 <      ilog(L_INFO,"Too many connections from %s.",
472 >      ilog(LOG_TYPE_IRCD, "Too many connections from %s.",
473             get_client_name(source_p, SHOW_IP));
474        ++ServerStats.is_ref;
475        exit_client(source_p, &me,
# Line 858 | Line 480 | check_client(va_list args)
480        ++ServerStats.is_ref;
481        /* jdc - lists server name & port connections are on */
482        /*       a purely cosmetical change */
483 <      sendto_realops_flags(UMODE_UNAUTH, L_ALL,
483 >      sendto_realops_flags(UMODE_UNAUTH, L_ALL, SEND_NOTICE,
484                             "Unauthorized client connection from %s [%s] on [%s/%u].",
485                             get_client_name(source_p, SHOW_IP),
486                             source_p->sockhost,
487                             source_p->localClient->listener->name,
488                             source_p->localClient->listener->port);
489 <      ilog(L_INFO,
489 >      ilog(LOG_TYPE_IRCD,
490            "Unauthorized client connection from %s on [%s/%u].",
491            get_client_name(source_p, SHOW_IP),
492            source_p->localClient->listener->name,
493            source_p->localClient->listener->port);
494  
495 <      /* XXX It is prolematical whether it is better to use the
874 <       * capture reject code here or rely on the connecting too fast code.
875 <       * - Dianora
876 <       */
877 <      if (REJECT_HOLD_TIME > 0)
878 <      {
879 <        sendto_one(source_p, ":%s NOTICE %s :You are not authorized to use this server",
880 <                   me.name, source_p->name);
881 <        source_p->localClient->reject_delay = CurrentTime + REJECT_HOLD_TIME;
882 <        SetCaptured(source_p);
883 <      }
884 <      else
885 <        exit_client(source_p, &me, "You are not authorized to use this server");
495 >      exit_client(source_p, &me, "You are not authorized to use this server");
496        break;
497  
498     case BANNED_CLIENT:
499 <     /*
890 <      * Don't exit them immediately, play with them a bit.
891 <      * - Dianora
892 <      */
893 <     if (REJECT_HOLD_TIME > 0)
894 <     {
895 <       source_p->localClient->reject_delay = CurrentTime + REJECT_HOLD_TIME;
896 <       SetCaptured(source_p);
897 <     }
898 <     else
899 <       exit_client(source_p, &me, "Banned");
499 >     exit_client(source_p, &me, "Banned");
500       ++ServerStats.is_ref;
501       break;
502  
# Line 905 | Line 505 | check_client(va_list args)
505       break;
506    }
507  
508 <  return (i < 0 ? NULL : source_p);
508 >  return (i < 0 ? 0 : 1);
509   }
510  
511   /* verify_access()
512   *
513   * inputs       - pointer to client to verify
914 *              - pointer to proposed username
514   * output       - 0 if success -'ve if not
515   * side effect  - find the first (best) I line to attach.
516   */
517   static int
518 < verify_access(struct Client *client_p, const char *username)
518 > verify_access(struct Client *client_p)
519   {
520 <  struct AccessItem *aconf = NULL, *rkconf = NULL;
922 <  struct ConfItem *conf = NULL;
520 >  struct MaskItem *conf = NULL, *rkconf = NULL;
521    char non_ident[USERLEN + 1] = { '~', '\0' };
522    const char *uhi[3];
523  
524    if (IsGotId(client_p))
525    {
526 <    aconf = find_address_conf(client_p->host, client_p->username,
526 >    conf = find_address_conf(client_p->host, client_p->username,
527                               &client_p->localClient->ip,
528                               client_p->localClient->aftype,
529                               client_p->localClient->passwd);
530    }
531    else
532    {
533 <    strlcpy(non_ident+1, username, sizeof(non_ident)-1);
534 <    aconf = find_address_conf(client_p->host,non_ident,
533 >    strlcpy(non_ident+1, client_p->username, sizeof(non_ident)-1);
534 >    conf = find_address_conf(client_p->host,non_ident,
535                               &client_p->localClient->ip,
536                               client_p->localClient->aftype,
537                               client_p->localClient->passwd);
# Line 945 | Line 543 | verify_access(struct Client *client_p, c
543  
544    rkconf = find_regexp_kline(uhi);
545  
546 <  if (aconf != NULL)
546 >  if (conf != NULL)
547    {
548 <    if (IsConfClient(aconf) && !rkconf)
548 >    if (IsConfClient(conf) && !rkconf)
549      {
550 <      conf = unmap_conf_item(aconf);
953 <
954 <      if (IsConfRedir(aconf))
550 >      if (IsConfRedir(conf))
551        {
552          sendto_one(client_p, form_str(RPL_REDIR),
553                     me.name, client_p->name,
554                     conf->name ? conf->name : "",
555 <                   aconf->port);
555 >                   conf->port);
556          return(NOT_AUTHORIZED);
557        }
558  
559 <      if (IsConfDoIdentd(aconf))
559 >      if (IsConfDoIdentd(conf))
560          SetNeedId(client_p);
561  
562        /* Thanks for spoof idea amm */
563 <      if (IsConfDoSpoofIp(aconf))
563 >      if (IsConfDoSpoofIp(conf))
564        {
565 <        conf = unmap_conf_item(aconf);
566 <
567 <        if (!ConfigFileEntry.hide_spoof_ips && IsConfSpoofNotice(aconf))
972 <          sendto_realops_flags(UMODE_ALL, L_ADMIN, "%s spoofing: %s as %s",
565 >        if (!ConfigFileEntry.hide_spoof_ips && IsConfSpoofNotice(conf))
566 >          sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
567 >                               "%s spoofing: %s as %s",
568                                 client_p->name, client_p->host, conf->name);
569          strlcpy(client_p->host, conf->name, sizeof(client_p->host));
570          SetIPSpoof(client_p);
# Line 977 | Line 572 | verify_access(struct Client *client_p, c
572  
573        return(attach_iline(client_p, conf));
574      }
575 <    else if (rkconf || IsConfKill(aconf) || (ConfigFileEntry.glines && IsConfGline(aconf)))
575 >    else if (rkconf || IsConfKill(conf) || (ConfigFileEntry.glines && IsConfGline(conf)))
576      {
577        /* XXX */
578 <      aconf = rkconf ? rkconf : aconf;
579 <      if (IsConfGline(aconf))
578 >      conf = rkconf ? rkconf : conf;
579 >      if (IsConfGline(conf))
580          sendto_one(client_p, ":%s NOTICE %s :*** G-lined", me.name,
581                     client_p->name);
582 <      if (ConfigFileEntry.kline_with_reason)
583 <        sendto_one(client_p, ":%s NOTICE %s :*** Banned %s",
989 <                  me.name, client_p->name, aconf->reason);
582 >      sendto_one(client_p, ":%s NOTICE %s :*** Banned: %s",
583 >                 me.name, client_p->name, conf->reason);
584        return(BANNED_CLIENT);
585      }
586    }
# Line 1002 | Line 596 | verify_access(struct Client *client_p, c
596   * side effects - do actual attach
597   */
598   static int
599 < attach_iline(struct Client *client_p, struct ConfItem *conf)
599 > attach_iline(struct Client *client_p, struct MaskItem *conf)
600   {
601 <  struct AccessItem *aconf;
1008 <  struct ClassItem *aclass;
601 >  struct ClassItem *class = NULL;
602    struct ip_entry *ip_found;
603    int a_limit_reached = 0;
604 <  int local = 0, global = 0, ident = 0;
604 >  unsigned int local = 0, global = 0, ident = 0;
605  
606    ip_found = find_or_add_ip(&client_p->localClient->ip);
607    ip_found->count++;
608    SetIpHash(client_p);
609  
610 <  aconf = map_to_conf(conf);
1018 <  if (aconf->class_ptr == NULL)
610 >  if (conf->class == NULL)
611      return NOT_AUTHORIZED;  /* If class is missing, this is best */
612  
613 <  aclass = map_to_conf(aconf->class_ptr);
613 >  class = conf->class;
614  
615    count_user_host(client_p->username, client_p->host,
616                    &global, &local, &ident);
# Line 1027 | Line 619 | attach_iline(struct Client *client_p, st
619     * setting a_limit_reached if any limit is reached.
620     * - Dianora
621     */
622 <  if (MaxTotal(aclass) != 0 && CurrUserCount(aclass) >= MaxTotal(aclass))
622 >  if (class->max_total != 0 && class->ref_count >= class->max_total)
623      a_limit_reached = 1;
624 <  else if (MaxPerIp(aclass) != 0 && ip_found->count > MaxPerIp(aclass))
624 >  else if (class->max_perip != 0 && ip_found->count > class->max_perip)
625      a_limit_reached = 1;
626 <  else if (MaxLocal(aclass) != 0 && local >= MaxLocal(aclass))
626 >  else if (class->max_local != 0 && local >= class->max_local)
627      a_limit_reached = 1;
628 <  else if (MaxGlobal(aclass) != 0 && global >= MaxGlobal(aclass))
628 >  else if (class->max_global != 0 && global >= class->max_global)
629      a_limit_reached = 1;
630 <  else if (MaxIdent(aclass) != 0 && ident >= MaxIdent(aclass) &&
630 >  else if (class->max_ident != 0 && ident >= class->max_ident &&
631             client_p->username[0] != '~')
632      a_limit_reached = 1;
633  
634    if (a_limit_reached)
635    {
636 <    if (!IsConfExemptLimits(aconf))
636 >    if (!IsConfExemptLimits(conf))
637        return TOO_MANY;   /* Already at maximum allowed */
638  
639      sendto_one(client_p,
# Line 1062 | Line 654 | attach_iline(struct Client *client_p, st
654   void
655   init_ip_hash_table(void)
656   {
657 <  ip_entry_heap = BlockHeapCreate("ip", sizeof(struct ip_entry),
657 >  ip_entry_pool = mp_pool_new(sizeof(struct ip_entry),
658      2 * hard_fdlimit);
659    memset(ip_hash_table, 0, sizeof(ip_hash_table));
660   }
# Line 1112 | Line 704 | find_or_add_ip(struct irc_ssaddr *ip_in)
704    if (ip_entries_count >= 2 * hard_fdlimit)
705      garbage_collect_ip_entries();
706  
707 <  newptr = BlockHeapAlloc(ip_entry_heap);
707 >  newptr = mp_pool_get(ip_entry_pool);
708 >  memset(newptr, 0, sizeof(*newptr));
709    ip_entries_count++;
710    memcpy(&newptr->ip, ip_in, sizeof(struct irc_ssaddr));
711  
# Line 1170 | Line 763 | remove_one_ip(struct irc_ssaddr *ip_in)
763        else
764          ip_hash_table[hash_index] = ptr->next;
765  
766 <      BlockHeapFree(ip_entry_heap, ptr);
766 >      mp_pool_release(ptr);
767        ip_entries_count--;
768        return;
769      }
# Line 1191 | Line 784 | hash_ip(struct irc_ssaddr *addr)
784    {
785      struct sockaddr_in *v4 = (struct sockaddr_in *)addr;
786      int hash;
787 <    u_int32_t ip;
787 >    uint32_t ip;
788  
789      ip   = ntohl(v4->sin_addr.s_addr);
790      hash = ((ip >> 12) + ip) & (IP_HASH_SIZE-1);
# Line 1202 | Line 795 | hash_ip(struct irc_ssaddr *addr)
795    {
796      int hash;
797      struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)addr;
798 <    u_int32_t *ip = (u_int32_t *)&v6->sin6_addr.s6_addr;
798 >    uint32_t *ip = (uint32_t *)&v6->sin6_addr.s6_addr;
799  
800      hash  = ip[0] ^ ip[3];
801      hash ^= hash >> 16;  
# Line 1226 | Line 819 | hash_ip(struct irc_ssaddr *addr)
819   * used in the hash.
820   */
821   void
822 < count_ip_hash(int *number_ips_stored, unsigned long *mem_ips_stored)
822 > count_ip_hash(unsigned int *number_ips_stored, uint64_t *mem_ips_stored)
823   {
824    struct ip_entry *ptr;
825    int i;
# Line 1273 | Line 866 | garbage_collect_ip_entries(void)
866            last_ptr->next = ptr->next;
867          else
868            ip_hash_table[i] = ptr->next;
869 <        BlockHeapFree(ip_entry_heap, ptr);
869 >        mp_pool_release(ptr);
870          ip_entries_count--;
871        }
872        else
# Line 1290 | Line 883 | garbage_collect_ip_entries(void)
883   * side effects - Disassociate configuration from the client.
884   *                Also removes a class from the list if marked for deleting.
885   */
886 < int
887 < detach_conf(struct Client *client_p, ConfType type)
886 > void
887 > detach_conf(struct Client *client_p, enum maskitem_type type)
888   {
889 <  dlink_node *ptr, *next_ptr;
1297 <  struct ConfItem *conf;
1298 <  struct ClassItem *aclass;
1299 <  struct AccessItem *aconf;
1300 <  struct ConfItem *aclass_conf;
1301 <  struct MatchItem *match_item;
889 >  dlink_node *ptr = NULL, *next_ptr = NULL;
890  
891    DLINK_FOREACH_SAFE(ptr, next_ptr, client_p->localClient->confs.head)
892    {
893 <    conf = ptr->data;
893 >    struct MaskItem *conf = ptr->data;
894  
895 <    if (type == CONF_TYPE || conf->type == type)
896 <    {
897 <      dlinkDelete(ptr, &client_p->localClient->confs);
1310 <      free_dlink_node(ptr);
1311 <
1312 <      switch (conf->type)
1313 <      {
1314 <      case CLIENT_TYPE:
1315 <      case OPER_TYPE:
1316 <      case SERVER_TYPE:
1317 <        aconf = map_to_conf(conf);
1318 <
1319 <        assert(aconf->clients > 0);
1320 <
1321 <        if ((aclass_conf = ClassPtr(aconf)) != NULL)
1322 <        {
1323 <          aclass = map_to_conf(aclass_conf);
895 >    assert(conf->type & (CONF_CLIENT | CONF_OPER | CONF_SERVER));
896 >    assert(conf->ref_count > 0);
897 >    assert(conf->class->ref_count > 0);
898  
899 <          assert(aclass->curr_user_count > 0);
900 <
1327 <          if (conf->type == CLIENT_TYPE)
1328 <            remove_from_cidr_check(&client_p->localClient->ip, aclass);
1329 <          if (--aclass->curr_user_count == 0 && aclass->active == 0)
1330 <            delete_conf_item(aclass_conf);
1331 <        }
1332 <
1333 <        if (--aconf->clients == 0 && IsConfIllegal(aconf))
1334 <          delete_conf_item(conf);
899 >    if (!(conf->type & type))
900 >      continue;
901  
902 <        break;
902 >    dlinkDelete(ptr, &client_p->localClient->confs);
903 >    free_dlink_node(ptr);
904  
905 <      case LEAF_TYPE:
906 <      case HUB_TYPE:
1340 <        match_item = map_to_conf(conf);
1341 <        if (match_item->ref_count == 0 && match_item->illegal)
1342 <          delete_conf_item(conf);
1343 <        break;
1344 <      default:
1345 <        break;
1346 <      }
905 >    if (conf->type == CONF_CLIENT)
906 >      remove_from_cidr_check(&client_p->localClient->ip, conf->class);
907  
908 <      if (type != CONF_TYPE)
909 <        return 0;
908 >    if (--conf->class->ref_count == 0 && conf->class->active == 0)
909 >    {
910 >      class_free(conf->class);
911 >      conf->class = NULL;
912      }
1351  }
913  
914 <  return -1;
914 >    if (--conf->ref_count == 0 && conf->active == 0)
915 >      conf_free(conf);
916 >  }
917   }
918  
919   /* attach_conf()
# Line 1364 | Line 927 | detach_conf(struct Client *client_p, Con
927   *                attachment if there was an old one...
928   */
929   int
930 < attach_conf(struct Client *client_p, struct ConfItem *conf)
930 > attach_conf(struct Client *client_p, struct MaskItem *conf)
931   {
932    if (dlinkFind(&client_p->localClient->confs, conf) != NULL)
933      return 1;
934  
935 <  if (conf->type == CLIENT_TYPE ||
936 <      conf->type == SERVER_TYPE ||
937 <      conf->type == OPER_TYPE)
938 <  {
1376 <    struct AccessItem *aconf = map_to_conf(conf);
1377 <    struct ClassItem *aclass = map_to_conf(aconf->class_ptr);
1378 <
1379 <    if (IsConfIllegal(aconf))
1380 <      return NOT_AUTHORIZED;
1381 <
1382 <    if (conf->type == CLIENT_TYPE)
1383 <      if (cidr_limit_reached(IsConfExemptLimits(aconf),
1384 <                             &client_p->localClient->ip, aclass))
1385 <        return TOO_MANY;    /* Already at maximum allowed */
935 >  if (conf->type == CONF_CLIENT)
936 >    if (cidr_limit_reached(IsConfExemptLimits(conf),
937 >                           &client_p->localClient->ip, conf->class))
938 >      return TOO_MANY;    /* Already at maximum allowed */
939  
940 <    CurrUserCount(aclass)++;
941 <    aconf->clients++;
1389 <  }
1390 <  else if (conf->type == HUB_TYPE || conf->type == LEAF_TYPE)
1391 <  {
1392 <    struct MatchItem *match_item = map_to_conf(conf);
1393 <    match_item->ref_count++;
1394 <  }
940 >  conf->class->ref_count++;
941 >  conf->ref_count++;
942  
943    dlinkAdd(conf, make_dlink_node(), &client_p->localClient->confs);
944  
# Line 1411 | Line 958 | attach_connect_block(struct Client *clie
958                       const char *host)
959   {
960    dlink_node *ptr;
961 <  struct ConfItem *conf;
1415 <  struct AccessItem *aconf;
961 >  struct MaskItem *conf = NULL;
962  
963    assert(client_p != NULL);
964    assert(host != NULL);
# Line 1423 | Line 969 | attach_connect_block(struct Client *clie
969    DLINK_FOREACH(ptr, server_items.head)
970    {
971      conf = ptr->data;
1426    aconf = map_to_conf(conf);
972  
973 <    if (match(conf->name, name) == 0 || match(aconf->host, host) == 0)
973 >    if (match(conf->name, name) || match(conf->host, host))
974        continue;
975  
976      attach_conf(client_p, conf);
# Line 1435 | Line 980 | attach_connect_block(struct Client *clie
980    return 0;
981   }
982  
1438 /* find_conf_exact()
1439 *
1440 * inputs       - type of ConfItem
1441 *              - pointer to name to find
1442 *              - pointer to username to find
1443 *              - pointer to host to find
1444 * output       - NULL or pointer to conf found
1445 * side effects - find a conf entry which matches the hostname
1446 *                and has the same name.
1447 */
1448 struct ConfItem *
1449 find_conf_exact(ConfType type, const char *name, const char *user,
1450                const char *host)
1451 {
1452  dlink_node *ptr;
1453  dlink_list *list_p;
1454  struct ConfItem *conf = NULL;
1455  struct AccessItem *aconf;
1456
1457  /* Only valid for OPER_TYPE and ...? */
1458  list_p = map_to_list(type);
1459
1460  DLINK_FOREACH(ptr, (*list_p).head)
1461  {
1462    conf = ptr->data;
1463
1464    if (conf->name == NULL)
1465      continue;
1466    aconf = map_to_conf(conf);
1467    if (aconf->host == NULL)
1468      continue;
1469    if (irccmp(conf->name, name) != 0)
1470      continue;
1471
1472    /*
1473    ** Accept if the *real* hostname (usually sockethost)
1474    ** socket host) matches *either* host or name field
1475    ** of the configuration.
1476    */
1477    if (!match(aconf->host, host) || !match(aconf->user, user))
1478      continue;
1479    if (type == OPER_TYPE)
1480    {
1481      struct ClassItem *aclass = map_to_conf(aconf->class_ptr);
1482
1483      if (aconf->clients >= MaxTotal(aclass))
1484        continue;
1485    }
1486
1487    return conf;
1488  }
1489
1490  return NULL;
1491 }
1492
983   /* find_conf_name()
984   *
985   * inputs       - pointer to conf link list to search
# Line 1499 | Line 989 | find_conf_exact(ConfType type, const cha
989   * side effects - find a conf entry which matches the name
990   *                and has the given mask.
991   */
992 < struct ConfItem *
993 < find_conf_name(dlink_list *list, const char *name, ConfType type)
992 > struct MaskItem *
993 > find_conf_name(dlink_list *list, const char *name, enum maskitem_type type)
994   {
995    dlink_node *ptr;
996 <  struct ConfItem* conf;
996 >  struct MaskItem* conf;
997  
998    DLINK_FOREACH(ptr, list->head)
999    {
# Line 1512 | Line 1002 | find_conf_name(dlink_list *list, const c
1002      if (conf->type == type)
1003      {
1004        if (conf->name && (irccmp(conf->name, name) == 0 ||
1005 <                         match(conf->name, name)))
1005 >                         !match(conf->name, name)))
1006        return conf;
1007      }
1008    }
# Line 1527 | Line 1017 | find_conf_name(dlink_list *list, const c
1017   * side effects - none
1018   */
1019   static dlink_list *
1020 < map_to_list(ConfType type)
1020 > map_to_list(enum maskitem_type type)
1021   {
1022    switch(type)
1023    {
1024 <  case RXLINE_TYPE:
1024 >  case CONF_RKLINE:
1025 >    return(&rkconf_items);
1026 >    break;
1027 >  case CONF_RXLINE:
1028      return(&rxconf_items);
1029      break;
1030 <  case XLINE_TYPE:
1030 >  case CONF_XLINE:
1031      return(&xconf_items);
1032      break;
1033 <  case ULINE_TYPE:
1033 >  case CONF_ULINE:
1034      return(&uconf_items);
1035      break;
1036 <  case NRESV_TYPE:
1036 >  case CONF_NRESV:
1037      return(&nresv_items);
1038      break;
1039 <  case OPER_TYPE:
1039 >  case CONF_CRESV:
1040 >    return(&resv_channel_list);
1041 >  case CONF_OPER:
1042      return(&oconf_items);
1043      break;
1044 <  case CLASS_TYPE:
1550 <    return(&class_items);
1551 <    break;
1552 <  case SERVER_TYPE:
1044 >  case CONF_SERVER:
1045      return(&server_items);
1046      break;
1047 <  case CLUSTER_TYPE:
1047 >  case CONF_SERVICE:
1048 >    return(&service_items);
1049 >    break;
1050 >  case CONF_CLUSTER:
1051      return(&cluster_items);
1052      break;
1558  case CONF_TYPE:
1559  case GLINE_TYPE:
1560  case KLINE_TYPE:
1561  case DLINE_TYPE:
1562  case CRESV_TYPE:
1053    default:
1054      return NULL;
1055    }
# Line 1571 | Line 1061 | map_to_list(ConfType type)
1061   *              - pointer to name string to find
1062   *              - pointer to user
1063   *              - pointer to host
1064 < *              - optional action to match on as well
1065 < * output       - NULL or pointer to found struct MatchItem
1064 > *              - optional flags to match on as well
1065 > * output       - NULL or pointer to found struct MaskItem
1066   * side effects - looks for a match on name field
1067   */
1068 < struct ConfItem *
1069 < find_matching_name_conf(ConfType type, const char *name, const char *user,
1070 <                        const char *host, int action)
1068 > struct MaskItem *
1069 > find_matching_name_conf(enum maskitem_type type, const char *name, const char *user,
1070 >                        const char *host, unsigned int flags)
1071   {
1072    dlink_node *ptr=NULL;
1073 <  struct ConfItem *conf=NULL;
1584 <  struct AccessItem *aconf=NULL;
1585 <  struct MatchItem *match_item=NULL;
1073 >  struct MaskItem *conf=NULL;
1074    dlink_list *list_p = map_to_list(type);
1075  
1076    switch (type)
1077    {
1078 <    case RXLINE_TYPE:
1078 > #ifdef HAVE_LIBPCRE
1079 >  case CONF_RXLINE:
1080        DLINK_FOREACH(ptr, list_p->head)
1081        {
1082          conf = ptr->data;
1083 <        assert(conf->regexpname);
1083 >        assert(conf->regexuser);
1084  
1085 <        if (!ircd_pcre_exec(conf->regexpname, name))
1085 >        if (!ircd_pcre_exec(conf->regexuser, name))
1086            return conf;
1087        }
1088        break;
1089 + #endif
1090 +  case CONF_SERVICE:
1091 +    DLINK_FOREACH(ptr, list_p->head)
1092 +    {
1093 +      conf = ptr->data;
1094 +
1095 +      if (EmptyString(conf->name))
1096 +        continue;
1097 +      if ((name != NULL) && !irccmp(name, conf->name))
1098 +        return conf;
1099 +    }
1100 +    break;
1101  
1102 <  case XLINE_TYPE:
1103 <  case ULINE_TYPE:
1104 <  case NRESV_TYPE:
1102 >  case CONF_XLINE:
1103 >  case CONF_ULINE:
1104 >  case CONF_NRESV:
1105 >  case CONF_CRESV:
1106      DLINK_FOREACH(ptr, list_p->head)
1107      {
1108        conf = ptr->data;
1109  
1608      match_item = map_to_conf(conf);
1110        if (EmptyString(conf->name))
1111          continue;
1112 <      if ((name != NULL) && match_esc(conf->name, name))
1112 >      if ((name != NULL) && !match(conf->name, name))
1113        {
1114          if ((user == NULL && (host == NULL)))
1115            return conf;
1116 <        if ((match_item->action & action) != action)
1116 >        if ((conf->flags & flags) != flags)
1117            continue;
1118 <        if (EmptyString(match_item->user) || EmptyString(match_item->host))
1118 >        if (EmptyString(conf->user) || EmptyString(conf->host))
1119            return conf;
1120 <        if (match(match_item->user, user) && match(match_item->host, host))
1120 >        if (!match(conf->user, user) && !match(conf->host, host))
1121            return conf;
1122        }
1123      }
1124        break;
1125  
1126 <  case SERVER_TYPE:
1126 >  case CONF_SERVER:
1127      DLINK_FOREACH(ptr, list_p->head)
1128      {
1129        conf = ptr->data;
1629      aconf = map_to_conf(conf);
1130  
1131 <      if ((name != NULL) && match_esc(name, conf->name))
1131 >      if ((name != NULL) && !match(name, conf->name))
1132          return conf;
1133 <      else if ((host != NULL) && match_esc(host, aconf->host))
1133 >      else if ((host != NULL) && !match(host, conf->host))
1134          return conf;
1135      }
1136      break;
# Line 1647 | Line 1147 | find_matching_name_conf(ConfType type, c
1147   *              - pointer to name string to find
1148   *              - pointer to user
1149   *              - pointer to host
1150 < * output       - NULL or pointer to found struct MatchItem
1150 > * output       - NULL or pointer to found struct MaskItem
1151   * side effects - looks for an exact match on name field
1152   */
1153 < struct ConfItem *
1154 < find_exact_name_conf(ConfType type, const char *name,
1153 > struct MaskItem *
1154 > find_exact_name_conf(enum maskitem_type type, const struct Client *who, const char *name,
1155                       const char *user, const char *host)
1156   {
1157    dlink_node *ptr = NULL;
1158 <  struct AccessItem *aconf;
1159 <  struct ConfItem *conf;
1660 <  struct MatchItem *match_item;
1661 <  dlink_list *list_p;
1662 <
1663 <  list_p = map_to_list(type);
1158 >  struct MaskItem *conf;
1159 >  dlink_list *list_p = map_to_list(type);
1160  
1161    switch(type)
1162    {
1163 <  case RXLINE_TYPE:
1164 <  case XLINE_TYPE:
1165 <  case ULINE_TYPE:
1166 <  case NRESV_TYPE:
1163 >  case CONF_RXLINE:
1164 >  case CONF_XLINE:
1165 >  case CONF_ULINE:
1166 >  case CONF_NRESV:
1167 >  case CONF_CRESV:
1168  
1169      DLINK_FOREACH(ptr, list_p->head)
1170      {
1171        conf = ptr->data;
1172 <      match_item = (struct MatchItem *)map_to_conf(conf);
1172 >
1173        if (EmptyString(conf->name))
1174          continue;
1175      
# Line 1680 | Line 1177 | find_exact_name_conf(ConfType type, cons
1177        {
1178          if ((user == NULL && (host == NULL)))
1179            return (conf);
1180 <        if (EmptyString(match_item->user) || EmptyString(match_item->host))
1180 >        if (EmptyString(conf->user) || EmptyString(conf->host))
1181            return (conf);
1182 <        if (match(match_item->user, user) && match(match_item->host, host))
1182 >        if (!match(conf->user, user) && !match(conf->host, host))
1183            return (conf);
1184        }
1185      }
1186      break;
1187  
1188 <  case OPER_TYPE:
1188 >  case CONF_OPER:
1189      DLINK_FOREACH(ptr, list_p->head)
1190      {
1191        conf = ptr->data;
1192 <      aconf = (struct AccessItem *)map_to_conf(conf);
1192 >
1193        if (EmptyString(conf->name))
1194 <        continue;
1195 <    
1196 <      if (irccmp(conf->name, name) == 0)
1194 >        continue;
1195 >
1196 >      if (!irccmp(conf->name, name))
1197        {
1198 <        if ((user == NULL && (host == NULL)))
1199 <          return (conf);
1200 <        if (EmptyString(aconf->user) || EmptyString(aconf->host))
1201 <          return (conf);
1202 <        if (match(aconf->user, user) && match(aconf->host, host))
1203 <          return (conf);
1198 >        if (!who)
1199 >          return conf;
1200 >        if (EmptyString(conf->user) || EmptyString(conf->host))
1201 >          return NULL;
1202 >        if (!match(conf->user, who->username))
1203 >        {
1204 >          switch (conf->htype)
1205 >          {
1206 >            case HM_HOST:
1207 >              if (!match(conf->host, who->host) || !match(conf->host, who->sockhost))
1208 >                if (!conf->class->max_total || conf->class->ref_count < conf->class->max_total)
1209 >                  return conf;
1210 >              break;
1211 >            case HM_IPV4:
1212 >              if (who->localClient->aftype == AF_INET)
1213 >                if (match_ipv4(&who->localClient->ip, &conf->addr, conf->bits))
1214 >                  if (!conf->class->max_total || conf->class->ref_count < conf->class->max_total)
1215 >                    return conf;
1216 >              break;
1217 > #ifdef IPV6
1218 >            case HM_IPV6:
1219 >              if (who->localClient->aftype == AF_INET6)
1220 >                if (match_ipv6(&who->localClient->ip, &conf->addr, conf->bits))
1221 >                  if (!conf->class->max_total || conf->class->ref_count < conf->class->max_total)
1222 >                    return conf;
1223 >              break;
1224 > #endif
1225 >            default:
1226 >              assert(0);
1227 >          }
1228 >        }
1229        }
1230      }
1231 +
1232      break;
1233  
1234 <  case SERVER_TYPE:
1234 >  case CONF_SERVER:
1235      DLINK_FOREACH(ptr, list_p->head)
1236      {
1237        conf = ptr->data;
1238 <      aconf = (struct AccessItem *)map_to_conf(conf);
1238 >
1239        if (EmptyString(conf->name))
1240          continue;
1241      
1242        if (name == NULL)
1243        {
1244 <        if (EmptyString(aconf->host))
1244 >        if (EmptyString(conf->host))
1245            continue;
1246 <        if (irccmp(aconf->host, host) == 0)
1246 >        if (irccmp(conf->host, host) == 0)
1247            return(conf);
1248        }
1249        else if (irccmp(conf->name, name) == 0)
# Line 1730 | Line 1253 | find_exact_name_conf(ConfType type, cons
1253      }
1254      break;
1255  
1733  case CLASS_TYPE:
1734    DLINK_FOREACH(ptr, list_p->head)
1735    {
1736      conf = ptr->data;
1737      if (EmptyString(conf->name))
1738        continue;
1739    
1740      if (irccmp(conf->name, name) == 0)
1741        return (conf);
1742    }
1743    break;
1744
1256    default:
1257      break;
1258    }
# Line 1758 | Line 1269 | int
1269   rehash(int sig)
1270   {
1271    if (sig != 0)
1272 <    sendto_realops_flags(UMODE_ALL, L_ALL,
1272 >    sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1273                           "Got signal SIGHUP, reloading ircd.conf file");
1274  
1764 #ifndef _WIN32
1275    restart_resolver();
1276 < #endif
1276 >
1277    /* don't close listeners until we know we can go ahead with the rehash */
1278  
1279    /* Check to see if we magically got(or lost) IPv6 support */
# Line 1774 | Line 1284 | rehash(int sig)
1284    if (ServerInfo.description != NULL)
1285      strlcpy(me.info, ServerInfo.description, sizeof(me.info));
1286  
1777 #ifndef STATIC_MODULES
1287    load_conf_modules();
1779 #endif
1780
1781  flush_deleted_I_P();
1288  
1289    rehashed_klines = 1;
1290 <
1290 > /* XXX */
1291    if (ConfigLoggingEntry.use_logging)
1292 <    reopen_log(logFileName);
1292 >    log_close_all();
1293  
1294    return(0);
1295   }
# Line 1803 | Line 1309 | set_default_conf(void)
1309    /* verify init_class() ran, this should be an unnecessary check
1310     * but its not much work.
1311     */
1312 <  assert(class_default == (struct ConfItem *) class_items.tail->data);
1312 >  assert(class_default == class_get_list()->tail->data);
1313  
1314   #ifdef HAVE_LIBCRYPTO
1315    ServerInfo.rsa_private_key = NULL;
# Line 1813 | Line 1319 | set_default_conf(void)
1319    /* ServerInfo.name is not rehashable */
1320    /* ServerInfo.name = ServerInfo.name; */
1321    ServerInfo.description = NULL;
1322 <  DupString(ServerInfo.network_name, NETWORK_NAME_DEFAULT);
1323 <  DupString(ServerInfo.network_desc, NETWORK_DESC_DEFAULT);
1322 >  ServerInfo.network_name = xstrdup(NETWORK_NAME_DEFAULT);
1323 >  ServerInfo.network_desc = xstrdup(NETWORK_DESC_DEFAULT);
1324  
1325    memset(&ServerInfo.ip, 0, sizeof(ServerInfo.ip));
1326    ServerInfo.specific_ipv4_vhost = 0;
# Line 1822 | Line 1328 | set_default_conf(void)
1328    ServerInfo.specific_ipv6_vhost = 0;
1329  
1330    ServerInfo.max_clients = MAXCLIENTS_MAX;
1331 <  /* Don't reset hub, as that will break lazylinks */
1332 <  /* ServerInfo.hub = NO; */
1331 >  ServerInfo.max_nick_length = 9;
1332 >  ServerInfo.max_topic_length = 80;
1333 >
1334 >  ServerInfo.hub = 0;
1335    ServerInfo.dns_host.sin_addr.s_addr = 0;
1336    ServerInfo.dns_host.sin_port = 0;
1337    AdminInfo.name = NULL;
1338    AdminInfo.email = NULL;
1339    AdminInfo.description = NULL;
1340  
1341 <  set_log_level(L_NOTICE);
1341 >  log_close_all();
1342 >
1343    ConfigLoggingEntry.use_logging = 1;
1344 <  ConfigLoggingEntry.operlog[0] = '\0';
1345 <  ConfigLoggingEntry.userlog[0] = '\0';
1346 <  ConfigLoggingEntry.klinelog[0] = '\0';
1838 <  ConfigLoggingEntry.glinelog[0] = '\0';
1839 <  ConfigLoggingEntry.killlog[0] = '\0';
1840 <  ConfigLoggingEntry.operspylog[0] = '\0';
1841 <  ConfigLoggingEntry.ioerrlog[0] = '\0';
1842 <  ConfigLoggingEntry.failed_operlog[0] = '\0';
1843 <
1844 <  ConfigChannel.disable_fake_channels = NO;
1845 <  ConfigChannel.restrict_channels = NO;
1846 <  ConfigChannel.disable_local_channels = NO;
1847 <  ConfigChannel.use_invex = YES;
1848 <  ConfigChannel.use_except = YES;
1849 <  ConfigChannel.use_knock = YES;
1344 >
1345 >  ConfigChannel.disable_fake_channels = 0;
1346 >  ConfigChannel.restrict_channels = 0;
1347    ConfigChannel.knock_delay = 300;
1348    ConfigChannel.knock_delay_channel = 60;
1349 <  ConfigChannel.max_chans_per_user = 15;
1350 <  ConfigChannel.quiet_on_ban = YES;
1349 >  ConfigChannel.max_chans_per_user = 25;
1350 >  ConfigChannel.max_chans_per_oper = 50;
1351 >  ConfigChannel.quiet_on_ban = 1;
1352    ConfigChannel.max_bans = 25;
1353    ConfigChannel.default_split_user_count = 0;
1354    ConfigChannel.default_split_server_count = 0;
1355 <  ConfigChannel.no_join_on_split = NO;
1356 <  ConfigChannel.no_create_on_split = NO;
1859 <  ConfigChannel.burst_topicwho = YES;
1355 >  ConfigChannel.no_join_on_split = 0;
1356 >  ConfigChannel.no_create_on_split = 0;
1357  
1358 <  ConfigServerHide.flatten_links = NO;
1358 >  ConfigServerHide.flatten_links = 0;
1359    ConfigServerHide.links_delay = 300;
1360 <  ConfigServerHide.hidden = NO;
1361 <  ConfigServerHide.disable_hidden = NO;
1362 <  ConfigServerHide.hide_servers = NO;
1363 <  DupString(ConfigServerHide.hidden_name, NETWORK_NAME_DEFAULT);
1867 <  ConfigServerHide.hide_server_ips = NO;
1360 >  ConfigServerHide.hidden = 0;
1361 >  ConfigServerHide.hide_servers = 0;
1362 >  ConfigServerHide.hidden_name = xstrdup(NETWORK_NAME_DEFAULT);
1363 >  ConfigServerHide.hide_server_ips = 0;
1364  
1365    
1366 +  ConfigFileEntry.service_name = xstrdup(SERVICE_NAME_DEFAULT);
1367    ConfigFileEntry.max_watch = WATCHSIZE_DEFAULT;
1368 +  ConfigFileEntry.glines = 0;
1369 +  ConfigFileEntry.gline_time = 12 * 3600;
1370 +  ConfigFileEntry.gline_request_time = GLINE_REQUEST_EXPIRE_DEFAULT;
1371    ConfigFileEntry.gline_min_cidr = 16;
1372    ConfigFileEntry.gline_min_cidr6 = 48;
1373 <  ConfigFileEntry.invisible_on_connect = YES;
1374 <  ConfigFileEntry.burst_away = NO;
1375 <  ConfigFileEntry.use_whois_actually = YES;
1376 <  ConfigFileEntry.tkline_expire_notices = YES;
1377 <  ConfigFileEntry.hide_spoof_ips = YES;
1378 <  ConfigFileEntry.ignore_bogus_ts = NO;
1879 <  ConfigFileEntry.disable_auth = NO;
1880 <  ConfigFileEntry.disable_remote = NO;
1373 >  ConfigFileEntry.invisible_on_connect = 1;
1374 >  ConfigFileEntry.tkline_expire_notices = 1;
1375 >  ConfigFileEntry.hide_spoof_ips = 1;
1376 >  ConfigFileEntry.ignore_bogus_ts = 0;
1377 >  ConfigFileEntry.disable_auth = 0;
1378 >  ConfigFileEntry.disable_remote = 0;
1379    ConfigFileEntry.kill_chase_time_limit = 90;
1380 <  ConfigFileEntry.default_floodcount = 8; /* XXX */
1381 <  ConfigFileEntry.failed_oper_notice = YES;
1382 <  ConfigFileEntry.dots_in_ident = 0;      /* XXX */
1885 <  ConfigFileEntry.dot_in_ip6_addr = YES;
1380 >  ConfigFileEntry.default_floodcount = 8;
1381 >  ConfigFileEntry.failed_oper_notice = 1;
1382 >  ConfigFileEntry.dots_in_ident = 0;
1383    ConfigFileEntry.min_nonwildcard = 4;
1384    ConfigFileEntry.min_nonwildcard_simple = 3;
1385    ConfigFileEntry.max_accept = 20;
1386 <  ConfigFileEntry.anti_nick_flood = NO;   /* XXX */
1386 >  ConfigFileEntry.anti_nick_flood = 0;
1387    ConfigFileEntry.max_nick_time = 20;
1388    ConfigFileEntry.max_nick_changes = 5;
1389 <  ConfigFileEntry.anti_spam_exit_message_time = 0;  /* XXX */
1389 >  ConfigFileEntry.anti_spam_exit_message_time = 0;
1390    ConfigFileEntry.ts_warn_delta = TS_WARN_DELTA_DEFAULT;
1391 <  ConfigFileEntry.ts_max_delta = TS_MAX_DELTA_DEFAULT;  /* XXX */
1392 <  ConfigFileEntry.kline_with_reason = YES;
1393 <  ConfigFileEntry.kline_reason = NULL;
1897 <  ConfigFileEntry.warn_no_nline = YES;
1898 <  ConfigFileEntry.stats_o_oper_only = NO; /* XXX */
1391 >  ConfigFileEntry.ts_max_delta = TS_MAX_DELTA_DEFAULT;
1392 >  ConfigFileEntry.warn_no_nline = 1;
1393 >  ConfigFileEntry.stats_o_oper_only = 0;
1394    ConfigFileEntry.stats_k_oper_only = 1;  /* masked */
1395    ConfigFileEntry.stats_i_oper_only = 1;  /* masked */
1396 <  ConfigFileEntry.stats_P_oper_only = NO;
1396 >  ConfigFileEntry.stats_P_oper_only = 0;
1397    ConfigFileEntry.caller_id_wait = 60;
1398 <  ConfigFileEntry.opers_bypass_callerid = NO;
1398 >  ConfigFileEntry.opers_bypass_callerid = 0;
1399    ConfigFileEntry.pace_wait = 10;
1400    ConfigFileEntry.pace_wait_simple = 1;
1401 <  ConfigFileEntry.short_motd = NO;
1402 <  ConfigFileEntry.ping_cookie = NO;
1403 <  ConfigFileEntry.no_oper_flood = NO;     /* XXX */
1404 <  ConfigFileEntry.true_no_oper_flood = NO;  /* XXX */
1405 <  ConfigFileEntry.oper_pass_resv = YES;
1911 <  ConfigFileEntry.glines = NO;            /* XXX */
1912 <  ConfigFileEntry.gline_time = 12 * 3600; /* XXX */
1913 <  ConfigFileEntry.idletime = 0;
1401 >  ConfigFileEntry.short_motd = 0;
1402 >  ConfigFileEntry.ping_cookie = 0;
1403 >  ConfigFileEntry.no_oper_flood = 0;
1404 >  ConfigFileEntry.true_no_oper_flood = 0;
1405 >  ConfigFileEntry.oper_pass_resv = 1;
1406    ConfigFileEntry.max_targets = MAX_TARGETS_DEFAULT;
1407 <  ConfigFileEntry.client_flood = CLIENT_FLOOD_DEFAULT;
1916 <  ConfigFileEntry.oper_only_umodes = UMODE_DEBUG;  /* XXX */
1407 >  ConfigFileEntry.oper_only_umodes = UMODE_DEBUG;
1408    ConfigFileEntry.oper_umodes = UMODE_BOTS | UMODE_LOCOPS | UMODE_SERVNOTICE |
1409 <    UMODE_OPERWALL | UMODE_WALLOP;        /* XXX */
1410 <  DupString(ConfigFileEntry.servlink_path, SLPATH);
1920 < #ifdef HAVE_LIBCRYPTO
1921 <  /* jdc -- This is our default value for a cipher.  According to the
1922 <   *        CRYPTLINK document (doc/cryptlink.txt), BF/128 must be supported
1923 <   *        under all circumstances if cryptlinks are enabled.  So,
1924 <   *        this will be our default.
1925 <   *
1926 <   *        NOTE: I apologise for the hard-coded value of "1" (BF/128).
1927 <   *              This should be moved into a find_cipher() routine.
1928 <   */
1929 <  ConfigFileEntry.default_cipher_preference = &CipherTable[1];
1930 < #endif
1931 <  ConfigFileEntry.use_egd = NO;
1409 >    UMODE_OPERWALL | UMODE_WALLOP;
1410 >  ConfigFileEntry.use_egd = 0;
1411    ConfigFileEntry.egdpool_path = NULL;
1933 #ifdef HAVE_LIBZ
1934  ConfigFileEntry.compression_level = 0;
1935 #endif
1412    ConfigFileEntry.throttle_time = 10;
1413   }
1414  
1415 + static void
1416 + validate_conf(void)
1417 + {
1418 +  if (ConfigFileEntry.ts_warn_delta < TS_WARN_DELTA_MIN)
1419 +    ConfigFileEntry.ts_warn_delta = TS_WARN_DELTA_DEFAULT;
1420 +
1421 +  if (ConfigFileEntry.ts_max_delta < TS_MAX_DELTA_MIN)
1422 +    ConfigFileEntry.ts_max_delta = TS_MAX_DELTA_DEFAULT;
1423 +
1424 +  if (ServerInfo.network_name == NULL)
1425 +    ServerInfo.network_name = xstrdup(NETWORK_NAME_DEFAULT);
1426 +
1427 +  if (ServerInfo.network_desc == NULL)
1428 +    ServerInfo.network_desc = xstrdup(NETWORK_DESC_DEFAULT);
1429 +
1430 +  if (ConfigFileEntry.service_name == NULL)
1431 +    ConfigFileEntry.service_name = xstrdup(SERVICE_NAME_DEFAULT);
1432 +
1433 +  ConfigFileEntry.max_watch = IRCD_MAX(ConfigFileEntry.max_watch, WATCHSIZE_MIN);
1434 + }
1435 +
1436   /* read_conf()
1437   *
1438   * inputs       - file descriptor pointing to config file to use
# Line 1943 | Line 1440 | set_default_conf(void)
1440   * side effects - Read configuration file.
1441   */
1442   static void
1443 < read_conf(FBFILE *file)
1443 > read_conf(FILE *file)
1444   {
1445    lineno = 0;
1446  
1447    set_default_conf(); /* Set default values prior to conf parsing */
1448 <  ypass = 1;
1448 >  conf_parser_ctx.pass = 1;
1449    yyparse();          /* pick up the classes first */
1450  
1451 <  fbrewind(file);
1451 >  rewind(file);
1452  
1453 <  ypass = 2;
1453 >  conf_parser_ctx.pass = 2;
1454    yyparse();          /* Load the values from the conf */
1455    validate_conf();    /* Check to make sure some values are still okay. */
1456                        /* Some global values are also loaded here. */
1457 <  check_class();      /* Make sure classes are valid */
1961 < }
1962 <
1963 < static void
1964 < validate_conf(void)
1965 < {
1966 <  if (ConfigFileEntry.ts_warn_delta < TS_WARN_DELTA_MIN)
1967 <    ConfigFileEntry.ts_warn_delta = TS_WARN_DELTA_DEFAULT;
1968 <
1969 <  if (ConfigFileEntry.ts_max_delta < TS_MAX_DELTA_MIN)
1970 <    ConfigFileEntry.ts_max_delta = TS_MAX_DELTA_DEFAULT;
1971 <
1972 <  if (ConfigFileEntry.servlink_path == NULL)
1973 <    DupString(ConfigFileEntry.servlink_path, SLPATH);
1974 <
1975 <  if (ServerInfo.network_name == NULL)
1976 <    DupString(ServerInfo.network_name,NETWORK_NAME_DEFAULT);
1977 <
1978 <  if (ServerInfo.network_desc == NULL)
1979 <    DupString(ServerInfo.network_desc,NETWORK_DESC_DEFAULT);
1980 <
1981 <  if ((ConfigFileEntry.client_flood < CLIENT_FLOOD_MIN) ||
1982 <      (ConfigFileEntry.client_flood > CLIENT_FLOOD_MAX))
1983 <    ConfigFileEntry.client_flood = CLIENT_FLOOD_MAX;
1984 <
1985 <  ConfigFileEntry.max_watch = IRCD_MAX(ConfigFileEntry.max_watch, WATCHSIZE_MIN);
1457 >  class_delete_marked();      /* Make sure classes are valid */
1458   }
1459  
1460   /* lookup_confhost()
# Line 1990 | Line 1462 | validate_conf(void)
1462   * start DNS lookups of all hostnames in the conf
1463   * line and convert an IP addresses in a.b.c.d number for to IP#s.
1464   */
1465 < static void
1466 < lookup_confhost(struct ConfItem *conf)
1465 > void
1466 > lookup_confhost(struct MaskItem *conf)
1467   {
1996  struct AccessItem *aconf;
1468    struct addrinfo hints, *res;
1469  
1999  aconf = map_to_conf(conf);
2000
2001  if (EmptyString(aconf->host) ||
2002      EmptyString(aconf->user))
2003  {
2004    ilog(L_ERROR, "Host/server name error: (%s) (%s)",
2005         aconf->host, conf->name);
2006    return;
2007  }
2008
2009  if (strchr(aconf->host, '*') ||
2010      strchr(aconf->host, '?'))
2011    return;
2012
1470    /* Do name lookup now on hostnames given and store the
1471     * ip numbers in conf structure.
1472     */
# Line 2021 | Line 1478 | lookup_confhost(struct ConfItem *conf)
1478    /* Get us ready for a bind() and don't bother doing dns lookup */
1479    hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
1480  
1481 <  if (irc_getaddrinfo(aconf->host, NULL, &hints, &res))
1481 >  if (getaddrinfo(conf->host, NULL, &hints, &res))
1482    {
1483 <    conf_dns_lookup(aconf);
1483 >    conf_dns_lookup(conf);
1484      return;
1485    }
1486  
1487    assert(res != NULL);
1488  
1489 <  memcpy(&aconf->ipnum, res->ai_addr, res->ai_addrlen);
1490 <  aconf->ipnum.ss_len = res->ai_addrlen;
1491 <  aconf->ipnum.ss.ss_family = res->ai_family;
1492 <  irc_freeaddrinfo(res);
1489 >  memcpy(&conf->addr, res->ai_addr, res->ai_addrlen);
1490 >  conf->addr.ss_len = res->ai_addrlen;
1491 >  conf->addr.ss.ss_family = res->ai_family;
1492 >
1493 >  freeaddrinfo(res);
1494   }
1495  
1496   /* conf_connect_allowed()
# Line 2046 | Line 1504 | int
1504   conf_connect_allowed(struct irc_ssaddr *addr, int aftype)
1505   {
1506    struct ip_entry *ip_found;
1507 <  struct AccessItem *aconf = find_dline_conf(addr, aftype);
1507 >  struct MaskItem *conf = find_dline_conf(addr, aftype);
1508  
1509    /* DLINE exempt also gets you out of static limits/pacing... */
1510 <  if (aconf && (aconf->status & CONF_EXEMPTDLINE))
1510 >  if (conf && (conf->type == CONF_EXEMPT))
1511      return 0;
1512  
1513 <  if (aconf != NULL)
1513 >  if (conf != NULL)
1514      return BANNED_CLIENT;
1515  
1516    ip_found = find_or_add_ip(addr);
# Line 2068 | Line 1526 | conf_connect_allowed(struct irc_ssaddr *
1526    return 0;
1527   }
1528  
1529 < static struct AccessItem *
1529 > static struct MaskItem *
1530   find_regexp_kline(const char *uhi[])
1531   {
1532 + #ifdef HAVE_LIBPCRE
1533    const dlink_node *ptr = NULL;
1534  
1535    DLINK_FOREACH(ptr, rkconf_items.head)
1536    {
1537 <    struct AccessItem *aptr = map_to_conf(ptr->data);
1537 >    struct MaskItem *aptr = ptr->data;
1538  
1539      assert(aptr->regexuser);
1540      assert(aptr->regexhost);
# Line 2085 | Line 1544 | find_regexp_kline(const char *uhi[])
1544           !ircd_pcre_exec(aptr->regexhost, uhi[2])))
1545        return aptr;
1546    }
1547 <
1547 > #endif
1548    return NULL;
1549   }
1550  
1551   /* find_kill()
1552   *
1553   * inputs       - pointer to client structure
1554 < * output       - pointer to struct AccessItem if found
1554 > * output       - pointer to struct MaskItem if found
1555   * side effects - See if this user is klined already,
1556 < *                and if so, return struct AccessItem pointer
1556 > *                and if so, return struct MaskItem pointer
1557   */
1558 < struct AccessItem *
1558 > struct MaskItem *
1559   find_kill(struct Client *client_p)
1560   {
1561 <  struct AccessItem *aconf = NULL;
1561 >  struct MaskItem *conf = NULL;
1562    const char *uhi[3];
1563  
1564    uhi[0] = client_p->username;
# Line 2108 | Line 1567 | find_kill(struct Client *client_p)
1567  
1568    assert(client_p != NULL);
1569  
1570 <  aconf = find_kline_conf(client_p->host, client_p->username,
1571 <                          &client_p->localClient->ip,
1572 <                          client_p->localClient->aftype);
1573 <  if (aconf == NULL)
1574 <    aconf = find_regexp_kline(uhi);
2116 <
2117 <  if (aconf && (aconf->status & CONF_KLINE))
2118 <    return aconf;
1570 >  conf = find_conf_by_address(client_p->host, &client_p->localClient->ip,
1571 >                              CONF_KLINE, client_p->localClient->aftype,
1572 >                              client_p->username, NULL, 1);
1573 >  if (conf == NULL)
1574 >    conf = find_regexp_kline(uhi);
1575  
1576 <  return NULL;
1576 >  return conf;
1577   }
1578  
1579 < struct AccessItem *
1579 > struct MaskItem *
1580   find_gline(struct Client *client_p)
1581   {
1582 <  struct AccessItem *aconf;
1582 >  struct MaskItem *conf;
1583  
1584    assert(client_p != NULL);
1585  
1586 <  aconf = find_gline_conf(client_p->host, client_p->username,
1587 <                          &client_p->localClient->ip,
1588 <                          client_p->localClient->aftype);
1589 <
2134 <  if (aconf && (aconf->status & CONF_GLINE))
2135 <    return aconf;
2136 <
2137 <  return NULL;
2138 < }
2139 <
2140 < /* add_temp_line()
2141 < *
2142 < * inputs        - pointer to struct ConfItem
2143 < * output        - none
2144 < * Side effects  - links in given struct ConfItem into
2145 < *                 temporary *line link list
2146 < */
2147 < void
2148 < add_temp_line(struct ConfItem *conf)
2149 < {
2150 <  struct AccessItem *aconf;
2151 <
2152 <  if (conf->type == DLINE_TYPE)
2153 <  {
2154 <    aconf = map_to_conf(conf);
2155 <    SetConfTemporary(aconf);
2156 <    dlinkAdd(conf, &conf->node, &temporary_dlines);
2157 <    MyFree(aconf->user);
2158 <    aconf->user = NULL;
2159 <    add_conf_by_address(CONF_DLINE, aconf);
2160 <  }
2161 <  else if (conf->type == KLINE_TYPE)
2162 <  {
2163 <    aconf = map_to_conf(conf);
2164 <    SetConfTemporary(aconf);
2165 <    dlinkAdd(conf, &conf->node, &temporary_klines);
2166 <    add_conf_by_address(CONF_KILL, aconf);
2167 <  }
2168 <  else if (conf->type == GLINE_TYPE)
2169 <  {
2170 <    aconf = map_to_conf(conf);
2171 <    SetConfTemporary(aconf);
2172 <    dlinkAdd(conf, &conf->node, &temporary_glines);
2173 <    add_conf_by_address(CONF_GLINE, aconf);
2174 <  }
2175 <  else if (conf->type == XLINE_TYPE)
2176 <  {
2177 <    conf->flags |= CONF_FLAGS_TEMPORARY;
2178 <    dlinkAdd(conf, make_dlink_node(), &temporary_xlines);
2179 <  }
2180 <  else if (conf->type == RXLINE_TYPE)
2181 <  {
2182 <    conf->flags |= CONF_FLAGS_TEMPORARY;
2183 <    dlinkAdd(conf, make_dlink_node(), &temporary_rxlines);
2184 <  }
2185 <  else if (conf->type == RKLINE_TYPE)
2186 <  {
2187 <    conf->flags |= CONF_FLAGS_TEMPORARY;
2188 <    dlinkAdd(conf, make_dlink_node(), &temporary_rklines);
2189 <  }
2190 <  else if ((conf->type == NRESV_TYPE) || (conf->type == CRESV_TYPE))
2191 <  {
2192 <    conf->flags |= CONF_FLAGS_TEMPORARY;
2193 <    dlinkAdd(conf, make_dlink_node(), &temporary_resv);
2194 <  }
1586 >  conf = find_conf_by_address(client_p->host, &client_p->localClient->ip,
1587 >                              CONF_GLINE, client_p->localClient->aftype,
1588 >                              client_p->username, NULL, 1);
1589 >  return conf;
1590   }
1591  
1592   /* cleanup_tklines()
# Line 2204 | Line 1599 | add_temp_line(struct ConfItem *conf)
1599   void
1600   cleanup_tklines(void *notused)
1601   {
1602 <  expire_tklines(&temporary_glines);
1603 <  expire_tklines(&temporary_klines);
1604 <  expire_tklines(&temporary_dlines);
1605 <  expire_tklines(&temporary_xlines);
2211 <  expire_tklines(&temporary_rxlines);
2212 <  expire_tklines(&temporary_rklines);
2213 <  expire_tklines(&temporary_resv);
1602 >  hostmask_expire_temporary();
1603 >  expire_tklines(&xconf_items);
1604 >  expire_tklines(&nresv_items);
1605 >  expire_tklines(&resv_channel_list);
1606   }
1607  
1608   /* expire_tklines()
# Line 2224 | Line 1616 | expire_tklines(dlink_list *tklist)
1616   {
1617    dlink_node *ptr;
1618    dlink_node *next_ptr;
1619 <  struct ConfItem *conf;
2228 <  struct MatchItem *xconf;
2229 <  struct MatchItem *nconf;
2230 <  struct AccessItem *aconf;
2231 <  struct ResvChannel *cconf;
1619 >  struct MaskItem *conf;
1620  
1621    DLINK_FOREACH_SAFE(ptr, next_ptr, tklist->head)
1622    {
1623      conf = ptr->data;
2236    if (conf->type == GLINE_TYPE ||
2237        conf->type == KLINE_TYPE ||
2238        conf->type == DLINE_TYPE)
2239    {
2240      aconf = (struct AccessItem *)map_to_conf(conf);
2241      if (aconf->hold <= CurrentTime)
2242      {
2243        /* XXX - Do we want GLINE expiry notices?? */
2244        /* Alert opers that a TKline expired - Hwy */
2245        if (ConfigFileEntry.tkline_expire_notices)
2246        {
2247          if (aconf->status & CONF_KILL)
2248          {
2249            sendto_realops_flags(UMODE_ALL, L_ALL,
2250                                 "Temporary K-line for [%s@%s] expired",
2251                                 (aconf->user) ? aconf->user : "*",
2252                                 (aconf->host) ? aconf->host : "*");
2253          }
2254          else if (conf->type == DLINE_TYPE)
2255          {
2256            sendto_realops_flags(UMODE_ALL, L_ALL,
2257                                 "Temporary D-line for [%s] expired",
2258                                 (aconf->host) ? aconf->host : "*");
2259          }
2260        }
1624  
1625 <        dlinkDelete(ptr, tklist);
1626 <        delete_one_address_conf(aconf->host, aconf);
1627 <      }
1628 <    }
2266 <    else if (conf->type == XLINE_TYPE ||
2267 <             conf->type == RXLINE_TYPE)
2268 <    {
2269 <      xconf = (struct MatchItem *)map_to_conf(conf);
2270 <      if (xconf->hold <= CurrentTime)
2271 <      {
2272 <        if (ConfigFileEntry.tkline_expire_notices)
2273 <          sendto_realops_flags(UMODE_ALL, L_ALL,
2274 <                               "Temporary X-line for [%s] %sexpired", conf->name,
2275 <                               conf->type == RXLINE_TYPE ? "(REGEX) " : "");
2276 <        dlinkDelete(ptr, tklist);
2277 <        free_dlink_node(ptr);
2278 <        delete_conf_item(conf);
2279 <      }
2280 <    }
2281 <    else if (conf->type == RKLINE_TYPE)
1625 >    if (!conf->until || conf->until > CurrentTime)
1626 >      continue;
1627 >
1628 >    if (conf->type == CONF_XLINE)
1629      {
1630 <      aconf = map_to_conf(conf);
1631 <      if (aconf->hold <= CurrentTime)
1632 <      {
1633 <        if (ConfigFileEntry.tkline_expire_notices)
2287 <           sendto_realops_flags(UMODE_ALL, L_ALL,
2288 <                                "Temporary K-line for [%s@%s] (REGEX) expired",
2289 <                                (aconf->user) ? aconf->user : "*",
2290 <                                (aconf->host) ? aconf->host : "*");
2291 <        dlinkDelete(ptr, tklist);
2292 <        free_dlink_node(ptr);
2293 <        delete_conf_item(conf);
2294 <      }
1630 >      if (ConfigFileEntry.tkline_expire_notices)
1631 >        sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1632 >                               "Temporary X-line for [%s] expired", conf->name);
1633 >      conf_free(conf);
1634      }
1635 <    else if (conf->type == NRESV_TYPE)
1635 >    else if (conf->type == CONF_NRESV || conf->type == CONF_CRESV)
1636      {
1637 <      nconf = (struct MatchItem *)map_to_conf(conf);
1638 <      if (nconf->hold <= CurrentTime)
2300 <      {
2301 <        if (ConfigFileEntry.tkline_expire_notices)
2302 <          sendto_realops_flags(UMODE_ALL, L_ALL,
1637 >      if (ConfigFileEntry.tkline_expire_notices)
1638 >        sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1639                                 "Temporary RESV for [%s] expired", conf->name);
1640 <        dlinkDelete(ptr, tklist);
2305 <        free_dlink_node(ptr);
2306 <        delete_conf_item(conf);
2307 <      }
2308 <    }
2309 <    else if (conf->type == CRESV_TYPE)
2310 <    {
2311 <      cconf = (struct ResvChannel *)map_to_conf(conf);
2312 <      if (cconf->hold <= CurrentTime)
2313 <      {
2314 <        if (ConfigFileEntry.tkline_expire_notices)
2315 <          sendto_realops_flags(UMODE_ALL, L_ALL,
2316 <                               "Temporary RESV for [%s] expired", cconf->name);
2317 <        delete_channel_resv(cconf);
2318 <      }
1640 >      conf_free(conf);
1641      }
1642    }
1643   }
# Line 2328 | Line 1650 | expire_tklines(dlink_list *tklist)
1650   */
1651   static const struct oper_privs
1652   {
1653 <  const unsigned int oprivs;
2332 <  const unsigned int hidden;
1653 >  const unsigned int flag;
1654    const unsigned char c;
1655   } flag_list[] = {
1656 <  { OPER_FLAG_ADMIN,       OPER_FLAG_HIDDEN_ADMIN,  'A' },
1657 <  { OPER_FLAG_REMOTEBAN,   0,                       'B' },
1658 <  { OPER_FLAG_DIE,         0,                       'D' },
1659 <  { OPER_FLAG_GLINE,       0,                       'G' },
1660 <  { OPER_FLAG_REHASH,      0,                       'H' },
1661 <  { OPER_FLAG_K,           0,                       'K' },
1662 <  { OPER_FLAG_OPERWALL,    0,                       'L' },
1663 <  { OPER_FLAG_N,           0,                       'N' },
1664 <  { OPER_FLAG_GLOBAL_KILL, 0,                       'O' },
1665 <  { OPER_FLAG_REMOTE,      0,                       'R' },
1666 <  { OPER_FLAG_OPER_SPY,    0,                       'S' },
1667 <  { OPER_FLAG_UNKLINE,     0,                       'U' },
1668 <  { OPER_FLAG_X,           0,                       'X' },
1669 <  { 0, 0, '\0' }
1656 >  { OPER_FLAG_ADMIN,       'A' },
1657 >  { OPER_FLAG_REMOTEBAN,   'B' },
1658 >  { OPER_FLAG_DIE,         'D' },
1659 >  { OPER_FLAG_GLINE,       'G' },
1660 >  { OPER_FLAG_REHASH,      'H' },
1661 >  { OPER_FLAG_K,           'K' },
1662 >  { OPER_FLAG_OPERWALL,    'L' },
1663 >  { OPER_FLAG_N,           'N' },
1664 >  { OPER_FLAG_GLOBAL_KILL, 'O' },
1665 >  { OPER_FLAG_REMOTE,      'R' },
1666 >  { OPER_FLAG_OPER_SPY,    'S' },
1667 >  { OPER_FLAG_UNKLINE,     'U' },
1668 >  { OPER_FLAG_X,           'X' },
1669 >  { 0, '\0' }
1670   };
1671  
1672   char *
# Line 2353 | Line 1674 | oper_privs_as_string(const unsigned int
1674   {
1675    static char privs_out[16];
1676    char *privs_ptr = privs_out;
1677 <  unsigned int i = 0;
1677 >  const struct oper_privs *opriv = flag_list;
1678  
1679 <  for (; flag_list[i].oprivs; ++i)
1679 >  for (; opriv->flag; ++opriv)
1680    {
1681 <    if ((port & flag_list[i].oprivs) &&
1682 <        (port & flag_list[i].hidden) == 0)
2362 <      *privs_ptr++ = flag_list[i].c;
1681 >    if (port & opriv->flag)
1682 >      *privs_ptr++ = opriv->c;
1683      else
1684 <      *privs_ptr++ = ToLowerTab[flag_list[i].c];
1684 >      *privs_ptr++ = ToLower(opriv->c);
1685    }
1686  
1687    *privs_ptr = '\0';
# Line 2375 | Line 1695 | oper_privs_as_string(const unsigned int
1695   *         "oper" is server name for remote opers
1696   * Side effects: None.
1697   */
1698 < char *
1698 > const char *
1699   get_oper_name(const struct Client *client_p)
1700   {
1701 <  dlink_node *cnode;
2382 <  struct ConfItem *conf;
2383 <  struct AccessItem *aconf;
2384 <
1701 >  dlink_node *cnode = NULL;
1702    /* +5 for !,@,{,} and null */
1703 <  static char buffer[NICKLEN+USERLEN+HOSTLEN+HOSTLEN+5];
1703 >  static char buffer[NICKLEN + USERLEN + HOSTLEN + HOSTLEN + 5];
1704  
1705    if (MyConnect(client_p))
1706    {
1707 <    DLINK_FOREACH(cnode, client_p->localClient->confs.head)
1707 >    if ((cnode = client_p->localClient->confs.head))
1708      {
1709 <      conf = cnode->data;
2393 <      aconf = map_to_conf(conf);
1709 >      struct MaskItem *conf = cnode->data;
1710  
1711 <      if (IsConfOperator(aconf))
1711 >      if (IsConfOperator(conf))
1712        {
1713 <        ircsprintf(buffer, "%s!%s@%s{%s}", client_p->name,
1714 <                   client_p->username, client_p->host,
2399 <                   conf->name);
1713 >        snprintf(buffer, sizeof(buffer), "%s!%s@%s{%s}", client_p->name,
1714 >                 client_p->username, client_p->host, conf->name);
1715          return buffer;
1716        }
1717      }
# Line 2407 | Line 1722 | get_oper_name(const struct Client *clien
1722      assert(0); /* Oper without oper conf! */
1723    }
1724  
1725 <  ircsprintf(buffer, "%s!%s@%s{%s}", client_p->name,
1726 <             client_p->username, client_p->host, client_p->servptr->name);
1725 >  snprintf(buffer, sizeof(buffer), "%s!%s@%s{%s}", client_p->name,
1726 >           client_p->username, client_p->host, client_p->servptr->name);
1727    return buffer;
1728   }
1729  
# Line 2425 | Line 1740 | read_conf_files(int cold)
1740    char chanmodes[32];
1741    char chanlimit[32];
1742  
1743 <  filename = get_conf_name(CONF_TYPE);
1743 >  conf_parser_ctx.boot = cold;
1744 >  filename = ConfigFileEntry.configfile;
1745  
1746    /* We need to know the initial filename for the yyerror() to report
1747       FIXME: The full path is in conffilenamebuf first time since we
# Line 2435 | Line 1751 | read_conf_files(int cold)
1751    */
1752    strlcpy(conffilebuf, filename, sizeof(conffilebuf));
1753  
1754 <  if ((conf_fbfile_in = fbopen(filename, "r")) == NULL)
1754 >  if ((conf_parser_ctx.conf_file = fopen(filename, "r")) == NULL)
1755    {
1756      if (cold)
1757      {
1758 <      ilog(L_CRIT, "Unable to read configuration file '%s': %s",
1758 >      ilog(LOG_TYPE_IRCD, "Unable to read configuration file '%s': %s",
1759             filename, strerror(errno));
1760        exit(-1);
1761      }
1762      else
1763      {
1764 <      sendto_realops_flags(UMODE_ALL, L_ALL,
1764 >      sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1765                             "Unable to read configuration file '%s': %s",
1766                             filename, strerror(errno));
1767        return;
# Line 2455 | Line 1771 | read_conf_files(int cold)
1771    if (!cold)
1772      clear_out_old_conf();
1773  
1774 <  read_conf(conf_fbfile_in);
1775 <  fbclose(conf_fbfile_in);
1774 >  read_conf(conf_parser_ctx.conf_file);
1775 >  fclose(conf_parser_ctx.conf_file);
1776  
1777 +  add_isupport("NICKLEN", NULL, ServerInfo.max_nick_length);
1778    add_isupport("NETWORK", ServerInfo.network_name, -1);
1779 <  ircsprintf(chanmodes, "b%s%s:%d", ConfigChannel.use_except ? "e" : "",
1780 <             ConfigChannel.use_invex ? "I" : "", ConfigChannel.max_bans);
1779 >
1780 >  snprintf(chanmodes, sizeof(chanmodes), "beI:%d", ConfigChannel.max_bans);
1781    add_isupport("MAXLIST", chanmodes, -1);
1782    add_isupport("MAXTARGETS", NULL, ConfigFileEntry.max_targets);
1783 <  if (ConfigChannel.disable_local_channels)
1784 <    add_isupport("CHANTYPES", "#", -1);
1785 <  else
1786 <    add_isupport("CHANTYPES", "#&", -1);
2470 <  ircsprintf(chanlimit, "%s:%d", ConfigChannel.disable_local_channels ? "#" : "#&",
2471 <             ConfigChannel.max_chans_per_user);
1783 >  add_isupport("CHANTYPES", "#", -1);
1784 >
1785 >  snprintf(chanlimit, sizeof(chanlimit), "#:%d",
1786 >           ConfigChannel.max_chans_per_user);
1787    add_isupport("CHANLIMIT", chanlimit, -1);
1788 <  ircsprintf(chanmodes, "%s%s%s", ConfigChannel.use_except ? "e" : "",
2474 <             ConfigChannel.use_invex ? "I" : "", "b,k,l,imnpst");
1788 >  snprintf(chanmodes, sizeof(chanmodes), "%s", "beI,k,l,imnprstORS");
1789    add_isupport("CHANNELLEN", NULL, LOCAL_CHANNELLEN);
1790 <  if (ConfigChannel.use_except)
1791 <    add_isupport("EXCEPTS", "e", -1);
1792 <  if (ConfigChannel.use_invex)
2479 <    add_isupport("INVEX", "I", -1);
1790 >  add_isupport("TOPICLEN", NULL, ServerInfo.max_topic_length);
1791 >  add_isupport("EXCEPTS", "e", -1);
1792 >  add_isupport("INVEX", "I", -1);
1793    add_isupport("CHANMODES", chanmodes, -1);
1794  
1795    /*
# Line 2484 | Line 1797 | read_conf_files(int cold)
1797     * on strlen(form_str(RPL_ISUPPORT))
1798     */
1799    rebuild_isupport_message_line();
2487
2488  parse_conf_file(KLINE_TYPE, cold);
2489  parse_conf_file(RKLINE_TYPE, cold);
2490  parse_conf_file(DLINE_TYPE, cold);
2491  parse_conf_file(XLINE_TYPE, cold);
2492  parse_conf_file(RXLINE_TYPE, cold);
2493  parse_conf_file(NRESV_TYPE, cold);
2494  parse_conf_file(CRESV_TYPE, cold);
2495 }
2496
2497 /* parse_conf_file()
2498 *
2499 * inputs       - type of conf file to parse
2500 * output       - none
2501 * side effects - conf file for givenconf type is opened and read then parsed
2502 */
2503 static void
2504 parse_conf_file(int type, int cold)
2505 {
2506  FBFILE *file = NULL;
2507  const char *filename = get_conf_name(type);
2508
2509  if ((file = fbopen(filename, "r")) == NULL)
2510  {
2511    if (cold)
2512      ilog(L_ERROR, "Unable to read configuration file '%s': %s",
2513           filename, strerror(errno));
2514    else
2515      sendto_realops_flags(UMODE_ALL, L_ALL,
2516                    "Unable to read configuration file '%s': %s",
2517                           filename, strerror(errno));
2518  }
2519  else
2520  {
2521    parse_csv_file(file, type);
2522    fbclose(file);
2523  }
1800   }
1801  
1802   /* clear_out_old_conf()
# Line 2533 | Line 1809 | static void
1809   clear_out_old_conf(void)
1810   {
1811    dlink_node *ptr = NULL, *next_ptr = NULL;
1812 <  struct ConfItem *conf;
2537 <  struct AccessItem *aconf;
2538 <  struct ClassItem *cltmp;
2539 <  struct MatchItem *match_item;
1812 >  struct MaskItem *conf;
1813    dlink_list *free_items [] = {
1814 <    &server_items,   &oconf_items,    &hub_items, &leaf_items,
1814 >    &server_items,   &oconf_items,
1815       &uconf_items,   &xconf_items, &rxconf_items, &rkconf_items,
1816 <     &nresv_items, &cluster_items,  &gdeny_items, NULL
1816 >     &nresv_items, &cluster_items,  &service_items, &resv_channel_list, NULL
1817    };
1818  
1819    dlink_list ** iterator = free_items; /* C is dumb */
# Line 2554 | Line 1827 | clear_out_old_conf(void)
1827      DLINK_FOREACH_SAFE(ptr, next_ptr, (*iterator)->head)
1828      {
1829        conf = ptr->data;
2557      /* XXX This is less than pretty */
2558      if (conf->type == SERVER_TYPE)
2559      {
2560        aconf = map_to_conf(conf);
1830  
1831 <        if (aconf->clients != 0)
2563 <        {
2564 <          SetConfIllegal(aconf);
2565 <          dlinkDelete(&conf->node, &server_items);
2566 <        }
2567 <        else
2568 <        {
2569 <          delete_conf_item(conf);
2570 <        }
2571 <      }
2572 <      else if (conf->type == OPER_TYPE)
2573 <      {
2574 <        aconf = map_to_conf(conf);
1831 >      dlinkDelete(&conf->node, map_to_list(conf->type));
1832  
1833 <        if (aconf->clients != 0)
1834 <        {
2578 <          SetConfIllegal(aconf);
2579 <          dlinkDelete(&conf->node, &oconf_items);
2580 <        }
2581 <        else
2582 <        {
2583 <          delete_conf_item(conf);
2584 <        }
2585 <      }
2586 <      else if (conf->type == CLIENT_TYPE)
1833 >      /* XXX This is less than pretty */
1834 >      if (conf->type == CONF_SERVER || conf->type == CONF_OPER)
1835        {
1836 <        aconf = map_to_conf(conf);
1837 <
2590 <        if (aconf->clients != 0)
2591 <        {
2592 <          SetConfIllegal(aconf);
2593 <        }
2594 <        else
2595 <        {
2596 <          delete_conf_item(conf);
2597 <        }
1836 >        if (!conf->ref_count)
1837 >          conf_free(conf);
1838        }
1839 <      else if (conf->type == XLINE_TYPE  ||
1840 <               conf->type == RXLINE_TYPE ||
1841 <               conf->type == RKLINE_TYPE)
1839 >      else if (conf->type == CONF_XLINE  ||
1840 >               conf->type == CONF_RXLINE ||
1841 >               conf->type == CONF_RKLINE)
1842        {
1843 <        /* temporary (r)xlines are also on
1844 <         * the (r)xconf items list */
2605 <        if (conf->flags & CONF_FLAGS_TEMPORARY)
2606 <          continue;
2607 <
2608 <        delete_conf_item(conf);
1843 >        if (!conf->until)
1844 >          conf_free(conf);
1845        }
1846        else
1847 <      {
2612 <        if ((conf->type == LEAF_TYPE) || (conf->type == HUB_TYPE))
2613 <        {
2614 <          match_item = map_to_conf(conf);
2615 <          if (match_item->ref_count <= 0)
2616 <            delete_conf_item(conf);
2617 <          else
2618 <          {
2619 <            match_item->illegal = 1;
2620 <            dlinkDelete(&conf->node, *iterator);
2621 <          }
2622 <        }
2623 <        else
2624 <          delete_conf_item(conf);
2625 <      }
1847 >        conf_free(conf);
1848      }
1849    }
1850  
1851    /*
1852     * don't delete the class table, rather mark all entries
1853 <   * for deletion. The table is cleaned up by check_class. - avalon
1853 >   * for deletion. The table is cleaned up by class_delete_marked. - avalon
1854     */
1855 <  DLINK_FOREACH(ptr, class_items.head)
2634 <  {
2635 <    cltmp = map_to_conf(ptr->data);
2636 <
2637 <    if (ptr != class_items.tail)  /* never mark the "default" class */
2638 <      cltmp->active = 0;
2639 <  }
1855 >  class_mark_for_deletion();
1856  
1857    clear_out_address_conf();
1858  
1859    /* clean out module paths */
2644 #ifndef STATIC_MODULES
1860    mod_clear_paths();
2646 #endif
1861  
1862    /* clean out ServerInfo */
1863    MyFree(ServerInfo.description);
# Line 2663 | Line 1877 | clear_out_old_conf(void)
1877  
1878    MyFree(ServerInfo.rsa_private_key_file);
1879    ServerInfo.rsa_private_key_file = NULL;
2666 #endif
1880  
1881 <  /* clean out old resvs from the conf */
1882 <  clear_conf_resv();
1881 >  if (ServerInfo.server_ctx)
1882 >    SSL_CTX_set_options(ServerInfo.server_ctx, SSL_OP_NO_SSLv2|
1883 >                                               SSL_OP_NO_SSLv3|
1884 >                                               SSL_OP_NO_TLSv1);
1885 >  if (ServerInfo.client_ctx)
1886 >    SSL_CTX_set_options(ServerInfo.client_ctx, SSL_OP_NO_SSLv2|
1887 >                                               SSL_OP_NO_SSLv3|
1888 >                                               SSL_OP_NO_TLSv1);
1889 > #endif
1890  
1891    /* clean out AdminInfo */
1892    MyFree(AdminInfo.name);
# Line 2676 | Line 1896 | clear_out_old_conf(void)
1896    MyFree(AdminInfo.description);
1897    AdminInfo.description = NULL;
1898  
2679  /* operator{} and class{} blocks are freed above */
1899    /* clean out listeners */
1900    close_listeners();
1901  
2683  /* auth{}, quarantine{}, shared{}, connect{}, kill{}, deny{},
2684   * exempt{} and gecos{} blocks are freed above too
2685   */
2686
1902    /* clean out general */
1903 <  MyFree(ConfigFileEntry.servlink_path);
1904 <  ConfigFileEntry.servlink_path = NULL;
1905 < #ifdef HAVE_LIBCRYPTO
2691 <  ConfigFileEntry.default_cipher_preference = NULL;
2692 < #endif /* HAVE_LIBCRYPTO */
1903 >  MyFree(ConfigFileEntry.service_name);
1904 >  ConfigFileEntry.service_name = NULL;
1905 >
1906    delete_isupport("INVEX");
1907    delete_isupport("EXCEPTS");
1908   }
1909  
2697 /* flush_deleted_I_P()
2698 *
2699 * inputs       - none
2700 * output       - none
2701 * side effects - This function removes I/P conf items
2702 */
2703 static void
2704 flush_deleted_I_P(void)
2705 {
2706  dlink_node *ptr;
2707  dlink_node *next_ptr;
2708  struct ConfItem *conf;
2709  struct AccessItem *aconf;
2710  dlink_list * free_items [] = {
2711    &server_items, &oconf_items, NULL
2712  };
2713  dlink_list ** iterator = free_items; /* C is dumb */
2714
2715  /* flush out deleted I and P lines
2716   * although still in use.
2717   */
2718  for (; *iterator != NULL; iterator++)
2719  {
2720    DLINK_FOREACH_SAFE(ptr, next_ptr, (*iterator)->head)
2721    {
2722      conf = ptr->data;
2723      aconf = (struct AccessItem *)map_to_conf(conf);
2724
2725      if (IsConfIllegal(aconf))
2726      {
2727        dlinkDelete(ptr, *iterator);
2728
2729        if (aconf->clients == 0)
2730          delete_conf_item(conf);
2731      }
2732    }
2733  }
2734 }
2735
2736 /* get_conf_name()
2737 *
2738 * inputs       - type of conf file to return name of file for
2739 * output       - pointer to filename for type of conf
2740 * side effects - none
2741 */
2742 const char *
2743 get_conf_name(ConfType type)
2744 {
2745  switch (type)
2746  {
2747    case CONF_TYPE:
2748      return ConfigFileEntry.configfile;
2749      break;
2750    case KLINE_TYPE:
2751      return ConfigFileEntry.klinefile;
2752      break;
2753    case RKLINE_TYPE:
2754      return ConfigFileEntry.rklinefile;
2755      break;
2756    case DLINE_TYPE:
2757      return ConfigFileEntry.dlinefile;
2758      break;
2759    case XLINE_TYPE:
2760      return ConfigFileEntry.xlinefile;
2761      break;
2762    case RXLINE_TYPE:
2763      return ConfigFileEntry.rxlinefile;
2764      break;
2765    case CRESV_TYPE:
2766      return ConfigFileEntry.cresvfile;
2767      break;
2768    case NRESV_TYPE:
2769      return ConfigFileEntry.nresvfile;
2770      break;
2771    case GLINE_TYPE:
2772      return ConfigFileEntry.glinefile;
2773      break;
2774
2775    default:
2776      return NULL;  /* This should NEVER HAPPEN since we call this function
2777                       only with the above values, this will cause us to core
2778                       at some point if this happens so we know where it was */
2779  }
2780 }
2781
2782 #define BAD_PING (-1)
2783
2784 /* get_conf_ping()
2785 *
2786 * inputs       - pointer to struct AccessItem
2787 *              - pointer to a variable that receives ping warning time
2788 * output       - ping frequency
2789 * side effects - NONE
2790 */
2791 static int
2792 get_conf_ping(struct ConfItem *conf, int *pingwarn)
2793 {
2794  struct ClassItem *aclass;
2795  struct AccessItem *aconf;
2796
2797  if (conf != NULL)
2798  {
2799    aconf = (struct AccessItem *)map_to_conf(conf);
2800    if (aconf->class_ptr != NULL)
2801    {
2802      aclass = (struct ClassItem *)map_to_conf(aconf->class_ptr);
2803      *pingwarn = PingWarning(aclass);
2804      return PingFreq(aclass);
2805    }
2806  }
2807
2808  return BAD_PING;
2809 }
2810
2811 /* get_client_class()
2812 *
2813 * inputs       - pointer to client struct
2814 * output       - pointer to name of class
2815 * side effects - NONE
2816 */
2817 const char *
2818 get_client_class(struct Client *target_p)
2819 {
2820  dlink_node *ptr;
2821  struct ConfItem *conf;
2822  struct AccessItem *aconf;
2823
2824  if (target_p != NULL && !IsMe(target_p) &&
2825      target_p->localClient->confs.head != NULL)
2826  {
2827    DLINK_FOREACH(ptr, target_p->localClient->confs.head)
2828    {
2829      conf = ptr->data;
2830
2831      if (conf->type == CLIENT_TYPE || conf->type == SERVER_TYPE ||
2832          conf->type == OPER_TYPE)
2833      {
2834        aconf = (struct AccessItem *) map_to_conf(conf);
2835        if (aconf->class_ptr != NULL)
2836          return aconf->class_ptr->name;
2837      }
2838    }
2839  }
2840
2841  return "default";
2842 }
2843
2844 /* get_client_ping()
2845 *
2846 * inputs       - pointer to client struct
2847 *              - pointer to a variable that receives ping warning time
2848 * output       - ping frequency
2849 * side effects - NONE
2850 */
2851 int
2852 get_client_ping(struct Client *target_p, int *pingwarn)
2853 {
2854  int ping;
2855  struct ConfItem *conf;
2856  dlink_node *nlink;
2857
2858  if (target_p->localClient->confs.head != NULL)
2859    DLINK_FOREACH(nlink, target_p->localClient->confs.head)
2860    {
2861      conf = nlink->data;
2862
2863      if ((conf->type == CLIENT_TYPE) || (conf->type == SERVER_TYPE) ||
2864          (conf->type == OPER_TYPE))
2865      {
2866        ping = get_conf_ping(conf, pingwarn);
2867        if (ping > 0)
2868          return ping;
2869      }
2870    }
2871
2872  *pingwarn = 0;
2873  return DEFAULT_PINGFREQUENCY;
2874 }
2875
2876 /* find_class()
2877 *
2878 * inputs       - string name of class
2879 * output       - corresponding Class pointer
2880 * side effects - NONE
2881 */
2882 struct ConfItem *
2883 find_class(const char *classname)
2884 {
2885  struct ConfItem *conf;
2886
2887  if ((conf = find_exact_name_conf(CLASS_TYPE, classname, NULL, NULL)) != NULL)
2888    return conf;
2889
2890  return class_default;
2891 }
2892
2893 /* check_class()
2894 *
2895 * inputs       - NONE
2896 * output       - NONE
2897 * side effects -
2898 */
2899 void
2900 check_class(void)
2901 {
2902  dlink_node *ptr = NULL, *next_ptr = NULL;
2903
2904  DLINK_FOREACH_SAFE(ptr, next_ptr, class_items.head)
2905  {
2906    struct ClassItem *aclass = map_to_conf(ptr->data);
2907
2908    if (!aclass->active && !CurrUserCount(aclass))
2909    {
2910      destroy_cidr_class(aclass);
2911      delete_conf_item(ptr->data);
2912    }
2913  }
2914 }
2915
2916 /* init_class()
2917 *
2918 * inputs       - NONE
2919 * output       - NONE
2920 * side effects -
2921 */
2922 void
2923 init_class(void)
2924 {
2925  struct ClassItem *aclass;
2926
2927  class_default = make_conf_item(CLASS_TYPE);
2928
2929  aclass = map_to_conf(class_default);
2930  aclass->active = 1;
2931  DupString(class_default->name, "default");
2932  ConFreq(aclass)  = DEFAULT_CONNECTFREQUENCY;
2933  PingFreq(aclass) = DEFAULT_PINGFREQUENCY;
2934  MaxTotal(aclass) = MAXIMUM_LINKS_DEFAULT;
2935  MaxSendq(aclass) = DEFAULT_SENDQ;
2936
2937  client_check_cb = register_callback("check_client", check_client);
2938 }
2939
2940 /* get_sendq()
2941 *
2942 * inputs       - pointer to client
2943 * output       - sendq for this client as found from its class
2944 * side effects - NONE
2945 */
2946 unsigned long
2947 get_sendq(struct Client *client_p)
2948 {
2949  unsigned long sendq = DEFAULT_SENDQ;
2950  dlink_node *ptr;
2951  struct ConfItem *conf;
2952  struct ConfItem *class_conf;
2953  struct ClassItem *aclass;
2954  struct AccessItem *aconf;
2955
2956  if (client_p && !IsMe(client_p) && (client_p->localClient->confs.head))
2957  {
2958    DLINK_FOREACH(ptr, client_p->localClient->confs.head)
2959    {
2960      conf = ptr->data;
2961      if ((conf->type == SERVER_TYPE) || (conf->type == OPER_TYPE)
2962          || (conf->type == CLIENT_TYPE))
2963      {
2964        aconf = (struct AccessItem *)map_to_conf(conf);
2965        if ((class_conf = aconf->class_ptr) == NULL)
2966          continue;
2967        aclass = (struct ClassItem *)map_to_conf(class_conf);
2968        sendq = MaxSendq(aclass);
2969        return sendq;
2970      }
2971    }
2972  }
2973  /* XXX return a default?
2974   * if here, then there wasn't an attached conf with a sendq
2975   * that is very bad -Dianora
2976   */
2977  return DEFAULT_SENDQ;
2978 }
2979
1910   /* conf_add_class_to_conf()
1911   *
1912   * inputs       - pointer to config item
# Line 2984 | Line 1914 | get_sendq(struct Client *client_p)
1914   * side effects - Add a class pointer to a conf
1915   */
1916   void
1917 < conf_add_class_to_conf(struct ConfItem *conf, const char *class_name)
1917 > conf_add_class_to_conf(struct MaskItem *conf, const char *class_name)
1918   {
2989  struct AccessItem *aconf = map_to_conf(conf);
2990  struct ClassItem *class = NULL;
2991
1919    if (class_name == NULL)
1920    {
1921 <    aconf->class_ptr = class_default;
1921 >    conf->class = class_default;
1922  
1923 <    if (conf->type == CLIENT_TYPE)
1924 <      sendto_realops_flags(UMODE_ALL, L_ALL,
1923 >    if (conf->type == CONF_CLIENT)
1924 >      sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1925                             "Warning *** Defaulting to default class for %s@%s",
1926 <                           aconf->user, aconf->host);
1926 >                           conf->user, conf->host);
1927      else
1928 <      sendto_realops_flags(UMODE_ALL, L_ALL,
1928 >      sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1929                             "Warning *** Defaulting to default class for %s",
1930                             conf->name);
1931    }
1932    else
1933 <    aconf->class_ptr = find_class(class_name);
3007 <
3008 <  if (aconf->class_ptr)
3009 <    class = map_to_conf(aconf->class_ptr);
1933 >    conf->class = class_find(class_name, 1);
1934  
1935 <  if (aconf->class_ptr == NULL || !class->active)
1935 >  if (conf->class == NULL)
1936    {
1937 <    if (conf->type == CLIENT_TYPE)
1938 <      sendto_realops_flags(UMODE_ALL, L_ALL,
1937 >    if (conf->type == CONF_CLIENT)
1938 >      sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1939                             "Warning *** Defaulting to default class for %s@%s",
1940 <                           aconf->user, aconf->host);
1940 >                           conf->user, conf->host);
1941      else
1942 <      sendto_realops_flags(UMODE_ALL, L_ALL,
1942 >      sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1943                             "Warning *** Defaulting to default class for %s",
1944                             conf->name);
1945 <    aconf->class_ptr = class_default;
3022 <  }
3023 < }
3024 <
3025 < /* conf_add_server()
3026 < *
3027 < * inputs       - pointer to config item
3028 < *              - pointer to link count already on this conf
3029 < * output       - NONE
3030 < * side effects - Add a connect block
3031 < */
3032 < int
3033 < conf_add_server(struct ConfItem *conf, const char *class_name)
3034 < {
3035 <  struct AccessItem *aconf;
3036 <  struct split_nuh_item nuh;
3037 <  char conf_user[USERLEN + 1];
3038 <  char conf_host[HOSTLEN + 1];
3039 <
3040 <  aconf = map_to_conf(conf);
3041 <
3042 <  conf_add_class_to_conf(conf, class_name);
3043 <
3044 <  if (!aconf->host || !conf->name)
3045 <  {
3046 <    sendto_realops_flags(UMODE_ALL, L_ALL, "Bad connect block");
3047 <    ilog(L_WARN, "Bad connect block");
3048 <    return -1;
3049 <  }
3050 <
3051 <  if (EmptyString(aconf->passwd) && !IsConfCryptLink(aconf))
3052 <  {
3053 <    sendto_realops_flags(UMODE_ALL, L_ALL, "Bad connect block, name %s",
3054 <                         conf->name);
3055 <    ilog(L_WARN, "Bad connect block, host %s", conf->name);
3056 <    return -1;
3057 <  }
3058 <
3059 <  nuh.nuhmask  = aconf->host;
3060 <  nuh.nickptr  = NULL;
3061 <  nuh.userptr  = conf_user;
3062 <  nuh.hostptr  = conf_host;
3063 <
3064 <  nuh.nicksize = 0;
3065 <  nuh.usersize = sizeof(conf_user);
3066 <  nuh.hostsize = sizeof(conf_host);
3067 <
3068 <  split_nuh(&nuh);
3069 <
3070 <  MyFree(aconf->host);
3071 <  aconf->host = NULL;
3072 <
3073 <  DupString(aconf->user, conf_user); /* somehow username checking for servers
3074 <                                 got lost in H6/7, will have to be re-added */
3075 <  DupString(aconf->host, conf_host);
3076 <
3077 <  lookup_confhost(conf);
3078 <
3079 <  return 0;
3080 < }
3081 <
3082 < /* conf_add_d_conf()
3083 < *
3084 < * inputs       - pointer to config item
3085 < * output       - NONE
3086 < * side effects - Add a d/D line
3087 < */
3088 < void
3089 < conf_add_d_conf(struct AccessItem *aconf)
3090 < {
3091 <  if (aconf->host == NULL)
3092 <    return;
3093 <
3094 <  aconf->user = NULL;
3095 <
3096 <  /* XXX - Should 'd' ever be in the old conf? For new conf we don't
3097 <   *       need this anyway, so I will disable it for now... -A1kmm
3098 <   */
3099 <  if (parse_netmask(aconf->host, NULL, NULL) == HM_HOST)
3100 <  {
3101 <    ilog(L_WARN, "Invalid Dline %s ignored", aconf->host);
3102 <    free_access_item(aconf);
3103 <  }
3104 <  else
3105 <  {
3106 <    /* XXX ensure user is NULL */
3107 <    MyFree(aconf->user);
3108 <    aconf->user = NULL;
3109 <    add_conf_by_address(CONF_DLINE, aconf);
1945 >    conf->class = class_default;
1946    }
1947   }
1948  
# Line 3121 | Line 1957 | yyerror(const char *msg)
1957   {
1958    char newlinebuf[IRCD_BUFSIZE];
1959  
1960 <  if (ypass != 1)
1960 >  if (conf_parser_ctx.pass != 1)
1961      return;
1962  
1963    strip_tabs(newlinebuf, linebuf, sizeof(newlinebuf));
1964 <  sendto_realops_flags(UMODE_ALL, L_ALL, "\"%s\", line %u: %s: %s",
1964 >  sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1965 >                       "\"%s\", line %u: %s: %s",
1966                         conffilebuf, lineno + 1, msg, newlinebuf);
1967 <  ilog(L_WARN, "\"%s\", line %u: %s: %s",
1967 >  ilog(LOG_TYPE_IRCD, "\"%s\", line %u: %s: %s",
1968         conffilebuf, lineno + 1, msg, newlinebuf);
1969   }
1970  
1971 < int
1972 < conf_fbgets(char *lbuf, unsigned int max_size, FBFILE *fb)
1971 > void
1972 > conf_error_report(const char *msg)
1973   {
1974 <  if (fbgets(lbuf, max_size, fb) == NULL)
3138 <    return 0;
3139 <
3140 <  return strlen(lbuf);
3141 < }
1974 >  char newlinebuf[IRCD_BUFSIZE];
1975  
1976 < int
1977 < conf_yy_fatal_error(const char *msg)
1978 < {
1979 <  return 0;
1976 >  strip_tabs(newlinebuf, linebuf, sizeof(newlinebuf));
1977 >  sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1978 >                       "\"%s\", line %u: %s: %s",
1979 >                       conffilebuf, lineno + 1, msg, newlinebuf);
1980 >  ilog(LOG_TYPE_IRCD, "\"%s\", line %u: %s: %s",
1981 >       conffilebuf, lineno + 1, msg, newlinebuf);
1982   }
1983  
1984   /*
# Line 3157 | Line 1992 | conf_yy_fatal_error(const char *msg)
1992   * Originally written by Dianora (Diane, db@db.net)
1993   */
1994   time_t
1995 < valid_tkline(char *p, int minutes)
1995 > valid_tkline(const char *p, int minutes)
1996   {
1997    time_t result = 0;
1998  
1999 <  while (*p)
1999 >  for (; *p; ++p)
2000    {
2001 <    if (IsDigit(*p))
3167 <    {
3168 <      result *= 10;
3169 <      result += ((*p) & 0xF);
3170 <      p++;
3171 <    }
3172 <    else
2001 >    if (!IsDigit(*p))
2002        return 0;
2003 +
2004 +    result *= 10;
2005 +    result += ((*p) & 0xF);
2006    }
2007  
2008 <  /* in the degenerate case where oper does a /quote kline 0 user@host :reason
2008 >  /*
2009 >   * In the degenerate case where oper does a /quote kline 0 user@host :reason
2010     * i.e. they specifically use 0, I am going to return 1 instead
2011     * as a return value of non-zero is used to flag it as a temporary kline
2012     */
3180
2013    if (result == 0)
2014      result = 1;
2015  
# Line 3278 | Line 2110 | valid_wild_card(struct Client *source_p,
2110   *                if target_server is NULL and an "ON" is found error
2111   *                is reported.
2112   *                if reason pointer is NULL ignore pointer,
2113 < *                this allows usee of parse_a_line in unkline etc.
2113 > *                this allows use of parse_a_line in unkline etc.
2114   *
2115   * - Dianora
2116   */
# Line 3348 | Line 2180 | parse_aline(const char *cmd, struct Clie
2180          return -1;
2181        }
2182  
2183 <      if (!IsOperRemoteBan(source_p))
2183 >      if (!HasOFlag(source_p, OPER_FLAG_REMOTEBAN))
2184        {
2185          sendto_one(source_p, form_str(ERR_NOPRIVS),
2186                     me.name, source_p->name, "remoteban");
# Line 3385 | Line 2217 | parse_aline(const char *cmd, struct Clie
2217        return -1;
2218      }
2219  
2220 <    if ((parse_flags & AWILD) && !valid_wild_card(source_p, YES, 2, *up_p, *h_p))
2220 >    if ((parse_flags & AWILD) && !valid_wild_card(source_p, 1, 2, *up_p, *h_p))
2221        return -1;
2222    }
2223    else
2224 <    if ((parse_flags & AWILD) && !valid_wild_card(source_p, YES, 1, *up_p))
2224 >    if ((parse_flags & AWILD) && !valid_wild_card(source_p, 1, 1, *up_p))
2225        return -1;
2226  
2227    if (reason != NULL)
# Line 3397 | Line 2229 | parse_aline(const char *cmd, struct Clie
2229      if (parc != 0 && !EmptyString(*parv))
2230      {
2231        *reason = *parv;
2232 <      if (!valid_comment(source_p, *reason, YES))
2232 >      if (!valid_comment(source_p, *reason, 1))
2233          return -1;
2234      }
2235      else
# Line 3454 | Line 2286 | find_user_host(struct Client *source_p,
2286      
2287      return 1;
2288    }
2289 <  else if (!(flags & NOUSERLOOKUP))
2289 >  else
2290    {
2291      /* Try to find user@host mask from nick */
2292      /* Okay to use source_p as the first param, because source_p == client_p */
# Line 3502 | Line 2334 | find_user_host(struct Client *source_p,
2334   int
2335   valid_comment(struct Client *source_p, char *comment, int warn)
2336   {
3505  if (strchr(comment, '"'))
3506  {
3507    if (warn)
3508      sendto_one(source_p, ":%s NOTICE %s :Invalid character '\"' in comment",
3509                 me.name, source_p->name);
3510    return 0;
3511  }
3512
2337    if (strlen(comment) > REASONLEN)
2338      comment[REASONLEN-1] = '\0';
2339  
# Line 3524 | Line 2348 | valid_comment(struct Client *source_p, c
2348   * side effects - none
2349   */
2350   int
2351 < match_conf_password(const char *password, const struct AccessItem *aconf)
2351 > match_conf_password(const char *password, const struct MaskItem *conf)
2352   {
2353    const char *encr = NULL;
2354  
2355 <  if (password == NULL || aconf->passwd == NULL)
2355 >  if (EmptyString(password) || EmptyString(conf->passwd))
2356      return 0;
2357  
2358 <  if (aconf->flags & CONF_FLAGS_ENCRYPTED)
2359 <  {
3536 <    /* use first two chars of the password they send in as salt */
3537 <    /* If the password in the conf is MD5, and ircd is linked
3538 <     * to scrypt on FreeBSD, or the standard crypt library on
3539 <     * glibc Linux, then this code will work fine on generating
3540 <     * the proper encrypted hash for comparison.
3541 <     */
3542 <    if (*aconf->passwd)
3543 <      encr = crypt(password, aconf->passwd);
3544 <    else
3545 <      encr = "";
3546 <  }
2358 >  if (conf->flags & CONF_FLAGS_ENCRYPTED)
2359 >    encr = crypt(password, conf->passwd);
2360    else
2361      encr = password;
2362  
2363 <  return !strcmp(encr, aconf->passwd);
2363 >  return !strcmp(encr, conf->passwd);
2364   }
2365  
2366   /*
# Line 3556 | Line 2369 | match_conf_password(const char *password
2369   * inputs       - client sending the cluster
2370   *              - command name "KLINE" "XLINE" etc.
2371   *              - capab -- CAP_KLN etc. from s_serv.h
2372 < *              - cluster type -- CLUSTER_KLINE etc. from s_conf.h
2372 > *              - cluster type -- CLUSTER_KLINE etc. from conf.h
2373   *              - pattern and args to send along
2374   * output       - none
2375   * side effects - Take source_p send the pattern with args given
# Line 3576 | Line 2389 | cluster_a_line(struct Client *source_p,
2389  
2390    DLINK_FOREACH(ptr, cluster_items.head)
2391    {
2392 <    const struct ConfItem *conf = ptr->data;
2392 >    const struct MaskItem *conf = ptr->data;
2393  
2394      if (conf->flags & cluster_type)
2395        sendto_match_servs(source_p, conf->name, CAP_CLUSTER|capab,
# Line 3670 | Line 2483 | split_nuh(struct split_nuh_item *const i
2483      }
2484    }
2485   }
3673
3674 /*
3675 * flags_to_ascii
3676 *
3677 * inputs       - flags is a bitmask
3678 *              - pointer to table of ascii letters corresponding
3679 *                to each bit
3680 *              - flag 1 for convert ToLower if bit missing
3681 *                0 if ignore.
3682 * output       - none
3683 * side effects - string pointed to by p has bitmap chars written to it
3684 */
3685 static void
3686 flags_to_ascii(unsigned int flags, const unsigned int bit_table[], char *p,
3687               int lowerit)
3688 {
3689  unsigned int mask = 1;
3690  int i = 0;
3691
3692  for (mask = 1; (mask != 0) && (bit_table[i] != 0); mask <<= 1, i++)
3693  {
3694    if (flags & mask)
3695      *p++ = bit_table[i];
3696    else if (lowerit)
3697      *p++ = ToLower(bit_table[i]);
3698  }
3699  *p = '\0';
3700 }
3701
3702 /*
3703 * cidr_limit_reached
3704 *
3705 * inputs       - int flag allowing over_rule of limits
3706 *              - pointer to the ip to be added
3707 *              - pointer to the class
3708 * output       - non zero if limit reached
3709 *                0 if limit not reached
3710 * side effects -
3711 */
3712 static int
3713 cidr_limit_reached(int over_rule,
3714                   struct irc_ssaddr *ip, struct ClassItem *aclass)
3715 {
3716  dlink_node *ptr = NULL;
3717  struct CidrItem *cidr;
3718
3719  if (NumberPerCidr(aclass) <= 0)
3720    return 0;
3721
3722  if (ip->ss.ss_family == AF_INET)
3723  {
3724    if (CidrBitlenIPV4(aclass) <= 0)
3725      return 0;
3726
3727    DLINK_FOREACH(ptr, aclass->list_ipv4.head)
3728    {
3729      cidr = ptr->data;
3730      if (match_ipv4(ip, &cidr->mask, CidrBitlenIPV4(aclass)))
3731      {
3732        if (!over_rule && (cidr->number_on_this_cidr >= NumberPerCidr(aclass)))
3733          return -1;
3734        cidr->number_on_this_cidr++;
3735        return 0;
3736      }
3737    }
3738    cidr = MyMalloc(sizeof(struct CidrItem));
3739    cidr->number_on_this_cidr = 1;
3740    cidr->mask = *ip;
3741    mask_addr(&cidr->mask, CidrBitlenIPV4(aclass));
3742    dlinkAdd(cidr, &cidr->node, &aclass->list_ipv4);
3743  }
3744 #ifdef IPV6
3745  else if (CidrBitlenIPV6(aclass) > 0)
3746  {
3747    DLINK_FOREACH(ptr, aclass->list_ipv6.head)
3748    {
3749      cidr = ptr->data;
3750      if (match_ipv6(ip, &cidr->mask, CidrBitlenIPV6(aclass)))
3751      {
3752        if (!over_rule && (cidr->number_on_this_cidr >= NumberPerCidr(aclass)))
3753          return -1;
3754        cidr->number_on_this_cidr++;
3755        return 0;
3756      }
3757    }
3758    cidr = MyMalloc(sizeof(struct CidrItem));
3759    cidr->number_on_this_cidr = 1;
3760    cidr->mask = *ip;
3761    mask_addr(&cidr->mask, CidrBitlenIPV6(aclass));
3762    dlinkAdd(cidr, &cidr->node, &aclass->list_ipv6);
3763  }
3764 #endif
3765  return 0;
3766 }
3767
3768 /*
3769 * remove_from_cidr_check
3770 *
3771 * inputs       - pointer to the ip to be removed
3772 *              - pointer to the class
3773 * output       - NONE
3774 * side effects -
3775 */
3776 static void
3777 remove_from_cidr_check(struct irc_ssaddr *ip, struct ClassItem *aclass)
3778 {
3779  dlink_node *ptr = NULL;
3780  dlink_node *next_ptr = NULL;
3781  struct CidrItem *cidr;
3782
3783  if (NumberPerCidr(aclass) == 0)
3784    return;
3785
3786  if (ip->ss.ss_family == AF_INET)
3787  {
3788    if (CidrBitlenIPV4(aclass) <= 0)
3789      return;
3790
3791    DLINK_FOREACH_SAFE(ptr, next_ptr, aclass->list_ipv4.head)
3792    {
3793      cidr = ptr->data;
3794      if (match_ipv4(ip, &cidr->mask, CidrBitlenIPV4(aclass)))
3795      {
3796        cidr->number_on_this_cidr--;
3797        if (cidr->number_on_this_cidr == 0)
3798        {
3799          dlinkDelete(ptr, &aclass->list_ipv4);
3800          MyFree(cidr);
3801          return;
3802        }
3803      }
3804    }
3805  }
3806 #ifdef IPV6
3807  else if (CidrBitlenIPV6(aclass) > 0)
3808  {
3809    DLINK_FOREACH_SAFE(ptr, next_ptr, aclass->list_ipv6.head)
3810    {
3811      cidr = ptr->data;
3812      if (match_ipv6(ip, &cidr->mask, CidrBitlenIPV6(aclass)))
3813      {
3814        cidr->number_on_this_cidr--;
3815        if (cidr->number_on_this_cidr == 0)
3816        {
3817          dlinkDelete(ptr, &aclass->list_ipv6);
3818          MyFree(cidr);
3819          return;
3820        }
3821      }
3822    }
3823  }
3824 #endif
3825 }
3826
3827 static void
3828 rebuild_cidr_list(int aftype, struct ConfItem *oldcl, struct ClassItem *newcl,
3829                  dlink_list *old_list, dlink_list *new_list, int changed)
3830 {
3831  dlink_node *ptr;
3832  struct Client *client_p;
3833  struct ConfItem *conf;
3834  struct AccessItem *aconf;
3835
3836  if (!changed)
3837  {
3838    *new_list = *old_list;
3839    old_list->head = old_list->tail = NULL;
3840    old_list->length = 0;
3841    return;
3842  }
3843
3844  DLINK_FOREACH(ptr, local_client_list.head)
3845  {
3846    client_p = ptr->data;
3847    if (client_p->localClient->aftype != aftype)
3848      continue;
3849    if (dlink_list_length(&client_p->localClient->confs) == 0)
3850      continue;
3851
3852    conf = client_p->localClient->confs.tail->data;
3853    if (conf->type == CLIENT_TYPE)
3854    {
3855      aconf = map_to_conf(conf);
3856      if (aconf->class_ptr == oldcl)
3857        cidr_limit_reached(1, &client_p->localClient->ip, newcl);
3858    }
3859  }
3860 }
3861
3862 /*
3863 * rebuild_cidr_class
3864 *
3865 * inputs       - pointer to old conf
3866 *              - pointer to new_class
3867 * output       - none
3868 * side effects - rebuilds the class link list of cidr blocks
3869 */
3870 void
3871 rebuild_cidr_class(struct ConfItem *conf, struct ClassItem *new_class)
3872 {
3873  struct ClassItem *old_class = map_to_conf(conf);
3874
3875  if (NumberPerCidr(old_class) > 0 && NumberPerCidr(new_class) > 0)
3876  {
3877    if (CidrBitlenIPV4(old_class) > 0 && CidrBitlenIPV4(new_class) > 0)
3878      rebuild_cidr_list(AF_INET, conf, new_class,
3879                        &old_class->list_ipv4, &new_class->list_ipv4,
3880                        CidrBitlenIPV4(old_class) != CidrBitlenIPV4(new_class));
3881
3882 #ifdef IPV6
3883    if (CidrBitlenIPV6(old_class) > 0 && CidrBitlenIPV6(new_class) > 0)
3884      rebuild_cidr_list(AF_INET6, conf, new_class,
3885                        &old_class->list_ipv6, &new_class->list_ipv6,
3886                        CidrBitlenIPV6(old_class) != CidrBitlenIPV6(new_class));
3887 #endif
3888  }
3889
3890  destroy_cidr_class(old_class);
3891 }
3892
3893 /*
3894 * destroy_cidr_list
3895 *
3896 * inputs       - pointer to class dlink list of cidr blocks
3897 * output       - none
3898 * side effects - completely destroys the class link list of cidr blocks
3899 */
3900 static void
3901 destroy_cidr_list(dlink_list *list)
3902 {
3903  dlink_node *ptr = NULL, *next_ptr = NULL;
3904
3905  DLINK_FOREACH_SAFE(ptr, next_ptr, list->head)
3906  {
3907    dlinkDelete(ptr, list);
3908    MyFree(ptr->data);
3909  }
3910 }
3911
3912 /*
3913 * destroy_cidr_class
3914 *
3915 * inputs       - pointer to class
3916 * output       - none
3917 * side effects - completely destroys the class link list of cidr blocks
3918 */
3919 static void
3920 destroy_cidr_class(struct ClassItem *aclass)
3921 {
3922  destroy_cidr_list(&aclass->list_ipv4);
3923  destroy_cidr_list(&aclass->list_ipv6);
3924 }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines