ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/src/ircd_parser.y
Revision: 261
Committed: Sun Nov 13 10:55:40 2005 UTC (20 years, 9 months ago) by michael
File size: 88165 byte(s)
Log Message:
- Changed cluster{} to use a MatchItem struct

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

Properties

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