ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/conf_parser.y
Revision: 1248
Committed: Sat Oct 1 10:02:53 2011 UTC (12 years, 5 months ago) by michael
Original Path: ircd-hybrid-8/src/ircd_parser.y
File size: 84835 byte(s)
Log Message:
- add log file rotation

File Contents

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

Properties

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