ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-8/src/conf_parser.y
Revision: 853
Committed: Thu Feb 22 06:01:30 2007 UTC (17 years, 1 month ago) by db
Original Path: ircd-hybrid-7.2/src/ircd_parser.y
File size: 90794 byte(s)
Log Message:
- fix typo in ircd_parser.y regenerate y.tab.c and lex.yy.c
- fix order shown in CLIEXIT
- remove mode parsing in ms_join
- reflect addiction cconn_full flag


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

Properties

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