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

Comparing ircd-hybrid/trunk/src/conf_parser.y (file contents):
Revision 6488 by michael, Fri Sep 4 17:56:25 2015 UTC vs.
Revision 9234 by michael, Fri Jan 31 17:38:34 2020 UTC

# Line 1 | Line 1
1   /*
2   *  ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3   *
4 < *  Copyright (c) 2000-2015 ircd-hybrid development team
4 > *  Copyright (c) 2000-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  
28   %{
29  
30 #include <sys/types.h>
31 #include <string.h>
32
30   #include "config.h"
31   #include "stdinc.h"
32   #include "ircd.h"
33   #include "list.h"
34 + #include "parse.h"
35   #include "conf.h"
36   #include "conf_class.h"
37 + #include "conf_cluster.h"
38 + #include "conf_gecos.h"
39   #include "conf_pseudo.h"
40 + #include "conf_resv.h"
41 + #include "conf_service.h"
42 + #include "conf_shared.h"
43   #include "event.h"
44   #include "id.h"
45   #include "log.h"
43 #include "client.h"     /* for UMODE_SERVNOTICE only */
46   #include "irc_string.h"
47   #include "memory.h"
48   #include "modules.h"
49   #include "server.h"
50   #include "hostmask.h"
49 #include "send.h"
51   #include "listener.h"
51 #include "resv.h"
52 #include "numeric.h"
52   #include "user.h"
53   #include "motd.h"
54  
56 #ifdef HAVE_LIBCRYPTO
57 #include <openssl/rsa.h>
58 #include <openssl/bio.h>
59 #include <openssl/pem.h>
60 #include <openssl/dh.h>
61 #endif
62
63 #include "rsa.h"
64
55   int yylex(void);
56  
57   static struct
# Line 101 | Line 91 | static struct
91      size,
92      type,
93      port,
94 +    timeout,
95      aftype,
96      ping_freq,
97 <    max_perip,
97 >    max_perip_local,
98 >    max_perip_global,
99      con_freq,
100      min_idle,
101      max_idle,
102      max_total,
111    max_global,
112    max_local,
113    max_ident,
103      max_sendq,
104      max_recvq,
105      max_channels,
# Line 122 | Line 111 | static struct
111   static void
112   reset_block_state(void)
113   {
114 <  dlink_node *node = NULL, *node_next = NULL;
115 <
116 <  DLINK_FOREACH_SAFE(node, node_next, block_state.mask.list.head)
128 <  {
129 <    MyFree(node->data);
130 <    dlinkDelete(node, &block_state.mask.list);
131 <    free_dlink_node(node);
132 <  }
133 <
134 <  DLINK_FOREACH_SAFE(node, node_next, block_state.leaf.list.head)
135 <  {
136 <    MyFree(node->data);
137 <    dlinkDelete(node, &block_state.leaf.list);
138 <    free_dlink_node(node);
139 <  }
114 >  dlink_node *node, *node_next;
115 >  dlink_list *tab[] = { &block_state.mask.list,
116 >                        &block_state.leaf.list, &block_state.hub.list, NULL };
117  
118 <  DLINK_FOREACH_SAFE(node, node_next, block_state.hub.list.head)
118 >  for (dlink_list **list = tab; *list; ++list)
119    {
120 <    MyFree(node->data);
121 <    dlinkDelete(node, &block_state.hub.list);
122 <    free_dlink_node(node);
120 >    DLINK_FOREACH_SAFE(node, node_next, (*list)->head)
121 >    {
122 >      xfree(node->data);
123 >      dlinkDelete(node, *list);
124 >      free_dlink_node(node);
125 >    }
126    }
127  
128    memset(&block_state, 0, sizeof(block_state));
# Line 175 | Line 155 | reset_block_state(void)
155   %token  CONNECTFREQ
156   %token  CYCLE_ON_HOST_CHANGE
157   %token  DEFAULT_FLOODCOUNT
158 + %token  DEFAULT_FLOODTIME
159   %token  DEFAULT_JOIN_FLOOD_COUNT
160   %token  DEFAULT_JOIN_FLOOD_TIME
161   %token  DEFAULT_MAX_CLIENTS
# Line 188 | Line 169 | reset_block_state(void)
169   %token  DLINE_MIN_CIDR6
170   %token  DOTS_IN_IDENT
171   %token  EMAIL
172 + %token  ENABLE_EXTBANS
173   %token  ENCRYPTED
174   %token  EXCEED_LIMIT
175   %token  EXEMPT
176 + %token  EXPIRATION
177   %token  FAILED_OPER_NOTICE
178   %token  FLATTEN_LINKS
179 + %token  FLATTEN_LINKS_DELAY
180 + %token  FLATTEN_LINKS_FILE
181   %token  GECOS
182   %token  GENERAL
183   %token  HIDDEN
# Line 206 | Line 191 | reset_block_state(void)
191   %token  HOST
192   %token  HUB
193   %token  HUB_MASK
209 %token  IGNORE_BOGUS_TS
194   %token  INVISIBLE_ON_CONNECT
195   %token  INVITE_CLIENT_COUNT
196   %token  INVITE_CLIENT_TIME
197 + %token  INVITE_DELAY_CHANNEL
198 + %token  INVITE_EXPIRE_TIME
199   %token  IP
200   %token  IRCD_AUTH
201   %token  IRCD_FLAGS
# Line 225 | Line 211 | reset_block_state(void)
211   %token  KNOCK_CLIENT_TIME
212   %token  KNOCK_DELAY_CHANNEL
213   %token  LEAF_MASK
228 %token  LINKS_DELAY
214   %token  LISTEN
215   %token  MASK
216   %token  MAX_ACCEPT
217   %token  MAX_BANS
218 + %token  MAX_BANS_LARGE
219   %token  MAX_CHANNELS
234 %token  MAX_GLOBAL
235 %token  MAX_IDENT
220   %token  MAX_IDLE
221 < %token  MAX_LOCAL
221 > %token  MAX_INVITES
222   %token  MAX_NICK_CHANGES
223   %token  MAX_NICK_LENGTH
224   %token  MAX_NICK_TIME
# Line 258 | Line 242 | reset_block_state(void)
242   %token  NO_TILDE
243   %token  NUMBER
244   %token  NUMBER_PER_CIDR
245 < %token  NUMBER_PER_IP
245 > %token  NUMBER_PER_IP_GLOBAL
246 > %token  NUMBER_PER_IP_LOCAL
247   %token  OPER_ONLY_UMODES
248   %token  OPER_UMODES
249   %token  OPERATOR
# Line 281 | Line 266 | reset_block_state(void)
266   %token  RESV
267   %token  RESV_EXEMPT
268   %token  RSA_PRIVATE_KEY_FILE
284 %token  RSA_PUBLIC_KEY_FILE
269   %token  SECONDS MINUTES HOURS DAYS WEEKS MONTHS YEARS
270   %token  SEND_PASSWORD
271   %token  SENDQ
# Line 291 | Line 275 | reset_block_state(void)
275   %token  SPOOF
276   %token  SPOOF_NOTICE
277   %token  SQUIT
294 %token  SSL_CERTIFICATE_FILE
295 %token  SSL_CERTIFICATE_FINGERPRINT
296 %token  SSL_CONNECTION_REQUIRED
297 %token  SSL_DH_ELLIPTIC_CURVE
298 %token  SSL_DH_PARAM_FILE
299 %token  SSL_MESSAGE_DIGEST_ALGORITHM
278   %token  STATS_E_DISABLED
279   %token  STATS_I_OPER_ONLY
280   %token  STATS_K_OPER_ONLY
# Line 305 | Line 283 | reset_block_state(void)
283   %token  STATS_P_OPER_ONLY
284   %token  STATS_U_OPER_ONLY
285   %token  T_ALL
286 + %token  T_BIND
287   %token  T_BOTS
288   %token  T_CALLERID
289   %token  T_CCONN
# Line 340 | Line 319 | reset_block_state(void)
319   %token  T_SKILL
320   %token  T_SOFTCALLERID
321   %token  T_SPY
343 %token  T_SSL
344 %token  T_SSL_CIPHER_LIST
322   %token  T_TARGET
323 + %token  T_TLS
324   %token  T_UMODES
325   %token  T_UNAUTH
326   %token  T_UNDLINE
# Line 355 | Line 333 | reset_block_state(void)
333   %token  TBOOL
334   %token  THROTTLE_COUNT
335   %token  THROTTLE_TIME
336 < %token  TKLINE_EXPIRE_NOTICES
336 > %token  TIMEOUT
337 > %token  TLS_CERTIFICATE_FILE
338 > %token  TLS_CERTIFICATE_FINGERPRINT
339 > %token  TLS_CIPHER_LIST
340 > %token  TLS_CIPHER_SUITES
341 > %token  TLS_CONNECTION_REQUIRED
342 > %token  TLS_DH_PARAM_FILE
343 > %token  TLS_MESSAGE_DIGEST_ALGORITHM
344 > %token  TLS_SUPPORTED_GROUPS
345   %token  TMASKED
346   %token  TS_MAX_DELTA
347   %token  TS_WARN_DELTA
# Line 368 | Line 354 | reset_block_state(void)
354   %token  VHOST6
355   %token  WARN_NO_CONNECT_BLOCK
356   %token  WHOIS
357 + %token  WHOWAS_HISTORY_LENGTH
358   %token  XLINE
359   %token  XLINE_EXEMPT
360  
# Line 430 | Line 417 | sizespec:   NUMBER sizespec_ { $$ = $1 +
417  
418  
419   /***************************************************************************
420 < *  section modules
420 > * modules {} section
421   ***************************************************************************/
422 < modules_entry: MODULES
436 <  '{' modules_items '}' ';';
422 > modules_entry: MODULES '{' modules_items '}' ';';
423  
424   modules_items:  modules_items modules_item | modules_item;
425   modules_item:   modules_module | modules_path | error ';' ;
# Line 451 | Line 437 | modules_path: PATH '=' QSTRING ';'
437   };
438  
439  
440 + /***************************************************************************
441 + * serverinfo {} section
442 + ***************************************************************************/
443   serverinfo_entry: SERVERINFO '{' serverinfo_items '}' ';';
444  
445   serverinfo_items:       serverinfo_items serverinfo_item | serverinfo_item ;
446   serverinfo_item:        serverinfo_name |
458                        serverinfo_vhost |
447                          serverinfo_hub |
448                          serverinfo_description |
449                          serverinfo_network_name |
# Line 463 | Line 451 | serverinfo_item:        serverinfo_name
451                          serverinfo_default_max_clients |
452                          serverinfo_max_nick_length |
453                          serverinfo_max_topic_length |
454 <                        serverinfo_ssl_dh_param_file |
455 <                        serverinfo_ssl_dh_elliptic_curve |
454 >                        serverinfo_tls_dh_param_file |
455 >                        serverinfo_tls_supported_groups |
456                          serverinfo_rsa_private_key_file |
469                        serverinfo_vhost6 |
457                          serverinfo_sid |
458 <                        serverinfo_ssl_certificate_file |
459 <                        serverinfo_ssl_cipher_list |
460 <                        serverinfo_ssl_message_digest_algorithm |
458 >                        serverinfo_tls_certificate_file |
459 >                        serverinfo_tls_cipher_list |
460 >                        serverinfo_tls_cipher_suites |
461 >                        serverinfo_tls_message_digest_algorithm |
462                          error ';' ;
463  
464  
465 < serverinfo_ssl_certificate_file: SSL_CERTIFICATE_FILE '=' QSTRING ';'
465 > serverinfo_tls_certificate_file: TLS_CERTIFICATE_FILE '=' QSTRING ';'
466   {
479 #ifdef HAVE_LIBCRYPTO
467    if (conf_parser_ctx.pass == 2)
468    {
469 <    if (!ConfigServerInfo.rsa_private_key_file)
470 <    {
484 <      conf_error_report("No rsa_private_key_file specified, SSL disabled");
485 <      break;
486 <    }
487 <
488 <    if (SSL_CTX_use_certificate_chain_file(ConfigServerInfo.server_ctx, yylval.string) <= 0 ||
489 <        SSL_CTX_use_certificate_chain_file(ConfigServerInfo.client_ctx, yylval.string) <= 0)
490 <    {
491 <      report_crypto_errors();
492 <      conf_error_report("Could not open/read certificate file");
493 <      break;
494 <    }
495 <
496 <    if (SSL_CTX_use_PrivateKey_file(ConfigServerInfo.server_ctx, ConfigServerInfo.rsa_private_key_file,
497 <                                    SSL_FILETYPE_PEM) <= 0 ||
498 <        SSL_CTX_use_PrivateKey_file(ConfigServerInfo.client_ctx, ConfigServerInfo.rsa_private_key_file,
499 <                                    SSL_FILETYPE_PEM) <= 0)
500 <    {
501 <      report_crypto_errors();
502 <      conf_error_report("Could not read RSA private key");
503 <      break;
504 <    }
505 <
506 <    if (!SSL_CTX_check_private_key(ConfigServerInfo.server_ctx) ||
507 <        !SSL_CTX_check_private_key(ConfigServerInfo.client_ctx))
508 <    {
509 <      report_crypto_errors();
510 <      conf_error_report("Could not read RSA private key");
511 <      break;
512 <    }
469 >    xfree(ConfigServerInfo.tls_certificate_file);
470 >    ConfigServerInfo.tls_certificate_file = xstrdup(yylval.string);
471    }
514 #endif
472   };
473  
474   serverinfo_rsa_private_key_file: RSA_PRIVATE_KEY_FILE '=' QSTRING ';'
475   {
476 < #ifdef HAVE_LIBCRYPTO
520 <  BIO *file = NULL;
521 <
522 <  if (conf_parser_ctx.pass != 1)
523 <    break;
524 <
525 <  if (ConfigServerInfo.rsa_private_key)
526 <  {
527 <    RSA_free(ConfigServerInfo.rsa_private_key);
528 <    ConfigServerInfo.rsa_private_key = NULL;
529 <  }
530 <
531 <  if (ConfigServerInfo.rsa_private_key_file)
532 <  {
533 <    MyFree(ConfigServerInfo.rsa_private_key_file);
534 <    ConfigServerInfo.rsa_private_key_file = NULL;
535 <  }
536 <
537 <  ConfigServerInfo.rsa_private_key_file = xstrdup(yylval.string);
538 <
539 <  if ((file = BIO_new_file(yylval.string, "r")) == NULL)
540 <  {
541 <    conf_error_report("File open failed, ignoring");
542 <    break;
543 <  }
544 <
545 <  ConfigServerInfo.rsa_private_key = PEM_read_bio_RSAPrivateKey(file, NULL, 0, NULL);
546 <
547 <  BIO_set_close(file, BIO_CLOSE);
548 <  BIO_free(file);
549 <
550 <  if (ConfigServerInfo.rsa_private_key == NULL)
476 >  if (conf_parser_ctx.pass == 2)
477    {
478 <    conf_error_report("Couldn't extract key, ignoring");
479 <    break;
554 <  }
555 <
556 <  if (!RSA_check_key(ConfigServerInfo.rsa_private_key))
557 <  {
558 <    RSA_free(ConfigServerInfo.rsa_private_key);
559 <    ConfigServerInfo.rsa_private_key = NULL;
560 <
561 <    conf_error_report("Invalid key, ignoring");
562 <    break;
478 >    xfree(ConfigServerInfo.rsa_private_key_file);
479 >    ConfigServerInfo.rsa_private_key_file = xstrdup(yylval.string);
480    }
481 + };
482  
483 <  if (RSA_size(ConfigServerInfo.rsa_private_key) < 128)
483 > serverinfo_tls_dh_param_file: TLS_DH_PARAM_FILE '=' QSTRING ';'
484 > {
485 >  if (conf_parser_ctx.pass == 2)
486    {
487 <    RSA_free(ConfigServerInfo.rsa_private_key);
488 <    ConfigServerInfo.rsa_private_key = NULL;
569 <
570 <    conf_error_report("Ignoring serverinfo::rsa_private_key_file -- need at least a 1024 bit key size");
487 >    xfree(ConfigServerInfo.tls_dh_param_file);
488 >    ConfigServerInfo.tls_dh_param_file = xstrdup(yylval.string);
489    }
572 #endif
490   };
491  
492 < serverinfo_ssl_dh_param_file: SSL_DH_PARAM_FILE '=' QSTRING ';'
492 > serverinfo_tls_cipher_list: TLS_CIPHER_LIST '=' QSTRING ';'
493   {
577 #ifdef HAVE_LIBCRYPTO
494    if (conf_parser_ctx.pass == 2)
495    {
496 <    BIO *file = BIO_new_file(yylval.string, "r");
497 <
582 <    if (file)
583 <    {
584 <      DH *dh = PEM_read_bio_DHparams(file, NULL, NULL, NULL);
585 <
586 <      BIO_free(file);
587 <
588 <      if (dh)
589 <      {
590 <        if (DH_size(dh) < 128)
591 <          conf_error_report("Ignoring serverinfo::ssl_dh_param_file -- need at least a 1024 bit DH prime size");
592 <        else
593 <          SSL_CTX_set_tmp_dh(ConfigServerInfo.server_ctx, dh);
594 <
595 <        DH_free(dh);
596 <      }
597 <    }
598 <    else
599 <      conf_error_report("Ignoring serverinfo::ssl_dh_param_file -- could not open/read Diffie-Hellman parameter file");
496 >    xfree(ConfigServerInfo.tls_cipher_list);
497 >    ConfigServerInfo.tls_cipher_list = xstrdup(yylval.string);
498    }
601 #endif
499   };
500  
501 < serverinfo_ssl_cipher_list: T_SSL_CIPHER_LIST '=' QSTRING ';'
501 > serverinfo_tls_cipher_suites: TLS_CIPHER_SUITES '=' QSTRING ';'
502   {
606 #ifdef HAVE_LIBCRYPTO
503    if (conf_parser_ctx.pass == 2)
504 <    SSL_CTX_set_cipher_list(ConfigServerInfo.server_ctx, yylval.string);
505 < #endif
504 >  {
505 >    xfree(ConfigServerInfo.tls_cipher_suites);
506 >    ConfigServerInfo.tls_cipher_suites = xstrdup(yylval.string);
507 >  }
508   };
509  
510 < serverinfo_ssl_message_digest_algorithm: SSL_MESSAGE_DIGEST_ALGORITHM '=' QSTRING ';'
510 > serverinfo_tls_message_digest_algorithm: TLS_MESSAGE_DIGEST_ALGORITHM '=' QSTRING ';'
511   {
614 #ifdef HAVE_LIBCRYPTO
512    if (conf_parser_ctx.pass == 2)
513    {
514 <    if ((ConfigServerInfo.message_digest_algorithm = EVP_get_digestbyname(yylval.string)) == NULL)
515 <    {
619 <      ConfigServerInfo.message_digest_algorithm = EVP_sha256();
620 <      conf_error_report("Ignoring serverinfo::ssl_message_digest_algorithm -- unknown message digest algorithm");
621 <    }
514 >    xfree(ConfigServerInfo.tls_message_digest_algorithm);
515 >    ConfigServerInfo.tls_message_digest_algorithm = xstrdup(yylval.string);
516    }
623 #endif
517   }
518  
519 < serverinfo_ssl_dh_elliptic_curve: SSL_DH_ELLIPTIC_CURVE '=' QSTRING ';'
519 > serverinfo_tls_supported_groups: TLS_SUPPORTED_GROUPS '=' QSTRING ';'
520   {
628 #ifdef HAVE_LIBCRYPTO
629 #if OPENSSL_VERSION_NUMBER >= 0x009080FFL && !defined(OPENSSL_NO_ECDH)
630  int nid = 0;
631  EC_KEY *key = NULL;
632
521    if (conf_parser_ctx.pass == 2)
522    {
523 <    if ((nid = OBJ_sn2nid(yylval.string)) == 0)
524 <    {
525 <        conf_error_report("Ignoring serverinfo::ssl_dh_elliptic_curve -- unknown curve name");
638 <        break;
639 <    }
640 <
641 <    if ((key = EC_KEY_new_by_curve_name(nid)) == NULL)
642 <    {
643 <      conf_error_report("Ignoring serverinfo::ssl_dh_elliptic_curve -- could not create curve");
644 <      break;
645 <    }
646 <
647 <    SSL_CTX_set_tmp_ecdh(ConfigServerInfo.server_ctx, key);
648 <    EC_KEY_free(key);
649 < }
650 < #endif
651 < #endif
523 >    xfree(ConfigServerInfo.tls_supported_groups);
524 >    ConfigServerInfo.tls_supported_groups = xstrdup(yylval.string);
525 >  }
526   };
527  
528   serverinfo_name: NAME '=' QSTRING ';'
529   {
530 <  /* this isn't rehashable */
531 <  if (conf_parser_ctx.pass == 2 && !ConfigServerInfo.name)
530 >  /* This isn't rehashable */
531 >  if (conf_parser_ctx.pass == 2 && ConfigServerInfo.name == NULL)
532    {
533 <    if (valid_servname(yylval.string))
533 >    if (server_valid_name(yylval.string) == true)
534        ConfigServerInfo.name = xstrdup(yylval.string);
535      else
536      {
537        conf_error_report("Ignoring serverinfo::name -- invalid name. Aborting.");
538 <      exit(0);
538 >      exit(EXIT_FAILURE);
539      }
540    }
541   };
542  
543   serverinfo_sid: IRCD_SID '=' QSTRING ';'
544   {
545 <  /* this isn't rehashable */
546 <  if (conf_parser_ctx.pass == 2 && !ConfigServerInfo.sid)
545 >  /* This isn't rehashable */
546 >  if (conf_parser_ctx.pass == 2 && ConfigServerInfo.sid == NULL)
547    {
548      if (valid_sid(yylval.string))
549        ConfigServerInfo.sid = xstrdup(yylval.string);
550      else
551      {
552        conf_error_report("Ignoring serverinfo::sid -- invalid SID. Aborting.");
553 <      exit(0);
553 >      exit(EXIT_FAILURE);
554      }
555    }
556   };
# Line 685 | Line 559 | serverinfo_description: DESCRIPTION '='
559   {
560    if (conf_parser_ctx.pass == 2)
561    {
562 <    MyFree(ConfigServerInfo.description);
562 >    xfree(ConfigServerInfo.description);
563      ConfigServerInfo.description = xstrdup(yylval.string);
564      strlcpy(me.info, ConfigServerInfo.description, sizeof(me.info));
565    }
# Line 695 | Line 569 | serverinfo_network_name: NETWORK_NAME '=
569   {
570    if (conf_parser_ctx.pass == 2)
571    {
572 <    char *p;
572 >    char *p = strchr(yylval.string, ' ');
573  
574 <    if ((p = strchr(yylval.string, ' ')))
574 >    if (p)
575        *p = '\0';
576  
577 <    MyFree(ConfigServerInfo.network_name);
577 >    xfree(ConfigServerInfo.network_name);
578      ConfigServerInfo.network_name = xstrdup(yylval.string);
579    }
580   };
# Line 710 | Line 584 | serverinfo_network_desc: NETWORK_DESC '=
584    if (conf_parser_ctx.pass != 2)
585      break;
586  
587 <  MyFree(ConfigServerInfo.network_desc);
587 >  xfree(ConfigServerInfo.network_desc);
588    ConfigServerInfo.network_desc = xstrdup(yylval.string);
589   };
590  
717 serverinfo_vhost: VHOST '=' QSTRING ';'
718 {
719  if (conf_parser_ctx.pass == 2 && *yylval.string != '*')
720  {
721    struct addrinfo hints, *res;
722
723    memset(&hints, 0, sizeof(hints));
724
725    hints.ai_family   = AF_UNSPEC;
726    hints.ai_socktype = SOCK_STREAM;
727    hints.ai_flags    = AI_PASSIVE | AI_NUMERICHOST;
728
729    if (getaddrinfo(yylval.string, NULL, &hints, &res))
730      ilog(LOG_TYPE_IRCD, "Invalid netmask for server vhost(%s)", yylval.string);
731    else
732    {
733      assert(res);
734
735      memcpy(&ConfigServerInfo.ip, res->ai_addr, res->ai_addrlen);
736      ConfigServerInfo.ip.ss.ss_family = res->ai_family;
737      ConfigServerInfo.ip.ss_len = res->ai_addrlen;
738      freeaddrinfo(res);
739
740      ConfigServerInfo.specific_ipv4_vhost = 1;
741    }
742  }
743 };
744
745 serverinfo_vhost6: VHOST6 '=' QSTRING ';'
746 {
747  if (conf_parser_ctx.pass == 2 && *yylval.string != '*')
748  {
749    struct addrinfo hints, *res;
750
751    memset(&hints, 0, sizeof(hints));
752
753    hints.ai_family   = AF_UNSPEC;
754    hints.ai_socktype = SOCK_STREAM;
755    hints.ai_flags    = AI_PASSIVE | AI_NUMERICHOST;
756
757    if (getaddrinfo(yylval.string, NULL, &hints, &res))
758      ilog(LOG_TYPE_IRCD, "Invalid netmask for server vhost6(%s)", yylval.string);
759    else
760    {
761      assert(res);
762
763      memcpy(&ConfigServerInfo.ip6, res->ai_addr, res->ai_addrlen);
764      ConfigServerInfo.ip6.ss.ss_family = res->ai_family;
765      ConfigServerInfo.ip6.ss_len = res->ai_addrlen;
766      freeaddrinfo(res);
767
768      ConfigServerInfo.specific_ipv6_vhost = 1;
769    }
770  }
771 };
772
591   serverinfo_default_max_clients: DEFAULT_MAX_CLIENTS '=' NUMBER ';'
592   {
593    if (conf_parser_ctx.pass != 2)
594      break;
595  
596 <  if ($3 < MAXCLIENTS_MIN)
596 >  if ($3 < 1)
597    {
598 <    char buf[IRCD_BUFSIZE] = "";
599 <
782 <    snprintf(buf, sizeof(buf), "MAXCLIENTS too low, setting to %d", MAXCLIENTS_MIN);
783 <    conf_error_report(buf);
784 <    ConfigServerInfo.default_max_clients = MAXCLIENTS_MIN;
598 >    conf_error_report("default_max_clients too low, setting to 1");
599 >    ConfigServerInfo.default_max_clients = 1;
600    }
601    else if ($3 > MAXCLIENTS_MAX)
602    {
603 <    char buf[IRCD_BUFSIZE] = "";
603 >    char buf[IRCD_BUFSIZE];
604  
605 <    snprintf(buf, sizeof(buf), "MAXCLIENTS too high, setting to %d", MAXCLIENTS_MAX);
605 >    snprintf(buf, sizeof(buf), "default_max_clients too high, setting to %d", MAXCLIENTS_MAX);
606      conf_error_report(buf);
607 +
608      ConfigServerInfo.default_max_clients = MAXCLIENTS_MAX;
609    }
610    else
# Line 807 | Line 623 | serverinfo_max_nick_length: MAX_NICK_LEN
623    }
624    else if ($3 > NICKLEN)
625    {
626 <    char buf[IRCD_BUFSIZE] = "";
626 >    char buf[IRCD_BUFSIZE];
627  
628      snprintf(buf, sizeof(buf), "max_nick_length too high, setting to %d", NICKLEN);
629      conf_error_report(buf);
630 +
631      ConfigServerInfo.max_nick_length = NICKLEN;
632    }
633    else
# Line 829 | Line 646 | serverinfo_max_topic_length: MAX_TOPIC_L
646    }
647    else if ($3 > TOPICLEN)
648    {
649 <    char buf[IRCD_BUFSIZE] = "";
649 >    char buf[IRCD_BUFSIZE];
650  
651      snprintf(buf, sizeof(buf), "max_topic_length too high, setting to %d", TOPICLEN);
652      conf_error_report(buf);
653 +
654      ConfigServerInfo.max_topic_length = TOPICLEN;
655    }
656    else
# Line 845 | Line 663 | serverinfo_hub: HUB '=' TBOOL ';'
663      ConfigServerInfo.hub = yylval.number;
664   };
665  
666 +
667   /***************************************************************************
668 < * admin section
668 > * admin {} section
669   ***************************************************************************/
670 < admin_entry: ADMIN  '{' admin_items '}' ';' ;
670 > admin_entry: ADMIN '{' admin_items '}' ';' ;
671  
672   admin_items: admin_items admin_item | admin_item;
673   admin_item:  admin_name |
# Line 861 | Line 680 | admin_name: NAME '=' QSTRING ';'
680    if (conf_parser_ctx.pass != 2)
681      break;
682  
683 <  MyFree(ConfigAdminInfo.name);
683 >  xfree(ConfigAdminInfo.name);
684    ConfigAdminInfo.name = xstrdup(yylval.string);
685   };
686  
# Line 870 | Line 689 | admin_email: EMAIL '=' QSTRING ';'
689    if (conf_parser_ctx.pass != 2)
690      break;
691  
692 <  MyFree(ConfigAdminInfo.email);
692 >  xfree(ConfigAdminInfo.email);
693    ConfigAdminInfo.email = xstrdup(yylval.string);
694   };
695  
# Line 879 | Line 698 | admin_description: DESCRIPTION '=' QSTRI
698    if (conf_parser_ctx.pass != 2)
699      break;
700  
701 <  MyFree(ConfigAdminInfo.description);
701 >  xfree(ConfigAdminInfo.description);
702    ConfigAdminInfo.description = xstrdup(yylval.string);
703   };
704  
705 +
706   /***************************************************************************
707 < * motd section
707 > * motd {} section
708   ***************************************************************************/
709   motd_entry: MOTD
710   {
# Line 892 | Line 712 | motd_entry: MOTD
712      reset_block_state();
713   } '{' motd_items '}' ';'
714   {
715 <  dlink_node *node = NULL;
715 >  dlink_node *node;
716  
717    if (conf_parser_ctx.pass != 2)
718      break;
# Line 919 | Line 739 | motd_file: T_FILE '=' QSTRING ';'
739      strlcpy(block_state.file.buf, yylval.string, sizeof(block_state.file.buf));
740   };
741  
742 +
743   /***************************************************************************
744 < * pseudo section
744 > * pseudo {} section
745   ***************************************************************************/
746   pseudo_entry: T_PSEUDO
747   {
# Line 980 | Line 801 | pseudo_target: T_TARGET '=' QSTRING ';'
801    }
802   };
803  
804 +
805   /***************************************************************************
806 < *  section logging
806 > * log {} section
807   ***************************************************************************/
808 < logging_entry:          T_LOG  '{' logging_items '}' ';' ;
808 > logging_entry:          T_LOG '{' logging_items '}' ';' ;
809   logging_items:          logging_items logging_item | logging_item ;
810  
811   logging_item:           logging_use_logging | logging_file_entry |
# Line 1035 | Line 857 | logging_file_type: TYPE
857   {
858    if (conf_parser_ctx.pass == 2)
859      block_state.type.value = 0;
860 < } '='  logging_file_type_items ';' ;
860 > } '=' logging_file_type_items ';' ;
861  
862   logging_file_type_items: logging_file_type_items ',' logging_file_type_item | logging_file_type_item;
863   logging_file_type_item:  USER
# Line 1074 | Line 896 | logging_file_type_item:  USER
896  
897  
898   /***************************************************************************
899 < * section oper
899 > * operator {} section
900   ***************************************************************************/
901   oper_entry: OPERATOR
902   {
# Line 1085 | Line 907 | oper_entry: OPERATOR
907    block_state.flags.value |= CONF_FLAGS_ENCRYPTED;
908   } '{' oper_items '}' ';'
909   {
910 <  dlink_node *node = NULL;
910 >  dlink_node *node;
911  
912    if (conf_parser_ctx.pass != 2)
913      break;
914  
915    if (!block_state.name.buf[0])
916      break;
917 < #ifdef HAVE_LIBCRYPTO
1096 <  if (!block_state.file.buf[0] &&
1097 <      !block_state.rpass.buf[0])
1098 <    break;
1099 < #else
917 >
918    if (!block_state.rpass.buf[0])
919      break;
1102 #endif
920  
921    DLINK_FOREACH(node, block_state.mask.list.head)
922    {
1106    struct MaskItem *conf = NULL;
923      struct split_nuh_item nuh;
924 +    char *s = node->data;
925  
926 <    nuh.nuhmask  = node->data;
926 >    if (EmptyString(s))
927 >      continue;
928 >
929 >    nuh.nuhmask  = s;
930      nuh.nickptr  = NULL;
931      nuh.userptr  = block_state.user.buf;
932      nuh.hostptr  = block_state.host.buf;
933 +
934      nuh.nicksize = 0;
935      nuh.usersize = sizeof(block_state.user.buf);
936      nuh.hostsize = sizeof(block_state.host.buf);
937 +
938      split_nuh(&nuh);
939  
940 <    conf         = conf_make(CONF_OPER);
941 <    conf->name   = xstrdup(block_state.name.buf);
942 <    conf->user   = xstrdup(block_state.user.buf);
943 <    conf->host   = xstrdup(block_state.host.buf);
940 >    struct MaskItem *conf = conf_make(CONF_OPER);
941 >    conf->addr = xcalloc(sizeof(*conf->addr));
942 >    conf->name = xstrdup(block_state.name.buf);
943 >    conf->user = xstrdup(block_state.user.buf);
944 >    conf->host = xstrdup(block_state.host.buf);
945  
946      if (block_state.cert.buf[0])
947        conf->certfp = xstrdup(block_state.cert.buf);
# Line 1132 | Line 955 | oper_entry: OPERATOR
955      conf->flags = block_state.flags.value;
956      conf->modes = block_state.modes.value;
957      conf->port  = block_state.port.value;
958 <    conf->htype = parse_netmask(conf->host, &conf->addr, &conf->bits);
958 >    conf->htype = parse_netmask(conf->host, conf->addr, &conf->bits);
959  
960      conf_add_class_to_conf(conf, block_state.class.buf);
1138
1139 #ifdef HAVE_LIBCRYPTO
1140    if (block_state.file.buf[0])
1141    {
1142      BIO *file = NULL;
1143      RSA *pkey = NULL;
1144
1145      if ((file = BIO_new_file(block_state.file.buf, "r")) == NULL)
1146      {
1147        ilog(LOG_TYPE_IRCD, "Ignoring rsa_public_key_file -- file doesn't exist");
1148        break;
1149      }
1150
1151      if ((pkey = PEM_read_bio_RSA_PUBKEY(file, NULL, 0, NULL)) == NULL)
1152        ilog(LOG_TYPE_IRCD, "Ignoring rsa_public_key_file -- key invalid; check key syntax");
1153      else
1154      {
1155        if (RSA_size(pkey) > 128)
1156          ilog(LOG_TYPE_IRCD, "Ignoring rsa_public_key_file -- key size must be 1024 or below");
1157        else
1158          conf->rsa_public_key = pkey;
1159      }
1160
1161      BIO_set_close(file, BIO_CLOSE);
1162      BIO_free(file);
1163    }
1164 #endif /* HAVE_LIBCRYPTO */
961    }
962   };
963  
# Line 1173 | Line 969 | oper_item:      oper_name |
969                  oper_umodes |
970                  oper_class |
971                  oper_encrypted |
972 <                oper_rsa_public_key_file |
973 <                oper_ssl_certificate_fingerprint |
1178 <                oper_ssl_connection_required |
972 >                oper_tls_certificate_fingerprint |
973 >                oper_tls_connection_required |
974                  oper_flags |
975                  error ';' ;
976  
# Line 1214 | Line 1009 | oper_encrypted: ENCRYPTED '=' TBOOL ';'
1009      block_state.flags.value &= ~CONF_FLAGS_ENCRYPTED;
1010   };
1011  
1012 < oper_rsa_public_key_file: RSA_PUBLIC_KEY_FILE '=' QSTRING ';'
1218 < {
1219 <  if (conf_parser_ctx.pass == 2)
1220 <    strlcpy(block_state.file.buf, yylval.string, sizeof(block_state.file.buf));
1221 < };
1222 <
1223 < oper_ssl_certificate_fingerprint: SSL_CERTIFICATE_FINGERPRINT '=' QSTRING ';'
1012 > oper_tls_certificate_fingerprint: TLS_CERTIFICATE_FINGERPRINT '=' QSTRING ';'
1013   {
1014    if (conf_parser_ctx.pass == 2)
1015      strlcpy(block_state.cert.buf, yylval.string, sizeof(block_state.cert.buf));
1016   };
1017  
1018 < oper_ssl_connection_required: SSL_CONNECTION_REQUIRED '=' TBOOL ';'
1018 > oper_tls_connection_required: TLS_CONNECTION_REQUIRED '=' TBOOL ';'
1019   {
1020    if (conf_parser_ctx.pass != 2)
1021      break;
1022  
1023    if (yylval.number)
1024 <    block_state.flags.value |= CONF_FLAGS_SSL;
1024 >    block_state.flags.value |= CONF_FLAGS_TLS;
1025    else
1026 <    block_state.flags.value &= ~CONF_FLAGS_SSL;
1026 >    block_state.flags.value &= ~CONF_FLAGS_TLS;
1027   };
1028  
1029   oper_class: CLASS '=' QSTRING ';'
# Line 1247 | Line 1036 | oper_umodes: T_UMODES
1036   {
1037    if (conf_parser_ctx.pass == 2)
1038      block_state.modes.value = 0;
1039 < } '='  oper_umodes_items ';' ;
1039 > } '=' oper_umodes_items ';' ;
1040  
1041   oper_umodes_items: oper_umodes_items ',' oper_umodes_item | oper_umodes_item;
1042   oper_umodes_item:  T_BOTS
# Line 1338 | Line 1127 | oper_umodes_item:  T_BOTS
1127   {
1128    if (conf_parser_ctx.pass == 2)
1129      block_state.modes.value |= UMODE_FARCONNECT;
1130 + } | EXPIRATION
1131 + {
1132 +  if (conf_parser_ctx.pass == 2)
1133 +    block_state.modes.value |= UMODE_EXPIRATION;
1134   };
1135  
1136   oper_flags: IRCD_FLAGS
1137   {
1138    if (conf_parser_ctx.pass == 2)
1139      block_state.port.value = 0;
1140 < } '='  oper_flags_items ';';
1140 > } '=' oper_flags_items ';';
1141  
1142   oper_flags_items: oper_flags_items ',' oper_flags_item | oper_flags_item;
1143   oper_flags_item: KILL ':' REMOTE
# Line 1403 | Line 1196 | oper_flags_item: KILL ':' REMOTE
1196   {
1197    if (conf_parser_ctx.pass == 2)
1198      block_state.port.value |= OPER_FLAG_RESTART;
1199 + } | REHASH ':' REMOTE
1200 + {
1201 +  if (conf_parser_ctx.pass == 2)
1202 +    block_state.port.value |= OPER_FLAG_REHASH_REMOTE;
1203   } | REHASH
1204   {
1205    if (conf_parser_ctx.pass == 2)
# Line 1463 | Line 1260 | oper_flags_item: KILL ':' REMOTE
1260  
1261  
1262   /***************************************************************************
1263 < *  section class
1263 > * class {} section
1264   ***************************************************************************/
1265   class_entry: CLASS
1266   {
# Line 1479 | Line 1276 | class_entry: CLASS
1276    block_state.max_recvq.value = DEFAULT_RECVQ;
1277   } '{' class_items '}' ';'
1278   {
1482  struct ClassItem *class = NULL;
1483
1279    if (conf_parser_ctx.pass != 1)
1280      break;
1281  
1282    if (!block_state.class.buf[0])
1283      break;
1284  
1285 <  if (!(class = class_find(block_state.class.buf, 0)))
1285 >  struct ClassItem *class = class_find(block_state.class.buf, false);
1286 >  if (class == NULL)
1287      class = class_make();
1288  
1289 <  class->active = 1;
1290 <  MyFree(class->name);
1289 >  class->active = true;
1290 >  xfree(class->name);
1291    class->name = xstrdup(block_state.class.buf);
1292    class->ping_freq = block_state.ping_freq.value;
1293 <  class->max_perip = block_state.max_perip.value;
1293 >  class->max_perip_local = block_state.max_perip_local.value;
1294 >  class->max_perip_global = block_state.max_perip_global.value;
1295    class->con_freq = block_state.con_freq.value;
1296    class->max_total = block_state.max_total.value;
1500  class->max_global = block_state.max_global.value;
1501  class->max_local = block_state.max_local.value;
1502  class->max_ident = block_state.max_ident.value;
1297    class->max_sendq = block_state.max_sendq.value;
1298    class->max_recvq = block_state.max_recvq.value;
1299    class->max_channels = block_state.max_channels.value;
# Line 1515 | Line 1309 | class_entry: CLASS
1309    class->min_idle = block_state.min_idle.value;
1310    class->max_idle = block_state.max_idle.value;
1311  
1312 <  rebuild_cidr_list(class);
1313 <
1312 >  bool diff = (class->cidr_bitlen_ipv4 != block_state.cidr_bitlen_ipv4.value ||
1313 >               class->cidr_bitlen_ipv6 != block_state.cidr_bitlen_ipv6.value);
1314    class->cidr_bitlen_ipv4 = block_state.cidr_bitlen_ipv4.value;
1315    class->cidr_bitlen_ipv6 = block_state.cidr_bitlen_ipv6.value;
1316    class->number_per_cidr = block_state.number_per_cidr.value;
1317 +
1318 +  if (diff)
1319 +    class_ip_limit_rebuild(class);
1320   };
1321  
1322   class_items:    class_items class_item | class_item;
# Line 1528 | Line 1325 | class_item:     class_name |
1325                  class_cidr_bitlen_ipv6 |
1326                  class_ping_time |
1327                  class_number_per_cidr |
1328 <                class_number_per_ip |
1328 >                class_number_per_ip_local |
1329 >                class_number_per_ip_global |
1330                  class_connectfreq |
1331                  class_max_channels |
1332                  class_max_number |
1333 <                class_max_global |
1334 <                class_max_local |
1537 <                class_max_ident |
1538 <                class_sendq | class_recvq |
1333 >                class_sendq |
1334 >                class_recvq |
1335                  class_min_idle |
1336                  class_max_idle |
1337                  class_flags |
# Line 1553 | Line 1349 | class_ping_time: PING_TIME '=' timespec
1349      block_state.ping_freq.value = $3;
1350   };
1351  
1352 < class_number_per_ip: NUMBER_PER_IP '=' NUMBER ';'
1352 > class_number_per_ip_local: NUMBER_PER_IP_LOCAL '=' NUMBER ';'
1353   {
1354    if (conf_parser_ctx.pass == 1)
1355 <    block_state.max_perip.value = $3;
1355 >    block_state.max_perip_local.value = $3;
1356 > };
1357 >
1358 > class_number_per_ip_global: NUMBER_PER_IP_GLOBAL '=' NUMBER ';'
1359 > {
1360 >  if (conf_parser_ctx.pass == 1)
1361 >    block_state.max_perip_global.value = $3;
1362   };
1363  
1364   class_connectfreq: CONNECTFREQ '=' timespec ';'
# Line 1577 | Line 1379 | class_max_number: MAX_NUMBER '=' NUMBER
1379      block_state.max_total.value = $3;
1380   };
1381  
1580 class_max_global: MAX_GLOBAL '=' NUMBER ';'
1581 {
1582  if (conf_parser_ctx.pass == 1)
1583    block_state.max_global.value = $3;
1584 };
1585
1586 class_max_local: MAX_LOCAL '=' NUMBER ';'
1587 {
1588  if (conf_parser_ctx.pass == 1)
1589    block_state.max_local.value = $3;
1590 };
1591
1592 class_max_ident: MAX_IDENT '=' NUMBER ';'
1593 {
1594  if (conf_parser_ctx.pass == 1)
1595    block_state.max_ident.value = $3;
1596 };
1597
1382   class_sendq: SENDQ '=' sizespec ';'
1383   {
1384    if (conf_parser_ctx.pass == 1)
# Line 1648 | Line 1432 | class_flags: IRCD_FLAGS
1432   {
1433    if (conf_parser_ctx.pass == 1)
1434      block_state.flags.value &= CLASS_FLAGS_FAKE_IDLE;
1435 < } '='  class_flags_items ';';
1435 > } '=' class_flags_items ';';
1436  
1437   class_flags_items: class_flags_items ',' class_flags_item | class_flags_item;
1438   class_flags_item: RANDOM_IDLE
# Line 1663 | Line 1447 | class_flags_item: RANDOM_IDLE
1447  
1448  
1449   /***************************************************************************
1450 < *  section listen
1450 > * listen {} section
1451   ***************************************************************************/
1452   listen_entry: LISTEN
1453   {
# Line 1674 | Line 1458 | listen_entry: LISTEN
1458   listen_flags: IRCD_FLAGS
1459   {
1460    block_state.flags.value = 0;
1461 < } '='  listen_flags_items ';';
1461 > } '=' listen_flags_items ';';
1462  
1463   listen_flags_items: listen_flags_items ',' listen_flags_item | listen_flags_item;
1464 < listen_flags_item: T_SSL
1464 > listen_flags_item: T_TLS
1465   {
1466    if (conf_parser_ctx.pass == 2)
1467 <    block_state.flags.value |= LISTENER_SSL;
1467 >    block_state.flags.value |= LISTENER_TLS;
1468   } | HIDDEN
1469   {
1470    if (conf_parser_ctx.pass == 2)
# Line 1702 | Line 1486 | port_item: NUMBER
1486   {
1487    if (conf_parser_ctx.pass == 2)
1488    {
1489 < #ifndef HAVE_LIBCRYPTO
1490 <    if (block_state.flags.value & LISTENER_SSL)
1489 > #ifndef HAVE_TLS
1490 >    if (block_state.flags.value & LISTENER_TLS)
1491      {
1492 <      conf_error_report("SSL not available - port closed");
1492 >      conf_error_report("TLS not available - port closed");
1493        break;
1494      }
1495   #endif
# Line 1715 | Line 1499 | port_item: NUMBER
1499   {
1500    if (conf_parser_ctx.pass == 2)
1501    {
1502 < #ifndef HAVE_LIBCRYPTO
1503 <    if (block_state.flags.value & LISTENER_SSL)
1502 > #ifndef HAVE_TLS
1503 >    if (block_state.flags.value & LISTENER_TLS)
1504      {
1505 <      conf_error_report("SSL not available - port closed");
1505 >      conf_error_report("TLS not available - port closed");
1506        break;
1507      }
1508   #endif
# Line 1740 | Line 1524 | listen_host: HOST '=' QSTRING ';'
1524      strlcpy(block_state.addr.buf, yylval.string, sizeof(block_state.addr.buf));
1525   };
1526  
1527 +
1528   /***************************************************************************
1529 < *  section auth
1529 > * auth {} section
1530   ***************************************************************************/
1531   auth_entry: IRCD_AUTH
1532   {
# Line 1749 | Line 1534 | auth_entry: IRCD_AUTH
1534      reset_block_state();
1535   } '{' auth_items '}' ';'
1536   {
1537 <  dlink_node *node = NULL;
1537 >  dlink_node *node;
1538  
1539    if (conf_parser_ctx.pass != 2)
1540      break;
1541  
1542    DLINK_FOREACH(node, block_state.mask.list.head)
1543    {
1759    struct MaskItem *conf = NULL;
1544      struct split_nuh_item nuh;
1545 +    char *s = node->data;
1546 +
1547 +    if (EmptyString(s))
1548 +      continue;
1549  
1550 <    nuh.nuhmask  = node->data;
1550 >    nuh.nuhmask  = s;
1551      nuh.nickptr  = NULL;
1552      nuh.userptr  = block_state.user.buf;
1553      nuh.hostptr  = block_state.host.buf;
1554 +
1555      nuh.nicksize = 0;
1556      nuh.usersize = sizeof(block_state.user.buf);
1557      nuh.hostsize = sizeof(block_state.host.buf);
1558 +
1559      split_nuh(&nuh);
1560  
1561 <    conf        = conf_make(CONF_CLIENT);
1562 <    conf->user  = xstrdup(block_state.user.buf);
1563 <    conf->host  = xstrdup(block_state.host.buf);
1561 >    struct MaskItem *conf = conf_make(CONF_CLIENT);
1562 >    conf->user = xstrdup(block_state.user.buf);
1563 >    conf->host = xstrdup(block_state.host.buf);
1564  
1565      if (block_state.rpass.buf[0])
1566        conf->passwd = xstrdup(block_state.rpass.buf);
# Line 1778 | Line 1568 | auth_entry: IRCD_AUTH
1568        conf->name = xstrdup(block_state.name.buf);
1569  
1570      conf->flags = block_state.flags.value;
1571 <    conf->port  = block_state.port.value;
1571 >    conf->port = block_state.port.value;
1572  
1573      conf_add_class_to_conf(conf, block_state.class.buf);
1574      add_conf_by_address(CONF_CLIENT, conf);
# Line 1829 | Line 1619 | auth_flags: IRCD_FLAGS
1619   {
1620    if (conf_parser_ctx.pass == 2)
1621      block_state.flags.value &= (CONF_FLAGS_ENCRYPTED | CONF_FLAGS_SPOOF_IP);
1622 < } '='  auth_flags_items ';';
1622 > } '=' auth_flags_items ';';
1623  
1624   auth_flags_items: auth_flags_items ',' auth_flags_item | auth_flags_item;
1625   auth_flags_item: SPOOF_NOTICE
# Line 1908 | Line 1698 | auth_redir_port: REDIRPORT '=' NUMBER ';
1698  
1699  
1700   /***************************************************************************
1701 < *  section resv
1701 > * resv {} section
1702   ***************************************************************************/
1703   resv_entry: RESV
1704   {
# Line 1922 | Line 1712 | resv_entry: RESV
1712    if (conf_parser_ctx.pass != 2)
1713      break;
1714  
1715 <  create_resv(block_state.name.buf, block_state.rpass.buf, &block_state.mask.list);
1715 >  resv_make(block_state.name.buf, block_state.rpass.buf, &block_state.mask.list);
1716   };
1717  
1718   resv_items:     resv_items resv_item | resv_item;
# Line 1948 | Line 1738 | resv_exempt: EXEMPT '=' QSTRING ';'
1738  
1739  
1740   /***************************************************************************
1741 < *  section service
1741 > * service {} section
1742   ***************************************************************************/
1743   service_entry: T_SERVICE '{' service_items '}' ';';
1744  
# Line 1960 | Line 1750 | service_name: NAME '=' QSTRING ';'
1750    if (conf_parser_ctx.pass != 2)
1751      break;
1752  
1753 <  if (valid_servname(yylval.string))
1753 >  if (server_valid_name(yylval.string) == true)
1754    {
1755 <    struct MaskItem *conf = conf_make(CONF_SERVICE);
1756 <    conf->name = xstrdup(yylval.string);
1755 >    struct ServiceItem *service = service_make();
1756 >    service->name = xstrdup(yylval.string);
1757    }
1758   };
1759  
1760 +
1761   /***************************************************************************
1762 < *  section shared, for sharing remote klines etc.
1762 > * shared {} section, for sharing remote klines etc.
1763   ***************************************************************************/
1764   shared_entry: T_SHARED
1765   {
# Line 1983 | Line 1774 | shared_entry: T_SHARED
1774    block_state.flags.value = SHARED_ALL;
1775   } '{' shared_items '}' ';'
1776   {
1986  struct MaskItem *conf = NULL;
1987
1777    if (conf_parser_ctx.pass != 2)
1778      break;
1779  
1780 <  conf = conf_make(CONF_ULINE);
1781 <  conf->flags = block_state.flags.value;
1782 <  conf->name = xstrdup(block_state.name.buf);
1783 <  conf->user = xstrdup(block_state.user.buf);
1784 <  conf->host = xstrdup(block_state.host.buf);
1780 >  struct SharedItem *shared = shared_make();
1781 >  shared->type = block_state.flags.value;
1782 >  shared->server = xstrdup(block_state.name.buf);
1783 >  shared->user = xstrdup(block_state.user.buf);
1784 >  shared->host = xstrdup(block_state.host.buf);
1785   };
1786  
1787   shared_items: shared_items shared_item | shared_item;
# Line 2072 | Line 1861 | shared_type_item: KLINE
1861      block_state.flags.value = SHARED_ALL;
1862   };
1863  
1864 +
1865   /***************************************************************************
1866 < *  section cluster
1866 > * cluster {} section
1867   ***************************************************************************/
1868   cluster_entry: T_CLUSTER
1869   {
# Line 2083 | Line 1873 | cluster_entry: T_CLUSTER
1873    reset_block_state();
1874  
1875    strlcpy(block_state.name.buf, "*", sizeof(block_state.name.buf));
1876 <  block_state.flags.value = SHARED_ALL;
1876 >  block_state.flags.value = CLUSTER_ALL;
1877   } '{' cluster_items '}' ';'
1878   {
2089  struct MaskItem *conf = NULL;
2090
1879    if (conf_parser_ctx.pass != 2)
1880      break;
1881  
1882 <  conf = conf_make(CONF_CLUSTER);
1883 <  conf->flags = block_state.flags.value;
1884 <  conf->name = xstrdup(block_state.name.buf);
1882 >  struct ClusterItem *cluster = cluster_make();
1883 >  cluster->type = block_state.flags.value;
1884 >  cluster->server = xstrdup(block_state.name.buf);
1885   };
1886  
1887   cluster_items:  cluster_items cluster_item | cluster_item;
# Line 2115 | Line 1903 | cluster_types:  cluster_types ',' cluste
1903   cluster_type_item: KLINE
1904   {
1905    if (conf_parser_ctx.pass == 2)
1906 <    block_state.flags.value |= SHARED_KLINE;
1906 >    block_state.flags.value |= CLUSTER_KLINE;
1907   } | UNKLINE
1908   {
1909    if (conf_parser_ctx.pass == 2)
1910 <    block_state.flags.value |= SHARED_UNKLINE;
1910 >    block_state.flags.value |= CLUSTER_UNKLINE;
1911   } | T_DLINE
1912   {
1913    if (conf_parser_ctx.pass == 2)
1914 <    block_state.flags.value |= SHARED_DLINE;
1914 >    block_state.flags.value |= CLUSTER_DLINE;
1915   } | T_UNDLINE
1916   {
1917    if (conf_parser_ctx.pass == 2)
1918 <    block_state.flags.value |= SHARED_UNDLINE;
1918 >    block_state.flags.value |= CLUSTER_UNDLINE;
1919   } | XLINE
1920   {
1921    if (conf_parser_ctx.pass == 2)
1922 <    block_state.flags.value |= SHARED_XLINE;
1922 >    block_state.flags.value |= CLUSTER_XLINE;
1923   } | T_UNXLINE
1924   {
1925    if (conf_parser_ctx.pass == 2)
1926 <    block_state.flags.value |= SHARED_UNXLINE;
1926 >    block_state.flags.value |= CLUSTER_UNXLINE;
1927   } | RESV
1928   {
1929    if (conf_parser_ctx.pass == 2)
1930 <    block_state.flags.value |= SHARED_RESV;
1930 >    block_state.flags.value |= CLUSTER_RESV;
1931   } | T_UNRESV
1932   {
1933    if (conf_parser_ctx.pass == 2)
1934 <    block_state.flags.value |= SHARED_UNRESV;
1934 >    block_state.flags.value |= CLUSTER_UNRESV;
1935   } | T_LOCOPS
1936   {
1937    if (conf_parser_ctx.pass == 2)
1938 <    block_state.flags.value |= SHARED_LOCOPS;
1938 >    block_state.flags.value |= CLUSTER_LOCOPS;
1939   } | T_ALL
1940   {
1941    if (conf_parser_ctx.pass == 2)
1942 <    block_state.flags.value = SHARED_ALL;
1942 >    block_state.flags.value = CLUSTER_ALL;
1943   };
1944  
1945 +
1946   /***************************************************************************
1947 < *  section connect
1947 > * connect {}  section
1948   ***************************************************************************/
1949   connect_entry: CONNECT
1950   {
# Line 2166 | Line 1955 | connect_entry: CONNECT
1955    reset_block_state();
1956    block_state.aftype.value = AF_INET;
1957    block_state.port.value = PORTNUM;
1958 +  block_state.timeout.value = CONNECTTIMEOUT;
1959   } '{' connect_items '}' ';'
1960   {
2171  struct MaskItem *conf = NULL;
1961    struct addrinfo hints, *res;
1962  
1963    if (conf_parser_ctx.pass != 2)
# Line 2182 | Line 1971 | connect_entry: CONNECT
1971        !block_state.spass.buf[0])
1972      break;
1973  
1974 +  if (server_valid_name(block_state.name.buf) == false)
1975 +    break;
1976 +
1977    if (has_wildcards(block_state.name.buf) ||
1978        has_wildcards(block_state.host.buf))
1979      break;
1980  
1981 <  conf = conf_make(CONF_SERVER);
1981 >  struct MaskItem *conf = conf_make(CONF_SERVER);
1982 >  conf->addr = xcalloc(sizeof(*conf->addr));
1983    conf->port = block_state.port.value;
1984 +  conf->timeout = block_state.timeout.value;
1985    conf->flags = block_state.flags.value;
1986    conf->aftype = block_state.aftype.value;
1987    conf->host = xstrdup(block_state.host.buf);
# Line 2213 | Line 2007 | connect_entry: CONNECT
2007      hints.ai_flags    = AI_PASSIVE | AI_NUMERICHOST;
2008  
2009      if (getaddrinfo(block_state.bind.buf, NULL, &hints, &res))
2010 <      ilog(LOG_TYPE_IRCD, "Invalid netmask for server vhost(%s)", block_state.bind.buf);
2010 >      ilog(LOG_TYPE_IRCD, "Invalid netmask for server bind(%s)", block_state.bind.buf);
2011      else
2012      {
2013        assert(res);
2014  
2015 <      memcpy(&conf->bind, res->ai_addr, res->ai_addrlen);
2016 <      conf->bind.ss.ss_family = res->ai_family;
2017 <      conf->bind.ss_len = res->ai_addrlen;
2015 >      conf->bind = xcalloc(sizeof(*conf->bind));
2016 >
2017 >      memcpy(conf->bind, res->ai_addr, res->ai_addrlen);
2018 >      conf->bind->ss_len = res->ai_addrlen;
2019        freeaddrinfo(res);
2020      }
2021    }
2022  
2023    conf_add_class_to_conf(conf, block_state.class.buf);
2024 <  lookup_confhost(conf);
2024 >  conf_dns_lookup(conf);
2025   };
2026  
2027   connect_items:  connect_items connect_item | connect_item;
2028   connect_item:   connect_name |
2029                  connect_host |
2030 <                connect_vhost |
2030 >                connect_timeout |
2031 >                connect_bind |
2032                  connect_send_password |
2033                  connect_accept_password |
2034 <                connect_ssl_certificate_fingerprint |
2034 >                connect_tls_certificate_fingerprint |
2035                  connect_aftype |
2036                  connect_port |
2037 <                connect_ssl_cipher_list |
2037 >                connect_tls_cipher_list |
2038                  connect_flags |
2039                  connect_hub_mask |
2040                  connect_leaf_mask |
# Line 2258 | Line 2054 | connect_host: HOST '=' QSTRING ';'
2054      strlcpy(block_state.host.buf, yylval.string, sizeof(block_state.host.buf));
2055   };
2056  
2057 < connect_vhost: VHOST '=' QSTRING ';'
2057 > connect_timeout: TIMEOUT '=' timespec ';'
2058 > {
2059 >  if (conf_parser_ctx.pass == 2)
2060 >    block_state.timeout.value = $3;
2061 > };
2062 >
2063 > connect_bind: T_BIND '=' QSTRING ';'
2064   {
2065    if (conf_parser_ctx.pass == 2)
2066      strlcpy(block_state.bind.buf, yylval.string, sizeof(block_state.bind.buf));
# Line 2269 | Line 2071 | connect_send_password: SEND_PASSWORD '='
2071    if (conf_parser_ctx.pass != 2)
2072      break;
2073  
2074 <  if ($3[0] == ':')
2074 >  if (*yylval.string == ':')
2075      conf_error_report("Server passwords cannot begin with a colon");
2076 <  else if (strchr($3, ' '))
2076 >  else if (strchr(yylval.string, ' '))
2077      conf_error_report("Server passwords cannot contain spaces");
2078    else
2079      strlcpy(block_state.spass.buf, yylval.string, sizeof(block_state.spass.buf));
# Line 2282 | Line 2084 | connect_accept_password: ACCEPT_PASSWORD
2084    if (conf_parser_ctx.pass != 2)
2085      break;
2086  
2087 <  if ($3[0] == ':')
2087 >  if (*yylval.string == ':')
2088      conf_error_report("Server passwords cannot begin with a colon");
2089 <  else if (strchr($3, ' '))
2089 >  else if (strchr(yylval.string, ' '))
2090      conf_error_report("Server passwords cannot contain spaces");
2091    else
2092      strlcpy(block_state.rpass.buf, yylval.string, sizeof(block_state.rpass.buf));
2093   };
2094  
2095 < connect_ssl_certificate_fingerprint: SSL_CERTIFICATE_FINGERPRINT '=' QSTRING ';'
2095 > connect_tls_certificate_fingerprint: TLS_CERTIFICATE_FINGERPRINT '=' QSTRING ';'
2096   {
2097    if (conf_parser_ctx.pass == 2)
2098      strlcpy(block_state.cert.buf, yylval.string, sizeof(block_state.cert.buf));
# Line 2315 | Line 2117 | connect_aftype: AFTYPE '=' T_IPV4 ';'
2117   connect_flags: IRCD_FLAGS
2118   {
2119    block_state.flags.value &= CONF_FLAGS_ENCRYPTED;
2120 < } '='  connect_flags_items ';';
2120 > } '=' connect_flags_items ';';
2121  
2122   connect_flags_items: connect_flags_items ',' connect_flags_item | connect_flags_item;
2123   connect_flags_item: AUTOCONN
2124   {
2125    if (conf_parser_ctx.pass == 2)
2126      block_state.flags.value |= CONF_FLAGS_ALLOW_AUTO_CONN;
2127 < } | T_SSL
2127 > } | T_TLS
2128   {
2129    if (conf_parser_ctx.pass == 2)
2130 <    block_state.flags.value |= CONF_FLAGS_SSL;
2130 >    block_state.flags.value |= CONF_FLAGS_TLS;
2131   };
2132  
2133   connect_encrypted: ENCRYPTED '=' TBOOL ';'
# Line 2357 | Line 2159 | connect_class: CLASS '=' QSTRING ';'
2159      strlcpy(block_state.class.buf, yylval.string, sizeof(block_state.class.buf));
2160   };
2161  
2162 < connect_ssl_cipher_list: T_SSL_CIPHER_LIST '=' QSTRING ';'
2162 > connect_tls_cipher_list: TLS_CIPHER_LIST '=' QSTRING ';'
2163   {
2164 < #ifdef HAVE_LIBCRYPTO
2164 > #ifdef HAVE_TLS
2165    if (conf_parser_ctx.pass == 2)
2166      strlcpy(block_state.ciph.buf, yylval.string, sizeof(block_state.ciph.buf));
2167   #else
2168    if (conf_parser_ctx.pass == 2)
2169 <    conf_error_report("Ignoring connect::ciphers -- no OpenSSL support");
2169 >    conf_error_report("Ignoring connect::tls_cipher_list -- no TLS support");
2170   #endif
2171   };
2172  
2173  
2174   /***************************************************************************
2175 < *  section kill
2175 > * kill {} section
2176   ***************************************************************************/
2177   kill_entry: KILL
2178   {
# Line 2378 | Line 2180 | kill_entry: KILL
2180      reset_block_state();
2181   } '{' kill_items '}' ';'
2182   {
2381  struct MaskItem *conf = NULL;
2382
2183    if (conf_parser_ctx.pass != 2)
2184      break;
2185  
# Line 2387 | Line 2187 | kill_entry: KILL
2187        !block_state.host.buf[0])
2188      break;
2189  
2190 <  conf = conf_make(CONF_KLINE);
2190 >  struct MaskItem *conf = conf_make(CONF_KLINE);
2191    conf->user = xstrdup(block_state.user.buf);
2192    conf->host = xstrdup(block_state.host.buf);
2193  
# Line 2427 | Line 2227 | kill_reason: REASON '=' QSTRING ';'
2227      strlcpy(block_state.rpass.buf, yylval.string, sizeof(block_state.rpass.buf));
2228   };
2229  
2230 +
2231   /***************************************************************************
2232 < *  section deny
2232 > * deny {} section
2233   ***************************************************************************/
2234   deny_entry: DENY
2235   {
# Line 2436 | Line 2237 | deny_entry: DENY
2237      reset_block_state();
2238   } '{' deny_items '}' ';'
2239   {
2439  struct MaskItem *conf = NULL;
2440
2240    if (conf_parser_ctx.pass != 2)
2241      break;
2242  
# Line 2446 | Line 2245 | deny_entry: DENY
2245  
2246    if (parse_netmask(block_state.addr.buf, NULL, NULL) != HM_HOST)
2247    {
2248 <    conf = conf_make(CONF_DLINE);
2248 >    struct MaskItem *conf = conf_make(CONF_DLINE);
2249      conf->host = xstrdup(block_state.addr.buf);
2250  
2251      if (block_state.rpass.buf[0])
# Line 2472 | Line 2271 | deny_reason: REASON '=' QSTRING ';'
2271      strlcpy(block_state.rpass.buf, yylval.string, sizeof(block_state.rpass.buf));
2272   };
2273  
2274 +
2275   /***************************************************************************
2276 < *  section exempt
2276 > * exempt {} section
2277   ***************************************************************************/
2278   exempt_entry: EXEMPT '{' exempt_items '}' ';';
2279  
2280 < exempt_items:     exempt_items exempt_item | exempt_item;
2281 < exempt_item:      exempt_ip | error;
2280 > exempt_items: exempt_items exempt_item | exempt_item;
2281 > exempt_item:  exempt_ip | error;
2282  
2283   exempt_ip: IP '=' QSTRING ';'
2284   {
2285    if (conf_parser_ctx.pass == 2)
2286    {
2287 <    if (yylval.string[0] && parse_netmask(yylval.string, NULL, NULL) != HM_HOST)
2287 >    if (*yylval.string && parse_netmask(yylval.string, NULL, NULL) != HM_HOST)
2288      {
2289        struct MaskItem *conf = conf_make(CONF_EXEMPT);
2290        conf->host = xstrdup(yylval.string);
# Line 2495 | Line 2295 | exempt_ip: IP '=' QSTRING ';'
2295   };
2296  
2297   /***************************************************************************
2298 < *  section gecos
2298 > * gecos {} section
2299   ***************************************************************************/
2300   gecos_entry: GECOS
2301   {
# Line 2503 | Line 2303 | gecos_entry: GECOS
2303      reset_block_state();
2304   } '{' gecos_items '}' ';'
2305   {
2506  struct MaskItem *conf = NULL;
2507
2306    if (conf_parser_ctx.pass != 2)
2307      break;
2308  
2309    if (!block_state.name.buf[0])
2310      break;
2311  
2312 <  conf = conf_make(CONF_XLINE);
2313 <  conf->name = xstrdup(block_state.name.buf);
2312 >  struct GecosItem *gecos = gecos_make();
2313 >  gecos->mask = xstrdup(block_state.name.buf);
2314  
2315    if (block_state.rpass.buf[0])
2316 <    conf->reason = xstrdup(block_state.rpass.buf);
2316 >    gecos->reason = xstrdup(block_state.rpass.buf);
2317    else
2318 <    conf->reason = xstrdup(CONF_NOREASON);
2318 >    gecos->reason = xstrdup(CONF_NOREASON);
2319   };
2320  
2321   gecos_items: gecos_items gecos_item | gecos_item;
# Line 2535 | Line 2333 | gecos_reason: REASON '=' QSTRING ';'
2333      strlcpy(block_state.rpass.buf, yylval.string, sizeof(block_state.rpass.buf));
2334   };
2335  
2336 +
2337   /***************************************************************************
2338 < *  section general
2338 > * general {} section
2339   ***************************************************************************/
2340 < general_entry: GENERAL
2542 <  '{' general_items '}' ';';
2340 > general_entry: GENERAL '{' general_items '}' ';';
2341  
2342   general_items:      general_items general_item | general_item;
2343   general_item:       general_away_count |
2344                      general_away_time |
2547                    general_ignore_bogus_ts |
2345                      general_failed_oper_notice |
2346                      general_anti_nick_flood |
2347                      general_max_nick_time |
2348                      general_max_nick_changes |
2349                      general_max_accept |
2350 +                    general_whowas_history_length |
2351                      general_anti_spam_exit_message_time |
2352                      general_ts_warn_delta |
2353                      general_ts_max_delta |
# Line 2573 | Line 2371 | general_item:       general_away_count |
2371                      general_caller_id_wait |
2372                      general_opers_bypass_callerid |
2373                      general_default_floodcount |
2374 +                    general_default_floodtime |
2375                      general_min_nonwildcard |
2376                      general_min_nonwildcard_simple |
2377                      general_throttle_count |
2378                      general_throttle_time |
2379                      general_ping_cookie |
2380                      general_disable_auth |
2582                    general_tkline_expire_notices |
2381                      general_dline_min_cidr |
2382                      general_dline_min_cidr6 |
2383                      general_kline_min_cidr |
# Line 2605 | Line 2403 | general_max_watch: MAX_WATCH '=' NUMBER
2403    ConfigGeneral.max_watch = $3;
2404   };
2405  
2406 + general_whowas_history_length: WHOWAS_HISTORY_LENGTH '=' NUMBER ';'
2407 + {
2408 +  ConfigGeneral.whowas_history_length = $3;
2409 + };
2410 +
2411   general_cycle_on_host_change: CYCLE_ON_HOST_CHANGE '=' TBOOL ';'
2412   {
2413 <  if (conf_parser_ctx.pass == 2)
2611 <    ConfigGeneral.cycle_on_host_change = yylval.number;
2413 >  ConfigGeneral.cycle_on_host_change = yylval.number;
2414   };
2415  
2416   general_dline_min_cidr: DLINE_MIN_CIDR '=' NUMBER ';'
# Line 2631 | Line 2433 | general_kline_min_cidr6: KLINE_MIN_CIDR6
2433    ConfigGeneral.kline_min_cidr6 = $3;
2434   };
2435  
2634 general_tkline_expire_notices: TKLINE_EXPIRE_NOTICES '=' TBOOL ';'
2635 {
2636  ConfigGeneral.tkline_expire_notices = yylval.number;
2637 };
2638
2436   general_kill_chase_time_limit: KILL_CHASE_TIME_LIMIT '=' timespec ';'
2437   {
2438    ConfigGeneral.kill_chase_time_limit = $3;
2439   };
2440  
2644 general_ignore_bogus_ts: IGNORE_BOGUS_TS '=' TBOOL ';'
2645 {
2646  ConfigGeneral.ignore_bogus_ts = yylval.number;
2647 };
2648
2441   general_failed_oper_notice: FAILED_OPER_NOTICE '=' TBOOL ';'
2442   {
2443    ConfigGeneral.failed_oper_notice = yylval.number;
# Line 2683 | Line 2475 | general_ts_warn_delta: TS_WARN_DELTA '='
2475  
2476   general_ts_max_delta: TS_MAX_DELTA '=' timespec ';'
2477   {
2478 <  if (conf_parser_ctx.pass == 2)
2687 <    ConfigGeneral.ts_max_delta = $3;
2478 >  ConfigGeneral.ts_max_delta = $3;
2479   };
2480  
2481   general_invisible_on_connect: INVISIBLE_ON_CONNECT '=' TBOOL ';'
# Line 2801 | Line 2592 | general_throttle_time: THROTTLE_TIME '='
2592   general_oper_umodes: OPER_UMODES
2593   {
2594    ConfigGeneral.oper_umodes = 0;
2595 < } '='  umode_oitems ';' ;
2595 > } '=' umode_oitems ';' ;
2596  
2597   umode_oitems:    umode_oitems ',' umode_oitem | umode_oitem;
2598   umode_oitem:     T_BOTS
# Line 2870 | Line 2661 | umode_oitem:     T_BOTS
2661   } | T_FARCONNECT
2662   {
2663    ConfigGeneral.oper_umodes |= UMODE_FARCONNECT;
2664 + } | EXPIRATION
2665 + {
2666 +  ConfigGeneral.oper_umodes |= UMODE_EXPIRATION;
2667   };
2668  
2669   general_oper_only_umodes: OPER_ONLY_UMODES
2670   {
2671    ConfigGeneral.oper_only_umodes = 0;
2672 < } '='  umode_items ';' ;
2672 > } '=' umode_items ';' ;
2673  
2674   umode_items:  umode_items ',' umode_item | umode_item;
2675   umode_item:   T_BOTS
# Line 2938 | Line 2732 | umode_item:   T_BOTS
2732   } | T_FARCONNECT
2733   {
2734    ConfigGeneral.oper_only_umodes |= UMODE_FARCONNECT;
2735 + } | EXPIRATION
2736 + {
2737 +  ConfigGeneral.oper_only_umodes |= UMODE_EXPIRATION;
2738   };
2739  
2740   general_min_nonwildcard: MIN_NONWILDCARD '=' NUMBER ';'
# Line 2955 | Line 2752 | general_default_floodcount: DEFAULT_FLOO
2752    ConfigGeneral.default_floodcount = $3;
2753   };
2754  
2755 + general_default_floodtime: DEFAULT_FLOODTIME '=' timespec ';'
2756 + {
2757 +  ConfigGeneral.default_floodtime = $3;
2758 + };
2759 +
2760  
2761   /***************************************************************************
2762 < *  section channel
2762 > * channel {} section
2763   ***************************************************************************/
2764 < channel_entry: CHANNEL
2963 <  '{' channel_items '}' ';';
2764 > channel_entry: CHANNEL '{' channel_items '}' ';';
2765  
2766   channel_items:      channel_items channel_item | channel_item;
2767   channel_item:       channel_max_bans |
2768 +                    channel_max_bans_large |
2769                      channel_invite_client_count |
2770                      channel_invite_client_time |
2771 +                    channel_invite_delay_channel |
2772 +                    channel_invite_expire_time |
2773                      channel_knock_client_count |
2774                      channel_knock_client_time |
2775                      channel_knock_delay_channel |
2776                      channel_max_channels |
2777 +                    channel_max_invites |
2778                      channel_default_join_flood_count |
2779                      channel_default_join_flood_time |
2780                      channel_disable_fake_channels |
2781 +                    channel_enable_extbans |
2782                      error;
2783  
2784 + channel_enable_extbans: ENABLE_EXTBANS '=' TBOOL ';'
2785 + {
2786 +  ConfigChannel.enable_extbans = yylval.number;
2787 + };
2788 +
2789   channel_disable_fake_channels: DISABLE_FAKE_CHANNELS '=' TBOOL ';'
2790   {
2791    ConfigChannel.disable_fake_channels = yylval.number;
# Line 2990 | Line 2801 | channel_invite_client_time: INVITE_CLIEN
2801    ConfigChannel.invite_client_time = $3;
2802   };
2803  
2804 + channel_invite_delay_channel: INVITE_DELAY_CHANNEL '=' timespec ';'
2805 + {
2806 +  ConfigChannel.invite_delay_channel = $3;
2807 + };
2808 +
2809 + channel_invite_expire_time: INVITE_EXPIRE_TIME '=' timespec ';'
2810 + {
2811 +  ConfigChannel.invite_expire_time = $3;
2812 + };
2813 +
2814   channel_knock_client_count: KNOCK_CLIENT_COUNT '=' NUMBER ';'
2815   {
2816    ConfigChannel.knock_client_count = $3;
# Line 3010 | Line 2831 | channel_max_channels: MAX_CHANNELS '=' N
2831    ConfigChannel.max_channels = $3;
2832   };
2833  
2834 + channel_max_invites: MAX_INVITES '=' NUMBER ';'
2835 + {
2836 +  ConfigChannel.max_invites = $3;
2837 + };
2838 +
2839   channel_max_bans: MAX_BANS '=' NUMBER ';'
2840   {
2841    ConfigChannel.max_bans = $3;
2842   };
2843  
2844 + channel_max_bans_large: MAX_BANS_LARGE '=' NUMBER ';'
2845 + {
2846 +  ConfigChannel.max_bans_large = $3;
2847 + };
2848 +
2849   channel_default_join_flood_count: DEFAULT_JOIN_FLOOD_COUNT '=' NUMBER ';'
2850   {
2851    ConfigChannel.default_join_flood_count = yylval.number;
# Line 3025 | Line 2856 | channel_default_join_flood_time: DEFAULT
2856    ConfigChannel.default_join_flood_time = $3;
2857   };
2858  
2859 +
2860   /***************************************************************************
2861 < *  section serverhide
2861 > * serverhide {} section
2862   ***************************************************************************/
2863 < serverhide_entry: SERVERHIDE
3032 <  '{' serverhide_items '}' ';';
2863 > serverhide_entry: SERVERHIDE '{' serverhide_items '}' ';';
2864  
2865   serverhide_items:   serverhide_items serverhide_item | serverhide_item;
2866   serverhide_item:    serverhide_flatten_links |
2867 +                    serverhide_flatten_links_delay |
2868 +                    serverhide_flatten_links_file |
2869                      serverhide_disable_remote_commands |
2870                      serverhide_hide_servers |
2871                      serverhide_hide_services |
3039                    serverhide_links_delay |
2872                      serverhide_hidden |
2873                      serverhide_hidden_name |
2874                      serverhide_hide_server_ips |
# Line 3048 | Line 2880 | serverhide_flatten_links: FLATTEN_LINKS
2880      ConfigServerHide.flatten_links = yylval.number;
2881   };
2882  
2883 + serverhide_flatten_links_delay: FLATTEN_LINKS_DELAY '=' timespec ';'
2884 + {
2885 +  if (conf_parser_ctx.pass == 2)
2886 +  {
2887 +    if ($3 > 0)
2888 +    {
2889 +      event_write_links_file.when = $3;
2890 +      event_add(&event_write_links_file, NULL);
2891 +    }
2892 +    else
2893 +     event_delete(&event_write_links_file);
2894 +
2895 +    ConfigServerHide.flatten_links_delay = $3;
2896 +  }
2897 + };
2898 +
2899 + serverhide_flatten_links_file: FLATTEN_LINKS_FILE '=' QSTRING ';'
2900 + {
2901 +  if (conf_parser_ctx.pass == 2)
2902 +  {
2903 +    xfree(ConfigServerHide.flatten_links_file);
2904 +    ConfigServerHide.flatten_links_file = xstrdup(yylval.string);
2905 +  }
2906 + };
2907 +
2908   serverhide_disable_remote_commands: DISABLE_REMOTE_COMMANDS '=' TBOOL ';'
2909   {
2910    if (conf_parser_ctx.pass == 2)
# Line 3070 | Line 2927 | serverhide_hidden_name: HIDDEN_NAME '='
2927   {
2928    if (conf_parser_ctx.pass == 2)
2929    {
2930 <    MyFree(ConfigServerHide.hidden_name);
2930 >    xfree(ConfigServerHide.hidden_name);
2931      ConfigServerHide.hidden_name = xstrdup(yylval.string);
2932    }
2933   };
2934  
3078 serverhide_links_delay: LINKS_DELAY '=' timespec ';'
3079 {
3080  if (conf_parser_ctx.pass == 2)
3081  {
3082    if (($3 > 0) && ConfigServerHide.links_disabled == 1)
3083    {
3084      event_write_links_file.when = $3;
3085      event_addish(&event_write_links_file, NULL);
3086      ConfigServerHide.links_disabled = 0;
3087    }
3088
3089    ConfigServerHide.links_delay = $3;
3090  }
3091 };
3092
2935   serverhide_hidden: HIDDEN '=' TBOOL ';'
2936   {
2937    if (conf_parser_ctx.pass == 2)

Comparing ircd-hybrid/trunk/src/conf_parser.y (property svn:keywords):
Revision 6488 by michael, Fri Sep 4 17:56:25 2015 UTC vs.
Revision 9234 by michael, Fri Jan 31 17:38:34 2020 UTC

# Line 1 | Line 1
1 < Id Revision
1 > Id

Diff Legend

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