ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/conf_parser.y
Revision: 912
Committed: Wed Nov 7 22:47:44 2007 UTC (16 years, 4 months ago) by michael
Original Path: ircd-hybrid-7.2/src/ircd_parser.y
File size: 89883 byte(s)
Log Message:
- Implemented libtool-ltdl. Only shared modules are supported currently
- Several build fixes and cleanups. ircd now builds and runs without any problems
- Added back all files to SVN that are needed to built the daemon
  I really don't want to force other people that want to test the snapshots
  or svn versions to install yyacc, lex, automake, autoconf and libtool...
  No problem having required files in svn
- Removed some automake maintainer stuff which is kinda useless for us

File Contents

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

Properties

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