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/trunk/src/conf.c (file contents):
Revision 1618 by michael, Tue Oct 30 21:04:38 2012 UTC vs.
Revision 1646 by michael, Wed Nov 7 21:02:43 2012 UTC

# Line 51 | Line 51
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  
55 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. */
# Line 65 | Line 66 | dlink_list xconf_items   = { NULL, NULL,
66   dlink_list rxconf_items  = { NULL, NULL, 0 };
67   dlink_list rkconf_items  = { NULL, NULL, 0 };
68   dlink_list nresv_items   = { NULL, NULL, 0 };
68 dlink_list class_items   = { NULL, NULL, 0 };
69
70 dlink_list temporary_xlines  = { NULL, NULL, 0 };
69   dlink_list temporary_resv = { NULL, NULL, 0 };
70  
71   extern unsigned int lineno;
# Line 80 | Line 78 | struct conf_parser_context conf_parser_c
78   /* internally defined functions */
79   static void read_conf(FILE *);
80   static void clear_out_old_conf(void);
83 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);
92 < 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  
95 /*
96 * bit_len
97 */
98 static int cidr_limit_reached(int, struct irc_ssaddr *, struct ClassItem *);
99 static void remove_from_cidr_check(struct irc_ssaddr *, struct ClassItem *);
100 static void destroy_cidr_class(struct ClassItem *);
101
102 static void flags_to_ascii(unsigned int, const unsigned int[], char *, int);
103
104 /* address of default class conf */
105 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 113 | Line 98 | static struct ConfItem *class_default;
98   struct ip_entry
99   {
100    struct irc_ssaddr ip;
101 <  int count;
101 >  unsigned int count;
102    time_t last_attempt;
103    struct ip_entry *next;
104   };
# Line 123 | Line 108 | static BlockHeap *ip_entry_heap = NULL;
108   static int ip_entries_count = 0;
109  
110  
126 void *
127 map_to_conf(struct ConfItem *aconf)
128 {
129  void *conf;
130  conf = (void *)((uintptr_t)aconf +
131                  (uintptr_t)sizeof(struct ConfItem));
132  return(conf);
133 }
134
135 struct ConfItem *
136 unmap_conf_item(void *aconf)
137 {
138  struct ConfItem *conf;
139
140  conf = (struct ConfItem *)((uintptr_t)aconf -
141                             (uintptr_t)sizeof(struct ConfItem));
142  return(conf);
143 }
144
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 155 | Line 121 | unmap_conf_item(void *aconf)
121   static void
122   conf_dns_callback(void *vptr, const struct irc_ssaddr *addr, const char *name)
123   {
124 <  struct AccessItem *aconf = vptr;
124 >  struct MaskItem *conf = vptr;
125  
126 <  aconf->dns_pending = 0;
126 >  conf->dns_pending = 0;
127  
128    if (addr != NULL)
129 <    memcpy(&aconf->addr, addr, sizeof(aconf->addr));
129 >    memcpy(&conf->addr, addr, sizeof(conf->addr));
130    else
131 <    aconf->dns_failed = 1;
131 >    conf->dns_failed = 1;
132   }
133  
134   /* conf_dns_lookup()
# Line 172 | Line 138 | conf_dns_callback(void *vptr, const stru
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_pending)
143 >  if (!conf->dns_pending)
144    {
145 <    aconf->dns_pending = 1;
146 <    gethost_byname(conf_dns_callback, aconf, aconf->host);
145 >    conf->dns_pending = 1;
146 >    gethost_byname(conf_dns_callback, conf, conf->host);
147    }
148   }
149  
150 < /* make_conf_item()
151 < *
186 < * inputs       - type of item
187 < * output       - pointer to new conf entry
188 < * side effects - none
189 < */
190 < struct ConfItem *
191 < 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;
195 <  struct ClassItem *aclass = NULL;
196 <  int status = 0;
197 <
198 <  switch (type)
199 <  {
200 <  case DLINE_TYPE:
201 <  case EXEMPTDLINE_TYPE:
202 <  case GLINE_TYPE:
203 <  case KLINE_TYPE:
204 <  case CLIENT_TYPE:
205 <  case OPER_TYPE:
206 <  case SERVER_TYPE:
207 <    conf = MyMalloc(sizeof(struct ConfItem) +
208 <                    sizeof(struct AccessItem));
209 <    aconf = map_to_conf(conf);
210 <    aconf->aftype = AF_INET;
153 >  struct MaskItem *conf = MyMalloc(sizeof(*conf));
154 >  dlink_list *list = NULL;
155  
156 <    /* Yes, sigh. switch on type again */
157 <    switch (type)
158 <    {
215 <    case EXEMPTDLINE_TYPE:
216 <      status = CONF_EXEMPTDLINE;
217 <      break;
218 <
219 <    case DLINE_TYPE:
220 <      status = CONF_DLINE;
221 <      break;
222 <
223 <    case KLINE_TYPE:
224 <      status = CONF_KLINE;
225 <      break;
226 <
227 <    case GLINE_TYPE:
228 <      status = CONF_GLINE;
229 <      break;
230 <
231 <    case CLIENT_TYPE:
232 <      status = CONF_CLIENT;
233 <      break;
234 <
235 <    case OPER_TYPE:
236 <      status = CONF_OPERATOR;
237 <      dlinkAdd(conf, &conf->node, &oconf_items);
238 <      break;
239 <
240 <    case SERVER_TYPE:
241 <      status = CONF_SERVER;
242 <      dlinkAdd(conf, &conf->node, &server_items);
243 <      break;
244 <
245 <    default:
246 <      break;
247 <    }
248 <    aconf->status = status;
249 <    break;
250 <
251 <  case ULINE_TYPE:
252 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
253 <                                       sizeof(struct MatchItem));
254 <    dlinkAdd(conf, &conf->node, &uconf_items);
255 <    break;
256 <
257 <  case XLINE_TYPE:
258 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
259 <                                       sizeof(struct MatchItem));
260 <    dlinkAdd(conf, &conf->node, &xconf_items);
261 <    break;
262 < #ifdef HAVE_LIBPCRE
263 <  case RXLINE_TYPE:
264 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
265 <                                       sizeof(struct MatchItem));
266 <    dlinkAdd(conf, &conf->node, &rxconf_items);
267 <    break;
268 <
269 <  case RKLINE_TYPE:
270 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
271 <                                       sizeof(struct AccessItem));
272 <    aconf = map_to_conf(conf);
273 <    aconf->status = CONF_KLINE;
274 <    dlinkAdd(conf, &conf->node, &rkconf_items);
275 <    break;
276 < #endif
277 <  case CLUSTER_TYPE:
278 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem));
279 <    dlinkAdd(conf, &conf->node, &cluster_items);
280 <    break;
281 <
282 <  case CRESV_TYPE:
283 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
284 <                                       sizeof(struct ResvChannel));
285 <    break;
286 <
287 <  case NRESV_TYPE:
288 <    conf = (struct ConfItem *)MyMalloc(sizeof(struct ConfItem) +
289 <                                       sizeof(struct MatchItem));
290 <    dlinkAdd(conf, &conf->node, &nresv_items);
291 <    break;
292 <
293 <  case SERVICE_TYPE:
294 <    status = CONF_SERVICE;
295 <    conf = MyMalloc(sizeof(struct ConfItem));
296 <    dlinkAdd(conf, &conf->node, &service_items);
297 <    break;
298 <
299 <  case CLASS_TYPE:
300 <    conf = MyMalloc(sizeof(struct ConfItem) +
301 <                           sizeof(struct ClassItem));
302 <    dlinkAdd(conf, &conf->node, &class_items);
303 <
304 <    aclass = map_to_conf(conf);
305 <    aclass->active = 1;
306 <    aclass->con_freq = DEFAULT_CONNECTFREQUENCY;
307 <    aclass->ping_freq = DEFAULT_PINGFREQUENCY;
308 <    aclass->max_total = MAXIMUM_LINKS_DEFAULT;
309 <    aclass->max_sendq = DEFAULT_SENDQ;
310 <    aclass->max_recvq = DEFAULT_RECVQ;
311 <
312 <    break;
313 <
314 <  default:
315 <    conf = NULL;
316 <    break;
317 <  }
318 <
319 <  /* XXX Yes, this will core if default is hit. I want it to for now - db */
320 <  conf->type = type;
156 >  conf->type   = type;
157 >  conf->active = 1;
158 >  conf->aftype = AF_INET;
159  
160 +  if ((list = map_to_list(type)))
161 +    dlinkAdd(conf, &conf->node, list);
162    return conf;
163   }
164  
165   void
166 < delete_conf_item(struct ConfItem *conf)
166 > conf_free(struct MaskItem *conf)
167   {
168 <  dlink_node *m = NULL, *m_next = NULL;
169 <  struct MatchItem *match_item;
170 <  struct AccessItem *aconf;
171 <  ConfType type = conf->type;
168 >  dlink_node *ptr = NULL, *ptr_next = NULL;
169 >  dlink_list *list = NULL;
170 >
171 >  if (conf->node.next)
172 >    if ((list = map_to_list(conf->type)))
173 >      dlinkDelete(&conf->node, list);
174  
175    MyFree(conf->name);
334  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_pending)
189 <      delete_resolver_queries(aconf);
190 <    if (aconf->passwd != NULL)
191 <      memset(aconf->passwd, 0, strlen(aconf->passwd));
192 <    if (aconf->spasswd != NULL)
352 <      memset(aconf->spasswd, 0, strlen(aconf->spasswd));
353 <    aconf->class_ptr = NULL;
354 <
355 <    MyFree(aconf->passwd);
356 <    MyFree(aconf->spasswd);
357 <    MyFree(aconf->reason);
358 <    MyFree(aconf->oper_reason);
359 <    MyFree(aconf->user);
360 <    MyFree(aconf->host);
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 <    MyFree(aconf->cipher_list);
194 >  MyFree(conf->cipher_list);
195  
196 <    if (aconf->rsa_public_key)
197 <      RSA_free(aconf->rsa_public_key);
366 <    MyFree(aconf->rsa_public_key_file);
367 < #endif
196 >  if (conf->rsa_public_key)
197 >    RSA_free(conf->rsa_public_key);
198  
199 <    /* Yes, sigh. switch on type again */
370 <    switch(type)
371 <    {
372 <    case EXEMPTDLINE_TYPE:
373 <    case DLINE_TYPE:
374 <    case GLINE_TYPE:
375 <    case KLINE_TYPE:
376 <    case CLIENT_TYPE:
377 <      MyFree(conf);
378 <      break;
379 <
380 <    case OPER_TYPE:
381 <      aconf = map_to_conf(conf);
382 <      if (!IsConfIllegal(aconf))
383 <        dlinkDelete(&conf->node, &oconf_items);
384 <      MyFree(conf);
385 <      break;
386 <
387 <    case SERVER_TYPE:
388 <      aconf = map_to_conf(conf);
389 <
390 <      DLINK_FOREACH_SAFE(m, m_next, aconf->hub_list.head)
391 <      {
392 <        MyFree(m->data);
393 <        free_dlink_node(m);
394 <      }
395 <
396 <      DLINK_FOREACH_SAFE(m, m_next, aconf->leaf_list.head)
397 <      {
398 <        MyFree(m->data);
399 <        free_dlink_node(m);  
400 <      }
401 <
402 <      if (!IsConfIllegal(aconf))
403 <        dlinkDelete(&conf->node, &server_items);
404 <      MyFree(conf);
405 <      break;
406 <
407 <    default:
408 <      break;
409 <    }
410 <    break;
411 <
412 <  case ULINE_TYPE:
413 <    match_item = map_to_conf(conf);
414 <    MyFree(match_item->user);
415 <    MyFree(match_item->host);
416 <    MyFree(match_item->reason);
417 <    MyFree(match_item->oper_reason);
418 <    dlinkDelete(&conf->node, &uconf_items);
419 <    MyFree(conf);
420 <    break;
421 <
422 <  case XLINE_TYPE:
423 <    match_item = map_to_conf(conf);
424 <    MyFree(match_item->user);
425 <    MyFree(match_item->host);
426 <    MyFree(match_item->reason);
427 <    MyFree(match_item->oper_reason);
428 <    dlinkDelete(&conf->node, &xconf_items);
429 <    MyFree(conf);
430 <    break;
431 < #ifdef HAVE_LIBPCRE
432 <  case RKLINE_TYPE:
433 <    aconf = map_to_conf(conf);
434 <    MyFree(aconf->regexuser);
435 <    MyFree(aconf->regexhost);
436 <    MyFree(aconf->user);
437 <    MyFree(aconf->host);
438 <    MyFree(aconf->reason);
439 <    MyFree(aconf->oper_reason);
440 <    dlinkDelete(&conf->node, &rkconf_items);
441 <    MyFree(conf);
442 <    break;
443 <
444 <  case RXLINE_TYPE:
445 <    MyFree(conf->regexpname);
446 <    match_item = map_to_conf(conf);
447 <    MyFree(match_item->user);
448 <    MyFree(match_item->host);
449 <    MyFree(match_item->reason);
450 <    MyFree(match_item->oper_reason);
451 <    dlinkDelete(&conf->node, &rxconf_items);
452 <    MyFree(conf);
453 <    break;
199 >  MyFree(conf->rsa_public_key_file);
200   #endif
201 <  case NRESV_TYPE:
202 <    match_item = map_to_conf(conf);
203 <    MyFree(match_item->user);
204 <    MyFree(match_item->host);
459 <    MyFree(match_item->reason);
460 <    MyFree(match_item->oper_reason);
461 <    dlinkDelete(&conf->node, &nresv_items);
462 <
463 <    if (conf->flags & CONF_FLAGS_TEMPORARY)
464 <      if ((m = dlinkFindDelete(&temporary_resv, conf)) != NULL)
465 <        free_dlink_node(m);
466 <
467 <    MyFree(conf);
468 <    break;
469 <
470 <  case CLUSTER_TYPE:
471 <    dlinkDelete(&conf->node, &cluster_items);
472 <    MyFree(conf);
473 <    break;
474 <
475 <  case CRESV_TYPE:
476 <    if (conf->flags & CONF_FLAGS_TEMPORARY)
477 <      if ((m = dlinkFindDelete(&temporary_resv, conf)) != NULL)
478 <        free_dlink_node(m);
479 <
480 <    MyFree(conf);
481 <    break;
482 <
483 <  case CLASS_TYPE:
484 <    dlinkDelete(&conf->node, &class_items);
485 <    MyFree(conf);
486 <    break;
487 <
488 <  case SERVICE_TYPE:
489 <    dlinkDelete(&conf->node, &service_items);
490 <    MyFree(conf);
491 <    break;
492 <
493 <  default:
494 <    break;
201 >  DLINK_FOREACH_SAFE(ptr, ptr_next, conf->hub_list.head)
202 >  {
203 >    MyFree(ptr->data);
204 >    free_dlink_node(ptr);
205    }
496 }
206  
207 < /* free_access_item()
208 < *
209 < * inputs       - pointer to conf to free
210 < * output       - none
211 < * side effects - crucial password fields are zeroed, conf is freed
503 < */
504 < void
505 < free_access_item(struct AccessItem *aconf)
506 < {
507 <  struct ConfItem *conf;
207 >  DLINK_FOREACH_SAFE(ptr, ptr_next, conf->leaf_list.head)
208 >  {
209 >    MyFree(ptr->data);
210 >    free_dlink_node(ptr);
211 >  }
212  
213 <  if (aconf == NULL)
510 <    return;
511 <  conf = unmap_conf_item(aconf);
512 <  delete_conf_item(conf);
213 >  MyFree(conf);
214   }
215  
216 < static const unsigned int shared_bit_table[] =
217 <  { 'K', 'k', 'U', 'X', 'x', 'Y', 'Q', 'q', 'R', 'L', 0};
216 > static const struct shared_flags
217 > {
218 >  const unsigned int type;
219 >  const unsigned char letter;
220 > } flag_table[] = {
221 >  { SHARED_KLINE,   'K' },
222 >  { SHARED_UNKLINE, 'U' },
223 >  { SHARED_XLINE,   'X' },
224 >  { SHARED_UNXLINE, 'Y' },
225 >  { SHARED_RESV,    'Q' },
226 >  { SHARED_UNRESV,  'R' },
227 >  { SHARED_LOCOPS,  'L' },
228 >  { SHARED_DLINE,   'D' },
229 >  { SHARED_UNDLINE, 'E' },
230 >  { 0, '\0' }
231 > };
232  
233 < /* report_confitem_types()
519 < *
233 > /*
234   * inputs       - pointer to client requesting confitem report
235   *              - ConfType to report
236   * output       - none
237   * side effects -
238   */
239   void
240 < report_confitem_types(struct Client *source_p, ConfType type)
240 > report_confitem_types(struct Client *source_p, enum maskitem_type type)
241   {
242    dlink_node *ptr = NULL, *dptr = NULL;
243 <  struct ConfItem *conf = NULL;
244 <  struct AccessItem *aconf = NULL;
245 <  struct MatchItem *matchitem = NULL;
532 <  struct ClassItem *classitem = NULL;
243 >  struct MaskItem *conf = NULL;
244 >  const struct ClassItem *class = NULL;
245 >  const struct shared_flags *shared = NULL;
246    char buf[12];
247    char *p = NULL;
248  
249    switch (type)
250    {
251 <  case XLINE_TYPE:
251 >  case CONF_XLINE:
252      DLINK_FOREACH(ptr, xconf_items.head)
253      {
254        conf = ptr->data;
542      matchitem = map_to_conf(conf);
255  
256        sendto_one(source_p, form_str(RPL_STATSXLINE),
257                   me.name, source_p->name,
258 <                 matchitem->hold ? "x": "X", matchitem->count,
259 <                 conf->name, matchitem->reason);
258 >                 conf->hold ? "x": "X", conf->count,
259 >                 conf->name, conf->reason);
260      }
261      break;
262  
263   #ifdef HAVE_LIBPCRE
264 <  case RXLINE_TYPE:
264 >  case CONF_RXLINE:
265      DLINK_FOREACH(ptr, rxconf_items.head)
266      {
267        conf = ptr->data;
556      matchitem = map_to_conf(conf);
268  
269        sendto_one(source_p, form_str(RPL_STATSXLINE),
270                   me.name, source_p->name,
271 <                 "XR", matchitem->count,
272 <                 conf->name, matchitem->reason);
271 >                 "XR", conf->count,
272 >                 conf->name, conf->reason);
273      }
274      break;
275  
276 <  case RKLINE_TYPE:
276 >  case CONF_RKLINE:
277      DLINK_FOREACH(ptr, rkconf_items.head)
278      {
279 <      aconf = map_to_conf((conf = ptr->data));
279 >      conf = ptr->data;
280  
281        sendto_one(source_p, form_str(RPL_STATSKLINE), me.name,
282 <                 source_p->name, "KR", aconf->host, aconf->user,
283 <                 aconf->reason, aconf->oper_reason ? aconf->oper_reason : "");
282 >                 source_p->name, "KR", conf->host, conf->user,
283 >                 conf->reason);
284      }
285      break;
286   #endif
287  
288 <  case ULINE_TYPE:
288 >  case CONF_ULINE:
289 >    shared = flag_table;
290      DLINK_FOREACH(ptr, uconf_items.head)
291      {
292        conf = ptr->data;
581      matchitem = map_to_conf(conf);
293  
294        p = buf;
295  
585      /* some of these are redundant for the sake of
586       * consistency with cluster{} flags
587       */
296        *p++ = 'c';
297 <      flags_to_ascii(matchitem->action, shared_bit_table, p, 0);
297 >      for (; shared->type; ++shared)
298 >        if (shared->type & conf->flags)
299 >          *p++ = shared->letter;
300 >        else
301 >          *p++ = ToLower(shared->letter);
302  
303        sendto_one(source_p, form_str(RPL_STATSULINE),
304                   me.name, source_p->name, conf->name,
305 <                 matchitem->user?matchitem->user: "*",
306 <                 matchitem->host?matchitem->host: "*", buf);
305 >                 conf->user?conf->user: "*",
306 >                 conf->host?conf->host: "*", buf);
307      }
308  
309 +    shared = flag_table;
310      DLINK_FOREACH(ptr, cluster_items.head)
311      {
312        conf = ptr->data;
# Line 601 | Line 314 | report_confitem_types(struct Client *sou
314        p = buf;
315  
316        *p++ = 'C';
317 <      flags_to_ascii(conf->flags, shared_bit_table, p, 0);
317 >      for (; shared->type; ++shared)
318 >        if (shared->type & conf->flags)
319 >          *p++ = shared->letter;
320 >        else
321 >          *p++ = ToLower(shared->letter);
322  
323        sendto_one(source_p, form_str(RPL_STATSULINE),
324                   me.name, source_p->name, conf->name,
# Line 610 | Line 327 | report_confitem_types(struct Client *sou
327  
328      break;
329  
330 <  case OPER_TYPE:
330 >  case CONF_OPER:
331      DLINK_FOREACH(ptr, oconf_items.head)
332      {
333        conf = ptr->data;
617      aconf = map_to_conf(conf);
334  
335        /* Don't allow non opers to see oper privs */
336        if (HasUMode(source_p, UMODE_OPER))
337          sendto_one(source_p, form_str(RPL_STATSOLINE),
338 <                   me.name, source_p->name, 'O', aconf->user, aconf->host,
339 <                   conf->name, oper_privs_as_string(aconf->port),
340 <                   aconf->class_ptr ? aconf->class_ptr->name : "<default>");
338 >                   me.name, source_p->name, 'O', conf->user, conf->host,
339 >                   conf->name, oper_privs_as_string(conf->port),
340 >                   conf->class ? conf->class->name : "<default>");
341        else
342          sendto_one(source_p, form_str(RPL_STATSOLINE),
343 <                   me.name, source_p->name, 'O', aconf->user, aconf->host,
343 >                   me.name, source_p->name, 'O', conf->user, conf->host,
344                     conf->name, "0",
345 <                   aconf->class_ptr ? aconf->class_ptr->name : "<default>");
345 >                   conf->class ? conf->class->name : "<default>");
346      }
347      break;
348  
349 <  case CLASS_TYPE:
350 <    DLINK_FOREACH(ptr, class_items.head)
349 >  case CONF_CLASS:
350 >    DLINK_FOREACH(ptr, class_get_list()->head)
351      {
352 <      conf = ptr->data;
637 <      classitem = map_to_conf(conf);
352 >      class = ptr->data;
353        sendto_one(source_p, form_str(RPL_STATSYLINE),
354                   me.name, source_p->name, 'Y',
355 <                 conf->name, classitem->ping_freq,
356 <                 classitem->con_freq,
357 <                 classitem->max_total, classitem->max_sendq,
358 <                 classitem->max_recvq,
359 <                 classitem->curr_user_count,
360 <                 classitem->number_per_cidr, classitem->cidr_bitlen_ipv4,
361 <                 classitem->number_per_cidr, classitem->cidr_bitlen_ipv6,
362 <                 classitem->active ? "active" : "disabled");
355 >                 class->name, class->ping_freq,
356 >                 class->con_freq,
357 >                 class->max_total, class->max_sendq,
358 >                 class->max_recvq,
359 >                 class->ref_count,
360 >                 class->number_per_cidr, class->cidr_bitlen_ipv4,
361 >                 class->number_per_cidr, class->cidr_bitlen_ipv6,
362 >                 class->active ? "active" : "disabled");
363      }
364      break;
365  
366 <  case CONF_TYPE:
652 <  case CLIENT_TYPE:
653 <    break;
654 <
655 <  case SERVICE_TYPE:
366 >  case CONF_SERVICE:
367      DLINK_FOREACH(ptr, service_items.head)
368      {
369        conf = ptr->data;
# Line 661 | Line 372 | report_confitem_types(struct Client *sou
372      }
373      break;
374  
375 <  case SERVER_TYPE:
375 >  case CONF_SERVER:
376      DLINK_FOREACH(ptr, server_items.head)
377      {
378        p = buf;
668
379        conf = ptr->data;
670      aconf = map_to_conf(conf);
380  
381        buf[0] = '\0';
382  
383 <      if (IsConfAllowAutoConn(aconf))
383 >      if (IsConfAllowAutoConn(conf))
384          *p++ = 'A';
385 <      if (IsConfSSL(aconf))
385 >      if (IsConfSSL(conf))
386          *p++ = 'S';
387        if (buf[0] == '\0')
388          *p++ = '*';
# Line 685 | Line 394 | report_confitem_types(struct Client *sou
394         */
395        if (!ConfigServerHide.hide_server_ips && HasUMode(source_p, UMODE_ADMIN))
396          sendto_one(source_p, form_str(RPL_STATSCLINE),
397 <                   me.name, source_p->name, 'C', aconf->host,
398 <                   buf, conf->name, aconf->port,
399 <                   aconf->class_ptr ? aconf->class_ptr->name : "<default>");
397 >                   me.name, source_p->name, 'C', conf->host,
398 >                   buf, conf->name, conf->port,
399 >                   conf->class ? conf->class->name : "<default>");
400          else
401            sendto_one(source_p, form_str(RPL_STATSCLINE),
402                       me.name, source_p->name, 'C',
403 <                     "*@127.0.0.1", buf, conf->name, aconf->port,
404 <                     aconf->class_ptr ? aconf->class_ptr->name : "<default>");
403 >                     "*@127.0.0.1", buf, conf->name, conf->port,
404 >                     conf->class ? conf->class->name : "<default>");
405      }
406      break;
407  
408 <  case HUB_TYPE:
408 >  case CONF_HUB:
409      DLINK_FOREACH(ptr, server_items.head)
410      {
411        conf = ptr->data;
703      aconf = map_to_conf(conf);
412  
413 <      DLINK_FOREACH(dptr, aconf->hub_list.head)
413 >      DLINK_FOREACH(dptr, conf->hub_list.head)
414          sendto_one(source_p, form_str(RPL_STATSHLINE), me.name,
415                     source_p->name, 'H', dptr->data, conf->name, 0, "*");
416      }
709    break;
417  
711  case LEAF_TYPE:
418      DLINK_FOREACH(ptr, server_items.head)
419      {
420        conf = ptr->data;
715      aconf = map_to_conf(conf);
421  
422 <      DLINK_FOREACH(dptr, aconf->leaf_list.head)
422 >      DLINK_FOREACH(dptr, conf->leaf_list.head)
423          sendto_one(source_p, form_str(RPL_STATSLLINE), me.name,
424                     source_p->name, 'L', dptr->data, conf->name, 0, "*");
425      }
426 +
427      break;
428  
723  case GLINE_TYPE:
724  case KLINE_TYPE:
725  case DLINE_TYPE:
726  case EXEMPTDLINE_TYPE:
727  case CRESV_TYPE:
728  case NRESV_TYPE:
729  case CLUSTER_TYPE:
429    default:
430      break;
431    }
# Line 745 | Line 444 | report_confitem_types(struct Client *sou
444   *                Look for conf lines which have the same
445   *                status as the flags passed.
446   */
447 < static void *
448 < check_client(va_list args)
447 > int
448 > check_client(struct Client *source_p)
449   {
751  struct Client *source_p = va_arg(args, struct Client *);
752  const char *username = va_arg(args, const char *);
450    int i;
451  
452 <  /* I'm already in big trouble if source_p->localClient is NULL -db */
756 <  if ((i = verify_access(source_p, username)))
452 >  if ((i = verify_access(source_p)))
453      ilog(LOG_TYPE_IRCD, "Access denied: %s[%s]",
454           source_p->name, source_p->sockhost);
455  
# Line 811 | Line 507 | check_client(va_list args)
507       break;
508    }
509  
510 <  return (i < 0 ? NULL : source_p);
510 >  return (i < 0 ? 0 : 1);
511   }
512  
513   /* verify_access()
514   *
515   * inputs       - pointer to client to verify
820 *              - pointer to proposed username
516   * output       - 0 if success -'ve if not
517   * side effect  - find the first (best) I line to attach.
518   */
519   static int
520 < verify_access(struct Client *client_p, const char *username)
520 > verify_access(struct Client *client_p)
521   {
522 <  struct AccessItem *aconf = NULL, *rkconf = NULL;
828 <  struct ConfItem *conf = NULL;
522 >  struct MaskItem *conf = NULL, *rkconf = NULL;
523    char non_ident[USERLEN + 1] = { '~', '\0' };
524    const char *uhi[3];
525  
526    if (IsGotId(client_p))
527    {
528 <    aconf = find_address_conf(client_p->host, client_p->username,
528 >    conf = find_address_conf(client_p->host, client_p->username,
529                               &client_p->localClient->ip,
530                               client_p->localClient->aftype,
531                               client_p->localClient->passwd);
532    }
533    else
534    {
535 <    strlcpy(non_ident+1, username, sizeof(non_ident)-1);
536 <    aconf = find_address_conf(client_p->host,non_ident,
535 >    strlcpy(non_ident+1, client_p->username, sizeof(non_ident)-1);
536 >    conf = find_address_conf(client_p->host,non_ident,
537                               &client_p->localClient->ip,
538                               client_p->localClient->aftype,
539                               client_p->localClient->passwd);
# Line 851 | Line 545 | verify_access(struct Client *client_p, c
545  
546    rkconf = find_regexp_kline(uhi);
547  
548 <  if (aconf != NULL)
548 >  if (conf != NULL)
549    {
550 <    if (IsConfClient(aconf) && !rkconf)
550 >    if (IsConfClient(conf) && !rkconf)
551      {
552 <      conf = unmap_conf_item(aconf);
859 <
860 <      if (IsConfRedir(aconf))
552 >      if (IsConfRedir(conf))
553        {
554          sendto_one(client_p, form_str(RPL_REDIR),
555                     me.name, client_p->name,
556                     conf->name ? conf->name : "",
557 <                   aconf->port);
557 >                   conf->port);
558          return(NOT_AUTHORIZED);
559        }
560  
561 <      if (IsConfDoIdentd(aconf))
561 >      if (IsConfDoIdentd(conf))
562          SetNeedId(client_p);
563  
564        /* Thanks for spoof idea amm */
565 <      if (IsConfDoSpoofIp(aconf))
565 >      if (IsConfDoSpoofIp(conf))
566        {
567 <        conf = unmap_conf_item(aconf);
876 <
877 <        if (!ConfigFileEntry.hide_spoof_ips && IsConfSpoofNotice(aconf))
567 >        if (!ConfigFileEntry.hide_spoof_ips && IsConfSpoofNotice(conf))
568            sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
569                                 "%s spoofing: %s as %s",
570                                 client_p->name, client_p->host, conf->name);
# Line 884 | Line 574 | verify_access(struct Client *client_p, c
574  
575        return(attach_iline(client_p, conf));
576      }
577 <    else if (rkconf || IsConfKill(aconf) || (ConfigFileEntry.glines && IsConfGline(aconf)))
577 >    else if (rkconf || IsConfKill(conf) || (ConfigFileEntry.glines && IsConfGline(conf)))
578      {
579        /* XXX */
580 <      aconf = rkconf ? rkconf : aconf;
581 <      if (IsConfGline(aconf))
580 >      conf = rkconf ? rkconf : conf;
581 >      if (IsConfGline(conf))
582          sendto_one(client_p, ":%s NOTICE %s :*** G-lined", me.name,
583                     client_p->name);
584        sendto_one(client_p, ":%s NOTICE %s :*** Banned: %s",
585 <                 me.name, client_p->name, aconf->reason);
585 >                 me.name, client_p->name, conf->reason);
586        return(BANNED_CLIENT);
587      }
588    }
# Line 908 | Line 598 | verify_access(struct Client *client_p, c
598   * side effects - do actual attach
599   */
600   static int
601 < attach_iline(struct Client *client_p, struct ConfItem *conf)
601 > attach_iline(struct Client *client_p, struct MaskItem *conf)
602   {
603 <  struct AccessItem *aconf;
914 <  struct ClassItem *aclass;
603 >  struct ClassItem *class = NULL;
604    struct ip_entry *ip_found;
605    int a_limit_reached = 0;
606 <  int local = 0, global = 0, ident = 0;
606 >  unsigned int local = 0, global = 0, ident = 0;
607  
608    ip_found = find_or_add_ip(&client_p->localClient->ip);
609    ip_found->count++;
610    SetIpHash(client_p);
611  
612 <  aconf = map_to_conf(conf);
924 <  if (aconf->class_ptr == NULL)
612 >  if (conf->class == NULL)
613      return NOT_AUTHORIZED;  /* If class is missing, this is best */
614  
615 <  aclass = map_to_conf(aconf->class_ptr);
615 >  class = conf->class;
616  
617    count_user_host(client_p->username, client_p->host,
618                    &global, &local, &ident);
# Line 933 | Line 621 | attach_iline(struct Client *client_p, st
621     * setting a_limit_reached if any limit is reached.
622     * - Dianora
623     */
624 <  if (aclass->max_total != 0 && aclass->curr_user_count >= aclass->max_total)
624 >  if (class->max_total != 0 && class->ref_count >= class->max_total)
625      a_limit_reached = 1;
626 <  else if (aclass->max_perip != 0 && ip_found->count > aclass->max_perip)
626 >  else if (class->max_perip != 0 && ip_found->count > class->max_perip)
627      a_limit_reached = 1;
628 <  else if (aclass->max_local != 0 && local >= aclass->max_local)
628 >  else if (class->max_local != 0 && local >= class->max_local)
629      a_limit_reached = 1;
630 <  else if (aclass->max_global != 0 && global >= aclass->max_global)
630 >  else if (class->max_global != 0 && global >= class->max_global)
631      a_limit_reached = 1;
632 <  else if (aclass->max_ident != 0 && ident >= aclass->max_ident &&
632 >  else if (class->max_ident != 0 && ident >= class->max_ident &&
633             client_p->username[0] != '~')
634      a_limit_reached = 1;
635  
636    if (a_limit_reached)
637    {
638 <    if (!IsConfExemptLimits(aconf))
638 >    if (!IsConfExemptLimits(conf))
639        return TOO_MANY;   /* Already at maximum allowed */
640  
641      sendto_one(client_p,
# Line 1196 | Line 884 | garbage_collect_ip_entries(void)
884   * side effects - Disassociate configuration from the client.
885   *                Also removes a class from the list if marked for deleting.
886   */
887 < int
888 < detach_conf(struct Client *client_p, ConfType type)
887 > void
888 > detach_conf(struct Client *client_p, enum maskitem_type type)
889   {
890 <  dlink_node *ptr, *next_ptr;
1203 <  struct ConfItem *conf;
1204 <  struct ClassItem *aclass;
1205 <  struct AccessItem *aconf;
1206 <  struct ConfItem *aclass_conf;
890 >  dlink_node *ptr = NULL, *next_ptr = NULL;
891  
892    DLINK_FOREACH_SAFE(ptr, next_ptr, client_p->localClient->confs.head)
893    {
894 <    conf = ptr->data;
894 >    struct MaskItem *conf = ptr->data;
895  
896 <    if (type == CONF_TYPE || conf->type == type)
897 <    {
898 <      dlinkDelete(ptr, &client_p->localClient->confs);
1215 <      free_dlink_node(ptr);
896 >    assert(conf->type & (CONF_CLIENT | CONF_OPER | CONF_SERVER));
897 >    assert(conf->ref_count > 0);
898 >    assert(conf->class->ref_count > 0);
899  
900 <      switch (conf->type)
901 <      {
1219 <      case CLIENT_TYPE:
1220 <      case OPER_TYPE:
1221 <      case SERVER_TYPE:
1222 <        aconf = map_to_conf(conf);
1223 <
1224 <        assert(aconf->clients > 0);
1225 <
1226 <        if ((aclass_conf = aconf->class_ptr) != NULL)
1227 <        {
1228 <          aclass = map_to_conf(aclass_conf);
1229 <
1230 <          assert(aclass->curr_user_count > 0);
1231 <
1232 <          if (conf->type == CLIENT_TYPE)
1233 <            remove_from_cidr_check(&client_p->localClient->ip, aclass);
1234 <          if (--aclass->curr_user_count == 0 && aclass->active == 0)
1235 <            delete_conf_item(aclass_conf);
1236 <        }
900 >    if (!(conf->type & type))
901 >      continue;
902  
903 <        if (--aconf->clients == 0 && IsConfIllegal(aconf))
904 <          delete_conf_item(conf);
903 >    dlinkDelete(ptr, &client_p->localClient->confs);
904 >    free_dlink_node(ptr);
905  
906 <        break;
907 <      default:
1243 <        break;
1244 <      }
906 >    if (conf->type == CONF_CLIENT)
907 >      remove_from_cidr_check(&client_p->localClient->ip, conf->class);
908  
909 <      if (type != CONF_TYPE)
910 <        return 0;
909 >    if (--conf->class->ref_count == 0 && conf->class->active == 0)
910 >    {
911 >      class_free(conf->class);
912 >      conf->class = NULL;
913      }
1249  }
914  
915 <  return -1;
915 >    if (--conf->ref_count == 0 && conf->active == 0)
916 >      conf_free(conf);
917 >  }
918   }
919  
920   /* attach_conf()
# Line 1262 | Line 928 | detach_conf(struct Client *client_p, Con
928   *                attachment if there was an old one...
929   */
930   int
931 < attach_conf(struct Client *client_p, struct ConfItem *conf)
931 > attach_conf(struct Client *client_p, struct MaskItem *conf)
932   {
1267  struct AccessItem *aconf = map_to_conf(conf);
1268  struct ClassItem *aclass = map_to_conf(aconf->class_ptr);
1269
933    if (dlinkFind(&client_p->localClient->confs, conf) != NULL)
934      return 1;
935  
936 <  if (IsConfIllegal(aconf)) /* TBV: can't happen */
937 <    return NOT_AUTHORIZED;
938 <
1276 <  if (conf->type == CLIENT_TYPE)
1277 <    if (cidr_limit_reached(IsConfExemptLimits(aconf),
1278 <                           &client_p->localClient->ip, aclass))
936 >  if (conf->type == CONF_CLIENT)
937 >    if (cidr_limit_reached(IsConfExemptLimits(conf),
938 >                           &client_p->localClient->ip, conf->class))
939        return TOO_MANY;    /* Already at maximum allowed */
940  
941 <  aclass->curr_user_count++;
942 <  aconf->clients++;
941 >  conf->class->ref_count++;
942 >  conf->ref_count++;
943  
944    dlinkAdd(conf, make_dlink_node(), &client_p->localClient->confs);
945  
# Line 1299 | Line 959 | attach_connect_block(struct Client *clie
959                       const char *host)
960   {
961    dlink_node *ptr;
962 <  struct ConfItem *conf;
1303 <  struct AccessItem *aconf;
962 >  struct MaskItem *conf = NULL;
963  
964    assert(client_p != NULL);
965    assert(host != NULL);
# Line 1311 | Line 970 | attach_connect_block(struct Client *clie
970    DLINK_FOREACH(ptr, server_items.head)
971    {
972      conf = ptr->data;
1314    aconf = map_to_conf(conf);
973  
974 <    if (match(conf->name, name) == 0 || match(aconf->host, host) == 0)
974 >    if (match(conf->name, name) == 0 || match(conf->host, host) == 0)
975        continue;
976  
977      attach_conf(client_p, conf);
# Line 1323 | Line 981 | attach_connect_block(struct Client *clie
981    return 0;
982   }
983  
1326 /* find_conf_exact()
1327 *
1328 * inputs       - type of ConfItem
1329 *              - pointer to name to find
1330 *              - pointer to username to find
1331 *              - pointer to host to find
1332 * output       - NULL or pointer to conf found
1333 * side effects - find a conf entry which matches the hostname
1334 *                and has the same name.
1335 */
1336 struct ConfItem *
1337 find_conf_exact(ConfType type, const char *name, const char *user,
1338                const char *host)
1339 {
1340  dlink_node *ptr;
1341  dlink_list *list_p;
1342  struct ConfItem *conf = NULL;
1343  struct AccessItem *aconf;
1344
1345  /* Only valid for OPER_TYPE and ...? */
1346  list_p = map_to_list(type);
1347
1348  DLINK_FOREACH(ptr, (*list_p).head)
1349  {
1350    conf = ptr->data;
1351
1352    if (conf->name == NULL)
1353      continue;
1354    aconf = map_to_conf(conf);
1355    if (aconf->host == NULL)
1356      continue;
1357    if (irccmp(conf->name, name) != 0)
1358      continue;
1359
1360    /*
1361    ** Accept if the *real* hostname (usually sockethost)
1362    ** socket host) matches *either* host or name field
1363    ** of the configuration.
1364    */
1365    if (!match(aconf->host, host) || !match(aconf->user, user))
1366      continue;
1367    if (type == OPER_TYPE)
1368    {
1369      struct ClassItem *aclass = map_to_conf(aconf->class_ptr);
1370
1371      if (aconf->clients >= aclass->max_total)
1372        continue;
1373    }
1374
1375    return conf;
1376  }
1377
1378  return NULL;
1379 }
1380
984   /* find_conf_name()
985   *
986   * inputs       - pointer to conf link list to search
# Line 1387 | Line 990 | find_conf_exact(ConfType type, const cha
990   * side effects - find a conf entry which matches the name
991   *                and has the given mask.
992   */
993 < struct ConfItem *
994 < find_conf_name(dlink_list *list, const char *name, ConfType type)
993 > struct MaskItem *
994 > find_conf_name(dlink_list *list, const char *name, enum maskitem_type type)
995   {
996    dlink_node *ptr;
997 <  struct ConfItem* conf;
997 >  struct MaskItem* conf;
998  
999    DLINK_FOREACH(ptr, list->head)
1000    {
# Line 1415 | Line 1018 | find_conf_name(dlink_list *list, const c
1018   * side effects - none
1019   */
1020   static dlink_list *
1021 < map_to_list(ConfType type)
1021 > map_to_list(enum maskitem_type type)
1022   {
1023    switch(type)
1024    {
1025 <  case RXLINE_TYPE:
1025 >  case CONF_RKLINE:
1026 >    return(&rkconf_items);
1027 >    break;
1028 >  case CONF_RXLINE:
1029      return(&rxconf_items);
1030      break;
1031 <  case XLINE_TYPE:
1031 >  case CONF_XLINE:
1032      return(&xconf_items);
1033      break;
1034 <  case ULINE_TYPE:
1034 >  case CONF_ULINE:
1035      return(&uconf_items);
1036      break;
1037 <  case NRESV_TYPE:
1037 >  case CONF_NRESV:
1038      return(&nresv_items);
1039      break;
1040 <  case OPER_TYPE:
1040 >  case CONF_OPER:
1041      return(&oconf_items);
1042      break;
1043 <  case CLASS_TYPE:
1438 <    return(&class_items);
1439 <    break;
1440 <  case SERVER_TYPE:
1043 >  case CONF_SERVER:
1044      return(&server_items);
1045      break;
1046 <  case SERVICE_TYPE:
1046 >  case CONF_SERVICE:
1047      return(&service_items);
1048      break;
1049 <  case CLUSTER_TYPE:
1049 >  case CONF_CLUSTER:
1050      return(&cluster_items);
1051      break;
1449  case CONF_TYPE:
1450  case GLINE_TYPE:
1451  case KLINE_TYPE:
1452  case DLINE_TYPE:
1453  case CRESV_TYPE:
1052    default:
1053      return NULL;
1054    }
# Line 1462 | Line 1060 | map_to_list(ConfType type)
1060   *              - pointer to name string to find
1061   *              - pointer to user
1062   *              - pointer to host
1063 < *              - optional action to match on as well
1064 < * output       - NULL or pointer to found struct MatchItem
1063 > *              - optional flags to match on as well
1064 > * output       - NULL or pointer to found struct MaskItem
1065   * side effects - looks for a match on name field
1066   */
1067 < struct ConfItem *
1068 < find_matching_name_conf(ConfType type, const char *name, const char *user,
1069 <                        const char *host, int action)
1067 > struct MaskItem *
1068 > find_matching_name_conf(enum maskitem_type type, const char *name, const char *user,
1069 >                        const char *host, unsigned int flags)
1070   {
1071    dlink_node *ptr=NULL;
1072 <  struct ConfItem *conf=NULL;
1475 <  struct AccessItem *aconf=NULL;
1476 <  struct MatchItem *match_item=NULL;
1072 >  struct MaskItem *conf=NULL;
1073    dlink_list *list_p = map_to_list(type);
1074  
1075    switch (type)
1076    {
1077   #ifdef HAVE_LIBPCRE
1078 <  case RXLINE_TYPE:
1078 >  case CONF_RXLINE:
1079        DLINK_FOREACH(ptr, list_p->head)
1080        {
1081          conf = ptr->data;
1082          assert(conf->regexpname);
1083  
1084 <        if (!ircd_pcre_exec(conf->regexpname, name))
1084 >        if (!ircd_pcre_exec(conf->regexuser, name))
1085            return conf;
1086        }
1087        break;
1088   #endif
1089 <  case SERVICE_TYPE:
1089 >  case CONF_SERVICE:
1090      DLINK_FOREACH(ptr, list_p->head)
1091      {
1092        conf = ptr->data;
# Line 1502 | Line 1098 | find_matching_name_conf(ConfType type, c
1098      }
1099      break;
1100  
1101 <  case XLINE_TYPE:
1102 <  case ULINE_TYPE:
1103 <  case NRESV_TYPE:
1101 >  case CONF_XLINE:
1102 >  case CONF_ULINE:
1103 >  case CONF_NRESV:
1104      DLINK_FOREACH(ptr, list_p->head)
1105      {
1106        conf = ptr->data;
1107  
1512      match_item = map_to_conf(conf);
1108        if (EmptyString(conf->name))
1109          continue;
1110        if ((name != NULL) && match_esc(conf->name, name))
1111        {
1112          if ((user == NULL && (host == NULL)))
1113            return conf;
1114 <        if ((match_item->action & action) != action)
1114 >        if ((conf->flags & flags) != flags)
1115            continue;
1116 <        if (EmptyString(match_item->user) || EmptyString(match_item->host))
1116 >        if (EmptyString(conf->user) || EmptyString(conf->host))
1117            return conf;
1118 <        if (match(match_item->user, user) && match(match_item->host, host))
1118 >        if (match(conf->user, user) && match(conf->host, host))
1119            return conf;
1120        }
1121      }
1122        break;
1123  
1124 <  case SERVER_TYPE:
1124 >  case CONF_SERVER:
1125      DLINK_FOREACH(ptr, list_p->head)
1126      {
1127        conf = ptr->data;
1533      aconf = map_to_conf(conf);
1128  
1129 <      if ((name != NULL) && match_esc(name, conf->name))
1129 >      if ((name != NULL) && match(name, conf->name))
1130          return conf;
1131 <      else if ((host != NULL) && match_esc(host, aconf->host))
1131 >      else if ((host != NULL) && match(host, conf->host))
1132          return conf;
1133      }
1134      break;
# Line 1551 | Line 1145 | find_matching_name_conf(ConfType type, c
1145   *              - pointer to name string to find
1146   *              - pointer to user
1147   *              - pointer to host
1148 < * output       - NULL or pointer to found struct MatchItem
1148 > * output       - NULL or pointer to found struct MaskItem
1149   * side effects - looks for an exact match on name field
1150   */
1151 < struct ConfItem *
1152 < find_exact_name_conf(ConfType type, const struct Client *who, const char *name,
1151 > struct MaskItem *
1152 > find_exact_name_conf(enum maskitem_type type, const struct Client *who, const char *name,
1153                       const char *user, const char *host)
1154   {
1155    dlink_node *ptr = NULL;
1156 <  struct AccessItem *aconf;
1157 <  struct ConfItem *conf;
1564 <  struct MatchItem *match_item;
1565 <  dlink_list *list_p;
1566 <
1567 <  list_p = map_to_list(type);
1156 >  struct MaskItem *conf;
1157 >  dlink_list *list_p = map_to_list(type);
1158  
1159    switch(type)
1160    {
1161 <  case RXLINE_TYPE:
1162 <  case XLINE_TYPE:
1163 <  case ULINE_TYPE:
1164 <  case NRESV_TYPE:
1161 >  case CONF_RXLINE:
1162 >  case CONF_XLINE:
1163 >  case CONF_ULINE:
1164 >  case CONF_NRESV:
1165  
1166      DLINK_FOREACH(ptr, list_p->head)
1167      {
1168        conf = ptr->data;
1169 <      match_item = (struct MatchItem *)map_to_conf(conf);
1169 >
1170        if (EmptyString(conf->name))
1171          continue;
1172      
# Line 1584 | Line 1174 | find_exact_name_conf(ConfType type, cons
1174        {
1175          if ((user == NULL && (host == NULL)))
1176            return (conf);
1177 <        if (EmptyString(match_item->user) || EmptyString(match_item->host))
1177 >        if (EmptyString(conf->user) || EmptyString(conf->host))
1178            return (conf);
1179 <        if (match(match_item->user, user) && match(match_item->host, host))
1179 >        if (match(conf->user, user) && match(conf->host, host))
1180            return (conf);
1181        }
1182      }
1183      break;
1184  
1185 <  case OPER_TYPE:
1185 >  case CONF_OPER:
1186      DLINK_FOREACH(ptr, list_p->head)
1187      {
1188        conf = ptr->data;
1599      aconf = map_to_conf(conf);
1189  
1190        if (EmptyString(conf->name))
1191          continue;
# Line 1605 | Line 1194 | find_exact_name_conf(ConfType type, cons
1194        {
1195          if (!who)
1196            return conf;
1197 <        if (EmptyString(aconf->user) || EmptyString(aconf->host))
1198 <          return conf;
1199 <        if (match(aconf->user, who->username))
1197 >        if (EmptyString(conf->user) || EmptyString(conf->host))
1198 >          return NULL;
1199 >        if (match(conf->user, who->username))
1200          {
1201 <          switch (aconf->type)
1201 >          switch (conf->htype)
1202            {
1203              case HM_HOST:
1204 <              if (match(aconf->host, who->host) || match(aconf->host, who->sockhost))
1205 <                return conf;
1204 >              if (match(conf->host, who->host) || match(conf->host, who->sockhost))
1205 >                if (!conf->class->max_total || conf->class->ref_count < conf->class->max_total)
1206 >                  return conf;
1207                break;
1208              case HM_IPV4:
1209                if (who->localClient->aftype == AF_INET)
1210 <                if (match_ipv4(&who->localClient->ip, &aconf->addr, aconf->bits))
1211 <                  return conf;
1210 >                if (match_ipv4(&who->localClient->ip, &conf->addr, conf->bits))
1211 >                  if (!conf->class->max_total || conf->class->ref_count < conf->class->max_total)
1212 >                    return conf;
1213                break;
1214   #ifdef IPV6
1215              case HM_IPV6:
1216                if (who->localClient->aftype == AF_INET6)
1217 <                if (match_ipv6(&who->localClient->ip, &aconf->addr, aconf->bits))
1218 <                  return conf;
1217 >                if (match_ipv6(&who->localClient->ip, &conf->addr, conf->bits))
1218 >                  if (!conf->class->max_total || conf->class->ref_count < conf->class->max_total)
1219 >                    return conf;
1220                break;
1221   #endif
1222              default:
# Line 1636 | Line 1228 | find_exact_name_conf(ConfType type, cons
1228  
1229      break;
1230  
1231 <  case SERVER_TYPE:
1231 >  case CONF_SERVER:
1232      DLINK_FOREACH(ptr, list_p->head)
1233      {
1234        conf = ptr->data;
1235 <      aconf = (struct AccessItem *)map_to_conf(conf);
1235 >
1236        if (EmptyString(conf->name))
1237          continue;
1238      
1239        if (name == NULL)
1240        {
1241 <        if (EmptyString(aconf->host))
1241 >        if (EmptyString(conf->host))
1242            continue;
1243 <        if (irccmp(aconf->host, host) == 0)
1243 >        if (irccmp(conf->host, host) == 0)
1244            return(conf);
1245        }
1246        else if (irccmp(conf->name, name) == 0)
# Line 1658 | Line 1250 | find_exact_name_conf(ConfType type, cons
1250      }
1251      break;
1252  
1661  case CLASS_TYPE:
1662    DLINK_FOREACH(ptr, list_p->head)
1663    {
1664      conf = ptr->data;
1665      if (EmptyString(conf->name))
1666        continue;
1667    
1668      if (irccmp(conf->name, name) == 0)
1669        return (conf);
1670    }
1671    break;
1672
1253    default:
1254      break;
1255    }
# Line 1703 | Line 1283 | rehash(int sig)
1283  
1284    load_conf_modules();
1285  
1706  flush_deleted_I_P();
1707
1286    rehashed_klines = 1;
1287   /* XXX */
1288    if (ConfigLoggingEntry.use_logging)
# Line 1728 | Line 1306 | set_default_conf(void)
1306    /* verify init_class() ran, this should be an unnecessary check
1307     * but its not much work.
1308     */
1309 <  assert(class_default == (struct ConfItem *) class_items.tail->data);
1309 >  assert(class_default == class_get_list()->tail->data);
1310  
1311   #ifdef HAVE_LIBCRYPTO
1312    ServerInfo.rsa_private_key = NULL;
# Line 1738 | Line 1316 | set_default_conf(void)
1316    /* ServerInfo.name is not rehashable */
1317    /* ServerInfo.name = ServerInfo.name; */
1318    ServerInfo.description = NULL;
1319 <  DupString(ServerInfo.network_name, NETWORK_NAME_DEFAULT);
1320 <  DupString(ServerInfo.network_desc, NETWORK_DESC_DEFAULT);
1319 >  ServerInfo.network_name = xstrdup(NETWORK_NAME_DEFAULT);
1320 >  ServerInfo.network_desc = xstrdup(NETWORK_DESC_DEFAULT);
1321  
1322    memset(&ServerInfo.ip, 0, sizeof(ServerInfo.ip));
1323    ServerInfo.specific_ipv4_vhost = 0;
# Line 1776 | Line 1354 | set_default_conf(void)
1354    ConfigServerHide.links_delay = 300;
1355    ConfigServerHide.hidden = 0;
1356    ConfigServerHide.hide_servers = 0;
1357 <  DupString(ConfigServerHide.hidden_name, NETWORK_NAME_DEFAULT);
1357 >  ConfigServerHide.hidden_name = xstrdup(NETWORK_NAME_DEFAULT);
1358    ConfigServerHide.hide_server_ips = 0;
1359  
1360    
1361 <  DupString(ConfigFileEntry.service_name, SERVICE_NAME_DEFAULT);
1361 >  ConfigFileEntry.service_name = xstrdup(SERVICE_NAME_DEFAULT);
1362    ConfigFileEntry.max_watch = WATCHSIZE_DEFAULT;
1363    ConfigFileEntry.glines = 0;
1364    ConfigFileEntry.gline_time = 12 * 3600;
# Line 1839 | Line 1417 | validate_conf(void)
1417      ConfigFileEntry.ts_max_delta = TS_MAX_DELTA_DEFAULT;
1418  
1419    if (ServerInfo.network_name == NULL)
1420 <    DupString(ServerInfo.network_name,NETWORK_NAME_DEFAULT);
1420 >    ServerInfo.network_name = xstrdup(NETWORK_NAME_DEFAULT);
1421  
1422    if (ServerInfo.network_desc == NULL)
1423 <    DupString(ServerInfo.network_desc,NETWORK_DESC_DEFAULT);
1423 >    ServerInfo.network_desc = xstrdup(NETWORK_DESC_DEFAULT);
1424  
1425    if (ConfigFileEntry.service_name == NULL)
1426 <    DupString(ConfigFileEntry.service_name, SERVICE_NAME_DEFAULT);
1426 >    ConfigFileEntry.service_name = xstrdup(SERVICE_NAME_DEFAULT);
1427  
1428    ConfigFileEntry.max_watch = IRCD_MAX(ConfigFileEntry.max_watch, WATCHSIZE_MIN);
1429   }
# Line 1871 | Line 1449 | read_conf(FILE *file)
1449    yyparse();          /* Load the values from the conf */
1450    validate_conf();    /* Check to make sure some values are still okay. */
1451                        /* Some global values are also loaded here. */
1452 <  check_class();      /* Make sure classes are valid */
1452 >  class_delete_marked();      /* Make sure classes are valid */
1453   }
1454  
1455   /* lookup_confhost()
# Line 1880 | Line 1458 | read_conf(FILE *file)
1458   * line and convert an IP addresses in a.b.c.d number for to IP#s.
1459   */
1460   static void
1461 < lookup_confhost(struct ConfItem *conf)
1461 > lookup_confhost(struct MaskItem *conf)
1462   {
1885  struct AccessItem *aconf;
1463    struct addrinfo hints, *res;
1464  
1465 <  aconf = map_to_conf(conf);
1889 <
1890 <  if (has_wildcards(aconf->host))
1465 >  if (has_wildcards(conf->host))
1466    {
1467      ilog(LOG_TYPE_IRCD, "Host/server name error: (%s) (%s)",
1468 <         aconf->host, conf->name);
1468 >         conf->host, conf->name);
1469      return;
1470    }
1471  
# Line 1905 | Line 1480 | lookup_confhost(struct ConfItem *conf)
1480    /* Get us ready for a bind() and don't bother doing dns lookup */
1481    hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
1482  
1483 <  if (getaddrinfo(aconf->host, NULL, &hints, &res))
1483 >  if (getaddrinfo(conf->host, NULL, &hints, &res))
1484    {
1485 <    conf_dns_lookup(aconf);
1485 >    conf_dns_lookup(conf);
1486      return;
1487    }
1488  
1489    assert(res != NULL);
1490  
1491 <  memcpy(&aconf->addr, res->ai_addr, res->ai_addrlen);
1492 <  aconf->addr.ss_len = res->ai_addrlen;
1493 <  aconf->addr.ss.ss_family = res->ai_family;
1491 >  memcpy(&conf->addr, res->ai_addr, res->ai_addrlen);
1492 >  conf->addr.ss_len = res->ai_addrlen;
1493 >  conf->addr.ss.ss_family = res->ai_family;
1494 >
1495    freeaddrinfo(res);
1496   }
1497  
# Line 1930 | Line 1506 | int
1506   conf_connect_allowed(struct irc_ssaddr *addr, int aftype)
1507   {
1508    struct ip_entry *ip_found;
1509 <  struct AccessItem *aconf = find_dline_conf(addr, aftype);
1509 >  struct MaskItem *conf = find_dline_conf(addr, aftype);
1510  
1511    /* DLINE exempt also gets you out of static limits/pacing... */
1512 <  if (aconf && (aconf->status & CONF_EXEMPTDLINE))
1512 >  if (conf && (conf->type == CONF_EXEMPT))
1513      return 0;
1514  
1515 <  if (aconf != NULL)
1515 >  if (conf != NULL)
1516      return BANNED_CLIENT;
1517  
1518    ip_found = find_or_add_ip(addr);
# Line 1952 | Line 1528 | conf_connect_allowed(struct irc_ssaddr *
1528    return 0;
1529   }
1530  
1531 < static struct AccessItem *
1531 > static struct MaskItem *
1532   find_regexp_kline(const char *uhi[])
1533   {
1534   #ifdef HAVE_LIBPCRE
# Line 1960 | Line 1536 | find_regexp_kline(const char *uhi[])
1536  
1537    DLINK_FOREACH(ptr, rkconf_items.head)
1538    {
1539 <    struct AccessItem *aptr = map_to_conf(ptr->data);
1539 >    struct MaskItem *aptr = ptr->data;
1540  
1541      assert(aptr->regexuser);
1542      assert(aptr->regexhost);
# Line 1977 | Line 1553 | find_regexp_kline(const char *uhi[])
1553   /* find_kill()
1554   *
1555   * inputs       - pointer to client structure
1556 < * output       - pointer to struct AccessItem if found
1556 > * output       - pointer to struct MaskItem if found
1557   * side effects - See if this user is klined already,
1558 < *                and if so, return struct AccessItem pointer
1558 > *                and if so, return struct MaskItem pointer
1559   */
1560 < struct AccessItem *
1560 > struct MaskItem *
1561   find_kill(struct Client *client_p)
1562   {
1563 <  struct AccessItem *aconf = NULL;
1563 >  struct MaskItem *conf = NULL;
1564    const char *uhi[3];
1565  
1566    uhi[0] = client_p->username;
# Line 1993 | Line 1569 | find_kill(struct Client *client_p)
1569  
1570    assert(client_p != NULL);
1571  
1572 <  aconf = find_conf_by_address(client_p->host, &client_p->localClient->ip,
1573 <                               CONF_KLINE, client_p->localClient->aftype,
1574 <                               client_p->username, NULL, 1);
1575 <  if (aconf == NULL)
1576 <    aconf = find_regexp_kline(uhi);
1572 >  conf = find_conf_by_address(client_p->host, &client_p->localClient->ip,
1573 >                              CONF_KLINE, client_p->localClient->aftype,
1574 >                              client_p->username, NULL, 1);
1575 >  if (conf == NULL)
1576 >    conf = find_regexp_kline(uhi);
1577  
1578 <  return aconf;
1578 >  return conf;
1579   }
1580  
1581 < struct AccessItem *
1581 > struct MaskItem *
1582   find_gline(struct Client *client_p)
1583   {
1584 <  struct AccessItem *aconf;
1584 >  struct MaskItem *conf;
1585  
1586    assert(client_p != NULL);
1587  
1588 <  aconf = find_conf_by_address(client_p->host, &client_p->localClient->ip,
1589 <                               CONF_GLINE, client_p->localClient->aftype,
1590 <                               client_p->username, NULL, 1);
1591 <  return aconf;
2016 < }
2017 <
2018 < /* add_temp_line()
2019 < *
2020 < * inputs        - pointer to struct ConfItem
2021 < * output        - none
2022 < * Side effects  - links in given struct ConfItem into
2023 < *                 temporary *line link list
2024 < */
2025 < void
2026 < add_temp_line(struct ConfItem *conf)
2027 < {
2028 <  if (conf->type == XLINE_TYPE)
2029 <  {
2030 <    conf->flags |= CONF_FLAGS_TEMPORARY;
2031 <    dlinkAdd(conf, make_dlink_node(), &temporary_xlines);
2032 <  }
2033 <  else if ((conf->type == NRESV_TYPE) || (conf->type == CRESV_TYPE))
2034 <  {
2035 <    conf->flags |= CONF_FLAGS_TEMPORARY;
2036 <    dlinkAdd(conf, make_dlink_node(), &temporary_resv);
2037 <  }
1588 >  conf = find_conf_by_address(client_p->host, &client_p->localClient->ip,
1589 >                              CONF_GLINE, client_p->localClient->aftype,
1590 >                              client_p->username, NULL, 1);
1591 >  return conf;
1592   }
1593  
1594   /* cleanup_tklines()
# Line 2048 | Line 1602 | void
1602   cleanup_tklines(void *notused)
1603   {
1604    hostmask_expire_temporary();
1605 <  expire_tklines(&temporary_xlines);
1606 <  expire_tklines(&temporary_resv);
1605 >  expire_tklines(&xconf_items);
1606 >  expire_tklines(&nresv_items);
1607 >  expire_tklines(&resv_channel_list);
1608   }
1609  
1610   /* expire_tklines()
# Line 2063 | Line 1618 | expire_tklines(dlink_list *tklist)
1618   {
1619    dlink_node *ptr;
1620    dlink_node *next_ptr;
1621 <  struct ConfItem *conf;
2067 <  struct MatchItem *xconf;
2068 <  struct MatchItem *nconf;
2069 <  struct ResvChannel *cconf;
1621 >  struct MaskItem *conf;
1622  
1623    DLINK_FOREACH_SAFE(ptr, next_ptr, tklist->head)
1624    {
1625      conf = ptr->data;
1626  
1627 <    if (conf->type == XLINE_TYPE)
1627 >    if (!conf->hold || conf->hold > CurrentTime)
1628 >      continue;
1629 >
1630 >    if (conf->type == CONF_XLINE)
1631      {
1632 <      xconf = (struct MatchItem *)map_to_conf(conf);
1633 <      if (xconf->hold <= CurrentTime)
2079 <      {
2080 <        if (ConfigFileEntry.tkline_expire_notices)
2081 <          sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1632 >      if (ConfigFileEntry.tkline_expire_notices)
1633 >        sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1634                                 "Temporary X-line for [%s] expired", conf->name);
1635 <        dlinkDelete(ptr, tklist);
2084 <        free_dlink_node(ptr);
2085 <        delete_conf_item(conf);
2086 <      }
1635 >      conf_free(conf);
1636      }
1637 <    else if (conf->type == NRESV_TYPE)
1637 >    else if (conf->type == CONF_NRESV)
1638      {
1639 <      nconf = (struct MatchItem *)map_to_conf(conf);
1640 <      if (nconf->hold <= CurrentTime)
2092 <      {
2093 <        if (ConfigFileEntry.tkline_expire_notices)
2094 <          sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1639 >      if (ConfigFileEntry.tkline_expire_notices)
1640 >        sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1641                                 "Temporary RESV for [%s] expired", conf->name);
1642 <        dlinkDelete(ptr, tklist);
2097 <        free_dlink_node(ptr);
2098 <        delete_conf_item(conf);
2099 <      }
1642 >      conf_free(conf);
1643      }
1644 <    else if (conf->type == CRESV_TYPE)
1644 >    else if (conf->type == CONF_CRESV)
1645      {
1646 <      cconf = (struct ResvChannel *)map_to_conf(conf);
1647 <      if (cconf->hold <= CurrentTime)
1648 <      {
1649 <        if (ConfigFileEntry.tkline_expire_notices)
2107 <          sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
2108 <                               "Temporary RESV for [%s] expired", cconf->name);
2109 <        delete_channel_resv(cconf);
2110 <      }
1646 >      if (ConfigFileEntry.tkline_expire_notices)
1647 >        sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1648 >                               "Temporary RESV for [%s] expired", conf->name);
1649 >      delete_channel_resv(conf);
1650      }
1651    }
1652   }
# Line 2120 | Line 1659 | expire_tklines(dlink_list *tklist)
1659   */
1660   static const struct oper_privs
1661   {
1662 <  const unsigned int oprivs;
1662 >  const unsigned int flag;
1663    const unsigned char c;
1664   } flag_list[] = {
1665    { OPER_FLAG_ADMIN,       'A' },
# Line 2144 | Line 1683 | oper_privs_as_string(const unsigned int
1683   {
1684    static char privs_out[16];
1685    char *privs_ptr = privs_out;
1686 <  unsigned int i = 0;
1686 >  const struct oper_privs *opriv = flag_list;
1687  
1688 <  for (; flag_list[i].oprivs; ++i)
1688 >  for (; opriv->flag; ++opriv)
1689    {
1690 <    if (port & flag_list[i].oprivs)
1691 <      *privs_ptr++ = flag_list[i].c;
1690 >    if (port & opriv->flag)
1691 >      *privs_ptr++ = opriv->c;
1692      else
1693 <      *privs_ptr++ = ToLowerTab[flag_list[i].c];
1693 >      *privs_ptr++ = ToLower(opriv->c);
1694    }
1695  
1696    *privs_ptr = '\0';
# Line 2176 | Line 1715 | get_oper_name(const struct Client *clien
1715    {
1716      if ((cnode = client_p->localClient->confs.head))
1717      {
1718 <      struct ConfItem *conf = cnode->data;
2180 <      const struct AccessItem *aconf = map_to_conf(conf);
1718 >      struct MaskItem *conf = cnode->data;
1719  
1720 <      if (IsConfOperator(aconf))
1720 >      if (IsConfOperator(conf))
1721        {
1722          snprintf(buffer, sizeof(buffer), "%s!%s@%s{%s}", client_p->name,
1723                   client_p->username, client_p->host, conf->name);
# Line 2212 | Line 1750 | read_conf_files(int cold)
1750    char chanlimit[32];
1751  
1752    conf_parser_ctx.boot = cold;
1753 <  filename = get_conf_name(CONF_TYPE);
1753 >  filename = ConfigFileEntry.configfile;
1754  
1755    /* We need to know the initial filename for the yyerror() to report
1756       FIXME: The full path is in conffilenamebuf first time since we
# Line 2269 | Line 1807 | read_conf_files(int cold)
1807     * on strlen(form_str(RPL_ISUPPORT))
1808     */
1809    rebuild_isupport_message_line();
2272
2273  parse_conf_file(KLINE_TYPE, cold);
2274  parse_conf_file(DLINE_TYPE, cold);
2275  parse_conf_file(XLINE_TYPE, cold);
2276  parse_conf_file(NRESV_TYPE, cold);
2277  parse_conf_file(CRESV_TYPE, cold);
2278 }
2279
2280 /* parse_conf_file()
2281 *
2282 * inputs       - type of conf file to parse
2283 * output       - none
2284 * side effects - conf file for givenconf type is opened and read then parsed
2285 */
2286 static void
2287 parse_conf_file(int type, int cold)
2288 {
2289  FILE *file = NULL;
2290  const char *filename = get_conf_name(type);
2291
2292  if ((file = fopen(filename, "r")) == NULL)
2293  {
2294    if (cold)
2295      ilog(LOG_TYPE_IRCD, "Unable to read configuration file '%s': %s",
2296           filename, strerror(errno));
2297    else
2298      sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
2299                    "Unable to read configuration file '%s': %s",
2300                           filename, strerror(errno));
2301  }
2302  else
2303  {
2304    parse_csv_file(file, type);
2305    fclose(file);
2306  }
1810   }
1811  
1812   /* clear_out_old_conf()
# Line 2316 | Line 1819 | static void
1819   clear_out_old_conf(void)
1820   {
1821    dlink_node *ptr = NULL, *next_ptr = NULL;
1822 <  struct ConfItem *conf;
2320 <  struct AccessItem *aconf;
2321 <  struct ClassItem *cltmp;
1822 >  struct MaskItem *conf;
1823    dlink_list *free_items [] = {
1824      &server_items,   &oconf_items,
1825       &uconf_items,   &xconf_items, &rxconf_items, &rkconf_items,
# Line 2336 | Line 1837 | clear_out_old_conf(void)
1837      DLINK_FOREACH_SAFE(ptr, next_ptr, (*iterator)->head)
1838      {
1839        conf = ptr->data;
2339      /* XXX This is less than pretty */
2340      if (conf->type == SERVER_TYPE)
2341      {
2342        aconf = map_to_conf(conf);
1840  
1841 <        if (aconf->clients != 0)
2345 <        {
2346 <          SetConfIllegal(aconf);
2347 <          dlinkDelete(&conf->node, &server_items);
2348 <        }
2349 <        else
2350 <        {
2351 <          delete_conf_item(conf);
2352 <        }
2353 <      }
2354 <      else if (conf->type == OPER_TYPE)
2355 <      {
2356 <        aconf = map_to_conf(conf);
1841 >      dlinkDelete(&conf->node, map_to_list(conf->type));
1842  
1843 <        if (aconf->clients != 0)
1844 <        {
2360 <          SetConfIllegal(aconf);
2361 <          dlinkDelete(&conf->node, &oconf_items);
2362 <        }
2363 <        else
2364 <        {
2365 <          delete_conf_item(conf);
2366 <        }
2367 <      }
2368 <      else if (conf->type == XLINE_TYPE  ||
2369 <               conf->type == RXLINE_TYPE ||
2370 <               conf->type == RKLINE_TYPE)
1843 >      /* XXX This is less than pretty */
1844 >      if (conf->type == CONF_SERVER || conf->type == CONF_OPER)
1845        {
1846 <        /* temporary (r)xlines are also on
1847 <         * the (r)xconf items list */
2374 <        if (conf->flags & CONF_FLAGS_TEMPORARY)
2375 <          continue;
2376 <
2377 <        delete_conf_item(conf);
1846 >        if (!conf->ref_count)
1847 >          conf_free(conf);
1848        }
1849 <      else
1849 >      else if (conf->type == CONF_XLINE  ||
1850 >               conf->type == CONF_RXLINE ||
1851 >               conf->type == CONF_RKLINE)
1852        {
1853 <          delete_conf_item(conf);
1853 >        if (!conf->hold)
1854 >          conf_free(conf);
1855        }
1856 +      else
1857 +        conf_free(conf);
1858      }
1859    }
1860  
1861    /*
1862     * don't delete the class table, rather mark all entries
1863 <   * for deletion. The table is cleaned up by check_class. - avalon
1863 >   * for deletion. The table is cleaned up by class_delete_marked. - avalon
1864     */
1865 <  DLINK_FOREACH(ptr, class_items.head)
2391 <  {
2392 <    cltmp = map_to_conf(ptr->data);
2393 <
2394 <    if (ptr != class_items.tail)  /* never mark the "default" class */
2395 <      cltmp->active = 0;
2396 <  }
1865 >  class_mark_for_deletion();
1866  
1867    clear_out_address_conf();
1868  
# Line 2440 | Line 1909 | clear_out_old_conf(void)
1909    MyFree(AdminInfo.description);
1910    AdminInfo.description = NULL;
1911  
2443  /* operator{} and class{} blocks are freed above */
1912    /* clean out listeners */
1913    close_listeners();
1914  
2447  /* auth{}, quarantine{}, shared{}, connect{}, kill{}, deny{},
2448   * exempt{} and gecos{} blocks are freed above too
2449   */
2450
1915    /* clean out general */
1916    MyFree(ConfigFileEntry.service_name);
1917    ConfigFileEntry.service_name = NULL;
# Line 2456 | Line 1920 | clear_out_old_conf(void)
1920    delete_isupport("EXCEPTS");
1921   }
1922  
2459 /* flush_deleted_I_P()
2460 *
2461 * inputs       - none
2462 * output       - none
2463 * side effects - This function removes I/P conf items
2464 */
2465 static void
2466 flush_deleted_I_P(void)
2467 {
2468  dlink_node *ptr;
2469  dlink_node *next_ptr;
2470  struct ConfItem *conf;
2471  struct AccessItem *aconf;
2472  dlink_list * free_items [] = {
2473    &server_items, &oconf_items, NULL
2474  };
2475  dlink_list ** iterator = free_items; /* C is dumb */
2476
2477  /* flush out deleted I and P lines
2478   * although still in use.
2479   */
2480  for (; *iterator != NULL; iterator++)
2481  {
2482    DLINK_FOREACH_SAFE(ptr, next_ptr, (*iterator)->head)
2483    {
2484      conf = ptr->data;
2485      aconf = (struct AccessItem *)map_to_conf(conf);
2486
2487      if (IsConfIllegal(aconf))
2488      {
2489        dlinkDelete(ptr, *iterator);
2490
2491        if (aconf->clients == 0)
2492          delete_conf_item(conf);
2493      }
2494    }
2495  }
2496 }
2497
2498 /* get_conf_name()
2499 *
2500 * inputs       - type of conf file to return name of file for
2501 * output       - pointer to filename for type of conf
2502 * side effects - none
2503 */
2504 const char *
2505 get_conf_name(ConfType type)
2506 {
2507  switch (type)
2508  {
2509    case CONF_TYPE:
2510      return ConfigFileEntry.configfile;
2511      break;
2512    case KLINE_TYPE:
2513      return ConfigFileEntry.klinefile;
2514      break;
2515    case DLINE_TYPE:
2516      return ConfigFileEntry.dlinefile;
2517      break;
2518    case XLINE_TYPE:
2519      return ConfigFileEntry.xlinefile;
2520      break;
2521    case CRESV_TYPE:
2522      return ConfigFileEntry.cresvfile;
2523      break;
2524    case NRESV_TYPE:
2525      return ConfigFileEntry.nresvfile;
2526      break;
2527    default:
2528      return NULL;  /* This should NEVER HAPPEN since we call this function
2529                       only with the above values, this will cause us to core
2530                       at some point if this happens so we know where it was */
2531  }
2532 }
2533
2534 #define BAD_PING (-1)
2535
2536 /* get_conf_ping()
2537 *
2538 * inputs       - pointer to struct AccessItem
2539 *              - pointer to a variable that receives ping warning time
2540 * output       - ping frequency
2541 * side effects - NONE
2542 */
2543 static int
2544 get_conf_ping(struct ConfItem *conf, int *pingwarn)
2545 {
2546  struct ClassItem *aclass;
2547  struct AccessItem *aconf;
2548
2549  if (conf != NULL)
2550  {
2551    aconf = (struct AccessItem *)map_to_conf(conf);
2552    if (aconf->class_ptr != NULL)
2553    {
2554      aclass = (struct ClassItem *)map_to_conf(aconf->class_ptr);
2555      *pingwarn = aclass->ping_warning;
2556      return aclass->ping_freq;
2557    }
2558  }
2559
2560  return BAD_PING;
2561 }
2562
2563 /* get_client_class()
2564 *
2565 * inputs       - pointer to client struct
2566 * output       - pointer to name of class
2567 * side effects - NONE
2568 */
2569 const char *
2570 get_client_class(struct Client *target_p)
2571 {
2572  dlink_node *cnode = NULL;
2573  struct AccessItem *aconf = NULL;
2574
2575  assert(!IsMe(target_p));
2576
2577  if ((cnode = target_p->localClient->confs.head))
2578  {
2579    struct ConfItem *conf = cnode->data;
2580
2581    assert((conf->type == CLIENT_TYPE) || (conf->type == SERVER_TYPE) ||
2582          (conf->type == OPER_TYPE));
2583
2584    aconf = map_to_conf(conf);
2585    if (aconf->class_ptr != NULL)
2586      return aconf->class_ptr->name;
2587  }
2588
2589  return "default";
2590 }
2591
2592 /* get_client_ping()
2593 *
2594 * inputs       - pointer to client struct
2595 *              - pointer to a variable that receives ping warning time
2596 * output       - ping frequency
2597 * side effects - NONE
2598 */
2599 int
2600 get_client_ping(struct Client *target_p, int *pingwarn)
2601 {
2602  int ping = 0;
2603  dlink_node *cnode = NULL;
2604
2605  if ((cnode = target_p->localClient->confs.head))
2606  {
2607    struct ConfItem *conf = cnode->data;
2608
2609    assert((conf->type == CLIENT_TYPE) || (conf->type == SERVER_TYPE) ||
2610          (conf->type == OPER_TYPE));
2611
2612    ping = get_conf_ping(conf, pingwarn);
2613    if (ping > 0)
2614      return ping;
2615  }
2616
2617  *pingwarn = 0;
2618  return DEFAULT_PINGFREQUENCY;
2619 }
2620
2621 /* find_class()
2622 *
2623 * inputs       - string name of class
2624 * output       - corresponding Class pointer
2625 * side effects - NONE
2626 */
2627 struct ConfItem *
2628 find_class(const char *classname)
2629 {
2630  struct ConfItem *conf;
2631
2632  if ((conf = find_exact_name_conf(CLASS_TYPE, NULL, classname, NULL, NULL)) != NULL)
2633    return conf;
2634
2635  return class_default;
2636 }
2637
2638 /* check_class()
2639 *
2640 * inputs       - NONE
2641 * output       - NONE
2642 * side effects -
2643 */
2644 void
2645 check_class(void)
2646 {
2647  dlink_node *ptr = NULL, *next_ptr = NULL;
2648
2649  DLINK_FOREACH_SAFE(ptr, next_ptr, class_items.head)
2650  {
2651    struct ClassItem *aclass = map_to_conf(ptr->data);
2652
2653    if (!aclass->active && !aclass->curr_user_count)
2654    {
2655      destroy_cidr_class(aclass);
2656      delete_conf_item(ptr->data);
2657    }
2658  }
2659 }
2660
2661 /* init_class()
2662 *
2663 * inputs       - NONE
2664 * output       - NONE
2665 * side effects -
2666 */
2667 void
2668 init_class(void)
2669 {
2670  struct ClassItem *aclass;
2671
2672  class_default = make_conf_item(CLASS_TYPE);
2673
2674  aclass = map_to_conf(class_default);
2675  aclass->active = 1;
2676  DupString(class_default->name, "default");
2677  aclass->con_freq  = DEFAULT_CONNECTFREQUENCY;
2678  aclass->ping_freq = DEFAULT_PINGFREQUENCY;
2679  aclass->max_total = MAXIMUM_LINKS_DEFAULT;
2680  aclass->max_sendq = DEFAULT_SENDQ;
2681  aclass->max_recvq = DEFAULT_RECVQ;
2682
2683  client_check_cb = register_callback("check_client", check_client);
2684 }
2685
2686 /* get_sendq()
2687 *
2688 * inputs       - pointer to client
2689 * output       - sendq for this client as found from its class
2690 * side effects - NONE
2691 */
2692 unsigned int
2693 get_sendq(struct Client *client_p)
2694 {
2695  unsigned int sendq = DEFAULT_SENDQ;
2696  dlink_node *cnode;
2697  struct ConfItem *class_conf;
2698  struct ClassItem *aclass;
2699  struct AccessItem *aconf;
2700
2701  assert(!IsMe(client_p));
2702
2703  if ((cnode = client_p->localClient->confs.head))
2704  {
2705    struct ConfItem *conf = cnode->data;
2706
2707    assert((conf->type == CLIENT_TYPE) || (conf->type == SERVER_TYPE) ||
2708          (conf->type == OPER_TYPE));
2709
2710    aconf = map_to_conf(conf);
2711
2712    if ((class_conf = aconf->class_ptr) == NULL)
2713      return DEFAULT_SENDQ; /* TBV: shouldn't be possible at all */
2714
2715    aclass = map_to_conf(class_conf);
2716    sendq = aclass->max_sendq;
2717    return sendq;
2718  }
2719
2720  /* XXX return a default?
2721   * if here, then there wasn't an attached conf with a sendq
2722   * that is very bad -Dianora
2723   */
2724  return DEFAULT_SENDQ;
2725 }
2726
2727 unsigned int
2728 get_recvq(struct Client *client_p)
2729 {
2730  unsigned int recvq = DEFAULT_RECVQ;
2731  dlink_node *cnode;
2732  struct ConfItem *class_conf;
2733  struct ClassItem *aclass;
2734  struct AccessItem *aconf;
2735
2736  assert(!IsMe(client_p));
2737
2738  if ((cnode = client_p->localClient->confs.head))
2739  {
2740    struct ConfItem *conf = cnode->data;
2741
2742    assert((conf->type == CLIENT_TYPE) || (conf->type == SERVER_TYPE) ||
2743          (conf->type == OPER_TYPE));
2744
2745    aconf = map_to_conf(conf);
2746
2747    if ((class_conf = aconf->class_ptr) == NULL)
2748      return DEFAULT_RECVQ; /* TBV: shouldn't be possible at all */
2749
2750    aclass = map_to_conf(class_conf);
2751    recvq = aclass->max_recvq;
2752    return recvq;
2753  }
2754
2755  /* XXX return a default?
2756   * if here, then there wasn't an attached conf with a recvq
2757   * that is very bad -Dianora
2758   */
2759  return DEFAULT_RECVQ;
2760 }
2761
1923   /* conf_add_class_to_conf()
1924   *
1925   * inputs       - pointer to config item
# Line 2766 | Line 1927 | get_recvq(struct Client *client_p)
1927   * side effects - Add a class pointer to a conf
1928   */
1929   void
1930 < conf_add_class_to_conf(struct ConfItem *conf, const char *class_name)
1930 > conf_add_class_to_conf(struct MaskItem *conf, const char *class_name)
1931   {
2771  struct AccessItem *aconf = map_to_conf(conf);
1932    struct ClassItem *class = NULL;
1933  
1934    if (class_name == NULL)
1935    {
1936 <    aconf->class_ptr = class_default;
1936 >    conf->class = class_default;
1937  
1938 <    if (conf->type == CLIENT_TYPE)
1938 >    if (conf->type == CONF_CLIENT)
1939        sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1940                             "Warning *** Defaulting to default class for %s@%s",
1941 <                           aconf->user, aconf->host);
1941 >                           conf->user, conf->host);
1942      else
1943        sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1944                             "Warning *** Defaulting to default class for %s",
1945                             conf->name);
1946    }
1947    else
1948 <    aconf->class_ptr = find_class(class_name);
1948 >    conf->class = class_find(class_name, 1);
1949  
1950 <  if (aconf->class_ptr)
2791 <    class = map_to_conf(aconf->class_ptr);
2792 <
2793 <  if (aconf->class_ptr == NULL || !class->active)
1950 >  if (conf->class == NULL)
1951    {
1952 <    if (conf->type == CLIENT_TYPE)
1952 >    if (conf->type == CONF_CLIENT)
1953        sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1954                             "Warning *** Defaulting to default class for %s@%s",
1955 <                           aconf->user, aconf->host);
1955 >                           conf->user, conf->host);
1956      else
1957        sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1958                             "Warning *** Defaulting to default class for %s",
1959                             conf->name);
1960 <    aconf->class_ptr = class_default;
1960 >    conf->class = class_default;
1961    }
1962   }
1963  
# Line 2812 | Line 1969 | conf_add_class_to_conf(struct ConfItem *
1969   * side effects - Add a connect block
1970   */
1971   int
1972 < conf_add_server(struct ConfItem *conf, const char *class_name)
1972 > conf_add_server(struct MaskItem *conf, const char *class_name)
1973   {
2817  struct AccessItem *aconf = map_to_conf(conf);
2818
1974    conf_add_class_to_conf(conf, class_name);
1975  
1976 <  if (!aconf->host || !conf->name)
1976 >  if (EmptyString(conf->host) || EmptyString(conf->name))
1977    {
1978      sendto_realops_flags(UMODE_ALL, L_ALL,  SEND_NOTICE,
1979                           "Bad connect block");
# Line 2826 | Line 1981 | conf_add_server(struct ConfItem *conf, c
1981      return -1;
1982    }
1983  
1984 <  if (EmptyString(aconf->passwd))
1984 >  if (EmptyString(conf->passwd))
1985    {
1986      sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
1987                           "Bad connect block, name %s",
# Line 3215 | Line 2370 | find_user_host(struct Client *source_p,
2370   int
2371   valid_comment(struct Client *source_p, char *comment, int warn)
2372   {
3218  if (strchr(comment, '"'))
3219  {
3220    if (warn)
3221      sendto_one(source_p, ":%s NOTICE %s :Invalid character '\"' in comment",
3222                 me.name, source_p->name);
3223    return 0;
3224  }
3225
2373    if (strlen(comment) > REASONLEN)
2374      comment[REASONLEN-1] = '\0';
2375  
# Line 3237 | Line 2384 | valid_comment(struct Client *source_p, c
2384   * side effects - none
2385   */
2386   int
2387 < match_conf_password(const char *password, const struct AccessItem *aconf)
2387 > match_conf_password(const char *password, const struct MaskItem *conf)
2388   {
2389    const char *encr = NULL;
2390  
2391 <  if (EmptyString(password) || EmptyString(aconf->passwd))
2391 >  if (EmptyString(password) || EmptyString(conf->passwd))
2392      return 0;
2393  
2394 <  if (aconf->flags & CONF_FLAGS_ENCRYPTED)
2395 <    encr = crypt(password, aconf->passwd);
2394 >  if (conf->flags & CONF_FLAGS_ENCRYPTED)
2395 >    encr = crypt(password, conf->passwd);
2396    else
2397      encr = password;
2398  
2399 <  return !strcmp(encr, aconf->passwd);
2399 >  return !strcmp(encr, conf->passwd);
2400   }
2401  
2402   /*
# Line 3278 | Line 2425 | cluster_a_line(struct Client *source_p,
2425  
2426    DLINK_FOREACH(ptr, cluster_items.head)
2427    {
2428 <    const struct ConfItem *conf = ptr->data;
2428 >    const struct MaskItem *conf = ptr->data;
2429  
2430      if (conf->flags & cluster_type)
2431        sendto_match_servs(source_p, conf->name, CAP_CLUSTER|capab,
# Line 3372 | Line 2519 | split_nuh(struct split_nuh_item *const i
2519      }
2520    }
2521   }
3375
3376 /*
3377 * flags_to_ascii
3378 *
3379 * inputs       - flags is a bitmask
3380 *              - pointer to table of ascii letters corresponding
3381 *                to each bit
3382 *              - flag 1 for convert ToLower if bit missing
3383 *                0 if ignore.
3384 * output       - none
3385 * side effects - string pointed to by p has bitmap chars written to it
3386 */
3387 static void
3388 flags_to_ascii(unsigned int flags, const unsigned int bit_table[], char *p,
3389               int lowerit)
3390 {
3391  unsigned int mask = 1;
3392  int i = 0;
3393
3394  for (mask = 1; (mask != 0) && (bit_table[i] != 0); mask <<= 1, i++)
3395  {
3396    if (flags & mask)
3397      *p++ = bit_table[i];
3398    else if (lowerit)
3399      *p++ = ToLower(bit_table[i]);
3400  }
3401  *p = '\0';
3402 }
3403
3404 /*
3405 * cidr_limit_reached
3406 *
3407 * inputs       - int flag allowing over_rule of limits
3408 *              - pointer to the ip to be added
3409 *              - pointer to the class
3410 * output       - non zero if limit reached
3411 *                0 if limit not reached
3412 * side effects -
3413 */
3414 static int
3415 cidr_limit_reached(int over_rule,
3416                   struct irc_ssaddr *ip, struct ClassItem *aclass)
3417 {
3418  dlink_node *ptr = NULL;
3419  struct CidrItem *cidr;
3420
3421  if (aclass->number_per_cidr <= 0)
3422    return 0;
3423
3424  if (ip->ss.ss_family == AF_INET)
3425  {
3426    if (aclass->cidr_bitlen_ipv4 <= 0)
3427      return 0;
3428
3429    DLINK_FOREACH(ptr, aclass->list_ipv4.head)
3430    {
3431      cidr = ptr->data;
3432      if (match_ipv4(ip, &cidr->mask, aclass->cidr_bitlen_ipv4))
3433      {
3434        if (!over_rule && (cidr->number_on_this_cidr >= aclass->number_per_cidr))
3435          return -1;
3436        cidr->number_on_this_cidr++;
3437        return 0;
3438      }
3439    }
3440    cidr = MyMalloc(sizeof(struct CidrItem));
3441    cidr->number_on_this_cidr = 1;
3442    cidr->mask = *ip;
3443    mask_addr(&cidr->mask, aclass->cidr_bitlen_ipv4);
3444    dlinkAdd(cidr, &cidr->node, &aclass->list_ipv4);
3445  }
3446 #ifdef IPV6
3447  else if (aclass->cidr_bitlen_ipv6 > 0)
3448  {
3449    DLINK_FOREACH(ptr, aclass->list_ipv6.head)
3450    {
3451      cidr = ptr->data;
3452      if (match_ipv6(ip, &cidr->mask, aclass->cidr_bitlen_ipv6))
3453      {
3454        if (!over_rule && (cidr->number_on_this_cidr >= aclass->number_per_cidr))
3455          return -1;
3456        cidr->number_on_this_cidr++;
3457        return 0;
3458      }
3459    }
3460    cidr = MyMalloc(sizeof(struct CidrItem));
3461    cidr->number_on_this_cidr = 1;
3462    cidr->mask = *ip;
3463    mask_addr(&cidr->mask, aclass->cidr_bitlen_ipv6);
3464    dlinkAdd(cidr, &cidr->node, &aclass->list_ipv6);
3465  }
3466 #endif
3467  return 0;
3468 }
3469
3470 /*
3471 * remove_from_cidr_check
3472 *
3473 * inputs       - pointer to the ip to be removed
3474 *              - pointer to the class
3475 * output       - NONE
3476 * side effects -
3477 */
3478 static void
3479 remove_from_cidr_check(struct irc_ssaddr *ip, struct ClassItem *aclass)
3480 {
3481  dlink_node *ptr = NULL;
3482  dlink_node *next_ptr = NULL;
3483  struct CidrItem *cidr;
3484
3485  if (aclass->number_per_cidr == 0)
3486    return;
3487
3488  if (ip->ss.ss_family == AF_INET)
3489  {
3490    if (aclass->cidr_bitlen_ipv4 <= 0)
3491      return;
3492
3493    DLINK_FOREACH_SAFE(ptr, next_ptr, aclass->list_ipv4.head)
3494    {
3495      cidr = ptr->data;
3496      if (match_ipv4(ip, &cidr->mask, aclass->cidr_bitlen_ipv4))
3497      {
3498        cidr->number_on_this_cidr--;
3499        if (cidr->number_on_this_cidr == 0)
3500        {
3501          dlinkDelete(ptr, &aclass->list_ipv4);
3502          MyFree(cidr);
3503          return;
3504        }
3505      }
3506    }
3507  }
3508 #ifdef IPV6
3509  else if (aclass->cidr_bitlen_ipv6 > 0)
3510  {
3511    DLINK_FOREACH_SAFE(ptr, next_ptr, aclass->list_ipv6.head)
3512    {
3513      cidr = ptr->data;
3514      if (match_ipv6(ip, &cidr->mask, aclass->cidr_bitlen_ipv6))
3515      {
3516        cidr->number_on_this_cidr--;
3517        if (cidr->number_on_this_cidr == 0)
3518        {
3519          dlinkDelete(ptr, &aclass->list_ipv6);
3520          MyFree(cidr);
3521          return;
3522        }
3523      }
3524    }
3525  }
3526 #endif
3527 }
3528
3529 static void
3530 rebuild_cidr_list(int aftype, struct ConfItem *oldcl, struct ClassItem *newcl,
3531                  dlink_list *old_list, dlink_list *new_list, int changed)
3532 {
3533  dlink_node *ptr;
3534  struct Client *client_p;
3535  struct ConfItem *conf;
3536  struct AccessItem *aconf;
3537
3538  if (!changed)
3539  {
3540    *new_list = *old_list;
3541    old_list->head = old_list->tail = NULL;
3542    old_list->length = 0;
3543    return;
3544  }
3545
3546  DLINK_FOREACH(ptr, local_client_list.head)
3547  {
3548    client_p = ptr->data;
3549    if (client_p->localClient->aftype != aftype)
3550      continue;
3551    if (dlink_list_length(&client_p->localClient->confs) == 0)
3552      continue;
3553
3554    conf = client_p->localClient->confs.tail->data;
3555    if (conf->type == CLIENT_TYPE)
3556    {
3557      aconf = map_to_conf(conf);
3558      if (aconf->class_ptr == oldcl)
3559        cidr_limit_reached(1, &client_p->localClient->ip, newcl);
3560    }
3561  }
3562 }
3563
3564 /*
3565 * rebuild_cidr_class
3566 *
3567 * inputs       - pointer to old conf
3568 *              - pointer to new_class
3569 * output       - none
3570 * side effects - rebuilds the class link list of cidr blocks
3571 */
3572 void
3573 rebuild_cidr_class(struct ConfItem *conf, struct ClassItem *new_class)
3574 {
3575  struct ClassItem *old_class = map_to_conf(conf);
3576
3577  if (old_class->number_per_cidr > 0 && new_class->number_per_cidr > 0)
3578  {
3579    if (old_class->cidr_bitlen_ipv4 > 0 && new_class->cidr_bitlen_ipv4 > 0)
3580      rebuild_cidr_list(AF_INET, conf, new_class,
3581                        &old_class->list_ipv4, &new_class->list_ipv4,
3582                        old_class->cidr_bitlen_ipv4 != new_class->cidr_bitlen_ipv4);
3583
3584 #ifdef IPV6
3585    if (old_class->cidr_bitlen_ipv6 > 0 && new_class->cidr_bitlen_ipv6 > 0)
3586      rebuild_cidr_list(AF_INET6, conf, new_class,
3587                        &old_class->list_ipv6, &new_class->list_ipv6,
3588                        old_class->cidr_bitlen_ipv6 != new_class->cidr_bitlen_ipv6);
3589 #endif
3590  }
3591
3592  destroy_cidr_class(old_class);
3593 }
3594
3595 /*
3596 * destroy_cidr_list
3597 *
3598 * inputs       - pointer to class dlink list of cidr blocks
3599 * output       - none
3600 * side effects - completely destroys the class link list of cidr blocks
3601 */
3602 static void
3603 destroy_cidr_list(dlink_list *list)
3604 {
3605  dlink_node *ptr = NULL, *next_ptr = NULL;
3606
3607  DLINK_FOREACH_SAFE(ptr, next_ptr, list->head)
3608  {
3609    dlinkDelete(ptr, list);
3610    MyFree(ptr->data);
3611  }
3612 }
3613
3614 /*
3615 * destroy_cidr_class
3616 *
3617 * inputs       - pointer to class
3618 * output       - none
3619 * side effects - completely destroys the class link list of cidr blocks
3620 */
3621 static void
3622 destroy_cidr_class(struct ClassItem *aclass)
3623 {
3624  destroy_cidr_list(&aclass->list_ipv4);
3625  destroy_cidr_list(&aclass->list_ipv6);
3626 }

Diff Legend

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