ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/conf_parser.y
Revision: 1011
Committed: Fri Sep 18 10:14:09 2009 UTC (15 years, 11 months ago) by michael
Original Path: ircd-hybrid-7.2/src/ircd_parser.y
File size: 94388 byte(s)
Log Message:
- move list manipulation routines from tools.c to list.c
- mem_frob() goes to memory.c
- sort out redundant/unneeded header includes

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

Properties

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