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 4499 by michael, Sat Aug 16 18:29:23 2014 UTC vs.
Revision 5800 by michael, Fri Apr 17 18:55:55 2015 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-2015 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
30   #include <sys/types.h>
31   #include <string.h>
32  
# Line 37 | Line 36
36   #include "list.h"
37   #include "conf.h"
38   #include "conf_class.h"
39 + #include "conf_pseudo.h"
40   #include "event.h"
41   #include "log.h"
42   #include "client.h"     /* for UMODE_ALL only */
# Line 76 | Line 76 | static struct
76    {
77      char buf[IRCD_BUFSIZE];
78    } name,
79 +    nick,
80      user,
81      host,
82      addr,
# Line 85 | Line 86 | static struct
86      cert,
87      rpass,
88      spass,
89 <    class;
89 >    whois,
90 >    class,
91 >    target,
92 >    prepend,
93 >    command;
94  
95    struct
96    {
# Line 116 | Line 121 | static struct
121   static void
122   reset_block_state(void)
123   {
124 <  dlink_node *ptr = NULL, *ptr_next = NULL;
124 >  dlink_node *node = NULL, *node_next = NULL;
125  
126 <  DLINK_FOREACH_SAFE(ptr, ptr_next, block_state.mask.list.head)
126 >  DLINK_FOREACH_SAFE(node, node_next, block_state.mask.list.head)
127    {
128 <    MyFree(ptr->data);
129 <    dlinkDelete(ptr, &block_state.mask.list);
130 <    free_dlink_node(ptr);
128 >    MyFree(node->data);
129 >    dlinkDelete(node, &block_state.mask.list);
130 >    free_dlink_node(node);
131    }
132  
133 <  DLINK_FOREACH_SAFE(ptr, ptr_next, block_state.leaf.list.head)
133 >  DLINK_FOREACH_SAFE(node, node_next, block_state.leaf.list.head)
134    {
135 <    MyFree(ptr->data);
136 <    dlinkDelete(ptr, &block_state.leaf.list);
137 <    free_dlink_node(ptr);
135 >    MyFree(node->data);
136 >    dlinkDelete(node, &block_state.leaf.list);
137 >    free_dlink_node(node);
138    }
139  
140 <  DLINK_FOREACH_SAFE(ptr, ptr_next, block_state.hub.list.head)
140 >  DLINK_FOREACH_SAFE(node, node_next, block_state.hub.list.head)
141    {
142 <    MyFree(ptr->data);
143 <    dlinkDelete(ptr, &block_state.hub.list);
144 <    free_dlink_node(ptr);
142 >    MyFree(node->data);
143 >    dlinkDelete(node, &block_state.hub.list);
144 >    free_dlink_node(node);
145    }
146  
147    memset(&block_state, 0, sizeof(block_state));
# Line 168 | Line 173 | reset_block_state(void)
173   %token  CONNECTFREQ
174   %token  CYCLE_ON_HOST_CHANGE
175   %token  DEFAULT_FLOODCOUNT
176 + %token  DEFAULT_JOIN_FLOOD_COUNT
177 + %token  DEFAULT_JOIN_FLOOD_TIME
178 + %token  DEFAULT_MAX_CLIENTS
179   %token  DEFAULT_SPLIT_SERVER_COUNT
180   %token  DEFAULT_SPLIT_USER_COUNT
181   %token  DENY
# Line 177 | Line 185 | reset_block_state(void)
185   %token  DISABLE_FAKE_CHANNELS
186   %token  DISABLE_REMOTE_COMMANDS
187   %token  DOTS_IN_IDENT
180 %token  EGDPOOL_PATH
188   %token  EMAIL
189   %token  ENCRYPTED
190   %token  EXCEED_LIMIT
# Line 193 | Line 200 | reset_block_state(void)
200   %token  GLINE_MIN_CIDR
201   %token  GLINE_MIN_CIDR6
202   %token  GLINE_REQUEST_DURATION
196 %token  GLOBAL_KILL
203   %token  HAVENT_READ_CONF
204   %token  HIDDEN
205   %token  HIDDEN_NAME
# Line 203 | Line 209 | reset_block_state(void)
209   %token  HIDE_SERVER_IPS
210   %token  HIDE_SERVERS
211   %token  HIDE_SERVICES
206 %token  HIDE_SPOOF_IPS
212   %token  HOST
213   %token  HUB
214   %token  HUB_MASK
# Line 215 | Line 220 | reset_block_state(void)
220   %token  IRCD_AUTH
221   %token  IRCD_FLAGS
222   %token  IRCD_SID
218 %token  JOIN_FLOOD_COUNT
219 %token  JOIN_FLOOD_TIME
223   %token  KILL
224   %token  KILL_CHASE_TIME_LIMIT
225   %token  KLINE
# Line 303 | Line 306 | reset_block_state(void)
306   %token  STATS_E_DISABLED
307   %token  STATS_I_OPER_ONLY
308   %token  STATS_K_OPER_ONLY
309 + %token  STATS_M_OPER_ONLY
310   %token  STATS_O_OPER_ONLY
311   %token  STATS_P_OPER_ONLY
312   %token  STATS_U_OPER_ONLY
# Line 310 | Line 314 | reset_block_state(void)
314   %token  T_BOTS
315   %token  T_CALLERID
316   %token  T_CCONN
317 + %token  T_COMMAND
318   %token  T_CLUSTER
319   %token  T_DEAF
320   %token  T_DEBUG
# Line 324 | Line 329 | reset_block_state(void)
329   %token  T_IPV6
330   %token  T_LOCOPS
331   %token  T_LOG
327 %token  T_MAX_CLIENTS
332   %token  T_NCHANGE
333   %token  T_NONONREG
334 + %token  T_OPME
335 + %token  T_PREPEND
336 + %token  T_PSEUDO
337   %token  T_RECVQ
338   %token  T_REJ
339   %token  T_RESTART
340   %token  T_SERVER
341   %token  T_SERVICE
335 %token  T_SERVICES_NAME
342   %token  T_SERVNOTICE
343   %token  T_SET
344   %token  T_SHARED
# Line 342 | Line 348 | reset_block_state(void)
348   %token  T_SPY
349   %token  T_SSL
350   %token  T_SSL_CIPHER_LIST
351 + %token  T_TARGET
352   %token  T_UMODES
353   %token  T_UNAUTH
354   %token  T_UNDLINE
# Line 356 | Line 363 | reset_block_state(void)
363   %token  THROTTLE_TIME
364   %token  TKLINE_EXPIRE_NOTICES
365   %token  TMASKED
359 %token  TRUE_NO_OPER_FLOOD
366   %token  TS_MAX_DELTA
367   %token  TS_WARN_DELTA
368   %token  TWODOTS
369   %token  TYPE
370   %token  UNKLINE
365 %token  USE_EGD
371   %token  USE_LOGGING
372   %token  USER
373   %token  VHOST
374   %token  VHOST6
375   %token  WARN_NO_CONNECT_BLOCK
376 + %token  WHOIS
377   %token  XLINE
378  
379   %type  <string> QSTRING
# Line 403 | Line 409 | conf_item:        admin_entry
409                  | gecos_entry
410                  | modules_entry
411                  | motd_entry
412 +                | pseudo_entry
413                  | error ';'
414                  | error '}'
415          ;
# Line 458 | Line 465 | serverinfo_item:        serverinfo_name
465                          serverinfo_description |
466                          serverinfo_network_name |
467                          serverinfo_network_desc |
468 <                        serverinfo_max_clients |
468 >                        serverinfo_default_max_clients |
469                          serverinfo_max_nick_length |
470                          serverinfo_max_topic_length |
471                          serverinfo_ssl_dh_param_file |
# Line 483 | Line 490 | serverinfo_ssl_certificate_file: SSL_CER
490        break;
491      }
492  
493 <    if (SSL_CTX_use_certificate_file(ConfigServerInfo.server_ctx, yylval.string,
494 <                                     SSL_FILETYPE_PEM) <= 0 ||
488 <        SSL_CTX_use_certificate_file(ConfigServerInfo.client_ctx, yylval.string,
489 <                                     SSL_FILETYPE_PEM) <= 0)
493 >    if (SSL_CTX_use_certificate_chain_file(ConfigServerInfo.server_ctx, yylval.string) <= 0 ||
494 >        SSL_CTX_use_certificate_chain_file(ConfigServerInfo.client_ctx, yylval.string) <= 0)
495      {
496        report_crypto_errors();
497        conf_error_report("Could not open/read certificate file");
# Line 626 | Line 631 | serverinfo_ssl_message_digest_algorithm:
631   serverinfo_ssl_dh_elliptic_curve: SSL_DH_ELLIPTIC_CURVE '=' QSTRING ';'
632   {
633   #ifdef HAVE_LIBCRYPTO
634 < #if OPENSSL_VERSION_NUMBER >= 0x1000005FL && !defined(OPENSSL_NO_ECDH)
634 > #if OPENSSL_VERSION_NUMBER >= 0x009080FFL && !defined(OPENSSL_NO_ECDH)
635    int nid = 0;
636    EC_KEY *key = NULL;
637  
# Line 634 | Line 639 | serverinfo_ssl_dh_elliptic_curve: SSL_DH
639    {
640      if ((nid = OBJ_sn2nid(yylval.string)) == 0)
641      {
642 <        conf_error_report("Ignoring serverinfo::serverinfo_ssl_dh_elliptic_curve -- unknown curve name");
642 >        conf_error_report("Ignoring serverinfo::ssl_dh_elliptic_curve -- unknown curve name");
643          break;
644      }
645  
646      if ((key = EC_KEY_new_by_curve_name(nid)) == NULL)
647      {
648 <      conf_error_report("Ignoring serverinfo::serverinfo_ssl_dh_elliptic_curve -- could not create curve");
648 >      conf_error_report("Ignoring serverinfo::ssl_dh_elliptic_curve -- could not create curve");
649        break;
650      }
651  
# Line 687 | Line 692 | serverinfo_description: DESCRIPTION '='
692    {
693      MyFree(ConfigServerInfo.description);
694      ConfigServerInfo.description = xstrdup(yylval.string);
695 +    strlcpy(me.info, ConfigServerInfo.description, sizeof(me.info));
696    }
697   };
698  
# Line 769 | Line 775 | serverinfo_vhost6: VHOST6 '=' QSTRING ';
775    }
776   };
777  
778 < serverinfo_max_clients: T_MAX_CLIENTS '=' NUMBER ';'
778 > serverinfo_default_max_clients: DEFAULT_MAX_CLIENTS '=' NUMBER ';'
779   {
780    if (conf_parser_ctx.pass != 2)
781      break;
# Line 780 | Line 786 | serverinfo_max_clients: T_MAX_CLIENTS '=
786  
787      snprintf(buf, sizeof(buf), "MAXCLIENTS too low, setting to %d", MAXCLIENTS_MIN);
788      conf_error_report(buf);
789 <    ConfigServerInfo.max_clients = MAXCLIENTS_MIN;
789 >    ConfigServerInfo.default_max_clients = MAXCLIENTS_MIN;
790    }
791    else if ($3 > MAXCLIENTS_MAX)
792    {
# Line 788 | Line 794 | serverinfo_max_clients: T_MAX_CLIENTS '=
794  
795      snprintf(buf, sizeof(buf), "MAXCLIENTS too high, setting to %d", MAXCLIENTS_MAX);
796      conf_error_report(buf);
797 <    ConfigServerInfo.max_clients = MAXCLIENTS_MAX;
797 >    ConfigServerInfo.default_max_clients = MAXCLIENTS_MAX;
798    }
799    else
800 <    ConfigServerInfo.max_clients = $3;
800 >    ConfigServerInfo.default_max_clients = $3;
801   };
802  
803   serverinfo_max_nick_length: MAX_NICK_LENGTH '=' NUMBER ';'
# Line 891 | Line 897 | motd_entry: MOTD
897      reset_block_state();
898   } '{' motd_items '}' ';'
899   {
900 <  dlink_node *ptr = NULL;
900 >  dlink_node *node = NULL;
901  
902    if (conf_parser_ctx.pass != 2)
903      break;
# Line 899 | Line 905 | motd_entry: MOTD
905    if (!block_state.file.buf[0])
906      break;
907  
908 <  DLINK_FOREACH(ptr, block_state.mask.list.head)
909 <    motd_add(ptr->data, block_state.file.buf);
908 >  DLINK_FOREACH(node, block_state.mask.list.head)
909 >    motd_add(node->data, block_state.file.buf);
910   };
911  
912   motd_items: motd_items motd_item | motd_item;
# Line 919 | Line 925 | motd_file: T_FILE '=' QSTRING ';'
925   };
926  
927   /***************************************************************************
928 + * pseudo section
929 + ***************************************************************************/
930 + pseudo_entry: T_PSEUDO
931 + {
932 +  if (conf_parser_ctx.pass == 2)
933 +    reset_block_state();
934 + } '{' pseudo_items '}' ';'
935 + {
936 +  if (conf_parser_ctx.pass != 2)
937 +    break;
938 +
939 +  if (!block_state.command.buf[0] ||
940 +      !block_state.name.buf[0] ||
941 +      !block_state.nick.buf[0] ||
942 +      !block_state.host.buf[0])
943 +    break;
944 +
945 +  pseudo_register(block_state.name.buf, block_state.nick.buf, block_state.host.buf,
946 +                  block_state.prepend.buf, block_state.command.buf);
947 + };
948 +
949 + pseudo_items: pseudo_items pseudo_item | pseudo_item;
950 + pseudo_item:  pseudo_command | pseudo_prepend | pseudo_name | pseudo_target | error ';' ;
951 +
952 + pseudo_command: T_COMMAND '=' QSTRING ';'
953 + {
954 +  if (conf_parser_ctx.pass == 2)
955 +    strlcpy(block_state.command.buf, yylval.string, sizeof(block_state.command.buf));
956 + };
957 +
958 + pseudo_name: NAME '=' QSTRING ';'
959 + {
960 +  if (conf_parser_ctx.pass == 2)
961 +    strlcpy(block_state.name.buf, yylval.string, sizeof(block_state.name.buf));
962 + };
963 +
964 + pseudo_prepend: T_PREPEND '=' QSTRING ';'
965 + {
966 +  if (conf_parser_ctx.pass == 2)
967 +    strlcpy(block_state.prepend.buf, yylval.string, sizeof(block_state.prepend.buf));
968 + };
969 +
970 + pseudo_target: T_TARGET '=' QSTRING ';'
971 + {
972 +  if (conf_parser_ctx.pass == 2)
973 +  {
974 +    struct split_nuh_item nuh;
975 +
976 +    nuh.nuhmask  = yylval.string;
977 +    nuh.nickptr  = NULL;
978 +    nuh.userptr  = block_state.nick.buf;
979 +    nuh.hostptr  = block_state.host.buf;
980 +    nuh.nicksize = 0;
981 +    nuh.usersize = sizeof(block_state.nick.buf);
982 +    nuh.hostsize = sizeof(block_state.host.buf);
983 +
984 +    split_nuh(&nuh);
985 +  }
986 + };
987 +
988 + /***************************************************************************
989   *  section logging
990   ***************************************************************************/
991   logging_entry:          T_LOG  '{' logging_items '}' ';' ;
# Line 1027 | Line 1094 | oper_entry: OPERATOR
1094    block_state.flags.value |= CONF_FLAGS_ENCRYPTED;
1095   } '{' oper_items '}' ';'
1096   {
1097 <  dlink_node *ptr = NULL;
1097 >  dlink_node *node = NULL;
1098  
1099    if (conf_parser_ctx.pass != 2)
1100      break;
# Line 1043 | Line 1110 | oper_entry: OPERATOR
1110      break;
1111   #endif
1112  
1113 <  DLINK_FOREACH(ptr, block_state.mask.list.head)
1113 >  DLINK_FOREACH(node, block_state.mask.list.head)
1114    {
1115      struct MaskItem *conf = NULL;
1116      struct split_nuh_item nuh;
1117  
1118 <    nuh.nuhmask  = ptr->data;
1118 >    nuh.nuhmask  = node->data;
1119      nuh.nickptr  = NULL;
1120      nuh.userptr  = block_state.user.buf;
1121      nuh.hostptr  = block_state.host.buf;
# Line 1068 | Line 1135 | oper_entry: OPERATOR
1135      if (block_state.rpass.buf[0])
1136        conf->passwd = xstrdup(block_state.rpass.buf);
1137  
1138 +    if (block_state.whois.buf[0])
1139 +      conf->whois = xstrdup(block_state.whois.buf);
1140 +
1141      conf->flags = block_state.flags.value;
1142      conf->modes = block_state.modes.value;
1143      conf->port  = block_state.port.value;
# Line 1108 | Line 1178 | oper_items:     oper_items oper_item | o
1178   oper_item:      oper_name |
1179                  oper_user |
1180                  oper_password |
1181 +                oper_whois |
1182                  oper_umodes |
1183                  oper_class |
1184                  oper_encrypted |
# Line 1135 | Line 1206 | oper_password: PASSWORD '=' QSTRING ';'
1206      strlcpy(block_state.rpass.buf, yylval.string, sizeof(block_state.rpass.buf));
1207   };
1208  
1209 + oper_whois: WHOIS '=' QSTRING ';'
1210 + {
1211 +  if (conf_parser_ctx.pass == 2)
1212 +    strlcpy(block_state.whois.buf, yylval.string, sizeof(block_state.whois.buf));
1213 + };
1214 +
1215   oper_encrypted: ENCRYPTED '=' TBOOL ';'
1216   {
1217    if (conf_parser_ctx.pass != 2)
# Line 1371 | Line 1448 | oper_flags_item: KILL ':' REMOTE
1448   {
1449    if (conf_parser_ctx.pass == 2)
1450      block_state.port.value |= OPER_FLAG_MODULE;
1451 + } | T_OPME
1452 + {
1453 +  if (conf_parser_ctx.pass == 2)
1454 +    block_state.port.value |= OPER_FLAG_OPME;
1455   };
1456  
1457  
# Line 1666 | Line 1747 | auth_entry: IRCD_AUTH
1747      reset_block_state();
1748   } '{' auth_items '}' ';'
1749   {
1750 <  dlink_node *ptr = NULL;
1750 >  dlink_node *node = NULL;
1751  
1752    if (conf_parser_ctx.pass != 2)
1753      break;
1754  
1755 <  DLINK_FOREACH(ptr, block_state.mask.list.head)
1755 >  DLINK_FOREACH(node, block_state.mask.list.head)
1756    {
1757      struct MaskItem *conf = NULL;
1758      struct split_nuh_item nuh;
1759  
1760 <    nuh.nuhmask  = ptr->data;
1760 >    nuh.nuhmask  = node->data;
1761      nuh.nickptr  = NULL;
1762      nuh.userptr  = block_state.user.buf;
1763      nuh.hostptr  = block_state.host.buf;
# Line 2461 | Line 2542 | general_entry: GENERAL
2542   general_items:      general_items general_item | general_item;
2543   general_item:       general_away_count |
2544                      general_away_time |
2464                    general_hide_spoof_ips |
2545                      general_ignore_bogus_ts |
2546                      general_failed_oper_notice |
2547                      general_anti_nick_flood |
# Line 2475 | Line 2555 | general_item:       general_away_count |
2555                      general_invisible_on_connect |
2556                      general_warn_no_connect_block |
2557                      general_dots_in_ident |
2478                    general_stats_o_oper_only |
2479                    general_stats_k_oper_only |
2480                    general_pace_wait |
2558                      general_stats_i_oper_only |
2559 <                    general_pace_wait_simple |
2559 >                    general_stats_k_oper_only |
2560 >                    general_stats_m_oper_only |
2561 >                    general_stats_o_oper_only |
2562                      general_stats_P_oper_only |
2563                      general_stats_u_oper_only |
2564 +                    general_pace_wait |
2565 +                    general_pace_wait_simple |
2566                      general_short_motd |
2567                      general_no_oper_flood |
2487                    general_true_no_oper_flood |
2568                      general_oper_pass_resv |
2569                      general_oper_only_umodes |
2570                      general_max_targets |
# Line 2507 | Line 2587 | general_item:       general_away_count |
2587                      general_gline_min_cidr6 |
2588                      general_stats_e_disabled |
2589                      general_max_watch |
2510                    general_services_name |
2590                      general_cycle_on_host_change |
2591                      error;
2592  
# Line 2571 | Line 2650 | general_kill_chase_time_limit: KILL_CHAS
2650    ConfigGeneral.kill_chase_time_limit = $3;
2651   };
2652  
2574 general_hide_spoof_ips: HIDE_SPOOF_IPS '=' TBOOL ';'
2575 {
2576  ConfigGeneral.hide_spoof_ips = yylval.number;
2577 };
2578
2653   general_ignore_bogus_ts: IGNORE_BOGUS_TS '=' TBOOL ';'
2654   {
2655    ConfigGeneral.ignore_bogus_ts = yylval.number;
# Line 2648 | Line 2722 | general_stats_e_disabled: STATS_E_DISABL
2722    ConfigGeneral.stats_e_disabled = yylval.number;
2723   };
2724  
2725 + general_stats_m_oper_only: STATS_M_OPER_ONLY '=' TBOOL ';'
2726 + {
2727 +  ConfigGeneral.stats_m_oper_only = yylval.number;
2728 + };
2729 +
2730   general_stats_o_oper_only: STATS_O_OPER_ONLY '=' TBOOL ';'
2731   {
2732    ConfigGeneral.stats_o_oper_only = yylval.number;
# Line 2709 | Line 2788 | general_no_oper_flood: NO_OPER_FLOOD '='
2788    ConfigGeneral.no_oper_flood = yylval.number;
2789   };
2790  
2712 general_true_no_oper_flood: TRUE_NO_OPER_FLOOD '=' TBOOL ';'
2713 {
2714  ConfigGeneral.true_no_oper_flood = yylval.number;
2715 };
2716
2791   general_oper_pass_resv: OPER_PASS_RESV '=' TBOOL ';'
2792   {
2793    ConfigGeneral.oper_pass_resv = yylval.number;
# Line 2729 | Line 2803 | general_max_targets: MAX_TARGETS '=' NUM
2803    ConfigGeneral.max_targets = $3;
2804   };
2805  
2732 general_services_name: T_SERVICES_NAME '=' QSTRING ';'
2733 {
2734  if (conf_parser_ctx.pass == 2 && valid_servname(yylval.string))
2735  {
2736    MyFree(ConfigGeneral.service_name);
2737    ConfigGeneral.service_name = xstrdup(yylval.string);
2738  }
2739 };
2740
2806   general_ping_cookie: PING_COOKIE '=' TBOOL ';'
2807   {
2808    ConfigGeneral.ping_cookie = yylval.number;
# Line 2934 | Line 2999 | channel_item:       channel_max_bans |
2999                      channel_default_split_server_count |
3000                      channel_no_create_on_split |
3001                      channel_no_join_on_split |
3002 <                    channel_jflood_count |
3003 <                    channel_jflood_time |
3002 >                    channel_default_join_flood_count |
3003 >                    channel_default_join_flood_time |
3004                      channel_disable_fake_channels |
3005                      error;
3006  
# Line 2999 | Line 3064 | channel_no_join_on_split: NO_JOIN_ON_SPL
3064    ConfigChannel.no_join_on_split = yylval.number;
3065   };
3066  
3067 < channel_jflood_count: JOIN_FLOOD_COUNT '=' NUMBER ';'
3067 > channel_default_join_flood_count: DEFAULT_JOIN_FLOOD_COUNT '=' NUMBER ';'
3068   {
3069 <  GlobalSetOptions.joinfloodcount = yylval.number;
3069 >  ConfigChannel.default_join_flood_count = yylval.number;
3070   };
3071  
3072 < channel_jflood_time: JOIN_FLOOD_TIME '=' timespec ';'
3072 > channel_default_join_flood_time: DEFAULT_JOIN_FLOOD_TIME '=' timespec ';'
3073   {
3074 <  GlobalSetOptions.joinfloodtime = $3;
3074 >  ConfigChannel.default_join_flood_time = $3;
3075   };
3076  
3077   /***************************************************************************

Diff Legend

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