1 /* {{{ irc-seven: Cows like it.
3 * Copyright (C) 2006 Elfyn McBratney.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to:
18 * Free Software Foundation, Inc.
19 * 51 Franklin St - Fifth Floor
20 * Boston, MA 02110-1301
30 #include "ircd_defs.h"
31 #include "sprintf_irc.h"
36 #include "s_newconf.h"
48 #include "blacklist.h"
51 # include <openssl/pem.h>
52 # include <openssl/rsa.h>
56 #define CF_TYPE(x) ((x) & CF_MTYPE)
58 struct TopConf
*conf_cur_block
;
59 static char *conf_cur_block_name
;
61 static dlink_list conf_items
;
63 static struct ConfItem
*yy_aconf
= NULL
;
65 static struct Class
*yy_class
= NULL
;
67 static struct remote_conf
*yy_shared
= NULL
;
68 static struct server_conf
*yy_server
= NULL
;
70 static dlink_list yy_aconf_list
;
71 static dlink_list yy_oper_list
;
72 static dlink_list yy_shared_list
;
73 static dlink_list yy_cluster_list
;
74 static struct oper_conf
*yy_oper
= NULL
;
76 static struct alias_entry
*yy_alias
= NULL
;
78 static char *yy_blacklist_host
= NULL
;
79 static char *yy_blacklist_reason
= NULL
;
81 /* {{{ static const char *conf_strtype() */
83 conf_strtype (int type
)
85 switch (CF_TYPE(type
))
88 return "integer value";
90 return "unquoted string";
92 return "yes/no value";
94 return "quoted string";
96 return "time/size value";
98 return "unknown type";
103 typedef int (*seven_tconf_cb
) (struct TopConf
*);
105 /* {{{ int add_top_conf() */
107 add_top_conf (const char *name
, seven_tconf_cb start_cb
, seven_tconf_cb end_cb
,
108 struct ConfEntry
*items
)
110 struct TopConf
*tc
= NULL
;
112 tc
= MyMalloc(sizeof(*tc
));
114 DupString(tc
->tc_name
, name
);
115 tc
->tc_sfunc
= start_cb
;
116 tc
->tc_efunc
= end_cb
;
117 tc
->tc_entries
= items
;
118 dlinkAddAlloc(tc
, &conf_items
);
124 /* {{{ struct TopConf *find_top_conf() */
126 find_top_conf (const char *name
)
128 dlink_node
*cur
= NULL
;
129 struct TopConf
*tc
= NULL
;
131 DLINK_FOREACH (cur
, conf_items
.head
)
134 if(!strcasecmp(tc
->tc_name
, name
))
142 /* {{{ struct ConfEntry *find_conf_item() */
144 find_conf_item (const struct TopConf
*top
, const char *name
)
146 struct ConfEntry
*cf
= NULL
;
147 dlink_node
*cur
= NULL
;
153 for (i
= 0; top
->tc_entries
[i
].cf_type
; ++i
)
155 cf
= &top
->tc_entries
[i
];
156 if (!strcasecmp(cf
->cf_name
, name
))
161 DLINK_FOREACH (cur
, top
->tc_items
.head
)
164 if (!strcasecmp(cf
->cf_name
, name
))
172 /* {{{ int remove_top_conf() */
174 remove_top_conf (char *name
)
176 struct TopConf
*tc
= NULL
;
177 dlink_node
*cur
= NULL
;
179 if ((tc
= find_top_conf(name
)) == NULL
)
181 if ((cur
= dlinkFind(tc
, &conf_items
)) == NULL
)
184 dlinkDestroy(cur
, &conf_items
);
192 /* {{{ static void conf_set_serverinfo_name() */
194 conf_set_serverinfo_name (void *data
)
196 const char *s
= data
;
199 if (!ServerInfo
.name
)
201 for (; *s
!= '\0'; ++s
)
205 conf_report_error("Ignoring serverinfo::name "
206 "-- bogus servername.");
215 conf_report_error("Ignoring serverinfo::name "
216 "-- must contain '.'");
223 conf_report_error("Ignoring serverinfo::name "
224 "-- cannot begin with digit.");
228 if (strlen(s
) <= HOSTLEN
)
229 DupString(ServerInfo
.name
, (char *) data
);
234 /* {{{ static void conf_set_serverinfo_sid() */
236 conf_set_serverinfo_sid (void *data
)
243 if (!IsDigit(sid
[0]) || !IsIdChar(sid
[1]) || !IsIdChar(sid
[2]) || sid
[3])
245 conf_report_error("Ignoring serverinfo::sid "
250 strcpy(ServerInfo
.sid
, sid
);
254 /* {{{ static void conf_set_serverinfo_network_name() */
256 conf_set_serverinfo_network_name (void *data
)
260 if ((p
= strchr((char *) data
, ' ')))
263 MyFree(ServerInfo
.network_name
);
264 DupString(ServerInfo
.network_name
, (char *) data
);
268 /* {{{ static void conf_set_serverinfo_vhost() */
270 conf_set_serverinfo_vhost (void *data
)
272 if (inetpton(AF_INET
, (char *) data
, &ServerInfo
.ip
.sin_addr
) <= 0)
274 conf_report_error("Invalid netmask for server IPv4 vhost (%s)",
279 ServerInfo
.ip
.sin_family
= AF_INET
;
280 ServerInfo
.specific_ipv4_vhost
= 1;
284 /* {{{ static void conf_set_serverinfo_vhost6() */
286 conf_set_serverinfo_vhost6 (void *data
)
289 if (inetpton(AF_INET6
, (char *) data
, &ServerInfo
.ip6
.sin6_addr
) <= 0)
291 conf_report_error("Invalid netmask for server IPv6 vhost (%s)",
296 ServerInfo
.specific_ipv6_vhost
= 1;
297 ServerInfo
.ip6
.sin6_family
= AF_INET6
;
299 conf_report_error("Warning -- ignoring serverinfo::vhost6 "
300 "-- IPv6 support not available.");
305 /* {{{ static void conf_set_modules_module() */
307 conf_set_modules_module (void *data
)
309 #ifdef STATIC_MODULES
310 conf_report_error("Ignoring modules::module -- "
311 "loadable module support not present.");
315 base
= irc_basename((char *) data
);
316 if (findmodule_byname(base
) < 0)
319 load_one_module((char *) data
, 0);
325 /* {{{ static void conf_set_modules_path() */
327 conf_set_modules_path (void *data
)
329 #ifndef STATIC_MODULES
330 mod_add_path((char *) data
);
332 conf_report_error("Ignoring modules::path -- loadable module support not present.");
343 /* {{{ static struct mode_table umode_table[] = { ... } */
344 static struct mode_table umode_table
[] =
346 {"callerid", UMODE_CALLERID
},
347 {"deaf", UMODE_DEAF
},
348 {"invisible", UMODE_INVISIBLE
},
349 {"noforward", UMODE_NOFORWARD
},
350 {"regonlymsg", UMODE_REGONLYMSG
},
351 {"servnotice", UMODE_SERVNOTICE
},
352 {"wallop", UMODE_WALLOP
},
353 {"operwall", UMODE_OPERWALL
},
354 {"helper", UMODE_HELPER
},
355 {"override", UMODE_OVERRIDE
},
360 /* {{{ struct mode_table flag_table[] = { ... }
362 * Used by modules/m_grant.c so cannot be static.
364 struct mode_table flag_table
[] =
366 {"encrypted", OPER_ENCRYPTED
},
368 {"routing", OPER_ROUTING
},
369 {"kline", OPER_KLINE
},
370 {"unkline", OPER_UNKLINE
},
371 {"override", OPER_OVERRIDE
},
372 {"mass_notice", OPER_MASSNOTICE
},
373 {"rehash", OPER_REHASH
},
375 {"admin", OPER_ADMIN
},
376 {"hidden_admin", OPER_HADMIN
},
377 {"xline", OPER_XLINE
},
378 {"operwall", OPER_OPERWALL
},
379 {"auspex", OPER_AUSPEX
},
380 {"hidden_oper", OPER_INVIS
},
381 {"helper", OPER_HELPER
},
382 {"set_cmodes", OPER_CMODES
},
384 {"wallops", OPER_WALLOPS
},
385 {"scan", OPER_EXPERIMENTAL
},
386 {"grant", OPER_GRANT
},
387 {"remoteban", OPER_REMOTEBAN
},
388 {"staffer", OPER_STAFFER
},
393 /* {{{ static struct mode_table auth_table[] = { ... } */
394 static struct mode_table auth_table
[] =
396 {"encrypted", CONF_FLAGS_ENCRYPTED
},
397 {"spoof_notice", CONF_FLAGS_SPOOF_NOTICE
},
398 {"exceed_limit", CONF_FLAGS_NOLIMIT
},
399 {"dnsbl_exempt", CONF_FLAGS_EXEMPTDNSBL
},
400 {"kline_exempt", CONF_FLAGS_EXEMPTKLINE
},
401 {"flood_exempt", CONF_FLAGS_EXEMPTFLOOD
},
402 {"spambot_exempt", CONF_FLAGS_EXEMPTSPAMBOT
},
403 {"shide_exempt", CONF_FLAGS_EXEMPTSHIDE
},
404 {"jupe_exempt", CONF_FLAGS_EXEMPTJUPE
},
405 {"resv_exempt", CONF_FLAGS_EXEMPTRESV
},
406 {"no_tilde", CONF_FLAGS_NO_TILDE
},
407 {"need_ident", CONF_FLAGS_NEED_IDENTD
},
408 {"have_ident", CONF_FLAGS_NEED_IDENTD
},
409 {"need_sasl", CONF_FLAGS_NEED_SASL
},
414 /* {{{ static struct mode_table connect_table[] = { ... } */
415 static struct mode_table connect_table
[] =
417 {"autoconn", SERVER_AUTOCONN
},
418 {"compressed", SERVER_COMPRESSED
},
419 {"encrypted", SERVER_ENCRYPTED
},
420 {"topicburst", SERVER_TB
},
425 /* {{{ static struct mode_table cluster_table[] = { ... } */
426 static struct mode_table cluster_table
[] = {
427 {"kline", SHARED_PKLINE
},
428 {"tkline", SHARED_TKLINE
},
429 {"unkline", SHARED_UNKLINE
},
430 {"xline", SHARED_PXLINE
},
431 {"txline", SHARED_TXLINE
},
432 {"unxline", SHARED_UNXLINE
},
433 {"resv", SHARED_PRESV
},
434 {"tresv", SHARED_TRESV
},
435 {"unresv", SHARED_UNRESV
},
436 {"dline", SHARED_PDLINE
},
437 {"tdline", SHARED_TDLINE
},
438 {"undline", SHARED_UNDLINE
},
439 {"all", CLUSTER_ALL
},
444 /* {{{ static struct mode_table shared_table[] = { ... } */
445 static struct mode_table shared_table
[] =
447 {"kline", SHARED_PKLINE
| SHARED_TKLINE
},
448 {"xline", SHARED_PXLINE
| SHARED_TXLINE
},
449 {"resv", SHARED_PRESV
| SHARED_TRESV
},
450 {"dline", SHARED_PDLINE
| SHARED_TDLINE
},
451 {"tkline", SHARED_TKLINE
},
452 {"unkline", SHARED_UNKLINE
},
453 {"txline", SHARED_TXLINE
},
454 {"unxline", SHARED_UNXLINE
},
455 {"tresv", SHARED_TRESV
},
456 {"unresv", SHARED_UNRESV
},
457 {"tdline", SHARED_TDLINE
},
458 {"undline", SHARED_UNDLINE
},
459 {"rehash", SHARED_REHASH
},
460 {"grant", SHARED_GRANT
},
462 {"module", SHARED_MODULE
},
469 /* {{{ static int find_umode() */
471 find_umode (struct mode_table
*tab
, const char *name
)
475 for (i
= 0; tab
[i
].name
; ++i
)
477 if (!strcmp(tab
[i
].name
, name
))
485 /* {{{ static void set_modes_from_table() */
487 set_modes_from_table (int *modes
, const char *whatis
, struct mode_table
*tab
, conf_parm_t
*args
)
489 const char *umode
= NULL
;
493 for (; args
; args
= args
->next
)
495 if (CF_TYPE(args
->type
) != CF_STRING
)
497 conf_report_error("Warning -- %s is not a string; ignoring.",
502 umode
= args
->v
.string
;
506 mode
= find_umode(tab
, umode
);
509 conf_report_error("Warning -- unknown %s %s.", whatis
,
522 /* {{{ static int conf_begin_oper() */
524 conf_begin_oper (struct TopConf
*tc
)
526 dlink_node
*cur
= NULL
;
527 dlink_node
*next
= NULL
;
531 free_oper_conf(yy_oper
);
535 DLINK_FOREACH_SAFE (cur
, next
, yy_oper_list
.head
)
537 free_oper_conf(cur
->data
);
538 dlinkDestroy(cur
, &yy_oper_list
);
541 yy_oper
= make_oper_conf();
542 yy_oper
->flags
|= OPER_ENCRYPTED
;
548 /* {{{ static int conf_end_oper() */
550 conf_end_oper (struct TopConf
*tc
)
552 struct oper_conf
*yy_tmpoper
= NULL
;
553 dlink_node
*cur
= NULL
;
554 dlink_node
*next
= NULL
;
556 if (conf_cur_block_name
)
558 if (strlen(conf_cur_block_name
) > OPERNICKLEN
)
559 conf_cur_block_name
[OPERNICKLEN
] = '\0';
561 DupString(yy_oper
->name
, conf_cur_block_name
);
564 if (EmptyString(yy_oper
->name
))
566 conf_report_error("Ignoring operator block -- missing name.");
570 #ifdef HAVE_LIBCRYPTO
571 if (EmptyString(yy_oper
->passwd
) && EmptyString(yy_oper
->rsa_pubkey_file
))
573 if (EmptyString(yy_oper
->passwd
))
576 conf_report_error("Ignoring operator block for %s -- "
577 "missing password", yy_oper
->name
);
581 /* now, yy_oper_list contains a stack of oper_conf's with just user
582 * and host in, yy_oper contains the rest of the information which
583 * we need to copy into each element in yy_oper_list
585 DLINK_FOREACH_SAFE (cur
, next
, yy_oper_list
.head
)
587 yy_tmpoper
= cur
->data
;
588 DupString(yy_tmpoper
->name
, yy_oper
->name
);
590 /* could be an rsa key instead.. */
591 if (!EmptyString(yy_oper
->passwd
))
592 DupString(yy_tmpoper
->passwd
, yy_oper
->passwd
);
594 yy_tmpoper
->flags
= yy_oper
->flags
;
595 yy_tmpoper
->umodes
= yy_oper
->umodes
;
596 yy_tmpoper
->snomask
= yy_oper
->snomask
;
597 yy_tmpoper
->allowed_snomask
= yy_oper
->allowed_snomask
;
599 #ifdef HAVE_LIBCRYPTO
600 if (yy_oper
->rsa_pubkey_file
)
604 if ((file
= BIO_new_file(yy_oper
->rsa_pubkey_file
, "r")) == NULL
)
606 conf_report_error("Ignoring operator block for %s -- "
607 "rsa_public_key_file cant be opened",
612 yy_tmpoper
->rsa_pubkey
= (RSA
*) PEM_read_bio_RSA_PUBKEY(file
,
615 BIO_set_close(file
, BIO_CLOSE
);
618 if (!yy_tmpoper
->rsa_pubkey
)
620 conf_report_error("Ignoring operator block for %s -- "
621 "rsa_public_key_file key invalid; check syntax",
628 /* all is ok, put it on oper_conf_list */
629 dlinkMoveNode(cur
, &yy_oper_list
, &oper_conf_list
);
632 free_oper_conf(yy_oper
);
639 /* {{{ static void conf_set_oper_flags() */
641 conf_set_oper_flags (void *data
)
643 conf_parm_t
*args
= data
;
645 set_modes_from_table(&yy_oper
->flags
, "flag", flag_table
, args
);
649 /* {{{ static void conf_set_oper_user() */
651 conf_set_oper_user (void *data
)
653 struct oper_conf
*yy_tmpoper
= NULL
;
655 char *host
= (char *) data
;
657 yy_tmpoper
= make_oper_conf();
659 if ((p
= strchr(host
, '@')))
663 DupString(yy_tmpoper
->username
, host
);
664 DupString(yy_tmpoper
->host
, p
);
669 DupString(yy_tmpoper
->username
, "*");
670 DupString(yy_tmpoper
->host
, host
);
673 if (EmptyString(yy_tmpoper
->username
) || EmptyString(yy_tmpoper
->host
))
675 conf_report_error("Ignoring user -- missing username/host");
676 free_oper_conf(yy_tmpoper
);
680 dlinkAddAlloc(yy_tmpoper
, &yy_oper_list
);
684 /* {{{ static void conf_set_oper_password() */
686 conf_set_oper_password (void *data
)
690 memset(yy_oper
->passwd
, 0, strlen(yy_oper
->passwd
));
691 MyFree(yy_oper
->passwd
);
694 DupString(yy_oper
->passwd
, (char *) data
);
698 /* {{{ static void conf_set_oper_rsa_public_key_file() */
700 conf_set_oper_rsa_public_key_file (void *data
)
702 #ifdef HAVE_LIBCRYPTO
703 MyFree(yy_oper
->rsa_pubkey_file
);
704 DupString(yy_oper
->rsa_pubkey_file
, (char *) data
);
706 conf_report_error("Warning -- ignoring rsa_public_key_file "
707 "(OpenSSL support not available");
712 /* {{{ static void conf_set_oper_umodes() */
714 conf_set_oper_umodes (void *data
)
716 set_modes_from_table(&yy_oper
->umodes
, "umode", umode_table
, data
);
720 /* {{{ static void conf_set_oper_snomask() */
722 conf_set_oper_snomask (void *data
)
724 yy_oper
->snomask
= parse_snobuf_to_mask(0, (const char *) data
);
728 /* {{{ static void conf_set_oper_allowed_snomask() */
730 conf_set_oper_allowed_snomask (void *data
)
732 yy_oper
->allowed_snomask
= parse_snobuf_to_mask(0, (const char *) data
);
736 /* {{{ static int conf_begin_class() */
738 conf_begin_class (struct TopConf
*tc
)
741 free_class(yy_class
);
743 yy_class
= make_class();
748 /* {{{ static int conf_end_class() */
750 conf_end_class (struct TopConf
*tc
)
752 if(conf_cur_block_name
)
753 DupString(yy_class
->class_name
, conf_cur_block_name
);
755 if (EmptyString(yy_class
->class_name
))
757 conf_report_error("Ignoring connect block -- missing name.");
768 /* {{{ static void conf_set_class_ping_time() */
770 conf_set_class_ping_time (void *data
)
772 yy_class
->ping_freq
= *((unsigned int *) data
);
777 # define CIDR_BITS 32
779 # define CIDR_BITS 128
782 /* {{{ static void conf_set_class_cidr_bitlen() */
784 conf_set_class_cidr_bitlen (void *data
)
786 unsigned int maxsize
= CIDR_BITS
;
788 if (*((unsigned int *) data
) > maxsize
)
790 "class::cidr_bitlen argument exceeds maxsize "
791 "(%d > %d) - ignoring.",
792 *((unsigned int *) data
), maxsize
);
794 yy_class
->cidr_bitlen
= *((unsigned int *) data
);
798 /* {{{ static void conf_set_class_number_per_cidr() */
800 conf_set_class_number_per_cidr (void *data
)
802 yy_class
->cidr_amount
= *((unsigned int *) data
);
806 /* {{{ static void conf_set_class_number_per_ip() */
808 conf_set_class_number_per_ip (void *data
)
810 yy_class
->max_local
= *((unsigned int *) data
);
814 /* {{{ static void conf_set_class_number_per_ip_global() */
816 conf_set_class_number_per_ip_global (void *data
)
818 yy_class
->max_global
= *((unsigned int *) data
);
822 /* {{{ static void conf_set_class_number_per_ident() */
824 conf_set_class_number_per_ident (void *data
)
826 yy_class
->max_ident
= *((unsigned int *) data
);
830 /* {{{ static void conf_set_class_connectfreq() */
832 conf_set_class_connectfreq (void *data
)
834 yy_class
->con_freq
= *((unsigned int *) data
);
838 /* {{{ static void conf_set_class_max_number() */
840 conf_set_class_max_number (void *data
)
842 yy_class
->max_total
= *((unsigned int *) data
);
846 /* {{{ static void conf_set_class_sendq() */
848 conf_set_class_sendq (void *data
)
850 yy_class
->max_sendq
= *((unsigned int *) data
);
854 static char *listener_address
;
856 /* {{{ static int conf_begin_listen() */
858 conf_begin_listen (struct TopConf
*tc
)
860 if (listener_address
)
862 MyFree(listener_address
);
863 listener_address
= NULL
;
870 /* {{{ static int conf_end_listen() */
872 conf_end_listen (struct TopConf
*tc
)
874 if (listener_address
)
876 MyFree(listener_address
);
877 listener_address
= NULL
;
884 /* {{{ static void conf_set_listen_port() */
886 conf_set_listen_port (void *data
)
888 conf_parm_t
*args
= data
;
891 for (; args
; args
= args
->next
)
893 if (CF_TYPE(args
->type
) != CF_INT
)
895 conf_report_error("listener::port argument is not an "
896 "integer -- ignoring.");
900 if (!listener_address
)
902 add_listener(args
->v
.number
, listener_address
, AF_INET
);
904 add_listener(args
->v
.number
, listener_address
, AF_INET6
);
910 if (strchr(listener_address
, ':'))
916 add_listener(args
->v
.number
, listener_address
, family
);
922 /* {{{ static void conf_set_listen_address() */
924 conf_set_listen_address (void *data
)
926 if (listener_address
)
927 MyFree(listener_address
);
929 DupString(listener_address
, data
);
933 /* {{{ static int conf_begin_auth() */
935 conf_begin_auth (struct TopConf
*tc
)
937 dlink_node
*cur
= NULL
;
938 dlink_node
*next
= NULL
;
943 DLINK_FOREACH_SAFE (cur
, next
, yy_aconf_list
.head
)
945 free_conf(cur
->data
);
946 dlinkDestroy(cur
, &yy_aconf_list
);
949 yy_aconf
= make_conf();
950 yy_aconf
->status
= CONF_CLIENT
;
956 /* {{{ static int conf_end_auth() */
958 conf_end_auth (struct TopConf
*tc
)
960 struct ConfItem
*yy_tmp
= NULL
;
961 dlink_node
*cur
= NULL
;
962 dlink_node
*next
= NULL
;
964 if (EmptyString(yy_aconf
->name
))
965 DupString(yy_aconf
->name
, "NOMATCH");
967 if(EmptyString(yy_aconf
->host
))
969 conf_report_error("Ignoring auth block -- missing user@host");
973 /* so the stacking works in order.. */
974 collapse(yy_aconf
->user
);
975 collapse(yy_aconf
->host
);
976 conf_add_class_to_conf(yy_aconf
);
977 add_conf_by_address(yy_aconf
->host
, CONF_CLIENT
, yy_aconf
->user
, yy_aconf
);
979 DLINK_FOREACH_SAFE (cur
, next
, yy_aconf_list
.head
)
984 DupString(yy_tmp
->passwd
, yy_aconf
->passwd
);
986 DupString(yy_tmp
->name
, yy_aconf
->name
);
987 if(yy_aconf
->className
)
988 DupString(yy_tmp
->className
, yy_aconf
->className
);
990 yy_tmp
->flags
= yy_aconf
->flags
;
991 yy_tmp
->port
= yy_aconf
->port
;
993 collapse(yy_tmp
->user
);
994 collapse(yy_tmp
->host
);
996 conf_add_class_to_conf(yy_tmp
);
997 add_conf_by_address(yy_tmp
->host
, CONF_CLIENT
, yy_tmp
->user
, yy_tmp
);
999 dlinkDestroy(cur
, &yy_aconf_list
);
1007 /* {{{ static void conf_set_auth_user() */
1009 conf_set_auth_user (void *data
)
1011 struct ConfItem
*yy_tmp
= NULL
;
1014 /* The first user= line doesn't allocate a new conf */
1015 if (!EmptyString(yy_aconf
->host
))
1017 yy_tmp
= make_conf();
1018 yy_tmp
->status
= CONF_CLIENT
;
1023 if ((p
= strchr(data
, '@')))
1027 DupString(yy_tmp
->user
, data
);
1028 DupString(yy_tmp
->host
, p
);
1032 DupString(yy_tmp
->user
, "*");
1033 DupString(yy_tmp
->host
, data
);
1036 if (yy_aconf
!= yy_tmp
)
1037 dlinkAddAlloc(yy_tmp
, &yy_aconf_list
);
1041 /* {{{ static void conf_set_auth_passwd() */
1043 conf_set_auth_passwd (void *data
)
1045 if(yy_aconf
->passwd
)
1046 memset(yy_aconf
->passwd
, 0, strlen(yy_aconf
->passwd
));
1048 MyFree(yy_aconf
->passwd
);
1049 DupString(yy_aconf
->passwd
, data
);
1053 /* {{{ static void conf_set_auth_spoof() */
1055 conf_set_auth_spoof (void *data
)
1062 if ((p
= strchr(host
, '@')))
1068 if (EmptyString(user
))
1070 conf_report_error("Warning -- spoof ident empty.");
1073 else if (strlen(user
) > USERLEN
)
1075 conf_report_error("Warning -- spoof ident length invalid.");
1078 else if (!valid_username(user
))
1080 conf_report_error("Warning -- invalid spoof (ident).");
1087 if (EmptyString(host
))
1089 conf_report_error("Warning -- spoof host empty.");
1092 else if (strlen(host
) > HOSTLEN
)
1094 conf_report_error("Warning -- spoof host length invalid.");
1097 else if (!valid_hostname(host
))
1099 conf_report_error("Warning -- invalid spoof (host).");
1103 MyFree(yy_aconf
->name
);
1104 DupString(yy_aconf
->name
, data
);
1105 yy_aconf
->flags
|= CONF_FLAGS_SPOOF_IP
;
1109 /* {{{ static void conf_set_auth_flags() */
1111 conf_set_auth_flags (void *data
)
1113 conf_parm_t
*args
= data
;
1115 set_modes_from_table((int *) &yy_aconf
->flags
, "flag", auth_table
, args
);
1119 /* {{{ static void conf_set_auth_redir_serv() */
1121 conf_set_auth_redir_serv (void *data
)
1123 yy_aconf
->flags
|= CONF_FLAGS_REDIR
;
1124 MyFree(yy_aconf
->name
);
1125 DupString(yy_aconf
->name
, data
);
1129 /* {{{ static void conf_set_auth_redir_port() */
1131 conf_set_auth_redir_port (void *data
)
1133 int port
= *((unsigned int *) data
);
1135 yy_aconf
->flags
|= CONF_FLAGS_REDIR
;
1136 yy_aconf
->port
= port
;
1140 /* {{{ static void conf_set_auth_class() */
1142 conf_set_auth_class (void *data
)
1144 MyFree(yy_aconf
->className
);
1145 DupString(yy_aconf
->className
, data
);
1149 /* {{{ static int conf_cleanup_shared()
1151 * ok, shared_oper handles the stacking, shared_flags handles adding
1152 * things.. so all we need to do when we start and end a shared block, is
1153 * clean up anything thats been left over.
1156 conf_cleanup_shared (struct TopConf
*tc
)
1158 dlink_node
*cur
= NULL
;
1159 dlink_node
*next
= NULL
;
1161 DLINK_FOREACH_SAFE (cur
, next
, yy_shared_list
.head
)
1163 free_remote_conf(cur
->data
);
1164 dlinkDestroy(cur
, &yy_shared_list
);
1169 free_remote_conf(yy_shared
);
1177 /* {{{ static void conf_set_shared_oper() */
1179 conf_set_shared_oper (void *data
)
1181 conf_parm_t
*args
= data
;
1182 const char *username
= NULL
;
1186 free_remote_conf(yy_shared
);
1188 yy_shared
= make_remote_conf();
1191 if (CF_TYPE(args
->type
) != CF_QSTRING
)
1193 conf_report_error("Ignoring shared::oper -- server is not a qstring");
1197 DupString(yy_shared
->server
, args
->v
.string
);
1201 DupString(yy_shared
->server
, "*");
1203 if (CF_TYPE(args
->type
) != CF_QSTRING
)
1205 conf_report_error("Ignoring shared::oper -- oper is not a qstring");
1208 else if ((p
= strchr(args
->v
.string
, '@')) == NULL
)
1210 conf_report_error("Ignoring shard::oper -- oper is not a user@host");
1214 username
= args
->v
.string
;
1218 DupString(yy_shared
->host
, "*");
1220 DupString(yy_shared
->host
, p
);
1222 if (EmptyString(username
))
1223 DupString(yy_shared
->username
, "*");
1225 DupString(yy_shared
->username
, username
);
1227 dlinkAddAlloc(yy_shared
, &yy_shared_list
);
1232 /* {{{ static void conf_set_shared_flags() */
1234 conf_set_shared_flags (void *data
)
1236 conf_parm_t
*args
= data
;
1238 dlink_node
*cur
= NULL
;
1239 dlink_node
*next
= NULL
;
1242 free_remote_conf(yy_shared
);
1244 set_modes_from_table(&flags
, "flag", shared_table
, args
);
1245 DLINK_FOREACH_SAFE (cur
, next
, yy_shared_list
.head
)
1247 yy_shared
= cur
->data
;
1248 yy_shared
->flags
= flags
;
1250 dlinkDestroy(cur
, &yy_shared_list
);
1251 dlinkAddTail(yy_shared
, &yy_shared
->node
, &shared_conf_list
);
1258 /* {{{ static int conf_begin_connect() */
1260 conf_begin_connect (struct TopConf
*tc
)
1263 free_server_conf(yy_server
);
1265 yy_server
= make_server_conf();
1266 yy_server
->port
= PORTNUM
;
1268 if (conf_cur_block_name
)
1269 DupString(yy_server
->name
, conf_cur_block_name
);
1275 /* {{{ static int conf_end_connect() */
1277 conf_end_connect (struct TopConf
*tc
)
1279 if (EmptyString(yy_server
->name
))
1281 conf_report_error("Ignoring connect block -- missing name.");
1284 else if (ServerInfo
.name
&& !irccmp(ServerInfo
.name
, yy_server
->name
))
1286 conf_report_error("Ignoring connect block for %s "
1287 "-- name is equal to my own name.",
1291 else if (EmptyString(yy_server
->passwd
) || EmptyString(yy_server
->spasswd
))
1293 conf_report_error("Ignoring connect block for %s "
1294 "-- missing password.", yy_server
->name
);
1297 else if (EmptyString(yy_server
->host
))
1299 conf_report_error("Ignoring connect block for %s -- missing host.",
1305 if (ServerConfCompressed(yy_server
))
1307 conf_report_error("Ignoring connect::flags::compressed -- zlib not available.");
1308 yy_server
->flags
&= ~SERVER_COMPRESSED
;
1312 add_server_conf(yy_server
);
1313 dlinkAdd(yy_server
, &yy_server
->node
, &server_conf_list
);
1320 /* {{{ static void conf_set_connect_host() */
1322 conf_set_connect_host (void *data
)
1324 if (yy_server
->host
)
1325 MyFree(yy_server
->host
);
1327 DupString(yy_server
->host
, data
);
1328 if (strchr(yy_server
->host
, ':'))
1329 yy_server
->aftype
= AF_INET6
;
1333 /* {{{ static void conf_set_connect_vhost() */
1335 conf_set_connect_vhost (void *data
)
1337 if (inetpton_sock(data
, (struct sockaddr
*) &yy_server
->my_ipnum
) <= 0)
1339 conf_report_error("Invalid netmask for server vhost (%s)",
1344 yy_server
->flags
|= SERVER_VHOSTED
;
1348 /* {{{ static void conf_set_connect_send_password() */
1350 conf_set_connect_send_password (void *data
)
1352 if (yy_server
->spasswd
)
1354 memset(yy_server
->spasswd
, 0, strlen(yy_server
->spasswd
));
1355 MyFree(yy_server
->spasswd
);
1358 DupString(yy_server
->spasswd
, data
);
1362 /* {{{ static void conf_set_connect_accept_password() */
1364 conf_set_connect_accept_password (void *data
)
1366 if (yy_server
->passwd
)
1368 memset(yy_server
->passwd
, 0, strlen(yy_server
->passwd
));
1369 MyFree(yy_server
->passwd
);
1372 DupString(yy_server
->passwd
, data
);
1376 /* {{{ static void conf_set_connect_port() */
1378 conf_set_connect_port (void *data
)
1380 int port
= *((unsigned int *) data
);
1385 yy_server
->port
= port
;
1389 /* {{{ static void conf_set_connect_aftype() */
1391 conf_set_connect_aftype (void *data
)
1395 if (!strcasecmp(aft
, "ipv4"))
1396 yy_server
->aftype
= AF_INET
;
1398 else if(!strcasecmp(aft
, "ipv6"))
1399 yy_server
->aftype
= AF_INET6
;
1402 conf_report_error("connect::aftype '%s' is unknown.", aft
);
1406 /* {{{ static void conf_set_connect_flags() */
1408 conf_set_connect_flags (void *data
)
1410 conf_parm_t
*args
= data
;
1412 set_modes_from_table(&yy_server
->flags
, "flag", connect_table
, args
);
1416 /* {{{ static void conf_set_connect_hub_mask() */
1418 conf_set_connect_hub_mask (void *data
)
1420 struct remote_conf
*yy_hub
= NULL
;
1422 if (EmptyString(yy_server
->name
))
1425 yy_hub
= make_remote_conf();
1426 yy_hub
->flags
= CONF_HUB
;
1428 DupString(yy_hub
->host
, data
);
1429 DupString(yy_hub
->server
, yy_server
->name
);
1430 dlinkAdd(yy_hub
, &yy_hub
->node
, &hubleaf_conf_list
);
1434 /* {{{ static void conf_set_connect_leaf_mask() */
1436 conf_set_connect_leaf_mask (void *data
)
1438 struct remote_conf
*yy_leaf
= NULL
;
1440 if (EmptyString(yy_server
->name
))
1443 yy_leaf
= make_remote_conf();
1444 yy_leaf
->flags
= CONF_LEAF
;
1446 DupString(yy_leaf
->host
, data
);
1447 DupString(yy_leaf
->server
, yy_server
->name
);
1448 dlinkAdd(yy_leaf
, &yy_leaf
->node
, &hubleaf_conf_list
);
1452 /* {{{ static void conf_set_connect_class() */
1454 conf_set_connect_class(void *data
)
1456 MyFree(yy_server
->class_name
);
1457 DupString(yy_server
->class_name
, data
);
1461 /* {{{ static void conf_set_exempt_ip() */
1463 conf_set_exempt_ip(void *data
)
1465 struct ConfItem
*yy_tmp
= NULL
;
1467 if (parse_netmask(data
, NULL
, NULL
) == HM_HOST
)
1469 conf_report_error("Ignoring exempt -- invalid exempt::ip.");
1473 yy_tmp
= make_conf();
1474 DupString(yy_tmp
->passwd
, "*");
1475 DupString(yy_tmp
->host
, data
);
1476 yy_tmp
->status
= CONF_EXEMPTDLINE
;
1477 add_conf_by_address(yy_tmp
->host
, CONF_EXEMPTDLINE
, NULL
, yy_tmp
);
1481 /* {{{ static int conf_cleanup_cluster() */
1483 conf_cleanup_cluster (struct TopConf
*tc
)
1485 dlink_node
*cur
= NULL
;
1486 dlink_node
*next
= NULL
;
1488 DLINK_FOREACH_SAFE (cur
, next
, yy_cluster_list
.head
)
1490 free_remote_conf(cur
->data
);
1491 dlinkDestroy(cur
, &yy_cluster_list
);
1496 free_remote_conf(yy_shared
);
1504 /* {{{ static void conf_set_cluster_name() */
1506 conf_set_cluster_name (void *data
)
1509 free_remote_conf(yy_shared
);
1511 yy_shared
= make_remote_conf();
1512 DupString(yy_shared
->server
, data
);
1513 dlinkAddAlloc(yy_shared
, &yy_cluster_list
);
1519 /* {{{ static void conf_set_cluster_flags() */
1521 conf_set_cluster_flags (void *data
)
1523 conf_parm_t
*args
= data
;
1525 dlink_node
*cur
= NULL
;
1526 dlink_node
*next
= NULL
;
1529 free_remote_conf(yy_shared
);
1531 set_modes_from_table(&flags
, "flag", cluster_table
, args
);
1532 DLINK_FOREACH_SAFE (cur
, next
, yy_cluster_list
.head
)
1534 yy_shared
= cur
->data
;
1535 yy_shared
->flags
= flags
;
1536 dlinkAddTail(yy_shared
, &yy_shared
->node
, &cluster_conf_list
);
1537 dlinkDestroy(cur
, &yy_cluster_list
);
1544 /* {{{ static void conf_set_general_havent_read_conf() */
1546 conf_set_general_havent_read_conf (void *data
)
1548 if (*((unsigned int *) data
))
1550 conf_report_error("You haven't read your config file properly.");
1551 conf_report_error("There is a line in the example conf that will "
1552 "kill your server if not removed.");
1553 conf_report_error("Consider actually reading/editing the conf "
1554 "file, and removing this line.");
1562 /* {{{ static void conf_set_general_hide_error_messages() */
1564 conf_set_general_hide_error_messages (void *data
)
1568 if (!strcasecmp(val
, "yes"))
1569 ConfigFileEntry
.hide_error_messages
= 2;
1570 else if (!strcasecmp(val
, "opers"))
1571 ConfigFileEntry
.hide_error_messages
= 1;
1572 else if(!strcasecmp(val
, "no"))
1573 ConfigFileEntry
.hide_error_messages
= 0;
1575 conf_report_error("Invalid setting '%s' for "
1576 "general::hide_error_messages.", val
);
1580 /* {{{ static void conf_set_general_kline_delay() */
1582 conf_set_general_kline_delay (void *data
)
1584 ConfigFileEntry
.kline_delay
= *((unsigned int *) data
);
1589 /* {{{ static void conf_set_general_stats_k_oper_only() */
1591 conf_set_general_stats_k_oper_only(void *data
)
1595 if (!strcasecmp(val
, "yes"))
1596 ConfigFileEntry
.stats_k_oper_only
= 2;
1597 else if (!strcasecmp(val
, "masked"))
1598 ConfigFileEntry
.stats_k_oper_only
= 1;
1599 else if (!strcasecmp(val
, "no"))
1600 ConfigFileEntry
.stats_k_oper_only
= 0;
1602 conf_report_error("Invalid setting '%s' for "
1603 "general::stats_k_oper_only.", val
);
1607 /* {{{ static void conf_set_general_stats_i_oper_only() */
1609 conf_set_general_stats_i_oper_only (void *data
)
1613 if (!strcasecmp(val
, "yes"))
1614 ConfigFileEntry
.stats_i_oper_only
= 2;
1615 else if (!strcasecmp(val
, "masked"))
1616 ConfigFileEntry
.stats_i_oper_only
= 1;
1617 else if (!strcasecmp(val
, "no"))
1618 ConfigFileEntry
.stats_i_oper_only
= 0;
1620 conf_report_error("Invalid setting '%s' for "
1621 "general::stats_i_oper_only.", val
);
1625 /* {{{ static void conf_set_general_compression_level() */
1627 conf_set_general_compression_level (void *data
)
1630 ConfigFileEntry
.compression_level
= *((unsigned int *) data
);
1632 if ((ConfigFileEntry
.compression_level
< 1) || (ConfigFileEntry
.compression_level
> 9))
1634 conf_report_error("Invalid general::compression_level %d "
1635 "-- using default.",
1636 ConfigFileEntry
.compression_level
);
1637 ConfigFileEntry
.compression_level
= 0;
1640 conf_report_error("Ignoring general::compression_level "
1641 "-- zlib not available.");
1646 /* {{{ static void conf_set_general_default_umodes() */
1648 conf_set_general_default_umodes (void *data
)
1651 int what
= MODE_ADD
;
1654 ConfigFileEntry
.default_umodes
= 0;
1655 for (pm
= (char *) data
; *pm
; ++pm
)
1666 /* don't allow +o */
1673 if ((flag
= user_modes
[(unsigned char) *pm
]))
1675 /* Proper value has probably not yet been set
1676 * so don't check oper_only_umodes -- jilles */
1677 if (what
== MODE_ADD
)
1678 ConfigFileEntry
.default_umodes
|= flag
;
1680 ConfigFileEntry
.default_umodes
&= ~flag
;
1688 /* {{{ static void conf_set_general_oper_umodes() */
1690 conf_set_general_oper_umodes (void *data
)
1692 set_modes_from_table(&ConfigFileEntry
.oper_umodes
, "umode",
1697 /* {{{ static void conf_set_general_oper_only_umodes() */
1699 conf_set_general_oper_only_umodes (void *data
)
1701 set_modes_from_table(&ConfigFileEntry
.oper_only_umodes
, "umode",
1706 /* {{{ static void conf_set_general_oper_snomask() */
1708 conf_set_general_oper_snomask (void *data
)
1711 int what
= MODE_ADD
;
1714 ConfigFileEntry
.oper_snomask
= 0;
1715 for (pm
= (char *) data
; *pm
; ++pm
)
1727 if ((flag
= snomask_modes
[(unsigned char) *pm
]))
1729 if (what
== MODE_ADD
)
1730 ConfigFileEntry
.oper_snomask
|= flag
;
1732 ConfigFileEntry
.oper_snomask
&= ~flag
;
1740 /* {{{ static void conf_set_serverhide_links_delay() */
1742 conf_set_serverhide_links_delay (void *data
)
1744 int val
= *((unsigned int *) data
);
1746 if ((val
> 0) && ConfigServerHide
.links_disabled
== 1)
1748 eventAddIsh("cache_links", cache_links
, NULL
, val
);
1749 ConfigServerHide
.links_disabled
= 0;
1751 else if (val
!= ConfigServerHide
.links_delay
)
1752 eventUpdate("cache_links", val
);
1754 ConfigServerHide
.links_delay
= val
;
1758 /* {{{ static int conf_begin_service() */
1760 conf_begin_service (struct TopConf
*tc
)
1762 struct Client
*target_p
= NULL
;
1763 dlink_node
*cur
= NULL
;
1765 DLINK_FOREACH (cur
, global_serv_list
.head
)
1767 target_p
= cur
->data
;
1768 target_p
->flags
&= ~FLAGS_SERVICE
;
1775 /* {{{ static void conf_set_service_name() */
1777 conf_set_service_name (void *data
)
1779 struct Client
*target_p
= NULL
;
1780 const char *s
= data
;
1784 for (; *s
!= '\0'; s
++)
1786 if (!IsServChar(*s
))
1788 conf_report_error("Ignoring service::name "
1789 "-- bogus servername.");
1798 conf_report_error("Ignoring service::name -- must contain '.'");
1802 DupString(tmp
, data
);
1803 dlinkAddAlloc(tmp
, &service_list
);
1805 if ((target_p
= find_server(NULL
, tmp
)))
1806 target_p
->flags
|= FLAGS_SERVICE
;
1810 /* {{{ static int alias_hash() */
1812 alias_hash (const char *p
)
1818 hash_val
+= ((int) (*p
) & 0xDF);
1822 return (hash_val
% MAX_MSG_HASH
);
1826 /* {{{ static int conf_begin_alias() */
1828 conf_begin_alias (struct TopConf
*tc
)
1830 yy_alias
= MyMalloc(sizeof(struct alias_entry
));
1832 if (conf_cur_block_name
)
1833 DupString(yy_alias
->name
, conf_cur_block_name
);
1835 yy_alias
->flags
= 0;
1842 /* {{{ static int conf_end_alias() */
1844 conf_end_alias (struct TopConf
*tc
)
1851 if (!yy_alias
->name
)
1853 conf_report_error("Ignoring alias -- must have a name.");
1858 else if (!yy_alias
->target
)
1860 conf_report_error("Ignoring alias -- must have a target.");
1866 hashval
= alias_hash(yy_alias
->name
);
1867 dlinkAddAlloc(yy_alias
, &alias_hash_table
[hashval
]);
1873 /* {{{ static void conf_set_alias_name() */
1875 conf_set_alias_name (void *data
)
1877 /* should never happen. */
1878 if (!data
|| !yy_alias
)
1881 DupString(yy_alias
->name
, data
);
1885 /* {{{ static void conf_set_alias_target() */
1887 conf_set_alias_target (void *data
)
1889 /* should never happen. */
1890 if (!data
|| !yy_alias
)
1893 DupString(yy_alias
->target
, data
);
1897 /* {{{ static void conf_set_blacklist_host() */
1899 conf_set_blacklist_host (void *data
)
1901 DupString(yy_blacklist_host
, data
);
1905 /* {{{ static void conf_set_blacklist_reason() */
1907 conf_set_blacklist_reason (void *data
)
1909 DupString(yy_blacklist_reason
, data
);
1911 if (yy_blacklist_host
&& yy_blacklist_reason
)
1913 new_blacklist(yy_blacklist_host
, yy_blacklist_reason
);
1914 MyFree(yy_blacklist_host
);
1915 MyFree(yy_blacklist_reason
);
1916 yy_blacklist_host
= NULL
;
1917 yy_blacklist_reason
= NULL
;
1926 /* {{{ void conf_report_error() */
1928 conf_report_error (const char *fmt
, ...)
1931 char msg
[IRCD_BUFSIZE
+ 1] = {0};
1934 ircvsnprintf(msg
, IRCD_BUFSIZE
, fmt
, ap
);
1939 fprintf(stderr
, "\"%s\", line %d: %s\n", current_file
,
1944 ierror("\"%s\", line %d: %s", current_file
, lineno
+ 1, msg
);
1945 sendto_realops_snomask(SNO_GENERAL
, L_ALL
, "\"%s\", line %d: %s",
1946 current_file
, lineno
+ 1, msg
);
1950 /* {{{ int conf_start_block() */
1952 conf_start_block (char *block
, char *name
)
1954 if (!(conf_cur_block
= find_top_conf(block
)))
1956 conf_report_error("Configuration block '%s' is not defined.",
1962 DupString(conf_cur_block_name
, name
);
1964 conf_cur_block_name
= NULL
;
1966 if (conf_cur_block
->tc_sfunc
)
1968 if (conf_cur_block
->tc_sfunc(conf_cur_block
) < 0)
1976 /* {{{ int conf_end_block() */
1978 conf_end_block (struct TopConf
*tc
)
1981 return tc
->tc_efunc(tc
);
1983 MyFree(conf_cur_block_name
);
1988 /* {{{ static void conf_set_generic_int() */
1990 conf_set_generic_int (void *data
, void *location
)
1992 *((int *) location
) = *((unsigned int *) data
);
1996 /* {{{ static void conf_set_generic_string() */
1998 conf_set_generic_string (void *data
, int len
, void *location
)
2000 char **loc
= location
;
2003 if (len
&& strlen(input
) > len
)
2007 DupString(*loc
, input
);
2011 /* {{{ int conf_call_set() */
2013 conf_call_set (struct TopConf
*tc
, char *item
, conf_parm_t
* value
, int type
)
2015 struct ConfEntry
*cf
= NULL
;
2016 conf_parm_t
*cp
= NULL
;
2021 if (!(cf
= find_conf_item(tc
, item
)))
2023 conf_report_error("Non-existant configuration setting %s::%s.",
2024 tc
->tc_name
, (char *) item
);
2029 * If this setting is a scalar type make sure we're not given a list.
2031 if (value
->type
& CF_FLIST
&& !cf
->cf_type
& CF_FLIST
)
2033 conf_report_error("Option %s::%s does not take a list of values.",
2039 if (CF_TYPE(value
->v
.list
->type
) != CF_TYPE(cf
->cf_type
))
2041 if ((CF_TYPE(value
->v
.list
->type
) == CF_YESNO
) &&
2042 (CF_TYPE(cf
->cf_type
) == CF_STRING
))
2044 value
->v
.list
->type
= CF_STRING
;
2045 if (cp
->v
.number
== 1)
2046 DupString(cp
->v
.string
, "yes");
2048 DupString(cp
->v
.string
, "no");
2050 else if (!((CF_TYPE(value
->v
.list
->type
) == CF_INT
) &&
2051 (CF_TYPE(cf
->cf_type
) == CF_TIME
)))
2054 "Wrong type for %s::%s (expected %s, got %s)",
2055 tc
->tc_name
, (char *) item
,
2056 conf_strtype(cf
->cf_type
),
2057 conf_strtype(value
->v
.list
->type
));
2062 if (cf
->cf_type
& CF_FLIST
)
2066 conf_set_generic_list(value
->v
.list
, cf
->cf_arg
);
2069 /* just pass it the extended argument list */
2070 cf
->cf_func(value
->v
.list
);
2074 /* it's old-style, needs only one arg */
2075 switch (cf
->cf_type
)
2081 conf_set_generic_int(&cp
->v
.number
, cf
->cf_arg
);
2083 cf
->cf_func(&cp
->v
.number
);
2087 if (EmptyString(cp
->v
.string
))
2089 conf_report_error("Ignoring %s::%s -- empty field",
2092 else if (cf
->cf_arg
)
2093 conf_set_generic_string(cp
->v
.string
, cf
->cf_len
, cf
->cf_arg
);
2095 cf
->cf_func(cp
->v
.string
);
2104 /* {{{ int add_conf_item() */
2106 add_conf_item (const char *topconf
, const char *name
, int type
, void (*func
) (void *))
2108 struct TopConf
*tc
= NULL
;
2109 struct ConfEntry
*cf
= NULL
;
2111 if (!(tc
= find_top_conf(topconf
)))
2113 if ((cf
= find_conf_item(tc
, name
)))
2116 cf
= MyMalloc(sizeof(struct ConfEntry
));
2117 DupString(cf
->cf_name
, name
);
2121 dlinkAddAlloc(cf
, &tc
->tc_items
);
2127 /* {{{ int remove_conf_item() */
2129 remove_conf_item (const char *topconf
, const char *name
)
2131 struct TopConf
*tc
= NULL
;
2132 struct ConfEntry
*cf
= NULL
;
2133 dlink_node
*cur
= NULL
;
2135 if (!(tc
= find_top_conf(topconf
)))
2137 if (!(cf
= find_conf_item(tc
, name
)))
2139 if (!(cur
= dlinkFind(cf
, &tc
->tc_items
)))
2142 dlinkDestroy(cur
, &tc
->tc_items
);
2150 * TODO: The below structures should really be auto-generated by the build
2154 /* {{{ static struct ConfEntry conf_serverinfo_table[] = { ... } */
2155 static struct ConfEntry conf_serverinfo_table
[] =
2157 {"description", CF_QSTRING
, NULL
, 0, &ServerInfo
.description
},
2158 {"network_desc", CF_QSTRING
, NULL
, 0, &ServerInfo
.network_desc
},
2159 {"hub", CF_YESNO
, NULL
, 0, &ServerInfo
.hub
},
2160 {"use_ts6", CF_YESNO
, NULL
, 0, &ServerInfo
.use_ts6
},
2161 {"network_name", CF_QSTRING
, conf_set_serverinfo_network_name
, 0, NULL
},
2162 {"name", CF_QSTRING
, conf_set_serverinfo_name
, 0, NULL
},
2163 {"sid", CF_QSTRING
, conf_set_serverinfo_sid
, 0, NULL
},
2164 {"vhost", CF_QSTRING
, conf_set_serverinfo_vhost
, 0, NULL
},
2165 {"vhost6", CF_QSTRING
, conf_set_serverinfo_vhost6
, 0, NULL
},
2166 {"", 0, NULL
, 0, NULL
},
2170 /* {{{ static struct ConfEntry conf_admin_table[] = { ... } */
2171 static struct ConfEntry conf_admin_table
[] =
2173 {"name", CF_QSTRING
, NULL
, 200, &AdminInfo
.name
},
2174 {"description", CF_QSTRING
, NULL
, 200, &AdminInfo
.description
},
2175 {"email", CF_QSTRING
, NULL
, 200, &AdminInfo
.email
},
2176 {"", 0, NULL
, 0, NULL
},
2180 /* {{{ static struct ConfEntry conf_log_table[] = { ... } */
2181 static struct ConfEntry conf_log_table
[] =
2183 {"fname_userlog", CF_QSTRING
, NULL
, MAXPATHLEN
, &ConfigFileEntry
.fname_userlog
},
2184 {"fname_fuserlog", CF_QSTRING
, NULL
, MAXPATHLEN
, &ConfigFileEntry
.fname_fuserlog
},
2185 {"fname_operlog", CF_QSTRING
, NULL
, MAXPATHLEN
, &ConfigFileEntry
.fname_operlog
},
2186 {"fname_foperlog", CF_QSTRING
, NULL
, MAXPATHLEN
, &ConfigFileEntry
.fname_foperlog
},
2187 {"fname_serverlog", CF_QSTRING
, NULL
, MAXPATHLEN
, &ConfigFileEntry
.fname_serverlog
},
2188 {"fname_killlog", CF_QSTRING
, NULL
, MAXPATHLEN
, &ConfigFileEntry
.fname_killlog
},
2189 {"fname_klinelog", CF_QSTRING
, NULL
, MAXPATHLEN
, &ConfigFileEntry
.fname_klinelog
},
2190 {"fname_ioerrorlog", CF_QSTRING
, NULL
, MAXPATHLEN
, &ConfigFileEntry
.fname_ioerrorlog
},
2191 {"", 0, NULL
, 0, NULL
},
2195 /* {{{ static struct ConfEntry conf_operator_table[] = { ... } */
2196 static struct ConfEntry conf_operator_table
[] =
2198 {"rsa_public_key_file", CF_QSTRING
, conf_set_oper_rsa_public_key_file
, 0, NULL
},
2199 {"flags", CF_STRING
| CF_FLIST
, conf_set_oper_flags
, 0, NULL
},
2200 {"umodes", CF_STRING
| CF_FLIST
, conf_set_oper_umodes
, 0, NULL
},
2201 {"snomask", CF_QSTRING
, conf_set_oper_snomask
, 0, NULL
},
2202 {"allowed_snomask", CF_QSTRING
, conf_set_oper_allowed_snomask
, 0, NULL
},
2203 {"user", CF_QSTRING
, conf_set_oper_user
, 0, NULL
},
2204 {"password", CF_QSTRING
, conf_set_oper_password
, 0, NULL
},
2205 {"", 0, NULL
, 0, NULL
},
2209 /* {{{ static struct ConfEntry conf_class_table[] = { ... } */
2210 static struct ConfEntry conf_class_table
[] =
2212 {"ping_time", CF_TIME
, conf_set_class_ping_time
, 0, NULL
},
2213 {"cidr_bitlen", CF_INT
, conf_set_class_cidr_bitlen
, 0, NULL
},
2214 {"number_per_cidr", CF_INT
, conf_set_class_number_per_cidr
, 0, NULL
},
2215 {"number_per_ip", CF_INT
, conf_set_class_number_per_ip
, 0, NULL
},
2216 {"number_per_ip_global", CF_INT
, conf_set_class_number_per_ip_global
, 0, NULL
},
2217 {"number_per_ident", CF_INT
, conf_set_class_number_per_ident
, 0, NULL
},
2218 {"connectfreq", CF_TIME
, conf_set_class_connectfreq
, 0, NULL
},
2219 {"max_number", CF_INT
, conf_set_class_max_number
, 0, NULL
},
2220 {"sendq", CF_TIME
, conf_set_class_sendq
, 0, NULL
},
2221 {"", 0, NULL
, 0, NULL
},
2225 /* {{{ static struct ConfEntry conf_auth_table[] = { ... } */
2226 static struct ConfEntry conf_auth_table
[] =
2228 {"user", CF_QSTRING
, conf_set_auth_user
, 0, NULL
},
2229 {"password", CF_QSTRING
, conf_set_auth_passwd
, 0, NULL
},
2230 {"class", CF_QSTRING
, conf_set_auth_class
, 0, NULL
},
2231 {"spoof", CF_QSTRING
, conf_set_auth_spoof
, 0, NULL
},
2232 {"redirserv", CF_QSTRING
, conf_set_auth_redir_serv
, 0, NULL
},
2233 {"redirport", CF_INT
, conf_set_auth_redir_port
, 0, NULL
},
2234 {"flags", CF_STRING
| CF_FLIST
, conf_set_auth_flags
, 0, NULL
},
2235 {"", 0, NULL
, 0, NULL
},
2239 /* {{{ static struct ConfEntry conf_connect_table[] = { ... } */
2240 static struct ConfEntry conf_connect_table
[] =
2242 {"send_password", CF_QSTRING
, conf_set_connect_send_password
, 0, NULL
},
2243 {"accept_password", CF_QSTRING
, conf_set_connect_accept_password
, 0, NULL
},
2244 {"flags", CF_STRING
| CF_FLIST
, conf_set_connect_flags
, 0, NULL
},
2245 {"host", CF_QSTRING
, conf_set_connect_host
, 0, NULL
},
2246 {"vhost", CF_QSTRING
, conf_set_connect_vhost
, 0, NULL
},
2247 {"port", CF_INT
, conf_set_connect_port
, 0, NULL
},
2248 {"aftype", CF_STRING
, conf_set_connect_aftype
, 0, NULL
},
2249 {"hub_mask", CF_QSTRING
, conf_set_connect_hub_mask
, 0, NULL
},
2250 {"leaf_mask", CF_QSTRING
, conf_set_connect_leaf_mask
, 0, NULL
},
2251 {"class", CF_QSTRING
, conf_set_connect_class
, 0, NULL
},
2252 {"", 0, NULL
, 0, NULL
},
2256 /* {{{ static struct ConfEntry conf_general_table[] = { ... } */
2257 static struct ConfEntry conf_general_table
[] =
2259 {"oper_only_umodes", CF_STRING
| CF_FLIST
, conf_set_general_oper_only_umodes
, 0, NULL
},
2260 {"oper_umodes", CF_STRING
| CF_FLIST
, conf_set_general_oper_umodes
, 0, NULL
},
2261 {"oper_snomask", CF_QSTRING
, conf_set_general_oper_snomask
, 0, NULL
},
2262 {"compression_level", CF_INT
, conf_set_general_compression_level
, 0, NULL
},
2263 {"havent_read_conf", CF_YESNO
, conf_set_general_havent_read_conf
, 0, NULL
},
2264 {"hide_error_messages", CF_STRING
, conf_set_general_hide_error_messages
, 0, NULL
},
2265 {"kline_delay", CF_TIME
, conf_set_general_kline_delay
, 0, NULL
},
2266 {"stats_k_oper_only", CF_STRING
, conf_set_general_stats_k_oper_only
, 0, NULL
},
2267 {"stats_i_oper_only", CF_STRING
, conf_set_general_stats_i_oper_only
, 0, NULL
},
2268 {"default_umodes", CF_QSTRING
, conf_set_general_default_umodes
, 0, NULL
},
2270 {"default_operstring", CF_QSTRING
, NULL
, REALLEN
, &ConfigFileEntry
.default_operstring
},
2271 {"default_adminstring", CF_QSTRING
, NULL
, REALLEN
, &ConfigFileEntry
.default_adminstring
},
2272 {"servicestring", CF_QSTRING
, NULL
, REALLEN
, &ConfigFileEntry
.servicestring
},
2273 {"egdpool_path", CF_QSTRING
, NULL
, MAXPATHLEN
, &ConfigFileEntry
.egdpool_path
},
2274 {"identify_service", CF_QSTRING
, NULL
, REALLEN
, &ConfigFileEntry
.identifyservice
},
2275 {"identify_command", CF_QSTRING
, NULL
, REALLEN
, &ConfigFileEntry
.identifycommand
},
2276 {"servlink_path", CF_QSTRING
, NULL
, MAXPATHLEN
, &ConfigFileEntry
.servlink_path
},
2278 {"anti_spam_exit_message_time", CF_TIME
, NULL
, 0, &ConfigFileEntry
.anti_spam_exit_message_time
},
2279 {"disable_fake_channels", CF_YESNO
, NULL
, 0, &ConfigFileEntry
.disable_fake_channels
},
2280 {"min_nonwildcard_simple", CF_INT
, NULL
, 0, &ConfigFileEntry
.min_nonwildcard_simple
},
2281 {"non_redundant_klines", CF_YESNO
, NULL
, 0, &ConfigFileEntry
.non_redundant_klines
},
2282 {"tkline_expire_notices", CF_YESNO
, NULL
, 0, &ConfigFileEntry
.tkline_expire_notices
},
2284 {"anti_nick_flood", CF_YESNO
, NULL
, 0, &ConfigFileEntry
.anti_nick_flood
},
2285 {"burst_away", CF_YESNO
, NULL
, 0, &ConfigFileEntry
.burst_away
},
2286 {"caller_id_wait", CF_TIME
, NULL
, 0, &ConfigFileEntry
.caller_id_wait
},
2287 {"client_exit", CF_YESNO
, NULL
, 0, &ConfigFileEntry
.client_exit
},
2288 {"client_flood", CF_INT
, NULL
, 0, &ConfigFileEntry
.client_flood
},
2289 {"collision_fnc", CF_YESNO
, NULL
, 0, &ConfigFileEntry
.collision_fnc
},
2290 {"connect_timeout", CF_TIME
, NULL
, 0, &ConfigFileEntry
.connect_timeout
},
2291 {"default_floodcount", CF_INT
, NULL
, 0, &ConfigFileEntry
.default_floodcount
},
2292 {"disable_auth", CF_YESNO
, NULL
, 0, &ConfigFileEntry
.disable_auth
},
2293 {"dot_in_ip6_addr", CF_YESNO
, NULL
, 0, &ConfigFileEntry
.dot_in_ip6_addr
},
2294 {"dots_in_ident", CF_INT
, NULL
, 0, &ConfigFileEntry
.dots_in_ident
},
2295 {"failed_oper_notice", CF_YESNO
, NULL
, 0, &ConfigFileEntry
.failed_oper_notice
},
2296 {"global_snotices", CF_YESNO
, NULL
, 0, &ConfigFileEntry
.global_snotices
},
2297 {"idletime", CF_TIME
, NULL
, 0, &ConfigFileEntry
.idletime
},
2298 {"hide_spoof_ips", CF_YESNO
, NULL
, 0, &ConfigFileEntry
.hide_spoof_ips
},
2299 {"dline_with_reason", CF_YESNO
, NULL
, 0, &ConfigFileEntry
.dline_with_reason
},
2300 {"kline_with_reason", CF_YESNO
, NULL
, 0, &ConfigFileEntry
.kline_with_reason
},
2301 {"map_oper_only", CF_YESNO
, NULL
, 0, &ConfigFileEntry
.map_oper_only
},
2302 {"max_accept", CF_INT
, NULL
, 0, &ConfigFileEntry
.max_accept
},
2303 {"max_monitor", CF_INT
, NULL
, 0, &ConfigFileEntry
.max_monitor
},
2304 {"max_nick_time", CF_TIME
, NULL
, 0, &ConfigFileEntry
.max_nick_time
},
2305 {"max_nick_changes", CF_INT
, NULL
, 0, &ConfigFileEntry
.max_nick_changes
},
2306 {"max_targets", CF_INT
, NULL
, 0, &ConfigFileEntry
.max_targets
},
2307 {"min_nonwildcard", CF_INT
, NULL
, 0, &ConfigFileEntry
.min_nonwildcard
},
2308 {"nick_delay", CF_TIME
, NULL
, 0, &ConfigFileEntry
.nick_delay
},
2309 {"no_oper_flood", CF_YESNO
, NULL
, 0, &ConfigFileEntry
.no_oper_flood
},
2310 {"pace_wait", CF_TIME
, NULL
, 0, &ConfigFileEntry
.pace_wait
},
2311 {"pace_wait_simple", CF_TIME
, NULL
, 0, &ConfigFileEntry
.pace_wait_simple
},
2312 {"ping_cookie", CF_YESNO
, NULL
, 0, &ConfigFileEntry
.ping_cookie
},
2313 {"reject_after_count", CF_INT
, NULL
, 0, &ConfigFileEntry
.reject_after_count
},
2314 {"reject_ban_time", CF_TIME
, NULL
, 0, &ConfigFileEntry
.reject_ban_time
},
2315 {"reject_duration", CF_TIME
, NULL
, 0, &ConfigFileEntry
.reject_duration
},
2316 {"short_motd", CF_YESNO
, NULL
, 0, &ConfigFileEntry
.short_motd
},
2317 {"stats_c_oper_only", CF_YESNO
, NULL
, 0, &ConfigFileEntry
.stats_c_oper_only
},
2318 {"stats_e_disabled", CF_YESNO
, NULL
, 0, &ConfigFileEntry
.stats_e_disabled
},
2319 {"stats_h_oper_only", CF_YESNO
, NULL
, 0, &ConfigFileEntry
.stats_h_oper_only
},
2320 {"stats_o_oper_only", CF_YESNO
, NULL
, 0, &ConfigFileEntry
.stats_o_oper_only
},
2321 {"stats_P_oper_only", CF_YESNO
, NULL
, 0, &ConfigFileEntry
.stats_P_oper_only
},
2322 {"stats_y_oper_only", CF_YESNO
, NULL
, 0, &ConfigFileEntry
.stats_y_oper_only
},
2323 {"target_change", CF_YESNO
, NULL
, 0, &ConfigFileEntry
.target_change
},
2324 {"ts_max_delta", CF_TIME
, NULL
, 0, &ConfigFileEntry
.ts_max_delta
},
2325 {"use_egd", CF_YESNO
, NULL
, 0, &ConfigFileEntry
.use_egd
},
2326 {"ts_warn_delta", CF_TIME
, NULL
, 0, &ConfigFileEntry
.ts_warn_delta
},
2327 {"use_whois_actually", CF_YESNO
, NULL
, 0, &ConfigFileEntry
.use_whois_actually
},
2328 {"warn_no_nline", CF_YESNO
, NULL
, 0, &ConfigFileEntry
.warn_no_nline
},
2329 {"hide_opers", CF_YESNO
, NULL
, 0, &ConfigFileEntry
.hide_opers
},
2330 {"allow_kline_on", CF_YESNO
, NULL
, 0, &ConfigFileEntry
.allow_kline_on
},
2331 {"no_ping_timeout", CF_YESNO
, NULL
, 0, &ConfigFileEntry
.no_ping_timeout
},
2332 {"remote_die", CF_YESNO
, NULL
, 0, &ConfigFileEntry
.remote_die
},
2333 {"remote_restart", CF_YESNO
, NULL
, 0, &ConfigFileEntry
.remote_restart
},
2334 {"idented_user_prefix", CF_QSTRING
, NULL
, IDPREFIXLEN
, &ConfigFileEntry
.idented_user_prefix
},
2335 {"unidented_user_prefix", CF_QSTRING
, NULL
, IDPREFIXLEN
, &ConfigFileEntry
.unidented_user_prefix
},
2336 {"", 0, NULL
, 0, NULL
},
2340 /* {{{ static struct ConfEntry conf_channel_table[] = { ... } */
2341 static struct ConfEntry conf_channel_table
[] =
2343 {"default_split_user_count", CF_INT
, NULL
, 0, &ConfigChannel
.default_split_user_count
},
2344 {"default_split_server_count", CF_INT
, NULL
, 0, &ConfigChannel
.default_split_server_count
},
2345 {"burst_topicwho", CF_YESNO
, NULL
, 0, &ConfigChannel
.burst_topicwho
},
2346 {"invite_ops_only", CF_YESNO
, NULL
, 0, &ConfigChannel
.invite_ops_only
},
2347 {"kick_on_split_riding", CF_YESNO
, NULL
, 0, &ConfigChannel
.kick_on_split_riding
},
2348 {"knock_delay", CF_TIME
, NULL
, 0, &ConfigChannel
.knock_delay
},
2349 {"knock_delay_channel", CF_TIME
, NULL
, 0, &ConfigChannel
.knock_delay_channel
},
2350 {"max_bans", CF_INT
, NULL
, 0, &ConfigChannel
.max_bans
},
2351 {"max_bans_large", CF_INT
, NULL
, 0, &ConfigChannel
.max_bans_large
},
2352 {"max_chans_per_user", CF_INT
, NULL
, 0, &ConfigChannel
.max_chans_per_user
},
2353 {"max_chans_per_user_large", CF_INT
, NULL
, 0, &ConfigChannel
.max_chans_per_user_large
},
2354 {"no_create_on_split", CF_YESNO
, NULL
, 0, &ConfigChannel
.no_create_on_split
},
2355 {"no_join_on_split", CF_YESNO
, NULL
, 0, &ConfigChannel
.no_join_on_split
},
2356 {"use_except", CF_YESNO
, NULL
, 0, &ConfigChannel
.use_except
},
2357 {"use_invex", CF_YESNO
, NULL
, 0, &ConfigChannel
.use_invex
},
2358 {"use_knock", CF_YESNO
, NULL
, 0, &ConfigChannel
.use_knock
},
2359 {"", 0, NULL
, 0, NULL
},
2363 /* {{{ static struct ConfEntry conf_serverhide_table[] = { ... } */
2364 static struct ConfEntry conf_serverhide_table
[] =
2366 {"disable_hidden", CF_YESNO
, NULL
, 0, &ConfigServerHide
.disable_hidden
},
2367 {"flatten_links", CF_YESNO
, NULL
, 0, &ConfigServerHide
.flatten_links
},
2368 {"hidden", CF_YESNO
, NULL
, 0, &ConfigServerHide
.hidden
},
2369 {"links_delay", CF_TIME
, conf_set_serverhide_links_delay
, 0, NULL
},
2370 {"", 0, NULL
, 0, NULL
},
2374 /* {{{ void newconf_init() */
2378 add_top_conf("modules", NULL
, NULL
, NULL
);
2379 add_conf_item("modules", "path", CF_QSTRING
, conf_set_modules_path
);
2380 add_conf_item("modules", "module", CF_QSTRING
, conf_set_modules_module
);
2382 add_top_conf("serverinfo", NULL
, NULL
, conf_serverinfo_table
);
2383 add_top_conf("admin", NULL
, NULL
, conf_admin_table
);
2384 add_top_conf("log", NULL
, NULL
, conf_log_table
);
2385 add_top_conf("operator", conf_begin_oper
, conf_end_oper
,
2386 conf_operator_table
);
2387 add_top_conf("class", conf_begin_class
, conf_end_class
,
2390 add_top_conf("listen", conf_begin_listen
, conf_end_listen
, NULL
);
2391 add_conf_item("listen", "port", CF_INT
| CF_FLIST
, conf_set_listen_port
);
2392 add_conf_item("listen", "ip", CF_QSTRING
, conf_set_listen_address
);
2393 add_conf_item("listen", "host", CF_QSTRING
, conf_set_listen_address
);
2395 add_top_conf("auth", conf_begin_auth
, conf_end_auth
, conf_auth_table
);
2397 add_top_conf("shared", conf_cleanup_shared
, conf_cleanup_shared
, NULL
);
2398 add_conf_item("shared", "oper", CF_QSTRING
|CF_FLIST
,
2399 conf_set_shared_oper
);
2400 add_conf_item("shared", "flags", CF_STRING
| CF_FLIST
,
2401 conf_set_shared_flags
);
2403 add_top_conf("connect", conf_begin_connect
, conf_end_connect
,
2404 conf_connect_table
);
2406 add_top_conf("exempt", NULL
, NULL
, NULL
);
2407 add_conf_item("exempt", "ip", CF_QSTRING
, conf_set_exempt_ip
);
2409 add_top_conf("cluster", conf_cleanup_cluster
, conf_cleanup_cluster
, NULL
);
2410 add_conf_item("cluster", "name", CF_QSTRING
, conf_set_cluster_name
);
2411 add_conf_item("cluster", "flags", CF_STRING
| CF_FLIST
,
2412 conf_set_cluster_flags
);
2414 add_top_conf("general", NULL
, NULL
, conf_general_table
);
2415 add_top_conf("channel", NULL
, NULL
, conf_channel_table
);
2416 add_top_conf("serverhide", NULL
, NULL
, conf_serverhide_table
);
2418 add_top_conf("service", conf_begin_service
, NULL
, NULL
);
2419 add_conf_item("service", "name", CF_QSTRING
, conf_set_service_name
);
2421 add_top_conf("alias", conf_begin_alias
, conf_end_alias
, NULL
);
2422 add_conf_item("alias", "name", CF_QSTRING
, conf_set_alias_name
);
2423 add_conf_item("alias", "target", CF_QSTRING
, conf_set_alias_target
);
2425 add_top_conf("blacklist", NULL
, NULL
, NULL
);
2426 add_conf_item("blacklist", "host", CF_QSTRING
, conf_set_blacklist_host
);
2427 add_conf_item("blacklist", "reject_reason", CF_QSTRING
,
2428 conf_set_blacklist_reason
);
2432 * vim: ts=8 sw=8 noet fdm=marker tw=80