ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/conf_parser.y
Revision: 909
Committed: Sun Nov 4 23:38:57 2007 UTC (16 years, 5 months ago) by stu
Original Path: ircd-hybrid-7.2/src/ircd_parser.y
File size: 89903 byte(s)
Log Message:
fix compile warning

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

Properties

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