ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/conf_parser.y
Revision: 573
Committed: Mon May 1 09:40:37 2006 UTC (19 years, 3 months ago) by michael
Original Path: ircd-hybrid-7.2/src/ircd_parser.y
File size: 88868 byte(s)
Log Message:
- ts6 fixes as explained on irc

File Contents

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

Properties

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