/[svn]/ircd-hybrid/trunk/src/conf_parser.y
ViewVC logotype

Contents of /ircd-hybrid/trunk/src/conf_parser.y

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1644 - (show annotations)
Tue Nov 6 22:20:16 2012 UTC (7 years, 7 months ago) by michael
File size: 71647 byte(s)
- More config subsystem cleanups

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

Properties

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

svnadmin@ircd-hybrid.org
ViewVC Help
Powered by ViewVC 1.1.28