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 3435 by michael, Thu May 1 13:57:39 2014 UTC vs.
Revision 9114 by michael, Sun Jan 5 09:43:16 2020 UTC

# Line 1 | Line 1
1   /*
2   *  ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3   *
4 < *  Copyright (c) 2000-2014 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 15 | Line 15
15   *
16   *  You should have received a copy of the GNU General Public License
17   *  along with this program; if not, write to the Free Software
18 < *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
18 > *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
19   *  USA
20   */
21  
# Line 27 | Line 27
27  
28   %{
29  
30 #define YY_NO_UNPUT
31 #include <sys/types.h>
32 #include <string.h>
33
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"
42 #include "client.h"     /* for UMODE_ALL only */
46   #include "irc_string.h"
47   #include "memory.h"
48   #include "modules.h"
49   #include "server.h"
50   #include "hostmask.h"
48 #include "send.h"
51   #include "listener.h"
50 #include "resv.h"
51 #include "numeric.h"
52   #include "user.h"
53   #include "motd.h"
54  
55 #ifdef HAVE_LIBCRYPTO
56 #include <openssl/rsa.h>
57 #include <openssl/bio.h>
58 #include <openssl/pem.h>
59 #include <openssl/dh.h>
60 #endif
61
62 #include "rsa.h"
63
55   int yylex(void);
56  
57   static struct
58   {
59 <  struct {
59 >  struct
60 >  {
61      dlink_list list;
62    } mask,
63      leaf,
64      hub;
65  
66 <  struct {
66 >  struct
67 >  {
68      char buf[IRCD_BUFSIZE];
69    } name,
70 +    nick,
71      user,
72      host,
73      addr,
# Line 83 | Line 77 | static struct
77      cert,
78      rpass,
79      spass,
80 <    class;
80 >    whois,
81 >    class,
82 >    target,
83 >    prepend,
84 >    command;
85  
86 <  struct {
86 >  struct
87 >  {
88      unsigned int value;
89    } flags,
90      modes,
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,
102    max_global,
103    max_local,
104    max_ident,
103      max_sendq,
104      max_recvq,
105 +    max_channels,
106      cidr_bitlen_ipv4,
107      cidr_bitlen_ipv6,
108      number_per_cidr;
# Line 112 | Line 111 | static struct
111   static void
112   reset_block_state(void)
113   {
114 <  dlink_node *ptr = NULL, *ptr_next = NULL;
114 >  dlink_node *node = NULL, *node_next = NULL;
115  
116 <  DLINK_FOREACH_SAFE(ptr, ptr_next, block_state.mask.list.head)
116 >  DLINK_FOREACH_SAFE(node, node_next, block_state.mask.list.head)
117    {
118 <    MyFree(ptr->data);
119 <    dlinkDelete(ptr, &block_state.mask.list);
120 <    free_dlink_node(ptr);
118 >    xfree(node->data);
119 >    dlinkDelete(node, &block_state.mask.list);
120 >    free_dlink_node(node);
121    }
122  
123 <  DLINK_FOREACH_SAFE(ptr, ptr_next, block_state.leaf.list.head)
123 >  DLINK_FOREACH_SAFE(node, node_next, block_state.leaf.list.head)
124    {
125 <    MyFree(ptr->data);
126 <    dlinkDelete(ptr, &block_state.leaf.list);
127 <    free_dlink_node(ptr);
125 >    xfree(node->data);
126 >    dlinkDelete(node, &block_state.leaf.list);
127 >    free_dlink_node(node);
128    }
129  
130 <  DLINK_FOREACH_SAFE(ptr, ptr_next, block_state.hub.list.head)
130 >  DLINK_FOREACH_SAFE(node, node_next, block_state.hub.list.head)
131    {
132 <    MyFree(ptr->data);
133 <    dlinkDelete(ptr, &block_state.hub.list);
134 <    free_dlink_node(ptr);
132 >    xfree(node->data);
133 >    dlinkDelete(node, &block_state.hub.list);
134 >    free_dlink_node(node);
135    }
136  
137    memset(&block_state, 0, sizeof(block_state));
# Line 151 | Line 150 | reset_block_state(void)
150   %token  ANTI_NICK_FLOOD
151   %token  ANTI_SPAM_EXIT_MESSAGE_TIME
152   %token  AUTOCONN
153 + %token  AWAY_COUNT
154 + %token  AWAY_TIME
155   %token  BYTES KBYTES MBYTES
156   %token  CALLER_ID_WAIT
157   %token  CAN_FLOOD
# Line 158 | Line 159 | reset_block_state(void)
159   %token  CIDR_BITLEN_IPV4
160   %token  CIDR_BITLEN_IPV6
161   %token  CLASS
162 + %token  CLOSE
163   %token  CONNECT
164   %token  CONNECTFREQ
165   %token  CYCLE_ON_HOST_CHANGE
166   %token  DEFAULT_FLOODCOUNT
167 < %token  DEFAULT_SPLIT_SERVER_COUNT
168 < %token  DEFAULT_SPLIT_USER_COUNT
167 > %token  DEFAULT_FLOODTIME
168 > %token  DEFAULT_JOIN_FLOOD_COUNT
169 > %token  DEFAULT_JOIN_FLOOD_TIME
170 > %token  DEFAULT_MAX_CLIENTS
171   %token  DENY
172   %token  DESCRIPTION
173   %token  DIE
174   %token  DISABLE_AUTH
175   %token  DISABLE_FAKE_CHANNELS
176   %token  DISABLE_REMOTE_COMMANDS
177 + %token  DLINE_MIN_CIDR
178 + %token  DLINE_MIN_CIDR6
179   %token  DOTS_IN_IDENT
174 %token  EGDPOOL_PATH
180   %token  EMAIL
181   %token  ENCRYPTED
182   %token  EXCEED_LIMIT
183   %token  EXEMPT
184 + %token  EXPIRATION
185   %token  FAILED_OPER_NOTICE
186   %token  FLATTEN_LINKS
187 + %token  FLATTEN_LINKS_DELAY
188 + %token  FLATTEN_LINKS_FILE
189   %token  GECOS
190   %token  GENERAL
183 %token  GLINE
184 %token  GLINE_DURATION
185 %token  GLINE_ENABLE
186 %token  GLINE_EXEMPT
187 %token  GLINE_MIN_CIDR
188 %token  GLINE_MIN_CIDR6
189 %token  GLINE_REQUEST_DURATION
190 %token  GLOBAL_KILL
191 %token  HAVENT_READ_CONF
191   %token  HIDDEN
192   %token  HIDDEN_NAME
193 + %token  HIDE_CHANS
194 + %token  HIDE_IDLE
195   %token  HIDE_IDLE_FROM_OPERS
196   %token  HIDE_SERVER_IPS
197   %token  HIDE_SERVERS
198   %token  HIDE_SERVICES
198 %token  HIDE_SPOOF_IPS
199   %token  HOST
200   %token  HUB
201   %token  HUB_MASK
202 %token  IGNORE_BOGUS_TS
202   %token  INVISIBLE_ON_CONNECT
203 + %token  INVITE_CLIENT_COUNT
204 + %token  INVITE_CLIENT_TIME
205 + %token  INVITE_DELAY_CHANNEL
206 + %token  INVITE_EXPIRE_TIME
207   %token  IP
208   %token  IRCD_AUTH
209   %token  IRCD_FLAGS
210   %token  IRCD_SID
211 < %token  JOIN_FLOOD_COUNT
209 < %token  JOIN_FLOOD_TIME
211 > %token  JOIN
212   %token  KILL
213   %token  KILL_CHASE_TIME_LIMIT
214   %token  KLINE
215   %token  KLINE_EXEMPT
216 < %token  KNOCK_DELAY
216 > %token  KLINE_MIN_CIDR
217 > %token  KLINE_MIN_CIDR6
218 > %token  KNOCK_CLIENT_COUNT
219 > %token  KNOCK_CLIENT_TIME
220   %token  KNOCK_DELAY_CHANNEL
221   %token  LEAF_MASK
217 %token  LINKS_DELAY
222   %token  LISTEN
223   %token  MASK
224   %token  MAX_ACCEPT
225   %token  MAX_BANS
226 < %token  MAX_CHANS_PER_OPER
227 < %token  MAX_CHANS_PER_USER
224 < %token  MAX_GLOBAL
225 < %token  MAX_IDENT
226 > %token  MAX_BANS_LARGE
227 > %token  MAX_CHANNELS
228   %token  MAX_IDLE
229 < %token  MAX_LOCAL
229 > %token  MAX_INVITES
230   %token  MAX_NICK_CHANGES
231   %token  MAX_NICK_LENGTH
232   %token  MAX_NICK_TIME
# Line 244 | Line 246 | reset_block_state(void)
246   %token  NETWORK_DESC
247   %token  NETWORK_NAME
248   %token  NICK
247 %token  NO_CREATE_ON_SPLIT
248 %token  NO_JOIN_ON_SPLIT
249   %token  NO_OPER_FLOOD
250   %token  NO_TILDE
251   %token  NUMBER
252   %token  NUMBER_PER_CIDR
253 < %token  NUMBER_PER_IP
253 > %token  NUMBER_PER_IP_GLOBAL
254 > %token  NUMBER_PER_IP_LOCAL
255   %token  OPER_ONLY_UMODES
255 %token  OPER_PASS_RESV
256   %token  OPER_UMODES
257   %token  OPERATOR
258   %token  OPERS_BYPASS_CALLERID
# Line 274 | Line 274 | reset_block_state(void)
274   %token  RESV
275   %token  RESV_EXEMPT
276   %token  RSA_PRIVATE_KEY_FILE
277 %token  RSA_PUBLIC_KEY_FILE
277   %token  SECONDS MINUTES HOURS DAYS WEEKS MONTHS YEARS
278   %token  SEND_PASSWORD
279   %token  SENDQ
# Line 287 | Line 286 | reset_block_state(void)
286   %token  SSL_CERTIFICATE_FILE
287   %token  SSL_CERTIFICATE_FINGERPRINT
288   %token  SSL_CONNECTION_REQUIRED
289 + %token  SSL_DH_ELLIPTIC_CURVE
290   %token  SSL_DH_PARAM_FILE
291 + %token  SSL_MESSAGE_DIGEST_ALGORITHM
292   %token  STATS_E_DISABLED
293   %token  STATS_I_OPER_ONLY
294   %token  STATS_K_OPER_ONLY
295 + %token  STATS_M_OPER_ONLY
296   %token  STATS_O_OPER_ONLY
297   %token  STATS_P_OPER_ONLY
298   %token  STATS_U_OPER_ONLY
299   %token  T_ALL
300 + %token  T_BIND
301   %token  T_BOTS
302   %token  T_CALLERID
303   %token  T_CCONN
304 + %token  T_COMMAND
305   %token  T_CLUSTER
306   %token  T_DEAF
307   %token  T_DEBUG
# Line 312 | Line 316 | reset_block_state(void)
316   %token  T_IPV6
317   %token  T_LOCOPS
318   %token  T_LOG
315 %token  T_MAX_CLIENTS
319   %token  T_NCHANGE
320   %token  T_NONONREG
321 < %token  T_OPERWALL
321 > %token  T_OPME
322 > %token  T_PREPEND
323 > %token  T_PSEUDO
324   %token  T_RECVQ
325   %token  T_REJ
326   %token  T_RESTART
327   %token  T_SERVER
328   %token  T_SERVICE
324 %token  T_SERVICES_NAME
329   %token  T_SERVNOTICE
330   %token  T_SET
331   %token  T_SHARED
# Line 331 | Line 335 | reset_block_state(void)
335   %token  T_SPY
336   %token  T_SSL
337   %token  T_SSL_CIPHER_LIST
338 < %token  T_SSL_CLIENT_METHOD
335 < %token  T_SSL_SERVER_METHOD
336 < %token  T_SSLV3
337 < %token  T_TLSV1
338 > %token  T_TARGET
339   %token  T_UMODES
340   %token  T_UNAUTH
341   %token  T_UNDLINE
# Line 345 | Line 346 | reset_block_state(void)
346   %token  T_WALLOPS
347   %token  T_WEBIRC
348   %token  TBOOL
349 + %token  THROTTLE_COUNT
350   %token  THROTTLE_TIME
351 < %token  TKLINE_EXPIRE_NOTICES
351 > %token  TIMEOUT
352   %token  TMASKED
351 %token  TRUE_NO_OPER_FLOOD
353   %token  TS_MAX_DELTA
354   %token  TS_WARN_DELTA
355   %token  TWODOTS
356   %token  TYPE
357   %token  UNKLINE
357 %token  USE_EGD
358   %token  USE_LOGGING
359   %token  USER
360   %token  VHOST
361   %token  VHOST6
362 < %token  WARN_NO_NLINE
362 > %token  WARN_NO_CONNECT_BLOCK
363 > %token  WHOIS
364 > %token  WHOWAS_HISTORY_LENGTH
365   %token  XLINE
366 + %token  XLINE_EXEMPT
367  
368   %type  <string> QSTRING
369   %type  <number> NUMBER
# Line 377 | Line 380 | conf:
380   conf_item:        admin_entry
381                  | logging_entry
382                  | oper_entry
383 <                | channel_entry
383 >                | channel_entry
384                  | class_entry
385                  | listen_entry
386                  | auth_entry
387                  | serverinfo_entry
388 <                | serverhide_entry
388 >                | serverhide_entry
389                  | resv_entry
390                  | service_entry
391                  | shared_entry
392 <                | cluster_entry
392 >                | cluster_entry
393                  | connect_entry
394                  | kill_entry
395                  | deny_entry
396 <                | exempt_entry
397 <                | general_entry
396 >                | exempt_entry
397 >                | general_entry
398                  | gecos_entry
399                  | modules_entry
400                  | motd_entry
401 +                | pseudo_entry
402                  | error ';'
403                  | error '}'
404          ;
405  
406  
407   timespec_: { $$ = 0; } | timespec;
408 < timespec:       NUMBER timespec_
409 <                {
410 <                        $$ = $1 + $2;
411 <                }
412 <                | NUMBER SECONDS timespec_
413 <                {
414 <                        $$ = $1 + $3;
415 <                }
416 <                | NUMBER MINUTES timespec_
417 <                {
418 <                        $$ = $1 * 60 + $3;
419 <                }
420 <                | NUMBER HOURS timespec_
421 <                {
422 <                        $$ = $1 * 60 * 60 + $3;
423 <                }
420 <                | NUMBER DAYS timespec_
421 <                {
422 <                        $$ = $1 * 60 * 60 * 24 + $3;
423 <                }
424 <                | NUMBER WEEKS timespec_
425 <                {
426 <                        $$ = $1 * 60 * 60 * 24 * 7 + $3;
427 <                }
428 <                | NUMBER MONTHS timespec_
429 <                {
430 <                        $$ = $1 * 60 * 60 * 24 * 7 * 4 + $3;
431 <                }
432 <                | NUMBER YEARS timespec_
433 <                {
434 <                        $$ = $1 * 60 * 60 * 24 * 365 + $3;
435 <                }
436 <                ;
437 <
438 < sizespec_:      { $$ = 0; } | sizespec;
439 < sizespec:       NUMBER sizespec_ { $$ = $1 + $2; }
440 <                | NUMBER BYTES sizespec_ { $$ = $1 + $3; }
441 <                | NUMBER KBYTES sizespec_ { $$ = $1 * 1024 + $3; }
442 <                | NUMBER MBYTES sizespec_ { $$ = $1 * 1024 * 1024 + $3; }
443 <                ;
408 > timespec:  NUMBER timespec_         { $$ = $1 + $2; } |
409 >           NUMBER SECONDS timespec_ { $$ = $1 + $3; } |
410 >           NUMBER MINUTES timespec_ { $$ = $1 * 60 + $3; } |
411 >           NUMBER HOURS timespec_   { $$ = $1 * 60 * 60 + $3; } |
412 >           NUMBER DAYS timespec_    { $$ = $1 * 60 * 60 * 24 + $3; } |
413 >           NUMBER WEEKS timespec_   { $$ = $1 * 60 * 60 * 24 * 7 + $3; } |
414 >           NUMBER MONTHS timespec_  { $$ = $1 * 60 * 60 * 24 * 7 * 4 + $3; } |
415 >           NUMBER YEARS timespec_   { $$ = $1 * 60 * 60 * 24 * 365 + $3; }
416 >           ;
417 >
418 > sizespec_:  { $$ = 0; } | sizespec;
419 > sizespec:   NUMBER sizespec_ { $$ = $1 + $2; } |
420 >            NUMBER BYTES sizespec_ { $$ = $1 + $3; } |
421 >            NUMBER KBYTES sizespec_ { $$ = $1 * 1024 + $3; } |
422 >            NUMBER MBYTES sizespec_ { $$ = $1 * 1024 * 1024 + $3; }
423 >            ;
424  
425  
426   /***************************************************************************
427 < *  section modules
427 > * modules {} section
428   ***************************************************************************/
429 < modules_entry: MODULES
450 <  '{' modules_items '}' ';';
429 > modules_entry: MODULES '{' modules_items '}' ';';
430  
431   modules_items:  modules_items modules_item | modules_item;
432   modules_item:   modules_module | modules_path | error ';' ;
# Line 465 | Line 444 | modules_path: PATH '=' QSTRING ';'
444   };
445  
446  
447 + /***************************************************************************
448 + * serverinfo {}  section
449 + ***************************************************************************/
450   serverinfo_entry: SERVERINFO '{' serverinfo_items '}' ';';
451  
452   serverinfo_items:       serverinfo_items serverinfo_item | serverinfo_item ;
453 < serverinfo_item:        serverinfo_name | serverinfo_vhost |
454 <                        serverinfo_hub | serverinfo_description |
455 <                        serverinfo_network_name | serverinfo_network_desc |
456 <                        serverinfo_max_clients | serverinfo_max_nick_length |
457 <                        serverinfo_max_topic_length | serverinfo_ssl_dh_param_file |
458 <                        serverinfo_rsa_private_key_file | serverinfo_vhost6 |
459 <                        serverinfo_sid | serverinfo_ssl_certificate_file |
460 <                        serverinfo_ssl_client_method | serverinfo_ssl_server_method |
453 > serverinfo_item:        serverinfo_name |
454 >                        serverinfo_hub |
455 >                        serverinfo_description |
456 >                        serverinfo_network_name |
457 >                        serverinfo_network_desc |
458 >                        serverinfo_default_max_clients |
459 >                        serverinfo_max_nick_length |
460 >                        serverinfo_max_topic_length |
461 >                        serverinfo_ssl_dh_param_file |
462 >                        serverinfo_ssl_dh_elliptic_curve |
463 >                        serverinfo_rsa_private_key_file |
464 >                        serverinfo_sid |
465 >                        serverinfo_ssl_certificate_file |
466                          serverinfo_ssl_cipher_list |
467 <                        error ';' ;
468 <
467 >                        serverinfo_ssl_message_digest_algorithm |
468 >                        error ';' ;
469  
483 serverinfo_ssl_client_method: T_SSL_CLIENT_METHOD '=' client_method_types ';' ;
484 serverinfo_ssl_server_method: T_SSL_SERVER_METHOD '=' server_method_types ';' ;
485
486 client_method_types: client_method_types ',' client_method_type_item | client_method_type_item;
487 client_method_type_item: T_SSLV3
488 {
489 #ifdef HAVE_LIBCRYPTO
490  if (conf_parser_ctx.pass == 2 && ServerInfo.client_ctx)
491    SSL_CTX_clear_options(ServerInfo.client_ctx, SSL_OP_NO_SSLv3);
492 #endif
493 } | T_TLSV1
494 {
495 #ifdef HAVE_LIBCRYPTO
496  if (conf_parser_ctx.pass == 2 && ServerInfo.client_ctx)
497    SSL_CTX_clear_options(ServerInfo.client_ctx, SSL_OP_NO_TLSv1);
498 #endif
499 };
500
501 server_method_types: server_method_types ',' server_method_type_item | server_method_type_item;
502 server_method_type_item: T_SSLV3
503 {
504 #ifdef HAVE_LIBCRYPTO
505  if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx)
506    SSL_CTX_clear_options(ServerInfo.server_ctx, SSL_OP_NO_SSLv3);
507 #endif
508 } | T_TLSV1
509 {
510 #ifdef HAVE_LIBCRYPTO
511  if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx)
512    SSL_CTX_clear_options(ServerInfo.server_ctx, SSL_OP_NO_TLSv1);
513 #endif
514 };
470  
471   serverinfo_ssl_certificate_file: SSL_CERTIFICATE_FILE '=' QSTRING ';'
472   {
473 < #ifdef HAVE_LIBCRYPTO
519 <  if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx)
473 >  if (conf_parser_ctx.pass == 2)
474    {
475 <    if (!ServerInfo.rsa_private_key_file)
476 <    {
523 <      conf_error_report("No rsa_private_key_file specified, SSL disabled");
524 <      break;
525 <    }
526 <
527 <    if (SSL_CTX_use_certificate_file(ServerInfo.server_ctx, yylval.string,
528 <                                     SSL_FILETYPE_PEM) <= 0 ||
529 <        SSL_CTX_use_certificate_file(ServerInfo.client_ctx, yylval.string,
530 <                                     SSL_FILETYPE_PEM) <= 0)
531 <    {
532 <      report_crypto_errors();
533 <      conf_error_report("Could not open/read certificate file");
534 <      break;
535 <    }
536 <
537 <    if (SSL_CTX_use_PrivateKey_file(ServerInfo.server_ctx, ServerInfo.rsa_private_key_file,
538 <                                    SSL_FILETYPE_PEM) <= 0 ||
539 <        SSL_CTX_use_PrivateKey_file(ServerInfo.client_ctx, ServerInfo.rsa_private_key_file,
540 <                                    SSL_FILETYPE_PEM) <= 0)
541 <    {
542 <      report_crypto_errors();
543 <      conf_error_report("Could not read RSA private key");
544 <      break;
545 <    }
546 <
547 <    if (!SSL_CTX_check_private_key(ServerInfo.server_ctx) ||
548 <        !SSL_CTX_check_private_key(ServerInfo.client_ctx))
549 <    {
550 <      report_crypto_errors();
551 <      conf_error_report("Could not read RSA private key");
552 <      break;
553 <    }
475 >    xfree(ConfigServerInfo.ssl_certificate_file);
476 >    ConfigServerInfo.ssl_certificate_file = xstrdup(yylval.string);
477    }
555 #endif
478   };
479  
480   serverinfo_rsa_private_key_file: RSA_PRIVATE_KEY_FILE '=' QSTRING ';'
481   {
482 < #ifdef HAVE_LIBCRYPTO
561 <  BIO *file = NULL;
562 <
563 <  if (conf_parser_ctx.pass != 1)
564 <    break;
565 <
566 <  if (ServerInfo.rsa_private_key)
567 <  {
568 <    RSA_free(ServerInfo.rsa_private_key);
569 <    ServerInfo.rsa_private_key = NULL;
570 <  }
571 <
572 <  if (ServerInfo.rsa_private_key_file)
573 <  {
574 <    MyFree(ServerInfo.rsa_private_key_file);
575 <    ServerInfo.rsa_private_key_file = NULL;
576 <  }
577 <
578 <  ServerInfo.rsa_private_key_file = xstrdup(yylval.string);
579 <
580 <  if ((file = BIO_new_file(yylval.string, "r")) == NULL)
482 >  if (conf_parser_ctx.pass == 2)
483    {
484 <    conf_error_report("File open failed, ignoring");
485 <    break;
484 >    xfree(ConfigServerInfo.rsa_private_key_file);
485 >    ConfigServerInfo.rsa_private_key_file = xstrdup(yylval.string);
486    }
487 + };
488  
489 <  ServerInfo.rsa_private_key = PEM_read_bio_RSAPrivateKey(file, NULL, 0, NULL);
490 <
491 <  BIO_set_close(file, BIO_CLOSE);
589 <  BIO_free(file);
590 <
591 <  if (ServerInfo.rsa_private_key == NULL)
489 > serverinfo_ssl_dh_param_file: SSL_DH_PARAM_FILE '=' QSTRING ';'
490 > {
491 >  if (conf_parser_ctx.pass == 2)
492    {
493 <    conf_error_report("Couldn't extract key, ignoring");
494 <    break;
595 <  }
596 <
597 <  if (!RSA_check_key(ServerInfo.rsa_private_key))
598 <  {
599 <    RSA_free(ServerInfo.rsa_private_key);
600 <    ServerInfo.rsa_private_key = NULL;
601 <
602 <    conf_error_report("Invalid key, ignoring");
603 <    break;
493 >    xfree(ConfigServerInfo.ssl_dh_param_file);
494 >    ConfigServerInfo.ssl_dh_param_file = xstrdup(yylval.string);
495    }
496 + };
497  
498 <  if (RSA_size(ServerInfo.rsa_private_key) < 128)
498 > serverinfo_ssl_cipher_list: T_SSL_CIPHER_LIST '=' QSTRING ';'
499 > {
500 >  if (conf_parser_ctx.pass == 2)
501    {
502 <    RSA_free(ServerInfo.rsa_private_key);
503 <    ServerInfo.rsa_private_key = NULL;
610 <
611 <    conf_error_report("Ignoring serverinfo::rsa_private_key_file -- need at least a 1024 bit key size");
502 >    xfree(ConfigServerInfo.ssl_cipher_list);
503 >    ConfigServerInfo.ssl_cipher_list = xstrdup(yylval.string);
504    }
613 #endif
505   };
506  
507 < serverinfo_ssl_dh_param_file: SSL_DH_PARAM_FILE '=' QSTRING ';'
507 > serverinfo_ssl_message_digest_algorithm: SSL_MESSAGE_DIGEST_ALGORITHM '=' QSTRING ';'
508   {
509 < /* TBD - XXX: error reporting */
619 < #ifdef HAVE_LIBCRYPTO
620 <  if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx)
509 >  if (conf_parser_ctx.pass == 2)
510    {
511 <    BIO *file = BIO_new_file(yylval.string, "r");
512 <
624 <    if (file)
625 <    {
626 <      DH *dh = PEM_read_bio_DHparams(file, NULL, NULL, NULL);
627 <
628 <      BIO_free(file);
629 <
630 <      if (dh)
631 <      {
632 <        if (DH_size(dh) < 128)
633 <          conf_error_report("Ignoring serverinfo::ssl_dh_param_file -- need at least a 1024 bit DH prime size");
634 <        else
635 <          SSL_CTX_set_tmp_dh(ServerInfo.server_ctx, dh);
636 <
637 <        DH_free(dh);
638 <      }
639 <    }
511 >    xfree(ConfigServerInfo.ssl_message_digest_algorithm);
512 >    ConfigServerInfo.ssl_message_digest_algorithm = xstrdup(yylval.string);
513    }
514 < #endif
642 < };
514 > }
515  
516 < serverinfo_ssl_cipher_list: T_SSL_CIPHER_LIST '=' QSTRING ';'
516 > serverinfo_ssl_dh_elliptic_curve: SSL_DH_ELLIPTIC_CURVE '=' QSTRING ';'
517   {
518 < #ifdef HAVE_LIBCRYPTO
519 <  if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx)
520 <    SSL_CTX_set_cipher_list(ServerInfo.server_ctx, yylval.string);
521 < #endif
518 >  if (conf_parser_ctx.pass == 2)
519 >  {
520 >    xfree(ConfigServerInfo.ssl_dh_elliptic_curve);
521 >    ConfigServerInfo.ssl_dh_elliptic_curve = xstrdup(yylval.string);
522 >  }
523   };
524  
525   serverinfo_name: NAME '=' QSTRING ';'
526   {
527 <  /* this isn't rehashable */
528 <  if (conf_parser_ctx.pass == 2 && !ServerInfo.name)
527 >  /* This isn't rehashable */
528 >  if (conf_parser_ctx.pass == 2 && ConfigServerInfo.name == NULL)
529    {
530 <    if (valid_servname(yylval.string))
531 <      ServerInfo.name = xstrdup(yylval.string);
530 >    if (server_valid_name(yylval.string) == true)
531 >      ConfigServerInfo.name = xstrdup(yylval.string);
532      else
533      {
534        conf_error_report("Ignoring serverinfo::name -- invalid name. Aborting.");
535 <      exit(0);
535 >      exit(EXIT_FAILURE);
536      }
537    }
538   };
539  
540   serverinfo_sid: IRCD_SID '=' QSTRING ';'
541   {
542 <  /* this isn't rehashable */
543 <  if (conf_parser_ctx.pass == 2 && !ServerInfo.sid)
542 >  /* This isn't rehashable */
543 >  if (conf_parser_ctx.pass == 2 && ConfigServerInfo.sid == NULL)
544    {
545      if (valid_sid(yylval.string))
546 <      ServerInfo.sid = xstrdup(yylval.string);
546 >      ConfigServerInfo.sid = xstrdup(yylval.string);
547      else
548      {
549        conf_error_report("Ignoring serverinfo::sid -- invalid SID. Aborting.");
550 <      exit(0);
550 >      exit(EXIT_FAILURE);
551      }
552    }
553   };
# Line 683 | Line 556 | serverinfo_description: DESCRIPTION '='
556   {
557    if (conf_parser_ctx.pass == 2)
558    {
559 <    MyFree(ServerInfo.description);
560 <    ServerInfo.description = xstrdup(yylval.string);
559 >    xfree(ConfigServerInfo.description);
560 >    ConfigServerInfo.description = xstrdup(yylval.string);
561 >    strlcpy(me.info, ConfigServerInfo.description, sizeof(me.info));
562    }
563   };
564  
# Line 694 | Line 568 | serverinfo_network_name: NETWORK_NAME '=
568    {
569      char *p;
570  
571 <    if ((p = strchr(yylval.string, ' ')) != NULL)
572 <      p = '\0';
571 >    if ((p = strchr(yylval.string, ' ')))
572 >      *p = '\0';
573  
574 <    MyFree(ServerInfo.network_name);
575 <    ServerInfo.network_name = xstrdup(yylval.string);
574 >    xfree(ConfigServerInfo.network_name);
575 >    ConfigServerInfo.network_name = xstrdup(yylval.string);
576    }
577   };
578  
# Line 707 | Line 581 | serverinfo_network_desc: NETWORK_DESC '=
581    if (conf_parser_ctx.pass != 2)
582      break;
583  
584 <  MyFree(ServerInfo.network_desc);
585 <  ServerInfo.network_desc = xstrdup(yylval.string);
584 >  xfree(ConfigServerInfo.network_desc);
585 >  ConfigServerInfo.network_desc = xstrdup(yylval.string);
586   };
587  
588 < serverinfo_vhost: VHOST '=' QSTRING ';'
715 < {
716 <  if (conf_parser_ctx.pass == 2 && *yylval.string != '*')
717 <  {
718 <    struct addrinfo hints, *res;
719 <
720 <    memset(&hints, 0, sizeof(hints));
721 <
722 <    hints.ai_family   = AF_UNSPEC;
723 <    hints.ai_socktype = SOCK_STREAM;
724 <    hints.ai_flags    = AI_PASSIVE | AI_NUMERICHOST;
725 <
726 <    if (getaddrinfo(yylval.string, NULL, &hints, &res))
727 <      ilog(LOG_TYPE_IRCD, "Invalid netmask for server vhost(%s)", yylval.string);
728 <    else
729 <    {
730 <      assert(res != NULL);
731 <
732 <      memcpy(&ServerInfo.ip, res->ai_addr, res->ai_addrlen);
733 <      ServerInfo.ip.ss.ss_family = res->ai_family;
734 <      ServerInfo.ip.ss_len = res->ai_addrlen;
735 <      freeaddrinfo(res);
736 <
737 <      ServerInfo.specific_ipv4_vhost = 1;
738 <    }
739 <  }
740 < };
741 <
742 < serverinfo_vhost6: VHOST6 '=' QSTRING ';'
743 < {
744 < #ifdef IPV6
745 <  if (conf_parser_ctx.pass == 2 && *yylval.string != '*')
746 <  {
747 <    struct addrinfo hints, *res;
748 <
749 <    memset(&hints, 0, sizeof(hints));
750 <
751 <    hints.ai_family   = AF_UNSPEC;
752 <    hints.ai_socktype = SOCK_STREAM;
753 <    hints.ai_flags    = AI_PASSIVE | AI_NUMERICHOST;
754 <
755 <    if (getaddrinfo(yylval.string, NULL, &hints, &res))
756 <      ilog(LOG_TYPE_IRCD, "Invalid netmask for server vhost6(%s)", yylval.string);
757 <    else
758 <    {
759 <      assert(res != NULL);
760 <
761 <      memcpy(&ServerInfo.ip6, res->ai_addr, res->ai_addrlen);
762 <      ServerInfo.ip6.ss.ss_family = res->ai_family;
763 <      ServerInfo.ip6.ss_len = res->ai_addrlen;
764 <      freeaddrinfo(res);
765 <
766 <      ServerInfo.specific_ipv6_vhost = 1;
767 <    }
768 <  }
769 < #endif
770 < };
771 <
772 < serverinfo_max_clients: T_MAX_CLIENTS '=' NUMBER ';'
588 > serverinfo_default_max_clients: DEFAULT_MAX_CLIENTS '=' NUMBER ';'
589   {
590    if (conf_parser_ctx.pass != 2)
591      break;
592  
593 <  if ($3 < MAXCLIENTS_MIN)
593 >  if ($3 < 1)
594    {
595 <    char buf[IRCD_BUFSIZE];
596 <
781 <    snprintf(buf, sizeof(buf), "MAXCLIENTS too low, setting to %d", MAXCLIENTS_MIN);
782 <    conf_error_report(buf);
783 <    ServerInfo.max_clients = MAXCLIENTS_MIN;
595 >    conf_error_report("default_max_clients too low, setting to 1");
596 >    ConfigServerInfo.default_max_clients = 1;
597    }
598    else if ($3 > MAXCLIENTS_MAX)
599    {
600 <    char buf[IRCD_BUFSIZE];
600 >    char buf[IRCD_BUFSIZE] = "";
601  
602 <    snprintf(buf, sizeof(buf), "MAXCLIENTS too high, setting to %d", MAXCLIENTS_MAX);
602 >    snprintf(buf, sizeof(buf), "default_max_clients too high, setting to %d", MAXCLIENTS_MAX);
603      conf_error_report(buf);
604 <    ServerInfo.max_clients = MAXCLIENTS_MAX;
604 >
605 >    ConfigServerInfo.default_max_clients = MAXCLIENTS_MAX;
606    }
607    else
608 <    ServerInfo.max_clients = $3;
608 >    ConfigServerInfo.default_max_clients = $3;
609   };
610  
611   serverinfo_max_nick_length: MAX_NICK_LENGTH '=' NUMBER ';'
# Line 802 | Line 616 | serverinfo_max_nick_length: MAX_NICK_LEN
616    if ($3 < 9)
617    {
618      conf_error_report("max_nick_length too low, setting to 9");
619 <    ServerInfo.max_nick_length = 9;
619 >    ConfigServerInfo.max_nick_length = 9;
620    }
621    else if ($3 > NICKLEN)
622    {
623 <    char buf[IRCD_BUFSIZE];
623 >    char buf[IRCD_BUFSIZE] = "";
624  
625      snprintf(buf, sizeof(buf), "max_nick_length too high, setting to %d", NICKLEN);
626      conf_error_report(buf);
627 <    ServerInfo.max_nick_length = NICKLEN;
627 >
628 >    ConfigServerInfo.max_nick_length = NICKLEN;
629    }
630    else
631 <    ServerInfo.max_nick_length = $3;
631 >    ConfigServerInfo.max_nick_length = $3;
632   };
633  
634   serverinfo_max_topic_length: MAX_TOPIC_LENGTH '=' NUMBER ';'
# Line 824 | Line 639 | serverinfo_max_topic_length: MAX_TOPIC_L
639    if ($3 < 80)
640    {
641      conf_error_report("max_topic_length too low, setting to 80");
642 <    ServerInfo.max_topic_length = 80;
642 >    ConfigServerInfo.max_topic_length = 80;
643    }
644    else if ($3 > TOPICLEN)
645    {
646 <    char buf[IRCD_BUFSIZE];
646 >    char buf[IRCD_BUFSIZE] = "";
647  
648      snprintf(buf, sizeof(buf), "max_topic_length too high, setting to %d", TOPICLEN);
649      conf_error_report(buf);
650 <    ServerInfo.max_topic_length = TOPICLEN;
650 >
651 >    ConfigServerInfo.max_topic_length = TOPICLEN;
652    }
653    else
654 <    ServerInfo.max_topic_length = $3;
654 >    ConfigServerInfo.max_topic_length = $3;
655   };
656  
657   serverinfo_hub: HUB '=' TBOOL ';'
658   {
659    if (conf_parser_ctx.pass == 2)
660 <    ServerInfo.hub = yylval.number;
660 >    ConfigServerInfo.hub = yylval.number;
661   };
662  
663 +
664   /***************************************************************************
665 < * admin section
665 > * admin {} section
666   ***************************************************************************/
667 < admin_entry: ADMIN  '{' admin_items '}' ';' ;
667 > admin_entry: ADMIN '{' admin_items '}' ';' ;
668  
669   admin_items: admin_items admin_item | admin_item;
670 < admin_item:  admin_name | admin_description |
671 <             admin_email | error ';' ;
670 > admin_item:  admin_name |
671 >             admin_description |
672 >             admin_email |
673 >             error ';' ;
674  
675   admin_name: NAME '=' QSTRING ';'
676   {
677    if (conf_parser_ctx.pass != 2)
678      break;
679  
680 <  MyFree(AdminInfo.name);
681 <  AdminInfo.name = xstrdup(yylval.string);
680 >  xfree(ConfigAdminInfo.name);
681 >  ConfigAdminInfo.name = xstrdup(yylval.string);
682   };
683  
684   admin_email: EMAIL '=' QSTRING ';'
# Line 867 | Line 686 | admin_email: EMAIL '=' QSTRING ';'
686    if (conf_parser_ctx.pass != 2)
687      break;
688  
689 <  MyFree(AdminInfo.email);
690 <  AdminInfo.email = xstrdup(yylval.string);
689 >  xfree(ConfigAdminInfo.email);
690 >  ConfigAdminInfo.email = xstrdup(yylval.string);
691   };
692  
693   admin_description: DESCRIPTION '=' QSTRING ';'
# Line 876 | Line 695 | admin_description: DESCRIPTION '=' QSTRI
695    if (conf_parser_ctx.pass != 2)
696      break;
697  
698 <  MyFree(AdminInfo.description);
699 <  AdminInfo.description = xstrdup(yylval.string);
698 >  xfree(ConfigAdminInfo.description);
699 >  ConfigAdminInfo.description = xstrdup(yylval.string);
700   };
701  
702 +
703   /***************************************************************************
704 < * motd section
704 > * motd {} section
705   ***************************************************************************/
706   motd_entry: MOTD
707   {
# Line 889 | Line 709 | motd_entry: MOTD
709      reset_block_state();
710   } '{' motd_items '}' ';'
711   {
712 <  dlink_node *ptr = NULL;
712 >  dlink_node *node = NULL;
713  
714    if (conf_parser_ctx.pass != 2)
715      break;
# Line 897 | Line 717 | motd_entry: MOTD
717    if (!block_state.file.buf[0])
718      break;
719  
720 <  DLINK_FOREACH(ptr, block_state.mask.list.head)
721 <    motd_add(ptr->data, block_state.file.buf);
720 >  DLINK_FOREACH(node, block_state.mask.list.head)
721 >    motd_add(node->data, block_state.file.buf);
722   };
723  
724   motd_items: motd_items motd_item | motd_item;
# Line 916 | Line 736 | motd_file: T_FILE '=' QSTRING ';'
736      strlcpy(block_state.file.buf, yylval.string, sizeof(block_state.file.buf));
737   };
738  
739 +
740 + /***************************************************************************
741 + * pseudo {} section
742 + ***************************************************************************/
743 + pseudo_entry: T_PSEUDO
744 + {
745 +  if (conf_parser_ctx.pass == 2)
746 +    reset_block_state();
747 + } '{' pseudo_items '}' ';'
748 + {
749 +  if (conf_parser_ctx.pass != 2)
750 +    break;
751 +
752 +  if (!block_state.command.buf[0] ||
753 +      !block_state.name.buf[0] ||
754 +      !block_state.nick.buf[0] ||
755 +      !block_state.host.buf[0])
756 +    break;
757 +
758 +  pseudo_register(block_state.name.buf, block_state.nick.buf, block_state.host.buf,
759 +                  block_state.prepend.buf, block_state.command.buf);
760 + };
761 +
762 + pseudo_items: pseudo_items pseudo_item | pseudo_item;
763 + pseudo_item:  pseudo_command | pseudo_prepend | pseudo_name | pseudo_target | error ';' ;
764 +
765 + pseudo_command: T_COMMAND '=' QSTRING ';'
766 + {
767 +  if (conf_parser_ctx.pass == 2)
768 +    strlcpy(block_state.command.buf, yylval.string, sizeof(block_state.command.buf));
769 + };
770 +
771 + pseudo_name: NAME '=' QSTRING ';'
772 + {
773 +  if (conf_parser_ctx.pass == 2)
774 +    strlcpy(block_state.name.buf, yylval.string, sizeof(block_state.name.buf));
775 + };
776 +
777 + pseudo_prepend: T_PREPEND '=' QSTRING ';'
778 + {
779 +  if (conf_parser_ctx.pass == 2)
780 +    strlcpy(block_state.prepend.buf, yylval.string, sizeof(block_state.prepend.buf));
781 + };
782 +
783 + pseudo_target: T_TARGET '=' QSTRING ';'
784 + {
785 +  if (conf_parser_ctx.pass == 2)
786 +  {
787 +    struct split_nuh_item nuh;
788 +
789 +    nuh.nuhmask  = yylval.string;
790 +    nuh.nickptr  = NULL;
791 +    nuh.userptr  = block_state.nick.buf;
792 +    nuh.hostptr  = block_state.host.buf;
793 +    nuh.nicksize = 0;
794 +    nuh.usersize = sizeof(block_state.nick.buf);
795 +    nuh.hostsize = sizeof(block_state.host.buf);
796 +
797 +    split_nuh(&nuh);
798 +  }
799 + };
800 +
801 +
802   /***************************************************************************
803 < *  section logging
803 > * log {} section
804   ***************************************************************************/
805   logging_entry:          T_LOG  '{' logging_items '}' ';' ;
806   logging_items:          logging_items logging_item | logging_item ;
807  
808 < logging_item:           logging_use_logging | logging_file_entry |
809 <                        error ';' ;
808 > logging_item:           logging_use_logging | logging_file_entry |
809 >                        error ';' ;
810  
811   logging_use_logging: USE_LOGGING '=' TBOOL ';'
812   {
813    if (conf_parser_ctx.pass == 2)
814 <    ConfigLoggingEntry.use_logging = yylval.number;
814 >    ConfigLog.use_logging = yylval.number;
815   };
816  
817   logging_file_entry:
# Line 982 | Line 865 | logging_file_type_item:  USER
865   {
866    if (conf_parser_ctx.pass == 2)
867      block_state.type.value = LOG_TYPE_OPER;
985 } | GLINE
986 {
987  if (conf_parser_ctx.pass == 2)
988    block_state.type.value = LOG_TYPE_GLINE;
868   } | XLINE
869   {
870    if (conf_parser_ctx.pass == 2)
# Line 1014 | Line 893 | logging_file_type_item:  USER
893  
894  
895   /***************************************************************************
896 < * section oper
896 > * operator {} section
897   ***************************************************************************/
898   oper_entry: OPERATOR
899   {
# Line 1025 | Line 904 | oper_entry: OPERATOR
904    block_state.flags.value |= CONF_FLAGS_ENCRYPTED;
905   } '{' oper_items '}' ';'
906   {
907 <  dlink_node *ptr = NULL;
907 >  dlink_node *node = NULL;
908  
909    if (conf_parser_ctx.pass != 2)
910      break;
911  
912    if (!block_state.name.buf[0])
913      break;
914 < #ifdef HAVE_LIBCRYPTO
1036 <  if (!block_state.file.buf[0] &&
1037 <      !block_state.rpass.buf[0])
1038 <    break;
1039 < #else
914 >
915    if (!block_state.rpass.buf[0])
916      break;
1042 #endif
917  
918 <  DLINK_FOREACH(ptr, block_state.mask.list.head)
918 >  DLINK_FOREACH(node, block_state.mask.list.head)
919    {
1046    struct MaskItem *conf = NULL;
920      struct split_nuh_item nuh;
921 +    char *s = node->data;
922  
923 <    nuh.nuhmask  = ptr->data;
923 >    if (EmptyString(s))
924 >      continue;
925 >
926 >    nuh.nuhmask  = s;
927      nuh.nickptr  = NULL;
928      nuh.userptr  = block_state.user.buf;
929      nuh.hostptr  = block_state.host.buf;
930 +
931      nuh.nicksize = 0;
932      nuh.usersize = sizeof(block_state.user.buf);
933      nuh.hostsize = sizeof(block_state.host.buf);
934 +
935      split_nuh(&nuh);
936  
937 <    conf         = conf_make(CONF_OPER);
938 <    conf->name   = xstrdup(block_state.name.buf);
939 <    conf->user   = xstrdup(block_state.user.buf);
940 <    conf->host   = xstrdup(block_state.host.buf);
937 >    struct MaskItem *conf = conf_make(CONF_OPER);
938 >    conf->addr = xcalloc(sizeof(*conf->addr));
939 >    conf->name = xstrdup(block_state.name.buf);
940 >    conf->user = xstrdup(block_state.user.buf);
941 >    conf->host = xstrdup(block_state.host.buf);
942  
943      if (block_state.cert.buf[0])
944        conf->certfp = xstrdup(block_state.cert.buf);
# Line 1066 | Line 946 | oper_entry: OPERATOR
946      if (block_state.rpass.buf[0])
947        conf->passwd = xstrdup(block_state.rpass.buf);
948  
949 +    if (block_state.whois.buf[0])
950 +      conf->whois = xstrdup(block_state.whois.buf);
951 +
952      conf->flags = block_state.flags.value;
953      conf->modes = block_state.modes.value;
954      conf->port  = block_state.port.value;
955 <    conf->htype = parse_netmask(conf->host, &conf->addr, &conf->bits);
955 >    conf->htype = parse_netmask(conf->host, conf->addr, &conf->bits);
956  
957      conf_add_class_to_conf(conf, block_state.class.buf);
1075
1076 #ifdef HAVE_LIBCRYPTO
1077    if (block_state.file.buf[0])
1078    {
1079      BIO *file = NULL;
1080      RSA *pkey = NULL;
1081
1082      if ((file = BIO_new_file(block_state.file.buf, "r")) == NULL)
1083      {
1084        conf_error_report("Ignoring rsa_public_key_file -- file doesn't exist");
1085        break;
1086      }
1087
1088      if ((pkey = PEM_read_bio_RSA_PUBKEY(file, NULL, 0, NULL)) == NULL)
1089        conf_error_report("Ignoring rsa_public_key_file -- Key invalid; check key syntax.");
1090
1091      conf->rsa_public_key = pkey;
1092      BIO_set_close(file, BIO_CLOSE);
1093      BIO_free(file);
1094    }
1095 #endif /* HAVE_LIBCRYPTO */
958    }
959   };
960  
961   oper_items:     oper_items oper_item | oper_item;
962 < oper_item:      oper_name | oper_user | oper_password |
963 <                oper_umodes | oper_class | oper_encrypted |
964 <                oper_rsa_public_key_file | oper_ssl_certificate_fingerprint |
965 <                oper_ssl_connection_required |
966 <                oper_flags | error ';' ;
962 > oper_item:      oper_name |
963 >                oper_user |
964 >                oper_password |
965 >                oper_whois |
966 >                oper_umodes |
967 >                oper_class |
968 >                oper_encrypted |
969 >                oper_ssl_certificate_fingerprint |
970 >                oper_ssl_connection_required |
971 >                oper_flags |
972 >                error ';' ;
973  
974   oper_name: NAME '=' QSTRING ';'
975   {
# Line 1121 | Line 989 | oper_password: PASSWORD '=' QSTRING ';'
989      strlcpy(block_state.rpass.buf, yylval.string, sizeof(block_state.rpass.buf));
990   };
991  
992 + oper_whois: WHOIS '=' QSTRING ';'
993 + {
994 +  if (conf_parser_ctx.pass == 2)
995 +    strlcpy(block_state.whois.buf, yylval.string, sizeof(block_state.whois.buf));
996 + };
997 +
998   oper_encrypted: ENCRYPTED '=' TBOOL ';'
999   {
1000    if (conf_parser_ctx.pass != 2)
# Line 1132 | Line 1006 | oper_encrypted: ENCRYPTED '=' TBOOL ';'
1006      block_state.flags.value &= ~CONF_FLAGS_ENCRYPTED;
1007   };
1008  
1135 oper_rsa_public_key_file: RSA_PUBLIC_KEY_FILE '=' QSTRING ';'
1136 {
1137  if (conf_parser_ctx.pass == 2)
1138    strlcpy(block_state.file.buf, yylval.string, sizeof(block_state.file.buf));
1139 };
1140
1009   oper_ssl_certificate_fingerprint: SSL_CERTIFICATE_FINGERPRINT '=' QSTRING ';'
1010   {
1011    if (conf_parser_ctx.pass == 2)
# Line 1192 | Line 1060 | oper_umodes_item:  T_BOTS
1060   {
1061    if (conf_parser_ctx.pass == 2)
1062      block_state.modes.value |= UMODE_HIDDEN;
1063 + } | HIDE_CHANS
1064 + {
1065 +  if (conf_parser_ctx.pass == 2)
1066 +    block_state.modes.value |= UMODE_HIDECHANS;
1067 + } | HIDE_IDLE
1068 + {
1069 +  if (conf_parser_ctx.pass == 2)
1070 +    block_state.modes.value |= UMODE_HIDEIDLE;
1071   } | T_SKILL
1072   {
1073    if (conf_parser_ctx.pass == 2)
# Line 1216 | Line 1092 | oper_umodes_item:  T_BOTS
1092   {
1093    if (conf_parser_ctx.pass == 2)
1094      block_state.modes.value |= UMODE_EXTERNAL;
1219 } | T_OPERWALL
1220 {
1221  if (conf_parser_ctx.pass == 2)
1222    block_state.modes.value |= UMODE_OPERWALL;
1095   } | T_SERVNOTICE
1096   {
1097    if (conf_parser_ctx.pass == 2)
# Line 1252 | Line 1124 | oper_umodes_item:  T_BOTS
1124   {
1125    if (conf_parser_ctx.pass == 2)
1126      block_state.modes.value |= UMODE_FARCONNECT;
1127 + } | EXPIRATION
1128 + {
1129 +  if (conf_parser_ctx.pass == 2)
1130 +    block_state.modes.value |= UMODE_EXPIRATION;
1131   };
1132  
1133   oper_flags: IRCD_FLAGS
# Line 1288 | Line 1164 | oper_flags_item: KILL ':' REMOTE
1164   } | KLINE
1165   {
1166    if (conf_parser_ctx.pass == 2)
1167 <    block_state.port.value |= OPER_FLAG_K;
1167 >    block_state.port.value |= OPER_FLAG_KLINE;
1168   } | UNKLINE
1169   {
1170    if (conf_parser_ctx.pass == 2)
# Line 1309 | Line 1185 | oper_flags_item: KILL ':' REMOTE
1185   {
1186    if (conf_parser_ctx.pass == 2)
1187      block_state.port.value |= OPER_FLAG_UNXLINE;
1312 } | GLINE
1313 {
1314  if (conf_parser_ctx.pass == 2)
1315    block_state.port.value |= OPER_FLAG_GLINE;
1188   } | DIE
1189   {
1190    if (conf_parser_ctx.pass == 2)
# Line 1321 | Line 1193 | oper_flags_item: KILL ':' REMOTE
1193   {
1194    if (conf_parser_ctx.pass == 2)
1195      block_state.port.value |= OPER_FLAG_RESTART;
1196 + } | REHASH ':' REMOTE
1197 + {
1198 +  if (conf_parser_ctx.pass == 2)
1199 +    block_state.port.value |= OPER_FLAG_REHASH_REMOTE;
1200   } | REHASH
1201   {
1202    if (conf_parser_ctx.pass == 2)
# Line 1329 | Line 1205 | oper_flags_item: KILL ':' REMOTE
1205   {
1206    if (conf_parser_ctx.pass == 2)
1207      block_state.port.value |= OPER_FLAG_ADMIN;
1332 } | T_OPERWALL
1333 {
1334  if (conf_parser_ctx.pass == 2)
1335    block_state.port.value |= OPER_FLAG_OPERWALL;
1208   } | T_GLOBOPS
1209   {
1210    if (conf_parser_ctx.pass == 2)
# Line 1357 | Line 1229 | oper_flags_item: KILL ':' REMOTE
1229   {
1230    if (conf_parser_ctx.pass == 2)
1231      block_state.port.value |= OPER_FLAG_MODULE;
1232 + } | T_OPME
1233 + {
1234 +  if (conf_parser_ctx.pass == 2)
1235 +    block_state.port.value |= OPER_FLAG_OPME;
1236 + } | NICK ':' RESV
1237 + {
1238 +  if (conf_parser_ctx.pass == 2)
1239 +    block_state.port.value |= OPER_FLAG_NICK_RESV;
1240 + } | JOIN ':' RESV
1241 + {
1242 +  if (conf_parser_ctx.pass == 2)
1243 +    block_state.port.value |= OPER_FLAG_JOIN_RESV;
1244 + } | RESV
1245 + {
1246 +  if (conf_parser_ctx.pass == 2)
1247 +    block_state.port.value |= OPER_FLAG_RESV;
1248 + } | T_UNRESV
1249 + {
1250 +  if (conf_parser_ctx.pass == 2)
1251 +    block_state.port.value |= OPER_FLAG_UNRESV;
1252 + } | CLOSE
1253 + {
1254 +  if (conf_parser_ctx.pass == 2)
1255 +    block_state.port.value |= OPER_FLAG_CLOSE;
1256   };
1257  
1258  
1259   /***************************************************************************
1260 < *  section class
1260 > * class {} section
1261   ***************************************************************************/
1262   class_entry: CLASS
1263   {
# Line 1377 | Line 1273 | class_entry: CLASS
1273    block_state.max_recvq.value = DEFAULT_RECVQ;
1274   } '{' class_items '}' ';'
1275   {
1380  struct ClassItem *class = NULL;
1381
1276    if (conf_parser_ctx.pass != 1)
1277      break;
1278  
1279    if (!block_state.class.buf[0])
1280      break;
1281  
1282 <  if (!(class = class_find(block_state.class.buf, 0)))
1282 >  struct ClassItem *class = class_find(block_state.class.buf, false);
1283 >  if (class == NULL)
1284      class = class_make();
1285  
1286 <  class->active = 1;
1287 <  MyFree(class->name);
1286 >  class->active = true;
1287 >  xfree(class->name);
1288    class->name = xstrdup(block_state.class.buf);
1289    class->ping_freq = block_state.ping_freq.value;
1290 <  class->max_perip = block_state.max_perip.value;
1290 >  class->max_perip_local = block_state.max_perip_local.value;
1291 >  class->max_perip_global = block_state.max_perip_global.value;
1292    class->con_freq = block_state.con_freq.value;
1293    class->max_total = block_state.max_total.value;
1398  class->max_global = block_state.max_global.value;
1399  class->max_local = block_state.max_local.value;
1400  class->max_ident = block_state.max_ident.value;
1294    class->max_sendq = block_state.max_sendq.value;
1295    class->max_recvq = block_state.max_recvq.value;
1296 +  class->max_channels = block_state.max_channels.value;
1297  
1298    if (block_state.min_idle.value > block_state.max_idle.value)
1299    {
# Line 1412 | Line 1306 | class_entry: CLASS
1306    class->min_idle = block_state.min_idle.value;
1307    class->max_idle = block_state.max_idle.value;
1308  
1309 <  if (class->number_per_cidr && block_state.number_per_cidr.value)
1310 <    if ((class->cidr_bitlen_ipv4 && block_state.cidr_bitlen_ipv4.value) ||
1417 <        (class->cidr_bitlen_ipv6 && block_state.cidr_bitlen_ipv6.value))
1418 <      if ((class->cidr_bitlen_ipv4 != block_state.cidr_bitlen_ipv4.value) ||
1419 <          (class->cidr_bitlen_ipv6 != block_state.cidr_bitlen_ipv6.value))
1420 <        rebuild_cidr_list(class);
1421 <
1309 >  bool diff = (class->cidr_bitlen_ipv4 != block_state.cidr_bitlen_ipv4.value ||
1310 >               class->cidr_bitlen_ipv6 != block_state.cidr_bitlen_ipv6.value);
1311    class->cidr_bitlen_ipv4 = block_state.cidr_bitlen_ipv4.value;
1312    class->cidr_bitlen_ipv6 = block_state.cidr_bitlen_ipv6.value;
1313    class->number_per_cidr = block_state.number_per_cidr.value;
1314 +
1315 +  if (diff)
1316 +    class_ip_limit_rebuild(class);
1317   };
1318  
1319   class_items:    class_items class_item | class_item;
1320   class_item:     class_name |
1321 <                class_cidr_bitlen_ipv4 | class_cidr_bitlen_ipv6 |
1321 >                class_cidr_bitlen_ipv4 |
1322 >                class_cidr_bitlen_ipv6 |
1323                  class_ping_time |
1324 <                class_number_per_cidr |
1325 <                class_number_per_ip |
1324 >                class_number_per_cidr |
1325 >                class_number_per_ip_local |
1326 >                class_number_per_ip_global |
1327                  class_connectfreq |
1328 +                class_max_channels |
1329                  class_max_number |
1330 <                class_max_global |
1331 <                class_max_local |
1437 <                class_max_ident |
1438 <                class_sendq | class_recvq |
1330 >                class_sendq |
1331 >                class_recvq |
1332                  class_min_idle |
1333                  class_max_idle |
1334                  class_flags |
1335 <                error ';' ;
1335 >                error ';' ;
1336  
1337   class_name: NAME '=' QSTRING ';'
1338   {
# Line 1453 | Line 1346 | class_ping_time: PING_TIME '=' timespec
1346      block_state.ping_freq.value = $3;
1347   };
1348  
1349 < class_number_per_ip: NUMBER_PER_IP '=' NUMBER ';'
1349 > class_number_per_ip_local: NUMBER_PER_IP_LOCAL '=' NUMBER ';'
1350   {
1351    if (conf_parser_ctx.pass == 1)
1352 <    block_state.max_perip.value = $3;
1352 >    block_state.max_perip_local.value = $3;
1353   };
1354  
1355 < class_connectfreq: CONNECTFREQ '=' timespec ';'
1463 < {
1464 <  if (conf_parser_ctx.pass == 1)
1465 <    block_state.con_freq.value = $3;
1466 < };
1467 <
1468 < class_max_number: MAX_NUMBER '=' NUMBER ';'
1355 > class_number_per_ip_global: NUMBER_PER_IP_GLOBAL '=' NUMBER ';'
1356   {
1357    if (conf_parser_ctx.pass == 1)
1358 <    block_state.max_total.value = $3;
1358 >    block_state.max_perip_global.value = $3;
1359   };
1360  
1361 < class_max_global: MAX_GLOBAL '=' NUMBER ';'
1361 > class_connectfreq: CONNECTFREQ '=' timespec ';'
1362   {
1363    if (conf_parser_ctx.pass == 1)
1364 <    block_state.max_global.value = $3;
1364 >    block_state.con_freq.value = $3;
1365   };
1366  
1367 < class_max_local: MAX_LOCAL '=' NUMBER ';'
1367 > class_max_channels: MAX_CHANNELS '=' NUMBER ';'
1368   {
1369    if (conf_parser_ctx.pass == 1)
1370 <    block_state.max_local.value = $3;
1370 >    block_state.max_channels.value = $3;
1371   };
1372  
1373 < class_max_ident: MAX_IDENT '=' NUMBER ';'
1373 > class_max_number: MAX_NUMBER '=' NUMBER ';'
1374   {
1375    if (conf_parser_ctx.pass == 1)
1376 <    block_state.max_ident.value = $3;
1376 >    block_state.max_total.value = $3;
1377   };
1378  
1379   class_sendq: SENDQ '=' sizespec ';'
# Line 1557 | Line 1444 | class_flags_item: RANDOM_IDLE
1444  
1445  
1446   /***************************************************************************
1447 < *  section listen
1447 > * listen {} section
1448   ***************************************************************************/
1449   listen_entry: LISTEN
1450   {
# Line 1596 | Line 1483 | port_item: NUMBER
1483   {
1484    if (conf_parser_ctx.pass == 2)
1485    {
1486 + #ifndef HAVE_TLS
1487      if (block_state.flags.value & LISTENER_SSL)
1488 < #ifdef HAVE_LIBCRYPTO
1489 <      if (!ServerInfo.server_ctx)
1488 >    {
1489 >      conf_error_report("TLS not available - port closed");
1490 >      break;
1491 >    }
1492   #endif
1493 <      {
1604 <        conf_error_report("SSL not available - port closed");
1605 <        break;
1606 <      }
1607 <    add_listener($1, block_state.addr.buf, block_state.flags.value);
1493 >    listener_add($1, block_state.addr.buf, block_state.flags.value);
1494    }
1495   } | NUMBER TWODOTS NUMBER
1496   {
1497    if (conf_parser_ctx.pass == 2)
1498    {
1499 <    int i;
1614 <
1499 > #ifndef HAVE_TLS
1500      if (block_state.flags.value & LISTENER_SSL)
1501 < #ifdef HAVE_LIBCRYPTO
1502 <      if (!ServerInfo.server_ctx)
1501 >    {
1502 >      conf_error_report("TLS not available - port closed");
1503 >      break;
1504 >    }
1505   #endif
1619      {
1620        conf_error_report("SSL not available - port closed");
1621        break;
1622      }
1506  
1507 <    for (i = $1; i <= $3; ++i)
1508 <      add_listener(i, block_state.addr.buf, block_state.flags.value);
1507 >    for (int i = $1; i <= $3; ++i)
1508 >      listener_add(i, block_state.addr.buf, block_state.flags.value);
1509    }
1510   };
1511  
# Line 1638 | Line 1521 | listen_host: HOST '=' QSTRING ';'
1521      strlcpy(block_state.addr.buf, yylval.string, sizeof(block_state.addr.buf));
1522   };
1523  
1524 +
1525   /***************************************************************************
1526 < *  section auth
1526 > * auth {} section
1527   ***************************************************************************/
1528   auth_entry: IRCD_AUTH
1529   {
# Line 1647 | Line 1531 | auth_entry: IRCD_AUTH
1531      reset_block_state();
1532   } '{' auth_items '}' ';'
1533   {
1534 <  dlink_node *ptr = NULL;
1534 >  dlink_node *node = NULL;
1535  
1536    if (conf_parser_ctx.pass != 2)
1537      break;
1538  
1539 <  DLINK_FOREACH(ptr, block_state.mask.list.head)
1539 >  DLINK_FOREACH(node, block_state.mask.list.head)
1540    {
1657    struct MaskItem *conf = NULL;
1541      struct split_nuh_item nuh;
1542 +    char *s = node->data;
1543 +
1544 +    if (EmptyString(s))
1545 +      continue;
1546  
1547 <    nuh.nuhmask  = ptr->data;
1547 >    nuh.nuhmask  = s;
1548      nuh.nickptr  = NULL;
1549      nuh.userptr  = block_state.user.buf;
1550      nuh.hostptr  = block_state.host.buf;
1551 +
1552      nuh.nicksize = 0;
1553      nuh.usersize = sizeof(block_state.user.buf);
1554      nuh.hostsize = sizeof(block_state.host.buf);
1555 +
1556      split_nuh(&nuh);
1557  
1558 <    conf        = conf_make(CONF_CLIENT);
1559 <    conf->user  = xstrdup(block_state.user.buf);
1560 <    conf->host  = xstrdup(block_state.host.buf);
1558 >    struct MaskItem *conf = conf_make(CONF_CLIENT);
1559 >    conf->user = xstrdup(block_state.user.buf);
1560 >    conf->host = xstrdup(block_state.host.buf);
1561  
1562      if (block_state.rpass.buf[0])
1563        conf->passwd = xstrdup(block_state.rpass.buf);
# Line 1684 | Line 1573 | auth_entry: IRCD_AUTH
1573   };
1574  
1575   auth_items:     auth_items auth_item | auth_item;
1576 < auth_item:      auth_user | auth_passwd | auth_class | auth_flags |
1577 <                auth_spoof | auth_redir_serv | auth_redir_port |
1578 <                auth_encrypted | error ';' ;
1576 > auth_item:      auth_user |
1577 >                auth_passwd |
1578 >                auth_class |
1579 >                auth_flags |
1580 >                auth_spoof |
1581 >                auth_redir_serv |
1582 >                auth_redir_port |
1583 >                auth_encrypted |
1584 >                error ';' ;
1585  
1586   auth_user: USER '=' QSTRING ';'
1587   {
# Line 1721 | Line 1616 | auth_flags: IRCD_FLAGS
1616   {
1617    if (conf_parser_ctx.pass == 2)
1618      block_state.flags.value &= (CONF_FLAGS_ENCRYPTED | CONF_FLAGS_SPOOF_IP);
1619 < } '='  auth_flags_items ';';
1619 > } '=' auth_flags_items ';';
1620  
1621   auth_flags_items: auth_flags_items ',' auth_flags_item | auth_flags_item;
1622   auth_flags_item: SPOOF_NOTICE
# Line 1736 | Line 1631 | auth_flags_item: SPOOF_NOTICE
1631   {
1632    if (conf_parser_ctx.pass == 2)
1633      block_state.flags.value |= CONF_FLAGS_EXEMPTKLINE;
1634 + } | XLINE_EXEMPT
1635 + {
1636 +  if (conf_parser_ctx.pass == 2)
1637 +    block_state.flags.value |= CONF_FLAGS_EXEMPTXLINE;
1638   } | NEED_IDENT
1639   {
1640    if (conf_parser_ctx.pass == 2)
# Line 1748 | Line 1647 | auth_flags_item: SPOOF_NOTICE
1647   {
1648    if (conf_parser_ctx.pass == 2)
1649      block_state.flags.value |= CONF_FLAGS_NO_TILDE;
1751 } | GLINE_EXEMPT
1752 {
1753  if (conf_parser_ctx.pass == 2)
1754    block_state.flags.value |= CONF_FLAGS_EXEMPTGLINE;
1650   } | RESV_EXEMPT
1651   {
1652    if (conf_parser_ctx.pass == 2)
# Line 1771 | Line 1666 | auth_spoof: SPOOF '=' QSTRING ';'
1666    if (conf_parser_ctx.pass != 2)
1667      break;
1668  
1669 <  if (strlen(yylval.string) <= HOSTLEN && valid_hostname(yylval.string))
1669 >  if (valid_hostname(yylval.string))
1670    {
1671      strlcpy(block_state.name.buf, yylval.string, sizeof(block_state.name.buf));
1672      block_state.flags.value |= CONF_FLAGS_SPOOF_IP;
# Line 1800 | Line 1695 | auth_redir_port: REDIRPORT '=' NUMBER ';
1695  
1696  
1697   /***************************************************************************
1698 < *  section resv
1698 > * resv {} section
1699   ***************************************************************************/
1700   resv_entry: RESV
1701   {
# Line 1814 | Line 1709 | resv_entry: RESV
1709    if (conf_parser_ctx.pass != 2)
1710      break;
1711  
1712 <  create_resv(block_state.name.buf, block_state.rpass.buf, &block_state.mask.list);
1712 >  resv_make(block_state.name.buf, block_state.rpass.buf, &block_state.mask.list);
1713   };
1714  
1715 < resv_items:     resv_items resv_item | resv_item;
1716 < resv_item:      resv_mask | resv_reason | resv_exempt | error ';' ;
1715 > resv_items:     resv_items resv_item | resv_item;
1716 > resv_item:      resv_mask | resv_reason | resv_exempt | error ';' ;
1717  
1718   resv_mask: MASK '=' QSTRING ';'
1719   {
# Line 1840 | Line 1735 | resv_exempt: EXEMPT '=' QSTRING ';'
1735  
1736  
1737   /***************************************************************************
1738 < *  section service
1738 > * service {} section
1739   ***************************************************************************/
1740   service_entry: T_SERVICE '{' service_items '}' ';';
1741  
# Line 1852 | Line 1747 | service_name: NAME '=' QSTRING ';'
1747    if (conf_parser_ctx.pass != 2)
1748      break;
1749  
1750 <  if (valid_servname(yylval.string))
1750 >  if (server_valid_name(yylval.string) == true)
1751    {
1752 <    struct MaskItem *conf = conf_make(CONF_SERVICE);
1753 <    conf->name = xstrdup(yylval.string);
1752 >    struct ServiceItem *service = service_make();
1753 >    service->name = xstrdup(yylval.string);
1754    }
1755   };
1756  
1757 +
1758   /***************************************************************************
1759 < *  section shared, for sharing remote klines etc.
1759 > * shared {} section, for sharing remote klines etc.
1760   ***************************************************************************/
1761   shared_entry: T_SHARED
1762   {
# Line 1875 | Line 1771 | shared_entry: T_SHARED
1771    block_state.flags.value = SHARED_ALL;
1772   } '{' shared_items '}' ';'
1773   {
1878  struct MaskItem *conf = NULL;
1879
1774    if (conf_parser_ctx.pass != 2)
1775      break;
1776  
1777 <  conf = conf_make(CONF_ULINE);
1778 <  conf->flags = block_state.flags.value;
1779 <  conf->name = xstrdup(block_state.name.buf);
1780 <  conf->user = xstrdup(block_state.user.buf);
1781 <  conf->host = xstrdup(block_state.host.buf);
1777 >  struct SharedItem *shared = shared_make();
1778 >  shared->type = block_state.flags.value;
1779 >  shared->server = xstrdup(block_state.name.buf);
1780 >  shared->user = xstrdup(block_state.user.buf);
1781 >  shared->host = xstrdup(block_state.host.buf);
1782   };
1783  
1784   shared_items: shared_items shared_item | shared_item;
# Line 1964 | Line 1858 | shared_type_item: KLINE
1858      block_state.flags.value = SHARED_ALL;
1859   };
1860  
1861 +
1862   /***************************************************************************
1863 < *  section cluster
1863 > * cluster {} section
1864   ***************************************************************************/
1865   cluster_entry: T_CLUSTER
1866   {
# Line 1975 | Line 1870 | cluster_entry: T_CLUSTER
1870    reset_block_state();
1871  
1872    strlcpy(block_state.name.buf, "*", sizeof(block_state.name.buf));
1873 <  block_state.flags.value = SHARED_ALL;
1873 >  block_state.flags.value = CLUSTER_ALL;
1874   } '{' cluster_items '}' ';'
1875   {
1981  struct MaskItem *conf = NULL;
1982
1876    if (conf_parser_ctx.pass != 2)
1877      break;
1878  
1879 <  conf = conf_make(CONF_CLUSTER);
1880 <  conf->flags = block_state.flags.value;
1881 <  conf->name = xstrdup(block_state.name.buf);
1879 >  struct ClusterItem *cluster = cluster_make();
1880 >  cluster->type = block_state.flags.value;
1881 >  cluster->server = xstrdup(block_state.name.buf);
1882   };
1883  
1884 < cluster_items:  cluster_items cluster_item | cluster_item;
1885 < cluster_item:   cluster_name | cluster_type | error ';' ;
1884 > cluster_items:  cluster_items cluster_item | cluster_item;
1885 > cluster_item:   cluster_name | cluster_type | error ';' ;
1886  
1887   cluster_name: NAME '=' QSTRING ';'
1888   {
# Line 2003 | Line 1896 | cluster_type: TYPE
1896      block_state.flags.value = 0;
1897   } '=' cluster_types ';' ;
1898  
1899 < cluster_types:  cluster_types ',' cluster_type_item | cluster_type_item;
1899 > cluster_types:  cluster_types ',' cluster_type_item | cluster_type_item;
1900   cluster_type_item: KLINE
1901   {
1902    if (conf_parser_ctx.pass == 2)
1903 <    block_state.flags.value |= SHARED_KLINE;
1903 >    block_state.flags.value |= CLUSTER_KLINE;
1904   } | UNKLINE
1905   {
1906    if (conf_parser_ctx.pass == 2)
1907 <    block_state.flags.value |= SHARED_UNKLINE;
1907 >    block_state.flags.value |= CLUSTER_UNKLINE;
1908   } | T_DLINE
1909   {
1910    if (conf_parser_ctx.pass == 2)
1911 <    block_state.flags.value |= SHARED_DLINE;
1911 >    block_state.flags.value |= CLUSTER_DLINE;
1912   } | T_UNDLINE
1913   {
1914    if (conf_parser_ctx.pass == 2)
1915 <    block_state.flags.value |= SHARED_UNDLINE;
1915 >    block_state.flags.value |= CLUSTER_UNDLINE;
1916   } | XLINE
1917   {
1918    if (conf_parser_ctx.pass == 2)
1919 <    block_state.flags.value |= SHARED_XLINE;
1919 >    block_state.flags.value |= CLUSTER_XLINE;
1920   } | T_UNXLINE
1921   {
1922    if (conf_parser_ctx.pass == 2)
1923 <    block_state.flags.value |= SHARED_UNXLINE;
1923 >    block_state.flags.value |= CLUSTER_UNXLINE;
1924   } | RESV
1925   {
1926    if (conf_parser_ctx.pass == 2)
1927 <    block_state.flags.value |= SHARED_RESV;
1927 >    block_state.flags.value |= CLUSTER_RESV;
1928   } | T_UNRESV
1929   {
1930    if (conf_parser_ctx.pass == 2)
1931 <    block_state.flags.value |= SHARED_UNRESV;
1931 >    block_state.flags.value |= CLUSTER_UNRESV;
1932   } | T_LOCOPS
1933   {
1934    if (conf_parser_ctx.pass == 2)
1935 <    block_state.flags.value |= SHARED_LOCOPS;
1935 >    block_state.flags.value |= CLUSTER_LOCOPS;
1936   } | T_ALL
1937   {
1938    if (conf_parser_ctx.pass == 2)
1939 <    block_state.flags.value = SHARED_ALL;
1939 >    block_state.flags.value = CLUSTER_ALL;
1940   };
1941  
1942 +
1943   /***************************************************************************
1944 < *  section connect
1944 > * connect {}  section
1945   ***************************************************************************/
1946   connect_entry: CONNECT
1947   {
# Line 2058 | Line 1952 | connect_entry: CONNECT
1952    reset_block_state();
1953    block_state.aftype.value = AF_INET;
1954    block_state.port.value = PORTNUM;
1955 +  block_state.timeout.value = CONNECTTIMEOUT;
1956   } '{' connect_items '}' ';'
1957   {
2063  struct MaskItem *conf = NULL;
1958    struct addrinfo hints, *res;
1959  
1960    if (conf_parser_ctx.pass != 2)
# Line 2074 | Line 1968 | connect_entry: CONNECT
1968        !block_state.spass.buf[0])
1969      break;
1970  
1971 +  if (server_valid_name(block_state.name.buf) == false)
1972 +    break;
1973 +
1974    if (has_wildcards(block_state.name.buf) ||
1975        has_wildcards(block_state.host.buf))
1976      break;
1977  
1978 <  conf = conf_make(CONF_SERVER);
1978 >  struct MaskItem *conf = conf_make(CONF_SERVER);
1979 >  conf->addr = xcalloc(sizeof(*conf->addr));
1980    conf->port = block_state.port.value;
1981 +  conf->timeout = block_state.timeout.value;
1982    conf->flags = block_state.flags.value;
1983    conf->aftype = block_state.aftype.value;
1984    conf->host = xstrdup(block_state.host.buf);
# Line 2105 | Line 2004 | connect_entry: CONNECT
2004      hints.ai_flags    = AI_PASSIVE | AI_NUMERICHOST;
2005  
2006      if (getaddrinfo(block_state.bind.buf, NULL, &hints, &res))
2007 <      ilog(LOG_TYPE_IRCD, "Invalid netmask for server vhost(%s)", block_state.bind.buf);
2007 >      ilog(LOG_TYPE_IRCD, "Invalid netmask for server bind(%s)", block_state.bind.buf);
2008      else
2009      {
2010 <      assert(res != NULL);
2010 >      assert(res);
2011  
2012 <      memcpy(&conf->bind, res->ai_addr, res->ai_addrlen);
2013 <      conf->bind.ss.ss_family = res->ai_family;
2014 <      conf->bind.ss_len = res->ai_addrlen;
2012 >      conf->bind = xcalloc(sizeof(*conf->bind));
2013 >
2014 >      memcpy(conf->bind, res->ai_addr, res->ai_addrlen);
2015 >      conf->bind->ss_len = res->ai_addrlen;
2016        freeaddrinfo(res);
2017      }
2018    }
2019  
2020    conf_add_class_to_conf(conf, block_state.class.buf);
2021 <  lookup_confhost(conf);
2021 >  conf_dns_lookup(conf);
2022   };
2023  
2024   connect_items:  connect_items connect_item | connect_item;
2025 < connect_item:   connect_name | connect_host | connect_vhost |
2026 <                connect_send_password | connect_accept_password |
2027 <                connect_ssl_certificate_fingerprint |
2028 <                connect_aftype | connect_port | connect_ssl_cipher_list |
2029 <                connect_flags | connect_hub_mask | connect_leaf_mask |
2030 <                connect_class | connect_encrypted |
2025 > connect_item:   connect_name |
2026 >                connect_host |
2027 >                connect_timeout |
2028 >                connect_bind |
2029 >                connect_send_password |
2030 >                connect_accept_password |
2031 >                connect_ssl_certificate_fingerprint |
2032 >                connect_aftype |
2033 >                connect_port |
2034 >                connect_ssl_cipher_list |
2035 >                connect_flags |
2036 >                connect_hub_mask |
2037 >                connect_leaf_mask |
2038 >                connect_class |
2039 >                connect_encrypted |
2040                  error ';' ;
2041  
2042   connect_name: NAME '=' QSTRING ';'
# Line 2142 | Line 2051 | connect_host: HOST '=' QSTRING ';'
2051      strlcpy(block_state.host.buf, yylval.string, sizeof(block_state.host.buf));
2052   };
2053  
2054 < connect_vhost: VHOST '=' QSTRING ';'
2054 > connect_timeout: TIMEOUT '=' timespec ';'
2055 > {
2056 >  if (conf_parser_ctx.pass == 2)
2057 >    block_state.timeout.value = $3;
2058 > };
2059 >
2060 > connect_bind: T_BIND '=' QSTRING ';'
2061   {
2062    if (conf_parser_ctx.pass == 2)
2063      strlcpy(block_state.bind.buf, yylval.string, sizeof(block_state.bind.buf));
# Line 2153 | Line 2068 | connect_send_password: SEND_PASSWORD '='
2068    if (conf_parser_ctx.pass != 2)
2069      break;
2070  
2071 <  if ($3[0] == ':')
2071 >  if (*yylval.string == ':')
2072      conf_error_report("Server passwords cannot begin with a colon");
2073 <  else if (strchr($3, ' ') != NULL)
2073 >  else if (strchr(yylval.string, ' '))
2074      conf_error_report("Server passwords cannot contain spaces");
2075    else
2076      strlcpy(block_state.spass.buf, yylval.string, sizeof(block_state.spass.buf));
# Line 2166 | Line 2081 | connect_accept_password: ACCEPT_PASSWORD
2081    if (conf_parser_ctx.pass != 2)
2082      break;
2083  
2084 <  if ($3[0] == ':')
2084 >  if (*yylval.string == ':')
2085      conf_error_report("Server passwords cannot begin with a colon");
2086 <  else if (strchr($3, ' ') != NULL)
2086 >  else if (strchr(yylval.string, ' '))
2087      conf_error_report("Server passwords cannot contain spaces");
2088    else
2089      strlcpy(block_state.rpass.buf, yylval.string, sizeof(block_state.rpass.buf));
# Line 2192 | Line 2107 | connect_aftype: AFTYPE '=' T_IPV4 ';'
2107      block_state.aftype.value = AF_INET;
2108   } | AFTYPE '=' T_IPV6 ';'
2109   {
2195 #ifdef IPV6
2110    if (conf_parser_ctx.pass == 2)
2111      block_state.aftype.value = AF_INET6;
2198 #endif
2112   };
2113  
2114   connect_flags: IRCD_FLAGS
2115   {
2116    block_state.flags.value &= CONF_FLAGS_ENCRYPTED;
2117 < } '='  connect_flags_items ';';
2117 > } '=' connect_flags_items ';';
2118  
2119   connect_flags_items: connect_flags_items ',' connect_flags_item | connect_flags_item;
2120   connect_flags_item: AUTOCONN
# Line 2245 | Line 2158 | connect_class: CLASS '=' QSTRING ';'
2158  
2159   connect_ssl_cipher_list: T_SSL_CIPHER_LIST '=' QSTRING ';'
2160   {
2161 < #ifdef HAVE_LIBCRYPTO
2161 > #ifdef HAVE_TLS
2162    if (conf_parser_ctx.pass == 2)
2163      strlcpy(block_state.ciph.buf, yylval.string, sizeof(block_state.ciph.buf));
2164   #else
2165    if (conf_parser_ctx.pass == 2)
2166 <    conf_error_report("Ignoring connect::ciphers -- no OpenSSL support");
2166 >    conf_error_report("Ignoring connect::ciphers -- no TLS support");
2167   #endif
2168   };
2169  
2170  
2171   /***************************************************************************
2172 < *  section kill
2172 > * kill {} section
2173   ***************************************************************************/
2174   kill_entry: KILL
2175   {
# Line 2264 | Line 2177 | kill_entry: KILL
2177      reset_block_state();
2178   } '{' kill_items '}' ';'
2179   {
2267  struct MaskItem *conf = NULL;
2268
2180    if (conf_parser_ctx.pass != 2)
2181      break;
2182  
# Line 2273 | Line 2184 | kill_entry: KILL
2184        !block_state.host.buf[0])
2185      break;
2186  
2187 <  conf = conf_make(CONF_KLINE);
2187 >  struct MaskItem *conf = conf_make(CONF_KLINE);
2188    conf->user = xstrdup(block_state.user.buf);
2189    conf->host = xstrdup(block_state.host.buf);
2190  
# Line 2313 | Line 2224 | kill_reason: REASON '=' QSTRING ';'
2224      strlcpy(block_state.rpass.buf, yylval.string, sizeof(block_state.rpass.buf));
2225   };
2226  
2227 +
2228   /***************************************************************************
2229 < *  section deny
2229 > * deny {} section
2230   ***************************************************************************/
2231   deny_entry: DENY
2232   {
# Line 2322 | Line 2234 | deny_entry: DENY
2234      reset_block_state();
2235   } '{' deny_items '}' ';'
2236   {
2325  struct MaskItem *conf = NULL;
2326
2237    if (conf_parser_ctx.pass != 2)
2238      break;
2239  
# Line 2332 | Line 2242 | deny_entry: DENY
2242  
2243    if (parse_netmask(block_state.addr.buf, NULL, NULL) != HM_HOST)
2244    {
2245 <    conf = conf_make(CONF_DLINE);
2245 >    struct MaskItem *conf = conf_make(CONF_DLINE);
2246      conf->host = xstrdup(block_state.addr.buf);
2247  
2248      if (block_state.rpass.buf[0])
# Line 2358 | Line 2268 | deny_reason: REASON '=' QSTRING ';'
2268      strlcpy(block_state.rpass.buf, yylval.string, sizeof(block_state.rpass.buf));
2269   };
2270  
2271 +
2272   /***************************************************************************
2273 < *  section exempt
2273 > * exempt {} section
2274   ***************************************************************************/
2275   exempt_entry: EXEMPT '{' exempt_items '}' ';';
2276  
2277 < exempt_items:     exempt_items exempt_item | exempt_item;
2278 < exempt_item:      exempt_ip | error;
2277 > exempt_items: exempt_items exempt_item | exempt_item;
2278 > exempt_item:  exempt_ip | error;
2279  
2280   exempt_ip: IP '=' QSTRING ';'
2281   {
2282    if (conf_parser_ctx.pass == 2)
2283    {
2284 <    if (yylval.string[0] && parse_netmask(yylval.string, NULL, NULL) != HM_HOST)
2284 >    if (*yylval.string && parse_netmask(yylval.string, NULL, NULL) != HM_HOST)
2285      {
2286        struct MaskItem *conf = conf_make(CONF_EXEMPT);
2287        conf->host = xstrdup(yylval.string);
# Line 2381 | Line 2292 | exempt_ip: IP '=' QSTRING ';'
2292   };
2293  
2294   /***************************************************************************
2295 < *  section gecos
2295 > * gecos {} section
2296   ***************************************************************************/
2297   gecos_entry: GECOS
2298   {
# Line 2389 | Line 2300 | gecos_entry: GECOS
2300      reset_block_state();
2301   } '{' gecos_items '}' ';'
2302   {
2392  struct MaskItem *conf = NULL;
2393
2303    if (conf_parser_ctx.pass != 2)
2304      break;
2305  
2306    if (!block_state.name.buf[0])
2307      break;
2308  
2309 <  conf = conf_make(CONF_XLINE);
2310 <  conf->name = xstrdup(block_state.name.buf);
2309 >  struct GecosItem *gecos = gecos_make();
2310 >  gecos->mask = xstrdup(block_state.name.buf);
2311  
2312    if (block_state.rpass.buf[0])
2313 <    conf->reason = xstrdup(block_state.rpass.buf);
2313 >    gecos->reason = xstrdup(block_state.rpass.buf);
2314    else
2315 <    conf->reason = xstrdup(CONF_NOREASON);
2315 >    gecos->reason = xstrdup(CONF_NOREASON);
2316   };
2317  
2318   gecos_items: gecos_items gecos_item | gecos_item;
# Line 2421 | Line 2330 | gecos_reason: REASON '=' QSTRING ';'
2330      strlcpy(block_state.rpass.buf, yylval.string, sizeof(block_state.rpass.buf));
2331   };
2332  
2333 +
2334   /***************************************************************************
2335 < *  section general
2335 > * general {} section
2336   ***************************************************************************/
2337 < general_entry: GENERAL
2428 <  '{' general_items '}' ';';
2337 > general_entry: GENERAL '{' general_items '}' ';';
2338  
2339   general_items:      general_items general_item | general_item;
2340 < general_item:       general_hide_spoof_ips | general_ignore_bogus_ts |
2341 <                    general_failed_oper_notice | general_anti_nick_flood |
2342 <                    general_max_nick_time | general_max_nick_changes |
2343 <                    general_max_accept | general_anti_spam_exit_message_time |
2344 <                    general_ts_warn_delta | general_ts_max_delta |
2340 > general_item:       general_away_count |
2341 >                    general_away_time |
2342 >                    general_failed_oper_notice |
2343 >                    general_anti_nick_flood |
2344 >                    general_max_nick_time |
2345 >                    general_max_nick_changes |
2346 >                    general_max_accept |
2347 >                    general_whowas_history_length |
2348 >                    general_anti_spam_exit_message_time |
2349 >                    general_ts_warn_delta |
2350 >                    general_ts_max_delta |
2351                      general_kill_chase_time_limit |
2352                      general_invisible_on_connect |
2353 <                    general_warn_no_nline | general_dots_in_ident |
2354 <                    general_stats_o_oper_only | general_stats_k_oper_only |
2355 <                    general_pace_wait | general_stats_i_oper_only |
2356 <                    general_pace_wait_simple | general_stats_P_oper_only |
2353 >                    general_warn_no_connect_block |
2354 >                    general_dots_in_ident |
2355 >                    general_stats_i_oper_only |
2356 >                    general_stats_k_oper_only |
2357 >                    general_stats_m_oper_only |
2358 >                    general_stats_o_oper_only |
2359 >                    general_stats_P_oper_only |
2360                      general_stats_u_oper_only |
2361 <                    general_short_motd | general_no_oper_flood |
2362 <                    general_true_no_oper_flood | general_oper_pass_resv |
2363 <                    general_oper_only_umodes | general_max_targets |
2364 <                    general_use_egd | general_egdpool_path |
2365 <                    general_oper_umodes | general_caller_id_wait |
2366 <                    general_opers_bypass_callerid | general_default_floodcount |
2367 <                    general_min_nonwildcard | general_min_nonwildcard_simple |
2368 <                    general_throttle_time | general_havent_read_conf |
2361 >                    general_pace_wait |
2362 >                    general_pace_wait_simple |
2363 >                    general_short_motd |
2364 >                    general_no_oper_flood |
2365 >                    general_oper_only_umodes |
2366 >                    general_max_targets |
2367 >                    general_oper_umodes |
2368 >                    general_caller_id_wait |
2369 >                    general_opers_bypass_callerid |
2370 >                    general_default_floodcount |
2371 >                    general_default_floodtime |
2372 >                    general_min_nonwildcard |
2373 >                    general_min_nonwildcard_simple |
2374 >                    general_throttle_count |
2375 >                    general_throttle_time |
2376                      general_ping_cookie |
2377                      general_disable_auth |
2378 <                    general_tkline_expire_notices | general_gline_enable |
2379 <                    general_gline_duration | general_gline_request_duration |
2380 <                    general_gline_min_cidr |
2381 <                    general_gline_min_cidr6 |
2382 <                    general_stats_e_disabled |
2383 <                    general_max_watch | general_services_name |
2384 <                    general_cycle_on_host_change |
2385 <                    error;
2378 >                    general_dline_min_cidr |
2379 >                    general_dline_min_cidr6 |
2380 >                    general_kline_min_cidr |
2381 >                    general_kline_min_cidr6 |
2382 >                    general_stats_e_disabled |
2383 >                    general_max_watch |
2384 >                    general_cycle_on_host_change |
2385 >                    error;
2386  
2387  
2388 < general_max_watch: MAX_WATCH '=' NUMBER ';'
2388 > general_away_count: AWAY_COUNT '=' NUMBER ';'
2389   {
2390 <  ConfigFileEntry.max_watch = $3;
2390 >  ConfigGeneral.away_count = $3;
2391   };
2392  
2393 < general_cycle_on_host_change: CYCLE_ON_HOST_CHANGE '=' TBOOL ';'
2393 > general_away_time: AWAY_TIME '=' timespec ';'
2394   {
2395 <  if (conf_parser_ctx.pass == 2)
2471 <    ConfigFileEntry.cycle_on_host_change = yylval.number;
2395 >  ConfigGeneral.away_time = $3;
2396   };
2397  
2398 < general_gline_enable: GLINE_ENABLE '=' TBOOL ';'
2475 < {
2476 <  if (conf_parser_ctx.pass == 2)
2477 <    ConfigFileEntry.glines = yylval.number;
2478 < };
2479 <
2480 < general_gline_duration: GLINE_DURATION '=' timespec ';'
2398 > general_max_watch: MAX_WATCH '=' NUMBER ';'
2399   {
2400 <  if (conf_parser_ctx.pass == 2)
2483 <    ConfigFileEntry.gline_time = $3;
2400 >  ConfigGeneral.max_watch = $3;
2401   };
2402  
2403 < general_gline_request_duration: GLINE_REQUEST_DURATION '=' timespec ';'
2403 > general_whowas_history_length: WHOWAS_HISTORY_LENGTH '=' NUMBER ';'
2404   {
2405 <  if (conf_parser_ctx.pass == 2)
2489 <    ConfigFileEntry.gline_request_time = $3;
2405 >  ConfigGeneral.whowas_history_length = $3;
2406   };
2407  
2408 < general_gline_min_cidr: GLINE_MIN_CIDR '=' NUMBER ';'
2408 > general_cycle_on_host_change: CYCLE_ON_HOST_CHANGE '=' TBOOL ';'
2409   {
2410 <  ConfigFileEntry.gline_min_cidr = $3;
2410 >  ConfigGeneral.cycle_on_host_change = yylval.number;
2411   };
2412  
2413 < general_gline_min_cidr6: GLINE_MIN_CIDR6 '=' NUMBER ';'
2413 > general_dline_min_cidr: DLINE_MIN_CIDR '=' NUMBER ';'
2414   {
2415 <  ConfigFileEntry.gline_min_cidr6 = $3;
2415 >  ConfigGeneral.dline_min_cidr = $3;
2416   };
2417  
2418 < general_tkline_expire_notices: TKLINE_EXPIRE_NOTICES '=' TBOOL ';'
2418 > general_dline_min_cidr6: DLINE_MIN_CIDR6 '=' NUMBER ';'
2419   {
2420 <  ConfigFileEntry.tkline_expire_notices = yylval.number;
2420 >  ConfigGeneral.dline_min_cidr6 = $3;
2421   };
2422  
2423 < general_kill_chase_time_limit: KILL_CHASE_TIME_LIMIT '=' timespec ';'
2423 > general_kline_min_cidr: KLINE_MIN_CIDR '=' NUMBER ';'
2424   {
2425 <  ConfigFileEntry.kill_chase_time_limit = $3;
2425 >  ConfigGeneral.kline_min_cidr = $3;
2426   };
2427  
2428 < general_hide_spoof_ips: HIDE_SPOOF_IPS '=' TBOOL ';'
2428 > general_kline_min_cidr6: KLINE_MIN_CIDR6 '=' NUMBER ';'
2429   {
2430 <  ConfigFileEntry.hide_spoof_ips = yylval.number;
2430 >  ConfigGeneral.kline_min_cidr6 = $3;
2431   };
2432  
2433 < general_ignore_bogus_ts: IGNORE_BOGUS_TS '=' TBOOL ';'
2433 > general_kill_chase_time_limit: KILL_CHASE_TIME_LIMIT '=' timespec ';'
2434   {
2435 <  ConfigFileEntry.ignore_bogus_ts = yylval.number;
2435 >  ConfigGeneral.kill_chase_time_limit = $3;
2436   };
2437  
2438   general_failed_oper_notice: FAILED_OPER_NOTICE '=' TBOOL ';'
2439   {
2440 <  ConfigFileEntry.failed_oper_notice = yylval.number;
2440 >  ConfigGeneral.failed_oper_notice = yylval.number;
2441   };
2442  
2443   general_anti_nick_flood: ANTI_NICK_FLOOD '=' TBOOL ';'
2444   {
2445 <  ConfigFileEntry.anti_nick_flood = yylval.number;
2445 >  ConfigGeneral.anti_nick_flood = yylval.number;
2446   };
2447  
2448   general_max_nick_time: MAX_NICK_TIME '=' timespec ';'
2449   {
2450 <  ConfigFileEntry.max_nick_time = $3;
2450 >  ConfigGeneral.max_nick_time = $3;
2451   };
2452  
2453   general_max_nick_changes: MAX_NICK_CHANGES '=' NUMBER ';'
2454   {
2455 <  ConfigFileEntry.max_nick_changes = $3;
2455 >  ConfigGeneral.max_nick_changes = $3;
2456   };
2457  
2458   general_max_accept: MAX_ACCEPT '=' NUMBER ';'
2459   {
2460 <  ConfigFileEntry.max_accept = $3;
2460 >  ConfigGeneral.max_accept = $3;
2461   };
2462  
2463   general_anti_spam_exit_message_time: ANTI_SPAM_EXIT_MESSAGE_TIME '=' timespec ';'
2464   {
2465 <  ConfigFileEntry.anti_spam_exit_message_time = $3;
2465 >  ConfigGeneral.anti_spam_exit_message_time = $3;
2466   };
2467  
2468   general_ts_warn_delta: TS_WARN_DELTA '=' timespec ';'
2469   {
2470 <  ConfigFileEntry.ts_warn_delta = $3;
2470 >  ConfigGeneral.ts_warn_delta = $3;
2471   };
2472  
2473   general_ts_max_delta: TS_MAX_DELTA '=' timespec ';'
2474   {
2475 <  if (conf_parser_ctx.pass == 2)
2560 <    ConfigFileEntry.ts_max_delta = $3;
2475 >  ConfigGeneral.ts_max_delta = $3;
2476   };
2477  
2478 < general_havent_read_conf: HAVENT_READ_CONF '=' NUMBER ';'
2478 > general_invisible_on_connect: INVISIBLE_ON_CONNECT '=' TBOOL ';'
2479   {
2480 <  if (($3 > 0) && conf_parser_ctx.pass == 1)
2566 <  {
2567 <    ilog(LOG_TYPE_IRCD, "You haven't read your config file properly.");
2568 <    ilog(LOG_TYPE_IRCD, "There is a line in the example conf that will kill your server if not removed.");
2569 <    ilog(LOG_TYPE_IRCD, "Consider actually reading/editing the conf file, and removing this line.");
2570 <    exit(0);
2571 <  }
2480 >  ConfigGeneral.invisible_on_connect = yylval.number;
2481   };
2482  
2483 < general_invisible_on_connect: INVISIBLE_ON_CONNECT '=' TBOOL ';'
2483 > general_warn_no_connect_block: WARN_NO_CONNECT_BLOCK '=' TBOOL ';'
2484   {
2485 <  ConfigFileEntry.invisible_on_connect = yylval.number;
2485 >  ConfigGeneral.warn_no_connect_block = yylval.number;
2486   };
2487  
2488 < general_warn_no_nline: WARN_NO_NLINE '=' TBOOL ';'
2488 > general_stats_e_disabled: STATS_E_DISABLED '=' TBOOL ';'
2489   {
2490 <  ConfigFileEntry.warn_no_nline = yylval.number;
2490 >  ConfigGeneral.stats_e_disabled = yylval.number;
2491   };
2492  
2493 < general_stats_e_disabled: STATS_E_DISABLED '=' TBOOL ';'
2493 > general_stats_m_oper_only: STATS_M_OPER_ONLY '=' TBOOL ';'
2494   {
2495 <  ConfigFileEntry.stats_e_disabled = yylval.number;
2495 >  ConfigGeneral.stats_m_oper_only = yylval.number;
2496   };
2497  
2498   general_stats_o_oper_only: STATS_O_OPER_ONLY '=' TBOOL ';'
2499   {
2500 <  ConfigFileEntry.stats_o_oper_only = yylval.number;
2500 >  ConfigGeneral.stats_o_oper_only = yylval.number;
2501   };
2502  
2503   general_stats_P_oper_only: STATS_P_OPER_ONLY '=' TBOOL ';'
2504   {
2505 <  ConfigFileEntry.stats_P_oper_only = yylval.number;
2505 >  ConfigGeneral.stats_P_oper_only = yylval.number;
2506   };
2507  
2508   general_stats_u_oper_only: STATS_U_OPER_ONLY '=' TBOOL ';'
2509   {
2510 <  ConfigFileEntry.stats_u_oper_only = yylval.number;
2510 >  ConfigGeneral.stats_u_oper_only = yylval.number;
2511   };
2512  
2513   general_stats_k_oper_only: STATS_K_OPER_ONLY '=' TBOOL ';'
2514   {
2515 <  ConfigFileEntry.stats_k_oper_only = 2 * yylval.number;
2515 >  ConfigGeneral.stats_k_oper_only = 2 * yylval.number;
2516   } | STATS_K_OPER_ONLY '=' TMASKED ';'
2517   {
2518 <  ConfigFileEntry.stats_k_oper_only = 1;
2518 >  ConfigGeneral.stats_k_oper_only = 1;
2519   };
2520  
2521   general_stats_i_oper_only: STATS_I_OPER_ONLY '=' TBOOL ';'
2522   {
2523 <  ConfigFileEntry.stats_i_oper_only = 2 * yylval.number;
2523 >  ConfigGeneral.stats_i_oper_only = 2 * yylval.number;
2524   } | STATS_I_OPER_ONLY '=' TMASKED ';'
2525   {
2526 <  ConfigFileEntry.stats_i_oper_only = 1;
2526 >  ConfigGeneral.stats_i_oper_only = 1;
2527   };
2528  
2529   general_pace_wait: PACE_WAIT '=' timespec ';'
2530   {
2531 <  ConfigFileEntry.pace_wait = $3;
2531 >  ConfigGeneral.pace_wait = $3;
2532   };
2533  
2534   general_caller_id_wait: CALLER_ID_WAIT '=' timespec ';'
2535   {
2536 <  ConfigFileEntry.caller_id_wait = $3;
2536 >  ConfigGeneral.caller_id_wait = $3;
2537   };
2538  
2539   general_opers_bypass_callerid: OPERS_BYPASS_CALLERID '=' TBOOL ';'
2540   {
2541 <  ConfigFileEntry.opers_bypass_callerid = yylval.number;
2541 >  ConfigGeneral.opers_bypass_callerid = yylval.number;
2542   };
2543  
2544   general_pace_wait_simple: PACE_WAIT_SIMPLE '=' timespec ';'
2545   {
2546 <  ConfigFileEntry.pace_wait_simple = $3;
2546 >  ConfigGeneral.pace_wait_simple = $3;
2547   };
2548  
2549   general_short_motd: SHORT_MOTD '=' TBOOL ';'
2550   {
2551 <  ConfigFileEntry.short_motd = yylval.number;
2551 >  ConfigGeneral.short_motd = yylval.number;
2552   };
2553  
2554   general_no_oper_flood: NO_OPER_FLOOD '=' TBOOL ';'
2555   {
2556 <  ConfigFileEntry.no_oper_flood = yylval.number;
2648 < };
2649 <
2650 < general_true_no_oper_flood: TRUE_NO_OPER_FLOOD '=' TBOOL ';'
2651 < {
2652 <  ConfigFileEntry.true_no_oper_flood = yylval.number;
2653 < };
2654 <
2655 < general_oper_pass_resv: OPER_PASS_RESV '=' TBOOL ';'
2656 < {
2657 <  ConfigFileEntry.oper_pass_resv = yylval.number;
2556 >  ConfigGeneral.no_oper_flood = yylval.number;
2557   };
2558  
2559   general_dots_in_ident: DOTS_IN_IDENT '=' NUMBER ';'
2560   {
2561 <  ConfigFileEntry.dots_in_ident = $3;
2561 >  ConfigGeneral.dots_in_ident = $3;
2562   };
2563  
2564   general_max_targets: MAX_TARGETS '=' NUMBER ';'
2565   {
2566 <  ConfigFileEntry.max_targets = $3;
2668 < };
2669 <
2670 < general_use_egd: USE_EGD '=' TBOOL ';'
2671 < {
2672 <  ConfigFileEntry.use_egd = yylval.number;
2673 < };
2674 <
2675 < general_egdpool_path: EGDPOOL_PATH '=' QSTRING ';'
2676 < {
2677 <  if (conf_parser_ctx.pass == 2)
2678 <  {
2679 <    MyFree(ConfigFileEntry.egdpool_path);
2680 <    ConfigFileEntry.egdpool_path = xstrdup(yylval.string);
2681 <  }
2566 >  ConfigGeneral.max_targets = $3;
2567   };
2568  
2569 < general_services_name: T_SERVICES_NAME '=' QSTRING ';'
2569 > general_ping_cookie: PING_COOKIE '=' TBOOL ';'
2570   {
2571 <  if (conf_parser_ctx.pass == 2 && valid_servname(yylval.string))
2687 <  {
2688 <    MyFree(ConfigFileEntry.service_name);
2689 <    ConfigFileEntry.service_name = xstrdup(yylval.string);
2690 <  }
2571 >  ConfigGeneral.ping_cookie = yylval.number;
2572   };
2573  
2574 < general_ping_cookie: PING_COOKIE '=' TBOOL ';'
2574 > general_disable_auth: DISABLE_AUTH '=' TBOOL ';'
2575   {
2576 <  ConfigFileEntry.ping_cookie = yylval.number;
2576 >  ConfigGeneral.disable_auth = yylval.number;
2577   };
2578  
2579 < general_disable_auth: DISABLE_AUTH '=' TBOOL ';'
2579 > general_throttle_count: THROTTLE_COUNT '=' NUMBER ';'
2580   {
2581 <  ConfigFileEntry.disable_auth = yylval.number;
2581 >  ConfigGeneral.throttle_count = $3;
2582   };
2583  
2584   general_throttle_time: THROTTLE_TIME '=' timespec ';'
2585   {
2586 <  ConfigFileEntry.throttle_time = $3;
2586 >  ConfigGeneral.throttle_time = $3;
2587   };
2588  
2589   general_oper_umodes: OPER_UMODES
2590   {
2591 <  ConfigFileEntry.oper_umodes = 0;
2592 < } '='  umode_oitems ';' ;
2591 >  ConfigGeneral.oper_umodes = 0;
2592 > } '=' umode_oitems ';' ;
2593  
2594   umode_oitems:    umode_oitems ',' umode_oitem | umode_oitem;
2595   umode_oitem:     T_BOTS
2596   {
2597 <  ConfigFileEntry.oper_umodes |= UMODE_BOTS;
2597 >  ConfigGeneral.oper_umodes |= UMODE_BOTS;
2598   } | T_CCONN
2599   {
2600 <  ConfigFileEntry.oper_umodes |= UMODE_CCONN;
2600 >  ConfigGeneral.oper_umodes |= UMODE_CCONN;
2601   } | T_DEAF
2602   {
2603 <  ConfigFileEntry.oper_umodes |= UMODE_DEAF;
2603 >  ConfigGeneral.oper_umodes |= UMODE_DEAF;
2604   } | T_DEBUG
2605   {
2606 <  ConfigFileEntry.oper_umodes |= UMODE_DEBUG;
2606 >  ConfigGeneral.oper_umodes |= UMODE_DEBUG;
2607   } | T_FULL
2608   {
2609 <  ConfigFileEntry.oper_umodes |= UMODE_FULL;
2609 >  ConfigGeneral.oper_umodes |= UMODE_FULL;
2610   } | HIDDEN
2611   {
2612 <  ConfigFileEntry.oper_umodes |= UMODE_HIDDEN;
2612 >  ConfigGeneral.oper_umodes |= UMODE_HIDDEN;
2613 > } | HIDE_CHANS
2614 > {
2615 >  ConfigGeneral.oper_umodes |= UMODE_HIDECHANS;
2616 > } | HIDE_IDLE
2617 > {
2618 >  ConfigGeneral.oper_umodes |= UMODE_HIDEIDLE;
2619   } | T_SKILL
2620   {
2621 <  ConfigFileEntry.oper_umodes |= UMODE_SKILL;
2621 >  ConfigGeneral.oper_umodes |= UMODE_SKILL;
2622   } | T_NCHANGE
2623   {
2624 <  ConfigFileEntry.oper_umodes |= UMODE_NCHANGE;
2624 >  ConfigGeneral.oper_umodes |= UMODE_NCHANGE;
2625   } | T_REJ
2626   {
2627 <  ConfigFileEntry.oper_umodes |= UMODE_REJ;
2627 >  ConfigGeneral.oper_umodes |= UMODE_REJ;
2628   } | T_UNAUTH
2629   {
2630 <  ConfigFileEntry.oper_umodes |= UMODE_UNAUTH;
2630 >  ConfigGeneral.oper_umodes |= UMODE_UNAUTH;
2631   } | T_SPY
2632   {
2633 <  ConfigFileEntry.oper_umodes |= UMODE_SPY;
2633 >  ConfigGeneral.oper_umodes |= UMODE_SPY;
2634   } | T_EXTERNAL
2635   {
2636 <  ConfigFileEntry.oper_umodes |= UMODE_EXTERNAL;
2750 < } | T_OPERWALL
2751 < {
2752 <  ConfigFileEntry.oper_umodes |= UMODE_OPERWALL;
2636 >  ConfigGeneral.oper_umodes |= UMODE_EXTERNAL;
2637   } | T_SERVNOTICE
2638   {
2639 <  ConfigFileEntry.oper_umodes |= UMODE_SERVNOTICE;
2639 >  ConfigGeneral.oper_umodes |= UMODE_SERVNOTICE;
2640   } | T_INVISIBLE
2641   {
2642 <  ConfigFileEntry.oper_umodes |= UMODE_INVISIBLE;
2642 >  ConfigGeneral.oper_umodes |= UMODE_INVISIBLE;
2643   } | T_WALLOP
2644   {
2645 <  ConfigFileEntry.oper_umodes |= UMODE_WALLOP;
2645 >  ConfigGeneral.oper_umodes |= UMODE_WALLOP;
2646   } | T_SOFTCALLERID
2647   {
2648 <  ConfigFileEntry.oper_umodes |= UMODE_SOFTCALLERID;
2648 >  ConfigGeneral.oper_umodes |= UMODE_SOFTCALLERID;
2649   } | T_CALLERID
2650   {
2651 <  ConfigFileEntry.oper_umodes |= UMODE_CALLERID;
2651 >  ConfigGeneral.oper_umodes |= UMODE_CALLERID;
2652   } | T_LOCOPS
2653   {
2654 <  ConfigFileEntry.oper_umodes |= UMODE_LOCOPS;
2654 >  ConfigGeneral.oper_umodes |= UMODE_LOCOPS;
2655   } | T_NONONREG
2656   {
2657 <  ConfigFileEntry.oper_umodes |= UMODE_REGONLY;
2657 >  ConfigGeneral.oper_umodes |= UMODE_REGONLY;
2658   } | T_FARCONNECT
2659   {
2660 <  ConfigFileEntry.oper_umodes |= UMODE_FARCONNECT;
2660 >  ConfigGeneral.oper_umodes |= UMODE_FARCONNECT;
2661 > } | EXPIRATION
2662 > {
2663 >  ConfigGeneral.oper_umodes |= UMODE_EXPIRATION;
2664   };
2665  
2666   general_oper_only_umodes: OPER_ONLY_UMODES
2667   {
2668 <  ConfigFileEntry.oper_only_umodes = 0;
2669 < } '='  umode_items ';' ;
2668 >  ConfigGeneral.oper_only_umodes = 0;
2669 > } '=' umode_items ';' ;
2670  
2671 < umode_items:    umode_items ',' umode_item | umode_item;
2672 < umode_item:     T_BOTS
2671 > umode_items:  umode_items ',' umode_item | umode_item;
2672 > umode_item:   T_BOTS
2673   {
2674 <  ConfigFileEntry.oper_only_umodes |= UMODE_BOTS;
2674 >  ConfigGeneral.oper_only_umodes |= UMODE_BOTS;
2675   } | T_CCONN
2676   {
2677 <  ConfigFileEntry.oper_only_umodes |= UMODE_CCONN;
2677 >  ConfigGeneral.oper_only_umodes |= UMODE_CCONN;
2678   } | T_DEAF
2679   {
2680 <  ConfigFileEntry.oper_only_umodes |= UMODE_DEAF;
2680 >  ConfigGeneral.oper_only_umodes |= UMODE_DEAF;
2681   } | T_DEBUG
2682   {
2683 <  ConfigFileEntry.oper_only_umodes |= UMODE_DEBUG;
2683 >  ConfigGeneral.oper_only_umodes |= UMODE_DEBUG;
2684   } | T_FULL
2685   {
2686 <  ConfigFileEntry.oper_only_umodes |= UMODE_FULL;
2686 >  ConfigGeneral.oper_only_umodes |= UMODE_FULL;
2687   } | T_SKILL
2688   {
2689 <  ConfigFileEntry.oper_only_umodes |= UMODE_SKILL;
2689 >  ConfigGeneral.oper_only_umodes |= UMODE_SKILL;
2690   } | HIDDEN
2691   {
2692 <  ConfigFileEntry.oper_only_umodes |= UMODE_HIDDEN;
2692 >  ConfigGeneral.oper_only_umodes |= UMODE_HIDDEN;
2693   } | T_NCHANGE
2694   {
2695 <  ConfigFileEntry.oper_only_umodes |= UMODE_NCHANGE;
2695 >  ConfigGeneral.oper_only_umodes |= UMODE_NCHANGE;
2696   } | T_REJ
2697   {
2698 <  ConfigFileEntry.oper_only_umodes |= UMODE_REJ;
2698 >  ConfigGeneral.oper_only_umodes |= UMODE_REJ;
2699   } | T_UNAUTH
2700   {
2701 <  ConfigFileEntry.oper_only_umodes |= UMODE_UNAUTH;
2701 >  ConfigGeneral.oper_only_umodes |= UMODE_UNAUTH;
2702   } | T_SPY
2703   {
2704 <  ConfigFileEntry.oper_only_umodes |= UMODE_SPY;
2704 >  ConfigGeneral.oper_only_umodes |= UMODE_SPY;
2705   } | T_EXTERNAL
2706   {
2707 <  ConfigFileEntry.oper_only_umodes |= UMODE_EXTERNAL;
2821 < } | T_OPERWALL
2822 < {
2823 <  ConfigFileEntry.oper_only_umodes |= UMODE_OPERWALL;
2707 >  ConfigGeneral.oper_only_umodes |= UMODE_EXTERNAL;
2708   } | T_SERVNOTICE
2709   {
2710 <  ConfigFileEntry.oper_only_umodes |= UMODE_SERVNOTICE;
2710 >  ConfigGeneral.oper_only_umodes |= UMODE_SERVNOTICE;
2711   } | T_INVISIBLE
2712   {
2713 <  ConfigFileEntry.oper_only_umodes |= UMODE_INVISIBLE;
2713 >  ConfigGeneral.oper_only_umodes |= UMODE_INVISIBLE;
2714   } | T_WALLOP
2715   {
2716 <  ConfigFileEntry.oper_only_umodes |= UMODE_WALLOP;
2716 >  ConfigGeneral.oper_only_umodes |= UMODE_WALLOP;
2717   } | T_SOFTCALLERID
2718   {
2719 <  ConfigFileEntry.oper_only_umodes |= UMODE_SOFTCALLERID;
2719 >  ConfigGeneral.oper_only_umodes |= UMODE_SOFTCALLERID;
2720   } | T_CALLERID
2721   {
2722 <  ConfigFileEntry.oper_only_umodes |= UMODE_CALLERID;
2722 >  ConfigGeneral.oper_only_umodes |= UMODE_CALLERID;
2723   } | T_LOCOPS
2724   {
2725 <  ConfigFileEntry.oper_only_umodes |= UMODE_LOCOPS;
2725 >  ConfigGeneral.oper_only_umodes |= UMODE_LOCOPS;
2726   } | T_NONONREG
2727   {
2728 <  ConfigFileEntry.oper_only_umodes |= UMODE_REGONLY;
2728 >  ConfigGeneral.oper_only_umodes |= UMODE_REGONLY;
2729   } | T_FARCONNECT
2730   {
2731 <  ConfigFileEntry.oper_only_umodes |= UMODE_FARCONNECT;
2731 >  ConfigGeneral.oper_only_umodes |= UMODE_FARCONNECT;
2732 > } | EXPIRATION
2733 > {
2734 >  ConfigGeneral.oper_only_umodes |= UMODE_EXPIRATION;
2735   };
2736  
2737   general_min_nonwildcard: MIN_NONWILDCARD '=' NUMBER ';'
2738   {
2739 <  ConfigFileEntry.min_nonwildcard = $3;
2739 >  ConfigGeneral.min_nonwildcard = $3;
2740   };
2741  
2742   general_min_nonwildcard_simple: MIN_NONWILDCARD_SIMPLE '=' NUMBER ';'
2743   {
2744 <  ConfigFileEntry.min_nonwildcard_simple = $3;
2744 >  ConfigGeneral.min_nonwildcard_simple = $3;
2745   };
2746  
2747   general_default_floodcount: DEFAULT_FLOODCOUNT '=' NUMBER ';'
2748   {
2749 <  ConfigFileEntry.default_floodcount = $3;
2749 >  ConfigGeneral.default_floodcount = $3;
2750 > };
2751 >
2752 > general_default_floodtime: DEFAULT_FLOODTIME '=' timespec ';'
2753 > {
2754 >  ConfigGeneral.default_floodtime = $3;
2755   };
2756  
2757  
2758   /***************************************************************************
2759 < *  section channel
2759 > * channel {} section
2760   ***************************************************************************/
2761 < channel_entry: CHANNEL
2870 <  '{' channel_items '}' ';';
2761 > channel_entry: CHANNEL '{' channel_items '}' ';';
2762  
2763   channel_items:      channel_items channel_item | channel_item;
2764   channel_item:       channel_max_bans |
2765 <                    channel_knock_delay | channel_knock_delay_channel |
2766 <                    channel_max_chans_per_user | channel_max_chans_per_oper |
2767 <                    channel_default_split_user_count |
2768 <                    channel_default_split_server_count |
2769 <                    channel_no_create_on_split |
2770 <                    channel_no_join_on_split |
2771 <                    channel_jflood_count | channel_jflood_time |
2772 <                    channel_disable_fake_channels | error;
2765 >                    channel_max_bans_large |
2766 >                    channel_invite_client_count |
2767 >                    channel_invite_client_time |
2768 >                    channel_invite_delay_channel |
2769 >                    channel_invite_expire_time |
2770 >                    channel_knock_client_count |
2771 >                    channel_knock_client_time |
2772 >                    channel_knock_delay_channel |
2773 >                    channel_max_channels |
2774 >                    channel_max_invites |
2775 >                    channel_default_join_flood_count |
2776 >                    channel_default_join_flood_time |
2777 >                    channel_disable_fake_channels |
2778 >                    error;
2779  
2780   channel_disable_fake_channels: DISABLE_FAKE_CHANNELS '=' TBOOL ';'
2781   {
2782    ConfigChannel.disable_fake_channels = yylval.number;
2783   };
2784  
2785 < channel_knock_delay: KNOCK_DELAY '=' timespec ';'
2785 > channel_invite_client_count: INVITE_CLIENT_COUNT '=' NUMBER ';'
2786   {
2787 <  ConfigChannel.knock_delay = $3;
2787 >  ConfigChannel.invite_client_count = $3;
2788   };
2789  
2790 < channel_knock_delay_channel: KNOCK_DELAY_CHANNEL '=' timespec ';'
2790 > channel_invite_client_time: INVITE_CLIENT_TIME '=' timespec ';'
2791   {
2792 <  ConfigChannel.knock_delay_channel = $3;
2792 >  ConfigChannel.invite_client_time = $3;
2793   };
2794  
2795 < channel_max_chans_per_user: MAX_CHANS_PER_USER '=' NUMBER ';'
2795 > channel_invite_delay_channel: INVITE_DELAY_CHANNEL '=' timespec ';'
2796   {
2797 <  ConfigChannel.max_chans_per_user = $3;
2797 >  ConfigChannel.invite_delay_channel = $3;
2798   };
2799  
2800 < channel_max_chans_per_oper: MAX_CHANS_PER_OPER '=' NUMBER ';'
2800 > channel_invite_expire_time: INVITE_EXPIRE_TIME '=' timespec ';'
2801   {
2802 <  ConfigChannel.max_chans_per_oper = $3;
2802 >  ConfigChannel.invite_expire_time = $3;
2803   };
2804  
2805 < channel_max_bans: MAX_BANS '=' NUMBER ';'
2805 > channel_knock_client_count: KNOCK_CLIENT_COUNT '=' NUMBER ';'
2806   {
2807 <  ConfigChannel.max_bans = $3;
2807 >  ConfigChannel.knock_client_count = $3;
2808   };
2809  
2810 < channel_default_split_user_count: DEFAULT_SPLIT_USER_COUNT '=' NUMBER ';'
2810 > channel_knock_client_time: KNOCK_CLIENT_TIME '=' timespec ';'
2811   {
2812 <  ConfigChannel.default_split_user_count = $3;
2812 >  ConfigChannel.knock_client_time = $3;
2813   };
2814  
2815 < channel_default_split_server_count: DEFAULT_SPLIT_SERVER_COUNT '=' NUMBER ';'
2815 > channel_knock_delay_channel: KNOCK_DELAY_CHANNEL '=' timespec ';'
2816 > {
2817 >  ConfigChannel.knock_delay_channel = $3;
2818 > };
2819 >
2820 > channel_max_channels: MAX_CHANNELS '=' NUMBER ';'
2821 > {
2822 >  ConfigChannel.max_channels = $3;
2823 > };
2824 >
2825 > channel_max_invites: MAX_INVITES '=' NUMBER ';'
2826   {
2827 <  ConfigChannel.default_split_server_count = $3;
2827 >  ConfigChannel.max_invites = $3;
2828   };
2829  
2830 < channel_no_create_on_split: NO_CREATE_ON_SPLIT '=' TBOOL ';'
2830 > channel_max_bans: MAX_BANS '=' NUMBER ';'
2831   {
2832 <  ConfigChannel.no_create_on_split = yylval.number;
2832 >  ConfigChannel.max_bans = $3;
2833   };
2834  
2835 < channel_no_join_on_split: NO_JOIN_ON_SPLIT '=' TBOOL ';'
2835 > channel_max_bans_large: MAX_BANS_LARGE '=' NUMBER ';'
2836   {
2837 <  ConfigChannel.no_join_on_split = yylval.number;
2837 >  ConfigChannel.max_bans_large = $3;
2838   };
2839  
2840 < channel_jflood_count: JOIN_FLOOD_COUNT '=' NUMBER ';'
2840 > channel_default_join_flood_count: DEFAULT_JOIN_FLOOD_COUNT '=' NUMBER ';'
2841   {
2842 <  GlobalSetOptions.joinfloodcount = yylval.number;
2842 >  ConfigChannel.default_join_flood_count = yylval.number;
2843   };
2844  
2845 < channel_jflood_time: JOIN_FLOOD_TIME '=' timespec ';'
2845 > channel_default_join_flood_time: DEFAULT_JOIN_FLOOD_TIME '=' timespec ';'
2846   {
2847 <  GlobalSetOptions.joinfloodtime = $3;
2847 >  ConfigChannel.default_join_flood_time = $3;
2848   };
2849  
2850 +
2851   /***************************************************************************
2852 < *  section serverhide
2852 > * serverhide {} section
2853   ***************************************************************************/
2854 < serverhide_entry: SERVERHIDE
2947 <  '{' serverhide_items '}' ';';
2854 > serverhide_entry: SERVERHIDE '{' serverhide_items '}' ';';
2855  
2856   serverhide_items:   serverhide_items serverhide_item | serverhide_item;
2857 < serverhide_item:    serverhide_flatten_links | serverhide_disable_remote_commands |
2857 > serverhide_item:    serverhide_flatten_links |
2858 >                    serverhide_flatten_links_delay |
2859 >                    serverhide_flatten_links_file |
2860 >                    serverhide_disable_remote_commands |
2861                      serverhide_hide_servers |
2862 <                    serverhide_hide_services |
2863 <                    serverhide_links_delay |
2864 <                    serverhide_hidden | serverhide_hidden_name |
2865 <                    serverhide_hide_server_ips |
2862 >                    serverhide_hide_services |
2863 >                    serverhide_hidden |
2864 >                    serverhide_hidden_name |
2865 >                    serverhide_hide_server_ips |
2866                      error;
2867  
2868   serverhide_flatten_links: FLATTEN_LINKS '=' TBOOL ';'
# Line 2961 | Line 2871 | serverhide_flatten_links: FLATTEN_LINKS
2871      ConfigServerHide.flatten_links = yylval.number;
2872   };
2873  
2874 + serverhide_flatten_links_delay: FLATTEN_LINKS_DELAY '=' timespec ';'
2875 + {
2876 +  if (conf_parser_ctx.pass == 2)
2877 +  {
2878 +    if ($3 > 0)
2879 +    {
2880 +      event_write_links_file.when = $3;
2881 +      event_add(&event_write_links_file, NULL);
2882 +    }
2883 +    else
2884 +     event_delete(&event_write_links_file);
2885 +
2886 +    ConfigServerHide.flatten_links_delay = $3;
2887 +  }
2888 + };
2889 +
2890 + serverhide_flatten_links_file: FLATTEN_LINKS_FILE '=' QSTRING ';'
2891 + {
2892 +  if (conf_parser_ctx.pass == 2)
2893 +  {
2894 +    xfree(ConfigServerHide.flatten_links_file);
2895 +    ConfigServerHide.flatten_links_file = xstrdup(yylval.string);
2896 +  }
2897 + };
2898 +
2899   serverhide_disable_remote_commands: DISABLE_REMOTE_COMMANDS '=' TBOOL ';'
2900   {
2901    if (conf_parser_ctx.pass == 2)
# Line 2983 | Line 2918 | serverhide_hidden_name: HIDDEN_NAME '='
2918   {
2919    if (conf_parser_ctx.pass == 2)
2920    {
2921 <    MyFree(ConfigServerHide.hidden_name);
2921 >    xfree(ConfigServerHide.hidden_name);
2922      ConfigServerHide.hidden_name = xstrdup(yylval.string);
2923    }
2924   };
2925  
2991 serverhide_links_delay: LINKS_DELAY '=' timespec ';'
2992 {
2993  if (conf_parser_ctx.pass == 2)
2994  {
2995    if (($3 > 0) && ConfigServerHide.links_disabled == 1)
2996    {
2997      eventAddIsh("write_links_file", write_links_file, NULL, $3);
2998      ConfigServerHide.links_disabled = 0;
2999    }
3000
3001    ConfigServerHide.links_delay = $3;
3002  }
3003 };
3004
2926   serverhide_hidden: HIDDEN '=' TBOOL ';'
2927   {
2928    if (conf_parser_ctx.pass == 2)

Comparing ircd-hybrid/trunk/src/conf_parser.y (property svn:keywords):
Revision 3435 by michael, Thu May 1 13:57:39 2014 UTC vs.
Revision 9114 by michael, Sun Jan 5 09:43:16 2020 UTC

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

Diff Legend

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