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

Comparing:
ircd-hybrid-7.2/src/s_conf.c (file contents), Revision 815 by michael, Sun Sep 10 17:35:18 2006 UTC vs.
ircd-hybrid/trunk/src/conf.c (file contents), Revision 1649 by michael, Sat Nov 10 19:27:13 2012 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"
29 < #include "s_conf.h"
28 > #include "balloc.h"
29 > #include "conf.h"
30   #include "s_serv.h"
31   #include "resv.h"
31 #include "s_stats.h"
32   #include "channel.h"
33   #include "client.h"
34 #include "common.h"
34   #include "event.h"
36 #include "hash.h"
35   #include "hook.h"
36   #include "irc_string.h"
39 #include "sprintf_irc.h"
37   #include "s_bsd.h"
41 #include "irc_getnameinfo.h"
42 #include "irc_getaddrinfo.h"
38   #include "ircd.h"
44 #include "list.h"
39   #include "listener.h"
40   #include "hostmask.h"
41   #include "modules.h"
42   #include "numeric.h"
43   #include "fdlist.h"
44 < #include "s_log.h"
44 > #include "log.h"
45   #include "send.h"
46   #include "s_gline.h"
53 #include "fileio.h"
47   #include "memory.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  
60 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 };
66 dlink_list hub_items     = { NULL, NULL, 0 };
67 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 };
74 dlink_list class_items   = { NULL, NULL, 0 };
75 dlink_list gdeny_items   = { NULL, NULL, 0 };
76
77 dlink_list temporary_klines  = { NULL, NULL, 0 };
78 dlink_list temporary_dlines  = { NULL, NULL, 0 };
79 dlink_list temporary_xlines  = { NULL, NULL, 0 };
80 dlink_list temporary_rklines = { NULL, NULL, 0 };
81 dlink_list temporary_glines  = { NULL, NULL, 0 };
82 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];
88 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 *);
94 < static void set_default_conf(void);
95 < static void validate_conf(void);
96 < static void read_conf(FBFILE *);
79 > static void read_conf(FILE *);
80   static void clear_out_old_conf(void);
98 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);
107 < 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  
110 /*
111 * bit_len
112 */
113 static int cidr_limit_reached(int, struct irc_ssaddr *, struct ClassItem *);
114 static void remove_from_cidr_check(struct irc_ssaddr *, struct ClassItem *);
115 static void destroy_cidr_class(struct ClassItem *);
116
117 static void flags_to_ascii(unsigned int, const unsigned int[], char *, int);
118
119 FBFILE *conf_fbfile_in = NULL;
120
121 /* address of default class conf */
122 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 130 | 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   };
# Line 140 | Line 108 | static BlockHeap *ip_entry_heap = NULL;
108   static int ip_entries_count = 0;
109  
110  
143 inline void *
144 map_to_conf(struct ConfItem *aconf)
145 {
146  void *conf;
147  conf = (void *)((unsigned long)aconf +
148                  (unsigned long)sizeof(struct ConfItem));
149  return(conf);
150 }
151
152 inline struct ConfItem *
153 unmap_conf_item(void *aconf)
154 {
155  struct ConfItem *conf;
156
157  conf = (struct ConfItem *)((unsigned long)aconf -
158                             (unsigned long)sizeof(struct ConfItem));
159  return(conf);
160 }
161
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 170 | 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;
176 <  struct ConfItem *conf;
124 >  struct MaskItem *conf = vptr;
125  
126 <  MyFree(aconf->dns_query);
179 <  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",
185 <         aconf->host);
186 <    conf = unmap_conf_item(aconf);
187 <    sendto_realops_flags(UMODE_ALL, L_ALL,
188 <                         "Ignoring connect{} block for %s - host not found",
189 <                         conf->name);
190 <    delete_conf_item(conf);
191 <  }
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 198 | 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;
207 <    aconf->dns_query->callback = conf_dns_callback;
208 <    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 < *
214 < * inputs       - type of item
215 < * output       - pointer to new conf entry
216 < * side effects - none
217 < */
218 < struct ConfItem *
219 < 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;
223 <  struct ClassItem *aclass = NULL;
224 <  int status = 0;
225 <
226 <  switch (type)
227 <  {
228 <  case DLINE_TYPE:
229 <  case EXEMPTDLINE_TYPE:
230 <  case GLINE_TYPE:
231 <  case KLINE_TYPE:
232 <  case CLIENT_TYPE:
233 <  case OPER_TYPE:
234 <  case SERVER_TYPE:
235 <    conf = MyMalloc(sizeof(struct ConfItem) +
236 <                    sizeof(struct AccessItem));
237 <    aconf = map_to_conf(conf);
238 <    aconf->aftype = AF_INET;
239 <
240 <    /* Yes, sigh. switch on type again */
241 <    switch (type)
242 <    {
243 <    case EXEMPTDLINE_TYPE:
244 <      status = CONF_EXEMPTDLINE;
245 <      break;
246 <
247 <    case DLINE_TYPE:
248 <      status = CONF_DLINE;
249 <      break;
250 <
251 <    case KLINE_TYPE:
252 <      status = CONF_KLINE;
253 <      break;
254 <
255 <    case GLINE_TYPE:
256 <      status = CONF_GLINE;
257 <      break;
258 <
259 <    case CLIENT_TYPE:
260 <      status = CONF_CLIENT;
261 <      break;
262 <
263 <    case OPER_TYPE:
264 <      status = CONF_OPERATOR;
265 <      dlinkAdd(conf, &conf->node, &oconf_items);
266 <      break;
267 <
268 <    case SERVER_TYPE:
269 <      status = CONF_SERVER;
270 <      dlinkAdd(conf, &conf->node, &server_items);
271 <      break;
272 <
273 <    default:
274 <      break;
275 <    }
276 <    aconf->status = status;
277 <    break;
278 <
279 <  case LEAF_TYPE:
280 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
281 <                                       sizeof(struct MatchItem));
282 <    dlinkAdd(conf, &conf->node, &leaf_items);
283 <    break;
284 <
285 <  case HUB_TYPE:
286 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
287 <                                       sizeof(struct MatchItem));
288 <    dlinkAdd(conf, &conf->node, &hub_items);
289 <    break;
290 <
291 <  case ULINE_TYPE:
292 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
293 <                                       sizeof(struct MatchItem));
294 <    dlinkAdd(conf, &conf->node, &uconf_items);
295 <    break;
296 <
297 <  case GDENY_TYPE:
298 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
299 <                                       sizeof(struct AccessItem));
300 <    dlinkAdd(conf, &conf->node, &gdeny_items);
301 <    break;
302 <
303 <  case XLINE_TYPE:
304 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
305 <                                       sizeof(struct MatchItem));
306 <    dlinkAdd(conf, &conf->node, &xconf_items);
307 <    break;
308 <
309 <  case RXLINE_TYPE:
310 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
311 <                                       sizeof(struct MatchItem));
312 <    dlinkAdd(conf, &conf->node, &rxconf_items);
313 <    break;
314 <
315 <  case RKLINE_TYPE:
316 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
317 <                                       sizeof(struct AccessItem));
318 <    aconf = map_to_conf(conf);
319 <    aconf->status = CONF_KLINE;
320 <    dlinkAdd(conf, &conf->node, &rkconf_items);
321 <    break;
322 <
323 <  case CLUSTER_TYPE:
324 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem));
325 <    dlinkAdd(conf, &conf->node, &cluster_items);
326 <    break;
327 <
328 <  case CRESV_TYPE:
329 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
330 <                                       sizeof(struct ResvChannel));
331 <    break;
332 <
333 <  case NRESV_TYPE:
334 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
335 <                                       sizeof(struct MatchItem));
336 <    dlinkAdd(conf, &conf->node, &nresv_items);
337 <    break;
338 <
339 <  case CLASS_TYPE:
340 <    conf = MyMalloc(sizeof(struct ConfItem) +
341 <                           sizeof(struct ClassItem));
342 <    dlinkAdd(conf, &conf->node, &class_items);
343 <
344 <    aclass = map_to_conf(conf);
345 <    aclass->active = 1;
346 <    ConFreq(aclass) = DEFAULT_CONNECTFREQUENCY;
347 <    PingFreq(aclass) = DEFAULT_PINGFREQUENCY;
348 <    MaxTotal(aclass) = MAXIMUM_LINKS_DEFAULT;
349 <    MaxSendq(aclass) = DEFAULT_SENDQ;
350 <
351 <    break;
352 <
353 <  default:
354 <    conf = NULL;
355 <    break;
356 <  }
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);
373  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 <    }
391 <    if (aconf->passwd != NULL)
392 <      memset(aconf->passwd, 0, strlen(aconf->passwd));
393 <    if (aconf->spasswd != NULL)
394 <      memset(aconf->spasswd, 0, strlen(aconf->spasswd));
395 <    aconf->class_ptr = NULL;
396 <
397 <    MyFree(aconf->passwd);
398 <    MyFree(aconf->spasswd);
399 <    MyFree(aconf->reason);
400 <    MyFree(aconf->oper_reason);
401 <    MyFree(aconf->user);
402 <    MyFree(aconf->host);
403 <    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)
406 <      RSA_free(aconf->rsa_public_key);
407 <    MyFree(aconf->rsa_public_key_file);
408 < #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:
417 <    case CLIENT_TYPE:
418 <      MyFree(conf);
419 <      break;
420 <
421 <    case OPER_TYPE:
422 <      aconf = map_to_conf(conf);
423 <      if (!IsConfIllegal(aconf))
424 <        dlinkDelete(&conf->node, &oconf_items);
425 <      MyFree(conf);
426 <      break;
427 <
428 <    case SERVER_TYPE:
429 <      aconf = map_to_conf(conf);
430 <      if (!IsConfIllegal(aconf))
431 <        dlinkDelete(&conf->node, &server_items);
432 <      MyFree(conf);
433 <      break;
434 <
435 <    default:
436 <      break;
437 <    }
438 <    break;
439 <
440 <  case HUB_TYPE:
441 <    match_item = map_to_conf(conf);
442 <    MyFree(match_item->user);
443 <    MyFree(match_item->host);
444 <    MyFree(match_item->reason);
445 <    MyFree(match_item->oper_reason);
446 <    /* If marked illegal, its already been pulled off of the hub_items list */
447 <    if (!match_item->illegal)
448 <      dlinkDelete(&conf->node, &hub_items);
449 <    MyFree(conf);
450 <    break;
451 <
452 <  case LEAF_TYPE:
453 <    match_item = map_to_conf(conf);
454 <    MyFree(match_item->user);
455 <    MyFree(match_item->host);
456 <    MyFree(match_item->reason);
457 <    MyFree(match_item->oper_reason);
458 <    /* If marked illegal, its already been pulled off of the leaf_items list */
459 <    if (!match_item->illegal)
460 <      dlinkDelete(&conf->node, &leaf_items);
461 <    MyFree(conf);
462 <    break;
463 <
464 <  case ULINE_TYPE:
465 <    match_item = map_to_conf(conf);
466 <    MyFree(match_item->user);
467 <    MyFree(match_item->host);
468 <    MyFree(match_item->reason);
469 <    MyFree(match_item->oper_reason);
470 <    dlinkDelete(&conf->node, &uconf_items);
471 <    MyFree(conf);
472 <    break;
473 <
474 <  case XLINE_TYPE:
475 <    match_item = map_to_conf(conf);
476 <    MyFree(match_item->user);
477 <    MyFree(match_item->host);
478 <    MyFree(match_item->reason);
479 <    MyFree(match_item->oper_reason);
480 <    dlinkDelete(&conf->node, &xconf_items);
481 <    MyFree(conf);
482 <    break;
483 <
484 <  case RKLINE_TYPE:
485 <    aconf = map_to_conf(conf);
486 <    MyFree(aconf->regexuser);
487 <    MyFree(aconf->regexhost);
488 <    MyFree(aconf->user);
489 <    MyFree(aconf->host);
490 <    MyFree(aconf->reason);
491 <    MyFree(aconf->oper_reason);
492 <    dlinkDelete(&conf->node, &rkconf_items);
493 <    MyFree(conf);
494 <    break;
495 <
496 <  case RXLINE_TYPE:
497 <    MyFree(conf->regexpname);
498 <    match_item = map_to_conf(conf);
499 <    MyFree(match_item->user);
500 <    MyFree(match_item->host);
501 <    MyFree(match_item->reason);
502 <    MyFree(match_item->oper_reason);
503 <    dlinkDelete(&conf->node, &rxconf_items);
504 <    MyFree(conf);
505 <    break;
506 <
507 <  case NRESV_TYPE:
508 <    match_item = map_to_conf(conf);
509 <    MyFree(match_item->user);
510 <    MyFree(match_item->host);
511 <    MyFree(match_item->reason);
512 <    MyFree(match_item->oper_reason);
513 <    dlinkDelete(&conf->node, &nresv_items);
514 <
515 <    if (conf->flags & CONF_FLAGS_TEMPORARY)
516 <      if ((m = dlinkFindDelete(&temporary_resv, conf)) != NULL)
517 <        free_dlink_node(m);
518 <
519 <    MyFree(conf);
520 <    break;
521 <
522 <  case GDENY_TYPE:
523 <    aconf = map_to_conf(conf);
524 <    MyFree(aconf->user);
525 <    MyFree(aconf->host);
526 <    dlinkDelete(&conf->node, &gdeny_items);
527 <    MyFree(conf);
528 <    break;
529 <
530 <  case CLUSTER_TYPE:
531 <    dlinkDelete(&conf->node, &cluster_items);
532 <    MyFree(conf);
533 <    break;
534 <
535 <  case CRESV_TYPE:
536 <    if (conf->flags & CONF_FLAGS_TEMPORARY)
537 <      if ((m = dlinkFindDelete(&temporary_resv, conf)) != NULL)
538 <        free_dlink_node(m);
539 <
540 <    MyFree(conf);
541 <    break;
542 <
543 <  case CLASS_TYPE:
544 <    dlinkDelete(&conf->node, &class_items);
545 <    MyFree(conf);
546 <    break;
547 <
548 <  default:
549 <    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    }
551 }
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
558 < */
559 < void
560 < free_access_item(struct AccessItem *aconf)
561 < {
562 <  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)
565 <    return;
566 <  conf = unmap_conf_item(aconf);
567 <  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()
574 < *
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;
587 <  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;
590  const char *pfx = NULL;
246  
247    switch (type)
248    {
249 <  case GDENY_TYPE:
595 <    DLINK_FOREACH(ptr, gdeny_items.head)
596 <    {
597 <      conf = ptr->data;
598 <      aconf = map_to_conf(conf);
599 <
600 <      p = buf;
601 <
602 <      if (aconf->flags & GDENY_BLOCK)
603 <        *p++ = 'B';
604 <      else
605 <        *p++ = 'b';
606 <
607 <      if (aconf->flags & GDENY_REJECT)
608 <        *p++ = 'R';
609 <      else
610 <        *p++ = 'r';
611 <
612 <      *p = '\0';
613 <
614 <      sendto_one(source_p, ":%s %d %s V %s@%s %s %s",
615 <                 me.name, RPL_STATSDEBUG, source_p->name,
616 <                 aconf->user, aconf->host, conf->name, buf);
617 <    }
618 <    break;
619 <
620 <  case XLINE_TYPE:
249 >  case CONF_XLINE:
250      DLINK_FOREACH(ptr, xconf_items.head)
251      {
252        conf = ptr->data;
624      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;
637      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:
647 <    pfx = temp ? "kR" : "KR";
648 <
274 >  case CONF_RKLINE:
275      DLINK_FOREACH(ptr, rkconf_items.head)
276      {
277 <      aconf = map_to_conf((conf = ptr->data));
652 <
653 <      if (temp && !(conf->flags & CONF_FLAGS_TEMPORARY))
654 <        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;
666      matchitem = map_to_conf(conf);
291  
292        p = buf;
293  
670      /* some of these are redundant for the sake of
671       * consistency with cluster{} flags
672       */
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 686 | 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 695 | 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;
702      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;
722 <      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;
741
377        conf = ptr->data;
743      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';
751 <      if (IsConfLazyLink(aconf))
752 <        *p++ = 'L';
753 <      if (aconf->fakename)
754 <        *p++ = 'M';
755 <      if (IsConfTopicBurst(aconf))
756 <        *p++ = 'T';
757 <      if (IsConfCompressed(aconf))
758 <        *p++ = 'Z';
383 >      if (IsConfSSL(conf))
384 >        *p++ = 'S';
385        if (buf[0] == '\0')
386          *p++ = '*';
387  
# Line 764 | 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      }
788    break;
415  
416 <  case LEAF_TYPE:
791 <    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:
801 <  case KLINE_TYPE:
802 <  case DLINE_TYPE:
803 <  case EXEMPTDLINE_TYPE:
804 <  case CRESV_TYPE:
805 <  case NRESV_TYPE:
806 <  case CLUSTER_TYPE:
427 >  default:
428      break;
429    }
430   }
# Line 821 | 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   {
827  struct Client *source_p = va_arg(args, struct Client *);
828  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)))
833 <    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++;
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++;
474 >      ++ServerStats.is_ref;
475        exit_client(source_p, &me,
476                  "No more connections allowed in your connection class");
477        break;
478  
479      case NOT_AUTHORIZED:
480 <    {
863 <      static char ipaddr[HOSTIPLEN];
864 <      ServerStats->is_ref++;
480 >      ++ServerStats.is_ref;
481        /* jdc - lists server name & port connections are on */
482        /*       a purely cosmetical change */
483 <      irc_getnameinfo((struct sockaddr*)&source_p->localClient->ip,
868 <            source_p->localClient->ip.ss_len, ipaddr, HOSTIPLEN, NULL, 0,
869 <            NI_NUMERICHOST);
870 <      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 <                           ipaddr,
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
883 <       * capture reject code here or rely on the connecting too fast code.
884 <       * - Dianora
885 <       */
886 <      if (REJECT_HOLD_TIME > 0)
887 <      {
888 <        sendto_one(source_p, ":%s NOTICE %s :You are not authorized to use this server",
889 <                   me.name, source_p->name);
890 <        source_p->localClient->reject_delay = CurrentTime + REJECT_HOLD_TIME;
891 <        SetCaptured(source_p);
892 <      }
893 <      else
894 <        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 <    }
897 <
497 >
498     case BANNED_CLIENT:
499 <     /*
500 <      * Don't exit them immediately, play with them a bit.
901 <      * - Dianora
902 <      */
903 <     if (REJECT_HOLD_TIME > 0)
904 <     {
905 <       source_p->localClient->reject_delay = CurrentTime + REJECT_HOLD_TIME;
906 <       SetCaptured(source_p);
907 <     }
908 <     else
909 <       exit_client(source_p, &me, "Banned");
910 <     ServerStats->is_ref++;
499 >     exit_client(source_p, &me, "Banned");
500 >     ++ServerStats.is_ref;
501       break;
502  
503     case 0:
# Line 915 | 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
924 *              - 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;
932 <  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 955 | 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);
963 <
964 <      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))
982 <          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 987 | 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",
999 <                  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 1012 | 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;
1018 <  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);
1028 <  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 1037 | 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 1201 | Line 783 | hash_ip(struct irc_ssaddr *addr)
783    {
784      struct sockaddr_in *v4 = (struct sockaddr_in *)addr;
785      int hash;
786 <    u_int32_t ip;
786 >    uint32_t ip;
787  
788      ip   = ntohl(v4->sin_addr.s_addr);
789      hash = ((ip >> 12) + ip) & (IP_HASH_SIZE-1);
# Line 1212 | Line 794 | hash_ip(struct irc_ssaddr *addr)
794    {
795      int hash;
796      struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)addr;
797 <    u_int32_t *ip = (u_int32_t *)&v6->sin6_addr.s6_addr;
797 >    uint32_t *ip = (uint32_t *)&v6->sin6_addr.s6_addr;
798  
799      hash  = ip[0] ^ ip[3];
800      hash ^= hash >> 16;  
# Line 1236 | Line 818 | hash_ip(struct irc_ssaddr *addr)
818   * used in the hash.
819   */
820   void
821 < count_ip_hash(int *number_ips_stored, unsigned long *mem_ips_stored)
821 > count_ip_hash(unsigned int *number_ips_stored, uint64_t *mem_ips_stored)
822   {
823    struct ip_entry *ptr;
824    int i;
# Line 1300 | Line 882 | garbage_collect_ip_entries(void)
882   * side effects - Disassociate configuration from the client.
883   *                Also removes a class from the list if marked for deleting.
884   */
885 < int
886 < detach_conf(struct Client *client_p, ConfType type)
885 > void
886 > detach_conf(struct Client *client_p, enum maskitem_type type)
887   {
888 <  dlink_node *ptr, *next_ptr;
1307 <  struct ConfItem *conf;
1308 <  struct ClassItem *aclass;
1309 <  struct AccessItem *aconf;
1310 <  struct ConfItem *aclass_conf;
1311 <  struct MatchItem *match_item;
888 >  dlink_node *ptr = NULL, *next_ptr = NULL;
889  
890    DLINK_FOREACH_SAFE(ptr, next_ptr, client_p->localClient->confs.head)
891    {
892 <    conf = ptr->data;
892 >    struct MaskItem *conf = ptr->data;
893  
894 <    if (type == CONF_TYPE || conf->type == type)
895 <    {
896 <      dlinkDelete(ptr, &client_p->localClient->confs);
1320 <      free_dlink_node(ptr);
894 >    assert(conf->type & (CONF_CLIENT | CONF_OPER | CONF_SERVER));
895 >    assert(conf->ref_count > 0);
896 >    assert(conf->class->ref_count > 0);
897  
898 <      switch (conf->type)
899 <      {
1324 <      case CLIENT_TYPE:
1325 <      case OPER_TYPE:
1326 <      case SERVER_TYPE:
1327 <        aconf = map_to_conf(conf);
1328 <
1329 <        assert(aconf->clients > 0);
1330 <
1331 <        if ((aclass_conf = ClassPtr(aconf)) != NULL)
1332 <        {
1333 <          aclass = map_to_conf(aclass_conf);
1334 <
1335 <          assert(aclass->curr_user_count > 0);
1336 <
1337 <          if (conf->type == CLIENT_TYPE)
1338 <            remove_from_cidr_check(&client_p->localClient->ip, aclass);
1339 <          if (--aclass->curr_user_count == 0 && aclass->active == 0)
1340 <            delete_conf_item(aclass_conf);
1341 <        }
1342 <
1343 <        if (--aconf->clients == 0 && IsConfIllegal(aconf))
1344 <          delete_conf_item(conf);
898 >    if (!(conf->type & type))
899 >      continue;
900  
901 <        break;
901 >    dlinkDelete(ptr, &client_p->localClient->confs);
902 >    free_dlink_node(ptr);
903  
904 <      case LEAF_TYPE:
905 <      case HUB_TYPE:
1350 <        match_item = map_to_conf(conf);
1351 <        if (match_item->ref_count == 0 && match_item->illegal)
1352 <          delete_conf_item(conf);
1353 <        break;
1354 <      default:
1355 <        break;
1356 <      }
904 >    if (conf->type == CONF_CLIENT)
905 >      remove_from_cidr_check(&client_p->localClient->ip, conf->class);
906  
907 <      if (type != CONF_TYPE)
908 <        return 0;
907 >    if (--conf->class->ref_count == 0 && conf->class->active == 0)
908 >    {
909 >      class_free(conf->class);
910 >      conf->class = NULL;
911      }
1361  }
912  
913 <  return -1;
913 >    if (--conf->ref_count == 0 && conf->active == 0)
914 >      conf_free(conf);
915 >  }
916   }
917  
918   /* attach_conf()
# Line 1374 | Line 926 | detach_conf(struct Client *client_p, Con
926   *                attachment if there was an old one...
927   */
928   int
929 < attach_conf(struct Client *client_p, struct ConfItem *conf)
929 > attach_conf(struct Client *client_p, struct MaskItem *conf)
930   {
931    if (dlinkFind(&client_p->localClient->confs, conf) != NULL)
932      return 1;
933  
934 <  if (conf->type == CLIENT_TYPE ||
935 <      conf->type == SERVER_TYPE ||
936 <      conf->type == OPER_TYPE)
937 <  {
1386 <    struct AccessItem *aconf = map_to_conf(conf);
1387 <    struct ClassItem *aclass = map_to_conf(aconf->class_ptr);
1388 <
1389 <    if (IsConfIllegal(aconf))
1390 <      return NOT_AUTHORIZED;
934 >  if (conf->type == CONF_CLIENT)
935 >    if (cidr_limit_reached(IsConfExemptLimits(conf),
936 >                           &client_p->localClient->ip, conf->class))
937 >      return TOO_MANY;    /* Already at maximum allowed */
938  
939 <    if (conf->type == CLIENT_TYPE)
940 <      if (cidr_limit_reached(IsConfExemptLimits(aconf),
1394 <                             &client_p->localClient->ip, aclass))
1395 <        return TOO_MANY;    /* Already at maximum allowed */
1396 <
1397 <    CurrUserCount(aclass)++;
1398 <    aconf->clients++;
1399 <  }
1400 <  else if (conf->type == HUB_TYPE || conf->type == LEAF_TYPE)
1401 <  {
1402 <    struct MatchItem *match_item = map_to_conf(conf);
1403 <    match_item->ref_count++;
1404 <  }
939 >  conf->class->ref_count++;
940 >  conf->ref_count++;
941  
942    dlinkAdd(conf, make_dlink_node(), &client_p->localClient->confs);
943  
# Line 1421 | Line 957 | attach_connect_block(struct Client *clie
957                       const char *host)
958   {
959    dlink_node *ptr;
960 <  struct ConfItem *conf;
1425 <  struct AccessItem *aconf;
960 >  struct MaskItem *conf = NULL;
961  
962    assert(client_p != NULL);
963    assert(host != NULL);
# Line 1433 | Line 968 | attach_connect_block(struct Client *clie
968    DLINK_FOREACH(ptr, server_items.head)
969    {
970      conf = ptr->data;
1436    aconf = map_to_conf(conf);
971  
972 <    if (match(conf->name, name) == 0 || match(aconf->host, host) == 0)
972 >    if (match(conf->name, name) == 0 || match(conf->host, host) == 0)
973        continue;
974  
975      attach_conf(client_p, conf);
# Line 1445 | Line 979 | attach_connect_block(struct Client *clie
979    return 0;
980   }
981  
1448 /* find_conf_exact()
1449 *
1450 * inputs       - type of ConfItem
1451 *              - pointer to name to find
1452 *              - pointer to username to find
1453 *              - pointer to host to find
1454 * output       - NULL or pointer to conf found
1455 * side effects - find a conf entry which matches the hostname
1456 *                and has the same name.
1457 */
1458 struct ConfItem *
1459 find_conf_exact(ConfType type, const char *name, const char *user,
1460                const char *host)
1461 {
1462  dlink_node *ptr;
1463  dlink_list *list_p;
1464  struct ConfItem *conf = NULL;
1465  struct AccessItem *aconf;
1466
1467  /* Only valid for OPER_TYPE and ...? */
1468  list_p = map_to_list(type);
1469
1470  DLINK_FOREACH(ptr, (*list_p).head)
1471  {
1472    conf = ptr->data;
1473
1474    if (conf->name == NULL)
1475      continue;
1476    aconf = map_to_conf(conf);
1477    if (aconf->host == NULL)
1478      continue;
1479    if (irccmp(conf->name, name) != 0)
1480      continue;
1481
1482    /*
1483    ** Accept if the *real* hostname (usually sockethost)
1484    ** socket host) matches *either* host or name field
1485    ** of the configuration.
1486    */
1487    if (!match(aconf->host, host) || !match(aconf->user, user))
1488      continue;
1489    if (type == OPER_TYPE)
1490    {
1491      struct ClassItem *aclass = map_to_conf(aconf->class_ptr);
1492
1493      if (aconf->clients >= MaxTotal(aclass))
1494        continue;
1495    }
1496
1497    return conf;
1498  }
1499
1500  return NULL;
1501 }
1502
982   /* find_conf_name()
983   *
984   * inputs       - pointer to conf link list to search
# Line 1509 | Line 988 | find_conf_exact(ConfType type, const cha
988   * side effects - find a conf entry which matches the name
989   *                and has the given mask.
990   */
991 < struct ConfItem *
992 < find_conf_name(dlink_list *list, const char *name, ConfType type)
991 > struct MaskItem *
992 > find_conf_name(dlink_list *list, const char *name, enum maskitem_type type)
993   {
994    dlink_node *ptr;
995 <  struct ConfItem* conf;
995 >  struct MaskItem* conf;
996  
997    DLINK_FOREACH(ptr, list->head)
998    {
# Line 1537 | Line 1016 | find_conf_name(dlink_list *list, const c
1016   * side effects - none
1017   */
1018   static dlink_list *
1019 < map_to_list(ConfType type)
1019 > map_to_list(enum maskitem_type type)
1020   {
1021    switch(type)
1022    {
1023 <  case RXLINE_TYPE:
1023 >  case CONF_RKLINE:
1024 >    return(&rkconf_items);
1025 >    break;
1026 >  case CONF_RXLINE:
1027      return(&rxconf_items);
1028      break;
1029 <  case XLINE_TYPE:
1029 >  case CONF_XLINE:
1030      return(&xconf_items);
1031      break;
1032 <  case ULINE_TYPE:
1032 >  case CONF_ULINE:
1033      return(&uconf_items);
1034      break;
1035 <  case NRESV_TYPE:
1035 >  case CONF_NRESV:
1036      return(&nresv_items);
1037      break;
1038 <  case OPER_TYPE:
1038 >  case CONF_OPER:
1039      return(&oconf_items);
1040      break;
1041 <  case CLASS_TYPE:
1560 <    return(&class_items);
1561 <    break;
1562 <  case SERVER_TYPE:
1041 >  case CONF_SERVER:
1042      return(&server_items);
1043      break;
1044 <  case CLUSTER_TYPE:
1044 >  case CONF_SERVICE:
1045 >    return(&service_items);
1046 >    break;
1047 >  case CONF_CLUSTER:
1048      return(&cluster_items);
1049      break;
1568  case CONF_TYPE:
1569  case GLINE_TYPE:
1570  case KLINE_TYPE:
1571  case DLINE_TYPE:
1572  case CRESV_TYPE:
1050    default:
1051      return NULL;
1052    }
# Line 1581 | Line 1058 | map_to_list(ConfType type)
1058   *              - pointer to name string to find
1059   *              - pointer to user
1060   *              - pointer to host
1061 < *              - optional action to match on as well
1062 < * output       - NULL or pointer to found struct MatchItem
1061 > *              - optional flags to match on as well
1062 > * output       - NULL or pointer to found struct MaskItem
1063   * side effects - looks for a match on name field
1064   */
1065 < struct ConfItem *
1066 < find_matching_name_conf(ConfType type, const char *name, const char *user,
1067 <                        const char *host, int action)
1065 > struct MaskItem *
1066 > find_matching_name_conf(enum maskitem_type type, const char *name, const char *user,
1067 >                        const char *host, unsigned int flags)
1068   {
1069    dlink_node *ptr=NULL;
1070 <  struct ConfItem *conf=NULL;
1594 <  struct AccessItem *aconf=NULL;
1595 <  struct MatchItem *match_item=NULL;
1070 >  struct MaskItem *conf=NULL;
1071    dlink_list *list_p = map_to_list(type);
1072  
1073    switch (type)
1074    {
1075 <    case RXLINE_TYPE:
1075 > #ifdef HAVE_LIBPCRE
1076 >  case CONF_RXLINE:
1077        DLINK_FOREACH(ptr, list_p->head)
1078        {
1079          conf = ptr->data;
1080          assert(conf->regexpname);
1081  
1082 <        if (!ircd_pcre_exec(conf->regexpname, name))
1082 >        if (!ircd_pcre_exec(conf->regexuser, name))
1083            return conf;
1084        }
1085        break;
1086 + #endif
1087 +  case CONF_SERVICE:
1088 +    DLINK_FOREACH(ptr, list_p->head)
1089 +    {
1090 +      conf = ptr->data;
1091  
1092 <  case XLINE_TYPE:
1093 <  case ULINE_TYPE:
1094 <  case NRESV_TYPE:
1092 >      if (EmptyString(conf->name))
1093 >        continue;
1094 >      if ((name != NULL) && !irccmp(name, conf->name))
1095 >        return conf;
1096 >    }
1097 >    break;
1098 >
1099 >  case CONF_XLINE:
1100 >  case CONF_ULINE:
1101 >  case CONF_NRESV:
1102      DLINK_FOREACH(ptr, list_p->head)
1103      {
1104        conf = ptr->data;
1105  
1618      match_item = map_to_conf(conf);
1106        if (EmptyString(conf->name))
1107          continue;
1108        if ((name != NULL) && match_esc(conf->name, name))
1109        {
1110          if ((user == NULL && (host == NULL)))
1111            return conf;
1112 <        if ((match_item->action & action) != action)
1112 >        if ((conf->flags & flags) != flags)
1113            continue;
1114 <        if (EmptyString(match_item->user) || EmptyString(match_item->host))
1114 >        if (EmptyString(conf->user) || EmptyString(conf->host))
1115            return conf;
1116 <        if (match(match_item->user, user) && match(match_item->host, host))
1116 >        if (match(conf->user, user) && match(conf->host, host))
1117            return conf;
1118        }
1119      }
1120        break;
1121  
1122 <  case SERVER_TYPE:
1122 >  case CONF_SERVER:
1123      DLINK_FOREACH(ptr, list_p->head)
1124      {
1125        conf = ptr->data;
1639      aconf = map_to_conf(conf);
1126  
1127 <      if ((name != NULL) && match_esc(name, conf->name))
1127 >      if ((name != NULL) && match(name, conf->name))
1128          return conf;
1129 <      else if ((host != NULL) && match_esc(host, aconf->host))
1129 >      else if ((host != NULL) && match(host, conf->host))
1130          return conf;
1131      }
1132      break;
# Line 1657 | Line 1143 | find_matching_name_conf(ConfType type, c
1143   *              - pointer to name string to find
1144   *              - pointer to user
1145   *              - pointer to host
1146 < * output       - NULL or pointer to found struct MatchItem
1146 > * output       - NULL or pointer to found struct MaskItem
1147   * side effects - looks for an exact match on name field
1148   */
1149 < struct ConfItem *
1150 < find_exact_name_conf(ConfType type, const char *name,
1149 > struct MaskItem *
1150 > find_exact_name_conf(enum maskitem_type type, const struct Client *who, const char *name,
1151                       const char *user, const char *host)
1152   {
1153    dlink_node *ptr = NULL;
1154 <  struct AccessItem *aconf;
1155 <  struct ConfItem *conf;
1670 <  struct MatchItem *match_item;
1671 <  dlink_list *list_p;
1672 <
1673 <  list_p = map_to_list(type);
1154 >  struct MaskItem *conf;
1155 >  dlink_list *list_p = map_to_list(type);
1156  
1157    switch(type)
1158    {
1159 <  case RXLINE_TYPE:
1160 <  case XLINE_TYPE:
1161 <  case ULINE_TYPE:
1162 <  case NRESV_TYPE:
1159 >  case CONF_RXLINE:
1160 >  case CONF_XLINE:
1161 >  case CONF_ULINE:
1162 >  case CONF_NRESV:
1163  
1164      DLINK_FOREACH(ptr, list_p->head)
1165      {
1166        conf = ptr->data;
1167 <      match_item = (struct MatchItem *)map_to_conf(conf);
1167 >
1168        if (EmptyString(conf->name))
1169          continue;
1170      
# Line 1690 | Line 1172 | find_exact_name_conf(ConfType type, cons
1172        {
1173          if ((user == NULL && (host == NULL)))
1174            return (conf);
1175 <        if (EmptyString(match_item->user) || EmptyString(match_item->host))
1175 >        if (EmptyString(conf->user) || EmptyString(conf->host))
1176            return (conf);
1177 <        if (match(match_item->user, user) && match(match_item->host, host))
1177 >        if (match(conf->user, user) && match(conf->host, host))
1178            return (conf);
1179        }
1180      }
1181      break;
1182  
1183 <  case OPER_TYPE:
1183 >  case CONF_OPER:
1184      DLINK_FOREACH(ptr, list_p->head)
1185      {
1186        conf = ptr->data;
1187 <      aconf = (struct AccessItem *)map_to_conf(conf);
1187 >
1188        if (EmptyString(conf->name))
1189 <        continue;
1190 <    
1191 <      if (irccmp(conf->name, name) == 0)
1189 >        continue;
1190 >
1191 >      if (!irccmp(conf->name, name))
1192        {
1193 <        if ((user == NULL && (host == NULL)))
1194 <          return (conf);
1195 <        if (EmptyString(aconf->user) || EmptyString(aconf->host))
1196 <          return (conf);
1197 <        if (match(aconf->user, user) && match(aconf->host, host))
1198 <          return (conf);
1193 >        if (!who)
1194 >          return conf;
1195 >        if (EmptyString(conf->user) || EmptyString(conf->host))
1196 >          return NULL;
1197 >        if (match(conf->user, who->username))
1198 >        {
1199 >          switch (conf->htype)
1200 >          {
1201 >            case HM_HOST:
1202 >              if (match(conf->host, who->host) || match(conf->host, who->sockhost))
1203 >                if (!conf->class->max_total || conf->class->ref_count < conf->class->max_total)
1204 >                  return conf;
1205 >              break;
1206 >            case HM_IPV4:
1207 >              if (who->localClient->aftype == AF_INET)
1208 >                if (match_ipv4(&who->localClient->ip, &conf->addr, conf->bits))
1209 >                  if (!conf->class->max_total || conf->class->ref_count < conf->class->max_total)
1210 >                    return conf;
1211 >              break;
1212 > #ifdef IPV6
1213 >            case HM_IPV6:
1214 >              if (who->localClient->aftype == AF_INET6)
1215 >                if (match_ipv6(&who->localClient->ip, &conf->addr, conf->bits))
1216 >                  if (!conf->class->max_total || conf->class->ref_count < conf->class->max_total)
1217 >                    return conf;
1218 >              break;
1219 > #endif
1220 >            default:
1221 >              assert(0);
1222 >          }
1223 >        }
1224        }
1225      }
1226 +
1227      break;
1228  
1229 <  case SERVER_TYPE:
1229 >  case CONF_SERVER:
1230      DLINK_FOREACH(ptr, list_p->head)
1231      {
1232        conf = ptr->data;
1233 <      aconf = (struct AccessItem *)map_to_conf(conf);
1233 >
1234        if (EmptyString(conf->name))
1235          continue;
1236      
1237        if (name == NULL)
1238        {
1239 <        if (EmptyString(aconf->host))
1239 >        if (EmptyString(conf->host))
1240            continue;
1241 <        if (irccmp(aconf->host, host) == 0)
1241 >        if (irccmp(conf->host, host) == 0)
1242            return(conf);
1243        }
1244        else if (irccmp(conf->name, name) == 0)
# Line 1740 | Line 1248 | find_exact_name_conf(ConfType type, cons
1248      }
1249      break;
1250  
1743  case CLASS_TYPE:
1744    DLINK_FOREACH(ptr, list_p->head)
1745    {
1746      conf = ptr->data;
1747      if (EmptyString(conf->name))
1748        continue;
1749    
1750      if (irccmp(conf->name, name) == 0)
1751        return (conf);
1752    }
1753    break;
1754
1251    default:
1252      break;
1253    }
# Line 1768 | Line 1264 | int
1264   rehash(int sig)
1265   {
1266    if (sig != 0)
1267 <    sendto_realops_flags(UMODE_ALL, L_ALL,
1267 >    sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1268                           "Got signal SIGHUP, reloading ircd.conf file");
1269  
1774 #ifndef _WIN32
1270    restart_resolver();
1271 < #endif
1271 >
1272    /* don't close listeners until we know we can go ahead with the rehash */
1273  
1274    /* Check to see if we magically got(or lost) IPv6 support */
# Line 1784 | Line 1279 | rehash(int sig)
1279    if (ServerInfo.description != NULL)
1280      strlcpy(me.info, ServerInfo.description, sizeof(me.info));
1281  
1787 #ifndef STATIC_MODULES
1282    load_conf_modules();
1789 #endif
1790
1791  flush_deleted_I_P();
1283  
1284    rehashed_klines = 1;
1285 <
1285 > /* XXX */
1286    if (ConfigLoggingEntry.use_logging)
1287 <    reopen_log(logFileName);
1287 >    log_close_all();
1288  
1289    return(0);
1290   }
# Line 1813 | Line 1304 | set_default_conf(void)
1304    /* verify init_class() ran, this should be an unnecessary check
1305     * but its not much work.
1306     */
1307 <  assert(class_default == (struct ConfItem *) class_items.tail->data);
1307 >  assert(class_default == class_get_list()->tail->data);
1308  
1309   #ifdef HAVE_LIBCRYPTO
1310    ServerInfo.rsa_private_key = NULL;
# Line 1823 | Line 1314 | set_default_conf(void)
1314    /* ServerInfo.name is not rehashable */
1315    /* ServerInfo.name = ServerInfo.name; */
1316    ServerInfo.description = NULL;
1317 <  DupString(ServerInfo.network_name, NETWORK_NAME_DEFAULT);
1318 <  DupString(ServerInfo.network_desc, NETWORK_DESC_DEFAULT);
1317 >  ServerInfo.network_name = xstrdup(NETWORK_NAME_DEFAULT);
1318 >  ServerInfo.network_desc = xstrdup(NETWORK_DESC_DEFAULT);
1319  
1320    memset(&ServerInfo.ip, 0, sizeof(ServerInfo.ip));
1321    ServerInfo.specific_ipv4_vhost = 0;
# Line 1832 | Line 1323 | set_default_conf(void)
1323    ServerInfo.specific_ipv6_vhost = 0;
1324  
1325    ServerInfo.max_clients = MAXCLIENTS_MAX;
1326 <  /* Don't reset hub, as that will break lazylinks */
1327 <  /* ServerInfo.hub = NO; */
1326 >
1327 >  ServerInfo.hub = 0;
1328    ServerInfo.dns_host.sin_addr.s_addr = 0;
1329    ServerInfo.dns_host.sin_port = 0;
1330    AdminInfo.name = NULL;
1331    AdminInfo.email = NULL;
1332    AdminInfo.description = NULL;
1333  
1334 <  set_log_level(L_NOTICE);
1334 >  log_close_all();
1335 >
1336    ConfigLoggingEntry.use_logging = 1;
1337 <  ConfigLoggingEntry.operlog[0] = '\0';
1338 <  ConfigLoggingEntry.userlog[0] = '\0';
1339 <  ConfigLoggingEntry.klinelog[0] = '\0';
1848 <  ConfigLoggingEntry.glinelog[0] = '\0';
1849 <  ConfigLoggingEntry.killlog[0] = '\0';
1850 <  ConfigLoggingEntry.operspylog[0] = '\0';
1851 <  ConfigLoggingEntry.ioerrlog[0] = '\0';
1852 <  ConfigLoggingEntry.failed_operlog[0] = '\0';
1853 <
1854 <  ConfigChannel.disable_fake_channels = NO;
1855 <  ConfigChannel.restrict_channels = NO;
1856 <  ConfigChannel.disable_local_channels = NO;
1857 <  ConfigChannel.use_invex = YES;
1858 <  ConfigChannel.use_except = YES;
1859 <  ConfigChannel.use_knock = YES;
1337 >
1338 >  ConfigChannel.disable_fake_channels = 0;
1339 >  ConfigChannel.restrict_channels = 0;
1340    ConfigChannel.knock_delay = 300;
1341    ConfigChannel.knock_delay_channel = 60;
1342 <  ConfigChannel.max_chans_per_user = 15;
1343 <  ConfigChannel.quiet_on_ban = YES;
1342 >  ConfigChannel.max_chans_per_user = 25;
1343 >  ConfigChannel.max_chans_per_oper = 50;
1344 >  ConfigChannel.quiet_on_ban = 1;
1345    ConfigChannel.max_bans = 25;
1346    ConfigChannel.default_split_user_count = 0;
1347    ConfigChannel.default_split_server_count = 0;
1348 <  ConfigChannel.no_join_on_split = NO;
1349 <  ConfigChannel.no_create_on_split = NO;
1869 <  ConfigChannel.burst_topicwho = YES;
1348 >  ConfigChannel.no_join_on_split = 0;
1349 >  ConfigChannel.no_create_on_split = 0;
1350  
1351 <  ConfigServerHide.flatten_links = NO;
1351 >  ConfigServerHide.flatten_links = 0;
1352    ConfigServerHide.links_delay = 300;
1353 <  ConfigServerHide.hidden = NO;
1354 <  ConfigServerHide.disable_hidden = NO;
1355 <  ConfigServerHide.hide_servers = NO;
1356 <  DupString(ConfigServerHide.hidden_name, NETWORK_NAME_DEFAULT);
1877 <  ConfigServerHide.hide_server_ips = NO;
1353 >  ConfigServerHide.hidden = 0;
1354 >  ConfigServerHide.hide_servers = 0;
1355 >  ConfigServerHide.hidden_name = xstrdup(NETWORK_NAME_DEFAULT);
1356 >  ConfigServerHide.hide_server_ips = 0;
1357  
1358 +  
1359 +  ConfigFileEntry.service_name = xstrdup(SERVICE_NAME_DEFAULT);
1360 +  ConfigFileEntry.max_watch = WATCHSIZE_DEFAULT;
1361 +  ConfigFileEntry.glines = 0;
1362 +  ConfigFileEntry.gline_time = 12 * 3600;
1363 +  ConfigFileEntry.gline_request_time = GLINE_REQUEST_EXPIRE_DEFAULT;
1364    ConfigFileEntry.gline_min_cidr = 16;
1365    ConfigFileEntry.gline_min_cidr6 = 48;
1366 <  ConfigFileEntry.invisible_on_connect = YES;
1367 <  ConfigFileEntry.burst_away = NO;
1368 <  ConfigFileEntry.use_whois_actually = YES;
1369 <  ConfigFileEntry.tkline_expire_notices = YES;
1370 <  ConfigFileEntry.hide_spoof_ips = YES;
1371 <  ConfigFileEntry.ignore_bogus_ts = NO;
1887 <  ConfigFileEntry.disable_auth = NO;
1888 <  ConfigFileEntry.disable_remote = NO;
1366 >  ConfigFileEntry.invisible_on_connect = 1;
1367 >  ConfigFileEntry.tkline_expire_notices = 1;
1368 >  ConfigFileEntry.hide_spoof_ips = 1;
1369 >  ConfigFileEntry.ignore_bogus_ts = 0;
1370 >  ConfigFileEntry.disable_auth = 0;
1371 >  ConfigFileEntry.disable_remote = 0;
1372    ConfigFileEntry.kill_chase_time_limit = 90;
1373 <  ConfigFileEntry.default_floodcount = 8; /* XXX */
1374 <  ConfigFileEntry.failed_oper_notice = YES;
1375 <  ConfigFileEntry.dots_in_ident = 0;      /* XXX */
1893 <  ConfigFileEntry.dot_in_ip6_addr = YES;
1373 >  ConfigFileEntry.default_floodcount = 8;
1374 >  ConfigFileEntry.failed_oper_notice = 1;
1375 >  ConfigFileEntry.dots_in_ident = 0;
1376    ConfigFileEntry.min_nonwildcard = 4;
1377    ConfigFileEntry.min_nonwildcard_simple = 3;
1378    ConfigFileEntry.max_accept = 20;
1379 <  ConfigFileEntry.anti_nick_flood = NO;   /* XXX */
1379 >  ConfigFileEntry.anti_nick_flood = 0;
1380    ConfigFileEntry.max_nick_time = 20;
1381    ConfigFileEntry.max_nick_changes = 5;
1382 <  ConfigFileEntry.anti_spam_exit_message_time = 0;  /* XXX */
1382 >  ConfigFileEntry.anti_spam_exit_message_time = 0;
1383    ConfigFileEntry.ts_warn_delta = TS_WARN_DELTA_DEFAULT;
1384 <  ConfigFileEntry.ts_max_delta = TS_MAX_DELTA_DEFAULT;  /* XXX */
1385 <  ConfigFileEntry.kline_with_reason = YES;
1386 <  ConfigFileEntry.kline_reason = NULL;
1905 <  ConfigFileEntry.warn_no_nline = YES;
1906 <  ConfigFileEntry.stats_o_oper_only = NO; /* XXX */
1384 >  ConfigFileEntry.ts_max_delta = TS_MAX_DELTA_DEFAULT;
1385 >  ConfigFileEntry.warn_no_nline = 1;
1386 >  ConfigFileEntry.stats_o_oper_only = 0;
1387    ConfigFileEntry.stats_k_oper_only = 1;  /* masked */
1388    ConfigFileEntry.stats_i_oper_only = 1;  /* masked */
1389 <  ConfigFileEntry.stats_P_oper_only = NO;
1389 >  ConfigFileEntry.stats_P_oper_only = 0;
1390    ConfigFileEntry.caller_id_wait = 60;
1391 <  ConfigFileEntry.opers_bypass_callerid = NO;
1391 >  ConfigFileEntry.opers_bypass_callerid = 0;
1392    ConfigFileEntry.pace_wait = 10;
1393    ConfigFileEntry.pace_wait_simple = 1;
1394 <  ConfigFileEntry.short_motd = NO;
1395 <  ConfigFileEntry.ping_cookie = NO;
1396 <  ConfigFileEntry.no_oper_flood = NO;     /* XXX */
1397 <  ConfigFileEntry.true_no_oper_flood = NO;  /* XXX */
1398 <  ConfigFileEntry.oper_pass_resv = YES;
1919 <  ConfigFileEntry.glines = NO;            /* XXX */
1920 <  ConfigFileEntry.gline_time = 12 * 3600; /* XXX */
1921 <  ConfigFileEntry.idletime = 0;
1394 >  ConfigFileEntry.short_motd = 0;
1395 >  ConfigFileEntry.ping_cookie = 0;
1396 >  ConfigFileEntry.no_oper_flood = 0;
1397 >  ConfigFileEntry.true_no_oper_flood = 0;
1398 >  ConfigFileEntry.oper_pass_resv = 1;
1399    ConfigFileEntry.max_targets = MAX_TARGETS_DEFAULT;
1400 <  ConfigFileEntry.client_flood = CLIENT_FLOOD_DEFAULT;
1924 <  ConfigFileEntry.oper_only_umodes = UMODE_DEBUG;  /* XXX */
1400 >  ConfigFileEntry.oper_only_umodes = UMODE_DEBUG;
1401    ConfigFileEntry.oper_umodes = UMODE_BOTS | UMODE_LOCOPS | UMODE_SERVNOTICE |
1402 <    UMODE_OPERWALL | UMODE_WALLOP;        /* XXX */
1403 <  DupString(ConfigFileEntry.servlink_path, SLPATH);
1928 < #ifdef HAVE_LIBCRYPTO
1929 <  /* jdc -- This is our default value for a cipher.  According to the
1930 <   *        CRYPTLINK document (doc/cryptlink.txt), BF/128 must be supported
1931 <   *        under all circumstances if cryptlinks are enabled.  So,
1932 <   *        this will be our default.
1933 <   *
1934 <   *        NOTE: I apologise for the hard-coded value of "1" (BF/128).
1935 <   *              This should be moved into a find_cipher() routine.
1936 <   */
1937 <  ConfigFileEntry.default_cipher_preference = &CipherTable[1];
1938 < #endif
1939 <  ConfigFileEntry.use_egd = NO;
1402 >    UMODE_OPERWALL | UMODE_WALLOP;
1403 >  ConfigFileEntry.use_egd = 0;
1404    ConfigFileEntry.egdpool_path = NULL;
1941 #ifdef HAVE_LIBZ
1942  ConfigFileEntry.compression_level = 0;
1943 #endif
1405    ConfigFileEntry.throttle_time = 10;
1406   }
1407  
1408 + static void
1409 + validate_conf(void)
1410 + {
1411 +  if (ConfigFileEntry.ts_warn_delta < TS_WARN_DELTA_MIN)
1412 +    ConfigFileEntry.ts_warn_delta = TS_WARN_DELTA_DEFAULT;
1413 +
1414 +  if (ConfigFileEntry.ts_max_delta < TS_MAX_DELTA_MIN)
1415 +    ConfigFileEntry.ts_max_delta = TS_MAX_DELTA_DEFAULT;
1416 +
1417 +  if (ServerInfo.network_name == NULL)
1418 +    ServerInfo.network_name = xstrdup(NETWORK_NAME_DEFAULT);
1419 +
1420 +  if (ServerInfo.network_desc == NULL)
1421 +    ServerInfo.network_desc = xstrdup(NETWORK_DESC_DEFAULT);
1422 +
1423 +  if (ConfigFileEntry.service_name == NULL)
1424 +    ConfigFileEntry.service_name = xstrdup(SERVICE_NAME_DEFAULT);
1425 +
1426 +  ConfigFileEntry.max_watch = IRCD_MAX(ConfigFileEntry.max_watch, WATCHSIZE_MIN);
1427 + }
1428 +
1429   /* read_conf()
1430   *
1431   * inputs       - file descriptor pointing to config file to use
# Line 1951 | Line 1433 | set_default_conf(void)
1433   * side effects - Read configuration file.
1434   */
1435   static void
1436 < read_conf(FBFILE *file)
1436 > read_conf(FILE *file)
1437   {
1438    lineno = 0;
1439  
1440    set_default_conf(); /* Set default values prior to conf parsing */
1441 <  ypass = 1;
1441 >  conf_parser_ctx.pass = 1;
1442    yyparse();          /* pick up the classes first */
1443  
1444 <  fbrewind(file);
1444 >  rewind(file);
1445  
1446 <  ypass = 2;
1446 >  conf_parser_ctx.pass = 2;
1447    yyparse();          /* Load the values from the conf */
1448    validate_conf();    /* Check to make sure some values are still okay. */
1449                        /* Some global values are also loaded here. */
1450 <  check_class();      /* Make sure classes are valid */
1969 < }
1970 <
1971 < static void
1972 < validate_conf(void)
1973 < {
1974 <  if (ConfigFileEntry.ts_warn_delta < TS_WARN_DELTA_MIN)
1975 <    ConfigFileEntry.ts_warn_delta = TS_WARN_DELTA_DEFAULT;
1976 <
1977 <  if (ConfigFileEntry.ts_max_delta < TS_MAX_DELTA_MIN)
1978 <    ConfigFileEntry.ts_max_delta = TS_MAX_DELTA_DEFAULT;
1979 <
1980 <  if (ConfigFileEntry.servlink_path == NULL)
1981 <    DupString(ConfigFileEntry.servlink_path, SLPATH);
1982 <
1983 <  if (ServerInfo.network_name == NULL)
1984 <    DupString(ServerInfo.network_name,NETWORK_NAME_DEFAULT);
1985 <
1986 <  if (ServerInfo.network_desc == NULL)
1987 <    DupString(ServerInfo.network_desc,NETWORK_DESC_DEFAULT);
1988 <
1989 <  if ((ConfigFileEntry.client_flood < CLIENT_FLOOD_MIN) ||
1990 <      (ConfigFileEntry.client_flood > CLIENT_FLOOD_MAX))
1991 <    ConfigFileEntry.client_flood = CLIENT_FLOOD_MAX;
1450 >  class_delete_marked();      /* Make sure classes are valid */
1451   }
1452  
1453   /* lookup_confhost()
# Line 1996 | Line 1455 | validate_conf(void)
1455   * start DNS lookups of all hostnames in the conf
1456   * line and convert an IP addresses in a.b.c.d number for to IP#s.
1457   */
1458 < static void
1459 < lookup_confhost(struct ConfItem *conf)
1458 > void
1459 > lookup_confhost(struct MaskItem *conf)
1460   {
2002  struct AccessItem *aconf;
1461    struct addrinfo hints, *res;
1462  
2005  aconf = map_to_conf(conf);
2006
2007  if (EmptyString(aconf->host) ||
2008      EmptyString(aconf->user))
2009  {
2010    ilog(L_ERROR, "Host/server name error: (%s) (%s)",
2011         aconf->host, conf->name);
2012    return;
2013  }
2014
2015  if (strchr(aconf->host, '*') ||
2016      strchr(aconf->host, '?'))
2017    return;
2018
1463    /* Do name lookup now on hostnames given and store the
1464     * ip numbers in conf structure.
1465     */
# Line 2027 | Line 1471 | lookup_confhost(struct ConfItem *conf)
1471    /* Get us ready for a bind() and don't bother doing dns lookup */
1472    hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
1473  
1474 <  if (irc_getaddrinfo(aconf->host, NULL, &hints, &res))
1474 >  if (getaddrinfo(conf->host, NULL, &hints, &res))
1475    {
1476 <    conf_dns_lookup(aconf);
1476 >    conf_dns_lookup(conf);
1477      return;
1478    }
1479  
1480    assert(res != NULL);
1481  
1482 <  memcpy(&aconf->ipnum, res->ai_addr, res->ai_addrlen);
1483 <  aconf->ipnum.ss_len = res->ai_addrlen;
1484 <  aconf->ipnum.ss.ss_family = res->ai_family;
1485 <  irc_freeaddrinfo(res);
1482 >  memcpy(&conf->addr, res->ai_addr, res->ai_addrlen);
1483 >  conf->addr.ss_len = res->ai_addrlen;
1484 >  conf->addr.ss.ss_family = res->ai_family;
1485 >
1486 >  freeaddrinfo(res);
1487   }
1488  
1489   /* conf_connect_allowed()
# Line 2052 | Line 1497 | int
1497   conf_connect_allowed(struct irc_ssaddr *addr, int aftype)
1498   {
1499    struct ip_entry *ip_found;
1500 <  struct AccessItem *aconf = find_dline_conf(addr, aftype);
1500 >  struct MaskItem *conf = find_dline_conf(addr, aftype);
1501  
1502    /* DLINE exempt also gets you out of static limits/pacing... */
1503 <  if (aconf && (aconf->status & CONF_EXEMPTDLINE))
1503 >  if (conf && (conf->type == CONF_EXEMPT))
1504      return 0;
1505  
1506 <  if (aconf != NULL)
1506 >  if (conf != NULL)
1507      return BANNED_CLIENT;
1508  
1509    ip_found = find_or_add_ip(addr);
# Line 2074 | Line 1519 | conf_connect_allowed(struct irc_ssaddr *
1519    return 0;
1520   }
1521  
1522 < static struct AccessItem *
1522 > static struct MaskItem *
1523   find_regexp_kline(const char *uhi[])
1524   {
1525 + #ifdef HAVE_LIBPCRE
1526    const dlink_node *ptr = NULL;
1527  
1528    DLINK_FOREACH(ptr, rkconf_items.head)
1529    {
1530 <    struct AccessItem *aptr = map_to_conf(ptr->data);
1530 >    struct MaskItem *aptr = ptr->data;
1531  
1532      assert(aptr->regexuser);
1533      assert(aptr->regexhost);
# Line 2091 | Line 1537 | find_regexp_kline(const char *uhi[])
1537           !ircd_pcre_exec(aptr->regexhost, uhi[2])))
1538        return aptr;
1539    }
1540 <
1540 > #endif
1541    return NULL;
1542   }
1543  
1544   /* find_kill()
1545   *
1546   * inputs       - pointer to client structure
1547 < * output       - pointer to struct AccessItem if found
1547 > * output       - pointer to struct MaskItem if found
1548   * side effects - See if this user is klined already,
1549 < *                and if so, return struct AccessItem pointer
1549 > *                and if so, return struct MaskItem pointer
1550   */
1551 < struct AccessItem *
1551 > struct MaskItem *
1552   find_kill(struct Client *client_p)
1553   {
1554 <  struct AccessItem *aconf = NULL;
1554 >  struct MaskItem *conf = NULL;
1555    const char *uhi[3];
1556  
1557    uhi[0] = client_p->username;
# Line 2114 | Line 1560 | find_kill(struct Client *client_p)
1560  
1561    assert(client_p != NULL);
1562  
1563 <  aconf = find_kline_conf(client_p->host, client_p->username,
1564 <                          &client_p->localClient->ip,
1565 <                          client_p->localClient->aftype);
1566 <  if (aconf == NULL)
1567 <    aconf = find_regexp_kline(uhi);
2122 <
2123 <  if (aconf && (aconf->status & CONF_KLINE))
2124 <    return aconf;
1563 >  conf = find_conf_by_address(client_p->host, &client_p->localClient->ip,
1564 >                              CONF_KLINE, client_p->localClient->aftype,
1565 >                              client_p->username, NULL, 1);
1566 >  if (conf == NULL)
1567 >    conf = find_regexp_kline(uhi);
1568  
1569 <  return NULL;
1569 >  return conf;
1570   }
1571  
1572 < struct AccessItem *
1572 > struct MaskItem *
1573   find_gline(struct Client *client_p)
1574   {
1575 <  struct AccessItem *aconf;
1575 >  struct MaskItem *conf;
1576  
1577    assert(client_p != NULL);
1578  
1579 <  aconf = find_gline_conf(client_p->host, client_p->username,
1580 <                          &client_p->localClient->ip,
1581 <                          client_p->localClient->aftype);
1582 <
2140 <  if (aconf && (aconf->status & CONF_GLINE))
2141 <    return aconf;
2142 <
2143 <  return NULL;
2144 < }
2145 <
2146 < /* add_temp_line()
2147 < *
2148 < * inputs        - pointer to struct ConfItem
2149 < * output        - none
2150 < * Side effects  - links in given struct ConfItem into
2151 < *                 temporary *line link list
2152 < */
2153 < void
2154 < add_temp_line(struct ConfItem *conf)
2155 < {
2156 <  struct AccessItem *aconf;
2157 <
2158 <  if (conf->type == DLINE_TYPE)
2159 <  {
2160 <    aconf = map_to_conf(conf);
2161 <    SetConfTemporary(aconf);
2162 <    dlinkAdd(conf, &conf->node, &temporary_dlines);
2163 <    MyFree(aconf->user);
2164 <    aconf->user = NULL;
2165 <    add_conf_by_address(CONF_DLINE, aconf);
2166 <  }
2167 <  else if (conf->type == KLINE_TYPE)
2168 <  {
2169 <    aconf = map_to_conf(conf);
2170 <    SetConfTemporary(aconf);
2171 <    dlinkAdd(conf, &conf->node, &temporary_klines);
2172 <    add_conf_by_address(CONF_KILL, aconf);
2173 <  }
2174 <  else if (conf->type == GLINE_TYPE)
2175 <  {
2176 <    aconf = map_to_conf(conf);
2177 <    SetConfTemporary(aconf);
2178 <    dlinkAdd(conf, &conf->node, &temporary_glines);
2179 <    add_conf_by_address(CONF_GLINE, aconf);
2180 <  }
2181 <  else if (conf->type == XLINE_TYPE)
2182 <  {
2183 <    conf->flags |= CONF_FLAGS_TEMPORARY;
2184 <    dlinkAdd(conf, make_dlink_node(), &temporary_xlines);
2185 <  }
2186 <  else if (conf->type == RXLINE_TYPE)
2187 <  {
2188 <    conf->flags |= CONF_FLAGS_TEMPORARY;
2189 <    dlinkAdd(conf, make_dlink_node(), &temporary_rxlines);
2190 <  }
2191 <  else if (conf->type == RKLINE_TYPE)
2192 <  {
2193 <    conf->flags |= CONF_FLAGS_TEMPORARY;
2194 <    dlinkAdd(conf, make_dlink_node(), &temporary_rklines);
2195 <  }
2196 <  else if ((conf->type == NRESV_TYPE) || (conf->type == CRESV_TYPE))
2197 <  {
2198 <    conf->flags |= CONF_FLAGS_TEMPORARY;
2199 <    dlinkAdd(conf, make_dlink_node(), &temporary_resv);
2200 <  }
1579 >  conf = find_conf_by_address(client_p->host, &client_p->localClient->ip,
1580 >                              CONF_GLINE, client_p->localClient->aftype,
1581 >                              client_p->username, NULL, 1);
1582 >  return conf;
1583   }
1584  
1585   /* cleanup_tklines()
# Line 2210 | Line 1592 | add_temp_line(struct ConfItem *conf)
1592   void
1593   cleanup_tklines(void *notused)
1594   {
1595 <  expire_tklines(&temporary_glines);
1596 <  expire_tklines(&temporary_klines);
1597 <  expire_tklines(&temporary_dlines);
1598 <  expire_tklines(&temporary_xlines);
2217 <  expire_tklines(&temporary_rxlines);
2218 <  expire_tklines(&temporary_rklines);
2219 <  expire_tklines(&temporary_resv);
1595 >  hostmask_expire_temporary();
1596 >  expire_tklines(&xconf_items);
1597 >  expire_tklines(&nresv_items);
1598 >  expire_tklines(&resv_channel_list);
1599   }
1600  
1601   /* expire_tklines()
# Line 2230 | Line 1609 | expire_tklines(dlink_list *tklist)
1609   {
1610    dlink_node *ptr;
1611    dlink_node *next_ptr;
1612 <  struct ConfItem *conf;
2234 <  struct MatchItem *xconf;
2235 <  struct MatchItem *nconf;
2236 <  struct AccessItem *aconf;
2237 <  struct ResvChannel *cconf;
1612 >  struct MaskItem *conf;
1613  
1614    DLINK_FOREACH_SAFE(ptr, next_ptr, tklist->head)
1615    {
1616      conf = ptr->data;
2242    if (conf->type == GLINE_TYPE ||
2243        conf->type == KLINE_TYPE ||
2244        conf->type == DLINE_TYPE)
2245    {
2246      aconf = (struct AccessItem *)map_to_conf(conf);
2247      if (aconf->hold <= CurrentTime)
2248      {
2249        /* XXX - Do we want GLINE expiry notices?? */
2250        /* Alert opers that a TKline expired - Hwy */
2251        if (ConfigFileEntry.tkline_expire_notices)
2252        {
2253          if (aconf->status & CONF_KILL)
2254          {
2255            sendto_realops_flags(UMODE_ALL, L_ALL,
2256                                 "Temporary K-line for [%s@%s] expired",
2257                                 (aconf->user) ? aconf->user : "*",
2258                                 (aconf->host) ? aconf->host : "*");
2259          }
2260          else if (conf->type == DLINE_TYPE)
2261          {
2262            sendto_realops_flags(UMODE_ALL, L_ALL,
2263                                 "Temporary D-line for [%s] expired",
2264                                 (aconf->host) ? aconf->host : "*");
2265          }
2266        }
1617  
1618 <        dlinkDelete(ptr, tklist);
1619 <        delete_one_address_conf(aconf->host, aconf);
1620 <      }
1621 <    }
2272 <    else if (conf->type == XLINE_TYPE ||
2273 <             conf->type == RXLINE_TYPE)
2274 <    {
2275 <      xconf = (struct MatchItem *)map_to_conf(conf);
2276 <      if (xconf->hold <= CurrentTime)
2277 <      {
2278 <        if (ConfigFileEntry.tkline_expire_notices)
2279 <          sendto_realops_flags(UMODE_ALL, L_ALL,
2280 <                               "Temporary X-line for [%s] %sexpired", conf->name,
2281 <                               conf->type == RXLINE_TYPE ? "(REGEX) " : "");
2282 <        dlinkDelete(ptr, tklist);
2283 <        free_dlink_node(ptr);
2284 <        delete_conf_item(conf);
2285 <      }
2286 <    }
2287 <    else if (conf->type == RKLINE_TYPE)
1618 >    if (!conf->until || conf->until > CurrentTime)
1619 >      continue;
1620 >
1621 >    if (conf->type == CONF_XLINE)
1622      {
1623 <      aconf = map_to_conf(conf);
1624 <      if (aconf->hold <= CurrentTime)
1625 <      {
1626 <        if (ConfigFileEntry.tkline_expire_notices)
2293 <           sendto_realops_flags(UMODE_ALL, L_ALL,
2294 <                                "Temporary K-line for [%s@%s] (REGEX) expired",
2295 <                                (aconf->user) ? aconf->user : "*",
2296 <                                (aconf->host) ? aconf->host : "*");
2297 <        dlinkDelete(ptr, tklist);
2298 <        free_dlink_node(ptr);
2299 <        delete_conf_item(conf);
2300 <      }
1623 >      if (ConfigFileEntry.tkline_expire_notices)
1624 >        sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1625 >                               "Temporary X-line for [%s] expired", conf->name);
1626 >      conf_free(conf);
1627      }
1628 <    else if (conf->type == NRESV_TYPE)
1628 >    else if (conf->type == CONF_NRESV)
1629      {
1630 <      nconf = (struct MatchItem *)map_to_conf(conf);
1631 <      if (nconf->hold <= CurrentTime)
2306 <      {
2307 <        if (ConfigFileEntry.tkline_expire_notices)
2308 <          sendto_realops_flags(UMODE_ALL, L_ALL,
1630 >      if (ConfigFileEntry.tkline_expire_notices)
1631 >        sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1632                                 "Temporary RESV for [%s] expired", conf->name);
1633 <        dlinkDelete(ptr, tklist);
2311 <        free_dlink_node(ptr);
2312 <        delete_conf_item(conf);
2313 <      }
1633 >      conf_free(conf);
1634      }
1635 <    else if (conf->type == CRESV_TYPE)
1635 >    else if (conf->type == CONF_CRESV)
1636      {
1637 <      cconf = (struct ResvChannel *)map_to_conf(conf);
1638 <      if (cconf->hold <= CurrentTime)
1639 <      {
1640 <        if (ConfigFileEntry.tkline_expire_notices)
2321 <          sendto_realops_flags(UMODE_ALL, L_ALL,
2322 <                               "Temporary RESV for [%s] expired", cconf->name);
2323 <        dlinkDelete(ptr, tklist);
2324 <        free_dlink_node(ptr);
2325 <        delete_conf_item(conf);
2326 <      }
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 >      delete_channel_resv(conf);
1641      }
1642    }
1643   }
# Line 2336 | Line 1650 | expire_tklines(dlink_list *tklist)
1650   */
1651   static const struct oper_privs
1652   {
1653 <  const unsigned int oprivs;
2340 <  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 2361 | 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)
2370 <      *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 2383 | 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;
2390 <  struct ConfItem *conf;
2391 <  struct AccessItem *aconf;
2392 <
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;
2401 <      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,
2407 <                   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 2415 | 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 2433 | 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 2443 | 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 2463 | 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("NETWORK", ServerInfo.network_name, -1);
1778 <  ircsprintf(chanmodes, "b%s%s:%d", ConfigChannel.use_except ? "e" : "",
1779 <             ConfigChannel.use_invex ? "I" : "", ConfigChannel.max_bans);
1778 >  snprintf(chanmodes, sizeof(chanmodes), "beI:%d",
1779 >           ConfigChannel.max_bans);
1780    add_isupport("MAXLIST", chanmodes, -1);
1781    add_isupport("MAXTARGETS", NULL, ConfigFileEntry.max_targets);
1782 <  if (ConfigChannel.disable_local_channels)
1783 <    add_isupport("CHANTYPES", "#", -1);
1784 <  else
1785 <    add_isupport("CHANTYPES", "#&", -1);
1786 <  ircsprintf(chanlimit, "%s:%d", ConfigChannel.disable_local_channels ? "#" : "#&",
2479 <             ConfigChannel.max_chans_per_user);
1782 >
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" : "",
1789 <             ConfigChannel.use_invex ? "I" : "", "b,k,l,imnpst");
1788 >  snprintf(chanmodes, sizeof(chanmodes), "%s",
1789 >           "beI,k,l,imnprstORS");
1790    add_isupport("CHANNELLEN", NULL, LOCAL_CHANNELLEN);
1791 <  if (ConfigChannel.use_except)
1792 <    add_isupport("EXCEPTS", "e", -1);
1793 <  if (ConfigChannel.use_invex)
2487 <    add_isupport("INVEX", "I", -1);
1791 >
1792 >  add_isupport("EXCEPTS", "e", -1);
1793 >  add_isupport("INVEX", "I", -1);
1794    add_isupport("CHANMODES", chanmodes, -1);
1795  
1796    /*
# Line 2492 | Line 1798 | read_conf_files(int cold)
1798     * on strlen(form_str(RPL_ISUPPORT))
1799     */
1800    rebuild_isupport_message_line();
2495
2496  parse_conf_file(KLINE_TYPE, cold);
2497  parse_conf_file(RKLINE_TYPE, cold);
2498  parse_conf_file(DLINE_TYPE, cold);
2499  parse_conf_file(XLINE_TYPE, cold);
2500  parse_conf_file(RXLINE_TYPE, cold);
2501  parse_conf_file(NRESV_TYPE, cold);
2502  parse_conf_file(CRESV_TYPE, cold);
2503 }
2504
2505 /* parse_conf_file()
2506 *
2507 * inputs       - type of conf file to parse
2508 * output       - none
2509 * side effects - conf file for givenconf type is opened and read then parsed
2510 */
2511 static void
2512 parse_conf_file(int type, int cold)
2513 {
2514  FBFILE *file = NULL;
2515  const char *filename = get_conf_name(type);
2516
2517  if ((file = fbopen(filename, "r")) == NULL)
2518  {
2519    if (cold)
2520      ilog(L_ERROR, "Unable to read configuration file '%s': %s",
2521           filename, strerror(errno));
2522    else
2523      sendto_realops_flags(UMODE_ALL, L_ALL,
2524                    "Unable to read configuration file '%s': %s",
2525                           filename, strerror(errno));
2526  }
2527  else
2528  {
2529    parse_csv_file(file, type);
2530    fbclose(file);
2531  }
1801   }
1802  
1803   /* clear_out_old_conf()
# Line 2541 | Line 1810 | static void
1810   clear_out_old_conf(void)
1811   {
1812    dlink_node *ptr = NULL, *next_ptr = NULL;
1813 <  struct ConfItem *conf;
2545 <  struct AccessItem *aconf;
2546 <  struct ClassItem *cltmp;
2547 <  struct MatchItem *match_item;
1813 >  struct MaskItem *conf;
1814    dlink_list *free_items [] = {
1815 <    &server_items,   &oconf_items,    &hub_items, &leaf_items,
1815 >    &server_items,   &oconf_items,
1816       &uconf_items,   &xconf_items, &rxconf_items, &rkconf_items,
1817 <     &nresv_items, &cluster_items,  &gdeny_items, NULL
1817 >     &nresv_items, &cluster_items,  &service_items, NULL
1818    };
1819  
1820    dlink_list ** iterator = free_items; /* C is dumb */
# Line 2562 | Line 1828 | clear_out_old_conf(void)
1828      DLINK_FOREACH_SAFE(ptr, next_ptr, (*iterator)->head)
1829      {
1830        conf = ptr->data;
2565      /* XXX This is less than pretty */
2566      if (conf->type == SERVER_TYPE)
2567      {
2568        aconf = map_to_conf(conf);
1831  
1832 <        if (aconf->clients != 0)
2571 <        {
2572 <          SetConfIllegal(aconf);
2573 <          dlinkDelete(&conf->node, &server_items);
2574 <        }
2575 <        else
2576 <        {
2577 <          delete_conf_item(conf);
2578 <        }
2579 <      }
2580 <      else if (conf->type == OPER_TYPE)
2581 <      {
2582 <        aconf = map_to_conf(conf);
1832 >      dlinkDelete(&conf->node, map_to_list(conf->type));
1833  
1834 <        if (aconf->clients != 0)
1835 <        {
2586 <          SetConfIllegal(aconf);
2587 <          dlinkDelete(&conf->node, &oconf_items);
2588 <        }
2589 <        else
2590 <        {
2591 <          delete_conf_item(conf);
2592 <        }
2593 <      }
2594 <      else if (conf->type == CLIENT_TYPE)
1834 >      /* XXX This is less than pretty */
1835 >      if (conf->type == CONF_SERVER || conf->type == CONF_OPER)
1836        {
1837 <        aconf = map_to_conf(conf);
1838 <
2598 <        if (aconf->clients != 0)
2599 <        {
2600 <          SetConfIllegal(aconf);
2601 <        }
2602 <        else
2603 <        {
2604 <          delete_conf_item(conf);
2605 <        }
1837 >        if (!conf->ref_count)
1838 >          conf_free(conf);
1839        }
1840 <      else if (conf->type == XLINE_TYPE  ||
1841 <               conf->type == RXLINE_TYPE ||
1842 <               conf->type == RKLINE_TYPE)
1840 >      else if (conf->type == CONF_XLINE  ||
1841 >               conf->type == CONF_RXLINE ||
1842 >               conf->type == CONF_RKLINE)
1843        {
1844 <        /* temporary (r)xlines are also on
1845 <         * the (r)xconf items list */
2613 <        if (conf->flags & CONF_FLAGS_TEMPORARY)
2614 <          continue;
2615 <
2616 <        delete_conf_item(conf);
1844 >        if (!conf->until)
1845 >          conf_free(conf);
1846        }
1847        else
1848 <      {
2620 <        if ((conf->type == LEAF_TYPE) || (conf->type == HUB_TYPE))
2621 <        {
2622 <          match_item = map_to_conf(conf);
2623 <          if (match_item->ref_count <= 0)
2624 <            delete_conf_item(conf);
2625 <          else
2626 <          {
2627 <            match_item->illegal = 1;
2628 <            dlinkDelete(&conf->node, *iterator);
2629 <          }
2630 <        }
2631 <        else
2632 <          delete_conf_item(conf);
2633 <      }
1848 >        conf_free(conf);
1849      }
1850    }
1851  
1852    /*
1853     * don't delete the class table, rather mark all entries
1854 <   * for deletion. The table is cleaned up by check_class. - avalon
1854 >   * for deletion. The table is cleaned up by class_delete_marked. - avalon
1855     */
1856 <  DLINK_FOREACH(ptr, class_items.head)
2642 <  {
2643 <    cltmp = map_to_conf(ptr->data);
2644 <
2645 <    if (ptr != class_items.tail)  /* never mark the "default" class */
2646 <      cltmp->active = 0;
2647 <  }
1856 >  class_mark_for_deletion();
1857  
1858    clear_out_address_conf();
1859  
1860    /* clean out module paths */
2652 #ifndef STATIC_MODULES
1861    mod_clear_paths();
2654 #endif
1862  
1863    /* clean out ServerInfo */
1864    MyFree(ServerInfo.description);
# Line 2671 | Line 1878 | clear_out_old_conf(void)
1878  
1879    MyFree(ServerInfo.rsa_private_key_file);
1880    ServerInfo.rsa_private_key_file = NULL;
1881 +
1882 +  if (ServerInfo.server_ctx)
1883 +    SSL_CTX_set_options(ServerInfo.server_ctx, SSL_OP_NO_SSLv2|
1884 +                                               SSL_OP_NO_SSLv3|
1885 +                                               SSL_OP_NO_TLSv1);
1886 +  if (ServerInfo.client_ctx)
1887 +    SSL_CTX_set_options(ServerInfo.client_ctx, SSL_OP_NO_SSLv2|
1888 +                                               SSL_OP_NO_SSLv3|
1889 +                                               SSL_OP_NO_TLSv1);
1890   #endif
1891  
1892    /* clean out old resvs from the conf */
# Line 2684 | Line 1900 | clear_out_old_conf(void)
1900    MyFree(AdminInfo.description);
1901    AdminInfo.description = NULL;
1902  
2687  /* operator{} and class{} blocks are freed above */
1903    /* clean out listeners */
1904    close_listeners();
1905  
2691  /* auth{}, quarantine{}, shared{}, connect{}, kill{}, deny{},
2692   * exempt{} and gecos{} blocks are freed above too
2693   */
2694
1906    /* clean out general */
1907 <  MyFree(ConfigFileEntry.servlink_path);
1908 <  ConfigFileEntry.servlink_path = NULL;
1909 < #ifdef HAVE_LIBCRYPTO
2699 <  ConfigFileEntry.default_cipher_preference = NULL;
2700 < #endif /* HAVE_LIBCRYPTO */
1907 >  MyFree(ConfigFileEntry.service_name);
1908 >  ConfigFileEntry.service_name = NULL;
1909 >
1910    delete_isupport("INVEX");
1911    delete_isupport("EXCEPTS");
1912   }
1913  
2705 /* flush_deleted_I_P()
2706 *
2707 * inputs       - none
2708 * output       - none
2709 * side effects - This function removes I/P conf items
2710 */
2711 static void
2712 flush_deleted_I_P(void)
2713 {
2714  dlink_node *ptr;
2715  dlink_node *next_ptr;
2716  struct ConfItem *conf;
2717  struct AccessItem *aconf;
2718  dlink_list * free_items [] = {
2719    &server_items, &oconf_items, NULL
2720  };
2721  dlink_list ** iterator = free_items; /* C is dumb */
2722
2723  /* flush out deleted I and P lines
2724   * although still in use.
2725   */
2726  for (; *iterator != NULL; iterator++)
2727  {
2728    DLINK_FOREACH_SAFE(ptr, next_ptr, (*iterator)->head)
2729    {
2730      conf = ptr->data;
2731      aconf = (struct AccessItem *)map_to_conf(conf);
2732
2733      if (IsConfIllegal(aconf))
2734      {
2735        dlinkDelete(ptr, *iterator);
2736
2737        if (aconf->clients == 0)
2738          delete_conf_item(conf);
2739      }
2740    }
2741  }
2742 }
2743
2744 /* get_conf_name()
2745 *
2746 * inputs       - type of conf file to return name of file for
2747 * output       - pointer to filename for type of conf
2748 * side effects - none
2749 */
2750 const char *
2751 get_conf_name(ConfType type)
2752 {
2753  switch (type)
2754  {
2755    case CONF_TYPE:
2756      return ConfigFileEntry.configfile;
2757      break;
2758    case KLINE_TYPE:
2759      return ConfigFileEntry.klinefile;
2760      break;
2761    case RKLINE_TYPE:
2762      return ConfigFileEntry.rklinefile;
2763      break;
2764    case DLINE_TYPE:
2765      return ConfigFileEntry.dlinefile;
2766      break;
2767    case XLINE_TYPE:
2768      return ConfigFileEntry.xlinefile;
2769      break;
2770    case RXLINE_TYPE:
2771      return ConfigFileEntry.rxlinefile;
2772      break;
2773    case CRESV_TYPE:
2774      return ConfigFileEntry.cresvfile;
2775      break;
2776    case NRESV_TYPE:
2777      return ConfigFileEntry.nresvfile;
2778      break;
2779    case GLINE_TYPE:
2780      return ConfigFileEntry.glinefile;
2781      break;
2782
2783    default:
2784      return NULL;  /* This should NEVER HAPPEN since we call this function
2785                       only with the above values, this will cause us to core
2786                       at some point if this happens so we know where it was */
2787  }
2788 }
2789
2790 #define BAD_PING (-1)
2791
2792 /* get_conf_ping()
2793 *
2794 * inputs       - pointer to struct AccessItem
2795 *              - pointer to a variable that receives ping warning time
2796 * output       - ping frequency
2797 * side effects - NONE
2798 */
2799 static int
2800 get_conf_ping(struct ConfItem *conf, int *pingwarn)
2801 {
2802  struct ClassItem *aclass;
2803  struct AccessItem *aconf;
2804
2805  if (conf != NULL)
2806  {
2807    aconf = (struct AccessItem *)map_to_conf(conf);
2808    if (aconf->class_ptr != NULL)
2809    {
2810      aclass = (struct ClassItem *)map_to_conf(aconf->class_ptr);
2811      *pingwarn = PingWarning(aclass);
2812      return PingFreq(aclass);
2813    }
2814  }
2815
2816  return BAD_PING;
2817 }
2818
2819 /* get_client_class()
2820 *
2821 * inputs       - pointer to client struct
2822 * output       - pointer to name of class
2823 * side effects - NONE
2824 */
2825 const char *
2826 get_client_class(struct Client *target_p)
2827 {
2828  dlink_node *ptr;
2829  struct ConfItem *conf;
2830  struct AccessItem *aconf;
2831
2832  if (target_p != NULL && !IsMe(target_p) &&
2833      target_p->localClient->confs.head != NULL)
2834  {
2835    DLINK_FOREACH(ptr, target_p->localClient->confs.head)
2836    {
2837      conf = ptr->data;
2838
2839      if (conf->type == CLIENT_TYPE || conf->type == SERVER_TYPE ||
2840          conf->type == OPER_TYPE)
2841      {
2842        aconf = (struct AccessItem *) map_to_conf(conf);
2843        if (aconf->class_ptr != NULL)
2844          return aconf->class_ptr->name;
2845      }
2846    }
2847  }
2848
2849  return "default";
2850 }
2851
2852 /* get_client_ping()
2853 *
2854 * inputs       - pointer to client struct
2855 *              - pointer to a variable that receives ping warning time
2856 * output       - ping frequency
2857 * side effects - NONE
2858 */
2859 int
2860 get_client_ping(struct Client *target_p, int *pingwarn)
2861 {
2862  int ping;
2863  struct ConfItem *conf;
2864  dlink_node *nlink;
2865
2866  if (target_p->localClient->confs.head != NULL)
2867    DLINK_FOREACH(nlink, target_p->localClient->confs.head)
2868    {
2869      conf = nlink->data;
2870
2871      if ((conf->type == CLIENT_TYPE) || (conf->type == SERVER_TYPE) ||
2872          (conf->type == OPER_TYPE))
2873      {
2874        ping = get_conf_ping(conf, pingwarn);
2875        if (ping > 0)
2876          return ping;
2877      }
2878    }
2879
2880  *pingwarn = 0;
2881  return DEFAULT_PINGFREQUENCY;
2882 }
2883
2884 /* find_class()
2885 *
2886 * inputs       - string name of class
2887 * output       - corresponding Class pointer
2888 * side effects - NONE
2889 */
2890 struct ConfItem *
2891 find_class(const char *classname)
2892 {
2893  struct ConfItem *conf;
2894
2895  if ((conf = find_exact_name_conf(CLASS_TYPE, classname, NULL, NULL)) != NULL)
2896    return conf;
2897
2898  return class_default;
2899 }
2900
2901 /* check_class()
2902 *
2903 * inputs       - NONE
2904 * output       - NONE
2905 * side effects -
2906 */
2907 void
2908 check_class(void)
2909 {
2910  dlink_node *ptr = NULL, *next_ptr = NULL;
2911
2912  DLINK_FOREACH_SAFE(ptr, next_ptr, class_items.head)
2913  {
2914    struct ClassItem *aclass = map_to_conf(ptr->data);
2915
2916    if (!aclass->active && !CurrUserCount(aclass))
2917    {
2918      destroy_cidr_class(aclass);
2919      delete_conf_item(ptr->data);
2920    }
2921  }
2922 }
2923
2924 /* init_class()
2925 *
2926 * inputs       - NONE
2927 * output       - NONE
2928 * side effects -
2929 */
2930 void
2931 init_class(void)
2932 {
2933  struct ClassItem *aclass;
2934
2935  class_default = make_conf_item(CLASS_TYPE);
2936
2937  aclass = map_to_conf(class_default);
2938  aclass->active = 1;
2939  DupString(class_default->name, "default");
2940  ConFreq(aclass)  = DEFAULT_CONNECTFREQUENCY;
2941  PingFreq(aclass) = DEFAULT_PINGFREQUENCY;
2942  MaxTotal(aclass) = MAXIMUM_LINKS_DEFAULT;
2943  MaxSendq(aclass) = DEFAULT_SENDQ;
2944
2945  client_check_cb = register_callback("check_client", check_client);
2946 }
2947
2948 /* get_sendq()
2949 *
2950 * inputs       - pointer to client
2951 * output       - sendq for this client as found from its class
2952 * side effects - NONE
2953 */
2954 unsigned long
2955 get_sendq(struct Client *client_p)
2956 {
2957  unsigned long sendq = DEFAULT_SENDQ;
2958  dlink_node *ptr;
2959  struct ConfItem *conf;
2960  struct ConfItem *class_conf;
2961  struct ClassItem *aclass;
2962  struct AccessItem *aconf;
2963
2964  if (client_p && !IsMe(client_p) && (client_p->localClient->confs.head))
2965  {
2966    DLINK_FOREACH(ptr, client_p->localClient->confs.head)
2967    {
2968      conf = ptr->data;
2969      if ((conf->type == SERVER_TYPE) || (conf->type == OPER_TYPE)
2970          || (conf->type == CLIENT_TYPE))
2971      {
2972        aconf = (struct AccessItem *)map_to_conf(conf);
2973        if ((class_conf = aconf->class_ptr) == NULL)
2974          continue;
2975        aclass = (struct ClassItem *)map_to_conf(class_conf);
2976        sendq = MaxSendq(aclass);
2977        return sendq;
2978      }
2979    }
2980  }
2981  /* XXX return a default?
2982   * if here, then there wasn't an attached conf with a sendq
2983   * that is very bad -Dianora
2984   */
2985  return DEFAULT_SENDQ;
2986 }
2987
1914   /* conf_add_class_to_conf()
1915   *
1916   * inputs       - pointer to config item
# Line 2992 | Line 1918 | get_sendq(struct Client *client_p)
1918   * side effects - Add a class pointer to a conf
1919   */
1920   void
1921 < conf_add_class_to_conf(struct ConfItem *conf, const char *class_name)
1921 > conf_add_class_to_conf(struct MaskItem *conf, const char *class_name)
1922   {
2997  struct AccessItem *aconf = map_to_conf(conf);
1923    struct ClassItem *class = NULL;
1924  
1925    if (class_name == NULL)
1926    {
1927 <    aconf->class_ptr = class_default;
1927 >    conf->class = class_default;
1928  
1929 <    if (conf->type == CLIENT_TYPE)
1930 <      sendto_realops_flags(UMODE_ALL, L_ALL,
1929 >    if (conf->type == CONF_CLIENT)
1930 >      sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1931                             "Warning *** Defaulting to default class for %s@%s",
1932 <                           aconf->user, aconf->host);
1932 >                           conf->user, conf->host);
1933      else
1934 <      sendto_realops_flags(UMODE_ALL, L_ALL,
1934 >      sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1935                             "Warning *** Defaulting to default class for %s",
1936                             conf->name);
1937    }
1938    else
1939 <    aconf->class_ptr = find_class(class_name);
3015 <
3016 <  if (aconf->class_ptr)
3017 <    class = map_to_conf(aconf->class_ptr);
1939 >    conf->class = class_find(class_name, 1);
1940  
1941 <  if (aconf->class_ptr == NULL || !class->active)
1941 >  if (conf->class == NULL)
1942    {
1943 <    if (conf->type == CLIENT_TYPE)
1944 <      sendto_realops_flags(UMODE_ALL, L_ALL,
1943 >    if (conf->type == CONF_CLIENT)
1944 >      sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1945                             "Warning *** Defaulting to default class for %s@%s",
1946 <                           aconf->user, aconf->host);
1946 >                           conf->user, conf->host);
1947      else
1948 <      sendto_realops_flags(UMODE_ALL, L_ALL,
1948 >      sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1949                             "Warning *** Defaulting to default class for %s",
1950                             conf->name);
1951 <    aconf->class_ptr = class_default;
3030 <  }
3031 < }
3032 <
3033 < /* conf_add_server()
3034 < *
3035 < * inputs       - pointer to config item
3036 < *              - pointer to link count already on this conf
3037 < * output       - NONE
3038 < * side effects - Add a connect block
3039 < */
3040 < int
3041 < conf_add_server(struct ConfItem *conf, const char *class_name)
3042 < {
3043 <  struct AccessItem *aconf;
3044 <  struct split_nuh_item nuh;
3045 <  char conf_user[USERLEN + 1];
3046 <  char conf_host[HOSTLEN + 1];
3047 <
3048 <  aconf = map_to_conf(conf);
3049 <
3050 <  conf_add_class_to_conf(conf, class_name);
3051 <
3052 <  if (!aconf->host || !conf->name)
3053 <  {
3054 <    sendto_realops_flags(UMODE_ALL, L_ALL, "Bad connect block");
3055 <    ilog(L_WARN, "Bad connect block");
3056 <    return -1;
3057 <  }
3058 <
3059 <  if (EmptyString(aconf->passwd) && !IsConfCryptLink(aconf))
3060 <  {
3061 <    sendto_realops_flags(UMODE_ALL, L_ALL, "Bad connect block, name %s",
3062 <                         conf->name);
3063 <    ilog(L_WARN, "Bad connect block, host %s", conf->name);
3064 <    return -1;
3065 <  }
3066 <
3067 <  nuh.nuhmask  = aconf->host;
3068 <  nuh.nickptr  = NULL;
3069 <  nuh.userptr  = conf_user;
3070 <  nuh.hostptr  = conf_host;
3071 <
3072 <  nuh.nicksize = 0;
3073 <  nuh.usersize = sizeof(conf_user);
3074 <  nuh.hostsize = sizeof(conf_host);
3075 <
3076 <  split_nuh(&nuh);
3077 <
3078 <  MyFree(aconf->host);
3079 <  aconf->host = NULL;
3080 <
3081 <  DupString(aconf->user, conf_user); /* somehow username checking for servers
3082 <                                 got lost in H6/7, will have to be re-added */
3083 <  DupString(aconf->host, conf_host);
3084 <
3085 <  lookup_confhost(conf);
3086 <
3087 <  return 0;
3088 < }
3089 <
3090 < /* conf_add_d_conf()
3091 < *
3092 < * inputs       - pointer to config item
3093 < * output       - NONE
3094 < * side effects - Add a d/D line
3095 < */
3096 < void
3097 < conf_add_d_conf(struct AccessItem *aconf)
3098 < {
3099 <  if (aconf->host == NULL)
3100 <    return;
3101 <
3102 <  aconf->user = NULL;
3103 <
3104 <  /* XXX - Should 'd' ever be in the old conf? For new conf we don't
3105 <   *       need this anyway, so I will disable it for now... -A1kmm
3106 <   */
3107 <  if (parse_netmask(aconf->host, NULL, NULL) == HM_HOST)
3108 <  {
3109 <    ilog(L_WARN, "Invalid Dline %s ignored", aconf->host);
3110 <    free_access_item(aconf);
3111 <  }
3112 <  else
3113 <  {
3114 <    /* XXX ensure user is NULL */
3115 <    MyFree(aconf->user);
3116 <    aconf->user = NULL;
3117 <    add_conf_by_address(CONF_DLINE, aconf);
1951 >    conf->class = class_default;
1952    }
1953   }
1954  
# Line 3129 | Line 1963 | yyerror(const char *msg)
1963   {
1964    char newlinebuf[IRCD_BUFSIZE];
1965  
1966 <  if (ypass != 1)
1966 >  if (conf_parser_ctx.pass != 1)
1967      return;
1968  
1969    strip_tabs(newlinebuf, linebuf, sizeof(newlinebuf));
1970 <  sendto_realops_flags(UMODE_ALL, L_ALL, "\"%s\", line %u: %s: %s",
1970 >  sendto_realops_flags(UMODE_ALL, L_ALL,  SEND_NOTICE,
1971 >                       "\"%s\", line %u: %s: %s",
1972                         conffilebuf, lineno + 1, msg, newlinebuf);
1973 <  ilog(L_WARN, "\"%s\", line %u: %s: %s",
1973 >  ilog(LOG_TYPE_IRCD, "\"%s\", line %u: %s: %s",
1974         conffilebuf, lineno + 1, msg, newlinebuf);
1975   }
1976  
3142 int
3143 conf_fbgets(char *lbuf, unsigned int max_size, FBFILE *fb)
3144 {
3145  if (fbgets(lbuf, max_size, fb) == NULL)
3146    return 0;
3147
3148  return strlen(lbuf);
3149 }
3150
3151 int
3152 conf_yy_fatal_error(const char *msg)
3153 {
3154  return 0;
3155 }
3156
1977   /*
1978   * valid_tkline()
1979   *
# Line 3165 | Line 1985 | conf_yy_fatal_error(const char *msg)
1985   * Originally written by Dianora (Diane, db@db.net)
1986   */
1987   time_t
1988 < valid_tkline(char *p, int minutes)
1988 > valid_tkline(const char *p, int minutes)
1989   {
1990    time_t result = 0;
1991  
1992 <  while (*p)
1992 >  for (; *p; ++p)
1993    {
1994 <    if (IsDigit(*p))
3175 <    {
3176 <      result *= 10;
3177 <      result += ((*p) & 0xF);
3178 <      p++;
3179 <    }
3180 <    else
1994 >    if (!IsDigit(*p))
1995        return 0;
1996 +
1997 +    result *= 10;
1998 +    result += ((*p) & 0xF);
1999    }
2000  
2001 <  /* in the degenerate case where oper does a /quote kline 0 user@host :reason
2001 >  /*
2002 >   * In the degenerate case where oper does a /quote kline 0 user@host :reason
2003     * i.e. they specifically use 0, I am going to return 1 instead
2004     * as a return value of non-zero is used to flag it as a temporary kline
2005     */
3188
2006    if (result == 0)
2007      result = 1;
2008  
# Line 3286 | Line 2103 | valid_wild_card(struct Client *source_p,
2103   *                if target_server is NULL and an "ON" is found error
2104   *                is reported.
2105   *                if reason pointer is NULL ignore pointer,
2106 < *                this allows usee of parse_a_line in unkline etc.
2106 > *                this allows use of parse_a_line in unkline etc.
2107   *
2108   * - Dianora
2109   */
# Line 3356 | Line 2173 | parse_aline(const char *cmd, struct Clie
2173          return -1;
2174        }
2175  
2176 <      if (!IsOperRemoteBan(source_p))
2176 >      if (!HasOFlag(source_p, OPER_FLAG_REMOTEBAN))
2177        {
2178          sendto_one(source_p, form_str(ERR_NOPRIVS),
2179                     me.name, source_p->name, "remoteban");
# Line 3393 | Line 2210 | parse_aline(const char *cmd, struct Clie
2210        return -1;
2211      }
2212  
2213 <    if ((parse_flags & AWILD) && !valid_wild_card(source_p, YES, 2, *up_p, *h_p))
2213 >    if ((parse_flags & AWILD) && !valid_wild_card(source_p, 1, 2, *up_p, *h_p))
2214        return -1;
2215    }
2216    else
2217 <    if ((parse_flags & AWILD) && !valid_wild_card(source_p, YES, 1, *up_p))
2217 >    if ((parse_flags & AWILD) && !valid_wild_card(source_p, 1, 1, *up_p))
2218        return -1;
2219  
2220    if (reason != NULL)
2221    {
2222 <    if (parc != 0)
2222 >    if (parc != 0 && !EmptyString(*parv))
2223      {
2224        *reason = *parv;
2225 <      if (!valid_comment(source_p, *reason, YES))
2225 >      if (!valid_comment(source_p, *reason, 1))
2226          return -1;
2227      }
2228      else
# Line 3462 | Line 2279 | find_user_host(struct Client *source_p,
2279      
2280      return 1;
2281    }
2282 <  else if (!(flags & NOUSERLOOKUP))
2282 >  else
2283    {
2284      /* Try to find user@host mask from nick */
2285      /* Okay to use source_p as the first param, because source_p == client_p */
# Line 3510 | Line 2327 | find_user_host(struct Client *source_p,
2327   int
2328   valid_comment(struct Client *source_p, char *comment, int warn)
2329   {
3513  if (strchr(comment, '"'))
3514  {
3515    if (warn)
3516      sendto_one(source_p, ":%s NOTICE %s :Invalid character '\"' in comment",
3517                 me.name, source_p->name);
3518    return 0;
3519  }
3520
2330    if (strlen(comment) > REASONLEN)
2331      comment[REASONLEN-1] = '\0';
2332  
# Line 3532 | Line 2341 | valid_comment(struct Client *source_p, c
2341   * side effects - none
2342   */
2343   int
2344 < match_conf_password(const char *password, const struct AccessItem *aconf)
2344 > match_conf_password(const char *password, const struct MaskItem *conf)
2345   {
2346    const char *encr = NULL;
2347  
2348 <  if (password == NULL || aconf->passwd == NULL)
2348 >  if (EmptyString(password) || EmptyString(conf->passwd))
2349      return 0;
2350  
2351 <  if (aconf->flags & CONF_FLAGS_ENCRYPTED)
2352 <  {
3544 <    /* use first two chars of the password they send in as salt */
3545 <    /* If the password in the conf is MD5, and ircd is linked
3546 <     * to scrypt on FreeBSD, or the standard crypt library on
3547 <     * glibc Linux, then this code will work fine on generating
3548 <     * the proper encrypted hash for comparison.
3549 <     */
3550 <    if (*aconf->passwd)
3551 <      encr = crypt(password, aconf->passwd);
3552 <    else
3553 <      encr = "";
3554 <  }
2351 >  if (conf->flags & CONF_FLAGS_ENCRYPTED)
2352 >    encr = crypt(password, conf->passwd);
2353    else
2354      encr = password;
2355  
2356 <  return !strcmp(encr, aconf->passwd);
2356 >  return !strcmp(encr, conf->passwd);
2357   }
2358  
2359   /*
# Line 3564 | Line 2362 | match_conf_password(const char *password
2362   * inputs       - client sending the cluster
2363   *              - command name "KLINE" "XLINE" etc.
2364   *              - capab -- CAP_KLN etc. from s_serv.h
2365 < *              - cluster type -- CLUSTER_KLINE etc. from s_conf.h
2365 > *              - cluster type -- CLUSTER_KLINE etc. from conf.h
2366   *              - pattern and args to send along
2367   * output       - none
2368   * side effects - Take source_p send the pattern with args given
# Line 3584 | Line 2382 | cluster_a_line(struct Client *source_p,
2382  
2383    DLINK_FOREACH(ptr, cluster_items.head)
2384    {
2385 <    const struct ConfItem *conf = ptr->data;
2385 >    const struct MaskItem *conf = ptr->data;
2386  
2387      if (conf->flags & cluster_type)
2388        sendto_match_servs(source_p, conf->name, CAP_CLUSTER|capab,
# Line 3678 | Line 2476 | split_nuh(struct split_nuh_item *const i
2476      }
2477    }
2478   }
3681
3682 /*
3683 * flags_to_ascii
3684 *
3685 * inputs       - flags is a bitmask
3686 *              - pointer to table of ascii letters corresponding
3687 *                to each bit
3688 *              - flag 1 for convert ToLower if bit missing
3689 *                0 if ignore.
3690 * output       - none
3691 * side effects - string pointed to by p has bitmap chars written to it
3692 */
3693 static void
3694 flags_to_ascii(unsigned int flags, const unsigned int bit_table[], char *p,
3695               int lowerit)
3696 {
3697  unsigned int mask = 1;
3698  int i = 0;
3699
3700  for (mask = 1; (mask != 0) && (bit_table[i] != 0); mask <<= 1, i++)
3701  {
3702    if (flags & mask)
3703      *p++ = bit_table[i];
3704    else if (lowerit)
3705      *p++ = ToLower(bit_table[i]);
3706  }
3707  *p = '\0';
3708 }
3709
3710 /*
3711 * cidr_limit_reached
3712 *
3713 * inputs       - int flag allowing over_rule of limits
3714 *              - pointer to the ip to be added
3715 *              - pointer to the class
3716 * output       - non zero if limit reached
3717 *                0 if limit not reached
3718 * side effects -
3719 */
3720 static int
3721 cidr_limit_reached(int over_rule,
3722                   struct irc_ssaddr *ip, struct ClassItem *aclass)
3723 {
3724  dlink_node *ptr = NULL;
3725  struct CidrItem *cidr;
3726
3727  if (NumberPerCidr(aclass) <= 0)
3728    return 0;
3729
3730  if (ip->ss.ss_family == AF_INET)
3731  {
3732    if (CidrBitlenIPV4(aclass) <= 0)
3733      return 0;
3734
3735    DLINK_FOREACH(ptr, aclass->list_ipv4.head)
3736    {
3737      cidr = ptr->data;
3738      if (match_ipv4(ip, &cidr->mask, CidrBitlenIPV4(aclass)))
3739      {
3740        if (!over_rule && (cidr->number_on_this_cidr >= NumberPerCidr(aclass)))
3741          return -1;
3742        cidr->number_on_this_cidr++;
3743        return 0;
3744      }
3745    }
3746    cidr = MyMalloc(sizeof(struct CidrItem));
3747    cidr->number_on_this_cidr = 1;
3748    cidr->mask = *ip;
3749    mask_addr(&cidr->mask, CidrBitlenIPV4(aclass));
3750    dlinkAdd(cidr, &cidr->node, &aclass->list_ipv4);
3751  }
3752 #ifdef IPV6
3753  else if (CidrBitlenIPV6(aclass) > 0)
3754  {
3755    DLINK_FOREACH(ptr, aclass->list_ipv6.head)
3756    {
3757      cidr = ptr->data;
3758      if (match_ipv6(ip, &cidr->mask, CidrBitlenIPV6(aclass)))
3759      {
3760        if (!over_rule && (cidr->number_on_this_cidr >= NumberPerCidr(aclass)))
3761          return -1;
3762        cidr->number_on_this_cidr++;
3763        return 0;
3764      }
3765    }
3766    cidr = MyMalloc(sizeof(struct CidrItem));
3767    cidr->number_on_this_cidr = 1;
3768    cidr->mask = *ip;
3769    mask_addr(&cidr->mask, CidrBitlenIPV6(aclass));
3770    dlinkAdd(cidr, &cidr->node, &aclass->list_ipv6);
3771  }
3772 #endif
3773  return 0;
3774 }
3775
3776 /*
3777 * remove_from_cidr_check
3778 *
3779 * inputs       - pointer to the ip to be removed
3780 *              - pointer to the class
3781 * output       - NONE
3782 * side effects -
3783 */
3784 static void
3785 remove_from_cidr_check(struct irc_ssaddr *ip, struct ClassItem *aclass)
3786 {
3787  dlink_node *ptr = NULL;
3788  dlink_node *next_ptr = NULL;
3789  struct CidrItem *cidr;
3790
3791  if (NumberPerCidr(aclass) == 0)
3792    return;
3793
3794  if (ip->ss.ss_family == AF_INET)
3795  {
3796    if (CidrBitlenIPV4(aclass) <= 0)
3797      return;
3798
3799    DLINK_FOREACH_SAFE(ptr, next_ptr, aclass->list_ipv4.head)
3800    {
3801      cidr = ptr->data;
3802      if (match_ipv4(ip, &cidr->mask, CidrBitlenIPV4(aclass)))
3803      {
3804        cidr->number_on_this_cidr--;
3805        if (cidr->number_on_this_cidr == 0)
3806        {
3807          dlinkDelete(ptr, &aclass->list_ipv4);
3808          MyFree(cidr);
3809          return;
3810        }
3811      }
3812    }
3813  }
3814 #ifdef IPV6
3815  else if (CidrBitlenIPV6(aclass) > 0)
3816  {
3817    DLINK_FOREACH_SAFE(ptr, next_ptr, aclass->list_ipv6.head)
3818    {
3819      cidr = ptr->data;
3820      if (match_ipv6(ip, &cidr->mask, CidrBitlenIPV6(aclass)))
3821      {
3822        cidr->number_on_this_cidr--;
3823        if (cidr->number_on_this_cidr == 0)
3824        {
3825          dlinkDelete(ptr, &aclass->list_ipv6);
3826          MyFree(cidr);
3827          return;
3828        }
3829      }
3830    }
3831  }
3832 #endif
3833 }
3834
3835 static void
3836 rebuild_cidr_list(int aftype, struct ConfItem *oldcl, struct ClassItem *newcl,
3837                  dlink_list *old_list, dlink_list *new_list, int changed)
3838 {
3839  dlink_node *ptr;
3840  struct Client *client_p;
3841  struct ConfItem *conf;
3842  struct AccessItem *aconf;
3843
3844  if (!changed)
3845  {
3846    *new_list = *old_list;
3847    old_list->head = old_list->tail = NULL;
3848    old_list->length = 0;
3849    return;
3850  }
3851
3852  DLINK_FOREACH(ptr, local_client_list.head)
3853  {
3854    client_p = ptr->data;
3855    if (client_p->localClient->aftype != aftype)
3856      continue;
3857    if (dlink_list_length(&client_p->localClient->confs) == 0)
3858      continue;
3859
3860    conf = client_p->localClient->confs.tail->data;
3861    if (conf->type == CLIENT_TYPE)
3862    {
3863      aconf = map_to_conf(conf);
3864      if (aconf->class_ptr == oldcl)
3865        cidr_limit_reached(1, &client_p->localClient->ip, newcl);
3866    }
3867  }
3868 }
3869
3870 /*
3871 * rebuild_cidr_class
3872 *
3873 * inputs       - pointer to old conf
3874 *              - pointer to new_class
3875 * output       - none
3876 * side effects - rebuilds the class link list of cidr blocks
3877 */
3878 void
3879 rebuild_cidr_class(struct ConfItem *conf, struct ClassItem *new_class)
3880 {
3881  struct ClassItem *old_class = map_to_conf(conf);
3882
3883  if (NumberPerCidr(old_class) > 0 && NumberPerCidr(new_class) > 0)
3884  {
3885    if (CidrBitlenIPV4(old_class) > 0 && CidrBitlenIPV4(new_class) > 0)
3886      rebuild_cidr_list(AF_INET, conf, new_class,
3887                        &old_class->list_ipv4, &new_class->list_ipv4,
3888                        CidrBitlenIPV4(old_class) != CidrBitlenIPV4(new_class));
3889
3890 #ifdef IPV6
3891    if (CidrBitlenIPV6(old_class) > 0 && CidrBitlenIPV6(new_class) > 0)
3892      rebuild_cidr_list(AF_INET6, conf, new_class,
3893                        &old_class->list_ipv6, &new_class->list_ipv6,
3894                        CidrBitlenIPV6(old_class) != CidrBitlenIPV6(new_class));
3895 #endif
3896  }
3897
3898  destroy_cidr_class(old_class);
3899 }
3900
3901 /*
3902 * destroy_cidr_list
3903 *
3904 * inputs       - pointer to class dlink list of cidr blocks
3905 * output       - none
3906 * side effects - completely destroys the class link list of cidr blocks
3907 */
3908 static void
3909 destroy_cidr_list(dlink_list *list)
3910 {
3911  dlink_node *ptr = NULL, *next_ptr = NULL;
3912
3913  DLINK_FOREACH_SAFE(ptr, next_ptr, list->head)
3914  {
3915    dlinkDelete(ptr, list);
3916    MyFree(ptr->data);
3917  }
3918 }
3919
3920 /*
3921 * destroy_cidr_class
3922 *
3923 * inputs       - pointer to class
3924 * output       - none
3925 * side effects - completely destroys the class link list of cidr blocks
3926 */
3927 static void
3928 destroy_cidr_class(struct ClassItem *aclass)
3929 {
3930  destroy_cidr_list(&aclass->list_ipv4);
3931  destroy_cidr_list(&aclass->list_ipv6);
3932 }

Diff Legend

Removed lines
+ Added lines
< Changed lines (old)
> Changed lines (new)