ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/conf_parser.y
Revision: 1646
Committed: Wed Nov 7 21:02:43 2012 UTC (13 years, 11 months ago) by michael
File size: 69808 byte(s)
Log Message:
- First pass of conf parser stabilization/cleanup

File Contents

# User Rev Content
1 adx 30 /*
2     * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 michael 1309 * conf_parser.y: Parses the ircd configuration file.
4 adx 30 *
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 michael 1309 #include "conf.h"
36 michael 1632 #include "conf_class.h"
37 adx 30 #include "event.h"
38 michael 1309 #include "log.h"
39 adx 30 #include "client.h" /* for UMODE_ALL only */
40     #include "irc_string.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 michael 1306 #include <openssl/dh.h>
57 adx 30 #endif
58    
59 michael 1329 int yylex(void);
60    
61 adx 30 static char *class_name = NULL;
62 michael 1632 static struct MaskItem *yy_conf = NULL;
63 adx 30 static struct ClassItem *yy_class = NULL;
64     static char *yy_class_name = NULL;
65    
66     static dlink_list col_conf_list = { NULL, NULL, 0 };
67     static unsigned int listener_flags = 0;
68     static unsigned int regex_ban = 0;
69     static char userbuf[IRCD_BUFSIZE];
70     static char hostbuf[IRCD_BUFSIZE];
71     static char reasonbuf[REASONLEN + 1];
72     static char gecos_name[REALLEN * 4];
73 michael 1247 static char lfile[IRCD_BUFSIZE];
74     static unsigned int ltype = 0;
75     static unsigned int lsize = 0;
76 adx 30 static char *resv_reason = NULL;
77     static char *listener_address = NULL;
78    
79 michael 1646 static struct
80 michael 593 {
81 michael 1646 struct {
82     dlink_list list;
83     } mask,
84     leaf,
85     hub;
86 adx 30
87 michael 1646 struct {
88     char buf[IRCD_BUFSIZE];
89     } name,
90     user,
91     host,
92     addr,
93     pass,
94     file,
95     class;
96    
97     struct {
98     unsigned int value;
99     } flags,
100     modes,
101     port,
102     ping_freq,
103     max_perip,
104     con_freq,
105     max_total,
106     max_global,
107     max_local,
108     max_ident,
109     max_sendq,
110     max_recvq,
111     cidr_bitlen_ipv4,
112     cidr_bitlen_ipv6,
113     number_per_cidr;
114     } block_state;
115    
116 adx 30 static void
117 michael 1646 reset_block_state(void)
118 adx 30 {
119 michael 1646 dlink_node *ptr = NULL, *ptr_next = NULL;
120    
121     DLINK_FOREACH_SAFE(ptr, ptr_next, block_state.mask.list.head)
122     {
123     MyFree(ptr->data);
124     dlinkDelete(ptr, &block_state.mask.list);
125     free_dlink_node(ptr);
126     }
127    
128     DLINK_FOREACH_SAFE(ptr, ptr_next, block_state.leaf.list.head)
129     {
130     MyFree(ptr->data);
131     dlinkDelete(ptr, &block_state.leaf.list);
132     free_dlink_node(ptr);
133     }
134    
135     DLINK_FOREACH_SAFE(ptr, ptr_next, block_state.hub.list.head)
136     {
137     MyFree(ptr->data);
138     dlinkDelete(ptr, &block_state.hub.list);
139     free_dlink_node(ptr);
140     }
141    
142     memset(&block_state, 0, sizeof(block_state));
143 adx 30 }
144    
145     %}
146    
147     %union {
148     int number;
149     char *string;
150     }
151    
152     %token ACCEPT_PASSWORD
153     %token ADMIN
154     %token AFTYPE
155     %token ANTI_NICK_FLOOD
156     %token ANTI_SPAM_EXIT_MESSAGE_TIME
157     %token AUTOCONN
158 michael 1520 %token BYTES KBYTES MBYTES
159 adx 30 %token CALLER_ID_WAIT
160     %token CAN_FLOOD
161     %token CHANNEL
162     %token CIDR_BITLEN_IPV4
163     %token CIDR_BITLEN_IPV6
164     %token CLASS
165     %token CONNECT
166     %token CONNECTFREQ
167     %token DEFAULT_FLOODCOUNT
168     %token DEFAULT_SPLIT_SERVER_COUNT
169     %token DEFAULT_SPLIT_USER_COUNT
170     %token DENY
171     %token DESCRIPTION
172     %token DIE
173     %token DISABLE_AUTH
174 michael 632 %token DISABLE_FAKE_CHANNELS
175 adx 30 %token DISABLE_REMOTE_COMMANDS
176     %token DOTS_IN_IDENT
177     %token EGDPOOL_PATH
178     %token EMAIL
179     %token ENCRYPTED
180     %token EXCEED_LIMIT
181     %token EXEMPT
182     %token FAILED_OPER_NOTICE
183     %token IRCD_FLAGS
184     %token FLATTEN_LINKS
185     %token GECOS
186     %token GENERAL
187     %token GLINE
188 michael 1459 %token GLINE_DURATION
189     %token GLINE_ENABLE
190 adx 30 %token GLINE_EXEMPT
191 michael 1459 %token GLINE_REQUEST_DURATION
192 adx 30 %token GLINE_MIN_CIDR
193     %token GLINE_MIN_CIDR6
194     %token GLOBAL_KILL
195     %token IRCD_AUTH
196     %token NEED_IDENT
197     %token HAVENT_READ_CONF
198     %token HIDDEN
199     %token HIDDEN_NAME
200     %token HIDE_SERVER_IPS
201     %token HIDE_SERVERS
202     %token HIDE_SPOOF_IPS
203     %token HOST
204     %token HUB
205     %token HUB_MASK
206     %token IGNORE_BOGUS_TS
207     %token INVISIBLE_ON_CONNECT
208     %token IP
209     %token KILL
210     %token KILL_CHASE_TIME_LIMIT
211     %token KLINE
212     %token KLINE_EXEMPT
213     %token KNOCK_DELAY
214     %token KNOCK_DELAY_CHANNEL
215     %token LEAF_MASK
216     %token LINKS_DELAY
217     %token LISTEN
218     %token T_LOG
219     %token MAX_ACCEPT
220     %token MAX_BANS
221 michael 1432 %token MAX_CHANS_PER_OPER
222 adx 30 %token MAX_CHANS_PER_USER
223     %token MAX_GLOBAL
224     %token MAX_IDENT
225     %token MAX_LOCAL
226     %token MAX_NICK_CHANGES
227     %token MAX_NICK_TIME
228     %token MAX_NUMBER
229     %token MAX_TARGETS
230 michael 876 %token MAX_WATCH
231 adx 30 %token MESSAGE_LOCALE
232     %token MIN_NONWILDCARD
233     %token MIN_NONWILDCARD_SIMPLE
234     %token MODULE
235     %token MODULES
236     %token NAME
237     %token NEED_PASSWORD
238     %token NETWORK_DESC
239     %token NETWORK_NAME
240     %token NICK
241     %token NICK_CHANGES
242     %token NO_CREATE_ON_SPLIT
243     %token NO_JOIN_ON_SPLIT
244     %token NO_OPER_FLOOD
245     %token NO_TILDE
246     %token NUMBER
247     %token NUMBER_PER_CIDR
248     %token NUMBER_PER_IP
249     %token OPERATOR
250     %token OPERS_BYPASS_CALLERID
251     %token OPER_ONLY_UMODES
252     %token OPER_PASS_RESV
253     %token OPER_SPY_T
254     %token OPER_UMODES
255     %token JOIN_FLOOD_COUNT
256     %token JOIN_FLOOD_TIME
257     %token PACE_WAIT
258     %token PACE_WAIT_SIMPLE
259     %token PASSWORD
260     %token PATH
261     %token PING_COOKIE
262     %token PING_TIME
263     %token PORT
264     %token QSTRING
265     %token QUIET_ON_BAN
266     %token REASON
267     %token REDIRPORT
268     %token REDIRSERV
269     %token REGEX_T
270     %token REHASH
271     %token REMOTE
272     %token REMOTEBAN
273     %token RESTRICT_CHANNELS
274     %token RSA_PRIVATE_KEY_FILE
275     %token RSA_PUBLIC_KEY_FILE
276     %token SSL_CERTIFICATE_FILE
277 michael 1306 %token SSL_DH_PARAM_FILE
278 michael 1316 %token T_SSL_CLIENT_METHOD
279     %token T_SSL_SERVER_METHOD
280 michael 967 %token T_SSLV3
281     %token T_TLSV1
282 adx 30 %token RESV
283     %token RESV_EXEMPT
284     %token SECONDS MINUTES HOURS DAYS WEEKS
285     %token SENDQ
286     %token SEND_PASSWORD
287     %token SERVERHIDE
288     %token SERVERINFO
289     %token IRCD_SID
290     %token TKLINE_EXPIRE_NOTICES
291     %token T_SHARED
292     %token T_CLUSTER
293     %token TYPE
294     %token SHORT_MOTD
295     %token SPOOF
296     %token SPOOF_NOTICE
297 michael 584 %token STATS_E_DISABLED
298 adx 30 %token STATS_I_OPER_ONLY
299     %token STATS_K_OPER_ONLY
300     %token STATS_O_OPER_ONLY
301     %token STATS_P_OPER_ONLY
302     %token TBOOL
303     %token TMASKED
304     %token TS_MAX_DELTA
305     %token TS_WARN_DELTA
306     %token TWODOTS
307     %token T_ALL
308     %token T_BOTS
309     %token T_SOFTCALLERID
310     %token T_CALLERID
311     %token T_CCONN
312 db 849 %token T_CCONN_FULL
313 michael 1306 %token T_SSL_CIPHER_LIST
314 adx 30 %token T_DEAF
315     %token T_DEBUG
316 michael 1247 %token T_DLINE
317 adx 30 %token T_EXTERNAL
318     %token T_FULL
319     %token T_INVISIBLE
320     %token T_IPV4
321     %token T_IPV6
322     %token T_LOCOPS
323     %token T_MAX_CLIENTS
324     %token T_NCHANGE
325     %token T_OPERWALL
326 michael 1516 %token T_RECVQ
327 adx 30 %token T_REJ
328 michael 900 %token T_SERVER
329 adx 30 %token T_SERVNOTICE
330 michael 1460 %token T_SET
331 adx 30 %token T_SKILL
332     %token T_SPY
333     %token T_SSL
334 michael 56 %token T_UMODES
335 adx 30 %token T_UNAUTH
336 michael 1301 %token T_UNDLINE
337 michael 1250 %token T_UNLIMITED
338 adx 30 %token T_UNRESV
339     %token T_UNXLINE
340 michael 1216 %token T_GLOBOPS
341 adx 30 %token T_WALLOP
342 michael 1228 %token T_RESTART
343 michael 1157 %token T_SERVICE
344 michael 1176 %token T_SERVICES_NAME
345 adx 30 %token THROTTLE_TIME
346     %token TRUE_NO_OPER_FLOOD
347     %token UNKLINE
348     %token USER
349     %token USE_EGD
350     %token USE_LOGGING
351     %token VHOST
352     %token VHOST6
353     %token XLINE
354     %token WARN_NO_NLINE
355 michael 1247 %token T_SIZE
356     %token T_FILE
357 adx 30
358     %type <string> QSTRING
359     %type <number> NUMBER
360     %type <number> timespec
361     %type <number> timespec_
362     %type <number> sizespec
363     %type <number> sizespec_
364    
365     %%
366     conf:
367     | conf conf_item
368     ;
369    
370     conf_item: admin_entry
371     | logging_entry
372     | oper_entry
373     | channel_entry
374     | class_entry
375     | listen_entry
376     | auth_entry
377     | serverinfo_entry
378     | serverhide_entry
379     | resv_entry
380 michael 1157 | service_entry
381 adx 30 | shared_entry
382     | cluster_entry
383     | connect_entry
384     | kill_entry
385     | deny_entry
386     | exempt_entry
387     | general_entry
388     | gecos_entry
389     | modules_entry
390     | error ';'
391     | error '}'
392     ;
393    
394    
395     timespec_: { $$ = 0; } | timespec;
396     timespec: NUMBER timespec_
397     {
398     $$ = $1 + $2;
399     }
400     | NUMBER SECONDS timespec_
401     {
402     $$ = $1 + $3;
403     }
404     | NUMBER MINUTES timespec_
405     {
406     $$ = $1 * 60 + $3;
407     }
408     | NUMBER HOURS timespec_
409     {
410     $$ = $1 * 60 * 60 + $3;
411     }
412     | NUMBER DAYS timespec_
413     {
414     $$ = $1 * 60 * 60 * 24 + $3;
415     }
416     | NUMBER WEEKS timespec_
417     {
418     $$ = $1 * 60 * 60 * 24 * 7 + $3;
419     }
420     ;
421    
422     sizespec_: { $$ = 0; } | sizespec;
423     sizespec: NUMBER sizespec_ { $$ = $1 + $2; }
424     | NUMBER BYTES sizespec_ { $$ = $1 + $3; }
425     | NUMBER KBYTES sizespec_ { $$ = $1 * 1024 + $3; }
426     | NUMBER MBYTES sizespec_ { $$ = $1 * 1024 * 1024 + $3; }
427     ;
428    
429    
430     /***************************************************************************
431     * section modules
432     ***************************************************************************/
433     modules_entry: MODULES
434     '{' modules_items '}' ';';
435    
436     modules_items: modules_items modules_item | modules_item;
437     modules_item: modules_module | modules_path | error ';' ;
438    
439     modules_module: MODULE '=' QSTRING ';'
440     {
441 michael 967 if (conf_parser_ctx.pass == 2)
442 michael 978 add_conf_module(libio_basename(yylval.string));
443 adx 30 };
444    
445     modules_path: PATH '=' QSTRING ';'
446     {
447 michael 967 if (conf_parser_ctx.pass == 2)
448 adx 30 mod_add_path(yylval.string);
449     };
450    
451    
452 michael 967 serverinfo_entry: SERVERINFO '{' serverinfo_items '}' ';';
453    
454     serverinfo_items: serverinfo_items serverinfo_item | serverinfo_item ;
455 adx 30 serverinfo_item: serverinfo_name | serverinfo_vhost |
456     serverinfo_hub | serverinfo_description |
457     serverinfo_network_name | serverinfo_network_desc |
458 michael 1306 serverinfo_max_clients | serverinfo_ssl_dh_param_file |
459 adx 30 serverinfo_rsa_private_key_file | serverinfo_vhost6 |
460     serverinfo_sid | serverinfo_ssl_certificate_file |
461 michael 1316 serverinfo_ssl_client_method | serverinfo_ssl_server_method |
462     serverinfo_ssl_cipher_list |
463 adx 30 error ';' ;
464    
465 michael 967
466 michael 1316 serverinfo_ssl_client_method: T_SSL_CLIENT_METHOD '=' client_method_types ';' ;
467     serverinfo_ssl_server_method: T_SSL_SERVER_METHOD '=' server_method_types ';' ;
468    
469     client_method_types: client_method_types ',' client_method_type_item | client_method_type_item;
470     client_method_type_item: T_SSLV3
471 michael 967 {
472 michael 1024 #ifdef HAVE_LIBCRYPTO
473 michael 1316 if (conf_parser_ctx.pass == 2 && ServerInfo.client_ctx)
474     SSL_CTX_clear_options(ServerInfo.client_ctx, SSL_OP_NO_SSLv3);
475 michael 1024 #endif
476 michael 1316 } | T_TLSV1
477 michael 967 {
478 michael 1024 #ifdef HAVE_LIBCRYPTO
479 michael 1316 if (conf_parser_ctx.pass == 2 && ServerInfo.client_ctx)
480     SSL_CTX_clear_options(ServerInfo.client_ctx, SSL_OP_NO_TLSv1);
481 michael 1024 #endif
482 michael 967 };
483    
484 michael 1316 server_method_types: server_method_types ',' server_method_type_item | server_method_type_item;
485     server_method_type_item: T_SSLV3
486 michael 967 {
487 michael 1024 #ifdef HAVE_LIBCRYPTO
488 michael 1316 if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx)
489     SSL_CTX_clear_options(ServerInfo.server_ctx, SSL_OP_NO_SSLv3);
490 michael 1024 #endif
491 michael 967 } | T_TLSV1
492     {
493 michael 1024 #ifdef HAVE_LIBCRYPTO
494 michael 1316 if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx)
495     SSL_CTX_clear_options(ServerInfo.server_ctx, SSL_OP_NO_TLSv1);
496 michael 1024 #endif
497 michael 967 };
498    
499 adx 30 serverinfo_ssl_certificate_file: SSL_CERTIFICATE_FILE '=' QSTRING ';'
500     {
501     #ifdef HAVE_LIBCRYPTO
502 michael 967 if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx)
503 adx 30 {
504     if (!ServerInfo.rsa_private_key_file)
505     {
506     yyerror("No rsa_private_key_file specified, SSL disabled");
507     break;
508     }
509    
510 michael 967 if (SSL_CTX_use_certificate_file(ServerInfo.server_ctx, yylval.string,
511 michael 1303 SSL_FILETYPE_PEM) <= 0 ||
512     SSL_CTX_use_certificate_file(ServerInfo.client_ctx, yylval.string,
513 michael 967 SSL_FILETYPE_PEM) <= 0)
514 adx 30 {
515     yyerror(ERR_lib_error_string(ERR_get_error()));
516     break;
517     }
518    
519 michael 967 if (SSL_CTX_use_PrivateKey_file(ServerInfo.server_ctx, ServerInfo.rsa_private_key_file,
520 michael 1303 SSL_FILETYPE_PEM) <= 0 ||
521     SSL_CTX_use_PrivateKey_file(ServerInfo.client_ctx, ServerInfo.rsa_private_key_file,
522 michael 967 SSL_FILETYPE_PEM) <= 0)
523 adx 30 {
524     yyerror(ERR_lib_error_string(ERR_get_error()));
525     break;
526     }
527    
528 michael 1303 if (!SSL_CTX_check_private_key(ServerInfo.server_ctx) ||
529     !SSL_CTX_check_private_key(ServerInfo.client_ctx))
530 adx 30 {
531 michael 967 yyerror(ERR_lib_error_string(ERR_get_error()));
532 adx 30 break;
533     }
534     }
535     #endif
536     };
537    
538     serverinfo_rsa_private_key_file: RSA_PRIVATE_KEY_FILE '=' QSTRING ';'
539     {
540     #ifdef HAVE_LIBCRYPTO
541 michael 967 if (conf_parser_ctx.pass == 1)
542 adx 30 {
543     BIO *file;
544    
545     if (ServerInfo.rsa_private_key)
546     {
547     RSA_free(ServerInfo.rsa_private_key);
548     ServerInfo.rsa_private_key = NULL;
549     }
550    
551     if (ServerInfo.rsa_private_key_file)
552     {
553     MyFree(ServerInfo.rsa_private_key_file);
554     ServerInfo.rsa_private_key_file = NULL;
555     }
556    
557 michael 1646 ServerInfo.rsa_private_key_file = xstrdup(yylval.string);
558 adx 30
559     if ((file = BIO_new_file(yylval.string, "r")) == NULL)
560     {
561     yyerror("File open failed, ignoring");
562     break;
563     }
564    
565 michael 1306 ServerInfo.rsa_private_key = PEM_read_bio_RSAPrivateKey(file, NULL, 0, NULL);
566 adx 30
567     BIO_set_close(file, BIO_CLOSE);
568     BIO_free(file);
569    
570     if (ServerInfo.rsa_private_key == NULL)
571     {
572     yyerror("Couldn't extract key, ignoring");
573     break;
574     }
575    
576     if (!RSA_check_key(ServerInfo.rsa_private_key))
577     {
578     RSA_free(ServerInfo.rsa_private_key);
579     ServerInfo.rsa_private_key = NULL;
580    
581     yyerror("Invalid key, ignoring");
582     break;
583     }
584    
585     /* require 2048 bit (256 byte) key */
586     if (RSA_size(ServerInfo.rsa_private_key) != 256)
587     {
588     RSA_free(ServerInfo.rsa_private_key);
589     ServerInfo.rsa_private_key = NULL;
590    
591     yyerror("Not a 2048 bit key, ignoring");
592     }
593     }
594     #endif
595     };
596    
597 michael 1306 serverinfo_ssl_dh_param_file: SSL_DH_PARAM_FILE '=' QSTRING ';'
598     {
599     /* TBD - XXX: error reporting */
600     #ifdef HAVE_LIBCRYPTO
601     if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx)
602     {
603     BIO *file = BIO_new_file(yylval.string, "r");
604    
605     if (file)
606     {
607     DH *dh = PEM_read_bio_DHparams(file, NULL, NULL, NULL);
608    
609     BIO_free(file);
610    
611     if (dh)
612     {
613 michael 1352 if (DH_size(dh) < 128)
614     ilog(LOG_TYPE_IRCD, "Ignoring serverinfo::ssl_dh_param_file -- need at least a 1024 bit DH prime size");
615     else
616     SSL_CTX_set_tmp_dh(ServerInfo.server_ctx, dh);
617    
618 michael 1306 DH_free(dh);
619     }
620     }
621     }
622     #endif
623     };
624    
625     serverinfo_ssl_cipher_list: T_SSL_CIPHER_LIST '=' QSTRING ';'
626     {
627     #ifdef HAVE_LIBCRYPTO
628     if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx)
629     SSL_CTX_set_cipher_list(ServerInfo.server_ctx, yylval.string);
630     #endif
631     };
632    
633 adx 30 serverinfo_name: NAME '=' QSTRING ';'
634     {
635     /* this isn't rehashable */
636 michael 1117 if (conf_parser_ctx.pass == 2 && !ServerInfo.name)
637 adx 30 {
638 michael 1117 if (valid_servname(yylval.string))
639 michael 1646 ServerInfo.name = xstrdup(yylval.string);
640 michael 1117 else
641 adx 30 {
642 michael 1247 ilog(LOG_TYPE_IRCD, "Ignoring serverinfo::name -- invalid name. Aborting.");
643 michael 1117 exit(0);
644 adx 30 }
645     }
646     };
647    
648     serverinfo_sid: IRCD_SID '=' QSTRING ';'
649     {
650     /* this isn't rehashable */
651 michael 967 if (conf_parser_ctx.pass == 2 && !ServerInfo.sid)
652 adx 30 {
653 michael 573 if (valid_sid(yylval.string))
654 michael 1646 ServerInfo.sid = xstrdup(yylval.string);
655 adx 30 else
656     {
657 michael 1247 ilog(LOG_TYPE_IRCD, "Ignoring serverinfo::sid -- invalid SID. Aborting.");
658 adx 30 exit(0);
659     }
660     }
661     };
662    
663     serverinfo_description: DESCRIPTION '=' QSTRING ';'
664     {
665 michael 967 if (conf_parser_ctx.pass == 2)
666 adx 30 {
667     MyFree(ServerInfo.description);
668 michael 1646 ServerInfo.description = xstrdup(yylval.string);
669 adx 30 }
670     };
671    
672     serverinfo_network_name: NETWORK_NAME '=' QSTRING ';'
673     {
674 michael 967 if (conf_parser_ctx.pass == 2)
675 adx 30 {
676     char *p;
677    
678     if ((p = strchr(yylval.string, ' ')) != NULL)
679     p = '\0';
680    
681     MyFree(ServerInfo.network_name);
682 michael 1646 ServerInfo.network_name = xstrdup(yylval.string);
683 adx 30 }
684     };
685    
686     serverinfo_network_desc: NETWORK_DESC '=' QSTRING ';'
687     {
688 michael 967 if (conf_parser_ctx.pass == 2)
689 adx 30 {
690     MyFree(ServerInfo.network_desc);
691 michael 1646 ServerInfo.network_desc = xstrdup(yylval.string);
692 adx 30 }
693     };
694    
695     serverinfo_vhost: VHOST '=' QSTRING ';'
696     {
697 michael 967 if (conf_parser_ctx.pass == 2 && *yylval.string != '*')
698 adx 30 {
699     struct addrinfo hints, *res;
700    
701     memset(&hints, 0, sizeof(hints));
702    
703     hints.ai_family = AF_UNSPEC;
704     hints.ai_socktype = SOCK_STREAM;
705     hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
706    
707 michael 1123 if (getaddrinfo(yylval.string, NULL, &hints, &res))
708 michael 1247 ilog(LOG_TYPE_IRCD, "Invalid netmask for server vhost(%s)", yylval.string);
709 adx 30 else
710     {
711     assert(res != NULL);
712    
713     memcpy(&ServerInfo.ip, res->ai_addr, res->ai_addrlen);
714     ServerInfo.ip.ss.ss_family = res->ai_family;
715     ServerInfo.ip.ss_len = res->ai_addrlen;
716 michael 1123 freeaddrinfo(res);
717 adx 30
718     ServerInfo.specific_ipv4_vhost = 1;
719     }
720     }
721     };
722    
723     serverinfo_vhost6: VHOST6 '=' QSTRING ';'
724     {
725     #ifdef IPV6
726 michael 967 if (conf_parser_ctx.pass == 2 && *yylval.string != '*')
727 adx 30 {
728     struct addrinfo hints, *res;
729    
730     memset(&hints, 0, sizeof(hints));
731    
732     hints.ai_family = AF_UNSPEC;
733     hints.ai_socktype = SOCK_STREAM;
734     hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
735    
736 michael 1123 if (getaddrinfo(yylval.string, NULL, &hints, &res))
737 michael 1247 ilog(LOG_TYPE_IRCD, "Invalid netmask for server vhost6(%s)", yylval.string);
738 adx 30 else
739     {
740     assert(res != NULL);
741    
742     memcpy(&ServerInfo.ip6, res->ai_addr, res->ai_addrlen);
743     ServerInfo.ip6.ss.ss_family = res->ai_family;
744     ServerInfo.ip6.ss_len = res->ai_addrlen;
745 michael 1123 freeaddrinfo(res);
746 adx 30
747     ServerInfo.specific_ipv6_vhost = 1;
748     }
749     }
750     #endif
751     };
752    
753     serverinfo_max_clients: T_MAX_CLIENTS '=' NUMBER ';'
754     {
755 michael 967 if (conf_parser_ctx.pass == 2)
756 adx 30 {
757     recalc_fdlimit(NULL);
758    
759     if ($3 < MAXCLIENTS_MIN)
760     {
761     char buf[IRCD_BUFSIZE];
762     ircsprintf(buf, "MAXCLIENTS too low, setting to %d", MAXCLIENTS_MIN);
763     yyerror(buf);
764     }
765     else if ($3 > MAXCLIENTS_MAX)
766     {
767     char buf[IRCD_BUFSIZE];
768     ircsprintf(buf, "MAXCLIENTS too high, setting to %d", MAXCLIENTS_MAX);
769     yyerror(buf);
770     }
771     else
772     ServerInfo.max_clients = $3;
773     }
774     };
775    
776     serverinfo_hub: HUB '=' TBOOL ';'
777     {
778 michael 967 if (conf_parser_ctx.pass == 2)
779 michael 1119 ServerInfo.hub = yylval.number;
780 adx 30 };
781    
782     /***************************************************************************
783     * admin section
784     ***************************************************************************/
785     admin_entry: ADMIN '{' admin_items '}' ';' ;
786    
787     admin_items: admin_items admin_item | admin_item;
788     admin_item: admin_name | admin_description |
789     admin_email | error ';' ;
790    
791     admin_name: NAME '=' QSTRING ';'
792     {
793 michael 967 if (conf_parser_ctx.pass == 2)
794 adx 30 {
795     MyFree(AdminInfo.name);
796 michael 1646 AdminInfo.name = xstrdup(yylval.string);
797 adx 30 }
798     };
799    
800     admin_email: EMAIL '=' QSTRING ';'
801     {
802 michael 967 if (conf_parser_ctx.pass == 2)
803 adx 30 {
804     MyFree(AdminInfo.email);
805 michael 1646 AdminInfo.email = xstrdup(yylval.string);
806 adx 30 }
807     };
808    
809     admin_description: DESCRIPTION '=' QSTRING ';'
810     {
811 michael 967 if (conf_parser_ctx.pass == 2)
812 adx 30 {
813     MyFree(AdminInfo.description);
814 michael 1646 AdminInfo.description = xstrdup(yylval.string);
815 adx 30 }
816     };
817    
818     /***************************************************************************
819     * section logging
820     ***************************************************************************/
821 michael 1247 logging_entry: T_LOG '{' logging_items '}' ';' ;
822     logging_items: logging_items logging_item | logging_item ;
823 adx 30
824 michael 1324 logging_item: logging_use_logging | logging_file_entry |
825 adx 30 error ';' ;
826    
827 michael 1247 logging_use_logging: USE_LOGGING '=' TBOOL ';'
828 adx 30 {
829 michael 967 if (conf_parser_ctx.pass == 2)
830 michael 1247 ConfigLoggingEntry.use_logging = yylval.number;
831 adx 30 };
832    
833 michael 1247 logging_file_entry:
834 adx 30 {
835 michael 1247 lfile[0] = '\0';
836     ltype = 0;
837     lsize = 0;
838     } T_FILE '{' logging_file_items '}' ';'
839 adx 30 {
840 michael 1248 if (conf_parser_ctx.pass == 2 && ltype > 0)
841 michael 1247 log_add_file(ltype, lsize, lfile);
842 adx 30 };
843    
844 michael 1247 logging_file_items: logging_file_items logging_file_item |
845     logging_file_item ;
846 adx 30
847 michael 1247 logging_file_item: logging_file_name | logging_file_type |
848     logging_file_size | error ';' ;
849    
850     logging_file_name: NAME '=' QSTRING ';'
851 adx 30 {
852 michael 1247 strlcpy(lfile, yylval.string, sizeof(lfile));
853     }
854 adx 30
855 michael 1247 logging_file_size: T_SIZE '=' sizespec ';'
856 adx 30 {
857 michael 1247 lsize = $3;
858 michael 1250 } | T_SIZE '=' T_UNLIMITED ';'
859     {
860     lsize = 0;
861 adx 30 };
862    
863 michael 1247 logging_file_type: TYPE
864 adx 30 {
865 michael 967 if (conf_parser_ctx.pass == 2)
866 michael 1247 ltype = 0;
867     } '=' logging_file_type_items ';' ;
868 adx 30
869 michael 1247 logging_file_type_items: logging_file_type_items ',' logging_file_type_item | logging_file_type_item;
870     logging_file_type_item: USER
871 adx 30 {
872 michael 967 if (conf_parser_ctx.pass == 2)
873 michael 1247 ltype = LOG_TYPE_USER;
874     } | OPERATOR
875 adx 30 {
876 michael 967 if (conf_parser_ctx.pass == 2)
877 michael 1247 ltype = LOG_TYPE_OPER;
878     } | GLINE
879 adx 30 {
880 michael 967 if (conf_parser_ctx.pass == 2)
881 michael 1247 ltype = LOG_TYPE_GLINE;
882     } | T_DLINE
883 adx 30 {
884 michael 967 if (conf_parser_ctx.pass == 2)
885 michael 1247 ltype = LOG_TYPE_DLINE;
886     } | KLINE
887 adx 30 {
888 michael 967 if (conf_parser_ctx.pass == 2)
889 michael 1247 ltype = LOG_TYPE_KLINE;
890     } | KILL
891 adx 30 {
892 michael 967 if (conf_parser_ctx.pass == 2)
893 michael 1247 ltype = LOG_TYPE_KILL;
894     } | T_DEBUG
895 adx 30 {
896 michael 967 if (conf_parser_ctx.pass == 2)
897 michael 1247 ltype = LOG_TYPE_DEBUG;
898 adx 30 };
899    
900 michael 1247
901 adx 30 /***************************************************************************
902     * section oper
903     ***************************************************************************/
904     oper_entry: OPERATOR
905     {
906 michael 1646 if (conf_parser_ctx.pass != 2)
907     break;
908    
909     reset_block_state();
910     block_state.flags.value |= CONF_FLAGS_ENCRYPTED;
911 michael 1285 } '{' oper_items '}' ';'
912 adx 30 {
913 michael 1646 dlink_node *ptr = NULL;
914 adx 30
915 michael 1646 if (conf_parser_ctx.pass != 2)
916     break;
917 adx 30
918 michael 1646 if (!block_state.name.buf[0])
919     break;
920     #ifdef HAVE_LIBCRYPTO
921     if (!(block_state.file.buf[0] ||
922     block_state.pass.buf[0]))
923     break;
924     #else
925     if (!block_state.pass.buf[0])
926     break;
927     #endif
928 adx 30
929 michael 1646 DLINK_FOREACH(ptr, block_state.mask.list.head)
930     {
931     struct MaskItem *conf = NULL;
932     struct split_nuh_item nuh;
933 adx 30
934 michael 1646 nuh.nuhmask = ptr->data;
935     nuh.nickptr = NULL;
936     nuh.userptr = userbuf;
937     nuh.hostptr = hostbuf;
938     nuh.nicksize = 0;
939     nuh.usersize = sizeof(userbuf);
940     nuh.hostsize = sizeof(hostbuf);
941     split_nuh(&nuh);
942 adx 30
943 michael 1646 conf = conf_make(CONF_OPER);
944     conf->user = xstrdup(userbuf);
945     conf->host = xstrdup(hostbuf);
946 michael 1285
947 michael 1646 if (block_state.pass.buf[0])
948     conf->passwd = xstrdup(block_state.pass.buf);
949 michael 1285
950 michael 1646 conf->flags = block_state.flags.value;
951     conf->modes = block_state.modes.value;
952     conf->port = block_state.port.value;
953     conf->htype = parse_netmask(conf->host, &conf->addr, &conf->bits);
954 adx 30
955 michael 1646 conf_add_class_to_conf(conf, block_state.class.buf);
956    
957 adx 30 #ifdef HAVE_LIBCRYPTO
958 michael 1646 if (block_state.file.buf[0])
959     {
960     BIO *file = NULL;
961     RSA *pkey = NULL;
962    
963     if ((file = BIO_new_file(block_state.file.buf, "r")) == NULL)
964 adx 30 {
965 michael 1646 yyerror("Ignoring rsa_public_key_file -- file doesn't exist");
966     break;
967 adx 30 }
968    
969 michael 1646 if ((pkey = PEM_read_bio_RSA_PUBKEY(file, NULL, 0, NULL)) == NULL)
970 adx 30 {
971 michael 1646 yyerror("Ignoring rsa_public_key_file -- Key invalid; check key syntax.");
972     break;
973 adx 30 }
974    
975 michael 1646 conf->rsa_public_key = pkey;
976     BIO_set_close(file, BIO_CLOSE);
977     BIO_free(file);
978 adx 30 }
979 michael 1646 #endif /* HAVE_LIBCRYPTO */
980 adx 30 }
981 michael 1646 };
982 adx 30
983     oper_items: oper_items oper_item | oper_item;
984 michael 1076 oper_item: oper_name | oper_user | oper_password |
985     oper_umodes | oper_class | oper_encrypted |
986     oper_rsa_public_key_file | oper_flags | error ';' ;
987 adx 30
988     oper_name: NAME '=' QSTRING ';'
989     {
990 michael 967 if (conf_parser_ctx.pass == 2)
991 michael 1646 strlcpy(block_state.name.buf, yylval.string, sizeof(block_state.name.buf));
992 adx 30 };
993    
994     oper_user: USER '=' QSTRING ';'
995     {
996 michael 967 if (conf_parser_ctx.pass == 2)
997 michael 1646 dlinkAdd(xstrdup(yylval.string), make_dlink_node(), &block_state.mask.list);
998 adx 30 };
999    
1000     oper_password: PASSWORD '=' QSTRING ';'
1001     {
1002 michael 967 if (conf_parser_ctx.pass == 2)
1003 michael 1646 strlcpy(block_state.pass.buf, yylval.string, sizeof(block_state.pass.buf));
1004 adx 30 };
1005    
1006     oper_encrypted: ENCRYPTED '=' TBOOL ';'
1007     {
1008 michael 967 if (conf_parser_ctx.pass == 2)
1009 adx 30 {
1010     if (yylval.number)
1011 michael 1646 block_state.flags.value |= CONF_FLAGS_ENCRYPTED;
1012 adx 30 else
1013 michael 1646 block_state.flags.value &= ~CONF_FLAGS_ENCRYPTED;
1014 adx 30 }
1015     };
1016    
1017     oper_rsa_public_key_file: RSA_PUBLIC_KEY_FILE '=' QSTRING ';'
1018     {
1019 michael 967 if (conf_parser_ctx.pass == 2)
1020 michael 1646 strlcpy(block_state.file.buf, yylval.string, sizeof(block_state.file.buf));
1021 adx 30 };
1022    
1023     oper_class: CLASS '=' QSTRING ';'
1024     {
1025 michael 967 if (conf_parser_ctx.pass == 2)
1026 michael 1646 strlcpy(block_state.class.buf, yylval.string, sizeof(block_state.class.buf));
1027 adx 30 };
1028    
1029 michael 56 oper_umodes: T_UMODES
1030     {
1031 michael 967 if (conf_parser_ctx.pass == 2)
1032 michael 1646 block_state.modes.value = 0;
1033 michael 56 } '=' oper_umodes_items ';' ;
1034    
1035     oper_umodes_items: oper_umodes_items ',' oper_umodes_item | oper_umodes_item;
1036     oper_umodes_item: T_BOTS
1037     {
1038 michael 967 if (conf_parser_ctx.pass == 2)
1039 michael 1646 block_state.modes.value |= UMODE_BOTS;
1040 michael 56 } | T_CCONN
1041     {
1042 michael 967 if (conf_parser_ctx.pass == 2)
1043 michael 1646 block_state.modes.value |= UMODE_CCONN;
1044 db 849 } | T_CCONN_FULL
1045     {
1046 michael 967 if (conf_parser_ctx.pass == 2)
1047 michael 1646 block_state.modes.value |= UMODE_CCONN_FULL;
1048 michael 56 } | T_DEAF
1049     {
1050 michael 967 if (conf_parser_ctx.pass == 2)
1051 michael 1646 block_state.modes.value |= UMODE_DEAF;
1052 michael 56 } | T_DEBUG
1053     {
1054 michael 967 if (conf_parser_ctx.pass == 2)
1055 michael 1646 block_state.modes.value |= UMODE_DEBUG;
1056 michael 56 } | T_FULL
1057     {
1058 michael 967 if (conf_parser_ctx.pass == 2)
1059 michael 1646 block_state.modes.value |= UMODE_FULL;
1060 michael 1294 } | HIDDEN
1061     {
1062     if (conf_parser_ctx.pass == 2)
1063 michael 1646 block_state.modes.value |= UMODE_HIDDEN;
1064 michael 56 } | T_SKILL
1065     {
1066 michael 967 if (conf_parser_ctx.pass == 2)
1067 michael 1646 block_state.modes.value |= UMODE_SKILL;
1068 michael 56 } | T_NCHANGE
1069     {
1070 michael 967 if (conf_parser_ctx.pass == 2)
1071 michael 1646 block_state.modes.value |= UMODE_NCHANGE;
1072 michael 56 } | T_REJ
1073     {
1074 michael 967 if (conf_parser_ctx.pass == 2)
1075 michael 1646 block_state.modes.value |= UMODE_REJ;
1076 michael 56 } | T_UNAUTH
1077     {
1078 michael 967 if (conf_parser_ctx.pass == 2)
1079 michael 1646 block_state.modes.value |= UMODE_UNAUTH;
1080 michael 56 } | T_SPY
1081     {
1082 michael 967 if (conf_parser_ctx.pass == 2)
1083 michael 1646 block_state.modes.value |= UMODE_SPY;
1084 michael 56 } | T_EXTERNAL
1085     {
1086 michael 967 if (conf_parser_ctx.pass == 2)
1087 michael 1646 block_state.modes.value |= UMODE_EXTERNAL;
1088 michael 56 } | T_OPERWALL
1089     {
1090 michael 967 if (conf_parser_ctx.pass == 2)
1091 michael 1646 block_state.modes.value |= UMODE_OPERWALL;
1092 michael 56 } | T_SERVNOTICE
1093     {
1094 michael 967 if (conf_parser_ctx.pass == 2)
1095 michael 1646 block_state.modes.value |= UMODE_SERVNOTICE;
1096 michael 56 } | T_INVISIBLE
1097     {
1098 michael 967 if (conf_parser_ctx.pass == 2)
1099 michael 1646 block_state.modes.value |= UMODE_INVISIBLE;
1100 michael 56 } | T_WALLOP
1101     {
1102 michael 967 if (conf_parser_ctx.pass == 2)
1103 michael 1646 block_state.modes.value |= UMODE_WALLOP;
1104 michael 56 } | T_SOFTCALLERID
1105     {
1106 michael 967 if (conf_parser_ctx.pass == 2)
1107 michael 1646 block_state.modes.value |= UMODE_SOFTCALLERID;
1108 michael 56 } | T_CALLERID
1109     {
1110 michael 967 if (conf_parser_ctx.pass == 2)
1111 michael 1646 block_state.modes.value |= UMODE_CALLERID;
1112 michael 56 } | T_LOCOPS
1113     {
1114 michael 967 if (conf_parser_ctx.pass == 2)
1115 michael 1646 block_state.modes.value |= UMODE_LOCOPS;
1116 michael 56 };
1117    
1118 adx 30 oper_flags: IRCD_FLAGS
1119     {
1120 michael 1228 if (conf_parser_ctx.pass == 2)
1121 michael 1646 block_state.port.value = 0;
1122 adx 30 } '=' oper_flags_items ';';
1123    
1124     oper_flags_items: oper_flags_items ',' oper_flags_item | oper_flags_item;
1125 michael 1228 oper_flags_item: GLOBAL_KILL
1126 adx 30 {
1127 michael 967 if (conf_parser_ctx.pass == 2)
1128 michael 1646 block_state.port.value |= OPER_FLAG_GLOBAL_KILL;
1129 adx 30 } | REMOTE
1130     {
1131 michael 967 if (conf_parser_ctx.pass == 2)
1132 michael 1646 block_state.port.value |= OPER_FLAG_REMOTE;
1133 adx 30 } | KLINE
1134     {
1135 michael 967 if (conf_parser_ctx.pass == 2)
1136 michael 1646 block_state.port.value |= OPER_FLAG_K;
1137 adx 30 } | UNKLINE
1138     {
1139 michael 967 if (conf_parser_ctx.pass == 2)
1140 michael 1646 block_state.port.value |= OPER_FLAG_UNKLINE;
1141 michael 1301 } | T_DLINE
1142     {
1143     if (conf_parser_ctx.pass == 2)
1144 michael 1646 block_state.port.value |= OPER_FLAG_DLINE;
1145 michael 1301 } | T_UNDLINE
1146     {
1147     if (conf_parser_ctx.pass == 2)
1148 michael 1646 block_state.port.value |= OPER_FLAG_UNDLINE;
1149 adx 30 } | XLINE
1150     {
1151 michael 967 if (conf_parser_ctx.pass == 2)
1152 michael 1646 block_state.port.value |= OPER_FLAG_X;
1153 adx 30 } | GLINE
1154     {
1155 michael 967 if (conf_parser_ctx.pass == 2)
1156 michael 1646 block_state.port.value |= OPER_FLAG_GLINE;
1157 adx 30 } | DIE
1158     {
1159 michael 967 if (conf_parser_ctx.pass == 2)
1160 michael 1646 block_state.port.value |= OPER_FLAG_DIE;
1161 michael 1228 } | T_RESTART
1162     {
1163     if (conf_parser_ctx.pass == 2)
1164 michael 1646 block_state.port.value |= OPER_FLAG_RESTART;
1165 adx 30 } | REHASH
1166     {
1167 michael 967 if (conf_parser_ctx.pass == 2)
1168 michael 1646 block_state.port.value |= OPER_FLAG_REHASH;
1169 adx 30 } | ADMIN
1170     {
1171 michael 967 if (conf_parser_ctx.pass == 2)
1172 michael 1646 block_state.port.value |= OPER_FLAG_ADMIN;
1173 adx 30 } | NICK_CHANGES
1174     {
1175 michael 967 if (conf_parser_ctx.pass == 2)
1176 michael 1646 block_state.port.value |= OPER_FLAG_N;
1177 adx 30 } | T_OPERWALL
1178     {
1179 michael 967 if (conf_parser_ctx.pass == 2)
1180 michael 1646 block_state.port.value |= OPER_FLAG_OPERWALL;
1181 michael 1216 } | T_GLOBOPS
1182     {
1183     if (conf_parser_ctx.pass == 2)
1184 michael 1646 block_state.port.value |= OPER_FLAG_GLOBOPS;
1185 adx 30 } | OPER_SPY_T
1186     {
1187 michael 967 if (conf_parser_ctx.pass == 2)
1188 michael 1646 block_state.port.value |= OPER_FLAG_OPER_SPY;
1189 adx 30 } | REMOTEBAN
1190     {
1191 michael 967 if (conf_parser_ctx.pass == 2)
1192 michael 1646 block_state.port.value |= OPER_FLAG_REMOTEBAN;
1193 michael 1460 } | T_SET
1194     {
1195     if (conf_parser_ctx.pass == 2)
1196 michael 1646 block_state.port.value |= OPER_FLAG_SET;
1197 michael 1228 } | MODULE
1198 adx 30 {
1199 michael 967 if (conf_parser_ctx.pass == 2)
1200 michael 1646 block_state.port.value |= OPER_FLAG_MODULE;
1201 adx 30 };
1202    
1203    
1204     /***************************************************************************
1205     * section class
1206     ***************************************************************************/
1207     class_entry: CLASS
1208     {
1209 michael 967 if (conf_parser_ctx.pass == 1)
1210 adx 30 {
1211 michael 1632 yy_class = class_make();
1212 adx 30 }
1213 michael 1285 } '{' class_items '}' ';'
1214 adx 30 {
1215 michael 967 if (conf_parser_ctx.pass == 1)
1216 adx 30 {
1217     struct ClassItem *class = NULL;
1218    
1219     if (yy_class_name == NULL)
1220 michael 1632 class_free(yy_class);
1221 adx 30 else
1222     {
1223 michael 1632 class = class_find(yy_class_name, 0);
1224 adx 30
1225 michael 1632 if (class != NULL) /* The class existed already */
1226 adx 30 {
1227 michael 671 int user_count = 0;
1228    
1229 michael 1632 rebuild_cidr_class(class, yy_class);
1230 michael 671
1231 michael 1632 user_count = class->ref_count;
1232 michael 671 memcpy(class, yy_class, sizeof(*class));
1233 michael 1632 class->ref_count = user_count;
1234 michael 671 class->active = 1;
1235    
1236 michael 1632 class_free(yy_class);
1237 adx 30
1238 michael 1632 MyFree(class->name); /* Allows case change of class name */
1239     class->name = yy_class_name;
1240 adx 30 }
1241     else /* Brand new class */
1242     {
1243 michael 1632 MyFree(yy_class->name); /* just in case it was allocated */
1244     yy_class->name = yy_class_name;
1245 michael 671 yy_class->active = 1;
1246 adx 30 }
1247     }
1248 michael 671
1249 adx 30 yy_class_name = NULL;
1250     }
1251     };
1252    
1253     class_items: class_items class_item | class_item;
1254     class_item: class_name |
1255     class_cidr_bitlen_ipv4 | class_cidr_bitlen_ipv6 |
1256     class_ping_time |
1257     class_number_per_cidr |
1258     class_number_per_ip |
1259     class_connectfreq |
1260     class_max_number |
1261     class_max_global |
1262     class_max_local |
1263     class_max_ident |
1264 michael 1516 class_sendq | class_recvq |
1265 adx 30 error ';' ;
1266    
1267     class_name: NAME '=' QSTRING ';'
1268     {
1269 michael 967 if (conf_parser_ctx.pass == 1)
1270 adx 30 {
1271     MyFree(yy_class_name);
1272 michael 1646 yy_class_name = xstrdup(yylval.string);
1273 adx 30 }
1274     };
1275    
1276     class_ping_time: PING_TIME '=' timespec ';'
1277     {
1278 michael 967 if (conf_parser_ctx.pass == 1)
1279 michael 1377 yy_class->ping_freq = $3;
1280 adx 30 };
1281    
1282     class_number_per_ip: NUMBER_PER_IP '=' NUMBER ';'
1283     {
1284 michael 967 if (conf_parser_ctx.pass == 1)
1285 michael 1377 yy_class->max_perip = $3;
1286 adx 30 };
1287    
1288     class_connectfreq: CONNECTFREQ '=' timespec ';'
1289     {
1290 michael 967 if (conf_parser_ctx.pass == 1)
1291 michael 1377 yy_class->con_freq = $3;
1292 adx 30 };
1293    
1294     class_max_number: MAX_NUMBER '=' NUMBER ';'
1295     {
1296 michael 967 if (conf_parser_ctx.pass == 1)
1297 michael 1377 yy_class->max_total = $3;
1298 adx 30 };
1299    
1300     class_max_global: MAX_GLOBAL '=' NUMBER ';'
1301     {
1302 michael 967 if (conf_parser_ctx.pass == 1)
1303 michael 1377 yy_class->max_global = $3;
1304 adx 30 };
1305    
1306     class_max_local: MAX_LOCAL '=' NUMBER ';'
1307     {
1308 michael 967 if (conf_parser_ctx.pass == 1)
1309 michael 1377 yy_class->max_local = $3;
1310 adx 30 };
1311    
1312     class_max_ident: MAX_IDENT '=' NUMBER ';'
1313     {
1314 michael 967 if (conf_parser_ctx.pass == 1)
1315 michael 1377 yy_class->max_ident = $3;
1316 adx 30 };
1317    
1318     class_sendq: SENDQ '=' sizespec ';'
1319     {
1320 michael 967 if (conf_parser_ctx.pass == 1)
1321 michael 1377 yy_class->max_sendq = $3;
1322 adx 30 };
1323    
1324 michael 1516 class_recvq: T_RECVQ '=' sizespec ';'
1325     {
1326     if (conf_parser_ctx.pass == 1)
1327     if ($3 >= CLIENT_FLOOD_MIN && $3 <= CLIENT_FLOOD_MAX)
1328     yy_class->max_recvq = $3;
1329     };
1330    
1331 adx 30 class_cidr_bitlen_ipv4: CIDR_BITLEN_IPV4 '=' NUMBER ';'
1332     {
1333 michael 967 if (conf_parser_ctx.pass == 1)
1334 michael 1416 yy_class->cidr_bitlen_ipv4 = $3 > 32 ? 32 : $3;
1335 adx 30 };
1336    
1337     class_cidr_bitlen_ipv6: CIDR_BITLEN_IPV6 '=' NUMBER ';'
1338     {
1339 michael 967 if (conf_parser_ctx.pass == 1)
1340 michael 1416 yy_class->cidr_bitlen_ipv6 = $3 > 128 ? 128 : $3;
1341 adx 30 };
1342    
1343     class_number_per_cidr: NUMBER_PER_CIDR '=' NUMBER ';'
1344     {
1345 michael 967 if (conf_parser_ctx.pass == 1)
1346 michael 1377 yy_class->number_per_cidr = $3;
1347 adx 30 };
1348    
1349     /***************************************************************************
1350     * section listen
1351     ***************************************************************************/
1352     listen_entry: LISTEN
1353     {
1354 michael 967 if (conf_parser_ctx.pass == 2)
1355 michael 1646 reset_block_state();
1356     } '{' listen_items '}' ';';
1357 adx 30
1358     listen_flags: IRCD_FLAGS
1359     {
1360 michael 1646 block_state.flags.value = 0;
1361 adx 30 } '=' listen_flags_items ';';
1362    
1363     listen_flags_items: listen_flags_items ',' listen_flags_item | listen_flags_item;
1364     listen_flags_item: T_SSL
1365     {
1366 michael 967 if (conf_parser_ctx.pass == 2)
1367 michael 1646 block_state.flags.value |= LISTENER_SSL;
1368 adx 30 } | HIDDEN
1369     {
1370 michael 967 if (conf_parser_ctx.pass == 2)
1371 michael 1646 block_state.flags.value |=LISTENER_HIDDEN;
1372 michael 900 } | T_SERVER
1373     {
1374 michael 967 if (conf_parser_ctx.pass == 2)
1375 michael 1646 block_state.flags.value |=LISTENER_SERVER;
1376 adx 30 };
1377    
1378     listen_items: listen_items listen_item | listen_item;
1379 michael 440 listen_item: listen_port | listen_flags | listen_address | listen_host | error ';';
1380 adx 30
1381 michael 1646 listen_port: PORT '=' port_items { block_state.flags.value |= 0; } ';';
1382 adx 30
1383     port_items: port_items ',' port_item | port_item;
1384    
1385     port_item: NUMBER
1386     {
1387 michael 967 if (conf_parser_ctx.pass == 2)
1388 adx 30 {
1389 michael 1646 if (block_state.flags.value & LISTENER_SSL)
1390 adx 30 #ifdef HAVE_LIBCRYPTO
1391 michael 967 if (!ServerInfo.server_ctx)
1392 adx 30 #endif
1393     {
1394     yyerror("SSL not available - port closed");
1395     break;
1396     }
1397 michael 1646 add_listener($1, block_state.addr.buf, block_state.flags.value);
1398 adx 30 }
1399     } | NUMBER TWODOTS NUMBER
1400     {
1401 michael 967 if (conf_parser_ctx.pass == 2)
1402 adx 30 {
1403     int i;
1404    
1405 michael 1646 if (block_state.flags.value & LISTENER_SSL)
1406 adx 30 #ifdef HAVE_LIBCRYPTO
1407 michael 967 if (!ServerInfo.server_ctx)
1408 adx 30 #endif
1409     {
1410     yyerror("SSL not available - port closed");
1411     break;
1412     }
1413    
1414     for (i = $1; i <= $3; ++i)
1415 michael 1646 add_listener(i, block_state.addr.buf, block_state.flags.value);
1416 adx 30 }
1417     };
1418    
1419     listen_address: IP '=' QSTRING ';'
1420     {
1421 michael 967 if (conf_parser_ctx.pass == 2)
1422 michael 1646 strlcpy(block_state.addr.buf, yylval.string, sizeof(block_state.addr.buf));
1423 adx 30 };
1424    
1425     listen_host: HOST '=' QSTRING ';'
1426     {
1427 michael 967 if (conf_parser_ctx.pass == 2)
1428 michael 1646 strlcpy(block_state.addr.buf, yylval.string, sizeof(block_state.addr.buf));
1429 adx 30 };
1430    
1431     /***************************************************************************
1432     * section auth
1433     ***************************************************************************/
1434     auth_entry: IRCD_AUTH
1435     {
1436 michael 967 if (conf_parser_ctx.pass == 2)
1437 michael 1646 reset_block_state();
1438 adx 30 } '{' auth_items '}' ';'
1439     {
1440 michael 1646 dlink_node *ptr = NULL;
1441 adx 30
1442 michael 1646 if (conf_parser_ctx.pass != 2)
1443     break;
1444 adx 30
1445 michael 1646 DLINK_FOREACH(ptr, block_state.mask.list.head)
1446     {
1447     struct MaskItem *conf = NULL;
1448     struct split_nuh_item nuh;
1449 adx 30
1450 michael 1646 nuh.nuhmask = ptr->data;
1451     nuh.nickptr = NULL;
1452     nuh.userptr = userbuf;
1453     nuh.hostptr = hostbuf;
1454     nuh.nicksize = 0;
1455     nuh.usersize = sizeof(userbuf);
1456     nuh.hostsize = sizeof(hostbuf);
1457     split_nuh(&nuh);
1458 adx 30
1459 michael 1646 conf = conf_make(CONF_CLIENT);
1460     conf->user = xstrdup(collapse(userbuf));
1461     conf->host = xstrdup(collapse(hostbuf));
1462 adx 30
1463 michael 1646 if (block_state.pass.buf[0])
1464     conf->passwd = xstrdup(block_state.pass.buf);
1465     if (block_state.name.buf[0])
1466     conf->passwd = xstrdup(block_state.name.buf);
1467 adx 30
1468 michael 1646 conf->flags = block_state.flags.value;
1469     conf->port = block_state.port.value;
1470 adx 30
1471 michael 1646 conf_add_class_to_conf(conf, block_state.class.buf);
1472     add_conf_by_address(CONF_CLIENT, conf);
1473 adx 30 }
1474     };
1475    
1476     auth_items: auth_items auth_item | auth_item;
1477     auth_item: auth_user | auth_passwd | auth_class | auth_flags |
1478 michael 1076 auth_spoof | auth_redir_serv | auth_redir_port |
1479     auth_encrypted | error ';' ;
1480 adx 30
1481     auth_user: USER '=' QSTRING ';'
1482     {
1483 michael 967 if (conf_parser_ctx.pass == 2)
1484 michael 1646 dlinkAdd(xstrdup(yylval.string), make_dlink_node(), &block_state.mask.list);
1485 adx 30 };
1486    
1487     auth_passwd: PASSWORD '=' QSTRING ';'
1488     {
1489 michael 967 if (conf_parser_ctx.pass == 2)
1490 michael 1646 strlcpy(block_state.pass.buf, yylval.string, sizeof(block_state.pass.buf));
1491 adx 30 };
1492    
1493     auth_class: CLASS '=' QSTRING ';'
1494     {
1495 michael 967 if (conf_parser_ctx.pass == 2)
1496 michael 1646 strlcpy(block_state.class.buf, yylval.string, sizeof(block_state.class.buf));
1497 adx 30 };
1498    
1499     auth_encrypted: ENCRYPTED '=' TBOOL ';'
1500     {
1501 michael 967 if (conf_parser_ctx.pass == 2)
1502 adx 30 {
1503     if (yylval.number)
1504 michael 1646 block_state.flags.value |= CONF_FLAGS_ENCRYPTED;
1505 adx 30 else
1506 michael 1646 block_state.flags.value &= ~CONF_FLAGS_ENCRYPTED;
1507 adx 30 }
1508     };
1509    
1510     auth_flags: IRCD_FLAGS
1511     {
1512 michael 1646 if (conf_parser_ctx.pass == 2)
1513     block_state.flags.value = 0;
1514 adx 30 } '=' auth_flags_items ';';
1515    
1516     auth_flags_items: auth_flags_items ',' auth_flags_item | auth_flags_item;
1517 michael 1228 auth_flags_item: SPOOF_NOTICE
1518 adx 30 {
1519 michael 967 if (conf_parser_ctx.pass == 2)
1520 michael 1646 block_state.flags.value |= CONF_FLAGS_SPOOF_NOTICE;
1521 adx 30 } | EXCEED_LIMIT
1522     {
1523 michael 967 if (conf_parser_ctx.pass == 2)
1524 michael 1646 block_state.flags.value |= CONF_FLAGS_NOLIMIT;
1525 adx 30 } | KLINE_EXEMPT
1526     {
1527 michael 967 if (conf_parser_ctx.pass == 2)
1528 michael 1646 block_state.flags.value |= CONF_FLAGS_EXEMPTKLINE;
1529 adx 30 } | NEED_IDENT
1530     {
1531 michael 967 if (conf_parser_ctx.pass == 2)
1532 michael 1646 block_state.flags.value |= CONF_FLAGS_NEED_IDENTD;
1533 adx 30 } | CAN_FLOOD
1534     {
1535 michael 967 if (conf_parser_ctx.pass == 2)
1536 michael 1646 block_state.flags.value |= CONF_FLAGS_CAN_FLOOD;
1537 adx 30 } | NO_TILDE
1538     {
1539 michael 967 if (conf_parser_ctx.pass == 2)
1540 michael 1646 block_state.flags.value |= CONF_FLAGS_NO_TILDE;
1541 adx 30 } | GLINE_EXEMPT
1542     {
1543 michael 967 if (conf_parser_ctx.pass == 2)
1544 michael 1646 block_state.flags.value |= CONF_FLAGS_EXEMPTGLINE;
1545 adx 30 } | RESV_EXEMPT
1546     {
1547 michael 967 if (conf_parser_ctx.pass == 2)
1548 michael 1646 block_state.flags.value |= CONF_FLAGS_EXEMPTRESV;
1549 adx 30 } | NEED_PASSWORD
1550     {
1551 michael 967 if (conf_parser_ctx.pass == 2)
1552 michael 1646 block_state.flags.value |= CONF_FLAGS_NEED_PASSWORD;
1553 adx 30 };
1554    
1555     auth_spoof: SPOOF '=' QSTRING ';'
1556     {
1557 michael 1646 if (conf_parser_ctx.pass != 2)
1558     break;
1559    
1560     if (strlen(yylval.string) <= HOSTLEN && valid_hostname(yylval.string))
1561 adx 30 {
1562 michael 1646 strlcpy(block_state.name.buf, yylval.string, sizeof(block_state.name.buf));
1563     block_state.flags.value |= CONF_FLAGS_SPOOF_IP;
1564 adx 30 }
1565 michael 1646 else
1566     ilog(LOG_TYPE_IRCD, "Spoof either is too long or contains invalid characters. Ignoring it.");
1567 adx 30 };
1568    
1569     auth_redir_serv: REDIRSERV '=' QSTRING ';'
1570     {
1571 michael 1646 if (conf_parser_ctx.pass != 2)
1572     break;
1573    
1574     strlcpy(block_state.name.buf, yylval.string, sizeof(block_state.name.buf));
1575     block_state.flags.value |= CONF_FLAGS_REDIR;
1576 adx 30 };
1577    
1578     auth_redir_port: REDIRPORT '=' NUMBER ';'
1579     {
1580 michael 1646 if (conf_parser_ctx.pass != 2)
1581     break;
1582     block_state.flags.value |= CONF_FLAGS_REDIR;
1583     block_state.port.value = $3;
1584 adx 30 };
1585    
1586    
1587     /***************************************************************************
1588     * section resv
1589     ***************************************************************************/
1590     resv_entry: RESV
1591     {
1592 michael 967 if (conf_parser_ctx.pass == 2)
1593 adx 30 {
1594     MyFree(resv_reason);
1595     resv_reason = NULL;
1596     }
1597     } '{' resv_items '}' ';'
1598     {
1599 michael 967 if (conf_parser_ctx.pass == 2)
1600 adx 30 {
1601     MyFree(resv_reason);
1602     resv_reason = NULL;
1603     }
1604     };
1605    
1606     resv_items: resv_items resv_item | resv_item;
1607     resv_item: resv_creason | resv_channel | resv_nick | error ';' ;
1608    
1609     resv_creason: REASON '=' QSTRING ';'
1610     {
1611 michael 967 if (conf_parser_ctx.pass == 2)
1612 adx 30 {
1613     MyFree(resv_reason);
1614 michael 1646 resv_reason = xstrdup(yylval.string);
1615 adx 30 }
1616     };
1617    
1618     resv_channel: CHANNEL '=' QSTRING ';'
1619     {
1620 michael 967 if (conf_parser_ctx.pass == 2)
1621 adx 30 {
1622     if (IsChanPrefix(*yylval.string))
1623     {
1624     char def_reason[] = "No reason";
1625    
1626     create_channel_resv(yylval.string, resv_reason != NULL ? resv_reason : def_reason, 1);
1627     }
1628     }
1629     /* ignore it for now.. but we really should make a warning if
1630     * its an erroneous name --fl_ */
1631     };
1632    
1633     resv_nick: NICK '=' QSTRING ';'
1634     {
1635 michael 967 if (conf_parser_ctx.pass == 2)
1636 adx 30 {
1637     char def_reason[] = "No reason";
1638    
1639     create_nick_resv(yylval.string, resv_reason != NULL ? resv_reason : def_reason, 1);
1640     }
1641     };
1642    
1643     /***************************************************************************
1644 michael 1157 * section service
1645     ***************************************************************************/
1646     service_entry: T_SERVICE '{' service_items '}' ';';
1647    
1648     service_items: service_items service_item | service_item;
1649     service_item: service_name | error;
1650    
1651     service_name: NAME '=' QSTRING ';'
1652     {
1653     if (conf_parser_ctx.pass == 2)
1654     {
1655     if (valid_servname(yylval.string))
1656     {
1657 michael 1632 yy_conf = conf_make(CONF_SERVICE);
1658 michael 1646 yy_conf->name = xstrdup(yylval.string);
1659 michael 1157 }
1660     }
1661     };
1662    
1663     /***************************************************************************
1664 adx 30 * section shared, for sharing remote klines etc.
1665     ***************************************************************************/
1666     shared_entry: T_SHARED
1667     {
1668 michael 967 if (conf_parser_ctx.pass == 2)
1669 adx 30 {
1670 michael 1632 yy_conf = conf_make(CONF_ULINE);
1671 michael 1644 yy_conf->flags = SHARED_ALL;
1672 adx 30 }
1673     } '{' shared_items '}' ';'
1674     {
1675 michael 967 if (conf_parser_ctx.pass == 2)
1676 adx 30 {
1677     yy_conf = NULL;
1678     }
1679     };
1680    
1681     shared_items: shared_items shared_item | shared_item;
1682     shared_item: shared_name | shared_user | shared_type | error ';' ;
1683    
1684     shared_name: NAME '=' QSTRING ';'
1685     {
1686 michael 967 if (conf_parser_ctx.pass == 2)
1687 adx 30 {
1688     MyFree(yy_conf->name);
1689     DupString(yy_conf->name, yylval.string);
1690     }
1691     };
1692    
1693     shared_user: USER '=' QSTRING ';'
1694     {
1695 michael 967 if (conf_parser_ctx.pass == 2)
1696 adx 30 {
1697 michael 593 struct split_nuh_item nuh;
1698    
1699     nuh.nuhmask = yylval.string;
1700     nuh.nickptr = NULL;
1701     nuh.userptr = userbuf;
1702     nuh.hostptr = hostbuf;
1703    
1704     nuh.nicksize = 0;
1705     nuh.usersize = sizeof(userbuf);
1706     nuh.hostsize = sizeof(hostbuf);
1707    
1708     split_nuh(&nuh);
1709    
1710 michael 1632 DupString(yy_conf->user, userbuf);
1711     DupString(yy_conf->host, hostbuf);
1712 adx 30 }
1713     };
1714    
1715     shared_type: TYPE
1716     {
1717 michael 967 if (conf_parser_ctx.pass == 2)
1718 michael 1644 yy_conf->flags = 0;
1719 adx 30 } '=' shared_types ';' ;
1720    
1721     shared_types: shared_types ',' shared_type_item | shared_type_item;
1722     shared_type_item: KLINE
1723     {
1724 michael 967 if (conf_parser_ctx.pass == 2)
1725 michael 1644 yy_conf->flags |= SHARED_KLINE;
1726 michael 1301 } | UNKLINE
1727 adx 30 {
1728 michael 967 if (conf_parser_ctx.pass == 2)
1729 michael 1644 yy_conf->flags |= SHARED_UNKLINE;
1730 michael 1301 } | T_DLINE
1731 adx 30 {
1732 michael 967 if (conf_parser_ctx.pass == 2)
1733 michael 1644 yy_conf->flags |= SHARED_DLINE;
1734 michael 1301 } | T_UNDLINE
1735     {
1736     if (conf_parser_ctx.pass == 2)
1737 michael 1644 yy_conf->flags |= SHARED_UNDLINE;
1738 adx 30 } | XLINE
1739     {
1740 michael 967 if (conf_parser_ctx.pass == 2)
1741 michael 1644 yy_conf->flags |= SHARED_XLINE;
1742 adx 30 } | T_UNXLINE
1743     {
1744 michael 967 if (conf_parser_ctx.pass == 2)
1745 michael 1644 yy_conf->flags |= SHARED_UNXLINE;
1746 adx 30 } | RESV
1747     {
1748 michael 967 if (conf_parser_ctx.pass == 2)
1749 michael 1644 yy_conf->flags |= SHARED_RESV;
1750 adx 30 } | T_UNRESV
1751     {
1752 michael 967 if (conf_parser_ctx.pass == 2)
1753 michael 1644 yy_conf->flags |= SHARED_UNRESV;
1754 adx 30 } | T_LOCOPS
1755     {
1756 michael 967 if (conf_parser_ctx.pass == 2)
1757 michael 1644 yy_conf->flags |= SHARED_LOCOPS;
1758 adx 30 } | T_ALL
1759     {
1760 michael 967 if (conf_parser_ctx.pass == 2)
1761 michael 1644 yy_conf->flags = SHARED_ALL;
1762 adx 30 };
1763    
1764     /***************************************************************************
1765     * section cluster
1766     ***************************************************************************/
1767     cluster_entry: T_CLUSTER
1768     {
1769 michael 967 if (conf_parser_ctx.pass == 2)
1770 adx 30 {
1771 michael 1632 yy_conf = conf_make(CONF_CLUSTER);
1772 adx 30 }
1773     } '{' cluster_items '}' ';'
1774     {
1775 michael 967 if (conf_parser_ctx.pass == 2)
1776 adx 30 {
1777     if (yy_conf->name == NULL)
1778     DupString(yy_conf->name, "*");
1779     yy_conf = NULL;
1780     }
1781     };
1782    
1783     cluster_items: cluster_items cluster_item | cluster_item;
1784     cluster_item: cluster_name | cluster_type | error ';' ;
1785    
1786     cluster_name: NAME '=' QSTRING ';'
1787     {
1788 michael 967 if (conf_parser_ctx.pass == 2)
1789 adx 30 DupString(yy_conf->name, yylval.string);
1790     };
1791    
1792     cluster_type: TYPE
1793     {
1794 michael 967 if (conf_parser_ctx.pass == 2)
1795 adx 30 yy_conf->flags = 0;
1796     } '=' cluster_types ';' ;
1797    
1798     cluster_types: cluster_types ',' cluster_type_item | cluster_type_item;
1799     cluster_type_item: KLINE
1800     {
1801 michael 967 if (conf_parser_ctx.pass == 2)
1802 adx 30 yy_conf->flags |= SHARED_KLINE;
1803 michael 1301 } | UNKLINE
1804 adx 30 {
1805 michael 967 if (conf_parser_ctx.pass == 2)
1806 michael 1301 yy_conf->flags |= SHARED_UNKLINE;
1807     } | T_DLINE
1808 adx 30 {
1809 michael 967 if (conf_parser_ctx.pass == 2)
1810 michael 1301 yy_conf->flags |= SHARED_DLINE;
1811     } | T_UNDLINE
1812     {
1813     if (conf_parser_ctx.pass == 2)
1814     yy_conf->flags |= SHARED_UNDLINE;
1815 adx 30 } | XLINE
1816     {
1817 michael 967 if (conf_parser_ctx.pass == 2)
1818 adx 30 yy_conf->flags |= SHARED_XLINE;
1819     } | T_UNXLINE
1820     {
1821 michael 967 if (conf_parser_ctx.pass == 2)
1822 adx 30 yy_conf->flags |= SHARED_UNXLINE;
1823     } | RESV
1824     {
1825 michael 967 if (conf_parser_ctx.pass == 2)
1826 adx 30 yy_conf->flags |= SHARED_RESV;
1827     } | T_UNRESV
1828     {
1829 michael 967 if (conf_parser_ctx.pass == 2)
1830 adx 30 yy_conf->flags |= SHARED_UNRESV;
1831     } | T_LOCOPS
1832     {
1833 michael 967 if (conf_parser_ctx.pass == 2)
1834 adx 30 yy_conf->flags |= SHARED_LOCOPS;
1835     } | T_ALL
1836     {
1837 michael 967 if (conf_parser_ctx.pass == 2)
1838 adx 30 yy_conf->flags = SHARED_ALL;
1839     };
1840    
1841     /***************************************************************************
1842     * section connect
1843     ***************************************************************************/
1844     connect_entry: CONNECT
1845     {
1846 michael 967 if (conf_parser_ctx.pass == 2)
1847 adx 30 {
1848 michael 1632 yy_conf = conf_make(CONF_SERVER);
1849 michael 1265
1850 adx 30 /* defaults */
1851 michael 1632 yy_conf->port = PORTNUM;
1852 adx 30 }
1853     else
1854     {
1855     MyFree(class_name);
1856     class_name = NULL;
1857     }
1858 michael 1285 } '{' connect_items '}' ';'
1859 adx 30 {
1860 michael 967 if (conf_parser_ctx.pass == 2)
1861 adx 30 {
1862 michael 1632 if (yy_conf->host && yy_conf->passwd && yy_conf->spasswd)
1863 michael 1302 {
1864     if (conf_add_server(yy_conf, class_name) == -1)
1865 michael 1632 conf_free(yy_conf);
1866 michael 1302 }
1867     else
1868     {
1869     if (yy_conf->name != NULL)
1870     {
1871 michael 1632 if (yy_conf->host == NULL)
1872 michael 1302 yyerror("Ignoring connect block -- missing host");
1873 michael 1632 else if (!yy_conf->passwd || !yy_conf->spasswd)
1874 michael 1302 yyerror("Ignoring connect block -- missing password");
1875     }
1876 adx 30
1877 michael 1302 /* XXX
1878     * This fixes a try_connections() core (caused by invalid class_ptr
1879     * pointers) reported by metalrock. That's an ugly fix, but there
1880     * is currently no better way. The entire config subsystem needs an
1881     * rewrite ASAP. make_conf_item() shouldn't really add things onto
1882     * a doubly linked list immediately without any sanity checks! -Michael
1883     */
1884 michael 1632 conf_free(yy_conf);
1885 michael 1302 }
1886 adx 30
1887 michael 1383 MyFree(class_name);
1888     class_name = NULL;
1889     yy_conf = NULL;
1890 adx 30 }
1891     };
1892    
1893     connect_items: connect_items connect_item | connect_item;
1894     connect_item: connect_name | connect_host | connect_vhost |
1895     connect_send_password | connect_accept_password |
1896 michael 1306 connect_aftype | connect_port | connect_ssl_cipher_list |
1897 michael 1076 connect_flags | connect_hub_mask | connect_leaf_mask |
1898 michael 1302 connect_class | connect_encrypted |
1899 michael 1076 error ';' ;
1900 adx 30
1901     connect_name: NAME '=' QSTRING ';'
1902     {
1903 michael 967 if (conf_parser_ctx.pass == 2)
1904 adx 30 {
1905     MyFree(yy_conf->name);
1906     DupString(yy_conf->name, yylval.string);
1907     }
1908     };
1909    
1910     connect_host: HOST '=' QSTRING ';'
1911     {
1912 michael 967 if (conf_parser_ctx.pass == 2)
1913 adx 30 {
1914 michael 1632 MyFree(yy_conf->host);
1915     DupString(yy_conf->host, yylval.string);
1916 adx 30 }
1917     };
1918    
1919     connect_vhost: VHOST '=' QSTRING ';'
1920     {
1921 michael 967 if (conf_parser_ctx.pass == 2)
1922 adx 30 {
1923     struct addrinfo hints, *res;
1924    
1925     memset(&hints, 0, sizeof(hints));
1926    
1927     hints.ai_family = AF_UNSPEC;
1928     hints.ai_socktype = SOCK_STREAM;
1929     hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
1930    
1931 michael 1123 if (getaddrinfo(yylval.string, NULL, &hints, &res))
1932 michael 1247 ilog(LOG_TYPE_IRCD, "Invalid netmask for server vhost(%s)", yylval.string);
1933 adx 30 else
1934     {
1935     assert(res != NULL);
1936    
1937 michael 1632 memcpy(&yy_conf->bind, res->ai_addr, res->ai_addrlen);
1938     yy_conf->bind.ss.ss_family = res->ai_family;
1939     yy_conf->bind.ss_len = res->ai_addrlen;
1940 michael 1123 freeaddrinfo(res);
1941 adx 30 }
1942     }
1943     };
1944    
1945     connect_send_password: SEND_PASSWORD '=' QSTRING ';'
1946     {
1947 michael 967 if (conf_parser_ctx.pass == 2)
1948 adx 30 {
1949 adx 38 if ($3[0] == ':')
1950     yyerror("Server passwords cannot begin with a colon");
1951     else if (strchr($3, ' ') != NULL)
1952     yyerror("Server passwords cannot contain spaces");
1953     else {
1954 michael 1632 if (yy_conf->spasswd != NULL)
1955     memset(yy_conf->spasswd, 0, strlen(yy_conf->spasswd));
1956 adx 30
1957 michael 1632 MyFree(yy_conf->spasswd);
1958     DupString(yy_conf->spasswd, yylval.string);
1959 adx 38 }
1960 adx 30 }
1961     };
1962    
1963     connect_accept_password: ACCEPT_PASSWORD '=' QSTRING ';'
1964     {
1965 michael 967 if (conf_parser_ctx.pass == 2)
1966 adx 30 {
1967 adx 38 if ($3[0] == ':')
1968     yyerror("Server passwords cannot begin with a colon");
1969     else if (strchr($3, ' ') != NULL)
1970     yyerror("Server passwords cannot contain spaces");
1971     else {
1972 michael 1632 if (yy_conf->passwd != NULL)
1973     memset(yy_conf->passwd, 0, strlen(yy_conf->passwd));
1974 adx 30
1975 michael 1632 MyFree(yy_conf->passwd);
1976     DupString(yy_conf->passwd, yylval.string);
1977 adx 38 }
1978 adx 30 }
1979     };
1980    
1981     connect_port: PORT '=' NUMBER ';'
1982     {
1983 michael 967 if (conf_parser_ctx.pass == 2)
1984 michael 1632 yy_conf->port = $3;
1985 adx 30 };
1986    
1987     connect_aftype: AFTYPE '=' T_IPV4 ';'
1988     {
1989 michael 967 if (conf_parser_ctx.pass == 2)
1990 michael 1632 yy_conf->aftype = AF_INET;
1991 adx 30 } | AFTYPE '=' T_IPV6 ';'
1992     {
1993     #ifdef IPV6
1994 michael 967 if (conf_parser_ctx.pass == 2)
1995 michael 1632 yy_conf->aftype = AF_INET6;
1996 adx 30 #endif
1997     };
1998    
1999     connect_flags: IRCD_FLAGS
2000     {
2001     } '=' connect_flags_items ';';
2002    
2003     connect_flags_items: connect_flags_items ',' connect_flags_item | connect_flags_item;
2004 michael 1302 connect_flags_item: AUTOCONN
2005 adx 30 {
2006 michael 967 if (conf_parser_ctx.pass == 2)
2007 michael 1632 SetConfAllowAutoConn(yy_conf);
2008 michael 1303 } | T_SSL
2009     {
2010     if (conf_parser_ctx.pass == 2)
2011 michael 1632 SetConfSSL(yy_conf);
2012 michael 1228 };
2013 adx 30
2014     connect_encrypted: ENCRYPTED '=' TBOOL ';'
2015     {
2016 michael 967 if (conf_parser_ctx.pass == 2)
2017 adx 30 {
2018     if (yylval.number)
2019 michael 1632 yy_conf->flags |= CONF_FLAGS_ENCRYPTED;
2020 adx 30 else
2021 michael 1632 yy_conf->flags &= ~CONF_FLAGS_ENCRYPTED;
2022 adx 30 }
2023     };
2024    
2025     connect_hub_mask: HUB_MASK '=' QSTRING ';'
2026     {
2027 michael 967 if (conf_parser_ctx.pass == 2)
2028 adx 30 {
2029 michael 1646 char *mask = xstrdup(yylval.string);
2030 adx 30
2031 michael 1632 dlinkAdd(mask, make_dlink_node(), &yy_conf->hub_list);
2032 adx 30 }
2033     };
2034    
2035     connect_leaf_mask: LEAF_MASK '=' QSTRING ';'
2036     {
2037 michael 967 if (conf_parser_ctx.pass == 2)
2038 adx 30 {
2039 michael 1383 char *mask;
2040 adx 30
2041 michael 1383 DupString(mask, yylval.string);
2042 michael 1632 dlinkAdd(mask, make_dlink_node(), &yy_conf->leaf_list);
2043 adx 30 }
2044     };
2045    
2046     connect_class: CLASS '=' QSTRING ';'
2047     {
2048 michael 967 if (conf_parser_ctx.pass == 2)
2049 adx 30 {
2050     MyFree(class_name);
2051     DupString(class_name, yylval.string);
2052     }
2053     };
2054    
2055 michael 1306 connect_ssl_cipher_list: T_SSL_CIPHER_LIST '=' QSTRING ';'
2056     {
2057     #ifdef HAVE_LIBCRYPTO
2058     if (conf_parser_ctx.pass == 2)
2059     {
2060 michael 1632 MyFree(yy_conf->cipher_list);
2061     DupString(yy_conf->cipher_list, yylval.string);
2062 michael 1306 }
2063     #else
2064     if (conf_parser_ctx.pass == 2)
2065     yyerror("Ignoring connect::ciphers -- no OpenSSL support");
2066     #endif
2067     };
2068    
2069    
2070 adx 30 /***************************************************************************
2071     * section kill
2072     ***************************************************************************/
2073     kill_entry: KILL
2074     {
2075 michael 967 if (conf_parser_ctx.pass == 2)
2076 adx 30 {
2077     userbuf[0] = hostbuf[0] = reasonbuf[0] = '\0';
2078     regex_ban = 0;
2079     }
2080     } '{' kill_items '}' ';'
2081     {
2082 michael 967 if (conf_parser_ctx.pass == 2)
2083 adx 30 {
2084 michael 1646 struct MaskItem *conf = NULL;
2085    
2086 adx 30 if (userbuf[0] && hostbuf[0])
2087     {
2088     if (regex_ban)
2089     {
2090 michael 1009 #ifdef HAVE_LIBPCRE
2091     void *exp_user = NULL;
2092     void *exp_host = NULL;
2093 adx 30 const char *errptr = NULL;
2094    
2095     if (!(exp_user = ircd_pcre_compile(userbuf, &errptr)) ||
2096     !(exp_host = ircd_pcre_compile(hostbuf, &errptr)))
2097     {
2098 michael 1247 ilog(LOG_TYPE_IRCD, "Failed to add regular expression based K-Line: %s",
2099 michael 595 errptr);
2100 adx 30 break;
2101     }
2102    
2103 michael 1646 conf = conf_make(CONF_RKLINE);
2104     conf->regexuser = exp_user;
2105     conf->regexhost = exp_host;
2106 adx 30
2107 michael 1646 conf->user = xstrdup(userbuf);
2108     conf->host = xstrdup(hostbuf);
2109 adx 30
2110     if (reasonbuf[0])
2111 michael 1646 conf->reason = xstrdup(reasonbuf);
2112 adx 30 else
2113 michael 1646 conf->reason = xstrdup(CONF_NOREASON);
2114 michael 1009 #else
2115 michael 1247 ilog(LOG_TYPE_IRCD, "Failed to add regular expression based K-Line: no PCRE support");
2116 michael 1009 break;
2117     #endif
2118 adx 30 }
2119     else
2120     {
2121 michael 1646 conf = conf_make(CONF_KLINE);
2122 adx 30
2123 michael 1646 conf->user = xstrdup(userbuf);
2124     conf->host = xstrdup(hostbuf);
2125 adx 30
2126     if (reasonbuf[0])
2127 michael 1646 conf->reason = xstrdup(reasonbuf);
2128 adx 30 else
2129 michael 1646 conf->reason = xstrdup(CONF_NOREASON);
2130     add_conf_by_address(CONF_KLINE, conf);
2131 adx 30 }
2132     }
2133     }
2134     };
2135    
2136     kill_type: TYPE
2137     {
2138     } '=' kill_type_items ';';
2139    
2140     kill_type_items: kill_type_items ',' kill_type_item | kill_type_item;
2141     kill_type_item: REGEX_T
2142     {
2143 michael 967 if (conf_parser_ctx.pass == 2)
2144 adx 30 regex_ban = 1;
2145     };
2146    
2147     kill_items: kill_items kill_item | kill_item;
2148     kill_item: kill_user | kill_reason | kill_type | error;
2149    
2150     kill_user: USER '=' QSTRING ';'
2151     {
2152 michael 967 if (conf_parser_ctx.pass == 2)
2153 adx 30 {
2154 michael 593 struct split_nuh_item nuh;
2155 adx 30
2156 michael 593 nuh.nuhmask = yylval.string;
2157     nuh.nickptr = NULL;
2158     nuh.userptr = userbuf;
2159     nuh.hostptr = hostbuf;
2160 adx 30
2161 michael 593 nuh.nicksize = 0;
2162     nuh.usersize = sizeof(userbuf);
2163     nuh.hostsize = sizeof(hostbuf);
2164 adx 30
2165 michael 593 split_nuh(&nuh);
2166 adx 30 }
2167     };
2168    
2169     kill_reason: REASON '=' QSTRING ';'
2170     {
2171 michael 967 if (conf_parser_ctx.pass == 2)
2172 adx 30 strlcpy(reasonbuf, yylval.string, sizeof(reasonbuf));
2173     };
2174    
2175     /***************************************************************************
2176     * section deny
2177     ***************************************************************************/
2178     deny_entry: DENY
2179     {
2180 michael 967 if (conf_parser_ctx.pass == 2)
2181 michael 1646 reset_block_state();
2182 adx 30 } '{' deny_items '}' ';'
2183     {
2184 michael 1646 struct MaskItem *conf = NULL;
2185    
2186     if (conf_parser_ctx.pass != 2)
2187     break;
2188    
2189     if (!block_state.addr.buf[0])
2190     break;
2191    
2192     if (parse_netmask(block_state.addr.buf, NULL, NULL) != HM_HOST)
2193 adx 30 {
2194 michael 1646 conf = conf_make(CONF_DLINE);
2195     conf->host = xstrdup(block_state.addr.buf);
2196 michael 1005
2197 michael 1646 if (block_state.pass.buf[0])
2198     conf->reason = xstrdup(block_state.pass.buf);
2199     else
2200     conf->reason = xstrdup(CONF_NOREASON);
2201     add_conf_by_address(CONF_DLINE, conf);
2202 adx 30 }
2203     };
2204    
2205     deny_items: deny_items deny_item | deny_item;
2206     deny_item: deny_ip | deny_reason | error;
2207    
2208     deny_ip: IP '=' QSTRING ';'
2209     {
2210 michael 967 if (conf_parser_ctx.pass == 2)
2211 michael 1646 strlcpy(block_state.addr.buf, yylval.string, sizeof(block_state.addr.buf));
2212 adx 30 };
2213    
2214     deny_reason: REASON '=' QSTRING ';'
2215     {
2216 michael 967 if (conf_parser_ctx.pass == 2)
2217 michael 1646 strlcpy(block_state.pass.buf, yylval.string, sizeof(block_state.pass.buf));
2218 adx 30 };
2219    
2220     /***************************************************************************
2221     * section exempt
2222     ***************************************************************************/
2223     exempt_entry: EXEMPT '{' exempt_items '}' ';';
2224    
2225     exempt_items: exempt_items exempt_item | exempt_item;
2226     exempt_item: exempt_ip | error;
2227    
2228     exempt_ip: IP '=' QSTRING ';'
2229     {
2230 michael 967 if (conf_parser_ctx.pass == 2)
2231 adx 30 {
2232     if (yylval.string[0] && parse_netmask(yylval.string, NULL, NULL) != HM_HOST)
2233     {
2234 michael 1646 struct MaskItem *conf = conf_make(CONF_EXEMPT);
2235     conf->host = xstrdup(yylval.string);
2236 adx 30
2237 michael 1646 add_conf_by_address(CONF_EXEMPT, conf);
2238 adx 30 }
2239     }
2240     };
2241    
2242     /***************************************************************************
2243     * section gecos
2244     ***************************************************************************/
2245     gecos_entry: GECOS
2246     {
2247 michael 967 if (conf_parser_ctx.pass == 2)
2248 michael 1646 reset_block_state();
2249 adx 30 } '{' gecos_items '}' ';'
2250     {
2251 michael 1646 struct MaskItem *conf = NULL;
2252    
2253     if (conf_parser_ctx.pass != 2)
2254     break;
2255    
2256     if (!block_state.name.buf[0])
2257     break;
2258    
2259     if (block_state.port.value == 1)
2260 adx 30 {
2261 michael 1009 #ifdef HAVE_LIBPCRE
2262 michael 1646 void *exp_p = NULL;
2263     const char *errptr = NULL;
2264 adx 30
2265 michael 1646 if (!(exp_p = ircd_pcre_compile(block_state.name.buf, &errptr)))
2266     {
2267     ilog(LOG_TYPE_IRCD, "Failed to add regular expression based X-Line: %s",
2268     errptr);
2269     break;
2270     }
2271 adx 30
2272 michael 1646 conf = conf_make(CONF_RXLINE);
2273     conf->regexuser = exp_p;
2274 michael 1009 #else
2275 michael 1646 ilog(LOG_TYPE_IRCD, "Failed to add regular expression based X-Line: no PCRE support");
2276     break;
2277 michael 1009 #endif
2278 michael 1646 }
2279     else
2280     conf = conf_make(CONF_XLINE);
2281 adx 30
2282 michael 1646 conf->name = xstrdup(block_state.name.buf);
2283 adx 30
2284 michael 1646 if (block_state.pass.buf[0])
2285     conf->reason = xstrdup(block_state.pass.buf);
2286     else
2287     conf->reason = xstrdup(CONF_NOREASON);
2288 adx 30 };
2289    
2290     gecos_flags: TYPE
2291     {
2292 michael 1646 if (conf_parser_ctx.pass == 2)
2293     block_state.port.value = 0;
2294 adx 30 } '=' gecos_flags_items ';';
2295    
2296     gecos_flags_items: gecos_flags_items ',' gecos_flags_item | gecos_flags_item;
2297     gecos_flags_item: REGEX_T
2298     {
2299 michael 967 if (conf_parser_ctx.pass == 2)
2300 michael 1646 block_state.port.value = 1;
2301 adx 30 };
2302    
2303     gecos_items: gecos_items gecos_item | gecos_item;
2304     gecos_item: gecos_name | gecos_reason | gecos_flags | error;
2305    
2306     gecos_name: NAME '=' QSTRING ';'
2307     {
2308 michael 967 if (conf_parser_ctx.pass == 2)
2309 michael 1646 strlcpy(block_state.name.buf, yylval.string, sizeof(block_state.name.buf));
2310 adx 30 };
2311    
2312     gecos_reason: REASON '=' QSTRING ';'
2313     {
2314 michael 967 if (conf_parser_ctx.pass == 2)
2315 michael 1646 strlcpy(block_state.pass.buf, yylval.string, sizeof(block_state.pass.buf));
2316 adx 30 };
2317    
2318     /***************************************************************************
2319     * section general
2320     ***************************************************************************/
2321     general_entry: GENERAL
2322     '{' general_items '}' ';';
2323    
2324     general_items: general_items general_item | general_item;
2325     general_item: general_hide_spoof_ips | general_ignore_bogus_ts |
2326     general_failed_oper_notice | general_anti_nick_flood |
2327     general_max_nick_time | general_max_nick_changes |
2328     general_max_accept | general_anti_spam_exit_message_time |
2329     general_ts_warn_delta | general_ts_max_delta |
2330 michael 1549 general_kill_chase_time_limit |
2331     general_invisible_on_connect |
2332 adx 30 general_warn_no_nline | general_dots_in_ident |
2333     general_stats_o_oper_only | general_stats_k_oper_only |
2334     general_pace_wait | general_stats_i_oper_only |
2335     general_pace_wait_simple | general_stats_P_oper_only |
2336     general_short_motd | general_no_oper_flood |
2337     general_true_no_oper_flood | general_oper_pass_resv |
2338 michael 1176 general_message_locale |
2339 adx 30 general_oper_only_umodes | general_max_targets |
2340     general_use_egd | general_egdpool_path |
2341     general_oper_umodes | general_caller_id_wait |
2342     general_opers_bypass_callerid | general_default_floodcount |
2343     general_min_nonwildcard | general_min_nonwildcard_simple |
2344 michael 1302 general_disable_remote_commands |
2345 adx 30 general_throttle_time | general_havent_read_conf |
2346 michael 1072 general_ping_cookie |
2347 michael 1264 general_disable_auth |
2348 michael 1459 general_tkline_expire_notices | general_gline_enable |
2349     general_gline_duration | general_gline_request_duration |
2350     general_gline_min_cidr |
2351 michael 1547 general_gline_min_cidr6 |
2352 michael 1549 general_stats_e_disabled |
2353 michael 1176 general_max_watch | general_services_name |
2354 adx 30 error;
2355    
2356    
2357 michael 876 general_max_watch: MAX_WATCH '=' NUMBER ';'
2358     {
2359     ConfigFileEntry.max_watch = $3;
2360     };
2361 adx 30
2362 michael 1459 general_gline_enable: GLINE_ENABLE '=' TBOOL ';'
2363     {
2364     if (conf_parser_ctx.pass == 2)
2365     ConfigFileEntry.glines = yylval.number;
2366     };
2367    
2368     general_gline_duration: GLINE_DURATION '=' timespec ';'
2369     {
2370     if (conf_parser_ctx.pass == 2)
2371     ConfigFileEntry.gline_time = $3;
2372     };
2373    
2374     general_gline_request_duration: GLINE_REQUEST_DURATION '=' timespec ';'
2375     {
2376     if (conf_parser_ctx.pass == 2)
2377     ConfigFileEntry.gline_request_time = $3;
2378     };
2379    
2380 adx 30 general_gline_min_cidr: GLINE_MIN_CIDR '=' NUMBER ';'
2381     {
2382     ConfigFileEntry.gline_min_cidr = $3;
2383     };
2384    
2385     general_gline_min_cidr6: GLINE_MIN_CIDR6 '=' NUMBER ';'
2386     {
2387     ConfigFileEntry.gline_min_cidr6 = $3;
2388     };
2389    
2390     general_tkline_expire_notices: TKLINE_EXPIRE_NOTICES '=' TBOOL ';'
2391     {
2392     ConfigFileEntry.tkline_expire_notices = yylval.number;
2393     };
2394    
2395 michael 1074 general_kill_chase_time_limit: KILL_CHASE_TIME_LIMIT '=' timespec ';'
2396 adx 30 {
2397     ConfigFileEntry.kill_chase_time_limit = $3;
2398     };
2399    
2400     general_hide_spoof_ips: HIDE_SPOOF_IPS '=' TBOOL ';'
2401     {
2402     ConfigFileEntry.hide_spoof_ips = yylval.number;
2403     };
2404    
2405     general_ignore_bogus_ts: IGNORE_BOGUS_TS '=' TBOOL ';'
2406     {
2407     ConfigFileEntry.ignore_bogus_ts = yylval.number;
2408     };
2409    
2410     general_disable_remote_commands: DISABLE_REMOTE_COMMANDS '=' TBOOL ';'
2411     {
2412     ConfigFileEntry.disable_remote = yylval.number;
2413     };
2414    
2415     general_failed_oper_notice: FAILED_OPER_NOTICE '=' TBOOL ';'
2416     {
2417     ConfigFileEntry.failed_oper_notice = yylval.number;
2418     };
2419    
2420     general_anti_nick_flood: ANTI_NICK_FLOOD '=' TBOOL ';'
2421     {
2422     ConfigFileEntry.anti_nick_flood = yylval.number;
2423     };
2424    
2425     general_max_nick_time: MAX_NICK_TIME '=' timespec ';'
2426     {
2427     ConfigFileEntry.max_nick_time = $3;
2428     };
2429    
2430     general_max_nick_changes: MAX_NICK_CHANGES '=' NUMBER ';'
2431     {
2432     ConfigFileEntry.max_nick_changes = $3;
2433     };
2434    
2435     general_max_accept: MAX_ACCEPT '=' NUMBER ';'
2436     {
2437     ConfigFileEntry.max_accept = $3;
2438     };
2439    
2440     general_anti_spam_exit_message_time: ANTI_SPAM_EXIT_MESSAGE_TIME '=' timespec ';'
2441     {
2442     ConfigFileEntry.anti_spam_exit_message_time = $3;
2443     };
2444    
2445     general_ts_warn_delta: TS_WARN_DELTA '=' timespec ';'
2446     {
2447     ConfigFileEntry.ts_warn_delta = $3;
2448     };
2449    
2450     general_ts_max_delta: TS_MAX_DELTA '=' timespec ';'
2451     {
2452 michael 967 if (conf_parser_ctx.pass == 2)
2453 adx 30 ConfigFileEntry.ts_max_delta = $3;
2454     };
2455    
2456     general_havent_read_conf: HAVENT_READ_CONF '=' NUMBER ';'
2457     {
2458 michael 967 if (($3 > 0) && conf_parser_ctx.pass == 1)
2459 adx 30 {
2460 michael 1247 ilog(LOG_TYPE_IRCD, "You haven't read your config file properly.");
2461     ilog(LOG_TYPE_IRCD, "There is a line in the example conf that will kill your server if not removed.");
2462     ilog(LOG_TYPE_IRCD, "Consider actually reading/editing the conf file, and removing this line.");
2463 adx 30 exit(0);
2464     }
2465     };
2466    
2467     general_invisible_on_connect: INVISIBLE_ON_CONNECT '=' TBOOL ';'
2468     {
2469     ConfigFileEntry.invisible_on_connect = yylval.number;
2470     };
2471    
2472     general_warn_no_nline: WARN_NO_NLINE '=' TBOOL ';'
2473     {
2474     ConfigFileEntry.warn_no_nline = yylval.number;
2475     };
2476    
2477 michael 584 general_stats_e_disabled: STATS_E_DISABLED '=' TBOOL ';'
2478     {
2479     ConfigFileEntry.stats_e_disabled = yylval.number;
2480     };
2481    
2482 adx 30 general_stats_o_oper_only: STATS_O_OPER_ONLY '=' TBOOL ';'
2483     {
2484     ConfigFileEntry.stats_o_oper_only = yylval.number;
2485     };
2486    
2487     general_stats_P_oper_only: STATS_P_OPER_ONLY '=' TBOOL ';'
2488     {
2489     ConfigFileEntry.stats_P_oper_only = yylval.number;
2490     };
2491    
2492     general_stats_k_oper_only: STATS_K_OPER_ONLY '=' TBOOL ';'
2493     {
2494     ConfigFileEntry.stats_k_oper_only = 2 * yylval.number;
2495     } | STATS_K_OPER_ONLY '=' TMASKED ';'
2496     {
2497     ConfigFileEntry.stats_k_oper_only = 1;
2498     };
2499    
2500     general_stats_i_oper_only: STATS_I_OPER_ONLY '=' TBOOL ';'
2501     {
2502     ConfigFileEntry.stats_i_oper_only = 2 * yylval.number;
2503     } | STATS_I_OPER_ONLY '=' TMASKED ';'
2504     {
2505     ConfigFileEntry.stats_i_oper_only = 1;
2506     };
2507    
2508     general_pace_wait: PACE_WAIT '=' timespec ';'
2509     {
2510     ConfigFileEntry.pace_wait = $3;
2511     };
2512    
2513     general_caller_id_wait: CALLER_ID_WAIT '=' timespec ';'
2514     {
2515     ConfigFileEntry.caller_id_wait = $3;
2516     };
2517    
2518     general_opers_bypass_callerid: OPERS_BYPASS_CALLERID '=' TBOOL ';'
2519     {
2520     ConfigFileEntry.opers_bypass_callerid = yylval.number;
2521     };
2522    
2523     general_pace_wait_simple: PACE_WAIT_SIMPLE '=' timespec ';'
2524     {
2525     ConfigFileEntry.pace_wait_simple = $3;
2526     };
2527    
2528     general_short_motd: SHORT_MOTD '=' TBOOL ';'
2529     {
2530     ConfigFileEntry.short_motd = yylval.number;
2531     };
2532    
2533     general_no_oper_flood: NO_OPER_FLOOD '=' TBOOL ';'
2534     {
2535     ConfigFileEntry.no_oper_flood = yylval.number;
2536     };
2537    
2538     general_true_no_oper_flood: TRUE_NO_OPER_FLOOD '=' TBOOL ';'
2539     {
2540     ConfigFileEntry.true_no_oper_flood = yylval.number;
2541     };
2542    
2543     general_oper_pass_resv: OPER_PASS_RESV '=' TBOOL ';'
2544     {
2545     ConfigFileEntry.oper_pass_resv = yylval.number;
2546     };
2547    
2548     general_message_locale: MESSAGE_LOCALE '=' QSTRING ';'
2549     {
2550 michael 967 if (conf_parser_ctx.pass == 2)
2551 adx 30 {
2552     if (strlen(yylval.string) > LOCALE_LENGTH-2)
2553     yylval.string[LOCALE_LENGTH-1] = '\0';
2554    
2555     set_locale(yylval.string);
2556     }
2557     };
2558    
2559     general_dots_in_ident: DOTS_IN_IDENT '=' NUMBER ';'
2560     {
2561     ConfigFileEntry.dots_in_ident = $3;
2562     };
2563    
2564     general_max_targets: MAX_TARGETS '=' NUMBER ';'
2565     {
2566     ConfigFileEntry.max_targets = $3;
2567     };
2568    
2569     general_use_egd: USE_EGD '=' TBOOL ';'
2570     {
2571     ConfigFileEntry.use_egd = yylval.number;
2572     };
2573    
2574     general_egdpool_path: EGDPOOL_PATH '=' QSTRING ';'
2575     {
2576 michael 967 if (conf_parser_ctx.pass == 2)
2577 adx 30 {
2578     MyFree(ConfigFileEntry.egdpool_path);
2579 michael 1646 ConfigFileEntry.egdpool_path = xstrdup(yylval.string);
2580 adx 30 }
2581     };
2582    
2583 michael 1176 general_services_name: T_SERVICES_NAME '=' QSTRING ';'
2584 michael 1157 {
2585 michael 1176 if (conf_parser_ctx.pass == 2 && valid_servname(yylval.string))
2586 michael 1157 {
2587     MyFree(ConfigFileEntry.service_name);
2588 michael 1646 ConfigFileEntry.service_name = xstrdup(yylval.string);
2589 michael 1157 }
2590     };
2591    
2592 adx 30 general_ping_cookie: PING_COOKIE '=' TBOOL ';'
2593     {
2594     ConfigFileEntry.ping_cookie = yylval.number;
2595     };
2596    
2597     general_disable_auth: DISABLE_AUTH '=' TBOOL ';'
2598     {
2599     ConfigFileEntry.disable_auth = yylval.number;
2600     };
2601    
2602     general_throttle_time: THROTTLE_TIME '=' timespec ';'
2603     {
2604     ConfigFileEntry.throttle_time = yylval.number;
2605     };
2606    
2607     general_oper_umodes: OPER_UMODES
2608     {
2609     ConfigFileEntry.oper_umodes = 0;
2610     } '=' umode_oitems ';' ;
2611    
2612     umode_oitems: umode_oitems ',' umode_oitem | umode_oitem;
2613     umode_oitem: T_BOTS
2614     {
2615     ConfigFileEntry.oper_umodes |= UMODE_BOTS;
2616     } | T_CCONN
2617     {
2618     ConfigFileEntry.oper_umodes |= UMODE_CCONN;
2619 db 849 } | T_CCONN_FULL
2620     {
2621     ConfigFileEntry.oper_umodes |= UMODE_CCONN_FULL;
2622 adx 30 } | T_DEAF
2623     {
2624     ConfigFileEntry.oper_umodes |= UMODE_DEAF;
2625     } | T_DEBUG
2626     {
2627     ConfigFileEntry.oper_umodes |= UMODE_DEBUG;
2628     } | T_FULL
2629     {
2630     ConfigFileEntry.oper_umodes |= UMODE_FULL;
2631 michael 1294 } | HIDDEN
2632     {
2633     ConfigFileEntry.oper_umodes |= UMODE_HIDDEN;
2634 adx 30 } | T_SKILL
2635     {
2636     ConfigFileEntry.oper_umodes |= UMODE_SKILL;
2637     } | T_NCHANGE
2638     {
2639     ConfigFileEntry.oper_umodes |= UMODE_NCHANGE;
2640     } | T_REJ
2641     {
2642     ConfigFileEntry.oper_umodes |= UMODE_REJ;
2643     } | T_UNAUTH
2644     {
2645     ConfigFileEntry.oper_umodes |= UMODE_UNAUTH;
2646     } | T_SPY
2647     {
2648     ConfigFileEntry.oper_umodes |= UMODE_SPY;
2649     } | T_EXTERNAL
2650     {
2651     ConfigFileEntry.oper_umodes |= UMODE_EXTERNAL;
2652     } | T_OPERWALL
2653     {
2654     ConfigFileEntry.oper_umodes |= UMODE_OPERWALL;
2655     } | T_SERVNOTICE
2656     {
2657     ConfigFileEntry.oper_umodes |= UMODE_SERVNOTICE;
2658     } | T_INVISIBLE
2659     {
2660     ConfigFileEntry.oper_umodes |= UMODE_INVISIBLE;
2661     } | T_WALLOP
2662     {
2663     ConfigFileEntry.oper_umodes |= UMODE_WALLOP;
2664     } | T_SOFTCALLERID
2665     {
2666     ConfigFileEntry.oper_umodes |= UMODE_SOFTCALLERID;
2667     } | T_CALLERID
2668     {
2669     ConfigFileEntry.oper_umodes |= UMODE_CALLERID;
2670     } | T_LOCOPS
2671     {
2672     ConfigFileEntry.oper_umodes |= UMODE_LOCOPS;
2673     };
2674    
2675     general_oper_only_umodes: OPER_ONLY_UMODES
2676     {
2677     ConfigFileEntry.oper_only_umodes = 0;
2678     } '=' umode_items ';' ;
2679    
2680     umode_items: umode_items ',' umode_item | umode_item;
2681     umode_item: T_BOTS
2682     {
2683     ConfigFileEntry.oper_only_umodes |= UMODE_BOTS;
2684     } | T_CCONN
2685     {
2686     ConfigFileEntry.oper_only_umodes |= UMODE_CCONN;
2687 db 853 } | T_CCONN_FULL
2688     {
2689     ConfigFileEntry.oper_only_umodes |= UMODE_CCONN_FULL;
2690 adx 30 } | T_DEAF
2691     {
2692     ConfigFileEntry.oper_only_umodes |= UMODE_DEAF;
2693     } | T_DEBUG
2694     {
2695     ConfigFileEntry.oper_only_umodes |= UMODE_DEBUG;
2696     } | T_FULL
2697     {
2698     ConfigFileEntry.oper_only_umodes |= UMODE_FULL;
2699     } | T_SKILL
2700     {
2701     ConfigFileEntry.oper_only_umodes |= UMODE_SKILL;
2702 michael 1294 } | HIDDEN
2703     {
2704     ConfigFileEntry.oper_only_umodes |= UMODE_HIDDEN;
2705 adx 30 } | T_NCHANGE
2706     {
2707     ConfigFileEntry.oper_only_umodes |= UMODE_NCHANGE;
2708     } | T_REJ
2709     {
2710     ConfigFileEntry.oper_only_umodes |= UMODE_REJ;
2711     } | T_UNAUTH
2712     {
2713     ConfigFileEntry.oper_only_umodes |= UMODE_UNAUTH;
2714     } | T_SPY
2715     {
2716     ConfigFileEntry.oper_only_umodes |= UMODE_SPY;
2717     } | T_EXTERNAL
2718     {
2719     ConfigFileEntry.oper_only_umodes |= UMODE_EXTERNAL;
2720     } | T_OPERWALL
2721     {
2722     ConfigFileEntry.oper_only_umodes |= UMODE_OPERWALL;
2723     } | T_SERVNOTICE
2724     {
2725     ConfigFileEntry.oper_only_umodes |= UMODE_SERVNOTICE;
2726     } | T_INVISIBLE
2727     {
2728     ConfigFileEntry.oper_only_umodes |= UMODE_INVISIBLE;
2729     } | T_WALLOP
2730     {
2731     ConfigFileEntry.oper_only_umodes |= UMODE_WALLOP;
2732     } | T_SOFTCALLERID
2733     {
2734     ConfigFileEntry.oper_only_umodes |= UMODE_SOFTCALLERID;
2735     } | T_CALLERID
2736     {
2737     ConfigFileEntry.oper_only_umodes |= UMODE_CALLERID;
2738     } | T_LOCOPS
2739     {
2740     ConfigFileEntry.oper_only_umodes |= UMODE_LOCOPS;
2741     };
2742    
2743     general_min_nonwildcard: MIN_NONWILDCARD '=' NUMBER ';'
2744     {
2745     ConfigFileEntry.min_nonwildcard = $3;
2746     };
2747    
2748     general_min_nonwildcard_simple: MIN_NONWILDCARD_SIMPLE '=' NUMBER ';'
2749     {
2750     ConfigFileEntry.min_nonwildcard_simple = $3;
2751     };
2752    
2753     general_default_floodcount: DEFAULT_FLOODCOUNT '=' NUMBER ';'
2754     {
2755     ConfigFileEntry.default_floodcount = $3;
2756     };
2757    
2758    
2759     /***************************************************************************
2760     * section channel
2761     ***************************************************************************/
2762     channel_entry: CHANNEL
2763     '{' channel_items '}' ';';
2764    
2765     channel_items: channel_items channel_item | channel_item;
2766 michael 1495 channel_item: channel_max_bans |
2767 michael 1432 channel_knock_delay | channel_knock_delay_channel |
2768     channel_max_chans_per_user | channel_max_chans_per_oper |
2769 adx 201 channel_quiet_on_ban | channel_default_split_user_count |
2770     channel_default_split_server_count |
2771     channel_no_create_on_split | channel_restrict_channels |
2772 michael 1401 channel_no_join_on_split |
2773 adx 201 channel_jflood_count | channel_jflood_time |
2774 michael 632 channel_disable_fake_channels | error;
2775 adx 30
2776 michael 632 channel_disable_fake_channels: DISABLE_FAKE_CHANNELS '=' TBOOL ';'
2777     {
2778     ConfigChannel.disable_fake_channels = yylval.number;
2779     };
2780    
2781 adx 30 channel_restrict_channels: RESTRICT_CHANNELS '=' TBOOL ';'
2782     {
2783     ConfigChannel.restrict_channels = yylval.number;
2784     };
2785    
2786     channel_knock_delay: KNOCK_DELAY '=' timespec ';'
2787     {
2788     ConfigChannel.knock_delay = $3;
2789     };
2790    
2791     channel_knock_delay_channel: KNOCK_DELAY_CHANNEL '=' timespec ';'
2792     {
2793     ConfigChannel.knock_delay_channel = $3;
2794     };
2795    
2796     channel_max_chans_per_user: MAX_CHANS_PER_USER '=' NUMBER ';'
2797     {
2798     ConfigChannel.max_chans_per_user = $3;
2799     };
2800    
2801 michael 1432 channel_max_chans_per_oper: MAX_CHANS_PER_OPER '=' NUMBER ';'
2802     {
2803     ConfigChannel.max_chans_per_oper = $3;
2804     };
2805    
2806 adx 30 channel_quiet_on_ban: QUIET_ON_BAN '=' TBOOL ';'
2807     {
2808     ConfigChannel.quiet_on_ban = yylval.number;
2809     };
2810    
2811     channel_max_bans: MAX_BANS '=' NUMBER ';'
2812     {
2813     ConfigChannel.max_bans = $3;
2814     };
2815    
2816     channel_default_split_user_count: DEFAULT_SPLIT_USER_COUNT '=' NUMBER ';'
2817     {
2818     ConfigChannel.default_split_user_count = $3;
2819     };
2820    
2821     channel_default_split_server_count: DEFAULT_SPLIT_SERVER_COUNT '=' NUMBER ';'
2822     {
2823     ConfigChannel.default_split_server_count = $3;
2824     };
2825    
2826     channel_no_create_on_split: NO_CREATE_ON_SPLIT '=' TBOOL ';'
2827     {
2828     ConfigChannel.no_create_on_split = yylval.number;
2829     };
2830    
2831     channel_no_join_on_split: NO_JOIN_ON_SPLIT '=' TBOOL ';'
2832     {
2833     ConfigChannel.no_join_on_split = yylval.number;
2834     };
2835    
2836     channel_jflood_count: JOIN_FLOOD_COUNT '=' NUMBER ';'
2837     {
2838     GlobalSetOptions.joinfloodcount = yylval.number;
2839     };
2840    
2841     channel_jflood_time: JOIN_FLOOD_TIME '=' timespec ';'
2842     {
2843     GlobalSetOptions.joinfloodtime = yylval.number;
2844     };
2845    
2846     /***************************************************************************
2847     * section serverhide
2848     ***************************************************************************/
2849     serverhide_entry: SERVERHIDE
2850     '{' serverhide_items '}' ';';
2851    
2852     serverhide_items: serverhide_items serverhide_item | serverhide_item;
2853     serverhide_item: serverhide_flatten_links | serverhide_hide_servers |
2854     serverhide_links_delay |
2855     serverhide_hidden | serverhide_hidden_name |
2856     serverhide_hide_server_ips |
2857     error;
2858    
2859     serverhide_flatten_links: FLATTEN_LINKS '=' TBOOL ';'
2860     {
2861 michael 967 if (conf_parser_ctx.pass == 2)
2862 adx 30 ConfigServerHide.flatten_links = yylval.number;
2863     };
2864    
2865     serverhide_hide_servers: HIDE_SERVERS '=' TBOOL ';'
2866     {
2867 michael 967 if (conf_parser_ctx.pass == 2)
2868 adx 30 ConfigServerHide.hide_servers = yylval.number;
2869     };
2870    
2871     serverhide_hidden_name: HIDDEN_NAME '=' QSTRING ';'
2872     {
2873 michael 967 if (conf_parser_ctx.pass == 2)
2874 adx 30 {
2875     MyFree(ConfigServerHide.hidden_name);
2876 michael 1646 ConfigServerHide.hidden_name = xstrdup(yylval.string);
2877 adx 30 }
2878     };
2879    
2880     serverhide_links_delay: LINKS_DELAY '=' timespec ';'
2881     {
2882 michael 967 if (conf_parser_ctx.pass == 2)
2883 adx 30 {
2884     if (($3 > 0) && ConfigServerHide.links_disabled == 1)
2885     {
2886     eventAddIsh("write_links_file", write_links_file, NULL, $3);
2887     ConfigServerHide.links_disabled = 0;
2888     }
2889    
2890     ConfigServerHide.links_delay = $3;
2891     }
2892     };
2893    
2894     serverhide_hidden: HIDDEN '=' TBOOL ';'
2895     {
2896 michael 967 if (conf_parser_ctx.pass == 2)
2897 adx 30 ConfigServerHide.hidden = yylval.number;
2898     };
2899    
2900     serverhide_hide_server_ips: HIDE_SERVER_IPS '=' TBOOL ';'
2901     {
2902 michael 967 if (conf_parser_ctx.pass == 2)
2903 adx 30 ConfigServerHide.hide_server_ips = yylval.number;
2904     };

Properties

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