ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/branches/8.2.x/src/conf_parser.y
Revision: 1074
Committed: Wed Feb 17 23:28:33 2010 UTC (16 years, 5 months ago) by michael
Original Path: ircd-hybrid-7.3/src/ircd_parser.y
File size: 94345 byte(s)
Log Message:
- Made general::kill_chase_time_limit accept time units. too bad this entire
  crap is still needed even with ts6.

File Contents

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

Properties

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