ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/conf_parser.y
Revision: 1009
Committed: Sun Sep 13 15:02:30 2009 UTC (15 years, 11 months ago) by michael
Original Path: ircd-hybrid-7.2/src/ircd_parser.y
File size: 94494 byte(s)
Log Message:
- add configure test for pcre lib and remove pcre sources from the tree

File Contents

# User Rev Content
1 adx 30 /*
2     * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3     * ircd_parser.y: Parses the ircd configuration file.
4     *
5     * Copyright (C) 2005 by the past and present ircd coders, and others.
6     *
7     * This program is free software; you can redistribute it and/or modify
8     * it under the terms of the GNU General Public License as published by
9     * the Free Software Foundation; either version 2 of the License, or
10     * (at your option) any later version.
11     *
12     * This program is distributed in the hope that it will be useful,
13     * but WITHOUT ANY WARRANTY; without even the implied warranty of
14     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15     * GNU General Public License for more details.
16     *
17     * You should have received a copy of the GNU General Public License
18     * along with this program; if not, write to the Free Software
19     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20     * USA
21     *
22 knight 31 * $Id$
23 adx 30 */
24    
25     %{
26    
27     #define YY_NO_UNPUT
28     #include <sys/types.h>
29 stu 909 #include <string.h>
30 adx 30
31 michael 1009 #include "config.h"
32     #ifdef HAVE_LIBPCRE
33     #include <pcre.h>
34     #endif
35 adx 30 #include "stdinc.h"
36     #include "ircd.h"
37     #include "tools.h"
38     #include "list.h"
39     #include "s_conf.h"
40     #include "event.h"
41     #include "s_log.h"
42     #include "client.h" /* for UMODE_ALL only */
43     #include "irc_string.h"
44     #include "irc_getaddrinfo.h"
45     #include "sprintf_irc.h"
46     #include "memory.h"
47     #include "modules.h"
48 michael 885 #include "s_serv.h"
49 adx 30 #include "hostmask.h"
50     #include "send.h"
51     #include "listener.h"
52     #include "resv.h"
53     #include "numeric.h"
54     #include "s_user.h"
55    
56     #ifdef HAVE_LIBCRYPTO
57     #include <openssl/rsa.h>
58     #include <openssl/bio.h>
59     #include <openssl/pem.h>
60     #endif
61    
62     static char *class_name = NULL;
63     static struct ConfItem *yy_conf = NULL;
64     static struct AccessItem *yy_aconf = NULL;
65     static struct MatchItem *yy_match_item = NULL;
66     static struct ClassItem *yy_class = NULL;
67     static char *yy_class_name = NULL;
68    
69     static dlink_list col_conf_list = { NULL, NULL, 0 };
70     static dlink_list hub_conf_list = { NULL, NULL, 0 };
71     static dlink_list leaf_conf_list = { NULL, NULL, 0 };
72     static unsigned int listener_flags = 0;
73     static unsigned int regex_ban = 0;
74     static char userbuf[IRCD_BUFSIZE];
75     static char hostbuf[IRCD_BUFSIZE];
76     static char reasonbuf[REASONLEN + 1];
77     static char gecos_name[REALLEN * 4];
78    
79     extern dlink_list gdeny_items; /* XXX */
80    
81     static char *resv_reason = NULL;
82     static char *listener_address = NULL;
83     static int not_atom = 0;
84    
85 michael 593 struct CollectItem
86     {
87 adx 30 dlink_node node;
88     char *name;
89     char *user;
90     char *host;
91     char *passwd;
92     int port;
93     int flags;
94     #ifdef HAVE_LIBCRYPTO
95     char *rsa_public_key_file;
96     RSA *rsa_public_key;
97     #endif
98     };
99    
100     static void
101     free_collect_item(struct CollectItem *item)
102     {
103     MyFree(item->name);
104     MyFree(item->user);
105     MyFree(item->host);
106     MyFree(item->passwd);
107     #ifdef HAVE_LIBCRYPTO
108     MyFree(item->rsa_public_key_file);
109     #endif
110     MyFree(item);
111     }
112    
113     static void
114     unhook_hub_leaf_confs(void)
115     {
116     dlink_node *ptr;
117     dlink_node *next_ptr;
118     struct CollectItem *yy_hconf;
119     struct CollectItem *yy_lconf;
120    
121     DLINK_FOREACH_SAFE(ptr, next_ptr, hub_conf_list.head)
122     {
123     yy_hconf = ptr->data;
124     dlinkDelete(&yy_hconf->node, &hub_conf_list);
125     free_collect_item(yy_hconf);
126     }
127    
128     DLINK_FOREACH_SAFE(ptr, next_ptr, leaf_conf_list.head)
129     {
130     yy_lconf = ptr->data;
131     dlinkDelete(&yy_lconf->node, &leaf_conf_list);
132     free_collect_item(yy_lconf);
133     }
134     }
135    
136     %}
137    
138     %union {
139     int number;
140     char *string;
141     }
142    
143     %token ACCEPT_PASSWORD
144     %token ACTION
145     %token ADMIN
146     %token AFTYPE
147     %token T_ALLOW
148     %token ANTI_NICK_FLOOD
149     %token ANTI_SPAM_EXIT_MESSAGE_TIME
150     %token AUTOCONN
151     %token T_BLOCK
152     %token BURST_AWAY
153     %token BURST_TOPICWHO
154     %token BYTES KBYTES MBYTES GBYTES TBYTES
155     %token CALLER_ID_WAIT
156     %token CAN_FLOOD
157     %token CAN_IDLE
158     %token CHANNEL
159     %token CIDR_BITLEN_IPV4
160     %token CIDR_BITLEN_IPV6
161     %token CIPHER_PREFERENCE
162     %token CLASS
163     %token COMPRESSED
164     %token COMPRESSION_LEVEL
165     %token CONNECT
166     %token CONNECTFREQ
167     %token CRYPTLINK
168     %token DEFAULT_CIPHER_PREFERENCE
169     %token DEFAULT_FLOODCOUNT
170     %token DEFAULT_SPLIT_SERVER_COUNT
171     %token DEFAULT_SPLIT_USER_COUNT
172     %token DENY
173     %token DESCRIPTION
174     %token DIE
175     %token DISABLE_AUTH
176 michael 632 %token DISABLE_FAKE_CHANNELS
177 adx 30 %token DISABLE_HIDDEN
178     %token DISABLE_LOCAL_CHANNELS
179     %token DISABLE_REMOTE_COMMANDS
180     %token DOT_IN_IP6_ADDR
181     %token DOTS_IN_IDENT
182     %token DURATION
183     %token EGDPOOL_PATH
184     %token EMAIL
185     %token ENABLE
186     %token ENCRYPTED
187     %token EXCEED_LIMIT
188     %token EXEMPT
189     %token FAILED_OPER_NOTICE
190     %token FAKENAME
191     %token IRCD_FLAGS
192     %token FLATTEN_LINKS
193     %token FFAILED_OPERLOG
194     %token FKILLLOG
195     %token FKLINELOG
196     %token FGLINELOG
197     %token FIOERRLOG
198     %token FOPERLOG
199     %token FOPERSPYLOG
200     %token FUSERLOG
201     %token GECOS
202     %token GENERAL
203     %token GLINE
204     %token GLINES
205     %token GLINE_EXEMPT
206     %token GLINE_LOG
207     %token GLINE_TIME
208     %token GLINE_MIN_CIDR
209     %token GLINE_MIN_CIDR6
210     %token GLOBAL_KILL
211     %token IRCD_AUTH
212     %token NEED_IDENT
213     %token HAVENT_READ_CONF
214     %token HIDDEN
215     %token HIDDEN_ADMIN
216     %token HIDDEN_NAME
217     %token HIDDEN_OPER
218     %token HIDE_SERVER_IPS
219     %token HIDE_SERVERS
220     %token HIDE_SPOOF_IPS
221     %token HOST
222     %token HUB
223     %token HUB_MASK
224     %token IDLETIME
225     %token IGNORE_BOGUS_TS
226     %token INVISIBLE_ON_CONNECT
227     %token IP
228     %token KILL
229     %token KILL_CHASE_TIME_LIMIT
230     %token KLINE
231     %token KLINE_EXEMPT
232     %token KLINE_REASON
233     %token KLINE_WITH_REASON
234     %token KNOCK_DELAY
235     %token KNOCK_DELAY_CHANNEL
236     %token LEAF_MASK
237     %token LINKS_DELAY
238     %token LISTEN
239     %token T_LOG
240     %token LOGGING
241     %token LOG_LEVEL
242     %token MAX_ACCEPT
243     %token MAX_BANS
244     %token MAX_CHANS_PER_USER
245     %token MAX_GLOBAL
246     %token MAX_IDENT
247     %token MAX_LOCAL
248     %token MAX_NICK_CHANGES
249     %token MAX_NICK_TIME
250     %token MAX_NUMBER
251     %token MAX_TARGETS
252 michael 876 %token MAX_WATCH
253 adx 30 %token MESSAGE_LOCALE
254     %token MIN_NONWILDCARD
255     %token MIN_NONWILDCARD_SIMPLE
256     %token MODULE
257     %token MODULES
258     %token NAME
259     %token NEED_PASSWORD
260     %token NETWORK_DESC
261     %token NETWORK_NAME
262     %token NICK
263     %token NICK_CHANGES
264     %token NO_CREATE_ON_SPLIT
265     %token NO_JOIN_ON_SPLIT
266     %token NO_OPER_FLOOD
267     %token NO_TILDE
268     %token NOT
269     %token NUMBER
270     %token NUMBER_PER_IDENT
271     %token NUMBER_PER_CIDR
272     %token NUMBER_PER_IP
273     %token NUMBER_PER_IP_GLOBAL
274     %token OPERATOR
275     %token OPERS_BYPASS_CALLERID
276     %token OPER_LOG
277     %token OPER_ONLY_UMODES
278     %token OPER_PASS_RESV
279     %token OPER_SPY_T
280     %token OPER_UMODES
281     %token JOIN_FLOOD_COUNT
282     %token JOIN_FLOOD_TIME
283     %token PACE_WAIT
284     %token PACE_WAIT_SIMPLE
285     %token PASSWORD
286     %token PATH
287     %token PING_COOKIE
288     %token PING_TIME
289     %token PING_WARNING
290     %token PORT
291     %token QSTRING
292     %token QUIET_ON_BAN
293     %token REASON
294     %token REDIRPORT
295     %token REDIRSERV
296     %token REGEX_T
297     %token REHASH
298     %token TREJECT_HOLD_TIME
299     %token REMOTE
300     %token REMOTEBAN
301     %token RESTRICT_CHANNELS
302     %token RESTRICTED
303     %token RSA_PRIVATE_KEY_FILE
304     %token RSA_PUBLIC_KEY_FILE
305     %token SSL_CERTIFICATE_FILE
306 michael 967 %token T_SSL_CONNECTION_METHOD
307     %token T_SSLV3
308     %token T_TLSV1
309 adx 30 %token RESV
310     %token RESV_EXEMPT
311     %token SECONDS MINUTES HOURS DAYS WEEKS
312     %token SENDQ
313     %token SEND_PASSWORD
314     %token SERVERHIDE
315     %token SERVERINFO
316     %token SERVLINK_PATH
317     %token IRCD_SID
318     %token TKLINE_EXPIRE_NOTICES
319     %token T_SHARED
320     %token T_CLUSTER
321     %token TYPE
322     %token SHORT_MOTD
323     %token SILENT
324     %token SPOOF
325     %token SPOOF_NOTICE
326 michael 584 %token STATS_E_DISABLED
327 adx 30 %token STATS_I_OPER_ONLY
328     %token STATS_K_OPER_ONLY
329     %token STATS_O_OPER_ONLY
330     %token STATS_P_OPER_ONLY
331     %token TBOOL
332     %token TMASKED
333     %token T_REJECT
334     %token TS_MAX_DELTA
335     %token TS_WARN_DELTA
336     %token TWODOTS
337     %token T_ALL
338     %token T_BOTS
339     %token T_SOFTCALLERID
340     %token T_CALLERID
341     %token T_CCONN
342 db 849 %token T_CCONN_FULL
343 adx 30 %token T_CLIENT_FLOOD
344     %token T_DEAF
345     %token T_DEBUG
346     %token T_DRONE
347     %token T_EXTERNAL
348     %token T_FULL
349     %token T_INVISIBLE
350     %token T_IPV4
351     %token T_IPV6
352     %token T_LOCOPS
353     %token T_LOGPATH
354     %token T_L_CRIT
355     %token T_L_DEBUG
356     %token T_L_ERROR
357     %token T_L_INFO
358     %token T_L_NOTICE
359     %token T_L_TRACE
360     %token T_L_WARN
361     %token T_MAX_CLIENTS
362     %token T_NCHANGE
363     %token T_OPERWALL
364     %token T_REJ
365 michael 900 %token T_SERVER
366 adx 30 %token T_SERVNOTICE
367     %token T_SKILL
368     %token T_SPY
369     %token T_SSL
370 michael 56 %token T_UMODES
371 adx 30 %token T_UNAUTH
372     %token T_UNRESV
373     %token T_UNXLINE
374     %token T_WALLOP
375     %token THROTTLE_TIME
376     %token TOPICBURST
377     %token TRUE_NO_OPER_FLOOD
378     %token TKLINE
379     %token TXLINE
380     %token TRESV
381     %token UNKLINE
382     %token USER
383     %token USE_EGD
384     %token USE_EXCEPT
385     %token USE_INVEX
386     %token USE_KNOCK
387     %token USE_LOGGING
388     %token USE_WHOIS_ACTUALLY
389     %token VHOST
390     %token VHOST6
391     %token XLINE
392     %token WARN
393     %token WARN_NO_NLINE
394    
395     %type <string> QSTRING
396     %type <number> NUMBER
397     %type <number> timespec
398     %type <number> timespec_
399     %type <number> sizespec
400     %type <number> sizespec_
401    
402     %%
403     conf:
404     | conf conf_item
405     ;
406    
407     conf_item: admin_entry
408     | logging_entry
409     | oper_entry
410     | channel_entry
411     | class_entry
412     | listen_entry
413     | auth_entry
414     | serverinfo_entry
415     | serverhide_entry
416     | resv_entry
417     | shared_entry
418     | cluster_entry
419     | connect_entry
420     | kill_entry
421     | deny_entry
422     | exempt_entry
423     | general_entry
424     | gline_entry
425     | gecos_entry
426     | modules_entry
427     | error ';'
428     | error '}'
429     ;
430    
431    
432     timespec_: { $$ = 0; } | timespec;
433     timespec: NUMBER timespec_
434     {
435     $$ = $1 + $2;
436     }
437     | NUMBER SECONDS timespec_
438     {
439     $$ = $1 + $3;
440     }
441     | NUMBER MINUTES timespec_
442     {
443     $$ = $1 * 60 + $3;
444     }
445     | NUMBER HOURS timespec_
446     {
447     $$ = $1 * 60 * 60 + $3;
448     }
449     | NUMBER DAYS timespec_
450     {
451     $$ = $1 * 60 * 60 * 24 + $3;
452     }
453     | NUMBER WEEKS timespec_
454     {
455     $$ = $1 * 60 * 60 * 24 * 7 + $3;
456     }
457     ;
458    
459     sizespec_: { $$ = 0; } | sizespec;
460     sizespec: NUMBER sizespec_ { $$ = $1 + $2; }
461     | NUMBER BYTES sizespec_ { $$ = $1 + $3; }
462     | NUMBER KBYTES sizespec_ { $$ = $1 * 1024 + $3; }
463     | NUMBER MBYTES sizespec_ { $$ = $1 * 1024 * 1024 + $3; }
464     ;
465    
466    
467     /***************************************************************************
468     * section modules
469     ***************************************************************************/
470     modules_entry: MODULES
471     '{' modules_items '}' ';';
472    
473     modules_items: modules_items modules_item | modules_item;
474     modules_item: modules_module | modules_path | error ';' ;
475    
476     modules_module: MODULE '=' QSTRING ';'
477     {
478     #ifndef STATIC_MODULES /* NOOP in the static case */
479 michael 967 if (conf_parser_ctx.pass == 2)
480 michael 978 add_conf_module(libio_basename(yylval.string));
481 adx 30 #endif
482     };
483    
484     modules_path: PATH '=' QSTRING ';'
485     {
486     #ifndef STATIC_MODULES
487 michael 967 if (conf_parser_ctx.pass == 2)
488 adx 30 mod_add_path(yylval.string);
489     #endif
490     };
491    
492    
493 michael 967 serverinfo_entry: SERVERINFO '{' serverinfo_items '}' ';';
494    
495     serverinfo_items: serverinfo_items serverinfo_item | serverinfo_item ;
496 adx 30 serverinfo_item: serverinfo_name | serverinfo_vhost |
497     serverinfo_hub | serverinfo_description |
498     serverinfo_network_name | serverinfo_network_desc |
499     serverinfo_max_clients |
500     serverinfo_rsa_private_key_file | serverinfo_vhost6 |
501     serverinfo_sid | serverinfo_ssl_certificate_file |
502 michael 967 serverinfo_ssl_connection_method |
503 adx 30 error ';' ;
504    
505 michael 967
506     serverinfo_ssl_connection_method: T_SSL_CONNECTION_METHOD
507     {
508     if (conf_parser_ctx.boot && conf_parser_ctx.pass == 2)
509     ServerInfo.tls_version = 0;
510     } '=' method_types ';'
511     {
512     if (conf_parser_ctx.boot && conf_parser_ctx.pass == 2)
513     {
514     if (!(ServerInfo.tls_version & CONF_SERVER_INFO_TLS_VERSION_SSLV3))
515     SSL_CTX_set_options(ServerInfo.server_ctx, SSL_OP_NO_SSLv3);
516     if (!(ServerInfo.tls_version & CONF_SERVER_INFO_TLS_VERSION_TLSV1))
517     SSL_CTX_set_options(ServerInfo.server_ctx, SSL_OP_NO_TLSv1);
518     }
519     };
520    
521     method_types: method_types ',' method_type_item | method_type_item;
522     method_type_item: T_SSLV3
523     {
524     if (conf_parser_ctx.boot && conf_parser_ctx.pass == 2)
525     ServerInfo.tls_version |= CONF_SERVER_INFO_TLS_VERSION_SSLV3;
526     } | T_TLSV1
527     {
528     if (conf_parser_ctx.boot && conf_parser_ctx.pass == 2)
529     ServerInfo.tls_version |= CONF_SERVER_INFO_TLS_VERSION_TLSV1;
530     };
531    
532 adx 30 serverinfo_ssl_certificate_file: SSL_CERTIFICATE_FILE '=' QSTRING ';'
533     {
534     #ifdef HAVE_LIBCRYPTO
535 michael 967 if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx)
536 adx 30 {
537     if (!ServerInfo.rsa_private_key_file)
538     {
539     yyerror("No rsa_private_key_file specified, SSL disabled");
540     break;
541     }
542    
543 michael 967 if (SSL_CTX_use_certificate_file(ServerInfo.server_ctx, yylval.string,
544     SSL_FILETYPE_PEM) <= 0)
545 adx 30 {
546     yyerror(ERR_lib_error_string(ERR_get_error()));
547     break;
548     }
549    
550 michael 967 if (SSL_CTX_use_PrivateKey_file(ServerInfo.server_ctx, ServerInfo.rsa_private_key_file,
551     SSL_FILETYPE_PEM) <= 0)
552 adx 30 {
553     yyerror(ERR_lib_error_string(ERR_get_error()));
554     break;
555     }
556    
557 michael 967 if (!SSL_CTX_check_private_key(ServerInfo.server_ctx))
558 adx 30 {
559 michael 967 yyerror(ERR_lib_error_string(ERR_get_error()));
560 adx 30 break;
561     }
562     }
563     #endif
564     };
565    
566     serverinfo_rsa_private_key_file: RSA_PRIVATE_KEY_FILE '=' QSTRING ';'
567     {
568     #ifdef HAVE_LIBCRYPTO
569 michael 967 if (conf_parser_ctx.pass == 1)
570 adx 30 {
571     BIO *file;
572    
573     if (ServerInfo.rsa_private_key)
574     {
575     RSA_free(ServerInfo.rsa_private_key);
576     ServerInfo.rsa_private_key = NULL;
577     }
578    
579     if (ServerInfo.rsa_private_key_file)
580     {
581     MyFree(ServerInfo.rsa_private_key_file);
582     ServerInfo.rsa_private_key_file = NULL;
583     }
584    
585     DupString(ServerInfo.rsa_private_key_file, yylval.string);
586    
587     if ((file = BIO_new_file(yylval.string, "r")) == NULL)
588     {
589     yyerror("File open failed, ignoring");
590     break;
591     }
592    
593     ServerInfo.rsa_private_key = (RSA *)PEM_read_bio_RSAPrivateKey(file, NULL,
594     0, NULL);
595    
596     BIO_set_close(file, BIO_CLOSE);
597     BIO_free(file);
598    
599     if (ServerInfo.rsa_private_key == NULL)
600     {
601     yyerror("Couldn't extract key, ignoring");
602     break;
603     }
604    
605     if (!RSA_check_key(ServerInfo.rsa_private_key))
606     {
607     RSA_free(ServerInfo.rsa_private_key);
608     ServerInfo.rsa_private_key = NULL;
609    
610     yyerror("Invalid key, ignoring");
611     break;
612     }
613    
614     /* require 2048 bit (256 byte) key */
615     if (RSA_size(ServerInfo.rsa_private_key) != 256)
616     {
617     RSA_free(ServerInfo.rsa_private_key);
618     ServerInfo.rsa_private_key = NULL;
619    
620     yyerror("Not a 2048 bit key, ignoring");
621     }
622     }
623     #endif
624     };
625    
626     serverinfo_name: NAME '=' QSTRING ';'
627     {
628     /* this isn't rehashable */
629 michael 967 if (conf_parser_ctx.pass == 2)
630 adx 30 {
631     if (ServerInfo.name == NULL)
632     {
633     /* the ircd will exit() in main() if we dont set one */
634     if (strlen(yylval.string) <= HOSTLEN)
635     DupString(ServerInfo.name, yylval.string);
636     }
637     }
638     };
639    
640     serverinfo_sid: IRCD_SID '=' QSTRING ';'
641     {
642     /* this isn't rehashable */
643 michael 967 if (conf_parser_ctx.pass == 2 && !ServerInfo.sid)
644 adx 30 {
645 michael 573 if (valid_sid(yylval.string))
646 adx 30 DupString(ServerInfo.sid, yylval.string);
647     else
648     {
649     ilog(L_ERROR, "Ignoring config file entry SID -- invalid SID. Aborting.");
650     exit(0);
651     }
652     }
653     };
654    
655     serverinfo_description: DESCRIPTION '=' QSTRING ';'
656     {
657 michael 967 if (conf_parser_ctx.pass == 2)
658 adx 30 {
659     MyFree(ServerInfo.description);
660     DupString(ServerInfo.description,yylval.string);
661     }
662     };
663    
664     serverinfo_network_name: NETWORK_NAME '=' QSTRING ';'
665     {
666 michael 967 if (conf_parser_ctx.pass == 2)
667 adx 30 {
668     char *p;
669    
670     if ((p = strchr(yylval.string, ' ')) != NULL)
671     p = '\0';
672    
673     MyFree(ServerInfo.network_name);
674     DupString(ServerInfo.network_name, yylval.string);
675     }
676     };
677    
678     serverinfo_network_desc: NETWORK_DESC '=' QSTRING ';'
679     {
680 michael 967 if (conf_parser_ctx.pass == 2)
681 adx 30 {
682     MyFree(ServerInfo.network_desc);
683     DupString(ServerInfo.network_desc, yylval.string);
684     }
685     };
686    
687     serverinfo_vhost: VHOST '=' QSTRING ';'
688     {
689 michael 967 if (conf_parser_ctx.pass == 2 && *yylval.string != '*')
690 adx 30 {
691     struct addrinfo hints, *res;
692    
693     memset(&hints, 0, sizeof(hints));
694    
695     hints.ai_family = AF_UNSPEC;
696     hints.ai_socktype = SOCK_STREAM;
697     hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
698    
699     if (irc_getaddrinfo(yylval.string, NULL, &hints, &res))
700     ilog(L_ERROR, "Invalid netmask for server vhost(%s)", yylval.string);
701     else
702     {
703     assert(res != NULL);
704    
705     memcpy(&ServerInfo.ip, res->ai_addr, res->ai_addrlen);
706     ServerInfo.ip.ss.ss_family = res->ai_family;
707     ServerInfo.ip.ss_len = res->ai_addrlen;
708     irc_freeaddrinfo(res);
709    
710     ServerInfo.specific_ipv4_vhost = 1;
711     }
712     }
713     };
714    
715     serverinfo_vhost6: VHOST6 '=' QSTRING ';'
716     {
717     #ifdef IPV6
718 michael 967 if (conf_parser_ctx.pass == 2 && *yylval.string != '*')
719 adx 30 {
720     struct addrinfo hints, *res;
721    
722     memset(&hints, 0, sizeof(hints));
723    
724     hints.ai_family = AF_UNSPEC;
725     hints.ai_socktype = SOCK_STREAM;
726     hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
727    
728     if (irc_getaddrinfo(yylval.string, NULL, &hints, &res))
729     ilog(L_ERROR, "Invalid netmask for server vhost6(%s)", yylval.string);
730     else
731     {
732     assert(res != NULL);
733    
734     memcpy(&ServerInfo.ip6, res->ai_addr, res->ai_addrlen);
735     ServerInfo.ip6.ss.ss_family = res->ai_family;
736     ServerInfo.ip6.ss_len = res->ai_addrlen;
737     irc_freeaddrinfo(res);
738    
739     ServerInfo.specific_ipv6_vhost = 1;
740     }
741     }
742     #endif
743     };
744    
745     serverinfo_max_clients: T_MAX_CLIENTS '=' NUMBER ';'
746     {
747 michael 967 if (conf_parser_ctx.pass == 2)
748 adx 30 {
749     recalc_fdlimit(NULL);
750    
751     if ($3 < MAXCLIENTS_MIN)
752     {
753     char buf[IRCD_BUFSIZE];
754     ircsprintf(buf, "MAXCLIENTS too low, setting to %d", MAXCLIENTS_MIN);
755     yyerror(buf);
756     }
757     else if ($3 > MAXCLIENTS_MAX)
758     {
759     char buf[IRCD_BUFSIZE];
760     ircsprintf(buf, "MAXCLIENTS too high, setting to %d", MAXCLIENTS_MAX);
761     yyerror(buf);
762     }
763     else
764     ServerInfo.max_clients = $3;
765     }
766     };
767    
768     serverinfo_hub: HUB '=' TBOOL ';'
769     {
770 michael 967 if (conf_parser_ctx.pass == 2)
771 adx 30 {
772     if (yylval.number)
773     {
774 michael 885 ServerInfo.hub = 1;
775     delete_capability("HUB");
776     add_capability("HUB", CAP_HUB, 1);
777 adx 30 }
778     else if (ServerInfo.hub)
779     {
780    
781     ServerInfo.hub = 0;
782     delete_capability("HUB");
783     }
784     }
785     };
786    
787     /***************************************************************************
788     * admin section
789     ***************************************************************************/
790     admin_entry: ADMIN '{' admin_items '}' ';' ;
791    
792     admin_items: admin_items admin_item | admin_item;
793     admin_item: admin_name | admin_description |
794     admin_email | error ';' ;
795    
796     admin_name: NAME '=' QSTRING ';'
797     {
798 michael 967 if (conf_parser_ctx.pass == 2)
799 adx 30 {
800     MyFree(AdminInfo.name);
801     DupString(AdminInfo.name, yylval.string);
802     }
803     };
804    
805     admin_email: EMAIL '=' QSTRING ';'
806     {
807 michael 967 if (conf_parser_ctx.pass == 2)
808 adx 30 {
809     MyFree(AdminInfo.email);
810     DupString(AdminInfo.email, yylval.string);
811     }
812     };
813    
814     admin_description: DESCRIPTION '=' QSTRING ';'
815     {
816 michael 967 if (conf_parser_ctx.pass == 2)
817 adx 30 {
818     MyFree(AdminInfo.description);
819     DupString(AdminInfo.description, yylval.string);
820     }
821     };
822    
823     /***************************************************************************
824     * section logging
825     ***************************************************************************/
826     /* XXX */
827     logging_entry: LOGGING '{' logging_items '}' ';' ;
828    
829     logging_items: logging_items logging_item |
830     logging_item ;
831    
832     logging_item: logging_path | logging_oper_log |
833     logging_log_level |
834     logging_use_logging | logging_fuserlog |
835     logging_foperlog | logging_fglinelog |
836     logging_fklinelog | logging_killlog |
837     logging_foperspylog | logging_ioerrlog |
838     logging_ffailed_operlog |
839     error ';' ;
840    
841     logging_path: T_LOGPATH '=' QSTRING ';'
842     {
843     };
844    
845     logging_oper_log: OPER_LOG '=' QSTRING ';'
846     {
847     };
848    
849     logging_fuserlog: FUSERLOG '=' QSTRING ';'
850     {
851 michael 967 if (conf_parser_ctx.pass == 2)
852 adx 30 strlcpy(ConfigLoggingEntry.userlog, yylval.string,
853     sizeof(ConfigLoggingEntry.userlog));
854     };
855    
856     logging_ffailed_operlog: FFAILED_OPERLOG '=' QSTRING ';'
857     {
858 michael 967 if (conf_parser_ctx.pass == 2)
859 adx 30 strlcpy(ConfigLoggingEntry.failed_operlog, yylval.string,
860     sizeof(ConfigLoggingEntry.failed_operlog));
861     };
862    
863     logging_foperlog: FOPERLOG '=' QSTRING ';'
864     {
865 michael 967 if (conf_parser_ctx.pass == 2)
866 adx 30 strlcpy(ConfigLoggingEntry.operlog, yylval.string,
867     sizeof(ConfigLoggingEntry.operlog));
868     };
869    
870     logging_foperspylog: FOPERSPYLOG '=' QSTRING ';'
871     {
872 michael 967 if (conf_parser_ctx.pass == 2)
873 adx 30 strlcpy(ConfigLoggingEntry.operspylog, yylval.string,
874     sizeof(ConfigLoggingEntry.operspylog));
875     };
876    
877     logging_fglinelog: FGLINELOG '=' QSTRING ';'
878     {
879 michael 967 if (conf_parser_ctx.pass == 2)
880 adx 30 strlcpy(ConfigLoggingEntry.glinelog, yylval.string,
881     sizeof(ConfigLoggingEntry.glinelog));
882     };
883    
884     logging_fklinelog: FKLINELOG '=' QSTRING ';'
885     {
886 michael 967 if (conf_parser_ctx.pass == 2)
887 adx 30 strlcpy(ConfigLoggingEntry.klinelog, yylval.string,
888     sizeof(ConfigLoggingEntry.klinelog));
889     };
890    
891     logging_ioerrlog: FIOERRLOG '=' QSTRING ';'
892     {
893 michael 967 if (conf_parser_ctx.pass == 2)
894 adx 30 strlcpy(ConfigLoggingEntry.ioerrlog, yylval.string,
895     sizeof(ConfigLoggingEntry.ioerrlog));
896     };
897    
898     logging_killlog: FKILLLOG '=' QSTRING ';'
899     {
900 michael 967 if (conf_parser_ctx.pass == 2)
901 adx 30 strlcpy(ConfigLoggingEntry.killlog, yylval.string,
902     sizeof(ConfigLoggingEntry.killlog));
903     };
904    
905     logging_log_level: LOG_LEVEL '=' T_L_CRIT ';'
906     {
907 michael 967 if (conf_parser_ctx.pass == 2)
908 adx 30 set_log_level(L_CRIT);
909     } | LOG_LEVEL '=' T_L_ERROR ';'
910     {
911 michael 967 if (conf_parser_ctx.pass == 2)
912 adx 30 set_log_level(L_ERROR);
913     } | LOG_LEVEL '=' T_L_WARN ';'
914     {
915 michael 967 if (conf_parser_ctx.pass == 2)
916 adx 30 set_log_level(L_WARN);
917     } | LOG_LEVEL '=' T_L_NOTICE ';'
918     {
919 michael 967 if (conf_parser_ctx.pass == 2)
920 adx 30 set_log_level(L_NOTICE);
921     } | LOG_LEVEL '=' T_L_TRACE ';'
922     {
923 michael 967 if (conf_parser_ctx.pass == 2)
924 adx 30 set_log_level(L_TRACE);
925     } | LOG_LEVEL '=' T_L_INFO ';'
926     {
927 michael 967 if (conf_parser_ctx.pass == 2)
928 adx 30 set_log_level(L_INFO);
929     } | LOG_LEVEL '=' T_L_DEBUG ';'
930     {
931 michael 967 if (conf_parser_ctx.pass == 2)
932 adx 30 set_log_level(L_DEBUG);
933     };
934    
935     logging_use_logging: USE_LOGGING '=' TBOOL ';'
936     {
937 michael 967 if (conf_parser_ctx.pass == 2)
938 adx 30 ConfigLoggingEntry.use_logging = yylval.number;
939     };
940    
941     /***************************************************************************
942     * section oper
943     ***************************************************************************/
944     oper_entry: OPERATOR
945     {
946 michael 967 if (conf_parser_ctx.pass == 2)
947 adx 30 {
948     yy_conf = make_conf_item(OPER_TYPE);
949     yy_aconf = map_to_conf(yy_conf);
950     SetConfEncrypted(yy_aconf); /* Yes, the default is encrypted */
951     }
952     else
953     {
954     MyFree(class_name);
955     class_name = NULL;
956     }
957     } oper_name_b '{' oper_items '}' ';'
958     {
959 michael 967 if (conf_parser_ctx.pass == 2)
960 adx 30 {
961     struct CollectItem *yy_tmp;
962     dlink_node *ptr;
963     dlink_node *next_ptr;
964    
965     conf_add_class_to_conf(yy_conf, class_name);
966    
967     /* Now, make sure there is a copy of the "base" given oper
968     * block in each of the collected copies
969     */
970    
971     DLINK_FOREACH_SAFE(ptr, next_ptr, col_conf_list.head)
972     {
973     struct AccessItem *new_aconf;
974     struct ConfItem *new_conf;
975     yy_tmp = ptr->data;
976    
977     new_conf = make_conf_item(OPER_TYPE);
978     new_aconf = (struct AccessItem *)map_to_conf(new_conf);
979    
980     new_aconf->flags = yy_aconf->flags;
981    
982     if (yy_conf->name != NULL)
983     DupString(new_conf->name, yy_conf->name);
984     if (yy_tmp->user != NULL)
985     DupString(new_aconf->user, yy_tmp->user);
986     else
987     DupString(new_aconf->user, "*");
988     if (yy_tmp->host != NULL)
989     DupString(new_aconf->host, yy_tmp->host);
990     else
991     DupString(new_aconf->host, "*");
992     conf_add_class_to_conf(new_conf, class_name);
993     if (yy_aconf->passwd != NULL)
994     DupString(new_aconf->passwd, yy_aconf->passwd);
995    
996     new_aconf->port = yy_aconf->port;
997     #ifdef HAVE_LIBCRYPTO
998     if (yy_aconf->rsa_public_key_file != NULL)
999     {
1000     BIO *file;
1001    
1002     DupString(new_aconf->rsa_public_key_file,
1003     yy_aconf->rsa_public_key_file);
1004    
1005     file = BIO_new_file(yy_aconf->rsa_public_key_file, "r");
1006     new_aconf->rsa_public_key = (RSA *)PEM_read_bio_RSA_PUBKEY(file,
1007     NULL, 0, NULL);
1008     BIO_set_close(file, BIO_CLOSE);
1009     BIO_free(file);
1010     }
1011     #endif
1012    
1013     #ifdef HAVE_LIBCRYPTO
1014     if (yy_tmp->name && (yy_tmp->passwd || yy_aconf->rsa_public_key)
1015     && yy_tmp->host)
1016     #else
1017     if (yy_tmp->name && yy_tmp->passwd && yy_tmp->host)
1018     #endif
1019     {
1020     conf_add_class_to_conf(new_conf, class_name);
1021     if (yy_tmp->name != NULL)
1022     DupString(new_conf->name, yy_tmp->name);
1023     }
1024    
1025     dlinkDelete(&yy_tmp->node, &col_conf_list);
1026     free_collect_item(yy_tmp);
1027     }
1028    
1029     yy_conf = NULL;
1030     yy_aconf = NULL;
1031    
1032    
1033     MyFree(class_name);
1034     class_name = NULL;
1035     }
1036     };
1037    
1038     oper_name_b: | oper_name_t;
1039     oper_items: oper_items oper_item | oper_item;
1040     oper_item: oper_name | oper_user | oper_password | oper_hidden_admin |
1041 michael 56 oper_hidden_oper | oper_umodes |
1042 adx 30 oper_class | oper_global_kill | oper_remote |
1043     oper_kline | oper_xline | oper_unkline |
1044     oper_gline | oper_nick_changes | oper_remoteban |
1045     oper_die | oper_rehash | oper_admin | oper_operwall |
1046     oper_encrypted | oper_rsa_public_key_file |
1047     oper_flags | error ';' ;
1048    
1049     oper_name: NAME '=' QSTRING ';'
1050     {
1051 michael 967 if (conf_parser_ctx.pass == 2)
1052 adx 30 {
1053     if (strlen(yylval.string) > OPERNICKLEN)
1054     yylval.string[OPERNICKLEN] = '\0';
1055    
1056     MyFree(yy_conf->name);
1057     DupString(yy_conf->name, yylval.string);
1058     }
1059     };
1060    
1061     oper_name_t: QSTRING
1062     {
1063 michael 967 if (conf_parser_ctx.pass == 2)
1064 adx 30 {
1065     if (strlen(yylval.string) > OPERNICKLEN)
1066     yylval.string[OPERNICKLEN] = '\0';
1067    
1068     MyFree(yy_conf->name);
1069     DupString(yy_conf->name, yylval.string);
1070     }
1071     };
1072    
1073     oper_user: USER '=' QSTRING ';'
1074     {
1075 michael 967 if (conf_parser_ctx.pass == 2)
1076 adx 30 {
1077 michael 593 struct split_nuh_item nuh;
1078 adx 30
1079 michael 593 nuh.nuhmask = yylval.string;
1080     nuh.nickptr = NULL;
1081     nuh.userptr = userbuf;
1082     nuh.hostptr = hostbuf;
1083    
1084     nuh.nicksize = 0;
1085     nuh.usersize = sizeof(userbuf);
1086     nuh.hostsize = sizeof(hostbuf);
1087    
1088     split_nuh(&nuh);
1089    
1090 adx 30 if (yy_aconf->user == NULL)
1091     {
1092 michael 593 DupString(yy_aconf->user, userbuf);
1093     DupString(yy_aconf->host, hostbuf);
1094 adx 30 }
1095     else
1096     {
1097 michael 593 struct CollectItem *yy_tmp = MyMalloc(sizeof(struct CollectItem));
1098    
1099     DupString(yy_tmp->user, userbuf);
1100     DupString(yy_tmp->host, hostbuf);
1101    
1102 adx 30 dlinkAdd(yy_tmp, &yy_tmp->node, &col_conf_list);
1103     }
1104     }
1105     };
1106    
1107     oper_password: PASSWORD '=' QSTRING ';'
1108     {
1109 michael 967 if (conf_parser_ctx.pass == 2)
1110 adx 30 {
1111     if (yy_aconf->passwd != NULL)
1112     memset(yy_aconf->passwd, 0, strlen(yy_aconf->passwd));
1113    
1114     MyFree(yy_aconf->passwd);
1115     DupString(yy_aconf->passwd, yylval.string);
1116     }
1117     };
1118    
1119     oper_encrypted: ENCRYPTED '=' TBOOL ';'
1120     {
1121 michael 967 if (conf_parser_ctx.pass == 2)
1122 adx 30 {
1123     if (yylval.number)
1124     SetConfEncrypted(yy_aconf);
1125     else
1126     ClearConfEncrypted(yy_aconf);
1127     }
1128     };
1129    
1130     oper_rsa_public_key_file: RSA_PUBLIC_KEY_FILE '=' QSTRING ';'
1131     {
1132     #ifdef HAVE_LIBCRYPTO
1133 michael 967 if (conf_parser_ctx.pass == 2)
1134 adx 30 {
1135     BIO *file;
1136    
1137     if (yy_aconf->rsa_public_key != NULL)
1138     {
1139     RSA_free(yy_aconf->rsa_public_key);
1140     yy_aconf->rsa_public_key = NULL;
1141     }
1142    
1143     if (yy_aconf->rsa_public_key_file != NULL)
1144     {
1145     MyFree(yy_aconf->rsa_public_key_file);
1146     yy_aconf->rsa_public_key_file = NULL;
1147     }
1148    
1149     DupString(yy_aconf->rsa_public_key_file, yylval.string);
1150     file = BIO_new_file(yylval.string, "r");
1151    
1152     if (file == NULL)
1153     {
1154     yyerror("Ignoring rsa_public_key_file -- file doesn't exist");
1155     break;
1156     }
1157    
1158     yy_aconf->rsa_public_key = (RSA *)PEM_read_bio_RSA_PUBKEY(file, NULL, 0, NULL);
1159    
1160     if (yy_aconf->rsa_public_key == NULL)
1161     {
1162     yyerror("Ignoring rsa_public_key_file -- Key invalid; check key syntax.");
1163     break;
1164     }
1165    
1166     BIO_set_close(file, BIO_CLOSE);
1167     BIO_free(file);
1168     }
1169     #endif /* HAVE_LIBCRYPTO */
1170     };
1171    
1172     oper_class: CLASS '=' QSTRING ';'
1173     {
1174 michael 967 if (conf_parser_ctx.pass == 2)
1175 adx 30 {
1176     MyFree(class_name);
1177     DupString(class_name, yylval.string);
1178     }
1179     };
1180    
1181 michael 56 oper_umodes: T_UMODES
1182     {
1183 michael 967 if (conf_parser_ctx.pass == 2)
1184 db 298 yy_aconf->modes = 0;
1185 michael 56 } '=' oper_umodes_items ';' ;
1186    
1187     oper_umodes_items: oper_umodes_items ',' oper_umodes_item | oper_umodes_item;
1188     oper_umodes_item: T_BOTS
1189     {
1190 michael 967 if (conf_parser_ctx.pass == 2)
1191 db 298 yy_aconf->modes |= UMODE_BOTS;
1192 michael 56 } | T_CCONN
1193     {
1194 michael 967 if (conf_parser_ctx.pass == 2)
1195 db 298 yy_aconf->modes |= UMODE_CCONN;
1196 db 849 } | T_CCONN_FULL
1197     {
1198 michael 967 if (conf_parser_ctx.pass == 2)
1199 db 849 yy_aconf->modes |= UMODE_CCONN_FULL;
1200 michael 56 } | T_DEAF
1201     {
1202 michael 967 if (conf_parser_ctx.pass == 2)
1203 db 298 yy_aconf->modes |= UMODE_DEAF;
1204 michael 56 } | T_DEBUG
1205     {
1206 michael 967 if (conf_parser_ctx.pass == 2)
1207 db 298 yy_aconf->modes |= UMODE_DEBUG;
1208 michael 56 } | T_FULL
1209     {
1210 michael 967 if (conf_parser_ctx.pass == 2)
1211 db 298 yy_aconf->modes |= UMODE_FULL;
1212 michael 56 } | T_SKILL
1213     {
1214 michael 967 if (conf_parser_ctx.pass == 2)
1215 db 298 yy_aconf->modes |= UMODE_SKILL;
1216 michael 56 } | T_NCHANGE
1217     {
1218 michael 967 if (conf_parser_ctx.pass == 2)
1219 db 298 yy_aconf->modes |= UMODE_NCHANGE;
1220 michael 56 } | T_REJ
1221     {
1222 michael 967 if (conf_parser_ctx.pass == 2)
1223 db 298 yy_aconf->modes |= UMODE_REJ;
1224 michael 56 } | T_UNAUTH
1225     {
1226 michael 967 if (conf_parser_ctx.pass == 2)
1227 db 298 yy_aconf->modes |= UMODE_UNAUTH;
1228 michael 56 } | T_SPY
1229     {
1230 michael 967 if (conf_parser_ctx.pass == 2)
1231 db 298 yy_aconf->modes |= UMODE_SPY;
1232 michael 56 } | T_EXTERNAL
1233     {
1234 michael 967 if (conf_parser_ctx.pass == 2)
1235 db 298 yy_aconf->modes |= UMODE_EXTERNAL;
1236 michael 56 } | T_OPERWALL
1237     {
1238 michael 967 if (conf_parser_ctx.pass == 2)
1239 db 298 yy_aconf->modes |= UMODE_OPERWALL;
1240 michael 56 } | T_SERVNOTICE
1241     {
1242 michael 967 if (conf_parser_ctx.pass == 2)
1243 db 298 yy_aconf->modes |= UMODE_SERVNOTICE;
1244 michael 56 } | T_INVISIBLE
1245     {
1246 michael 967 if (conf_parser_ctx.pass == 2)
1247 db 298 yy_aconf->modes |= UMODE_INVISIBLE;
1248 michael 56 } | T_WALLOP
1249     {
1250 michael 967 if (conf_parser_ctx.pass == 2)
1251 db 298 yy_aconf->modes |= UMODE_WALLOP;
1252 michael 56 } | T_SOFTCALLERID
1253     {
1254 michael 967 if (conf_parser_ctx.pass == 2)
1255 db 298 yy_aconf->modes |= UMODE_SOFTCALLERID;
1256 michael 56 } | T_CALLERID
1257     {
1258 michael 967 if (conf_parser_ctx.pass == 2)
1259 db 298 yy_aconf->modes |= UMODE_CALLERID;
1260 michael 56 } | T_LOCOPS
1261     {
1262 michael 967 if (conf_parser_ctx.pass == 2)
1263 db 298 yy_aconf->modes |= UMODE_LOCOPS;
1264 michael 56 };
1265    
1266 adx 30 oper_global_kill: GLOBAL_KILL '=' TBOOL ';'
1267     {
1268 michael 967 if (conf_parser_ctx.pass == 2)
1269 adx 30 {
1270     if (yylval.number)
1271     yy_aconf->port |= OPER_FLAG_GLOBAL_KILL;
1272     else
1273     yy_aconf->port &= ~OPER_FLAG_GLOBAL_KILL;
1274     }
1275     };
1276    
1277     oper_remote: REMOTE '=' TBOOL ';'
1278     {
1279 michael 967 if (conf_parser_ctx.pass == 2)
1280 adx 30 {
1281     if (yylval.number)
1282     yy_aconf->port |= OPER_FLAG_REMOTE;
1283     else
1284     yy_aconf->port &= ~OPER_FLAG_REMOTE;
1285     }
1286     };
1287    
1288     oper_remoteban: REMOTEBAN '=' TBOOL ';'
1289     {
1290 michael 967 if (conf_parser_ctx.pass == 2)
1291 adx 30 {
1292     if (yylval.number)
1293     yy_aconf->port |= OPER_FLAG_REMOTEBAN;
1294     else
1295     yy_aconf->port &= ~OPER_FLAG_REMOTEBAN;
1296     }
1297     };
1298    
1299     oper_kline: KLINE '=' TBOOL ';'
1300     {
1301 michael 967 if (conf_parser_ctx.pass == 2)
1302 adx 30 {
1303     if (yylval.number)
1304     yy_aconf->port |= OPER_FLAG_K;
1305     else
1306     yy_aconf->port &= ~OPER_FLAG_K;
1307     }
1308     };
1309    
1310     oper_xline: XLINE '=' TBOOL ';'
1311     {
1312 michael 967 if (conf_parser_ctx.pass == 2)
1313 adx 30 {
1314     if (yylval.number)
1315     yy_aconf->port |= OPER_FLAG_X;
1316     else
1317     yy_aconf->port &= ~OPER_FLAG_X;
1318     }
1319     };
1320    
1321     oper_unkline: UNKLINE '=' TBOOL ';'
1322     {
1323 michael 967 if (conf_parser_ctx.pass == 2)
1324 adx 30 {
1325     if (yylval.number)
1326     yy_aconf->port |= OPER_FLAG_UNKLINE;
1327     else
1328     yy_aconf->port &= ~OPER_FLAG_UNKLINE;
1329     }
1330     };
1331    
1332     oper_gline: GLINE '=' TBOOL ';'
1333     {
1334 michael 967 if (conf_parser_ctx.pass == 2)
1335 adx 30 {
1336     if (yylval.number)
1337     yy_aconf->port |= OPER_FLAG_GLINE;
1338     else
1339     yy_aconf->port &= ~OPER_FLAG_GLINE;
1340     }
1341     };
1342    
1343     oper_nick_changes: NICK_CHANGES '=' TBOOL ';'
1344     {
1345 michael 967 if (conf_parser_ctx.pass == 2)
1346 adx 30 {
1347     if (yylval.number)
1348     yy_aconf->port |= OPER_FLAG_N;
1349     else
1350     yy_aconf->port &= ~OPER_FLAG_N;
1351     }
1352     };
1353    
1354     oper_die: DIE '=' TBOOL ';'
1355     {
1356 michael 967 if (conf_parser_ctx.pass == 2)
1357 adx 30 {
1358     if (yylval.number)
1359     yy_aconf->port |= OPER_FLAG_DIE;
1360     else
1361     yy_aconf->port &= ~OPER_FLAG_DIE;
1362     }
1363     };
1364    
1365     oper_rehash: REHASH '=' TBOOL ';'
1366     {
1367 michael 967 if (conf_parser_ctx.pass == 2)
1368 adx 30 {
1369     if (yylval.number)
1370     yy_aconf->port |= OPER_FLAG_REHASH;
1371     else
1372     yy_aconf->port &= ~OPER_FLAG_REHASH;
1373     }
1374     };
1375    
1376     oper_admin: ADMIN '=' TBOOL ';'
1377     {
1378 michael 967 if (conf_parser_ctx.pass == 2)
1379 adx 30 {
1380     if (yylval.number)
1381     yy_aconf->port |= OPER_FLAG_ADMIN;
1382     else
1383     yy_aconf->port &= ~OPER_FLAG_ADMIN;
1384     }
1385     };
1386    
1387     oper_hidden_admin: HIDDEN_ADMIN '=' TBOOL ';'
1388     {
1389 michael 967 if (conf_parser_ctx.pass == 2)
1390 adx 30 {
1391     if (yylval.number)
1392     yy_aconf->port |= OPER_FLAG_HIDDEN_ADMIN;
1393     else
1394     yy_aconf->port &= ~OPER_FLAG_HIDDEN_ADMIN;
1395     }
1396     };
1397    
1398     oper_hidden_oper: HIDDEN_OPER '=' TBOOL ';'
1399     {
1400 michael 967 if (conf_parser_ctx.pass == 2)
1401 adx 30 {
1402     if (yylval.number)
1403     yy_aconf->port |= OPER_FLAG_HIDDEN_OPER;
1404     else
1405     yy_aconf->port &= ~OPER_FLAG_HIDDEN_OPER;
1406     }
1407     };
1408    
1409     oper_operwall: T_OPERWALL '=' TBOOL ';'
1410     {
1411 michael 967 if (conf_parser_ctx.pass == 2)
1412 adx 30 {
1413     if (yylval.number)
1414     yy_aconf->port |= OPER_FLAG_OPERWALL;
1415     else
1416     yy_aconf->port &= ~OPER_FLAG_OPERWALL;
1417     }
1418     };
1419    
1420     oper_flags: IRCD_FLAGS
1421     {
1422     } '=' oper_flags_items ';';
1423    
1424     oper_flags_items: oper_flags_items ',' oper_flags_item | oper_flags_item;
1425 db 136 oper_flags_item: NOT { not_atom = 1; } oper_flags_item_atom
1426     | { not_atom = 0; } oper_flags_item_atom;
1427 adx 30
1428     oper_flags_item_atom: GLOBAL_KILL
1429     {
1430 michael 967 if (conf_parser_ctx.pass == 2)
1431 adx 30 {
1432     if (not_atom)yy_aconf->port &= ~OPER_FLAG_GLOBAL_KILL;
1433     else yy_aconf->port |= OPER_FLAG_GLOBAL_KILL;
1434     }
1435     } | REMOTE
1436     {
1437 michael 967 if (conf_parser_ctx.pass == 2)
1438 adx 30 {
1439     if (not_atom) yy_aconf->port &= ~OPER_FLAG_REMOTE;
1440     else yy_aconf->port |= OPER_FLAG_REMOTE;
1441     }
1442     } | KLINE
1443     {
1444 michael 967 if (conf_parser_ctx.pass == 2)
1445 adx 30 {
1446     if (not_atom) yy_aconf->port &= ~OPER_FLAG_K;
1447     else yy_aconf->port |= OPER_FLAG_K;
1448     }
1449     } | UNKLINE
1450     {
1451 michael 967 if (conf_parser_ctx.pass == 2)
1452 adx 30 {
1453     if (not_atom) yy_aconf->port &= ~OPER_FLAG_UNKLINE;
1454     else yy_aconf->port |= OPER_FLAG_UNKLINE;
1455     }
1456     } | XLINE
1457     {
1458 michael 967 if (conf_parser_ctx.pass == 2)
1459 adx 30 {
1460     if (not_atom) yy_aconf->port &= ~OPER_FLAG_X;
1461     else yy_aconf->port |= OPER_FLAG_X;
1462     }
1463     } | GLINE
1464     {
1465 michael 967 if (conf_parser_ctx.pass == 2)
1466 adx 30 {
1467     if (not_atom) yy_aconf->port &= ~OPER_FLAG_GLINE;
1468     else yy_aconf->port |= OPER_FLAG_GLINE;
1469     }
1470     } | DIE
1471     {
1472 michael 967 if (conf_parser_ctx.pass == 2)
1473 adx 30 {
1474     if (not_atom) yy_aconf->port &= ~OPER_FLAG_DIE;
1475     else yy_aconf->port |= OPER_FLAG_DIE;
1476     }
1477     } | REHASH
1478     {
1479 michael 967 if (conf_parser_ctx.pass == 2)
1480 adx 30 {
1481     if (not_atom) yy_aconf->port &= ~OPER_FLAG_REHASH;
1482     else yy_aconf->port |= OPER_FLAG_REHASH;
1483     }
1484     } | ADMIN
1485     {
1486 michael 967 if (conf_parser_ctx.pass == 2)
1487 adx 30 {
1488     if (not_atom) yy_aconf->port &= ~OPER_FLAG_ADMIN;
1489     else yy_aconf->port |= OPER_FLAG_ADMIN;
1490     }
1491     } | HIDDEN_ADMIN
1492     {
1493 michael 967 if (conf_parser_ctx.pass == 2)
1494 adx 30 {
1495     if (not_atom) yy_aconf->port &= ~OPER_FLAG_HIDDEN_ADMIN;
1496     else yy_aconf->port |= OPER_FLAG_HIDDEN_ADMIN;
1497     }
1498     } | NICK_CHANGES
1499     {
1500 michael 967 if (conf_parser_ctx.pass == 2)
1501 adx 30 {
1502     if (not_atom) yy_aconf->port &= ~OPER_FLAG_N;
1503     else yy_aconf->port |= OPER_FLAG_N;
1504     }
1505     } | T_OPERWALL
1506     {
1507 michael 967 if (conf_parser_ctx.pass == 2)
1508 adx 30 {
1509     if (not_atom) yy_aconf->port &= ~OPER_FLAG_OPERWALL;
1510     else yy_aconf->port |= OPER_FLAG_OPERWALL;
1511     }
1512     } | OPER_SPY_T
1513     {
1514 michael 967 if (conf_parser_ctx.pass == 2)
1515 adx 30 {
1516     if (not_atom) yy_aconf->port &= ~OPER_FLAG_OPER_SPY;
1517     else yy_aconf->port |= OPER_FLAG_OPER_SPY;
1518     }
1519     } | HIDDEN_OPER
1520     {
1521 michael 967 if (conf_parser_ctx.pass == 2)
1522 adx 30 {
1523     if (not_atom) yy_aconf->port &= ~OPER_FLAG_HIDDEN_OPER;
1524     else yy_aconf->port |= OPER_FLAG_HIDDEN_OPER;
1525     }
1526     } | REMOTEBAN
1527     {
1528 michael 967 if (conf_parser_ctx.pass == 2)
1529 adx 30 {
1530     if (not_atom) yy_aconf->port &= ~OPER_FLAG_REMOTEBAN;
1531     else yy_aconf->port |= OPER_FLAG_REMOTEBAN;
1532     }
1533     } | ENCRYPTED
1534     {
1535 michael 967 if (conf_parser_ctx.pass == 2)
1536 adx 30 {
1537     if (not_atom) ClearConfEncrypted(yy_aconf);
1538     else SetConfEncrypted(yy_aconf);
1539     }
1540     };
1541    
1542    
1543     /***************************************************************************
1544     * section class
1545     ***************************************************************************/
1546     class_entry: CLASS
1547     {
1548 michael 967 if (conf_parser_ctx.pass == 1)
1549 adx 30 {
1550     yy_conf = make_conf_item(CLASS_TYPE);
1551 michael 671 yy_class = map_to_conf(yy_conf);
1552 adx 30 }
1553     } class_name_b '{' class_items '}' ';'
1554     {
1555 michael 967 if (conf_parser_ctx.pass == 1)
1556 adx 30 {
1557 michael 671 struct ConfItem *cconf = NULL;
1558 adx 30 struct ClassItem *class = NULL;
1559    
1560     if (yy_class_name == NULL)
1561     delete_conf_item(yy_conf);
1562     else
1563     {
1564     cconf = find_exact_name_conf(CLASS_TYPE, yy_class_name, NULL, NULL);
1565    
1566     if (cconf != NULL) /* The class existed already */
1567     {
1568 michael 671 int user_count = 0;
1569    
1570 adx 30 rebuild_cidr_class(cconf, yy_class);
1571 michael 671
1572     class = map_to_conf(cconf);
1573    
1574     user_count = class->curr_user_count;
1575     memcpy(class, yy_class, sizeof(*class));
1576     class->curr_user_count = user_count;
1577     class->active = 1;
1578    
1579 adx 30 delete_conf_item(yy_conf);
1580    
1581     MyFree(cconf->name); /* Allows case change of class name */
1582     cconf->name = yy_class_name;
1583     }
1584     else /* Brand new class */
1585     {
1586     MyFree(yy_conf->name); /* just in case it was allocated */
1587     yy_conf->name = yy_class_name;
1588 michael 671 yy_class->active = 1;
1589 adx 30 }
1590     }
1591 michael 671
1592 adx 30 yy_class_name = NULL;
1593     }
1594     };
1595    
1596     class_name_b: | class_name_t;
1597    
1598     class_items: class_items class_item | class_item;
1599     class_item: class_name |
1600     class_cidr_bitlen_ipv4 | class_cidr_bitlen_ipv6 |
1601     class_ping_time |
1602     class_ping_warning |
1603     class_number_per_cidr |
1604     class_number_per_ip |
1605     class_connectfreq |
1606     class_max_number |
1607     class_max_global |
1608     class_max_local |
1609     class_max_ident |
1610     class_sendq |
1611     error ';' ;
1612    
1613     class_name: NAME '=' QSTRING ';'
1614     {
1615 michael 967 if (conf_parser_ctx.pass == 1)
1616 adx 30 {
1617     MyFree(yy_class_name);
1618     DupString(yy_class_name, yylval.string);
1619     }
1620     };
1621    
1622     class_name_t: QSTRING
1623     {
1624 michael 967 if (conf_parser_ctx.pass == 1)
1625 adx 30 {
1626     MyFree(yy_class_name);
1627     DupString(yy_class_name, yylval.string);
1628     }
1629     };
1630    
1631     class_ping_time: PING_TIME '=' timespec ';'
1632     {
1633 michael 967 if (conf_parser_ctx.pass == 1)
1634 adx 30 PingFreq(yy_class) = $3;
1635     };
1636    
1637     class_ping_warning: PING_WARNING '=' timespec ';'
1638     {
1639 michael 967 if (conf_parser_ctx.pass == 1)
1640 adx 30 PingWarning(yy_class) = $3;
1641     };
1642    
1643     class_number_per_ip: NUMBER_PER_IP '=' NUMBER ';'
1644     {
1645 michael 967 if (conf_parser_ctx.pass == 1)
1646 adx 30 MaxPerIp(yy_class) = $3;
1647     };
1648    
1649     class_connectfreq: CONNECTFREQ '=' timespec ';'
1650     {
1651 michael 967 if (conf_parser_ctx.pass == 1)
1652 adx 30 ConFreq(yy_class) = $3;
1653     };
1654    
1655     class_max_number: MAX_NUMBER '=' NUMBER ';'
1656     {
1657 michael 967 if (conf_parser_ctx.pass == 1)
1658 adx 30 MaxTotal(yy_class) = $3;
1659     };
1660    
1661     class_max_global: MAX_GLOBAL '=' NUMBER ';'
1662     {
1663 michael 967 if (conf_parser_ctx.pass == 1)
1664 adx 30 MaxGlobal(yy_class) = $3;
1665     };
1666    
1667     class_max_local: MAX_LOCAL '=' NUMBER ';'
1668     {
1669 michael 967 if (conf_parser_ctx.pass == 1)
1670 adx 30 MaxLocal(yy_class) = $3;
1671     };
1672    
1673     class_max_ident: MAX_IDENT '=' NUMBER ';'
1674     {
1675 michael 967 if (conf_parser_ctx.pass == 1)
1676 adx 30 MaxIdent(yy_class) = $3;
1677     };
1678    
1679     class_sendq: SENDQ '=' sizespec ';'
1680     {
1681 michael 967 if (conf_parser_ctx.pass == 1)
1682 adx 30 MaxSendq(yy_class) = $3;
1683     };
1684    
1685     class_cidr_bitlen_ipv4: CIDR_BITLEN_IPV4 '=' NUMBER ';'
1686     {
1687 michael 967 if (conf_parser_ctx.pass == 1)
1688 adx 30 CidrBitlenIPV4(yy_class) = $3;
1689     };
1690    
1691     class_cidr_bitlen_ipv6: CIDR_BITLEN_IPV6 '=' NUMBER ';'
1692     {
1693 michael 967 if (conf_parser_ctx.pass == 1)
1694 adx 30 CidrBitlenIPV6(yy_class) = $3;
1695     };
1696    
1697     class_number_per_cidr: NUMBER_PER_CIDR '=' NUMBER ';'
1698     {
1699 michael 967 if (conf_parser_ctx.pass == 1)
1700 adx 30 NumberPerCidr(yy_class) = $3;
1701     };
1702    
1703     /***************************************************************************
1704     * section listen
1705     ***************************************************************************/
1706     listen_entry: LISTEN
1707     {
1708 michael 967 if (conf_parser_ctx.pass == 2)
1709 adx 30 {
1710     listener_address = NULL;
1711     listener_flags = 0;
1712     }
1713     } '{' listen_items '}' ';'
1714     {
1715 michael 967 if (conf_parser_ctx.pass == 2)
1716 adx 30 {
1717     MyFree(listener_address);
1718     listener_address = NULL;
1719     }
1720     };
1721    
1722     listen_flags: IRCD_FLAGS
1723     {
1724 michael 440 listener_flags = 0;
1725 adx 30 } '=' listen_flags_items ';';
1726    
1727     listen_flags_items: listen_flags_items ',' listen_flags_item | listen_flags_item;
1728     listen_flags_item: T_SSL
1729     {
1730 michael 967 if (conf_parser_ctx.pass == 2)
1731 adx 30 listener_flags |= LISTENER_SSL;
1732     } | HIDDEN
1733     {
1734 michael 967 if (conf_parser_ctx.pass == 2)
1735 adx 30 listener_flags |= LISTENER_HIDDEN;
1736 michael 900 } | T_SERVER
1737     {
1738 michael 967 if (conf_parser_ctx.pass == 2)
1739 michael 900 listener_flags |= LISTENER_SERVER;
1740 adx 30 };
1741    
1742 michael 900
1743    
1744 adx 30 listen_items: listen_items listen_item | listen_item;
1745 michael 440 listen_item: listen_port | listen_flags | listen_address | listen_host | error ';';
1746 adx 30
1747 michael 440 listen_port: PORT '=' port_items { listener_flags = 0; } ';';
1748 adx 30
1749     port_items: port_items ',' port_item | port_item;
1750    
1751     port_item: NUMBER
1752     {
1753 michael 967 if (conf_parser_ctx.pass == 2)
1754 adx 30 {
1755     if ((listener_flags & LISTENER_SSL))
1756     #ifdef HAVE_LIBCRYPTO
1757 michael 967 if (!ServerInfo.server_ctx)
1758 adx 30 #endif
1759     {
1760     yyerror("SSL not available - port closed");
1761     break;
1762     }
1763     add_listener($1, listener_address, listener_flags);
1764     }
1765     } | NUMBER TWODOTS NUMBER
1766     {
1767 michael 967 if (conf_parser_ctx.pass == 2)
1768 adx 30 {
1769     int i;
1770    
1771     if ((listener_flags & LISTENER_SSL))
1772     #ifdef HAVE_LIBCRYPTO
1773 michael 967 if (!ServerInfo.server_ctx)
1774 adx 30 #endif
1775     {
1776     yyerror("SSL not available - port closed");
1777     break;
1778     }
1779    
1780     for (i = $1; i <= $3; ++i)
1781     add_listener(i, listener_address, listener_flags);
1782     }
1783     };
1784    
1785     listen_address: IP '=' QSTRING ';'
1786     {
1787 michael 967 if (conf_parser_ctx.pass == 2)
1788 adx 30 {
1789     MyFree(listener_address);
1790     DupString(listener_address, yylval.string);
1791     }
1792     };
1793    
1794     listen_host: HOST '=' QSTRING ';'
1795     {
1796 michael 967 if (conf_parser_ctx.pass == 2)
1797 adx 30 {
1798     MyFree(listener_address);
1799     DupString(listener_address, yylval.string);
1800     }
1801     };
1802    
1803     /***************************************************************************
1804     * section auth
1805     ***************************************************************************/
1806     auth_entry: IRCD_AUTH
1807     {
1808 michael 967 if (conf_parser_ctx.pass == 2)
1809 adx 30 {
1810     yy_conf = make_conf_item(CLIENT_TYPE);
1811     yy_aconf = map_to_conf(yy_conf);
1812     }
1813     else
1814     {
1815     MyFree(class_name);
1816     class_name = NULL;
1817     }
1818     } '{' auth_items '}' ';'
1819     {
1820 michael 967 if (conf_parser_ctx.pass == 2)
1821 adx 30 {
1822     struct CollectItem *yy_tmp = NULL;
1823     dlink_node *ptr = NULL, *next_ptr = NULL;
1824    
1825     if (yy_aconf->user && yy_aconf->host)
1826     {
1827     conf_add_class_to_conf(yy_conf, class_name);
1828     add_conf_by_address(CONF_CLIENT, yy_aconf);
1829     }
1830     else
1831     delete_conf_item(yy_conf);
1832    
1833     /* copy over settings from first struct */
1834     DLINK_FOREACH_SAFE(ptr, next_ptr, col_conf_list.head)
1835     {
1836     struct AccessItem *new_aconf;
1837     struct ConfItem *new_conf;
1838    
1839     new_conf = make_conf_item(CLIENT_TYPE);
1840     new_aconf = map_to_conf(new_conf);
1841    
1842     yy_tmp = ptr->data;
1843    
1844     assert(yy_tmp->user && yy_tmp->host);
1845    
1846     if (yy_aconf->passwd != NULL)
1847     DupString(new_aconf->passwd, yy_aconf->passwd);
1848     if (yy_conf->name != NULL)
1849     DupString(new_conf->name, yy_conf->name);
1850     if (yy_aconf->passwd != NULL)
1851     DupString(new_aconf->passwd, yy_aconf->passwd);
1852    
1853     new_aconf->flags = yy_aconf->flags;
1854     new_aconf->port = yy_aconf->port;
1855    
1856     DupString(new_aconf->user, yy_tmp->user);
1857     collapse(new_aconf->user);
1858    
1859     DupString(new_aconf->host, yy_tmp->host);
1860     collapse(new_aconf->host);
1861    
1862     conf_add_class_to_conf(new_conf, class_name);
1863     add_conf_by_address(CONF_CLIENT, new_aconf);
1864     dlinkDelete(&yy_tmp->node, &col_conf_list);
1865     free_collect_item(yy_tmp);
1866     }
1867    
1868     MyFree(class_name);
1869     class_name = NULL;
1870     yy_conf = NULL;
1871     yy_aconf = NULL;
1872     }
1873     };
1874    
1875     auth_items: auth_items auth_item | auth_item;
1876     auth_item: auth_user | auth_passwd | auth_class | auth_flags |
1877     auth_kline_exempt | auth_need_ident |
1878     auth_exceed_limit | auth_no_tilde | auth_gline_exempt |
1879     auth_spoof | auth_spoof_notice |
1880     auth_redir_serv | auth_redir_port | auth_can_flood |
1881     auth_need_password | auth_encrypted | error ';' ;
1882    
1883     auth_user: USER '=' QSTRING ';'
1884     {
1885 michael 967 if (conf_parser_ctx.pass == 2)
1886 adx 30 {
1887 michael 593 struct CollectItem *yy_tmp = NULL;
1888     struct split_nuh_item nuh;
1889 adx 30
1890 michael 593 nuh.nuhmask = yylval.string;
1891     nuh.nickptr = NULL;
1892     nuh.userptr = userbuf;
1893     nuh.hostptr = hostbuf;
1894    
1895     nuh.nicksize = 0;
1896     nuh.usersize = sizeof(userbuf);
1897     nuh.hostsize = sizeof(hostbuf);
1898    
1899     split_nuh(&nuh);
1900    
1901 adx 30 if (yy_aconf->user == NULL)
1902 michael 593 {
1903     DupString(yy_aconf->user, userbuf);
1904     DupString(yy_aconf->host, hostbuf);
1905     }
1906 adx 30 else
1907     {
1908     yy_tmp = MyMalloc(sizeof(struct CollectItem));
1909 michael 593
1910     DupString(yy_tmp->user, userbuf);
1911     DupString(yy_tmp->host, hostbuf);
1912    
1913 adx 30 dlinkAdd(yy_tmp, &yy_tmp->node, &col_conf_list);
1914     }
1915     }
1916     };
1917    
1918     /* XXX - IP/IPV6 tags don't exist anymore - put IP/IPV6 into user. */
1919    
1920     auth_passwd: PASSWORD '=' QSTRING ';'
1921     {
1922 michael 967 if (conf_parser_ctx.pass == 2)
1923 adx 30 {
1924     /* be paranoid */
1925     if (yy_aconf->passwd != NULL)
1926     memset(yy_aconf->passwd, 0, strlen(yy_aconf->passwd));
1927    
1928     MyFree(yy_aconf->passwd);
1929     DupString(yy_aconf->passwd, yylval.string);
1930     }
1931     };
1932    
1933     auth_spoof_notice: SPOOF_NOTICE '=' TBOOL ';'
1934     {
1935 michael 967 if (conf_parser_ctx.pass == 2)
1936 adx 30 {
1937     if (yylval.number)
1938     yy_aconf->flags |= CONF_FLAGS_SPOOF_NOTICE;
1939     else
1940     yy_aconf->flags &= ~CONF_FLAGS_SPOOF_NOTICE;
1941     }
1942     };
1943    
1944     auth_class: CLASS '=' QSTRING ';'
1945     {
1946 michael 967 if (conf_parser_ctx.pass == 2)
1947 adx 30 {
1948     MyFree(class_name);
1949     DupString(class_name, yylval.string);
1950     }
1951     };
1952    
1953     auth_encrypted: ENCRYPTED '=' TBOOL ';'
1954     {
1955 michael 967 if (conf_parser_ctx.pass == 2)
1956 adx 30 {
1957     if (yylval.number)
1958     SetConfEncrypted(yy_aconf);
1959     else
1960     ClearConfEncrypted(yy_aconf);
1961     }
1962     };
1963    
1964     auth_flags: IRCD_FLAGS
1965     {
1966     } '=' auth_flags_items ';';
1967    
1968     auth_flags_items: auth_flags_items ',' auth_flags_item | auth_flags_item;
1969 db 136 auth_flags_item: NOT { not_atom = 1; } auth_flags_item_atom
1970     | { not_atom = 0; } auth_flags_item_atom;
1971 adx 30
1972     auth_flags_item_atom: SPOOF_NOTICE
1973     {
1974 michael 967 if (conf_parser_ctx.pass == 2)
1975 adx 30 {
1976     if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_SPOOF_NOTICE;
1977     else yy_aconf->flags |= CONF_FLAGS_SPOOF_NOTICE;
1978     }
1979    
1980     } | EXCEED_LIMIT
1981     {
1982 michael 967 if (conf_parser_ctx.pass == 2)
1983 adx 30 {
1984     if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_NOLIMIT;
1985     else yy_aconf->flags |= CONF_FLAGS_NOLIMIT;
1986     }
1987     } | KLINE_EXEMPT
1988     {
1989 michael 967 if (conf_parser_ctx.pass == 2)
1990 adx 30 {
1991     if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_EXEMPTKLINE;
1992     else yy_aconf->flags |= CONF_FLAGS_EXEMPTKLINE;
1993     }
1994     } | NEED_IDENT
1995     {
1996 michael 967 if (conf_parser_ctx.pass == 2)
1997 adx 30 {
1998     if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_NEED_IDENTD;
1999     else yy_aconf->flags |= CONF_FLAGS_NEED_IDENTD;
2000     }
2001     } | CAN_FLOOD
2002     {
2003 michael 967 if (conf_parser_ctx.pass == 2)
2004 adx 30 {
2005     if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_CAN_FLOOD;
2006     else yy_aconf->flags |= CONF_FLAGS_CAN_FLOOD;
2007     }
2008     } | CAN_IDLE
2009     {
2010 michael 967 if (conf_parser_ctx.pass == 2)
2011 adx 30 {
2012     if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_IDLE_LINED;
2013     else yy_aconf->flags |= CONF_FLAGS_IDLE_LINED;
2014     }
2015     } | NO_TILDE
2016     {
2017 michael 967 if (conf_parser_ctx.pass == 2)
2018 adx 30 {
2019     if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_NO_TILDE;
2020     else yy_aconf->flags |= CONF_FLAGS_NO_TILDE;
2021     }
2022     } | GLINE_EXEMPT
2023     {
2024 michael 967 if (conf_parser_ctx.pass == 2)
2025 adx 30 {
2026     if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_EXEMPTGLINE;
2027     else yy_aconf->flags |= CONF_FLAGS_EXEMPTGLINE;
2028     }
2029     } | RESV_EXEMPT
2030     {
2031 michael 967 if (conf_parser_ctx.pass == 2)
2032 adx 30 {
2033     if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_EXEMPTRESV;
2034     else yy_aconf->flags |= CONF_FLAGS_EXEMPTRESV;
2035     }
2036     } | NEED_PASSWORD
2037     {
2038 michael 967 if (conf_parser_ctx.pass == 2)
2039 adx 30 {
2040     if (not_atom) yy_aconf->flags &= ~CONF_FLAGS_NEED_PASSWORD;
2041     else yy_aconf->flags |= CONF_FLAGS_NEED_PASSWORD;
2042     }
2043     };
2044    
2045     auth_kline_exempt: KLINE_EXEMPT '=' TBOOL ';'
2046     {
2047 michael 967 if (conf_parser_ctx.pass == 2)
2048 adx 30 {
2049     if (yylval.number)
2050     yy_aconf->flags |= CONF_FLAGS_EXEMPTKLINE;
2051     else
2052     yy_aconf->flags &= ~CONF_FLAGS_EXEMPTKLINE;
2053     }
2054     };
2055    
2056     auth_need_ident: NEED_IDENT '=' TBOOL ';'
2057     {
2058 michael 967 if (conf_parser_ctx.pass == 2)
2059 adx 30 {
2060     if (yylval.number)
2061     yy_aconf->flags |= CONF_FLAGS_NEED_IDENTD;
2062     else
2063     yy_aconf->flags &= ~CONF_FLAGS_NEED_IDENTD;
2064     }
2065     };
2066    
2067     auth_exceed_limit: EXCEED_LIMIT '=' TBOOL ';'
2068     {
2069 michael 967 if (conf_parser_ctx.pass == 2)
2070 adx 30 {
2071     if (yylval.number)
2072     yy_aconf->flags |= CONF_FLAGS_NOLIMIT;
2073     else
2074     yy_aconf->flags &= ~CONF_FLAGS_NOLIMIT;
2075     }
2076     };
2077    
2078     auth_can_flood: CAN_FLOOD '=' TBOOL ';'
2079     {
2080 michael 967 if (conf_parser_ctx.pass == 2)
2081 adx 30 {
2082     if (yylval.number)
2083     yy_aconf->flags |= CONF_FLAGS_CAN_FLOOD;
2084     else
2085     yy_aconf->flags &= ~CONF_FLAGS_CAN_FLOOD;
2086     }
2087     };
2088    
2089     auth_no_tilde: NO_TILDE '=' TBOOL ';'
2090     {
2091 michael 967 if (conf_parser_ctx.pass == 2)
2092 adx 30 {
2093     if (yylval.number)
2094     yy_aconf->flags |= CONF_FLAGS_NO_TILDE;
2095     else
2096     yy_aconf->flags &= ~CONF_FLAGS_NO_TILDE;
2097     }
2098     };
2099    
2100     auth_gline_exempt: GLINE_EXEMPT '=' TBOOL ';'
2101     {
2102 michael 967 if (conf_parser_ctx.pass == 2)
2103 adx 30 {
2104     if (yylval.number)
2105     yy_aconf->flags |= CONF_FLAGS_EXEMPTGLINE;
2106     else
2107     yy_aconf->flags &= ~CONF_FLAGS_EXEMPTGLINE;
2108     }
2109     };
2110    
2111     /* XXX - need check for illegal hostnames here */
2112     auth_spoof: SPOOF '=' QSTRING ';'
2113     {
2114 michael 967 if (conf_parser_ctx.pass == 2)
2115 adx 30 {
2116     MyFree(yy_conf->name);
2117    
2118     if (strlen(yylval.string) < HOSTLEN)
2119     {
2120     DupString(yy_conf->name, yylval.string);
2121     yy_aconf->flags |= CONF_FLAGS_SPOOF_IP;
2122     }
2123     else
2124     {
2125     ilog(L_ERROR, "Spoofs must be less than %d..ignoring it", HOSTLEN);
2126     yy_conf->name = NULL;
2127     }
2128     }
2129     };
2130    
2131     auth_redir_serv: REDIRSERV '=' QSTRING ';'
2132     {
2133 michael 967 if (conf_parser_ctx.pass == 2)
2134 adx 30 {
2135     yy_aconf->flags |= CONF_FLAGS_REDIR;
2136     MyFree(yy_conf->name);
2137     DupString(yy_conf->name, yylval.string);
2138     }
2139     };
2140    
2141     auth_redir_port: REDIRPORT '=' NUMBER ';'
2142     {
2143 michael 967 if (conf_parser_ctx.pass == 2)
2144 adx 30 {
2145     yy_aconf->flags |= CONF_FLAGS_REDIR;
2146     yy_aconf->port = $3;
2147     }
2148     };
2149    
2150     auth_need_password: NEED_PASSWORD '=' TBOOL ';'
2151     {
2152 michael 967 if (conf_parser_ctx.pass == 2)
2153 adx 30 {
2154     if (yylval.number)
2155     yy_aconf->flags |= CONF_FLAGS_NEED_PASSWORD;
2156     else
2157     yy_aconf->flags &= ~CONF_FLAGS_NEED_PASSWORD;
2158     }
2159     };
2160    
2161    
2162     /***************************************************************************
2163     * section resv
2164     ***************************************************************************/
2165     resv_entry: RESV
2166     {
2167 michael 967 if (conf_parser_ctx.pass == 2)
2168 adx 30 {
2169     MyFree(resv_reason);
2170     resv_reason = NULL;
2171     }
2172     } '{' resv_items '}' ';'
2173     {
2174 michael 967 if (conf_parser_ctx.pass == 2)
2175 adx 30 {
2176     MyFree(resv_reason);
2177     resv_reason = NULL;
2178     }
2179     };
2180    
2181     resv_items: resv_items resv_item | resv_item;
2182     resv_item: resv_creason | resv_channel | resv_nick | error ';' ;
2183    
2184     resv_creason: REASON '=' QSTRING ';'
2185     {
2186 michael 967 if (conf_parser_ctx.pass == 2)
2187 adx 30 {
2188     MyFree(resv_reason);
2189     DupString(resv_reason, yylval.string);
2190     }
2191     };
2192    
2193     resv_channel: CHANNEL '=' QSTRING ';'
2194     {
2195 michael 967 if (conf_parser_ctx.pass == 2)
2196 adx 30 {
2197     if (IsChanPrefix(*yylval.string))
2198     {
2199     char def_reason[] = "No reason";
2200    
2201     create_channel_resv(yylval.string, resv_reason != NULL ? resv_reason : def_reason, 1);
2202     }
2203     }
2204     /* ignore it for now.. but we really should make a warning if
2205     * its an erroneous name --fl_ */
2206     };
2207    
2208     resv_nick: NICK '=' QSTRING ';'
2209     {
2210 michael 967 if (conf_parser_ctx.pass == 2)
2211 adx 30 {
2212     char def_reason[] = "No reason";
2213    
2214     create_nick_resv(yylval.string, resv_reason != NULL ? resv_reason : def_reason, 1);
2215     }
2216     };
2217    
2218     /***************************************************************************
2219     * section shared, for sharing remote klines etc.
2220     ***************************************************************************/
2221     shared_entry: T_SHARED
2222     {
2223 michael 967 if (conf_parser_ctx.pass == 2)
2224 adx 30 {
2225     yy_conf = make_conf_item(ULINE_TYPE);
2226     yy_match_item = map_to_conf(yy_conf);
2227     yy_match_item->action = SHARED_ALL;
2228     }
2229     } '{' shared_items '}' ';'
2230     {
2231 michael 967 if (conf_parser_ctx.pass == 2)
2232 adx 30 {
2233     yy_conf = NULL;
2234     }
2235     };
2236    
2237     shared_items: shared_items shared_item | shared_item;
2238     shared_item: shared_name | shared_user | shared_type | error ';' ;
2239    
2240     shared_name: NAME '=' QSTRING ';'
2241     {
2242 michael 967 if (conf_parser_ctx.pass == 2)
2243 adx 30 {
2244     MyFree(yy_conf->name);
2245     DupString(yy_conf->name, yylval.string);
2246     }
2247     };
2248    
2249     shared_user: USER '=' QSTRING ';'
2250     {
2251 michael 967 if (conf_parser_ctx.pass == 2)
2252 adx 30 {
2253 michael 593 struct split_nuh_item nuh;
2254    
2255     nuh.nuhmask = yylval.string;
2256     nuh.nickptr = NULL;
2257     nuh.userptr = userbuf;
2258     nuh.hostptr = hostbuf;
2259    
2260     nuh.nicksize = 0;
2261     nuh.usersize = sizeof(userbuf);
2262     nuh.hostsize = sizeof(hostbuf);
2263    
2264     split_nuh(&nuh);
2265    
2266     DupString(yy_match_item->user, userbuf);
2267     DupString(yy_match_item->host, hostbuf);
2268 adx 30 }
2269     };
2270    
2271     shared_type: TYPE
2272     {
2273 michael 967 if (conf_parser_ctx.pass == 2)
2274 adx 30 yy_match_item->action = 0;
2275     } '=' shared_types ';' ;
2276    
2277     shared_types: shared_types ',' shared_type_item | shared_type_item;
2278     shared_type_item: KLINE
2279     {
2280 michael 967 if (conf_parser_ctx.pass == 2)
2281 adx 30 yy_match_item->action |= SHARED_KLINE;
2282     } | TKLINE
2283     {
2284 michael 967 if (conf_parser_ctx.pass == 2)
2285 adx 30 yy_match_item->action |= SHARED_TKLINE;
2286     } | UNKLINE
2287     {
2288 michael 967 if (conf_parser_ctx.pass == 2)
2289 adx 30 yy_match_item->action |= SHARED_UNKLINE;
2290     } | XLINE
2291     {
2292 michael 967 if (conf_parser_ctx.pass == 2)
2293 adx 30 yy_match_item->action |= SHARED_XLINE;
2294     } | TXLINE
2295     {
2296 michael 967 if (conf_parser_ctx.pass == 2)
2297 adx 30 yy_match_item->action |= SHARED_TXLINE;
2298     } | T_UNXLINE
2299     {
2300 michael 967 if (conf_parser_ctx.pass == 2)
2301 adx 30 yy_match_item->action |= SHARED_UNXLINE;
2302     } | RESV
2303     {
2304 michael 967 if (conf_parser_ctx.pass == 2)
2305 adx 30 yy_match_item->action |= SHARED_RESV;
2306     } | TRESV
2307     {
2308 michael 967 if (conf_parser_ctx.pass == 2)
2309 adx 30 yy_match_item->action |= SHARED_TRESV;
2310     } | T_UNRESV
2311     {
2312 michael 967 if (conf_parser_ctx.pass == 2)
2313 adx 30 yy_match_item->action |= SHARED_UNRESV;
2314     } | T_LOCOPS
2315     {
2316 michael 967 if (conf_parser_ctx.pass == 2)
2317 adx 30 yy_match_item->action |= SHARED_LOCOPS;
2318     } | T_ALL
2319     {
2320 michael 967 if (conf_parser_ctx.pass == 2)
2321 adx 30 yy_match_item->action = SHARED_ALL;
2322     };
2323    
2324     /***************************************************************************
2325     * section cluster
2326     ***************************************************************************/
2327     cluster_entry: T_CLUSTER
2328     {
2329 michael 967 if (conf_parser_ctx.pass == 2)
2330 adx 30 {
2331     yy_conf = make_conf_item(CLUSTER_TYPE);
2332     yy_conf->flags = SHARED_ALL;
2333     }
2334     } '{' cluster_items '}' ';'
2335     {
2336 michael 967 if (conf_parser_ctx.pass == 2)
2337 adx 30 {
2338     if (yy_conf->name == NULL)
2339     DupString(yy_conf->name, "*");
2340     yy_conf = NULL;
2341     }
2342     };
2343    
2344     cluster_items: cluster_items cluster_item | cluster_item;
2345     cluster_item: cluster_name | cluster_type | error ';' ;
2346    
2347     cluster_name: NAME '=' QSTRING ';'
2348     {
2349 michael 967 if (conf_parser_ctx.pass == 2)
2350 adx 30 DupString(yy_conf->name, yylval.string);
2351     };
2352    
2353     cluster_type: TYPE
2354     {
2355 michael 967 if (conf_parser_ctx.pass == 2)
2356 adx 30 yy_conf->flags = 0;
2357     } '=' cluster_types ';' ;
2358    
2359     cluster_types: cluster_types ',' cluster_type_item | cluster_type_item;
2360     cluster_type_item: KLINE
2361     {
2362 michael 967 if (conf_parser_ctx.pass == 2)
2363 adx 30 yy_conf->flags |= SHARED_KLINE;
2364     } | TKLINE
2365     {
2366 michael 967 if (conf_parser_ctx.pass == 2)
2367 adx 30 yy_conf->flags |= SHARED_TKLINE;
2368     } | UNKLINE
2369     {
2370 michael 967 if (conf_parser_ctx.pass == 2)
2371 adx 30 yy_conf->flags |= SHARED_UNKLINE;
2372     } | XLINE
2373     {
2374 michael 967 if (conf_parser_ctx.pass == 2)
2375 adx 30 yy_conf->flags |= SHARED_XLINE;
2376     } | TXLINE
2377     {
2378 michael 967 if (conf_parser_ctx.pass == 2)
2379 adx 30 yy_conf->flags |= SHARED_TXLINE;
2380     } | T_UNXLINE
2381     {
2382 michael 967 if (conf_parser_ctx.pass == 2)
2383 adx 30 yy_conf->flags |= SHARED_UNXLINE;
2384     } | RESV
2385     {
2386 michael 967 if (conf_parser_ctx.pass == 2)
2387 adx 30 yy_conf->flags |= SHARED_RESV;
2388     } | TRESV
2389     {
2390 michael 967 if (conf_parser_ctx.pass == 2)
2391 adx 30 yy_conf->flags |= SHARED_TRESV;
2392     } | T_UNRESV
2393     {
2394 michael 967 if (conf_parser_ctx.pass == 2)
2395 adx 30 yy_conf->flags |= SHARED_UNRESV;
2396     } | T_LOCOPS
2397     {
2398 michael 967 if (conf_parser_ctx.pass == 2)
2399 adx 30 yy_conf->flags |= SHARED_LOCOPS;
2400     } | T_ALL
2401     {
2402 michael 967 if (conf_parser_ctx.pass == 2)
2403 adx 30 yy_conf->flags = SHARED_ALL;
2404     };
2405    
2406     /***************************************************************************
2407     * section connect
2408     ***************************************************************************/
2409     connect_entry: CONNECT
2410     {
2411 michael 967 if (conf_parser_ctx.pass == 2)
2412 adx 30 {
2413     yy_conf = make_conf_item(SERVER_TYPE);
2414     yy_aconf = (struct AccessItem *)map_to_conf(yy_conf);
2415     yy_aconf->passwd = NULL;
2416     /* defaults */
2417     yy_aconf->port = PORTNUM;
2418    
2419     if (ConfigFileEntry.burst_away)
2420     yy_aconf->flags = CONF_FLAGS_BURST_AWAY;
2421     }
2422     else
2423     {
2424     MyFree(class_name);
2425     class_name = NULL;
2426     }
2427     } connect_name_b '{' connect_items '}' ';'
2428     {
2429 michael 967 if (conf_parser_ctx.pass == 2)
2430 adx 30 {
2431     struct CollectItem *yy_hconf=NULL;
2432     struct CollectItem *yy_lconf=NULL;
2433     dlink_node *ptr;
2434     dlink_node *next_ptr;
2435     #ifdef HAVE_LIBCRYPTO
2436     if (yy_aconf->host &&
2437     ((yy_aconf->passwd && yy_aconf->spasswd) ||
2438     (yy_aconf->rsa_public_key && IsConfCryptLink(yy_aconf))))
2439     #else /* !HAVE_LIBCRYPTO */
2440     if (yy_aconf->host && !IsConfCryptLink(yy_aconf) &&
2441     yy_aconf->passwd && yy_aconf->spasswd)
2442     #endif /* !HAVE_LIBCRYPTO */
2443     {
2444 michael 593 if (conf_add_server(yy_conf, class_name) == -1)
2445 adx 30 {
2446     delete_conf_item(yy_conf);
2447     yy_conf = NULL;
2448     yy_aconf = NULL;
2449     }
2450     }
2451     else
2452     {
2453     /* Even if yy_conf ->name is NULL
2454     * should still unhook any hub/leaf confs still pending
2455     */
2456     unhook_hub_leaf_confs();
2457    
2458     if (yy_conf->name != NULL)
2459     {
2460     #ifndef HAVE_LIBCRYPTO
2461     if (IsConfCryptLink(yy_aconf))
2462     yyerror("Ignoring connect block -- no OpenSSL support");
2463     #else
2464     if (IsConfCryptLink(yy_aconf) && !yy_aconf->rsa_public_key)
2465     yyerror("Ignoring connect block -- missing key");
2466     #endif
2467     if (yy_aconf->host == NULL)
2468     yyerror("Ignoring connect block -- missing host");
2469     else if (!IsConfCryptLink(yy_aconf) &&
2470     (!yy_aconf->passwd || !yy_aconf->spasswd))
2471     yyerror("Ignoring connect block -- missing password");
2472     }
2473    
2474    
2475     /* XXX
2476     * This fixes a try_connections() core (caused by invalid class_ptr
2477     * pointers) reported by metalrock. That's an ugly fix, but there
2478     * is currently no better way. The entire config subsystem needs an
2479     * rewrite ASAP. make_conf_item() shouldn't really add things onto
2480     * a doubly linked list immediately without any sanity checks! -Michael
2481     */
2482     delete_conf_item(yy_conf);
2483    
2484     yy_aconf = NULL;
2485     yy_conf = NULL;
2486     }
2487    
2488     /*
2489     * yy_conf is still pointing at the server that is having
2490     * a connect block built for it. This means, y_aconf->name
2491     * points to the actual irc name this server will be known as.
2492     * Now this new server has a set or even just one hub_mask (or leaf_mask)
2493     * given in the link list at yy_hconf. Fill in the HUB confs
2494     * from this link list now.
2495     */
2496     DLINK_FOREACH_SAFE(ptr, next_ptr, hub_conf_list.head)
2497     {
2498     struct ConfItem *new_hub_conf;
2499     struct MatchItem *match_item;
2500    
2501     yy_hconf = ptr->data;
2502    
2503     /* yy_conf == NULL is a fatal error for this connect block! */
2504     if ((yy_conf != NULL) && (yy_conf->name != NULL))
2505     {
2506     new_hub_conf = make_conf_item(HUB_TYPE);
2507     match_item = (struct MatchItem *)map_to_conf(new_hub_conf);
2508     DupString(new_hub_conf->name, yy_conf->name);
2509     if (yy_hconf->user != NULL)
2510     DupString(match_item->user, yy_hconf->user);
2511     else
2512     DupString(match_item->user, "*");
2513     if (yy_hconf->host != NULL)
2514     DupString(match_item->host, yy_hconf->host);
2515     else
2516     DupString(match_item->host, "*");
2517     }
2518     dlinkDelete(&yy_hconf->node, &hub_conf_list);
2519     free_collect_item(yy_hconf);
2520     }
2521    
2522     /* Ditto for the LEAF confs */
2523    
2524     DLINK_FOREACH_SAFE(ptr, next_ptr, leaf_conf_list.head)
2525     {
2526     struct ConfItem *new_leaf_conf;
2527     struct MatchItem *match_item;
2528    
2529     yy_lconf = ptr->data;
2530    
2531     if ((yy_conf != NULL) && (yy_conf->name != NULL))
2532     {
2533     new_leaf_conf = make_conf_item(LEAF_TYPE);
2534     match_item = (struct MatchItem *)map_to_conf(new_leaf_conf);
2535     DupString(new_leaf_conf->name, yy_conf->name);
2536     if (yy_lconf->user != NULL)
2537     DupString(match_item->user, yy_lconf->user);
2538     else
2539     DupString(match_item->user, "*");
2540     if (yy_lconf->host != NULL)
2541     DupString(match_item->host, yy_lconf->host);
2542     else
2543     DupString(match_item->host, "*");
2544     }
2545     dlinkDelete(&yy_lconf->node, &leaf_conf_list);
2546     free_collect_item(yy_lconf);
2547     }
2548     MyFree(class_name);
2549     class_name = NULL;
2550     yy_conf = NULL;
2551     yy_aconf = NULL;
2552     }
2553     };
2554    
2555     connect_name_b: | connect_name_t;
2556     connect_items: connect_items connect_item | connect_item;
2557     connect_item: connect_name | connect_host | connect_vhost |
2558     connect_send_password | connect_accept_password |
2559     connect_aftype | connect_port |
2560     connect_fakename | connect_flags | connect_hub_mask |
2561     connect_leaf_mask | connect_class | connect_auto |
2562     connect_encrypted | connect_compressed | connect_cryptlink |
2563     connect_rsa_public_key_file | connect_cipher_preference |
2564 michael 341 connect_topicburst | error ';' ;
2565 adx 30
2566     connect_name: NAME '=' QSTRING ';'
2567     {
2568 michael 967 if (conf_parser_ctx.pass == 2)
2569 adx 30 {
2570     if (yy_conf->name != NULL)
2571     yyerror("Multiple connect name entry");
2572    
2573     MyFree(yy_conf->name);
2574     DupString(yy_conf->name, yylval.string);
2575     }
2576     };
2577    
2578     connect_name_t: QSTRING
2579     {
2580 michael 967 if (conf_parser_ctx.pass == 2)
2581 adx 30 {
2582     if (yy_conf->name != NULL)
2583     yyerror("Multiple connect name entry");
2584    
2585     MyFree(yy_conf->name);
2586     DupString(yy_conf->name, yylval.string);
2587     }
2588     };
2589    
2590     connect_host: HOST '=' QSTRING ';'
2591     {
2592 michael 967 if (conf_parser_ctx.pass == 2)
2593 adx 30 {
2594     MyFree(yy_aconf->host);
2595     DupString(yy_aconf->host, yylval.string);
2596     }
2597     };
2598    
2599     connect_vhost: VHOST '=' QSTRING ';'
2600     {
2601 michael 967 if (conf_parser_ctx.pass == 2)
2602 adx 30 {
2603     struct addrinfo hints, *res;
2604    
2605     memset(&hints, 0, sizeof(hints));
2606    
2607     hints.ai_family = AF_UNSPEC;
2608     hints.ai_socktype = SOCK_STREAM;
2609     hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
2610    
2611     if (irc_getaddrinfo(yylval.string, NULL, &hints, &res))
2612     ilog(L_ERROR, "Invalid netmask for server vhost(%s)", yylval.string);
2613     else
2614     {
2615     assert(res != NULL);
2616    
2617     memcpy(&yy_aconf->my_ipnum, res->ai_addr, res->ai_addrlen);
2618     yy_aconf->my_ipnum.ss.ss_family = res->ai_family;
2619     yy_aconf->my_ipnum.ss_len = res->ai_addrlen;
2620     irc_freeaddrinfo(res);
2621     }
2622     }
2623     };
2624    
2625     connect_send_password: SEND_PASSWORD '=' QSTRING ';'
2626     {
2627 michael 967 if (conf_parser_ctx.pass == 2)
2628 adx 30 {
2629 adx 38 if ($3[0] == ':')
2630     yyerror("Server passwords cannot begin with a colon");
2631     else if (strchr($3, ' ') != NULL)
2632     yyerror("Server passwords cannot contain spaces");
2633     else {
2634     if (yy_aconf->spasswd != NULL)
2635     memset(yy_aconf->spasswd, 0, strlen(yy_aconf->spasswd));
2636 adx 30
2637 adx 38 MyFree(yy_aconf->spasswd);
2638     DupString(yy_aconf->spasswd, yylval.string);
2639     }
2640 adx 30 }
2641     };
2642    
2643     connect_accept_password: ACCEPT_PASSWORD '=' QSTRING ';'
2644     {
2645 michael 967 if (conf_parser_ctx.pass == 2)
2646 adx 30 {
2647 adx 38 if ($3[0] == ':')
2648     yyerror("Server passwords cannot begin with a colon");
2649     else if (strchr($3, ' ') != NULL)
2650     yyerror("Server passwords cannot contain spaces");
2651     else {
2652     if (yy_aconf->passwd != NULL)
2653     memset(yy_aconf->passwd, 0, strlen(yy_aconf->passwd));
2654 adx 30
2655 adx 38 MyFree(yy_aconf->passwd);
2656     DupString(yy_aconf->passwd, yylval.string);
2657     }
2658 adx 30 }
2659     };
2660    
2661     connect_port: PORT '=' NUMBER ';'
2662     {
2663 michael 967 if (conf_parser_ctx.pass == 2)
2664 adx 30 yy_aconf->port = $3;
2665     };
2666    
2667     connect_aftype: AFTYPE '=' T_IPV4 ';'
2668     {
2669 michael 967 if (conf_parser_ctx.pass == 2)
2670 adx 30 yy_aconf->aftype = AF_INET;
2671     } | AFTYPE '=' T_IPV6 ';'
2672     {
2673     #ifdef IPV6
2674 michael 967 if (conf_parser_ctx.pass == 2)
2675 adx 30 yy_aconf->aftype = AF_INET6;
2676     #endif
2677     };
2678    
2679     connect_fakename: FAKENAME '=' QSTRING ';'
2680     {
2681 michael 967 if (conf_parser_ctx.pass == 2)
2682 adx 30 {
2683     MyFree(yy_aconf->fakename);
2684     DupString(yy_aconf->fakename, yylval.string);
2685     }
2686     };
2687    
2688     connect_flags: IRCD_FLAGS
2689     {
2690     } '=' connect_flags_items ';';
2691    
2692     connect_flags_items: connect_flags_items ',' connect_flags_item | connect_flags_item;
2693 db 136 connect_flags_item: NOT { not_atom = 1; } connect_flags_item_atom
2694     | { not_atom = 0; } connect_flags_item_atom;
2695 adx 30
2696 michael 885 connect_flags_item_atom: COMPRESSED
2697 adx 30 {
2698 michael 967 if (conf_parser_ctx.pass == 2)
2699 adx 30 #ifndef HAVE_LIBZ
2700     yyerror("Ignoring flags = compressed; -- no zlib support");
2701     #else
2702     {
2703     if (not_atom)ClearConfCompressed(yy_aconf);
2704     else SetConfCompressed(yy_aconf);
2705     }
2706     #endif
2707     } | CRYPTLINK
2708     {
2709 michael 967 if (conf_parser_ctx.pass == 2)
2710 adx 30 {
2711     if (not_atom)ClearConfCryptLink(yy_aconf);
2712     else SetConfCryptLink(yy_aconf);
2713     }
2714     } | AUTOCONN
2715     {
2716 michael 967 if (conf_parser_ctx.pass == 2)
2717 adx 30 {
2718     if (not_atom)ClearConfAllowAutoConn(yy_aconf);
2719     else SetConfAllowAutoConn(yy_aconf);
2720     }
2721     } | BURST_AWAY
2722     {
2723 michael 967 if (conf_parser_ctx.pass == 2)
2724 adx 30 {
2725     if (not_atom)ClearConfAwayBurst(yy_aconf);
2726     else SetConfAwayBurst(yy_aconf);
2727     }
2728     } | TOPICBURST
2729     {
2730 michael 967 if (conf_parser_ctx.pass == 2)
2731 adx 30 {
2732     if (not_atom)ClearConfTopicBurst(yy_aconf);
2733     else SetConfTopicBurst(yy_aconf);
2734     }
2735     }
2736     ;
2737    
2738     connect_rsa_public_key_file: RSA_PUBLIC_KEY_FILE '=' QSTRING ';'
2739     {
2740     #ifdef HAVE_LIBCRYPTO
2741 michael 967 if (conf_parser_ctx.pass == 2)
2742 adx 30 {
2743     BIO *file;
2744    
2745     if (yy_aconf->rsa_public_key != NULL)
2746     {
2747     RSA_free(yy_aconf->rsa_public_key);
2748     yy_aconf->rsa_public_key = NULL;
2749     }
2750    
2751     if (yy_aconf->rsa_public_key_file != NULL)
2752     {
2753     MyFree(yy_aconf->rsa_public_key_file);
2754     yy_aconf->rsa_public_key_file = NULL;
2755     }
2756    
2757     DupString(yy_aconf->rsa_public_key_file, yylval.string);
2758    
2759     if ((file = BIO_new_file(yylval.string, "r")) == NULL)
2760     {
2761     yyerror("Ignoring rsa_public_key_file -- file doesn't exist");
2762     break;
2763     }
2764    
2765     yy_aconf->rsa_public_key = (RSA *)PEM_read_bio_RSA_PUBKEY(file, NULL, 0, NULL);
2766    
2767     if (yy_aconf->rsa_public_key == NULL)
2768     {
2769     yyerror("Ignoring rsa_public_key_file -- Key invalid; check key syntax.");
2770     break;
2771     }
2772    
2773     BIO_set_close(file, BIO_CLOSE);
2774     BIO_free(file);
2775     }
2776     #endif /* HAVE_LIBCRYPTO */
2777     };
2778    
2779     connect_encrypted: ENCRYPTED '=' TBOOL ';'
2780     {
2781 michael 967 if (conf_parser_ctx.pass == 2)
2782 adx 30 {
2783     if (yylval.number)
2784     yy_aconf->flags |= CONF_FLAGS_ENCRYPTED;
2785     else
2786     yy_aconf->flags &= ~CONF_FLAGS_ENCRYPTED;
2787     }
2788     };
2789    
2790     connect_cryptlink: CRYPTLINK '=' TBOOL ';'
2791     {
2792 michael 967 if (conf_parser_ctx.pass == 2)
2793 adx 30 {
2794     if (yylval.number)
2795     yy_aconf->flags |= CONF_FLAGS_CRYPTLINK;
2796     else
2797     yy_aconf->flags &= ~CONF_FLAGS_CRYPTLINK;
2798     }
2799     };
2800    
2801     connect_compressed: COMPRESSED '=' TBOOL ';'
2802     {
2803 michael 967 if (conf_parser_ctx.pass == 2)
2804 adx 30 {
2805     if (yylval.number)
2806     #ifndef HAVE_LIBZ
2807     yyerror("Ignoring compressed=yes; -- no zlib support");
2808     #else
2809     yy_aconf->flags |= CONF_FLAGS_COMPRESSED;
2810     #endif
2811     else
2812     yy_aconf->flags &= ~CONF_FLAGS_COMPRESSED;
2813     }
2814     };
2815    
2816     connect_auto: AUTOCONN '=' TBOOL ';'
2817     {
2818 michael 967 if (conf_parser_ctx.pass == 2)
2819 adx 30 {
2820     if (yylval.number)
2821     yy_aconf->flags |= CONF_FLAGS_ALLOW_AUTO_CONN;
2822     else
2823     yy_aconf->flags &= ~CONF_FLAGS_ALLOW_AUTO_CONN;
2824     }
2825     };
2826    
2827 michael 341 connect_topicburst: TOPICBURST '=' TBOOL ';'
2828     {
2829 michael 967 if (conf_parser_ctx.pass == 2)
2830 michael 341 {
2831     if (yylval.number)
2832 michael 342 SetConfTopicBurst(yy_aconf);
2833 michael 341 else
2834     ClearConfTopicBurst(yy_aconf);
2835     }
2836     };
2837    
2838 adx 30 connect_hub_mask: HUB_MASK '=' QSTRING ';'
2839     {
2840 michael 967 if (conf_parser_ctx.pass == 2)
2841 adx 30 {
2842     struct CollectItem *yy_tmp;
2843    
2844     yy_tmp = (struct CollectItem *)MyMalloc(sizeof(struct CollectItem));
2845     DupString(yy_tmp->host, yylval.string);
2846     DupString(yy_tmp->user, "*");
2847     dlinkAdd(yy_tmp, &yy_tmp->node, &hub_conf_list);
2848     }
2849     };
2850    
2851     connect_leaf_mask: LEAF_MASK '=' QSTRING ';'
2852     {
2853 michael 967 if (conf_parser_ctx.pass == 2)
2854 adx 30 {
2855     struct CollectItem *yy_tmp;
2856    
2857     yy_tmp = (struct CollectItem *)MyMalloc(sizeof(struct CollectItem));
2858     DupString(yy_tmp->host, yylval.string);
2859     DupString(yy_tmp->user, "*");
2860     dlinkAdd(yy_tmp, &yy_tmp->node, &leaf_conf_list);
2861     }
2862     };
2863    
2864     connect_class: CLASS '=' QSTRING ';'
2865     {
2866 michael 967 if (conf_parser_ctx.pass == 2)
2867 adx 30 {
2868     MyFree(class_name);
2869     DupString(class_name, yylval.string);
2870     }
2871     };
2872    
2873     connect_cipher_preference: CIPHER_PREFERENCE '=' QSTRING ';'
2874     {
2875     #ifdef HAVE_LIBCRYPTO
2876 michael 967 if (conf_parser_ctx.pass == 2)
2877 adx 30 {
2878     struct EncCapability *ecap;
2879     const char *cipher_name;
2880     int found = 0;
2881    
2882     yy_aconf->cipher_preference = NULL;
2883     cipher_name = yylval.string;
2884    
2885     for (ecap = CipherTable; ecap->name; ecap++)
2886     {
2887     if ((irccmp(ecap->name, cipher_name) == 0) &&
2888     (ecap->cap & CAP_ENC_MASK))
2889     {
2890     yy_aconf->cipher_preference = ecap;
2891     found = 1;
2892     break;
2893     }
2894     }
2895    
2896     if (!found)
2897     yyerror("Invalid cipher");
2898     }
2899     #else
2900 michael 967 if (conf_parser_ctx.pass == 2)
2901 adx 30 yyerror("Ignoring cipher_preference -- no OpenSSL support");
2902     #endif
2903     };
2904    
2905     /***************************************************************************
2906     * section kill
2907     ***************************************************************************/
2908     kill_entry: KILL
2909     {
2910 michael 967 if (conf_parser_ctx.pass == 2)
2911 adx 30 {
2912     userbuf[0] = hostbuf[0] = reasonbuf[0] = '\0';
2913     regex_ban = 0;
2914     }
2915     } '{' kill_items '}' ';'
2916     {
2917 michael 967 if (conf_parser_ctx.pass == 2)
2918 adx 30 {
2919     if (userbuf[0] && hostbuf[0])
2920     {
2921     if (regex_ban)
2922     {
2923 michael 1009 #ifdef HAVE_LIBPCRE
2924     void *exp_user = NULL;
2925     void *exp_host = NULL;
2926 adx 30 const char *errptr = NULL;
2927    
2928     if (!(exp_user = ircd_pcre_compile(userbuf, &errptr)) ||
2929     !(exp_host = ircd_pcre_compile(hostbuf, &errptr)))
2930     {
2931 michael 595 ilog(L_ERROR, "Failed to add regular expression based K-Line: %s",
2932     errptr);
2933 adx 30 break;
2934     }
2935    
2936 michael 1005 yy_aconf = map_to_conf(make_conf_item(RKLINE_TYPE));
2937 adx 30 yy_aconf->regexuser = exp_user;
2938     yy_aconf->regexhost = exp_host;
2939    
2940     DupString(yy_aconf->user, userbuf);
2941     DupString(yy_aconf->host, hostbuf);
2942    
2943     if (reasonbuf[0])
2944     DupString(yy_aconf->reason, reasonbuf);
2945     else
2946     DupString(yy_aconf->reason, "No reason");
2947 michael 1009 #else
2948     ilog(L_ERROR, "Failed to add regular expression based K-Line: no PCRE support");
2949     break;
2950     #endif
2951 adx 30 }
2952     else
2953     {
2954 michael 1005 yy_aconf = map_to_conf(make_conf_item(KLINE_TYPE));
2955 adx 30
2956     DupString(yy_aconf->user, userbuf);
2957     DupString(yy_aconf->host, hostbuf);
2958    
2959     if (reasonbuf[0])
2960     DupString(yy_aconf->reason, reasonbuf);
2961     else
2962     DupString(yy_aconf->reason, "No reason");
2963     add_conf_by_address(CONF_KILL, yy_aconf);
2964     }
2965     }
2966    
2967     yy_aconf = NULL;
2968     }
2969     };
2970    
2971     kill_type: TYPE
2972     {
2973     } '=' kill_type_items ';';
2974    
2975     kill_type_items: kill_type_items ',' kill_type_item | kill_type_item;
2976     kill_type_item: REGEX_T
2977     {
2978 michael 967 if (conf_parser_ctx.pass == 2)
2979 adx 30 regex_ban = 1;
2980     };
2981    
2982     kill_items: kill_items kill_item | kill_item;
2983     kill_item: kill_user | kill_reason | kill_type | error;
2984    
2985     kill_user: USER '=' QSTRING ';'
2986     {
2987 michael 967 if (conf_parser_ctx.pass == 2)
2988 adx 30 {
2989 michael 593 struct split_nuh_item nuh;
2990 adx 30
2991 michael 593 nuh.nuhmask = yylval.string;
2992     nuh.nickptr = NULL;
2993     nuh.userptr = userbuf;
2994     nuh.hostptr = hostbuf;
2995 adx 30
2996 michael 593 nuh.nicksize = 0;
2997     nuh.usersize = sizeof(userbuf);
2998     nuh.hostsize = sizeof(hostbuf);
2999 adx 30
3000 michael 593 split_nuh(&nuh);
3001 adx 30 }
3002     };
3003    
3004     kill_reason: REASON '=' QSTRING ';'
3005     {
3006 michael 967 if (conf_parser_ctx.pass == 2)
3007 adx 30 strlcpy(reasonbuf, yylval.string, sizeof(reasonbuf));
3008     };
3009    
3010     /***************************************************************************
3011     * section deny
3012     ***************************************************************************/
3013     deny_entry: DENY
3014     {
3015 michael 967 if (conf_parser_ctx.pass == 2)
3016 michael 1005 hostbuf[0] = reasonbuf[0] = '\0';
3017 adx 30 } '{' deny_items '}' ';'
3018     {
3019 michael 967 if (conf_parser_ctx.pass == 2)
3020 adx 30 {
3021 michael 1005 if (hostbuf[0] && parse_netmask(hostbuf, NULL, NULL) != HM_HOST)
3022     {
3023     yy_aconf = map_to_conf(make_conf_item(DLINE_TYPE));
3024     DupString(yy_aconf->host, hostbuf);
3025    
3026     if (reasonbuf[0])
3027     DupString(yy_aconf->reason, reasonbuf);
3028     else
3029     DupString(yy_aconf->reason, "No reason");
3030 adx 30 add_conf_by_address(CONF_DLINE, yy_aconf);
3031 michael 1005 yy_aconf = NULL;
3032     }
3033 adx 30 }
3034     };
3035    
3036     deny_items: deny_items deny_item | deny_item;
3037     deny_item: deny_ip | deny_reason | error;
3038    
3039     deny_ip: IP '=' QSTRING ';'
3040     {
3041 michael 967 if (conf_parser_ctx.pass == 2)
3042 michael 1005 strlcpy(hostbuf, yylval.string, sizeof(hostbuf));
3043 adx 30 };
3044    
3045     deny_reason: REASON '=' QSTRING ';'
3046     {
3047 michael 967 if (conf_parser_ctx.pass == 2)
3048 michael 1005 strlcpy(reasonbuf, yylval.string, sizeof(reasonbuf));
3049 adx 30 };
3050    
3051     /***************************************************************************
3052     * section exempt
3053     ***************************************************************************/
3054     exempt_entry: EXEMPT '{' exempt_items '}' ';';
3055    
3056     exempt_items: exempt_items exempt_item | exempt_item;
3057     exempt_item: exempt_ip | error;
3058    
3059     exempt_ip: IP '=' QSTRING ';'
3060     {
3061 michael 967 if (conf_parser_ctx.pass == 2)
3062 adx 30 {
3063     if (yylval.string[0] && parse_netmask(yylval.string, NULL, NULL) != HM_HOST)
3064     {
3065 michael 1005 yy_aconf = map_to_conf(make_conf_item(EXEMPTDLINE_TYPE));
3066 adx 30 DupString(yy_aconf->host, yylval.string);
3067    
3068     add_conf_by_address(CONF_EXEMPTDLINE, yy_aconf);
3069     yy_aconf = NULL;
3070     }
3071     }
3072     };
3073    
3074     /***************************************************************************
3075     * section gecos
3076     ***************************************************************************/
3077     gecos_entry: GECOS
3078     {
3079 michael 967 if (conf_parser_ctx.pass == 2)
3080 adx 30 {
3081     regex_ban = 0;
3082     reasonbuf[0] = gecos_name[0] = '\0';
3083     }
3084     } '{' gecos_items '}' ';'
3085     {
3086 michael 967 if (conf_parser_ctx.pass == 2)
3087 adx 30 {
3088     if (gecos_name[0])
3089     {
3090     if (regex_ban)
3091     {
3092 michael 1009 #ifdef HAVE_LIBPCRE
3093     void *exp_p = NULL;
3094 adx 30 const char *errptr = NULL;
3095    
3096     if (!(exp_p = ircd_pcre_compile(gecos_name, &errptr)))
3097     {
3098 michael 595 ilog(L_ERROR, "Failed to add regular expression based X-Line: %s",
3099     errptr);
3100 adx 30 break;
3101     }
3102    
3103     yy_conf = make_conf_item(RXLINE_TYPE);
3104     yy_conf->regexpname = exp_p;
3105 michael 1009 #else
3106     ilog(L_ERROR, "Failed to add regular expression based X-Line: no PCRE support");
3107     break;
3108     #endif
3109 adx 30 }
3110     else
3111     yy_conf = make_conf_item(XLINE_TYPE);
3112    
3113     yy_match_item = map_to_conf(yy_conf);
3114     DupString(yy_conf->name, gecos_name);
3115    
3116     if (reasonbuf[0])
3117     DupString(yy_match_item->reason, reasonbuf);
3118     else
3119     DupString(yy_match_item->reason, "No reason");
3120     }
3121     }
3122     };
3123    
3124     gecos_flags: TYPE
3125     {
3126     } '=' gecos_flags_items ';';
3127    
3128     gecos_flags_items: gecos_flags_items ',' gecos_flags_item | gecos_flags_item;
3129     gecos_flags_item: REGEX_T
3130     {
3131 michael 967 if (conf_parser_ctx.pass == 2)
3132 adx 30 regex_ban = 1;
3133     };
3134    
3135     gecos_items: gecos_items gecos_item | gecos_item;
3136     gecos_item: gecos_name | gecos_reason | gecos_flags | error;
3137    
3138     gecos_name: NAME '=' QSTRING ';'
3139     {
3140 michael 967 if (conf_parser_ctx.pass == 2)
3141 adx 30 strlcpy(gecos_name, yylval.string, sizeof(gecos_name));
3142     };
3143    
3144     gecos_reason: REASON '=' QSTRING ';'
3145     {
3146 michael 967 if (conf_parser_ctx.pass == 2)
3147 adx 30 strlcpy(reasonbuf, yylval.string, sizeof(reasonbuf));
3148     };
3149    
3150     /***************************************************************************
3151     * section general
3152     ***************************************************************************/
3153     general_entry: GENERAL
3154     '{' general_items '}' ';';
3155    
3156     general_items: general_items general_item | general_item;
3157     general_item: general_hide_spoof_ips | general_ignore_bogus_ts |
3158     general_failed_oper_notice | general_anti_nick_flood |
3159     general_max_nick_time | general_max_nick_changes |
3160     general_max_accept | general_anti_spam_exit_message_time |
3161     general_ts_warn_delta | general_ts_max_delta |
3162     general_kill_chase_time_limit | general_kline_with_reason |
3163     general_kline_reason | general_invisible_on_connect |
3164     general_warn_no_nline | general_dots_in_ident |
3165     general_stats_o_oper_only | general_stats_k_oper_only |
3166     general_pace_wait | general_stats_i_oper_only |
3167     general_pace_wait_simple | general_stats_P_oper_only |
3168     general_short_motd | general_no_oper_flood |
3169     general_true_no_oper_flood | general_oper_pass_resv |
3170     general_idletime | general_message_locale |
3171     general_oper_only_umodes | general_max_targets |
3172     general_use_egd | general_egdpool_path |
3173     general_oper_umodes | general_caller_id_wait |
3174     general_opers_bypass_callerid | general_default_floodcount |
3175     general_min_nonwildcard | general_min_nonwildcard_simple |
3176     general_servlink_path | general_disable_remote_commands |
3177     general_default_cipher_preference |
3178     general_compression_level | general_client_flood |
3179     general_throttle_time | general_havent_read_conf |
3180     general_dot_in_ip6_addr | general_ping_cookie |
3181     general_disable_auth | general_burst_away |
3182     general_tkline_expire_notices | general_gline_min_cidr |
3183     general_gline_min_cidr6 | general_use_whois_actually |
3184 michael 584 general_reject_hold_time | general_stats_e_disabled |
3185 michael 876 general_max_watch |
3186 adx 30 error;
3187    
3188    
3189 michael 876 general_max_watch: MAX_WATCH '=' NUMBER ';'
3190     {
3191     ConfigFileEntry.max_watch = $3;
3192     };
3193 adx 30
3194     general_gline_min_cidr: GLINE_MIN_CIDR '=' NUMBER ';'
3195     {
3196     ConfigFileEntry.gline_min_cidr = $3;
3197     };
3198    
3199     general_gline_min_cidr6: GLINE_MIN_CIDR6 '=' NUMBER ';'
3200     {
3201     ConfigFileEntry.gline_min_cidr6 = $3;
3202     };
3203    
3204     general_burst_away: BURST_AWAY '=' TBOOL ';'
3205     {
3206     ConfigFileEntry.burst_away = yylval.number;
3207     };
3208    
3209     general_use_whois_actually: USE_WHOIS_ACTUALLY '=' TBOOL ';'
3210     {
3211     ConfigFileEntry.use_whois_actually = yylval.number;
3212     };
3213    
3214     general_reject_hold_time: TREJECT_HOLD_TIME '=' timespec ';'
3215     {
3216     GlobalSetOptions.rejecttime = yylval.number;
3217     };
3218    
3219     general_tkline_expire_notices: TKLINE_EXPIRE_NOTICES '=' TBOOL ';'
3220     {
3221     ConfigFileEntry.tkline_expire_notices = yylval.number;
3222     };
3223    
3224     general_kill_chase_time_limit: KILL_CHASE_TIME_LIMIT '=' NUMBER ';'
3225     {
3226     ConfigFileEntry.kill_chase_time_limit = $3;
3227     };
3228    
3229     general_hide_spoof_ips: HIDE_SPOOF_IPS '=' TBOOL ';'
3230     {
3231     ConfigFileEntry.hide_spoof_ips = yylval.number;
3232     };
3233    
3234     general_ignore_bogus_ts: IGNORE_BOGUS_TS '=' TBOOL ';'
3235     {
3236     ConfigFileEntry.ignore_bogus_ts = yylval.number;
3237     };
3238    
3239     general_disable_remote_commands: DISABLE_REMOTE_COMMANDS '=' TBOOL ';'
3240     {
3241     ConfigFileEntry.disable_remote = yylval.number;
3242     };
3243    
3244     general_failed_oper_notice: FAILED_OPER_NOTICE '=' TBOOL ';'
3245     {
3246     ConfigFileEntry.failed_oper_notice = yylval.number;
3247     };
3248    
3249     general_anti_nick_flood: ANTI_NICK_FLOOD '=' TBOOL ';'
3250     {
3251     ConfigFileEntry.anti_nick_flood = yylval.number;
3252     };
3253    
3254     general_max_nick_time: MAX_NICK_TIME '=' timespec ';'
3255     {
3256     ConfigFileEntry.max_nick_time = $3;
3257     };
3258    
3259     general_max_nick_changes: MAX_NICK_CHANGES '=' NUMBER ';'
3260     {
3261     ConfigFileEntry.max_nick_changes = $3;
3262     };
3263    
3264     general_max_accept: MAX_ACCEPT '=' NUMBER ';'
3265     {
3266     ConfigFileEntry.max_accept = $3;
3267     };
3268    
3269     general_anti_spam_exit_message_time: ANTI_SPAM_EXIT_MESSAGE_TIME '=' timespec ';'
3270     {
3271     ConfigFileEntry.anti_spam_exit_message_time = $3;
3272     };
3273    
3274     general_ts_warn_delta: TS_WARN_DELTA '=' timespec ';'
3275     {
3276     ConfigFileEntry.ts_warn_delta = $3;
3277     };
3278    
3279     general_ts_max_delta: TS_MAX_DELTA '=' timespec ';'
3280     {
3281 michael 967 if (conf_parser_ctx.pass == 2)
3282 adx 30 ConfigFileEntry.ts_max_delta = $3;
3283     };
3284    
3285     general_havent_read_conf: HAVENT_READ_CONF '=' NUMBER ';'
3286     {
3287 michael 967 if (($3 > 0) && conf_parser_ctx.pass == 1)
3288 adx 30 {
3289     ilog(L_CRIT, "You haven't read your config file properly.");
3290     ilog(L_CRIT, "There is a line in the example conf that will kill your server if not removed.");
3291     ilog(L_CRIT, "Consider actually reading/editing the conf file, and removing this line.");
3292     exit(0);
3293     }
3294     };
3295    
3296     general_kline_with_reason: KLINE_WITH_REASON '=' TBOOL ';'
3297     {
3298     ConfigFileEntry.kline_with_reason = yylval.number;
3299     };
3300    
3301     general_kline_reason: KLINE_REASON '=' QSTRING ';'
3302     {
3303 michael 967 if (conf_parser_ctx.pass == 2)
3304 adx 30 {
3305     MyFree(ConfigFileEntry.kline_reason);
3306     DupString(ConfigFileEntry.kline_reason, yylval.string);
3307     }
3308     };
3309    
3310     general_invisible_on_connect: INVISIBLE_ON_CONNECT '=' TBOOL ';'
3311     {
3312     ConfigFileEntry.invisible_on_connect = yylval.number;
3313     };
3314    
3315     general_warn_no_nline: WARN_NO_NLINE '=' TBOOL ';'
3316     {
3317     ConfigFileEntry.warn_no_nline = yylval.number;
3318     };
3319    
3320 michael 584 general_stats_e_disabled: STATS_E_DISABLED '=' TBOOL ';'
3321     {
3322     ConfigFileEntry.stats_e_disabled = yylval.number;
3323     };
3324    
3325 adx 30 general_stats_o_oper_only: STATS_O_OPER_ONLY '=' TBOOL ';'
3326     {
3327     ConfigFileEntry.stats_o_oper_only = yylval.number;
3328     };
3329    
3330     general_stats_P_oper_only: STATS_P_OPER_ONLY '=' TBOOL ';'
3331     {
3332     ConfigFileEntry.stats_P_oper_only = yylval.number;
3333     };
3334    
3335     general_stats_k_oper_only: STATS_K_OPER_ONLY '=' TBOOL ';'
3336     {
3337     ConfigFileEntry.stats_k_oper_only = 2 * yylval.number;
3338     } | STATS_K_OPER_ONLY '=' TMASKED ';'
3339     {
3340     ConfigFileEntry.stats_k_oper_only = 1;
3341     };
3342    
3343     general_stats_i_oper_only: STATS_I_OPER_ONLY '=' TBOOL ';'
3344     {
3345     ConfigFileEntry.stats_i_oper_only = 2 * yylval.number;
3346     } | STATS_I_OPER_ONLY '=' TMASKED ';'
3347     {
3348     ConfigFileEntry.stats_i_oper_only = 1;
3349     };
3350    
3351     general_pace_wait: PACE_WAIT '=' timespec ';'
3352     {
3353     ConfigFileEntry.pace_wait = $3;
3354     };
3355    
3356     general_caller_id_wait: CALLER_ID_WAIT '=' timespec ';'
3357     {
3358     ConfigFileEntry.caller_id_wait = $3;
3359     };
3360    
3361     general_opers_bypass_callerid: OPERS_BYPASS_CALLERID '=' TBOOL ';'
3362     {
3363     ConfigFileEntry.opers_bypass_callerid = yylval.number;
3364     };
3365    
3366     general_pace_wait_simple: PACE_WAIT_SIMPLE '=' timespec ';'
3367     {
3368     ConfigFileEntry.pace_wait_simple = $3;
3369     };
3370    
3371     general_short_motd: SHORT_MOTD '=' TBOOL ';'
3372     {
3373     ConfigFileEntry.short_motd = yylval.number;
3374     };
3375    
3376     general_no_oper_flood: NO_OPER_FLOOD '=' TBOOL ';'
3377     {
3378     ConfigFileEntry.no_oper_flood = yylval.number;
3379     };
3380    
3381     general_true_no_oper_flood: TRUE_NO_OPER_FLOOD '=' TBOOL ';'
3382     {
3383     ConfigFileEntry.true_no_oper_flood = yylval.number;
3384     };
3385    
3386     general_oper_pass_resv: OPER_PASS_RESV '=' TBOOL ';'
3387     {
3388     ConfigFileEntry.oper_pass_resv = yylval.number;
3389     };
3390    
3391     general_message_locale: MESSAGE_LOCALE '=' QSTRING ';'
3392     {
3393 michael 967 if (conf_parser_ctx.pass == 2)
3394 adx 30 {
3395     if (strlen(yylval.string) > LOCALE_LENGTH-2)
3396     yylval.string[LOCALE_LENGTH-1] = '\0';
3397    
3398     set_locale(yylval.string);
3399     }
3400     };
3401    
3402     general_idletime: IDLETIME '=' timespec ';'
3403     {
3404     ConfigFileEntry.idletime = $3;
3405     };
3406    
3407     general_dots_in_ident: DOTS_IN_IDENT '=' NUMBER ';'
3408     {
3409     ConfigFileEntry.dots_in_ident = $3;
3410     };
3411    
3412     general_max_targets: MAX_TARGETS '=' NUMBER ';'
3413     {
3414     ConfigFileEntry.max_targets = $3;
3415     };
3416    
3417     general_servlink_path: SERVLINK_PATH '=' QSTRING ';'
3418     {
3419 michael 967 if (conf_parser_ctx.pass == 2)
3420 adx 30 {
3421     MyFree(ConfigFileEntry.servlink_path);
3422     DupString(ConfigFileEntry.servlink_path, yylval.string);
3423     }
3424     };
3425    
3426     general_default_cipher_preference: DEFAULT_CIPHER_PREFERENCE '=' QSTRING ';'
3427     {
3428     #ifdef HAVE_LIBCRYPTO
3429 michael 967 if (conf_parser_ctx.pass == 2)
3430 adx 30 {
3431     struct EncCapability *ecap;
3432     const char *cipher_name;
3433     int found = 0;
3434    
3435     ConfigFileEntry.default_cipher_preference = NULL;
3436     cipher_name = yylval.string;
3437    
3438     for (ecap = CipherTable; ecap->name; ecap++)
3439     {
3440     if ((irccmp(ecap->name, cipher_name) == 0) &&
3441     (ecap->cap & CAP_ENC_MASK))
3442     {
3443     ConfigFileEntry.default_cipher_preference = ecap;
3444     found = 1;
3445     break;
3446     }
3447     }
3448    
3449     if (!found)
3450     yyerror("Invalid cipher");
3451     }
3452     #else
3453 michael 967 if (conf_parser_ctx.pass == 2)
3454 adx 30 yyerror("Ignoring default_cipher_preference -- no OpenSSL support");
3455     #endif
3456     };
3457    
3458     general_compression_level: COMPRESSION_LEVEL '=' NUMBER ';'
3459     {
3460 michael 967 if (conf_parser_ctx.pass == 2)
3461 adx 30 {
3462     ConfigFileEntry.compression_level = $3;
3463     #ifndef HAVE_LIBZ
3464     yyerror("Ignoring compression_level -- no zlib support");
3465     #else
3466     if ((ConfigFileEntry.compression_level < 1) ||
3467     (ConfigFileEntry.compression_level > 9))
3468     {
3469     yyerror("Ignoring invalid compression_level, using default");
3470     ConfigFileEntry.compression_level = 0;
3471     }
3472     #endif
3473     }
3474     };
3475    
3476     general_use_egd: USE_EGD '=' TBOOL ';'
3477     {
3478     ConfigFileEntry.use_egd = yylval.number;
3479     };
3480    
3481     general_egdpool_path: EGDPOOL_PATH '=' QSTRING ';'
3482     {
3483 michael 967 if (conf_parser_ctx.pass == 2)
3484 adx 30 {
3485     MyFree(ConfigFileEntry.egdpool_path);
3486     DupString(ConfigFileEntry.egdpool_path, yylval.string);
3487     }
3488     };
3489    
3490     general_ping_cookie: PING_COOKIE '=' TBOOL ';'
3491     {
3492     ConfigFileEntry.ping_cookie = yylval.number;
3493     };
3494    
3495     general_disable_auth: DISABLE_AUTH '=' TBOOL ';'
3496     {
3497     ConfigFileEntry.disable_auth = yylval.number;
3498     };
3499    
3500     general_throttle_time: THROTTLE_TIME '=' timespec ';'
3501     {
3502     ConfigFileEntry.throttle_time = yylval.number;
3503     };
3504    
3505     general_oper_umodes: OPER_UMODES
3506     {
3507     ConfigFileEntry.oper_umodes = 0;
3508     } '=' umode_oitems ';' ;
3509    
3510     umode_oitems: umode_oitems ',' umode_oitem | umode_oitem;
3511     umode_oitem: T_BOTS
3512     {
3513     ConfigFileEntry.oper_umodes |= UMODE_BOTS;
3514     } | T_CCONN
3515     {
3516     ConfigFileEntry.oper_umodes |= UMODE_CCONN;
3517 db 849 } | T_CCONN_FULL
3518     {
3519     ConfigFileEntry.oper_umodes |= UMODE_CCONN_FULL;
3520 adx 30 } | T_DEAF
3521     {
3522     ConfigFileEntry.oper_umodes |= UMODE_DEAF;
3523     } | T_DEBUG
3524     {
3525     ConfigFileEntry.oper_umodes |= UMODE_DEBUG;
3526     } | T_FULL
3527     {
3528     ConfigFileEntry.oper_umodes |= UMODE_FULL;
3529     } | T_SKILL
3530     {
3531     ConfigFileEntry.oper_umodes |= UMODE_SKILL;
3532     } | T_NCHANGE
3533     {
3534     ConfigFileEntry.oper_umodes |= UMODE_NCHANGE;
3535     } | T_REJ
3536     {
3537     ConfigFileEntry.oper_umodes |= UMODE_REJ;
3538     } | T_UNAUTH
3539     {
3540     ConfigFileEntry.oper_umodes |= UMODE_UNAUTH;
3541     } | T_SPY
3542     {
3543     ConfigFileEntry.oper_umodes |= UMODE_SPY;
3544     } | T_EXTERNAL
3545     {
3546     ConfigFileEntry.oper_umodes |= UMODE_EXTERNAL;
3547     } | T_OPERWALL
3548     {
3549     ConfigFileEntry.oper_umodes |= UMODE_OPERWALL;
3550     } | T_SERVNOTICE
3551     {
3552     ConfigFileEntry.oper_umodes |= UMODE_SERVNOTICE;
3553     } | T_INVISIBLE
3554     {
3555     ConfigFileEntry.oper_umodes |= UMODE_INVISIBLE;
3556     } | T_WALLOP
3557     {
3558     ConfigFileEntry.oper_umodes |= UMODE_WALLOP;
3559     } | T_SOFTCALLERID
3560     {
3561     ConfigFileEntry.oper_umodes |= UMODE_SOFTCALLERID;
3562     } | T_CALLERID
3563     {
3564     ConfigFileEntry.oper_umodes |= UMODE_CALLERID;
3565     } | T_LOCOPS
3566     {
3567     ConfigFileEntry.oper_umodes |= UMODE_LOCOPS;
3568     };
3569    
3570     general_oper_only_umodes: OPER_ONLY_UMODES
3571     {
3572     ConfigFileEntry.oper_only_umodes = 0;
3573     } '=' umode_items ';' ;
3574    
3575     umode_items: umode_items ',' umode_item | umode_item;
3576     umode_item: T_BOTS
3577     {
3578     ConfigFileEntry.oper_only_umodes |= UMODE_BOTS;
3579     } | T_CCONN
3580     {
3581     ConfigFileEntry.oper_only_umodes |= UMODE_CCONN;
3582 db 853 } | T_CCONN_FULL
3583     {
3584     ConfigFileEntry.oper_only_umodes |= UMODE_CCONN_FULL;
3585 adx 30 } | T_DEAF
3586     {
3587     ConfigFileEntry.oper_only_umodes |= UMODE_DEAF;
3588     } | T_DEBUG
3589     {
3590     ConfigFileEntry.oper_only_umodes |= UMODE_DEBUG;
3591     } | T_FULL
3592     {
3593     ConfigFileEntry.oper_only_umodes |= UMODE_FULL;
3594     } | T_SKILL
3595     {
3596     ConfigFileEntry.oper_only_umodes |= UMODE_SKILL;
3597     } | T_NCHANGE
3598     {
3599     ConfigFileEntry.oper_only_umodes |= UMODE_NCHANGE;
3600     } | T_REJ
3601     {
3602     ConfigFileEntry.oper_only_umodes |= UMODE_REJ;
3603     } | T_UNAUTH
3604     {
3605     ConfigFileEntry.oper_only_umodes |= UMODE_UNAUTH;
3606     } | T_SPY
3607     {
3608     ConfigFileEntry.oper_only_umodes |= UMODE_SPY;
3609     } | T_EXTERNAL
3610     {
3611     ConfigFileEntry.oper_only_umodes |= UMODE_EXTERNAL;
3612     } | T_OPERWALL
3613     {
3614     ConfigFileEntry.oper_only_umodes |= UMODE_OPERWALL;
3615     } | T_SERVNOTICE
3616     {
3617     ConfigFileEntry.oper_only_umodes |= UMODE_SERVNOTICE;
3618     } | T_INVISIBLE
3619     {
3620     ConfigFileEntry.oper_only_umodes |= UMODE_INVISIBLE;
3621     } | T_WALLOP
3622     {
3623     ConfigFileEntry.oper_only_umodes |= UMODE_WALLOP;
3624     } | T_SOFTCALLERID
3625     {
3626     ConfigFileEntry.oper_only_umodes |= UMODE_SOFTCALLERID;
3627     } | T_CALLERID
3628     {
3629     ConfigFileEntry.oper_only_umodes |= UMODE_CALLERID;
3630     } | T_LOCOPS
3631     {
3632     ConfigFileEntry.oper_only_umodes |= UMODE_LOCOPS;
3633     };
3634    
3635     general_min_nonwildcard: MIN_NONWILDCARD '=' NUMBER ';'
3636     {
3637     ConfigFileEntry.min_nonwildcard = $3;
3638     };
3639    
3640     general_min_nonwildcard_simple: MIN_NONWILDCARD_SIMPLE '=' NUMBER ';'
3641     {
3642     ConfigFileEntry.min_nonwildcard_simple = $3;
3643     };
3644    
3645     general_default_floodcount: DEFAULT_FLOODCOUNT '=' NUMBER ';'
3646     {
3647     ConfigFileEntry.default_floodcount = $3;
3648     };
3649    
3650     general_client_flood: T_CLIENT_FLOOD '=' sizespec ';'
3651     {
3652     ConfigFileEntry.client_flood = $3;
3653     };
3654    
3655     general_dot_in_ip6_addr: DOT_IN_IP6_ADDR '=' TBOOL ';'
3656     {
3657     ConfigFileEntry.dot_in_ip6_addr = yylval.number;
3658     };
3659    
3660     /***************************************************************************
3661     * section glines
3662     ***************************************************************************/
3663     gline_entry: GLINES
3664     {
3665 michael 967 if (conf_parser_ctx.pass == 2)
3666 adx 30 {
3667     yy_conf = make_conf_item(GDENY_TYPE);
3668 michael 102 yy_aconf = map_to_conf(yy_conf);
3669 adx 30 }
3670     } '{' gline_items '}' ';'
3671     {
3672 michael 967 if (conf_parser_ctx.pass == 2)
3673 adx 30 {
3674     /*
3675     * since we re-allocate yy_conf/yy_aconf after the end of action=, at the
3676     * end we will have one extra, so we should free it.
3677     */
3678 michael 102 if (yy_conf->name == NULL || yy_aconf->user == NULL)
3679 adx 30 {
3680 michael 102 delete_conf_item(yy_conf);
3681 adx 30 yy_conf = NULL;
3682     yy_aconf = NULL;
3683     }
3684     }
3685     };
3686    
3687     gline_items: gline_items gline_item | gline_item;
3688     gline_item: gline_enable |
3689     gline_duration |
3690     gline_logging |
3691     gline_user |
3692     gline_server |
3693     gline_action |
3694     error;
3695    
3696     gline_enable: ENABLE '=' TBOOL ';'
3697     {
3698 michael 967 if (conf_parser_ctx.pass == 2)
3699 adx 30 ConfigFileEntry.glines = yylval.number;
3700     };
3701    
3702     gline_duration: DURATION '=' timespec ';'
3703     {
3704 michael 967 if (conf_parser_ctx.pass == 2)
3705 adx 30 ConfigFileEntry.gline_time = $3;
3706     };
3707    
3708     gline_logging: LOGGING
3709     {
3710 michael 967 if (conf_parser_ctx.pass == 2)
3711 adx 30 ConfigFileEntry.gline_logging = 0;
3712     } '=' gline_logging_types ';';
3713     gline_logging_types: gline_logging_types ',' gline_logging_type_item | gline_logging_type_item;
3714     gline_logging_type_item: T_REJECT
3715     {
3716 michael 967 if (conf_parser_ctx.pass == 2)
3717 adx 30 ConfigFileEntry.gline_logging |= GDENY_REJECT;
3718     } | T_BLOCK
3719     {
3720 michael 967 if (conf_parser_ctx.pass == 2)
3721 adx 30 ConfigFileEntry.gline_logging |= GDENY_BLOCK;
3722     };
3723    
3724     gline_user: USER '=' QSTRING ';'
3725     {
3726 michael 967 if (conf_parser_ctx.pass == 2)
3727 adx 30 {
3728 michael 593 struct split_nuh_item nuh;
3729 adx 30
3730 michael 593 nuh.nuhmask = yylval.string;
3731     nuh.nickptr = NULL;
3732     nuh.userptr = userbuf;
3733     nuh.hostptr = hostbuf;
3734    
3735     nuh.nicksize = 0;
3736     nuh.usersize = sizeof(userbuf);
3737     nuh.hostsize = sizeof(hostbuf);
3738    
3739     split_nuh(&nuh);
3740    
3741 adx 30 if (yy_aconf->user == NULL)
3742     {
3743 michael 593 DupString(yy_aconf->user, userbuf);
3744     DupString(yy_aconf->host, hostbuf);
3745 adx 30 }
3746     else
3747     {
3748 michael 593 struct CollectItem *yy_tmp = MyMalloc(sizeof(struct CollectItem));
3749    
3750     DupString(yy_tmp->user, userbuf);
3751     DupString(yy_tmp->host, hostbuf);
3752    
3753 adx 30 dlinkAdd(yy_tmp, &yy_tmp->node, &col_conf_list);
3754     }
3755     }
3756     };
3757    
3758     gline_server: NAME '=' QSTRING ';'
3759     {
3760 michael 967 if (conf_parser_ctx.pass == 2)
3761 adx 30 {
3762     MyFree(yy_conf->name);
3763     DupString(yy_conf->name, yylval.string);
3764     }
3765     };
3766    
3767     gline_action: ACTION
3768     {
3769 michael 967 if (conf_parser_ctx.pass == 2)
3770 adx 30 yy_aconf->flags = 0;
3771     } '=' gdeny_types ';'
3772     {
3773 michael 967 if (conf_parser_ctx.pass == 2)
3774 adx 30 {
3775 michael 102 struct CollectItem *yy_tmp = NULL;
3776 adx 30 dlink_node *ptr, *next_ptr;
3777    
3778     DLINK_FOREACH_SAFE(ptr, next_ptr, col_conf_list.head)
3779     {
3780     struct AccessItem *new_aconf;
3781     struct ConfItem *new_conf;
3782    
3783     yy_tmp = ptr->data;
3784     new_conf = make_conf_item(GDENY_TYPE);
3785 michael 102 new_aconf = map_to_conf(new_conf);
3786 adx 30
3787     new_aconf->flags = yy_aconf->flags;
3788    
3789     if (yy_conf->name != NULL)
3790     DupString(new_conf->name, yy_conf->name);
3791     else
3792     DupString(new_conf->name, "*");
3793     if (yy_aconf->user != NULL)
3794     DupString(new_aconf->user, yy_tmp->user);
3795     else
3796     DupString(new_aconf->user, "*");
3797     if (yy_aconf->host != NULL)
3798     DupString(new_aconf->host, yy_tmp->host);
3799     else
3800     DupString(new_aconf->host, "*");
3801    
3802     dlinkDelete(&yy_tmp->node, &col_conf_list);
3803     }
3804 michael 102
3805     /*
3806     * In case someone has fed us with more than one action= after user/name
3807     * which would leak memory -Michael
3808     */
3809     if (yy_conf->name == NULL || yy_aconf->user == NULL)
3810     delete_conf_item(yy_conf);
3811    
3812     yy_conf = make_conf_item(GDENY_TYPE);
3813     yy_aconf = map_to_conf(yy_conf);
3814 adx 30 }
3815     };
3816    
3817     gdeny_types: gdeny_types ',' gdeny_type_item | gdeny_type_item;
3818     gdeny_type_item: T_REJECT
3819     {
3820 michael 967 if (conf_parser_ctx.pass == 2)
3821 adx 30 yy_aconf->flags |= GDENY_REJECT;
3822     } | T_BLOCK
3823     {
3824 michael 967 if (conf_parser_ctx.pass == 2)
3825 adx 30 yy_aconf->flags |= GDENY_BLOCK;
3826     };
3827    
3828     /***************************************************************************
3829     * section channel
3830     ***************************************************************************/
3831     channel_entry: CHANNEL
3832     '{' channel_items '}' ';';
3833    
3834     channel_items: channel_items channel_item | channel_item;
3835     channel_item: channel_disable_local_channels | channel_use_except |
3836     channel_use_invex | channel_use_knock |
3837     channel_max_bans | channel_knock_delay |
3838 adx 201 channel_knock_delay_channel | channel_max_chans_per_user |
3839     channel_quiet_on_ban | channel_default_split_user_count |
3840     channel_default_split_server_count |
3841     channel_no_create_on_split | channel_restrict_channels |
3842     channel_no_join_on_split | channel_burst_topicwho |
3843     channel_jflood_count | channel_jflood_time |
3844 michael 632 channel_disable_fake_channels | error;
3845 adx 30
3846 michael 632 channel_disable_fake_channels: DISABLE_FAKE_CHANNELS '=' TBOOL ';'
3847     {
3848     ConfigChannel.disable_fake_channels = yylval.number;
3849     };
3850    
3851 adx 30 channel_restrict_channels: RESTRICT_CHANNELS '=' TBOOL ';'
3852     {
3853     ConfigChannel.restrict_channels = yylval.number;
3854     };
3855    
3856     channel_disable_local_channels: DISABLE_LOCAL_CHANNELS '=' TBOOL ';'
3857     {
3858     ConfigChannel.disable_local_channels = yylval.number;
3859     };
3860    
3861     channel_use_except: USE_EXCEPT '=' TBOOL ';'
3862     {
3863     ConfigChannel.use_except = yylval.number;
3864     };
3865    
3866     channel_use_invex: USE_INVEX '=' TBOOL ';'
3867     {
3868     ConfigChannel.use_invex = yylval.number;
3869     };
3870    
3871     channel_use_knock: USE_KNOCK '=' TBOOL ';'
3872     {
3873     ConfigChannel.use_knock = yylval.number;
3874     };
3875    
3876     channel_knock_delay: KNOCK_DELAY '=' timespec ';'
3877     {
3878     ConfigChannel.knock_delay = $3;
3879     };
3880    
3881     channel_knock_delay_channel: KNOCK_DELAY_CHANNEL '=' timespec ';'
3882     {
3883     ConfigChannel.knock_delay_channel = $3;
3884     };
3885    
3886     channel_max_chans_per_user: MAX_CHANS_PER_USER '=' NUMBER ';'
3887     {
3888     ConfigChannel.max_chans_per_user = $3;
3889     };
3890    
3891     channel_quiet_on_ban: QUIET_ON_BAN '=' TBOOL ';'
3892     {
3893     ConfigChannel.quiet_on_ban = yylval.number;
3894     };
3895    
3896     channel_max_bans: MAX_BANS '=' NUMBER ';'
3897     {
3898     ConfigChannel.max_bans = $3;
3899     };
3900    
3901     channel_default_split_user_count: DEFAULT_SPLIT_USER_COUNT '=' NUMBER ';'
3902     {
3903     ConfigChannel.default_split_user_count = $3;
3904     };
3905    
3906     channel_default_split_server_count: DEFAULT_SPLIT_SERVER_COUNT '=' NUMBER ';'
3907     {
3908     ConfigChannel.default_split_server_count = $3;
3909     };
3910    
3911     channel_no_create_on_split: NO_CREATE_ON_SPLIT '=' TBOOL ';'
3912     {
3913     ConfigChannel.no_create_on_split = yylval.number;
3914     };
3915    
3916     channel_no_join_on_split: NO_JOIN_ON_SPLIT '=' TBOOL ';'
3917     {
3918     ConfigChannel.no_join_on_split = yylval.number;
3919     };
3920    
3921     channel_burst_topicwho: BURST_TOPICWHO '=' TBOOL ';'
3922     {
3923     ConfigChannel.burst_topicwho = yylval.number;
3924     };
3925    
3926     channel_jflood_count: JOIN_FLOOD_COUNT '=' NUMBER ';'
3927     {
3928     GlobalSetOptions.joinfloodcount = yylval.number;
3929     };
3930    
3931     channel_jflood_time: JOIN_FLOOD_TIME '=' timespec ';'
3932     {
3933     GlobalSetOptions.joinfloodtime = yylval.number;
3934     };
3935    
3936     /***************************************************************************
3937     * section serverhide
3938     ***************************************************************************/
3939     serverhide_entry: SERVERHIDE
3940     '{' serverhide_items '}' ';';
3941    
3942     serverhide_items: serverhide_items serverhide_item | serverhide_item;
3943     serverhide_item: serverhide_flatten_links | serverhide_hide_servers |
3944     serverhide_links_delay |
3945     serverhide_disable_hidden |
3946     serverhide_hidden | serverhide_hidden_name |
3947     serverhide_hide_server_ips |
3948     error;
3949    
3950     serverhide_flatten_links: FLATTEN_LINKS '=' TBOOL ';'
3951     {
3952 michael 967 if (conf_parser_ctx.pass == 2)
3953 adx 30 ConfigServerHide.flatten_links = yylval.number;
3954     };
3955    
3956     serverhide_hide_servers: HIDE_SERVERS '=' TBOOL ';'
3957     {
3958 michael 967 if (conf_parser_ctx.pass == 2)
3959 adx 30 ConfigServerHide.hide_servers = yylval.number;
3960     };
3961    
3962     serverhide_hidden_name: HIDDEN_NAME '=' QSTRING ';'
3963     {
3964 michael 967 if (conf_parser_ctx.pass == 2)
3965 adx 30 {
3966     MyFree(ConfigServerHide.hidden_name);
3967     DupString(ConfigServerHide.hidden_name, yylval.string);
3968     }
3969     };
3970    
3971     serverhide_links_delay: LINKS_DELAY '=' timespec ';'
3972     {
3973 michael 967 if (conf_parser_ctx.pass == 2)
3974 adx 30 {
3975     if (($3 > 0) && ConfigServerHide.links_disabled == 1)
3976     {
3977     eventAddIsh("write_links_file", write_links_file, NULL, $3);
3978     ConfigServerHide.links_disabled = 0;
3979     }
3980    
3981     ConfigServerHide.links_delay = $3;
3982     }
3983     };
3984    
3985     serverhide_hidden: HIDDEN '=' TBOOL ';'
3986     {
3987 michael 967 if (conf_parser_ctx.pass == 2)
3988 adx 30 ConfigServerHide.hidden = yylval.number;
3989     };
3990    
3991     serverhide_disable_hidden: DISABLE_HIDDEN '=' TBOOL ';'
3992     {
3993 michael 967 if (conf_parser_ctx.pass == 2)
3994 adx 30 ConfigServerHide.disable_hidden = yylval.number;
3995     };
3996    
3997     serverhide_hide_server_ips: HIDE_SERVER_IPS '=' TBOOL ';'
3998     {
3999 michael 967 if (conf_parser_ctx.pass == 2)
4000 adx 30 ConfigServerHide.hide_server_ips = yylval.number;
4001     };

Properties

Name Value
svn:eol-style native
svn:keywords Id Revision