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 201 by adx, Tue Nov 1 11:41:52 2005 UTC vs.
ircd-hybrid/trunk/src/conf.c (file contents), Revision 1831 by michael, Mon Apr 15 10:57:05 2013 UTC

# Line 1 | Line 1
1   /*
2   *  ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 < *  s_conf.c: Configuration file functions.
3 > *  conf.c: Configuration file functions.
4   *
5   *  Copyright (C) 2002 by the past and present ircd coders, and others.
6   *
# Line 23 | Line 23
23   */
24  
25   #include "stdinc.h"
26 + #include "list.h"
27   #include "ircd_defs.h"
28 < #include "tools.h"
28 < #include "s_conf.h"
28 > #include "conf.h"
29   #include "s_serv.h"
30   #include "resv.h"
31 #include "s_stats.h"
31   #include "channel.h"
32   #include "client.h"
34 #include "common.h"
33   #include "event.h"
36 #include "hash.h"
34   #include "hook.h"
35   #include "irc_string.h"
39 #include "sprintf_irc.h"
36   #include "s_bsd.h"
41 #include "irc_getnameinfo.h"
42 #include "irc_getaddrinfo.h"
37   #include "ircd.h"
44 #include "list.h"
38   #include "listener.h"
39   #include "hostmask.h"
40   #include "modules.h"
41   #include "numeric.h"
42   #include "fdlist.h"
43 < #include "s_log.h"
43 > #include "log.h"
44   #include "send.h"
45   #include "s_gline.h"
53 #include "fileio.h"
46   #include "memory.h"
47 + #include "mempool.h"
48   #include "irc_res.h"
49   #include "userhost.h"
50   #include "s_user.h"
51   #include "channel_mode.h"
52 + #include "parse.h"
53 + #include "s_misc.h"
54 + #include "conf_db.h"
55 + #include "conf_class.h"
56  
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 < unsigned int scount = 0; /* used by yyparse(), etc */
76 < 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 *);
95 < static void set_default_conf(void);
96 < static void validate_conf(void);
97 < static void read_conf(FBFILE *);
79 > static void read_conf(FILE *);
80   static void clear_out_old_conf(void);
99 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);
108 < 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  
111 /*
112 * bit_len
113 */
114 static int cidr_limit_reached(int, struct irc_ssaddr *, struct ClassItem *);
115 static void remove_from_cidr_check(struct irc_ssaddr *, struct ClassItem *);
116 static void destroy_cidr_class(struct ClassItem *);
117
118 static void flags_to_ascii(unsigned int, const unsigned int[], char *, int);
119
120 FBFILE *conf_fbfile_in = NULL;
121
122 /* address of default class conf */
123 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 131 | Line 98 | static struct ConfItem *class_default;
98   struct ip_entry
99   {
100    struct irc_ssaddr ip;
101 <  int count;
101 >  unsigned int count;
102    time_t last_attempt;
103    struct ip_entry *next;
104   };
105  
106   static struct ip_entry *ip_hash_table[IP_HASH_SIZE];
107 < static BlockHeap *ip_entry_heap = NULL;
107 > static mp_pool_t *ip_entry_pool = NULL;
108   static int ip_entries_count = 0;
109  
110  
144 inline void *
145 map_to_conf(struct ConfItem *aconf)
146 {
147  void *conf;
148  conf = (void *)((unsigned long)aconf +
149                  (unsigned long)sizeof(struct ConfItem));
150  return(conf);
151 }
152
153 inline struct ConfItem *
154 unmap_conf_item(void *aconf)
155 {
156  struct ConfItem *conf;
157
158  conf = (struct ConfItem *)((unsigned long)aconf -
159                             (unsigned long)sizeof(struct ConfItem));
160  return(conf);
161 }
162
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 171 | 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;
177 <  struct ConfItem *conf;
124 >  struct MaskItem *conf = vptr;
125  
126 <  MyFree(aconf->dns_query);
180 <  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",
186 <         aconf->host);
187 <    conf = unmap_conf_item(aconf);
188 <    sendto_realops_flags(UMODE_ALL, L_ALL,
189 <                         "Ignoring connect{} block for %s - host not found",
190 <                         conf->name);
191 <    delete_conf_item(conf);
192 <  }
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 199 | 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;
208 <    aconf->dns_query->callback = conf_dns_callback;
209 <    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 < *
215 < * inputs       - type of item
216 < * output       - pointer to new conf entry
217 < * side effects - none
218 < */
219 < struct ConfItem *
220 < 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;
224 <  struct ClassItem *aclass = NULL;
225 <  int status = 0;
153 >  struct MaskItem *conf = MyMalloc(sizeof(*conf));
154 >  dlink_list *list = NULL;
155  
156 <  switch (type)
157 <  {
158 <  case DLINE_TYPE:
230 <  case EXEMPTDLINE_TYPE:
231 <  case GLINE_TYPE:
232 <  case KLINE_TYPE:
233 <  case CLIENT_TYPE:
234 <  case OPER_TYPE:
235 <  case SERVER_TYPE:
236 <    conf = MyMalloc(sizeof(struct ConfItem) +
237 <                    sizeof(struct AccessItem));
238 <    aconf = map_to_conf(conf);
239 <    aconf->aftype = AF_INET;
156 >  conf->type   = type;
157 >  conf->active = 1;
158 >  conf->aftype = AF_INET;
159  
160 <    /* Yes, sigh. switch on type again */
161 <    switch (type)
162 <    {
244 <    case EXEMPTDLINE_TYPE:
245 <      status = CONF_EXEMPTDLINE;
246 <      break;
247 <
248 <    case DLINE_TYPE:
249 <      status = CONF_DLINE;
250 <      break;
251 <
252 <    case KLINE_TYPE:
253 <      status = CONF_KLINE;
254 <      break;
255 <
256 <    case GLINE_TYPE:
257 <      status = CONF_GLINE;
258 <      break;
259 <
260 <    case CLIENT_TYPE:
261 <      status = CONF_CLIENT;
262 <      break;
263 <
264 <    case OPER_TYPE:
265 <      status = CONF_OPERATOR;
266 <      dlinkAdd(conf, &conf->node, &oconf_items);
267 <      break;
268 <
269 <    case SERVER_TYPE:
270 <      status = CONF_SERVER;
271 <      dlinkAdd(conf, &conf->node, &server_items);
272 <      break;
273 <
274 <    default:
275 <      break;
276 <    }
277 <    aconf->status = status;
278 <    break;
279 <
280 <  case LEAF_TYPE:
281 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
282 <                                       sizeof(struct MatchItem));
283 <    dlinkAdd(conf, &conf->node, &leaf_items);
284 <    break;
285 <
286 <  case HUB_TYPE:
287 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
288 <                                       sizeof(struct MatchItem));
289 <    dlinkAdd(conf, &conf->node, &hub_items);
290 <    break;
291 <
292 <  case ULINE_TYPE:
293 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
294 <                                       sizeof(struct MatchItem));
295 <    dlinkAdd(conf, &conf->node, &uconf_items);
296 <    break;
297 <
298 <  case GDENY_TYPE:
299 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
300 <                                       sizeof(struct AccessItem));
301 <    dlinkAdd(conf, &conf->node, &gdeny_items);
302 <    break;
303 <
304 <  case XLINE_TYPE:
305 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
306 <                                       sizeof(struct MatchItem));
307 <    dlinkAdd(conf, &conf->node, &xconf_items);
308 <    break;
309 <
310 <  case RXLINE_TYPE:
311 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
312 <                                       sizeof(struct MatchItem));
313 <    dlinkAdd(conf, &conf->node, &rxconf_items);
314 <    break;
315 <
316 <  case RKLINE_TYPE:
317 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
318 <                                       sizeof(struct AccessItem));
319 <    aconf = map_to_conf(conf);
320 <    aconf->status = CONF_KLINE;
321 <    dlinkAdd(conf, &conf->node, &rkconf_items);
322 <    break;
323 <
324 <  case CLUSTER_TYPE:
325 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem));
326 <    dlinkAdd(conf, &conf->node, &cluster_items);
327 <    break;
328 <
329 <  case CRESV_TYPE:
330 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
331 <                                       sizeof(struct ResvChannel));
332 <    break;
333 <
334 <  case NRESV_TYPE:
335 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
336 <                                       sizeof(struct MatchItem));
337 <    dlinkAdd(conf, &conf->node, &nresv_items);
338 <    break;
339 <
340 <  case CLASS_TYPE:
341 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
342 <                                       sizeof(struct ClassItem));
343 <    dlinkAdd(conf, &conf->node, &class_items);
344 <    aclass = (struct ClassItem *)map_to_conf(conf);
345 <    ConFreq(aclass)  = DEFAULT_CONNECTFREQUENCY;
346 <    PingFreq(aclass) = DEFAULT_PINGFREQUENCY;
347 <    MaxTotal(aclass) = MAXIMUM_LINKS_DEFAULT;
348 <    MaxSendq(aclass) = DEFAULT_SENDQ;
349 <    CurrUserCount(aclass) = 0;
350 <    break;
351 <
352 <  default:
353 <    conf = NULL;
354 <    break;
355 <  }
356 <
357 <  /* XXX Yes, this will core if default is hit. I want it to for now - db */
358 <  conf->type = type;
359 <
360 <  return(conf);
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 <  struct MatchItem *match_item;
169 <  struct AccessItem *aconf;
170 <  ConfType type = conf->type;
168 >  dlink_node *ptr = NULL, *ptr_next = NULL;
169 >  dlink_list *list = NULL;
170 >
171 >  if (conf->node.next)
172 >    if ((list = map_to_list(conf->type)))
173 >      dlinkDelete(&conf->node, list);
174  
175    MyFree(conf->name);
371  conf->name = NULL;
176  
177 <  switch(type)
178 <  {
179 <  case DLINE_TYPE:
180 <  case EXEMPTDLINE_TYPE:
181 <  case GLINE_TYPE:
182 <  case KLINE_TYPE:
183 <  case CLIENT_TYPE:
184 <  case OPER_TYPE:
185 <  case SERVER_TYPE:
186 <    aconf = map_to_conf(conf);
187 <
188 <    if (aconf->dns_query != NULL)
189 <    {
190 <      delete_resolver_queries(aconf->dns_query);
191 <      MyFree(aconf->dns_query);
192 <    }
389 <    if (aconf->passwd != NULL)
390 <      memset(aconf->passwd, 0, strlen(aconf->passwd));
391 <    if (aconf->spasswd != NULL)
392 <      memset(aconf->spasswd, 0, strlen(aconf->spasswd));
393 <    aconf->class_ptr = NULL;
394 <
395 <    MyFree(aconf->passwd);
396 <    MyFree(aconf->spasswd);
397 <    MyFree(aconf->reason);
398 <    MyFree(aconf->oper_reason);
399 <    MyFree(aconf->user);
400 <    MyFree(aconf->host);
401 <    MyFree(aconf->fakename);
177 >  if (conf->dns_pending)
178 >    delete_resolver_queries(conf);
179 >  if (conf->passwd != NULL)
180 >    memset(conf->passwd, 0, strlen(conf->passwd));
181 >  if (conf->spasswd != NULL)
182 >    memset(conf->spasswd, 0, strlen(conf->spasswd));
183 >
184 >  conf->class = NULL;
185 >
186 >  MyFree(conf->passwd);
187 >  MyFree(conf->spasswd);
188 >  MyFree(conf->reason);
189 >  MyFree(conf->user);
190 >  MyFree(conf->host);
191 >  MyFree(conf->regexuser);
192 >  MyFree(conf->regexhost);
193   #ifdef HAVE_LIBCRYPTO
194 <    if (aconf->rsa_public_key)
404 <      RSA_free(aconf->rsa_public_key);
405 <    MyFree(aconf->rsa_public_key_file);
406 < #endif
194 >  MyFree(conf->cipher_list);
195  
196 <    /* Yes, sigh. switch on type again */
197 <    switch(type)
198 <    {
199 <    case EXEMPTDLINE_TYPE:
200 <    case DLINE_TYPE:
201 <    case GLINE_TYPE:
202 <    case KLINE_TYPE:
415 <    case CLIENT_TYPE:
416 <      MyFree(conf);
417 <      break;
418 <
419 <    case OPER_TYPE:
420 <      aconf = map_to_conf(conf);
421 <      if (!IsConfIllegal(aconf))
422 <        dlinkDelete(&conf->node, &oconf_items);
423 <      MyFree(conf);
424 <      break;
425 <
426 <    case SERVER_TYPE:
427 <      aconf = map_to_conf(conf);
428 <      if (!IsConfIllegal(aconf))
429 <        dlinkDelete(&conf->node, &server_items);
430 <      MyFree(conf);
431 <      break;
432 <
433 <    default:
434 <      break;
435 <    }
436 <    break;
437 <
438 <  case HUB_TYPE:
439 <    match_item = map_to_conf(conf);
440 <    MyFree(match_item->user);
441 <    MyFree(match_item->host);
442 <    MyFree(match_item->reason);
443 <    MyFree(match_item->oper_reason);
444 <    /* If marked illegal, its already been pulled off of the hub_items list */
445 <    if (!match_item->illegal)
446 <      dlinkDelete(&conf->node, &hub_items);
447 <    MyFree(conf);
448 <    break;
449 <
450 <  case LEAF_TYPE:
451 <    match_item = map_to_conf(conf);
452 <    MyFree(match_item->user);
453 <    MyFree(match_item->host);
454 <    MyFree(match_item->reason);
455 <    MyFree(match_item->oper_reason);
456 <    /* If marked illegal, its already been pulled off of the leaf_items list */
457 <    if (!match_item->illegal)
458 <      dlinkDelete(&conf->node, &leaf_items);
459 <    MyFree(conf);
460 <    break;
461 <
462 <  case ULINE_TYPE:
463 <    match_item = map_to_conf(conf);
464 <    MyFree(match_item->user);
465 <    MyFree(match_item->host);
466 <    MyFree(match_item->reason);
467 <    MyFree(match_item->oper_reason);
468 <    dlinkDelete(&conf->node, &uconf_items);
469 <    MyFree(conf);
470 <    break;
471 <
472 <  case XLINE_TYPE:
473 <    match_item = map_to_conf(conf);
474 <    MyFree(match_item->user);
475 <    MyFree(match_item->host);
476 <    MyFree(match_item->reason);
477 <    MyFree(match_item->oper_reason);
478 <    dlinkDelete(&conf->node, &xconf_items);
479 <    MyFree(conf);
480 <    break;
481 <
482 <  case RKLINE_TYPE:
483 <    aconf = map_to_conf(conf);
484 <    MyFree(aconf->regexuser);
485 <    MyFree(aconf->regexhost);
486 <    MyFree(aconf->user);
487 <    MyFree(aconf->host);
488 <    MyFree(aconf->reason);
489 <    MyFree(aconf->oper_reason);
490 <    dlinkDelete(&conf->node, &rkconf_items);
491 <    MyFree(conf);
492 <    break;
493 <
494 <  case RXLINE_TYPE:
495 <    MyFree(conf->regexpname);
496 <    match_item = map_to_conf(conf);
497 <    MyFree(match_item->user);
498 <    MyFree(match_item->host);
499 <    MyFree(match_item->reason);
500 <    MyFree(match_item->oper_reason);
501 <    dlinkDelete(&conf->node, &rxconf_items);
502 <    MyFree(conf);
503 <    break;
504 <
505 <  case NRESV_TYPE:
506 <    match_item = map_to_conf(conf);
507 <    MyFree(match_item->user);
508 <    MyFree(match_item->host);
509 <    MyFree(match_item->reason);
510 <    MyFree(match_item->oper_reason);
511 <    dlinkDelete(&conf->node, &nresv_items);
512 <    MyFree(conf);
513 <    break;
514 <
515 <  case GDENY_TYPE:
516 <    aconf = map_to_conf(conf);
517 <    MyFree(aconf->user);
518 <    MyFree(aconf->host);
519 <    dlinkDelete(&conf->node, &gdeny_items);
520 <    MyFree(conf);
521 <    break;
522 <
523 <  case CLUSTER_TYPE:
524 <    dlinkDelete(&conf->node, &cluster_items);
525 <    MyFree(conf);
526 <    break;
527 <
528 <  case CRESV_TYPE:
529 <    MyFree(conf);
530 <    break;
531 <
532 <  case CLASS_TYPE:
533 <    dlinkDelete(&conf->node, &class_items);
534 <    MyFree(conf);
535 <    break;
536 <
537 <  default:
538 <    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    }
540 }
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
547 < */
548 < void
549 < free_access_item(struct AccessItem *aconf)
550 < {
551 <  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)
554 <    return;
555 <  conf = unmap_conf_item(aconf);
556 <  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()
563 < *
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;
576 <  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;
246  
247    switch (type)
248    {
249 <  case GDENY_TYPE:
583 <    DLINK_FOREACH(ptr, gdeny_items.head)
584 <    {
585 <      conf = ptr->data;
586 <      aconf = map_to_conf(conf);
587 <
588 <      p = buf;
589 <
590 <      if (aconf->flags & GDENY_BLOCK)
591 <        *p++ = 'B';
592 <      else
593 <        *p++ = 'b';
594 <
595 <      if (aconf->flags & GDENY_REJECT)
596 <        *p++ = 'R';
597 <      else
598 <        *p++ = 'r';
599 <
600 <      *p = '\0';
601 <
602 <      sendto_one(source_p, ":%s %d %s V %s@%s %s %s",
603 <                 me.name, RPL_STATSDEBUG, source_p->name,
604 <                 aconf->user, aconf->host, conf->name, buf);
605 <    }
606 <    break;
607 <
608 <  case XLINE_TYPE:
249 >  case CONF_XLINE:
250      DLINK_FOREACH(ptr, xconf_items.head)
251      {
252        conf = ptr->data;
612      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;
625      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:
635 <    p = temp ? "Rk" : "RK";
636 <
274 >  case CONF_RKLINE:
275      DLINK_FOREACH(ptr, rkconf_items.head)
276      {
277 <      aconf = map_to_conf((conf = ptr->data));
640 <
641 <      if (temp && !(conf->flags & CONF_FLAGS_TEMPORARY))
642 <        continue;
277 >      conf = ptr->data;
278  
279        sendto_one(source_p, form_str(RPL_STATSKLINE), me.name,
280 <                 source_p->name, p, 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;
654      matchitem = map_to_conf(conf);
291  
292        p = buf;
293  
658      /* some of these are redundant for the sake of
659       * consistency with cluster{} flags
660       */
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 674 | 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 683 | 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;
690      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;
710 <      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));
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;
727
377        conf = ptr->data;
729      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';
737 <      if (IsConfLazyLink(aconf))
738 <        *p++ = 'L';
739 <      if (aconf->fakename)
740 <        *p++ = 'M';
741 <      if (IsConfTopicBurst(aconf))
742 <        *p++ = 'T';
743 <      if (IsConfCompressed(aconf))
744 <        *p++ = 'Z';
383 >      if (IsConfSSL(conf))
384 >        *p++ = 'S';
385        if (buf[0] == '\0')
386          *p++ = '*';
387  
388        *p = '\0';
389  
390 <      /* Allow admins to see actual ips
391 <       * unless hide_server_ips is enabled
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      }
774    break;
415  
416 <  case LEAF_TYPE:
777 <    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:
787 <  case KLINE_TYPE:
788 <  case DLINE_TYPE:
789 <  case EXEMPTDLINE_TYPE:
790 <  case CRESV_TYPE:
791 <  case NRESV_TYPE:
792 <  case CLUSTER_TYPE:
427 >  default:
428      break;
429    }
430   }
# Line 807 | 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   {
813  struct Client *source_p = va_arg(args, struct Client *);
814  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)))
819 <  {
820 <    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);
822  }
453  
454    switch (i)
455    {
826    case IRCD_SOCKET_ERROR:
827      exit_client(source_p, &me, "Socket Error");
828      break;
829
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 <    {
855 <      static char ipaddr[HOSTIPLEN];
856 <      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,
860 <            source_p->localClient->ip.ss_len, ipaddr, HOSTIPLEN, NULL, 0,
861 <            NI_NUMERICHOST);
862 <      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
875 <       * capture reject code here or rely on the connecting too fast code.
876 <       * - Dianora
877 <       */
878 <      if(REJECT_HOLD_TIME > 0)
879 <      {
880 <        sendto_one(source_p, ":%s NOTICE %s :You are not authorized to use this server",
881 <                   me.name, source_p->name);
882 <        source_p->localClient->reject_delay = CurrentTime + REJECT_HOLD_TIME;
883 <        SetCaptured(source_p);
884 <      }
885 <      else
886 <        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 <    }
889 <
497 >
498     case BANNED_CLIENT:
499 <     /*
500 <      * Don't exit them immediately, play with them a bit.
893 <      * - Dianora
894 <      */
895 <     if (REJECT_HOLD_TIME > 0)
896 <     {
897 <       source_p->localClient->reject_delay = CurrentTime + REJECT_HOLD_TIME;
898 <       SetCaptured(source_p);
899 <     }
900 <     else
901 <       exit_client(source_p, &me, "Banned");
902 <     ServerStats->is_ref++;
499 >     exit_client(source_p, &me, "Banned");
500 >     ++ServerStats.is_ref;
501       break;
502  
503     case 0:
# Line 907 | 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
916 *              - 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;
924 <  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 947 | 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);
955 <
956 <      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))
974 <          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 979 | 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",
991 <                  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 1004 | 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;
1010 <  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 = (struct AccessItem *)map_to_conf(conf);
1020 <  if (aconf->class_ptr == NULL)
610 >  if (conf->class == NULL)
611      return NOT_AUTHORIZED;  /* If class is missing, this is best */
612  
613 <  aclass = (struct ClassItem *)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 1029 | 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))
637 <      return TOO_MANY;  /* Already at maximum allowed */
636 >    if (!IsConfExemptLimits(conf))
637 >      return TOO_MANY;   /* Already at maximum allowed */
638  
639      sendto_one(client_p,
640                 ":%s NOTICE %s :*** Your connection class is full, "
# Line 1064 | Line 654 | attach_iline(struct Client *client_p, st
654   void
655   init_ip_hash_table(void)
656   {
657 <  ip_entry_heap = BlockHeapCreate("ip", sizeof(struct ip_entry),
657 >  ip_entry_pool = mp_pool_new(sizeof(struct ip_entry),
658      2 * hard_fdlimit);
659    memset(ip_hash_table, 0, sizeof(ip_hash_table));
660   }
# Line 1114 | Line 704 | find_or_add_ip(struct irc_ssaddr *ip_in)
704    if (ip_entries_count >= 2 * hard_fdlimit)
705      garbage_collect_ip_entries();
706  
707 <  newptr = BlockHeapAlloc(ip_entry_heap);
707 >  newptr = mp_pool_get(ip_entry_pool);
708 >  memset(newptr, 0, sizeof(*newptr));
709    ip_entries_count++;
710    memcpy(&newptr->ip, ip_in, sizeof(struct irc_ssaddr));
711  
# Line 1172 | Line 763 | remove_one_ip(struct irc_ssaddr *ip_in)
763        else
764          ip_hash_table[hash_index] = ptr->next;
765  
766 <      BlockHeapFree(ip_entry_heap, ptr);
766 >      mp_pool_release(ptr);
767        ip_entries_count--;
768        return;
769      }
# Line 1193 | Line 784 | hash_ip(struct irc_ssaddr *addr)
784    {
785      struct sockaddr_in *v4 = (struct sockaddr_in *)addr;
786      int hash;
787 <    u_int32_t ip;
787 >    uint32_t ip;
788  
789      ip   = ntohl(v4->sin_addr.s_addr);
790      hash = ((ip >> 12) + ip) & (IP_HASH_SIZE-1);
# Line 1204 | Line 795 | hash_ip(struct irc_ssaddr *addr)
795    {
796      int hash;
797      struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)addr;
798 <    u_int32_t *ip = (u_int32_t *)&v6->sin6_addr.s6_addr;
798 >    uint32_t *ip = (uint32_t *)&v6->sin6_addr.s6_addr;
799  
800      hash  = ip[0] ^ ip[3];
801      hash ^= hash >> 16;  
# Line 1228 | Line 819 | hash_ip(struct irc_ssaddr *addr)
819   * used in the hash.
820   */
821   void
822 < count_ip_hash(int *number_ips_stored, unsigned long *mem_ips_stored)
822 > count_ip_hash(unsigned int *number_ips_stored, uint64_t *mem_ips_stored)
823   {
824    struct ip_entry *ptr;
825    int i;
# Line 1275 | Line 866 | garbage_collect_ip_entries(void)
866            last_ptr->next = ptr->next;
867          else
868            ip_hash_table[i] = ptr->next;
869 <        BlockHeapFree(ip_entry_heap, ptr);
869 >        mp_pool_release(ptr);
870          ip_entries_count--;
871        }
872        else
# Line 1292 | Line 883 | garbage_collect_ip_entries(void)
883   * side effects - Disassociate configuration from the client.
884   *                Also removes a class from the list if marked for deleting.
885   */
886 < int
887 < detach_conf(struct Client *client_p, ConfType type)
886 > void
887 > detach_conf(struct Client *client_p, enum maskitem_type type)
888   {
889 <  dlink_node *ptr, *next_ptr;
1299 <  struct ConfItem *conf;
1300 <  struct ClassItem *aclass;
1301 <  struct AccessItem *aconf;
1302 <  struct ConfItem *aclass_conf;
1303 <  struct MatchItem *match_item;
889 >  dlink_node *ptr = NULL, *next_ptr = NULL;
890  
891    DLINK_FOREACH_SAFE(ptr, next_ptr, client_p->localClient->confs.head)
892    {
893 <    conf = ptr->data;
1308 <
1309 <    if (type == CONF_TYPE || conf->type == type)
1310 <    {
1311 <      dlinkDelete(ptr, &client_p->localClient->confs);
1312 <      free_dlink_node(ptr);
893 >    struct MaskItem *conf = ptr->data;
894  
895 <      switch (conf->type)
896 <      {
897 <      case CLIENT_TYPE:
1317 <      case OPER_TYPE:
1318 <      case SERVER_TYPE:
1319 <        aconf = (struct AccessItem *)map_to_conf(conf);
1320 <        if ((aclass_conf = ClassPtr(aconf)) != NULL)
1321 <        {
1322 <          aclass = (struct ClassItem *)map_to_conf(aclass_conf);
895 >    assert(conf->type & (CONF_CLIENT | CONF_OPER | CONF_SERVER));
896 >    assert(conf->ref_count > 0);
897 >    assert(conf->class->ref_count > 0);
898  
899 <          if (conf->type == CLIENT_TYPE)
900 <            remove_from_cidr_check(&client_p->localClient->ip, aclass);
899 >    if (!(conf->type & type))
900 >      continue;
901  
902 <          if (CurrUserCount(aclass) > 0)
903 <            aclass->curr_user_count--;
1329 <          if (MaxTotal(aclass) < 0 && CurrUserCount(aclass) <= 0)
1330 <            delete_conf_item(aclass_conf);
1331 <        }
902 >    dlinkDelete(ptr, &client_p->localClient->confs);
903 >    free_dlink_node(ptr);
904  
905 <        /* Please, no ioccc entries - Dianora */
906 <        if (aconf->clients > 0)
1335 <          --aconf->clients;
1336 <        if (aconf->clients == 0 && IsConfIllegal(aconf))
1337 <          delete_conf_item(conf);
1338 <        break;
1339 <      case LEAF_TYPE:
1340 <      case HUB_TYPE:
1341 <        match_item = (struct MatchItem *)map_to_conf(conf);
1342 <        if (match_item->ref_count == 0 && match_item->illegal)
1343 <          delete_conf_item(conf);
1344 <        break;
1345 <      default:
1346 <        break;
1347 <      }
905 >    if (conf->type == CONF_CLIENT)
906 >      remove_from_cidr_check(&client_p->localClient->ip, conf->class);
907  
908 <      if (type != CONF_TYPE)
909 <        return 0;
908 >    if (--conf->class->ref_count == 0 && conf->class->active == 0)
909 >    {
910 >      class_free(conf->class);
911 >      conf->class = NULL;
912      }
1352  }
913  
914 <  return -1;
914 >    if (--conf->ref_count == 0 && conf->active == 0)
915 >      conf_free(conf);
916 >  }
917   }
918  
919   /* attach_conf()
# Line 1365 | Line 927 | detach_conf(struct Client *client_p, Con
927   *                attachment if there was an old one...
928   */
929   int
930 < attach_conf(struct Client *client_p, struct ConfItem *conf)
930 > attach_conf(struct Client *client_p, struct MaskItem *conf)
931   {
1370  struct AccessItem *aconf;
1371  struct MatchItem *match_item;
1372
932    if (dlinkFind(&client_p->localClient->confs, conf) != NULL)
933      return 1;
934  
935 <  if (conf->type == CLIENT_TYPE ||
936 <      conf->type == SERVER_TYPE ||
937 <      conf->type == OPER_TYPE)
938 <  {
1380 <    aconf = (struct AccessItem *)map_to_conf(conf);
1381 <
1382 <    if (IsConfIllegal(aconf))
1383 <      return NOT_AUTHORIZED;
1384 <
1385 <    if (conf->type == CLIENT_TYPE)
1386 <    {
1387 <      struct ClassItem *aclass;
1388 <      aclass = (struct ClassItem *)map_to_conf(aconf->class_ptr);
1389 <
1390 <      if (cidr_limit_reached(IsConfExemptLimits(aconf),
1391 <                             &client_p->localClient->ip, aclass))
1392 <        return TOO_MANY;  /* Already at maximum allowed */
1393 <
1394 <      CurrUserCount(aclass)++;
1395 <    }
935 >  if (conf->type == CONF_CLIENT)
936 >    if (cidr_limit_reached(IsConfExemptLimits(conf),
937 >                           &client_p->localClient->ip, conf->class))
938 >      return TOO_MANY;    /* Already at maximum allowed */
939  
940 <    aconf->clients++;
941 <  }
1399 <  else if (conf->type == HUB_TYPE || conf->type == LEAF_TYPE)
1400 <  {
1401 <    match_item = (struct MatchItem *)map_to_conf(conf);
1402 <    match_item->ref_count++;
1403 <  }
940 >  conf->class->ref_count++;
941 >  conf->ref_count++;
942  
943    dlinkAdd(conf, make_dlink_node(), &client_p->localClient->confs);
944  
# Line 1420 | Line 958 | attach_connect_block(struct Client *clie
958                       const char *host)
959   {
960    dlink_node *ptr;
961 <  struct ConfItem *conf;
1424 <  struct AccessItem *aconf;
961 >  struct MaskItem *conf = NULL;
962  
963    assert(client_p != NULL);
964    assert(host != NULL);
# Line 1432 | Line 969 | attach_connect_block(struct Client *clie
969    DLINK_FOREACH(ptr, server_items.head)
970    {
971      conf = ptr->data;
1435    aconf = (struct AccessItem *)map_to_conf(conf);
972  
973 <    if (match(conf->name, name) == 0 || match(aconf->host, host) == 0)
973 >    if (match(conf->name, name) || match(conf->host, host))
974        continue;
975  
976      attach_conf(client_p, conf);
# Line 1444 | Line 980 | attach_connect_block(struct Client *clie
980    return 0;
981   }
982  
1447 /* find_conf_exact()
1448 *
1449 * inputs       - type of ConfItem
1450 *              - pointer to name to find
1451 *              - pointer to username to find
1452 *              - pointer to host to find
1453 * output       - NULL or pointer to conf found
1454 * side effects - find a conf entry which matches the hostname
1455 *                and has the same name.
1456 */
1457 struct ConfItem *
1458 find_conf_exact(ConfType type, const char *name, const char *user,
1459                const char *host)
1460 {
1461  dlink_node *ptr;
1462  dlink_list *list_p;
1463  struct ConfItem *conf = NULL;
1464  struct AccessItem *aconf;
1465
1466  /* Only valid for OPER_TYPE and ...? */
1467  list_p = map_to_list(type);
1468
1469  DLINK_FOREACH(ptr, (*list_p).head)
1470  {
1471    conf = ptr->data;
1472
1473    if (conf->name == NULL)
1474      continue;
1475    aconf = (struct AccessItem *)map_to_conf(conf);
1476    if (aconf->host == NULL)
1477      continue;
1478    if (irccmp(conf->name, name) != 0)
1479      continue;
1480
1481    /*
1482    ** Accept if the *real* hostname (usually sockethost)
1483    ** socket host) matches *either* host or name field
1484    ** of the configuration.
1485    */
1486    if (!match(aconf->host, host) || !match(aconf->user,user)
1487        || irccmp(conf->name, name) )
1488      continue;
1489    if (type == OPER_TYPE)
1490    {
1491      struct ClassItem *aclass;
1492
1493      aclass = (struct ClassItem *)aconf->class_ptr;
1494      if (aconf->clients < MaxTotal(aclass))
1495        return conf;
1496      else
1497        continue;
1498    }
1499    else
1500      return conf;
1501  }
1502  return NULL;
1503 }
1504
983   /* find_conf_name()
984   *
985   * inputs       - pointer to conf link list to search
# Line 1511 | Line 989 | find_conf_exact(ConfType type, const cha
989   * side effects - find a conf entry which matches the name
990   *                and has the given mask.
991   */
992 < struct ConfItem *
993 < find_conf_name(dlink_list *list, const char *name, ConfType type)
992 > struct MaskItem *
993 > find_conf_name(dlink_list *list, const char *name, enum maskitem_type type)
994   {
995    dlink_node *ptr;
996 <  struct ConfItem* conf;
996 >  struct MaskItem* conf;
997  
998    DLINK_FOREACH(ptr, list->head)
999    {
# Line 1524 | Line 1002 | find_conf_name(dlink_list *list, const c
1002      if (conf->type == type)
1003      {
1004        if (conf->name && (irccmp(conf->name, name) == 0 ||
1005 <                         match(conf->name, name)))
1005 >                         !match(conf->name, name)))
1006        return conf;
1007      }
1008    }
# Line 1539 | Line 1017 | find_conf_name(dlink_list *list, const c
1017   * side effects - none
1018   */
1019   static dlink_list *
1020 < map_to_list(ConfType type)
1020 > map_to_list(enum maskitem_type type)
1021   {
1022    switch(type)
1023    {
1024 <  case RXLINE_TYPE:
1024 >  case CONF_RKLINE:
1025 >    return(&rkconf_items);
1026 >    break;
1027 >  case CONF_RXLINE:
1028      return(&rxconf_items);
1029      break;
1030 <  case XLINE_TYPE:
1030 >  case CONF_XLINE:
1031      return(&xconf_items);
1032      break;
1033 <  case ULINE_TYPE:
1033 >  case CONF_ULINE:
1034      return(&uconf_items);
1035      break;
1036 <  case NRESV_TYPE:
1036 >  case CONF_NRESV:
1037      return(&nresv_items);
1038      break;
1039 <  case OPER_TYPE:
1039 >  case CONF_CRESV:
1040 >    return(&resv_channel_list);
1041 >  case CONF_OPER:
1042      return(&oconf_items);
1043      break;
1044 <  case CLASS_TYPE:
1562 <    return(&class_items);
1563 <    break;
1564 <  case SERVER_TYPE:
1044 >  case CONF_SERVER:
1045      return(&server_items);
1046      break;
1047 <  case CLUSTER_TYPE:
1047 >  case CONF_SERVICE:
1048 >    return(&service_items);
1049 >    break;
1050 >  case CONF_CLUSTER:
1051      return(&cluster_items);
1052      break;
1570  case CONF_TYPE:
1571  case GLINE_TYPE:
1572  case KLINE_TYPE:
1573  case DLINE_TYPE:
1574  case CRESV_TYPE:
1053    default:
1054      return NULL;
1055    }
# Line 1583 | Line 1061 | map_to_list(ConfType type)
1061   *              - pointer to name string to find
1062   *              - pointer to user
1063   *              - pointer to host
1064 < *              - optional action to match on as well
1065 < * output       - NULL or pointer to found struct MatchItem
1064 > *              - optional flags to match on as well
1065 > * output       - NULL or pointer to found struct MaskItem
1066   * side effects - looks for a match on name field
1067   */
1068 < struct ConfItem *
1069 < find_matching_name_conf(ConfType type, const char *name, const char *user,
1070 <                        const char *host, int action)
1068 > struct MaskItem *
1069 > find_matching_name_conf(enum maskitem_type type, const char *name, const char *user,
1070 >                        const char *host, unsigned int flags)
1071   {
1072    dlink_node *ptr=NULL;
1073 <  struct ConfItem *conf=NULL;
1596 <  struct AccessItem *aconf=NULL;
1597 <  struct MatchItem *match_item=NULL;
1073 >  struct MaskItem *conf=NULL;
1074    dlink_list *list_p = map_to_list(type);
1075  
1076    switch (type)
1077    {
1078 <    case RXLINE_TYPE:
1078 > #ifdef HAVE_LIBPCRE
1079 >  case CONF_RXLINE:
1080        DLINK_FOREACH(ptr, list_p->head)
1081        {
1082          conf = ptr->data;
1083 <        assert(conf->regexpname);
1083 >        assert(conf->regexuser);
1084  
1085 <        if (!ircd_pcre_exec(conf->regexpname, name))
1085 >        if (!ircd_pcre_exec(conf->regexuser, name))
1086            return conf;
1087        }
1088        break;
1089 + #endif
1090 +  case CONF_SERVICE:
1091 +    DLINK_FOREACH(ptr, list_p->head)
1092 +    {
1093 +      conf = ptr->data;
1094  
1095 <  case XLINE_TYPE:
1096 <  case ULINE_TYPE:
1097 <  case NRESV_TYPE:
1095 >      if (EmptyString(conf->name))
1096 >        continue;
1097 >      if ((name != NULL) && !irccmp(name, conf->name))
1098 >        return conf;
1099 >    }
1100 >    break;
1101 >
1102 >  case CONF_XLINE:
1103 >  case CONF_ULINE:
1104 >  case CONF_NRESV:
1105 >  case CONF_CRESV:
1106      DLINK_FOREACH(ptr, list_p->head)
1107      {
1108        conf = ptr->data;
1109  
1620      match_item = map_to_conf(conf);
1110        if (EmptyString(conf->name))
1111          continue;
1112 <      if ((name != NULL) && match_esc(conf->name, name))
1112 >      if ((name != NULL) && !match(conf->name, name))
1113        {
1114          if ((user == NULL && (host == NULL)))
1115            return conf;
1116 <        if ((match_item->action & action) != action)
1116 >        if ((conf->flags & flags) != flags)
1117            continue;
1118 <        if (EmptyString(match_item->user) || EmptyString(match_item->host))
1118 >        if (EmptyString(conf->user) || EmptyString(conf->host))
1119            return conf;
1120 <        if (match(match_item->user, user) && match(match_item->host, host))
1120 >        if (!match(conf->user, user) && !match(conf->host, host))
1121            return conf;
1122        }
1123      }
1124        break;
1125  
1126 <  case SERVER_TYPE:
1126 >  case CONF_SERVER:
1127      DLINK_FOREACH(ptr, list_p->head)
1128      {
1129        conf = ptr->data;
1641      aconf = map_to_conf(conf);
1130  
1131 <      if ((name != NULL) && match_esc(name, conf->name))
1131 >      if ((name != NULL) && !match(name, conf->name))
1132          return conf;
1133 <      else if ((host != NULL) && match_esc(host, aconf->host))
1133 >      else if ((host != NULL) && !match(host, conf->host))
1134          return conf;
1135      }
1136      break;
# Line 1659 | Line 1147 | find_matching_name_conf(ConfType type, c
1147   *              - pointer to name string to find
1148   *              - pointer to user
1149   *              - pointer to host
1150 < * output       - NULL or pointer to found struct MatchItem
1150 > * output       - NULL or pointer to found struct MaskItem
1151   * side effects - looks for an exact match on name field
1152   */
1153 < struct ConfItem *
1154 < find_exact_name_conf(ConfType type, const char *name,
1153 > struct MaskItem *
1154 > find_exact_name_conf(enum maskitem_type type, const struct Client *who, const char *name,
1155                       const char *user, const char *host)
1156   {
1157    dlink_node *ptr = NULL;
1158 <  struct AccessItem *aconf;
1159 <  struct ConfItem *conf;
1672 <  struct MatchItem *match_item;
1673 <  dlink_list *list_p;
1674 <
1675 <  list_p = map_to_list(type);
1158 >  struct MaskItem *conf;
1159 >  dlink_list *list_p = map_to_list(type);
1160  
1161    switch(type)
1162    {
1163 <  case RXLINE_TYPE:
1164 <  case XLINE_TYPE:
1165 <  case ULINE_TYPE:
1166 <  case NRESV_TYPE:
1163 >  case CONF_RXLINE:
1164 >  case CONF_XLINE:
1165 >  case CONF_ULINE:
1166 >  case CONF_NRESV:
1167 >  case CONF_CRESV:
1168  
1169      DLINK_FOREACH(ptr, list_p->head)
1170      {
1171        conf = ptr->data;
1172 <      match_item = (struct MatchItem *)map_to_conf(conf);
1172 >
1173        if (EmptyString(conf->name))
1174          continue;
1175      
# Line 1692 | Line 1177 | find_exact_name_conf(ConfType type, cons
1177        {
1178          if ((user == NULL && (host == NULL)))
1179            return (conf);
1180 <        if (EmptyString(match_item->user) || EmptyString(match_item->host))
1180 >        if (EmptyString(conf->user) || EmptyString(conf->host))
1181            return (conf);
1182 <        if (match(match_item->user, user) && match(match_item->host, host))
1182 >        if (!match(conf->user, user) && !match(conf->host, host))
1183            return (conf);
1184        }
1185      }
1186      break;
1187  
1188 <  case OPER_TYPE:
1188 >  case CONF_OPER:
1189      DLINK_FOREACH(ptr, list_p->head)
1190      {
1191        conf = ptr->data;
1192 <      aconf = (struct AccessItem *)map_to_conf(conf);
1192 >
1193        if (EmptyString(conf->name))
1194 <        continue;
1195 <    
1196 <      if (irccmp(conf->name, name) == 0)
1194 >        continue;
1195 >
1196 >      if (!irccmp(conf->name, name))
1197        {
1198 <        if ((user == NULL && (host == NULL)))
1199 <          return (conf);
1200 <        if (EmptyString(aconf->user) || EmptyString(aconf->host))
1201 <          return (conf);
1202 <        if (match(aconf->user, user) && match(aconf->host, host))
1203 <          return (conf);
1198 >        if (!who)
1199 >          return conf;
1200 >        if (EmptyString(conf->user) || EmptyString(conf->host))
1201 >          return NULL;
1202 >        if (!match(conf->user, who->username))
1203 >        {
1204 >          switch (conf->htype)
1205 >          {
1206 >            case HM_HOST:
1207 >              if (!match(conf->host, who->host) || !match(conf->host, who->sockhost))
1208 >                if (!conf->class->max_total || conf->class->ref_count < conf->class->max_total)
1209 >                  return conf;
1210 >              break;
1211 >            case HM_IPV4:
1212 >              if (who->localClient->aftype == AF_INET)
1213 >                if (match_ipv4(&who->localClient->ip, &conf->addr, conf->bits))
1214 >                  if (!conf->class->max_total || conf->class->ref_count < conf->class->max_total)
1215 >                    return conf;
1216 >              break;
1217 > #ifdef IPV6
1218 >            case HM_IPV6:
1219 >              if (who->localClient->aftype == AF_INET6)
1220 >                if (match_ipv6(&who->localClient->ip, &conf->addr, conf->bits))
1221 >                  if (!conf->class->max_total || conf->class->ref_count < conf->class->max_total)
1222 >                    return conf;
1223 >              break;
1224 > #endif
1225 >            default:
1226 >              assert(0);
1227 >          }
1228 >        }
1229        }
1230      }
1231 +
1232      break;
1233  
1234 <  case SERVER_TYPE:
1234 >  case CONF_SERVER:
1235      DLINK_FOREACH(ptr, list_p->head)
1236      {
1237        conf = ptr->data;
1238 <      aconf = (struct AccessItem *)map_to_conf(conf);
1238 >
1239        if (EmptyString(conf->name))
1240          continue;
1241      
1242        if (name == NULL)
1243        {
1244 <        if (EmptyString(aconf->host))
1244 >        if (EmptyString(conf->host))
1245            continue;
1246 <        if (irccmp(aconf->host, host) == 0)
1246 >        if (irccmp(conf->host, host) == 0)
1247            return(conf);
1248        }
1249        else if (irccmp(conf->name, name) == 0)
# Line 1742 | Line 1253 | find_exact_name_conf(ConfType type, cons
1253      }
1254      break;
1255  
1745  case CLASS_TYPE:
1746    DLINK_FOREACH(ptr, list_p->head)
1747    {
1748      conf = ptr->data;
1749      if (EmptyString(conf->name))
1750        continue;
1751    
1752      if (irccmp(conf->name, name) == 0)
1753        return (conf);
1754    }
1755    break;
1756
1256    default:
1257      break;
1258    }
# Line 1770 | Line 1269 | int
1269   rehash(int sig)
1270   {
1271    if (sig != 0)
1272 <    sendto_realops_flags(UMODE_ALL, L_ALL,
1272 >    sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1273                           "Got signal SIGHUP, reloading ircd.conf file");
1274  
1776 #ifndef _WIN32
1275    restart_resolver();
1276 < #endif
1276 >
1277    /* don't close listeners until we know we can go ahead with the rehash */
1278  
1279    /* Check to see if we magically got(or lost) IPv6 support */
# Line 1786 | Line 1284 | rehash(int sig)
1284    if (ServerInfo.description != NULL)
1285      strlcpy(me.info, ServerInfo.description, sizeof(me.info));
1286  
1789 #ifndef STATIC_MODULES
1287    load_conf_modules();
1791 #endif
1792
1793  flush_deleted_I_P();
1288  
1289    rehashed_klines = 1;
1290  
1291 <  if (ConfigLoggingEntry.use_logging)
1798 <    reopen_log(logFileName);
1799 <
1800 <  return(0);
1291 >  return 0;
1292   }
1293  
1294   /* set_default_conf()
# Line 1815 | Line 1306 | set_default_conf(void)
1306    /* verify init_class() ran, this should be an unnecessary check
1307     * but its not much work.
1308     */
1309 <  assert(class_default == (struct ConfItem *) class_items.tail->data);
1309 >  assert(class_default == class_get_list()->tail->data);
1310  
1311   #ifdef HAVE_LIBCRYPTO
1312    ServerInfo.rsa_private_key = NULL;
# Line 1825 | Line 1316 | set_default_conf(void)
1316    /* ServerInfo.name is not rehashable */
1317    /* ServerInfo.name = ServerInfo.name; */
1318    ServerInfo.description = NULL;
1319 <  DupString(ServerInfo.network_name, NETWORK_NAME_DEFAULT);
1320 <  DupString(ServerInfo.network_desc, NETWORK_DESC_DEFAULT);
1319 >  ServerInfo.network_name = xstrdup(NETWORK_NAME_DEFAULT);
1320 >  ServerInfo.network_desc = xstrdup(NETWORK_DESC_DEFAULT);
1321  
1322    memset(&ServerInfo.ip, 0, sizeof(ServerInfo.ip));
1323    ServerInfo.specific_ipv4_vhost = 0;
# Line 1834 | Line 1325 | set_default_conf(void)
1325    ServerInfo.specific_ipv6_vhost = 0;
1326  
1327    ServerInfo.max_clients = MAXCLIENTS_MAX;
1328 <  /* Don't reset hub, as that will break lazylinks */
1329 <  /* ServerInfo.hub = NO; */
1328 >  ServerInfo.max_nick_length = 9;
1329 >  ServerInfo.max_topic_length = 80;
1330 >
1331 >  ServerInfo.hub = 0;
1332    ServerInfo.dns_host.sin_addr.s_addr = 0;
1333    ServerInfo.dns_host.sin_port = 0;
1334    AdminInfo.name = NULL;
1335    AdminInfo.email = NULL;
1336    AdminInfo.description = NULL;
1337  
1338 <  set_log_level(L_NOTICE);
1338 >  log_del_all();
1339 >
1340    ConfigLoggingEntry.use_logging = 1;
1341 <  ConfigLoggingEntry.operlog[0] = '\0';
1342 <  ConfigLoggingEntry.userlog[0] = '\0';
1343 <  ConfigLoggingEntry.klinelog[0] = '\0';
1850 <  ConfigLoggingEntry.glinelog[0] = '\0';
1851 <  ConfigLoggingEntry.killlog[0] = '\0';
1852 <  ConfigLoggingEntry.operspylog[0] = '\0';
1853 <  ConfigLoggingEntry.ioerrlog[0] = '\0';
1854 <  ConfigLoggingEntry.failed_operlog[0] = '\0';
1855 <
1856 <  ConfigChannel.restrict_channels = NO;
1857 <  ConfigChannel.disable_local_channels = NO;
1858 <  ConfigChannel.use_invex = YES;
1859 <  ConfigChannel.use_except = YES;
1860 <  ConfigChannel.use_knock = YES;
1341 >
1342 >  ConfigChannel.disable_fake_channels = 0;
1343 >  ConfigChannel.restrict_channels = 0;
1344    ConfigChannel.knock_delay = 300;
1345    ConfigChannel.knock_delay_channel = 60;
1346 <  ConfigChannel.max_chans_per_user = 15;
1347 <  ConfigChannel.quiet_on_ban = YES;
1346 >  ConfigChannel.max_chans_per_user = 25;
1347 >  ConfigChannel.max_chans_per_oper = 50;
1348 >  ConfigChannel.quiet_on_ban = 1;
1349    ConfigChannel.max_bans = 25;
1350    ConfigChannel.default_split_user_count = 0;
1351    ConfigChannel.default_split_server_count = 0;
1352 <  ConfigChannel.no_join_on_split = NO;
1353 <  ConfigChannel.no_create_on_split = NO;
1870 <  ConfigChannel.burst_topicwho = YES;
1352 >  ConfigChannel.no_join_on_split = 0;
1353 >  ConfigChannel.no_create_on_split = 0;
1354  
1355 <  ConfigServerHide.flatten_links = NO;
1355 >  ConfigServerHide.flatten_links = 0;
1356    ConfigServerHide.links_delay = 300;
1357 <  ConfigServerHide.hidden = NO;
1358 <  ConfigServerHide.disable_hidden = NO;
1359 <  ConfigServerHide.hide_servers = NO;
1360 <  DupString(ConfigServerHide.hidden_name, NETWORK_NAME_DEFAULT);
1878 <  ConfigServerHide.hide_server_ips = NO;
1357 >  ConfigServerHide.hidden = 0;
1358 >  ConfigServerHide.hide_servers = 0;
1359 >  ConfigServerHide.hidden_name = xstrdup(NETWORK_NAME_DEFAULT);
1360 >  ConfigServerHide.hide_server_ips = 0;
1361  
1362 +  
1363 +  ConfigFileEntry.service_name = xstrdup(SERVICE_NAME_DEFAULT);
1364 +  ConfigFileEntry.max_watch = WATCHSIZE_DEFAULT;
1365 +  ConfigFileEntry.glines = 0;
1366 +  ConfigFileEntry.gline_time = 12 * 3600;
1367 +  ConfigFileEntry.gline_request_time = GLINE_REQUEST_EXPIRE_DEFAULT;
1368    ConfigFileEntry.gline_min_cidr = 16;
1369    ConfigFileEntry.gline_min_cidr6 = 48;
1370 <  ConfigFileEntry.invisible_on_connect = YES;
1371 <  ConfigFileEntry.burst_away = NO;
1372 <  ConfigFileEntry.use_whois_actually = YES;
1373 <  ConfigFileEntry.tkline_expire_notices = YES;
1374 <  ConfigFileEntry.hide_spoof_ips = YES;
1375 <  ConfigFileEntry.ignore_bogus_ts = NO;
1888 <  ConfigFileEntry.disable_auth = NO;
1889 <  ConfigFileEntry.disable_remote = NO;
1370 >  ConfigFileEntry.invisible_on_connect = 1;
1371 >  ConfigFileEntry.tkline_expire_notices = 1;
1372 >  ConfigFileEntry.hide_spoof_ips = 1;
1373 >  ConfigFileEntry.ignore_bogus_ts = 0;
1374 >  ConfigFileEntry.disable_auth = 0;
1375 >  ConfigFileEntry.disable_remote = 0;
1376    ConfigFileEntry.kill_chase_time_limit = 90;
1377 <  ConfigFileEntry.default_floodcount = 8; /* XXX */
1378 <  ConfigFileEntry.failed_oper_notice = YES;
1379 <  ConfigFileEntry.dots_in_ident = 0;      /* XXX */
1894 <  ConfigFileEntry.dot_in_ip6_addr = YES;
1377 >  ConfigFileEntry.default_floodcount = 8;
1378 >  ConfigFileEntry.failed_oper_notice = 1;
1379 >  ConfigFileEntry.dots_in_ident = 0;
1380    ConfigFileEntry.min_nonwildcard = 4;
1381    ConfigFileEntry.min_nonwildcard_simple = 3;
1382    ConfigFileEntry.max_accept = 20;
1383 <  ConfigFileEntry.anti_nick_flood = NO;   /* XXX */
1383 >  ConfigFileEntry.anti_nick_flood = 0;
1384    ConfigFileEntry.max_nick_time = 20;
1385    ConfigFileEntry.max_nick_changes = 5;
1386 <  ConfigFileEntry.anti_spam_exit_message_time = 0;  /* XXX */
1386 >  ConfigFileEntry.anti_spam_exit_message_time = 0;
1387    ConfigFileEntry.ts_warn_delta = TS_WARN_DELTA_DEFAULT;
1388 <  ConfigFileEntry.ts_max_delta = TS_MAX_DELTA_DEFAULT;  /* XXX */
1389 <  ConfigFileEntry.kline_with_reason = YES;
1390 <  ConfigFileEntry.kline_reason = NULL;
1906 <  ConfigFileEntry.warn_no_nline = YES;
1907 <  ConfigFileEntry.stats_o_oper_only = NO; /* XXX */
1388 >  ConfigFileEntry.ts_max_delta = TS_MAX_DELTA_DEFAULT;
1389 >  ConfigFileEntry.warn_no_nline = 1;
1390 >  ConfigFileEntry.stats_o_oper_only = 0;
1391    ConfigFileEntry.stats_k_oper_only = 1;  /* masked */
1392    ConfigFileEntry.stats_i_oper_only = 1;  /* masked */
1393 <  ConfigFileEntry.stats_P_oper_only = NO;
1393 >  ConfigFileEntry.stats_P_oper_only = 0;
1394    ConfigFileEntry.caller_id_wait = 60;
1395 <  ConfigFileEntry.opers_bypass_callerid = NO;
1395 >  ConfigFileEntry.opers_bypass_callerid = 0;
1396    ConfigFileEntry.pace_wait = 10;
1397    ConfigFileEntry.pace_wait_simple = 1;
1398 <  ConfigFileEntry.short_motd = NO;
1399 <  ConfigFileEntry.ping_cookie = NO;
1400 <  ConfigFileEntry.no_oper_flood = NO;     /* XXX */
1401 <  ConfigFileEntry.true_no_oper_flood = NO;  /* XXX */
1402 <  ConfigFileEntry.oper_pass_resv = YES;
1920 <  ConfigFileEntry.glines = NO;            /* XXX */
1921 <  ConfigFileEntry.gline_time = 12 * 3600; /* XXX */
1922 <  ConfigFileEntry.idletime = 0;
1398 >  ConfigFileEntry.short_motd = 0;
1399 >  ConfigFileEntry.ping_cookie = 0;
1400 >  ConfigFileEntry.no_oper_flood = 0;
1401 >  ConfigFileEntry.true_no_oper_flood = 0;
1402 >  ConfigFileEntry.oper_pass_resv = 1;
1403    ConfigFileEntry.max_targets = MAX_TARGETS_DEFAULT;
1404 <  ConfigFileEntry.client_flood = CLIENT_FLOOD_DEFAULT;
1405 <  ConfigFileEntry.oper_only_umodes = UMODE_DEBUG;  /* XXX */
1406 <  ConfigFileEntry.oper_umodes = UMODE_LOCOPS | UMODE_SERVNOTICE |
1407 <    UMODE_OPERWALL | UMODE_WALLOP;        /* XXX */
1928 <  DupString(ConfigFileEntry.servlink_path, SLPATH);
1929 < #ifdef HAVE_LIBCRYPTO
1930 <  /* jdc -- This is our default value for a cipher.  According to the
1931 <   *        CRYPTLINK document (doc/cryptlink.txt), BF/128 must be supported
1932 <   *        under all circumstances if cryptlinks are enabled.  So,
1933 <   *        this will be our default.
1934 <   *
1935 <   *        NOTE: I apologise for the hard-coded value of "1" (BF/128).
1936 <   *              This should be moved into a find_cipher() routine.
1937 <   */
1938 <  ConfigFileEntry.default_cipher_preference = &CipherTable[1];
1939 < #endif
1940 <  ConfigFileEntry.use_egd = NO;
1404 >  ConfigFileEntry.oper_only_umodes = UMODE_DEBUG;
1405 >  ConfigFileEntry.oper_umodes = UMODE_BOTS | UMODE_LOCOPS | UMODE_SERVNOTICE |
1406 >    UMODE_OPERWALL | UMODE_WALLOP;
1407 >  ConfigFileEntry.use_egd = 0;
1408    ConfigFileEntry.egdpool_path = NULL;
1942 #ifdef HAVE_LIBZ
1943  ConfigFileEntry.compression_level = 0;
1944 #endif
1409    ConfigFileEntry.throttle_time = 10;
1410   }
1411  
1412 + static void
1413 + validate_conf(void)
1414 + {
1415 +  if (ConfigFileEntry.ts_warn_delta < TS_WARN_DELTA_MIN)
1416 +    ConfigFileEntry.ts_warn_delta = TS_WARN_DELTA_DEFAULT;
1417 +
1418 +  if (ConfigFileEntry.ts_max_delta < TS_MAX_DELTA_MIN)
1419 +    ConfigFileEntry.ts_max_delta = TS_MAX_DELTA_DEFAULT;
1420 +
1421 +  if (ServerInfo.network_name == NULL)
1422 +    ServerInfo.network_name = xstrdup(NETWORK_NAME_DEFAULT);
1423 +
1424 +  if (ServerInfo.network_desc == NULL)
1425 +    ServerInfo.network_desc = xstrdup(NETWORK_DESC_DEFAULT);
1426 +
1427 +  if (ConfigFileEntry.service_name == NULL)
1428 +    ConfigFileEntry.service_name = xstrdup(SERVICE_NAME_DEFAULT);
1429 +
1430 +  ConfigFileEntry.max_watch = IRCD_MAX(ConfigFileEntry.max_watch, WATCHSIZE_MIN);
1431 + }
1432 +
1433   /* read_conf()
1434   *
1435   * inputs       - file descriptor pointing to config file to use
# Line 1952 | Line 1437 | set_default_conf(void)
1437   * side effects - Read configuration file.
1438   */
1439   static void
1440 < read_conf(FBFILE *file)
1440 > read_conf(FILE *file)
1441   {
1442 <  scount = lineno = 0;
1442 >  lineno = 0;
1443  
1444    set_default_conf(); /* Set default values prior to conf parsing */
1445 <  ypass = 1;
1445 >  conf_parser_ctx.pass = 1;
1446    yyparse();          /* pick up the classes first */
1447  
1448 <  fbrewind(file);
1448 >  rewind(file);
1449  
1450 <  ypass = 2;
1450 >  conf_parser_ctx.pass = 2;
1451    yyparse();          /* Load the values from the conf */
1452    validate_conf();    /* Check to make sure some values are still okay. */
1453                        /* Some global values are also loaded here. */
1454 <  check_class();      /* Make sure classes are valid */
1970 < }
1971 <
1972 < static void
1973 < validate_conf(void)
1974 < {
1975 <  if (ConfigFileEntry.ts_warn_delta < TS_WARN_DELTA_MIN)
1976 <    ConfigFileEntry.ts_warn_delta = TS_WARN_DELTA_DEFAULT;
1977 <
1978 <  if (ConfigFileEntry.ts_max_delta < TS_MAX_DELTA_MIN)
1979 <    ConfigFileEntry.ts_max_delta = TS_MAX_DELTA_DEFAULT;
1980 <
1981 <  if (ConfigFileEntry.servlink_path == NULL)
1982 <    DupString(ConfigFileEntry.servlink_path, SLPATH);
1983 <
1984 <  if (ServerInfo.network_name == NULL)
1985 <    DupString(ServerInfo.network_name,NETWORK_NAME_DEFAULT);
1986 <
1987 <  if (ServerInfo.network_desc == NULL)
1988 <    DupString(ServerInfo.network_desc,NETWORK_DESC_DEFAULT);
1989 <
1990 <  if ((ConfigFileEntry.client_flood < CLIENT_FLOOD_MIN) ||
1991 <      (ConfigFileEntry.client_flood > CLIENT_FLOOD_MAX))
1992 <    ConfigFileEntry.client_flood = CLIENT_FLOOD_MAX;
1454 >  class_delete_marked();      /* Make sure classes are valid */
1455   }
1456  
1457   /* lookup_confhost()
# Line 1997 | Line 1459 | validate_conf(void)
1459   * start DNS lookups of all hostnames in the conf
1460   * line and convert an IP addresses in a.b.c.d number for to IP#s.
1461   */
1462 < static void
1463 < lookup_confhost(struct ConfItem *conf)
1462 > void
1463 > lookup_confhost(struct MaskItem *conf)
1464   {
2003  struct AccessItem *aconf;
1465    struct addrinfo hints, *res;
1466  
2006  aconf = map_to_conf(conf);
2007
2008  if (EmptyString(aconf->host) ||
2009      EmptyString(aconf->user))
2010  {
2011    ilog(L_ERROR, "Host/server name error: (%s) (%s)",
2012         aconf->host, conf->name);
2013    return;
2014  }
2015
2016  if (strchr(aconf->host, '*') ||
2017      strchr(aconf->host, '?'))
2018    return;
2019
1467    /* Do name lookup now on hostnames given and store the
1468     * ip numbers in conf structure.
1469     */
# Line 2028 | Line 1475 | lookup_confhost(struct ConfItem *conf)
1475    /* Get us ready for a bind() and don't bother doing dns lookup */
1476    hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
1477  
1478 <  if (irc_getaddrinfo(aconf->host, NULL, &hints, &res))
1478 >  if (getaddrinfo(conf->host, NULL, &hints, &res))
1479    {
1480 <    conf_dns_lookup(aconf);
1480 >    conf_dns_lookup(conf);
1481      return;
1482    }
1483  
1484    assert(res != NULL);
1485  
1486 <  memcpy(&aconf->ipnum, res->ai_addr, res->ai_addrlen);
1487 <  aconf->ipnum.ss_len = res->ai_addrlen;
1488 <  aconf->ipnum.ss.ss_family = res->ai_family;
1489 <  irc_freeaddrinfo(res);
1486 >  memcpy(&conf->addr, res->ai_addr, res->ai_addrlen);
1487 >  conf->addr.ss_len = res->ai_addrlen;
1488 >  conf->addr.ss.ss_family = res->ai_family;
1489 >
1490 >  freeaddrinfo(res);
1491   }
1492  
1493   /* conf_connect_allowed()
# Line 2053 | Line 1501 | int
1501   conf_connect_allowed(struct irc_ssaddr *addr, int aftype)
1502   {
1503    struct ip_entry *ip_found;
1504 <  struct AccessItem *aconf = find_dline_conf(addr, aftype);
1504 >  struct MaskItem *conf = find_dline_conf(addr, aftype);
1505  
1506    /* DLINE exempt also gets you out of static limits/pacing... */
1507 <  if (aconf && (aconf->status & CONF_EXEMPTDLINE))
1507 >  if (conf && (conf->type == CONF_EXEMPT))
1508      return 0;
1509  
1510 <  if (aconf != NULL)
1510 >  if (conf != NULL)
1511      return BANNED_CLIENT;
1512  
1513    ip_found = find_or_add_ip(addr);
# Line 2075 | Line 1523 | conf_connect_allowed(struct irc_ssaddr *
1523    return 0;
1524   }
1525  
1526 < static struct AccessItem *
1526 > static struct MaskItem *
1527   find_regexp_kline(const char *uhi[])
1528   {
1529 + #ifdef HAVE_LIBPCRE
1530    const dlink_node *ptr = NULL;
1531  
1532    DLINK_FOREACH(ptr, rkconf_items.head)
1533    {
1534 <    struct AccessItem *aptr = map_to_conf(ptr->data);
1534 >    struct MaskItem *aptr = ptr->data;
1535  
1536      assert(aptr->regexuser);
1537      assert(aptr->regexhost);
# Line 2092 | Line 1541 | find_regexp_kline(const char *uhi[])
1541           !ircd_pcre_exec(aptr->regexhost, uhi[2])))
1542        return aptr;
1543    }
1544 <
1544 > #endif
1545    return NULL;
1546   }
1547  
1548   /* find_kill()
1549   *
1550   * inputs       - pointer to client structure
1551 < * output       - pointer to struct AccessItem if found
1551 > * output       - pointer to struct MaskItem if found
1552   * side effects - See if this user is klined already,
1553 < *                and if so, return struct AccessItem pointer
1553 > *                and if so, return struct MaskItem pointer
1554   */
1555 < struct AccessItem *
1555 > struct MaskItem *
1556   find_kill(struct Client *client_p)
1557   {
1558 <  struct AccessItem *aconf = NULL;
1558 >  struct MaskItem *conf = NULL;
1559    const char *uhi[3];
1560  
1561    uhi[0] = client_p->username;
# Line 2115 | Line 1564 | find_kill(struct Client *client_p)
1564  
1565    assert(client_p != NULL);
1566  
1567 <  aconf = find_kline_conf(client_p->host, client_p->username,
1568 <                          &client_p->localClient->ip,
1569 <                          client_p->localClient->aftype);
1570 <  if (aconf == NULL)
1571 <    aconf = find_regexp_kline(uhi);
2123 <
2124 <  if (aconf && (aconf->status & CONF_KLINE))
2125 <    return aconf;
1567 >  conf = find_conf_by_address(client_p->host, &client_p->localClient->ip,
1568 >                              CONF_KLINE, client_p->localClient->aftype,
1569 >                              client_p->username, NULL, 1);
1570 >  if (conf == NULL)
1571 >    conf = find_regexp_kline(uhi);
1572  
1573 <  return NULL;
1573 >  return conf;
1574   }
1575  
1576 < struct AccessItem *
1576 > struct MaskItem *
1577   find_gline(struct Client *client_p)
1578   {
1579 <  struct AccessItem *aconf;
1579 >  struct MaskItem *conf;
1580  
1581    assert(client_p != NULL);
1582  
1583 <  aconf = find_gline_conf(client_p->host, client_p->username,
1584 <                          &client_p->localClient->ip,
1585 <                          client_p->localClient->aftype);
1586 <
2141 <  if (aconf && (aconf->status & CONF_GLINE))
2142 <    return aconf;
2143 <
2144 <  return NULL;
2145 < }
2146 <
2147 < /* add_temp_line()
2148 < *
2149 < * inputs        - pointer to struct ConfItem
2150 < * output        - none
2151 < * Side effects  - links in given struct ConfItem into
2152 < *                 temporary *line link list
2153 < */
2154 < void
2155 < add_temp_line(struct ConfItem *conf)
2156 < {
2157 <  struct AccessItem *aconf;
2158 <
2159 <  if (conf->type == DLINE_TYPE)
2160 <  {
2161 <    aconf = map_to_conf(conf);
2162 <    SetConfTemporary(aconf);
2163 <    dlinkAdd(conf, &conf->node, &temporary_dlines);
2164 <    MyFree(aconf->user);
2165 <    aconf->user = NULL;
2166 <    add_conf_by_address(CONF_DLINE, aconf);
2167 <  }
2168 <  else if (conf->type == KLINE_TYPE)
2169 <  {
2170 <    aconf = map_to_conf(conf);
2171 <    SetConfTemporary(aconf);
2172 <    dlinkAdd(conf, &conf->node, &temporary_klines);
2173 <    add_conf_by_address(CONF_KILL, aconf);
2174 <  }
2175 <  else if (conf->type == GLINE_TYPE)
2176 <  {
2177 <    aconf = map_to_conf(conf);
2178 <    SetConfTemporary(aconf);
2179 <    dlinkAdd(conf, &conf->node, &temporary_glines);
2180 <    add_conf_by_address(CONF_GLINE, aconf);
2181 <  }
2182 <  else if (conf->type == XLINE_TYPE)
2183 <  {
2184 <    conf->flags |= CONF_FLAGS_TEMPORARY;
2185 <    dlinkAdd(conf, make_dlink_node(), &temporary_xlines);
2186 <  }
2187 <  else if (conf->type == RXLINE_TYPE)
2188 <  {
2189 <    conf->flags |= CONF_FLAGS_TEMPORARY;
2190 <    dlinkAdd(conf, make_dlink_node(), &temporary_rxlines);
2191 <  }
2192 <  else if (conf->type == RKLINE_TYPE)
2193 <  {
2194 <    conf->flags |= CONF_FLAGS_TEMPORARY;
2195 <    dlinkAdd(conf, make_dlink_node(), &temporary_rklines);
2196 <  }
2197 <  else if ((conf->type == NRESV_TYPE) || (conf->type == CRESV_TYPE))
2198 <  {
2199 <    conf->flags |= CONF_FLAGS_TEMPORARY;
2200 <    dlinkAdd(conf, make_dlink_node(), &temporary_resv);
2201 <  }
1583 >  conf = find_conf_by_address(client_p->host, &client_p->localClient->ip,
1584 >                              CONF_GLINE, client_p->localClient->aftype,
1585 >                              client_p->username, NULL, 1);
1586 >  return conf;
1587   }
1588  
1589   /* cleanup_tklines()
# Line 2211 | Line 1596 | add_temp_line(struct ConfItem *conf)
1596   void
1597   cleanup_tklines(void *notused)
1598   {
1599 <  expire_tklines(&temporary_glines);
1600 <  expire_tklines(&temporary_klines);
1601 <  expire_tklines(&temporary_dlines);
1602 <  expire_tklines(&temporary_xlines);
2218 <  expire_tklines(&temporary_rxlines);
2219 <  expire_tklines(&temporary_rklines);
2220 <  expire_tklines(&temporary_resv);
1599 >  hostmask_expire_temporary();
1600 >  expire_tklines(&xconf_items);
1601 >  expire_tklines(&nresv_items);
1602 >  expire_tklines(&resv_channel_list);
1603   }
1604  
1605   /* expire_tklines()
# Line 2231 | Line 1613 | expire_tklines(dlink_list *tklist)
1613   {
1614    dlink_node *ptr;
1615    dlink_node *next_ptr;
1616 <  struct ConfItem *conf;
2235 <  struct MatchItem *xconf;
2236 <  struct MatchItem *nconf;
2237 <  struct AccessItem *aconf;
2238 <  struct ResvChannel *cconf;
1616 >  struct MaskItem *conf;
1617  
1618    DLINK_FOREACH_SAFE(ptr, next_ptr, tklist->head)
1619    {
1620      conf = ptr->data;
2243    if (conf->type == GLINE_TYPE ||
2244        conf->type == KLINE_TYPE ||
2245        conf->type == DLINE_TYPE)
2246    {
2247      aconf = (struct AccessItem *)map_to_conf(conf);
2248      if (aconf->hold <= CurrentTime)
2249      {
2250        /* XXX - Do we want GLINE expiry notices?? */
2251        /* Alert opers that a TKline expired - Hwy */
2252        if (ConfigFileEntry.tkline_expire_notices)
2253        {
2254          if (aconf->status & CONF_KILL)
2255          {
2256            sendto_realops_flags(UMODE_ALL, L_ALL,
2257                                 "Temporary K-line for [%s@%s] expired",
2258                                 (aconf->user) ? aconf->user : "*",
2259                                 (aconf->host) ? aconf->host : "*");
2260          }
2261          else if (conf->type == DLINE_TYPE)
2262          {
2263            sendto_realops_flags(UMODE_ALL, L_ALL,
2264                                 "Temporary D-line for [%s] expired",
2265                                 (aconf->host) ? aconf->host : "*");
2266          }
2267        }
1621  
1622 <        delete_one_address_conf(aconf->host, aconf);
1623 <        dlinkDelete(ptr, tklist);
1624 <      }
1625 <    }
2273 <    else if (conf->type == XLINE_TYPE ||
2274 <             conf->type == RXLINE_TYPE)
2275 <    {
2276 <      xconf = (struct MatchItem *)map_to_conf(conf);
2277 <      if (xconf->hold <= CurrentTime)
2278 <      {
2279 <        if (ConfigFileEntry.tkline_expire_notices)
2280 <          sendto_realops_flags(UMODE_ALL, L_ALL,
2281 <                               "Temporary X-line for [%s] %sexpired", conf->name,
2282 <                               conf->type == RXLINE_TYPE ? "(REGEX) " : "");
2283 <        dlinkDelete(ptr, tklist);
2284 <        free_dlink_node(ptr);
2285 <        delete_conf_item(conf);
2286 <      }
2287 <    }
2288 <    else if (conf->type == RKLINE_TYPE)
1622 >    if (!conf->until || conf->until > CurrentTime)
1623 >      continue;
1624 >
1625 >    if (conf->type == CONF_XLINE)
1626      {
1627 <      aconf = map_to_conf(conf);
1628 <      if (aconf->hold <= CurrentTime)
1629 <      {
1630 <        if (ConfigFileEntry.tkline_expire_notices)
2294 <           sendto_realops_flags(UMODE_ALL, L_ALL,
2295 <                                "Temporary K-line for [%s@%s] (REGEX) expired",
2296 <                                (aconf->user) ? aconf->user : "*",
2297 <                                (aconf->host) ? aconf->host : "*");
2298 <        dlinkDelete(ptr, tklist);
2299 <        free_dlink_node(ptr);
2300 <        delete_conf_item(conf);
2301 <      }
1627 >      if (ConfigFileEntry.tkline_expire_notices)
1628 >        sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1629 >                               "Temporary X-line for [%s] expired", conf->name);
1630 >      conf_free(conf);
1631      }
1632 <    else if (conf->type == NRESV_TYPE)
1632 >    else if (conf->type == CONF_NRESV || conf->type == CONF_CRESV)
1633      {
1634 <      nconf = (struct MatchItem *)map_to_conf(conf);
1635 <      if (nconf->hold <= CurrentTime)
2307 <      {
2308 <        if (ConfigFileEntry.tkline_expire_notices)
2309 <          sendto_realops_flags(UMODE_ALL, L_ALL,
1634 >      if (ConfigFileEntry.tkline_expire_notices)
1635 >        sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1636                                 "Temporary RESV for [%s] expired", conf->name);
1637 <        dlinkDelete(ptr, tklist);
2312 <        free_dlink_node(ptr);
2313 <        delete_conf_item(conf);
2314 <      }
2315 <    }
2316 <    else if (conf->type == CRESV_TYPE)
2317 <    {
2318 <      cconf = (struct ResvChannel *)map_to_conf(conf);
2319 <      if (cconf->hold <= CurrentTime)
2320 <      {
2321 <        if (ConfigFileEntry.tkline_expire_notices)
2322 <          sendto_realops_flags(UMODE_ALL, L_ALL,
2323 <                               "Temporary RESV for [%s] expired", cconf->name);
2324 <        dlinkDelete(ptr, tklist);
2325 <        free_dlink_node(ptr);
2326 <        delete_conf_item(conf);
2327 <      }
1637 >      conf_free(conf);
1638      }
1639    }
1640   }
# Line 2337 | Line 1647 | expire_tklines(dlink_list *tklist)
1647   */
1648   static const struct oper_privs
1649   {
1650 <  const unsigned int oprivs;
2341 <  const unsigned int hidden;
1650 >  const unsigned int flag;
1651    const unsigned char c;
1652   } flag_list[] = {
1653 <  { OPER_FLAG_ADMIN,       OPER_FLAG_HIDDEN_ADMIN,  'A' },
1654 <  { OPER_FLAG_REMOTEBAN,   0,                       'B' },
1655 <  { OPER_FLAG_DIE,         0,                       'D' },
1656 <  { OPER_FLAG_GLINE,       0,                       'G' },
1657 <  { OPER_FLAG_REHASH,      0,                       'H' },
1658 <  { OPER_FLAG_K,           0,                       'K' },
1659 <  { OPER_FLAG_OPERWALL,    0,                       'L' },
1660 <  { OPER_FLAG_N,           0,                       'N' },
1661 <  { OPER_FLAG_GLOBAL_KILL, 0,                       'O' },
1662 <  { OPER_FLAG_REMOTE,      0,                       'R' },
1663 <  { OPER_FLAG_OPER_SPY,    0,                       'S' },
1664 <  { OPER_FLAG_UNKLINE,     0,                       'U' },
1665 <  { OPER_FLAG_X,           0,                       'X' },
1666 <  { 0, 0, '\0' }
1653 >  { OPER_FLAG_ADMIN,       'A' },
1654 >  { OPER_FLAG_REMOTEBAN,   'B' },
1655 >  { OPER_FLAG_DIE,         'D' },
1656 >  { OPER_FLAG_GLINE,       'G' },
1657 >  { OPER_FLAG_REHASH,      'H' },
1658 >  { OPER_FLAG_K,           'K' },
1659 >  { OPER_FLAG_OPERWALL,    'L' },
1660 >  { OPER_FLAG_N,           'N' },
1661 >  { OPER_FLAG_GLOBAL_KILL, 'O' },
1662 >  { OPER_FLAG_REMOTE,      'R' },
1663 >  { OPER_FLAG_OPER_SPY,    'S' },
1664 >  { OPER_FLAG_UNKLINE,     'U' },
1665 >  { OPER_FLAG_X,           'X' },
1666 >  { 0, '\0' }
1667   };
1668  
1669   char *
# Line 2362 | Line 1671 | oper_privs_as_string(const unsigned int
1671   {
1672    static char privs_out[16];
1673    char *privs_ptr = privs_out;
1674 <  unsigned int i = 0;
1674 >  const struct oper_privs *opriv = flag_list;
1675  
1676 <  for (; flag_list[i].oprivs; ++i)
1676 >  for (; opriv->flag; ++opriv)
1677    {
1678 <    if ((port & flag_list[i].oprivs) &&
1679 <        (port & flag_list[i].hidden) == 0)
2371 <      *privs_ptr++ = flag_list[i].c;
1678 >    if (port & opriv->flag)
1679 >      *privs_ptr++ = opriv->c;
1680      else
1681 <      *privs_ptr++ = ToLowerTab[flag_list[i].c];
1681 >      *privs_ptr++ = ToLower(opriv->c);
1682    }
1683  
1684    *privs_ptr = '\0';
# Line 2384 | Line 1692 | oper_privs_as_string(const unsigned int
1692   *         "oper" is server name for remote opers
1693   * Side effects: None.
1694   */
1695 < char *
1695 > const char *
1696   get_oper_name(const struct Client *client_p)
1697   {
1698 <  dlink_node *cnode;
2391 <  struct ConfItem *conf;
2392 <  struct AccessItem *aconf;
2393 <
1698 >  dlink_node *cnode = NULL;
1699    /* +5 for !,@,{,} and null */
1700 <  static char buffer[NICKLEN+USERLEN+HOSTLEN+HOSTLEN+5];
1700 >  static char buffer[NICKLEN + USERLEN + HOSTLEN + HOSTLEN + 5];
1701  
1702    if (MyConnect(client_p))
1703    {
1704 <    DLINK_FOREACH(cnode, client_p->localClient->confs.head)
1704 >    if ((cnode = client_p->localClient->confs.head))
1705      {
1706 <      conf = cnode->data;
2402 <      aconf = map_to_conf(conf);
1706 >      struct MaskItem *conf = cnode->data;
1707  
1708 <      if (IsConfOperator(aconf))
1708 >      if (IsConfOperator(conf))
1709        {
1710 <        ircsprintf(buffer, "%s!%s@%s{%s}", client_p->name,
1711 <                   client_p->username, client_p->host,
2408 <                   conf->name);
1710 >        snprintf(buffer, sizeof(buffer), "%s!%s@%s{%s}", client_p->name,
1711 >                 client_p->username, client_p->host, conf->name);
1712          return buffer;
1713        }
1714      }
# Line 2416 | Line 1719 | get_oper_name(const struct Client *clien
1719      assert(0); /* Oper without oper conf! */
1720    }
1721  
1722 <  ircsprintf(buffer, "%s!%s@%s{%s}", client_p->name,
1723 <             client_p->username, client_p->host, client_p->servptr->name);
1722 >  snprintf(buffer, sizeof(buffer), "%s!%s@%s{%s}", client_p->name,
1723 >           client_p->username, client_p->host, client_p->servptr->name);
1724    return buffer;
1725   }
1726  
# Line 2434 | Line 1737 | read_conf_files(int cold)
1737    char chanmodes[32];
1738    char chanlimit[32];
1739  
1740 <  filename = get_conf_name(CONF_TYPE);
1740 >  conf_parser_ctx.boot = cold;
1741 >  filename = ConfigFileEntry.configfile;
1742  
1743    /* We need to know the initial filename for the yyerror() to report
1744       FIXME: The full path is in conffilenamebuf first time since we
# Line 2444 | Line 1748 | read_conf_files(int cold)
1748    */
1749    strlcpy(conffilebuf, filename, sizeof(conffilebuf));
1750  
1751 <  if ((conf_fbfile_in = fbopen(filename, "r")) == NULL)
1751 >  if ((conf_parser_ctx.conf_file = fopen(filename, "r")) == NULL)
1752    {
1753      if (cold)
1754      {
1755 <      ilog(L_CRIT, "Unable to read configuration file '%s': %s",
1755 >      ilog(LOG_TYPE_IRCD, "Unable to read configuration file '%s': %s",
1756             filename, strerror(errno));
1757        exit(-1);
1758      }
1759      else
1760      {
1761 <      sendto_realops_flags(UMODE_ALL, L_ALL,
1761 >      sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1762                             "Unable to read configuration file '%s': %s",
1763                             filename, strerror(errno));
1764        return;
# Line 2464 | Line 1768 | read_conf_files(int cold)
1768    if (!cold)
1769      clear_out_old_conf();
1770  
1771 <  read_conf(conf_fbfile_in);
1772 <  fbclose(conf_fbfile_in);
1771 >  read_conf(conf_parser_ctx.conf_file);
1772 >  fclose(conf_parser_ctx.conf_file);
1773 >
1774 >  log_reopen_all();
1775  
1776 +  add_isupport("NICKLEN", NULL, ServerInfo.max_nick_length);
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 >
1779 >  snprintf(chanmodes, sizeof(chanmodes), "beI:%d", 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);
2479 <  ircsprintf(chanlimit, "%s:%d", ConfigChannel.disable_local_channels ? "#" : "#&",
2480 <             ConfigChannel.max_chans_per_user);
1782 >  add_isupport("CHANTYPES", "#", -1);
1783 >
1784 >  snprintf(chanlimit, sizeof(chanlimit), "#:%d",
1785 >           ConfigChannel.max_chans_per_user);
1786    add_isupport("CHANLIMIT", chanlimit, -1);
1787 <  ircsprintf(chanmodes, "%s%s%s", ConfigChannel.use_except ? "e" : "",
2483 <             ConfigChannel.use_invex ? "I" : "", "b,k,l,imnpst");
1787 >  snprintf(chanmodes, sizeof(chanmodes), "%s", "beI,k,l,imnprstORS");
1788    add_isupport("CHANNELLEN", NULL, LOCAL_CHANNELLEN);
1789 <  if (ConfigChannel.use_except)
1790 <    add_isupport("EXCEPTS", "e", -1);
1791 <  if (ConfigChannel.use_invex)
2488 <    add_isupport("INVEX", "I", -1);
1789 >  add_isupport("TOPICLEN", NULL, ServerInfo.max_topic_length);
1790 >  add_isupport("EXCEPTS", "e", -1);
1791 >  add_isupport("INVEX", "I", -1);
1792    add_isupport("CHANMODES", chanmodes, -1);
1793  
1794    /*
# Line 2493 | Line 1796 | read_conf_files(int cold)
1796     * on strlen(form_str(RPL_ISUPPORT))
1797     */
1798    rebuild_isupport_message_line();
2496
2497  parse_conf_file(KLINE_TYPE, cold);
2498  parse_conf_file(RKLINE_TYPE, cold);
2499  parse_conf_file(DLINE_TYPE, cold);
2500  parse_conf_file(XLINE_TYPE, cold);
2501  parse_conf_file(RXLINE_TYPE, cold);
2502  parse_conf_file(NRESV_TYPE, cold);
2503  parse_conf_file(CRESV_TYPE, cold);
2504 }
2505
2506 /* parse_conf_file()
2507 *
2508 * inputs       - type of conf file to parse
2509 * output       - none
2510 * side effects - conf file for givenconf type is opened and read then parsed
2511 */
2512 static void
2513 parse_conf_file(int type, int cold)
2514 {
2515  FBFILE *file = NULL;
2516  const char *filename = get_conf_name(type);
2517
2518  if ((file = fbopen(filename, "r")) == NULL)
2519  {
2520    if (cold)
2521      ilog(L_ERROR, "Unable to read configuration file '%s': %s",
2522           filename, strerror(errno));
2523    else
2524      sendto_realops_flags(UMODE_ALL, L_ALL,
2525                    "Unable to read configuration file '%s': %s",
2526                           filename, strerror(errno));
2527  }
2528  else
2529  {
2530    parse_csv_file(file, type);
2531    fbclose(file);
2532  }
1799   }
1800  
1801   /* clear_out_old_conf()
# Line 2542 | Line 1808 | static void
1808   clear_out_old_conf(void)
1809   {
1810    dlink_node *ptr = NULL, *next_ptr = NULL;
1811 <  struct ConfItem *conf;
2546 <  struct AccessItem *aconf;
2547 <  struct ClassItem *cltmp;
2548 <  struct MatchItem *match_item;
1811 >  struct MaskItem *conf;
1812    dlink_list *free_items [] = {
1813 <    &server_items,   &oconf_items,    &hub_items, &leaf_items,
1813 >    &server_items,   &oconf_items,
1814       &uconf_items,   &xconf_items, &rxconf_items, &rkconf_items,
1815 <     &nresv_items, &cluster_items,  &gdeny_items, NULL
1815 >     &nresv_items, &cluster_items,  &service_items, &resv_channel_list, NULL
1816    };
1817  
1818    dlink_list ** iterator = free_items; /* C is dumb */
# Line 2563 | Line 1826 | clear_out_old_conf(void)
1826      DLINK_FOREACH_SAFE(ptr, next_ptr, (*iterator)->head)
1827      {
1828        conf = ptr->data;
1829 +
1830 +      dlinkDelete(&conf->node, map_to_list(conf->type));
1831 +
1832        /* XXX This is less than pretty */
1833 <      if (conf->type == SERVER_TYPE)
2568 <      {
2569 <        aconf = (struct AccessItem *)map_to_conf(conf);
2570 <        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)
1833 >      if (conf->type == CONF_SERVER || conf->type == CONF_OPER)
1834        {
1835 <        aconf = (struct AccessItem *)map_to_conf(conf);
1836 <        if (aconf->clients != 0)
2584 <        {
2585 <          SetConfIllegal(aconf);
2586 <          dlinkDelete(&conf->node, &oconf_items);
2587 <        }
2588 <        else
2589 <        {
2590 <          delete_conf_item(conf);
2591 <        }
1835 >        if (!conf->ref_count)
1836 >          conf_free(conf);
1837        }
1838 <      else if (conf->type == CLIENT_TYPE)
1838 >      else if (conf->type == CONF_XLINE  ||
1839 >               conf->type == CONF_RXLINE ||
1840 >               conf->type == CONF_RKLINE)
1841        {
1842 <        aconf = (struct AccessItem *)map_to_conf(conf);
1843 <        if (aconf->clients != 0)
2597 <        {
2598 <          SetConfIllegal(aconf);
2599 <        }
2600 <        else
2601 <        {
2602 <          delete_conf_item(conf);
2603 <        }
2604 <      }
2605 <      else if (conf->type == XLINE_TYPE  ||
2606 <               conf->type == RXLINE_TYPE ||
2607 <               conf->type == RKLINE_TYPE)
2608 <      {
2609 <        /* temporary (r)xlines are also on
2610 <         * the (r)xconf items list */
2611 <        if (conf->flags & CONF_FLAGS_TEMPORARY)
2612 <          continue;
2613 <
2614 <        delete_conf_item(conf);
1842 >        if (!conf->until)
1843 >          conf_free(conf);
1844        }
1845        else
1846 <      {
2618 <        if ((conf->type == LEAF_TYPE) || (conf->type == HUB_TYPE))
2619 <        {
2620 <          match_item = (struct MatchItem *)map_to_conf(conf);
2621 <          if ((match_item->ref_count <= 0))
2622 <            delete_conf_item(conf);
2623 <          else
2624 <          {
2625 <            match_item->illegal = 1;
2626 <            dlinkDelete(&conf->node, *iterator);
2627 <          }
2628 <        }
2629 <        else
2630 <          delete_conf_item(conf);
2631 <      }
1846 >        conf_free(conf);
1847      }
1848    }
1849  
1850 <  /* don't delete the class table, rather mark all entries
1851 <   * for deletion. The table is cleaned up by check_class. - avalon
1850 >  /*
1851 >   * don't delete the class table, rather mark all entries
1852 >   * for deletion. The table is cleaned up by class_delete_marked. - avalon
1853     */
1854 <  DLINK_FOREACH(ptr, class_items.head)
2639 <  {
2640 <    conf = ptr->data;
2641 <    cltmp = (struct ClassItem *)map_to_conf(conf);
2642 <    if (ptr != class_items.tail)  /* never mark the "default" class */
2643 <      MaxTotal(cltmp) = -1;
2644 <  }
1854 >  class_mark_for_deletion();
1855  
1856    clear_out_address_conf();
1857  
1858    /* clean out module paths */
2649 #ifndef STATIC_MODULES
1859    mod_clear_paths();
2651 #endif
1860  
1861    /* clean out ServerInfo */
1862    MyFree(ServerInfo.description);
# Line 2668 | Line 1876 | clear_out_old_conf(void)
1876  
1877    MyFree(ServerInfo.rsa_private_key_file);
1878    ServerInfo.rsa_private_key_file = NULL;
2671 #endif
1879  
1880 <  /* clean out old resvs from the conf */
1881 <  clear_conf_resv();
1880 >  if (ServerInfo.server_ctx)
1881 >    SSL_CTX_set_options(ServerInfo.server_ctx, SSL_OP_NO_SSLv2|
1882 >                                               SSL_OP_NO_SSLv3|
1883 >                                               SSL_OP_NO_TLSv1);
1884 >  if (ServerInfo.client_ctx)
1885 >    SSL_CTX_set_options(ServerInfo.client_ctx, SSL_OP_NO_SSLv2|
1886 >                                               SSL_OP_NO_SSLv3|
1887 >                                               SSL_OP_NO_TLSv1);
1888 > #endif
1889  
1890    /* clean out AdminInfo */
1891    MyFree(AdminInfo.name);
# Line 2681 | Line 1895 | clear_out_old_conf(void)
1895    MyFree(AdminInfo.description);
1896    AdminInfo.description = NULL;
1897  
2684  /* operator{} and class{} blocks are freed above */
1898    /* clean out listeners */
1899    close_listeners();
1900  
2688  /* auth{}, quarantine{}, shared{}, connect{}, kill{}, deny{},
2689   * exempt{} and gecos{} blocks are freed above too
2690   */
2691
1901    /* clean out general */
1902 <  MyFree(ConfigFileEntry.servlink_path);
1903 <  ConfigFileEntry.servlink_path = NULL;
1904 < #ifdef HAVE_LIBCRYPTO
2696 <  ConfigFileEntry.default_cipher_preference = NULL;
2697 < #endif /* HAVE_LIBCRYPTO */
1902 >  MyFree(ConfigFileEntry.service_name);
1903 >  ConfigFileEntry.service_name = NULL;
1904 >
1905    delete_isupport("INVEX");
1906    delete_isupport("EXCEPTS");
1907   }
1908  
2702 /* flush_deleted_I_P()
2703 *
2704 * inputs       - none
2705 * output       - none
2706 * side effects - This function removes I/P conf items
2707 */
2708 static void
2709 flush_deleted_I_P(void)
2710 {
2711  dlink_node *ptr;
2712  dlink_node *next_ptr;
2713  struct ConfItem *conf;
2714  struct AccessItem *aconf;
2715  dlink_list * free_items [] = {
2716    &server_items, &oconf_items, NULL
2717  };
2718  dlink_list ** iterator = free_items; /* C is dumb */
2719
2720  /* flush out deleted I and P lines
2721   * although still in use.
2722   */
2723  for (; *iterator != NULL; iterator++)
2724  {
2725    DLINK_FOREACH_SAFE(ptr, next_ptr, (*iterator)->head)
2726    {
2727      conf = ptr->data;
2728      aconf = (struct AccessItem *)map_to_conf(conf);
2729
2730      if (IsConfIllegal(aconf))
2731      {
2732        dlinkDelete(ptr, *iterator);
2733
2734        if (aconf->clients == 0)
2735          delete_conf_item(conf);
2736      }
2737    }
2738  }
2739 }
2740
2741 /* get_conf_name()
2742 *
2743 * inputs       - type of conf file to return name of file for
2744 * output       - pointer to filename for type of conf
2745 * side effects - none
2746 */
2747 const char *
2748 get_conf_name(ConfType type)
2749 {
2750  switch (type)
2751  {
2752    case CONF_TYPE:
2753      return ConfigFileEntry.configfile;
2754      break;
2755    case KLINE_TYPE:
2756      return ConfigFileEntry.klinefile;
2757      break;
2758    case RKLINE_TYPE:
2759      return ConfigFileEntry.rklinefile;
2760      break;
2761    case DLINE_TYPE:
2762      return ConfigFileEntry.dlinefile;
2763      break;
2764    case XLINE_TYPE:
2765      return ConfigFileEntry.xlinefile;
2766      break;
2767    case RXLINE_TYPE:
2768      return ConfigFileEntry.rxlinefile;
2769      break;
2770    case CRESV_TYPE:
2771      return ConfigFileEntry.cresvfile;
2772      break;
2773    case NRESV_TYPE:
2774      return ConfigFileEntry.nresvfile;
2775      break;
2776    case GLINE_TYPE:
2777      return ConfigFileEntry.glinefile;
2778      break;
2779
2780    default:
2781      return NULL;  /* This should NEVER HAPPEN since we call this function
2782                       only with the above values, this will cause us to core
2783                       at some point if this happens so we know where it was */
2784  }
2785 }
2786
2787 #define BAD_PING (-1)
2788
2789 /* get_conf_ping()
2790 *
2791 * inputs       - pointer to struct AccessItem
2792 *              - pointer to a variable that receives ping warning time
2793 * output       - ping frequency
2794 * side effects - NONE
2795 */
2796 static int
2797 get_conf_ping(struct ConfItem *conf, int *pingwarn)
2798 {
2799  struct ClassItem *aclass;
2800  struct AccessItem *aconf;
2801
2802  if (conf != NULL)
2803  {
2804    aconf = (struct AccessItem *)map_to_conf(conf);
2805    if (aconf->class_ptr != NULL)
2806    {
2807      aclass = (struct ClassItem *)map_to_conf(aconf->class_ptr);
2808      *pingwarn = PingWarning(aclass);
2809      return PingFreq(aclass);
2810    }
2811  }
2812
2813  return BAD_PING;
2814 }
2815
2816 /* get_client_class()
2817 *
2818 * inputs       - pointer to client struct
2819 * output       - pointer to name of class
2820 * side effects - NONE
2821 */
2822 const char *
2823 get_client_class(struct Client *target_p)
2824 {
2825  dlink_node *ptr;
2826  struct ConfItem *conf;
2827  struct AccessItem *aconf;
2828
2829  if (target_p != NULL && !IsMe(target_p) &&
2830      target_p->localClient->confs.head != NULL)
2831  {
2832    DLINK_FOREACH(ptr, target_p->localClient->confs.head)
2833    {
2834      conf = ptr->data;
2835
2836      if (conf->type == CLIENT_TYPE || conf->type == SERVER_TYPE ||
2837          conf->type == OPER_TYPE)
2838      {
2839        aconf = (struct AccessItem *) map_to_conf(conf);
2840        if (aconf->class_ptr != NULL)
2841          return aconf->class_ptr->name;
2842      }
2843    }
2844  }
2845
2846  return "default";
2847 }
2848
2849 /* get_client_ping()
2850 *
2851 * inputs       - pointer to client struct
2852 *              - pointer to a variable that receives ping warning time
2853 * output       - ping frequency
2854 * side effects - NONE
2855 */
2856 int
2857 get_client_ping(struct Client *target_p, int *pingwarn)
2858 {
2859  int ping;
2860  struct ConfItem *conf;
2861  dlink_node *nlink;
2862
2863  if (target_p->localClient->confs.head != NULL)
2864    DLINK_FOREACH(nlink, target_p->localClient->confs.head)
2865    {
2866      conf = nlink->data;
2867
2868      if ((conf->type == CLIENT_TYPE) || (conf->type == SERVER_TYPE) ||
2869          (conf->type == OPER_TYPE))
2870      {
2871        ping = get_conf_ping(conf, pingwarn);
2872        if (ping > 0)
2873          return ping;
2874      }
2875    }
2876
2877  *pingwarn = 0;
2878  return DEFAULT_PINGFREQUENCY;
2879 }
2880
2881 /* find_class()
2882 *
2883 * inputs       - string name of class
2884 * output       - corresponding Class pointer
2885 * side effects - NONE
2886 */
2887 struct ConfItem *
2888 find_class(const char *classname)
2889 {
2890  struct ConfItem *conf;
2891
2892  if ((conf = find_exact_name_conf(CLASS_TYPE, classname, NULL, NULL)) != NULL)
2893    return(conf);
2894
2895  return class_default;
2896 }
2897
2898 /* check_class()
2899 *
2900 * inputs       - NONE
2901 * output       - NONE
2902 * side effects -
2903 */
2904 void
2905 check_class(void)
2906 {
2907  dlink_node *ptr;
2908  dlink_node *next_ptr;
2909  struct ConfItem *conf;
2910  struct ClassItem *aclass;
2911
2912  DLINK_FOREACH_SAFE(ptr, next_ptr, class_items.head)
2913  {
2914    conf = ptr->data;
2915    aclass = (struct ClassItem *)map_to_conf(conf);
2916
2917    if (MaxTotal(aclass) < 0)
2918    {
2919      destroy_cidr_class(aclass);
2920      if (CurrUserCount(aclass) > 0)
2921        dlinkDelete(&conf->node, &class_items);
2922      else
2923        delete_conf_item(conf);
2924    }
2925  }
2926 }
2927
2928 /* init_class()
2929 *
2930 * inputs       - NONE
2931 * output       - NONE
2932 * side effects -
2933 */
2934 void
2935 init_class(void)
2936 {
2937  struct ClassItem *aclass;
2938
2939  class_default = make_conf_item(CLASS_TYPE);
2940  aclass = (struct ClassItem *)map_to_conf(class_default);
2941  DupString(class_default->name, "default");
2942  ConFreq(aclass)  = DEFAULT_CONNECTFREQUENCY;
2943  PingFreq(aclass) = DEFAULT_PINGFREQUENCY;
2944  MaxTotal(aclass) = MAXIMUM_LINKS_DEFAULT;
2945  MaxSendq(aclass) = DEFAULT_SENDQ;
2946
2947  client_check_cb = register_callback("check_client", check_client);
2948 }
2949
2950 /* get_sendq()
2951 *
2952 * inputs       - pointer to client
2953 * output       - sendq for this client as found from its class
2954 * side effects - NONE
2955 */
2956 unsigned long
2957 get_sendq(struct Client *client_p)
2958 {
2959  unsigned long sendq = DEFAULT_SENDQ;
2960  dlink_node *ptr;
2961  struct ConfItem *conf;
2962  struct ConfItem *class_conf;
2963  struct ClassItem *aclass;
2964  struct AccessItem *aconf;
2965
2966  if (client_p && !IsMe(client_p) && (client_p->localClient->confs.head))
2967  {
2968    DLINK_FOREACH(ptr, client_p->localClient->confs.head)
2969    {
2970      conf = ptr->data;
2971      if ((conf->type == SERVER_TYPE) || (conf->type == OPER_TYPE)
2972          || (conf->type == CLIENT_TYPE))
2973      {
2974        aconf = (struct AccessItem *)map_to_conf(conf);
2975        if ((class_conf = aconf->class_ptr) == NULL)
2976          continue;
2977        aclass = (struct ClassItem *)map_to_conf(class_conf);
2978        sendq = MaxSendq(aclass);
2979        return sendq;
2980      }
2981    }
2982  }
2983  /* XXX return a default?
2984   * if here, then there wasn't an attached conf with a sendq
2985   * that is very bad -Dianora
2986   */
2987  return DEFAULT_SENDQ;
2988 }
2989
1909   /* conf_add_class_to_conf()
1910   *
1911   * inputs       - pointer to config item
# Line 2994 | Line 1913 | get_sendq(struct Client *client_p)
1913   * side effects - Add a class pointer to a conf
1914   */
1915   void
1916 < conf_add_class_to_conf(struct ConfItem *conf, const char *class_name)
1916 > conf_add_class_to_conf(struct MaskItem *conf, const char *class_name)
1917   {
2999  struct AccessItem *aconf;
3000  struct ClassItem *aclass;
3001
3002  aconf = (struct AccessItem *)map_to_conf(conf);
3003
1918    if (class_name == NULL)
1919    {
1920 <    aconf->class_ptr = class_default;
1921 <    if (conf->type == CLIENT_TYPE)
1922 <      sendto_realops_flags(UMODE_ALL, L_ALL,
1920 >    conf->class = class_default;
1921 >
1922 >    if (conf->type == CONF_CLIENT)
1923 >      sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1924                             "Warning *** Defaulting to default class for %s@%s",
1925 <                           aconf->user, aconf->host);
1925 >                           conf->user, conf->host);
1926      else
1927 <      sendto_realops_flags(UMODE_ALL, L_ALL,
1927 >      sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1928                             "Warning *** Defaulting to default class for %s",
1929                             conf->name);
1930    }
1931    else
1932 <  {
3018 <    aconf->class_ptr = find_class(class_name);
3019 <  }
1932 >    conf->class = class_find(class_name, 1);
1933  
1934 <  if (aconf->class_ptr == NULL)
1934 >  if (conf->class == NULL)
1935    {
1936 <    if (conf->type == CLIENT_TYPE)
1937 <      sendto_realops_flags(UMODE_ALL, L_ALL,
1936 >    if (conf->type == CONF_CLIENT)
1937 >      sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1938                             "Warning *** Defaulting to default class for %s@%s",
1939 <                           aconf->user, aconf->host);
1939 >                           conf->user, conf->host);
1940      else
1941 <      sendto_realops_flags(UMODE_ALL, L_ALL,
1941 >      sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1942                             "Warning *** Defaulting to default class for %s",
1943                             conf->name);
1944 <    aconf->class_ptr = class_default;
3032 <  }
3033 <  else
3034 <  {
3035 <    aclass = (struct ClassItem *)map_to_conf(aconf->class_ptr);
3036 <    if (MaxTotal(aclass) < 0)
3037 <    {
3038 <      aconf->class_ptr = class_default;
3039 <    }
3040 <  }
3041 < }
3042 <
3043 < #define MAXCONFLINKS 150
3044 <
3045 < /* conf_add_server()
3046 < *
3047 < * inputs       - pointer to config item
3048 < *              - pointer to link count already on this conf
3049 < * output       - NONE
3050 < * side effects - Add a connect block
3051 < */
3052 < int
3053 < conf_add_server(struct ConfItem *conf, unsigned int lcount, const char *class_name)
3054 < {
3055 <  struct AccessItem *aconf;
3056 <  char *orig_host;
3057 <
3058 <  aconf = map_to_conf(conf);
3059 <
3060 <  conf_add_class_to_conf(conf, class_name);
3061 <
3062 <  if (lcount > MAXCONFLINKS || !aconf->host || !conf->name)
3063 <  {
3064 <    sendto_realops_flags(UMODE_ALL, L_ALL, "Bad connect block");
3065 <    ilog(L_WARN, "Bad connect block");
3066 <    return -1;
3067 <  }
3068 <
3069 <  if (EmptyString(aconf->passwd) && !IsConfCryptLink(aconf))
3070 <  {
3071 <    sendto_realops_flags(UMODE_ALL, L_ALL, "Bad connect block, name %s",
3072 <                         conf->name);
3073 <    ilog(L_WARN, "Bad connect block, host %s", conf->name);
3074 <    return -1;
3075 <  }
3076 <
3077 <  orig_host = aconf->host;
3078 <  split_nuh(orig_host, NULL, &aconf->user, &aconf->host);
3079 <  MyFree(orig_host);
3080 <  lookup_confhost(conf);
3081 <
3082 <  return 0;
3083 < }
3084 <
3085 < /* conf_add_d_conf()
3086 < *
3087 < * inputs       - pointer to config item
3088 < * output       - NONE
3089 < * side effects - Add a d/D line
3090 < */
3091 < void
3092 < conf_add_d_conf(struct AccessItem *aconf)
3093 < {
3094 <  if (aconf->host == NULL)
3095 <    return;
3096 <
3097 <  aconf->user = NULL;
3098 <
3099 <  /* XXX - Should 'd' ever be in the old conf? For new conf we don't
3100 <   *       need this anyway, so I will disable it for now... -A1kmm
3101 <   */
3102 <  if (parse_netmask(aconf->host, NULL, NULL) == HM_HOST)
3103 <  {
3104 <    ilog(L_WARN, "Invalid Dline %s ignored", aconf->host);
3105 <    free_access_item(aconf);
3106 <  }
3107 <  else
3108 <  {
3109 <    /* XXX ensure user is NULL */
3110 <    MyFree(aconf->user);
3111 <    aconf->user = NULL;
3112 <    add_conf_by_address(CONF_DLINE, aconf);
1944 >    conf->class = class_default;
1945    }
1946   }
1947  
# Line 3124 | Line 1956 | yyerror(const char *msg)
1956   {
1957    char newlinebuf[IRCD_BUFSIZE];
1958  
1959 <  if (ypass != 1)
1959 >  if (conf_parser_ctx.pass != 1)
1960      return;
1961  
1962    strip_tabs(newlinebuf, linebuf, sizeof(newlinebuf));
1963 <  sendto_realops_flags(UMODE_ALL, L_ALL, "\"%s\", line %u: %s: %s",
1963 >  sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1964 >                       "\"%s\", line %u: %s: %s",
1965                         conffilebuf, lineno + 1, msg, newlinebuf);
1966 <  ilog(L_WARN, "\"%s\", line %u: %s: %s",
1966 >  ilog(LOG_TYPE_IRCD, "\"%s\", line %u: %s: %s",
1967         conffilebuf, lineno + 1, msg, newlinebuf);
1968   }
1969  
1970 < int
1971 < conf_fbgets(char *lbuf, unsigned int max_size, FBFILE *fb)
1970 > void
1971 > conf_error_report(const char *msg)
1972   {
1973 <  if (fbgets(lbuf, max_size, fb) == NULL)
3141 <    return 0;
3142 <
3143 <  return strlen(lbuf);
3144 < }
1973 >  char newlinebuf[IRCD_BUFSIZE];
1974  
1975 < int
1976 < conf_yy_fatal_error(const char *msg)
1977 < {
1978 <  return 0;
1975 >  strip_tabs(newlinebuf, linebuf, sizeof(newlinebuf));
1976 >  sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1977 >                       "\"%s\", line %u: %s: %s",
1978 >                       conffilebuf, lineno + 1, msg, newlinebuf);
1979 >  ilog(LOG_TYPE_IRCD, "\"%s\", line %u: %s: %s",
1980 >       conffilebuf, lineno + 1, msg, newlinebuf);
1981   }
1982  
1983   /*
# Line 3160 | Line 1991 | conf_yy_fatal_error(const char *msg)
1991   * Originally written by Dianora (Diane, db@db.net)
1992   */
1993   time_t
1994 < valid_tkline(char *p, int minutes)
1994 > valid_tkline(const char *p, int minutes)
1995   {
1996    time_t result = 0;
1997  
1998 <  while (*p)
1998 >  for (; *p; ++p)
1999    {
2000 <    if (IsDigit(*p))
3170 <    {
3171 <      result *= 10;
3172 <      result += ((*p) & 0xF);
3173 <      p++;
3174 <    }
3175 <    else
2000 >    if (!IsDigit(*p))
2001        return 0;
2002 +
2003 +    result *= 10;
2004 +    result += ((*p) & 0xF);
2005    }
2006  
2007 <  /* in the degenerate case where oper does a /quote kline 0 user@host :reason
2007 >  /*
2008 >   * In the degenerate case where oper does a /quote kline 0 user@host :reason
2009     * i.e. they specifically use 0, I am going to return 1 instead
2010     * as a return value of non-zero is used to flag it as a temporary kline
2011     */
3183
2012    if (result == 0)
2013      result = 1;
2014  
# Line 3281 | Line 2109 | valid_wild_card(struct Client *source_p,
2109   *                if target_server is NULL and an "ON" is found error
2110   *                is reported.
2111   *                if reason pointer is NULL ignore pointer,
2112 < *                this allows usee of parse_a_line in unkline etc.
2112 > *                this allows use of parse_a_line in unkline etc.
2113   *
2114   * - Dianora
2115   */
# Line 3351 | Line 2179 | parse_aline(const char *cmd, struct Clie
2179          return -1;
2180        }
2181  
2182 <      if (!IsOperRemoteBan(source_p))
2182 >      if (!HasOFlag(source_p, OPER_FLAG_REMOTEBAN))
2183        {
2184          sendto_one(source_p, form_str(ERR_NOPRIVS),
2185                     me.name, source_p->name, "remoteban");
# Line 3388 | Line 2216 | parse_aline(const char *cmd, struct Clie
2216        return -1;
2217      }
2218  
2219 <    if ((parse_flags & AWILD) && !valid_wild_card(source_p, YES, 2, *up_p, *h_p))
2219 >    if ((parse_flags & AWILD) && !valid_wild_card(source_p, 1, 2, *up_p, *h_p))
2220        return -1;
2221    }
2222    else
2223 <    if ((parse_flags & AWILD) && !valid_wild_card(source_p, YES, 1, *up_p))
2223 >    if ((parse_flags & AWILD) && !valid_wild_card(source_p, 1, 1, *up_p))
2224        return -1;
2225  
2226    if (reason != NULL)
2227    {
2228 <    if (parc != 0)
2228 >    if (parc != 0 && !EmptyString(*parv))
2229      {
2230        *reason = *parv;
2231 <      if (!valid_comment(source_p, *reason, YES))
2231 >      if (!valid_comment(source_p, *reason, 1))
2232          return -1;
2233      }
2234      else
# Line 3436 | Line 2264 | find_user_host(struct Client *source_p,
2264    {
2265      /* Explicit user@host mask given */
2266  
2267 <    if(hostp != NULL)                            /* I'm a little user@host */
2267 >    if (hostp != NULL)                            /* I'm a little user@host */
2268      {
2269        *(hostp++) = '\0';                       /* short and squat */
2270        if (*user_host_or_nick)
# Line 3457 | Line 2285 | find_user_host(struct Client *source_p,
2285      
2286      return 1;
2287    }
2288 <  else if (!(flags & NOUSERLOOKUP))
2288 >  else
2289    {
2290      /* Try to find user@host mask from nick */
2291      /* Okay to use source_p as the first param, because source_p == client_p */
# Line 3505 | Line 2333 | find_user_host(struct Client *source_p,
2333   int
2334   valid_comment(struct Client *source_p, char *comment, int warn)
2335   {
3508  if (strchr(comment, '"'))
3509  {
3510    if (warn)
3511      sendto_one(source_p, ":%s NOTICE %s :Invalid character '\"' in comment",
3512                 me.name, source_p->name);
3513    return 0;
3514  }
3515
2336    if (strlen(comment) > REASONLEN)
2337      comment[REASONLEN-1] = '\0';
2338  
# Line 3527 | Line 2347 | valid_comment(struct Client *source_p, c
2347   * side effects - none
2348   */
2349   int
2350 < match_conf_password(const char *password, const struct AccessItem *aconf)
2350 > match_conf_password(const char *password, const struct MaskItem *conf)
2351   {
2352    const char *encr = NULL;
2353  
2354 <  if (password == NULL || aconf->passwd == NULL)
2354 >  if (EmptyString(password) || EmptyString(conf->passwd))
2355      return 0;
2356  
2357 <  if (aconf->flags & CONF_FLAGS_ENCRYPTED)
2358 <  {
3539 <    /* use first two chars of the password they send in as salt */
3540 <    /* If the password in the conf is MD5, and ircd is linked
3541 <     * to scrypt on FreeBSD, or the standard crypt library on
3542 <     * glibc Linux, then this code will work fine on generating
3543 <     * the proper encrypted hash for comparison.
3544 <     */
3545 <    if (*aconf->passwd)
3546 <      encr = crypt(password, aconf->passwd);
3547 <    else
3548 <      encr = "";
3549 <  }
2357 >  if (conf->flags & CONF_FLAGS_ENCRYPTED)
2358 >    encr = crypt(password, conf->passwd);
2359    else
2360      encr = password;
2361  
2362 <  return !strcmp(encr, aconf->passwd);
2362 >  return !strcmp(encr, conf->passwd);
2363   }
2364  
2365   /*
# Line 3559 | Line 2368 | match_conf_password(const char *password
2368   * inputs       - client sending the cluster
2369   *              - command name "KLINE" "XLINE" etc.
2370   *              - capab -- CAP_KLN etc. from s_serv.h
2371 < *              - cluster type -- CLUSTER_KLINE etc. from s_conf.h
2371 > *              - cluster type -- CLUSTER_KLINE etc. from conf.h
2372   *              - pattern and args to send along
2373   * output       - none
2374   * side effects - Take source_p send the pattern with args given
# Line 3567 | Line 2376 | match_conf_password(const char *password
2376   */
2377   void
2378   cluster_a_line(struct Client *source_p, const char *command,
2379 <               int capab, int cluster_type, const char *pattern, ...)
2379 >               int capab, int cluster_type, const char *pattern, ...)
2380   {
2381    va_list args;
2382    char buffer[IRCD_BUFSIZE];
2383 <  struct ConfItem *conf;
3575 <  dlink_node *ptr;
2383 >  const dlink_node *ptr = NULL;
2384  
2385    va_start(args, pattern);
2386    vsnprintf(buffer, sizeof(buffer), pattern, args);
# Line 3580 | Line 2388 | cluster_a_line(struct Client *source_p,
2388  
2389    DLINK_FOREACH(ptr, cluster_items.head)
2390    {
2391 <    conf = ptr->data;
2391 >    const struct MaskItem *conf = ptr->data;
2392  
2393      if (conf->flags & cluster_type)
3586    {
2394        sendto_match_servs(source_p, conf->name, CAP_CLUSTER|capab,
2395                           "%s %s %s", command, conf->name, buffer);
3589    }
2396    }
2397   }
2398  
# Line 3618 | Line 2424 | cluster_a_line(struct Client *source_p,
2424   * @                            *       *       *
2425   * !                            *       *       *
2426   */
3621
2427   void
2428 < split_nuh(char *mask, char **nick, char **user, char **host)
2428 > split_nuh(struct split_nuh_item *const iptr)
2429   {
2430    char *p = NULL, *q = NULL;
2431  
2432 <  if ((p = strchr(mask, '!')) != NULL)
2432 >  if (iptr->nickptr)
2433 >    strlcpy(iptr->nickptr, "*", iptr->nicksize);
2434 >  if (iptr->userptr)
2435 >    strlcpy(iptr->userptr, "*", iptr->usersize);
2436 >  if (iptr->hostptr)
2437 >    strlcpy(iptr->hostptr, "*", iptr->hostsize);
2438 >
2439 >  if ((p = strchr(iptr->nuhmask, '!')))
2440    {
2441      *p = '\0';
3630    if (nick != NULL)
3631    {
3632      if (*mask != '\0')
3633        *nick = xstrldup(mask, NICKLEN);
3634      else
3635        DupString(*nick, "*");
3636    }
2442  
2443 <    if ((q = strchr(++p, '@')) != NULL)
2444 <    {
2445 <      *q = '\0';
2443 >    if (iptr->nickptr && *iptr->nuhmask != '\0')
2444 >      strlcpy(iptr->nickptr, iptr->nuhmask, iptr->nicksize);
2445 >
2446 >    if ((q = strchr(++p, '@'))) {
2447 >      *q++ = '\0';
2448  
2449        if (*p != '\0')
2450 <        *user = xstrldup(p, USERLEN+1);
3644 <      else
3645 <        DupString(*user, "*");
2450 >        strlcpy(iptr->userptr, p, iptr->usersize);
2451  
2452 <      if (*++q != '\0')
2453 <        *host = xstrldup(q, HOSTLEN+1);
3649 <      else
3650 <        DupString(*host, "*");
2452 >      if (*q != '\0')
2453 >        strlcpy(iptr->hostptr, q, iptr->hostsize);
2454      }
2455      else
2456      {
2457        if (*p != '\0')
2458 <        *user = xstrldup(p, USERLEN+1);
3656 <      else
3657 <        DupString(*user, "*");
3658 <
3659 <      DupString(*host, "*");
2458 >        strlcpy(iptr->userptr, p, iptr->usersize);
2459      }
2460    }
2461 <  else  /* No ! found so lets look for a user@host */
2461 >  else
2462    {
2463 <    if ((p = strchr(mask, '@')) != NULL)        /* if found a @ */
2463 >    /* No ! found so lets look for a user@host */
2464 >    if ((p = strchr(iptr->nuhmask, '@')))
2465      {
2466 <      if (nick != NULL)
2467 <        DupString(*nick, "*");
3668 <      *p = '\0';
2466 >      /* if found a @ */
2467 >      *p++ = '\0';
2468  
2469 <      if (*mask != '\0')
2470 <        *user = xstrldup(mask, USERLEN+1);
3672 <      else
3673 <        DupString(*user, "*");
2469 >      if (*iptr->nuhmask != '\0')
2470 >        strlcpy(iptr->userptr, iptr->nuhmask, iptr->usersize);
2471  
2472 <      if (*++p != '\0')
2473 <        *host = xstrldup(p, HOSTLEN+1);
3677 <      else
3678 <        DupString(*host, "*");
2472 >      if (*p != '\0')
2473 >        strlcpy(iptr->hostptr, p, iptr->hostsize);
2474      }
2475 <    else                                        /* no @ found */
2475 >    else
2476      {
2477 <      if (nick != NULL)
2478 <      {
2479 <        if (strpbrk(mask, ".:"))
3685 <        {
3686 <          DupString(*nick, "*");
3687 <          *host = xstrldup(mask, HOSTLEN+1);
3688 <        }
3689 <        else
3690 <        {
3691 <          *nick = xstrldup(mask, NICKLEN);
3692 <          DupString(*host, "*");
3693 <        }
3694 <
3695 <        DupString(*user, "*");
3696 <      }
2477 >      /* no @ found */
2478 >      if (!iptr->nickptr || strpbrk(iptr->nuhmask, ".:"))
2479 >        strlcpy(iptr->hostptr, iptr->nuhmask, iptr->hostsize);
2480        else
2481 <      {
3699 <        DupString(*user, "*");
3700 <        *host = xstrldup(mask, HOSTLEN+1);
3701 <      }
3702 <    }
3703 <  }
3704 < }
3705 <
3706 < /*
3707 < * flags_to_ascii
3708 < *
3709 < * inputs       - flags is a bitmask
3710 < *              - pointer to table of ascii letters corresponding
3711 < *                to each bit
3712 < *              - flag 1 for convert ToLower if bit missing
3713 < *                0 if ignore.
3714 < * output       - none
3715 < * side effects - string pointed to by p has bitmap chars written to it
3716 < */
3717 < static void
3718 < flags_to_ascii(unsigned int flags, const unsigned int bit_table[], char *p,
3719 <               int lowerit)
3720 < {
3721 <  unsigned int mask = 1;
3722 <  int i = 0;
3723 <
3724 <  for (mask = 1; (mask != 0) && (bit_table[i] != 0); mask <<= 1, i++)
3725 <  {
3726 <    if (flags & mask)
3727 <      *p++ = bit_table[i];
3728 <    else if(lowerit)
3729 <      *p++ = ToLower(bit_table[i]);
3730 <  }
3731 <  *p = '\0';
3732 < }
3733 <
3734 < /*
3735 < * cidr_limit_reached
3736 < *
3737 < * inputs       - int flag allowing over_rule of limits
3738 < *              - pointer to the ip to be added
3739 < *              - pointer to the class
3740 < * output       - non zero if limit reached
3741 < *                0 if limit not reached
3742 < * side effects -
3743 < */
3744 < static int
3745 < cidr_limit_reached(int over_rule,
3746 <                   struct irc_ssaddr *ip, struct ClassItem *aclass)
3747 < {
3748 <  dlink_node *ptr = NULL;
3749 <  struct CidrItem *cidr;
3750 <
3751 <  if (NumberPerCidr(aclass) <= 0)
3752 <    return 0;
3753 <
3754 <  if (ip->ss.ss_family == AF_INET)
3755 <  {
3756 <    if (CidrBitlenIPV4(aclass) <= 0)
3757 <      return 0;
3758 <
3759 <    DLINK_FOREACH(ptr, aclass->list_ipv4.head)
3760 <    {
3761 <      cidr = ptr->data;
3762 <      if (match_ipv4(ip, &cidr->mask, CidrBitlenIPV4(aclass)))
3763 <      {
3764 <        if (!over_rule && (cidr->number_on_this_cidr >= NumberPerCidr(aclass)))
3765 <          return -1;
3766 <        cidr->number_on_this_cidr++;
3767 <        return 0;
3768 <      }
3769 <    }
3770 <    cidr = MyMalloc(sizeof(struct CidrItem));
3771 <    cidr->number_on_this_cidr = 1;
3772 <    cidr->mask = *ip;
3773 <    mask_addr(&cidr->mask, CidrBitlenIPV4(aclass));
3774 <    dlinkAdd(cidr, &cidr->node, &aclass->list_ipv4);
3775 <  }
3776 < #ifdef IPV6
3777 <  else if (CidrBitlenIPV6(aclass) > 0)
3778 <  {
3779 <    DLINK_FOREACH(ptr, aclass->list_ipv6.head)
3780 <    {
3781 <      cidr = ptr->data;
3782 <      if (match_ipv6(ip, &cidr->mask, CidrBitlenIPV6(aclass)))
3783 <      {
3784 <        if (!over_rule && (cidr->number_on_this_cidr >= NumberPerCidr(aclass)))
3785 <          return -1;
3786 <        cidr->number_on_this_cidr++;
3787 <        return 0;
3788 <      }
3789 <    }
3790 <    cidr = MyMalloc(sizeof(struct CidrItem));
3791 <    cidr->number_on_this_cidr = 1;
3792 <    cidr->mask = *ip;
3793 <    mask_addr(&cidr->mask, CidrBitlenIPV6(aclass));
3794 <    dlinkAdd(cidr, &cidr->node, &aclass->list_ipv6);
3795 <  }
3796 < #endif
3797 <  return 0;
3798 < }
3799 <
3800 < /*
3801 < * remove_from_cidr_check
3802 < *
3803 < * inputs       - pointer to the ip to be removed
3804 < *              - pointer to the class
3805 < * output       - NONE
3806 < * side effects -
3807 < */
3808 < static void
3809 < remove_from_cidr_check(struct irc_ssaddr *ip, struct ClassItem *aclass)
3810 < {
3811 <  dlink_node *ptr = NULL;
3812 <  dlink_node *next_ptr = NULL;
3813 <  struct CidrItem *cidr;
3814 <
3815 <  if (NumberPerCidr(aclass) == 0)
3816 <    return;
3817 <
3818 <  if (ip->ss.ss_family == AF_INET)
3819 <  {
3820 <    if (CidrBitlenIPV4(aclass) <= 0)
3821 <      return;
3822 <
3823 <    DLINK_FOREACH_SAFE(ptr, next_ptr, aclass->list_ipv4.head)
3824 <    {
3825 <      cidr = ptr->data;
3826 <      if (match_ipv4(ip, &cidr->mask, CidrBitlenIPV4(aclass)))
3827 <      {
3828 <        cidr->number_on_this_cidr--;
3829 <        if (cidr->number_on_this_cidr == 0)
3830 <        {
3831 <          dlinkDelete(ptr, &aclass->list_ipv4);
3832 <          MyFree(cidr);
3833 <          return;
3834 <        }
3835 <      }
3836 <    }
3837 <  }
3838 < #ifdef IPV6
3839 <  else if (CidrBitlenIPV6(aclass) > 0)
3840 <  {
3841 <    DLINK_FOREACH_SAFE(ptr, next_ptr, aclass->list_ipv6.head)
3842 <    {
3843 <      cidr = ptr->data;
3844 <      if (match_ipv6(ip, &cidr->mask, CidrBitlenIPV6(aclass)))
3845 <      {
3846 <        cidr->number_on_this_cidr--;
3847 <        if (cidr->number_on_this_cidr == 0)
3848 <        {
3849 <          dlinkDelete(ptr, &aclass->list_ipv6);
3850 <          MyFree(cidr);
3851 <          return;
3852 <        }
3853 <      }
3854 <    }
3855 <  }
3856 < #endif
3857 < }
3858 <
3859 < static void
3860 < rebuild_cidr_list(int aftype, struct ConfItem *oldcl, struct ClassItem *newcl,
3861 <                  dlink_list *old_list, dlink_list *new_list, int changed)
3862 < {
3863 <  dlink_node *ptr;
3864 <  struct Client *client_p;
3865 <  struct ConfItem *conf;
3866 <  struct AccessItem *aconf;
3867 <
3868 <  if (!changed)
3869 <  {
3870 <    *new_list = *old_list;
3871 <    old_list->head = old_list->tail = NULL;
3872 <    old_list->length = 0;
3873 <    return;
3874 <  }
3875 <
3876 <  DLINK_FOREACH(ptr, local_client_list.head)
3877 <  {
3878 <    client_p = ptr->data;
3879 <    if (client_p->localClient->aftype != aftype)
3880 <      continue;
3881 <    if (dlink_list_length(&client_p->localClient->confs) == 0)
3882 <      continue;
3883 <
3884 <    conf = client_p->localClient->confs.tail->data;
3885 <    if (conf->type == CLIENT_TYPE)
3886 <    {
3887 <      aconf = map_to_conf(conf);
3888 <      if (aconf->class_ptr == oldcl)
3889 <        cidr_limit_reached(1, &client_p->localClient->ip, newcl);
2481 >        strlcpy(iptr->nickptr, iptr->nuhmask, iptr->nicksize);
2482      }
2483    }
2484   }
3893
3894 /*
3895 * rebuild_cidr_class
3896 *
3897 * inputs       - pointer to old conf
3898 *              - pointer to new_class
3899 * output       - none
3900 * side effects - rebuilds the class link list of cidr blocks
3901 */
3902 void
3903 rebuild_cidr_class(struct ConfItem *conf, struct ClassItem *new_class)
3904 {
3905  struct ClassItem *old_class = map_to_conf(conf);
3906
3907  if (NumberPerCidr(old_class) > 0 && NumberPerCidr(new_class) > 0)
3908  {
3909    if (CidrBitlenIPV4(old_class) > 0 && CidrBitlenIPV4(new_class) > 0)
3910      rebuild_cidr_list(AF_INET, conf, new_class,
3911                        &old_class->list_ipv4, &new_class->list_ipv4,
3912                        CidrBitlenIPV4(old_class) != CidrBitlenIPV4(new_class));
3913
3914 #ifdef IPV6
3915    if (CidrBitlenIPV6(old_class) > 0 && CidrBitlenIPV6(new_class) > 0)
3916      rebuild_cidr_list(AF_INET6, conf, new_class,
3917                        &old_class->list_ipv6, &new_class->list_ipv6,
3918                        CidrBitlenIPV6(old_class) != CidrBitlenIPV6(new_class));
3919 #endif
3920  }
3921
3922  destroy_cidr_class(old_class);
3923 }
3924
3925 /*
3926 * destroy_cidr_list
3927 *
3928 * inputs       - pointer to class dlink list of cidr blocks
3929 * output       - none
3930 * side effects - completely destroys the class link list of cidr blocks
3931 */
3932 static void
3933 destroy_cidr_list(dlink_list *list)
3934 {
3935  dlink_node *ptr = NULL;
3936  dlink_node *next_ptr = NULL;
3937  struct CidrItem *cidr;
3938
3939  DLINK_FOREACH_SAFE(ptr, next_ptr, list->head)
3940  {
3941    cidr = ptr->data;
3942    dlinkDelete(ptr, list);
3943    MyFree(cidr);
3944  }
3945 }
3946
3947 /*
3948 * destroy_cidr_class
3949 *
3950 * inputs       - pointer to class
3951 * output       - none
3952 * side effects - completely destroys the class link list of cidr blocks
3953 */
3954 static void
3955 destroy_cidr_class(struct ClassItem *aclass)
3956 {
3957  destroy_cidr_list(&aclass->list_ipv4);
3958  destroy_cidr_list(&aclass->list_ipv6);
3959 }

Diff Legend

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