--- ircd-hybrid-7.2/src/ircd_parser.y 2006/06/13 07:15:38 671 +++ ircd-hybrid/trunk/src/conf_parser.y 2016/06/23 12:44:09 7624 @@ -1,8 +1,7 @@ /* - * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). - * ircd_parser.y: Parses the ircd configuration file. + * ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd) * - * Copyright (C) 2005 by the past and present ircd coders, and others. + * Copyright (c) 2000-2016 ircd-hybrid development team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,117 +15,125 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 * USA - * - * $Id$ */ -%{ +/*! \file conf_parser.y + * \brief Parses the ircd configuration file. + * \version $Id$ + */ -#define YY_NO_UNPUT -#include +%{ + +#include "config.h" #include "stdinc.h" #include "ircd.h" -#include "tools.h" #include "list.h" -#include "s_conf.h" +#include "conf.h" +#include "conf_class.h" +#include "conf_cluster.h" +#include "conf_gecos.h" +#include "conf_pseudo.h" +#include "conf_resv.h" +#include "conf_service.h" +#include "conf_shared.h" #include "event.h" -#include "s_log.h" -#include "client.h" /* for UMODE_ALL only */ -#include "pcre.h" +#include "id.h" +#include "log.h" #include "irc_string.h" -#include "irc_getaddrinfo.h" -#include "sprintf_irc.h" #include "memory.h" #include "modules.h" -#include "s_serv.h" /* for CAP_LL / IsCapable */ +#include "server.h" #include "hostmask.h" -#include "send.h" #include "listener.h" -#include "resv.h" -#include "numeric.h" -#include "s_user.h" - -#ifdef HAVE_LIBCRYPTO -#include -#include -#include -#endif +#include "user.h" +#include "motd.h" -static char *class_name = NULL; -static struct ConfItem *yy_conf = NULL; -static struct AccessItem *yy_aconf = NULL; -static struct MatchItem *yy_match_item = NULL; -static struct ClassItem *yy_class = NULL; -static char *yy_class_name = NULL; - -static dlink_list col_conf_list = { NULL, NULL, 0 }; -static dlink_list hub_conf_list = { NULL, NULL, 0 }; -static dlink_list leaf_conf_list = { NULL, NULL, 0 }; -static unsigned int listener_flags = 0; -static unsigned int regex_ban = 0; -static char userbuf[IRCD_BUFSIZE]; -static char hostbuf[IRCD_BUFSIZE]; -static char reasonbuf[REASONLEN + 1]; -static char gecos_name[REALLEN * 4]; - -extern dlink_list gdeny_items; /* XXX */ - -static char *resv_reason = NULL; -static char *listener_address = NULL; -static int not_atom = 0; - -struct CollectItem -{ - dlink_node node; - char *name; - char *user; - char *host; - char *passwd; - int port; - int flags; -#ifdef HAVE_LIBCRYPTO - char *rsa_public_key_file; - RSA *rsa_public_key; -#endif -}; +int yylex(void); -static void -free_collect_item(struct CollectItem *item) +static struct { - MyFree(item->name); - MyFree(item->user); - MyFree(item->host); - MyFree(item->passwd); -#ifdef HAVE_LIBCRYPTO - MyFree(item->rsa_public_key_file); -#endif - MyFree(item); -} + struct + { + dlink_list list; + } mask, + leaf, + hub; + + struct + { + char buf[IRCD_BUFSIZE]; + } name, + nick, + user, + host, + addr, + bind, + file, + ciph, + cert, + rpass, + spass, + whois, + class, + target, + prepend, + command; + + struct + { + unsigned int value; + } flags, + modes, + size, + type, + port, + aftype, + ping_freq, + max_perip, + con_freq, + min_idle, + max_idle, + max_total, + max_global, + max_local, + max_sendq, + max_recvq, + max_channels, + cidr_bitlen_ipv4, + cidr_bitlen_ipv6, + number_per_cidr; +} block_state; static void -unhook_hub_leaf_confs(void) +reset_block_state(void) { - dlink_node *ptr; - dlink_node *next_ptr; - struct CollectItem *yy_hconf; - struct CollectItem *yy_lconf; + dlink_node *node = NULL, *node_next = NULL; + + DLINK_FOREACH_SAFE(node, node_next, block_state.mask.list.head) + { + xfree(node->data); + dlinkDelete(node, &block_state.mask.list); + free_dlink_node(node); + } - DLINK_FOREACH_SAFE(ptr, next_ptr, hub_conf_list.head) + DLINK_FOREACH_SAFE(node, node_next, block_state.leaf.list.head) { - yy_hconf = ptr->data; - dlinkDelete(&yy_hconf->node, &hub_conf_list); - free_collect_item(yy_hconf); + xfree(node->data); + dlinkDelete(node, &block_state.leaf.list); + free_dlink_node(node); } - DLINK_FOREACH_SAFE(ptr, next_ptr, leaf_conf_list.head) + DLINK_FOREACH_SAFE(node, node_next, block_state.hub.list.head) { - yy_lconf = ptr->data; - dlinkDelete(&yy_lconf->node, &leaf_conf_list); - free_collect_item(yy_lconf); + xfree(node->data); + dlinkDelete(node, &block_state.hub.list); + free_dlink_node(node); } + + memset(&block_state, 0, sizeof(block_state)); } %} @@ -137,532 +144,520 @@ unhook_hub_leaf_confs(void) } %token ACCEPT_PASSWORD -%token ACTION %token ADMIN %token AFTYPE -%token T_ALLOW %token ANTI_NICK_FLOOD %token ANTI_SPAM_EXIT_MESSAGE_TIME %token AUTOCONN -%token T_BLOCK -%token BURST_AWAY -%token BURST_TOPICWHO -%token BYTES KBYTES MBYTES GBYTES TBYTES +%token AWAY_COUNT +%token AWAY_TIME +%token BYTES KBYTES MBYTES %token CALLER_ID_WAIT %token CAN_FLOOD -%token CAN_IDLE %token CHANNEL -%token CIDR_BITLEN_IPV4 -%token CIDR_BITLEN_IPV6 -%token CIPHER_PREFERENCE +%token CHECK_CACHE +%token CIDR_BITLEN_IPV4 +%token CIDR_BITLEN_IPV6 %token CLASS -%token COMPRESSED -%token COMPRESSION_LEVEL +%token CLOSE %token CONNECT %token CONNECTFREQ -%token CRYPTLINK -%token DEFAULT_CIPHER_PREFERENCE +%token CYCLE_ON_HOST_CHANGE %token DEFAULT_FLOODCOUNT -%token DEFAULT_SPLIT_SERVER_COUNT -%token DEFAULT_SPLIT_USER_COUNT +%token DEFAULT_JOIN_FLOOD_COUNT +%token DEFAULT_JOIN_FLOOD_TIME +%token DEFAULT_MAX_CLIENTS %token DENY %token DESCRIPTION %token DIE %token DISABLE_AUTH %token DISABLE_FAKE_CHANNELS -%token DISABLE_HIDDEN -%token DISABLE_LOCAL_CHANNELS %token DISABLE_REMOTE_COMMANDS -%token DOT_IN_IP6_ADDR +%token DLINE_MIN_CIDR +%token DLINE_MIN_CIDR6 %token DOTS_IN_IDENT -%token DURATION -%token EGDPOOL_PATH %token EMAIL -%token ENABLE %token ENCRYPTED %token EXCEED_LIMIT %token EXEMPT %token FAILED_OPER_NOTICE -%token FAKENAME -%token IRCD_FLAGS %token FLATTEN_LINKS -%token FFAILED_OPERLOG -%token FKILLLOG -%token FKLINELOG -%token FGLINELOG -%token FIOERRLOG -%token FOPERLOG -%token FOPERSPYLOG -%token FUSERLOG +%token FLATTEN_LINKS_DELAY +%token FLATTEN_LINKS_FILE %token GECOS %token GENERAL -%token GLINE -%token GLINES -%token GLINE_EXEMPT -%token GLINE_LOG -%token GLINE_TIME -%token GLINE_MIN_CIDR -%token GLINE_MIN_CIDR6 -%token GLOBAL_KILL -%token IRCD_AUTH -%token NEED_IDENT -%token HAVENT_READ_CONF %token HIDDEN -%token HIDDEN_ADMIN -%token HIDDEN_NAME -%token HIDDEN_OPER +%token HIDDEN_NAME +%token HIDE_CHANS +%token HIDE_IDLE +%token HIDE_IDLE_FROM_OPERS %token HIDE_SERVER_IPS %token HIDE_SERVERS -%token HIDE_SPOOF_IPS +%token HIDE_SERVICES %token HOST %token HUB %token HUB_MASK -%token IDLETIME %token IGNORE_BOGUS_TS %token INVISIBLE_ON_CONNECT +%token INVITE_CLIENT_COUNT +%token INVITE_CLIENT_TIME +%token INVITE_DELAY_CHANNEL %token IP +%token IRCD_AUTH +%token IRCD_FLAGS +%token IRCD_SID +%token JOIN %token KILL -%token KILL_CHASE_TIME_LIMIT +%token KILL_CHASE_TIME_LIMIT %token KLINE %token KLINE_EXEMPT -%token KLINE_REASON -%token KLINE_WITH_REASON -%token KNOCK_DELAY +%token KLINE_MIN_CIDR +%token KLINE_MIN_CIDR6 +%token KNOCK_CLIENT_COUNT +%token KNOCK_CLIENT_TIME %token KNOCK_DELAY_CHANNEL -%token LAZYLINK %token LEAF_MASK -%token LINKS_DELAY +%token LIBGEOIP_DATABASE_OPTIONS +%token LIBGEOIP_IPV4_DATABASE_FILE +%token LIBGEOIP_IPV6_DATABASE_FILE %token LISTEN -%token T_LOG -%token LOGGING -%token LOG_LEVEL +%token MASK %token MAX_ACCEPT %token MAX_BANS -%token MAX_CHANS_PER_USER +%token MAX_CHANNELS %token MAX_GLOBAL -%token MAX_IDENT +%token MAX_IDLE %token MAX_LOCAL %token MAX_NICK_CHANGES +%token MAX_NICK_LENGTH %token MAX_NICK_TIME %token MAX_NUMBER %token MAX_TARGETS -%token MESSAGE_LOCALE +%token MAX_TOPIC_LENGTH +%token MAX_WATCH +%token MEMORY_CACHE +%token MIN_IDLE %token MIN_NONWILDCARD %token MIN_NONWILDCARD_SIMPLE +%token MMAP_CACHE %token MODULE %token MODULES +%token MOTD %token NAME +%token NEED_IDENT %token NEED_PASSWORD %token NETWORK_DESC %token NETWORK_NAME %token NICK -%token NICK_CHANGES -%token NO_CREATE_ON_SPLIT -%token NO_JOIN_ON_SPLIT %token NO_OPER_FLOOD %token NO_TILDE -%token NOT %token NUMBER -%token NUMBER_PER_IDENT %token NUMBER_PER_CIDR %token NUMBER_PER_IP -%token NUMBER_PER_IP_GLOBAL -%token OPERATOR -%token OPERS_BYPASS_CALLERID -%token OPER_LOG %token OPER_ONLY_UMODES -%token OPER_PASS_RESV -%token OPER_SPY_T %token OPER_UMODES -%token JOIN_FLOOD_COUNT -%token JOIN_FLOOD_TIME +%token OPERATOR +%token OPERS_BYPASS_CALLERID %token PACE_WAIT %token PACE_WAIT_SIMPLE %token PASSWORD %token PATH %token PING_COOKIE %token PING_TIME -%token PING_WARNING %token PORT %token QSTRING -%token QUIET_ON_BAN +%token RANDOM_IDLE %token REASON %token REDIRPORT %token REDIRSERV -%token REGEX_T %token REHASH -%token TREJECT_HOLD_TIME %token REMOTE %token REMOTEBAN -%token RESTRICT_CHANNELS -%token RESTRICTED -%token RSA_PRIVATE_KEY_FILE -%token RSA_PUBLIC_KEY_FILE -%token SSL_CERTIFICATE_FILE %token RESV %token RESV_EXEMPT -%token SECONDS MINUTES HOURS DAYS WEEKS -%token SENDQ +%token RSA_PRIVATE_KEY_FILE +%token SECONDS MINUTES HOURS DAYS WEEKS MONTHS YEARS %token SEND_PASSWORD +%token SENDQ %token SERVERHIDE %token SERVERINFO -%token SERVLINK_PATH -%token IRCD_SID -%token TKLINE_EXPIRE_NOTICES -%token T_SHARED -%token T_CLUSTER -%token TYPE %token SHORT_MOTD -%token SILENT %token SPOOF %token SPOOF_NOTICE +%token SQUIT +%token SSL_CERTIFICATE_FILE +%token SSL_CERTIFICATE_FINGERPRINT +%token SSL_CONNECTION_REQUIRED +%token SSL_DH_ELLIPTIC_CURVE +%token SSL_DH_PARAM_FILE +%token SSL_MESSAGE_DIGEST_ALGORITHM +%token STANDARD %token STATS_E_DISABLED %token STATS_I_OPER_ONLY %token STATS_K_OPER_ONLY +%token STATS_M_OPER_ONLY %token STATS_O_OPER_ONLY %token STATS_P_OPER_ONLY -%token TBOOL -%token TMASKED -%token T_REJECT -%token TS_MAX_DELTA -%token TS_WARN_DELTA -%token TWODOTS +%token STATS_U_OPER_ONLY %token T_ALL %token T_BOTS -%token T_SOFTCALLERID %token T_CALLERID %token T_CCONN -%token T_CLIENT_FLOOD +%token T_COMMAND +%token T_CLUSTER %token T_DEAF %token T_DEBUG -%token T_DRONE +%token T_DLINE %token T_EXTERNAL +%token T_FARCONNECT +%token T_FILE %token T_FULL +%token T_GLOBOPS %token T_INVISIBLE %token T_IPV4 %token T_IPV6 %token T_LOCOPS -%token T_LOGPATH -%token T_L_CRIT -%token T_L_DEBUG -%token T_L_ERROR -%token T_L_INFO -%token T_L_NOTICE -%token T_L_TRACE -%token T_L_WARN -%token T_MAX_CLIENTS +%token T_LOG %token T_NCHANGE -%token T_OPERWALL +%token T_NONONREG +%token T_OPME +%token T_PREPEND +%token T_PSEUDO +%token T_RECVQ %token T_REJ +%token T_RESTART +%token T_SERVER +%token T_SERVICE %token T_SERVNOTICE +%token T_SET +%token T_SHARED +%token T_SIZE %token T_SKILL +%token T_SOFTCALLERID %token T_SPY %token T_SSL +%token T_SSL_CIPHER_LIST +%token T_TARGET %token T_UMODES %token T_UNAUTH +%token T_UNDLINE +%token T_UNLIMITED %token T_UNRESV %token T_UNXLINE %token T_WALLOP +%token T_WALLOPS +%token T_WEBIRC +%token TBOOL +%token THROTTLE_COUNT %token THROTTLE_TIME -%token TOPICBURST -%token TRUE_NO_OPER_FLOOD -%token TKLINE -%token TXLINE -%token TRESV +%token TKLINE_EXPIRE_NOTICES +%token TMASKED +%token TS_MAX_DELTA +%token TS_WARN_DELTA +%token TWODOTS +%token TYPE %token UNKLINE -%token USER -%token USE_EGD -%token USE_EXCEPT -%token USE_INVEX -%token USE_KNOCK %token USE_LOGGING -%token USE_WHOIS_ACTUALLY +%token USER %token VHOST %token VHOST6 +%token WARN_NO_CONNECT_BLOCK +%token WHOIS +%token WHOWAS_HISTORY_LENGTH %token XLINE -%token WARN -%token WARN_NO_NLINE +%token XLINE_EXEMPT -%type QSTRING -%type NUMBER -%type timespec -%type timespec_ -%type sizespec -%type sizespec_ +%type QSTRING +%type NUMBER +%type timespec +%type timespec_ +%type sizespec +%type sizespec_ %% -conf: +conf: | conf conf_item ; conf_item: admin_entry | logging_entry | oper_entry - | channel_entry - | class_entry + | channel_entry + | class_entry | listen_entry | auth_entry | serverinfo_entry - | serverhide_entry + | serverhide_entry | resv_entry + | service_entry | shared_entry - | cluster_entry + | cluster_entry | connect_entry | kill_entry | deny_entry - | exempt_entry - | general_entry - | gline_entry + | exempt_entry + | general_entry | gecos_entry | modules_entry + | motd_entry + | pseudo_entry | error ';' | error '}' ; timespec_: { $$ = 0; } | timespec; -timespec: NUMBER timespec_ - { - $$ = $1 + $2; - } - | NUMBER SECONDS timespec_ - { - $$ = $1 + $3; - } - | NUMBER MINUTES timespec_ - { - $$ = $1 * 60 + $3; - } - | NUMBER HOURS timespec_ - { - $$ = $1 * 60 * 60 + $3; - } - | NUMBER DAYS timespec_ - { - $$ = $1 * 60 * 60 * 24 + $3; - } - | NUMBER WEEKS timespec_ - { - $$ = $1 * 60 * 60 * 24 * 7 + $3; - } - ; - -sizespec_: { $$ = 0; } | sizespec; -sizespec: NUMBER sizespec_ { $$ = $1 + $2; } - | NUMBER BYTES sizespec_ { $$ = $1 + $3; } - | NUMBER KBYTES sizespec_ { $$ = $1 * 1024 + $3; } - | NUMBER MBYTES sizespec_ { $$ = $1 * 1024 * 1024 + $3; } - ; +timespec: NUMBER timespec_ { $$ = $1 + $2; } | + NUMBER SECONDS timespec_ { $$ = $1 + $3; } | + NUMBER MINUTES timespec_ { $$ = $1 * 60 + $3; } | + NUMBER HOURS timespec_ { $$ = $1 * 60 * 60 + $3; } | + NUMBER DAYS timespec_ { $$ = $1 * 60 * 60 * 24 + $3; } | + NUMBER WEEKS timespec_ { $$ = $1 * 60 * 60 * 24 * 7 + $3; } | + NUMBER MONTHS timespec_ { $$ = $1 * 60 * 60 * 24 * 7 * 4 + $3; } | + NUMBER YEARS timespec_ { $$ = $1 * 60 * 60 * 24 * 365 + $3; } + ; + +sizespec_: { $$ = 0; } | sizespec; +sizespec: NUMBER sizespec_ { $$ = $1 + $2; } | + NUMBER BYTES sizespec_ { $$ = $1 + $3; } | + NUMBER KBYTES sizespec_ { $$ = $1 * 1024 + $3; } | + NUMBER MBYTES sizespec_ { $$ = $1 * 1024 * 1024 + $3; } + ; /*************************************************************************** - * section modules + * modules {} section ***************************************************************************/ -modules_entry: MODULES - '{' modules_items '}' ';'; +modules_entry: MODULES '{' modules_items '}' ';'; modules_items: modules_items modules_item | modules_item; modules_item: modules_module | modules_path | error ';' ; modules_module: MODULE '=' QSTRING ';' { -#ifndef STATIC_MODULES /* NOOP in the static case */ - if (ypass == 2) - { - char *m_bn; - - m_bn = basename(yylval.string); - - /* I suppose we should just ignore it if it is already loaded(since - * otherwise we would flood the opers on rehash) -A1kmm. - */ - add_conf_module(yylval.string); - } -#endif + if (conf_parser_ctx.pass == 2) + add_conf_module(libio_basename(yylval.string)); }; modules_path: PATH '=' QSTRING ';' { -#ifndef STATIC_MODULES - if (ypass == 2) + if (conf_parser_ctx.pass == 2) mod_add_path(yylval.string); -#endif }; + /*************************************************************************** - * section serverinfo + * serverinfo {} section ***************************************************************************/ -serverinfo_entry: SERVERINFO - '{' serverinfo_items '}' ';'; +serverinfo_entry: SERVERINFO '{' serverinfo_items '}' ';'; + +serverinfo_items: serverinfo_items serverinfo_item | serverinfo_item ; +serverinfo_item: serverinfo_name | + serverinfo_vhost | + serverinfo_hub | + serverinfo_description | + serverinfo_network_name | + serverinfo_network_desc | + serverinfo_default_max_clients | + serverinfo_max_nick_length | + serverinfo_max_topic_length | + serverinfo_ssl_dh_param_file | + serverinfo_ssl_dh_elliptic_curve | + serverinfo_rsa_private_key_file | + serverinfo_vhost6 | + serverinfo_sid | + serverinfo_ssl_certificate_file | + serverinfo_ssl_cipher_list | + serverinfo_ssl_message_digest_algorithm | + serverinfo_libgeoip_database_options | + serverinfo_libgeoip_ipv4_database_file | + serverinfo_libgeoip_ipv6_database_file | + error ';' ; -serverinfo_items: serverinfo_items serverinfo_item | - serverinfo_item ; -serverinfo_item: serverinfo_name | serverinfo_vhost | - serverinfo_hub | serverinfo_description | - serverinfo_network_name | serverinfo_network_desc | - serverinfo_max_clients | - serverinfo_rsa_private_key_file | serverinfo_vhost6 | - serverinfo_sid | serverinfo_ssl_certificate_file | - error ';' ; serverinfo_ssl_certificate_file: SSL_CERTIFICATE_FILE '=' QSTRING ';' { -#ifdef HAVE_LIBCRYPTO - if (ypass == 2 && ServerInfo.ctx) + if (conf_parser_ctx.pass == 2) { - if (!ServerInfo.rsa_private_key_file) - { - yyerror("No rsa_private_key_file specified, SSL disabled"); - break; - } - - if (SSL_CTX_use_certificate_file(ServerInfo.ctx, - yylval.string, SSL_FILETYPE_PEM) <= 0) - { - yyerror(ERR_lib_error_string(ERR_get_error())); - break; - } - - if (SSL_CTX_use_PrivateKey_file(ServerInfo.ctx, - ServerInfo.rsa_private_key_file, SSL_FILETYPE_PEM) <= 0) - { - yyerror(ERR_lib_error_string(ERR_get_error())); - break; - } - - if (!SSL_CTX_check_private_key(ServerInfo.ctx)) - { - yyerror("RSA private key does not match the SSL certificate public key!"); - break; - } + xfree(ConfigServerInfo.ssl_certificate_file); + ConfigServerInfo.ssl_certificate_file = xstrdup(yylval.string); } -#endif }; serverinfo_rsa_private_key_file: RSA_PRIVATE_KEY_FILE '=' QSTRING ';' { -#ifdef HAVE_LIBCRYPTO - if (ypass == 1) + if (conf_parser_ctx.pass == 2) { - BIO *file; - - if (ServerInfo.rsa_private_key) - { - RSA_free(ServerInfo.rsa_private_key); - ServerInfo.rsa_private_key = NULL; - } + xfree(ConfigServerInfo.rsa_private_key_file); + ConfigServerInfo.rsa_private_key_file = xstrdup(yylval.string); + } +}; - if (ServerInfo.rsa_private_key_file) - { - MyFree(ServerInfo.rsa_private_key_file); - ServerInfo.rsa_private_key_file = NULL; - } +serverinfo_ssl_dh_param_file: SSL_DH_PARAM_FILE '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + { + xfree(ConfigServerInfo.ssl_dh_param_file); + ConfigServerInfo.ssl_dh_param_file = xstrdup(yylval.string); + } +}; - DupString(ServerInfo.rsa_private_key_file, yylval.string); +serverinfo_ssl_cipher_list: T_SSL_CIPHER_LIST '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + { + xfree(ConfigServerInfo.ssl_cipher_list); + ConfigServerInfo.ssl_cipher_list = xstrdup(yylval.string); + } +}; - if ((file = BIO_new_file(yylval.string, "r")) == NULL) - { - yyerror("File open failed, ignoring"); - break; - } +serverinfo_ssl_message_digest_algorithm: SSL_MESSAGE_DIGEST_ALGORITHM '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + { + xfree(ConfigServerInfo.ssl_message_digest_algorithm); + ConfigServerInfo.ssl_message_digest_algorithm = xstrdup(yylval.string); + } +} - ServerInfo.rsa_private_key = (RSA *)PEM_read_bio_RSAPrivateKey(file, NULL, - 0, NULL); +serverinfo_ssl_dh_elliptic_curve: SSL_DH_ELLIPTIC_CURVE '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + { + xfree(ConfigServerInfo.ssl_dh_elliptic_curve); + ConfigServerInfo.ssl_dh_elliptic_curve = xstrdup(yylval.string); + } +}; - BIO_set_close(file, BIO_CLOSE); - BIO_free(file); +serverinfo_libgeoip_database_options: LIBGEOIP_DATABASE_OPTIONS +{ + if (conf_parser_ctx.pass == 1) + ConfigServerInfo.libgeoip_database_options = 0; +} '=' options_items ';'; - if (ServerInfo.rsa_private_key == NULL) - { - yyerror("Couldn't extract key, ignoring"); - break; - } +options_items: options_items ',' options_item | options_item; +options_item: STANDARD +{ +#ifdef HAVE_LIBGEOIP + if (conf_parser_ctx.pass == 1) + ConfigServerInfo.libgeoip_database_options |= GEOIP_STANDARD; +#endif +} | MEMORY_CACHE +{ +#ifdef HAVE_LIBGEOIP + if (conf_parser_ctx.pass == 1) + ConfigServerInfo.libgeoip_database_options |= GEOIP_MEMORY_CACHE; +#endif +} | MMAP_CACHE +{ +#ifdef HAVE_LIBGEOIP + if (conf_parser_ctx.pass == 1) + ConfigServerInfo.libgeoip_database_options |= GEOIP_MMAP_CACHE; +#endif +} | CHECK_CACHE +{ +#ifdef HAVE_LIBGEOIP + if (conf_parser_ctx.pass == 1) + ConfigServerInfo.libgeoip_database_options |= GEOIP_CHECK_CACHE; +#endif +}; - if (!RSA_check_key(ServerInfo.rsa_private_key)) - { - RSA_free(ServerInfo.rsa_private_key); - ServerInfo.rsa_private_key = NULL; +serverinfo_libgeoip_ipv4_database_file: LIBGEOIP_IPV4_DATABASE_FILE '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + { + xfree(ConfigServerInfo.libgeoip_ipv4_database_file); + ConfigServerInfo.libgeoip_ipv4_database_file = xstrdup(yylval.string); - yyerror("Invalid key, ignoring"); - break; - } +#ifdef HAVE_LIBGEOIP + if (GeoIPv4_ctx) + GeoIP_delete(GeoIPv4_ctx); + GeoIPv4_ctx = GeoIP_open(yylval.string, ConfigServerInfo.libgeoip_database_options); +#endif + } +}; - /* require 2048 bit (256 byte) key */ - if (RSA_size(ServerInfo.rsa_private_key) != 256) - { - RSA_free(ServerInfo.rsa_private_key); - ServerInfo.rsa_private_key = NULL; +serverinfo_libgeoip_ipv6_database_file: LIBGEOIP_IPV6_DATABASE_FILE '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + { + xfree(ConfigServerInfo.libgeoip_ipv6_database_file); + ConfigServerInfo.libgeoip_ipv6_database_file = xstrdup(yylval.string); - yyerror("Not a 2048 bit key, ignoring"); - } - } +#ifdef HAVE_LIBGEOIP + if (GeoIPv6_ctx) + GeoIP_delete(GeoIPv6_ctx); + GeoIPv6_ctx = GeoIP_open(yylval.string, ConfigServerInfo.libgeoip_database_options); #endif + } }; -serverinfo_name: NAME '=' QSTRING ';' +serverinfo_name: NAME '=' QSTRING ';' { - /* this isn't rehashable */ - if (ypass == 2) + /* This isn't rehashable */ + if (conf_parser_ctx.pass == 2 && !ConfigServerInfo.name) { - if (ServerInfo.name == NULL) + if (valid_servname(yylval.string)) + ConfigServerInfo.name = xstrdup(yylval.string); + else { - /* the ircd will exit() in main() if we dont set one */ - if (strlen(yylval.string) <= HOSTLEN) - DupString(ServerInfo.name, yylval.string); + conf_error_report("Ignoring serverinfo::name -- invalid name. Aborting."); + exit(EXIT_FAILURE); } } }; -serverinfo_sid: IRCD_SID '=' QSTRING ';' +serverinfo_sid: IRCD_SID '=' QSTRING ';' { - /* this isn't rehashable */ - if (ypass == 2 && !ServerInfo.sid) + /* This isn't rehashable */ + if (conf_parser_ctx.pass == 2 && !ConfigServerInfo.sid) { if (valid_sid(yylval.string)) - DupString(ServerInfo.sid, yylval.string); + ConfigServerInfo.sid = xstrdup(yylval.string); else { - ilog(L_ERROR, "Ignoring config file entry SID -- invalid SID. Aborting."); - exit(0); + conf_error_report("Ignoring serverinfo::sid -- invalid SID. Aborting."); + exit(EXIT_FAILURE); } } }; serverinfo_description: DESCRIPTION '=' QSTRING ';' { - if (ypass == 2) + if (conf_parser_ctx.pass == 2) { - MyFree(ServerInfo.description); - DupString(ServerInfo.description,yylval.string); + xfree(ConfigServerInfo.description); + ConfigServerInfo.description = xstrdup(yylval.string); + strlcpy(me.info, ConfigServerInfo.description, sizeof(me.info)); } }; serverinfo_network_name: NETWORK_NAME '=' QSTRING ';' { - if (ypass == 2) + if (conf_parser_ctx.pass == 2) { char *p; - if ((p = strchr(yylval.string, ' ')) != NULL) - p = '\0'; + if ((p = strchr(yylval.string, ' '))) + *p = '\0'; - MyFree(ServerInfo.network_name); - DupString(ServerInfo.network_name, yylval.string); + xfree(ConfigServerInfo.network_name); + ConfigServerInfo.network_name = xstrdup(yylval.string); } }; serverinfo_network_desc: NETWORK_DESC '=' QSTRING ';' { - if (ypass == 2) - { - MyFree(ServerInfo.network_desc); - DupString(ServerInfo.network_desc, yylval.string); - } + if (conf_parser_ctx.pass != 2) + break; + + xfree(ConfigServerInfo.network_desc); + ConfigServerInfo.network_desc = xstrdup(yylval.string); }; serverinfo_vhost: VHOST '=' QSTRING ';' { - if (ypass == 2 && *yylval.string != '*') + if (conf_parser_ctx.pass == 2 && *yylval.string != '*') { struct addrinfo hints, *res; @@ -672,26 +667,25 @@ serverinfo_vhost: VHOST '=' QSTRING ';' hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; - if (irc_getaddrinfo(yylval.string, NULL, &hints, &res)) - ilog(L_ERROR, "Invalid netmask for server vhost(%s)", yylval.string); + if (getaddrinfo(yylval.string, NULL, &hints, &res)) + ilog(LOG_TYPE_IRCD, "Invalid netmask for server vhost(%s)", yylval.string); else { - assert(res != NULL); + assert(res); - memcpy(&ServerInfo.ip, res->ai_addr, res->ai_addrlen); - ServerInfo.ip.ss.ss_family = res->ai_family; - ServerInfo.ip.ss_len = res->ai_addrlen; - irc_freeaddrinfo(res); + memcpy(&ConfigServerInfo.ip, res->ai_addr, res->ai_addrlen); + ConfigServerInfo.ip.ss.ss_family = res->ai_family; + ConfigServerInfo.ip.ss_len = res->ai_addrlen; + freeaddrinfo(res); - ServerInfo.specific_ipv4_vhost = 1; + ConfigServerInfo.specific_ipv4_vhost = 1; } } }; serverinfo_vhost6: VHOST6 '=' QSTRING ';' { -#ifdef IPV6 - if (ypass == 2 && *yylval.string != '*') + if (conf_parser_ctx.pass == 2 && *yylval.string != '*') { struct addrinfo hints, *res; @@ -701,1531 +695,1215 @@ serverinfo_vhost6: VHOST6 '=' QSTRING '; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; - if (irc_getaddrinfo(yylval.string, NULL, &hints, &res)) - ilog(L_ERROR, "Invalid netmask for server vhost6(%s)", yylval.string); + if (getaddrinfo(yylval.string, NULL, &hints, &res)) + ilog(LOG_TYPE_IRCD, "Invalid netmask for server vhost6(%s)", yylval.string); else { - assert(res != NULL); + assert(res); - memcpy(&ServerInfo.ip6, res->ai_addr, res->ai_addrlen); - ServerInfo.ip6.ss.ss_family = res->ai_family; - ServerInfo.ip6.ss_len = res->ai_addrlen; - irc_freeaddrinfo(res); + memcpy(&ConfigServerInfo.ip6, res->ai_addr, res->ai_addrlen); + ConfigServerInfo.ip6.ss.ss_family = res->ai_family; + ConfigServerInfo.ip6.ss_len = res->ai_addrlen; + freeaddrinfo(res); - ServerInfo.specific_ipv6_vhost = 1; + ConfigServerInfo.specific_ipv6_vhost = 1; } } -#endif }; -serverinfo_max_clients: T_MAX_CLIENTS '=' NUMBER ';' +serverinfo_default_max_clients: DEFAULT_MAX_CLIENTS '=' NUMBER ';' { - if (ypass == 2) + if (conf_parser_ctx.pass != 2) + break; + + if ($3 < MAXCLIENTS_MIN) { - recalc_fdlimit(NULL); + char buf[IRCD_BUFSIZE] = ""; - if ($3 < MAXCLIENTS_MIN) - { - char buf[IRCD_BUFSIZE]; - ircsprintf(buf, "MAXCLIENTS too low, setting to %d", MAXCLIENTS_MIN); - yyerror(buf); - } - else if ($3 > MAXCLIENTS_MAX) - { - char buf[IRCD_BUFSIZE]; - ircsprintf(buf, "MAXCLIENTS too high, setting to %d", MAXCLIENTS_MAX); - yyerror(buf); - } - else - ServerInfo.max_clients = $3; + snprintf(buf, sizeof(buf), "MAXCLIENTS too low, setting to %d", MAXCLIENTS_MIN); + conf_error_report(buf); + ConfigServerInfo.default_max_clients = MAXCLIENTS_MIN; + } + else if ($3 > MAXCLIENTS_MAX) + { + char buf[IRCD_BUFSIZE] = ""; + + snprintf(buf, sizeof(buf), "MAXCLIENTS too high, setting to %d", MAXCLIENTS_MAX); + conf_error_report(buf); + ConfigServerInfo.default_max_clients = MAXCLIENTS_MAX; } + else + ConfigServerInfo.default_max_clients = $3; }; -serverinfo_hub: HUB '=' TBOOL ';' +serverinfo_max_nick_length: MAX_NICK_LENGTH '=' NUMBER ';' { - if (ypass == 2) + if (conf_parser_ctx.pass != 2) + break; + + if ($3 < 9) { - if (yylval.number) - { - /* Don't become a hub if we have a lazylink active. */ - if (!ServerInfo.hub && uplink && IsCapable(uplink, CAP_LL)) - { - sendto_realops_flags(UMODE_ALL, L_ALL, - "Ignoring config file line hub=yes; " - "due to active LazyLink (%s)", uplink->name); - } - else - { - ServerInfo.hub = 1; - uplink = NULL; - delete_capability("HUB"); - add_capability("HUB", CAP_HUB, 1); - } - } - else if (ServerInfo.hub) - { - dlink_node *ptr = NULL; + conf_error_report("max_nick_length too low, setting to 9"); + ConfigServerInfo.max_nick_length = 9; + } + else if ($3 > NICKLEN) + { + char buf[IRCD_BUFSIZE] = ""; + + snprintf(buf, sizeof(buf), "max_nick_length too high, setting to %d", NICKLEN); + conf_error_report(buf); + ConfigServerInfo.max_nick_length = NICKLEN; + } + else + ConfigServerInfo.max_nick_length = $3; +}; - ServerInfo.hub = 0; - delete_capability("HUB"); +serverinfo_max_topic_length: MAX_TOPIC_LENGTH '=' NUMBER ';' +{ + if (conf_parser_ctx.pass != 2) + break; - /* Don't become a leaf if we have a lazylink active. */ - DLINK_FOREACH(ptr, serv_list.head) - { - const struct Client *acptr = ptr->data; - if (MyConnect(acptr) && IsCapable(acptr, CAP_LL)) - { - sendto_realops_flags(UMODE_ALL, L_ALL, - "Ignoring config file line hub=no; " - "due to active LazyLink (%s)", - acptr->name); - add_capability("HUB", CAP_HUB, 1); - ServerInfo.hub = 1; - break; - } - } - } + if ($3 < 80) + { + conf_error_report("max_topic_length too low, setting to 80"); + ConfigServerInfo.max_topic_length = 80; } + else if ($3 > TOPICLEN) + { + char buf[IRCD_BUFSIZE] = ""; + + snprintf(buf, sizeof(buf), "max_topic_length too high, setting to %d", TOPICLEN); + conf_error_report(buf); + ConfigServerInfo.max_topic_length = TOPICLEN; + } + else + ConfigServerInfo.max_topic_length = $3; }; +serverinfo_hub: HUB '=' TBOOL ';' +{ + if (conf_parser_ctx.pass == 2) + ConfigServerInfo.hub = yylval.number; +}; + + /*************************************************************************** - * admin section + * admin {} section ***************************************************************************/ admin_entry: ADMIN '{' admin_items '}' ';' ; admin_items: admin_items admin_item | admin_item; -admin_item: admin_name | admin_description | - admin_email | error ';' ; +admin_item: admin_name | + admin_description | + admin_email | + error ';' ; -admin_name: NAME '=' QSTRING ';' +admin_name: NAME '=' QSTRING ';' { - if (ypass == 2) - { - MyFree(AdminInfo.name); - DupString(AdminInfo.name, yylval.string); - } + if (conf_parser_ctx.pass != 2) + break; + + xfree(ConfigAdminInfo.name); + ConfigAdminInfo.name = xstrdup(yylval.string); }; admin_email: EMAIL '=' QSTRING ';' { - if (ypass == 2) - { - MyFree(AdminInfo.email); - DupString(AdminInfo.email, yylval.string); - } + if (conf_parser_ctx.pass != 2) + break; + + xfree(ConfigAdminInfo.email); + ConfigAdminInfo.email = xstrdup(yylval.string); }; admin_description: DESCRIPTION '=' QSTRING ';' { - if (ypass == 2) - { - MyFree(AdminInfo.description); - DupString(AdminInfo.description, yylval.string); - } + if (conf_parser_ctx.pass != 2) + break; + + xfree(ConfigAdminInfo.description); + ConfigAdminInfo.description = xstrdup(yylval.string); }; + /*************************************************************************** - * section logging + * motd {} section ***************************************************************************/ -/* XXX */ -logging_entry: LOGGING '{' logging_items '}' ';' ; +motd_entry: MOTD +{ + if (conf_parser_ctx.pass == 2) + reset_block_state(); +} '{' motd_items '}' ';' +{ + dlink_node *node = NULL; -logging_items: logging_items logging_item | - logging_item ; + if (conf_parser_ctx.pass != 2) + break; -logging_item: logging_path | logging_oper_log | - logging_log_level | - logging_use_logging | logging_fuserlog | - logging_foperlog | logging_fglinelog | - logging_fklinelog | logging_killlog | - logging_foperspylog | logging_ioerrlog | - logging_ffailed_operlog | - error ';' ; + if (!block_state.file.buf[0]) + break; -logging_path: T_LOGPATH '=' QSTRING ';' - { - }; + DLINK_FOREACH(node, block_state.mask.list.head) + motd_add(node->data, block_state.file.buf); +}; -logging_oper_log: OPER_LOG '=' QSTRING ';' - { - }; +motd_items: motd_items motd_item | motd_item; +motd_item: motd_mask | motd_file | error ';' ; -logging_fuserlog: FUSERLOG '=' QSTRING ';' +motd_mask: MASK '=' QSTRING ';' { - if (ypass == 2) - strlcpy(ConfigLoggingEntry.userlog, yylval.string, - sizeof(ConfigLoggingEntry.userlog)); + if (conf_parser_ctx.pass == 2) + dlinkAdd(xstrdup(yylval.string), make_dlink_node(), &block_state.mask.list); }; -logging_ffailed_operlog: FFAILED_OPERLOG '=' QSTRING ';' +motd_file: T_FILE '=' QSTRING ';' { - if (ypass == 2) - strlcpy(ConfigLoggingEntry.failed_operlog, yylval.string, - sizeof(ConfigLoggingEntry.failed_operlog)); + if (conf_parser_ctx.pass == 2) + strlcpy(block_state.file.buf, yylval.string, sizeof(block_state.file.buf)); }; -logging_foperlog: FOPERLOG '=' QSTRING ';' + +/*************************************************************************** + * pseudo {} section + ***************************************************************************/ +pseudo_entry: T_PSEUDO +{ + if (conf_parser_ctx.pass == 2) + reset_block_state(); +} '{' pseudo_items '}' ';' { - if (ypass == 2) - strlcpy(ConfigLoggingEntry.operlog, yylval.string, - sizeof(ConfigLoggingEntry.operlog)); + if (conf_parser_ctx.pass != 2) + break; + + if (!block_state.command.buf[0] || + !block_state.name.buf[0] || + !block_state.nick.buf[0] || + !block_state.host.buf[0]) + break; + + pseudo_register(block_state.name.buf, block_state.nick.buf, block_state.host.buf, + block_state.prepend.buf, block_state.command.buf); }; -logging_foperspylog: FOPERSPYLOG '=' QSTRING ';' +pseudo_items: pseudo_items pseudo_item | pseudo_item; +pseudo_item: pseudo_command | pseudo_prepend | pseudo_name | pseudo_target | error ';' ; + +pseudo_command: T_COMMAND '=' QSTRING ';' { - if (ypass == 2) - strlcpy(ConfigLoggingEntry.operspylog, yylval.string, - sizeof(ConfigLoggingEntry.operspylog)); + if (conf_parser_ctx.pass == 2) + strlcpy(block_state.command.buf, yylval.string, sizeof(block_state.command.buf)); }; -logging_fglinelog: FGLINELOG '=' QSTRING ';' +pseudo_name: NAME '=' QSTRING ';' { - if (ypass == 2) - strlcpy(ConfigLoggingEntry.glinelog, yylval.string, - sizeof(ConfigLoggingEntry.glinelog)); + if (conf_parser_ctx.pass == 2) + strlcpy(block_state.name.buf, yylval.string, sizeof(block_state.name.buf)); }; -logging_fklinelog: FKLINELOG '=' QSTRING ';' +pseudo_prepend: T_PREPEND '=' QSTRING ';' { - if (ypass == 2) - strlcpy(ConfigLoggingEntry.klinelog, yylval.string, - sizeof(ConfigLoggingEntry.klinelog)); + if (conf_parser_ctx.pass == 2) + strlcpy(block_state.prepend.buf, yylval.string, sizeof(block_state.prepend.buf)); }; -logging_ioerrlog: FIOERRLOG '=' QSTRING ';' +pseudo_target: T_TARGET '=' QSTRING ';' { - if (ypass == 2) - strlcpy(ConfigLoggingEntry.ioerrlog, yylval.string, - sizeof(ConfigLoggingEntry.ioerrlog)); + if (conf_parser_ctx.pass == 2) + { + struct split_nuh_item nuh; + + nuh.nuhmask = yylval.string; + nuh.nickptr = NULL; + nuh.userptr = block_state.nick.buf; + nuh.hostptr = block_state.host.buf; + nuh.nicksize = 0; + nuh.usersize = sizeof(block_state.nick.buf); + nuh.hostsize = sizeof(block_state.host.buf); + + split_nuh(&nuh); + } }; -logging_killlog: FKILLLOG '=' QSTRING ';' + +/*************************************************************************** + * log {} section + ***************************************************************************/ +logging_entry: T_LOG '{' logging_items '}' ';' ; +logging_items: logging_items logging_item | logging_item ; + +logging_item: logging_use_logging | logging_file_entry | + error ';' ; + +logging_use_logging: USE_LOGGING '=' TBOOL ';' { - if (ypass == 2) - strlcpy(ConfigLoggingEntry.killlog, yylval.string, - sizeof(ConfigLoggingEntry.killlog)); + if (conf_parser_ctx.pass == 2) + ConfigLog.use_logging = yylval.number; }; -logging_log_level: LOG_LEVEL '=' T_L_CRIT ';' -{ - if (ypass == 2) - set_log_level(L_CRIT); -} | LOG_LEVEL '=' T_L_ERROR ';' -{ - if (ypass == 2) - set_log_level(L_ERROR); -} | LOG_LEVEL '=' T_L_WARN ';' +logging_file_entry: { - if (ypass == 2) - set_log_level(L_WARN); -} | LOG_LEVEL '=' T_L_NOTICE ';' + if (conf_parser_ctx.pass == 2) + reset_block_state(); +} T_FILE '{' logging_file_items '}' ';' { - if (ypass == 2) - set_log_level(L_NOTICE); -} | LOG_LEVEL '=' T_L_TRACE ';' + if (conf_parser_ctx.pass != 2) + break; + + if (block_state.type.value && block_state.file.buf[0]) + log_set_file(block_state.type.value, block_state.size.value, + block_state.file.buf); +}; + +logging_file_items: logging_file_items logging_file_item | + logging_file_item ; + +logging_file_item: logging_file_name | logging_file_type | + logging_file_size | error ';' ; + +logging_file_name: NAME '=' QSTRING ';' { - if (ypass == 2) - set_log_level(L_TRACE); -} | LOG_LEVEL '=' T_L_INFO ';' + if (conf_parser_ctx.pass != 2) + break; + + strlcpy(block_state.file.buf, yylval.string, sizeof(block_state.file.buf)); +} + +logging_file_size: T_SIZE '=' sizespec ';' { - if (ypass == 2) - set_log_level(L_INFO); -} | LOG_LEVEL '=' T_L_DEBUG ';' + block_state.size.value = $3; +} | T_SIZE '=' T_UNLIMITED ';' { - if (ypass == 2) - set_log_level(L_DEBUG); + block_state.size.value = 0; }; -logging_use_logging: USE_LOGGING '=' TBOOL ';' +logging_file_type: TYPE { - if (ypass == 2) - ConfigLoggingEntry.use_logging = yylval.number; + if (conf_parser_ctx.pass == 2) + block_state.type.value = 0; +} '=' logging_file_type_items ';' ; + +logging_file_type_items: logging_file_type_items ',' logging_file_type_item | logging_file_type_item; +logging_file_type_item: USER +{ + if (conf_parser_ctx.pass == 2) + block_state.type.value = LOG_TYPE_USER; +} | OPERATOR +{ + if (conf_parser_ctx.pass == 2) + block_state.type.value = LOG_TYPE_OPER; +} | XLINE +{ + if (conf_parser_ctx.pass == 2) + block_state.type.value = LOG_TYPE_XLINE; +} | RESV +{ + if (conf_parser_ctx.pass == 2) + block_state.type.value = LOG_TYPE_RESV; +} | T_DLINE +{ + if (conf_parser_ctx.pass == 2) + block_state.type.value = LOG_TYPE_DLINE; +} | KLINE +{ + if (conf_parser_ctx.pass == 2) + block_state.type.value = LOG_TYPE_KLINE; +} | KILL +{ + if (conf_parser_ctx.pass == 2) + block_state.type.value = LOG_TYPE_KILL; +} | T_DEBUG +{ + if (conf_parser_ctx.pass == 2) + block_state.type.value = LOG_TYPE_DEBUG; }; + /*************************************************************************** - * section oper + * operator {} section ***************************************************************************/ -oper_entry: OPERATOR +oper_entry: OPERATOR { - if (ypass == 2) - { - yy_conf = make_conf_item(OPER_TYPE); - yy_aconf = map_to_conf(yy_conf); - SetConfEncrypted(yy_aconf); /* Yes, the default is encrypted */ - } - else - { - MyFree(class_name); - class_name = NULL; - } -} oper_name_b '{' oper_items '}' ';' + if (conf_parser_ctx.pass != 2) + break; + + reset_block_state(); + block_state.flags.value |= CONF_FLAGS_ENCRYPTED; +} '{' oper_items '}' ';' { - if (ypass == 2) - { - struct CollectItem *yy_tmp; - dlink_node *ptr; - dlink_node *next_ptr; + dlink_node *node = NULL; - conf_add_class_to_conf(yy_conf, class_name); + if (conf_parser_ctx.pass != 2) + break; - /* Now, make sure there is a copy of the "base" given oper - * block in each of the collected copies - */ + if (!block_state.name.buf[0]) + break; - DLINK_FOREACH_SAFE(ptr, next_ptr, col_conf_list.head) - { - struct AccessItem *new_aconf; - struct ConfItem *new_conf; - yy_tmp = ptr->data; - - new_conf = make_conf_item(OPER_TYPE); - new_aconf = (struct AccessItem *)map_to_conf(new_conf); - - new_aconf->flags = yy_aconf->flags; - - if (yy_conf->name != NULL) - DupString(new_conf->name, yy_conf->name); - if (yy_tmp->user != NULL) - DupString(new_aconf->user, yy_tmp->user); - else - DupString(new_aconf->user, "*"); - if (yy_tmp->host != NULL) - DupString(new_aconf->host, yy_tmp->host); - else - DupString(new_aconf->host, "*"); - conf_add_class_to_conf(new_conf, class_name); - if (yy_aconf->passwd != NULL) - DupString(new_aconf->passwd, yy_aconf->passwd); - - new_aconf->port = yy_aconf->port; -#ifdef HAVE_LIBCRYPTO - if (yy_aconf->rsa_public_key_file != NULL) - { - BIO *file; - - DupString(new_aconf->rsa_public_key_file, - yy_aconf->rsa_public_key_file); - - file = BIO_new_file(yy_aconf->rsa_public_key_file, "r"); - new_aconf->rsa_public_key = (RSA *)PEM_read_bio_RSA_PUBKEY(file, - NULL, 0, NULL); - BIO_set_close(file, BIO_CLOSE); - BIO_free(file); - } -#endif + if (!block_state.rpass.buf[0]) + break; -#ifdef HAVE_LIBCRYPTO - if (yy_tmp->name && (yy_tmp->passwd || yy_aconf->rsa_public_key) - && yy_tmp->host) -#else - if (yy_tmp->name && yy_tmp->passwd && yy_tmp->host) -#endif - { - conf_add_class_to_conf(new_conf, class_name); - if (yy_tmp->name != NULL) - DupString(new_conf->name, yy_tmp->name); - } + DLINK_FOREACH(node, block_state.mask.list.head) + { + struct MaskItem *conf = NULL; + struct split_nuh_item nuh; + char *s = node->data; - dlinkDelete(&yy_tmp->node, &col_conf_list); - free_collect_item(yy_tmp); - } + if (EmptyString(s)) + continue; - yy_conf = NULL; - yy_aconf = NULL; + nuh.nuhmask = s; + nuh.nickptr = NULL; + nuh.userptr = block_state.user.buf; + nuh.hostptr = block_state.host.buf; + nuh.nicksize = 0; + nuh.usersize = sizeof(block_state.user.buf); + nuh.hostsize = sizeof(block_state.host.buf); + split_nuh(&nuh); + conf = conf_make(CONF_OPER); + conf->name = xstrdup(block_state.name.buf); + conf->user = xstrdup(block_state.user.buf); + conf->host = xstrdup(block_state.host.buf); + + if (block_state.cert.buf[0]) + conf->certfp = xstrdup(block_state.cert.buf); + + if (block_state.rpass.buf[0]) + conf->passwd = xstrdup(block_state.rpass.buf); + + if (block_state.whois.buf[0]) + conf->whois = xstrdup(block_state.whois.buf); + + conf->flags = block_state.flags.value; + conf->modes = block_state.modes.value; + conf->port = block_state.port.value; + conf->htype = parse_netmask(conf->host, &conf->addr, &conf->bits); - MyFree(class_name); - class_name = NULL; + conf_add_class_to_conf(conf, block_state.class.buf); } -}; +}; -oper_name_b: | oper_name_t; oper_items: oper_items oper_item | oper_item; -oper_item: oper_name | oper_user | oper_password | oper_hidden_admin | - oper_hidden_oper | oper_umodes | - oper_class | oper_global_kill | oper_remote | - oper_kline | oper_xline | oper_unkline | - oper_gline | oper_nick_changes | oper_remoteban | - oper_die | oper_rehash | oper_admin | oper_operwall | - oper_encrypted | oper_rsa_public_key_file | - oper_flags | error ';' ; +oper_item: oper_name | + oper_user | + oper_password | + oper_whois | + oper_umodes | + oper_class | + oper_encrypted | + oper_ssl_certificate_fingerprint | + oper_ssl_connection_required | + oper_flags | + error ';' ; oper_name: NAME '=' QSTRING ';' { - if (ypass == 2) - { - if (strlen(yylval.string) > OPERNICKLEN) - yylval.string[OPERNICKLEN] = '\0'; - - MyFree(yy_conf->name); - DupString(yy_conf->name, yylval.string); - } -}; - -oper_name_t: QSTRING -{ - if (ypass == 2) - { - if (strlen(yylval.string) > OPERNICKLEN) - yylval.string[OPERNICKLEN] = '\0'; - - MyFree(yy_conf->name); - DupString(yy_conf->name, yylval.string); - } + if (conf_parser_ctx.pass == 2) + strlcpy(block_state.name.buf, yylval.string, sizeof(block_state.name.buf)); }; oper_user: USER '=' QSTRING ';' { - if (ypass == 2) - { - struct split_nuh_item nuh; - - nuh.nuhmask = yylval.string; - nuh.nickptr = NULL; - nuh.userptr = userbuf; - nuh.hostptr = hostbuf; - - nuh.nicksize = 0; - nuh.usersize = sizeof(userbuf); - nuh.hostsize = sizeof(hostbuf); - - split_nuh(&nuh); - - if (yy_aconf->user == NULL) - { - DupString(yy_aconf->user, userbuf); - DupString(yy_aconf->host, hostbuf); - } - else - { - struct CollectItem *yy_tmp = MyMalloc(sizeof(struct CollectItem)); - - DupString(yy_tmp->user, userbuf); - DupString(yy_tmp->host, hostbuf); - - dlinkAdd(yy_tmp, &yy_tmp->node, &col_conf_list); - } - } + if (conf_parser_ctx.pass == 2) + dlinkAdd(xstrdup(yylval.string), make_dlink_node(), &block_state.mask.list); }; oper_password: PASSWORD '=' QSTRING ';' { - if (ypass == 2) - { - if (yy_aconf->passwd != NULL) - memset(yy_aconf->passwd, 0, strlen(yy_aconf->passwd)); - - MyFree(yy_aconf->passwd); - DupString(yy_aconf->passwd, yylval.string); - } + if (conf_parser_ctx.pass == 2) + strlcpy(block_state.rpass.buf, yylval.string, sizeof(block_state.rpass.buf)); }; -oper_encrypted: ENCRYPTED '=' TBOOL ';' +oper_whois: WHOIS '=' QSTRING ';' { - if (ypass == 2) - { - if (yylval.number) - SetConfEncrypted(yy_aconf); - else - ClearConfEncrypted(yy_aconf); - } + if (conf_parser_ctx.pass == 2) + strlcpy(block_state.whois.buf, yylval.string, sizeof(block_state.whois.buf)); }; -oper_rsa_public_key_file: RSA_PUBLIC_KEY_FILE '=' QSTRING ';' +oper_encrypted: ENCRYPTED '=' TBOOL ';' { -#ifdef HAVE_LIBCRYPTO - if (ypass == 2) - { - BIO *file; - - if (yy_aconf->rsa_public_key != NULL) - { - RSA_free(yy_aconf->rsa_public_key); - yy_aconf->rsa_public_key = NULL; - } - - if (yy_aconf->rsa_public_key_file != NULL) - { - MyFree(yy_aconf->rsa_public_key_file); - yy_aconf->rsa_public_key_file = NULL; - } - - DupString(yy_aconf->rsa_public_key_file, yylval.string); - file = BIO_new_file(yylval.string, "r"); + if (conf_parser_ctx.pass != 2) + break; - if (file == NULL) - { - yyerror("Ignoring rsa_public_key_file -- file doesn't exist"); - break; - } + if (yylval.number) + block_state.flags.value |= CONF_FLAGS_ENCRYPTED; + else + block_state.flags.value &= ~CONF_FLAGS_ENCRYPTED; +}; - yy_aconf->rsa_public_key = (RSA *)PEM_read_bio_RSA_PUBKEY(file, NULL, 0, NULL); +oper_ssl_certificate_fingerprint: SSL_CERTIFICATE_FINGERPRINT '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + strlcpy(block_state.cert.buf, yylval.string, sizeof(block_state.cert.buf)); +}; - if (yy_aconf->rsa_public_key == NULL) - { - yyerror("Ignoring rsa_public_key_file -- Key invalid; check key syntax."); - break; - } +oper_ssl_connection_required: SSL_CONNECTION_REQUIRED '=' TBOOL ';' +{ + if (conf_parser_ctx.pass != 2) + break; - BIO_set_close(file, BIO_CLOSE); - BIO_free(file); - } -#endif /* HAVE_LIBCRYPTO */ + if (yylval.number) + block_state.flags.value |= CONF_FLAGS_SSL; + else + block_state.flags.value &= ~CONF_FLAGS_SSL; }; oper_class: CLASS '=' QSTRING ';' { - if (ypass == 2) - { - MyFree(class_name); - DupString(class_name, yylval.string); - } + if (conf_parser_ctx.pass == 2) + strlcpy(block_state.class.buf, yylval.string, sizeof(block_state.class.buf)); }; oper_umodes: T_UMODES { - if (ypass == 2) - yy_aconf->modes = 0; + if (conf_parser_ctx.pass == 2) + block_state.modes.value = 0; } '=' oper_umodes_items ';' ; oper_umodes_items: oper_umodes_items ',' oper_umodes_item | oper_umodes_item; oper_umodes_item: T_BOTS { - if (ypass == 2) - yy_aconf->modes |= UMODE_BOTS; + if (conf_parser_ctx.pass == 2) + block_state.modes.value |= UMODE_BOTS; } | T_CCONN { - if (ypass == 2) - yy_aconf->modes |= UMODE_CCONN; + if (conf_parser_ctx.pass == 2) + block_state.modes.value |= UMODE_CCONN; } | T_DEAF { - if (ypass == 2) - yy_aconf->modes |= UMODE_DEAF; + if (conf_parser_ctx.pass == 2) + block_state.modes.value |= UMODE_DEAF; } | T_DEBUG { - if (ypass == 2) - yy_aconf->modes |= UMODE_DEBUG; + if (conf_parser_ctx.pass == 2) + block_state.modes.value |= UMODE_DEBUG; } | T_FULL { - if (ypass == 2) - yy_aconf->modes |= UMODE_FULL; + if (conf_parser_ctx.pass == 2) + block_state.modes.value |= UMODE_FULL; +} | HIDDEN +{ + if (conf_parser_ctx.pass == 2) + block_state.modes.value |= UMODE_HIDDEN; +} | HIDE_CHANS +{ + if (conf_parser_ctx.pass == 2) + block_state.modes.value |= UMODE_HIDECHANS; +} | HIDE_IDLE +{ + if (conf_parser_ctx.pass == 2) + block_state.modes.value |= UMODE_HIDEIDLE; } | T_SKILL { - if (ypass == 2) - yy_aconf->modes |= UMODE_SKILL; + if (conf_parser_ctx.pass == 2) + block_state.modes.value |= UMODE_SKILL; } | T_NCHANGE { - if (ypass == 2) - yy_aconf->modes |= UMODE_NCHANGE; + if (conf_parser_ctx.pass == 2) + block_state.modes.value |= UMODE_NCHANGE; } | T_REJ { - if (ypass == 2) - yy_aconf->modes |= UMODE_REJ; + if (conf_parser_ctx.pass == 2) + block_state.modes.value |= UMODE_REJ; } | T_UNAUTH { - if (ypass == 2) - yy_aconf->modes |= UMODE_UNAUTH; + if (conf_parser_ctx.pass == 2) + block_state.modes.value |= UMODE_UNAUTH; } | T_SPY { - if (ypass == 2) - yy_aconf->modes |= UMODE_SPY; + if (conf_parser_ctx.pass == 2) + block_state.modes.value |= UMODE_SPY; } | T_EXTERNAL { - if (ypass == 2) - yy_aconf->modes |= UMODE_EXTERNAL; -} | T_OPERWALL -{ - if (ypass == 2) - yy_aconf->modes |= UMODE_OPERWALL; + if (conf_parser_ctx.pass == 2) + block_state.modes.value |= UMODE_EXTERNAL; } | T_SERVNOTICE { - if (ypass == 2) - yy_aconf->modes |= UMODE_SERVNOTICE; + if (conf_parser_ctx.pass == 2) + block_state.modes.value |= UMODE_SERVNOTICE; } | T_INVISIBLE { - if (ypass == 2) - yy_aconf->modes |= UMODE_INVISIBLE; + if (conf_parser_ctx.pass == 2) + block_state.modes.value |= UMODE_INVISIBLE; } | T_WALLOP { - if (ypass == 2) - yy_aconf->modes |= UMODE_WALLOP; + if (conf_parser_ctx.pass == 2) + block_state.modes.value |= UMODE_WALLOP; } | T_SOFTCALLERID { - if (ypass == 2) - yy_aconf->modes |= UMODE_SOFTCALLERID; + if (conf_parser_ctx.pass == 2) + block_state.modes.value |= UMODE_SOFTCALLERID; } | T_CALLERID { - if (ypass == 2) - yy_aconf->modes |= UMODE_CALLERID; + if (conf_parser_ctx.pass == 2) + block_state.modes.value |= UMODE_CALLERID; } | T_LOCOPS { - if (ypass == 2) - yy_aconf->modes |= UMODE_LOCOPS; -}; - -oper_global_kill: GLOBAL_KILL '=' TBOOL ';' + if (conf_parser_ctx.pass == 2) + block_state.modes.value |= UMODE_LOCOPS; +} | T_NONONREG +{ + if (conf_parser_ctx.pass == 2) + block_state.modes.value |= UMODE_REGONLY; +} | T_FARCONNECT { - if (ypass == 2) - { - if (yylval.number) - yy_aconf->port |= OPER_FLAG_GLOBAL_KILL; - else - yy_aconf->port &= ~OPER_FLAG_GLOBAL_KILL; - } -}; - -oper_remote: REMOTE '=' TBOOL ';' -{ - if (ypass == 2) - { - if (yylval.number) - yy_aconf->port |= OPER_FLAG_REMOTE; - else - yy_aconf->port &= ~OPER_FLAG_REMOTE; - } -}; - -oper_remoteban: REMOTEBAN '=' TBOOL ';' -{ - if (ypass == 2) - { - if (yylval.number) - yy_aconf->port |= OPER_FLAG_REMOTEBAN; - else - yy_aconf->port &= ~OPER_FLAG_REMOTEBAN; - } -}; - -oper_kline: KLINE '=' TBOOL ';' -{ - if (ypass == 2) - { - if (yylval.number) - yy_aconf->port |= OPER_FLAG_K; - else - yy_aconf->port &= ~OPER_FLAG_K; - } -}; - -oper_xline: XLINE '=' TBOOL ';' -{ - if (ypass == 2) - { - if (yylval.number) - yy_aconf->port |= OPER_FLAG_X; - else - yy_aconf->port &= ~OPER_FLAG_X; - } -}; - -oper_unkline: UNKLINE '=' TBOOL ';' -{ - if (ypass == 2) - { - if (yylval.number) - yy_aconf->port |= OPER_FLAG_UNKLINE; - else - yy_aconf->port &= ~OPER_FLAG_UNKLINE; - } -}; - -oper_gline: GLINE '=' TBOOL ';' -{ - if (ypass == 2) - { - if (yylval.number) - yy_aconf->port |= OPER_FLAG_GLINE; - else - yy_aconf->port &= ~OPER_FLAG_GLINE; - } -}; - -oper_nick_changes: NICK_CHANGES '=' TBOOL ';' -{ - if (ypass == 2) - { - if (yylval.number) - yy_aconf->port |= OPER_FLAG_N; - else - yy_aconf->port &= ~OPER_FLAG_N; - } -}; - -oper_die: DIE '=' TBOOL ';' -{ - if (ypass == 2) - { - if (yylval.number) - yy_aconf->port |= OPER_FLAG_DIE; - else - yy_aconf->port &= ~OPER_FLAG_DIE; - } -}; - -oper_rehash: REHASH '=' TBOOL ';' -{ - if (ypass == 2) - { - if (yylval.number) - yy_aconf->port |= OPER_FLAG_REHASH; - else - yy_aconf->port &= ~OPER_FLAG_REHASH; - } -}; - -oper_admin: ADMIN '=' TBOOL ';' -{ - if (ypass == 2) - { - if (yylval.number) - yy_aconf->port |= OPER_FLAG_ADMIN; - else - yy_aconf->port &= ~OPER_FLAG_ADMIN; - } -}; - -oper_hidden_admin: HIDDEN_ADMIN '=' TBOOL ';' -{ - if (ypass == 2) - { - if (yylval.number) - yy_aconf->port |= OPER_FLAG_HIDDEN_ADMIN; - else - yy_aconf->port &= ~OPER_FLAG_HIDDEN_ADMIN; - } -}; - -oper_hidden_oper: HIDDEN_OPER '=' TBOOL ';' -{ - if (ypass == 2) - { - if (yylval.number) - yy_aconf->port |= OPER_FLAG_HIDDEN_OPER; - else - yy_aconf->port &= ~OPER_FLAG_HIDDEN_OPER; - } -}; - -oper_operwall: T_OPERWALL '=' TBOOL ';' -{ - if (ypass == 2) - { - if (yylval.number) - yy_aconf->port |= OPER_FLAG_OPERWALL; - else - yy_aconf->port &= ~OPER_FLAG_OPERWALL; - } + if (conf_parser_ctx.pass == 2) + block_state.modes.value |= UMODE_FARCONNECT; }; oper_flags: IRCD_FLAGS { + if (conf_parser_ctx.pass == 2) + block_state.port.value = 0; } '=' oper_flags_items ';'; oper_flags_items: oper_flags_items ',' oper_flags_item | oper_flags_item; -oper_flags_item: NOT { not_atom = 1; } oper_flags_item_atom - | { not_atom = 0; } oper_flags_item_atom; - -oper_flags_item_atom: GLOBAL_KILL +oper_flags_item: KILL ':' REMOTE { - if (ypass == 2) - { - if (not_atom)yy_aconf->port &= ~OPER_FLAG_GLOBAL_KILL; - else yy_aconf->port |= OPER_FLAG_GLOBAL_KILL; - } -} | REMOTE + if (conf_parser_ctx.pass == 2) + block_state.port.value |= OPER_FLAG_KILL_REMOTE; +} | KILL +{ + if (conf_parser_ctx.pass == 2) + block_state.port.value |= OPER_FLAG_KILL; +} | CONNECT ':' REMOTE +{ + if (conf_parser_ctx.pass == 2) + block_state.port.value |= OPER_FLAG_CONNECT_REMOTE; +} | CONNECT +{ + if (conf_parser_ctx.pass == 2) + block_state.port.value |= OPER_FLAG_CONNECT; +} | SQUIT ':' REMOTE +{ + if (conf_parser_ctx.pass == 2) + block_state.port.value |= OPER_FLAG_SQUIT_REMOTE; +} | SQUIT { - if (ypass == 2) - { - if (not_atom) yy_aconf->port &= ~OPER_FLAG_REMOTE; - else yy_aconf->port |= OPER_FLAG_REMOTE; - } + if (conf_parser_ctx.pass == 2) + block_state.port.value |= OPER_FLAG_SQUIT; } | KLINE { - if (ypass == 2) - { - if (not_atom) yy_aconf->port &= ~OPER_FLAG_K; - else yy_aconf->port |= OPER_FLAG_K; - } + if (conf_parser_ctx.pass == 2) + block_state.port.value |= OPER_FLAG_KLINE; } | UNKLINE { - if (ypass == 2) - { - if (not_atom) yy_aconf->port &= ~OPER_FLAG_UNKLINE; - else yy_aconf->port |= OPER_FLAG_UNKLINE; - } + if (conf_parser_ctx.pass == 2) + block_state.port.value |= OPER_FLAG_UNKLINE; +} | T_DLINE +{ + if (conf_parser_ctx.pass == 2) + block_state.port.value |= OPER_FLAG_DLINE; +} | T_UNDLINE +{ + if (conf_parser_ctx.pass == 2) + block_state.port.value |= OPER_FLAG_UNDLINE; } | XLINE { - if (ypass == 2) - { - if (not_atom) yy_aconf->port &= ~OPER_FLAG_X; - else yy_aconf->port |= OPER_FLAG_X; - } -} | GLINE + if (conf_parser_ctx.pass == 2) + block_state.port.value |= OPER_FLAG_XLINE; +} | T_UNXLINE { - if (ypass == 2) - { - if (not_atom) yy_aconf->port &= ~OPER_FLAG_GLINE; - else yy_aconf->port |= OPER_FLAG_GLINE; - } + if (conf_parser_ctx.pass == 2) + block_state.port.value |= OPER_FLAG_UNXLINE; } | DIE { - if (ypass == 2) - { - if (not_atom) yy_aconf->port &= ~OPER_FLAG_DIE; - else yy_aconf->port |= OPER_FLAG_DIE; - } + if (conf_parser_ctx.pass == 2) + block_state.port.value |= OPER_FLAG_DIE; +} | T_RESTART +{ + if (conf_parser_ctx.pass == 2) + block_state.port.value |= OPER_FLAG_RESTART; +} | REHASH ':' REMOTE +{ + if (conf_parser_ctx.pass == 2) + block_state.port.value |= OPER_FLAG_REHASH_REMOTE; } | REHASH { - if (ypass == 2) - { - if (not_atom) yy_aconf->port &= ~OPER_FLAG_REHASH; - else yy_aconf->port |= OPER_FLAG_REHASH; - } + if (conf_parser_ctx.pass == 2) + block_state.port.value |= OPER_FLAG_REHASH; } | ADMIN { - if (ypass == 2) - { - if (not_atom) yy_aconf->port &= ~OPER_FLAG_ADMIN; - else yy_aconf->port |= OPER_FLAG_ADMIN; - } -} | HIDDEN_ADMIN + if (conf_parser_ctx.pass == 2) + block_state.port.value |= OPER_FLAG_ADMIN; +} | T_GLOBOPS +{ + if (conf_parser_ctx.pass == 2) + block_state.port.value |= OPER_FLAG_GLOBOPS; +} | T_WALLOPS { - if (ypass == 2) - { - if (not_atom) yy_aconf->port &= ~OPER_FLAG_HIDDEN_ADMIN; - else yy_aconf->port |= OPER_FLAG_HIDDEN_ADMIN; - } -} | NICK_CHANGES + if (conf_parser_ctx.pass == 2) + block_state.port.value |= OPER_FLAG_WALLOPS; +} | T_LOCOPS { - if (ypass == 2) - { - if (not_atom) yy_aconf->port &= ~OPER_FLAG_N; - else yy_aconf->port |= OPER_FLAG_N; - } -} | T_OPERWALL + if (conf_parser_ctx.pass == 2) + block_state.port.value |= OPER_FLAG_LOCOPS; +} | REMOTEBAN { - if (ypass == 2) - { - if (not_atom) yy_aconf->port &= ~OPER_FLAG_OPERWALL; - else yy_aconf->port |= OPER_FLAG_OPERWALL; - } -} | OPER_SPY_T + if (conf_parser_ctx.pass == 2) + block_state.port.value |= OPER_FLAG_REMOTEBAN; +} | T_SET +{ + if (conf_parser_ctx.pass == 2) + block_state.port.value |= OPER_FLAG_SET; +} | MODULE +{ + if (conf_parser_ctx.pass == 2) + block_state.port.value |= OPER_FLAG_MODULE; +} | T_OPME +{ + if (conf_parser_ctx.pass == 2) + block_state.port.value |= OPER_FLAG_OPME; +} | NICK ':' RESV +{ + if (conf_parser_ctx.pass == 2) + block_state.port.value |= OPER_FLAG_NICK_RESV; +} | JOIN ':' RESV { - if (ypass == 2) - { - if (not_atom) yy_aconf->port &= ~OPER_FLAG_OPER_SPY; - else yy_aconf->port |= OPER_FLAG_OPER_SPY; - } -} | HIDDEN_OPER + if (conf_parser_ctx.pass == 2) + block_state.port.value |= OPER_FLAG_JOIN_RESV; +} | RESV { - if (ypass == 2) - { - if (not_atom) yy_aconf->port &= ~OPER_FLAG_HIDDEN_OPER; - else yy_aconf->port |= OPER_FLAG_HIDDEN_OPER; - } -} | REMOTEBAN + if (conf_parser_ctx.pass == 2) + block_state.port.value |= OPER_FLAG_RESV; +} | T_UNRESV { - if (ypass == 2) - { - if (not_atom) yy_aconf->port &= ~OPER_FLAG_REMOTEBAN; - else yy_aconf->port |= OPER_FLAG_REMOTEBAN; - } -} | ENCRYPTED + if (conf_parser_ctx.pass == 2) + block_state.port.value |= OPER_FLAG_UNRESV; +} | CLOSE { - if (ypass == 2) - { - if (not_atom) ClearConfEncrypted(yy_aconf); - else SetConfEncrypted(yy_aconf); - } + if (conf_parser_ctx.pass == 2) + block_state.port.value |= OPER_FLAG_CLOSE; }; /*************************************************************************** - * section class + * class {} section ***************************************************************************/ class_entry: CLASS { - if (ypass == 1) - { - yy_conf = make_conf_item(CLASS_TYPE); - yy_class = map_to_conf(yy_conf); - } -} class_name_b '{' class_items '}' ';' -{ - if (ypass == 1) - { - struct ConfItem *cconf = NULL; - struct ClassItem *class = NULL; - - if (yy_class_name == NULL) - delete_conf_item(yy_conf); - else - { - cconf = find_exact_name_conf(CLASS_TYPE, yy_class_name, NULL, NULL); + if (conf_parser_ctx.pass != 1) + break; - if (cconf != NULL) /* The class existed already */ - { - int user_count = 0; - - rebuild_cidr_class(cconf, yy_class); - - class = map_to_conf(cconf); - - user_count = class->curr_user_count; - memcpy(class, yy_class, sizeof(*class)); - class->curr_user_count = user_count; - class->active = 1; - - delete_conf_item(yy_conf); - - MyFree(cconf->name); /* Allows case change of class name */ - cconf->name = yy_class_name; - } - else /* Brand new class */ - { - MyFree(yy_conf->name); /* just in case it was allocated */ - yy_conf->name = yy_class_name; - yy_class->active = 1; - } - } + reset_block_state(); - yy_class_name = NULL; - } + block_state.ping_freq.value = DEFAULT_PINGFREQUENCY; + block_state.con_freq.value = DEFAULT_CONNECTFREQUENCY; + block_state.max_total.value = MAXIMUM_LINKS_DEFAULT; + block_state.max_sendq.value = DEFAULT_SENDQ; + block_state.max_recvq.value = DEFAULT_RECVQ; +} '{' class_items '}' ';' +{ + struct ClassItem *class = NULL; + + if (conf_parser_ctx.pass != 1) + break; + + if (!block_state.class.buf[0]) + break; + + if (!(class = class_find(block_state.class.buf, 0))) + class = class_make(); + + class->active = 1; + xfree(class->name); + class->name = xstrdup(block_state.class.buf); + class->ping_freq = block_state.ping_freq.value; + class->max_perip = block_state.max_perip.value; + class->con_freq = block_state.con_freq.value; + class->max_total = block_state.max_total.value; + class->max_global = block_state.max_global.value; + class->max_local = block_state.max_local.value; + class->max_sendq = block_state.max_sendq.value; + class->max_recvq = block_state.max_recvq.value; + class->max_channels = block_state.max_channels.value; + + if (block_state.min_idle.value > block_state.max_idle.value) + { + block_state.min_idle.value = 0; + block_state.max_idle.value = 0; + block_state.flags.value &= ~CLASS_FLAGS_FAKE_IDLE; + } + + class->flags = block_state.flags.value; + class->min_idle = block_state.min_idle.value; + class->max_idle = block_state.max_idle.value; + + rebuild_cidr_list(class); + + class->cidr_bitlen_ipv4 = block_state.cidr_bitlen_ipv4.value; + class->cidr_bitlen_ipv6 = block_state.cidr_bitlen_ipv6.value; + class->number_per_cidr = block_state.number_per_cidr.value; }; -class_name_b: | class_name_t; - class_items: class_items class_item | class_item; class_item: class_name | - class_cidr_bitlen_ipv4 | class_cidr_bitlen_ipv6 | + class_cidr_bitlen_ipv4 | + class_cidr_bitlen_ipv6 | class_ping_time | - class_ping_warning | - class_number_per_cidr | + class_number_per_cidr | class_number_per_ip | class_connectfreq | + class_max_channels | class_max_number | - class_max_global | - class_max_local | - class_max_ident | + class_max_global | + class_max_local | class_sendq | - error ';' ; - -class_name: NAME '=' QSTRING ';' -{ - if (ypass == 1) - { - MyFree(yy_class_name); - DupString(yy_class_name, yylval.string); - } -}; + class_recvq | + class_min_idle | + class_max_idle | + class_flags | + error ';' ; -class_name_t: QSTRING +class_name: NAME '=' QSTRING ';' { - if (ypass == 1) - { - MyFree(yy_class_name); - DupString(yy_class_name, yylval.string); - } + if (conf_parser_ctx.pass == 1) + strlcpy(block_state.class.buf, yylval.string, sizeof(block_state.class.buf)); }; class_ping_time: PING_TIME '=' timespec ';' { - if (ypass == 1) - PingFreq(yy_class) = $3; + if (conf_parser_ctx.pass == 1) + block_state.ping_freq.value = $3; }; -class_ping_warning: PING_WARNING '=' timespec ';' +class_number_per_ip: NUMBER_PER_IP '=' NUMBER ';' { - if (ypass == 1) - PingWarning(yy_class) = $3; + if (conf_parser_ctx.pass == 1) + block_state.max_perip.value = $3; }; -class_number_per_ip: NUMBER_PER_IP '=' NUMBER ';' +class_connectfreq: CONNECTFREQ '=' timespec ';' { - if (ypass == 1) - MaxPerIp(yy_class) = $3; + if (conf_parser_ctx.pass == 1) + block_state.con_freq.value = $3; }; -class_connectfreq: CONNECTFREQ '=' timespec ';' +class_max_channels: MAX_CHANNELS '=' NUMBER ';' { - if (ypass == 1) - ConFreq(yy_class) = $3; + if (conf_parser_ctx.pass == 1) + block_state.max_channels.value = $3; }; class_max_number: MAX_NUMBER '=' NUMBER ';' { - if (ypass == 1) - MaxTotal(yy_class) = $3; + if (conf_parser_ctx.pass == 1) + block_state.max_total.value = $3; }; class_max_global: MAX_GLOBAL '=' NUMBER ';' { - if (ypass == 1) - MaxGlobal(yy_class) = $3; + if (conf_parser_ctx.pass == 1) + block_state.max_global.value = $3; }; class_max_local: MAX_LOCAL '=' NUMBER ';' { - if (ypass == 1) - MaxLocal(yy_class) = $3; + if (conf_parser_ctx.pass == 1) + block_state.max_local.value = $3; }; -class_max_ident: MAX_IDENT '=' NUMBER ';' +class_sendq: SENDQ '=' sizespec ';' { - if (ypass == 1) - MaxIdent(yy_class) = $3; + if (conf_parser_ctx.pass == 1) + block_state.max_sendq.value = $3; }; -class_sendq: SENDQ '=' sizespec ';' +class_recvq: T_RECVQ '=' sizespec ';' { - if (ypass == 1) - MaxSendq(yy_class) = $3; + if (conf_parser_ctx.pass == 1) + if ($3 >= CLIENT_FLOOD_MIN && $3 <= CLIENT_FLOOD_MAX) + block_state.max_recvq.value = $3; }; class_cidr_bitlen_ipv4: CIDR_BITLEN_IPV4 '=' NUMBER ';' { - if (ypass == 1) - CidrBitlenIPV4(yy_class) = $3; + if (conf_parser_ctx.pass == 1) + block_state.cidr_bitlen_ipv4.value = $3 > 32 ? 32 : $3; }; class_cidr_bitlen_ipv6: CIDR_BITLEN_IPV6 '=' NUMBER ';' { - if (ypass == 1) - CidrBitlenIPV6(yy_class) = $3; + if (conf_parser_ctx.pass == 1) + block_state.cidr_bitlen_ipv6.value = $3 > 128 ? 128 : $3; }; class_number_per_cidr: NUMBER_PER_CIDR '=' NUMBER ';' { - if (ypass == 1) - NumberPerCidr(yy_class) = $3; + if (conf_parser_ctx.pass == 1) + block_state.number_per_cidr.value = $3; }; +class_min_idle: MIN_IDLE '=' timespec ';' +{ + if (conf_parser_ctx.pass != 1) + break; + + block_state.min_idle.value = $3; + block_state.flags.value |= CLASS_FLAGS_FAKE_IDLE; +}; + +class_max_idle: MAX_IDLE '=' timespec ';' +{ + if (conf_parser_ctx.pass != 1) + break; + + block_state.max_idle.value = $3; + block_state.flags.value |= CLASS_FLAGS_FAKE_IDLE; +}; + +class_flags: IRCD_FLAGS +{ + if (conf_parser_ctx.pass == 1) + block_state.flags.value &= CLASS_FLAGS_FAKE_IDLE; +} '=' class_flags_items ';'; + +class_flags_items: class_flags_items ',' class_flags_item | class_flags_item; +class_flags_item: RANDOM_IDLE +{ + if (conf_parser_ctx.pass == 1) + block_state.flags.value |= CLASS_FLAGS_RANDOM_IDLE; +} | HIDE_IDLE_FROM_OPERS +{ + if (conf_parser_ctx.pass == 1) + block_state.flags.value |= CLASS_FLAGS_HIDE_IDLE_FROM_OPERS; +}; + + /*************************************************************************** - * section listen + * listen {} section ***************************************************************************/ listen_entry: LISTEN { - if (ypass == 2) - { - listener_address = NULL; - listener_flags = 0; - } -} '{' listen_items '}' ';' -{ - if (ypass == 2) - { - MyFree(listener_address); - listener_address = NULL; - } -}; + if (conf_parser_ctx.pass == 2) + reset_block_state(); +} '{' listen_items '}' ';'; listen_flags: IRCD_FLAGS { - listener_flags = 0; + block_state.flags.value = 0; } '=' listen_flags_items ';'; listen_flags_items: listen_flags_items ',' listen_flags_item | listen_flags_item; listen_flags_item: T_SSL { - if (ypass == 2) - listener_flags |= LISTENER_SSL; + if (conf_parser_ctx.pass == 2) + block_state.flags.value |= LISTENER_SSL; } | HIDDEN { - if (ypass == 2) - listener_flags |= LISTENER_HIDDEN; + if (conf_parser_ctx.pass == 2) + block_state.flags.value |= LISTENER_HIDDEN; +} | T_SERVER +{ + if (conf_parser_ctx.pass == 2) + block_state.flags.value |= LISTENER_SERVER; }; listen_items: listen_items listen_item | listen_item; listen_item: listen_port | listen_flags | listen_address | listen_host | error ';'; -listen_port: PORT '=' port_items { listener_flags = 0; } ';'; +listen_port: PORT '=' port_items { block_state.flags.value = 0; } ';'; port_items: port_items ',' port_item | port_item; port_item: NUMBER { - if (ypass == 2) + if (conf_parser_ctx.pass == 2) { - if ((listener_flags & LISTENER_SSL)) -#ifdef HAVE_LIBCRYPTO - if (!ServerInfo.ctx) +#ifndef HAVE_TLS + if (block_state.flags.value & LISTENER_SSL) + { + conf_error_report("TLS not available - port closed"); + break; + } #endif - { - yyerror("SSL not available - port closed"); - break; - } - add_listener($1, listener_address, listener_flags); + listener_add($1, block_state.addr.buf, block_state.flags.value); } } | NUMBER TWODOTS NUMBER { - if (ypass == 2) + if (conf_parser_ctx.pass == 2) { - int i; - - if ((listener_flags & LISTENER_SSL)) -#ifdef HAVE_LIBCRYPTO - if (!ServerInfo.ctx) +#ifndef HAVE_TLS + if (block_state.flags.value & LISTENER_SSL) + { + conf_error_report("TLS not available - port closed"); + break; + } #endif - { - yyerror("SSL not available - port closed"); - break; - } - for (i = $1; i <= $3; ++i) - add_listener(i, listener_address, listener_flags); + for (int i = $1; i <= $3; ++i) + listener_add(i, block_state.addr.buf, block_state.flags.value); } }; listen_address: IP '=' QSTRING ';' { - if (ypass == 2) - { - MyFree(listener_address); - DupString(listener_address, yylval.string); - } + if (conf_parser_ctx.pass == 2) + strlcpy(block_state.addr.buf, yylval.string, sizeof(block_state.addr.buf)); }; listen_host: HOST '=' QSTRING ';' { - if (ypass == 2) - { - MyFree(listener_address); - DupString(listener_address, yylval.string); - } + if (conf_parser_ctx.pass == 2) + strlcpy(block_state.addr.buf, yylval.string, sizeof(block_state.addr.buf)); }; + /*************************************************************************** - * section auth + * auth {} section ***************************************************************************/ auth_entry: IRCD_AUTH { - if (ypass == 2) - { - yy_conf = make_conf_item(CLIENT_TYPE); - yy_aconf = map_to_conf(yy_conf); - } - else - { - MyFree(class_name); - class_name = NULL; - } + if (conf_parser_ctx.pass == 2) + reset_block_state(); } '{' auth_items '}' ';' { - if (ypass == 2) - { - struct CollectItem *yy_tmp = NULL; - dlink_node *ptr = NULL, *next_ptr = NULL; + dlink_node *node = NULL; - if (yy_aconf->user && yy_aconf->host) - { - conf_add_class_to_conf(yy_conf, class_name); - add_conf_by_address(CONF_CLIENT, yy_aconf); - } - else - delete_conf_item(yy_conf); + if (conf_parser_ctx.pass != 2) + break; - /* copy over settings from first struct */ - DLINK_FOREACH_SAFE(ptr, next_ptr, col_conf_list.head) - { - struct AccessItem *new_aconf; - struct ConfItem *new_conf; - - new_conf = make_conf_item(CLIENT_TYPE); - new_aconf = map_to_conf(new_conf); - - yy_tmp = ptr->data; - - assert(yy_tmp->user && yy_tmp->host); - - if (yy_aconf->passwd != NULL) - DupString(new_aconf->passwd, yy_aconf->passwd); - if (yy_conf->name != NULL) - DupString(new_conf->name, yy_conf->name); - if (yy_aconf->passwd != NULL) - DupString(new_aconf->passwd, yy_aconf->passwd); - - new_aconf->flags = yy_aconf->flags; - new_aconf->port = yy_aconf->port; - - DupString(new_aconf->user, yy_tmp->user); - collapse(new_aconf->user); - - DupString(new_aconf->host, yy_tmp->host); - collapse(new_aconf->host); - - conf_add_class_to_conf(new_conf, class_name); - add_conf_by_address(CONF_CLIENT, new_aconf); - dlinkDelete(&yy_tmp->node, &col_conf_list); - free_collect_item(yy_tmp); - } - - MyFree(class_name); - class_name = NULL; - yy_conf = NULL; - yy_aconf = NULL; - } -}; - -auth_items: auth_items auth_item | auth_item; -auth_item: auth_user | auth_passwd | auth_class | auth_flags | - auth_kline_exempt | auth_need_ident | - auth_exceed_limit | auth_no_tilde | auth_gline_exempt | - auth_spoof | auth_spoof_notice | - auth_redir_serv | auth_redir_port | auth_can_flood | - auth_need_password | auth_encrypted | error ';' ; - -auth_user: USER '=' QSTRING ';' -{ - if (ypass == 2) + DLINK_FOREACH(node, block_state.mask.list.head) { - struct CollectItem *yy_tmp = NULL; + struct MaskItem *conf = NULL; struct split_nuh_item nuh; + char *s = node->data; - nuh.nuhmask = yylval.string; - nuh.nickptr = NULL; - nuh.userptr = userbuf; - nuh.hostptr = hostbuf; + if (EmptyString(s)) + continue; + nuh.nuhmask = s; + nuh.nickptr = NULL; + nuh.userptr = block_state.user.buf; + nuh.hostptr = block_state.host.buf; nuh.nicksize = 0; - nuh.usersize = sizeof(userbuf); - nuh.hostsize = sizeof(hostbuf); - + nuh.usersize = sizeof(block_state.user.buf); + nuh.hostsize = sizeof(block_state.host.buf); split_nuh(&nuh); - if (yy_aconf->user == NULL) - { - DupString(yy_aconf->user, userbuf); - DupString(yy_aconf->host, hostbuf); - } - else - { - yy_tmp = MyMalloc(sizeof(struct CollectItem)); + conf = conf_make(CONF_CLIENT); + conf->user = xstrdup(block_state.user.buf); + conf->host = xstrdup(block_state.host.buf); + + if (block_state.rpass.buf[0]) + conf->passwd = xstrdup(block_state.rpass.buf); + if (block_state.name.buf[0]) + conf->name = xstrdup(block_state.name.buf); - DupString(yy_tmp->user, userbuf); - DupString(yy_tmp->host, hostbuf); + conf->flags = block_state.flags.value; + conf->port = block_state.port.value; - dlinkAdd(yy_tmp, &yy_tmp->node, &col_conf_list); - } + conf_add_class_to_conf(conf, block_state.class.buf); + add_conf_by_address(CONF_CLIENT, conf); } }; -/* XXX - IP/IPV6 tags don't exist anymore - put IP/IPV6 into user. */ +auth_items: auth_items auth_item | auth_item; +auth_item: auth_user | + auth_passwd | + auth_class | + auth_flags | + auth_spoof | + auth_redir_serv | + auth_redir_port | + auth_encrypted | + error ';' ; -auth_passwd: PASSWORD '=' QSTRING ';' +auth_user: USER '=' QSTRING ';' { - if (ypass == 2) - { - /* be paranoid */ - if (yy_aconf->passwd != NULL) - memset(yy_aconf->passwd, 0, strlen(yy_aconf->passwd)); - - MyFree(yy_aconf->passwd); - DupString(yy_aconf->passwd, yylval.string); - } + if (conf_parser_ctx.pass == 2) + dlinkAdd(xstrdup(yylval.string), make_dlink_node(), &block_state.mask.list); }; -auth_spoof_notice: SPOOF_NOTICE '=' TBOOL ';' +auth_passwd: PASSWORD '=' QSTRING ';' { - if (ypass == 2) - { - if (yylval.number) - yy_aconf->flags |= CONF_FLAGS_SPOOF_NOTICE; - else - yy_aconf->flags &= ~CONF_FLAGS_SPOOF_NOTICE; - } + if (conf_parser_ctx.pass == 2) + strlcpy(block_state.rpass.buf, yylval.string, sizeof(block_state.rpass.buf)); }; auth_class: CLASS '=' QSTRING ';' { - if (ypass == 2) - { - MyFree(class_name); - DupString(class_name, yylval.string); - } + if (conf_parser_ctx.pass == 2) + strlcpy(block_state.class.buf, yylval.string, sizeof(block_state.class.buf)); }; auth_encrypted: ENCRYPTED '=' TBOOL ';' { - if (ypass == 2) + if (conf_parser_ctx.pass == 2) { if (yylval.number) - SetConfEncrypted(yy_aconf); + block_state.flags.value |= CONF_FLAGS_ENCRYPTED; else - ClearConfEncrypted(yy_aconf); + block_state.flags.value &= ~CONF_FLAGS_ENCRYPTED; } }; auth_flags: IRCD_FLAGS { + if (conf_parser_ctx.pass == 2) + block_state.flags.value &= (CONF_FLAGS_ENCRYPTED | CONF_FLAGS_SPOOF_IP); } '=' auth_flags_items ';'; auth_flags_items: auth_flags_items ',' auth_flags_item | auth_flags_item; -auth_flags_item: NOT { not_atom = 1; } auth_flags_item_atom - | { not_atom = 0; } auth_flags_item_atom; - -auth_flags_item_atom: SPOOF_NOTICE +auth_flags_item: SPOOF_NOTICE { - if (ypass == 2) - { - if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_SPOOF_NOTICE; - else yy_aconf->flags |= CONF_FLAGS_SPOOF_NOTICE; - } - + if (conf_parser_ctx.pass == 2) + block_state.flags.value |= CONF_FLAGS_SPOOF_NOTICE; } | EXCEED_LIMIT { - if (ypass == 2) - { - if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_NOLIMIT; - else yy_aconf->flags |= CONF_FLAGS_NOLIMIT; - } + if (conf_parser_ctx.pass == 2) + block_state.flags.value |= CONF_FLAGS_NOLIMIT; } | KLINE_EXEMPT { - if (ypass == 2) - { - if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_EXEMPTKLINE; - else yy_aconf->flags |= CONF_FLAGS_EXEMPTKLINE; - } + if (conf_parser_ctx.pass == 2) + block_state.flags.value |= CONF_FLAGS_EXEMPTKLINE; +} | XLINE_EXEMPT +{ + if (conf_parser_ctx.pass == 2) + block_state.flags.value |= CONF_FLAGS_EXEMPTXLINE; } | NEED_IDENT { - if (ypass == 2) - { - if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_NEED_IDENTD; - else yy_aconf->flags |= CONF_FLAGS_NEED_IDENTD; - } + if (conf_parser_ctx.pass == 2) + block_state.flags.value |= CONF_FLAGS_NEED_IDENTD; } | CAN_FLOOD { - if (ypass == 2) - { - if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_CAN_FLOOD; - else yy_aconf->flags |= CONF_FLAGS_CAN_FLOOD; - } -} | CAN_IDLE -{ - if (ypass == 2) - { - if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_IDLE_LINED; - else yy_aconf->flags |= CONF_FLAGS_IDLE_LINED; - } + if (conf_parser_ctx.pass == 2) + block_state.flags.value |= CONF_FLAGS_CAN_FLOOD; } | NO_TILDE { - if (ypass == 2) - { - if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_NO_TILDE; - else yy_aconf->flags |= CONF_FLAGS_NO_TILDE; - } -} | GLINE_EXEMPT -{ - if (ypass == 2) - { - if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_EXEMPTGLINE; - else yy_aconf->flags |= CONF_FLAGS_EXEMPTGLINE; - } + if (conf_parser_ctx.pass == 2) + block_state.flags.value |= CONF_FLAGS_NO_TILDE; } | RESV_EXEMPT { - if (ypass == 2) - { - if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_EXEMPTRESV; - else yy_aconf->flags |= CONF_FLAGS_EXEMPTRESV; - } + if (conf_parser_ctx.pass == 2) + block_state.flags.value |= CONF_FLAGS_EXEMPTRESV; +} | T_WEBIRC +{ + if (conf_parser_ctx.pass == 2) + block_state.flags.value |= CONF_FLAGS_WEBIRC; } | NEED_PASSWORD { - if (ypass == 2) - { - if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_NEED_PASSWORD; - else yy_aconf->flags |= CONF_FLAGS_NEED_PASSWORD; - } + if (conf_parser_ctx.pass == 2) + block_state.flags.value |= CONF_FLAGS_NEED_PASSWORD; }; -auth_kline_exempt: KLINE_EXEMPT '=' TBOOL ';' +auth_spoof: SPOOF '=' QSTRING ';' { - if (ypass == 2) - { - if (yylval.number) - yy_aconf->flags |= CONF_FLAGS_EXEMPTKLINE; - else - yy_aconf->flags &= ~CONF_FLAGS_EXEMPTKLINE; - } -}; + if (conf_parser_ctx.pass != 2) + break; -auth_need_ident: NEED_IDENT '=' TBOOL ';' -{ - if (ypass == 2) + if (valid_hostname(yylval.string)) { - if (yylval.number) - yy_aconf->flags |= CONF_FLAGS_NEED_IDENTD; - else - yy_aconf->flags &= ~CONF_FLAGS_NEED_IDENTD; + strlcpy(block_state.name.buf, yylval.string, sizeof(block_state.name.buf)); + block_state.flags.value |= CONF_FLAGS_SPOOF_IP; } + else + ilog(LOG_TYPE_IRCD, "Spoof either is too long or contains invalid characters. Ignoring it."); }; -auth_exceed_limit: EXCEED_LIMIT '=' TBOOL ';' +auth_redir_serv: REDIRSERV '=' QSTRING ';' { - if (ypass == 2) - { - if (yylval.number) - yy_aconf->flags |= CONF_FLAGS_NOLIMIT; - else - yy_aconf->flags &= ~CONF_FLAGS_NOLIMIT; - } -}; + if (conf_parser_ctx.pass != 2) + break; -auth_can_flood: CAN_FLOOD '=' TBOOL ';' -{ - if (ypass == 2) - { - if (yylval.number) - yy_aconf->flags |= CONF_FLAGS_CAN_FLOOD; - else - yy_aconf->flags &= ~CONF_FLAGS_CAN_FLOOD; - } + strlcpy(block_state.name.buf, yylval.string, sizeof(block_state.name.buf)); + block_state.flags.value |= CONF_FLAGS_REDIR; }; -auth_no_tilde: NO_TILDE '=' TBOOL ';' +auth_redir_port: REDIRPORT '=' NUMBER ';' { - if (ypass == 2) - { - if (yylval.number) - yy_aconf->flags |= CONF_FLAGS_NO_TILDE; - else - yy_aconf->flags &= ~CONF_FLAGS_NO_TILDE; - } + if (conf_parser_ctx.pass != 2) + break; + + block_state.flags.value |= CONF_FLAGS_REDIR; + block_state.port.value = $3; }; -auth_gline_exempt: GLINE_EXEMPT '=' TBOOL ';' + +/*************************************************************************** + * resv {} section + ***************************************************************************/ +resv_entry: RESV { - if (ypass == 2) - { - if (yylval.number) - yy_aconf->flags |= CONF_FLAGS_EXEMPTGLINE; - else - yy_aconf->flags &= ~CONF_FLAGS_EXEMPTGLINE; - } -}; + if (conf_parser_ctx.pass != 2) + break; -/* XXX - need check for illegal hostnames here */ -auth_spoof: SPOOF '=' QSTRING ';' + reset_block_state(); + strlcpy(block_state.rpass.buf, CONF_NOREASON, sizeof(block_state.rpass.buf)); +} '{' resv_items '}' ';' { - if (ypass == 2) - { - MyFree(yy_conf->name); + if (conf_parser_ctx.pass != 2) + break; - if (strlen(yylval.string) < HOSTLEN) - { - DupString(yy_conf->name, yylval.string); - yy_aconf->flags |= CONF_FLAGS_SPOOF_IP; - } - else - { - ilog(L_ERROR, "Spoofs must be less than %d..ignoring it", HOSTLEN); - yy_conf->name = NULL; - } - } + resv_make(block_state.name.buf, block_state.rpass.buf, &block_state.mask.list); }; -auth_redir_serv: REDIRSERV '=' QSTRING ';' +resv_items: resv_items resv_item | resv_item; +resv_item: resv_mask | resv_reason | resv_exempt | error ';' ; + +resv_mask: MASK '=' QSTRING ';' { - if (ypass == 2) - { - yy_aconf->flags |= CONF_FLAGS_REDIR; - MyFree(yy_conf->name); - DupString(yy_conf->name, yylval.string); - } + if (conf_parser_ctx.pass == 2) + strlcpy(block_state.name.buf, yylval.string, sizeof(block_state.name.buf)); }; -auth_redir_port: REDIRPORT '=' NUMBER ';' +resv_reason: REASON '=' QSTRING ';' { - if (ypass == 2) - { - yy_aconf->flags |= CONF_FLAGS_REDIR; - yy_aconf->port = $3; - } + if (conf_parser_ctx.pass == 2) + strlcpy(block_state.rpass.buf, yylval.string, sizeof(block_state.rpass.buf)); }; -auth_need_password: NEED_PASSWORD '=' TBOOL ';' +resv_exempt: EXEMPT '=' QSTRING ';' { - if (ypass == 2) - { - if (yylval.number) - yy_aconf->flags |= CONF_FLAGS_NEED_PASSWORD; - else - yy_aconf->flags &= ~CONF_FLAGS_NEED_PASSWORD; - } + if (conf_parser_ctx.pass == 2) + dlinkAdd(xstrdup(yylval.string), make_dlink_node(), &block_state.mask.list); }; /*************************************************************************** - * section resv + * service {} section ***************************************************************************/ -resv_entry: RESV -{ - if (ypass == 2) - { - MyFree(resv_reason); - resv_reason = NULL; - } -} '{' resv_items '}' ';' -{ - if (ypass == 2) - { - MyFree(resv_reason); - resv_reason = NULL; - } -}; +service_entry: T_SERVICE '{' service_items '}' ';'; -resv_items: resv_items resv_item | resv_item; -resv_item: resv_creason | resv_channel | resv_nick | error ';' ; +service_items: service_items service_item | service_item; +service_item: service_name | error; -resv_creason: REASON '=' QSTRING ';' +service_name: NAME '=' QSTRING ';' { - if (ypass == 2) - { - MyFree(resv_reason); - DupString(resv_reason, yylval.string); - } -}; + if (conf_parser_ctx.pass != 2) + break; -resv_channel: CHANNEL '=' QSTRING ';' -{ - if (ypass == 2) + if (valid_servname(yylval.string)) { - if (IsChanPrefix(*yylval.string)) - { - char def_reason[] = "No reason"; - - create_channel_resv(yylval.string, resv_reason != NULL ? resv_reason : def_reason, 1); - } + struct ServiceItem *service = service_make(); + service->name = xstrdup(yylval.string); } - /* ignore it for now.. but we really should make a warning if - * its an erroneous name --fl_ */ }; -resv_nick: NICK '=' QSTRING ';' -{ - if (ypass == 2) - { - char def_reason[] = "No reason"; - - create_nick_resv(yylval.string, resv_reason != NULL ? resv_reason : def_reason, 1); - } -}; /*************************************************************************** - * section shared, for sharing remote klines etc. + * shared {} section, for sharing remote klines etc. ***************************************************************************/ shared_entry: T_SHARED { - if (ypass == 2) - { - yy_conf = make_conf_item(ULINE_TYPE); - yy_match_item = map_to_conf(yy_conf); - yy_match_item->action = SHARED_ALL; - } + if (conf_parser_ctx.pass != 2) + break; + + reset_block_state(); + + strlcpy(block_state.name.buf, "*", sizeof(block_state.name.buf)); + strlcpy(block_state.user.buf, "*", sizeof(block_state.user.buf)); + strlcpy(block_state.host.buf, "*", sizeof(block_state.host.buf)); + block_state.flags.value = SHARED_ALL; } '{' shared_items '}' ';' { - if (ypass == 2) - { - yy_conf = NULL; - } + if (conf_parser_ctx.pass != 2) + break; + + struct SharedItem *shared = shared_make(); + shared->type = block_state.flags.value; + shared->server = xstrdup(block_state.name.buf); + shared->user = xstrdup(block_state.user.buf); + shared->host = xstrdup(block_state.host.buf); }; shared_items: shared_items shared_item | shared_item; @@ -2233,1643 +1911,1015 @@ shared_item: shared_name | shared_user shared_name: NAME '=' QSTRING ';' { - if (ypass == 2) - { - MyFree(yy_conf->name); - DupString(yy_conf->name, yylval.string); - } + if (conf_parser_ctx.pass == 2) + strlcpy(block_state.name.buf, yylval.string, sizeof(block_state.name.buf)); }; shared_user: USER '=' QSTRING ';' { - if (ypass == 2) + if (conf_parser_ctx.pass == 2) { struct split_nuh_item nuh; nuh.nuhmask = yylval.string; nuh.nickptr = NULL; - nuh.userptr = userbuf; - nuh.hostptr = hostbuf; + nuh.userptr = block_state.user.buf; + nuh.hostptr = block_state.host.buf; nuh.nicksize = 0; - nuh.usersize = sizeof(userbuf); - nuh.hostsize = sizeof(hostbuf); + nuh.usersize = sizeof(block_state.user.buf); + nuh.hostsize = sizeof(block_state.host.buf); split_nuh(&nuh); - - DupString(yy_match_item->user, userbuf); - DupString(yy_match_item->host, hostbuf); } }; shared_type: TYPE { - if (ypass == 2) - yy_match_item->action = 0; + if (conf_parser_ctx.pass == 2) + block_state.flags.value = 0; } '=' shared_types ';' ; shared_types: shared_types ',' shared_type_item | shared_type_item; shared_type_item: KLINE { - if (ypass == 2) - yy_match_item->action |= SHARED_KLINE; -} | TKLINE -{ - if (ypass == 2) - yy_match_item->action |= SHARED_TKLINE; + if (conf_parser_ctx.pass == 2) + block_state.flags.value |= SHARED_KLINE; } | UNKLINE { - if (ypass == 2) - yy_match_item->action |= SHARED_UNKLINE; -} | XLINE + if (conf_parser_ctx.pass == 2) + block_state.flags.value |= SHARED_UNKLINE; +} | T_DLINE +{ + if (conf_parser_ctx.pass == 2) + block_state.flags.value |= SHARED_DLINE; +} | T_UNDLINE { - if (ypass == 2) - yy_match_item->action |= SHARED_XLINE; -} | TXLINE + if (conf_parser_ctx.pass == 2) + block_state.flags.value |= SHARED_UNDLINE; +} | XLINE { - if (ypass == 2) - yy_match_item->action |= SHARED_TXLINE; + if (conf_parser_ctx.pass == 2) + block_state.flags.value |= SHARED_XLINE; } | T_UNXLINE { - if (ypass == 2) - yy_match_item->action |= SHARED_UNXLINE; + if (conf_parser_ctx.pass == 2) + block_state.flags.value |= SHARED_UNXLINE; } | RESV { - if (ypass == 2) - yy_match_item->action |= SHARED_RESV; -} | TRESV -{ - if (ypass == 2) - yy_match_item->action |= SHARED_TRESV; + if (conf_parser_ctx.pass == 2) + block_state.flags.value |= SHARED_RESV; } | T_UNRESV { - if (ypass == 2) - yy_match_item->action |= SHARED_UNRESV; + if (conf_parser_ctx.pass == 2) + block_state.flags.value |= SHARED_UNRESV; } | T_LOCOPS { - if (ypass == 2) - yy_match_item->action |= SHARED_LOCOPS; + if (conf_parser_ctx.pass == 2) + block_state.flags.value |= SHARED_LOCOPS; } | T_ALL { - if (ypass == 2) - yy_match_item->action = SHARED_ALL; + if (conf_parser_ctx.pass == 2) + block_state.flags.value = SHARED_ALL; }; + /*************************************************************************** - * section cluster + * cluster {} section ***************************************************************************/ cluster_entry: T_CLUSTER { - if (ypass == 2) - { - yy_conf = make_conf_item(CLUSTER_TYPE); - yy_conf->flags = SHARED_ALL; - } + if (conf_parser_ctx.pass != 2) + break; + + reset_block_state(); + + strlcpy(block_state.name.buf, "*", sizeof(block_state.name.buf)); + block_state.flags.value = CLUSTER_ALL; } '{' cluster_items '}' ';' { - if (ypass == 2) - { - if (yy_conf->name == NULL) - DupString(yy_conf->name, "*"); - yy_conf = NULL; - } + if (conf_parser_ctx.pass != 2) + break; + + struct ClusterItem *cluster = cluster_make(); + cluster->type = block_state.flags.value; + cluster->server = xstrdup(block_state.name.buf); }; -cluster_items: cluster_items cluster_item | cluster_item; -cluster_item: cluster_name | cluster_type | error ';' ; +cluster_items: cluster_items cluster_item | cluster_item; +cluster_item: cluster_name | cluster_type | error ';' ; cluster_name: NAME '=' QSTRING ';' { - if (ypass == 2) - DupString(yy_conf->name, yylval.string); + if (conf_parser_ctx.pass == 2) + strlcpy(block_state.name.buf, yylval.string, sizeof(block_state.name.buf)); }; cluster_type: TYPE { - if (ypass == 2) - yy_conf->flags = 0; + if (conf_parser_ctx.pass == 2) + block_state.flags.value = 0; } '=' cluster_types ';' ; -cluster_types: cluster_types ',' cluster_type_item | cluster_type_item; +cluster_types: cluster_types ',' cluster_type_item | cluster_type_item; cluster_type_item: KLINE { - if (ypass == 2) - yy_conf->flags |= SHARED_KLINE; -} | TKLINE -{ - if (ypass == 2) - yy_conf->flags |= SHARED_TKLINE; + if (conf_parser_ctx.pass == 2) + block_state.flags.value |= CLUSTER_KLINE; } | UNKLINE { - if (ypass == 2) - yy_conf->flags |= SHARED_UNKLINE; -} | XLINE + if (conf_parser_ctx.pass == 2) + block_state.flags.value |= CLUSTER_UNKLINE; +} | T_DLINE +{ + if (conf_parser_ctx.pass == 2) + block_state.flags.value |= CLUSTER_DLINE; +} | T_UNDLINE { - if (ypass == 2) - yy_conf->flags |= SHARED_XLINE; -} | TXLINE + if (conf_parser_ctx.pass == 2) + block_state.flags.value |= CLUSTER_UNDLINE; +} | XLINE { - if (ypass == 2) - yy_conf->flags |= SHARED_TXLINE; + if (conf_parser_ctx.pass == 2) + block_state.flags.value |= CLUSTER_XLINE; } | T_UNXLINE { - if (ypass == 2) - yy_conf->flags |= SHARED_UNXLINE; + if (conf_parser_ctx.pass == 2) + block_state.flags.value |= CLUSTER_UNXLINE; } | RESV { - if (ypass == 2) - yy_conf->flags |= SHARED_RESV; -} | TRESV -{ - if (ypass == 2) - yy_conf->flags |= SHARED_TRESV; + if (conf_parser_ctx.pass == 2) + block_state.flags.value |= CLUSTER_RESV; } | T_UNRESV { - if (ypass == 2) - yy_conf->flags |= SHARED_UNRESV; + if (conf_parser_ctx.pass == 2) + block_state.flags.value |= CLUSTER_UNRESV; } | T_LOCOPS { - if (ypass == 2) - yy_conf->flags |= SHARED_LOCOPS; + if (conf_parser_ctx.pass == 2) + block_state.flags.value |= CLUSTER_LOCOPS; } | T_ALL { - if (ypass == 2) - yy_conf->flags = SHARED_ALL; + if (conf_parser_ctx.pass == 2) + block_state.flags.value = CLUSTER_ALL; }; + /*************************************************************************** - * section connect + * connect {} section ***************************************************************************/ -connect_entry: CONNECT +connect_entry: CONNECT { - if (ypass == 2) - { - yy_conf = make_conf_item(SERVER_TYPE); - yy_aconf = (struct AccessItem *)map_to_conf(yy_conf); - yy_aconf->passwd = NULL; - /* defaults */ - yy_aconf->port = PORTNUM; - if (ConfigFileEntry.burst_away) - yy_aconf->flags = CONF_FLAGS_BURST_AWAY; - } - else - { - MyFree(class_name); - class_name = NULL; - } -} connect_name_b '{' connect_items '}' ';' + if (conf_parser_ctx.pass != 2) + break; + + reset_block_state(); + block_state.aftype.value = AF_INET; + block_state.port.value = PORTNUM; +} '{' connect_items '}' ';' { - if (ypass == 2) - { - struct CollectItem *yy_hconf=NULL; - struct CollectItem *yy_lconf=NULL; - dlink_node *ptr; - dlink_node *next_ptr; -#ifdef HAVE_LIBCRYPTO - if (yy_aconf->host && - ((yy_aconf->passwd && yy_aconf->spasswd) || - (yy_aconf->rsa_public_key && IsConfCryptLink(yy_aconf)))) -#else /* !HAVE_LIBCRYPTO */ - if (yy_aconf->host && !IsConfCryptLink(yy_aconf) && - yy_aconf->passwd && yy_aconf->spasswd) -#endif /* !HAVE_LIBCRYPTO */ - { - if (conf_add_server(yy_conf, class_name) == -1) - { - delete_conf_item(yy_conf); - yy_conf = NULL; - yy_aconf = NULL; - } - } - else - { - /* Even if yy_conf ->name is NULL - * should still unhook any hub/leaf confs still pending - */ - unhook_hub_leaf_confs(); - - if (yy_conf->name != NULL) - { -#ifndef HAVE_LIBCRYPTO - if (IsConfCryptLink(yy_aconf)) - yyerror("Ignoring connect block -- no OpenSSL support"); -#else - if (IsConfCryptLink(yy_aconf) && !yy_aconf->rsa_public_key) - yyerror("Ignoring connect block -- missing key"); -#endif - if (yy_aconf->host == NULL) - yyerror("Ignoring connect block -- missing host"); - else if (!IsConfCryptLink(yy_aconf) && - (!yy_aconf->passwd || !yy_aconf->spasswd)) - yyerror("Ignoring connect block -- missing password"); - } - - - /* XXX - * This fixes a try_connections() core (caused by invalid class_ptr - * pointers) reported by metalrock. That's an ugly fix, but there - * is currently no better way. The entire config subsystem needs an - * rewrite ASAP. make_conf_item() shouldn't really add things onto - * a doubly linked list immediately without any sanity checks! -Michael - */ - delete_conf_item(yy_conf); - - yy_aconf = NULL; - yy_conf = NULL; - } - - /* - * yy_conf is still pointing at the server that is having - * a connect block built for it. This means, y_aconf->name - * points to the actual irc name this server will be known as. - * Now this new server has a set or even just one hub_mask (or leaf_mask) - * given in the link list at yy_hconf. Fill in the HUB confs - * from this link list now. - */ - DLINK_FOREACH_SAFE(ptr, next_ptr, hub_conf_list.head) - { - struct ConfItem *new_hub_conf; - struct MatchItem *match_item; - - yy_hconf = ptr->data; - - /* yy_conf == NULL is a fatal error for this connect block! */ - if ((yy_conf != NULL) && (yy_conf->name != NULL)) - { - new_hub_conf = make_conf_item(HUB_TYPE); - match_item = (struct MatchItem *)map_to_conf(new_hub_conf); - DupString(new_hub_conf->name, yy_conf->name); - if (yy_hconf->user != NULL) - DupString(match_item->user, yy_hconf->user); - else - DupString(match_item->user, "*"); - if (yy_hconf->host != NULL) - DupString(match_item->host, yy_hconf->host); - else - DupString(match_item->host, "*"); - } - dlinkDelete(&yy_hconf->node, &hub_conf_list); - free_collect_item(yy_hconf); - } - - /* Ditto for the LEAF confs */ - - DLINK_FOREACH_SAFE(ptr, next_ptr, leaf_conf_list.head) - { - struct ConfItem *new_leaf_conf; - struct MatchItem *match_item; - - yy_lconf = ptr->data; - - if ((yy_conf != NULL) && (yy_conf->name != NULL)) - { - new_leaf_conf = make_conf_item(LEAF_TYPE); - match_item = (struct MatchItem *)map_to_conf(new_leaf_conf); - DupString(new_leaf_conf->name, yy_conf->name); - if (yy_lconf->user != NULL) - DupString(match_item->user, yy_lconf->user); - else - DupString(match_item->user, "*"); - if (yy_lconf->host != NULL) - DupString(match_item->host, yy_lconf->host); - else - DupString(match_item->host, "*"); - } - dlinkDelete(&yy_lconf->node, &leaf_conf_list); - free_collect_item(yy_lconf); - } - MyFree(class_name); - class_name = NULL; - yy_conf = NULL; - yy_aconf = NULL; - } -}; + struct MaskItem *conf = NULL; + struct addrinfo hints, *res; -connect_name_b: | connect_name_t; -connect_items: connect_items connect_item | connect_item; -connect_item: connect_name | connect_host | connect_vhost | - connect_send_password | connect_accept_password | - connect_aftype | connect_port | - connect_fakename | connect_flags | connect_hub_mask | - connect_leaf_mask | connect_class | connect_auto | - connect_encrypted | connect_compressed | connect_cryptlink | - connect_rsa_public_key_file | connect_cipher_preference | - connect_topicburst | error ';' ; + if (conf_parser_ctx.pass != 2) + break; -connect_name: NAME '=' QSTRING ';' -{ - if (ypass == 2) - { - if (yy_conf->name != NULL) - yyerror("Multiple connect name entry"); + if (!block_state.name.buf[0] || + !block_state.host.buf[0]) + break; - MyFree(yy_conf->name); - DupString(yy_conf->name, yylval.string); - } -}; + if (!block_state.rpass.buf[0] || + !block_state.spass.buf[0]) + break; -connect_name_t: QSTRING -{ - if (ypass == 2) - { - if (yy_conf->name != NULL) - yyerror("Multiple connect name entry"); + if (has_wildcards(block_state.name.buf) || + has_wildcards(block_state.host.buf)) + break; - MyFree(yy_conf->name); - DupString(yy_conf->name, yylval.string); - } -}; + conf = conf_make(CONF_SERVER); + conf->port = block_state.port.value; + conf->flags = block_state.flags.value; + conf->aftype = block_state.aftype.value; + conf->host = xstrdup(block_state.host.buf); + conf->name = xstrdup(block_state.name.buf); + conf->passwd = xstrdup(block_state.rpass.buf); + conf->spasswd = xstrdup(block_state.spass.buf); -connect_host: HOST '=' QSTRING ';' -{ - if (ypass == 2) - { - MyFree(yy_aconf->host); - DupString(yy_aconf->host, yylval.string); - } -}; + if (block_state.cert.buf[0]) + conf->certfp = xstrdup(block_state.cert.buf); -connect_vhost: VHOST '=' QSTRING ';' -{ - if (ypass == 2) - { - struct addrinfo hints, *res; + if (block_state.ciph.buf[0]) + conf->cipher_list = xstrdup(block_state.ciph.buf); + + dlinkMoveList(&block_state.leaf.list, &conf->leaf_list); + dlinkMoveList(&block_state.hub.list, &conf->hub_list); + if (block_state.bind.buf[0]) + { memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; - if (irc_getaddrinfo(yylval.string, NULL, &hints, &res)) - ilog(L_ERROR, "Invalid netmask for server vhost(%s)", yylval.string); + if (getaddrinfo(block_state.bind.buf, NULL, &hints, &res)) + ilog(LOG_TYPE_IRCD, "Invalid netmask for server vhost(%s)", block_state.bind.buf); else { - assert(res != NULL); + assert(res); - memcpy(&yy_aconf->my_ipnum, res->ai_addr, res->ai_addrlen); - yy_aconf->my_ipnum.ss.ss_family = res->ai_family; - yy_aconf->my_ipnum.ss_len = res->ai_addrlen; - irc_freeaddrinfo(res); + memcpy(&conf->bind, res->ai_addr, res->ai_addrlen); + conf->bind.ss.ss_family = res->ai_family; + conf->bind.ss_len = res->ai_addrlen; + freeaddrinfo(res); } } -}; - -connect_send_password: SEND_PASSWORD '=' QSTRING ';' -{ - if (ypass == 2) - { - if ($3[0] == ':') - yyerror("Server passwords cannot begin with a colon"); - else if (strchr($3, ' ') != NULL) - yyerror("Server passwords cannot contain spaces"); - else { - if (yy_aconf->spasswd != NULL) - memset(yy_aconf->spasswd, 0, strlen(yy_aconf->spasswd)); - MyFree(yy_aconf->spasswd); - DupString(yy_aconf->spasswd, yylval.string); - } - } + conf_add_class_to_conf(conf, block_state.class.buf); + lookup_confhost(conf); }; -connect_accept_password: ACCEPT_PASSWORD '=' QSTRING ';' -{ - if (ypass == 2) - { - if ($3[0] == ':') - yyerror("Server passwords cannot begin with a colon"); - else if (strchr($3, ' ') != NULL) - yyerror("Server passwords cannot contain spaces"); - else { - if (yy_aconf->passwd != NULL) - memset(yy_aconf->passwd, 0, strlen(yy_aconf->passwd)); - - MyFree(yy_aconf->passwd); - DupString(yy_aconf->passwd, yylval.string); - } - } -}; +connect_items: connect_items connect_item | connect_item; +connect_item: connect_name | + connect_host | + connect_vhost | + connect_send_password | + connect_accept_password | + connect_ssl_certificate_fingerprint | + connect_aftype | + connect_port | + connect_ssl_cipher_list | + connect_flags | + connect_hub_mask | + connect_leaf_mask | + connect_class | + connect_encrypted | + error ';' ; -connect_port: PORT '=' NUMBER ';' +connect_name: NAME '=' QSTRING ';' { - if (ypass == 2) - yy_aconf->port = $3; + if (conf_parser_ctx.pass == 2) + strlcpy(block_state.name.buf, yylval.string, sizeof(block_state.name.buf)); }; -connect_aftype: AFTYPE '=' T_IPV4 ';' +connect_host: HOST '=' QSTRING ';' { - if (ypass == 2) - yy_aconf->aftype = AF_INET; -} | AFTYPE '=' T_IPV6 ';' -{ -#ifdef IPV6 - if (ypass == 2) - yy_aconf->aftype = AF_INET6; -#endif + if (conf_parser_ctx.pass == 2) + strlcpy(block_state.host.buf, yylval.string, sizeof(block_state.host.buf)); }; -connect_fakename: FAKENAME '=' QSTRING ';' +connect_vhost: VHOST '=' QSTRING ';' { - if (ypass == 2) - { - MyFree(yy_aconf->fakename); - DupString(yy_aconf->fakename, yylval.string); - } + if (conf_parser_ctx.pass == 2) + strlcpy(block_state.bind.buf, yylval.string, sizeof(block_state.bind.buf)); }; -connect_flags: IRCD_FLAGS +connect_send_password: SEND_PASSWORD '=' QSTRING ';' { -} '=' connect_flags_items ';'; + if (conf_parser_ctx.pass != 2) + break; -connect_flags_items: connect_flags_items ',' connect_flags_item | connect_flags_item; -connect_flags_item: NOT { not_atom = 1; } connect_flags_item_atom - | { not_atom = 0; } connect_flags_item_atom; - -connect_flags_item_atom: LAZYLINK -{ - if (ypass == 2) - { - if (not_atom)ClearConfLazyLink(yy_aconf); - else SetConfLazyLink(yy_aconf); - } -} | COMPRESSED -{ - if (ypass == 2) -#ifndef HAVE_LIBZ - yyerror("Ignoring flags = compressed; -- no zlib support"); -#else - { - if (not_atom)ClearConfCompressed(yy_aconf); - else SetConfCompressed(yy_aconf); - } -#endif -} | CRYPTLINK -{ - if (ypass == 2) - { - if (not_atom)ClearConfCryptLink(yy_aconf); - else SetConfCryptLink(yy_aconf); - } -} | AUTOCONN -{ - if (ypass == 2) - { - if (not_atom)ClearConfAllowAutoConn(yy_aconf); - else SetConfAllowAutoConn(yy_aconf); - } -} | BURST_AWAY -{ - if (ypass == 2) - { - if (not_atom)ClearConfAwayBurst(yy_aconf); - else SetConfAwayBurst(yy_aconf); - } -} | TOPICBURST -{ - if (ypass == 2) - { - if (not_atom)ClearConfTopicBurst(yy_aconf); - else SetConfTopicBurst(yy_aconf); - } -} -; + if ($3[0] == ':') + conf_error_report("Server passwords cannot begin with a colon"); + else if (strchr($3, ' ')) + conf_error_report("Server passwords cannot contain spaces"); + else + strlcpy(block_state.spass.buf, yylval.string, sizeof(block_state.spass.buf)); +}; -connect_rsa_public_key_file: RSA_PUBLIC_KEY_FILE '=' QSTRING ';' +connect_accept_password: ACCEPT_PASSWORD '=' QSTRING ';' { -#ifdef HAVE_LIBCRYPTO - if (ypass == 2) - { - BIO *file; - - if (yy_aconf->rsa_public_key != NULL) - { - RSA_free(yy_aconf->rsa_public_key); - yy_aconf->rsa_public_key = NULL; - } - - if (yy_aconf->rsa_public_key_file != NULL) - { - MyFree(yy_aconf->rsa_public_key_file); - yy_aconf->rsa_public_key_file = NULL; - } - - DupString(yy_aconf->rsa_public_key_file, yylval.string); - - if ((file = BIO_new_file(yylval.string, "r")) == NULL) - { - yyerror("Ignoring rsa_public_key_file -- file doesn't exist"); - break; - } + if (conf_parser_ctx.pass != 2) + break; - yy_aconf->rsa_public_key = (RSA *)PEM_read_bio_RSA_PUBKEY(file, NULL, 0, NULL); - - if (yy_aconf->rsa_public_key == NULL) - { - yyerror("Ignoring rsa_public_key_file -- Key invalid; check key syntax."); - break; - } - - BIO_set_close(file, BIO_CLOSE); - BIO_free(file); - } -#endif /* HAVE_LIBCRYPTO */ + if ($3[0] == ':') + conf_error_report("Server passwords cannot begin with a colon"); + else if (strchr($3, ' ')) + conf_error_report("Server passwords cannot contain spaces"); + else + strlcpy(block_state.rpass.buf, yylval.string, sizeof(block_state.rpass.buf)); }; -connect_encrypted: ENCRYPTED '=' TBOOL ';' +connect_ssl_certificate_fingerprint: SSL_CERTIFICATE_FINGERPRINT '=' QSTRING ';' { - if (ypass == 2) - { - if (yylval.number) - yy_aconf->flags |= CONF_FLAGS_ENCRYPTED; - else - yy_aconf->flags &= ~CONF_FLAGS_ENCRYPTED; - } + if (conf_parser_ctx.pass == 2) + strlcpy(block_state.cert.buf, yylval.string, sizeof(block_state.cert.buf)); }; -connect_cryptlink: CRYPTLINK '=' TBOOL ';' +connect_port: PORT '=' NUMBER ';' { - if (ypass == 2) - { - if (yylval.number) - yy_aconf->flags |= CONF_FLAGS_CRYPTLINK; - else - yy_aconf->flags &= ~CONF_FLAGS_CRYPTLINK; - } + if (conf_parser_ctx.pass == 2) + block_state.port.value = $3; }; -connect_compressed: COMPRESSED '=' TBOOL ';' +connect_aftype: AFTYPE '=' T_IPV4 ';' { - if (ypass == 2) - { - if (yylval.number) -#ifndef HAVE_LIBZ - yyerror("Ignoring compressed=yes; -- no zlib support"); -#else - yy_aconf->flags |= CONF_FLAGS_COMPRESSED; -#endif - else - yy_aconf->flags &= ~CONF_FLAGS_COMPRESSED; - } + if (conf_parser_ctx.pass == 2) + block_state.aftype.value = AF_INET; +} | AFTYPE '=' T_IPV6 ';' +{ + if (conf_parser_ctx.pass == 2) + block_state.aftype.value = AF_INET6; }; -connect_auto: AUTOCONN '=' TBOOL ';' +connect_flags: IRCD_FLAGS { - if (ypass == 2) - { - if (yylval.number) - yy_aconf->flags |= CONF_FLAGS_ALLOW_AUTO_CONN; - else - yy_aconf->flags &= ~CONF_FLAGS_ALLOW_AUTO_CONN; - } + block_state.flags.value &= CONF_FLAGS_ENCRYPTED; +} '=' connect_flags_items ';'; + +connect_flags_items: connect_flags_items ',' connect_flags_item | connect_flags_item; +connect_flags_item: AUTOCONN +{ + if (conf_parser_ctx.pass == 2) + block_state.flags.value |= CONF_FLAGS_ALLOW_AUTO_CONN; +} | T_SSL +{ + if (conf_parser_ctx.pass == 2) + block_state.flags.value |= CONF_FLAGS_SSL; }; -connect_topicburst: TOPICBURST '=' TBOOL ';' +connect_encrypted: ENCRYPTED '=' TBOOL ';' { - if (ypass == 2) + if (conf_parser_ctx.pass == 2) { if (yylval.number) - SetConfTopicBurst(yy_aconf); + block_state.flags.value |= CONF_FLAGS_ENCRYPTED; else - ClearConfTopicBurst(yy_aconf); + block_state.flags.value &= ~CONF_FLAGS_ENCRYPTED; } }; -connect_hub_mask: HUB_MASK '=' QSTRING ';' +connect_hub_mask: HUB_MASK '=' QSTRING ';' { - if (ypass == 2) - { - struct CollectItem *yy_tmp; - - yy_tmp = (struct CollectItem *)MyMalloc(sizeof(struct CollectItem)); - DupString(yy_tmp->host, yylval.string); - DupString(yy_tmp->user, "*"); - dlinkAdd(yy_tmp, &yy_tmp->node, &hub_conf_list); - } + if (conf_parser_ctx.pass == 2) + dlinkAdd(xstrdup(yylval.string), make_dlink_node(), &block_state.hub.list); }; -connect_leaf_mask: LEAF_MASK '=' QSTRING ';' +connect_leaf_mask: LEAF_MASK '=' QSTRING ';' { - if (ypass == 2) - { - struct CollectItem *yy_tmp; - - yy_tmp = (struct CollectItem *)MyMalloc(sizeof(struct CollectItem)); - DupString(yy_tmp->host, yylval.string); - DupString(yy_tmp->user, "*"); - dlinkAdd(yy_tmp, &yy_tmp->node, &leaf_conf_list); - } + if (conf_parser_ctx.pass == 2) + dlinkAdd(xstrdup(yylval.string), make_dlink_node(), &block_state.leaf.list); }; connect_class: CLASS '=' QSTRING ';' { - if (ypass == 2) - { - MyFree(class_name); - DupString(class_name, yylval.string); - } + if (conf_parser_ctx.pass == 2) + strlcpy(block_state.class.buf, yylval.string, sizeof(block_state.class.buf)); }; -connect_cipher_preference: CIPHER_PREFERENCE '=' QSTRING ';' +connect_ssl_cipher_list: T_SSL_CIPHER_LIST '=' QSTRING ';' { -#ifdef HAVE_LIBCRYPTO - if (ypass == 2) - { - struct EncCapability *ecap; - const char *cipher_name; - int found = 0; - - yy_aconf->cipher_preference = NULL; - cipher_name = yylval.string; - - for (ecap = CipherTable; ecap->name; ecap++) - { - if ((irccmp(ecap->name, cipher_name) == 0) && - (ecap->cap & CAP_ENC_MASK)) - { - yy_aconf->cipher_preference = ecap; - found = 1; - break; - } - } - - if (!found) - yyerror("Invalid cipher"); - } +#ifdef HAVE_TLS + if (conf_parser_ctx.pass == 2) + strlcpy(block_state.ciph.buf, yylval.string, sizeof(block_state.ciph.buf)); #else - if (ypass == 2) - yyerror("Ignoring cipher_preference -- no OpenSSL support"); + if (conf_parser_ctx.pass == 2) + conf_error_report("Ignoring connect::ciphers -- no TLS support"); #endif }; + /*************************************************************************** - * section kill + * kill {} section ***************************************************************************/ kill_entry: KILL { - if (ypass == 2) - { - userbuf[0] = hostbuf[0] = reasonbuf[0] = '\0'; - regex_ban = 0; - } + if (conf_parser_ctx.pass == 2) + reset_block_state(); } '{' kill_items '}' ';' { - if (ypass == 2) - { - if (userbuf[0] && hostbuf[0]) - { - if (regex_ban) - { - pcre *exp_user = NULL; - pcre *exp_host = NULL; - const char *errptr = NULL; - - if (!(exp_user = ircd_pcre_compile(userbuf, &errptr)) || - !(exp_host = ircd_pcre_compile(hostbuf, &errptr))) - { - ilog(L_ERROR, "Failed to add regular expression based K-Line: %s", - errptr); - break; - } - - yy_conf = make_conf_item(RKLINE_TYPE); - yy_aconf = map_to_conf(yy_conf); - - yy_aconf->regexuser = exp_user; - yy_aconf->regexhost = exp_host; - - DupString(yy_aconf->user, userbuf); - DupString(yy_aconf->host, hostbuf); - - if (reasonbuf[0]) - DupString(yy_aconf->reason, reasonbuf); - else - DupString(yy_aconf->reason, "No reason"); - } - else - { - yy_conf = make_conf_item(KLINE_TYPE); - yy_aconf = map_to_conf(yy_conf); - - DupString(yy_aconf->user, userbuf); - DupString(yy_aconf->host, hostbuf); - - if (reasonbuf[0]) - DupString(yy_aconf->reason, reasonbuf); - else - DupString(yy_aconf->reason, "No reason"); - add_conf_by_address(CONF_KILL, yy_aconf); - } - } - else - delete_conf_item(yy_conf); + struct MaskItem *conf = NULL; - yy_conf = NULL; - yy_aconf = NULL; - } -}; + if (conf_parser_ctx.pass != 2) + break; -kill_type: TYPE -{ -} '=' kill_type_items ';'; + if (!block_state.user.buf[0] || + !block_state.host.buf[0]) + break; -kill_type_items: kill_type_items ',' kill_type_item | kill_type_item; -kill_type_item: REGEX_T -{ - if (ypass == 2) - regex_ban = 1; + conf = conf_make(CONF_KLINE); + conf->user = xstrdup(block_state.user.buf); + conf->host = xstrdup(block_state.host.buf); + + if (block_state.rpass.buf[0]) + conf->reason = xstrdup(block_state.rpass.buf); + else + conf->reason = xstrdup(CONF_NOREASON); + add_conf_by_address(CONF_KLINE, conf); }; kill_items: kill_items kill_item | kill_item; -kill_item: kill_user | kill_reason | kill_type | error; +kill_item: kill_user | kill_reason | error; kill_user: USER '=' QSTRING ';' { - if (ypass == 2) + + if (conf_parser_ctx.pass == 2) { struct split_nuh_item nuh; nuh.nuhmask = yylval.string; nuh.nickptr = NULL; - nuh.userptr = userbuf; - nuh.hostptr = hostbuf; + nuh.userptr = block_state.user.buf; + nuh.hostptr = block_state.host.buf; nuh.nicksize = 0; - nuh.usersize = sizeof(userbuf); - nuh.hostsize = sizeof(hostbuf); + nuh.usersize = sizeof(block_state.user.buf); + nuh.hostsize = sizeof(block_state.host.buf); split_nuh(&nuh); } }; -kill_reason: REASON '=' QSTRING ';' +kill_reason: REASON '=' QSTRING ';' { - if (ypass == 2) - strlcpy(reasonbuf, yylval.string, sizeof(reasonbuf)); + if (conf_parser_ctx.pass == 2) + strlcpy(block_state.rpass.buf, yylval.string, sizeof(block_state.rpass.buf)); }; + /*************************************************************************** - * section deny + * deny {} section ***************************************************************************/ -deny_entry: DENY +deny_entry: DENY { - if (ypass == 2) - { - yy_conf = make_conf_item(DLINE_TYPE); - yy_aconf = map_to_conf(yy_conf); - /* default reason */ - DupString(yy_aconf->reason, "No reason"); - } + if (conf_parser_ctx.pass == 2) + reset_block_state(); } '{' deny_items '}' ';' { - if (ypass == 2) + struct MaskItem *conf = NULL; + + if (conf_parser_ctx.pass != 2) + break; + + if (!block_state.addr.buf[0]) + break; + + if (parse_netmask(block_state.addr.buf, NULL, NULL) != HM_HOST) { - if (yy_aconf->host && parse_netmask(yy_aconf->host, NULL, NULL) != HM_HOST) - add_conf_by_address(CONF_DLINE, yy_aconf); + conf = conf_make(CONF_DLINE); + conf->host = xstrdup(block_state.addr.buf); + + if (block_state.rpass.buf[0]) + conf->reason = xstrdup(block_state.rpass.buf); else - delete_conf_item(yy_conf); - yy_conf = NULL; - yy_aconf = NULL; + conf->reason = xstrdup(CONF_NOREASON); + add_conf_by_address(CONF_DLINE, conf); } -}; +}; deny_items: deny_items deny_item | deny_item; deny_item: deny_ip | deny_reason | error; deny_ip: IP '=' QSTRING ';' { - if (ypass == 2) - { - MyFree(yy_aconf->host); - DupString(yy_aconf->host, yylval.string); - } + if (conf_parser_ctx.pass == 2) + strlcpy(block_state.addr.buf, yylval.string, sizeof(block_state.addr.buf)); }; -deny_reason: REASON '=' QSTRING ';' +deny_reason: REASON '=' QSTRING ';' { - if (ypass == 2) - { - MyFree(yy_aconf->reason); - DupString(yy_aconf->reason, yylval.string); - } + if (conf_parser_ctx.pass == 2) + strlcpy(block_state.rpass.buf, yylval.string, sizeof(block_state.rpass.buf)); }; + /*************************************************************************** - * section exempt + * exempt {} section ***************************************************************************/ exempt_entry: EXEMPT '{' exempt_items '}' ';'; -exempt_items: exempt_items exempt_item | exempt_item; -exempt_item: exempt_ip | error; +exempt_items: exempt_items exempt_item | exempt_item; +exempt_item: exempt_ip | error; exempt_ip: IP '=' QSTRING ';' { - if (ypass == 2) + if (conf_parser_ctx.pass == 2) { - if (yylval.string[0] && parse_netmask(yylval.string, NULL, NULL) != HM_HOST) + if (*yylval.string && parse_netmask(yylval.string, NULL, NULL) != HM_HOST) { - yy_conf = make_conf_item(EXEMPTDLINE_TYPE); - yy_aconf = map_to_conf(yy_conf); - DupString(yy_aconf->host, yylval.string); + struct MaskItem *conf = conf_make(CONF_EXEMPT); + conf->host = xstrdup(yylval.string); - add_conf_by_address(CONF_EXEMPTDLINE, yy_aconf); - - yy_conf = NULL; - yy_aconf = NULL; + add_conf_by_address(CONF_EXEMPT, conf); } } }; /*************************************************************************** - * section gecos + * gecos {} section ***************************************************************************/ gecos_entry: GECOS { - if (ypass == 2) - { - regex_ban = 0; - reasonbuf[0] = gecos_name[0] = '\0'; - } + if (conf_parser_ctx.pass == 2) + reset_block_state(); } '{' gecos_items '}' ';' { - if (ypass == 2) - { - if (gecos_name[0]) - { - if (regex_ban) - { - pcre *exp_p = NULL; - const char *errptr = NULL; - - if (!(exp_p = ircd_pcre_compile(gecos_name, &errptr))) - { - ilog(L_ERROR, "Failed to add regular expression based X-Line: %s", - errptr); - break; - } - - yy_conf = make_conf_item(RXLINE_TYPE); - yy_conf->regexpname = exp_p; - } - else - yy_conf = make_conf_item(XLINE_TYPE); - - yy_match_item = map_to_conf(yy_conf); - DupString(yy_conf->name, gecos_name); - - if (reasonbuf[0]) - DupString(yy_match_item->reason, reasonbuf); - else - DupString(yy_match_item->reason, "No reason"); - } - } -}; + if (conf_parser_ctx.pass != 2) + break; -gecos_flags: TYPE -{ -} '=' gecos_flags_items ';'; + if (!block_state.name.buf[0]) + break; -gecos_flags_items: gecos_flags_items ',' gecos_flags_item | gecos_flags_item; -gecos_flags_item: REGEX_T -{ - if (ypass == 2) - regex_ban = 1; + struct GecosItem *gecos = gecos_make(); + gecos->mask = xstrdup(block_state.name.buf); + + if (block_state.rpass.buf[0]) + gecos->reason = xstrdup(block_state.rpass.buf); + else + gecos->reason = xstrdup(CONF_NOREASON); }; gecos_items: gecos_items gecos_item | gecos_item; -gecos_item: gecos_name | gecos_reason | gecos_flags | error; +gecos_item: gecos_name | gecos_reason | error; -gecos_name: NAME '=' QSTRING ';' +gecos_name: NAME '=' QSTRING ';' { - if (ypass == 2) - strlcpy(gecos_name, yylval.string, sizeof(gecos_name)); + if (conf_parser_ctx.pass == 2) + strlcpy(block_state.name.buf, yylval.string, sizeof(block_state.name.buf)); }; -gecos_reason: REASON '=' QSTRING ';' +gecos_reason: REASON '=' QSTRING ';' { - if (ypass == 2) - strlcpy(reasonbuf, yylval.string, sizeof(reasonbuf)); + if (conf_parser_ctx.pass == 2) + strlcpy(block_state.rpass.buf, yylval.string, sizeof(block_state.rpass.buf)); }; + /*************************************************************************** - * section general + * general {} section ***************************************************************************/ -general_entry: GENERAL - '{' general_items '}' ';'; +general_entry: GENERAL '{' general_items '}' ';'; general_items: general_items general_item | general_item; -general_item: general_hide_spoof_ips | general_ignore_bogus_ts | - general_failed_oper_notice | general_anti_nick_flood | - general_max_nick_time | general_max_nick_changes | - general_max_accept | general_anti_spam_exit_message_time | - general_ts_warn_delta | general_ts_max_delta | - general_kill_chase_time_limit | general_kline_with_reason | - general_kline_reason | general_invisible_on_connect | - general_warn_no_nline | general_dots_in_ident | - general_stats_o_oper_only | general_stats_k_oper_only | - general_pace_wait | general_stats_i_oper_only | - general_pace_wait_simple | general_stats_P_oper_only | - general_short_motd | general_no_oper_flood | - general_true_no_oper_flood | general_oper_pass_resv | - general_idletime | general_message_locale | - general_oper_only_umodes | general_max_targets | - general_use_egd | general_egdpool_path | - general_oper_umodes | general_caller_id_wait | - general_opers_bypass_callerid | general_default_floodcount | - general_min_nonwildcard | general_min_nonwildcard_simple | - general_servlink_path | general_disable_remote_commands | - general_default_cipher_preference | - general_compression_level | general_client_flood | - general_throttle_time | general_havent_read_conf | - general_dot_in_ip6_addr | general_ping_cookie | - general_disable_auth | general_burst_away | - general_tkline_expire_notices | general_gline_min_cidr | - general_gline_min_cidr6 | general_use_whois_actually | - general_reject_hold_time | general_stats_e_disabled | - error; +general_item: general_away_count | + general_away_time | + general_ignore_bogus_ts | + general_failed_oper_notice | + general_anti_nick_flood | + general_max_nick_time | + general_max_nick_changes | + general_max_accept | + general_whowas_history_length | + general_anti_spam_exit_message_time | + general_ts_warn_delta | + general_ts_max_delta | + general_kill_chase_time_limit | + general_invisible_on_connect | + general_warn_no_connect_block | + general_dots_in_ident | + general_stats_i_oper_only | + general_stats_k_oper_only | + general_stats_m_oper_only | + general_stats_o_oper_only | + general_stats_P_oper_only | + general_stats_u_oper_only | + general_pace_wait | + general_pace_wait_simple | + general_short_motd | + general_no_oper_flood | + general_oper_only_umodes | + general_max_targets | + general_oper_umodes | + general_caller_id_wait | + general_opers_bypass_callerid | + general_default_floodcount | + general_min_nonwildcard | + general_min_nonwildcard_simple | + general_throttle_count | + general_throttle_time | + general_ping_cookie | + general_disable_auth | + general_tkline_expire_notices | + general_dline_min_cidr | + general_dline_min_cidr6 | + general_kline_min_cidr | + general_kline_min_cidr6 | + general_stats_e_disabled | + general_max_watch | + general_cycle_on_host_change | + error; +general_away_count: AWAY_COUNT '=' NUMBER ';' +{ + ConfigGeneral.away_count = $3; +}; -general_gline_min_cidr: GLINE_MIN_CIDR '=' NUMBER ';' +general_away_time: AWAY_TIME '=' timespec ';' { - ConfigFileEntry.gline_min_cidr = $3; + ConfigGeneral.away_time = $3; }; -general_gline_min_cidr6: GLINE_MIN_CIDR6 '=' NUMBER ';' +general_max_watch: MAX_WATCH '=' NUMBER ';' { - ConfigFileEntry.gline_min_cidr6 = $3; + ConfigGeneral.max_watch = $3; }; -general_burst_away: BURST_AWAY '=' TBOOL ';' +general_whowas_history_length: WHOWAS_HISTORY_LENGTH '=' NUMBER ';' { - ConfigFileEntry.burst_away = yylval.number; + ConfigGeneral.whowas_history_length = $3; }; -general_use_whois_actually: USE_WHOIS_ACTUALLY '=' TBOOL ';' +general_cycle_on_host_change: CYCLE_ON_HOST_CHANGE '=' TBOOL ';' { - ConfigFileEntry.use_whois_actually = yylval.number; + if (conf_parser_ctx.pass == 2) + ConfigGeneral.cycle_on_host_change = yylval.number; }; -general_reject_hold_time: TREJECT_HOLD_TIME '=' timespec ';' +general_dline_min_cidr: DLINE_MIN_CIDR '=' NUMBER ';' { - GlobalSetOptions.rejecttime = yylval.number; + ConfigGeneral.dline_min_cidr = $3; }; -general_tkline_expire_notices: TKLINE_EXPIRE_NOTICES '=' TBOOL ';' +general_dline_min_cidr6: DLINE_MIN_CIDR6 '=' NUMBER ';' { - ConfigFileEntry.tkline_expire_notices = yylval.number; + ConfigGeneral.dline_min_cidr6 = $3; }; -general_kill_chase_time_limit: KILL_CHASE_TIME_LIMIT '=' NUMBER ';' +general_kline_min_cidr: KLINE_MIN_CIDR '=' NUMBER ';' { - ConfigFileEntry.kill_chase_time_limit = $3; + ConfigGeneral.kline_min_cidr = $3; }; -general_hide_spoof_ips: HIDE_SPOOF_IPS '=' TBOOL ';' +general_kline_min_cidr6: KLINE_MIN_CIDR6 '=' NUMBER ';' { - ConfigFileEntry.hide_spoof_ips = yylval.number; + ConfigGeneral.kline_min_cidr6 = $3; }; -general_ignore_bogus_ts: IGNORE_BOGUS_TS '=' TBOOL ';' +general_tkline_expire_notices: TKLINE_EXPIRE_NOTICES '=' TBOOL ';' { - ConfigFileEntry.ignore_bogus_ts = yylval.number; + ConfigGeneral.tkline_expire_notices = yylval.number; }; -general_disable_remote_commands: DISABLE_REMOTE_COMMANDS '=' TBOOL ';' +general_kill_chase_time_limit: KILL_CHASE_TIME_LIMIT '=' timespec ';' { - ConfigFileEntry.disable_remote = yylval.number; + ConfigGeneral.kill_chase_time_limit = $3; +}; + +general_ignore_bogus_ts: IGNORE_BOGUS_TS '=' TBOOL ';' +{ + ConfigGeneral.ignore_bogus_ts = yylval.number; }; general_failed_oper_notice: FAILED_OPER_NOTICE '=' TBOOL ';' { - ConfigFileEntry.failed_oper_notice = yylval.number; + ConfigGeneral.failed_oper_notice = yylval.number; }; general_anti_nick_flood: ANTI_NICK_FLOOD '=' TBOOL ';' { - ConfigFileEntry.anti_nick_flood = yylval.number; + ConfigGeneral.anti_nick_flood = yylval.number; }; general_max_nick_time: MAX_NICK_TIME '=' timespec ';' { - ConfigFileEntry.max_nick_time = $3; + ConfigGeneral.max_nick_time = $3; }; general_max_nick_changes: MAX_NICK_CHANGES '=' NUMBER ';' { - ConfigFileEntry.max_nick_changes = $3; + ConfigGeneral.max_nick_changes = $3; }; general_max_accept: MAX_ACCEPT '=' NUMBER ';' { - ConfigFileEntry.max_accept = $3; + ConfigGeneral.max_accept = $3; }; general_anti_spam_exit_message_time: ANTI_SPAM_EXIT_MESSAGE_TIME '=' timespec ';' { - ConfigFileEntry.anti_spam_exit_message_time = $3; + ConfigGeneral.anti_spam_exit_message_time = $3; }; general_ts_warn_delta: TS_WARN_DELTA '=' timespec ';' { - ConfigFileEntry.ts_warn_delta = $3; + ConfigGeneral.ts_warn_delta = $3; }; general_ts_max_delta: TS_MAX_DELTA '=' timespec ';' { - if (ypass == 2) - ConfigFileEntry.ts_max_delta = $3; + if (conf_parser_ctx.pass == 2) + ConfigGeneral.ts_max_delta = $3; }; -general_havent_read_conf: HAVENT_READ_CONF '=' NUMBER ';' +general_invisible_on_connect: INVISIBLE_ON_CONNECT '=' TBOOL ';' { - if (($3 > 0) && ypass == 1) - { - ilog(L_CRIT, "You haven't read your config file properly."); - ilog(L_CRIT, "There is a line in the example conf that will kill your server if not removed."); - ilog(L_CRIT, "Consider actually reading/editing the conf file, and removing this line."); - exit(0); - } + ConfigGeneral.invisible_on_connect = yylval.number; }; -general_kline_with_reason: KLINE_WITH_REASON '=' TBOOL ';' +general_warn_no_connect_block: WARN_NO_CONNECT_BLOCK '=' TBOOL ';' { - ConfigFileEntry.kline_with_reason = yylval.number; + ConfigGeneral.warn_no_connect_block = yylval.number; }; -general_kline_reason: KLINE_REASON '=' QSTRING ';' +general_stats_e_disabled: STATS_E_DISABLED '=' TBOOL ';' { - if (ypass == 2) - { - MyFree(ConfigFileEntry.kline_reason); - DupString(ConfigFileEntry.kline_reason, yylval.string); - } + ConfigGeneral.stats_e_disabled = yylval.number; }; -general_invisible_on_connect: INVISIBLE_ON_CONNECT '=' TBOOL ';' +general_stats_m_oper_only: STATS_M_OPER_ONLY '=' TBOOL ';' { - ConfigFileEntry.invisible_on_connect = yylval.number; + ConfigGeneral.stats_m_oper_only = yylval.number; }; -general_warn_no_nline: WARN_NO_NLINE '=' TBOOL ';' +general_stats_o_oper_only: STATS_O_OPER_ONLY '=' TBOOL ';' { - ConfigFileEntry.warn_no_nline = yylval.number; + ConfigGeneral.stats_o_oper_only = yylval.number; }; -general_stats_e_disabled: STATS_E_DISABLED '=' TBOOL ';' +general_stats_P_oper_only: STATS_P_OPER_ONLY '=' TBOOL ';' { - ConfigFileEntry.stats_e_disabled = yylval.number; + ConfigGeneral.stats_P_oper_only = yylval.number; }; -general_stats_o_oper_only: STATS_O_OPER_ONLY '=' TBOOL ';' +general_stats_u_oper_only: STATS_U_OPER_ONLY '=' TBOOL ';' { - ConfigFileEntry.stats_o_oper_only = yylval.number; -}; - -general_stats_P_oper_only: STATS_P_OPER_ONLY '=' TBOOL ';' -{ - ConfigFileEntry.stats_P_oper_only = yylval.number; + ConfigGeneral.stats_u_oper_only = yylval.number; }; general_stats_k_oper_only: STATS_K_OPER_ONLY '=' TBOOL ';' { - ConfigFileEntry.stats_k_oper_only = 2 * yylval.number; + ConfigGeneral.stats_k_oper_only = 2 * yylval.number; } | STATS_K_OPER_ONLY '=' TMASKED ';' { - ConfigFileEntry.stats_k_oper_only = 1; + ConfigGeneral.stats_k_oper_only = 1; }; general_stats_i_oper_only: STATS_I_OPER_ONLY '=' TBOOL ';' { - ConfigFileEntry.stats_i_oper_only = 2 * yylval.number; + ConfigGeneral.stats_i_oper_only = 2 * yylval.number; } | STATS_I_OPER_ONLY '=' TMASKED ';' { - ConfigFileEntry.stats_i_oper_only = 1; + ConfigGeneral.stats_i_oper_only = 1; }; general_pace_wait: PACE_WAIT '=' timespec ';' { - ConfigFileEntry.pace_wait = $3; + ConfigGeneral.pace_wait = $3; }; general_caller_id_wait: CALLER_ID_WAIT '=' timespec ';' { - ConfigFileEntry.caller_id_wait = $3; + ConfigGeneral.caller_id_wait = $3; }; general_opers_bypass_callerid: OPERS_BYPASS_CALLERID '=' TBOOL ';' { - ConfigFileEntry.opers_bypass_callerid = yylval.number; + ConfigGeneral.opers_bypass_callerid = yylval.number; }; general_pace_wait_simple: PACE_WAIT_SIMPLE '=' timespec ';' { - ConfigFileEntry.pace_wait_simple = $3; + ConfigGeneral.pace_wait_simple = $3; }; general_short_motd: SHORT_MOTD '=' TBOOL ';' { - ConfigFileEntry.short_motd = yylval.number; -}; - -general_no_oper_flood: NO_OPER_FLOOD '=' TBOOL ';' -{ - ConfigFileEntry.no_oper_flood = yylval.number; -}; - -general_true_no_oper_flood: TRUE_NO_OPER_FLOOD '=' TBOOL ';' -{ - ConfigFileEntry.true_no_oper_flood = yylval.number; -}; - -general_oper_pass_resv: OPER_PASS_RESV '=' TBOOL ';' -{ - ConfigFileEntry.oper_pass_resv = yylval.number; -}; - -general_message_locale: MESSAGE_LOCALE '=' QSTRING ';' -{ - if (ypass == 2) - { - if (strlen(yylval.string) > LOCALE_LENGTH-2) - yylval.string[LOCALE_LENGTH-1] = '\0'; - - set_locale(yylval.string); - } + ConfigGeneral.short_motd = yylval.number; }; -general_idletime: IDLETIME '=' timespec ';' +general_no_oper_flood: NO_OPER_FLOOD '=' TBOOL ';' { - ConfigFileEntry.idletime = $3; + ConfigGeneral.no_oper_flood = yylval.number; }; general_dots_in_ident: DOTS_IN_IDENT '=' NUMBER ';' { - ConfigFileEntry.dots_in_ident = $3; + ConfigGeneral.dots_in_ident = $3; }; general_max_targets: MAX_TARGETS '=' NUMBER ';' { - ConfigFileEntry.max_targets = $3; + ConfigGeneral.max_targets = $3; }; -general_servlink_path: SERVLINK_PATH '=' QSTRING ';' -{ - if (ypass == 2) - { - MyFree(ConfigFileEntry.servlink_path); - DupString(ConfigFileEntry.servlink_path, yylval.string); - } -}; - -general_default_cipher_preference: DEFAULT_CIPHER_PREFERENCE '=' QSTRING ';' -{ -#ifdef HAVE_LIBCRYPTO - if (ypass == 2) - { - struct EncCapability *ecap; - const char *cipher_name; - int found = 0; - - ConfigFileEntry.default_cipher_preference = NULL; - cipher_name = yylval.string; - - for (ecap = CipherTable; ecap->name; ecap++) - { - if ((irccmp(ecap->name, cipher_name) == 0) && - (ecap->cap & CAP_ENC_MASK)) - { - ConfigFileEntry.default_cipher_preference = ecap; - found = 1; - break; - } - } - - if (!found) - yyerror("Invalid cipher"); - } -#else - if (ypass == 2) - yyerror("Ignoring default_cipher_preference -- no OpenSSL support"); -#endif -}; - -general_compression_level: COMPRESSION_LEVEL '=' NUMBER ';' -{ - if (ypass == 2) - { - ConfigFileEntry.compression_level = $3; -#ifndef HAVE_LIBZ - yyerror("Ignoring compression_level -- no zlib support"); -#else - if ((ConfigFileEntry.compression_level < 1) || - (ConfigFileEntry.compression_level > 9)) - { - yyerror("Ignoring invalid compression_level, using default"); - ConfigFileEntry.compression_level = 0; - } -#endif - } -}; - -general_use_egd: USE_EGD '=' TBOOL ';' -{ - ConfigFileEntry.use_egd = yylval.number; -}; - -general_egdpool_path: EGDPOOL_PATH '=' QSTRING ';' +general_ping_cookie: PING_COOKIE '=' TBOOL ';' { - if (ypass == 2) - { - MyFree(ConfigFileEntry.egdpool_path); - DupString(ConfigFileEntry.egdpool_path, yylval.string); - } + ConfigGeneral.ping_cookie = yylval.number; }; -general_ping_cookie: PING_COOKIE '=' TBOOL ';' +general_disable_auth: DISABLE_AUTH '=' TBOOL ';' { - ConfigFileEntry.ping_cookie = yylval.number; + ConfigGeneral.disable_auth = yylval.number; }; -general_disable_auth: DISABLE_AUTH '=' TBOOL ';' +general_throttle_count: THROTTLE_COUNT '=' NUMBER ';' { - ConfigFileEntry.disable_auth = yylval.number; + ConfigGeneral.throttle_count = $3; }; general_throttle_time: THROTTLE_TIME '=' timespec ';' { - ConfigFileEntry.throttle_time = yylval.number; + ConfigGeneral.throttle_time = $3; }; general_oper_umodes: OPER_UMODES { - ConfigFileEntry.oper_umodes = 0; + ConfigGeneral.oper_umodes = 0; } '=' umode_oitems ';' ; umode_oitems: umode_oitems ',' umode_oitem | umode_oitem; umode_oitem: T_BOTS { - ConfigFileEntry.oper_umodes |= UMODE_BOTS; + ConfigGeneral.oper_umodes |= UMODE_BOTS; } | T_CCONN { - ConfigFileEntry.oper_umodes |= UMODE_CCONN; + ConfigGeneral.oper_umodes |= UMODE_CCONN; } | T_DEAF { - ConfigFileEntry.oper_umodes |= UMODE_DEAF; + ConfigGeneral.oper_umodes |= UMODE_DEAF; } | T_DEBUG { - ConfigFileEntry.oper_umodes |= UMODE_DEBUG; + ConfigGeneral.oper_umodes |= UMODE_DEBUG; } | T_FULL { - ConfigFileEntry.oper_umodes |= UMODE_FULL; + ConfigGeneral.oper_umodes |= UMODE_FULL; +} | HIDDEN +{ + ConfigGeneral.oper_umodes |= UMODE_HIDDEN; +} | HIDE_CHANS +{ + ConfigGeneral.oper_umodes |= UMODE_HIDECHANS; +} | HIDE_IDLE +{ + ConfigGeneral.oper_umodes |= UMODE_HIDEIDLE; } | T_SKILL { - ConfigFileEntry.oper_umodes |= UMODE_SKILL; + ConfigGeneral.oper_umodes |= UMODE_SKILL; } | T_NCHANGE { - ConfigFileEntry.oper_umodes |= UMODE_NCHANGE; + ConfigGeneral.oper_umodes |= UMODE_NCHANGE; } | T_REJ { - ConfigFileEntry.oper_umodes |= UMODE_REJ; + ConfigGeneral.oper_umodes |= UMODE_REJ; } | T_UNAUTH { - ConfigFileEntry.oper_umodes |= UMODE_UNAUTH; + ConfigGeneral.oper_umodes |= UMODE_UNAUTH; } | T_SPY { - ConfigFileEntry.oper_umodes |= UMODE_SPY; + ConfigGeneral.oper_umodes |= UMODE_SPY; } | T_EXTERNAL { - ConfigFileEntry.oper_umodes |= UMODE_EXTERNAL; -} | T_OPERWALL -{ - ConfigFileEntry.oper_umodes |= UMODE_OPERWALL; + ConfigGeneral.oper_umodes |= UMODE_EXTERNAL; } | T_SERVNOTICE { - ConfigFileEntry.oper_umodes |= UMODE_SERVNOTICE; + ConfigGeneral.oper_umodes |= UMODE_SERVNOTICE; } | T_INVISIBLE { - ConfigFileEntry.oper_umodes |= UMODE_INVISIBLE; + ConfigGeneral.oper_umodes |= UMODE_INVISIBLE; } | T_WALLOP { - ConfigFileEntry.oper_umodes |= UMODE_WALLOP; + ConfigGeneral.oper_umodes |= UMODE_WALLOP; } | T_SOFTCALLERID { - ConfigFileEntry.oper_umodes |= UMODE_SOFTCALLERID; + ConfigGeneral.oper_umodes |= UMODE_SOFTCALLERID; } | T_CALLERID { - ConfigFileEntry.oper_umodes |= UMODE_CALLERID; + ConfigGeneral.oper_umodes |= UMODE_CALLERID; } | T_LOCOPS { - ConfigFileEntry.oper_umodes |= UMODE_LOCOPS; + ConfigGeneral.oper_umodes |= UMODE_LOCOPS; +} | T_NONONREG +{ + ConfigGeneral.oper_umodes |= UMODE_REGONLY; +} | T_FARCONNECT +{ + ConfigGeneral.oper_umodes |= UMODE_FARCONNECT; }; -general_oper_only_umodes: OPER_ONLY_UMODES +general_oper_only_umodes: OPER_ONLY_UMODES { - ConfigFileEntry.oper_only_umodes = 0; + ConfigGeneral.oper_only_umodes = 0; } '=' umode_items ';' ; -umode_items: umode_items ',' umode_item | umode_item; -umode_item: T_BOTS +umode_items: umode_items ',' umode_item | umode_item; +umode_item: T_BOTS { - ConfigFileEntry.oper_only_umodes |= UMODE_BOTS; + ConfigGeneral.oper_only_umodes |= UMODE_BOTS; } | T_CCONN { - ConfigFileEntry.oper_only_umodes |= UMODE_CCONN; + ConfigGeneral.oper_only_umodes |= UMODE_CCONN; } | T_DEAF { - ConfigFileEntry.oper_only_umodes |= UMODE_DEAF; + ConfigGeneral.oper_only_umodes |= UMODE_DEAF; } | T_DEBUG { - ConfigFileEntry.oper_only_umodes |= UMODE_DEBUG; + ConfigGeneral.oper_only_umodes |= UMODE_DEBUG; } | T_FULL -{ - ConfigFileEntry.oper_only_umodes |= UMODE_FULL; +{ + ConfigGeneral.oper_only_umodes |= UMODE_FULL; } | T_SKILL { - ConfigFileEntry.oper_only_umodes |= UMODE_SKILL; + ConfigGeneral.oper_only_umodes |= UMODE_SKILL; +} | HIDDEN +{ + ConfigGeneral.oper_only_umodes |= UMODE_HIDDEN; } | T_NCHANGE { - ConfigFileEntry.oper_only_umodes |= UMODE_NCHANGE; + ConfigGeneral.oper_only_umodes |= UMODE_NCHANGE; } | T_REJ { - ConfigFileEntry.oper_only_umodes |= UMODE_REJ; + ConfigGeneral.oper_only_umodes |= UMODE_REJ; } | T_UNAUTH { - ConfigFileEntry.oper_only_umodes |= UMODE_UNAUTH; + ConfigGeneral.oper_only_umodes |= UMODE_UNAUTH; } | T_SPY { - ConfigFileEntry.oper_only_umodes |= UMODE_SPY; + ConfigGeneral.oper_only_umodes |= UMODE_SPY; } | T_EXTERNAL { - ConfigFileEntry.oper_only_umodes |= UMODE_EXTERNAL; -} | T_OPERWALL -{ - ConfigFileEntry.oper_only_umodes |= UMODE_OPERWALL; + ConfigGeneral.oper_only_umodes |= UMODE_EXTERNAL; } | T_SERVNOTICE { - ConfigFileEntry.oper_only_umodes |= UMODE_SERVNOTICE; + ConfigGeneral.oper_only_umodes |= UMODE_SERVNOTICE; } | T_INVISIBLE { - ConfigFileEntry.oper_only_umodes |= UMODE_INVISIBLE; + ConfigGeneral.oper_only_umodes |= UMODE_INVISIBLE; } | T_WALLOP { - ConfigFileEntry.oper_only_umodes |= UMODE_WALLOP; + ConfigGeneral.oper_only_umodes |= UMODE_WALLOP; } | T_SOFTCALLERID { - ConfigFileEntry.oper_only_umodes |= UMODE_SOFTCALLERID; + ConfigGeneral.oper_only_umodes |= UMODE_SOFTCALLERID; } | T_CALLERID { - ConfigFileEntry.oper_only_umodes |= UMODE_CALLERID; + ConfigGeneral.oper_only_umodes |= UMODE_CALLERID; } | T_LOCOPS { - ConfigFileEntry.oper_only_umodes |= UMODE_LOCOPS; + ConfigGeneral.oper_only_umodes |= UMODE_LOCOPS; +} | T_NONONREG +{ + ConfigGeneral.oper_only_umodes |= UMODE_REGONLY; +} | T_FARCONNECT +{ + ConfigGeneral.oper_only_umodes |= UMODE_FARCONNECT; }; general_min_nonwildcard: MIN_NONWILDCARD '=' NUMBER ';' { - ConfigFileEntry.min_nonwildcard = $3; + ConfigGeneral.min_nonwildcard = $3; }; general_min_nonwildcard_simple: MIN_NONWILDCARD_SIMPLE '=' NUMBER ';' { - ConfigFileEntry.min_nonwildcard_simple = $3; + ConfigGeneral.min_nonwildcard_simple = $3; }; general_default_floodcount: DEFAULT_FLOODCOUNT '=' NUMBER ';' { - ConfigFileEntry.default_floodcount = $3; -}; - -general_client_flood: T_CLIENT_FLOOD '=' sizespec ';' -{ - ConfigFileEntry.client_flood = $3; -}; - -general_dot_in_ip6_addr: DOT_IN_IP6_ADDR '=' TBOOL ';' -{ - ConfigFileEntry.dot_in_ip6_addr = yylval.number; -}; - -/*************************************************************************** - * section glines - ***************************************************************************/ -gline_entry: GLINES -{ - if (ypass == 2) - { - yy_conf = make_conf_item(GDENY_TYPE); - yy_aconf = map_to_conf(yy_conf); - } -} '{' gline_items '}' ';' -{ - if (ypass == 2) - { - /* - * since we re-allocate yy_conf/yy_aconf after the end of action=, at the - * end we will have one extra, so we should free it. - */ - if (yy_conf->name == NULL || yy_aconf->user == NULL) - { - delete_conf_item(yy_conf); - yy_conf = NULL; - yy_aconf = NULL; - } - } -}; - -gline_items: gline_items gline_item | gline_item; -gline_item: gline_enable | - gline_duration | - gline_logging | - gline_user | - gline_server | - gline_action | - error; - -gline_enable: ENABLE '=' TBOOL ';' -{ - if (ypass == 2) - ConfigFileEntry.glines = yylval.number; -}; - -gline_duration: DURATION '=' timespec ';' -{ - if (ypass == 2) - ConfigFileEntry.gline_time = $3; -}; - -gline_logging: LOGGING -{ - if (ypass == 2) - ConfigFileEntry.gline_logging = 0; -} '=' gline_logging_types ';'; -gline_logging_types: gline_logging_types ',' gline_logging_type_item | gline_logging_type_item; -gline_logging_type_item: T_REJECT -{ - if (ypass == 2) - ConfigFileEntry.gline_logging |= GDENY_REJECT; -} | T_BLOCK -{ - if (ypass == 2) - ConfigFileEntry.gline_logging |= GDENY_BLOCK; -}; - -gline_user: USER '=' QSTRING ';' -{ - if (ypass == 2) - { - struct split_nuh_item nuh; - - nuh.nuhmask = yylval.string; - nuh.nickptr = NULL; - nuh.userptr = userbuf; - nuh.hostptr = hostbuf; - - nuh.nicksize = 0; - nuh.usersize = sizeof(userbuf); - nuh.hostsize = sizeof(hostbuf); - - split_nuh(&nuh); - - if (yy_aconf->user == NULL) - { - DupString(yy_aconf->user, userbuf); - DupString(yy_aconf->host, hostbuf); - } - else - { - struct CollectItem *yy_tmp = MyMalloc(sizeof(struct CollectItem)); - - DupString(yy_tmp->user, userbuf); - DupString(yy_tmp->host, hostbuf); - - dlinkAdd(yy_tmp, &yy_tmp->node, &col_conf_list); - } - } -}; - -gline_server: NAME '=' QSTRING ';' -{ - if (ypass == 2) - { - MyFree(yy_conf->name); - DupString(yy_conf->name, yylval.string); - } + ConfigGeneral.default_floodcount = $3; }; -gline_action: ACTION -{ - if (ypass == 2) - yy_aconf->flags = 0; -} '=' gdeny_types ';' -{ - if (ypass == 2) - { - struct CollectItem *yy_tmp = NULL; - dlink_node *ptr, *next_ptr; - - DLINK_FOREACH_SAFE(ptr, next_ptr, col_conf_list.head) - { - struct AccessItem *new_aconf; - struct ConfItem *new_conf; - - yy_tmp = ptr->data; - new_conf = make_conf_item(GDENY_TYPE); - new_aconf = map_to_conf(new_conf); - - new_aconf->flags = yy_aconf->flags; - - if (yy_conf->name != NULL) - DupString(new_conf->name, yy_conf->name); - else - DupString(new_conf->name, "*"); - if (yy_aconf->user != NULL) - DupString(new_aconf->user, yy_tmp->user); - else - DupString(new_aconf->user, "*"); - if (yy_aconf->host != NULL) - DupString(new_aconf->host, yy_tmp->host); - else - DupString(new_aconf->host, "*"); - - dlinkDelete(&yy_tmp->node, &col_conf_list); - } - - /* - * In case someone has fed us with more than one action= after user/name - * which would leak memory -Michael - */ - if (yy_conf->name == NULL || yy_aconf->user == NULL) - delete_conf_item(yy_conf); - - yy_conf = make_conf_item(GDENY_TYPE); - yy_aconf = map_to_conf(yy_conf); - } -}; - -gdeny_types: gdeny_types ',' gdeny_type_item | gdeny_type_item; -gdeny_type_item: T_REJECT -{ - if (ypass == 2) - yy_aconf->flags |= GDENY_REJECT; -} | T_BLOCK -{ - if (ypass == 2) - yy_aconf->flags |= GDENY_BLOCK; -}; /*************************************************************************** - * section channel + * channel {} section ***************************************************************************/ -channel_entry: CHANNEL - '{' channel_items '}' ';'; +channel_entry: CHANNEL '{' channel_items '}' ';'; channel_items: channel_items channel_item | channel_item; -channel_item: channel_disable_local_channels | channel_use_except | - channel_use_invex | channel_use_knock | - channel_max_bans | channel_knock_delay | - channel_knock_delay_channel | channel_max_chans_per_user | - channel_quiet_on_ban | channel_default_split_user_count | - channel_default_split_server_count | - channel_no_create_on_split | channel_restrict_channels | - channel_no_join_on_split | channel_burst_topicwho | - channel_jflood_count | channel_jflood_time | - channel_disable_fake_channels | error; +channel_item: channel_max_bans | + channel_invite_client_count | + channel_invite_client_time | + channel_invite_delay_channel | + channel_knock_client_count | + channel_knock_client_time | + channel_knock_delay_channel | + channel_max_channels | + channel_default_join_flood_count | + channel_default_join_flood_time | + channel_disable_fake_channels | + error; channel_disable_fake_channels: DISABLE_FAKE_CHANNELS '=' TBOOL ';' { ConfigChannel.disable_fake_channels = yylval.number; }; -channel_restrict_channels: RESTRICT_CHANNELS '=' TBOOL ';' -{ - ConfigChannel.restrict_channels = yylval.number; -}; - -channel_disable_local_channels: DISABLE_LOCAL_CHANNELS '=' TBOOL ';' +channel_invite_client_count: INVITE_CLIENT_COUNT '=' NUMBER ';' { - ConfigChannel.disable_local_channels = yylval.number; + ConfigChannel.invite_client_count = $3; }; -channel_use_except: USE_EXCEPT '=' TBOOL ';' +channel_invite_client_time: INVITE_CLIENT_TIME '=' timespec ';' { - ConfigChannel.use_except = yylval.number; + ConfigChannel.invite_client_time = $3; }; -channel_use_invex: USE_INVEX '=' TBOOL ';' +channel_invite_delay_channel: INVITE_DELAY_CHANNEL '=' timespec ';' { - ConfigChannel.use_invex = yylval.number; + ConfigChannel.invite_delay_channel = $3; }; -channel_use_knock: USE_KNOCK '=' TBOOL ';' +channel_knock_client_count: KNOCK_CLIENT_COUNT '=' NUMBER ';' { - ConfigChannel.use_knock = yylval.number; + ConfigChannel.knock_client_count = $3; }; -channel_knock_delay: KNOCK_DELAY '=' timespec ';' +channel_knock_client_time: KNOCK_CLIENT_TIME '=' timespec ';' { - ConfigChannel.knock_delay = $3; + ConfigChannel.knock_client_time = $3; }; channel_knock_delay_channel: KNOCK_DELAY_CHANNEL '=' timespec ';' @@ -3877,14 +2927,9 @@ channel_knock_delay_channel: KNOCK_DELAY ConfigChannel.knock_delay_channel = $3; }; -channel_max_chans_per_user: MAX_CHANS_PER_USER '=' NUMBER ';' -{ - ConfigChannel.max_chans_per_user = $3; -}; - -channel_quiet_on_ban: QUIET_ON_BAN '=' TBOOL ';' +channel_max_channels: MAX_CHANNELS '=' NUMBER ';' { - ConfigChannel.quiet_on_ban = yylval.number; + ConfigChannel.max_channels = $3; }; channel_max_bans: MAX_BANS '=' NUMBER ';' @@ -3892,104 +2937,100 @@ channel_max_bans: MAX_BANS '=' NUMBER '; ConfigChannel.max_bans = $3; }; -channel_default_split_user_count: DEFAULT_SPLIT_USER_COUNT '=' NUMBER ';' +channel_default_join_flood_count: DEFAULT_JOIN_FLOOD_COUNT '=' NUMBER ';' { - ConfigChannel.default_split_user_count = $3; + ConfigChannel.default_join_flood_count = yylval.number; }; -channel_default_split_server_count: DEFAULT_SPLIT_SERVER_COUNT '=' NUMBER ';' +channel_default_join_flood_time: DEFAULT_JOIN_FLOOD_TIME '=' timespec ';' { - ConfigChannel.default_split_server_count = $3; + ConfigChannel.default_join_flood_time = $3; }; -channel_no_create_on_split: NO_CREATE_ON_SPLIT '=' TBOOL ';' -{ - ConfigChannel.no_create_on_split = yylval.number; -}; -channel_no_join_on_split: NO_JOIN_ON_SPLIT '=' TBOOL ';' -{ - ConfigChannel.no_join_on_split = yylval.number; -}; +/*************************************************************************** + * serverhide {} section + ***************************************************************************/ +serverhide_entry: SERVERHIDE '{' serverhide_items '}' ';'; + +serverhide_items: serverhide_items serverhide_item | serverhide_item; +serverhide_item: serverhide_flatten_links | + serverhide_flatten_links_delay | + serverhide_flatten_links_file | + serverhide_disable_remote_commands | + serverhide_hide_servers | + serverhide_hide_services | + serverhide_hidden | + serverhide_hidden_name | + serverhide_hide_server_ips | + error; -channel_burst_topicwho: BURST_TOPICWHO '=' TBOOL ';' +serverhide_flatten_links: FLATTEN_LINKS '=' TBOOL ';' { - ConfigChannel.burst_topicwho = yylval.number; + if (conf_parser_ctx.pass == 2) + ConfigServerHide.flatten_links = yylval.number; }; -channel_jflood_count: JOIN_FLOOD_COUNT '=' NUMBER ';' +serverhide_flatten_links_delay: FLATTEN_LINKS_DELAY '=' timespec ';' { - GlobalSetOptions.joinfloodcount = yylval.number; + if (conf_parser_ctx.pass == 2) + { + if ($3 > 0) + { + event_write_links_file.when = $3; + event_add(&event_write_links_file, NULL); + } + else + event_delete(&event_write_links_file); + + ConfigServerHide.flatten_links_delay = $3; + } }; -channel_jflood_time: JOIN_FLOOD_TIME '=' timespec ';' +serverhide_flatten_links_file: FLATTEN_LINKS_FILE '=' QSTRING ';' { - GlobalSetOptions.joinfloodtime = yylval.number; + if (conf_parser_ctx.pass == 2) + { + xfree(ConfigServerHide.flatten_links_file); + ConfigServerHide.flatten_links_file = xstrdup(yylval.string); + } }; -/*************************************************************************** - * section serverhide - ***************************************************************************/ -serverhide_entry: SERVERHIDE - '{' serverhide_items '}' ';'; - -serverhide_items: serverhide_items serverhide_item | serverhide_item; -serverhide_item: serverhide_flatten_links | serverhide_hide_servers | - serverhide_links_delay | - serverhide_disable_hidden | - serverhide_hidden | serverhide_hidden_name | - serverhide_hide_server_ips | - error; - -serverhide_flatten_links: FLATTEN_LINKS '=' TBOOL ';' +serverhide_disable_remote_commands: DISABLE_REMOTE_COMMANDS '=' TBOOL ';' { - if (ypass == 2) - ConfigServerHide.flatten_links = yylval.number; + if (conf_parser_ctx.pass == 2) + ConfigServerHide.disable_remote_commands = yylval.number; }; serverhide_hide_servers: HIDE_SERVERS '=' TBOOL ';' { - if (ypass == 2) + if (conf_parser_ctx.pass == 2) ConfigServerHide.hide_servers = yylval.number; }; -serverhide_hidden_name: HIDDEN_NAME '=' QSTRING ';' +serverhide_hide_services: HIDE_SERVICES '=' TBOOL ';' { - if (ypass == 2) - { - MyFree(ConfigServerHide.hidden_name); - DupString(ConfigServerHide.hidden_name, yylval.string); - } + if (conf_parser_ctx.pass == 2) + ConfigServerHide.hide_services = yylval.number; }; -serverhide_links_delay: LINKS_DELAY '=' timespec ';' +serverhide_hidden_name: HIDDEN_NAME '=' QSTRING ';' { - if (ypass == 2) + if (conf_parser_ctx.pass == 2) { - if (($3 > 0) && ConfigServerHide.links_disabled == 1) - { - eventAddIsh("write_links_file", write_links_file, NULL, $3); - ConfigServerHide.links_disabled = 0; - } - - ConfigServerHide.links_delay = $3; + xfree(ConfigServerHide.hidden_name); + ConfigServerHide.hidden_name = xstrdup(yylval.string); } }; serverhide_hidden: HIDDEN '=' TBOOL ';' { - if (ypass == 2) + if (conf_parser_ctx.pass == 2) ConfigServerHide.hidden = yylval.number; }; -serverhide_disable_hidden: DISABLE_HIDDEN '=' TBOOL ';' -{ - if (ypass == 2) - ConfigServerHide.disable_hidden = yylval.number; -}; - serverhide_hide_server_ips: HIDE_SERVER_IPS '=' TBOOL ';' { - if (ypass == 2) + if (conf_parser_ctx.pass == 2) ConfigServerHide.hide_server_ips = yylval.number; };