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-7.2/src/ircd_parser.y (file contents), Revision 1024 by michael, Sun Nov 1 23:14:25 2009 UTC vs.
ircd-hybrid-8/src/conf_parser.y (file contents), Revision 1459 by michael, Fri Jul 6 14:23:09 2012 UTC

# Line 1 | Line 1
1   /*
2   *  ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 < *  ircd_parser.y: Parses the ircd configuration file.
3 > *  conf_parser.y: Parses the ircd configuration file.
4   *
5   *  Copyright (C) 2005 by the past and present ircd coders, and others.
6   *
# Line 32 | Line 32
32   #include "stdinc.h"
33   #include "ircd.h"
34   #include "list.h"
35 < #include "s_conf.h"
35 > #include "conf.h"
36   #include "event.h"
37 < #include "s_log.h"
37 > #include "log.h"
38   #include "client.h"     /* for UMODE_ALL only */
39   #include "irc_string.h"
40 #include "irc_getaddrinfo.h"
40   #include "sprintf_irc.h"
41   #include "memory.h"
42   #include "modules.h"
# Line 53 | Line 52
52   #include <openssl/rsa.h>
53   #include <openssl/bio.h>
54   #include <openssl/pem.h>
55 + #include <openssl/dh.h>
56   #endif
57  
58 + int yylex(void);
59 +
60   static char *class_name = NULL;
61   static struct ConfItem *yy_conf = NULL;
62   static struct AccessItem *yy_aconf = NULL;
# Line 63 | Line 65 | static struct ClassItem *yy_class = NULL
65   static char *yy_class_name = NULL;
66  
67   static dlink_list col_conf_list  = { NULL, NULL, 0 };
66 static dlink_list hub_conf_list  = { NULL, NULL, 0 };
67 static dlink_list leaf_conf_list = { NULL, NULL, 0 };
68   static unsigned int listener_flags = 0;
69   static unsigned int regex_ban = 0;
70   static char userbuf[IRCD_BUFSIZE];
71   static char hostbuf[IRCD_BUFSIZE];
72   static char reasonbuf[REASONLEN + 1];
73   static char gecos_name[REALLEN * 4];
74 <
74 > static char lfile[IRCD_BUFSIZE];
75 > static unsigned int ltype = 0;
76 > static unsigned int lsize = 0;
77   static char *resv_reason = NULL;
78   static char *listener_address = NULL;
77 static int not_atom = 0;
79  
80   struct CollectItem
81   {
# Line 104 | Line 105 | free_collect_item(struct CollectItem *it
105    MyFree(item);
106   }
107  
107 static void
108 unhook_hub_leaf_confs(void)
109 {
110  dlink_node *ptr;
111  dlink_node *next_ptr;
112  struct CollectItem *yy_hconf;
113  struct CollectItem *yy_lconf;
114
115  DLINK_FOREACH_SAFE(ptr, next_ptr, hub_conf_list.head)
116  {
117    yy_hconf = ptr->data;
118    dlinkDelete(&yy_hconf->node, &hub_conf_list);
119    free_collect_item(yy_hconf);
120  }
121
122  DLINK_FOREACH_SAFE(ptr, next_ptr, leaf_conf_list.head)
123  {
124    yy_lconf = ptr->data;
125    dlinkDelete(&yy_lconf->node, &leaf_conf_list);
126    free_collect_item(yy_lconf);
127  }
128 }
129
108   %}
109  
110   %union {
# Line 144 | Line 122 | unhook_hub_leaf_confs(void)
122   %token  AUTOCONN
123   %token  T_BLOCK
124   %token  BURST_AWAY
147 %token  BURST_TOPICWHO
125   %token  BYTES KBYTES MBYTES GBYTES TBYTES
126   %token  CALLER_ID_WAIT
127   %token  CAN_FLOOD
151 %token  CAN_IDLE
128   %token  CHANNEL
129   %token  CIDR_BITLEN_IPV4
130   %token  CIDR_BITLEN_IPV6
155 %token  CIPHER_PREFERENCE
131   %token  CLASS
157 %token  COMPRESSED
158 %token  COMPRESSION_LEVEL
132   %token  CONNECT
133   %token  CONNECTFREQ
161 %token  CRYPTLINK
162 %token  DEFAULT_CIPHER_PREFERENCE
134   %token  DEFAULT_FLOODCOUNT
135   %token  DEFAULT_SPLIT_SERVER_COUNT
136   %token  DEFAULT_SPLIT_USER_COUNT
# Line 171 | Line 142 | unhook_hub_leaf_confs(void)
142   %token  DISABLE_HIDDEN
143   %token  DISABLE_LOCAL_CHANNELS
144   %token  DISABLE_REMOTE_COMMANDS
174 %token  DOT_IN_IP6_ADDR
145   %token  DOTS_IN_IDENT
146   %token  DURATION
147   %token  EGDPOOL_PATH
# Line 181 | Line 151 | unhook_hub_leaf_confs(void)
151   %token  EXCEED_LIMIT
152   %token  EXEMPT
153   %token  FAILED_OPER_NOTICE
184 %token  FAKENAME
154   %token  IRCD_FLAGS
155   %token  FLATTEN_LINKS
187 %token  FFAILED_OPERLOG
188 %token  FKILLLOG
189 %token  FKLINELOG
190 %token  FGLINELOG
191 %token  FIOERRLOG
192 %token  FOPERLOG
193 %token  FOPERSPYLOG
194 %token  FUSERLOG
156   %token  GECOS
157   %token  GENERAL
158   %token  GLINE
159 < %token  GLINES
159 > %token  GLINE_DURATION
160 > %token  GLINE_ENABLE
161   %token  GLINE_EXEMPT
200 %token  GLINE_LOG
162   %token  GLINE_TIME
163 + %token  GLINE_REQUEST_DURATION
164   %token  GLINE_MIN_CIDR
165   %token  GLINE_MIN_CIDR6
166   %token  GLOBAL_KILL
# Line 206 | Line 168 | unhook_hub_leaf_confs(void)
168   %token  NEED_IDENT
169   %token  HAVENT_READ_CONF
170   %token  HIDDEN
209 %token  HIDDEN_ADMIN
171   %token  HIDDEN_NAME
211 %token  HIDDEN_OPER
172   %token  HIDE_SERVER_IPS
173   %token  HIDE_SERVERS
174   %token  HIDE_SPOOF_IPS
175   %token  HOST
176   %token  HUB
177   %token  HUB_MASK
218 %token  IDLETIME
178   %token  IGNORE_BOGUS_TS
179   %token  INVISIBLE_ON_CONNECT
180   %token  IP
# Line 231 | Line 190 | unhook_hub_leaf_confs(void)
190   %token  LINKS_DELAY
191   %token  LISTEN
192   %token  T_LOG
234 %token  LOGGING
235 %token  LOG_LEVEL
193   %token  MAX_ACCEPT
194   %token  MAX_BANS
195 + %token  MAX_CHANS_PER_OPER
196   %token  MAX_CHANS_PER_USER
197   %token  MAX_GLOBAL
198   %token  MAX_IDENT
# Line 259 | Line 217 | unhook_hub_leaf_confs(void)
217   %token  NO_JOIN_ON_SPLIT
218   %token  NO_OPER_FLOOD
219   %token  NO_TILDE
262 %token  NOT
220   %token  NUMBER
221   %token  NUMBER_PER_IDENT
222   %token  NUMBER_PER_CIDR
# Line 267 | Line 224 | unhook_hub_leaf_confs(void)
224   %token  NUMBER_PER_IP_GLOBAL
225   %token  OPERATOR
226   %token  OPERS_BYPASS_CALLERID
270 %token  OPER_LOG
227   %token  OPER_ONLY_UMODES
228   %token  OPER_PASS_RESV
229   %token  OPER_SPY_T
# Line 297 | Line 253 | unhook_hub_leaf_confs(void)
253   %token  RSA_PRIVATE_KEY_FILE
254   %token  RSA_PUBLIC_KEY_FILE
255   %token  SSL_CERTIFICATE_FILE
256 < %token  T_SSL_CONNECTION_METHOD
256 > %token  SSL_DH_PARAM_FILE
257 > %token  T_SSL_CLIENT_METHOD
258 > %token  T_SSL_SERVER_METHOD
259   %token  T_SSLV3
260   %token  T_TLSV1
261   %token  RESV
# Line 307 | Line 265 | unhook_hub_leaf_confs(void)
265   %token  SEND_PASSWORD
266   %token  SERVERHIDE
267   %token  SERVERINFO
310 %token  SERVLINK_PATH
268   %token  IRCD_SID
269   %token  TKLINE_EXPIRE_NOTICES
270   %token  T_SHARED
# Line 334 | Line 291 | unhook_hub_leaf_confs(void)
291   %token  T_CALLERID
292   %token  T_CCONN
293   %token  T_CCONN_FULL
294 + %token  T_SSL_CIPHER_LIST
295   %token  T_CLIENT_FLOOD
296   %token  T_DEAF
297   %token  T_DEBUG
298 + %token  T_DLINE
299   %token  T_DRONE
300   %token  T_EXTERNAL
301   %token  T_FULL
# Line 344 | Line 303 | unhook_hub_leaf_confs(void)
303   %token  T_IPV4
304   %token  T_IPV6
305   %token  T_LOCOPS
347 %token  T_LOGPATH
348 %token  T_L_CRIT
349 %token  T_L_DEBUG
350 %token  T_L_ERROR
351 %token  T_L_INFO
352 %token  T_L_NOTICE
353 %token  T_L_TRACE
354 %token  T_L_WARN
306   %token  T_MAX_CLIENTS
307   %token  T_NCHANGE
308   %token  T_OPERWALL
# Line 363 | Line 314 | unhook_hub_leaf_confs(void)
314   %token  T_SSL
315   %token  T_UMODES
316   %token  T_UNAUTH
317 + %token  T_UNDLINE
318 + %token  T_UNLIMITED
319   %token  T_UNRESV
320   %token  T_UNXLINE
321 + %token  T_GLOBOPS
322   %token  T_WALLOP
323 + %token  T_RESTART
324 + %token  T_SERVICE
325 + %token  T_SERVICES_NAME
326   %token  THROTTLE_TIME
327   %token  TOPICBURST
328   %token  TRUE_NO_OPER_FLOOD
# Line 385 | Line 342 | unhook_hub_leaf_confs(void)
342   %token  XLINE
343   %token  WARN
344   %token  WARN_NO_NLINE
345 + %token  T_SIZE
346 + %token  T_FILE
347  
348   %type <string> QSTRING
349   %type <number> NUMBER
# Line 408 | Line 367 | conf_item:        admin_entry
367                  | serverinfo_entry
368                  | serverhide_entry
369                  | resv_entry
370 +                | service_entry
371                  | shared_entry
372                  | cluster_entry
373                  | connect_entry
# Line 415 | Line 375 | conf_item:        admin_entry
375                  | deny_entry
376                  | exempt_entry
377                  | general_entry
418                | gline_entry
378                  | gecos_entry
379                  | modules_entry
380                  | error ';'
# Line 469 | Line 428 | modules_item:   modules_module | modules
428  
429   modules_module: MODULE '=' QSTRING ';'
430   {
472 #ifndef STATIC_MODULES /* NOOP in the static case */
431    if (conf_parser_ctx.pass == 2)
432      add_conf_module(libio_basename(yylval.string));
475 #endif
433   };
434  
435   modules_path: PATH '=' QSTRING ';'
436   {
480 #ifndef STATIC_MODULES
437    if (conf_parser_ctx.pass == 2)
438      mod_add_path(yylval.string);
483 #endif
439   };
440  
441  
# Line 490 | Line 445 | serverinfo_items:       serverinfo_items
445   serverinfo_item:        serverinfo_name | serverinfo_vhost |
446                          serverinfo_hub | serverinfo_description |
447                          serverinfo_network_name | serverinfo_network_desc |
448 <                        serverinfo_max_clients |
448 >                        serverinfo_max_clients | serverinfo_ssl_dh_param_file |
449                          serverinfo_rsa_private_key_file | serverinfo_vhost6 |
450                          serverinfo_sid | serverinfo_ssl_certificate_file |
451 <                        serverinfo_ssl_connection_method |
451 >                        serverinfo_ssl_client_method | serverinfo_ssl_server_method |
452 >                        serverinfo_ssl_cipher_list |
453                          error ';' ;
454  
455  
456 < serverinfo_ssl_connection_method: T_SSL_CONNECTION_METHOD
456 > serverinfo_ssl_client_method: T_SSL_CLIENT_METHOD '=' client_method_types ';' ;
457 > serverinfo_ssl_server_method: T_SSL_SERVER_METHOD '=' server_method_types ';' ;
458 >
459 > client_method_types: client_method_types ',' client_method_type_item | client_method_type_item;
460 > client_method_type_item: T_SSLV3
461   {
462   #ifdef HAVE_LIBCRYPTO
463 <  if (conf_parser_ctx.boot && conf_parser_ctx.pass == 2)
464 <    ServerInfo.tls_version = 0;
463 >  if (conf_parser_ctx.pass == 2 && ServerInfo.client_ctx)
464 >    SSL_CTX_clear_options(ServerInfo.client_ctx, SSL_OP_NO_SSLv3);
465   #endif
466 < } '=' method_types ';'
466 > } | T_TLSV1
467   {
468   #ifdef HAVE_LIBCRYPTO
469 <  if (conf_parser_ctx.boot && conf_parser_ctx.pass == 2)
470 <  {
511 <    if (!(ServerInfo.tls_version & CONF_SERVER_INFO_TLS_VERSION_SSLV3))
512 <      SSL_CTX_set_options(ServerInfo.server_ctx, SSL_OP_NO_SSLv3);
513 <    if (!(ServerInfo.tls_version & CONF_SERVER_INFO_TLS_VERSION_TLSV1))
514 <      SSL_CTX_set_options(ServerInfo.server_ctx, SSL_OP_NO_TLSv1);
515 <  }
469 >  if (conf_parser_ctx.pass == 2 && ServerInfo.client_ctx)
470 >    SSL_CTX_clear_options(ServerInfo.client_ctx, SSL_OP_NO_TLSv1);
471   #endif
472   };
473  
474 < method_types: method_types ',' method_type_item | method_type_item;
475 < method_type_item: T_SSLV3
474 > server_method_types: server_method_types ',' server_method_type_item | server_method_type_item;
475 > server_method_type_item: T_SSLV3
476   {
477   #ifdef HAVE_LIBCRYPTO
478 <  if (conf_parser_ctx.boot && conf_parser_ctx.pass == 2)
479 <    ServerInfo.tls_version |= CONF_SERVER_INFO_TLS_VERSION_SSLV3;
478 >  if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx)
479 >    SSL_CTX_clear_options(ServerInfo.server_ctx, SSL_OP_NO_SSLv3);
480   #endif
481   } | T_TLSV1
482   {
483   #ifdef HAVE_LIBCRYPTO
484 <  if (conf_parser_ctx.boot && conf_parser_ctx.pass == 2)
485 <    ServerInfo.tls_version |= CONF_SERVER_INFO_TLS_VERSION_TLSV1;
484 >  if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx)
485 >    SSL_CTX_clear_options(ServerInfo.server_ctx, SSL_OP_NO_TLSv1);
486   #endif
487   };
488  
# Line 543 | Line 498 | serverinfo_ssl_certificate_file: SSL_CER
498      }
499  
500      if (SSL_CTX_use_certificate_file(ServerInfo.server_ctx, yylval.string,
501 +                                     SSL_FILETYPE_PEM) <= 0 ||
502 +        SSL_CTX_use_certificate_file(ServerInfo.client_ctx, yylval.string,
503                                       SSL_FILETYPE_PEM) <= 0)
504      {
505        yyerror(ERR_lib_error_string(ERR_get_error()));
# Line 550 | Line 507 | serverinfo_ssl_certificate_file: SSL_CER
507      }
508  
509      if (SSL_CTX_use_PrivateKey_file(ServerInfo.server_ctx, ServerInfo.rsa_private_key_file,
510 +                                    SSL_FILETYPE_PEM) <= 0 ||
511 +        SSL_CTX_use_PrivateKey_file(ServerInfo.client_ctx, ServerInfo.rsa_private_key_file,
512                                      SSL_FILETYPE_PEM) <= 0)
513      {
514        yyerror(ERR_lib_error_string(ERR_get_error()));
515        break;
516      }
517  
518 <    if (!SSL_CTX_check_private_key(ServerInfo.server_ctx))
518 >    if (!SSL_CTX_check_private_key(ServerInfo.server_ctx) ||
519 >        !SSL_CTX_check_private_key(ServerInfo.client_ctx))
520      {
521        yyerror(ERR_lib_error_string(ERR_get_error()));
522        break;
# Line 592 | Line 552 | serverinfo_rsa_private_key_file: RSA_PRI
552        break;
553      }
554  
555 <    ServerInfo.rsa_private_key = (RSA *)PEM_read_bio_RSAPrivateKey(file, NULL,
596 <      0, NULL);
555 >    ServerInfo.rsa_private_key = PEM_read_bio_RSAPrivateKey(file, NULL, 0, NULL);
556  
557      BIO_set_close(file, BIO_CLOSE);
558      BIO_free(file);
# Line 625 | Line 584 | serverinfo_rsa_private_key_file: RSA_PRI
584   #endif
585   };
586  
587 + serverinfo_ssl_dh_param_file: SSL_DH_PARAM_FILE '=' QSTRING ';'
588 + {
589 + /* TBD - XXX: error reporting */
590 + #ifdef HAVE_LIBCRYPTO
591 +  if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx)
592 +  {
593 +    BIO *file = BIO_new_file(yylval.string, "r");
594 +
595 +    if (file)
596 +    {
597 +      DH *dh = PEM_read_bio_DHparams(file, NULL, NULL, NULL);
598 +
599 +      BIO_free(file);
600 +
601 +      if (dh)
602 +      {
603 +        if (DH_size(dh) < 128)
604 +          ilog(LOG_TYPE_IRCD, "Ignoring serverinfo::ssl_dh_param_file -- need at least a 1024 bit DH prime size");
605 +        else
606 +          SSL_CTX_set_tmp_dh(ServerInfo.server_ctx, dh);
607 +
608 +        DH_free(dh);
609 +      }
610 +    }
611 +  }
612 + #endif
613 + };
614 +
615 + serverinfo_ssl_cipher_list: T_SSL_CIPHER_LIST '=' QSTRING ';'
616 + {
617 + #ifdef HAVE_LIBCRYPTO
618 +  if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx)
619 +    SSL_CTX_set_cipher_list(ServerInfo.server_ctx, yylval.string);
620 + #endif
621 + };
622 +
623   serverinfo_name: NAME '=' QSTRING ';'
624   {
625    /* this isn't rehashable */
626 <  if (conf_parser_ctx.pass == 2)
626 >  if (conf_parser_ctx.pass == 2 && !ServerInfo.name)
627    {
628 <    if (ServerInfo.name == NULL)
628 >    if (valid_servname(yylval.string))
629 >      DupString(ServerInfo.name, yylval.string);
630 >    else
631      {
632 <      /* the ircd will exit() in main() if we dont set one */
633 <      if (strlen(yylval.string) <= HOSTLEN)
637 <        DupString(ServerInfo.name, yylval.string);
632 >      ilog(LOG_TYPE_IRCD, "Ignoring serverinfo::name -- invalid name. Aborting.");
633 >      exit(0);
634      }
635    }
636   };
# Line 648 | Line 644 | serverinfo_sid: IRCD_SID '=' QSTRING ';'
644        DupString(ServerInfo.sid, yylval.string);
645      else
646      {
647 <      ilog(L_ERROR, "Ignoring config file entry SID -- invalid SID. Aborting.");
647 >      ilog(LOG_TYPE_IRCD, "Ignoring serverinfo::sid -- invalid SID. Aborting.");
648        exit(0);
649      }
650    }
# Line 698 | Line 694 | serverinfo_vhost: VHOST '=' QSTRING ';'
694      hints.ai_socktype = SOCK_STREAM;
695      hints.ai_flags    = AI_PASSIVE | AI_NUMERICHOST;
696  
697 <    if (irc_getaddrinfo(yylval.string, NULL, &hints, &res))
698 <      ilog(L_ERROR, "Invalid netmask for server vhost(%s)", yylval.string);
697 >    if (getaddrinfo(yylval.string, NULL, &hints, &res))
698 >      ilog(LOG_TYPE_IRCD, "Invalid netmask for server vhost(%s)", yylval.string);
699      else
700      {
701        assert(res != NULL);
# Line 707 | Line 703 | serverinfo_vhost: VHOST '=' QSTRING ';'
703        memcpy(&ServerInfo.ip, res->ai_addr, res->ai_addrlen);
704        ServerInfo.ip.ss.ss_family = res->ai_family;
705        ServerInfo.ip.ss_len = res->ai_addrlen;
706 <      irc_freeaddrinfo(res);
706 >      freeaddrinfo(res);
707  
708        ServerInfo.specific_ipv4_vhost = 1;
709      }
# Line 727 | Line 723 | serverinfo_vhost6: VHOST6 '=' QSTRING ';
723      hints.ai_socktype = SOCK_STREAM;
724      hints.ai_flags    = AI_PASSIVE | AI_NUMERICHOST;
725  
726 <    if (irc_getaddrinfo(yylval.string, NULL, &hints, &res))
727 <      ilog(L_ERROR, "Invalid netmask for server vhost6(%s)", yylval.string);
726 >    if (getaddrinfo(yylval.string, NULL, &hints, &res))
727 >      ilog(LOG_TYPE_IRCD, "Invalid netmask for server vhost6(%s)", yylval.string);
728      else
729      {
730        assert(res != NULL);
# Line 736 | Line 732 | serverinfo_vhost6: VHOST6 '=' QSTRING ';
732        memcpy(&ServerInfo.ip6, res->ai_addr, res->ai_addrlen);
733        ServerInfo.ip6.ss.ss_family = res->ai_family;
734        ServerInfo.ip6.ss_len = res->ai_addrlen;
735 <      irc_freeaddrinfo(res);
735 >      freeaddrinfo(res);
736  
737        ServerInfo.specific_ipv6_vhost = 1;
738      }
# Line 770 | Line 766 | serverinfo_max_clients: T_MAX_CLIENTS '=
766   serverinfo_hub: HUB '=' TBOOL ';'
767   {
768    if (conf_parser_ctx.pass == 2)
769 <  {
774 <    if (yylval.number)
775 <    {
776 <      ServerInfo.hub = 1;
777 <      delete_capability("HUB");
778 <      add_capability("HUB", CAP_HUB, 1);
779 <    }
780 <    else if (ServerInfo.hub)
781 <    {
782 <
783 <      ServerInfo.hub = 0;
784 <      delete_capability("HUB");
785 <    }
786 <  }
769 >    ServerInfo.hub = yylval.number;
770   };
771  
772   /***************************************************************************
# Line 825 | Line 808 | admin_description: DESCRIPTION '=' QSTRI
808   /***************************************************************************
809   *  section logging
810   ***************************************************************************/
811 < /* XXX */
812 < logging_entry:          LOGGING  '{' logging_items '}' ';' ;
830 <
831 < logging_items:          logging_items logging_item |
832 <                        logging_item ;
811 > logging_entry:          T_LOG  '{' logging_items '}' ';' ;
812 > logging_items:          logging_items logging_item | logging_item ;
813  
814 < logging_item:           logging_path | logging_oper_log |
835 <                        logging_log_level |
836 <                        logging_use_logging | logging_fuserlog |
837 <                        logging_foperlog | logging_fglinelog |
838 <                        logging_fklinelog | logging_killlog |
839 <                        logging_foperspylog | logging_ioerrlog |
840 <                        logging_ffailed_operlog |
814 > logging_item:           logging_use_logging | logging_file_entry |
815                          error ';' ;
816  
817 < logging_path:           T_LOGPATH '=' QSTRING ';'
844 <                        {
845 <                        };
846 <
847 < logging_oper_log:       OPER_LOG '=' QSTRING ';'
848 <                        {
849 <                        };
850 <
851 < logging_fuserlog: FUSERLOG '=' QSTRING ';'
817 > logging_use_logging: USE_LOGGING '=' TBOOL ';'
818   {
819    if (conf_parser_ctx.pass == 2)
820 <    strlcpy(ConfigLoggingEntry.userlog, yylval.string,
855 <            sizeof(ConfigLoggingEntry.userlog));
820 >    ConfigLoggingEntry.use_logging = yylval.number;
821   };
822  
823 < logging_ffailed_operlog: FFAILED_OPERLOG '=' QSTRING ';'
823 > logging_file_entry:
824   {
825 <  if (conf_parser_ctx.pass == 2)
826 <    strlcpy(ConfigLoggingEntry.failed_operlog, yylval.string,
827 <            sizeof(ConfigLoggingEntry.failed_operlog));
828 < };
864 <
865 < logging_foperlog: FOPERLOG '=' QSTRING ';'
825 >  lfile[0] = '\0';
826 >  ltype = 0;
827 >  lsize = 0;
828 > } T_FILE  '{' logging_file_items '}' ';'
829   {
830 <  if (conf_parser_ctx.pass == 2)
831 <    strlcpy(ConfigLoggingEntry.operlog, yylval.string,
869 <            sizeof(ConfigLoggingEntry.operlog));
830 >  if (conf_parser_ctx.pass == 2 && ltype > 0)
831 >    log_add_file(ltype, lsize, lfile);
832   };
833  
834 < logging_foperspylog: FOPERSPYLOG '=' QSTRING ';'
835 < {
874 <  if (conf_parser_ctx.pass == 2)
875 <    strlcpy(ConfigLoggingEntry.operspylog, yylval.string,
876 <            sizeof(ConfigLoggingEntry.operspylog));
877 < };
834 > logging_file_items: logging_file_items logging_file_item |
835 >                    logging_file_item ;
836  
837 < logging_fglinelog: FGLINELOG '=' QSTRING ';'
838 < {
881 <  if (conf_parser_ctx.pass == 2)
882 <    strlcpy(ConfigLoggingEntry.glinelog, yylval.string,
883 <            sizeof(ConfigLoggingEntry.glinelog));
884 < };
837 > logging_file_item:  logging_file_name | logging_file_type |
838 >                    logging_file_size | error ';' ;
839  
840 < logging_fklinelog: FKLINELOG '=' QSTRING ';'
840 > logging_file_name: NAME '=' QSTRING ';'
841   {
842 <  if (conf_parser_ctx.pass == 2)
843 <    strlcpy(ConfigLoggingEntry.klinelog, yylval.string,
890 <            sizeof(ConfigLoggingEntry.klinelog));
891 < };
842 >  strlcpy(lfile, yylval.string, sizeof(lfile));
843 > }
844  
845 < logging_ioerrlog: FIOERRLOG '=' QSTRING ';'
845 > logging_file_size: T_SIZE '=' sizespec ';'
846   {
847 <  if (conf_parser_ctx.pass == 2)
848 <    strlcpy(ConfigLoggingEntry.ioerrlog, yylval.string,
849 <            sizeof(ConfigLoggingEntry.ioerrlog));
847 >  lsize = $3;
848 > } | T_SIZE '=' T_UNLIMITED ';'
849 > {
850 >  lsize = 0;
851   };
852  
853 < logging_killlog: FKILLLOG '=' QSTRING ';'
853 > logging_file_type: TYPE
854   {
855    if (conf_parser_ctx.pass == 2)
856 <    strlcpy(ConfigLoggingEntry.killlog, yylval.string,
857 <            sizeof(ConfigLoggingEntry.killlog));
905 < };
856 >    ltype = 0;
857 > } '='  logging_file_type_items ';' ;
858  
859 < logging_log_level: LOG_LEVEL '=' T_L_CRIT ';'
860 < {
909 <  if (conf_parser_ctx.pass == 2)
910 <    set_log_level(L_CRIT);
911 < } | LOG_LEVEL '=' T_L_ERROR ';'
859 > logging_file_type_items: logging_file_type_items ',' logging_file_type_item | logging_file_type_item;
860 > logging_file_type_item:  USER
861   {
862    if (conf_parser_ctx.pass == 2)
863 <    set_log_level(L_ERROR);
864 < } | LOG_LEVEL '=' T_L_WARN ';'
863 >    ltype = LOG_TYPE_USER;
864 > } | OPERATOR
865   {
866    if (conf_parser_ctx.pass == 2)
867 <    set_log_level(L_WARN);
868 < } | LOG_LEVEL '=' T_L_NOTICE ';'
867 >    ltype = LOG_TYPE_OPER;
868 > } | GLINE
869   {
870    if (conf_parser_ctx.pass == 2)
871 <    set_log_level(L_NOTICE);
872 < } | LOG_LEVEL '=' T_L_TRACE ';'
871 >    ltype = LOG_TYPE_GLINE;
872 > } | T_DLINE
873   {
874    if (conf_parser_ctx.pass == 2)
875 <    set_log_level(L_TRACE);
876 < } | LOG_LEVEL '=' T_L_INFO ';'
875 >    ltype = LOG_TYPE_DLINE;
876 > } | KLINE
877   {
878    if (conf_parser_ctx.pass == 2)
879 <    set_log_level(L_INFO);
880 < } | LOG_LEVEL '=' T_L_DEBUG ';'
879 >    ltype = LOG_TYPE_KLINE;
880 > } | KILL
881   {
882    if (conf_parser_ctx.pass == 2)
883 <    set_log_level(L_DEBUG);
884 < };
936 <
937 < logging_use_logging: USE_LOGGING '=' TBOOL ';'
883 >    ltype = LOG_TYPE_KILL;
884 > } | T_DEBUG
885   {
886    if (conf_parser_ctx.pass == 2)
887 <    ConfigLoggingEntry.use_logging = yylval.number;
887 >    ltype = LOG_TYPE_DEBUG;
888   };
889  
890 +
891   /***************************************************************************
892   * section oper
893   ***************************************************************************/
# Line 956 | Line 904 | oper_entry: OPERATOR
904      MyFree(class_name);
905      class_name = NULL;
906    }
907 < } oper_name_b '{' oper_items '}' ';'
907 > } '{' oper_items '}' ';'
908   {
909    if (conf_parser_ctx.pass == 2)
910    {
# Line 991 | Line 939 | oper_entry: OPERATOR
939          DupString(new_aconf->host, yy_tmp->host);
940        else
941          DupString(new_aconf->host, "*");
942 +
943 +      new_aconf->type = parse_netmask(new_aconf->host, &new_aconf->addr,
944 +                                     &new_aconf->bits);
945 +
946        conf_add_class_to_conf(new_conf, class_name);
947        if (yy_aconf->passwd != NULL)
948          DupString(new_aconf->passwd, yy_aconf->passwd);
# Line 1037 | Line 989 | oper_entry: OPERATOR
989    }
990   };
991  
1040 oper_name_b: | oper_name_t;
992   oper_items:     oper_items oper_item | oper_item;
993 < oper_item:      oper_name | oper_user | oper_password | oper_hidden_admin |
994 <                oper_hidden_oper | oper_umodes |
995 <                oper_class | oper_global_kill | oper_remote |
1045 <                oper_kline | oper_xline | oper_unkline |
1046 <                oper_gline | oper_nick_changes | oper_remoteban |
1047 <                oper_die | oper_rehash | oper_admin | oper_operwall |
1048 <                oper_encrypted | oper_rsa_public_key_file |
1049 <                oper_flags | error ';' ;
993 > oper_item:      oper_name | oper_user | oper_password |
994 >                oper_umodes | oper_class | oper_encrypted |
995 >                oper_rsa_public_key_file | oper_flags | error ';' ;
996  
997   oper_name: NAME '=' QSTRING ';'
998   {
999    if (conf_parser_ctx.pass == 2)
1000    {
1055    if (strlen(yylval.string) > OPERNICKLEN)
1056      yylval.string[OPERNICKLEN] = '\0';
1057
1058    MyFree(yy_conf->name);
1059    DupString(yy_conf->name, yylval.string);
1060  }
1061 };
1062
1063 oper_name_t: QSTRING
1064 {
1065  if (conf_parser_ctx.pass == 2)
1066  {
1067    if (strlen(yylval.string) > OPERNICKLEN)
1068      yylval.string[OPERNICKLEN] = '\0';
1069
1001      MyFree(yy_conf->name);
1002      DupString(yy_conf->name, yylval.string);
1003    }
# Line 1093 | Line 1024 | oper_user: USER '=' QSTRING ';'
1024      {
1025        DupString(yy_aconf->user, userbuf);
1026        DupString(yy_aconf->host, hostbuf);
1027 +
1028 +      yy_aconf->type = parse_netmask(yy_aconf->host, &yy_aconf->addr,
1029 +                                    &yy_aconf->bits);
1030      }
1031      else
1032      {
# Line 1211 | Line 1145 | oper_umodes_item:  T_BOTS
1145   {
1146    if (conf_parser_ctx.pass == 2)
1147      yy_aconf->modes |= UMODE_FULL;
1148 + } | HIDDEN
1149 + {
1150 +  if (conf_parser_ctx.pass == 2)
1151 +    yy_aconf->modes |= UMODE_HIDDEN;
1152   } | T_SKILL
1153   {
1154    if (conf_parser_ctx.pass == 2)
# Line 1265 | Line 1203 | oper_umodes_item:  T_BOTS
1203      yy_aconf->modes |= UMODE_LOCOPS;
1204   };
1205  
1268 oper_global_kill: GLOBAL_KILL '=' TBOOL ';'
1269 {
1270  if (conf_parser_ctx.pass == 2)
1271  {
1272    if (yylval.number)
1273      yy_aconf->port |= OPER_FLAG_GLOBAL_KILL;
1274    else
1275      yy_aconf->port &= ~OPER_FLAG_GLOBAL_KILL;
1276  }
1277 };
1278
1279 oper_remote: REMOTE '=' TBOOL ';'
1280 {
1281  if (conf_parser_ctx.pass == 2)
1282  {
1283    if (yylval.number)
1284      yy_aconf->port |= OPER_FLAG_REMOTE;
1285    else
1286      yy_aconf->port &= ~OPER_FLAG_REMOTE;
1287  }
1288 };
1289
1290 oper_remoteban: REMOTEBAN '=' TBOOL ';'
1291 {
1292  if (conf_parser_ctx.pass == 2)
1293  {
1294    if (yylval.number)
1295      yy_aconf->port |= OPER_FLAG_REMOTEBAN;
1296    else
1297      yy_aconf->port &= ~OPER_FLAG_REMOTEBAN;
1298  }
1299 };
1300
1301 oper_kline: KLINE '=' TBOOL ';'
1302 {
1303  if (conf_parser_ctx.pass == 2)
1304  {
1305    if (yylval.number)
1306      yy_aconf->port |= OPER_FLAG_K;
1307    else
1308      yy_aconf->port &= ~OPER_FLAG_K;
1309  }
1310 };
1311
1312 oper_xline: XLINE '=' TBOOL ';'
1313 {
1314  if (conf_parser_ctx.pass == 2)
1315  {
1316    if (yylval.number)
1317      yy_aconf->port |= OPER_FLAG_X;
1318    else
1319      yy_aconf->port &= ~OPER_FLAG_X;
1320  }
1321 };
1322
1323 oper_unkline: UNKLINE '=' TBOOL ';'
1324 {
1325  if (conf_parser_ctx.pass == 2)
1326  {
1327    if (yylval.number)
1328      yy_aconf->port |= OPER_FLAG_UNKLINE;
1329    else
1330      yy_aconf->port &= ~OPER_FLAG_UNKLINE;
1331  }
1332 };
1333
1334 oper_gline: GLINE '=' TBOOL ';'
1335 {
1336  if (conf_parser_ctx.pass == 2)
1337  {
1338    if (yylval.number)
1339      yy_aconf->port |= OPER_FLAG_GLINE;
1340    else
1341      yy_aconf->port &= ~OPER_FLAG_GLINE;
1342  }
1343 };
1344
1345 oper_nick_changes: NICK_CHANGES '=' TBOOL ';'
1346 {
1347  if (conf_parser_ctx.pass == 2)
1348  {
1349    if (yylval.number)
1350      yy_aconf->port |= OPER_FLAG_N;
1351    else
1352      yy_aconf->port &= ~OPER_FLAG_N;
1353  }
1354 };
1355
1356 oper_die: DIE '=' TBOOL ';'
1357 {
1358  if (conf_parser_ctx.pass == 2)
1359  {
1360    if (yylval.number)
1361      yy_aconf->port |= OPER_FLAG_DIE;
1362    else
1363      yy_aconf->port &= ~OPER_FLAG_DIE;
1364  }
1365 };
1366
1367 oper_rehash: REHASH '=' TBOOL ';'
1368 {
1369  if (conf_parser_ctx.pass == 2)
1370  {
1371    if (yylval.number)
1372      yy_aconf->port |= OPER_FLAG_REHASH;
1373    else
1374      yy_aconf->port &= ~OPER_FLAG_REHASH;
1375  }
1376 };
1377
1378 oper_admin: ADMIN '=' TBOOL ';'
1379 {
1380  if (conf_parser_ctx.pass == 2)
1381  {
1382    if (yylval.number)
1383      yy_aconf->port |= OPER_FLAG_ADMIN;
1384    else
1385      yy_aconf->port &= ~OPER_FLAG_ADMIN;
1386  }
1387 };
1388
1389 oper_hidden_admin: HIDDEN_ADMIN '=' TBOOL ';'
1390 {
1391  if (conf_parser_ctx.pass == 2)
1392  {
1393    if (yylval.number)
1394      yy_aconf->port |= OPER_FLAG_HIDDEN_ADMIN;
1395    else
1396      yy_aconf->port &= ~OPER_FLAG_HIDDEN_ADMIN;
1397  }
1398 };
1399
1400 oper_hidden_oper: HIDDEN_OPER '=' TBOOL ';'
1401 {
1402  if (conf_parser_ctx.pass == 2)
1403  {
1404    if (yylval.number)
1405      yy_aconf->port |= OPER_FLAG_HIDDEN_OPER;
1406    else
1407      yy_aconf->port &= ~OPER_FLAG_HIDDEN_OPER;
1408  }
1409 };
1410
1411 oper_operwall: T_OPERWALL '=' TBOOL ';'
1412 {
1413  if (conf_parser_ctx.pass == 2)
1414  {
1415    if (yylval.number)
1416      yy_aconf->port |= OPER_FLAG_OPERWALL;
1417    else
1418      yy_aconf->port &= ~OPER_FLAG_OPERWALL;
1419  }
1420 };
1421
1206   oper_flags: IRCD_FLAGS
1207   {
1208 +  if (conf_parser_ctx.pass == 2)
1209 +    yy_aconf->port = 0;
1210   } '='  oper_flags_items ';';
1211  
1212   oper_flags_items: oper_flags_items ',' oper_flags_item | oper_flags_item;
1213 < oper_flags_item: NOT { not_atom = 1; } oper_flags_item_atom
1428 <                | { not_atom = 0; } oper_flags_item_atom;
1429 <
1430 < oper_flags_item_atom: GLOBAL_KILL
1213 > oper_flags_item: GLOBAL_KILL
1214   {
1215    if (conf_parser_ctx.pass == 2)
1216 <  {
1434 <    if (not_atom)yy_aconf->port &= ~OPER_FLAG_GLOBAL_KILL;
1435 <    else yy_aconf->port |= OPER_FLAG_GLOBAL_KILL;
1436 <  }
1216 >    yy_aconf->port |= OPER_FLAG_GLOBAL_KILL;
1217   } | REMOTE
1218   {
1219    if (conf_parser_ctx.pass == 2)
1220 <  {
1441 <    if (not_atom) yy_aconf->port &= ~OPER_FLAG_REMOTE;
1442 <    else yy_aconf->port |= OPER_FLAG_REMOTE;
1443 <  }
1220 >    yy_aconf->port |= OPER_FLAG_REMOTE;
1221   } | KLINE
1222   {
1223    if (conf_parser_ctx.pass == 2)
1224 <  {
1448 <    if (not_atom) yy_aconf->port &= ~OPER_FLAG_K;
1449 <    else yy_aconf->port |= OPER_FLAG_K;
1450 <  }
1224 >    yy_aconf->port |= OPER_FLAG_K;
1225   } | UNKLINE
1226   {
1227    if (conf_parser_ctx.pass == 2)
1228 <  {
1229 <    if (not_atom) yy_aconf->port &= ~OPER_FLAG_UNKLINE;
1230 <    else yy_aconf->port |= OPER_FLAG_UNKLINE;
1231 <  }
1228 >    yy_aconf->port |= OPER_FLAG_UNKLINE;
1229 > } | T_DLINE
1230 > {
1231 >  if (conf_parser_ctx.pass == 2)
1232 >    yy_aconf->port |= OPER_FLAG_DLINE;
1233 > } | T_UNDLINE
1234 > {
1235 >  if (conf_parser_ctx.pass == 2)
1236 >    yy_aconf->port |= OPER_FLAG_UNDLINE;
1237   } | XLINE
1238   {
1239    if (conf_parser_ctx.pass == 2)
1240 <  {
1462 <    if (not_atom) yy_aconf->port &= ~OPER_FLAG_X;
1463 <    else yy_aconf->port |= OPER_FLAG_X;
1464 <  }
1240 >    yy_aconf->port |= OPER_FLAG_X;
1241   } | GLINE
1242   {
1243    if (conf_parser_ctx.pass == 2)
1244 <  {
1469 <    if (not_atom) yy_aconf->port &= ~OPER_FLAG_GLINE;
1470 <    else yy_aconf->port |= OPER_FLAG_GLINE;
1471 <  }
1244 >    yy_aconf->port |= OPER_FLAG_GLINE;
1245   } | DIE
1246   {
1247    if (conf_parser_ctx.pass == 2)
1248 <  {
1249 <    if (not_atom) yy_aconf->port &= ~OPER_FLAG_DIE;
1477 <    else yy_aconf->port |= OPER_FLAG_DIE;
1478 <  }
1479 < } | REHASH
1248 >    yy_aconf->port |= OPER_FLAG_DIE;
1249 > } | T_RESTART
1250   {
1251    if (conf_parser_ctx.pass == 2)
1252 <  {
1253 <    if (not_atom) yy_aconf->port &= ~OPER_FLAG_REHASH;
1484 <    else yy_aconf->port |= OPER_FLAG_REHASH;
1485 <  }
1486 < } | ADMIN
1252 >    yy_aconf->port |= OPER_FLAG_RESTART;
1253 > } | REHASH
1254   {
1255    if (conf_parser_ctx.pass == 2)
1256 <  {
1257 <    if (not_atom) yy_aconf->port &= ~OPER_FLAG_ADMIN;
1491 <    else yy_aconf->port |= OPER_FLAG_ADMIN;
1492 <  }
1493 < } | HIDDEN_ADMIN
1256 >    yy_aconf->port |= OPER_FLAG_REHASH;
1257 > } | ADMIN
1258   {
1259    if (conf_parser_ctx.pass == 2)
1260 <  {
1497 <    if (not_atom) yy_aconf->port &= ~OPER_FLAG_HIDDEN_ADMIN;
1498 <    else yy_aconf->port |= OPER_FLAG_HIDDEN_ADMIN;
1499 <  }
1260 >    yy_aconf->port |= OPER_FLAG_ADMIN;
1261   } | NICK_CHANGES
1262   {
1263    if (conf_parser_ctx.pass == 2)
1264 <  {
1504 <    if (not_atom) yy_aconf->port &= ~OPER_FLAG_N;
1505 <    else yy_aconf->port |= OPER_FLAG_N;
1506 <  }
1264 >    yy_aconf->port |= OPER_FLAG_N;
1265   } | T_OPERWALL
1266   {
1267    if (conf_parser_ctx.pass == 2)
1268 <  {
1269 <    if (not_atom) yy_aconf->port &= ~OPER_FLAG_OPERWALL;
1512 <    else yy_aconf->port |= OPER_FLAG_OPERWALL;
1513 <  }
1514 < } | OPER_SPY_T
1268 >    yy_aconf->port |= OPER_FLAG_OPERWALL;
1269 > } | T_GLOBOPS
1270   {
1271    if (conf_parser_ctx.pass == 2)
1272 <  {
1273 <    if (not_atom) yy_aconf->port &= ~OPER_FLAG_OPER_SPY;
1519 <    else yy_aconf->port |= OPER_FLAG_OPER_SPY;
1520 <  }
1521 < } | HIDDEN_OPER
1272 >    yy_aconf->port |= OPER_FLAG_GLOBOPS;
1273 > } | OPER_SPY_T
1274   {
1275    if (conf_parser_ctx.pass == 2)
1276 <  {
1525 <    if (not_atom) yy_aconf->port &= ~OPER_FLAG_HIDDEN_OPER;
1526 <    else yy_aconf->port |= OPER_FLAG_HIDDEN_OPER;
1527 <  }
1276 >    yy_aconf->port |= OPER_FLAG_OPER_SPY;
1277   } | REMOTEBAN
1278   {
1279    if (conf_parser_ctx.pass == 2)
1280 <  {
1281 <    if (not_atom) yy_aconf->port &= ~OPER_FLAG_REMOTEBAN;
1533 <    else yy_aconf->port |= OPER_FLAG_REMOTEBAN;
1534 <  }
1535 < } | ENCRYPTED
1280 >    yy_aconf->port |= OPER_FLAG_REMOTEBAN;
1281 > } | MODULE
1282   {
1283    if (conf_parser_ctx.pass == 2)
1284 <  {
1539 <    if (not_atom) ClearConfEncrypted(yy_aconf);
1540 <    else SetConfEncrypted(yy_aconf);
1541 <  }
1284 >    yy_aconf->port |= OPER_FLAG_MODULE;
1285   };
1286  
1287  
# Line 1552 | Line 1295 | class_entry: CLASS
1295      yy_conf = make_conf_item(CLASS_TYPE);
1296      yy_class = map_to_conf(yy_conf);
1297    }
1298 < } class_name_b '{' class_items '}' ';'
1298 > } '{' class_items '}' ';'
1299   {
1300    if (conf_parser_ctx.pass == 1)
1301    {
# Line 1563 | Line 1306 | class_entry: CLASS
1306        delete_conf_item(yy_conf);
1307      else
1308      {
1309 <      cconf = find_exact_name_conf(CLASS_TYPE, yy_class_name, NULL, NULL);
1309 >      cconf = find_exact_name_conf(CLASS_TYPE, NULL, yy_class_name, NULL, NULL);
1310  
1311        if (cconf != NULL)                /* The class existed already */
1312        {
# Line 1595 | Line 1338 | class_entry: CLASS
1338    }
1339   };
1340  
1598 class_name_b: | class_name_t;
1599
1341   class_items:    class_items class_item | class_item;
1342   class_item:     class_name |
1343                  class_cidr_bitlen_ipv4 | class_cidr_bitlen_ipv6 |
# Line 1621 | Line 1362 | class_name: NAME '=' QSTRING ';'
1362    }
1363   };
1364  
1624 class_name_t: QSTRING
1625 {
1626  if (conf_parser_ctx.pass == 1)
1627  {
1628    MyFree(yy_class_name);
1629    DupString(yy_class_name, yylval.string);
1630  }
1631 };
1632
1365   class_ping_time: PING_TIME '=' timespec ';'
1366   {
1367    if (conf_parser_ctx.pass == 1)
1368 <    PingFreq(yy_class) = $3;
1368 >    yy_class->ping_freq = $3;
1369   };
1370  
1371   class_ping_warning: PING_WARNING '=' timespec ';'
1372   {
1373    if (conf_parser_ctx.pass == 1)
1374 <    PingWarning(yy_class) = $3;
1374 >    yy_class->ping_warning = $3;
1375   };
1376  
1377   class_number_per_ip: NUMBER_PER_IP '=' NUMBER ';'
1378   {
1379    if (conf_parser_ctx.pass == 1)
1380 <    MaxPerIp(yy_class) = $3;
1380 >    yy_class->max_perip = $3;
1381   };
1382  
1383   class_connectfreq: CONNECTFREQ '=' timespec ';'
1384   {
1385    if (conf_parser_ctx.pass == 1)
1386 <    ConFreq(yy_class) = $3;
1386 >    yy_class->con_freq = $3;
1387   };
1388  
1389   class_max_number: MAX_NUMBER '=' NUMBER ';'
1390   {
1391    if (conf_parser_ctx.pass == 1)
1392 <    MaxTotal(yy_class) = $3;
1392 >    yy_class->max_total = $3;
1393   };
1394  
1395   class_max_global: MAX_GLOBAL '=' NUMBER ';'
1396   {
1397    if (conf_parser_ctx.pass == 1)
1398 <    MaxGlobal(yy_class) = $3;
1398 >    yy_class->max_global = $3;
1399   };
1400  
1401   class_max_local: MAX_LOCAL '=' NUMBER ';'
1402   {
1403    if (conf_parser_ctx.pass == 1)
1404 <    MaxLocal(yy_class) = $3;
1404 >    yy_class->max_local = $3;
1405   };
1406  
1407   class_max_ident: MAX_IDENT '=' NUMBER ';'
1408   {
1409    if (conf_parser_ctx.pass == 1)
1410 <    MaxIdent(yy_class) = $3;
1410 >    yy_class->max_ident = $3;
1411   };
1412  
1413   class_sendq: SENDQ '=' sizespec ';'
1414   {
1415    if (conf_parser_ctx.pass == 1)
1416 <    MaxSendq(yy_class) = $3;
1416 >    yy_class->max_sendq = $3;
1417   };
1418  
1419   class_cidr_bitlen_ipv4: CIDR_BITLEN_IPV4 '=' NUMBER ';'
1420   {
1421    if (conf_parser_ctx.pass == 1)
1422 <    CidrBitlenIPV4(yy_class) = $3;
1422 >    yy_class->cidr_bitlen_ipv4 = $3 > 32 ? 32 : $3;
1423   };
1424  
1425   class_cidr_bitlen_ipv6: CIDR_BITLEN_IPV6 '=' NUMBER ';'
1426   {
1427    if (conf_parser_ctx.pass == 1)
1428 <    CidrBitlenIPV6(yy_class) = $3;
1428 >    yy_class->cidr_bitlen_ipv6 = $3 > 128 ? 128 : $3;
1429   };
1430  
1431   class_number_per_cidr: NUMBER_PER_CIDR '=' NUMBER ';'
1432   {
1433    if (conf_parser_ctx.pass == 1)
1434 <    NumberPerCidr(yy_class) = $3;
1434 >    yy_class->number_per_cidr = $3;
1435   };
1436  
1437   /***************************************************************************
# Line 1876 | Line 1608 | auth_entry: IRCD_AUTH
1608  
1609   auth_items:     auth_items auth_item | auth_item;
1610   auth_item:      auth_user | auth_passwd | auth_class | auth_flags |
1611 <                auth_kline_exempt | auth_need_ident |
1612 <                auth_exceed_limit | auth_no_tilde | auth_gline_exempt |
1881 <                auth_spoof | auth_spoof_notice |
1882 <                auth_redir_serv | auth_redir_port | auth_can_flood |
1883 <                auth_need_password | auth_encrypted | error ';' ;
1611 >                auth_spoof | auth_redir_serv | auth_redir_port |
1612 >                auth_encrypted | error ';' ;
1613  
1614   auth_user: USER '=' QSTRING ';'
1615   {
# Line 1917 | Line 1646 | auth_user: USER '=' QSTRING ';'
1646    }
1647   };
1648  
1920 /* XXX - IP/IPV6 tags don't exist anymore - put IP/IPV6 into user. */
1921
1649   auth_passwd: PASSWORD '=' QSTRING ';'
1650   {
1651    if (conf_parser_ctx.pass == 2)
# Line 1932 | Line 1659 | auth_passwd: PASSWORD '=' QSTRING ';'
1659    }
1660   };
1661  
1935 auth_spoof_notice: SPOOF_NOTICE '=' TBOOL ';'
1936 {
1937  if (conf_parser_ctx.pass == 2)
1938  {
1939    if (yylval.number)
1940      yy_aconf->flags |= CONF_FLAGS_SPOOF_NOTICE;
1941    else
1942      yy_aconf->flags &= ~CONF_FLAGS_SPOOF_NOTICE;
1943  }
1944 };
1945
1662   auth_class: CLASS '=' QSTRING ';'
1663   {
1664    if (conf_parser_ctx.pass == 2)
# Line 1968 | Line 1684 | auth_flags: IRCD_FLAGS
1684   } '='  auth_flags_items ';';
1685  
1686   auth_flags_items: auth_flags_items ',' auth_flags_item | auth_flags_item;
1687 < auth_flags_item: NOT { not_atom = 1; } auth_flags_item_atom
1972 <                | { not_atom = 0; } auth_flags_item_atom;
1973 <
1974 < auth_flags_item_atom: SPOOF_NOTICE
1687 > auth_flags_item: SPOOF_NOTICE
1688   {
1689    if (conf_parser_ctx.pass == 2)
1690 <  {
1978 <    if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_SPOOF_NOTICE;
1979 <    else yy_aconf->flags |= CONF_FLAGS_SPOOF_NOTICE;
1980 <  }
1981 <
1690 >    yy_aconf->flags |= CONF_FLAGS_SPOOF_NOTICE;
1691   } | EXCEED_LIMIT
1692   {
1693    if (conf_parser_ctx.pass == 2)
1694 <  {
1986 <    if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_NOLIMIT;
1987 <    else yy_aconf->flags |= CONF_FLAGS_NOLIMIT;
1988 <  }
1694 >    yy_aconf->flags |= CONF_FLAGS_NOLIMIT;
1695   } | KLINE_EXEMPT
1696   {
1697    if (conf_parser_ctx.pass == 2)
1698 <  {
1993 <    if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_EXEMPTKLINE;
1994 <    else yy_aconf->flags |= CONF_FLAGS_EXEMPTKLINE;
1995 <  }
1698 >    yy_aconf->flags |= CONF_FLAGS_EXEMPTKLINE;
1699   } | NEED_IDENT
1700   {
1701    if (conf_parser_ctx.pass == 2)
1702 <  {
2000 <    if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_NEED_IDENTD;
2001 <    else yy_aconf->flags |= CONF_FLAGS_NEED_IDENTD;
2002 <  }
1702 >    yy_aconf->flags |= CONF_FLAGS_NEED_IDENTD;
1703   } | CAN_FLOOD
1704   {
1705    if (conf_parser_ctx.pass == 2)
1706 <  {
2007 <    if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_CAN_FLOOD;
2008 <    else yy_aconf->flags |= CONF_FLAGS_CAN_FLOOD;
2009 <  }
2010 < } | CAN_IDLE
2011 < {
2012 <  if (conf_parser_ctx.pass == 2)
2013 <  {
2014 <    if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_IDLE_LINED;
2015 <    else yy_aconf->flags |= CONF_FLAGS_IDLE_LINED;
2016 <  }
1706 >    yy_aconf->flags |= CONF_FLAGS_CAN_FLOOD;
1707   } | NO_TILDE
1708   {
1709    if (conf_parser_ctx.pass == 2)
1710 <  {
2021 <    if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_NO_TILDE;
2022 <    else yy_aconf->flags |= CONF_FLAGS_NO_TILDE;
2023 <  }
1710 >    yy_aconf->flags |= CONF_FLAGS_NO_TILDE;
1711   } | GLINE_EXEMPT
1712   {
1713    if (conf_parser_ctx.pass == 2)
1714 <  {
2028 <    if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_EXEMPTGLINE;
2029 <    else yy_aconf->flags |= CONF_FLAGS_EXEMPTGLINE;
2030 <  }
1714 >    yy_aconf->flags |= CONF_FLAGS_EXEMPTGLINE;
1715   } | RESV_EXEMPT
1716   {
1717    if (conf_parser_ctx.pass == 2)
1718 <  {
2035 <    if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_EXEMPTRESV;
2036 <    else yy_aconf->flags |= CONF_FLAGS_EXEMPTRESV;
2037 <  }
1718 >    yy_aconf->flags |= CONF_FLAGS_EXEMPTRESV;
1719   } | NEED_PASSWORD
1720   {
1721    if (conf_parser_ctx.pass == 2)
1722 <  {
2042 <    if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_NEED_PASSWORD;
2043 <    else yy_aconf->flags |= CONF_FLAGS_NEED_PASSWORD;
2044 <  }
2045 < };
2046 <
2047 < auth_kline_exempt: KLINE_EXEMPT '=' TBOOL ';'
2048 < {
2049 <  if (conf_parser_ctx.pass == 2)
2050 <  {
2051 <    if (yylval.number)
2052 <      yy_aconf->flags |= CONF_FLAGS_EXEMPTKLINE;
2053 <    else
2054 <      yy_aconf->flags &= ~CONF_FLAGS_EXEMPTKLINE;
2055 <  }
2056 < };
2057 <
2058 < auth_need_ident: NEED_IDENT '=' TBOOL ';'
2059 < {
2060 <  if (conf_parser_ctx.pass == 2)
2061 <  {
2062 <    if (yylval.number)
2063 <      yy_aconf->flags |= CONF_FLAGS_NEED_IDENTD;
2064 <    else
2065 <      yy_aconf->flags &= ~CONF_FLAGS_NEED_IDENTD;
2066 <  }
2067 < };
2068 <
2069 < auth_exceed_limit: EXCEED_LIMIT '=' TBOOL ';'
2070 < {
2071 <  if (conf_parser_ctx.pass == 2)
2072 <  {
2073 <    if (yylval.number)
2074 <      yy_aconf->flags |= CONF_FLAGS_NOLIMIT;
2075 <    else
2076 <      yy_aconf->flags &= ~CONF_FLAGS_NOLIMIT;
2077 <  }
2078 < };
2079 <
2080 < auth_can_flood: CAN_FLOOD '=' TBOOL ';'
2081 < {
2082 <  if (conf_parser_ctx.pass == 2)
2083 <  {
2084 <    if (yylval.number)
2085 <      yy_aconf->flags |= CONF_FLAGS_CAN_FLOOD;
2086 <    else
2087 <      yy_aconf->flags &= ~CONF_FLAGS_CAN_FLOOD;
2088 <  }
2089 < };
2090 <
2091 < auth_no_tilde: NO_TILDE '=' TBOOL ';'
2092 < {
2093 <  if (conf_parser_ctx.pass == 2)
2094 <  {
2095 <    if (yylval.number)
2096 <      yy_aconf->flags |= CONF_FLAGS_NO_TILDE;
2097 <    else
2098 <      yy_aconf->flags &= ~CONF_FLAGS_NO_TILDE;
2099 <  }
2100 < };
2101 <
2102 < auth_gline_exempt: GLINE_EXEMPT '=' TBOOL ';'
2103 < {
2104 <  if (conf_parser_ctx.pass == 2)
2105 <  {
2106 <    if (yylval.number)
2107 <      yy_aconf->flags |= CONF_FLAGS_EXEMPTGLINE;
2108 <    else
2109 <      yy_aconf->flags &= ~CONF_FLAGS_EXEMPTGLINE;
2110 <  }
1722 >    yy_aconf->flags |= CONF_FLAGS_NEED_PASSWORD;
1723   };
1724  
1725   /* XXX - need check for illegal hostnames here */
# Line 2124 | Line 1736 | auth_spoof: SPOOF '=' QSTRING ';'
1736      }
1737      else
1738      {
1739 <      ilog(L_ERROR, "Spoofs must be less than %d..ignoring it", HOSTLEN);
1739 >      ilog(LOG_TYPE_IRCD, "Spoofs must be less than %d..ignoring it", HOSTLEN);
1740        yy_conf->name = NULL;
1741      }
1742    }
# Line 2149 | Line 1761 | auth_redir_port: REDIRPORT '=' NUMBER ';
1761    }
1762   };
1763  
2152 auth_need_password: NEED_PASSWORD '=' TBOOL ';'
2153 {
2154  if (conf_parser_ctx.pass == 2)
2155  {
2156    if (yylval.number)
2157      yy_aconf->flags |= CONF_FLAGS_NEED_PASSWORD;
2158    else
2159      yy_aconf->flags &= ~CONF_FLAGS_NEED_PASSWORD;
2160  }
2161 };
2162
1764  
1765   /***************************************************************************
1766   *  section resv
# Line 2218 | Line 1819 | resv_nick: NICK '=' QSTRING ';'
1819   };
1820  
1821   /***************************************************************************
1822 + *  section service
1823 + ***************************************************************************/
1824 + service_entry: T_SERVICE '{' service_items '}' ';';
1825 +
1826 + service_items:     service_items service_item | service_item;
1827 + service_item:      service_name | error;
1828 +
1829 + service_name: NAME '=' QSTRING ';'
1830 + {
1831 +  if (conf_parser_ctx.pass == 2)
1832 +  {
1833 +    if (valid_servname(yylval.string))
1834 +    {
1835 +      yy_conf = make_conf_item(SERVICE_TYPE);
1836 +      DupString(yy_conf->name, yylval.string);
1837 +    }
1838 +  }
1839 + };
1840 +
1841 + /***************************************************************************
1842   *  section shared, for sharing remote klines etc.
1843   ***************************************************************************/
1844   shared_entry: T_SHARED
# Line 2281 | Line 1902 | shared_type_item: KLINE
1902   {
1903    if (conf_parser_ctx.pass == 2)
1904      yy_match_item->action |= SHARED_KLINE;
2284 } | TKLINE
2285 {
2286  if (conf_parser_ctx.pass == 2)
2287    yy_match_item->action |= SHARED_TKLINE;
1905   } | UNKLINE
1906   {
1907    if (conf_parser_ctx.pass == 2)
1908      yy_match_item->action |= SHARED_UNKLINE;
1909 < } | XLINE
1909 > } | T_DLINE
1910   {
1911    if (conf_parser_ctx.pass == 2)
1912 <    yy_match_item->action |= SHARED_XLINE;
1913 < } | TXLINE
1912 >    yy_match_item->action |= SHARED_DLINE;
1913 > } | T_UNDLINE
1914   {
1915    if (conf_parser_ctx.pass == 2)
1916 <    yy_match_item->action |= SHARED_TXLINE;
1916 >    yy_match_item->action |= SHARED_UNDLINE;
1917 > } | XLINE
1918 > {
1919 >  if (conf_parser_ctx.pass == 2)
1920 >    yy_match_item->action |= SHARED_XLINE;
1921   } | T_UNXLINE
1922   {
1923    if (conf_parser_ctx.pass == 2)
# Line 2305 | Line 1926 | shared_type_item: KLINE
1926   {
1927    if (conf_parser_ctx.pass == 2)
1928      yy_match_item->action |= SHARED_RESV;
2308 } | TRESV
2309 {
2310  if (conf_parser_ctx.pass == 2)
2311    yy_match_item->action |= SHARED_TRESV;
1929   } | T_UNRESV
1930   {
1931    if (conf_parser_ctx.pass == 2)
# Line 2363 | Line 1980 | cluster_type_item: KLINE
1980   {
1981    if (conf_parser_ctx.pass == 2)
1982      yy_conf->flags |= SHARED_KLINE;
2366 } | TKLINE
2367 {
2368  if (conf_parser_ctx.pass == 2)
2369    yy_conf->flags |= SHARED_TKLINE;
1983   } | UNKLINE
1984   {
1985    if (conf_parser_ctx.pass == 2)
1986      yy_conf->flags |= SHARED_UNKLINE;
1987 < } | XLINE
1987 > } | T_DLINE
1988   {
1989    if (conf_parser_ctx.pass == 2)
1990 <    yy_conf->flags |= SHARED_XLINE;
1991 < } | TXLINE
1990 >    yy_conf->flags |= SHARED_DLINE;
1991 > } | T_UNDLINE
1992 > {
1993 >  if (conf_parser_ctx.pass == 2)
1994 >    yy_conf->flags |= SHARED_UNDLINE;
1995 > } | XLINE
1996   {
1997    if (conf_parser_ctx.pass == 2)
1998 <    yy_conf->flags |= SHARED_TXLINE;
1998 >    yy_conf->flags |= SHARED_XLINE;
1999   } | T_UNXLINE
2000   {
2001    if (conf_parser_ctx.pass == 2)
# Line 2387 | Line 2004 | cluster_type_item: KLINE
2004   {
2005    if (conf_parser_ctx.pass == 2)
2006      yy_conf->flags |= SHARED_RESV;
2390 } | TRESV
2391 {
2392  if (conf_parser_ctx.pass == 2)
2393    yy_conf->flags |= SHARED_TRESV;
2007   } | T_UNRESV
2008   {
2009    if (conf_parser_ctx.pass == 2)
# Line 2413 | Line 2026 | connect_entry: CONNECT
2026    if (conf_parser_ctx.pass == 2)
2027    {
2028      yy_conf = make_conf_item(SERVER_TYPE);
2029 <    yy_aconf = (struct AccessItem *)map_to_conf(yy_conf);
2030 <    yy_aconf->passwd = NULL;
2029 >    yy_aconf = map_to_conf(yy_conf);
2030 >
2031      /* defaults */
2032      yy_aconf->port = PORTNUM;
2420
2421    if (ConfigFileEntry.burst_away)
2422      yy_aconf->flags = CONF_FLAGS_BURST_AWAY;
2033    }
2034    else
2035    {
2036      MyFree(class_name);
2037      class_name = NULL;
2038    }
2039 < } connect_name_b '{' connect_items '}' ';'
2039 > } '{' connect_items '}' ';'
2040   {
2041    if (conf_parser_ctx.pass == 2)
2042    {
2043 <    struct CollectItem *yy_hconf=NULL;
2044 <    struct CollectItem *yy_lconf=NULL;
2045 <    dlink_node *ptr;
2046 <    dlink_node *next_ptr;
2047 < #ifdef HAVE_LIBCRYPTO
2048 <    if (yy_aconf->host &&
2049 <        ((yy_aconf->passwd && yy_aconf->spasswd) ||
2050 <         (yy_aconf->rsa_public_key && IsConfCryptLink(yy_aconf))))
2441 < #else /* !HAVE_LIBCRYPTO */
2442 <      if (yy_aconf->host && !IsConfCryptLink(yy_aconf) &&
2443 <          yy_aconf->passwd && yy_aconf->spasswd)
2444 < #endif /* !HAVE_LIBCRYPTO */
2445 <        {
2446 <          if (conf_add_server(yy_conf, class_name) == -1)
2447 <          {
2448 <            delete_conf_item(yy_conf);
2449 <            yy_conf = NULL;
2450 <            yy_aconf = NULL;
2451 <          }
2452 <        }
2453 <        else
2454 <        {
2455 <          /* Even if yy_conf ->name is NULL
2456 <           * should still unhook any hub/leaf confs still pending
2457 <           */
2458 <          unhook_hub_leaf_confs();
2459 <
2460 <          if (yy_conf->name != NULL)
2461 <          {
2462 < #ifndef HAVE_LIBCRYPTO
2463 <            if (IsConfCryptLink(yy_aconf))
2464 <              yyerror("Ignoring connect block -- no OpenSSL support");
2465 < #else
2466 <            if (IsConfCryptLink(yy_aconf) && !yy_aconf->rsa_public_key)
2467 <              yyerror("Ignoring connect block -- missing key");
2468 < #endif
2469 <            if (yy_aconf->host == NULL)
2470 <              yyerror("Ignoring connect block -- missing host");
2471 <            else if (!IsConfCryptLink(yy_aconf) &&
2472 <                    (!yy_aconf->passwd || !yy_aconf->spasswd))
2473 <              yyerror("Ignoring connect block -- missing password");
2474 <          }
2475 <
2476 <
2477 <          /* XXX
2478 <           * This fixes a try_connections() core (caused by invalid class_ptr
2479 <           * pointers) reported by metalrock. That's an ugly fix, but there
2480 <           * is currently no better way. The entire config subsystem needs an
2481 <           * rewrite ASAP. make_conf_item() shouldn't really add things onto
2482 <           * a doubly linked list immediately without any sanity checks!  -Michael
2483 <           */
2484 <          delete_conf_item(yy_conf);
2485 <
2486 <          yy_aconf = NULL;
2487 <          yy_conf = NULL;
2488 <        }
2489 <
2490 <      /*
2491 <       * yy_conf is still pointing at the server that is having
2492 <       * a connect block built for it. This means, y_aconf->name
2493 <       * points to the actual irc name this server will be known as.
2494 <       * Now this new server has a set or even just one hub_mask (or leaf_mask)
2495 <       * given in the link list at yy_hconf. Fill in the HUB confs
2496 <       * from this link list now.
2497 <       */        
2498 <      DLINK_FOREACH_SAFE(ptr, next_ptr, hub_conf_list.head)
2043 >    if (yy_aconf->host && yy_aconf->passwd && yy_aconf->spasswd)
2044 >    {
2045 >      if (conf_add_server(yy_conf, class_name) == -1)
2046 >        delete_conf_item(yy_conf);
2047 >    }
2048 >    else
2049 >    {
2050 >      if (yy_conf->name != NULL)
2051        {
2052 <        struct ConfItem *new_hub_conf;
2053 <        struct MatchItem *match_item;
2054 <
2055 <        yy_hconf = ptr->data;
2504 <
2505 <        /* yy_conf == NULL is a fatal error for this connect block! */
2506 <        if ((yy_conf != NULL) && (yy_conf->name != NULL))
2507 <        {
2508 <          new_hub_conf = make_conf_item(HUB_TYPE);
2509 <          match_item = (struct MatchItem *)map_to_conf(new_hub_conf);
2510 <          DupString(new_hub_conf->name, yy_conf->name);
2511 <          if (yy_hconf->user != NULL)
2512 <            DupString(match_item->user, yy_hconf->user);
2513 <          else
2514 <            DupString(match_item->user, "*");
2515 <          if (yy_hconf->host != NULL)
2516 <            DupString(match_item->host, yy_hconf->host);
2517 <          else
2518 <            DupString(match_item->host, "*");
2519 <        }
2520 <        dlinkDelete(&yy_hconf->node, &hub_conf_list);
2521 <        free_collect_item(yy_hconf);
2052 >        if (yy_aconf->host == NULL)
2053 >          yyerror("Ignoring connect block -- missing host");
2054 >        else if (!yy_aconf->passwd || !yy_aconf->spasswd)
2055 >          yyerror("Ignoring connect block -- missing password");
2056        }
2057  
2058 <      /* Ditto for the LEAF confs */
2059 <
2060 <      DLINK_FOREACH_SAFE(ptr, next_ptr, leaf_conf_list.head)
2061 <      {
2062 <        struct ConfItem *new_leaf_conf;
2063 <        struct MatchItem *match_item;
2064 <
2065 <        yy_lconf = ptr->data;
2058 >      /* XXX
2059 >       * This fixes a try_connections() core (caused by invalid class_ptr
2060 >       * pointers) reported by metalrock. That's an ugly fix, but there
2061 >       * is currently no better way. The entire config subsystem needs an
2062 >       * rewrite ASAP. make_conf_item() shouldn't really add things onto
2063 >       * a doubly linked list immediately without any sanity checks!  -Michael
2064 >       */
2065 >      delete_conf_item(yy_conf);
2066 >    }
2067  
2068 <        if ((yy_conf != NULL) && (yy_conf->name != NULL))
2069 <        {
2070 <          new_leaf_conf = make_conf_item(LEAF_TYPE);
2071 <          match_item = (struct MatchItem *)map_to_conf(new_leaf_conf);
2537 <          DupString(new_leaf_conf->name, yy_conf->name);
2538 <          if (yy_lconf->user != NULL)
2539 <            DupString(match_item->user, yy_lconf->user);
2540 <          else
2541 <            DupString(match_item->user, "*");
2542 <          if (yy_lconf->host != NULL)
2543 <            DupString(match_item->host, yy_lconf->host);
2544 <          else
2545 <            DupString(match_item->host, "*");
2546 <        }
2547 <        dlinkDelete(&yy_lconf->node, &leaf_conf_list);
2548 <        free_collect_item(yy_lconf);
2549 <      }
2550 <      MyFree(class_name);
2551 <      class_name = NULL;
2552 <      yy_conf = NULL;
2553 <      yy_aconf = NULL;
2068 >    MyFree(class_name);
2069 >    class_name = NULL;
2070 >    yy_conf = NULL;
2071 >    yy_aconf = NULL;
2072    }
2073   };
2074  
2557 connect_name_b: | connect_name_t;
2075   connect_items:  connect_items connect_item | connect_item;
2076   connect_item:   connect_name | connect_host | connect_vhost |
2077                  connect_send_password | connect_accept_password |
2078 <                connect_aftype | connect_port |
2079 <                connect_fakename | connect_flags | connect_hub_mask |
2080 <                connect_leaf_mask | connect_class | connect_auto |
2081 <                connect_encrypted | connect_compressed | connect_cryptlink |
2565 <                connect_rsa_public_key_file | connect_cipher_preference |
2566 <                connect_topicburst | error ';' ;
2078 >                connect_aftype | connect_port | connect_ssl_cipher_list |
2079 >                connect_flags | connect_hub_mask | connect_leaf_mask |
2080 >                connect_class | connect_encrypted |
2081 >                error ';' ;
2082  
2083   connect_name: NAME '=' QSTRING ';'
2084   {
2085    if (conf_parser_ctx.pass == 2)
2086    {
2572    if (yy_conf->name != NULL)
2573      yyerror("Multiple connect name entry");
2574
2575    MyFree(yy_conf->name);
2576    DupString(yy_conf->name, yylval.string);
2577  }
2578 };
2579
2580 connect_name_t: QSTRING
2581 {
2582  if (conf_parser_ctx.pass == 2)
2583  {
2584    if (yy_conf->name != NULL)
2585      yyerror("Multiple connect name entry");
2586
2087      MyFree(yy_conf->name);
2088      DupString(yy_conf->name, yylval.string);
2089    }
# Line 2610 | Line 2110 | connect_vhost: VHOST '=' QSTRING ';'
2110      hints.ai_socktype = SOCK_STREAM;
2111      hints.ai_flags    = AI_PASSIVE | AI_NUMERICHOST;
2112  
2113 <    if (irc_getaddrinfo(yylval.string, NULL, &hints, &res))
2114 <      ilog(L_ERROR, "Invalid netmask for server vhost(%s)", yylval.string);
2113 >    if (getaddrinfo(yylval.string, NULL, &hints, &res))
2114 >      ilog(LOG_TYPE_IRCD, "Invalid netmask for server vhost(%s)", yylval.string);
2115      else
2116      {
2117        assert(res != NULL);
2118  
2119 <      memcpy(&yy_aconf->my_ipnum, res->ai_addr, res->ai_addrlen);
2120 <      yy_aconf->my_ipnum.ss.ss_family = res->ai_family;
2121 <      yy_aconf->my_ipnum.ss_len = res->ai_addrlen;
2122 <      irc_freeaddrinfo(res);
2119 >      memcpy(&yy_aconf->bind, res->ai_addr, res->ai_addrlen);
2120 >      yy_aconf->bind.ss.ss_family = res->ai_family;
2121 >      yy_aconf->bind.ss_len = res->ai_addrlen;
2122 >      freeaddrinfo(res);
2123      }
2124    }
2125   };
# Line 2678 | Line 2178 | connect_aftype: AFTYPE '=' T_IPV4 ';'
2178   #endif
2179   };
2180  
2681 connect_fakename: FAKENAME '=' QSTRING ';'
2682 {
2683  if (conf_parser_ctx.pass == 2)
2684  {
2685    MyFree(yy_aconf->fakename);
2686    DupString(yy_aconf->fakename, yylval.string);
2687  }
2688 };
2689
2181   connect_flags: IRCD_FLAGS
2182   {
2183   } '='  connect_flags_items ';';
2184  
2185   connect_flags_items: connect_flags_items ',' connect_flags_item | connect_flags_item;
2186 < connect_flags_item: NOT  { not_atom = 1; } connect_flags_item_atom
2696 <                        |  { not_atom = 0; } connect_flags_item_atom;
2697 <
2698 < connect_flags_item_atom: COMPRESSED
2699 < {
2700 <  if (conf_parser_ctx.pass == 2)
2701 < #ifndef HAVE_LIBZ
2702 <    yyerror("Ignoring flags = compressed; -- no zlib support");
2703 < #else
2704 < {
2705 <   if (not_atom)ClearConfCompressed(yy_aconf);
2706 <   else SetConfCompressed(yy_aconf);
2707 < }
2708 < #endif
2709 < } | CRYPTLINK
2710 < {
2711 <  if (conf_parser_ctx.pass == 2)
2712 <  {
2713 <    if (not_atom)ClearConfCryptLink(yy_aconf);
2714 <    else SetConfCryptLink(yy_aconf);
2715 <  }
2716 < } | AUTOCONN
2186 > connect_flags_item: AUTOCONN
2187   {
2188    if (conf_parser_ctx.pass == 2)
2189 <  {
2720 <    if (not_atom)ClearConfAllowAutoConn(yy_aconf);
2721 <    else SetConfAllowAutoConn(yy_aconf);
2722 <  }
2189 >    SetConfAllowAutoConn(yy_aconf);
2190   } | BURST_AWAY
2191   {
2192    if (conf_parser_ctx.pass == 2)
2193 <  {
2727 <    if (not_atom)ClearConfAwayBurst(yy_aconf);
2728 <    else SetConfAwayBurst(yy_aconf);
2729 <  }
2193 >    SetConfAwayBurst(yy_aconf);
2194   } | TOPICBURST
2195   {
2196    if (conf_parser_ctx.pass == 2)
2197 <  {
2198 <    if (not_atom)ClearConfTopicBurst(yy_aconf);
2735 <    else SetConfTopicBurst(yy_aconf);
2736 <  }
2737 < }
2738 < ;
2739 <
2740 < connect_rsa_public_key_file: RSA_PUBLIC_KEY_FILE '=' QSTRING ';'
2197 >    SetConfTopicBurst(yy_aconf);
2198 > } | T_SSL
2199   {
2742 #ifdef HAVE_LIBCRYPTO
2200    if (conf_parser_ctx.pass == 2)
2201 <  {
2745 <    BIO *file;
2746 <
2747 <    if (yy_aconf->rsa_public_key != NULL)
2748 <    {
2749 <      RSA_free(yy_aconf->rsa_public_key);
2750 <      yy_aconf->rsa_public_key = NULL;
2751 <    }
2752 <
2753 <    if (yy_aconf->rsa_public_key_file != NULL)
2754 <    {
2755 <      MyFree(yy_aconf->rsa_public_key_file);
2756 <      yy_aconf->rsa_public_key_file = NULL;
2757 <    }
2758 <
2759 <    DupString(yy_aconf->rsa_public_key_file, yylval.string);
2760 <
2761 <    if ((file = BIO_new_file(yylval.string, "r")) == NULL)
2762 <    {
2763 <      yyerror("Ignoring rsa_public_key_file -- file doesn't exist");
2764 <      break;
2765 <    }
2766 <
2767 <    yy_aconf->rsa_public_key = (RSA *)PEM_read_bio_RSA_PUBKEY(file, NULL, 0, NULL);
2768 <
2769 <    if (yy_aconf->rsa_public_key == NULL)
2770 <    {
2771 <      yyerror("Ignoring rsa_public_key_file -- Key invalid; check key syntax.");
2772 <      break;
2773 <    }
2774 <      
2775 <    BIO_set_close(file, BIO_CLOSE);
2776 <    BIO_free(file);
2777 <  }
2778 < #endif /* HAVE_LIBCRYPTO */
2201 >    SetConfSSL(yy_aconf);
2202   };
2203  
2204   connect_encrypted: ENCRYPTED '=' TBOOL ';'
# Line 2789 | Line 2212 | connect_encrypted: ENCRYPTED '=' TBOOL '
2212    }
2213   };
2214  
2792 connect_cryptlink: CRYPTLINK '=' TBOOL ';'
2793 {
2794  if (conf_parser_ctx.pass == 2)
2795  {
2796    if (yylval.number)
2797      yy_aconf->flags |= CONF_FLAGS_CRYPTLINK;
2798    else
2799      yy_aconf->flags &= ~CONF_FLAGS_CRYPTLINK;
2800  }
2801 };
2802
2803 connect_compressed: COMPRESSED '=' TBOOL ';'
2804 {
2805  if (conf_parser_ctx.pass == 2)
2806  {
2807    if (yylval.number)
2808 #ifndef HAVE_LIBZ
2809      yyerror("Ignoring compressed=yes; -- no zlib support");
2810 #else
2811      yy_aconf->flags |= CONF_FLAGS_COMPRESSED;
2812 #endif
2813    else
2814      yy_aconf->flags &= ~CONF_FLAGS_COMPRESSED;
2815  }
2816 };
2817
2818 connect_auto: AUTOCONN '=' TBOOL ';'
2819 {
2820  if (conf_parser_ctx.pass == 2)
2821  {
2822    if (yylval.number)
2823      yy_aconf->flags |= CONF_FLAGS_ALLOW_AUTO_CONN;
2824    else
2825      yy_aconf->flags &= ~CONF_FLAGS_ALLOW_AUTO_CONN;
2826  }
2827 };
2828
2829 connect_topicburst: TOPICBURST '=' TBOOL ';'
2830 {
2831  if (conf_parser_ctx.pass == 2)
2832  {
2833    if (yylval.number)
2834      SetConfTopicBurst(yy_aconf);
2835    else
2836      ClearConfTopicBurst(yy_aconf);
2837  }
2838 };
2839
2215   connect_hub_mask: HUB_MASK '=' QSTRING ';'
2216   {
2217    if (conf_parser_ctx.pass == 2)
2218    {
2219 <    struct CollectItem *yy_tmp;
2219 >    char *mask;
2220  
2221 <    yy_tmp = (struct CollectItem *)MyMalloc(sizeof(struct CollectItem));
2222 <    DupString(yy_tmp->host, yylval.string);
2848 <    DupString(yy_tmp->user, "*");
2849 <    dlinkAdd(yy_tmp, &yy_tmp->node, &hub_conf_list);
2221 >    DupString(mask, yylval.string);
2222 >    dlinkAdd(mask, make_dlink_node(), &yy_aconf->hub_list);
2223    }
2224   };
2225  
# Line 2854 | Line 2227 | connect_leaf_mask: LEAF_MASK '=' QSTRING
2227   {
2228    if (conf_parser_ctx.pass == 2)
2229    {
2230 <    struct CollectItem *yy_tmp;
2230 >    char *mask;
2231  
2232 <    yy_tmp = (struct CollectItem *)MyMalloc(sizeof(struct CollectItem));
2233 <    DupString(yy_tmp->host, yylval.string);
2861 <    DupString(yy_tmp->user, "*");
2862 <    dlinkAdd(yy_tmp, &yy_tmp->node, &leaf_conf_list);
2232 >    DupString(mask, yylval.string);
2233 >    dlinkAdd(mask, make_dlink_node(), &yy_aconf->leaf_list);
2234    }
2235   };
2236  
# Line 2872 | Line 2243 | connect_class: CLASS '=' QSTRING ';'
2243    }
2244   };
2245  
2246 < connect_cipher_preference: CIPHER_PREFERENCE '=' QSTRING ';'
2246 > connect_ssl_cipher_list: T_SSL_CIPHER_LIST '=' QSTRING ';'
2247   {
2248   #ifdef HAVE_LIBCRYPTO
2249    if (conf_parser_ctx.pass == 2)
2250    {
2251 <    struct EncCapability *ecap;
2252 <    const char *cipher_name;
2882 <    int found = 0;
2883 <
2884 <    yy_aconf->cipher_preference = NULL;
2885 <    cipher_name = yylval.string;
2886 <
2887 <    for (ecap = CipherTable; ecap->name; ecap++)
2888 <    {
2889 <      if ((irccmp(ecap->name, cipher_name) == 0) &&
2890 <          (ecap->cap & CAP_ENC_MASK))
2891 <      {
2892 <        yy_aconf->cipher_preference = ecap;
2893 <        found = 1;
2894 <        break;
2895 <      }
2896 <    }
2897 <
2898 <    if (!found)
2899 <      yyerror("Invalid cipher");
2251 >    MyFree(yy_aconf->cipher_list);
2252 >    DupString(yy_aconf->cipher_list, yylval.string);
2253    }
2254   #else
2255    if (conf_parser_ctx.pass == 2)
2256 <    yyerror("Ignoring cipher_preference -- no OpenSSL support");
2256 >    yyerror("Ignoring connect::ciphers -- no OpenSSL support");
2257   #endif
2258   };
2259  
2260 +
2261   /***************************************************************************
2262   *  section kill
2263   ***************************************************************************/
# Line 2930 | Line 2284 | kill_entry: KILL
2284          if (!(exp_user = ircd_pcre_compile(userbuf, &errptr)) ||
2285              !(exp_host = ircd_pcre_compile(hostbuf, &errptr)))
2286          {
2287 <          ilog(L_ERROR, "Failed to add regular expression based K-Line: %s",
2287 >          ilog(LOG_TYPE_IRCD, "Failed to add regular expression based K-Line: %s",
2288                 errptr);
2289            break;
2290          }
# Line 2947 | Line 2301 | kill_entry: KILL
2301          else
2302            DupString(yy_aconf->reason, "No reason");
2303   #else
2304 <        ilog(L_ERROR, "Failed to add regular expression based K-Line: no PCRE support");
2304 >        ilog(LOG_TYPE_IRCD, "Failed to add regular expression based K-Line: no PCRE support");
2305          break;
2306   #endif
2307        }
2308        else
2309        {
2310 +        find_and_delete_temporary(userbuf, hostbuf, CONF_KLINE);
2311 +
2312          yy_aconf = map_to_conf(make_conf_item(KLINE_TYPE));
2313  
2314          DupString(yy_aconf->user, userbuf);
# Line 2962 | Line 2318 | kill_entry: KILL
2318            DupString(yy_aconf->reason, reasonbuf);
2319          else
2320            DupString(yy_aconf->reason, "No reason");
2321 <        add_conf_by_address(CONF_KILL, yy_aconf);
2321 >        add_conf_by_address(CONF_KLINE, yy_aconf);
2322        }
2323      }
2324  
# Line 3022 | Line 2378 | deny_entry: DENY
2378    {
2379      if (hostbuf[0] && parse_netmask(hostbuf, NULL, NULL) != HM_HOST)
2380      {
2381 +      find_and_delete_temporary(NULL, hostbuf, CONF_DLINE);
2382 +
2383        yy_aconf = map_to_conf(make_conf_item(DLINE_TYPE));
2384        DupString(yy_aconf->host, hostbuf);
2385  
# Line 3097 | Line 2455 | gecos_entry: GECOS
2455  
2456          if (!(exp_p = ircd_pcre_compile(gecos_name, &errptr)))
2457          {
2458 <          ilog(L_ERROR, "Failed to add regular expression based X-Line: %s",
2458 >          ilog(LOG_TYPE_IRCD, "Failed to add regular expression based X-Line: %s",
2459                 errptr);
2460            break;
2461          }
# Line 3105 | Line 2463 | gecos_entry: GECOS
2463          yy_conf = make_conf_item(RXLINE_TYPE);
2464          yy_conf->regexpname = exp_p;
2465   #else
2466 <        ilog(L_ERROR, "Failed to add regular expression based X-Line: no PCRE support");
2466 >        ilog(LOG_TYPE_IRCD, "Failed to add regular expression based X-Line: no PCRE support");
2467          break;
2468   #endif
2469        }
# Line 3169 | Line 2527 | general_item:       general_hide_spoof_i
2527                      general_pace_wait_simple | general_stats_P_oper_only |
2528                      general_short_motd | general_no_oper_flood |
2529                      general_true_no_oper_flood | general_oper_pass_resv |
2530 <                    general_idletime | general_message_locale |
2530 >                    general_message_locale |
2531                      general_oper_only_umodes | general_max_targets |
2532                      general_use_egd | general_egdpool_path |
2533                      general_oper_umodes | general_caller_id_wait |
2534                      general_opers_bypass_callerid | general_default_floodcount |
2535                      general_min_nonwildcard | general_min_nonwildcard_simple |
2536 <                    general_servlink_path | general_disable_remote_commands |
2537 <                    general_default_cipher_preference |
3180 <                    general_compression_level | general_client_flood |
2536 >                    general_disable_remote_commands |
2537 >                    general_client_flood |
2538                      general_throttle_time | general_havent_read_conf |
2539 <                    general_dot_in_ip6_addr | general_ping_cookie |
2540 <                    general_disable_auth | general_burst_away |
2541 <                    general_tkline_expire_notices | general_gline_min_cidr |
2539 >                    general_ping_cookie |
2540 >                    general_disable_auth |
2541 >                    general_tkline_expire_notices | general_gline_enable |
2542 >                    general_gline_duration | general_gline_request_duration |
2543 >                    general_gline_min_cidr |
2544                      general_gline_min_cidr6 | general_use_whois_actually |
2545                      general_reject_hold_time | general_stats_e_disabled |
2546 <                    general_max_watch |
2546 >                    general_max_watch | general_services_name |
2547                      error;
2548  
2549  
# Line 3193 | Line 2552 | general_max_watch: MAX_WATCH '=' NUMBER
2552    ConfigFileEntry.max_watch = $3;
2553   };
2554  
2555 + general_gline_enable: GLINE_ENABLE '=' TBOOL ';'
2556 + {
2557 +  if (conf_parser_ctx.pass == 2)
2558 +    ConfigFileEntry.glines = yylval.number;
2559 + };
2560 +
2561 + general_gline_duration: GLINE_DURATION '=' timespec ';'
2562 + {
2563 +  if (conf_parser_ctx.pass == 2)
2564 +    ConfigFileEntry.gline_time = $3;
2565 + };
2566 +
2567 + general_gline_request_duration: GLINE_REQUEST_DURATION '=' timespec ';'
2568 + {
2569 +  if (conf_parser_ctx.pass == 2)
2570 +    ConfigFileEntry.gline_request_time = $3;
2571 + };
2572 +
2573   general_gline_min_cidr: GLINE_MIN_CIDR '=' NUMBER ';'
2574   {
2575    ConfigFileEntry.gline_min_cidr = $3;
# Line 3203 | Line 2580 | general_gline_min_cidr6: GLINE_MIN_CIDR6
2580    ConfigFileEntry.gline_min_cidr6 = $3;
2581   };
2582  
3206 general_burst_away: BURST_AWAY '=' TBOOL ';'
3207 {
3208  ConfigFileEntry.burst_away = yylval.number;
3209 };
3210
2583   general_use_whois_actually: USE_WHOIS_ACTUALLY '=' TBOOL ';'
2584   {
2585    ConfigFileEntry.use_whois_actually = yylval.number;
# Line 3223 | Line 2595 | general_tkline_expire_notices: TKLINE_EX
2595    ConfigFileEntry.tkline_expire_notices = yylval.number;
2596   };
2597  
2598 < general_kill_chase_time_limit: KILL_CHASE_TIME_LIMIT '=' NUMBER ';'
2598 > general_kill_chase_time_limit: KILL_CHASE_TIME_LIMIT '=' timespec ';'
2599   {
2600    ConfigFileEntry.kill_chase_time_limit = $3;
2601   };
# Line 3288 | Line 2660 | general_havent_read_conf: HAVENT_READ_CO
2660   {
2661    if (($3 > 0) && conf_parser_ctx.pass == 1)
2662    {
2663 <    ilog(L_CRIT, "You haven't read your config file properly.");
2664 <    ilog(L_CRIT, "There is a line in the example conf that will kill your server if not removed.");
2665 <    ilog(L_CRIT, "Consider actually reading/editing the conf file, and removing this line.");
2663 >    ilog(LOG_TYPE_IRCD, "You haven't read your config file properly.");
2664 >    ilog(LOG_TYPE_IRCD, "There is a line in the example conf that will kill your server if not removed.");
2665 >    ilog(LOG_TYPE_IRCD, "Consider actually reading/editing the conf file, and removing this line.");
2666      exit(0);
2667    }
2668   };
# Line 3401 | Line 2773 | general_message_locale: MESSAGE_LOCALE '
2773    }
2774   };
2775  
3404 general_idletime: IDLETIME '=' timespec ';'
3405 {
3406  ConfigFileEntry.idletime = $3;
3407 };
3408
2776   general_dots_in_ident: DOTS_IN_IDENT '=' NUMBER ';'
2777   {
2778    ConfigFileEntry.dots_in_ident = $3;
# Line 3416 | Line 2783 | general_max_targets: MAX_TARGETS '=' NUM
2783    ConfigFileEntry.max_targets = $3;
2784   };
2785  
3419 general_servlink_path: SERVLINK_PATH '=' QSTRING ';'
3420 {
3421  if (conf_parser_ctx.pass == 2)
3422  {
3423    MyFree(ConfigFileEntry.servlink_path);
3424    DupString(ConfigFileEntry.servlink_path, yylval.string);
3425  }
3426 };
3427
3428 general_default_cipher_preference: DEFAULT_CIPHER_PREFERENCE '=' QSTRING ';'
3429 {
3430 #ifdef HAVE_LIBCRYPTO
3431  if (conf_parser_ctx.pass == 2)
3432  {
3433    struct EncCapability *ecap;
3434    const char *cipher_name;
3435    int found = 0;
3436
3437    ConfigFileEntry.default_cipher_preference = NULL;
3438    cipher_name = yylval.string;
3439
3440    for (ecap = CipherTable; ecap->name; ecap++)
3441    {
3442      if ((irccmp(ecap->name, cipher_name) == 0) &&
3443          (ecap->cap & CAP_ENC_MASK))
3444      {
3445        ConfigFileEntry.default_cipher_preference = ecap;
3446        found = 1;
3447        break;
3448      }
3449    }
3450
3451    if (!found)
3452      yyerror("Invalid cipher");
3453  }
3454 #else
3455  if (conf_parser_ctx.pass == 2)
3456    yyerror("Ignoring default_cipher_preference -- no OpenSSL support");
3457 #endif
3458 };
3459
3460 general_compression_level: COMPRESSION_LEVEL '=' NUMBER ';'
3461 {
3462  if (conf_parser_ctx.pass == 2)
3463  {
3464    ConfigFileEntry.compression_level = $3;
3465 #ifndef HAVE_LIBZ
3466    yyerror("Ignoring compression_level -- no zlib support");
3467 #else
3468    if ((ConfigFileEntry.compression_level < 1) ||
3469        (ConfigFileEntry.compression_level > 9))
3470    {
3471      yyerror("Ignoring invalid compression_level, using default");
3472      ConfigFileEntry.compression_level = 0;
3473    }
3474 #endif
3475  }
3476 };
3477
2786   general_use_egd: USE_EGD '=' TBOOL ';'
2787   {
2788    ConfigFileEntry.use_egd = yylval.number;
# Line 3489 | Line 2797 | general_egdpool_path: EGDPOOL_PATH '=' Q
2797    }
2798   };
2799  
2800 + general_services_name: T_SERVICES_NAME '=' QSTRING ';'
2801 + {
2802 +  if (conf_parser_ctx.pass == 2 && valid_servname(yylval.string))
2803 +  {
2804 +    MyFree(ConfigFileEntry.service_name);
2805 +    DupString(ConfigFileEntry.service_name, yylval.string);
2806 +  }
2807 + };
2808 +
2809   general_ping_cookie: PING_COOKIE '=' TBOOL ';'
2810   {
2811    ConfigFileEntry.ping_cookie = yylval.number;
# Line 3528 | Line 2845 | umode_oitem:     T_BOTS
2845   } | T_FULL
2846   {
2847    ConfigFileEntry.oper_umodes |= UMODE_FULL;
2848 + } | HIDDEN
2849 + {
2850 +  ConfigFileEntry.oper_umodes |= UMODE_HIDDEN;
2851   } | T_SKILL
2852   {
2853    ConfigFileEntry.oper_umodes |= UMODE_SKILL;
# Line 3596 | Line 2916 | umode_item:    T_BOTS
2916   } | T_SKILL
2917   {
2918    ConfigFileEntry.oper_only_umodes |= UMODE_SKILL;
2919 + } | HIDDEN
2920 + {
2921 +  ConfigFileEntry.oper_only_umodes |= UMODE_HIDDEN;
2922   } | T_NCHANGE
2923   {
2924    ConfigFileEntry.oper_only_umodes |= UMODE_NCHANGE;
# Line 3654 | Line 2977 | general_client_flood: T_CLIENT_FLOOD '='
2977    ConfigFileEntry.client_flood = $3;
2978   };
2979  
3657 general_dot_in_ip6_addr: DOT_IN_IP6_ADDR '=' TBOOL ';'
3658 {
3659  ConfigFileEntry.dot_in_ip6_addr = yylval.number;
3660 };
3661
3662 /***************************************************************************
3663 *  section glines
3664 ***************************************************************************/
3665 gline_entry: GLINES
3666 {
3667  if (conf_parser_ctx.pass == 2)
3668  {
3669    yy_conf = make_conf_item(GDENY_TYPE);
3670    yy_aconf = map_to_conf(yy_conf);
3671  }
3672 } '{' gline_items '}' ';'
3673 {
3674  if (conf_parser_ctx.pass == 2)
3675  {
3676    /*
3677     * since we re-allocate yy_conf/yy_aconf after the end of action=, at the
3678     * end we will have one extra, so we should free it.
3679     */
3680    if (yy_conf->name == NULL || yy_aconf->user == NULL)
3681    {
3682      delete_conf_item(yy_conf);
3683      yy_conf = NULL;
3684      yy_aconf = NULL;
3685    }
3686  }
3687 };
3688
3689 gline_items:        gline_items gline_item | gline_item;
3690 gline_item:         gline_enable |
3691                    gline_duration |
3692                    gline_logging |
3693                    gline_user |
3694                    gline_server |
3695                    gline_action |
3696                    error;
3697
3698 gline_enable: ENABLE '=' TBOOL ';'
3699 {
3700  if (conf_parser_ctx.pass == 2)
3701    ConfigFileEntry.glines = yylval.number;
3702 };
3703
3704 gline_duration: DURATION '=' timespec ';'
3705 {
3706  if (conf_parser_ctx.pass == 2)
3707    ConfigFileEntry.gline_time = $3;
3708 };
3709
3710 gline_logging: LOGGING
3711 {
3712  if (conf_parser_ctx.pass == 2)
3713    ConfigFileEntry.gline_logging = 0;
3714 } '=' gline_logging_types ';';
3715 gline_logging_types:     gline_logging_types ',' gline_logging_type_item | gline_logging_type_item;
3716 gline_logging_type_item: T_REJECT
3717 {
3718  if (conf_parser_ctx.pass == 2)
3719    ConfigFileEntry.gline_logging |= GDENY_REJECT;
3720 } | T_BLOCK
3721 {
3722  if (conf_parser_ctx.pass == 2)
3723    ConfigFileEntry.gline_logging |= GDENY_BLOCK;
3724 };
3725
3726 gline_user: USER '=' QSTRING ';'
3727 {
3728  if (conf_parser_ctx.pass == 2)
3729  {
3730    struct split_nuh_item nuh;
3731
3732    nuh.nuhmask  = yylval.string;
3733    nuh.nickptr  = NULL;
3734    nuh.userptr  = userbuf;
3735    nuh.hostptr  = hostbuf;
3736
3737    nuh.nicksize = 0;
3738    nuh.usersize = sizeof(userbuf);
3739    nuh.hostsize = sizeof(hostbuf);
3740
3741    split_nuh(&nuh);
3742
3743    if (yy_aconf->user == NULL)
3744    {
3745      DupString(yy_aconf->user, userbuf);
3746      DupString(yy_aconf->host, hostbuf);
3747    }
3748    else
3749    {
3750      struct CollectItem *yy_tmp = MyMalloc(sizeof(struct CollectItem));
3751
3752      DupString(yy_tmp->user, userbuf);
3753      DupString(yy_tmp->host, hostbuf);
3754
3755      dlinkAdd(yy_tmp, &yy_tmp->node, &col_conf_list);
3756    }
3757  }
3758 };
3759
3760 gline_server: NAME '=' QSTRING ';'
3761 {
3762  if (conf_parser_ctx.pass == 2)  
3763  {
3764    MyFree(yy_conf->name);
3765    DupString(yy_conf->name, yylval.string);
3766  }
3767 };
3768
3769 gline_action: ACTION
3770 {
3771  if (conf_parser_ctx.pass == 2)
3772    yy_aconf->flags = 0;
3773 } '=' gdeny_types ';'
3774 {
3775  if (conf_parser_ctx.pass == 2)
3776  {
3777    struct CollectItem *yy_tmp = NULL;
3778    dlink_node *ptr, *next_ptr;
3779
3780    DLINK_FOREACH_SAFE(ptr, next_ptr, col_conf_list.head)
3781    {
3782      struct AccessItem *new_aconf;
3783      struct ConfItem *new_conf;
3784
3785      yy_tmp = ptr->data;
3786      new_conf = make_conf_item(GDENY_TYPE);
3787      new_aconf = map_to_conf(new_conf);
3788
3789      new_aconf->flags = yy_aconf->flags;
3790
3791      if (yy_conf->name != NULL)
3792        DupString(new_conf->name, yy_conf->name);
3793      else
3794        DupString(new_conf->name, "*");
3795      if (yy_aconf->user != NULL)
3796         DupString(new_aconf->user, yy_tmp->user);
3797      else  
3798        DupString(new_aconf->user, "*");
3799      if (yy_aconf->host != NULL)
3800        DupString(new_aconf->host, yy_tmp->host);
3801      else
3802        DupString(new_aconf->host, "*");
3803
3804      dlinkDelete(&yy_tmp->node, &col_conf_list);
3805    }
3806
3807    /*
3808     * In case someone has fed us with more than one action= after user/name
3809     * which would leak memory  -Michael
3810     */
3811    if (yy_conf->name == NULL || yy_aconf->user == NULL)
3812      delete_conf_item(yy_conf);
3813
3814    yy_conf = make_conf_item(GDENY_TYPE);
3815    yy_aconf = map_to_conf(yy_conf);
3816  }
3817 };
3818
3819 gdeny_types: gdeny_types ',' gdeny_type_item | gdeny_type_item;
3820 gdeny_type_item: T_REJECT
3821 {
3822  if (conf_parser_ctx.pass == 2)
3823    yy_aconf->flags |= GDENY_REJECT;
3824 } | T_BLOCK
3825 {
3826  if (conf_parser_ctx.pass == 2)
3827    yy_aconf->flags |= GDENY_BLOCK;
3828 };
2980  
2981   /***************************************************************************
2982   *  section channel
# Line 3835 | Line 2986 | channel_entry: CHANNEL
2986  
2987   channel_items:      channel_items channel_item | channel_item;
2988   channel_item:       channel_disable_local_channels | channel_use_except |
2989 <                    channel_use_invex | channel_use_knock |
2990 <                    channel_max_bans | channel_knock_delay |
2991 <                    channel_knock_delay_channel | channel_max_chans_per_user |
2989 >                    channel_use_invex | channel_use_knock | channel_max_bans |
2990 >                    channel_knock_delay | channel_knock_delay_channel |
2991 >                    channel_max_chans_per_user | channel_max_chans_per_oper |
2992                      channel_quiet_on_ban | channel_default_split_user_count |
2993                      channel_default_split_server_count |
2994                      channel_no_create_on_split | channel_restrict_channels |
2995 <                    channel_no_join_on_split | channel_burst_topicwho |
2995 >                    channel_no_join_on_split |
2996                      channel_jflood_count | channel_jflood_time |
2997                      channel_disable_fake_channels | error;
2998  
# Line 3890 | Line 3041 | channel_max_chans_per_user: MAX_CHANS_PE
3041    ConfigChannel.max_chans_per_user = $3;
3042   };
3043  
3044 + channel_max_chans_per_oper: MAX_CHANS_PER_OPER '=' NUMBER ';'
3045 + {
3046 +  ConfigChannel.max_chans_per_oper = $3;
3047 + };
3048 +
3049   channel_quiet_on_ban: QUIET_ON_BAN '=' TBOOL ';'
3050   {
3051    ConfigChannel.quiet_on_ban = yylval.number;
# Line 3920 | Line 3076 | channel_no_join_on_split: NO_JOIN_ON_SPL
3076    ConfigChannel.no_join_on_split = yylval.number;
3077   };
3078  
3923 channel_burst_topicwho: BURST_TOPICWHO '=' TBOOL ';'
3924 {
3925  ConfigChannel.burst_topicwho = yylval.number;
3926 };
3927
3079   channel_jflood_count: JOIN_FLOOD_COUNT '=' NUMBER ';'
3080   {
3081    GlobalSetOptions.joinfloodcount = yylval.number;

Diff Legend

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