ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/conf_parser.y
Revision: 885
Committed: Wed Oct 31 18:09:24 2007 UTC (17 years, 9 months ago) by michael
Original Path: ircd-hybrid-7.2/src/ircd_parser.y
File size: 89772 byte(s)
Log Message:
- Removed LazyLinks in 7.2 to stop people from asking why we keep
  broken code for half a decade. LL will be implemented in a smarter
  fashion in due time

File Contents

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

Properties

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