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

Comparing ircd-hybrid/branches/8.2.x/src/conf.c (file contents):
Revision 7725 by michael, Mon Sep 26 14:59:44 2016 UTC vs.
Revision 9221 by michael, Sun Jan 26 11:25:33 2020 UTC

# Line 1 | Line 1
1   /*
2   *  ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3   *
4 < *  Copyright (c) 1997-2016 ircd-hybrid development team
4 > *  Copyright (c) 1997-2020 ircd-hybrid development team
5   *
6   *  This program is free software; you can redistribute it and/or modify
7   *  it under the terms of the GNU General Public License as published by
# Line 27 | Line 27
27   #include "stdinc.h"
28   #include "list.h"
29   #include "ircd_defs.h"
30 + #include "parse.h"
31   #include "conf.h"
32   #include "conf_cluster.h"
33   #include "conf_gecos.h"
# Line 50 | Line 51
51   #include "send.h"
52   #include "memory.h"
53   #include "res.h"
53 #include "userhost.h"
54   #include "user.h"
55   #include "channel_mode.h"
56 #include "parse.h"
56   #include "misc.h"
57   #include "conf_db.h"
58   #include "conf_class.h"
# Line 96 | Line 95 | conf_dns_callback(void *vptr, const stru
95   {
96    struct MaskItem *const conf = vptr;
97  
98 <  conf->dns_pending = 0;
98 >  conf->dns_pending = false;
99  
100    if (addr)
101 <    memcpy(&conf->addr, addr, sizeof(conf->addr));
101 >    *conf->addr = *addr;
102    else
103 <    conf->dns_failed = 1;
103 >    conf->dns_failed = true;
104   }
105  
106 < /* conf_dns_lookup()
106 > /* conf_resolve_host()
107   *
108 < * do a nameserver lookup of the conf host
109 < * if the conf entry is currently doing a ns lookup do nothing, otherwise
111 < * allocate a dns_query and start ns lookup.
108 > * start DNS lookups of all hostnames in the conf
109 > * line and convert an IP addresses in a.b.c.d number for to IP#s.
110   */
111 < static void
111 > void
112   conf_dns_lookup(struct MaskItem *conf)
113   {
114 <  if (conf->dns_pending)
114 >  struct addrinfo hints, *res;
115 >
116 >  /*
117 >   * Do name lookup now on hostnames given and store the
118 >   * ip numbers in conf structure.
119 >   */
120 >  memset(&hints, 0, sizeof(hints));
121 >
122 >  hints.ai_family = AF_UNSPEC;
123 >  hints.ai_socktype = SOCK_STREAM;
124 >
125 >  /* Get us ready for a bind() and don't bother doing dns lookup */
126 >  hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
127 >
128 >  if (getaddrinfo(conf->host, NULL, &hints, &res))
129 >  {
130 >    /*
131 >     * By this point conf->host possibly is not a numerical network address. Do a nameserver
132 >     * lookup of the conf host. If the conf entry is currently doing a ns lookup do nothing.
133 >     */
134 >    if (conf->dns_pending == true)
135 >      return;
136 >
137 >    conf->dns_pending = true;
138 >
139 >    if (conf->aftype == AF_INET)
140 >      gethost_byname_type(conf_dns_callback, conf, conf->host, T_A);
141 >    else
142 >      gethost_byname_type(conf_dns_callback, conf, conf->host, T_AAAA);
143      return;
144 +  }
145  
146 <  conf->dns_pending = 1;
146 >  assert(res);
147  
148 <  if (conf->aftype == AF_INET)
149 <    gethost_byname_type(conf_dns_callback, conf, conf->host, T_A);
150 <  else
151 <    gethost_byname_type(conf_dns_callback, conf, conf->host, T_AAAA);
148 >  memcpy(conf->addr, res->ai_addr, res->ai_addrlen);
149 >  conf->addr->ss_len = res->ai_addrlen;
150 >
151 >  freeaddrinfo(res);
152   }
153  
154   /* map_to_list()
# Line 153 | Line 180 | conf_make(enum maskitem_type type)
180    dlink_list *list = NULL;
181  
182    conf->type   = type;
183 <  conf->active = 1;
183 >  conf->active = true;
184    conf->aftype = AF_INET;
185  
186    if ((list = map_to_list(type)))
# Line 172 | Line 199 | conf_free(struct MaskItem *conf)
199  
200    xfree(conf->name);
201  
202 <  if (conf->dns_pending)
202 >  if (conf->dns_pending == true)
203      delete_resolver_queries(conf);
204    if (conf->passwd)
205      memset(conf->passwd, 0, strlen(conf->passwd));
# Line 188 | Line 215 | conf_free(struct MaskItem *conf)
215    xfree(conf->whois);
216    xfree(conf->user);
217    xfree(conf->host);
218 +  xfree(conf->addr);
219 +  xfree(conf->bind);
220    xfree(conf->cipher_list);
221  
222    DLINK_FOREACH_SAFE(node, node_next, conf->hub_list.head)
# Line 218 | Line 247 | static int
247   attach_iline(struct Client *client_p, struct MaskItem *conf)
248   {
249    const struct ClassItem *const class = conf->class;
250 <  struct ip_entry *ip_found;
222 <  int a_limit_reached = 0;
223 <  unsigned int local = 0, global = 0;
250 >  bool a_limit_reached = false;
251  
252 <  ip_found = ipcache_find_or_add_address(&client_p->connection->ip);
253 <  ip_found->count++;
252 >  struct ip_entry *ipcache = ipcache_record_find_or_add(&client_p->ip);
253 >  ++ipcache->count_local;
254    AddFlag(client_p, FLAGS_IPHASH);
255  
229  userhost_count(client_p->sockhost, &global, &local);
230
231  /* XXX blah. go down checking the various silly limits
232   * setting a_limit_reached if any limit is reached.
233   * - Dianora
234   */
256    if (class->max_total && class->ref_count >= class->max_total)
257 <    a_limit_reached = 1;
258 <  else if (class->max_perip && ip_found->count > class->max_perip)
259 <    a_limit_reached = 1;
260 <  else if (class->max_local && local >= class->max_local) /* XXX: redundant */
261 <    a_limit_reached = 1;
262 <  else if (class->max_global && global >= class->max_global)
242 <    a_limit_reached = 1;
257 >    a_limit_reached = true;
258 >  else if (class->max_perip_local && ipcache->count_local > class->max_perip_local)
259 >    a_limit_reached = true;
260 >  else if (class->max_perip_global &&
261 >           (ipcache->count_local + ipcache->count_remote) > class->max_perip_global)
262 >    a_limit_reached = true;
263  
264 <  if (a_limit_reached)
264 >  if (a_limit_reached == true)
265    {
266      if (!IsConfExemptLimits(conf))
267        return TOO_MANY;   /* Already at maximum allowed */
# Line 250 | Line 270 | attach_iline(struct Client *client_p, st
270                        "but you have exceed_limit = yes;");
271    }
272  
273 <  return attach_conf(client_p, conf);
273 >  return conf_attach(client_p, conf);
274   }
275  
276   /* verify_access()
# Line 262 | Line 282 | attach_iline(struct Client *client_p, st
282   static int
283   verify_access(struct Client *client_p)
284   {
285 <  struct MaskItem *conf = NULL;
285 >  struct MaskItem *conf;
286  
287    if (HasFlag(client_p, FLAGS_GOTID))
288 <  {
269 <    conf = find_address_conf(client_p->host, client_p->username,
270 <                             &client_p->connection->ip,
271 <                             client_p->connection->aftype,
288 >    conf = find_address_conf(client_p->host, client_p->username, &client_p->ip,
289                               client_p->connection->password);
273  }
290    else
291    {
292      char non_ident[USERLEN + 1] = "~";
293  
294      strlcpy(non_ident + 1, client_p->username, sizeof(non_ident) - 1);
295 <    conf = find_address_conf(client_p->host, non_ident,
280 <                             &client_p->connection->ip,
281 <                             client_p->connection->aftype,
295 >    conf = find_address_conf(client_p->host, non_ident, &client_p->ip,
296                               client_p->connection->password);
297    }
298  
299 <  if (!conf)
299 >  if (conf == NULL)
300      return NOT_AUTHORIZED;
301  
302    assert(IsConfClient(conf) || IsConfKill(conf));
303  
304 <  if (IsConfClient(conf))
304 >  if (IsConfKill(conf))
305    {
306 <    if (IsConfRedir(conf))
307 <    {
308 <      sendto_one_numeric(client_p, &me, RPL_REDIR,
295 <                         conf->name ? conf->name : "",
296 <                         conf->port);
297 <      return NOT_AUTHORIZED;
298 <    }
306 >    sendto_one_notice(client_p, &me, ":*** Banned: %s", conf->reason);
307 >    return BANNED_CLIENT;
308 >  }
309  
310 <    if (IsConfDoSpoofIp(conf))
311 <    {
312 <      if (IsConfSpoofNotice(conf))
313 <        sendto_realops_flags(UMODE_SERVNOTICE, L_ADMIN, SEND_NOTICE, "%s spoofing: %s as %s",
314 <                             client_p->name, client_p->host, conf->name);
310 >  if (IsConfRedir(conf))
311 >  {
312 >    sendto_one_numeric(client_p, &me, RPL_REDIR,
313 >                       conf->name ? conf->name : "",
314 >                       conf->port);
315 >    return NOT_AUTHORIZED;
316 >  }
317  
318 <      strlcpy(client_p->host, conf->name, sizeof(client_p->host));
319 <    }
318 >  if (IsConfDoSpoofIp(conf))
319 >  {
320 >    if (IsConfSpoofNotice(conf))
321 >      sendto_realops_flags(UMODE_SERVNOTICE, L_ADMIN, SEND_NOTICE, "%s spoofing: %s as %s",
322 >                           client_p->name, client_p->host, conf->name);
323  
324 <    return attach_iline(client_p, conf);
324 >    strlcpy(client_p->host, conf->name, sizeof(client_p->host));
325    }
326  
327 <  sendto_one_notice(client_p, &me, ":*** Banned: %s", conf->reason);
313 <  return BANNED_CLIENT;
327 >  return attach_iline(client_p, conf);
328   }
329  
330   /* check_client()
# Line 326 | Line 340 | verify_access(struct Client *client_p)
340   *                Look for conf lines which have the same
341   *                status as the flags passed.
342   */
343 < int
344 < check_client(struct Client *source_p)
343 > bool
344 > conf_check_client(struct Client *source_p)
345   {
346    int i;
347  
# Line 340 | Line 354 | check_client(struct Client *source_p)
354      case TOO_MANY:
355        sendto_realops_flags(UMODE_FULL, L_ALL, SEND_NOTICE,
356                             "Too many on IP for %s (%s).",
357 <                           get_client_name(source_p, SHOW_IP),
357 >                           client_get_name(source_p, SHOW_IP),
358                             source_p->sockhost);
359        ilog(LOG_TYPE_IRCD, "Too many connections on IP from %s.",
360 <           get_client_name(source_p, SHOW_IP));
360 >           client_get_name(source_p, SHOW_IP));
361        ++ServerStats.is_ref;
362        exit_client(source_p, "No more connections allowed on that IP");
363        break;
# Line 351 | Line 365 | check_client(struct Client *source_p)
365      case I_LINE_FULL:
366        sendto_realops_flags(UMODE_FULL, L_ALL, SEND_NOTICE,
367                             "auth {} block is full for %s (%s).",
368 <                           get_client_name(source_p, SHOW_IP),
368 >                           client_get_name(source_p, SHOW_IP),
369                             source_p->sockhost);
370        ilog(LOG_TYPE_IRCD, "Too many connections from %s.",
371 <           get_client_name(source_p, SHOW_IP));
371 >           client_get_name(source_p, SHOW_IP));
372        ++ServerStats.is_ref;
373        exit_client(source_p, "No more connections allowed in your connection class");
374        break;
# Line 364 | Line 378 | check_client(struct Client *source_p)
378        /*       a purely cosmetical change */
379        sendto_realops_flags(UMODE_UNAUTH, L_ALL, SEND_NOTICE,
380                             "Unauthorized client connection from %s on [%s/%u].",
381 <                           get_client_name(source_p, SHOW_IP),
381 >                           client_get_name(source_p, SHOW_IP),
382                             source_p->connection->listener->name,
383                             source_p->connection->listener->port);
384        ilog(LOG_TYPE_IRCD, "Unauthorized client connection from %s on [%s/%u].",
385 <           get_client_name(source_p, SHOW_IP),
385 >           client_get_name(source_p, SHOW_IP),
386             source_p->connection->listener->name,
387             source_p->connection->listener->port);
388  
# Line 386 | Line 400 | check_client(struct Client *source_p)
400        break;
401    }
402  
403 <  return !(i < 0);
403 >  if (i < 0)
404 >    return false;
405 >  return true;
406   }
407  
408 < /* detach_conf()
409 < *
410 < * inputs       - pointer to client to detach
411 < *              - type of conf to detach
396 < * output       - 0 for success, -1 for failure
397 < * side effects - Disassociate configuration from the client.
398 < *                Also removes a class from the list if marked for deleting.
408 > /*! \brief Disassociate configuration from the client. Also removes a class
409 > *         from the list if marked for deleting.
410 > * \param client_p Client to operate on
411 > * \param type     Type of conf to detach
412   */
413   void
414 < detach_conf(struct Client *client_p, enum maskitem_type type)
414 > conf_detach(struct Client *client_p, enum maskitem_type type)
415   {
416 <  dlink_node *node = NULL, *node_next = NULL;
416 >  dlink_node *node, *node_next;
417  
418    DLINK_FOREACH_SAFE(node, node_next, client_p->connection->confs.head)
419    {
# Line 417 | Line 430 | detach_conf(struct Client *client_p, enu
430      free_dlink_node(node);
431  
432      if (conf->type == CONF_CLIENT)
433 <      remove_from_cidr_check(&client_p->connection->ip, conf->class);
433 >      class_ip_limit_remove(conf->class, &client_p->ip);
434  
435 <    if (--conf->class->ref_count == 0 && conf->class->active == 0)
435 >    if (--conf->class->ref_count == 0 && conf->class->active == false)
436      {
437        class_free(conf->class);
438        conf->class = NULL;
439      }
440  
441 <    if (--conf->ref_count == 0 && conf->active == 0)
441 >    if (--conf->ref_count == 0 && conf->active == false)
442        conf_free(conf);
443    }
444   }
445  
446 < /* attach_conf()
447 < *
448 < * inputs       - client pointer
449 < *              - conf pointer
450 < * output       -
438 < * side effects - Associate a specific configuration entry to a *local*
439 < *                client (this is the one which used in accepting the
440 < *                connection). Note, that this automatically changes the
441 < *                attachment if there was an old one...
446 > /*! \brief Associate a specific configuration entry to a *local* client (this
447 > *         is the one which used in accepting the connection). Note, that this
448 > *         automatically changes the attachment if there was an old one.
449 > * \param client_p Client to attach the conf to
450 > * \param conf Configuration record to attach
451   */
452   int
453 < attach_conf(struct Client *client_p, struct MaskItem *conf)
453 > conf_attach(struct Client *client_p, struct MaskItem *conf)
454   {
455    if (dlinkFind(&client_p->connection->confs, conf))
456      return 1;
457  
458    if (conf->type == CONF_CLIENT)
459 <    if (cidr_limit_reached(IsConfExemptLimits(conf),
451 <                           &client_p->connection->ip, conf->class))
459 >    if (class_ip_limit_add(conf->class, &client_p->ip, IsConfExemptLimits(conf)) == true)
460        return TOO_MANY;    /* Already at maximum allowed */
461  
462    conf->class->ref_count++;
# Line 459 | Line 467 | attach_conf(struct Client *client_p, str
467    return 0;
468   }
469  
462 /* attach_connect_block()
463 *
464 * inputs       - pointer to server to attach
465 *              - name of server
466 *              - hostname of server
467 * output       - true (1) if both are found, otherwise return false (0)
468 * side effects - find connect block and attach them to connecting client
469 */
470 int
471 attach_connect_block(struct Client *client_p, const char *name,
472                     const char *host)
473 {
474  dlink_node *node = NULL;
475
476  assert(host);
477
478  DLINK_FOREACH(node, connect_items.head)
479  {
480    struct MaskItem *conf = node->data;
481
482    if (irccmp(conf->name, name) ||
483        irccmp(conf->host, host))
484      continue;
485
486    attach_conf(client_p, conf);
487    return 1;
488  }
489
490  return 0;
491 }
492
470   /* find_conf_name()
471   *
472   * inputs       - pointer to conf link list to search
# Line 518 | Line 495 | find_conf_name(dlink_list *list, const c
495    return NULL;
496   }
497  
498 < /* find_matching_name_conf()
499 < *
500 < * inputs       - type of link list to look in
524 < *              - pointer to name string to find
525 < *              - pointer to user
526 < *              - pointer to host
527 < *              - optional flags to match on as well
528 < * output       - NULL or pointer to found struct MaskItem
529 < * side effects - looks for a match on name field
498 > /*! \brief Find a connect {} conf that has a name that matches \a name.
499 > * \param name Name to match
500 > * \param compare Pointer to function to be used for string matching
501   */
502   struct MaskItem *
503 < connect_find(const char *name, const char *host, int (*compare)(const char *, const char *))
503 > connect_find(const char *name, int (*compare)(const char *, const char *))
504   {
505 <  dlink_node *node = NULL;
505 >  dlink_node *node;
506  
507    DLINK_FOREACH(node, connect_items.head)
508    {
509      struct MaskItem *conf = node->data;
510  
511 <    if (name && !compare(name, conf->name))
541 <      return conf;
542 <    if (host && !compare(host, conf->host))
511 >    if (compare(name, conf->name) == 0)
512        return conf;
513    }
514  
# Line 558 | Line 527 | connect_find(const char *name, const cha
527   struct MaskItem *
528   operator_find(const struct Client *who, const char *name)
529   {
530 <  dlink_node *node = NULL;
530 >  dlink_node *node;
531  
532    DLINK_FOREACH(node, operator_items.head)
533    {
534      struct MaskItem *conf = node->data;
535  
536 <    if (!irccmp(conf->name, name))
536 >    if (irccmp(conf->name, name) == 0)
537      {
538 <      if (!who)
538 >      if (who == NULL)
539          return conf;
540  
541 <      if (!match(conf->user, who->username))
541 >      if (match(conf->user, who->username) == 0)
542        {
543          switch (conf->htype)
544          {
545            case HM_HOST:
546 <            if (!match(conf->host, who->host) || !match(conf->host, who->sockhost))
547 <              if (!conf->class->max_total || conf->class->ref_count < conf->class->max_total)
546 >            if (match(conf->host, who->host) == 0 || match(conf->host, who->sockhost) == 0)
547 >              if (conf->class->max_total == 0 || conf->class->ref_count < conf->class->max_total)
548                  return conf;
549              break;
550            case HM_IPV4:
551 <            if (who->connection->aftype == AF_INET)
552 <              if (match_ipv4(&who->connection->ip, &conf->addr, conf->bits))
553 <                if (!conf->class->max_total || conf->class->ref_count < conf->class->max_total)
551 >            if (who->ip.ss.ss_family == AF_INET)
552 >              if (match_ipv4(&who->ip, conf->addr, conf->bits))
553 >                if (conf->class->max_total == 0 || conf->class->ref_count < conf->class->max_total)
554                    return conf;
555              break;
556            case HM_IPV6:
557 <            if (who->connection->aftype == AF_INET6)
558 <              if (match_ipv6(&who->connection->ip, &conf->addr, conf->bits))
559 <                if (!conf->class->max_total || conf->class->ref_count < conf->class->max_total)
557 >            if (who->ip.ss.ss_family == AF_INET6)
558 >              if (match_ipv6(&who->ip, conf->addr, conf->bits))
559 >                if (conf->class->max_total == 0 || conf->class->ref_count < conf->class->max_total)
560                    return conf;
561              break;
562            default:
# Line 600 | Line 569 | operator_find(const struct Client *who,
569    return NULL;
570   }
571  
572 < /* set_default_conf()
572 > /* conf_set_defaults()
573   *
574   * inputs       - NONE
575   * output       - NONE
# Line 610 | Line 579 | operator_find(const struct Client *who,
579   *                of values later, put them in validate_conf().
580   */
581   static void
582 < set_default_conf(void)
582 > conf_set_defaults(void)
583   {
584 <  /* verify init_class() ran, this should be an unnecessary check
585 <   * but its not much work.
584 >  /*
585 >   * Verify init_class() ran, this should be an unnecessary check
586 >   * but it's not much work.
587     */
588    assert(class_default == class_get_list()->tail->data);
589  
590    ConfigServerInfo.network_name = xstrdup(NETWORK_NAME_DEFAULT);
591    ConfigServerInfo.network_desc = xstrdup(NETWORK_DESC_DEFAULT);
622
623  memset(&ConfigServerInfo.ip, 0, sizeof(ConfigServerInfo.ip));
624  ConfigServerInfo.specific_ipv4_vhost = 0;
625  memset(&ConfigServerInfo.ip6, 0, sizeof(ConfigServerInfo.ip6));
626  ConfigServerInfo.specific_ipv6_vhost = 0;
627
592    ConfigServerInfo.default_max_clients = MAXCLIENTS_MAX;
593    ConfigServerInfo.max_nick_length = 9;
594    ConfigServerInfo.max_topic_length = 80;
595    ConfigServerInfo.hub = 0;
632  ConfigServerInfo.libgeoip_database_options = 0;
596  
597 <  log_del_all();
597 >  log_iterate(log_free);
598  
599    ConfigLog.use_logging = 1;
600  
# Line 639 | Line 602 | set_default_conf(void)
602    ConfigChannel.invite_client_count = 10;
603    ConfigChannel.invite_client_time = 300;
604    ConfigChannel.invite_delay_channel = 5;
605 +  ConfigChannel.invite_expire_time = 1800;
606    ConfigChannel.knock_client_count = 1;
607    ConfigChannel.knock_client_time = 300;
608    ConfigChannel.knock_delay_channel = 60;
609    ConfigChannel.max_channels = 25;
610 <  ConfigChannel.max_bans = 25;
610 >  ConfigChannel.max_invites = 20;
611 >  ConfigChannel.max_bans = 100;
612 >  ConfigChannel.max_bans_large = 500;
613    ConfigChannel.default_join_flood_count = 18;
614    ConfigChannel.default_join_flood_time = 6;
615  
# Line 666 | Line 632 | set_default_conf(void)
632    ConfigGeneral.kline_min_cidr = 16;
633    ConfigGeneral.kline_min_cidr6 = 48;
634    ConfigGeneral.invisible_on_connect = 1;
669  ConfigGeneral.tkline_expire_notices = 1;
670  ConfigGeneral.ignore_bogus_ts = 0;
635    ConfigGeneral.disable_auth = 0;
636    ConfigGeneral.kill_chase_time_limit = 90;
637    ConfigGeneral.default_floodcount = 8;
638 +  ConfigGeneral.default_floodtime = 1;
639    ConfigGeneral.failed_oper_notice = 1;
640    ConfigGeneral.dots_in_ident = 0;
641    ConfigGeneral.min_nonwildcard = 4;
# Line 691 | Line 656 | set_default_conf(void)
656    ConfigGeneral.stats_P_oper_only = 0;
657    ConfigGeneral.stats_u_oper_only = 0;
658    ConfigGeneral.caller_id_wait = 60;
659 <  ConfigGeneral.opers_bypass_callerid = 0;
659 >  ConfigGeneral.opers_bypass_callerid = 1;
660    ConfigGeneral.pace_wait = 10;
661    ConfigGeneral.pace_wait_simple = 1;
662    ConfigGeneral.short_motd = 0;
# Line 707 | Line 672 | set_default_conf(void)
672   }
673  
674   static void
675 < validate_conf(void)
675 > conf_validate(void)
676   {
677    if (EmptyString(ConfigServerInfo.network_name))
678      ConfigServerInfo.network_name = xstrdup(NETWORK_NAME_DEFAULT);
# Line 716 | Line 681 | validate_conf(void)
681      ConfigServerInfo.network_desc = xstrdup(NETWORK_DESC_DEFAULT);
682   }
683  
684 < /* read_conf()
684 > /* conf_read()
685   *
686   * inputs       - file descriptor pointing to config file to use
687   * output       - None
688   * side effects - Read configuration file.
689   */
690   static void
691 < read_conf(FILE *file)
691 > conf_read(FILE *file)
692   {
693 <  lineno = 0;
693 >  lineno = 1;
694  
695 <  set_default_conf();  /* Set default values prior to conf parsing */
695 >  conf_set_defaults();  /* Set default values prior to conf parsing */
696    conf_parser_ctx.pass = 1;
697    yyparse();  /* Pick up the classes first */
698  
# Line 735 | Line 700 | read_conf(FILE *file)
700  
701    conf_parser_ctx.pass = 2;
702    yyparse();  /* Load the values from the conf */
703 <  validate_conf();  /* Check to make sure some values are still okay. */
703 >  conf_validate();  /* Check to make sure some values are still okay. */
704                      /* Some global values are also loaded here. */
705    whowas_trim();  /* Attempt to trim whowas list if necessary */
706    class_delete_marked();  /* Delete unused classes that are marked for deletion */
# Line 748 | Line 713 | read_conf(FILE *file)
713   * called as a result of the server receiving a HUP signal.
714   */
715   void
716 < conf_rehash(int sig)
716 > conf_rehash(bool sig)
717   {
718 <  if (sig)
718 >  if (sig == true)
719    {
720      sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE,
721                           "Got signal SIGHUP, reloading configuration file(s)");
# Line 761 | Line 726 | conf_rehash(int sig)
726  
727    /* don't close listeners until we know we can go ahead with the rehash */
728  
729 <  read_conf_files(0);
729 >  conf_read_files(false);
730  
731    load_conf_modules();
732    check_conf_klines();
733   }
734  
770 /* lookup_confhost()
771 *
772 * start DNS lookups of all hostnames in the conf
773 * line and convert an IP addresses in a.b.c.d number for to IP#s.
774 */
775 void
776 lookup_confhost(struct MaskItem *conf)
777 {
778  struct addrinfo hints, *res;
779
780  /*
781   * Do name lookup now on hostnames given and store the
782   * ip numbers in conf structure.
783   */
784  memset(&hints, 0, sizeof(hints));
785
786  hints.ai_family   = AF_UNSPEC;
787  hints.ai_socktype = SOCK_STREAM;
788
789  /* Get us ready for a bind() and don't bother doing dns lookup */
790  hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
791
792  if (getaddrinfo(conf->host, NULL, &hints, &res))
793  {
794    conf_dns_lookup(conf);
795    return;
796  }
797
798  assert(res);
799
800  memcpy(&conf->addr, res->ai_addr, res->ai_addrlen);
801  conf->addr.ss_len = res->ai_addrlen;
802  conf->addr.ss.ss_family = res->ai_family;
803
804  freeaddrinfo(res);
805 }
806
735   /* conf_connect_allowed()
736   *
737   * inputs       - pointer to inaddr
# Line 812 | Line 740 | lookup_confhost(struct MaskItem *conf)
740   * side effects - none
741   */
742   int
743 < conf_connect_allowed(struct irc_ssaddr *addr, int aftype)
743 > conf_connect_allowed(struct irc_ssaddr *addr)
744   {
745 <  struct ip_entry *ip_found = NULL;
818 <  const struct MaskItem *conf = find_dline_conf(addr, aftype);
745 >  const struct MaskItem *conf = find_dline_conf(addr);
746  
747    if (conf)
748    {
# Line 825 | Line 752 | conf_connect_allowed(struct irc_ssaddr *
752      return BANNED_CLIENT;
753    }
754  
755 <  ip_found = ipcache_find_or_add_address(addr);
756 <
830 <  if ((CurrentTime - ip_found->last_attempt) < ConfigGeneral.throttle_time)
755 >  struct ip_entry *ip_found = ipcache_record_find_or_add(addr);
756 >  if ((event_base->time.sec_monotonic - ip_found->last_attempt) < ConfigGeneral.throttle_time)
757    {
758      if (ip_found->connection_count >= ConfigGeneral.throttle_count)
759        return TOO_FAST;
# Line 837 | Line 763 | conf_connect_allowed(struct irc_ssaddr *
763    else
764      ip_found->connection_count = 1;
765  
766 <  ip_found->last_attempt = CurrentTime;
766 >  ip_found->last_attempt = event_base->time.sec_monotonic;
767    return 0;
768   }
769  
# Line 856 | Line 782 | cleanup_tklines(void *unused)
782    resv_expire();
783   }
784  
859 /* oper_privs_as_string()
860 *
861 * inputs        - pointer to client_p
862 * output        - pointer to static string showing oper privs
863 * side effects  - return as string, the oper privs as derived from port
864 */
865 static const struct oper_flags
866 {
867  const unsigned int flag;
868  const unsigned char c;
869 } flag_table[] = {
870  { OPER_FLAG_ADMIN,          'A' },
871  { OPER_FLAG_CLOSE,          'B' },
872  { OPER_FLAG_CONNECT,        'C' },
873  { OPER_FLAG_CONNECT_REMOTE, 'D' },
874  { OPER_FLAG_DIE,            'E' },
875  { OPER_FLAG_DLINE,          'F' },
876  { OPER_FLAG_GLOBOPS,        'G' },
877  { OPER_FLAG_JOIN_RESV,      'H' },
878  { OPER_FLAG_KILL,           'I' },
879  { OPER_FLAG_KILL_REMOTE,    'J' },
880  { OPER_FLAG_KLINE,          'K' },
881  { OPER_FLAG_LOCOPS,         'L' },
882  { OPER_FLAG_MODULE,         'M' },
883  { OPER_FLAG_NICK_RESV,      'N' },
884  { OPER_FLAG_OPME,           'O' },
885  { OPER_FLAG_REHASH,         'P' },
886  { OPER_FLAG_REMOTEBAN,      'Q' },
887  { OPER_FLAG_RESTART,        'R' },
888  { OPER_FLAG_RESV,           'S' },
889  { OPER_FLAG_SET,            'T' },
890  { OPER_FLAG_SQUIT,          'U' },
891  { OPER_FLAG_SQUIT_REMOTE,   'V' },
892  { OPER_FLAG_UNDLINE,        'W' },
893  { OPER_FLAG_UNKLINE,        'X' },
894  { OPER_FLAG_UNRESV,         'Y' },
895  { OPER_FLAG_UNXLINE,        'Z' },
896  { OPER_FLAG_WALLOPS,        'a' },
897  { OPER_FLAG_XLINE,          'b' },
898  { 0, '\0' }
899 };
900
901 const char *
902 oper_privs_as_string(const unsigned int flags)
903 {
904  static char buf[sizeof(flag_table) / sizeof(struct oper_flags)];
905  char *p = buf;
906
907  for (const struct oper_flags *tab = flag_table; tab->flag; ++tab)
908    if (flags & tab->flag)
909      *p++ = tab->c;
910
911  if (p == buf)
912    *p++ = '0';
913
914  *p = '\0';
915
916  return buf;
917 }
918
785   /*
786   * Input: A client to find the active operator {} name for.
787   * Output: The nick!user@host{oper} of the oper.
# Line 958 | Line 824 | get_oper_name(const struct Client *clien
824    return buffer;
825   }
826  
827 < /* clear_out_old_conf()
827 > /* conf_clear()
828   *
829   * inputs       - none
830   * output       - none
831   * side effects - Clear out the old configuration
832   */
833   static void
834 < clear_out_old_conf(void)
834 > conf_clear(void)
835   {
836    dlink_node *node = NULL, *node_next = NULL;
837    dlink_list *free_items [] = {
# Line 975 | Line 841 | clear_out_old_conf(void)
841    dlink_list ** iterator = free_items; /* C is dumb */
842  
843    /* We only need to free anything allocated by yyparse() here.
844 <   * Resetting structs, etc, is taken care of by set_default_conf().
844 >   * Resetting structs, etc, is taken care of by conf_set_defaults().
845     */
846  
847    for (; *iterator; iterator++)
# Line 984 | Line 850 | clear_out_old_conf(void)
850      {
851        struct MaskItem *conf = node->data;
852  
853 <      conf->active = 0;
853 >      conf->active = false;
854        dlinkDelete(&conf->node, *iterator);
855  
856        if (!conf->ref_count)
# Line 1016 | Line 882 | clear_out_old_conf(void)
882  
883    pseudo_clear();  /* Clear pseudo {} items */
884  
1019 #ifdef HAVE_LIBGEOIP
1020  GeoIP_delete(GeoIPv4_ctx);
1021  GeoIPv4_ctx = NULL;
1022  GeoIP_delete(GeoIPv6_ctx);
1023  GeoIPv6_ctx = NULL;
1024 #endif
1025
885    /* Clean out ConfigServerInfo */
886    xfree(ConfigServerInfo.description);
887    ConfigServerInfo.description = NULL;
# Line 1030 | Line 889 | clear_out_old_conf(void)
889    ConfigServerInfo.network_name = NULL;
890    xfree(ConfigServerInfo.network_desc);
891    ConfigServerInfo.network_desc = NULL;
1033  xfree(ConfigServerInfo.libgeoip_ipv6_database_file);
1034  ConfigServerInfo.libgeoip_ipv6_database_file = NULL;
1035  xfree(ConfigServerInfo.libgeoip_ipv4_database_file);
1036  ConfigServerInfo.libgeoip_ipv4_database_file = NULL;
892    xfree(ConfigServerInfo.rsa_private_key_file);
893    ConfigServerInfo.rsa_private_key_file = NULL;
894 <  xfree(ConfigServerInfo.ssl_certificate_file);
895 <  ConfigServerInfo.ssl_certificate_file = NULL;
896 <  xfree(ConfigServerInfo.ssl_dh_param_file);
897 <  ConfigServerInfo.ssl_dh_param_file = NULL;
898 <  xfree(ConfigServerInfo.ssl_dh_elliptic_curve);
899 <  ConfigServerInfo.ssl_dh_elliptic_curve = NULL;
900 <  xfree(ConfigServerInfo.ssl_cipher_list);
901 <  ConfigServerInfo.ssl_cipher_list = NULL;
902 <  xfree(ConfigServerInfo.ssl_message_digest_algorithm);
903 <  ConfigServerInfo.ssl_message_digest_algorithm = NULL;
894 >  xfree(ConfigServerInfo.tls_certificate_file);
895 >  ConfigServerInfo.tls_certificate_file = NULL;
896 >  xfree(ConfigServerInfo.tls_dh_param_file);
897 >  ConfigServerInfo.tls_dh_param_file = NULL;
898 >  xfree(ConfigServerInfo.tls_supported_groups);
899 >  ConfigServerInfo.tls_supported_groups = NULL;
900 >  xfree(ConfigServerInfo.tls_cipher_list);
901 >  ConfigServerInfo.tls_cipher_list = NULL;
902 >  xfree(ConfigServerInfo.tls_cipher_suites);
903 >  ConfigServerInfo.tls_cipher_suites = NULL;
904 >  xfree(ConfigServerInfo.tls_message_digest_algorithm);
905 >  ConfigServerInfo.tls_message_digest_algorithm = NULL;
906  
907    /* Clean out ConfigAdminInfo */
908    xfree(ConfigAdminInfo.name);
# Line 1055 | Line 912 | clear_out_old_conf(void)
912    xfree(ConfigAdminInfo.description);
913    ConfigAdminInfo.description = NULL;
914  
915 +  /* Clean out ConfigServerHide */
916    xfree(ConfigServerHide.flatten_links_file);
917    ConfigServerHide.flatten_links_file = NULL;
918 +  xfree(ConfigServerHide.hidden_name);
919 +  ConfigServerHide.hidden_name = NULL;
920  
921    /* Clean out listeners */
922    listener_close_marked();
923   }
924  
925   static void
926 < conf_handle_tls(int cold)
926 > conf_handle_tls(bool cold)
927   {
928 <  if (!tls_new_cred())
928 >  if (tls_new_cred() == false)
929    {
930 <    if (cold)
930 >    if (cold == true)
931      {
932        ilog(LOG_TYPE_IRCD, "Error while initializing TLS");
933        exit(EXIT_FAILURE);
# Line 1088 | Line 948 | conf_handle_tls(int cold)
948   * side effects - read all conf files needed, ircd.conf kline.conf etc.
949   */
950   void
951 < read_conf_files(int cold)
951 > conf_read_files(bool cold)
952   {
953 <  const char *filename = NULL;
1094 <  char chanmodes[IRCD_BUFSIZE] = "";
1095 <  char chanlimit[IRCD_BUFSIZE] = "";
953 >  char buf[IRCD_BUFSIZE];
954  
955    conf_parser_ctx.boot = cold;
956 <  filename = ConfigGeneral.configfile;
1099 <
1100 <  /* We need to know the initial filename for the yyerror() to report
1101 <     FIXME: The full path is in conffilenamebuf first time since we
1102 <             don't know anything else
1103 <
1104 <     - Gozem 2002-07-21
1105 <  */
1106 <  strlcpy(conffilebuf, filename, sizeof(conffilebuf));
956 >  conf_parser_ctx.conf_file = fopen(ConfigGeneral.configfile, "r");
957  
958 <  if ((conf_parser_ctx.conf_file = fopen(filename, "r")) == NULL)
958 >  if (conf_parser_ctx.conf_file == NULL)
959    {
960 <    if (cold)
960 >    if (cold == true)
961      {
962        ilog(LOG_TYPE_IRCD, "Unable to read configuration file '%s': %s",
963 <           filename, strerror(errno));
963 >           ConfigGeneral.configfile, strerror(errno));
964        exit(EXIT_FAILURE);
965      }
966      else
967      {
968        sendto_realops_flags(UMODE_SERVNOTICE, L_ADMIN, SEND_NOTICE,
969                             "Unable to read configuration file '%s': %s",
970 <                           filename, strerror(errno));
970 >                           ConfigGeneral.configfile, strerror(errno));
971        return;
972      }
973    }
974  
975 <  if (!cold)
976 <    clear_out_old_conf();
975 >  /*
976 >   * We need to know the initial filename for the yyerror() to report
977 >   *
978 >   *  FIXME: The full path is in conffilenamebuf first time since we
979 >   *          don't know anything else
980 >   *
981 >   *  - Gozem 2002-07-21
982 >   */
983 >  strlcpy(conffilebuf, ConfigGeneral.configfile, sizeof(conffilebuf));
984 >
985 >  if (cold == false)
986 >    conf_clear();
987  
988 <  read_conf(conf_parser_ctx.conf_file);
988 >  conf_read(conf_parser_ctx.conf_file);
989    fclose(conf_parser_ctx.conf_file);
990  
991 <  log_reopen_all();
991 >  log_iterate(log_reopen);
992    conf_handle_tls(cold);
993  
994    isupport_add("NICKLEN", NULL, ConfigServerInfo.max_nick_length);
995    isupport_add("NETWORK", ConfigServerInfo.network_name, -1);
996  
997 <  snprintf(chanmodes, sizeof(chanmodes), "beI:%u", ConfigChannel.max_bans);
998 <  isupport_add("MAXLIST", chanmodes, -1);
997 >  snprintf(buf, sizeof(buf), "beI:%u", ConfigChannel.max_bans);
998 >  isupport_add("MAXLIST", buf, -1);
999 >
1000    isupport_add("MAXTARGETS", NULL, ConfigGeneral.max_targets);
1001    isupport_add("CHANTYPES", "#", -1);
1002  
1003 <  snprintf(chanlimit, sizeof(chanlimit), "#:%u",
1004 <           ConfigChannel.max_channels);
1005 <  isupport_add("CHANLIMIT", chanlimit, -1);
1145 <  snprintf(chanmodes, sizeof(chanmodes), "%s", "beI,k,l,cimnprstCMORST");
1003 >  snprintf(buf, sizeof(buf), "#:%u", ConfigChannel.max_channels);
1004 >  isupport_add("CHANLIMIT", buf, -1);
1005 >
1006    isupport_add("CHANNELLEN", NULL, CHANNELLEN);
1007    isupport_add("TOPICLEN", NULL, ConfigServerInfo.max_topic_length);
1008 <  isupport_add("CHANMODES", chanmodes, -1);
1008 >
1009 >  snprintf(buf, sizeof(buf), "%s", "beI,k,l,cimnprstuCLMNORST");
1010 >  isupport_add("CHANMODES", buf, -1);
1011   }
1012  
1013   /* conf_add_class_to_conf()
# Line 1157 | Line 1019 | read_conf_files(int cold)
1019   void
1020   conf_add_class_to_conf(struct MaskItem *conf, const char *name)
1021   {
1022 <  if (EmptyString(name) || (conf->class = class_find(name, 1)) == NULL)
1022 >  if (EmptyString(name) || (conf->class = class_find(name, true)) == NULL)
1023    {
1024      conf->class = class_default;
1025  
# Line 1184 | Line 1046 | yyerror(const char *msg)
1046    if (conf_parser_ctx.pass != 1)
1047      return;
1048  
1049 <  char *p = stripws(linebuf);
1049 >  const char *p = stripws(linebuf);
1050    sendto_realops_flags(UMODE_SERVNOTICE, L_ADMIN, SEND_NOTICE,
1051                         "\"%s\", line %u: %s: %s",
1052 <                       conffilebuf, lineno + 1, msg, p);
1052 >                       conffilebuf, lineno, msg, p);
1053    ilog(LOG_TYPE_IRCD, "\"%s\", line %u: %s: %s",
1054 <       conffilebuf, lineno + 1, msg, p);
1054 >       conffilebuf, lineno, msg, p);
1055   }
1056  
1057   void
1058   conf_error_report(const char *msg)
1059   {
1060 <  char *p = stripws(linebuf);
1060 >  const char *p = stripws(linebuf);
1061    sendto_realops_flags(UMODE_SERVNOTICE, L_ADMIN, SEND_NOTICE,
1062                         "\"%s\", line %u: %s: %s",
1063 <                       conffilebuf, lineno + 1, msg, linebuf);
1063 >                       conffilebuf, lineno, msg, p);
1064    ilog(LOG_TYPE_IRCD, "\"%s\", line %u: %s: %s",
1065 <       conffilebuf, lineno + 1, msg, linebuf);
1065 >       conffilebuf, lineno, msg, p);
1066   }
1067  
1068   /*
# Line 1241 | Line 1103 | valid_tkline(const char *data, const int
1103     * If the incoming time is in seconds convert it to minutes for the purpose
1104     * of this calculation
1105     */
1106 <  if (!minutes)
1106 >  if (minutes == 0)
1107      result = result / 60;
1108  
1109    if (result > MAX_TDKLINE_TIME)
# Line 1258 | Line 1120 | valid_tkline(const char *data, const int
1120   * outputs      - 1 if valid, else 0
1121   * side effects - none
1122   */
1123 < int
1123 > bool
1124   valid_wild_card_simple(const char *data)
1125   {
1126    const unsigned char *p = (const unsigned char *)data;
# Line 1271 | Line 1133 | valid_wild_card_simple(const char *data)
1133      {
1134        ++p;
1135        if (++nonwild >= ConfigGeneral.min_nonwildcard_simple)
1136 <        return 1;
1136 >        return true;
1137      }
1138      else if (!IsMWildChar(tmpch))
1139      {
1140        if (++nonwild >= ConfigGeneral.min_nonwildcard_simple)
1141 <        return 1;
1141 >        return true;
1142      }
1143      else
1144        ++wild;
1145    }
1146  
1147 <  return !wild;
1147 >  return wild == 0;
1148   }
1149  
1150   /* valid_wild_card()
# Line 1293 | Line 1155 | valid_wild_card_simple(const char *data)
1155   * output       - 0 if not valid, 1 if valid
1156   * side effects - NOTICE is given to source_p if warn is 1
1157   */
1158 < int
1158 > bool
1159   valid_wild_card(int count, ...)
1160   {
1161    unsigned char tmpch = '\0';
# Line 1331 | Line 1193 | valid_wild_card(int count, ...)
1193          if (++nonwild >= ConfigGeneral.min_nonwildcard)
1194          {
1195            va_end(args);
1196 <          return 1;
1196 >          return true;
1197          }
1198        }
1199      }
1200    }
1201  
1202    va_end(args);
1203 <  return 0;
1342 < }
1343 <
1344 < /* find_user_host()
1345 < *
1346 < * inputs       - pointer to client placing kline
1347 < *              - pointer to user_host_or_nick
1348 < *              - pointer to user buffer
1349 < *              - pointer to host buffer
1350 < * output       - 0 if not ok to kline, 1 to kline i.e. if valid user host
1351 < * side effects -
1352 < */
1353 < static int
1354 < find_user_host(struct Client *source_p, char *user_host_or_nick,
1355 <               char *luser, char *lhost)
1356 < {
1357 <  struct Client *target_p = NULL;
1358 <  char *hostp = NULL;
1359 <
1360 <  if (lhost == NULL)
1361 <  {
1362 <    strlcpy(luser, user_host_or_nick, USERLEN*4 + 1);
1363 <    return 1;
1364 <  }
1365 <
1366 <  if ((hostp = strchr(user_host_or_nick, '@')) || *user_host_or_nick == '*')
1367 <  {
1368 <    /* Explicit user@host mask given */
1369 <    if (hostp)                            /* I'm a little user@host */
1370 <    {
1371 <      *(hostp++) = '\0';                       /* short and squat */
1372 <
1373 <      if (*user_host_or_nick)
1374 <        strlcpy(luser, user_host_or_nick, USERLEN*4 + 1); /* here is my user */
1375 <      else
1376 <        strcpy(luser, "*");
1377 <
1378 <      if (*hostp)
1379 <        strlcpy(lhost, hostp, HOSTLEN + 1);    /* here is my host */
1380 <      else
1381 <        strcpy(lhost, "*");
1382 <    }
1383 <    else
1384 <    {
1385 <      luser[0] = '*';             /* no @ found, assume its *@somehost */
1386 <      luser[1] = '\0';
1387 <      strlcpy(lhost, user_host_or_nick, HOSTLEN*4 + 1);
1388 <    }
1389 <
1390 <    return 1;
1391 <  }
1392 <  else
1393 <  {
1394 <    /* Try to find user@host mask from nick */
1395 <    /* Okay to use source_p as the first param, because source_p == client_p */
1396 <    if ((target_p =
1397 <        find_chasing(source_p, user_host_or_nick)) == NULL)
1398 <      return 0;  /* find_chasing sends ERR_NOSUCHNICK */
1399 <
1400 <    if (HasFlag(target_p, FLAGS_EXEMPTKLINE))
1401 <    {
1402 <      if (IsClient(source_p))
1403 <        sendto_one_notice(source_p, &me, ":%s is E-lined", target_p->name);
1404 <      return 0;
1405 <    }
1406 <
1407 <    /*
1408 <     * Turn the "user" bit into "*user", blow away '~'
1409 <     * if found in original user name (non-idented)
1410 <     */
1411 <    strlcpy(luser, target_p->username, USERLEN*4 + 1);
1412 <
1413 <    if (target_p->username[0] == '~')
1414 <      luser[0] = '*';
1415 <
1416 <    strlcpy(lhost, target_p->sockhost, HOSTLEN*4 + 1);
1417 <    return 1;
1418 <  }
1419 <
1420 <  return 0;
1203 >  return false;
1204   }
1205  
1206   /* XXX should this go into a separate file ? -Dianora */
# Line 1450 | Line 1233 | find_user_host(struct Client *source_p,
1233   *
1234   * - Dianora
1235   */
1236 < int
1237 < parse_aline(const char *cmd, struct Client *source_p,
1455 <            int parc, char **parv,
1456 <            char **up_p, char **h_p, uintmax_t *tkline_time,
1457 <            char **target_server, char **reason)
1236 > bool
1237 > parse_aline(const char *cmd, struct Client *source_p, int parc, char **parv, struct aline_ctx *aline)
1238   {
1459  uintmax_t found_tkline_time=0;
1239    static char default_reason[] = CONF_NOREASON;
1240 <  static char user[USERLEN*4+1];
1241 <  static char host[HOSTLEN*4+1];
1463 <
1464 <  parv++;
1465 <  parc--;
1240 >  static char user[USERLEN * 2 + 1];
1241 >  static char host[HOSTLEN * 2 + 1];
1242  
1243 <  found_tkline_time = valid_tkline(*parv, TK_MINUTES);
1243 >  ++parv;
1244 >  --parc;
1245  
1246 <  if (found_tkline_time)
1246 >  if (aline->add == true && (aline->duration = valid_tkline(*parv, TK_MINUTES)))
1247    {
1248 <    parv++;
1249 <    parc--;
1473 <
1474 <    if (tkline_time)
1475 <      *tkline_time = found_tkline_time;
1476 <    else
1477 <    {
1478 <      sendto_one_notice(source_p, &me, ":temp_line not supported by %s", cmd);
1479 <      return 0;
1480 <    }
1248 >    ++parv;
1249 >    --parc;
1250    }
1251  
1252    if (parc == 0)
1253    {
1254      sendto_one_numeric(source_p, &me, ERR_NEEDMOREPARAMS, cmd);
1255 <    return 0;
1255 >    return false;
1256    }
1257  
1258 <  if (h_p == NULL)
1259 <    *up_p = *parv;
1258 >  if (aline->simple_mask == true)
1259 >  {
1260 >    aline->mask = *parv;
1261 >    aline->user = NULL;
1262 >    aline->host = NULL;
1263 >  }
1264    else
1265    {
1266 <    if (find_user_host(source_p, *parv, user, host) == 0)
1267 <      return 0;
1266 >    struct split_nuh_item nuh;
1267 >
1268 >    nuh.nuhmask  = *parv;
1269 >    nuh.nickptr  = NULL;
1270 >    nuh.userptr  = user;
1271 >    nuh.hostptr  = host;
1272  
1273 <    *up_p = user;
1274 <    *h_p = host;
1273 >    nuh.nicksize = 0;
1274 >    nuh.usersize = sizeof(user);
1275 >    nuh.hostsize = sizeof(host);
1276 >
1277 >    split_nuh(&nuh);
1278 >
1279 >    aline->mask = NULL;
1280 >    aline->user = user;
1281 >    aline->host = host;
1282    }
1283  
1284 <  parc--;
1285 <  parv++;
1284 >  ++parv;
1285 >  --parc;
1286  
1287    if (parc)
1288    {
1289      if (irccmp(*parv, "ON") == 0)
1290      {
1291 <      parc--;
1292 <      parv++;
1291 >      ++parv;
1292 >      --parc;
1293  
1294        if (!HasOFlag(source_p, OPER_FLAG_REMOTEBAN))
1295        {
1296          sendto_one_numeric(source_p, &me, ERR_NOPRIVS, "remoteban");
1297 <        return 0;
1297 >        return false;
1298        }
1299  
1300        if (parc == 0 || EmptyString(*parv))
1301        {
1302          sendto_one_numeric(source_p, &me, ERR_NEEDMOREPARAMS, cmd);
1303 <        return 0;
1303 >        return false;
1304        }
1305  
1306 <      *target_server = *parv;
1307 <      parc--;
1308 <      parv++;
1306 >      aline->server = *parv;
1307 >      ++parv;
1308 >      --parc;
1309      }
1310      else
1311 <    {
1528 <      /* Make sure target_server *is* NULL if no ON server found
1529 <       * caller probably NULL'd it first, but no harm to do it again -db
1530 <       */
1531 <      if (target_server)
1532 <        *target_server = NULL;
1533 <    }
1311 >      aline->server = NULL;
1312    }
1313  
1314 <  if (reason)
1314 >  if (aline->add == true)
1315    {
1316 <    if (parc && !EmptyString(*parv))
1317 <      *reason = *parv;
1316 >    if (parc == 0 || EmptyString(*parv))
1317 >      aline->reason = default_reason;
1318      else
1319 <      *reason = default_reason;
1319 >      aline->reason = *parv;
1320    }
1321  
1322 <  return 1;
1322 >  return true;
1323   }
1324  
1325   /* match_conf_password()
# Line 1551 | Line 1329 | parse_aline(const char *cmd, struct Clie
1329   * output       - 1 or 0 if match
1330   * side effects - none
1331   */
1332 < int
1332 > bool
1333   match_conf_password(const char *password, const struct MaskItem *conf)
1334   {
1335    const char *encr = NULL;
1336  
1337    if (EmptyString(password) || EmptyString(conf->passwd))
1338 <    return 0;
1338 >    return false;
1339  
1340    if (conf->flags & CONF_FLAGS_ENCRYPTED)
1341      encr = crypt(password, conf->passwd);
1342    else
1343      encr = password;
1344  
1345 <  return encr && !strcmp(encr, conf->passwd);
1345 >  return encr && strcmp(encr, conf->passwd) == 0;
1346   }
1347  
1348   /*
# Line 1649 | Line 1427 | split_nuh(struct split_nuh_item *const i
1427      else
1428      {
1429        /* No @ found */
1430 <      if (!iptr->nickptr || strpbrk(iptr->nuhmask, ".:"))
1430 >      if (iptr->nickptr == NULL || strpbrk(iptr->nuhmask, ".:"))
1431          strlcpy(iptr->hostptr, iptr->nuhmask, iptr->hostsize);
1432        else
1433          strlcpy(iptr->nickptr, iptr->nuhmask, iptr->nicksize);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines