ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/conf_parser.y
Revision: 967
Committed: Sun Aug 2 18:05:28 2009 UTC (14 years, 7 months ago) by michael
Original Path: ircd-hybrid-7.2/src/ircd_parser.y
File size: 94526 byte(s)
Log Message:
- added ssl_server_protocol configuration option to servinfo{}.
  valid flags are 'sslv3' and 'tlsv1'

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

Properties

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