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 1904 by michael, Sat Apr 27 21:16:22 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:
203 <    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;
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 >  }
204  
205 <    default:
206 <      break;
207 <    }
208 <    break;
205 >  DLINK_FOREACH_SAFE(ptr, ptr_next, conf->leaf_list.head)
206 >  {
207 >    MyFree(ptr->data);
208 >    free_dlink_node(ptr);
209 >  }
210  
211 <  case HUB_TYPE:
212 <    match_item = map_to_conf(conf);
213 <    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;
211 >  DLINK_FOREACH_SAFE(ptr, ptr_next, conf->exempt_list.head)
212 >  {
213 >    struct exempt *exptr = ptr->data;
214  
215 <  default:
216 <    break;
215 >    MyFree(exptr->name);
216 >    MyFree(exptr->user);
217 >    MyFree(exptr->host);
218 >    MyFree(exptr);
219    }
540 }
220  
221 < /* free_access_item()
543 < *
544 < * inputs       - pointer to conf to free
545 < * output       - none
546 < * 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;
552 <
553 <  if (aconf == NULL)
554 <    return;
555 <  conf = unmap_conf_item(aconf);
556 <  delete_conf_item(conf);
221 >  MyFree(conf);
222   }
223  
224 < static const unsigned int shared_bit_table[] =
225 <  { 'K', 'k', 'U', 'X', 'x', 'Y', 'Q', 'q', 'R', 'L', 0};
224 > static const struct shared_flags
225 > {
226 >  const unsigned int type;
227 >  const unsigned char letter;
228 > } flag_table[] = {
229 >  { SHARED_KLINE,   'K' },
230 >  { SHARED_UNKLINE, 'U' },
231 >  { SHARED_XLINE,   'X' },
232 >  { SHARED_UNXLINE, 'Y' },
233 >  { SHARED_RESV,    'Q' },
234 >  { SHARED_UNRESV,  'R' },
235 >  { SHARED_LOCOPS,  'L' },
236 >  { SHARED_DLINE,   'D' },
237 >  { SHARED_UNDLINE, 'E' },
238 >  { 0, '\0' }
239 > };
240  
241 < /* report_confitem_types()
563 < *
241 > /*
242   * inputs       - pointer to client requesting confitem report
243   *              - ConfType to report
244   * output       - none
245   * side effects -
246   */
247   void
248 < report_confitem_types(struct Client *source_p, ConfType type, int temp)
248 > report_confitem_types(struct Client *source_p, enum maskitem_type type)
249   {
250 <  dlink_node *ptr = NULL;
251 <  struct ConfItem *conf = NULL;
252 <  struct AccessItem *aconf = NULL;
253 <  struct MatchItem *matchitem = NULL;
576 <  struct ClassItem *classitem = NULL;
250 >  dlink_node *ptr = NULL, *dptr = NULL;
251 >  struct MaskItem *conf = NULL;
252 >  const struct ClassItem *class = NULL;
253 >  const struct shared_flags *shared = NULL;
254    char buf[12];
255    char *p = NULL;
256  
257    switch (type)
258    {
259 <  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:
259 >  case CONF_XLINE:
260      DLINK_FOREACH(ptr, xconf_items.head)
261      {
262        conf = ptr->data;
612      matchitem = map_to_conf(conf);
263  
264        sendto_one(source_p, form_str(RPL_STATSXLINE),
265                   me.name, source_p->name,
266 <                 matchitem->hold ? "x": "X", matchitem->count,
267 <                 conf->name, matchitem->reason);
266 >                 conf->until ? "x": "X", conf->count,
267 >                 conf->name, conf->reason);
268      }
269      break;
270  
271 <  case RXLINE_TYPE:
271 > #ifdef HAVE_LIBPCRE
272 >  case CONF_RXLINE:
273      DLINK_FOREACH(ptr, rxconf_items.head)
274      {
275        conf = ptr->data;
625      matchitem = map_to_conf(conf);
276  
277        sendto_one(source_p, form_str(RPL_STATSXLINE),
278                   me.name, source_p->name,
279 <                 matchitem->hold ? "xR": "XR", matchitem->count,
280 <                 conf->name, matchitem->reason);
279 >                 "XR", conf->count,
280 >                 conf->name, conf->reason);
281      }
282      break;
283  
284 <  case RKLINE_TYPE:
635 <    p = temp ? "Rk" : "RK";
636 <
284 >  case CONF_RKLINE:
285      DLINK_FOREACH(ptr, rkconf_items.head)
286      {
287 <      aconf = map_to_conf((conf = ptr->data));
640 <
641 <      if (temp && !(conf->flags & CONF_FLAGS_TEMPORARY))
642 <        continue;
287 >      conf = ptr->data;
288  
289        sendto_one(source_p, form_str(RPL_STATSKLINE), me.name,
290 <                 source_p->name, p, aconf->host, aconf->user,
291 <                 aconf->reason, aconf->oper_reason ? aconf->oper_reason : "");
290 >                 source_p->name, "KR", conf->host, conf->user,
291 >                 conf->reason);
292      }
293      break;
294 + #endif
295  
296 <  case ULINE_TYPE:
296 >  case CONF_ULINE:
297 >    shared = flag_table;
298      DLINK_FOREACH(ptr, uconf_items.head)
299      {
300        conf = ptr->data;
654      matchitem = map_to_conf(conf);
301  
302        p = buf;
303  
658      /* some of these are redundant for the sake of
659       * consistency with cluster{} flags
660       */
304        *p++ = 'c';
305 <      flags_to_ascii(matchitem->action, shared_bit_table, p, 0);
305 >      for (; shared->type; ++shared)
306 >        if (shared->type & conf->flags)
307 >          *p++ = shared->letter;
308 >        else
309 >          *p++ = ToLower(shared->letter);
310  
311        sendto_one(source_p, form_str(RPL_STATSULINE),
312                   me.name, source_p->name, conf->name,
313 <                 matchitem->user?matchitem->user: "*",
314 <                 matchitem->host?matchitem->host: "*", buf);
313 >                 conf->user?conf->user: "*",
314 >                 conf->host?conf->host: "*", buf);
315      }
316  
317 +    shared = flag_table;
318      DLINK_FOREACH(ptr, cluster_items.head)
319      {
320        conf = ptr->data;
# Line 674 | Line 322 | report_confitem_types(struct Client *sou
322        p = buf;
323  
324        *p++ = 'C';
325 <      flags_to_ascii(conf->flags, shared_bit_table, p, 0);
325 >      for (; shared->type; ++shared)
326 >        if (shared->type & conf->flags)
327 >          *p++ = shared->letter;
328 >        else
329 >          *p++ = ToLower(shared->letter);
330  
331        sendto_one(source_p, form_str(RPL_STATSULINE),
332                   me.name, source_p->name, conf->name,
# Line 683 | Line 335 | report_confitem_types(struct Client *sou
335  
336      break;
337  
338 <  case OPER_TYPE:
338 >  case CONF_OPER:
339      DLINK_FOREACH(ptr, oconf_items.head)
340      {
341        conf = ptr->data;
690      aconf = map_to_conf(conf);
342  
343        /* Don't allow non opers to see oper privs */
344 <      if (IsOper(source_p))
344 >      if (HasUMode(source_p, UMODE_OPER))
345          sendto_one(source_p, form_str(RPL_STATSOLINE),
346 <                   me.name, source_p->name, 'O', aconf->user, aconf->host,
347 <                   conf->name, oper_privs_as_string(aconf->port),
348 <                   aconf->class_ptr ? aconf->class_ptr->name : "<default>");
346 >                   me.name, source_p->name, 'O', conf->user, conf->host,
347 >                   conf->name, oper_privs_as_string(conf->port),
348 >                   conf->class ? conf->class->name : "<default>");
349        else
350          sendto_one(source_p, form_str(RPL_STATSOLINE),
351 <                   me.name, source_p->name, 'O', aconf->user, aconf->host,
351 >                   me.name, source_p->name, 'O', conf->user, conf->host,
352                     conf->name, "0",
353 <                   aconf->class_ptr ? aconf->class_ptr->name : "<default>");
353 >                   conf->class ? conf->class->name : "<default>");
354      }
355      break;
356  
357 <  case CLASS_TYPE:
358 <    DLINK_FOREACH(ptr, class_items.head)
357 >  case CONF_CLASS:
358 >    DLINK_FOREACH(ptr, class_get_list()->head)
359      {
360 <      conf = ptr->data;
710 <      classitem = map_to_conf(conf);
360 >      class = ptr->data;
361        sendto_one(source_p, form_str(RPL_STATSYLINE),
362                   me.name, source_p->name, 'Y',
363 <                 conf->name, PingFreq(classitem),
364 <                 ConFreq(classitem),
365 <                 MaxTotal(classitem), MaxSendq(classitem));
363 >                 class->name, class->ping_freq,
364 >                 class->con_freq,
365 >                 class->max_total, class->max_sendq,
366 >                 class->max_recvq,
367 >                 class->ref_count,
368 >                 class->number_per_cidr, class->cidr_bitlen_ipv4,
369 >                 class->number_per_cidr, class->cidr_bitlen_ipv6,
370 >                 class->active ? "active" : "disabled");
371      }
372      break;
373  
374 <  case CONF_TYPE:
375 <  case CLIENT_TYPE:
374 >  case CONF_SERVICE:
375 >    DLINK_FOREACH(ptr, service_items.head)
376 >    {
377 >      conf = ptr->data;
378 >      sendto_one(source_p, form_str(RPL_STATSSERVICE),
379 >                 me.name, source_p->name, 'S', "*", conf->name, 0, 0);
380 >    }
381      break;
382  
383 <  case SERVER_TYPE:
383 >  case CONF_SERVER:
384      DLINK_FOREACH(ptr, server_items.head)
385      {
386        p = buf;
727
387        conf = ptr->data;
729      aconf = map_to_conf(conf);
388  
389        buf[0] = '\0';
390  
391 <      if (IsConfAllowAutoConn(aconf))
391 >      if (IsConfAllowAutoConn(conf))
392          *p++ = 'A';
393 <      if (IsConfCryptLink(aconf))
394 <        *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';
393 >      if (IsConfSSL(conf))
394 >        *p++ = 'S';
395        if (buf[0] == '\0')
396          *p++ = '*';
397  
398        *p = '\0';
399  
400 <      /* Allow admins to see actual ips
401 <       * unless hide_server_ips is enabled
400 >      /*
401 >       * Allow admins to see actual ips unless hide_server_ips is enabled
402         */
403 <      if (!ConfigServerHide.hide_server_ips && IsAdmin(source_p))
403 >      if (!ConfigServerHide.hide_server_ips && HasUMode(source_p, UMODE_ADMIN))
404          sendto_one(source_p, form_str(RPL_STATSCLINE),
405 <                   me.name, source_p->name, 'C', aconf->host,
406 <                   buf, conf->name, aconf->port,
407 <                   aconf->class_ptr ? aconf->class_ptr->name : "<default>");
405 >                   me.name, source_p->name, 'C', conf->host,
406 >                   buf, conf->name, conf->port,
407 >                   conf->class ? conf->class->name : "<default>");
408          else
409            sendto_one(source_p, form_str(RPL_STATSCLINE),
410                       me.name, source_p->name, 'C',
411 <                     "*@127.0.0.1", buf, conf->name, aconf->port,
412 <                     aconf->class_ptr ? aconf->class_ptr->name : "<default>");
411 >                     "*@127.0.0.1", buf, conf->name, conf->port,
412 >                     conf->class ? conf->class->name : "<default>");
413      }
414      break;
415  
416 <  case HUB_TYPE:
417 <    DLINK_FOREACH(ptr, hub_items.head)
416 >  case CONF_HUB:
417 >    DLINK_FOREACH(ptr, server_items.head)
418      {
419        conf = ptr->data;
420 <      matchitem = map_to_conf(conf);
421 <      sendto_one(source_p, form_str(RPL_STATSHLINE), me.name,
422 <                 source_p->name, 'H', matchitem->host, conf->name, 0, "*");
420 >
421 >      DLINK_FOREACH(dptr, conf->hub_list.head)
422 >        sendto_one(source_p, form_str(RPL_STATSHLINE), me.name,
423 >                   source_p->name, 'H', dptr->data, conf->name, 0, "*");
424      }
774    break;
425  
426 <  case LEAF_TYPE:
777 <    DLINK_FOREACH(ptr, leaf_items.head)
426 >    DLINK_FOREACH(ptr, server_items.head)
427      {
428        conf = ptr->data;
429 <      matchitem = map_to_conf(conf);
430 <      sendto_one(source_p, form_str(RPL_STATSLLINE), me.name,
431 <                 source_p->name, 'L', matchitem->host, conf->name, 0, "*");
429 >
430 >      DLINK_FOREACH(dptr, conf->leaf_list.head)
431 >        sendto_one(source_p, form_str(RPL_STATSLLINE), me.name,
432 >                   source_p->name, 'L', dptr->data, conf->name, 0, "*");
433      }
434 +
435      break;
436  
437 <  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:
437 >  default:
438      break;
439    }
440   }
# Line 807 | Line 452 | report_confitem_types(struct Client *sou
452   *                Look for conf lines which have the same
453   *                status as the flags passed.
454   */
455 < static void *
456 < check_client(va_list args)
455 > int
456 > check_client(struct Client *source_p)
457   {
813  struct Client *source_p = va_arg(args, struct Client *);
814  const char *username = va_arg(args, const char *);
458    int i;
459  
460 <  /* I'm already in big trouble if source_p->localClient is NULL -db */
461 <  if ((i = verify_access(source_p, username)))
819 <  {
820 <    ilog(L_INFO, "Access denied: %s[%s]",
460 >  if ((i = verify_access(source_p)))
461 >    ilog(LOG_TYPE_IRCD, "Access denied: %s[%s]",
462           source_p->name, source_p->sockhost);
822  }
463  
464    switch (i)
465    {
826    case IRCD_SOCKET_ERROR:
827      exit_client(source_p, &me, "Socket Error");
828      break;
829
466      case TOO_MANY:
467 <      sendto_realops_flags(UMODE_FULL, L_ALL,
467 >      sendto_realops_flags(UMODE_FULL, L_ALL, SEND_NOTICE,
468                             "Too many on IP for %s (%s).",
469                             get_client_name(source_p, SHOW_IP),
470                             source_p->sockhost);
471 <      ilog(L_INFO,"Too many connections on IP from %s.",
471 >      ilog(LOG_TYPE_IRCD, "Too many connections on IP from %s.",
472             get_client_name(source_p, SHOW_IP));
473 <      ServerStats->is_ref++;
473 >      ++ServerStats.is_ref;
474        exit_client(source_p, &me, "No more connections allowed on that IP");
475        break;
476  
477      case I_LINE_FULL:
478 <      sendto_realops_flags(UMODE_FULL, L_ALL,
479 <                           "I-line is full for %s (%s).",
478 >      sendto_realops_flags(UMODE_FULL, L_ALL, SEND_NOTICE,
479 >                           "auth{} block is full for %s (%s).",
480                             get_client_name(source_p, SHOW_IP),
481                             source_p->sockhost);
482 <      ilog(L_INFO,"Too many connections from %s.",
482 >      ilog(LOG_TYPE_IRCD, "Too many connections from %s.",
483             get_client_name(source_p, SHOW_IP));
484 <       ServerStats->is_ref++;
484 >      ++ServerStats.is_ref;
485        exit_client(source_p, &me,
486                  "No more connections allowed in your connection class");
487        break;
488  
489      case NOT_AUTHORIZED:
490 <    {
855 <      static char ipaddr[HOSTIPLEN];
856 <      ServerStats->is_ref++;
490 >      ++ServerStats.is_ref;
491        /* jdc - lists server name & port connections are on */
492        /*       a purely cosmetical change */
493 <      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,
493 >      sendto_realops_flags(UMODE_UNAUTH, L_ALL, SEND_NOTICE,
494                             "Unauthorized client connection from %s [%s] on [%s/%u].",
495                             get_client_name(source_p, SHOW_IP),
496 <                           ipaddr,
496 >                           source_p->sockhost,
497                             source_p->localClient->listener->name,
498                             source_p->localClient->listener->port);
499 <      ilog(L_INFO,
499 >      ilog(LOG_TYPE_IRCD,
500            "Unauthorized client connection from %s on [%s/%u].",
501            get_client_name(source_p, SHOW_IP),
502            source_p->localClient->listener->name,
503            source_p->localClient->listener->port);
504  
505 <      /* 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");
505 >      exit_client(source_p, &me, "You are not authorized to use this server");
506        break;
507 <    }
889 <
507 >
508     case BANNED_CLIENT:
509 <     /*
510 <      * 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++;
509 >     exit_client(source_p, &me, "Banned");
510 >     ++ServerStats.is_ref;
511       break;
512  
513     case 0:
# Line 907 | Line 515 | check_client(va_list args)
515       break;
516    }
517  
518 <  return (i < 0 ? NULL : source_p);
518 >  return (i < 0 ? 0 : 1);
519   }
520  
521   /* verify_access()
522   *
523   * inputs       - pointer to client to verify
916 *              - pointer to proposed username
524   * output       - 0 if success -'ve if not
525   * side effect  - find the first (best) I line to attach.
526   */
527   static int
528 < verify_access(struct Client *client_p, const char *username)
528 > verify_access(struct Client *client_p)
529   {
530 <  struct AccessItem *aconf = NULL, *rkconf = NULL;
924 <  struct ConfItem *conf = NULL;
530 >  struct MaskItem *conf = NULL, *rkconf = NULL;
531    char non_ident[USERLEN + 1] = { '~', '\0' };
532    const char *uhi[3];
533  
534    if (IsGotId(client_p))
535    {
536 <    aconf = find_address_conf(client_p->host, client_p->username,
536 >    conf = find_address_conf(client_p->host, client_p->username,
537                               &client_p->localClient->ip,
538                               client_p->localClient->aftype,
539                               client_p->localClient->passwd);
540    }
541    else
542    {
543 <    strlcpy(non_ident+1, username, sizeof(non_ident)-1);
544 <    aconf = find_address_conf(client_p->host,non_ident,
543 >    strlcpy(non_ident+1, client_p->username, sizeof(non_ident)-1);
544 >    conf = find_address_conf(client_p->host,non_ident,
545                               &client_p->localClient->ip,
546                               client_p->localClient->aftype,
547                               client_p->localClient->passwd);
# Line 947 | Line 553 | verify_access(struct Client *client_p, c
553  
554    rkconf = find_regexp_kline(uhi);
555  
556 <  if (aconf != NULL)
556 >  if (conf != NULL)
557    {
558 <    if (IsConfClient(aconf) && !rkconf)
558 >    if (IsConfClient(conf) && !rkconf)
559      {
560 <      conf = unmap_conf_item(aconf);
955 <
956 <      if (IsConfRedir(aconf))
560 >      if (IsConfRedir(conf))
561        {
562          sendto_one(client_p, form_str(RPL_REDIR),
563                     me.name, client_p->name,
564                     conf->name ? conf->name : "",
565 <                   aconf->port);
565 >                   conf->port);
566          return(NOT_AUTHORIZED);
567        }
568  
569 <      if (IsConfDoIdentd(aconf))
569 >      if (IsConfDoIdentd(conf))
570          SetNeedId(client_p);
571  
572        /* Thanks for spoof idea amm */
573 <      if (IsConfDoSpoofIp(aconf))
573 >      if (IsConfDoSpoofIp(conf))
574        {
575 <        conf = unmap_conf_item(aconf);
576 <
577 <        if (!ConfigFileEntry.hide_spoof_ips && IsConfSpoofNotice(aconf))
974 <          sendto_realops_flags(UMODE_ALL, L_ADMIN, "%s spoofing: %s as %s",
575 >        if (!ConfigFileEntry.hide_spoof_ips && IsConfSpoofNotice(conf))
576 >          sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
577 >                               "%s spoofing: %s as %s",
578                                 client_p->name, client_p->host, conf->name);
579          strlcpy(client_p->host, conf->name, sizeof(client_p->host));
580          SetIPSpoof(client_p);
# Line 979 | Line 582 | verify_access(struct Client *client_p, c
582  
583        return(attach_iline(client_p, conf));
584      }
585 <    else if (rkconf || IsConfKill(aconf) || (ConfigFileEntry.glines && IsConfGline(aconf)))
585 >    else if (rkconf || IsConfKill(conf) || (ConfigFileEntry.glines && IsConfGline(conf)))
586      {
587        /* XXX */
588 <      aconf = rkconf ? rkconf : aconf;
589 <      if (IsConfGline(aconf))
588 >      conf = rkconf ? rkconf : conf;
589 >      if (IsConfGline(conf))
590          sendto_one(client_p, ":%s NOTICE %s :*** G-lined", me.name,
591                     client_p->name);
592 <      if (ConfigFileEntry.kline_with_reason)
593 <        sendto_one(client_p, ":%s NOTICE %s :*** Banned %s",
991 <                  me.name, client_p->name, aconf->reason);
592 >      sendto_one(client_p, ":%s NOTICE %s :*** Banned: %s",
593 >                 me.name, client_p->name, conf->reason);
594        return(BANNED_CLIENT);
595      }
596    }
# Line 1004 | Line 606 | verify_access(struct Client *client_p, c
606   * side effects - do actual attach
607   */
608   static int
609 < attach_iline(struct Client *client_p, struct ConfItem *conf)
609 > attach_iline(struct Client *client_p, struct MaskItem *conf)
610   {
611 <  struct AccessItem *aconf;
1010 <  struct ClassItem *aclass;
611 >  struct ClassItem *class = NULL;
612    struct ip_entry *ip_found;
613    int a_limit_reached = 0;
614 <  int local = 0, global = 0, ident = 0;
614 >  unsigned int local = 0, global = 0, ident = 0;
615  
616    ip_found = find_or_add_ip(&client_p->localClient->ip);
617    ip_found->count++;
618    SetIpHash(client_p);
619  
620 <  aconf = (struct AccessItem *)map_to_conf(conf);
1020 <  if (aconf->class_ptr == NULL)
620 >  if (conf->class == NULL)
621      return NOT_AUTHORIZED;  /* If class is missing, this is best */
622  
623 <  aclass = (struct ClassItem *)map_to_conf(aconf->class_ptr);
623 >  class = conf->class;
624  
625    count_user_host(client_p->username, client_p->host,
626                    &global, &local, &ident);
# Line 1029 | Line 629 | attach_iline(struct Client *client_p, st
629     * setting a_limit_reached if any limit is reached.
630     * - Dianora
631     */
632 <  if (MaxTotal(aclass) != 0 && CurrUserCount(aclass) >= MaxTotal(aclass))
632 >  if (class->max_total != 0 && class->ref_count >= class->max_total)
633      a_limit_reached = 1;
634 <  else if (MaxPerIp(aclass) != 0 && ip_found->count >= MaxPerIp(aclass))
634 >  else if (class->max_perip != 0 && ip_found->count > class->max_perip)
635      a_limit_reached = 1;
636 <  else if (MaxLocal(aclass) != 0 && local >= MaxLocal(aclass))
636 >  else if (class->max_local != 0 && local >= class->max_local)
637      a_limit_reached = 1;
638 <  else if (MaxGlobal(aclass) != 0 && global >= MaxGlobal(aclass))
638 >  else if (class->max_global != 0 && global >= class->max_global)
639      a_limit_reached = 1;
640 <  else if (MaxIdent(aclass) != 0 && ident >= MaxIdent(aclass) &&
640 >  else if (class->max_ident != 0 && ident >= class->max_ident &&
641             client_p->username[0] != '~')
642      a_limit_reached = 1;
643  
644    if (a_limit_reached)
645    {
646 <    if (!IsConfExemptLimits(aconf))
647 <      return TOO_MANY;  /* Already at maximum allowed */
646 >    if (!IsConfExemptLimits(conf))
647 >      return TOO_MANY;   /* Already at maximum allowed */
648  
649      sendto_one(client_p,
650                 ":%s NOTICE %s :*** Your connection class is full, "
# Line 1064 | Line 664 | attach_iline(struct Client *client_p, st
664   void
665   init_ip_hash_table(void)
666   {
667 <  ip_entry_heap = BlockHeapCreate("ip", sizeof(struct ip_entry),
667 >  ip_entry_pool = mp_pool_new(sizeof(struct ip_entry),
668      2 * hard_fdlimit);
669    memset(ip_hash_table, 0, sizeof(ip_hash_table));
670   }
# Line 1114 | Line 714 | find_or_add_ip(struct irc_ssaddr *ip_in)
714    if (ip_entries_count >= 2 * hard_fdlimit)
715      garbage_collect_ip_entries();
716  
717 <  newptr = BlockHeapAlloc(ip_entry_heap);
717 >  newptr = mp_pool_get(ip_entry_pool);
718 >  memset(newptr, 0, sizeof(*newptr));
719    ip_entries_count++;
720    memcpy(&newptr->ip, ip_in, sizeof(struct irc_ssaddr));
721  
# Line 1172 | Line 773 | remove_one_ip(struct irc_ssaddr *ip_in)
773        else
774          ip_hash_table[hash_index] = ptr->next;
775  
776 <      BlockHeapFree(ip_entry_heap, ptr);
776 >      mp_pool_release(ptr);
777        ip_entries_count--;
778        return;
779      }
# Line 1193 | Line 794 | hash_ip(struct irc_ssaddr *addr)
794    {
795      struct sockaddr_in *v4 = (struct sockaddr_in *)addr;
796      int hash;
797 <    u_int32_t ip;
797 >    uint32_t ip;
798  
799      ip   = ntohl(v4->sin_addr.s_addr);
800      hash = ((ip >> 12) + ip) & (IP_HASH_SIZE-1);
# Line 1204 | Line 805 | hash_ip(struct irc_ssaddr *addr)
805    {
806      int hash;
807      struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)addr;
808 <    u_int32_t *ip = (u_int32_t *)&v6->sin6_addr.s6_addr;
808 >    uint32_t *ip = (uint32_t *)&v6->sin6_addr.s6_addr;
809  
810      hash  = ip[0] ^ ip[3];
811      hash ^= hash >> 16;  
# Line 1228 | Line 829 | hash_ip(struct irc_ssaddr *addr)
829   * used in the hash.
830   */
831   void
832 < count_ip_hash(int *number_ips_stored, unsigned long *mem_ips_stored)
832 > count_ip_hash(unsigned int *number_ips_stored, uint64_t *mem_ips_stored)
833   {
834    struct ip_entry *ptr;
835    int i;
# Line 1275 | Line 876 | garbage_collect_ip_entries(void)
876            last_ptr->next = ptr->next;
877          else
878            ip_hash_table[i] = ptr->next;
879 <        BlockHeapFree(ip_entry_heap, ptr);
879 >        mp_pool_release(ptr);
880          ip_entries_count--;
881        }
882        else
# Line 1292 | Line 893 | garbage_collect_ip_entries(void)
893   * side effects - Disassociate configuration from the client.
894   *                Also removes a class from the list if marked for deleting.
895   */
896 < int
897 < detach_conf(struct Client *client_p, ConfType type)
896 > void
897 > detach_conf(struct Client *client_p, enum maskitem_type type)
898   {
899 <  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;
899 >  dlink_node *ptr = NULL, *next_ptr = NULL;
900  
901    DLINK_FOREACH_SAFE(ptr, next_ptr, client_p->localClient->confs.head)
902    {
903 <    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);
903 >    struct MaskItem *conf = ptr->data;
904  
905 <      switch (conf->type)
906 <      {
907 <      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);
905 >    assert(conf->type & (CONF_CLIENT | CONF_OPER | CONF_SERVER));
906 >    assert(conf->ref_count > 0);
907 >    assert(conf->class->ref_count > 0);
908  
909 <          if (conf->type == CLIENT_TYPE)
910 <            remove_from_cidr_check(&client_p->localClient->ip, aclass);
909 >    if (!(conf->type & type))
910 >      continue;
911  
912 <          if (CurrUserCount(aclass) > 0)
913 <            aclass->curr_user_count--;
1329 <          if (MaxTotal(aclass) < 0 && CurrUserCount(aclass) <= 0)
1330 <            delete_conf_item(aclass_conf);
1331 <        }
912 >    dlinkDelete(ptr, &client_p->localClient->confs);
913 >    free_dlink_node(ptr);
914  
915 <        /* Please, no ioccc entries - Dianora */
916 <        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 <      }
915 >    if (conf->type == CONF_CLIENT)
916 >      remove_from_cidr_check(&client_p->localClient->ip, conf->class);
917  
918 <      if (type != CONF_TYPE)
919 <        return 0;
918 >    if (--conf->class->ref_count == 0 && conf->class->active == 0)
919 >    {
920 >      class_free(conf->class);
921 >      conf->class = NULL;
922      }
1352  }
923  
924 <  return -1;
924 >    if (--conf->ref_count == 0 && conf->active == 0)
925 >      conf_free(conf);
926 >  }
927   }
928  
929   /* attach_conf()
# Line 1365 | Line 937 | detach_conf(struct Client *client_p, Con
937   *                attachment if there was an old one...
938   */
939   int
940 < attach_conf(struct Client *client_p, struct ConfItem *conf)
940 > attach_conf(struct Client *client_p, struct MaskItem *conf)
941   {
1370  struct AccessItem *aconf;
1371  struct MatchItem *match_item;
1372
942    if (dlinkFind(&client_p->localClient->confs, conf) != NULL)
943      return 1;
944  
945 <  if (conf->type == CLIENT_TYPE ||
946 <      conf->type == SERVER_TYPE ||
947 <      conf->type == OPER_TYPE)
948 <  {
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 <    }
945 >  if (conf->type == CONF_CLIENT)
946 >    if (cidr_limit_reached(IsConfExemptLimits(conf),
947 >                           &client_p->localClient->ip, conf->class))
948 >      return TOO_MANY;    /* Already at maximum allowed */
949  
950 <    aconf->clients++;
951 <  }
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 <  }
950 >  conf->class->ref_count++;
951 >  conf->ref_count++;
952  
953    dlinkAdd(conf, make_dlink_node(), &client_p->localClient->confs);
954  
# Line 1420 | Line 968 | attach_connect_block(struct Client *clie
968                       const char *host)
969   {
970    dlink_node *ptr;
971 <  struct ConfItem *conf;
1424 <  struct AccessItem *aconf;
971 >  struct MaskItem *conf = NULL;
972  
973    assert(client_p != NULL);
974    assert(host != NULL);
# Line 1432 | Line 979 | attach_connect_block(struct Client *clie
979    DLINK_FOREACH(ptr, server_items.head)
980    {
981      conf = ptr->data;
1435    aconf = (struct AccessItem *)map_to_conf(conf);
982  
983 <    if (match(conf->name, name) == 0 || match(aconf->host, host) == 0)
983 >    if (match(conf->name, name) || match(conf->host, host))
984        continue;
985  
986      attach_conf(client_p, conf);
# Line 1444 | Line 990 | attach_connect_block(struct Client *clie
990    return 0;
991   }
992  
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
993   /* find_conf_name()
994   *
995   * inputs       - pointer to conf link list to search
# Line 1511 | Line 999 | find_conf_exact(ConfType type, const cha
999   * side effects - find a conf entry which matches the name
1000   *                and has the given mask.
1001   */
1002 < struct ConfItem *
1003 < find_conf_name(dlink_list *list, const char *name, ConfType type)
1002 > struct MaskItem *
1003 > find_conf_name(dlink_list *list, const char *name, enum maskitem_type type)
1004   {
1005    dlink_node *ptr;
1006 <  struct ConfItem* conf;
1006 >  struct MaskItem* conf;
1007  
1008    DLINK_FOREACH(ptr, list->head)
1009    {
# Line 1524 | Line 1012 | find_conf_name(dlink_list *list, const c
1012      if (conf->type == type)
1013      {
1014        if (conf->name && (irccmp(conf->name, name) == 0 ||
1015 <                         match(conf->name, name)))
1015 >                         !match(conf->name, name)))
1016        return conf;
1017      }
1018    }
# Line 1539 | Line 1027 | find_conf_name(dlink_list *list, const c
1027   * side effects - none
1028   */
1029   static dlink_list *
1030 < map_to_list(ConfType type)
1030 > map_to_list(enum maskitem_type type)
1031   {
1032    switch(type)
1033    {
1034 <  case RXLINE_TYPE:
1034 >  case CONF_RKLINE:
1035 >    return(&rkconf_items);
1036 >    break;
1037 >  case CONF_RXLINE:
1038      return(&rxconf_items);
1039      break;
1040 <  case XLINE_TYPE:
1040 >  case CONF_XLINE:
1041      return(&xconf_items);
1042      break;
1043 <  case ULINE_TYPE:
1043 >  case CONF_ULINE:
1044      return(&uconf_items);
1045      break;
1046 <  case NRESV_TYPE:
1046 >  case CONF_NRESV:
1047      return(&nresv_items);
1048      break;
1049 <  case OPER_TYPE:
1049 >  case CONF_CRESV:
1050 >    return(&resv_channel_list);
1051 >  case CONF_OPER:
1052      return(&oconf_items);
1053      break;
1054 <  case CLASS_TYPE:
1562 <    return(&class_items);
1563 <    break;
1564 <  case SERVER_TYPE:
1054 >  case CONF_SERVER:
1055      return(&server_items);
1056      break;
1057 <  case CLUSTER_TYPE:
1057 >  case CONF_SERVICE:
1058 >    return(&service_items);
1059 >    break;
1060 >  case CONF_CLUSTER:
1061      return(&cluster_items);
1062      break;
1570  case CONF_TYPE:
1571  case GLINE_TYPE:
1572  case KLINE_TYPE:
1573  case DLINE_TYPE:
1574  case CRESV_TYPE:
1063    default:
1064      return NULL;
1065    }
# Line 1583 | Line 1071 | map_to_list(ConfType type)
1071   *              - pointer to name string to find
1072   *              - pointer to user
1073   *              - pointer to host
1074 < *              - optional action to match on as well
1075 < * output       - NULL or pointer to found struct MatchItem
1074 > *              - optional flags to match on as well
1075 > * output       - NULL or pointer to found struct MaskItem
1076   * side effects - looks for a match on name field
1077   */
1078 < struct ConfItem *
1079 < find_matching_name_conf(ConfType type, const char *name, const char *user,
1080 <                        const char *host, int action)
1078 > struct MaskItem *
1079 > find_matching_name_conf(enum maskitem_type type, const char *name, const char *user,
1080 >                        const char *host, unsigned int flags)
1081   {
1082    dlink_node *ptr=NULL;
1083 <  struct ConfItem *conf=NULL;
1596 <  struct AccessItem *aconf=NULL;
1597 <  struct MatchItem *match_item=NULL;
1083 >  struct MaskItem *conf=NULL;
1084    dlink_list *list_p = map_to_list(type);
1085  
1086    switch (type)
1087    {
1088 <    case RXLINE_TYPE:
1088 > #ifdef HAVE_LIBPCRE
1089 >  case CONF_RXLINE:
1090        DLINK_FOREACH(ptr, list_p->head)
1091        {
1092          conf = ptr->data;
1093 <        assert(conf->regexpname);
1093 >        assert(conf->regexuser);
1094  
1095 <        if (!ircd_pcre_exec(conf->regexpname, name))
1095 >        if (!ircd_pcre_exec(conf->regexuser, name))
1096            return conf;
1097        }
1098        break;
1099 + #endif
1100 +  case CONF_SERVICE:
1101 +    DLINK_FOREACH(ptr, list_p->head)
1102 +    {
1103 +      conf = ptr->data;
1104  
1105 <  case XLINE_TYPE:
1106 <  case ULINE_TYPE:
1107 <  case NRESV_TYPE:
1105 >      if (EmptyString(conf->name))
1106 >        continue;
1107 >      if ((name != NULL) && !irccmp(name, conf->name))
1108 >        return conf;
1109 >    }
1110 >    break;
1111 >
1112 >  case CONF_XLINE:
1113 >  case CONF_ULINE:
1114 >  case CONF_NRESV:
1115 >  case CONF_CRESV:
1116      DLINK_FOREACH(ptr, list_p->head)
1117      {
1118        conf = ptr->data;
1119  
1620      match_item = map_to_conf(conf);
1120        if (EmptyString(conf->name))
1121          continue;
1122 <      if ((name != NULL) && match_esc(conf->name, name))
1122 >      if ((name != NULL) && !match(conf->name, name))
1123        {
1124          if ((user == NULL && (host == NULL)))
1125            return conf;
1126 <        if ((match_item->action & action) != action)
1126 >        if ((conf->flags & flags) != flags)
1127            continue;
1128 <        if (EmptyString(match_item->user) || EmptyString(match_item->host))
1128 >        if (EmptyString(conf->user) || EmptyString(conf->host))
1129            return conf;
1130 <        if (match(match_item->user, user) && match(match_item->host, host))
1130 >        if (!match(conf->user, user) && !match(conf->host, host))
1131            return conf;
1132        }
1133      }
1134        break;
1135  
1136 <  case SERVER_TYPE:
1136 >  case CONF_SERVER:
1137      DLINK_FOREACH(ptr, list_p->head)
1138      {
1139        conf = ptr->data;
1641      aconf = map_to_conf(conf);
1140  
1141 <      if ((name != NULL) && match_esc(name, conf->name))
1141 >      if ((name != NULL) && !match(name, conf->name))
1142          return conf;
1143 <      else if ((host != NULL) && match_esc(host, aconf->host))
1143 >      else if ((host != NULL) && !match(host, conf->host))
1144          return conf;
1145      }
1146      break;
# Line 1659 | Line 1157 | find_matching_name_conf(ConfType type, c
1157   *              - pointer to name string to find
1158   *              - pointer to user
1159   *              - pointer to host
1160 < * output       - NULL or pointer to found struct MatchItem
1160 > * output       - NULL or pointer to found struct MaskItem
1161   * side effects - looks for an exact match on name field
1162   */
1163 < struct ConfItem *
1164 < find_exact_name_conf(ConfType type, const char *name,
1163 > struct MaskItem *
1164 > find_exact_name_conf(enum maskitem_type type, const struct Client *who, const char *name,
1165                       const char *user, const char *host)
1166   {
1167    dlink_node *ptr = NULL;
1168 <  struct AccessItem *aconf;
1169 <  struct ConfItem *conf;
1672 <  struct MatchItem *match_item;
1673 <  dlink_list *list_p;
1674 <
1675 <  list_p = map_to_list(type);
1168 >  struct MaskItem *conf;
1169 >  dlink_list *list_p = map_to_list(type);
1170  
1171    switch(type)
1172    {
1173 <  case RXLINE_TYPE:
1174 <  case XLINE_TYPE:
1175 <  case ULINE_TYPE:
1176 <  case NRESV_TYPE:
1173 >  case CONF_RXLINE:
1174 >  case CONF_XLINE:
1175 >  case CONF_ULINE:
1176 >  case CONF_NRESV:
1177 >  case CONF_CRESV:
1178  
1179      DLINK_FOREACH(ptr, list_p->head)
1180      {
1181        conf = ptr->data;
1182 <      match_item = (struct MatchItem *)map_to_conf(conf);
1182 >
1183        if (EmptyString(conf->name))
1184          continue;
1185      
# Line 1692 | Line 1187 | find_exact_name_conf(ConfType type, cons
1187        {
1188          if ((user == NULL && (host == NULL)))
1189            return (conf);
1190 <        if (EmptyString(match_item->user) || EmptyString(match_item->host))
1190 >        if (EmptyString(conf->user) || EmptyString(conf->host))
1191            return (conf);
1192 <        if (match(match_item->user, user) && match(match_item->host, host))
1192 >        if (!match(conf->user, user) && !match(conf->host, host))
1193            return (conf);
1194        }
1195      }
1196      break;
1197  
1198 <  case OPER_TYPE:
1198 >  case CONF_OPER:
1199      DLINK_FOREACH(ptr, list_p->head)
1200      {
1201        conf = ptr->data;
1202 <      aconf = (struct AccessItem *)map_to_conf(conf);
1202 >
1203        if (EmptyString(conf->name))
1204 <        continue;
1205 <    
1206 <      if (irccmp(conf->name, name) == 0)
1204 >        continue;
1205 >
1206 >      if (!irccmp(conf->name, name))
1207        {
1208 <        if ((user == NULL && (host == NULL)))
1209 <          return (conf);
1210 <        if (EmptyString(aconf->user) || EmptyString(aconf->host))
1211 <          return (conf);
1212 <        if (match(aconf->user, user) && match(aconf->host, host))
1213 <          return (conf);
1208 >        if (!who)
1209 >          return conf;
1210 >        if (EmptyString(conf->user) || EmptyString(conf->host))
1211 >          return NULL;
1212 >        if (!match(conf->user, who->username))
1213 >        {
1214 >          switch (conf->htype)
1215 >          {
1216 >            case HM_HOST:
1217 >              if (!match(conf->host, who->host) || !match(conf->host, who->sockhost))
1218 >                if (!conf->class->max_total || conf->class->ref_count < conf->class->max_total)
1219 >                  return conf;
1220 >              break;
1221 >            case HM_IPV4:
1222 >              if (who->localClient->aftype == AF_INET)
1223 >                if (match_ipv4(&who->localClient->ip, &conf->addr, conf->bits))
1224 >                  if (!conf->class->max_total || conf->class->ref_count < conf->class->max_total)
1225 >                    return conf;
1226 >              break;
1227 > #ifdef IPV6
1228 >            case HM_IPV6:
1229 >              if (who->localClient->aftype == AF_INET6)
1230 >                if (match_ipv6(&who->localClient->ip, &conf->addr, conf->bits))
1231 >                  if (!conf->class->max_total || conf->class->ref_count < conf->class->max_total)
1232 >                    return conf;
1233 >              break;
1234 > #endif
1235 >            default:
1236 >              assert(0);
1237 >          }
1238 >        }
1239        }
1240      }
1241 +
1242      break;
1243  
1244 <  case SERVER_TYPE:
1244 >  case CONF_SERVER:
1245      DLINK_FOREACH(ptr, list_p->head)
1246      {
1247        conf = ptr->data;
1248 <      aconf = (struct AccessItem *)map_to_conf(conf);
1248 >
1249        if (EmptyString(conf->name))
1250          continue;
1251      
1252        if (name == NULL)
1253        {
1254 <        if (EmptyString(aconf->host))
1254 >        if (EmptyString(conf->host))
1255            continue;
1256 <        if (irccmp(aconf->host, host) == 0)
1256 >        if (irccmp(conf->host, host) == 0)
1257            return(conf);
1258        }
1259        else if (irccmp(conf->name, name) == 0)
# Line 1742 | Line 1263 | find_exact_name_conf(ConfType type, cons
1263      }
1264      break;
1265  
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
1266    default:
1267      break;
1268    }
# Line 1770 | Line 1279 | int
1279   rehash(int sig)
1280   {
1281    if (sig != 0)
1282 <    sendto_realops_flags(UMODE_ALL, L_ALL,
1282 >    sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1283                           "Got signal SIGHUP, reloading ircd.conf file");
1284  
1776 #ifndef _WIN32
1285    restart_resolver();
1286 < #endif
1286 >
1287    /* don't close listeners until we know we can go ahead with the rehash */
1288  
1289    /* Check to see if we magically got(or lost) IPv6 support */
# Line 1786 | Line 1294 | rehash(int sig)
1294    if (ServerInfo.description != NULL)
1295      strlcpy(me.info, ServerInfo.description, sizeof(me.info));
1296  
1789 #ifndef STATIC_MODULES
1297    load_conf_modules();
1791 #endif
1792
1793  flush_deleted_I_P();
1298  
1299    rehashed_klines = 1;
1300  
1301 <  if (ConfigLoggingEntry.use_logging)
1798 <    reopen_log(logFileName);
1799 <
1800 <  return(0);
1301 >  return 0;
1302   }
1303  
1304   /* set_default_conf()
# Line 1815 | Line 1316 | set_default_conf(void)
1316    /* verify init_class() ran, this should be an unnecessary check
1317     * but its not much work.
1318     */
1319 <  assert(class_default == (struct ConfItem *) class_items.tail->data);
1319 >  assert(class_default == class_get_list()->tail->data);
1320  
1321   #ifdef HAVE_LIBCRYPTO
1322    ServerInfo.rsa_private_key = NULL;
# Line 1825 | Line 1326 | set_default_conf(void)
1326    /* ServerInfo.name is not rehashable */
1327    /* ServerInfo.name = ServerInfo.name; */
1328    ServerInfo.description = NULL;
1329 <  DupString(ServerInfo.network_name, NETWORK_NAME_DEFAULT);
1330 <  DupString(ServerInfo.network_desc, NETWORK_DESC_DEFAULT);
1329 >  ServerInfo.network_name = xstrdup(NETWORK_NAME_DEFAULT);
1330 >  ServerInfo.network_desc = xstrdup(NETWORK_DESC_DEFAULT);
1331  
1332    memset(&ServerInfo.ip, 0, sizeof(ServerInfo.ip));
1333    ServerInfo.specific_ipv4_vhost = 0;
# Line 1834 | Line 1335 | set_default_conf(void)
1335    ServerInfo.specific_ipv6_vhost = 0;
1336  
1337    ServerInfo.max_clients = MAXCLIENTS_MAX;
1338 <  /* Don't reset hub, as that will break lazylinks */
1339 <  /* ServerInfo.hub = NO; */
1338 >  ServerInfo.max_nick_length = 9;
1339 >  ServerInfo.max_topic_length = 80;
1340 >
1341 >  ServerInfo.hub = 0;
1342    ServerInfo.dns_host.sin_addr.s_addr = 0;
1343    ServerInfo.dns_host.sin_port = 0;
1344    AdminInfo.name = NULL;
1345    AdminInfo.email = NULL;
1346    AdminInfo.description = NULL;
1347  
1348 <  set_log_level(L_NOTICE);
1348 >  log_del_all();
1349 >
1350    ConfigLoggingEntry.use_logging = 1;
1351 <  ConfigLoggingEntry.operlog[0] = '\0';
1352 <  ConfigLoggingEntry.userlog[0] = '\0';
1849 <  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;
1351 >
1352 >  ConfigChannel.disable_fake_channels = 0;
1353    ConfigChannel.knock_delay = 300;
1354    ConfigChannel.knock_delay_channel = 60;
1355 <  ConfigChannel.max_chans_per_user = 15;
1356 <  ConfigChannel.quiet_on_ban = YES;
1355 >  ConfigChannel.max_chans_per_user = 25;
1356 >  ConfigChannel.max_chans_per_oper = 50;
1357 >  ConfigChannel.quiet_on_ban = 1;
1358    ConfigChannel.max_bans = 25;
1359    ConfigChannel.default_split_user_count = 0;
1360    ConfigChannel.default_split_server_count = 0;
1361 <  ConfigChannel.no_join_on_split = NO;
1362 <  ConfigChannel.no_create_on_split = NO;
1870 <  ConfigChannel.burst_topicwho = YES;
1361 >  ConfigChannel.no_join_on_split = 0;
1362 >  ConfigChannel.no_create_on_split = 0;
1363  
1364 <  ConfigServerHide.flatten_links = NO;
1364 >  ConfigServerHide.flatten_links = 0;
1365    ConfigServerHide.links_delay = 300;
1366 <  ConfigServerHide.hidden = NO;
1367 <  ConfigServerHide.disable_hidden = NO;
1368 <  ConfigServerHide.hide_servers = NO;
1369 <  DupString(ConfigServerHide.hidden_name, NETWORK_NAME_DEFAULT);
1370 <  ConfigServerHide.hide_server_ips = NO;
1366 >  ConfigServerHide.hidden = 0;
1367 >  ConfigServerHide.hide_servers = 0;
1368 >  ConfigServerHide.hide_services = 0;
1369 >  ConfigServerHide.hidden_name = xstrdup(NETWORK_NAME_DEFAULT);
1370 >  ConfigServerHide.hide_server_ips = 0;
1371  
1372 +  
1373 +  ConfigFileEntry.service_name = xstrdup(SERVICE_NAME_DEFAULT);
1374 +  ConfigFileEntry.max_watch = WATCHSIZE_DEFAULT;
1375 +  ConfigFileEntry.glines = 0;
1376 +  ConfigFileEntry.gline_time = 12 * 3600;
1377 +  ConfigFileEntry.gline_request_time = GLINE_REQUEST_EXPIRE_DEFAULT;
1378    ConfigFileEntry.gline_min_cidr = 16;
1379    ConfigFileEntry.gline_min_cidr6 = 48;
1380 <  ConfigFileEntry.invisible_on_connect = YES;
1381 <  ConfigFileEntry.burst_away = NO;
1382 <  ConfigFileEntry.use_whois_actually = YES;
1383 <  ConfigFileEntry.tkline_expire_notices = YES;
1384 <  ConfigFileEntry.hide_spoof_ips = YES;
1385 <  ConfigFileEntry.ignore_bogus_ts = NO;
1888 <  ConfigFileEntry.disable_auth = NO;
1889 <  ConfigFileEntry.disable_remote = NO;
1380 >  ConfigFileEntry.invisible_on_connect = 1;
1381 >  ConfigFileEntry.tkline_expire_notices = 1;
1382 >  ConfigFileEntry.hide_spoof_ips = 1;
1383 >  ConfigFileEntry.ignore_bogus_ts = 0;
1384 >  ConfigFileEntry.disable_auth = 0;
1385 >  ConfigFileEntry.disable_remote = 0;
1386    ConfigFileEntry.kill_chase_time_limit = 90;
1387 <  ConfigFileEntry.default_floodcount = 8; /* XXX */
1388 <  ConfigFileEntry.failed_oper_notice = YES;
1389 <  ConfigFileEntry.dots_in_ident = 0;      /* XXX */
1894 <  ConfigFileEntry.dot_in_ip6_addr = YES;
1387 >  ConfigFileEntry.default_floodcount = 8;
1388 >  ConfigFileEntry.failed_oper_notice = 1;
1389 >  ConfigFileEntry.dots_in_ident = 0;
1390    ConfigFileEntry.min_nonwildcard = 4;
1391    ConfigFileEntry.min_nonwildcard_simple = 3;
1392    ConfigFileEntry.max_accept = 20;
1393 <  ConfigFileEntry.anti_nick_flood = NO;   /* XXX */
1393 >  ConfigFileEntry.anti_nick_flood = 0;
1394    ConfigFileEntry.max_nick_time = 20;
1395    ConfigFileEntry.max_nick_changes = 5;
1396 <  ConfigFileEntry.anti_spam_exit_message_time = 0;  /* XXX */
1396 >  ConfigFileEntry.anti_spam_exit_message_time = 0;
1397    ConfigFileEntry.ts_warn_delta = TS_WARN_DELTA_DEFAULT;
1398 <  ConfigFileEntry.ts_max_delta = TS_MAX_DELTA_DEFAULT;  /* XXX */
1399 <  ConfigFileEntry.kline_with_reason = YES;
1400 <  ConfigFileEntry.kline_reason = NULL;
1906 <  ConfigFileEntry.warn_no_nline = YES;
1907 <  ConfigFileEntry.stats_o_oper_only = NO; /* XXX */
1398 >  ConfigFileEntry.ts_max_delta = TS_MAX_DELTA_DEFAULT;
1399 >  ConfigFileEntry.warn_no_nline = 1;
1400 >  ConfigFileEntry.stats_o_oper_only = 0;
1401    ConfigFileEntry.stats_k_oper_only = 1;  /* masked */
1402    ConfigFileEntry.stats_i_oper_only = 1;  /* masked */
1403 <  ConfigFileEntry.stats_P_oper_only = NO;
1403 >  ConfigFileEntry.stats_P_oper_only = 0;
1404    ConfigFileEntry.caller_id_wait = 60;
1405 <  ConfigFileEntry.opers_bypass_callerid = NO;
1405 >  ConfigFileEntry.opers_bypass_callerid = 0;
1406    ConfigFileEntry.pace_wait = 10;
1407    ConfigFileEntry.pace_wait_simple = 1;
1408 <  ConfigFileEntry.short_motd = NO;
1409 <  ConfigFileEntry.ping_cookie = NO;
1410 <  ConfigFileEntry.no_oper_flood = NO;     /* XXX */
1411 <  ConfigFileEntry.true_no_oper_flood = NO;  /* XXX */
1412 <  ConfigFileEntry.oper_pass_resv = YES;
1920 <  ConfigFileEntry.glines = NO;            /* XXX */
1921 <  ConfigFileEntry.gline_time = 12 * 3600; /* XXX */
1922 <  ConfigFileEntry.idletime = 0;
1408 >  ConfigFileEntry.short_motd = 0;
1409 >  ConfigFileEntry.ping_cookie = 0;
1410 >  ConfigFileEntry.no_oper_flood = 0;
1411 >  ConfigFileEntry.true_no_oper_flood = 0;
1412 >  ConfigFileEntry.oper_pass_resv = 1;
1413    ConfigFileEntry.max_targets = MAX_TARGETS_DEFAULT;
1414 <  ConfigFileEntry.client_flood = CLIENT_FLOOD_DEFAULT;
1415 <  ConfigFileEntry.oper_only_umodes = UMODE_DEBUG;  /* XXX */
1416 <  ConfigFileEntry.oper_umodes = UMODE_LOCOPS | UMODE_SERVNOTICE |
1417 <    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;
1414 >  ConfigFileEntry.oper_only_umodes = UMODE_DEBUG;
1415 >  ConfigFileEntry.oper_umodes = UMODE_BOTS | UMODE_LOCOPS | UMODE_SERVNOTICE |
1416 >    UMODE_OPERWALL | UMODE_WALLOP;
1417 >  ConfigFileEntry.use_egd = 0;
1418    ConfigFileEntry.egdpool_path = NULL;
1942 #ifdef HAVE_LIBZ
1943  ConfigFileEntry.compression_level = 0;
1944 #endif
1419    ConfigFileEntry.throttle_time = 10;
1420   }
1421  
1422 + static void
1423 + validate_conf(void)
1424 + {
1425 +  if (ConfigFileEntry.ts_warn_delta < TS_WARN_DELTA_MIN)
1426 +    ConfigFileEntry.ts_warn_delta = TS_WARN_DELTA_DEFAULT;
1427 +
1428 +  if (ConfigFileEntry.ts_max_delta < TS_MAX_DELTA_MIN)
1429 +    ConfigFileEntry.ts_max_delta = TS_MAX_DELTA_DEFAULT;
1430 +
1431 +  if (ServerInfo.network_name == NULL)
1432 +    ServerInfo.network_name = xstrdup(NETWORK_NAME_DEFAULT);
1433 +
1434 +  if (ServerInfo.network_desc == NULL)
1435 +    ServerInfo.network_desc = xstrdup(NETWORK_DESC_DEFAULT);
1436 +
1437 +  if (ConfigFileEntry.service_name == NULL)
1438 +    ConfigFileEntry.service_name = xstrdup(SERVICE_NAME_DEFAULT);
1439 +
1440 +  ConfigFileEntry.max_watch = IRCD_MAX(ConfigFileEntry.max_watch, WATCHSIZE_MIN);
1441 + }
1442 +
1443   /* read_conf()
1444   *
1445   * inputs       - file descriptor pointing to config file to use
# Line 1952 | Line 1447 | set_default_conf(void)
1447   * side effects - Read configuration file.
1448   */
1449   static void
1450 < read_conf(FBFILE *file)
1450 > read_conf(FILE *file)
1451   {
1452 <  scount = lineno = 0;
1452 >  lineno = 0;
1453  
1454    set_default_conf(); /* Set default values prior to conf parsing */
1455 <  ypass = 1;
1455 >  conf_parser_ctx.pass = 1;
1456    yyparse();          /* pick up the classes first */
1457  
1458 <  fbrewind(file);
1458 >  rewind(file);
1459  
1460 <  ypass = 2;
1460 >  conf_parser_ctx.pass = 2;
1461    yyparse();          /* Load the values from the conf */
1462    validate_conf();    /* Check to make sure some values are still okay. */
1463                        /* Some global values are also loaded here. */
1464 <  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;
1464 >  class_delete_marked();      /* Make sure classes are valid */
1465   }
1466  
1467   /* lookup_confhost()
# Line 1997 | Line 1469 | validate_conf(void)
1469   * start DNS lookups of all hostnames in the conf
1470   * line and convert an IP addresses in a.b.c.d number for to IP#s.
1471   */
1472 < static void
1473 < lookup_confhost(struct ConfItem *conf)
1472 > void
1473 > lookup_confhost(struct MaskItem *conf)
1474   {
2003  struct AccessItem *aconf;
1475    struct addrinfo hints, *res;
1476  
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
1477    /* Do name lookup now on hostnames given and store the
1478     * ip numbers in conf structure.
1479     */
# Line 2028 | Line 1485 | lookup_confhost(struct ConfItem *conf)
1485    /* Get us ready for a bind() and don't bother doing dns lookup */
1486    hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
1487  
1488 <  if (irc_getaddrinfo(aconf->host, NULL, &hints, &res))
1488 >  if (getaddrinfo(conf->host, NULL, &hints, &res))
1489    {
1490 <    conf_dns_lookup(aconf);
1490 >    conf_dns_lookup(conf);
1491      return;
1492    }
1493  
1494    assert(res != NULL);
1495  
1496 <  memcpy(&aconf->ipnum, res->ai_addr, res->ai_addrlen);
1497 <  aconf->ipnum.ss_len = res->ai_addrlen;
1498 <  aconf->ipnum.ss.ss_family = res->ai_family;
1499 <  irc_freeaddrinfo(res);
1496 >  memcpy(&conf->addr, res->ai_addr, res->ai_addrlen);
1497 >  conf->addr.ss_len = res->ai_addrlen;
1498 >  conf->addr.ss.ss_family = res->ai_family;
1499 >
1500 >  freeaddrinfo(res);
1501   }
1502  
1503   /* conf_connect_allowed()
# Line 2053 | Line 1511 | int
1511   conf_connect_allowed(struct irc_ssaddr *addr, int aftype)
1512   {
1513    struct ip_entry *ip_found;
1514 <  struct AccessItem *aconf = find_dline_conf(addr, aftype);
1514 >  struct MaskItem *conf = find_dline_conf(addr, aftype);
1515  
1516    /* DLINE exempt also gets you out of static limits/pacing... */
1517 <  if (aconf && (aconf->status & CONF_EXEMPTDLINE))
1517 >  if (conf && (conf->type == CONF_EXEMPT))
1518      return 0;
1519  
1520 <  if (aconf != NULL)
1520 >  if (conf != NULL)
1521      return BANNED_CLIENT;
1522  
1523    ip_found = find_or_add_ip(addr);
# Line 2075 | Line 1533 | conf_connect_allowed(struct irc_ssaddr *
1533    return 0;
1534   }
1535  
1536 < static struct AccessItem *
1536 > static struct MaskItem *
1537   find_regexp_kline(const char *uhi[])
1538   {
1539 + #ifdef HAVE_LIBPCRE
1540    const dlink_node *ptr = NULL;
1541  
1542    DLINK_FOREACH(ptr, rkconf_items.head)
1543    {
1544 <    struct AccessItem *aptr = map_to_conf(ptr->data);
1544 >    struct MaskItem *aptr = ptr->data;
1545  
1546      assert(aptr->regexuser);
1547      assert(aptr->regexhost);
# Line 2092 | Line 1551 | find_regexp_kline(const char *uhi[])
1551           !ircd_pcre_exec(aptr->regexhost, uhi[2])))
1552        return aptr;
1553    }
1554 <
1554 > #endif
1555    return NULL;
1556   }
1557  
1558   /* find_kill()
1559   *
1560   * inputs       - pointer to client structure
1561 < * output       - pointer to struct AccessItem if found
1561 > * output       - pointer to struct MaskItem if found
1562   * side effects - See if this user is klined already,
1563 < *                and if so, return struct AccessItem pointer
1563 > *                and if so, return struct MaskItem pointer
1564   */
1565 < struct AccessItem *
1565 > struct MaskItem *
1566   find_kill(struct Client *client_p)
1567   {
1568 <  struct AccessItem *aconf = NULL;
1568 >  struct MaskItem *conf = NULL;
1569    const char *uhi[3];
1570  
1571    uhi[0] = client_p->username;
# Line 2115 | Line 1574 | find_kill(struct Client *client_p)
1574  
1575    assert(client_p != NULL);
1576  
1577 <  aconf = find_kline_conf(client_p->host, client_p->username,
1578 <                          &client_p->localClient->ip,
1579 <                          client_p->localClient->aftype);
1580 <  if (aconf == NULL)
1581 <    aconf = find_regexp_kline(uhi);
2123 <
2124 <  if (aconf && (aconf->status & CONF_KLINE))
2125 <    return aconf;
1577 >  conf = find_conf_by_address(client_p->host, &client_p->localClient->ip,
1578 >                              CONF_KLINE, client_p->localClient->aftype,
1579 >                              client_p->username, NULL, 1);
1580 >  if (conf == NULL)
1581 >    conf = find_regexp_kline(uhi);
1582  
1583 <  return NULL;
1583 >  return conf;
1584   }
1585  
1586 < struct AccessItem *
1586 > struct MaskItem *
1587   find_gline(struct Client *client_p)
1588   {
1589 <  struct AccessItem *aconf;
1589 >  struct MaskItem *conf;
1590  
1591    assert(client_p != NULL);
1592  
1593 <  aconf = find_gline_conf(client_p->host, client_p->username,
1594 <                          &client_p->localClient->ip,
1595 <                          client_p->localClient->aftype);
1596 <
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 <  }
1593 >  conf = find_conf_by_address(client_p->host, &client_p->localClient->ip,
1594 >                              CONF_GLINE, client_p->localClient->aftype,
1595 >                              client_p->username, NULL, 1);
1596 >  return conf;
1597   }
1598  
1599   /* cleanup_tklines()
# Line 2211 | Line 1606 | add_temp_line(struct ConfItem *conf)
1606   void
1607   cleanup_tklines(void *notused)
1608   {
1609 <  expire_tklines(&temporary_glines);
1610 <  expire_tklines(&temporary_klines);
1611 <  expire_tklines(&temporary_dlines);
1612 <  expire_tklines(&temporary_xlines);
2218 <  expire_tklines(&temporary_rxlines);
2219 <  expire_tklines(&temporary_rklines);
2220 <  expire_tklines(&temporary_resv);
1609 >  hostmask_expire_temporary();
1610 >  expire_tklines(&xconf_items);
1611 >  expire_tklines(&nresv_items);
1612 >  expire_tklines(&resv_channel_list);
1613   }
1614  
1615   /* expire_tklines()
# Line 2231 | Line 1623 | expire_tklines(dlink_list *tklist)
1623   {
1624    dlink_node *ptr;
1625    dlink_node *next_ptr;
1626 <  struct ConfItem *conf;
2235 <  struct MatchItem *xconf;
2236 <  struct MatchItem *nconf;
2237 <  struct AccessItem *aconf;
2238 <  struct ResvChannel *cconf;
1626 >  struct MaskItem *conf;
1627  
1628    DLINK_FOREACH_SAFE(ptr, next_ptr, tklist->head)
1629    {
1630      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        }
1631  
1632 <        delete_one_address_conf(aconf->host, aconf);
1633 <        dlinkDelete(ptr, tklist);
1634 <      }
1635 <    }
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)
1632 >    if (!conf->until || conf->until > CurrentTime)
1633 >      continue;
1634 >
1635 >    if (conf->type == CONF_XLINE)
1636      {
1637 <      aconf = map_to_conf(conf);
1638 <      if (aconf->hold <= CurrentTime)
1639 <      {
1640 <        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 <      }
1637 >      if (ConfigFileEntry.tkline_expire_notices)
1638 >        sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1639 >                               "Temporary X-line for [%s] expired", conf->name);
1640 >      conf_free(conf);
1641      }
1642 <    else if (conf->type == NRESV_TYPE)
1642 >    else if (conf->type == CONF_NRESV || conf->type == CONF_CRESV)
1643      {
1644 <      nconf = (struct MatchItem *)map_to_conf(conf);
1645 <      if (nconf->hold <= CurrentTime)
2307 <      {
2308 <        if (ConfigFileEntry.tkline_expire_notices)
2309 <          sendto_realops_flags(UMODE_ALL, L_ALL,
1644 >      if (ConfigFileEntry.tkline_expire_notices)
1645 >        sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1646                                 "Temporary RESV for [%s] expired", conf->name);
1647 <        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 <      }
1647 >      conf_free(conf);
1648      }
1649    }
1650   }
# Line 2337 | Line 1657 | expire_tklines(dlink_list *tklist)
1657   */
1658   static const struct oper_privs
1659   {
1660 <  const unsigned int oprivs;
2341 <  const unsigned int hidden;
1660 >  const unsigned int flag;
1661    const unsigned char c;
1662   } flag_list[] = {
1663 <  { OPER_FLAG_ADMIN,       OPER_FLAG_HIDDEN_ADMIN,  'A' },
1664 <  { OPER_FLAG_REMOTEBAN,   0,                       'B' },
1665 <  { OPER_FLAG_DIE,         0,                       'D' },
1666 <  { OPER_FLAG_GLINE,       0,                       'G' },
1667 <  { OPER_FLAG_REHASH,      0,                       'H' },
1668 <  { OPER_FLAG_K,           0,                       'K' },
1669 <  { OPER_FLAG_OPERWALL,    0,                       'L' },
1670 <  { OPER_FLAG_N,           0,                       'N' },
1671 <  { OPER_FLAG_GLOBAL_KILL, 0,                       'O' },
1672 <  { OPER_FLAG_REMOTE,      0,                       'R' },
1673 <  { OPER_FLAG_OPER_SPY,    0,                       'S' },
1674 <  { OPER_FLAG_UNKLINE,     0,                       'U' },
1675 <  { OPER_FLAG_X,           0,                       'X' },
2357 <  { 0, 0, '\0' }
1663 >  { OPER_FLAG_ADMIN,       'A' },
1664 >  { OPER_FLAG_REMOTEBAN,   'B' },
1665 >  { OPER_FLAG_DIE,         'D' },
1666 >  { OPER_FLAG_GLINE,       'G' },
1667 >  { OPER_FLAG_REHASH,      'H' },
1668 >  { OPER_FLAG_K,           'K' },
1669 >  { OPER_FLAG_OPERWALL,    'L' },
1670 >  { OPER_FLAG_GLOBAL_KILL, 'O' },
1671 >  { OPER_FLAG_REMOTE,      'R' },
1672 >  { OPER_FLAG_OPER_SPY,    'S' },
1673 >  { OPER_FLAG_UNKLINE,     'U' },
1674 >  { OPER_FLAG_X,           'X' },
1675 >  { 0, '\0' }
1676   };
1677  
1678   char *
# Line 2362 | Line 1680 | oper_privs_as_string(const unsigned int
1680   {
1681    static char privs_out[16];
1682    char *privs_ptr = privs_out;
1683 <  unsigned int i = 0;
1683 >  const struct oper_privs *opriv = flag_list;
1684  
1685 <  for (; flag_list[i].oprivs; ++i)
1685 >  for (; opriv->flag; ++opriv)
1686    {
1687 <    if ((port & flag_list[i].oprivs) &&
1688 <        (port & flag_list[i].hidden) == 0)
2371 <      *privs_ptr++ = flag_list[i].c;
1687 >    if (port & opriv->flag)
1688 >      *privs_ptr++ = opriv->c;
1689      else
1690 <      *privs_ptr++ = ToLowerTab[flag_list[i].c];
1690 >      *privs_ptr++ = ToLower(opriv->c);
1691    }
1692  
1693    *privs_ptr = '\0';
# Line 2384 | Line 1701 | oper_privs_as_string(const unsigned int
1701   *         "oper" is server name for remote opers
1702   * Side effects: None.
1703   */
1704 < char *
1704 > const char *
1705   get_oper_name(const struct Client *client_p)
1706   {
1707 <  dlink_node *cnode;
2391 <  struct ConfItem *conf;
2392 <  struct AccessItem *aconf;
2393 <
1707 >  dlink_node *cnode = NULL;
1708    /* +5 for !,@,{,} and null */
1709 <  static char buffer[NICKLEN+USERLEN+HOSTLEN+HOSTLEN+5];
1709 >  static char buffer[NICKLEN + USERLEN + HOSTLEN + HOSTLEN + 5];
1710  
1711    if (MyConnect(client_p))
1712    {
1713 <    DLINK_FOREACH(cnode, client_p->localClient->confs.head)
1713 >    if ((cnode = client_p->localClient->confs.head))
1714      {
1715 <      conf = cnode->data;
2402 <      aconf = map_to_conf(conf);
1715 >      struct MaskItem *conf = cnode->data;
1716  
1717 <      if (IsConfOperator(aconf))
1717 >      if (IsConfOperator(conf))
1718        {
1719 <        ircsprintf(buffer, "%s!%s@%s{%s}", client_p->name,
1720 <                   client_p->username, client_p->host,
2408 <                   conf->name);
1719 >        snprintf(buffer, sizeof(buffer), "%s!%s@%s{%s}", client_p->name,
1720 >                 client_p->username, client_p->host, conf->name);
1721          return buffer;
1722        }
1723      }
# Line 2416 | Line 1728 | get_oper_name(const struct Client *clien
1728      assert(0); /* Oper without oper conf! */
1729    }
1730  
1731 <  ircsprintf(buffer, "%s!%s@%s{%s}", client_p->name,
1732 <             client_p->username, client_p->host, client_p->servptr->name);
1731 >  snprintf(buffer, sizeof(buffer), "%s!%s@%s{%s}", client_p->name,
1732 >           client_p->username, client_p->host, client_p->servptr->name);
1733    return buffer;
1734   }
1735  
# Line 2434 | Line 1746 | read_conf_files(int cold)
1746    char chanmodes[32];
1747    char chanlimit[32];
1748  
1749 <  filename = get_conf_name(CONF_TYPE);
1749 >  conf_parser_ctx.boot = cold;
1750 >  filename = ConfigFileEntry.configfile;
1751  
1752    /* We need to know the initial filename for the yyerror() to report
1753       FIXME: The full path is in conffilenamebuf first time since we
# Line 2444 | Line 1757 | read_conf_files(int cold)
1757    */
1758    strlcpy(conffilebuf, filename, sizeof(conffilebuf));
1759  
1760 <  if ((conf_fbfile_in = fbopen(filename, "r")) == NULL)
1760 >  if ((conf_parser_ctx.conf_file = fopen(filename, "r")) == NULL)
1761    {
1762      if (cold)
1763      {
1764 <      ilog(L_CRIT, "Unable to read configuration file '%s': %s",
1764 >      ilog(LOG_TYPE_IRCD, "Unable to read configuration file '%s': %s",
1765             filename, strerror(errno));
1766        exit(-1);
1767      }
1768      else
1769      {
1770 <      sendto_realops_flags(UMODE_ALL, L_ALL,
1770 >      sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1771                             "Unable to read configuration file '%s': %s",
1772                             filename, strerror(errno));
1773        return;
# Line 2464 | Line 1777 | read_conf_files(int cold)
1777    if (!cold)
1778      clear_out_old_conf();
1779  
1780 <  read_conf(conf_fbfile_in);
1781 <  fbclose(conf_fbfile_in);
1780 >  read_conf(conf_parser_ctx.conf_file);
1781 >  fclose(conf_parser_ctx.conf_file);
1782 >
1783 >  log_reopen_all();
1784  
1785 +  add_isupport("NICKLEN", NULL, ServerInfo.max_nick_length);
1786    add_isupport("NETWORK", ServerInfo.network_name, -1);
1787 <  ircsprintf(chanmodes, "b%s%s:%d", ConfigChannel.use_except ? "e" : "",
1788 <             ConfigChannel.use_invex ? "I" : "", ConfigChannel.max_bans);
1787 >
1788 >  snprintf(chanmodes, sizeof(chanmodes), "beI:%d", ConfigChannel.max_bans);
1789    add_isupport("MAXLIST", chanmodes, -1);
1790    add_isupport("MAXTARGETS", NULL, ConfigFileEntry.max_targets);
1791 <  if (ConfigChannel.disable_local_channels)
1792 <    add_isupport("CHANTYPES", "#", -1);
1793 <  else
1794 <    add_isupport("CHANTYPES", "#&", -1);
2479 <  ircsprintf(chanlimit, "%s:%d", ConfigChannel.disable_local_channels ? "#" : "#&",
2480 <             ConfigChannel.max_chans_per_user);
1791 >  add_isupport("CHANTYPES", "#", -1);
1792 >
1793 >  snprintf(chanlimit, sizeof(chanlimit), "#:%d",
1794 >           ConfigChannel.max_chans_per_user);
1795    add_isupport("CHANLIMIT", chanlimit, -1);
1796 <  ircsprintf(chanmodes, "%s%s%s", ConfigChannel.use_except ? "e" : "",
2483 <             ConfigChannel.use_invex ? "I" : "", "b,k,l,imnpst");
1796 >  snprintf(chanmodes, sizeof(chanmodes), "%s", "beI,k,l,imnprstORS");
1797    add_isupport("CHANNELLEN", NULL, LOCAL_CHANNELLEN);
1798 <  if (ConfigChannel.use_except)
1799 <    add_isupport("EXCEPTS", "e", -1);
1800 <  if (ConfigChannel.use_invex)
2488 <    add_isupport("INVEX", "I", -1);
1798 >  add_isupport("TOPICLEN", NULL, ServerInfo.max_topic_length);
1799 >  add_isupport("EXCEPTS", "e", -1);
1800 >  add_isupport("INVEX", "I", -1);
1801    add_isupport("CHANMODES", chanmodes, -1);
1802  
1803    /*
# Line 2493 | Line 1805 | read_conf_files(int cold)
1805     * on strlen(form_str(RPL_ISUPPORT))
1806     */
1807    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  }
1808   }
1809  
1810   /* clear_out_old_conf()
# Line 2542 | Line 1817 | static void
1817   clear_out_old_conf(void)
1818   {
1819    dlink_node *ptr = NULL, *next_ptr = NULL;
1820 <  struct ConfItem *conf;
2546 <  struct AccessItem *aconf;
2547 <  struct ClassItem *cltmp;
2548 <  struct MatchItem *match_item;
1820 >  struct MaskItem *conf;
1821    dlink_list *free_items [] = {
1822 <    &server_items,   &oconf_items,    &hub_items, &leaf_items,
1822 >    &server_items,   &oconf_items,
1823       &uconf_items,   &xconf_items, &rxconf_items, &rkconf_items,
1824 <     &nresv_items, &cluster_items,  &gdeny_items, NULL
1824 >     &nresv_items, &cluster_items,  &service_items, &resv_channel_list, NULL
1825    };
1826  
1827    dlink_list ** iterator = free_items; /* C is dumb */
# Line 2563 | Line 1835 | clear_out_old_conf(void)
1835      DLINK_FOREACH_SAFE(ptr, next_ptr, (*iterator)->head)
1836      {
1837        conf = ptr->data;
1838 +
1839 +      dlinkDelete(&conf->node, map_to_list(conf->type));
1840 +
1841        /* XXX This is less than pretty */
1842 <      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)
1842 >      if (conf->type == CONF_SERVER || conf->type == CONF_OPER)
1843        {
1844 <        aconf = (struct AccessItem *)map_to_conf(conf);
1845 <        if (aconf->clients != 0)
2584 <        {
2585 <          SetConfIllegal(aconf);
2586 <          dlinkDelete(&conf->node, &oconf_items);
2587 <        }
2588 <        else
2589 <        {
2590 <          delete_conf_item(conf);
2591 <        }
1844 >        if (!conf->ref_count)
1845 >          conf_free(conf);
1846        }
1847 <      else if (conf->type == CLIENT_TYPE)
1847 >      else if (conf->type == CONF_XLINE  ||
1848 >               conf->type == CONF_RXLINE ||
1849 >               conf->type == CONF_RKLINE)
1850        {
1851 <        aconf = (struct AccessItem *)map_to_conf(conf);
1852 <        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);
1851 >        if (!conf->until)
1852 >          conf_free(conf);
1853        }
1854        else
1855 <      {
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 <      }
1855 >        conf_free(conf);
1856      }
1857    }
1858  
1859 <  /* don't delete the class table, rather mark all entries
1860 <   * for deletion. The table is cleaned up by check_class. - avalon
1859 >  /*
1860 >   * don't delete the class table, rather mark all entries
1861 >   * for deletion. The table is cleaned up by class_delete_marked. - avalon
1862     */
1863 <  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 <  }
1863 >  class_mark_for_deletion();
1864  
1865    clear_out_address_conf();
1866  
1867    /* clean out module paths */
2649 #ifndef STATIC_MODULES
1868    mod_clear_paths();
2651 #endif
1869  
1870    /* clean out ServerInfo */
1871    MyFree(ServerInfo.description);
# Line 2668 | Line 1885 | clear_out_old_conf(void)
1885  
1886    MyFree(ServerInfo.rsa_private_key_file);
1887    ServerInfo.rsa_private_key_file = NULL;
2671 #endif
1888  
1889 <  /* clean out old resvs from the conf */
1890 <  clear_conf_resv();
1889 >  if (ServerInfo.server_ctx)
1890 >    SSL_CTX_set_options(ServerInfo.server_ctx, SSL_OP_NO_SSLv2|
1891 >                                               SSL_OP_NO_SSLv3|
1892 >                                               SSL_OP_NO_TLSv1);
1893 >  if (ServerInfo.client_ctx)
1894 >    SSL_CTX_set_options(ServerInfo.client_ctx, SSL_OP_NO_SSLv2|
1895 >                                               SSL_OP_NO_SSLv3|
1896 >                                               SSL_OP_NO_TLSv1);
1897 > #endif
1898  
1899    /* clean out AdminInfo */
1900    MyFree(AdminInfo.name);
# Line 2681 | Line 1904 | clear_out_old_conf(void)
1904    MyFree(AdminInfo.description);
1905    AdminInfo.description = NULL;
1906  
2684  /* operator{} and class{} blocks are freed above */
1907    /* clean out listeners */
1908    close_listeners();
1909  
2688  /* auth{}, quarantine{}, shared{}, connect{}, kill{}, deny{},
2689   * exempt{} and gecos{} blocks are freed above too
2690   */
2691
1910    /* clean out general */
1911 <  MyFree(ConfigFileEntry.servlink_path);
1912 <  ConfigFileEntry.servlink_path = NULL;
1913 < #ifdef HAVE_LIBCRYPTO
2696 <  ConfigFileEntry.default_cipher_preference = NULL;
2697 < #endif /* HAVE_LIBCRYPTO */
1911 >  MyFree(ConfigFileEntry.service_name);
1912 >  ConfigFileEntry.service_name = NULL;
1913 >
1914    delete_isupport("INVEX");
1915    delete_isupport("EXCEPTS");
1916   }
1917  
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
1918   /* conf_add_class_to_conf()
1919   *
1920   * inputs       - pointer to config item
# Line 2994 | Line 1922 | get_sendq(struct Client *client_p)
1922   * side effects - Add a class pointer to a conf
1923   */
1924   void
1925 < conf_add_class_to_conf(struct ConfItem *conf, const char *class_name)
1925 > conf_add_class_to_conf(struct MaskItem *conf, const char *class_name)
1926   {
2999  struct AccessItem *aconf;
3000  struct ClassItem *aclass;
3001
3002  aconf = (struct AccessItem *)map_to_conf(conf);
3003
1927    if (class_name == NULL)
1928    {
1929 <    aconf->class_ptr = class_default;
1930 <    if (conf->type == CLIENT_TYPE)
1931 <      sendto_realops_flags(UMODE_ALL, L_ALL,
1929 >    conf->class = class_default;
1930 >
1931 >    if (conf->type == CONF_CLIENT)
1932 >      sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1933                             "Warning *** Defaulting to default class for %s@%s",
1934 <                           aconf->user, aconf->host);
1934 >                           conf->user, conf->host);
1935      else
1936 <      sendto_realops_flags(UMODE_ALL, L_ALL,
1936 >      sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1937                             "Warning *** Defaulting to default class for %s",
1938                             conf->name);
1939    }
1940    else
1941 <  {
3018 <    aconf->class_ptr = find_class(class_name);
3019 <  }
1941 >    conf->class = class_find(class_name, 1);
1942  
1943 <  if (aconf->class_ptr == NULL)
1943 >  if (conf->class == NULL)
1944    {
1945 <    if (conf->type == CLIENT_TYPE)
1946 <      sendto_realops_flags(UMODE_ALL, L_ALL,
1945 >    if (conf->type == CONF_CLIENT)
1946 >      sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1947                             "Warning *** Defaulting to default class for %s@%s",
1948 <                           aconf->user, aconf->host);
1948 >                           conf->user, conf->host);
1949      else
1950 <      sendto_realops_flags(UMODE_ALL, L_ALL,
1950 >      sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1951                             "Warning *** Defaulting to default class for %s",
1952                             conf->name);
1953 <    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);
1953 >    conf->class = class_default;
1954    }
1955   }
1956  
# Line 3124 | Line 1965 | yyerror(const char *msg)
1965   {
1966    char newlinebuf[IRCD_BUFSIZE];
1967  
1968 <  if (ypass != 1)
1968 >  if (conf_parser_ctx.pass != 1)
1969      return;
1970  
1971    strip_tabs(newlinebuf, linebuf, sizeof(newlinebuf));
1972 <  sendto_realops_flags(UMODE_ALL, L_ALL, "\"%s\", line %u: %s: %s",
1972 >  sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1973 >                       "\"%s\", line %u: %s: %s",
1974                         conffilebuf, lineno + 1, msg, newlinebuf);
1975 <  ilog(L_WARN, "\"%s\", line %u: %s: %s",
1975 >  ilog(LOG_TYPE_IRCD, "\"%s\", line %u: %s: %s",
1976         conffilebuf, lineno + 1, msg, newlinebuf);
1977   }
1978  
1979 < int
1980 < conf_fbgets(char *lbuf, unsigned int max_size, FBFILE *fb)
1979 > void
1980 > conf_error_report(const char *msg)
1981   {
1982 <  if (fbgets(lbuf, max_size, fb) == NULL)
3141 <    return 0;
3142 <
3143 <  return strlen(lbuf);
3144 < }
1982 >  char newlinebuf[IRCD_BUFSIZE];
1983  
1984 < int
1985 < conf_yy_fatal_error(const char *msg)
1986 < {
1987 <  return 0;
1984 >  strip_tabs(newlinebuf, linebuf, sizeof(newlinebuf));
1985 >  sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1986 >                       "\"%s\", line %u: %s: %s",
1987 >                       conffilebuf, lineno + 1, msg, newlinebuf);
1988 >  ilog(LOG_TYPE_IRCD, "\"%s\", line %u: %s: %s",
1989 >       conffilebuf, lineno + 1, msg, newlinebuf);
1990   }
1991  
1992   /*
# Line 3160 | Line 2000 | conf_yy_fatal_error(const char *msg)
2000   * Originally written by Dianora (Diane, db@db.net)
2001   */
2002   time_t
2003 < valid_tkline(char *p, int minutes)
2003 > valid_tkline(const char *p, int minutes)
2004   {
2005    time_t result = 0;
2006  
2007 <  while (*p)
2007 >  for (; *p; ++p)
2008    {
2009 <    if (IsDigit(*p))
3170 <    {
3171 <      result *= 10;
3172 <      result += ((*p) & 0xF);
3173 <      p++;
3174 <    }
3175 <    else
2009 >    if (!IsDigit(*p))
2010        return 0;
2011 +
2012 +    result *= 10;
2013 +    result += ((*p) & 0xF);
2014    }
2015  
2016 <  /* in the degenerate case where oper does a /quote kline 0 user@host :reason
2016 >  /*
2017 >   * In the degenerate case where oper does a /quote kline 0 user@host :reason
2018     * i.e. they specifically use 0, I am going to return 1 instead
2019     * as a return value of non-zero is used to flag it as a temporary kline
2020     */
3183
2021    if (result == 0)
2022      result = 1;
2023  
# Line 3281 | Line 2118 | valid_wild_card(struct Client *source_p,
2118   *                if target_server is NULL and an "ON" is found error
2119   *                is reported.
2120   *                if reason pointer is NULL ignore pointer,
2121 < *                this allows usee of parse_a_line in unkline etc.
2121 > *                this allows use of parse_a_line in unkline etc.
2122   *
2123   * - Dianora
2124   */
# Line 3351 | Line 2188 | parse_aline(const char *cmd, struct Clie
2188          return -1;
2189        }
2190  
2191 <      if (!IsOperRemoteBan(source_p))
2191 >      if (!HasOFlag(source_p, OPER_FLAG_REMOTEBAN))
2192        {
2193          sendto_one(source_p, form_str(ERR_NOPRIVS),
2194                     me.name, source_p->name, "remoteban");
# Line 3388 | Line 2225 | parse_aline(const char *cmd, struct Clie
2225        return -1;
2226      }
2227  
2228 <    if ((parse_flags & AWILD) && !valid_wild_card(source_p, YES, 2, *up_p, *h_p))
2228 >    if ((parse_flags & AWILD) && !valid_wild_card(source_p, 1, 2, *up_p, *h_p))
2229        return -1;
2230    }
2231    else
2232 <    if ((parse_flags & AWILD) && !valid_wild_card(source_p, YES, 1, *up_p))
2232 >    if ((parse_flags & AWILD) && !valid_wild_card(source_p, 1, 1, *up_p))
2233        return -1;
2234  
2235    if (reason != NULL)
2236    {
2237 <    if (parc != 0)
2237 >    if (parc != 0 && !EmptyString(*parv))
2238      {
2239        *reason = *parv;
2240 <      if (!valid_comment(source_p, *reason, YES))
2240 >      if (!valid_comment(source_p, *reason, 1))
2241          return -1;
2242      }
2243      else
# Line 3436 | Line 2273 | find_user_host(struct Client *source_p,
2273    {
2274      /* Explicit user@host mask given */
2275  
2276 <    if(hostp != NULL)                            /* I'm a little user@host */
2276 >    if (hostp != NULL)                            /* I'm a little user@host */
2277      {
2278        *(hostp++) = '\0';                       /* short and squat */
2279        if (*user_host_or_nick)
# Line 3457 | Line 2294 | find_user_host(struct Client *source_p,
2294      
2295      return 1;
2296    }
2297 <  else if (!(flags & NOUSERLOOKUP))
2297 >  else
2298    {
2299      /* Try to find user@host mask from nick */
2300      /* Okay to use source_p as the first param, because source_p == client_p */
# Line 3505 | Line 2342 | find_user_host(struct Client *source_p,
2342   int
2343   valid_comment(struct Client *source_p, char *comment, int warn)
2344   {
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
2345    if (strlen(comment) > REASONLEN)
2346      comment[REASONLEN-1] = '\0';
2347  
# Line 3527 | Line 2356 | valid_comment(struct Client *source_p, c
2356   * side effects - none
2357   */
2358   int
2359 < match_conf_password(const char *password, const struct AccessItem *aconf)
2359 > match_conf_password(const char *password, const struct MaskItem *conf)
2360   {
2361    const char *encr = NULL;
2362  
2363 <  if (password == NULL || aconf->passwd == NULL)
2363 >  if (EmptyString(password) || EmptyString(conf->passwd))
2364      return 0;
2365  
2366 <  if (aconf->flags & CONF_FLAGS_ENCRYPTED)
2367 <  {
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 <  }
2366 >  if (conf->flags & CONF_FLAGS_ENCRYPTED)
2367 >    encr = crypt(password, conf->passwd);
2368    else
2369      encr = password;
2370  
2371 <  return !strcmp(encr, aconf->passwd);
2371 >  return !strcmp(encr, conf->passwd);
2372   }
2373  
2374   /*
# Line 3559 | Line 2377 | match_conf_password(const char *password
2377   * inputs       - client sending the cluster
2378   *              - command name "KLINE" "XLINE" etc.
2379   *              - capab -- CAP_KLN etc. from s_serv.h
2380 < *              - cluster type -- CLUSTER_KLINE etc. from s_conf.h
2380 > *              - cluster type -- CLUSTER_KLINE etc. from conf.h
2381   *              - pattern and args to send along
2382   * output       - none
2383   * side effects - Take source_p send the pattern with args given
# Line 3567 | Line 2385 | match_conf_password(const char *password
2385   */
2386   void
2387   cluster_a_line(struct Client *source_p, const char *command,
2388 <               int capab, int cluster_type, const char *pattern, ...)
2388 >               int capab, int cluster_type, const char *pattern, ...)
2389   {
2390    va_list args;
2391    char buffer[IRCD_BUFSIZE];
2392 <  struct ConfItem *conf;
3575 <  dlink_node *ptr;
2392 >  const dlink_node *ptr = NULL;
2393  
2394    va_start(args, pattern);
2395    vsnprintf(buffer, sizeof(buffer), pattern, args);
# Line 3580 | Line 2397 | cluster_a_line(struct Client *source_p,
2397  
2398    DLINK_FOREACH(ptr, cluster_items.head)
2399    {
2400 <    conf = ptr->data;
2400 >    const struct MaskItem *conf = ptr->data;
2401  
2402      if (conf->flags & cluster_type)
3586    {
2403        sendto_match_servs(source_p, conf->name, CAP_CLUSTER|capab,
2404                           "%s %s %s", command, conf->name, buffer);
3589    }
2405    }
2406   }
2407  
# Line 3618 | Line 2433 | cluster_a_line(struct Client *source_p,
2433   * @                            *       *       *
2434   * !                            *       *       *
2435   */
3621
2436   void
2437 < split_nuh(char *mask, char **nick, char **user, char **host)
2437 > split_nuh(struct split_nuh_item *const iptr)
2438   {
2439    char *p = NULL, *q = NULL;
2440  
2441 <  if ((p = strchr(mask, '!')) != NULL)
2441 >  if (iptr->nickptr)
2442 >    strlcpy(iptr->nickptr, "*", iptr->nicksize);
2443 >  if (iptr->userptr)
2444 >    strlcpy(iptr->userptr, "*", iptr->usersize);
2445 >  if (iptr->hostptr)
2446 >    strlcpy(iptr->hostptr, "*", iptr->hostsize);
2447 >
2448 >  if ((p = strchr(iptr->nuhmask, '!')))
2449    {
2450      *p = '\0';
3630    if (nick != NULL)
3631    {
3632      if (*mask != '\0')
3633        *nick = xstrldup(mask, NICKLEN);
3634      else
3635        DupString(*nick, "*");
3636    }
2451  
2452 <    if ((q = strchr(++p, '@')) != NULL)
2453 <    {
2454 <      *q = '\0';
2452 >    if (iptr->nickptr && *iptr->nuhmask != '\0')
2453 >      strlcpy(iptr->nickptr, iptr->nuhmask, iptr->nicksize);
2454 >
2455 >    if ((q = strchr(++p, '@'))) {
2456 >      *q++ = '\0';
2457  
2458        if (*p != '\0')
2459 <        *user = xstrldup(p, USERLEN+1);
3644 <      else
3645 <        DupString(*user, "*");
2459 >        strlcpy(iptr->userptr, p, iptr->usersize);
2460  
2461 <      if (*++q != '\0')
2462 <        *host = xstrldup(q, HOSTLEN+1);
3649 <      else
3650 <        DupString(*host, "*");
2461 >      if (*q != '\0')
2462 >        strlcpy(iptr->hostptr, q, iptr->hostsize);
2463      }
2464      else
2465      {
2466        if (*p != '\0')
2467 <        *user = xstrldup(p, USERLEN+1);
3656 <      else
3657 <        DupString(*user, "*");
3658 <
3659 <      DupString(*host, "*");
2467 >        strlcpy(iptr->userptr, p, iptr->usersize);
2468      }
2469    }
2470 <  else  /* No ! found so lets look for a user@host */
2470 >  else
2471    {
2472 <    if ((p = strchr(mask, '@')) != NULL)        /* if found a @ */
2472 >    /* No ! found so lets look for a user@host */
2473 >    if ((p = strchr(iptr->nuhmask, '@')))
2474      {
2475 <      if (nick != NULL)
2476 <        DupString(*nick, "*");
3668 <      *p = '\0';
2475 >      /* if found a @ */
2476 >      *p++ = '\0';
2477  
2478 <      if (*mask != '\0')
2479 <        *user = xstrldup(mask, USERLEN+1);
3672 <      else
3673 <        DupString(*user, "*");
2478 >      if (*iptr->nuhmask != '\0')
2479 >        strlcpy(iptr->userptr, iptr->nuhmask, iptr->usersize);
2480  
2481 <      if (*++p != '\0')
2482 <        *host = xstrldup(p, HOSTLEN+1);
3677 <      else
3678 <        DupString(*host, "*");
2481 >      if (*p != '\0')
2482 >        strlcpy(iptr->hostptr, p, iptr->hostsize);
2483      }
2484 <    else                                        /* no @ found */
2484 >    else
2485      {
2486 <      if (nick != NULL)
2487 <      {
2488 <        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 <      }
2486 >      /* no @ found */
2487 >      if (!iptr->nickptr || strpbrk(iptr->nuhmask, ".:"))
2488 >        strlcpy(iptr->hostptr, iptr->nuhmask, iptr->hostsize);
2489        else
2490 <      {
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);
2490 >        strlcpy(iptr->nickptr, iptr->nuhmask, iptr->nicksize);
2491      }
2492    }
2493   }
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)