summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2013-05-05 01:55:04 -0400
committerAdam <Adam@anope.org>2013-05-05 01:55:04 -0400
commit1d0bb9b26b7ad58ab0bf979ac046f4511b3bf12b (patch)
tree4486f0784bdf050fd7eb225c0cb9df352ce1f45a
parent781defb7076ddfddf723ca08cd0a518b6657b64f (diff)
Rework the config file reader to be much more flexible and move many configuration directives to the actual modules they are used in.
-rw-r--r--data/botserv.example.conf86
-rw-r--r--data/chanserv.example.conf105
-rw-r--r--data/chanstats.example.conf5
-rw-r--r--data/example.conf267
-rw-r--r--data/global.example.conf30
-rw-r--r--data/hostserv.example.conf52
-rw-r--r--data/memoserv.example.conf32
-rw-r--r--data/modules.example.conf84
-rw-r--r--data/nickserv.example.conf286
-rw-r--r--data/operserv.example.conf237
-rw-r--r--include/account.h4
-rw-r--r--include/anope.h1
-rw-r--r--include/bots.h7
-rw-r--r--include/channels.h4
-rw-r--r--include/config.h850
-rw-r--r--include/defs.h3
-rw-r--r--include/modes.h13
-rw-r--r--include/module.h2
-rw-r--r--include/modules.h89
-rw-r--r--include/protocol.h5
-rw-r--r--include/servers.h4
-rw-r--r--include/users.h2
-rw-r--r--modules/bs_autoassign.cpp17
-rw-r--r--modules/commands/bs_badwords.cpp18
-rw-r--r--modules/commands/bs_bot.cpp38
-rw-r--r--modules/commands/bs_kick.cpp38
-rw-r--r--modules/commands/bs_set.cpp7
-rw-r--r--modules/commands/cs_access.cpp23
-rw-r--r--modules/commands/cs_akick.cpp16
-rw-r--r--modules/commands/cs_ban.cpp5
-rw-r--r--modules/commands/cs_clone.cpp22
-rw-r--r--modules/commands/cs_entrymsg.cpp11
-rw-r--r--modules/commands/cs_fantasy_stats.cpp9
-rw-r--r--modules/commands/cs_fantasy_top.cpp9
-rw-r--r--modules/commands/cs_flags.cpp16
-rw-r--r--modules/commands/cs_info.cpp7
-rw-r--r--modules/commands/cs_kick.cpp7
-rw-r--r--modules/commands/cs_list.cpp10
-rw-r--r--modules/commands/cs_mode.cpp2
-rw-r--r--modules/commands/cs_register.cpp15
-rw-r--r--modules/commands/cs_seen.cpp24
-rw-r--r--modules/commands/cs_set.cpp34
-rw-r--r--modules/commands/cs_set_misc.cpp12
-rw-r--r--modules/commands/cs_suspend.cpp11
-rw-r--r--modules/commands/cs_xop.cpp29
-rw-r--r--modules/commands/help.cpp9
-rw-r--r--modules/commands/hs_list.cpp11
-rw-r--r--modules/commands/hs_request.cpp56
-rw-r--r--modules/commands/hs_set.cpp8
-rw-r--r--modules/commands/ms_read.cpp7
-rw-r--r--modules/commands/ms_rsend.cpp26
-rw-r--r--modules/commands/ms_send.cpp4
-rw-r--r--modules/commands/ms_set.cpp27
-rw-r--r--modules/commands/ns_access.cpp21
-rw-r--r--modules/commands/ns_ajoin.cpp2
-rw-r--r--modules/commands/ns_cert.cpp10
-rw-r--r--modules/commands/ns_drop.cpp4
-rw-r--r--modules/commands/ns_getpass.cpp4
-rw-r--r--modules/commands/ns_group.cpp34
-rw-r--r--modules/commands/ns_info.cpp14
-rw-r--r--modules/commands/ns_list.cpp11
-rw-r--r--modules/commands/ns_recover.cpp13
-rw-r--r--modules/commands/ns_register.cpp78
-rw-r--r--modules/commands/ns_resetpass.cpp13
-rw-r--r--modules/commands/ns_set.cpp77
-rw-r--r--modules/commands/ns_set_misc.cpp14
-rw-r--r--modules/commands/ns_suspend.cpp7
-rw-r--r--modules/commands/ns_update.cpp2
-rw-r--r--modules/commands/os_akill.cpp24
-rw-r--r--modules/commands/os_chankill.cpp5
-rw-r--r--modules/commands/os_config.cpp154
-rw-r--r--modules/commands/os_defcon.cpp66
-rw-r--r--modules/commands/os_dns.cpp18
-rw-r--r--modules/commands/os_forbid.cpp35
-rw-r--r--modules/commands/os_ignore.cpp5
-rw-r--r--modules/commands/os_kill.cpp4
-rw-r--r--modules/commands/os_list.cpp10
-rw-r--r--modules/commands/os_login.cpp12
-rw-r--r--modules/commands/os_logsearch.cpp10
-rw-r--r--modules/commands/os_news.cpp21
-rw-r--r--modules/commands/os_noop.cpp4
-rw-r--r--modules/commands/os_reload.cpp4
-rw-r--r--modules/commands/os_session.cpp125
-rw-r--r--modules/commands/os_set.cpp16
-rw-r--r--modules/commands/os_stats.cpp7
-rw-r--r--modules/commands/os_svs.cpp9
-rw-r--r--modules/commands/os_sxline.cpp55
-rw-r--r--modules/database/db_flatfile.cpp31
-rw-r--r--modules/database/db_old.cpp3
-rw-r--r--modules/database/db_plain.cpp14
-rw-r--r--modules/database/db_sql.cpp10
-rw-r--r--modules/database/db_sql_live.cpp11
-rw-r--r--modules/extra/m_chanstats.cpp29
-rw-r--r--modules/extra/m_httpd.cpp21
-rw-r--r--modules/extra/m_ldap.cpp24
-rw-r--r--modules/extra/m_ldap_authentication.cpp36
-rw-r--r--modules/extra/m_ldap_oper.cpp16
-rw-r--r--modules/extra/m_mysql.cpp26
-rw-r--r--modules/extra/m_proxyscan.cpp43
-rw-r--r--modules/extra/m_sql_authentication.cpp22
-rw-r--r--modules/extra/m_sql_oper.cpp8
-rw-r--r--modules/extra/m_sqlite.cpp16
-rw-r--r--modules/extra/m_ssl.cpp12
-rw-r--r--modules/extra/m_xmlrpc_main.cpp9
-rw-r--r--modules/extra/webcpanel/pages/chanserv/access.cpp8
-rw-r--r--modules/extra/webcpanel/pages/chanserv/akick.cpp4
-rw-r--r--modules/extra/webcpanel/pages/chanserv/drop.cpp2
-rw-r--r--modules/extra/webcpanel/pages/confirm.cpp2
-rw-r--r--modules/extra/webcpanel/pages/hostserv/request.cpp2
-rw-r--r--modules/extra/webcpanel/pages/memoserv/memos.cpp4
-rw-r--r--modules/extra/webcpanel/pages/nickserv/access.cpp4
-rw-r--r--modules/extra/webcpanel/pages/nickserv/cert.cpp4
-rw-r--r--modules/extra/webcpanel/pages/operserv/akill.cpp4
-rw-r--r--modules/extra/webcpanel/pages/register.cpp2
-rw-r--r--modules/extra/webcpanel/webcpanel.cpp37
-rw-r--r--modules/ldapapi.h (renamed from modules/ldap.h)0
-rw-r--r--modules/m_dns.cpp19
-rw-r--r--modules/m_dnsbl.cpp28
-rw-r--r--modules/m_helpchan.cpp11
-rw-r--r--modules/m_rewrite.cpp17
-rw-r--r--modules/ns_maxemail.cpp20
-rw-r--r--modules/protocol/bahamut.cpp6
-rw-r--r--modules/protocol/charybdis.cpp29
-rw-r--r--modules/protocol/hybrid.cpp18
-rw-r--r--modules/protocol/inspircd11.cpp8
-rw-r--r--modules/protocol/inspircd12.cpp18
-rw-r--r--modules/protocol/inspircd20.cpp39
-rw-r--r--modules/protocol/ngircd.cpp11
-rw-r--r--modules/protocol/plexus.cpp6
-rw-r--r--modules/protocol/ratbox.cpp7
-rw-r--r--modules/protocol/unreal.cpp50
-rw-r--r--modules/pseudoclients/botserv.cpp144
-rw-r--r--modules/pseudoclients/chanserv.cpp205
-rw-r--r--modules/pseudoclients/chanserv.h18
-rw-r--r--modules/pseudoclients/global.cpp48
-rw-r--r--modules/pseudoclients/global.h4
-rw-r--r--modules/pseudoclients/hostserv.cpp24
-rw-r--r--modules/pseudoclients/memoserv.cpp64
-rw-r--r--modules/pseudoclients/memoserv.h4
-rw-r--r--modules/pseudoclients/nickserv.cpp136
-rw-r--r--modules/pseudoclients/nickserv.h4
-rw-r--r--modules/pseudoclients/operserv.cpp29
-rw-r--r--src/bots.cpp68
-rw-r--r--src/channels.cpp97
-rw-r--r--src/command.cpp6
-rw-r--r--src/config.cpp2119
-rw-r--r--src/configreader.cpp116
-rw-r--r--src/init.cpp24
-rw-r--r--src/language.cpp15
-rw-r--r--src/logger.cpp5
-rw-r--r--src/mail.cpp21
-rw-r--r--src/main.cpp6
-rw-r--r--src/messages.cpp46
-rw-r--r--src/misc.cpp40
-rw-r--r--src/modes.cpp82
-rw-r--r--src/modulemanager.cpp3
-rw-r--r--src/nickalias.cpp9
-rw-r--r--src/nickcore.cpp14
-rw-r--r--src/opertype.cpp4
-rw-r--r--src/protocol.cpp37
-rw-r--r--src/regchannel.cpp42
-rw-r--r--src/servers.cpp34
-rw-r--r--src/uplink.cpp24
-rw-r--r--src/users.cpp75
-rw-r--r--src/xline.cpp8
165 files changed, 3041 insertions, 4809 deletions
diff --git a/data/botserv.example.conf b/data/botserv.example.conf
index b0cc513ae..8f67c4be2 100644
--- a/data/botserv.example.conf
+++ b/data/botserv.example.conf
@@ -56,17 +56,14 @@ service
*
* Provides essential functionality for BotServ.
*/
-module { name = "botserv" }
-
-/*
- * Configuration for BotServ provided by bs_main.
- */
-botserv
+module
{
+ name = "botserv"
+
/*
* The name of the client that should be BotServ.
*/
- name = "BotServ"
+ client = "BotServ"
/*
* The default bot options for newly registered channels. Note that changing these options
@@ -92,19 +89,6 @@ botserv
minusers = 1
/*
- * The maximum number of entries a single bad words list can have. Setting it too high can
- * reduce performance slightly.
- */
- badwordsmax = 32
-
- /*
- * The amount of time that data for a user is valid in BotServ. If the data exceeds this time,
- * it is reset or deleted depending on the case. Do not set it too high, otherwise your
- * resources will be slightly affected.
- */
- keepdata = 10m
-
- /*
* The bots are currently not affected by any modes or bans when they try to join a channel.
* But some people may want to make it act like a real bot, that is, for example, remove all
* the bans affecting the bot before joining the channel, remove a ban that affects the bot
@@ -116,26 +100,18 @@ botserv
#smartjoin = yes
/*
- * If set, the bots will use a kick reason that does not state the word when it is kicking.
- * This is especially useful if you have young people on your network.
- *
- * This directive is optional.
+ * Defines the prefixes for fantasy commands in channels. One of these characters will have to be prepended
+ * to all fantasy commands. If you choose "!", for example, fantasy commands will be "!kick",
+ * "!op", etc. This directive is optional, if left out, the default fantasy character is "!".
*/
- gentlebadwordreason = yes
+ #fantasycharacter = "!."
/*
- * If set, BotServ will use case sensitive checking for badwords.
+ * Modes to set on service bots when they join channels, comment this out for no modes
*
* This directive is optional.
*/
- #casesensitive = yes
-
- /*
- * Defines the prefixes for fantasy commands in channels. One of these characters will have to be prepended
- * to all fantasy commands. If you choose "!", for example, fantasy commands will be "!kick",
- * "!op", etc. This directive is optional, if left out, the default fantasy character is "!".
- */
- #fantasycharacter = "!."
+ botmodes = "ao"
}
/*
@@ -184,7 +160,22 @@ bs_autoassign
*
* Used for controlling the channel badword list.
*/
-module { name = "bs_badwords" }
+module
+{
+ name = "bs_badwords"
+
+ /*
+ * The maximum number of entries a single bad words list can have.
+ */
+ badwordsmax = 32
+
+ /*
+ * If set, BotServ will use case sensitive checking for badwords.
+ *
+ * This directive is optional.
+ */
+ #casesensitive = yes
+}
command { service = "BotServ"; name = "BADWORDS"; command = "botserv/badwords"; }
/*
@@ -246,7 +237,26 @@ command { service = "BotServ"; name = "INFO"; command = "botserv/info"; }
*
* Used for configuring what bots should kick for.
*/
-module { name = "bs_kick" }
+module
+{
+ name = "bs_kick"
+
+ /*
+ * The amount of time that data for a user is valid in BotServ. If the data exceeds this time,
+ * it is reset or deleted depending on the case. Do not set it too high, otherwise your
+ * resources will be slightly affected.
+ */
+ keepdata = 10m
+
+ /*
+ * If set, the bots will use a kick reason that does not state the word when it is kicking.
+ * This is especially useful if you have young people on your network.
+ *
+ * This directive is optional.
+ */
+ gentlebadwordreason = yes
+}
+
command { service = "BotServ"; name = "KICK"; command = "botserv/kick"; }
command { service = "BotServ"; name = "KICK AMSG"; command = "botserv/kick/amsg"; }
command { service = "BotServ"; name = "KICK BADWORDS"; command = "botserv/kick/badwords"; }
@@ -285,7 +295,8 @@ command { service = "BotServ"; name = "SET PRIVATE"; command = "botserv/set/priv
/* Fantasy commands
*
* Fantasy commands can be executed in channels that have a BotServ bot by prefixing the
- * command with one of the fantasy characters configured in botserv:fantasycharacter.
+ * command with one of the fantasy characters configured in botserv's fantasycharacter
+ * directive.
*
* Sane defaults are provided below that do not need to be edited unless you wish to change the default behavior.
*/
@@ -321,7 +332,6 @@ fantasy { name = "UNSUSPEND"; command = "chanserv/unsuspend"; permission = "chan
fantasy { name = "UP"; command = "chanserv/up"; }
fantasy { name = "VOP"; command = "chanserv/vop"; }
-
/* Use m_rewrite to rewrite the op, deop, etc. fantasy commands (see chanserv.conf). */
fantasy { name = "OWNER"; command = "rewrite"; }
fantasy { name = "DEOWNER"; command = "rewrite"; }
diff --git a/data/chanserv.example.conf b/data/chanserv.example.conf
index 08954eaa6..6dc40991a 100644
--- a/data/chanserv.example.conf
+++ b/data/chanserv.example.conf
@@ -56,17 +56,14 @@ service
*
* Provides essential functionality for ChanServ.
*/
-module { name = "chanserv" }
-
-/*
- * Configuration for ChanServ provided by cs_main.
- */
-chanserv
+module
{
+ name = "chanserv"
+
/*
* The name of the client that should be ChanServ.
*/
- name = "ChanServ"
+ client = "ChanServ"
/*
* The default options for newly registered channels. Note that changing these options
@@ -95,7 +92,7 @@ chanserv
* This directive is optional, if left blank, the options will default to keeptopic, secure, securefounder,
* and signkick. If you really want no defaults, use "none" by itself as the option.
*/
- defaults="keeptopic peace secure securefounder signkick"
+ defaults = "keeptopic peace secure securefounder signkick"
/*
* The maximum number of channels which may be registered to a single nickname.
@@ -114,23 +111,7 @@ chanserv
expire = 14d
/*
- * The length of time before a suspended channel becomes unsuspended.
- *
- * This directive is optional.
- * If not set, the default is never.
- */
- #suspendexpire = 90d
-
- /*
- * The lenth of time before a forbidden channel drops.
- *
- * This directive is optional.
- * If not set, the default is never.
- */
- #forbidexpire = 90d
-
- /*
- * The default ban type for newly registered channels (and when importing old databases).
+ * The default ban type for newly registered channels.
*
* defbantype can be:
*
@@ -147,27 +128,12 @@ chanserv
accessmax = 1024
/*
- * The maximum number of entries on a channel's autokick list.
- */
- autokickmax = 32
-
- /*
- * The default reason for an autokick if none is given.
- */
- autokickreason = "User has been banned from the channel"
-
- /*
* The length of time ChanServ stays in a channel after kicking a user from a channel they are not
* permitted to be in. This only occurs when the user is the only one in the channel.
*/
inhabit = 15s
/*
- * The maximum number of channels to be returned for a ChanServ LIST command.
- */
- listmax = 50
-
- /*
* Allow only IRC Operators to use ChanServ.
*
* This directive is optional.
@@ -195,18 +161,6 @@ chanserv
require = "r"
/*
- * Some IRCds can enforce mode locks server-side. This reduces the spam caused by
- * services immediately reversing mode changes for locked modes.
- */
- use_server_side_mlock = yes
-
- /*
- * Some IRCds can enforce topic locks server-side. This reduces the spam caused by
- * services immediately reversing topic changes.
- */
- use_server_side_topiclock = yes
-
- /*
* The maximum length of the reason field for user commands such as chanserv/kick
* and chanserv/ban.
*/
@@ -902,7 +856,21 @@ command { service = "ChanServ"; name = "LEVELS"; command = "chanserv/levels"; gr
*
* Used for preventing users from joining channels.
*/
-module { name = "cs_akick" }
+module
+{
+ name = "cs_akick"
+
+ /*
+ * The maximum number of entries on a channel's autokick list.
+ */
+ autokickmax = 32
+
+ /*
+ * The default reason for an autokick if none is given.
+ */
+ autokickreason = "User has been banned from the channel"
+}
+
command { service = "ChanServ"; name = "AKICK"; command = "chanserv/akick"; group = "chanserv/management"; }
/*
@@ -952,13 +920,14 @@ command { service = "ChanServ"; name = "ENFORCE"; command = "chanserv/enforce";
*
* Used to configure entry messages sent to users when they join a channel.
*/
-module { name = "cs_entrymsg" }
-command { service = "ChanServ"; name = "ENTRYMSG"; command = "chanserv/entrymsg"; group = "chanserv/management"; }
-cs_entrymsg
+module
{
+ name = "cs_entrymsg"
+
/* The maximum number of entrymsgs allowed per channel. If not set, defaults to 5. */
maxentries = 5
}
+command { service = "ChanServ"; name = "ENTRYMSG"; command = "chanserv/entrymsg"; group = "chanserv/management"; }
/*
* cs_flags
@@ -1018,7 +987,16 @@ command { service = "ChanServ"; name = "KICK"; command = "chanserv/kick"; }
*
* Used for retrieving and searching the registered channel list.
*/
-module { name = "cs_list" }
+module
+{
+ name = "cs_list"
+
+ /*
+ * The maximum number of channels to be returned for a ChanServ LIST command.
+ */
+ listmax = 50
+}
+
command { service = "ChanServ"; name = "LIST"; command = "chanserv/list"; permission = "chanserv/list"; group = "chanserv/admin"; }
/*
@@ -1143,7 +1121,18 @@ command { service = "ChanServ"; name = "STATUS"; command = "chanserv/status"; }
*
* Used for suspending and unsuspending channels. Suspended channels can not be used but their settings are stored.
*/
-module { name = "cs_suspend" }
+module
+{
+ name = "cs_suspend"
+
+ /*
+ * The length of time before a suspended channel expires.
+ *
+ * This directive is optional.
+ * If not set, the default is never.
+ */
+ expire = 90d
+}
command { service = "ChanServ"; name = "SUSPEND"; command = "chanserv/suspend"; permission = "chanserv/suspend"; group = "chanserv/admin"; }
command { service = "ChanServ"; name = "UNSUSPEND"; command = "chanserv/unsuspend"; permission = "chanserv/suspend"; group = "chanserv/admin"; }
diff --git a/data/chanstats.example.conf b/data/chanstats.example.conf
index 0f131a85a..f686cd216 100644
--- a/data/chanstats.example.conf
+++ b/data/chanstats.example.conf
@@ -3,9 +3,10 @@
* Make sure BotServ, ChanServ and NickServ are running.
*/
-module { name = "m_chanstats" }
-chanstats
+module
{
+ name = "m_chanstats"
+
/*
* The name of this engine.
* This must match with the name of an SQL engine block.
diff --git a/data/example.conf b/data/example.conf
index 55390e391..82be8c9b5 100644
--- a/data/example.conf
+++ b/data/example.conf
@@ -21,6 +21,15 @@
* foo = bar
* }
*
+ * Note that nameless blocks are allowed and are often used with comments to allow
+ * easially commenting an entire block, for example:
+ * #foobar
+ * {
+ * moo = "cow"
+ * foo = bar
+ * }
+ * is an entirely commented block.
+ *
* Keys are case insensitive. Values depend on what key - generally, information is
* given in the key comment. The quoting of values (and most other syntax) is quite
* flexible, however, please do not forget to quote your strings:
@@ -40,11 +49,6 @@
*
* "86400", "86400s", "1440m", "24h", "1d"
*
- * CAUTION:
- * Please note that your services might _CRASH_ if you add more format-
- * strings (%s, %d, etc.) to custom messages than Anope needs. Use the
- * default messages to see how many format-strings are needed.
- *
* In the documentation for each directive, one of the following will be
* included to indicate whether an option is required:
*
@@ -106,19 +110,17 @@ define
* the output from it will be included into your configuration.
*/
-/*
-include
+#include
{
type = "file"
name = "some.conf"
}
-include
+#include
{
type = "executable"
name = "/usr/bin/wget -q -O - http://some.misconfigured.network.com/services.conf"
}
-*/
/*
* [REQUIRED] IRCd Config
@@ -234,7 +236,33 @@ serverinfo
* - ratbox
* - unreal
*/
-module { name = "inspircd12" }
+module
+{
+ name = "inspircd20"
+
+ /*
+ * Some protocol modules can enforce mode locks server-side. This reduces the spam caused by
+ * services immediately reversing mode changes for locked modes.
+ *
+ * If the protocol module you have loaded does not support this, this setting will have no effect.
+ */
+ use_server_side_mlock = yes
+
+ /*
+ * Some protocol modules can enforce topic locks server-side. This reduces the spam caused by
+ * services immediately reversing topic changes.
+ *
+ * If the protocol module you have loaded does not support this, this setting will have no effect.
+ */
+ use_server_side_topiclock = yes
+
+ /*
+ * Some IRCds allow "SASL" authentication to let users identify to Services
+ * during the IRCd user registration process. If set, Services will allow
+ * authenticating users through this mechanism.
+ */
+ sasl = yes
+}
/*
* [REQUIRED] Network Information
@@ -279,6 +307,34 @@ networkinfo
* Comment out or set to 0 to disable.
*/
modelistsize = 100
+
+ /*
+ * The characters allowed in hostnames. This is used for validating hostnames given
+ * to services, such as BotServ bot hostnames and user vhosts. Changing this is not
+ * recommended unless you know for sure your IRCd supports whatever characters you are
+ * wanting to use. Telling services to set a vHost containing characters your IRCd
+ * disallows could potentially break the IRCd and/or Services.
+ *
+ * It is recommended you DON'T change this.
+ */
+ vhost_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-"
+
+ /*
+ * If set to true, allows vHosts to not contain dots (.).
+ * Newer IRCds generally do not have a problem with this, but the same warning as
+ * vhost_chars applies.
+ *
+ * It is recommended you DON'T change this.
+ */
+ allow_undotted_vhosts = false
+
+ /*
+ * The characters that are not allowed to be at the very beginning or very ending
+ * of a vHost. The same warning as vhost_chars applies.
+ *
+ * It is recommended you DON'T change this.
+ */
+ disallow_start_or_end = ".-"
}
/*
@@ -328,19 +384,6 @@ options
#seed = 9866235
/*
- * Allows Services to continue file write operations (i.e. database saving)
- * even if the original file cannot be backed up. Enabling this option may
- * allow Services to continue operation under conditions where it might
- * otherwise fail, such as a nearly-full disk.
- *
- * NOTE: Enabling this option can cause irrecoverable data loss under some
- * conditions, so make CERTAIN you know what you're doing when you enable it!
- *
- * This directive is optional, and you are discouraged against enabling it.
- */
- #nobackupokay = yes
-
- /*
* If set, Services will perform more stringent checks on passwords. If this
* isn't set, Services will only disallow a password if it is the same as the
* entity (nickname name) with which it is associated. When set, however,
@@ -406,41 +449,15 @@ options
* will use doing this. Higher values will cause less accurate timing but
* less CPU usage.
*
- * This shouldn't be set any higher than 10 seconds, and 1 second is best
- * if your system is powerful enough (or your network small enough) to
- * handle it. 0 will cause the timeout list to be checked every time
- * through the main loop, which will probably slow down Services too much
- * to be useful on most networks.
- *
* Note that this value is not an absolute limit on the period between
* checks of the timeout list; the previous may be as great as readtimeout
* (above) during periods of inactivity.
*
- * If this directive is not given, it will default to 0. See the 2nd paragraph
- * above for performance impacts if you do this.
+ * If this directive is not given, it will default to 0.
*/
timeoutcheck = 3s
/*
- * Sets the number of days backups of databases are kept. If you don't give it,
- * or if you set it to 0, Services won't backup the databases.
- *
- * NOTE: Services must run 24 hours a day for this feature to work.
- *
- * This directive is optional, but recommended.
- */
- keepbackups = 3
-
- /*
- * If set, Services will require a reason when a FORBID is added, else the
- * reason is optional. This directive also applies to SUSPENDed channels as
- * well.
- *
- * This directive is optional.
- */
- forceforbidreason = yes
-
- /*
* If set, this will allow users to let Services send PRIVMSGs to them
* instead of NOTICEs. Also see the defmsg option of nickserv:defaults,
* which also toggles the default communication (PRIVMSG or NOTICE) to
@@ -471,35 +488,6 @@ options
#hidestatso = yes
/*
- * Prevents users from registering their nick if they are not connected
- * for at least the given number of seconds.
- *
- * This directive is optional.
- */
- #nickregdelay = 30
-
- /*
- * If set, forbids the registration of nicks that contain an existing
- * nick with Services access. For example, if Tester is a Services Oper,
- * you can't register NewTester or Tester123 unless you are an IRC
- * Operator.
- *
- * NOTE: If you enable this, you will have to be logged in as an IRC
- * operator in order to register a Services Root nick when setting up
- * Anope for the first time.
- *
- * This directive is optional.
- */
- #restrictopernicks = yes
-
- /*
- * The number of LOGON/OPER news items to display when a user logs on.
- *
- * This directive is optional, if no set it will default to 3.
- */
- #newscount = 3
-
- /*
* A space-separated list of ulined servers on your network, it is assumed that
* the servers in this list are allowed to set channel modes and Services will
* not attempt to reverse their mode changes.
@@ -511,16 +499,9 @@ options
#ulineservers = "stats.your.network"
/*
- * Modes to set on service bots when they join channels, comment this out for no modes
- *
- * This directive is optional.
- */
- botmodes = "ao"
-
- /*
- * How long to wait between connection retries, in seconds.
+ * How long to wait between connection retries with the uplink(s).
*/
- retrywait = 60
+ retrywait = 60s
/*
* If set, Services will hide commands that users don't have the privileges to execute
@@ -539,6 +520,39 @@ options
* Note for this to work the regex module providing the regex engine must be loaded.
*/
regexengine = "regex/pcre"
+
+ /*
+ * A list of languages to load on startup that will be available in /nickserv set language.
+ * Useful if you translate Anope to your language. (Explained further in docs/LANGUAGE).
+ * Note that english should not be listed here because it is the base language.
+ *
+ * Removing .UTF-8 will instead use the default encoding for the language, eg. iso-8859-1 for western European languages.
+ */
+ languages = "ca_ES.UTF-8 de_DE.UTF-8 el_GR.UTF-8 es_ES.UTF-8 fr_FR.UTF-8 hu_HU.UTF-8 it_IT.UTF-8 nl_NL.UTF-8 pl_PL.UTF-8 pt_PT.UTF-8 ru_RU.UTF-8 tr_TR.UTF-8"
+
+ /*
+ * Default language that non- and newly-registered nicks will receive messages in.
+ * Leave empty to default to English.
+ */
+ #defaultlanguage = "es_ES.UTF-8"
+
+ /*
+ * The username, and possibly hostname, used for fake users created when Services needs to
+ * hold a nickname.
+ */
+ enforceruser = "enforcer"
+ enforcerhost = "localhost.net"
+
+ /*
+ * The length of time Services hold nicknames.
+ */
+ releasetimeout = 1m
+
+ /*
+ * When a user's nick is forcibly changed to enforce a "nick kill", their new nick will start
+ * with this value. The rest will be made up of 6 or 7 digits.
+ */
+ guestnickprefix = "Guest"
}
/*
@@ -865,7 +879,7 @@ opertype
* As with all permissions, make sure to only give trustworthy people access to Services.
*/
-oper
+#oper
{
/* The nickname of this services oper */
#name = "nick1"
@@ -893,19 +907,17 @@ oper
#vhost = "oper.mynet"
}
-/*
-oper
+#oper
{
name = "nick2"
type = "Services Administrator"
}
-oper
+#oper
{
name = "nick3"
type = "Helper"
}
-*/
/*
* [OPTIONAL] Mail Config
@@ -1048,9 +1060,10 @@ mail
* You should only use this to upgrade old databases to a newer database format by loading
* other database modules in addition to this one, which will be used when saving databases.
*/
-#module { name = "db_old" }
-db_old
+#module
{
+ name = "db_old"
+
/*
* This is the encryption type used by the databases. This must be set correctly or
* your passwords will not work. Valid options are: md5, oldmd5, sha1, and plain.
@@ -1067,28 +1080,45 @@ db_old
* Then unload this and restart Anope, loading from the new database.
*/
#module { name = "db_plain" }
-db_plain
-{
- /*
- * The database name db_plain should use
- */
- database = "anope.db"
-}
/*
* db_flatfile
*
* This is the default flatfile database format.
*/
-module { name = "db_flatfile" }
-db_flatfile
+module
{
+ name = "db_flatfile"
+
/*
* The database name db_flatfile should use
*/
database = "anope.db"
/*
+ * Sets the number of days backups of databases are kept. If you don't give it,
+ * or if you set it to 0, Services won't backup the databases.
+ *
+ * NOTE: Services must run 24 hours a day for this feature to work.
+ *
+ * This directive is optional, but recommended.
+ */
+ keepbackups = 3
+
+ /*
+ * Allows Services to continue file write operations (i.e. database saving)
+ * even if the original file cannot be backed up. Enabling this option may
+ * allow Services to continue operation under conditions where it might
+ * otherwise fail, such as a nearly-full disk.
+ *
+ * NOTE: Enabling this option can cause irrecoverable data loss under some
+ * conditions, so make CERTAIN you know what you're doing when you enable it!
+ *
+ * This directive is optional, and you are discouraged against enabling it.
+ */
+ #nobackupokay = yes
+
+ /*
* If enabled, services will fork a child process to save databases.
*
* This is only useful with very large databases, with hundreds
@@ -1099,29 +1129,24 @@ db_flatfile
}
/*
- * db_sql
+ * db_sql and db_sql_live
*
- * This module allows saving and loading databases using one of the SQL engines.
+ * db_sql module allows saving and loading databases using one of the SQL engines.
* This module loads the databases once on startup, then incrementally updates
* objects in the database as they are changed within Anope in real time. Changes
* to the SQL tables not done by Anope will have no effect and will be overwritten.
*
- */
-#module { name = "db_sql" }
-
-/*
- * db_sql_live
- *
- * This module allows saving and loading databases using one of the SQL engines.
+ * db_sql_live module allows saving and loading databases using one of the SQL engines.
* This module reads and writes to SQL in real time. Changes to the SQL tables
* will be immediately reflected into Anope. This module should not be loaded
* in conjunction with db_sql.
+ *
*/
-#module { name = "db_sql_live" }
-
-/* Configuration block for both db_sql and db_sql_live */
-db_sql
+#module
{
+ name = "db_sql"
+ #name = "db_sql_live
+
/*
* The SQL service db_sql(_live) should use, these are configured in modules.conf.
* For MySQL, this should probably be mysql/main.
@@ -1210,7 +1235,7 @@ include
* Requires a MySQL Database.
*/
#include
-#{
-# type = "file"
-# name = "chanstats.example.conf"
-#}
+{
+ type = "file"
+ name = "chanstats.example.conf"
+}
diff --git a/data/global.example.conf b/data/global.example.conf
index 2ae7cdc99..b013537d6 100644
--- a/data/global.example.conf
+++ b/data/global.example.conf
@@ -56,38 +56,30 @@ service
*
* Provides essential functionality for Global.
*/
-module { name = "global" }
-
-/*
- * Configuration for Global provided by gl_main.
- */
-global
+module
{
+ name = "global"
+
/*
* The name of the client that should be Global.
*/
- name = "Global"
+ client = "Global"
/*
- * If set, Services will send global messages on starting up and shutting
- * down/restarting.
+ * This is the global message that will be sent when Services are being
+ * shutdown/restarted.
*
* This directive is optional.
*/
- #globaloncycle = yes
-
- /*
- * This is the global message that will be sent when Services are being
- * shutdown/restarted. This directive is only required if you enable
- * globaloncycle above.
- */
- globaloncycledown = "Services are restarting, they will be back shortly - please be good while we're gone"
+ #globaloncycledown = "Services are restarting, they will be back shortly - please be good while we're gone"
/*
* This is the global message that will be sent when Services (re)join the
- * network. This directive is only required if you enable globaloncycle above.
+ * network.
+ *
+ * This directive is optional.
*/
- globaloncycleup = "Services are now back online - have a nice day"
+ #globaloncycleup = "Services are now back online - have a nice day"
/*
* If set, Services will hide the IRC Operator's nick in a global
diff --git a/data/hostserv.example.conf b/data/hostserv.example.conf
index 1d406ef5b..10063ae7d 100644
--- a/data/hostserv.example.conf
+++ b/data/hostserv.example.conf
@@ -56,45 +56,14 @@ service
*
* Provides essential functionality for HostServ.
*/
-module { name = "hostserv" }
-
-/*
- * Configuration for HostServ provided by hs_main.
- */
-hostserv
+module
{
- /*
- * The name of the client that should be HostServ.
- */
- name = "HostServ"
+ name = "hostserv"
/*
- * The characters allowed in a vHost. Changing this is not recommended unless
- * you know for sure your IRCd supports whatever characters you are wanting to use.
- * Telling services to set a vHost containing characters your IRCd disallows could
- * potentially break the IRCd and/or Services. Note these are 1 byte characters, so
- * UTF-8 characters will not work.
- *
- * It is recommended you DON'T change this.
- */
- vhost_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-"
-
- /*
- * If set to true, allows vHosts to not contain dots (.).
- * Newer IRCds generally do not have a problem with this, but the same warning as
- * vhost_chars applies.
- *
- * It is recommended you DON'T change this.
- */
- allow_undotted_vhosts = false
-
- /*
- * The characters that are not allowed to be at the very beginning or very ending
- * of a vHost. The same warning as vhost_chars applies.
- *
- * It is recommended you DON'T change this.
+ * The name of the client that should be HostServ.
*/
- disallow_start_or_end = ".-"
+ client = "HostServ"
}
/*
@@ -169,13 +138,10 @@ command { service = "HostServ"; name = "ON"; command = "hostserv/on"; }
*
* Used to manage vHosts requested by users.
*/
-module { name = "hs_request" }
-command { service = "HostServ"; name = "REQUEST"; command = "hostserv/request"; }
-command { service = "HostServ"; name = "ACTIVATE"; command = "hostserv/activate"; permission = "hostserv/set"; }
-command { service = "HostServ"; name = "REJECT"; command = "hostserv/reject"; permission = "hostserv/set"; }
-command { service = "HostServ"; name = "WAITING"; command = "hostserv/waiting"; permission = "hostserv/set"; }
-hs_request
+module
{
+ name = "hs_request"
+
/*
* If set, Services will send a memo to the user requesting a vHost when it's been
* approved or rejected.
@@ -187,6 +153,10 @@ hs_request
*/
#memooper = yes
}
+command { service = "HostServ"; name = "REQUEST"; command = "hostserv/request"; }
+command { service = "HostServ"; name = "ACTIVATE"; command = "hostserv/activate"; permission = "hostserv/set"; }
+command { service = "HostServ"; name = "REJECT"; command = "hostserv/reject"; permission = "hostserv/set"; }
+command { service = "HostServ"; name = "WAITING"; command = "hostserv/waiting"; permission = "hostserv/set"; }
/*
* hs_set
diff --git a/data/memoserv.example.conf b/data/memoserv.example.conf
index 40678bf53..6e4fd1e8d 100644
--- a/data/memoserv.example.conf
+++ b/data/memoserv.example.conf
@@ -56,18 +56,14 @@ service
*
* Provides essential functionality for MemoServ.
*/
-module { name = "memoserv" }
-
-/*
- * Configuration for MemoServ provided by ms_main.
- */
-memoserv
+module
{
+ name = "memoserv"
/*
* The name of the client that should be MemoServ. Clients are configured
* with the service blocks.
*/
- name = "MemoServ"
+ client = "MemoServ"
/*
* The maximum number of memos a user is allowed to keep by default. Normal users may set the
@@ -88,16 +84,6 @@ memoserv
* This directive is optional, but recommended.
*/
senddelay = 3s
-
- /*
- * Allow the use of memo receipts for the following groups:
- *
- * 1 - Opers Only
- * 2 - Everybody
- *
- * This directive is optional.
- */
- #memoreceipt = 1
}
/*
@@ -193,7 +179,17 @@ command { service = "MemoServ"; name = "READ"; command = "memoserv/read"; }
*
* Requires configuring memoserv:memoreceipt.
*/
-#module { name = "ms_rsend" }
+#module
+{
+ name = "ms_rsend"
+
+ /*
+ * Only allow Services Operators to use ms_rsend.
+ *
+ * This directive is optional.
+ */
+ operonly = false
+}
#command { service = "MemoServ"; name = "RSEND"; command = "memoserv/rsend"; }
/*
diff --git a/data/modules.example.conf b/data/modules.example.conf
index ef862221f..f1a5b8d7f 100644
--- a/data/modules.example.conf
+++ b/data/modules.example.conf
@@ -21,9 +21,10 @@ module { name = "help" }
* Adds support for the DNS protocol. By itself this module does nothing useful,
* but other modules such as m_dnsbl and os_dns require this.
*/
-#module { name = "m_dns" }
-dns
+#module
{
+ name = "m_dns"
+
/*
* The nameserver to use for resolving hostnames, must be an IP or a resolver configuration file.
* The below should work fine on all unix like systems. Windows users will have to find their nameservers
@@ -74,9 +75,10 @@ dns
* is found on the blacklist they will be immediately banned. This is a crucial module
* to prevent bot attacks.
*/
-#module { name = "m_dnsbl" }
-m_dnsbl
+#module
{
+ name = "m_dnsbl"
+
/*
* If set, Services will check clients against the DNSBLs when services connect to its uplink.
* This is not recommended, and on large networks will open a very large amount of DNS queries.
@@ -136,9 +138,10 @@ blacklist
*
* Gives users who are op in the specified help channel usermode +h (helpop).
*/
-#module { name = "m_helpchan" }
-m_helpchan
+#module
{
+ name = "m_helpchan"
+
helpchannel = "#help"
}
@@ -324,9 +327,10 @@ mysql
* back to services. If services are able to connect through the proxy to itself
* then it knows it is an insecure proxy, and will ban it.
*/
-#module { name = "m_proxyscan" }
-m_proxyscan
+#module
{
+ name = "m_proxyscan"
+
/*
* The target IP services tells the proxy to connect back to. This must be a publicly
* avaiable IP that remote proxies can connect to.
@@ -402,9 +406,10 @@ proxyscan
* This module allows authenticating users against an external SQL database using a custom
* query.
*/
-#module { name = "m_sql_authentication" }
-m_sql_authentication
+#module
{
+ name = "m_sql_authentication"
+
/* SQL engine to use. Should be configured elsewhere with m_mysql, m_sqlite, etc. */
engine = "mysql/main"
@@ -446,9 +451,10 @@ m_sql_authentication
* This module allows granting users services operator privileges and possibly IRC Operator
* privileges based on an external SQL database using a custom query.
*/
-#module { name = "m_sql_oper" }
-m_sql_oper
+module
{
+ name = "m_sql_oper"
+
/* SQL engine to use. Should be configured elsewhere with m_mysql, m_sqlite, etc. */
engine = "mysql/main"
@@ -509,37 +515,38 @@ module { name = "m_regex_pcre" }
*/
module { name = "m_rewrite" }
#command
-#{
-# service = "ChanServ"; name = "CLEAR"; command = "rewrite"
-#
-# /* Enable m_rewrite. */
-# rewrite = true
-#
-# /* Source message to match. A $ can be used to match anything. */
-# rewrite_source = "CLEAR $ USERS"
-#
-# /*
-# * Message to rewrite the source message to. A $ followed by a number, eg $0, gets
-# * replaced by the number-th word from the source_message, starting from 0.
-# */
-# rewrite_target = "KICK $1 *"
-#
-# /*
-# * The command description. This only shows up in HELP's output.
-# * Comment this option to prevent the command from showing in the
-# * HELP command.
-# */
-# rewrite_description = "Clears all users from a channel"
-#}
+{
+ service = "ChanServ"; name = "CLEAR"; command = "rewrite"
+
+ /* Enable m_rewrite. */
+ rewrite = true
+
+ /* Source message to match. A $ can be used to match anything. */
+ rewrite_source = "CLEAR $ USERS"
+
+ /*
+ * Message to rewrite the source message to. A $ followed by a number, eg $0, gets
+ * replaced by the number-th word from the source_message, starting from 0.
+ */
+ rewrite_target = "KICK $1 *"
+
+ /*
+ * The command description. This only shows up in HELP's output.
+ * Comment this option to prevent the command from showing in the
+ * HELP command.
+ */
+ rewrite_description = "Clears all users from a channel"
+}
/*
* m_ssl
*
* This module uses SSL to connect to the uplink server(s).
*/
-#module { name = "m_ssl" }
-ssl
+module
{
+ name = "m_ssl"
+
/*
* An optional certificate and key for m_ssl to give to the uplink.
*
@@ -582,9 +589,10 @@ m_xmlrpc
*
* This module requires m_httpd.
*/
-#module { name = "webcpanel" }
-webcpanel
+#module
{
+ name = "webcpanel"
+
/* Web server to use. */
server = "httpd/main";
diff --git a/data/nickserv.example.conf b/data/nickserv.example.conf
index 3c2034ddb..67358b9d6 100644
--- a/data/nickserv.example.conf
+++ b/data/nickserv.example.conf
@@ -56,17 +56,14 @@ service
*
* Provides essential functionality for NickServ.
*/
-module { name = "nickserv" }
-
-/*
- * Configuration for NickServ provided by ns_main.
- */
-nickserv
+module
{
+ name = "nickserv"
+
/*
* The name of the client that should be NickServ.
*/
- name = "NickServ"
+ client = "NickServ"
/*
* Force users to give an e-mail address when they register a nick.
@@ -77,18 +74,11 @@ nickserv
/*
* Require users who change their email address to confirm they
- * own it.
+ * own their new email.
*/
confirmemailchanges = no
/*
- * Registration confirmation setting. Set to "none" for no registration confirmation,
- * "mail" for email confirmation, and "admin" to have services operators manually confirm
- * every registration. Set to "disable" to completely disable all registrations.
- */
- registration = "none"
-
- /*
* A message sent to users on connect if they use an unregistered nick.
*
* This directive is optional.
@@ -122,34 +112,12 @@ nickserv
defaults = "secure private hide_email hide_mask memo_signon memo_receive autoop"
/*
- * A list of languages to load on startup that will be available in /nickserv set language.
- * Useful if you translate Anope to your language. (Explained further in docs/LANGUAGE).
- * Note that english should not be listed here because it is the base language.
- *
- * Removing .UTF-8 will instead use the default encoding for the language, eg. iso-8859-1 for western European languages.
- */
- languages = "ca_ES.UTF-8 de_DE.UTF-8 el_GR.UTF-8 es_ES.UTF-8 fr_FR.UTF-8 hu_HU.UTF-8 it_IT.UTF-8 nl_NL.UTF-8 pl_PL.UTF-8 pt_PT.UTF-8 ru_RU.UTF-8 tr_TR.UTF-8"
-
- /*
- * Default language that non- and newly-registered nicks will receive messages in.
- * Leave empty to default to English.
- */
- #defaultlanguage = "es_ES.UTF-8"
-
- /*
* The minimum length of time between consecutive uses of NickServ's REGISTER command. This
* directive is optional, but recommended. If not set, this restriction will be disabled.
*/
regdelay = 30s
/*
- * The minimum length of time between consecutive uses of NickServ's RESEND command.
- *
- * This directive is optional, but recommended. If not set, this restriction will be disabled.
- */
- resenddelay = 90s
-
- /*
* The length of time before a nick's registration expires.
*
* This directive is optional, but recommended. If not set, the default is 21 days.
@@ -157,13 +125,6 @@ nickserv
expire = 21d
/*
- * The length of time before a suspended nick becomes unsuspended.
- *
- * This directive is optional. If not set, the default is never.
- */
- #suspendexpire = 90d
-
- /*
* The length of time a user using an unconfirmed account has
* before the account will be released for general use again.
*
@@ -172,57 +133,6 @@ nickserv
#unconfirmedexpire = 1d
/*
- * The maximum number of nicks allowed in a group.
- *
- * This directive is optional, but recommended. If not set or set to 0, no limits will be applied.
- */
- maxaliases = 16
-
- /*
- * The maximum number of entries allowed on a nickname's access list.
- */
- accessmax = 32
-
- /*
- * The username (and possibly hostname) used for the fake user created when NickServ collides
- * a user.
- */
- enforceruser = "enforcer"
- enforcerhost = "localhost.net"
-
- /*
- * The delay before a NickServ collided nick is released.
- */
- releasetimeout = 1m
-
- /*
- * Allow the use of the IMMED option in the NickServ SET KILL command.
- *
- * This directive is optional.
- */
- #allowkillimmed = yes
-
- /*
- * If set, the NickServ GROUP command won't allow any group change. This is recommended for
- * better performance and to protect against nick stealing, however users will have less
- * flexibility.
- *
- * This directive is optional, but recommended.
- */
- #nogroupchange = yes
-
- /*
- * The maximum number of nicks to be returned for a NickServ LIST command.
- */
- listmax = 50
-
- /*
- * When a user's nick is forcibly changed to enforce a "nick kill", their new nick will start
- * with this value. The rest will be made up of 6 or 7 digits.
- */
- guestnickprefix = "Guest"
-
- /*
* Prevents the use of the ACCESS (excluding the LIST subcommand), DROP, FORBID, SUSPEND,
* GETPASS and SET PASSWORD commands by services operators on other services operators.
*
@@ -231,14 +141,6 @@ nickserv
secureadmins = yes
/*
- * If set, any user wanting to use the privileges of Services Root, Services Admin, or Services
- * Operator must have been logged as an IRC Operator with the /OPER command.
- *
- * This directive is optional, but recommended.
- */
- strictprivileges = yes
-
- /*
* If set, Services will set the channel modes a user has access to upon identifying, assuming
* they are not already set.
*
@@ -247,17 +149,17 @@ nickserv
modeonid = yes
/*
- * If set, Services will add the usermask of registering users to the access list of their
- * newly created account. If not set, users will always have to identify to NickServ before
- * being recognized, unless they manually add an address to the access list of their account.
+ * If set, Services will set these user modes on any user who identifies.
+ *
* This directive is optional.
*/
- addaccessonreg = yes
+ #modesonid = "+R"
/*
- * The maximum number of channels a user can have on NickServ's AJOIN command.
+ * If set, Services will not show netsplits in the last quit message field
+ * of NickServ's INFO command.
*/
- ajoinmax = 10
+ hidenetsplitquit = no
/*
* If set, is the length of time NickServ's killquick and kill options wait before
@@ -267,32 +169,18 @@ nickserv
kill = 60s
/*
- * If set, Services will set these user modes on any user who identifies.
+ * If set, forbids the registration of nicks that contain an existing
+ * nick with Services access. For example, if Tester is a Services Oper,
+ * you can't register NewTester or Tester123 unless you are an IRC
+ * Operator.
*
- * This directive is optional.
- */
- #modesonid = "+R"
-
- /*
- * If set, Services will svsnick and svsjoin users who use the recover
- * command on an identified user to the nick and channels of the recovered user.
+ * NOTE: If you enable this, you will have to be logged in as an IRC
+ * operator in order to register a Services Root nick when setting up
+ * Anope for the first time.
*
- * This directive is opional.
- */
- restoreonrecover = yes
-
- /*
- * Some IRCds allow "SASL" authentication to let users identify to Services
- * during the IRCd user registration process. If set, Services will allow
- * authenticating users through this mechanism.
- */
- sasl = yes
-
- /*
- * If set, Services will not show netsplits in the last quit message field
- * of NickServ's INFO command.
+ * This directive is optional.
*/
- hidenetsplitquit = no
+ #restrictopernicks = yes
}
/*
@@ -327,7 +215,24 @@ command { service = "NickServ"; name = "HELP"; command = "generic/help"; }
*
* Used for configuring what hosts have access to your account.
*/
-module { name = "ns_access" }
+module
+{
+ name = "ns_access"
+
+ /*
+ * The maximum number of entries allowed on a nickname's access list.
+ */
+ accessmax = 32
+
+ /*
+ * If set, Services will add the usermask of registering users to the access list of their
+ * newly created account. If not set, users will always have to identify to NickServ before
+ * being recognized, unless they manually add an address to the access list of their account.
+ * This directive is optional.
+ */
+ addaccessonreg = yes
+}
+
command { service = "NickServ"; name = "ACCESS"; command = "nickserv/access"; }
/*
@@ -337,7 +242,15 @@ command { service = "NickServ"; name = "ACCESS"; command = "nickserv/access"; }
*
* Used for configuring channels to join once you identify.
*/
-module { name = "ns_ajoin" }
+module
+{
+ name = "ns_ajoin"
+
+ /*
+ * The maximum number of channels a user can have on NickServ's AJOIN command.
+ */
+ ajoinmax = 10
+}
command { service = "NickServ"; name = "AJOIN"; command = "nickserv/ajoin"; }
/*
@@ -399,7 +312,26 @@ command { service = "NickServ"; name = "GETEMAIL"; command = "nickserv/getemail"
*
* Used for controlling nick groups.
*/
-module { name = "ns_group" }
+module
+{
+ name = "ns_group"
+
+ /*
+ * The maximum number of nicks allowed in a group.
+ *
+ * This directive is optional, but recommended. If not set or set to 0, no limits will be applied.
+ */
+ maxaliases = 16
+
+ /*
+ * If set, the NickServ GROUP command won't allow any group change. This is recommended for
+ * better performance and to protect against nick stealing, however users will have less
+ * flexibility.
+ *
+ * This directive is optional, but recommended.
+ */
+ #nogroupchange = yes
+}
command { service = "NickServ"; name = "GLIST"; command = "nickserv/glist"; }
command { service = "NickServ"; name = "GROUP"; command = "nickserv/group"; }
command { service = "NickServ"; name = "UNGROUP"; command = "nickserv/ungroup"; }
@@ -432,7 +364,15 @@ command { service = "NickServ"; name = "INFO"; command = "nickserv/info"; }
*
* Used for retrieving and searching the registered account list.
*/
-module { name = "ns_list" }
+module
+{
+ name = "ns_list"
+
+ /*
+ * The maximum number of nicks to be returned for a NickServ LIST command.
+ */
+ listmax = 50
+}
command { service = "NickServ"; name = "LIST"; command = "nickserv/list"; group = "nickserv/admin"; }
/*
@@ -452,9 +392,20 @@ command { service = "NickServ"; name = "LOGOUT"; command = "nickserv/logout"; }
*
* Used for recovering your nick from services or another user.
*/
-module { name = "ns_recover" }
+module
+{
+ name = "ns_recover"
+
+ /*
+ * If set, Services will svsnick and svsjoin users who use the recover
+ * command on an identified user to the nick and channels of the recovered user.
+ *
+ * This directive is opional.
+ */
+ restoreonrecover = yes
+}
command { service = "NickServ"; name = "RECOVER"; command = "nickserv/recover"; }
-# Uncomment below to emulate 1.8's behavior of ghost, recover, and release.
+# Uncomment below to emulate 1.8's behavior of ghost and release.
#command { service = "NickServ"; name = "GHOST"; command = "nickserv/recover"; }
#command { service = "NickServ"; name = "RELEASE"; command = "nickserv/recover"; }
@@ -465,7 +416,33 @@ command { service = "NickServ"; name = "RECOVER"; command = "nickserv/recover";
*
* Used for registering accounts.
*/
-module { name = "ns_register" }
+module
+{
+ name = "ns_register"
+
+ /*
+ * Registration confirmation setting. Set to "none" for no registration confirmation,
+ * "mail" for email confirmation, and "admin" to have services operators manually confirm
+ * every registration. Set to "disable" to completely disable all registrations.
+ */
+ registration = "none"
+
+ /*
+ * The minimum length of time between consecutive uses of NickServ's RESEND command.
+ *
+ * This directive is optional, but recommended. If not set, this restriction will be disabled.
+ */
+ resenddelay = 90s
+
+ /*
+ * Prevents users from registering their nick if they are not connected
+ * for at least the given number of seconds.
+ *
+ * This directive is optional.
+ */
+ #nickregdelay = 30
+}
+
command { service = "NickServ"; name = "CONFIRM"; command = "nickserv/confirm"; }
command { service = "NickServ"; name = "REGISTER"; command = "nickserv/register"; }
command { service = "NickServ"; name = "RESEND"; command = "nickserv/resend"; }
@@ -500,7 +477,18 @@ command { service = "NickServ"; name = "RESETPASS"; command = "nickserv/resetpas
*
* This is a dummy command to provide a help wrapper for the various SET and SASET commands.
*/
-module { name = "ns_set" }
+module
+{
+ name = "ns_set"
+
+ /*
+ * Allow the use of the IMMED option in the NickServ SET KILL command.
+ *
+ * This directive is optional.
+ */
+ #allowkillimmed = yes
+}
+
command { service = "NickServ"; name = "SET"; command = "nickserv/set"; }
command { service = "NickServ"; name = "SASET"; command = "nickserv/saset"; permission = "nickserv/saset/"; group = "nickserv/admin"; }
@@ -575,7 +563,18 @@ command { service = "NickServ"; name = "STATUS"; command = "nickserv/status"; }
*
* Used to suspend and unsuspend nicknames. Suspended nicknames can not be used but their settings are preserved.
*/
-module { name = "ns_suspend" }
+module
+{
+ name = "ns_suspend"
+
+ /*
+ * The length of time before a suspended nick becomes unsuspended.
+ *
+ * This directive is optional. If not set, the default is never.
+ */
+ #suspendexpire = 90d
+}
+
command { service = "NickServ"; name = "SUSPEND"; command = "nickserv/suspend"; permission = "nickserv/suspend"; group = "nickserv/admin"; }
command { service = "NickServ"; name = "UNSUSPEND"; command = "nickserv/unsuspend"; permission = "nickserv/suspend"; group = "nickserv/admin"; }
@@ -600,9 +599,10 @@ command { service = "NickServ"; name = "UPDATE"; command = "nickserv/update"; }
* Limits how many times the same email address may be used in Anope
* to register accounts.
*/
-module { name = "ns_maxemail" }
-ns_maxemail
+module
{
+ name = "ns_maxemail"
+
/*
* The limit to how many registered nicks can use the same e-mail address. If set to 0 or left
* commented, there will be no limit enforced when registering new accounts or using
diff --git a/data/operserv.example.conf b/data/operserv.example.conf
index fa17a1df9..687247f0a 100644
--- a/data/operserv.example.conf
+++ b/data/operserv.example.conf
@@ -56,25 +56,14 @@ service
*
* Provides essential functionality for OperServ.
*/
-module { name = "operserv" }
-
-/*
- * Configuration for OperServ provided by os_main.
- */
-operserv
+module
{
- /*
- * The name of the client that should be OperServ.
- */
- name = "OperServ"
+ name = "operserv"
/*
- * If set, Services Admins will be able to use SUPERADMIN [ON|OFF] which will temporarily grant
- * them extra privileges such as being a founder on ALL channels.
- *
- * This directive is optional.
+ * The name of the client that should be OperServ.
*/
- #superadmin = yes
+ client = "OperServ"
/*
* These define the default expiration times for, respectively, AKILLs, CHANKILLs, SNLINEs,
@@ -98,9 +87,9 @@ operserv
* If set, this option will make Services send an (SVS)KILL command immediately after SNLINE ADD.
* This eliminates the need for killing the user after the SNLINE has been added.
*
- *This directive is optional.
+ * This directive is optional.
*/
- #killonsnline = yes
+ killonsnline = yes
/*
* If set, this option will make Services send an (SVS)KILL command immediately after SQLINE ADD.
@@ -108,87 +97,7 @@ operserv
*
* This directive is optional.
*/
- #killonsqline = yes
-
- /*
- * Enables session limiting. Session limiting prevents users from connecting more than a certain
- * number of times from the same host at the same time - thus preventing most types of cloning.
- * Once a host reaches it's session limit, all clients attempting to connect from that host will
- * be killed. Exceptions to the default session limit can be defined via the exception list. It
- * should be noted that session limiting, along with a large exception list, can degrade Services'
- * performance.
- *
- * See the online help for more information about session limiting.
- *
- * This directive is optional.
- */
- limitsessions = yes
-
- /*
- * Default session limit per host. Once a host reaches it's session limit, all clients attempting
- * to connect from that host will be killed. A value of zero means an unlimited session limit.
- *
- * This directive is optional.
- * If not given and session limiting is enabled, it will default to no limit.
- */
- defaultsessionlimit = 3
-
- /*
- * The maximum session limit that may be set for a host in an exception.
- *
- * This directive is only required if session limiting is enabled.
- */
- maxsessionlimit = 100
-
- /*
- * Sets the default expiry time for session exceptions.
- *
- * This directive is only required if session limiting is enabled.
- */
- exceptionexpiry = 1d
-
- /*
- * The message that will be NOTICE'd to a user just before they are removed from the network because
- * their host's session limit has been exceeded. It may be used to give a slightly more descriptive
- * reason for the impending kill as opposed to simply "Session limit exceeded".
- *
- * This directive is optional, if not set, nothing will be sent.
- */
- sessionlimitexceeded = "The session limit for your IP %s has been exceeded."
-
- /*
- * Same as above, but should be used to provide a website address where users can find out more
- * about session limits and how to go about applying for an exception.
- *
- * Note: This directive has been intentionally commented out in an effort to remind you to change
- * the URL it contains. It is recommended that you supply an address/URL where people can get help
- * regarding session limits.
- *
- * This directive is optional, if not set, nothing will be sent.
- */
- #sessionlimitdetailsloc = "Please visit http://your.website.url/ for more information about session limits."
-
- /*
- * If set and is not 0, this directive tells Services to add an AKILL the number of subsequent kills
- * for the same host exceeds this value, preventing the network from experiencing KILL floods.
- *
- * This directive is optional.
- */
- maxsessionkill = 15
-
- /*
- * Sets the expiry time for AKILLs set for hosts exceeding the maxsessionkill directive limit.
- *
- * This directive is optional, if not set, defaults to 30 minutes.
- */
- sessionautokillexpiry = 30m
-
- /*
- * Sets the CIDR value used to determine which IP addresses represent the same person.
- * By default this would limit 3 connections per IPv4 IP and 3 connections per IPv6 IP.
- */
- session_ipv4_cidr = 32
- session_ipv6_cidr = 128
+ killonsqline = yes
/*
* Adds the nickname of the IRC Operator issuing an AKILL to the kill reason.
@@ -204,8 +113,7 @@ operserv
akillids = yes
/*
- * If set, only IRC Operators will be permitted to use OperServ, regardless of module-based command
- * access restrictions.
+ * If set, only IRC Operators will be permitted to use OperServ, regardless of command access restrictions.
*
* This directive is optional, but recommended.
*/
@@ -254,10 +162,10 @@ command { service = "OperServ"; name = "CHANKILL"; command = "operserv/chankill"
* Allows you to set services in defcon mode, which can be used to restrict services access
* during bot attacks.
*/
-#module { name = "os_defcon" }
-#command { service = "OperServ"; name = "DEFCON"; command = "operserv/defcon"; }
-defcon
+#module
{
+ name = "os_defcon"
+
/*
* Default DefCon level (1-5) to use when starting Services up. Level 5 constitutes normal operation
* while level 1 constitutes the most restrictive operation. If this setting is left out or set to
@@ -352,6 +260,7 @@ defcon
*/
#akillreason = "This network is currently not accepting connections, please try again later."
}
+#command { service = "OperServ"; name = "DEFCON"; command = "operserv/defcon"; }
/*
* os_dns
@@ -384,10 +293,10 @@ defcon
*
* Finally set a NS record for irc.example.com. to BIND or services.
*/
-#module { name = "os_dns" }
-#command { service = "OperServ"; name = "DNS"; command = "operserv/dns"; permission = "operserv/dns"; }
-os_dns
+module
{
+ name = "os_dns"
+
/* TTL for records. This should be very low if your records change often. */
ttl = 1m
@@ -412,6 +321,7 @@ os_dns
*/
readd_connected_servers = no
}
+#command { service = "OperServ"; name = "DNS"; command = "operserv/dns"; permission = "operserv/dns"; }
/*
* os_config
@@ -502,15 +412,16 @@ command { service = "OperServ"; name = "LOGOUT"; command = "operserv/logout"; }
*
* Used to search services log files.
*/
-module { name = "os_logsearch" }
-command { service = "OperServ"; name = "LOGSEARCH"; command = "operserv/logsearch"; permission = "operserv/logsearch"; }
-logsearch
+module
{
+ name = "os_logsearch"
+
/* The log file name to search. There should be a log{} block configured to log
* to a file of this name.
*/
- name = "services.log"
+ logname = "services.log"
}
+command { service = "OperServ"; name = "LOGSEARCH"; command = "operserv/logsearch"; permission = "operserv/logsearch"; }
/*
* os_mode
@@ -553,7 +464,18 @@ command { service = "OperServ"; name = "MODUNLOAD"; command = "operserv/modunloa
*
* Used to configure news notices shown to users when they connect, and opers when they oper.
*/
-module { name = "os_news" }
+module
+{
+ name = "os_news"
+
+ /*
+ * The number of LOGON/OPER news items to display when a user logs on.
+ *
+ * This directive is optional, if no set it will default to 3.
+ */
+ #newscount = 3
+}
+
command { service = "OperServ"; name = "LOGONNEWS"; command = "operserv/logonnews"; permission = "operserv/news"; }
command { service = "OperServ"; name = "OPERNEWS"; command = "operserv/opernews"; permission = "operserv/news"; }
command { service = "OperServ"; name = "RANDOMNEWS"; command = "operserv/randomnews"; permission = "operserv/news"; }
@@ -604,9 +526,84 @@ command { service = "OperServ"; name = "RELOAD"; command = "operserv/reload"; pe
*
* Provides the commands operserv/exception and operserv/session.
*
+ * This module enables session limiting. Session limiting prevents users from connecting more than a certain
+ * number of times from the same IP at the same time - thus preventing most types of cloning.
+ * Once a host reaches it's session limit, all clients attempting to connect from that host will
+ * be killed. Exceptions to the default session limit can be defined via the exception list.
+ *
* Used to manage the session limit exception list, and view currently active sessions.
*/
-module { name = "os_session" }
+module
+{
+ name = "os_session"
+
+ /*
+ * Default session limit per host. Once a host reaches it's session limit, all clients attempting
+ * to connect from that host will be killed.
+ *
+ * This directive is require if os_session is loaded.
+ */
+ defaultsessionlimit = 3
+
+ /*
+ * The maximum session limit that may be set for a host in an exception.
+ *
+ * This directive is require if os_session is loaded.
+ */
+ maxsessionlimit = 100
+
+ /*
+ * Sets the default expiry time for session exceptions.
+ *
+ * This directive is require if os_session is loaded.
+ */
+ exceptionexpiry = 1d
+
+ /*
+ * The message that will be NOTICE'd to a user just before they are removed from the network because
+ * their host's session limit has been exceeded. It may be used to give a slightly more descriptive
+ * reason for the impending kill as opposed to simply "Session limit exceeded".
+ *
+ * This directive is optional, if not set, nothing will be sent.
+ */
+ sessionlimitexceeded = "The session limit for your IP %IP% has been exceeded."
+
+ /*
+ * Same as above, but should be used to provide a website address where users can find out more
+ * about session limits and how to go about applying for an exception.
+ *
+ * Note: This directive has been intentionally commented out in an effort to remind you to change
+ * the URL it contains. It is recommended that you supply an address/URL where people can get help
+ * regarding session limits.
+ *
+ * This directive is optional, if not set, nothing will be sent.
+ */
+ #sessionlimitdetailsloc = "Please visit http://your.website.url/ for more information about session limits."
+
+ /*
+ * If set and is not 0, this directive tells Services to add an AKILL the number of subsequent kills
+ * for the same host exceeds this value, preventing the network from experiencing KILL floods.
+ *
+ * This directive is optional.
+ */
+ maxsessionkill = 15
+
+ /*
+ * Sets the expiry time for AKILLs set for hosts exceeding the maxsessionkill directive limit.
+ *
+ * This directive is optional, if not set, defaults to 30 minutes.
+ */
+ sessionautokillexpiry = 30m
+
+ /*
+ * Sets the CIDR value used to determine which IP addresses represent the same person.
+ * By default this would limit 3 connections per IPv4 IP and 3 connections per IPv6 IP.
+ * If you are receiving IPv6 clone attacks it may be useful to set session_ipv6_cidr to
+ * 64 or 48.
+ */
+ session_ipv4_cidr = 32
+ session_ipv6_cidr = 128
+}
command { service = "OperServ"; name = "EXCEPTION"; command = "operserv/exception"; permission = "operserv/exception"; }
command { service = "OperServ"; name = "SESSION"; command = "operserv/session"; permission = "operserv/session"; }
@@ -617,7 +614,19 @@ command { service = "OperServ"; name = "SESSION"; command = "operserv/session";
*
* Used to set various settings such as superadmin, debug mode, etc.
*/
-module { name = "os_set" }
+module
+{
+ name = "os_set"
+
+ /*
+ * If set, Services Admins will be able to use SUPERADMIN [ON|OFF] which will temporarily grant
+ * them extra privileges such as being a founder on ALL channels.
+ *
+ * This directive is optional.
+ */
+ #superadmin = yes
+}
+
command { service = "OperServ"; name = "SET"; command = "operserv/set"; permission = "operserv/set"; }
/*
@@ -659,7 +668,7 @@ command { service = "OperServ"; name = "SVSPART"; command = "operserv/svspart";
*
* Provides the operserv/snline and operserv/sqline commands.
*
- * Used to ban different things such as realnames, nicknames, and IPs.
+ * Used to ban real names, nick names, and possibly channels.
*/
module { name = "os_sxline" }
command { service = "OperServ"; name = "SNLINE"; command = "operserv/snline"; permission = "operserv/snline"; }
diff --git a/include/account.h b/include/account.h
index 98827fd81..b5edd7ec2 100644
--- a/include/account.h
+++ b/include/account.h
@@ -219,6 +219,10 @@ class CoreExport NickCore : public Serializable, public Extensible
*/
Anope::string GetAccess(unsigned entry) const;
+ /** Get the number of entries on the access list for this account.
+ */
+ unsigned GetAccessCount() const;
+
/** Find an entry in the nick's access list
*
* @param entry The nick!ident@host entry to search for
diff --git a/include/anope.h b/include/anope.h
index 8e24d12da..90c0e4c36 100644
--- a/include/anope.h
+++ b/include/anope.h
@@ -333,6 +333,7 @@ namespace Anope
};
template<typename T> class map : public std::map<string, T, ci::less> { };
+ template<typename T> class multimap : public std::multimap<string, T, ci::less> { };
template<typename T> class hash_map : public std::tr1::unordered_map<string, T, hash_ci, compare> { };
static const char *const compiled = __TIME__ " " __DATE__;
diff --git a/include/bots.h b/include/bots.h
index 3b42424bd..42345d8ea 100644
--- a/include/bots.h
+++ b/include/bots.h
@@ -23,6 +23,8 @@ extern CoreExport Serialize::Checker<botinfo_map> BotListByNick, BotListByUID;
/* A service bot (NickServ, ChanServ, a BotServ bot, etc). */
class CoreExport BotInfo : public User, public Serializable
{
+ /* Channels this bot is assigned to */
+ Serialize::Checker<std::set<ChannelInfo *> > channels;
public:
time_t created;
/* Last time this bot said something (via privmsg) */
@@ -63,10 +65,9 @@ class CoreExport BotInfo : public User, public Serializable
*/
void SetNewNick(const Anope::string &newnick);
- /** Rejoins all channels that this bot is assigned to.
- * Used on /kill, rename, etc.
+ /** Return the channels this bot is assigned to
*/
- void RejoinAll();
+ const std::set<ChannelInfo *> &GetChannels() const;
/** Assign this bot to a given channel, removing the existing assigned bot if one exists.
* @param u The user assigning the bot, or NULL
diff --git a/include/channels.h b/include/channels.h
index 118864c8a..56d0edd2c 100644
--- a/include/channels.h
+++ b/include/channels.h
@@ -264,10 +264,6 @@ class CoreExport Channel : public Base, public Extensible
*/
void ChangeTopic(const Anope::string &user, const Anope::string &newtopic, time_t ts = Anope::CurTime);
- /** Hold the channel open using ChanServ
- */
- void Hold();
-
/** Set the correct modes, or remove the ones granted without permission,
* for the specified user.
* @param user The user to give/remove modes to/from
diff --git a/include/config.h b/include/config.h
index 901fe0138..ca09c347f 100644
--- a/include/config.h
+++ b/include/config.h
@@ -16,319 +16,113 @@
#include "account.h"
#include "regchannel.h"
#include "users.h"
+#include "opertype.h"
+#include <stack>
-/** A configuration key and value pair
- */
-typedef std::pair<Anope::string, Anope::string> KeyVal;
-
-/** A list of related configuration keys and values
- */
-typedef std::vector<KeyVal> KeyValList;
-
-/** An entire config file, built up of KeyValLists
- */
-typedef std::multimap<Anope::string, KeyValList> ConfigDataHash;
-
-// Required forward definitions
-
-/** Types of data in the core config
- */
-enum ConfigDataType
-{
- DT_NOTHING, // No data
- DT_INTEGER, // Integer
- DT_UINTEGER, // Unsigned Integer
- DT_LUINTEGER, // Long Unsigned Integer
- DT_STRING, // Anope::string
- DT_BOOLEAN, // Boolean
- DT_HOSTNAME, // Hostname syntax
- DT_NOSPACES, // No spaces
- DT_IPADDRESS, // IP address (v4, v6)
- DT_TIME, // Time value
- DT_NORELOAD = 32, // Item can't be reloaded after startup
- DT_ALLOW_WILD = 64, // Allow wildcards/CIDR in DT_IPADDRESS
- DT_ALLOW_NEWLINE = 128, // New line characters allowed in DT_STRING
- DT_ALLOW_EMPTY = 256 // Allow empty value
-};
-
-/** Holds a config value, either string, integer or boolean.
- * Callback functions receive one or more of these, either on
- * their own as a reference, or in a reference to a deque of them.
- * The callback function can then alter the values of the ValueItem
- * classes to validate the settings.
- */
-class CoreExport ValueItem
-{
- private:
- /** Actual data */
- Anope::string v;
- public:
- /** Initialize with nothing */
- ValueItem();
- /** Initialize with an int */
- ValueItem(int);
- /** Initialize with a bool */
- ValueItem(bool);
- /** Initialize with an Anope::string */
- ValueItem(const Anope::string &);
- /** Initialize with a long */
- ValueItem(long);
- /** Change value to an Anope::string */
- void Set(const Anope::string &);
- /** Change value to an int */
- void Set(int);
- /** Get value as an int */
- int GetInteger() const;
- /** Get value as a string */
- const char *GetString() const;
- /** Get value as an Anope::string */
- inline const Anope::string &GetValue() const { return v; }
- /** Get value as a bool */
- bool GetBool() const;
-};
-
-/** The base class of the container 'ValueContainer'
- * used internally by the core to hold core values.
- */
-class ValueContainerBase
+namespace Configuration
{
- public:
- /** Constructor */
- ValueContainerBase() { }
- /** Destructor */
- virtual ~ValueContainerBase() { }
-};
-
-/** ValueContainer is used to contain pointers to different
- * core values such as the server name, maximum number of
- * clients etc.
- * It is specialized to hold a data type, then pointed at
- * a value in the ServerConfig class. When the value has been
- * read and validated, the Set method is called to write the
- * value safely in a type-safe manner.
- */
-template<typename T> class ValueContainer : public ValueContainerBase
-{
- private:
- /** Contained item */
- T val;
- public:
- /** Initialize with nothing */
- ValueContainer() : ValueContainerBase(), val(NULL) { }
- /** Initialize with a value of type T */
- ValueContainer(T Val) : ValueContainerBase(), val(Val) { }
- /** Initialize with a copy */
- ValueContainer(const ValueContainer &Val) : ValueContainerBase(), val(Val.val) { }
- ValueContainer &operator=(const ValueContainer &Val)
- {
- val = Val.val;
- return *this;
- }
- /** Change value to type T of size s */
- void Set(const T newval, size_t s)
+ class Block
{
- memcpy(val, newval, s);
- }
-};
+ friend class Conf;
-/** This a specific version of ValueContainer to handle Anope::string specially
- */
-template<> class ValueContainer<Anope::string *> : public ValueContainerBase
-{
- private:
- /** Contained item */
- Anope::string *val;
- public:
- /** Initialize with nothing */
- ValueContainer() : ValueContainerBase(), val(NULL) { }
- /** Initialize with an std::string */
- ValueContainer(Anope::string *Val) : ValueContainerBase(), val(Val) { }
- /** Initialize with a copy */
- ValueContainer(const ValueContainer &Val) : ValueContainerBase(), val(Val.val) { }
- ValueContainer &operator=(const ValueContainer &Val)
- {
- val = Val.val;
- return *this;
- }
+ public:
+ typedef Anope::map<Anope::string> item_map;
+ typedef Anope::multimap<Block> block_map;
- /** Change value to given Anope::string */
- void Set(const Anope::string &newval)
- {
- *val = newval;
- }
- /** Change value to given char pointer */
- void Set(const char *newval)
- {
- *val = newval;
- }
-};
+ private:
+ Anope::string name;
+ item_map items;
+ block_map blocks;
-/** A specialization of ValueContainer to hold a pointer to a bool
- */
-typedef ValueContainer<bool *> ValueContainerBool;
+ public:
+ Block(const Anope::string &);
+ const Anope::string &GetName() const;
+ int CountBlock(const Anope::string &name);
+ Block* GetBlock(const Anope::string &name, int num = 0);
-/** A specialization of ValueContainer to hold a pointer to
- * an unsigned int
- */
-typedef ValueContainer<unsigned *> ValueContainerUInt;
-
-/** A specialization of ValueContainer to hold a pointer to
- * a long unsigned int
- */
-typedef ValueContainer<long unsigned *> ValueContainerLUInt;
-
-/** A specialization of ValueContainer to hold a pointer to
- * an int
- */
-typedef ValueContainer<int *> ValueContainerInt;
-
-/** A specialization of ValueContainer to hold a pointer to
- * a time_t
- */
-typedef ValueContainer<time_t *> ValueContainerTime;
-
-/** A specialization of ValueContainer to hold a pointer to
- * an Anope::string
- */
-typedef ValueContainer<Anope::string *> ValueContainerString;
-
-/** A set of ValueItems used by multi-value validator functions
- */
-typedef std::deque<ValueItem> ValueList;
-
-/** A callback for validating a single value
- */
-typedef bool (*Validator)(ServerConfig *, const Anope::string &, const Anope::string &, ValueItem &);
-/** A callback for validating multiple value entries
- */
-typedef bool (*MultiValidator)(ServerConfig *, const Anope::string &, const Anope::string *, ValueList &, int *);
-/** A callback indicating the end of a group of entries
- */
-typedef bool (*MultiNotify)(ServerConfig *, const Anope::string &);
-
-/** Represents a configuration file
- */
-class ConfigurationFile
-{
- Anope::string name;
- bool executable;
- FILE *fp;
- public:
- ConfigurationFile(const Anope::string &, bool);
- ~ConfigurationFile();
- const Anope::string &GetName() const;
+ template<typename T> T Get(const Anope::string &tag, const Anope::string &def = "") const
+ {
+ const Anope::string &value = this->Get<const Anope::string &>(tag, def);
+ try
+ {
+ return convertTo<T>(value);
+ }
+ catch (const ConvertException &)
+ {
+ return T();
+ }
+ }
- bool IsOpen() const;
- bool Open();
- void Close();
- bool End() const;
- Anope::string Read();
-};
+ bool Set(const Anope::string &tag, const Anope::string &value);
+ const item_map* GetItems() const;
+ };
-/** Holds all of the core configuration items
- */
-class CoreExport ConfigItems
-{
- public:
- /** Holds a core configuration item and its callbacks
- */
- struct Item
- {
- /** Tag name */
- Anope::string tag;
- /** Value name */
- Anope::string value;
- /** Default, if not defined */
- Anope::string default_value;
- /** Value containers */
- ValueContainerBase *val;
- /** Data types */
- int datatype;
- /** Validation function */
- Validator validation_function;
- } *Values;
+ template<> const Anope::string& Block::Get(const Anope::string &tag, const Anope::string& def) const;
+ template<> time_t Block::Get(const Anope::string &tag, const Anope::string &def) const;
+ template<> const char* Block::Get(const Anope::string &tag, const Anope::string &def) const;
+ template<> bool Block::Get(const Anope::string &tag, const Anope::string &def) const;
- /** Holds a core configuration item and its callbacks
- * where there may be more than one item
+ /** Represents a configuration file
*/
- struct MultiItem
+ class File
{
- /** Tag name */
- Anope::string tag;
- /** One or more items within tag */
- Anope::string items[17];
- /** One or more defaults for items within tags */
- Anope::string items_default[17];
- /** One or more data types */
- int datatype[17];
- /** Initialization function */
- MultiNotify init_function;
- /** Validation function */
- MultiValidator validation_function;
- /** Completion function */
- MultiNotify finish_function;
- } *MultiValues;
-
- ConfigItems(ServerConfig *conf);
- ~ConfigItems();
-};
+ Anope::string name;
+ bool executable;
+ FILE *fp;
+ public:
+ File(const Anope::string &, bool);
+ ~File();
+ const Anope::string &GetName() const;
+
+ bool IsOpen() const;
+ bool Open();
+ void Close();
+ bool End() const;
+ Anope::string Read();
+ };
-/** This class holds the bulk of the runtime configuration for Anope.
- * It allows for reading new config values, accessing configuration files,
- * and storage of the configuration data needed to run Anope.
- */
-class CoreExport ServerConfig
-{
- private:
- /** Check that there is only one of each configuration item
- */
- bool CheckOnce(const Anope::string &);
- public:
- /** This holds all the information in the config file,
- * it's indexed by tag name to a vector of key/values.
- */
- ConfigDataHash config_data;
- /** Construct a new ServerConfig
- */
- ServerConfig();
+ struct Uplink;
- /** Read the entire configuration into memory
- * and initialize this class. All other methods
- * should be used only by the core.
- */
- void Read();
- /** Load the configuration file into 'this'. With the new config parser everything is parsed into
- * tag/key/value at load-time rather than at read-value time.
- */
- void LoadConf(ConfigurationFile &file);
- // Both these return true if the value existed or false otherwise
- /** Writes 'length' chars into 'result' as a string
- */
- bool ConfValue(ConfigDataHash &, const Anope::string &, const Anope::string &, int, Anope::string &, bool = false);
- /** Writes 'length' chars into 'result' as a string
- */
- bool ConfValue(ConfigDataHash &, const Anope::string &, const Anope::string &, const Anope::string &, int, Anope::string &, bool = false);
- /** Tries to convert the value to an integer and write it to 'result'
- */
- bool ConfValueInteger(ConfigDataHash &, const Anope::string &, const Anope::string &, int, int &);
- /** Tries to convert the value to an integer and write it to 'result'
- */
- bool ConfValueInteger(ConfigDataHash &, const Anope::string &, const Anope::string &, const Anope::string &, int, int &);
- /** Returns true if the value exists and has a true value, false otherwise
- */
- bool ConfValueBool(ConfigDataHash &, const Anope::string &, const Anope::string &, int);
- /** Returns true if the value exists and has a true value, false otherwise
- */
- bool ConfValueBool(ConfigDataHash &, const Anope::string &, const Anope::string &, const Anope::string &, int);
- /** Returns the number of occurences of tag in the config file
- */
- int ConfValueEnum(const ConfigDataHash &, const Anope::string &);
- /** Returns the numbers of vars inside the index'th 'tag in the config file
- */
- int ConfVarEnum(ConfigDataHash &, const Anope::string &, int);
- void ValidateHostname(const Anope::string &, const Anope::string &, const Anope::string &) const;
- void ValidateIP(const Anope::string &p, const Anope::string &, const Anope::string &, bool) const;
- void ValidateNoSpaces(const Anope::string &, const Anope::string &, const Anope::string &) const;
+ struct Conf : Block
+ {
+ /* options:readtimeout */
+ time_t ReadTimeout;
+ /* options:useprivmsg */
+ bool UsePrivmsg;
+ /* If we should default to privmsging clients */
+ bool DefPrivmsg;
+ /* Default language */
+ Anope::string DefLanguage;
+
+ /* either "/msg " or "/" */
+ Anope::string StrictPrivmsg;
+ /* List of uplink servers to try and connect to */
+ std::vector<Uplink> Uplinks;
+ /* A vector of our logfile options */
+ std::vector<LogInfo> LogInfos;
+ /* Array of ulined servers */
+ std::vector<Anope::string> Ulines;
+ /* List of available opertypes */
+ std::vector<OperType *> MyOperTypes;
+ /* List of pairs of opers and their opertype from the config */
+ std::vector<Oper *> Opers;
+ /* Map of fantasy commands */
+ CommandInfo::map Fantasy;
+ /* Command groups */
+ std::vector<CommandGroup> CommandGroups;
+ /* List of modules to autoload */
+ std::vector<Anope::string> ModulesAutoLoad;
+
+ /* module configuration blocks */
+ std::map<Anope::string, Block *> modules;
+
+ Conf();
+
+ void LoadConf(File &file);
+
+ Block *GetModule(Module *);
+ Block *GetModule(const Anope::string &name);
+ };
struct Uplink
{
@@ -338,352 +132,10 @@ class CoreExport ServerConfig
bool ipv6;
Uplink(const Anope::string &_host, int _port, const Anope::string &_password, bool _ipv6) : host(_host), port(_port), password(_password), ipv6(_ipv6) { }
- bool operator==(const Uplink &other) const
- {
- if (this->host != other.host)
- return false;
- if (this->port != other.port)
- return false;
- if (this->password != other.password)
- return false;
- if (this->ipv6 != other.ipv6)
- return false;
- return true;
- }
+ inline bool operator==(const Uplink &other) const { return host == other.host && port == other.port && password == other.password && ipv6 == other.ipv6; }
inline bool operator!=(const Uplink &other) const { return !(*this == other); }
};
-
- /** Below here is a list of variables which contain the config files values
- */
- /* Host to bind to */
- Anope::string LocalHost;
- /* List of uplink servers to try and connect to */
- std::vector<Uplink *> Uplinks;
-
- /* Our server name */
- Anope::string ServerName;
- /* Our servers description */
- Anope::string ServerDesc;
-
- /* Name of the network were on */
- Anope::string NetworkName;
- /* The max legnth of nicks */
- unsigned NickLen;
- /* Max length of idents */
- unsigned UserLen;
- /* Max lenght of hostnames */
- unsigned HostLen;
- /* Max length of channel names */
- unsigned ChanLen;
- /* Max length of b/e/I lists */
- unsigned ListSize;
-
- /* User and group to run as */
- Anope::string User;
- Anope::string Group;
-
- /* Casemapping to use */
- Anope::string CaseMap;
-
- /* Max length of passwords */
- unsigned PassLen;
-
- /* Filename for the PID file */
- Anope::string PIDFilename;
- /* MOTD filename */
- Anope::string MOTDFilename;
-
- Anope::string BotServ;
- Anope::string ChanServ;
- Anope::string Global;
- Anope::string HostServ;
- Anope::string NickServ;
- Anope::string OperServ;
- Anope::string MemoServ;
-
- /* True if its ok to not be able to save backs */
- bool NoBackupOkay;
- /* Do password checking when new people register */
- bool StrictPasswords;
- /* How many times you're allowed to give a bad password before being killed */
- unsigned BadPassLimit;
- /* How long before bad passwords are forgotten */
- time_t BadPassTimeout;
- /* Delay between automatic database updates */
- time_t UpdateTimeout;
- /* Delay between checks for expired nicks and channels */
- time_t ExpireTimeout;
- /* How long to wait for something from the uplink, this is passed to select() */
- time_t ReadTimeout;
- /* How often to send program errors */
- time_t WarningTimeout;
- /* How long to process things such as timers to see if there is anything to calll */
- time_t TimeoutCheck;
- /* Number of days backups are kept */
- int KeepBackups;
- /* Forbidding requires a reason */
- bool ForceForbidReason;
- /* Services should use privmsgs instead of notices */
- bool UsePrivmsg;
- /* Services only respond to full PRIVMSG client@services.server.name messages */
- bool UseStrictPrivMsg;
- /* This is not a configurable option.
- * Config::Config will set it depending on the value of UseStrictPrivMsg */
- Anope::string UseStrictPrivMsgString;
- /* Number of seconds between consecutive uses of the REGISTER command
- * Not to be confused with NSRegDelay */
- unsigned NickRegDelay;
- /* Max number if news items allowed in the list */
- unsigned NewsCount;
- /* Default mlock modes */
- Anope::string MLock;
- /* Unmlockable modes */
- Anope::string NoMLock;
- /* Modes that are required to be on registered channels */
- Anope::string CSRequire;
- /* Use server side mlock */
- bool UseServerSideMLock;
- /* Use server side topic lock */
- bool UseServerSideTopicLock;
- /* The max length for reasons (cs_kick, cs_ban, etc) */
- unsigned CSReasonMax;
- /* Default botmodes on channels, defaults to ao */
- Anope::string BotModes;
- /* How long to wait between connection attempts */
- int RetryWait;
- /* If services should hide unprivileged commands */
- bool HidePrivilegedCommands;
- /* If set, nicks cant be owned/everything is entirely account based */
- bool NoNicknameOwnership;
- /* Regex engine to use */
- Anope::string RegexEngine;
-
- /* A vector of our logfile options */
- std::vector<LogInfo *> LogInfos;
-
- /* Services can use email */
- bool UseMail;
- /* Path to the sendmail executable */
- Anope::string SendMailPath;
- /* Address to send from */
- Anope::string SendFrom;
- /* Only opers can have services send mail */
- bool RestrictMail;
- /* Delay between sending mail */
- time_t MailDelay;
- /* Don't quote the To: address */
- bool DontQuoteAddresses;
- /* Mail messages to send */
- Anope::string MailRegistrationSubject, MailRegistrationMessage;
- Anope::string MailResetSubject, MailResetMessage;
- Anope::string MailEmailchangeSubject, MailEmailchangeMessage;
- Anope::string MailMemoSubject, MailMemoMessage;
-
- /* Prefix of guest nicks when a user gets forced off of a nick */
- Anope::string NSGuestNickPrefix;
- /* Allow users to set kill immed on */
- bool NSAllowKillImmed;
- /* Don't allow nicks to use /ns group to regroup nicks */
- bool NSNoGroupChange;
- /* Default flags for newly registered nicks */
- std::set<Anope::string> NSDefFlags;
- /* All languages Anope is aware about */
- Anope::string Languages;
- /* Default language used by services */
- Anope::string NSDefLanguage;
- /* Users must be connected this long before they can register
- * Not to be confused with NickRegDelay */
- time_t NSRegDelay;
- /* Time before the registering mail will be resent */
- time_t NSResendDelay;
- /* How long before nicks expire */
- time_t NSExpire;
- /* How long before suspended nicks expire */
- time_t NSSuspendExpire;
- /* Time before unconfirmed nicks expire */
- time_t NSUnconfirmedExpire;
- /* Force email when registering */
- bool NSForceEmail;
- /* Force users to validate new email addresses */
- bool NSConfirmEmailChanges;
- /* Max number of nicks in a group */
- unsigned NSMaxAliases;
- /* Max number of allowed strings on the access list */
- unsigned NSAccessMax;
- /* Enforcer client user name */
- Anope::string NSEnforcerUser;
- /* Enforcer client hostname */
- Anope::string NSEnforcerHost;
- /* How long before recovered nicks are released */
- time_t NSReleaseTimeout;
- /* Max number of entries that can be returned from the list command */
- unsigned NSListMax;
- /* Only allow usermode +a etc on real services admins */
- bool NSSecureAdmins;
- /* Services opers must be /operd on the ircd aswell */
- bool NSStrictPrivileges;
- /* Type of confirmation to use, or to disable registration completely */
- Anope::string NSRegistration;
- /* A message sent to unregistered users on connect */
- Anope::string NSUnregisteredNotice;
- /* Core NickServ modules */
- Anope::string NickCoreModules;
- /* Set the proper channel modes on users when they identify */
- bool NSModeOnID;
- /* Add the users hostnask their access list when they register */
- bool NSAddAccessOnReg;
- /* Maximum number of channels on AJoin */
- unsigned AJoinMax;
- /* Kill & killquick delays before force changing off users */
- time_t NSKillQuick;
- time_t NSKill;
- /* Modes set on a user when they identify */
- Anope::string NSModesOnID;
- /* Restore nick/channels on recover */
- bool NSRestoreOnRecover;
- /* Whether or not to use SASL */
- bool NSSASL;
- /* If set, hides netsplits in the last_quit field of nicks */
- bool NSHideNetSplitQuit;
-
- /* Core ChanServ modules */
- Anope::string ChanCoreModules;
- /* Default flags for newly registered channels */
- std::set<Anope::string> CSDefFlags;
- /* Max number of channels a user can own */
- unsigned CSMaxReg;
- /* Time before a channel expires */
- time_t CSExpire;
- /* How long before suspended channels expire */
- time_t CSSuspendExpire;
- /* How long before forbidden channels expire */
- time_t CSForbidExpire;
- /* Default ban type to use for channels */
- int CSDefBantype;
- /* Max number of entries allowed on channel access lists */
- unsigned CSAccessMax;
- /* Max number of entries allowed on autokick lists */
- unsigned CSAutokickMax;
- /* Default autokick reason */
- Anope::string CSAutokickReason;
- /* Time ChanServ should stay in the channel to hold it to keep users from getting in */
- time_t CSInhabit;
- /* Max number of entries allowed to be returned from the LIST command */
- unsigned CSListMax;
- /* true to make ChanServ oper only */
- bool CSOpersOnly;
-
- /* Max number of memos allowed */
- unsigned MSMaxMemos;
- /* Time you must wait between sending memos */
- time_t MSSendDelay;
- /* Notify all of the aliases of the core the memo was sent to */
- bool MSNotifyAll;
- /* Who can use memos reciepts */
- unsigned MSMemoReceipt;
-
- /* Valid chars allowed in vhosts */
- Anope::string VhostChars;
- /* Allow undotted vhosts? */
- bool VhostUndotted;
- /* Chars disallowed at the beginning or end of vhosts */
- Anope::string VhostDisallowBE;
-
- /* Core BotServ modules */
- Anope::string BotCoreModules;
- /* Default BotServ flags */
- std::set<Anope::string> BSDefFlags;
- /* How long before botserv forgets a user. This is used for flood kickers etc */
- time_t BSKeepData;
- /* Min number of users to have in the channel before the service bot joins */
- unsigned BSMinUsers;
- /* Max number of words allowed on the badwordslist */
- unsigned BSBadWordsMax;
- /* BotServ bot only joins if it would normally allowed to, abides by bans etc */
- bool BSSmartJoin;
- /* Dont tell users what badword they used */
- bool BSGentleBWReason;
- /* Case sensitive badwords matching */
- bool BSCaseSensitive;
- /* Char to use for the fantasy char, eg ! */
- Anope::string BSFantasyCharacter;
-
- /* Only show /stats o to opers */
- bool HideStatsO;
- /* Send out a global when services shut down or restart */
- bool GlobalOnCycle;
- /* Don't include the opers name in globals */
- bool AnonymousGlobal;
- /* Dont allow users to register nicks with oper names in them */
- bool RestrictOperNicks;
- /* Message to send when shutting down */
- Anope::string GlobalOnCycleMessage;
- /* Message to send when starting up */
- Anope::string GlobalOnCycleUP;
- /* Super admin is allowed */
- bool SuperAdmin;
- /* Default expiry time for akills */
- time_t AutokillExpiry;
- /* Default expiry time for chan kills */
- time_t ChankillExpiry;
- /* Default expiry time for SNLine Expire */
- time_t SNLineExpiry;
- /* Default expiry time for SQLines */
- time_t SQLineExpiry;
- /* Actually akill the user when the akill is added */
- bool AkillOnAdd;
- /* Kill users on SNLine */
- bool KillonSNline;
- /* Kill users on SQline */
- bool KillonSQline;
- /* Add the akillers nick to the akill reason */
- bool AddAkiller;
- /* Add akill ids to akill reason */
- bool AkillIds;
-
- /* Limit sessions */
- bool LimitSessions;
- /* The default session limit */
- unsigned DefSessionLimit;
- /* How long before exceptions expire */
- time_t ExceptionExpiry;
- /* How many times to kill before adding an KILL */
- unsigned MaxSessionKill;
- /* Max limit that can be used for exceptions */
- unsigned MaxSessionLimit;
- /* How long session akills should last */
- time_t SessionAutoKillExpiry;
- /* Number of bits to use when comparing session IPs */
- unsigned SessionIPv4CIDR;
- unsigned SessionIPv6CIDR;
- /* Reason to use for session kills */
- Anope::string SessionLimitExceeded;
- /* Optional second reason */
- Anope::string SessionLimitDetailsLoc;
- /* OperServ requires you to be an operator */
- bool OSOpersOnly;
-
- /* List of modules to autoload */
- std::list<Anope::string> ModulesAutoLoad;
-
- /* Seed to use for RNG */
- unsigned long Seed;
-
- /* Numeric */
- Anope::string Numeric;
- /* Array of ulined servers */
- std::list<Anope::string> Ulines;
-
- /* List of available opertypes */
- std::list<OperType *> MyOperTypes;
- /* List of pairs of opers and their opertype from the config */
- std::vector<Oper *> Opers;
-
- /* Map of fantasy commands */
- CommandInfo::map Fantasy;
-
- std::vector<CommandGroup> CommandGroups;
-};
+}
/** This class can be used on its own to represent an exception, or derived to represent a module-specific exception.
* When a module whishes to abort, e.g. within a constructor, it should throw an exception using ModuleException or
@@ -707,115 +159,7 @@ class ConfigException : public CoreException
virtual ~ConfigException() throw() { }
};
-enum
-{
- CONF_NO_ERROR,
- CONF_INT_NEGATIVE = 1 << 1,
- CONF_VALUE_NOT_FOUND = 1 << 2
-};
-
-/** Allows reading of values from configuration files
- * This class allows a module to read from either the main configuration file (services.conf) or from
- * a module-specified configuration file. It may either be instantiated with one parameter or none.
- * Constructing the class using one parameter allows you to specify a path to your own configuration
- * file, otherwise, inspircd.conf is read.
- */
-class CoreExport ConfigReader
-{
- ServerConfig *conf;
- protected:
- /** True if an error occured reading the config file
- */
- bool readerror;
- /** Error code
- */
- long error;
- public:
- /** Default constructor.
- * This constructor initialises the ConfigReader class to read the configuration file(s).
- */
- ConfigReader();
- /** Overloaded constructor.
- * This constructor initialises the ConfigReader class to read a user-specified config file
- */
- ConfigReader(const Anope::string &);
- /** Overloaded constructor
- * This constructor initialises the ConfigReader class to use a user sepcific ServerConfig object,
- */
- ConfigReader(ServerConfig *);
- /** Default destructor.
- * This method destroys the ConfigReader class.
- */
- ~ConfigReader();
- /** Retrieves a value from the config file.
- * This method retrieves a value from the config file. Where multiple copies of the tag
- * exist in the config file, index indicates which of the values to retrieve.
- */
- Anope::string ReadValue(const Anope::string &, const Anope::string &, int, bool = false);
- /** Retrieves a value from the config file.
- * This method retrieves a value from the config file. Where multiple copies of the tag
- * exist in the config file, index indicates which of the values to retrieve. If the
- * tag is not found the default value is returned instead.
- */
- Anope::string ReadValue(const Anope::string &, const Anope::string &, const Anope::string &, int, bool = false);
- /** Retrieves a boolean value from the config file.
- * This method retrieves a boolean value from the config file. Where multiple copies of the tag
- * exist in the config file, index indicates which of the values to retrieve. The values "1", "yes"
- * and "true" in the config file count as true to ReadFlag, and any other value counts as false.
- */
- bool ReadFlag(const Anope::string &, const Anope::string &, int);
- /** Retrieves a boolean value from the config file.
- * This method retrieves a boolean value from the config file. Where multiple copies of the tag
- * exist in the config file, index indicates which of the values to retrieve. The values "1", "yes"
- * and "true" in the config file count as true to ReadFlag, and any other value counts as false.
- * If the tag is not found, the default value is used instead.
- */
- bool ReadFlag(const Anope::string &, const Anope::string &, const Anope::string &, int);
- /** Retrieves an integer value from the config file.
- * This method retrieves an integer value from the config file. Where multiple copies of the tag
- * exist in the config file, index indicates which of the values to retrieve. Any invalid integer
- * values in the tag will cause the objects error value to be set, and any call to GetError() will
- * return CONF_INVALID_NUMBER to be returned. need_positive is set if the number must be non-negative.
- * If a negative number is placed into a tag which is specified positive, 0 will be returned and GetError()
- * will return CONF_INT_NEGATIVE. Note that need_positive is not suitable to get an unsigned int - you
- * should cast the result to achieve that effect.
- */
- int ReadInteger(const Anope::string &, const Anope::string &, int, bool);
- /** Retrieves an integer value from the config file.
- * This method retrieves an integer value from the config file. Where multiple copies of the tag
- * exist in the config file, index indicates which of the values to retrieve. Any invalid integer
- * values in the tag will cause the objects error value to be set, and any call to GetError() will
- * return CONF_INVALID_NUMBER to be returned. needs_unsigned is set if the number must be unsigned.
- * If a signed number is placed into a tag which is specified unsigned, 0 will be returned and GetError()
- * will return CONF_NOT_UNSIGNED. If the tag is not found, the default value is used instead.
- */
- int ReadInteger(const Anope::string &, const Anope::string &, const Anope::string &, int, bool);
- /** Returns the last error to occur.
- * Valid errors can be found by looking in modules.h. Any nonzero value indicates an error condition.
- * A call to GetError() resets the error flag back to 0.
- */
- long GetError();
- /** Counts the number of times a given tag appears in the config file.
- * This method counts the number of times a tag appears in a config file, for use where
- * there are several tags of the same kind, e.g. with opers and connect types. It can be
- * used with the index value of ConfigReader::ReadValue to loop through all copies of a
- * multiple instance tag.
- */
- int Enumerate(const Anope::string &) const;
- /** Returns true if a config file is valid.
- * This method is partially implemented and will only return false if the config
- * file does not exist or could not be opened.
- */
- bool Verify();
- /** Returns the number of items within a tag.
- * For example if the tag was &lt;test tag="blah" data="foo"&gt; then this
- * function would return 2. Spaces and newlines both qualify as valid seperators
- * between values.
- */
- int EnumerateValues(const Anope::string &, int);
-};
-
-extern ConfigurationFile ServicesConf;
-extern CoreExport ServerConfig *Config;
+extern Configuration::File ServicesConf;
+extern CoreExport Configuration::Conf *Config;
#endif // CONFIG_H
diff --git a/include/defs.h b/include/defs.h
index 34e900717..8e1f17898 100644
--- a/include/defs.h
+++ b/include/defs.h
@@ -20,9 +20,11 @@ class ChanAccess;
class Channel;
class ChannelInfo;
class ChannelStatus;
+struct ChanUserContainer;
class ClientSocket;
class Command;
class CommandSource;
+namespace Configuration { class Conf; }
class ConnectionSocket;
namespace DNS { class Packet; }
class Entry;
@@ -42,7 +44,6 @@ class ReferenceBase;
class Regex;
class Serializable;
class Server;
-class ServerConfig;
class Socket;
class Thread;
class User;
diff --git a/include/modes.h b/include/modes.h
index f5a1296c5..2d9755817 100644
--- a/include/modes.h
+++ b/include/modes.h
@@ -205,6 +205,8 @@ class CoreExport ChannelStatus
{
Anope::string modes;
public:
+ ChannelStatus();
+ ChannelStatus(const Anope::string &modes);
void AddMode(char c);
void DelMode(char c);
bool HasMode(char c) const;
@@ -308,11 +310,6 @@ class CoreExport ModeManager
/* Number of generic channel and user modes we are tracking */
static unsigned GenericChannelModes;
static unsigned GenericUserModes;
- /* Default channel mode lock */
- static std::list<std::pair<Anope::string, Anope::string> > ModeLockOn;
- static std::list<Anope::string> ModeLockOff;
- /* Default modes bots have on channels */
- static ChannelStatus DefaultBotModes;
/** Add a user mode to Anope
* @param um A UserMode or UserMode derived class
@@ -398,12 +395,6 @@ class CoreExport ModeManager
static void StackerDel(User *u);
static void StackerDel(Channel *c);
static void StackerDel(Mode *m);
-
- /** Updates the default mode locks and default bot modes
- * @param config The configuration to read from. This is often called
- * during a config reload.
- */
- static void UpdateDefaultMLock(ServerConfig *config);
};
/** Represents a mask set on a channel (b/e/I)
diff --git a/include/module.h b/include/module.h
index 08ba8a4bd..6ff54a31f 100644
--- a/include/module.h
+++ b/include/module.h
@@ -12,7 +12,6 @@
#ifndef MODULE_H
#define MODULE_H
-/* Just include everything for now */
#include "access.h"
#include "account.h"
#include "anope.h"
@@ -47,6 +46,7 @@
#include "users.h"
#include "xline.h"
+#include "chanserv.h"
#include "global.h"
#include "memoserv.h"
#include "nickserv.h"
diff --git a/include/modules.h b/include/modules.h
index e9846f609..5ff58751f 100644
--- a/include/modules.h
+++ b/include/modules.h
@@ -112,8 +112,6 @@ if (true) \
else \
static_cast<void>(0)
-class ConfigReader;
-
/** Possible return types from events.
*/
enum EventReturn
@@ -278,20 +276,27 @@ class CoreExport Module : public Extensible
* before they will be called.
*/
- /** Called when the ircd notifies that a user has been kicked from a channel.
- * @param c The channel the user has been kicked from.
- * @param target The user that has been kicked.
- * @param source The nick of the sender.
+ /** Called before a user has been kicked from a channel.
+ * @param source The kicker
+ * @param cu The user, channel, and status of the user being kicked
+ * @param kickmsg The reason for the kick.
+ */
+ virtual void OnPreUserKicked(MessageSource &source, ChanUserContainer *cu, const Anope::string &kickmsg) { }
+
+ /** Called when a user has been kicked from a channel.
+ * @param source The kicker
+ * @param target The user being kicked
+ * @param channel The channel the user was kicked from, which may no longer exist
+ * @param status The status the kicked user had on the channel before they were kicked
* @param kickmsg The reason for the kick.
*/
- virtual void OnUserKicked(Channel *c, User *target, MessageSource &source, const Anope::string &kickmsg) { }
+ virtual void OnUserKicked(MessageSource &source, User *target, const Anope::string &channel, ChannelStatus &status, const Anope::string &kickmsg) { }
/** Called when Services' configuration is being (re)loaded.
* @param conf The config that is being built now and will replace the global Config object
- * @param reader A config reader for conf
* @throws A ConfigException to abort the config (re)loading process.
*/
- virtual void OnReload(ServerConfig *conf, ConfigReader &reader) { }
+ virtual void OnReload(Configuration::Conf *conf) { }
/** Called before a bot is assigned to a channel.
* @param sender The user assigning the bot
@@ -299,7 +304,11 @@ class CoreExport Module : public Extensible
* @param bi The bot being assigned.
* @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to deny the assign.
*/
- virtual EventReturn OnBotAssign(User *sender, ChannelInfo *ci, BotInfo *bi) { return EVENT_CONTINUE; }
+ virtual EventReturn OnPreBotAssign(User *sender, ChannelInfo *ci, BotInfo *bi) { return EVENT_CONTINUE; }
+
+ /** Called when a bot is assigned ot a channel
+ */
+ virtual void OnBotAssign(User *sender, ChannelInfo *ci, BotInfo *bi) { }
/** Called before a bot is unassigned from a channel.
* @param sender The user unassigning the bot
@@ -387,12 +396,6 @@ class CoreExport Module : public Extensible
*/
virtual EventReturn OnBotNoFantasyAccess(CommandSource &source, Command *c, ChannelInfo *ci, const std::vector<Anope::string> &params) { return EVENT_CONTINUE; }
- /** Called after a bot joins a channel
- * @param c The channel
- * @param bi The bot
- */
- virtual void OnBotJoin(Channel *c, BotInfo *bi) { }
-
/** Called when a bot places a ban
* @param u User being banned
* @param ci Channel the ban is placed on
@@ -442,13 +445,6 @@ class CoreExport Module : public Extensible
*/
virtual void OnLeaveChannel(User *u, Channel *c) { }
- /** Called before a user joins a channel
- * @param u The user
- * @param c The channel
- * @return EVENT_STOP to allow the user to join the channel through restrictions, EVENT_CONTINUE to let other modules decide
- */
- virtual EventReturn OnPreJoinChannel(User *u, Channel *c) { return EVENT_CONTINUE; }
-
/** Called when a user joins a channel
* @param u The user
* @param channel The channel
@@ -551,13 +547,15 @@ class CoreExport Module : public Extensible
*/
virtual void OnServerQuit(Server *server) { }
- /** Called on a QUIT
+ /** Called when a user quits, or is killed
* @param u The user
* @param msg The quit message
*/
virtual void OnUserQuit(User *u, const Anope::string &msg) { }
- /** Called when a user disconnects, before and after being internally removed from
+ /** Called when a user is quit, before and after being internally removed from
+ * This is different from OnUserQuit, which takes place at the time of the quit.
+ * This happens shortly after when all message processing is finished.
* all lists (channels, user list, etc)
* @param u The user
*/
@@ -721,9 +719,10 @@ class CoreExport Module : public Extensible
virtual void OnNickLogout(User *u) { }
/** Called when a nick is registered
+ * @param user The user registering the nick, of any
* @param The nick
*/
- virtual void OnNickRegister(NickAlias *na) { }
+ virtual void OnNickRegister(User *user, NickAlias *na) { }
/** Called when a nick is suspended
* @param na The nick alias
@@ -740,6 +739,11 @@ class CoreExport Module : public Extensible
*/
virtual void OnDelNick(NickAlias *na) { }
+ /** Called when a nickcore is created
+ * @param nc The nickcore
+ */
+ virtual void OnNickCoreCreate(NickCore *nc) { }
+
/** Called on delcore()
* @param nc pointer to the NickCore
*/
@@ -963,6 +967,21 @@ class CoreExport Module : public Extensible
*/
virtual EventReturn OnCheckModes(Channel *c) { return EVENT_CONTINUE; }
+ /** Called when a channel is synced.
+ * Channels are synced after a sjoin is finished processing
+ * for a newly created channel to set the correct modes, topic,
+ * set.
+ */
+ virtual void OnChannelSync(Channel *c) { }
+
+ /** Called to set the correct modes on the user on the given channel
+ * @param user The user
+ * @param chan The channel
+ * @param access The user's access on the channel
+ * @param give_modes If giving modes is desired
+ */
+ virtual void OnSetCorrectModes(User *user, Channel *chan, AccessGroup &access, bool give_modes) { }
+
virtual void OnSerializeCheck(Serialize::Type *) { }
virtual void OnSerializableConstruct(Serializable *) { }
virtual void OnSerializableDestruct(Serializable *) { }
@@ -994,6 +1013,12 @@ class CoreExport Module : public Extensible
* @return EVENT_STOP to prevent the protocol module from processing this message
*/
virtual EventReturn OnMessage(MessageSource &source, Anope::string &command, std::vector<Anope::string> &param) { return EVENT_CONTINUE; }
+
+ /** Called to determine if a chnanel mode can be set by a user
+ * @param u The user
+ * @param cm The mode
+ */
+ virtual EventReturn OnCanSet(User *u, const ChannelMode *cm) { return EVENT_CONTINUE; }
};
/** Implementation-specific flags which may be set in ModuleManager::Attach()
@@ -1003,7 +1028,7 @@ enum Implementation
I_BEGIN,
/* NickServ */
I_OnPreNickExpire, I_OnNickExpire, I_OnNickForbidden, I_OnNickGroup, I_OnNickLogout, I_OnNickIdentify, I_OnNickDrop,
- I_OnNickRegister, I_OnNickSuspended, I_OnNickUnsuspended, I_OnDelNick, I_OnDelCore, I_OnChangeCoreDisplay,
+ I_OnNickRegister, I_OnNickSuspended, I_OnNickUnsuspended, I_OnDelNick, I_OnNickCoreCreate, I_OnDelCore, I_OnChangeCoreDisplay,
I_OnNickClearAccess, I_OnNickAddAccess, I_OnNickEraseAccess, I_OnNickClearCert, I_OnNickAddCert, I_OnNickEraseCert,
I_OnNickInfo, I_OnCheckAuthentication, I_OnNickUpdate, I_OnSetNickOption,
@@ -1011,11 +1036,11 @@ enum Implementation
I_OnChanSuspend, I_OnChanDrop, I_OnPreChanExpire, I_OnChanExpire, I_OnAccessAdd,
I_OnAccessDel, I_OnAccessClear, I_OnLevelChange, I_OnChanRegistered, I_OnChanUnsuspend, I_OnCreateChan, I_OnDelChan, I_OnChannelCreate,
I_OnChannelDelete, I_OnAkickAdd, I_OnAkickDel, I_OnCheckKick, I_OnCheckModes,
- I_OnChanInfo, I_OnCheckPriv, I_OnGroupCheckPriv, I_OnSetChannelOption,
+ I_OnChanInfo, I_OnCheckPriv, I_OnGroupCheckPriv, I_OnSetChannelOption, I_OnChannelSync, I_OnSetCorrectModes,
/* BotServ */
- I_OnBotJoin, I_OnBotKick, I_OnBotCreate, I_OnBotChange, I_OnBotDelete, I_OnBotAssign, I_OnBotUnAssign,
- I_OnUserKicked, I_OnBotFantasy, I_OnBotNoFantasyAccess, I_OnBotBan, I_OnBadWordAdd, I_OnBadWordDel,
+ I_OnBotKick, I_OnBotCreate, I_OnBotChange, I_OnBotDelete, I_OnPreBotAssign, I_OnBotAssign, I_OnBotUnAssign,
+ I_OnPreUserKicked, I_OnUserKicked, I_OnBotFantasy, I_OnBotNoFantasyAccess, I_OnBotBan, I_OnBadWordAdd, I_OnBadWordDel,
/* HostServ */
I_OnSetVhost, I_OnDeleteVhost,
@@ -1024,7 +1049,7 @@ enum Implementation
I_OnMemoSend, I_OnMemoDel,
/* Users */
- I_OnUserConnect, I_OnUserNickChange, I_OnUserQuit, I_OnPreUserLogoff, I_OnPostUserLogoff, I_OnPreJoinChannel,
+ I_OnUserConnect, I_OnUserNickChange, I_OnUserQuit, I_OnPreUserLogoff, I_OnPostUserLogoff,
I_OnJoinChannel, I_OnPrePartChannel, I_OnPartChannel, I_OnLeaveChannel, I_OnFingerprint, I_OnUserAway, I_OnInvite,
/* OperServ */
@@ -1044,7 +1069,7 @@ enum Implementation
I_OnEncrypt, I_OnDecrypt,
I_OnChannelModeSet, I_OnChannelModeUnset, I_OnUserModeSet, I_OnUserModeUnset, I_OnChannelModeAdd, I_OnUserModeAdd,
I_OnMLock, I_OnUnMLock, I_OnServerSync, I_OnUplinkSync, I_OnBotPrivmsg, I_OnPrivmsg, I_OnLog, I_OnDnsRequest,
- I_OnMessage,
+ I_OnMessage, I_OnCanSet,
I_OnSerializeCheck, I_OnSerializableConstruct, I_OnSerializableDestruct, I_OnSerializableUpdate, I_OnSerializeTypeCreate,
I_END
diff --git a/include/protocol.h b/include/protocol.h
index 2de0c8e08..874fbbe2c 100644
--- a/include/protocol.h
+++ b/include/protocol.h
@@ -31,7 +31,6 @@ class CoreExport IRCDProto : public Service
virtual void SendModeInternal(const BotInfo *, const Channel *, const Anope::string &);
virtual void SendModeInternal(const BotInfo *, const User *, const Anope::string &);
virtual void SendKickInternal(const BotInfo *, const Channel *, const User *, const Anope::string &);
- virtual void SendMessageInternal(const BotInfo *bi, const Anope::string &dest, const Anope::string &buf);
virtual void SendNoticeInternal(const BotInfo *bi, const Anope::string &dest, const Anope::string &msg);
virtual void SendPrivmsgInternal(const BotInfo *bi, const Anope::string &dest, const Anope::string &buf);
virtual void SendQuitInternal(const User *u, const Anope::string &buf);
@@ -127,8 +126,6 @@ class CoreExport IRCDProto : public Service
virtual void SendKick(const BotInfo *bi, const Channel *chan, const User *user, const char *fmt, ...);
- /* Sends a message using SendPrivmsg or SendNotice, depending on the default message method. */
- virtual void SendMessage(const BotInfo *bi, const Anope::string &dest, const char *fmt, ...);
virtual void SendNotice(const BotInfo *bi, const Anope::string &dest, const char *fmt, ...);
virtual void SendPrivmsg(const BotInfo *bi, const Anope::string &dest, const char *fmt, ...);
virtual void SendAction(const BotInfo *bi, const Anope::string &dest, const char *fmt, ...);
@@ -193,7 +190,7 @@ class CoreExport IRCDProto : public Service
virtual void SendBOB() { }
virtual void SendEOB() { }
- virtual void SendSVSHold(const Anope::string &) { }
+ virtual void SendSVSHold(const Anope::string &, time_t) { }
virtual void SendSVSHoldDel(const Anope::string &) { }
virtual void SendSWhois(const BotInfo *bi, const Anope::string &, const Anope::string &) { }
diff --git a/include/servers.h b/include/servers.h
index bf0acb523..fe5f40365 100644
--- a/include/servers.h
+++ b/include/servers.h
@@ -121,6 +121,10 @@ class CoreExport Server : public Extensible
*/
const Anope::string &GetSID() const;
+ /** Retrieves the reason this server is quitting
+ */
+ const Anope::string &GetQuitReason() const;
+
/** Get the list of links this server has, or NULL if it has none
* @return A list of servers
*/
diff --git a/include/users.h b/include/users.h
index 4248ce744..00ff5e410 100644
--- a/include/users.h
+++ b/include/users.h
@@ -212,7 +212,7 @@ class CoreExport User : public virtual Base, public Extensible, public CommandRe
/** Get the account the user is logged in using
* @return The account or NULL
*/
- virtual NickCore *Account() const;
+ NickCore *Account() const;
/** Check if the user is identified for their nick
* @param check_nick True to check if the user is identified to the nickname they are on too
diff --git a/modules/bs_autoassign.cpp b/modules/bs_autoassign.cpp
index 134904925..3604fe69b 100644
--- a/modules/bs_autoassign.cpp
+++ b/modules/bs_autoassign.cpp
@@ -11,35 +11,28 @@
class BSAutoAssign : public Module
{
- Anope::string bot;
-
public:
BSAutoAssign(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
{
-
- Implementation i[] = { I_OnChanRegistered, I_OnReload };
+ Implementation i[] = { I_OnChanRegistered };
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
}
void OnChanRegistered(ChannelInfo *ci) anope_override
{
- if (this->bot.empty())
+ const Anope::string &bot = Config->GetModule(this)->Get<const Anope::string &>("bot");
+ if (bot.empty())
return;
- BotInfo *bi = BotInfo::Find(this->bot);
+ BotInfo *bi = BotInfo::Find(bot);
if (bi == NULL)
{
- Log(this) << "bs_autoassign is configured to assign bot " << this->bot << ", but it does not exist?";
+ Log(this) << "bs_autoassign is configured to assign bot " << bot << ", but it does not exist?";
return;
}
bi->Assign(NULL, ci);
}
-
- void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override
- {
- this->bot = reader.ReadValue("bs_autoassign", "bot", "", 0);
- }
};
MODULE_INIT(BSAutoAssign)
diff --git a/modules/commands/bs_badwords.cpp b/modules/commands/bs_badwords.cpp
index 90fbb875d..31dee8f8e 100644
--- a/modules/commands/bs_badwords.cpp
+++ b/modules/commands/bs_badwords.cpp
@@ -9,11 +9,8 @@
* Based on the original code of Services by Andy Church.
*/
-/*************************************************************************/
-
#include "module.h"
-
class BadwordsDelCallback : public NumberList
{
CommandSource &source;
@@ -146,17 +143,20 @@ class CommandBSBadwords : public Command
realword = word.substr(0, pos);
}
- if (ci->GetBadWordCount() >= Config->BSBadWordsMax)
+ unsigned badwordsmax = Config->GetModule(this->module)->Get<unsigned>("badwordsmax");
+ if (ci->GetBadWordCount() >= badwordsmax)
{
- source.Reply(_("Sorry, you can only have %d bad words entries on a channel."), Config->BSBadWordsMax);
+ source.Reply(_("Sorry, you can only have %d bad words entries on a channel."), badwordsmax);
return;
}
+ bool casesensitive = Config->GetModule("botserv")->Get<bool>("casesensitive");
+
for (unsigned i = 0, end = ci->GetBadWordCount(); i < end; ++i)
{
const BadWord *bw = ci->GetBadWord(i);
- if (!bw->word.empty() && ((Config->BSCaseSensitive && realword.equals_cs(bw->word)) || (!Config->BSCaseSensitive && realword.equals_ci(bw->word))))
+ if ((casesensitive && realword.equals_cs(bw->word)) || (!casesensitive && realword.equals_ci(bw->word)))
{
source.Reply(_("\002%s\002 already exists in %s bad words list."), bw->word.c_str(), ci->name.c_str());
return;
@@ -168,8 +168,6 @@ class CommandBSBadwords : public Command
ci->AddBadWord(realword, bwtype);
source.Reply(_("\002%s\002 added to %s bad words list."), realword.c_str(), ci->name.c_str());
-
- return;
}
void DoDelete(CommandSource &source, ChannelInfo *ci, const Anope::string &word)
@@ -219,6 +217,7 @@ class CommandBSBadwords : public Command
source.Reply(_("Bad words list is now empty."));
return;
}
+
public:
CommandBSBadwords(Module *creator) : Command(creator, "botserv/badwords", 2, 3)
{
@@ -289,7 +288,7 @@ class CommandBSBadwords : public Command
"will be done if a user says a word that ends with\n"
"\037word\037. If you don't specify anything, a kick will\n"
"be issued every time \037word\037 is said by a user.\n"
- " \n"), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str(), source.command.c_str());
+ " \n"), Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), source.command.c_str());
source.Reply(_("The \002DEL\002 command removes the given word from the\n"
"bad words list. If a list of entry numbers is given, those\n"
"entries are deleted. (See the example for LIST below.)\n"
@@ -316,7 +315,6 @@ class BSBadwords : public Module
BSBadwords(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
commandbsbadwords(this)
{
-
}
};
diff --git a/modules/commands/bs_bot.cpp b/modules/commands/bs_bot.cpp
index f8ecb1a1d..16fd9f2f2 100644
--- a/modules/commands/bs_bot.cpp
+++ b/modules/commands/bs_bot.cpp
@@ -29,21 +29,23 @@ class CommandBSBot : public Command
return;
}
- if (nick.length() > Config->NickLen)
+ Configuration::Block *networkinfo = Config->GetBlock("networkinfo");
+
+ if (nick.length() > networkinfo->Get<unsigned>("nicklen"))
{
- source.Reply(_("Bot nicks may only be %d characters long."), Config->NickLen);
+ source.Reply(_("Bot nicks may only be %d characters long."), networkinfo->Get<unsigned>("nicklen"));
return;
}
- if (user.length() > Config->UserLen)
+ if (user.length() > networkinfo->Get<unsigned>("userlen"))
{
- source.Reply(_("Bot idents may only be %d characters long."), Config->UserLen);
+ source.Reply(_("Bot idents may only be %d characters long."), networkinfo->Get<unsigned>("userlen"));
return;
}
- if (host.length() > Config->HostLen)
+ if (host.length() > networkinfo->Get<unsigned>("hostlen"))
{
- source.Reply(_("Bot hosts may only be %d characters long."), Config->HostLen);
+ source.Reply(_("Bot hosts may only be %d characters long."), networkinfo->Get<unsigned>("hostlen"));
return;
}
@@ -112,21 +114,23 @@ class CommandBSBot : public Command
return;
}
- if (nick.length() > Config->NickLen)
+ Configuration::Block *networkinfo = Config->GetBlock("networkinfo");
+
+ if (nick.length() > networkinfo->Get<unsigned>("nicklen"))
{
- source.Reply(_("Bot nicks may only be %d characters long."), Config->NickLen);
+ source.Reply(_("Bot nicks may only be %d characters long."), networkinfo->Get<unsigned>("nicklen"));
return;
}
- if (!user.empty() && user.length() > Config->UserLen)
+ if (user.length() > networkinfo->Get<unsigned>("userlen"))
{
- source.Reply(_("Bot idents may only be %d characters long."), Config->UserLen);
+ source.Reply(_("Bot idents may only be %d characters long."), networkinfo->Get<unsigned>("userlen"));
return;
}
- if (!host.empty() && host.length() > Config->HostLen)
+ if (host.length() > networkinfo->Get<unsigned>("hostlen"))
{
- source.Reply(_("Bot hosts may only be %d characters long."), Config->HostLen);
+ source.Reply(_("Bot hosts may only be %d characters long."), networkinfo->Get<unsigned>("hostlen"));
return;
}
@@ -204,7 +208,15 @@ class CommandBSBot : public Command
if (!user.empty())
{
IRCD->SendClientIntroduction(bi);
- bi->RejoinAll();
+ unsigned minusers = Config->GetBlock("botserv")->Get<unsigned>("minusers");
+ const std::set<ChannelInfo *> &channels = bi->GetChannels();
+ for (std::set<ChannelInfo *>::const_iterator it = channels.begin(), it_end = channels.end(); it != it_end; ++it)
+ {
+ const ChannelInfo *ci = *it;
+
+ if (ci->c && ci->c->users.size() >= minusers)
+ bi->Join(ci->c);
+ }
}
source.Reply(_("Bot \002%s\002 has been changed to %s!%s@%s (%s)."), oldnick.c_str(), bi->nick.c_str(), bi->GetIdent().c_str(), bi->host.c_str(), bi->realname.c_str());
diff --git a/modules/commands/bs_kick.cpp b/modules/commands/bs_kick.cpp
index 86248ae80..5c1bdc6a8 100644
--- a/modules/commands/bs_kick.cpp
+++ b/modules/commands/bs_kick.cpp
@@ -13,6 +13,8 @@
#include "module.h"
+static Module *me;
+
class CommandBSKick : public Command
{
public:
@@ -54,7 +56,7 @@ class CommandBSKick : public Command
"on a specific option.\n"
" \n"
"Note: access to this command is controlled by the\n"
- "level SET."), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str(), this_name.c_str());
+ "level SET."), Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), this_name.c_str());
return true;
}
@@ -199,7 +201,7 @@ class CommandBSKickBadwords : public CommandBSKickBase
"more information.\n"
"ttb is the number of times a user can be kicked\n"
"before it get banned. Don't give ttb to disable\n"
- "the ban system once activated."), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str());
+ "the ban system once activated."), Config->StrictPrivmsg.c_str(), source.service->nick.c_str());
return true;
}
};
@@ -406,8 +408,8 @@ class CommandBSKickFlood : public CommandBSKickBase
catch (const ConvertException &) { }
if (ci->floodsecs < 1)
ci->floodsecs = 10;
- if (ci->floodsecs > Config->BSKeepData)
- ci->floodsecs = Config->BSKeepData;
+ if (ci->floodsecs > Config->GetModule(me)->Get<time_t>("keepdata"))
+ ci->floodsecs = Config->GetModule(me)->Get<time_t>("keepdata");
ci->ExtendMetadata("BS_KICK_FLOOD");
if (ci->ttb[TTB_FLOOD])
@@ -639,13 +641,14 @@ struct BanData : ExtensibleItem
void purge()
{
+ time_t keepdata = Config->GetModule(me)->Get<time_t>("keepdata");
for (data_type::iterator it = data_map.begin(), it_end = data_map.end(); it != it_end;)
{
const Anope::string &user = it->first;
Data &bd = it->second;
++it;
- if (Anope::CurTime - bd.last_use > Config->BSKeepData)
+ if (Anope::CurTime - bd.last_use > keepdata)
data_map.erase(user);
}
}
@@ -797,8 +800,10 @@ class BSKick : public Module
purger(this)
{
+ me = this;
- ModuleManager::Attach(I_OnPrivmsg, this);
+ Implementation i[] = { I_OnPrivmsg };
+ ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
}
~BSKick()
@@ -920,30 +925,31 @@ class BSKick : public Module
/* Normalize the buffer */
Anope::string nbuf = Anope::NormalizeBuffer(realbuf);
+ bool casesensitive = Config->GetModule("botserv")->Get<bool>("casesensitive");
for (unsigned i = 0, end = ci->GetBadWordCount(); i < end; ++i)
{
const BadWord *bw = ci->GetBadWord(i);
- if (bw->type == BW_ANY && ((Config->BSCaseSensitive && nbuf.find(bw->word) != Anope::string::npos) || (!Config->BSCaseSensitive && nbuf.find_ci(bw->word) != Anope::string::npos)))
+ if (bw->type == BW_ANY && ((casesensitive && nbuf.find(bw->word) != Anope::string::npos) || (!casesensitive && nbuf.find_ci(bw->word) != Anope::string::npos)))
mustkick = true;
else if (bw->type == BW_SINGLE)
{
size_t len = bw->word.length();
- if ((Config->BSCaseSensitive && bw->word.equals_cs(nbuf)) || (!Config->BSCaseSensitive && bw->word.equals_ci(nbuf)))
+ if ((casesensitive && bw->word.equals_cs(nbuf)) || (!casesensitive && bw->word.equals_ci(nbuf)))
mustkick = true;
- else if (nbuf.find(' ') == len && ((Config->BSCaseSensitive && bw->word.equals_cs(nbuf)) || (!Config->BSCaseSensitive && bw->word.equals_ci(nbuf))))
+ else if (nbuf.find(' ') == len && ((casesensitive && bw->word.equals_cs(nbuf)) || (!casesensitive && bw->word.equals_ci(nbuf))))
mustkick = true;
else
{
- if (nbuf.rfind(' ') == nbuf.length() - len - 1 && ((Config->BSCaseSensitive && nbuf.find(bw->word) == nbuf.length() - len) || (!Config->BSCaseSensitive && nbuf.find_ci(bw->word) == nbuf.length() - len)))
+ if (nbuf.rfind(' ') == nbuf.length() - len - 1 && ((casesensitive && nbuf.find(bw->word) == nbuf.length() - len) || (!casesensitive && nbuf.find_ci(bw->word) == nbuf.length() - len)))
mustkick = true;
else
{
Anope::string wordbuf = " " + bw->word + " ";
- if ((Config->BSCaseSensitive && nbuf.find(wordbuf) != Anope::string::npos) || (!Config->BSCaseSensitive && nbuf.find_ci(wordbuf) != Anope::string::npos))
+ if ((casesensitive && nbuf.find(wordbuf) != Anope::string::npos) || (!casesensitive && nbuf.find_ci(wordbuf) != Anope::string::npos))
mustkick = true;
}
}
@@ -952,13 +958,13 @@ class BSKick : public Module
{
size_t len = bw->word.length();
- if ((Config->BSCaseSensitive && nbuf.substr(0, len).equals_cs(bw->word)) || (!Config->BSCaseSensitive && nbuf.substr(0, len).equals_ci(bw->word)))
+ if ((casesensitive && nbuf.substr(0, len).equals_cs(bw->word)) || (!casesensitive && nbuf.substr(0, len).equals_ci(bw->word)))
mustkick = true;
else
{
Anope::string wordbuf = " " + bw->word;
- if ((Config->BSCaseSensitive && nbuf.find(wordbuf) != Anope::string::npos) || (!Config->BSCaseSensitive && nbuf.find_ci(wordbuf) != Anope::string::npos))
+ if ((casesensitive && nbuf.find(wordbuf) != Anope::string::npos) || (!casesensitive && nbuf.find_ci(wordbuf) != Anope::string::npos))
mustkick = true;
}
}
@@ -966,13 +972,13 @@ class BSKick : public Module
{
size_t len = bw->word.length();
- if ((Config->BSCaseSensitive && nbuf.substr(nbuf.length() - len).equals_cs(bw->word)) || (!Config->BSCaseSensitive && nbuf.substr(nbuf.length() - len).equals_ci(bw->word)))
+ if ((casesensitive && nbuf.substr(nbuf.length() - len).equals_cs(bw->word)) || (!casesensitive && nbuf.substr(nbuf.length() - len).equals_ci(bw->word)))
mustkick = true;
else
{
Anope::string wordbuf = bw->word + " ";
- if ((Config->BSCaseSensitive && nbuf.find(wordbuf) != Anope::string::npos) || (!Config->BSCaseSensitive && nbuf.find_ci(wordbuf) != Anope::string::npos))
+ if ((casesensitive && nbuf.find(wordbuf) != Anope::string::npos) || (!casesensitive && nbuf.find_ci(wordbuf) != Anope::string::npos))
mustkick = true;
}
}
@@ -980,7 +986,7 @@ class BSKick : public Module
if (mustkick)
{
check_ban(ci, u, TTB_BADWORDS);
- if (Config->BSGentleBWReason)
+ if (Config->GetModule(me)->Get<bool>("gentlebadwordreason"))
bot_kick(ci, u, _("Watch your language!"));
else
bot_kick(ci, u, _("Don't use the word \"%s\" on this channel!"), bw->word.c_str());
diff --git a/modules/commands/bs_set.cpp b/modules/commands/bs_set.cpp
index 6d764c665..20a53faf3 100644
--- a/modules/commands/bs_set.cpp
+++ b/modules/commands/bs_set.cpp
@@ -48,7 +48,7 @@ class CommandBSSet : public Command
}
}
source.Reply(_("Type \002%s%s HELP %s \037option\037\002 for more information on a\n"
- "particular option."), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str(), this_name.c_str());
+ "particular option."), Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), this_name.c_str());
return true;
}
@@ -309,13 +309,13 @@ class CommandBSSetFantasy : public Command
source.Reply(_(" \n"
"Enables or disables \002fantasy\002 mode on a channel.\n"
"When it is enabled, users will be able to use\n"
- "%s commands on a channel when prefixed\n"
+ "fantasy commands on a channel when prefixed\n"
"with one of the following fantasy characters: \002%s\002\n"
" \n"
"Note that users wanting to use fantaisist\n"
"commands MUST have enough access for both\n"
"the FANTASIA and the command they are executing."),
- Config->ChanServ.c_str(), Config->BSFantasyCharacter.c_str());
+ Config->GetModule("botserv")->Get<const char *>("fantasycharacter", "!"));
return true;
}
};
@@ -495,7 +495,6 @@ class BSSet : public Module
commandbsset(this), commandbssetbanexpire(this), commandbssetdontkickops(this), commandbssetdontkickvoices(this),
commandbssetfantasy(this), commandbssetgreet(this), commandbssetnobot(this), commandbssetprivate(this)
{
-
ModuleManager::Attach(I_OnBotBan, this);
}
diff --git a/modules/commands/cs_access.cpp b/modules/commands/cs_access.cpp
index 90e17eeed..de434337b 100644
--- a/modules/commands/cs_access.cpp
+++ b/modules/commands/cs_access.cpp
@@ -158,9 +158,10 @@ class CommandCSAccess : public Command
}
}
- if (ci->GetAccessCount() >= Config->CSAccessMax)
+ unsigned access_max = Config->GetModule("chanserv")->Get<unsigned>("accessmax", "1024");
+ if (access_max && ci->GetAccessCount() >= access_max)
{
- source.Reply(_("Sorry, you can only have %d access entries on a channel."), Config->CSAccessMax);
+ source.Reply(_("Sorry, you can only have %d access entries on a channel."), access_max);
return;
}
@@ -555,7 +556,7 @@ class CommandCSAccess : public Command
source.Reply(" ");
source.Reply(_("\002User access levels\002 can be seen by using the\n"
"\002LEVELS\002 command; type \002%s%s HELP LEVELS\002 for\n"
- "information."), source.service->nick.c_str(), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str());
+ "information."), source.service->nick.c_str(), Config->StrictPrivmsg.c_str(), source.service->nick.c_str());
return true;
}
};
@@ -590,7 +591,7 @@ class CommandCSLevels : public Command
{
Privilege *p = PrivilegeManager::FindPrivilege(what);
if (p == NULL)
- source.Reply(_("Setting \002%s\002 not known. Type \002%s%s HELP LEVELS\002 for a list of valid settings."), what.c_str(), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str());
+ source.Reply(_("Setting \002%s\002 not known. Type \002%s%s HELP LEVELS\002 for a list of valid settings."), what.c_str(), Config->StrictPrivmsg.c_str(), source.service->nick.c_str());
else
{
ci->SetLevel(p->name, level);
@@ -628,7 +629,7 @@ class CommandCSLevels : public Command
}
}
- source.Reply(_("Setting \002%s\002 not known. Type \002%s%s HELP LEVELS\002 for a list of valid settings."), what.c_str(), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str());
+ source.Reply(_("Setting \002%s\002 not known. Type \002%s%s HELP LEVELS\002 for a list of valid settings."), what.c_str(), Config->StrictPrivmsg.c_str(), source.service->nick.c_str());
return;
}
@@ -792,19 +793,21 @@ class CSAccess : public Module
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
}
- void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override
+ void OnReload(Configuration::Conf *conf) anope_override
{
defaultLevels.clear();
- for (int i = 0; i < reader.Enumerate("privilege"); ++i)
+ for (int i = 0; i < conf->CountBlock("privilege"); ++i)
{
- const Anope::string &pname = reader.ReadValue("privilege", "name", "", i);
+ Configuration::Block *priv = conf->GetBlock("privilege", i);
+
+ const Anope::string &pname = priv->Get<const Anope::string &>("name");
Privilege *p = PrivilegeManager::FindPrivilege(pname);
if (p == NULL)
continue;
- const Anope::string &value = reader.ReadValue("privilege", "level", "", i);
+ const Anope::string &value = priv->Get<const Anope::string &>("level");
if (value.empty())
continue;
else if (value.equals_ci("founder"))
@@ -812,7 +815,7 @@ class CSAccess : public Module
else if (value.equals_ci("disabled"))
defaultLevels[p->name] = ACCESS_INVALID;
else
- defaultLevels[p->name] = reader.ReadInteger("privilege", "level", i, false);
+ defaultLevels[p->name] = priv->Get<int16_t>("level");
}
}
diff --git a/modules/commands/cs_akick.cpp b/modules/commands/cs_akick.cpp
index b2b1c7579..bb1e6ecd6 100644
--- a/modules/commands/cs_akick.cpp
+++ b/modules/commands/cs_akick.cpp
@@ -23,8 +23,9 @@ class CommandCSAKick : public Command
NickCore *nc = NULL;
const AutoKick *akick;
- if (reason.length() > Config->CSReasonMax)
- reason = reason.substr(0, Config->CSReasonMax);
+ unsigned reasonmax = Config->GetModule("chanserv")->Get<unsigned>("reasonmax", "200");
+ if (reason.length() > reasonmax)
+ reason = reason.substr(0, reasonmax);
if (IRCD->IsExtbanValid(mask))
; /* If this is an extban don't try to complete the mask */
@@ -148,9 +149,9 @@ class CommandCSAKick : public Command
}
}
- if (ci->GetAkickCount() >= Config->CSAutokickMax)
+ if (ci->GetAkickCount() >= Config->GetModule(this->owner)->Get<unsigned>("autokickmax"))
{
- source.Reply(_("Sorry, you can only have %d autokick masks on a channel."), Config->CSAutokickMax);
+ source.Reply(_("Sorry, you can only have %d autokick masks on a channel."), Config->GetModule(this->owner)->Get<unsigned>("autokickmax"));
return;
}
@@ -513,7 +514,6 @@ class CSAKick : public Module
CSAKick(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
commandcsakick(this)
{
-
Implementation i[] = { I_OnCheckKick };
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
}
@@ -544,7 +544,11 @@ class CSAKick : public Module
autokick->last_used = Anope::CurTime;
if (!autokick->nc && autokick->mask.find('#') == Anope::string::npos)
mask = autokick->mask;
- reason = autokick->reason.empty() ? Config->CSAutokickReason : autokick->reason;
+ reason = autokick->reason;
+ if (reason.empty())
+ reason = Config->GetModule(this)->Get<const Anope::string &>("autokickreason");
+ if (reason.empty())
+ reason = "User has been banned from the channel";
return EVENT_STOP;
}
}
diff --git a/modules/commands/cs_ban.cpp b/modules/commands/cs_ban.cpp
index 7d441f14d..c3fffecd9 100644
--- a/modules/commands/cs_ban.cpp
+++ b/modules/commands/cs_ban.cpp
@@ -91,8 +91,9 @@ class CommandCSBan : public Command
reason += " " + params[3];
}
- if (reason.length() > Config->CSReasonMax)
- reason = reason.substr(0, Config->CSReasonMax);
+ unsigned reasonmax = Config->GetModule("chanserv")->Get<unsigned>("reasonmax", "200");
+ if (reason.length() > reasonmax)
+ reason = reason.substr(0, reasonmax);
User *u = source.GetUser();
User *u2 = User::Find(target, true);
diff --git a/modules/commands/cs_clone.cpp b/modules/commands/cs_clone.cpp
index da8c82647..e4c1ac7f6 100644
--- a/modules/commands/cs_clone.cpp
+++ b/modules/commands/cs_clone.cpp
@@ -64,31 +64,25 @@ public:
target_ci->name = target;
(*RegisteredChannelList)[target_ci->name] = target_ci;
target_ci->c = Channel::Find(target_ci->name);
+
+ target_ci->bi = NULL;
+ if (ci->bi)
+ ci->bi->Assign(u, target_ci);
+
if (target_ci->c)
{
target_ci->c->ci = target_ci;
target_ci->c->CheckModes();
- ChannelMode *cm;
- if (u && u->FindChannel(target_ci->c) != NULL)
- {
- /* On most ircds you do not receive the admin/owner mode till its registered */
- if ((cm = ModeManager::FindChannelModeByName("OWNER")))
- target_ci->c->SetMode(NULL, cm, u->GetUID());
- else if ((cm = ModeManager::FindChannelModeByName("PROTECT")))
- target_ci->c->RemoveMode(NULL, cm, u->GetUID());
- }
+ target_ci->c->SetCorrectModes(u, true, true);
/* Mark the channel as persistent */
if (target_ci->c->HasMode("PERM"))
target_ci->ExtendMetadata("PERSIST");
/* Persist may be in def cflags, set it here */
- else if (target_ci->HasExt("PERSIST") && (cm = ModeManager::FindChannelModeByName("PERM")))
- target_ci->c->SetMode(NULL, cm);
-
- if (target_ci->bi && target_ci->c->FindUser(target_ci->bi) == NULL)
- target_ci->bi->Join(target_ci->c, &ModeManager::DefaultBotModes);
+ else if (target_ci->HasExt("PERSIST"))
+ target_ci->c->SetMode(NULL, "PERM");
}
if (target_ci->c && !target_ci->c->topic.empty())
diff --git a/modules/commands/cs_entrymsg.cpp b/modules/commands/cs_entrymsg.cpp
index 961cf1895..da764d81c 100644
--- a/modules/commands/cs_entrymsg.cpp
+++ b/modules/commands/cs_entrymsg.cpp
@@ -39,8 +39,6 @@ struct EntryMsg : Serializable
static Serializable* Unserialize(Serializable *obj, Serialize::Data &data);
};
-static unsigned MaxEntries = 0;
-
struct EntryMessageList : Serialize::Checker<std::vector<EntryMsg *> >, ExtensibleItem
{
EntryMessageList() : Serialize::Checker<std::vector<EntryMsg *> >("EntryMsg") { }
@@ -140,7 +138,7 @@ class CommandEntryMessage : public Command
ci->Extend("cs_entrymsg", messages);
}
- if (MaxEntries && (*messages)->size() >= MaxEntries)
+ if ((*messages)->size() >= Config->GetModule(this->owner)->Get<unsigned>("maxentries"))
source.Reply(_("The entry message list for \002%s\002 is full."), ci->name.c_str());
else
{
@@ -276,7 +274,7 @@ class CSEntryMessage : public Module
CSEntryMessage(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), entrymsg_type("EntryMsg", EntryMsg::Unserialize), commandentrymsg(this)
{
- Implementation i[] = { I_OnReload, I_OnJoinChannel };
+ Implementation i[] = { I_OnJoinChannel };
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
}
@@ -291,11 +289,6 @@ class CSEntryMessage : public Module
u->SendMessage(c->ci->WhoSends(), "[%s] %s", c->ci->name.c_str(), (*messages)->at(i)->message.c_str());
}
}
-
- void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override
- {
- MaxEntries = reader.ReadInteger("cs_entrymsg", "maxentries", "5", 0, true);
- }
};
MODULE_INIT(CSEntryMessage)
diff --git a/modules/commands/cs_fantasy_stats.cpp b/modules/commands/cs_fantasy_stats.cpp
index df24710a0..7709a38d3 100644
--- a/modules/commands/cs_fantasy_stats.cpp
+++ b/modules/commands/cs_fantasy_stats.cpp
@@ -77,11 +77,12 @@ class CSStats : public Module
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
}
- void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override
+ void OnReload(Configuration::Conf *conf) anope_override
{
- prefix = reader.ReadValue("chanstats", "prefix", "anope_", 0);
- Anope::string engine = reader.ReadValue("chanstats", "engine", "", 0);
- this->sql = ServiceReference<SQL::Provider>("SQL::Provider", engine);
+ prefix = conf->GetModule(this)->Get<const Anope::string &>("prefix");
+ if (prefix.empty())
+ prefix = "anope_";
+ this->sql = ServiceReference<SQL::Provider>("SQL::Provider", conf->GetModule(this)->Get<const Anope::string &>("engine"));
}
SQL::Result RunQuery(const SQL::Query &query)
diff --git a/modules/commands/cs_fantasy_top.cpp b/modules/commands/cs_fantasy_top.cpp
index 9baceeda3..ef87cd87f 100644
--- a/modules/commands/cs_fantasy_top.cpp
+++ b/modules/commands/cs_fantasy_top.cpp
@@ -102,11 +102,12 @@ class CSTop : public Module
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
}
- void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override
+ void OnReload(Configuration::Conf *conf) anope_override
{
- prefix = reader.ReadValue("chanstats", "prefix", "anope_", 0);
- Anope::string engine = reader.ReadValue("chanstats", "engine", "", 0);
- this->sql = ServiceReference<SQL::Provider>("SQL::Provider", engine);
+ prefix = conf->GetModule(this)->Get<const Anope::string &>("prefix");
+ if (prefix.empty())
+ prefix = "anope_";
+ this->sql = ServiceReference<SQL::Provider>("SQL::Provider", conf->GetModule(this)->Get<const Anope::string &>("engine"));
}
SQL::Result RunQuery(const SQL::Query &query)
diff --git a/modules/commands/cs_flags.cpp b/modules/commands/cs_flags.cpp
index cd1a14e83..8ed4cc8c6 100644
--- a/modules/commands/cs_flags.cpp
+++ b/modules/commands/cs_flags.cpp
@@ -13,6 +13,7 @@
#include "module.h"
+static ServiceReference<ChanServService> chanserv("ChanServService", "ChanServ");
static std::map<Anope::string, char> defaultFlags;
class FlagsChanAccess : public ChanAccess
@@ -113,9 +114,10 @@ class CommandCSFlags : public Command
}
}
- if (ci->GetAccessCount() >= Config->CSAccessMax)
+ unsigned access_max = Config->GetModule("chanserv")->Get<unsigned>("accessmax", "1024");
+ if (access_max && ci->GetAccessCount() >= access_max)
{
- source.Reply(_("Sorry, you can only have %d access entries on a channel."), Config->CSAccessMax);
+ source.Reply(_("Sorry, you can only have %d access entries on a channel."), access_max);
return;
}
@@ -396,19 +398,21 @@ class CSFlags : public Module
ModuleManager::Attach(i, this, 1);
}
- void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override
+ void OnReload(Configuration::Conf *conf) anope_override
{
defaultFlags.clear();
- for (int i = 0; i < reader.Enumerate("privilege"); ++i)
+ for (int i = 0; i < conf->CountBlock("privilege"); ++i)
{
- const Anope::string &pname = reader.ReadValue("privilege", "name", "", i);
+ Configuration::Block *priv = conf->GetBlock("privilege", i);
+
+ const Anope::string &pname = priv->Get<const Anope::string &>("name");
Privilege *p = PrivilegeManager::FindPrivilege(pname);
if (p == NULL)
continue;
- const Anope::string &value = reader.ReadValue("privilege", "flag", "", i);
+ const Anope::string &value = priv->Get<const Anope::string &>("flag");
if (value.empty())
continue;
diff --git a/modules/commands/cs_info.cpp b/modules/commands/cs_info.cpp
index a686541be..e26dc1970 100644
--- a/modules/commands/cs_info.cpp
+++ b/modules/commands/cs_info.cpp
@@ -13,6 +13,8 @@
#include "module.h"
+static ServiceReference<ChanServService> chanserv("ChanServService", "ChanServ");
+
class CommandCSInfo : public Command
{
void CheckOptStr(Anope::string &buf, const Anope::string &opt, const char *str, const ChannelInfo *ci, const NickCore *nc)
@@ -102,8 +104,9 @@ class CommandCSInfo : public Command
if (!ml.empty())
info["Mode lock"] = ml;
- if (!ci->HasExt("NO_EXPIRE"))
- info["Expires on"] = Anope::strftime(ci->last_used + Config->CSExpire);
+ time_t chanserv_expire = Config->GetModule("chanserv")->Get<time_t>("expire", "14d");
+ if (!ci->HasExt("NO_EXPIRE") && chanserv_expire && !Anope::NoExpire)
+ info["Expires on"] = Anope::strftime(ci->last_used + chanserv_expire);
}
if (ci->HasExt("SUSPENDED"))
{
diff --git a/modules/commands/cs_kick.cpp b/modules/commands/cs_kick.cpp
index d7251ec6b..f1a632af3 100644
--- a/modules/commands/cs_kick.cpp
+++ b/modules/commands/cs_kick.cpp
@@ -13,6 +13,8 @@
#include "module.h"
+static ServiceReference<ChanServService> chanserv("ChanServService", "ChanServ");
+
class CommandCSKick : public Command
{
public:
@@ -45,8 +47,9 @@ class CommandCSKick : public Command
return;
}
- if (reason.length() > Config->CSReasonMax)
- reason = reason.substr(0, Config->CSReasonMax);
+ unsigned reasonmax = Config->GetModule("chanserv")->Get<unsigned>("reasonmax", "200");
+ if (reason.length() > reasonmax)
+ reason = reason.substr(0, reasonmax);
AccessGroup u_access = source.AccessFor(ci);
diff --git a/modules/commands/cs_list.cpp b/modules/commands/cs_list.cpp
index 72f3e35dc..5d0f16f60 100644
--- a/modules/commands/cs_list.cpp
+++ b/modules/commands/cs_list.cpp
@@ -68,6 +68,7 @@ class CommandCSList : public Command
}
Anope::string spattern = "#" + pattern;
+ unsigned listmax = Config->GetModule(this->owner)->Get<unsigned>("listmax");
source.Reply(_("List of entries matching \002%s\002:"), pattern.c_str());
@@ -91,7 +92,7 @@ class CommandCSList : public Command
if (pattern.equals_ci(ci->name) || ci->name.equals_ci(spattern) || Anope::Match(ci->name, pattern, false, true) || Anope::Match(ci->name, spattern, false, true))
{
- if (((count + 1 >= from && count + 1 <= to) || (!from && !to)) && ++nchans <= Config->CSListMax)
+ if (((count + 1 >= from && count + 1 <= to) || (!from && !to)) && ++nchans <= listmax)
{
bool isnoexpire = false;
if (is_servadmin && (ci->HasExt("NO_EXPIRE")))
@@ -115,7 +116,7 @@ class CommandCSList : public Command
for (unsigned i = 0; i < replies.size(); ++i)
source.Reply(replies[i]);
- source.Reply(_("End of list - %d/%d matches shown."), nchans > Config->CSListMax ? Config->CSListMax : nchans, nchans);
+ source.Reply(_("End of list - %d/%d matches shown."), nchans > listmax ? listmax : nchans, nchans);
return;
}
@@ -150,11 +151,11 @@ class CommandCSList : public Command
" \002LIST #51-100\002\n"
" Lists all registered channels within the given range (51-100)."));
- if (!Config->RegexEngine.empty())
+ if (!Config->GetBlock("options")->Get<const Anope::string &>("regexengine").empty())
{
source.Reply(" ");
source.Reply(_("Regex matches are also supported using the %s engine.\n"
- "Enclose your pattern in // if this is desired."), Config->RegexEngine.c_str());
+ "Enclose your pattern in // if this is desired."), Config->GetBlock("options")->Get<const char *>("regexengine"));
}
return true;
@@ -168,7 +169,6 @@ class CSList : public Module
public:
CSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandcslist(this)
{
-
}
};
diff --git a/modules/commands/cs_mode.cpp b/modules/commands/cs_mode.cpp
index f1d700cfa..38390251b 100644
--- a/modules/commands/cs_mode.cpp
+++ b/modules/commands/cs_mode.cpp
@@ -391,7 +391,7 @@ class CommandCSMode : public Command
new_params.push_back("-*");
this->DoSet(source, ci, new_params);
}
- else if (param.equals_ci("BANS") || param.equals_ci("EXCEPTS") || param.equals_ci("INVITEOVERRIDES") || param.equals_ci("VOICES") || param.equals_ci("HALFOPS") || param.equals_ci("OPS"))
+ else if (param.equals_ci("BANS") || param.equals_ci("EXEMPTS") || param.equals_ci("INVITEOVERRIDES") || param.equals_ci("VOICES") || param.equals_ci("HALFOPS") || param.equals_ci("OPS"))
{
const Anope::string &mname = param.upper().substr(0, param.length() - 1);
ChannelMode *cm = ModeManager::FindChannelModeByName(mname);
diff --git a/modules/commands/cs_register.cpp b/modules/commands/cs_register.cpp
index 5f31d823c..feeb605bc 100644
--- a/modules/commands/cs_register.cpp
+++ b/modules/commands/cs_register.cpp
@@ -26,6 +26,7 @@ class CommandCSRegister : public Command
{
const Anope::string &chan = params[0];
const Anope::string &chdesc = params.size() > 1 ? params[1] : "";
+ unsigned maxregistered = Config->GetModule("chanserv")->Get<unsigned>("maxregistered");
User *u = source.GetUser();
NickCore *nc = source.nc;
@@ -48,19 +49,14 @@ class CommandCSRegister : public Command
source.Reply(_("Channel \002%s\002 is already registered!"), chan.c_str());
else if (c && !c->HasUserStatus(u, "OP"))
source.Reply(_("You must be a channel operator to register the channel."));
- else if (Config->CSMaxReg && nc->channelcount >= Config->CSMaxReg && !source.HasPriv("chanserv/no-register-limit"))
- source.Reply(nc->channelcount > Config->CSMaxReg ? CHAN_EXCEEDED_CHANNEL_LIMIT : CHAN_REACHED_CHANNEL_LIMIT, Config->CSMaxReg);
+ else if (maxregistered && nc->channelcount >= maxregistered && !source.HasPriv("chanserv/no-register-limit"))
+ source.Reply(nc->channelcount > maxregistered ? CHAN_EXCEEDED_CHANNEL_LIMIT : CHAN_REACHED_CHANNEL_LIMIT, maxregistered);
else
{
ci = new ChannelInfo(chan);
ci->SetFounder(nc);
ci->desc = chdesc;
- for (std::list<std::pair<Anope::string, Anope::string> >::const_iterator it = ModeManager::ModeLockOn.begin(), it_end = ModeManager::ModeLockOn.end(); it != it_end; ++it)
- ci->SetMLock(ModeManager::FindChannelModeByName(it->first), true, it->second, source.GetNick());
- for (std::list<Anope::string>::const_iterator it = ModeManager::ModeLockOff.begin(), it_end = ModeManager::ModeLockOff.end(); it != it_end; ++it)
- ci->SetMLock(ModeManager::FindChannelModeByName(*it), false, "", source.GetNick());
-
if (c && !c->topic.empty())
{
ci->last_topic = c->topic;
@@ -113,9 +109,8 @@ class CommandCSRegister : public Command
"other channel users.\n"
" \n"
"NOTICE: In order to register a channel, you must have\n"
- "first registered your nickname. If you haven't,\n"
- "\002%s%s HELP\002 for information on how to do so."),
- source.service->nick.c_str(), source.service->nick.c_str(), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str());
+ "first registered your nickname."),
+ source.service->nick.c_str(), source.service->nick.c_str(), Config->StrictPrivmsg.c_str(), source.service->nick.c_str());
return true;
}
};
diff --git a/modules/commands/cs_seen.cpp b/modules/commands/cs_seen.cpp
index 2d45f9a15..610ad4475 100644
--- a/modules/commands/cs_seen.cpp
+++ b/modules/commands/cs_seen.cpp
@@ -82,9 +82,6 @@ struct SeenInfo : Serializable
}
};
-static time_t purgetime;
-static time_t expiretimeout;
-
static SeenInfo *FindInfo(const Anope::string &nick)
{
database_map::iterator iter = database.find(nick);
@@ -192,9 +189,9 @@ class CommandSeen : public Command
{
const Anope::string &target = params[0];
- if (target.length() > Config->NickLen)
+ if (target.length() > Config->GetBlock("networkinfo")->Get<unsigned>("nicklen"))
{
- source.Reply(_("Nick too long, max length is %u characters."), Config->NickLen);
+ source.Reply(_("Nick too long, max length is %u characters."), Config->GetBlock("networkinfo")->Get<unsigned>("nicklen"));
return;
}
@@ -300,7 +297,9 @@ class DataBasePurger : public Timer
void Tick(time_t) anope_override
{
- size_t previous_size = database.size();
+ size_t previous_size = database.size(), purgetime = Config->GetModule(this->GetOwner())->Get<time_t>("purgetime");
+ if (!purgetime)
+ purgetime = Anope::DoTime("30d");
for (database_map::iterator it = database.begin(), it_end = database.end(); it != it_end;)
{
database_map::iterator cur = it;
@@ -333,14 +332,15 @@ class CSSeen : public Module
I_OnUserQuit,
I_OnJoinChannel,
I_OnPartChannel,
- I_OnUserKicked };
+ I_OnPreUserKicked };
ModuleManager::Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation));
}
- void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override
+ void OnReload(Configuration::Conf *conf) anope_override
{
- purgetime = Anope::DoTime(reader.ReadValue("cs_seen", "purgetime", "30d", 0));
- expiretimeout = Anope::DoTime(reader.ReadValue("cs_seen", "expiretimeout", "1d", 0));
+ time_t expiretimeout = conf->GetModule(this)->Get<time_t>("expiretimeout");
+ if (!expiretimeout)
+ expiretimeout = Anope::DoTime("1d");
if (purger.GetSecs() != expiretimeout)
purger.SetSecs(expiretimeout);
@@ -373,9 +373,9 @@ class CSSeen : public Module
UpdateUser(u, PART, u->nick, "", channel, msg);
}
- void OnUserKicked(Channel *c, User *target, MessageSource &source, const Anope::string &msg) anope_override
+ void OnPreUserKicked(MessageSource &source, ChanUserContainer *cu, const Anope::string &msg) anope_override
{
- UpdateUser(target, KICK, target->nick, source.GetSource(), c->name, msg);
+ UpdateUser(cu->user, KICK, cu->user->nick, source.GetSource(), cu->chan->name, msg);
}
private:
diff --git a/modules/commands/cs_set.cpp b/modules/commands/cs_set.cpp
index 99b3e3ec5..0de1a39ad 100644
--- a/modules/commands/cs_set.cpp
+++ b/modules/commands/cs_set.cpp
@@ -50,7 +50,7 @@ class CommandCSSet : public Command
}
}
source.Reply(_("Type \002%s%s HELP %s \037option\037\002 for more information on a\n"
- "particular option."), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str(), this_name.c_str());
+ "particular option."), Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), this_name.c_str());
return true;
}
};
@@ -106,8 +106,8 @@ class CommandCSSetAutoOp : public Command
source.Reply(" ");
source.Reply(_("Enables or disables %s's autoop feature for a\n"
"channel. When disabled, users who join the channel will\n"
- "not automatically gain any status from %s."), Config->ChanServ.c_str(),
- Config->ChanServ.c_str(), this->name.c_str());
+ "not automatically gain any status from %s."), ChanServ->nick.c_str(),
+ ChanServ->nick.c_str(), this->name.c_str());
return true;
}
};
@@ -319,7 +319,8 @@ class CommandCSSetFounder : public Command
}
NickCore *nc = na->nc;
- if (Config->CSMaxReg && nc->channelcount >= Config->CSMaxReg && !source.HasPriv("chanserv/no-register-limit"))
+ unsigned max_reg = Config->GetModule("chanserv")->Get<unsigned>("maxregistered");
+ if (max_reg && nc->channelcount >= max_reg && !source.HasPriv("chanserv/no-register-limit"))
{
source.Reply(_("\002%s\002 has too many channels registered."), na->nick.c_str());
return;
@@ -552,7 +553,7 @@ class CommandCSSetPersist : public Command
/* No channel mode, no BotServ, but using ChanServ as the botserv bot
* which was assigned when persist was set on
*/
- if (!cm && Config->BotServ.empty() && ci->bi)
+ if (!cm && !BotServ && ci->bi)
{
if (!ChanServ)
{
@@ -654,7 +655,7 @@ class CommandCSSetPrivate : public Command
source.Reply(_("Enables or disables the \002private\002 option for a channel.\n"
"When \002private\002 is set, a \002%s%s LIST\002 will not\n"
"include the channel in any lists."),
- Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str());
+ Config->StrictPrivmsg.c_str(), source.service->nick.c_str());
return true;
}
};
@@ -1027,10 +1028,12 @@ class CommandCSSetSuccessor : public Command
source.Reply(_("Changes the successor of a channel. If the founder's\n"
"nickname expires or is dropped while the channel is still\n"
"registered, the successor will become the new founder of the\n"
- "channel. However, if the successor already has too many\n"
+ "channel. The new nickname must be a registered one."));
+ unsigned max_reg = Config->GetModule("chanserv")->Get<unsigned>("maxregistered");
+ if (max_reg)
+ source.Reply(_("However, if the successor already has too many\n"
"channels registered (%d), the channel will be dropped\n"
- "instead, just as if no successor had been set. The new\n"
- "nickname must be a registered one."), Config->CSMaxReg);
+ "instead, just as if no successor had been set."), max_reg);
return true;
}
};
@@ -1117,21 +1120,10 @@ class CSSet : public Module
commandcssetsuccessor(this), commandcssetnoexpire(this)
{
- Implementation i[] = { I_OnReload, I_OnChanRegistered, I_OnCheckKick, I_OnDelChan };
+ Implementation i[] = { I_OnCheckKick, I_OnDelChan };
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
}
- void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override
- {
- CSDefChanstats = reader.ReadFlag("chanstats", "CSDefChanstats", "0", 0);
- }
-
- void OnChanRegistered(ChannelInfo *ci) anope_override
- {
- if (CSDefChanstats)
- ci->ExtendMetadata("STATS");
- }
-
EventReturn OnCheckKick(User *u, ChannelInfo *ci, Anope::string &mask, Anope::string &reason) anope_override
{
if (!ci->HasExt("RESTRICTED") || ci->c->MatchesList(u, "EXCEPT"))
diff --git a/modules/commands/cs_set_misc.cpp b/modules/commands/cs_set_misc.cpp
index e74587be1..325b652cd 100644
--- a/modules/commands/cs_set_misc.cpp
+++ b/modules/commands/cs_set_misc.cpp
@@ -142,17 +142,19 @@ class CSSetMisc : public Module
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
}
- void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override
+ void OnReload(Configuration::Conf *conf) anope_override
{
descriptions.clear();
- for (int i = 0; i < reader.Enumerate("command"); ++i)
+ for (int i = 0; i < conf->CountBlock("command"); ++i)
{
- if (reader.ReadValue("command", "command", "", i) != "chanserv/set/misc")
+ Configuration::Block *block = conf->GetBlock("command", i);
+
+ if (block->Get<const Anope::string &>("command") != "chanserv/set/misc")
continue;
- Anope::string cname = reader.ReadValue("command", "name", "", i);
- Anope::string desc = reader.ReadValue("command", "misc_description", "", i);
+ Anope::string cname = block->Get<const Anope::string &>("name");
+ Anope::string desc = block->Get<const Anope::string &>("misc_description");
if (cname.empty() || desc.empty())
continue;
diff --git a/modules/commands/cs_suspend.cpp b/modules/commands/cs_suspend.cpp
index 4927737f6..a26cbacd5 100644
--- a/modules/commands/cs_suspend.cpp
+++ b/modules/commands/cs_suspend.cpp
@@ -27,8 +27,7 @@ class CommandCSSuspend : public Command
const Anope::string &chan = params[0];
Anope::string expiry = params.size() > 1 ? params[1] : "";
Anope::string reason = params.size() > 2 ? params[2] : "";
- time_t expiry_secs = Config->CSSuspendExpire;
-
+ time_t expiry_secs = Config->GetModule(this->owner)->Get<time_t>("expire");
if (!expiry.empty() && expiry[0] != '+')
{
@@ -39,12 +38,6 @@ class CommandCSSuspend : public Command
else
expiry_secs = Anope::DoTime(expiry);
- if (Config->ForceForbidReason && reason.empty())
- {
- this->OnSyntaxError(source, "");
- return;
- }
-
if (Anope::ReadOnly)
source.Reply(READ_ONLY_MODE);
@@ -172,6 +165,8 @@ class CSSuspend : public Module
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
}
+ // cs info output?
+
void OnPreChanExpire(ChannelInfo *ci, bool &expire) anope_override
{
if (!ci->HasExt("SUSPENDED"))
diff --git a/modules/commands/cs_xop.cpp b/modules/commands/cs_xop.cpp
index 8b6bc4bb7..5d0fe9f21 100644
--- a/modules/commands/cs_xop.cpp
+++ b/modules/commands/cs_xop.cpp
@@ -13,6 +13,7 @@
namespace
{
+ ServiceReference<ChanServService> chanserv("ChanServService", "ChanServ");
std::vector<Anope::string> order;
std::map<Anope::string, std::vector<Anope::string> > permissions;
}
@@ -161,9 +162,10 @@ class CommandCSXOP : public Command
}
}
- if (ci->GetAccessCount() >= Config->CSAccessMax)
+ unsigned access_max = Config->GetModule("chanserv")->Get<unsigned>("accessmax", "1024");
+ if (access_max && ci->GetAccessCount() >= access_max)
{
- source.Reply(_("Sorry, you can only have %d %s entries on a channel."), Config->CSAccessMax, source.command.c_str());
+ source.Reply(_("Sorry, you can only have %d %s entries on a channel."), access_max, source.command.c_str());
return;
}
@@ -527,8 +529,8 @@ class CommandCSXOP : public Command
"available. See \002%s%s HELP ACCESS\002 for information\n"
"about the access list, and \002%s%s HELP FLAGS\002 for\n"
"information about the flags based system."),
- Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str(),
- Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str());
+ Config->StrictPrivmsg.c_str(), source.service->nick.c_str(),
+ Config->StrictPrivmsg.c_str(), source.service->nick.c_str());
return true;
}
};
@@ -548,31 +550,32 @@ class CSXOP : public Module
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
}
- void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override
+ void OnReload(Configuration::Conf *conf) anope_override
{
order.clear();
permissions.clear();
-
- for (int i = 0; i < reader.Enumerate("privilege"); ++i)
+ for (int i = 0; i < conf->CountBlock("privilege"); ++i)
{
- const Anope::string &pname = reader.ReadValue("privilege", "name", "", i);
+ Configuration::Block *block = conf->GetBlock("privilege", i);
+ const Anope::string &pname = block->Get<const Anope::string &>("name");
Privilege *p = PrivilegeManager::FindPrivilege(pname);
if (p == NULL)
continue;
- const Anope::string &xop = reader.ReadValue("privilege", "xop", "", i);
- if (xop.empty())
+ const Anope::string &xop = block->Get<const Anope::string &>("xop");
+ if (pname.empty() || xop.empty())
continue;
permissions[xop].push_back(pname);
}
- for (int i = 0; i < reader.Enumerate("command"); ++i)
+ for (int i = 0; i < conf->CountBlock("command"); ++i)
{
- const Anope::string &cname = reader.ReadValue("command", "name", "", i),
- &cserv = reader.ReadValue("command", "command", "", i);
+ Configuration::Block *block = conf->GetBlock("command", i);
+ const Anope::string &cname = block->Get<const Anope::string &>("name"),
+ &cserv = block->Get<const Anope::string &>("command");
if (cname.empty() || cserv != "chanserv/xop")
continue;
diff --git a/modules/commands/help.cpp b/modules/commands/help.cpp
index a55af89ff..eaf45ebf4 100644
--- a/modules/commands/help.cpp
+++ b/modules/commands/help.cpp
@@ -46,6 +46,7 @@ class CommandHelp : public Command
Anope::string source_command = source.command;
const BotInfo *bi = source.service;
const CommandInfo::map &map = source.c ? Config->Fantasy : bi->commands;
+ bool hide_privileged_commands = Config->GetBlock("options")->Get<bool>("hideprivilegedcommands");
if (params.empty() || params[0].equals_ci("ALL"))
{
@@ -73,8 +74,8 @@ class CommandHelp : public Command
ServiceReference<Command> c("Command", info.name);
if (!c)
continue;
- else if (!Config->HidePrivilegedCommands)
- ; // Always show with HidePrivilegedCommands disabled
+ else if (!hide_privileged_commands)
+ ; // Always show with hide_privileged_commands disabled
else if (!c->AllowUnregistered() && !source.GetAccount())
continue;
else if (!info.permission.empty() && !source.HasCommand(info.permission))
@@ -146,8 +147,8 @@ class CommandHelp : public Command
ServiceReference<Command> c("Command", info.name);
if (!c)
continue;
- else if (!Config->HidePrivilegedCommands)
- ; // Always show with HidePrivilegedCommands disabled
+ else if (!hide_privileged_commands)
+ ; // Always show with hide_privileged_commands disabled
else if (!info.permission.empty() && !source.HasCommand(info.permission))
continue;
diff --git a/modules/commands/hs_list.cpp b/modules/commands/hs_list.cpp
index 94533e73d..6bf6d49a9 100644
--- a/modules/commands/hs_list.cpp
+++ b/modules/commands/hs_list.cpp
@@ -55,7 +55,7 @@ class CommandHSList : public Command
}
}
- unsigned display_counter = 0;
+ unsigned display_counter = 0, listmax = Config->GetModule(this->owner)->Get<unsigned>("listmax");
ListFormatter list;
list.AddColumn("Number").AddColumn("Nick").AddColumn("Vhost").AddColumn("Creator").AddColumn("Created");
@@ -68,7 +68,7 @@ class CommandHSList : public Command
if (!key.empty() && key[0] != '#')
{
- if ((Anope::Match(na->nick, key) || Anope::Match(na->GetVhostHost(), key)) && display_counter < Config->NSListMax)
+ if ((Anope::Match(na->nick, key) || Anope::Match(na->GetVhostHost(), key)) && display_counter < listmax)
{
++display_counter;
@@ -90,7 +90,7 @@ class CommandHSList : public Command
* List the host if its in the display range, and not more
* than NSListMax records have been displayed...
**/
- if (((counter >= from && counter <= to) || (!from && !to)) && display_counter < Config->NSListMax)
+ if (((counter >= from && counter <= to) || (!from && !to)) && display_counter < listmax)
{
++display_counter;
ListFormatter::ListEntry entry;
@@ -141,9 +141,7 @@ class CommandHSList : public Command
"entries beginning with \"Rob\"\n"
"If a \037#X-Y\037 style is used, only entries between the range of \002X\002\n"
"and \002Y\002 will be displayed, e.g. \002#1-3\002 will display the first 3\n"
- "nick/vhost entries.\n"
- "The list uses the value of NSListMax as a hard limit for the\n"
- "number of items to display to a operator at any one time."));
+ "nick/vhost entries."));
return true;
}
};
@@ -156,7 +154,6 @@ class HSList : public Module
HSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
commandhslist(this)
{
-
}
};
diff --git a/modules/commands/hs_request.cpp b/modules/commands/hs_request.cpp
index 1e8f2aa82..0c29705ef 100644
--- a/modules/commands/hs_request.cpp
+++ b/modules/commands/hs_request.cpp
@@ -18,12 +18,9 @@
#include "module.h"
#include "memoserv.h"
-static ServiceReference<MemoServService> MemoServService("MemoServService", "MemoServ");
+static ServiceReference<MemoServService> memoserv("MemoServService", "MemoServ");
-static bool HSRequestMemoUser = false;
-static bool HSRequestMemoOper = false;
-
-void req_send_memos(CommandSource &source, const Anope::string &vIdent, const Anope::string &vHost);
+static void req_send_memos(Module *me, CommandSource &source, const Anope::string &vIdent, const Anope::string &vHost);
struct HostRequest : ExtensibleItem, Serializable
{
@@ -114,9 +111,9 @@ class CommandHSRequest : public Command
if (!user.empty())
{
- if (user.length() > Config->UserLen)
+ if (user.length() > Config->GetBlock("networkinfo")->Get<unsigned>("userlen"))
{
- source.Reply(HOST_SET_IDENTTOOLONG, Config->UserLen);
+ source.Reply(HOST_SET_IDENTTOOLONG, Config->GetBlock("networkinfo")->Get<unsigned>("userlen"));
return;
}
else if (!IRCD->CanSetVIdent)
@@ -132,9 +129,9 @@ class CommandHSRequest : public Command
}
}
- if (host.length() > Config->HostLen)
+ if (host.length() > Config->GetBlock("networkinfo")->Get<unsigned>("hostlen"))
{
- source.Reply(HOST_SET_TOOLONG, Config->HostLen);
+ source.Reply(HOST_SET_TOOLONG, Config->GetBlock("networkinfo")->Get<unsigned>("hostlen"));
return;
}
@@ -144,14 +141,14 @@ class CommandHSRequest : public Command
return;
}
- if (HSRequestMemoOper && Config->MSSendDelay > 0 && u && u->lastmemosend + Config->MSSendDelay > Anope::CurTime)
+ time_t send_delay = Config->GetModule("memoserv")->Get<time_t>("senddelay");
+ if (Config->GetModule(this->owner)->Get<bool>("memooper") && send_delay > 0 && u && u->lastmemosend + send_delay > Anope::CurTime)
{
- source.Reply(_("Please wait %d seconds before requesting a new vHost."), Config->MSSendDelay);
+ source.Reply(_("Please wait %d seconds before requesting a new vHost."), send_delay);
u->lastmemosend = Anope::CurTime;
return;
}
-
HostRequest *req = new HostRequest;
req->nick = source.GetNick();
req->ident = user;
@@ -160,10 +157,8 @@ class CommandHSRequest : public Command
na->Extend("hs_request", req);
source.Reply(_("Your vHost has been requested."));
- req_send_memos(source, user, host);
+ req_send_memos(owner, source, user, host);
Log(LOG_COMMAND, source, this) << "to request new vhost " << (!user.empty() ? user + "@" : "") << host;
-
- return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
@@ -198,8 +193,8 @@ class CommandHSActivate : public Command
na->SetVhost(req->ident, req->host, source.GetNick(), req->time);
FOREACH_MOD(I_OnSetVhost, OnSetVhost(na));
- if (HSRequestMemoUser && MemoServService)
- MemoServService->Send(Config->HostServ, na->nick, _("[auto memo] Your requested vHost has been approved."), true);
+ if (Config->GetModule(this->owner)->Get<bool>("memouser") && memoserv)
+ memoserv->Send(HostServ->nick, na->nick, _("[auto memo] Your requested vHost has been approved."), true);
source.Reply(_("vHost for %s has been activated."), na->nick.c_str());
Log(LOG_COMMAND, source, this) << "for " << na->nick << " for vhost " << (!req->ident.empty() ? req->ident + "@" : "") << req->host;
@@ -214,7 +209,7 @@ class CommandHSActivate : public Command
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Activate the requested vHost for the given nick."));
- if (HSRequestMemoUser)
+ if (Config->GetModule(this->owner)->Get<bool>("memouser"))
source.Reply(_("A memo informing the user will also be sent."));
return true;
@@ -242,7 +237,7 @@ class CommandHSReject : public Command
{
na->Shrink("hs_request");
- if (HSRequestMemoUser && MemoServService)
+ if (Config->GetModule(this->owner)->Get<bool>("memouser") && memoserv)
{
Anope::string message;
if (!reason.empty())
@@ -250,7 +245,7 @@ class CommandHSReject : public Command
else
message = _("[auto memo] Your requested vHost has been rejected.");
- MemoServService->Send(Config->HostServ, nick, message, true);
+ memoserv->Send(HostServ->nick, nick, message, true);
}
source.Reply(_("vHost for %s has been rejected."), nick.c_str());
@@ -267,7 +262,7 @@ class CommandHSReject : public Command
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Reject the requested vHost for the given nick."));
- if (HSRequestMemoUser)
+ if (Config->GetModule(this->owner)->Get<bool>("memouser"))
source.Reply(_("A memo informing the user will also be sent."));
return true;
@@ -280,7 +275,7 @@ class CommandHSWaiting : public Command
{
int counter = 1;
int from = 0, to = 0;
- unsigned display_counter = 0;
+ unsigned display_counter = 0, listmax = Config->GetModule(this->owner)->Get<unsigned>("listmax");
ListFormatter list;
list.AddColumn("Number").AddColumn("Nick").AddColumn("Vhost").AddColumn("Created");
@@ -292,7 +287,7 @@ class CommandHSWaiting : public Command
if (!hr)
continue;
- if (((counter >= from && counter <= to) || (!from && !to)) && display_counter < Config->NSListMax)
+ if (((counter >= from && counter <= to) || (!from && !to)) && display_counter < listmax)
{
++display_counter;
@@ -353,9 +348,6 @@ class HSRequest : public Module
if (!IRCD || !IRCD->CanSetVHost)
throw ModuleException("Your IRCd does not support vhosts");
-
- Implementation i[] = { I_OnReload };
- ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
}
~HSRequest()
@@ -366,15 +358,9 @@ class HSRequest : public Module
na->Shrink("hs_request");
}
}
-
- void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override
- {
- HSRequestMemoUser = reader.ReadFlag("hs_request", "memouser", "no", 0);
- HSRequestMemoOper = reader.ReadFlag("hs_request", "memooper", "no", 0);
- }
};
-void req_send_memos(CommandSource &source, const Anope::string &vIdent, const Anope::string &vHost)
+static void req_send_memos(Module *me, CommandSource &source, const Anope::string &vIdent, const Anope::string &vHost)
{
Anope::string host;
std::list<std::pair<Anope::string, Anope::string> >::iterator it, it_end;
@@ -384,7 +370,7 @@ void req_send_memos(CommandSource &source, const Anope::string &vIdent, const An
else
host = vHost;
- if (HSRequestMemoOper == 1 && MemoServService)
+ if (Config->GetModule(me)->Get<bool>("memooper") && memoserv)
for (unsigned i = 0; i < Config->Opers.size(); ++i)
{
Oper *o = Config->Opers[i];
@@ -395,7 +381,7 @@ void req_send_memos(CommandSource &source, const Anope::string &vIdent, const An
Anope::string message = Anope::printf(_("[auto memo] vHost \002%s\002 has been requested by %s."), host.c_str(), source.GetNick().c_str());
- MemoServService->Send(Config->HostServ, na->nick, message, true);
+ memoserv->Send(HostServ->nick, na->nick, message, true);
}
}
diff --git a/modules/commands/hs_set.cpp b/modules/commands/hs_set.cpp
index 4adc86897..8e83ae8a8 100644
--- a/modules/commands/hs_set.cpp
+++ b/modules/commands/hs_set.cpp
@@ -67,9 +67,9 @@ class CommandHSSet : public Command
}
}
- if (host.length() > Config->HostLen)
+ if (host.length() > Config->GetBlock("networkinfo")->Get<unsigned>("hostlen"))
{
- source.Reply(HOST_SET_TOOLONG, Config->HostLen);
+ source.Reply(HOST_SET_TOOLONG, Config->GetBlock("networkinfo")->Get<unsigned>("hostlen"));
return;
}
@@ -168,9 +168,9 @@ class CommandHSSetAll : public Command
}
}
- if (host.length() > Config->HostLen)
+ if (host.length() > Config->GetBlock("networkinfo")->Get<unsigned>("hostlen"))
{
- source.Reply(HOST_SET_TOOLONG, Config->HostLen);
+ source.Reply(HOST_SET_TOOLONG, Config->GetBlock("networkinfo")->Get<unsigned>("hostlen"));
return;
}
diff --git a/modules/commands/ms_read.cpp b/modules/commands/ms_read.cpp
index c98708724..0d269bd02 100644
--- a/modules/commands/ms_read.cpp
+++ b/modules/commands/ms_read.cpp
@@ -71,10 +71,13 @@ class MemoListCallback : public NumberList
static void DoRead(CommandSource &source, MemoInfo *mi, const ChannelInfo *ci, unsigned index)
{
Memo *m = mi->GetMemo(index);
+ if (!m)
+ return;
+
if (ci)
- source.Reply(_("Memo %d from %s (%s). To delete, type: \002%s%s DEL %s %d\002"), index + 1, m->sender.c_str(), Anope::strftime(m->time).c_str(), Config->UseStrictPrivMsgString.c_str(), Config->MemoServ.c_str(), ci->name.c_str(), index + 1);
+ source.Reply(_("Memo %d from %s (%s). To delete, type: \002%s%s DEL %s %d\002"), index + 1, m->sender.c_str(), Anope::strftime(m->time).c_str(), Config->StrictPrivmsg.c_str(), MemoServ->nick.c_str(), ci->name.c_str(), index + 1);
else
- source.Reply(_("Memo %d from %s (%s). To delete, type: \002%s%s DEL %d\002"), index + 1, m->sender.c_str(), Anope::strftime(m->time).c_str(), Config->UseStrictPrivMsgString.c_str(), Config->MemoServ.c_str(), index + 1);
+ source.Reply(_("Memo %d from %s (%s). To delete, type: \002%s%s DEL %d\002"), index + 1, m->sender.c_str(), Anope::strftime(m->time).c_str(), Config->StrictPrivmsg.c_str(), MemoServ->nick.c_str(), index + 1);
source.Reply("%s", m->text.c_str());
m->unread = false;
diff --git a/modules/commands/ms_rsend.cpp b/modules/commands/ms_rsend.cpp
index bbfb50117..19a20a279 100644
--- a/modules/commands/ms_rsend.cpp
+++ b/modules/commands/ms_rsend.cpp
@@ -14,7 +14,10 @@
#include "module.h"
#include "memoserv.h"
-static ServiceReference<MemoServService> MemoServService("MemoServService", "MemoServ");
+namespace
+{
+ ServiceReference<MemoServService> memoserv("MemoServService", "MemoServ");
+}
class CommandMSRSend : public Command
{
@@ -27,10 +30,9 @@ class CommandMSRSend : public Command
void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
{
- if (!MemoServService)
+ if (!memoserv)
return;
-
const Anope::string &nick = params[0];
const Anope::string &text = params[1];
const NickAlias *na = NULL;
@@ -42,20 +44,15 @@ class CommandMSRSend : public Command
return;
}
- if (Config->MSMemoReceipt == 1 && !source.IsServicesOper())
+ if (Config->GetModule(this->owner)->Get<bool>("operonly") && !source.IsServicesOper())
source.Reply(ACCESS_DENIED);
- else if (Config->MSMemoReceipt > 2 || Config->MSMemoReceipt == 0)
- {
- Log(this->owner) << "MSMemoReceipt is misconfigured to " << Config->MSMemoReceipt;
- source.Reply(_("Sorry, RSEND has been disabled on this network."));
- }
else
{
- MemoServService::MemoResult result = MemoServService->Send(source.GetNick(), nick, text);
+ MemoServService::MemoResult result = memoserv->Send(source.GetNick(), nick, text);
if (result == MemoServService::MEMO_INVALID_TARGET)
source.Reply(_("\002%s\002 is not a registered unforbidden nick or channel."), nick.c_str());
else if (result == MemoServService::MEMO_TOO_FAST)
- source.Reply(_("Please wait %d seconds before using the SEND command again."), Config->MSSendDelay);
+ source.Reply(_("Please wait %d seconds before using the %s command again."), Config->GetModule("memoserv")->Get<time_t>("senddelay"), source.command.c_str());
else if (result == MemoServService::MEMO_TARGET_FULL)
source.Reply(_("Sorry, %s currently has too many memos and cannot receive more."), nick.c_str());
else
@@ -71,8 +68,6 @@ class CommandMSRSend : public Command
m->receipt = true;
}
}
-
- return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
@@ -98,11 +93,8 @@ class MSRSend : public Module
MSRSend(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
commandmsrsend(this)
{
-
- if (!MemoServService)
+ if (!memoserv)
throw ModuleException("No MemoServ!");
- else if (!Config->MSMemoReceipt)
- throw ModuleException("Invalid value for memoreceipt");
}
};
diff --git a/modules/commands/ms_send.cpp b/modules/commands/ms_send.cpp
index 15ca4a6ba..18a609893 100644
--- a/modules/commands/ms_send.cpp
+++ b/modules/commands/ms_send.cpp
@@ -39,11 +39,9 @@ class CommandMSSend : public Command
else if (result == MemoServService::MEMO_INVALID_TARGET)
source.Reply(_("\002%s\002 is not a registered unforbidden nick or channel."), nick.c_str());
else if (result == MemoServService::MEMO_TOO_FAST)
- source.Reply(_("Please wait %d seconds before using the SEND command again."), Config->MSSendDelay);
+ source.Reply(_("Please wait %d seconds before using the %s command again."), Config->GetModule("memoserv")->Get<time_t>("senddelay"), source.command.c_str());
else if (result == MemoServService::MEMO_TARGET_FULL)
source.Reply(_("Sorry, %s currently has too many memos and cannot receive more."), nick.c_str());
-
- return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
diff --git a/modules/commands/ms_set.cpp b/modules/commands/ms_set.cpp
index b0a2fb8ba..dafb5a857 100644
--- a/modules/commands/ms_set.cpp
+++ b/modules/commands/ms_set.cpp
@@ -13,6 +13,11 @@
#include "module.h"
+namespace
+{
+ ServiceReference<MemoServService> memoserv("MemoServService", "MemoServ");
+}
+
class CommandMSSet : public Command
{
private:
@@ -25,19 +30,19 @@ class CommandMSSet : public Command
{
nc->ExtendMetadata("MEMO_SIGNON");
nc->ExtendMetadata("MEMO_RECEIVE");
- source.Reply(_("%s will now notify you of memos when you log on and when they are sent to you."), Config->MemoServ.c_str());
+ source.Reply(_("%s will now notify you of memos when you log on and when they are sent to you."), MemoServ->nick.c_str());
}
else if (param.equals_ci("LOGON"))
{
nc->ExtendMetadata("MEMO_SIGNON");
nc->Shrink("MEMO_RECEIVE");
- source.Reply(_("%s will now notify you of memos when you log on or unset /AWAY."), Config->MemoServ.c_str());
+ source.Reply(_("%s will now notify you of memos when you log on or unset /AWAY."), MemoServ->nick.c_str());
}
else if (param.equals_ci("NEW"))
{
nc->Shrink("MEMO_SIGNON");
nc->ExtendMetadata("MEMO_RECEIVE");
- source.Reply(_("%s will now notify you of memos when they are sent to you."), Config->MemoServ.c_str());
+ source.Reply(_("%s will now notify you of memos when they are sent to you."), MemoServ->nick.c_str());
}
else if (param.equals_ci("MAIL"))
{
@@ -59,7 +64,7 @@ class CommandMSSet : public Command
nc->Shrink("MEMO_SIGNON");
nc->Shrink("MEMO_RECEIVE");
nc->Shrink("MEMO_MAIL");
- source.Reply(_("%s will not send you any notification of memos."), Config->MemoServ.c_str());
+ source.Reply(_("%s will not send you any notification of memos."), MemoServ->nick.c_str());
}
else
this->OnSyntaxError(source, "");
@@ -158,6 +163,7 @@ class CommandMSSet : public Command
source.Reply(_("You are not permitted to change your memo limit."));
return;
}
+ int max_memos = Config->GetModule("memoserv")->Get<int>("maxmemos");
limit = -1;
try
{
@@ -166,12 +172,12 @@ class CommandMSSet : public Command
catch (const ConvertException &) { }
/* The first character is a digit, but we could still go negative
* from overflow... watch out! */
- if (limit < 0 || (Config->MSMaxMemos > 0 && static_cast<unsigned>(limit) > Config->MSMaxMemos))
+ if (limit < 0 || (max_memos > 0 && limit > max_memos))
{
if (!chan.empty())
- source.Reply(_("You cannot set the memo limit for %s higher than %d."), chan.c_str(), Config->MSMaxMemos);
+ source.Reply(_("You cannot set the memo limit for %s higher than %d."), chan.c_str(), max_memos);
else
- source.Reply(_("You cannot set your memo limit higher than %d."), Config->MSMaxMemos);
+ source.Reply(_("You cannot set your memo limit higher than %d."), max_memos);
return;
}
}
@@ -239,7 +245,7 @@ class CommandMSSet : public Command
" receive\n"
" \n"
"Type \002%s%s HELP %s \037option\037\002 for more information\n"
- "on a specific option."), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str(), source.command.c_str());
+ "on a specific option."), Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), source.command.c_str());
}
else if (subcommand.equals_ci("NOTIFY"))
source.Reply(_("Syntax: \002NOTIFY {ON | LOGON | NEW | MAIL | NOMAIL | OFF}\002\n"
@@ -260,6 +266,7 @@ class CommandMSSet : public Command
"\002ON\002 is essentially \002LOGON\002 and \002NEW\002 combined."));
else if (subcommand.equals_ci("LIMIT"))
{
+ int max_memos = Config->GetModule("memoserv")->Get<int>("maxmemos");
if (source.IsServicesOper())
source.Reply(_("Syntax: \002LIMIT [\037user\037 | \037channel\037] {\037limit\037 | NONE} [HARD]\002\n"
" \n"
@@ -278,14 +285,14 @@ class CommandMSSet : public Command
"\002Admins\002. Other users may only enter a limit for themselves\n"
"or a channel on which they have such privileges, may not\n"
"remove their limit, may not set a limit above %d, and may\n"
- "not set a hard limit."), Config->MSMaxMemos);
+ "not set a hard limit."), max_memos);
else
source.Reply(_("Syntax: \002LIMIT [\037channel\037] \037limit\037\002\n"
" \n"
"Sets the maximum number of memos you (or the given channel)\n"
"are allowed to have. If you set this to 0, no one will be\n"
"able to send any memos to you. However, you cannot set\n"
- "this any higher than %d."), Config->MSMaxMemos);
+ "this any higher than %d."), max_memos);
}
else
return false;
diff --git a/modules/commands/ns_access.cpp b/modules/commands/ns_access.cpp
index a026314e0..7de20b9b7 100644
--- a/modules/commands/ns_access.cpp
+++ b/modules/commands/ns_access.cpp
@@ -13,6 +13,8 @@
#include "module.h"
+static ServiceReference<NickServService> nickserv("NickServService", "NickServ");
+
class CommandNSAccess : public Command
{
private:
@@ -24,9 +26,9 @@ class CommandNSAccess : public Command
return;
}
- if (nc->access.size() >= Config->NSAccessMax)
+ if (nc->access.size() >= Config->GetModule(this->owner)->Get<unsigned>("accessmax"))
{
- source.Reply(_("Sorry, you can only have %d access entries for a nickname."), Config->NSAccessMax);
+ source.Reply(_("Sorry, you can only have %d access entries for a nickname."), Config->GetModule(this->owner)->Get<unsigned>("accessmax"));
return;
}
@@ -119,7 +121,7 @@ class CommandNSAccess : public Command
source.Reply(ACCESS_DENIED);
return;
}
- else if (Config->NSSecureAdmins && source.GetAccount() != na->nc && na->nc->IsServicesOper() && !cmd.equals_ci("LIST"))
+ else if (Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && source.GetAccount() != na->nc && na->nc->IsServicesOper() && !cmd.equals_ci("LIST"))
{
source.Reply(_("You may view but not modify the access list of other Services Operators."));
return;
@@ -133,7 +135,7 @@ class CommandNSAccess : public Command
if (!mask.empty() && (mask.find('@') == Anope::string::npos || mask.find('!') != Anope::string::npos))
{
source.Reply(BAD_USERHOST_MASK);
- source.Reply(MORE_INFO, Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str(), this->name.c_str());
+ source.Reply(MORE_INFO, Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), source.command.c_str());
}
else if (nc->HasExt("SUSPENDED"))
source.Reply(NICK_X_SUSPENDED, nc->display.c_str());
@@ -145,8 +147,6 @@ class CommandNSAccess : public Command
return this->DoList(source, nc, mask);
else
this->OnSyntaxError(source, "");
-
- return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
@@ -171,7 +171,7 @@ class CommandNSAccess : public Command
" Reverses the previous command.\n"
" \n"
" \002ACCESS LIST\002\n"
- " Displays the current access list."), Config->NickServ.c_str(), Config->NickServ.c_str());
+ " Displays the current access list."), source.service->nick.c_str(), source.service->nick.c_str());
return true;
}
};
@@ -184,7 +184,14 @@ class NSAccess : public Module
NSAccess(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
commandnsaccess(this)
{
+ Implementation i[] = { I_OnNickRegister };
+ ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
+ }
+ void OnNickRegister(User *u, NickAlias *na) anope_override
+ {
+ if (u && Config->GetModule(this)->Get<bool>("addaccessonreg"))
+ na->nc->AddAccess(u->Mask());
}
};
diff --git a/modules/commands/ns_ajoin.cpp b/modules/commands/ns_ajoin.cpp
index d427e9cf3..ba7e53912 100644
--- a/modules/commands/ns_ajoin.cpp
+++ b/modules/commands/ns_ajoin.cpp
@@ -133,7 +133,7 @@ class CommandNSAJoin : public Command
if ((*channels)->at(i)->channel.equals_ci(chan))
break;
- if (*source.nc == nc && (*channels)->size() >= Config->AJoinMax)
+ if (*source.nc == nc && (*channels)->size() >= Config->GetModule(this->owner)->Get<unsigned>("ajoinmax"))
source.Reply(_("Your auto join list is full."));
else if (i != (*channels)->size())
source.Reply(_("%s is already on %s's auto join list."), chan.c_str(), nc->display.c_str());
diff --git a/modules/commands/ns_cert.cpp b/modules/commands/ns_cert.cpp
index 1191aaa9b..71836481a 100644
--- a/modules/commands/ns_cert.cpp
+++ b/modules/commands/ns_cert.cpp
@@ -13,6 +13,8 @@
#include "module.h"
+static unsigned accessmax;
+
class CommandNSCert : public Command
{
private:
@@ -54,9 +56,9 @@ class CommandNSCert : public Command
void DoAdd(CommandSource &source, NickCore *nc, const Anope::string &mask)
{
- if (nc->cert.size() >= Config->NSAccessMax)
+ if (nc->cert.size() >= Config->GetModule(this->owner)->Get<unsigned>("accessmax"))
{
- source.Reply(_("Sorry, you can only have %d certificate entries for a nickname."), Config->NSAccessMax);
+ source.Reply(_("Sorry, you can only have %d certificate entries for a nickname."), Config->GetModule(this->owner)->Get<unsigned>("accessmax"));
return;
}
@@ -179,7 +181,7 @@ class CommandNSCert : public Command
"If you connect to IRC and provide a client certificate with a\n"
"matching fingerprint in the cert list, your nick will be\n"
"automatically identified to %s.\n"
- " \n"), Config->NickServ.c_str(), Config->NickServ.c_str());
+ " \n"), NickServ ? NickServ->nick.c_str() : source.service->nick.c_str());
source.Reply(_("Examples:\n"
" \n"
" \002CERT ADD <fingerprint>\002\n"
@@ -191,7 +193,7 @@ class CommandNSCert : public Command
" Reverses the previous command.\n"
" \n"
" \002CERT LIST\002\n"
- " Displays the current certificate list."), Config->NickServ.c_str());
+ " Displays the current certificate list."));
return true;
}
};
diff --git a/modules/commands/ns_drop.cpp b/modules/commands/ns_drop.cpp
index 047770f89..023d696f6 100644
--- a/modules/commands/ns_drop.cpp
+++ b/modules/commands/ns_drop.cpp
@@ -13,6 +13,8 @@
#include "module.h"
+static ServiceReference<NickServService> nickserv("NickServService", "NickServ");
+
class CommandNSDrop : public Command
{
public:
@@ -43,7 +45,7 @@ class CommandNSDrop : public Command
if (!is_mine && !source.HasPriv("nickserv/drop"))
source.Reply(ACCESS_DENIED);
- else if (Config->NSSecureAdmins && !is_mine && na->nc->IsServicesOper())
+ else if (Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && !is_mine && na->nc->IsServicesOper())
source.Reply(_("You may not drop other Services Operators' nicknames."));
else
{
diff --git a/modules/commands/ns_getpass.cpp b/modules/commands/ns_getpass.cpp
index aad6fb55b..a99181b3f 100644
--- a/modules/commands/ns_getpass.cpp
+++ b/modules/commands/ns_getpass.cpp
@@ -13,6 +13,8 @@
#include "module.h"
+static ServiceReference<NickServService> nickserv("NickServService", "NickServ");
+
class CommandNSGetPass : public Command
{
public:
@@ -30,7 +32,7 @@ class CommandNSGetPass : public Command
if (!(na = NickAlias::Find(nick)))
source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
- else if (Config->NSSecureAdmins && na->nc->IsServicesOper())
+ else if (Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && na->nc->IsServicesOper())
source.Reply(_("You may not get the password of other Services Operators."));
else
{
diff --git a/modules/commands/ns_group.cpp b/modules/commands/ns_group.cpp
index 090b47fd4..cca6cd91c 100644
--- a/modules/commands/ns_group.cpp
+++ b/modules/commands/ns_group.cpp
@@ -13,6 +13,8 @@
#include "module.h"
+static ServiceReference<NickServService> nickserv("NickServService", "NickServ");
+
class NSGroupRequest : public IdentifyRequest
{
CommandSource source;
@@ -46,7 +48,7 @@ class NSGroupRequest : public IdentifyRequest
u->Login(target->nc);
IRCD->SendLogin(u);
- if (!Config->NoNicknameOwnership && na->nc == u->Account() && na->nc->HasExt("UNCONFIRMED") == false)
+ if (!Config->GetBlock("options")->Get<bool>("nonicknameownership") && na->nc == u->Account() && na->nc->HasExt("UNCONFIRMED") == false)
u->SetMode(NickServ, "REGISTERED");
FOREACH_MOD(I_OnNickGroup, OnNickGroup(u, target));
@@ -102,7 +104,7 @@ class CommandNSGroup : public Command
return;
}
- if (Config->RestrictOperNicks)
+ if (Config->GetBlock("nickserv")->Get<bool>("restrictopernicks"))
for (unsigned i = 0; i < Config->Opers.size(); ++i)
{
Oper *o = Config->Opers[i];
@@ -115,10 +117,12 @@ class CommandNSGroup : public Command
}
NickAlias *target, *na = NickAlias::Find(u->nick);
+ const Anope::string &guestnick = Config->GetBlock("options")->Get<const Anope::string &>("guestnickprefix");
+ time_t reg_delay = Config->GetModule("nickserv")->Get<time_t>("regdelay");
if (!(target = NickAlias::Find(nick)))
source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
- else if (Anope::CurTime < u->lastnickreg + Config->NSRegDelay)
- source.Reply(_("Please wait %d seconds before using the GROUP command again."), (Config->NSRegDelay + u->lastnickreg) - Anope::CurTime);
+ else if (Anope::CurTime < u->lastnickreg + reg_delay)
+ source.Reply(_("Please wait %d seconds before using the GROUP command again."), (reg_delay + u->lastnickreg) - Anope::CurTime);
else if (target->nc->HasExt("SUSPENDED"))
{
Log(LOG_COMMAND, source, this) << "tried to use GROUP for SUSPENDED nick " << target->nick;
@@ -127,14 +131,14 @@ class CommandNSGroup : public Command
else if (na && *target->nc == *na->nc)
source.Reply(_("You are already a member of the group of \002%s\002."), target->nick.c_str());
else if (na && na->nc != u->Account())
- source.Reply(NICK_IDENTIFY_REQUIRED, Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str());
- else if (na && Config->NSNoGroupChange)
+ source.Reply(NICK_IDENTIFY_REQUIRED, Config->StrictPrivmsg.c_str(), NickServ->nick.c_str());
+ else if (na && Config->GetModule(this->owner)->Get<bool>("nogroupchange"))
source.Reply(_("Your nick is already registered."));
- else if (Config->NSMaxAliases && (target->nc->aliases->size() >= Config->NSMaxAliases) && !target->nc->IsServicesOper())
- source.Reply(_("There are too many nicks in %s's group."));
- else if (u->nick.length() <= Config->NSGuestNickPrefix.length() + 7 &&
- u->nick.length() >= Config->NSGuestNickPrefix.length() + 1 &&
- !u->nick.find_ci(Config->NSGuestNickPrefix) && !u->nick.substr(Config->NSGuestNickPrefix.length()).find_first_not_of("1234567890"))
+ else if (target->nc->aliases->size() >= Config->GetModule(this->owner)->Get<unsigned>("maxaliases") && !target->nc->IsServicesOper())
+ source.Reply(_("There are too many nicks in your group."));
+ else if (u->nick.length() <= guestnick.length() + 7 &&
+ u->nick.length() >= guestnick.length() + 1 &&
+ !u->nick.find_ci(guestnick) && !u->nick.substr(guestnick.length()).find_first_not_of("1234567890"))
{
source.Reply(NICK_CANNOT_BE_REGISTERED, u->nick.c_str());
}
@@ -289,7 +293,7 @@ class CommandNSGList : public Command
}
else if (na->nc != source.GetAccount() && !source.IsServicesOper())
{
- source.Reply(ACCESS_DENIED, Config->NickServ.c_str());
+ source.Reply(ACCESS_DENIED);
return;
}
@@ -300,13 +304,14 @@ class CommandNSGList : public Command
ListFormatter list;
list.AddColumn("Nick").AddColumn("Expires");
+ time_t nickserv_expire = Config->GetModule("nickserv")->Get<time_t>("expire");
for (unsigned i = 0; i < nc->aliases->size(); ++i)
{
const NickAlias *na2 = nc->aliases->at(i);
ListFormatter::ListEntry entry;
entry["Nick"] = na2->nick;
- entry["Expires"] = (na2->HasExt("NO_EXPIRE") || !Config->NSExpire) ? "Does not expire" : ("expires in " + Anope::strftime(na2->last_seen + Config->NSExpire));
+ entry["Expires"] = (na2->HasExt("NO_EXPIRE") || !nickserv_expire || Anope::NoExpire) ? "Does not expire" : ("expires in " + Anope::strftime(na2->last_seen + nickserv_expire));
list.AddEntry(entry);
}
@@ -351,8 +356,7 @@ class NSGroup : public Module
NSGroup(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
commandnsgroup(this), commandnsungroup(this), commandnsglist(this)
{
-
- if (Config->NoNicknameOwnership)
+ if (Config->GetBlock("options")->Get<bool>("nonicknameownership"))
throw ModuleException(modname + " can not be used with options:nonicknameownership enabled");
}
};
diff --git a/modules/commands/ns_info.cpp b/modules/commands/ns_info.cpp
index 171937730..3e946a1f1 100644
--- a/modules/commands/ns_info.cpp
+++ b/modules/commands/ns_info.cpp
@@ -13,6 +13,8 @@
#include "module.h"
+static ServiceReference<NickServService> nickserv("NickServService", "NickServ");
+
class CommandNSInfo : public Command
{
private:
@@ -126,13 +128,15 @@ class CommandNSInfo : public Command
if (na->nc->HasExt("UNCONFIRMED") == false)
{
- if (na->HasExt("NO_EXPIRE") || !Config->NSExpire)
- ;
- else
- info[_("Expires")] = Anope::strftime(na->last_seen + Config->NSExpire);
+ time_t nickserv_expire = Config->GetModule("nickserv")->Get<time_t>("expire");
+ if (!na->HasExt("NO_EXPIRE") && nickserv_expire && !Anope::NoExpire)
+ info[_("Expires")] = Anope::strftime(na->last_seen + nickserv_expire);
}
else
- info[_("Expires")] = Anope::strftime(na->time_registered + Config->NSUnconfirmedExpire);
+ {
+ time_t unconfirmed_expire = Config->GetModule("nickserv")->Get<time_t>("unconfirmedexpire", "1d");
+ info[_("Expires")] = Anope::strftime(na->time_registered + unconfirmed_expire);
+ }
}
FOREACH_MOD(I_OnNickInfo, OnNickInfo(source, na, info, show_hidden));
diff --git a/modules/commands/ns_list.cpp b/modules/commands/ns_list.cpp
index d1887f287..88d5929eb 100644
--- a/modules/commands/ns_list.cpp
+++ b/modules/commands/ns_list.cpp
@@ -31,6 +31,7 @@ class CommandNSList : public Command
bool is_servadmin = source.HasCommand("nickserv/list");
int count = 0, from = 0, to = 0;
bool suspended, nsnoexpire, unconfirmed;
+ unsigned listmax = Config->GetModule(this->owner)->Get<unsigned>("listmax");
suspended = nsnoexpire = unconfirmed = false;
@@ -99,7 +100,7 @@ class CommandNSList : public Command
Anope::string buf = Anope::printf("%s!%s", na->nick.c_str(), !na->last_usermask.empty() ? na->last_usermask.c_str() : "*@*");
if (na->nick.equals_ci(pattern) || Anope::Match(buf, pattern, false, true))
{
- if (((count + 1 >= from && count + 1 <= to) || (!from && !to)) && ++nnicks <= Config->NSListMax)
+ if (((count + 1 >= from && count + 1 <= to) || (!from && !to)) && ++nnicks <= listmax)
{
bool isnoexpire = false;
if (is_servadmin && na->HasExt("NO_EXPIRE"))
@@ -129,7 +130,7 @@ class CommandNSList : public Command
for (unsigned i = 0; i < replies.size(); ++i)
source.Reply(replies[i]);
- source.Reply(_("End of list - %d/%d matches shown."), nnicks > Config->NSListMax ? Config->NSListMax : nnicks, nnicks);
+ source.Reply(_("End of list - %d/%d matches shown."), nnicks > listmax ? listmax : nnicks, nnicks);
return;
}
@@ -166,11 +167,12 @@ class CommandNSList : public Command
" \002LIST #51-100\002\n"
" Lists all registered nicks within the given range (51-100)."));
- if (!Config->RegexEngine.empty())
+ const Anope::string &regexengine = Config->GetBlock("options")->Get<const Anope::string &>("regexengine");
+ if (!regexengine.empty())
{
source.Reply(" ");
source.Reply(_("Regex matches are also supported using the %s engine.\n"
- "Enclose your pattern in // if this is desired."), Config->RegexEngine.c_str());
+ "Enclose your pattern in // if this is desired."), regexengine.c_str());
}
return true;
@@ -185,7 +187,6 @@ class NSList : public Module
NSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
commandnslist(this)
{
-
}
};
diff --git a/modules/commands/ns_recover.cpp b/modules/commands/ns_recover.cpp
index 669d26da9..845c98915 100644
--- a/modules/commands/ns_recover.cpp
+++ b/modules/commands/ns_recover.cpp
@@ -13,6 +13,11 @@
#include "module.h"
+namespace
+{
+ bool restoreonrecover;
+}
+
struct NSRecoverExtensibleInfo : ExtensibleItem, std::map<Anope::string, ChannelStatus> { };
class NSRecoverRequest : public IdentifyRequest
@@ -56,7 +61,7 @@ class NSRecoverRequest : public IdentifyRequest
Log(LOG_COMMAND, source, cmd) << "and was automatically identified to " << u->Account()->display;
}
- if (Config->NSRestoreOnRecover)
+ if (restoreonrecover)
{
if (!u->chans.empty())
{
@@ -205,7 +210,7 @@ class NSRecover : public Module
commandnsrecover(this)
{
- if (Config->NoNicknameOwnership)
+ if (Config->GetBlock("options")->Get<bool>("nonicknameownership"))
throw ModuleException(modname + " can not be used with options:nonicknameownership enabled");
Implementation i[] = { I_OnUserNickChange, I_OnJoinChannel, I_OnShutdown, I_OnRestart };
@@ -233,7 +238,7 @@ class NSRecover : public Module
void OnUserNickChange(User *u, const Anope::string &oldnick) anope_override
{
- if (Config->NSRestoreOnRecover)
+ if (Config->GetModule(this)->Get<bool>("restoreonrecover"))
{
NSRecoverExtensibleInfo *ei = u->GetExt<NSRecoverExtensibleInfo *>("ns_recover_info");
@@ -255,7 +260,7 @@ class NSRecover : public Module
void OnJoinChannel(User *u, Channel *c) anope_override
{
- if (Config->NSRestoreOnRecover)
+ if (Config->GetModule(this)->Get<bool>("restoreonrecover"))
{
NSRecoverExtensibleInfo *ei = u->GetExt<NSRecoverExtensibleInfo *>("ns_recover_info");
diff --git a/modules/commands/ns_register.cpp b/modules/commands/ns_register.cpp
index 49e6a84d9..e0b8c77b5 100644
--- a/modules/commands/ns_register.cpp
+++ b/modules/commands/ns_register.cpp
@@ -13,6 +13,10 @@
#include "module.h"
+namespace
+{
+ ServiceReference<NickServService> nickserv("NickServService", "NickServ");
+}
static bool SendRegmail(User *u, const NickAlias *na, const BotInfo *bi);
class CommandNSConfirm : public Command
@@ -58,7 +62,7 @@ class CommandNSConfirm : public Command
{
IRCD->SendLogin(source.GetUser());
const NickAlias *na = NickAlias::Find(source.GetNick());
- if (!Config->NoNicknameOwnership && na != NULL && na->nc == source.GetAccount() && na->nc->HasExt("UNCONFIRMED") == false)
+ if (!Config->GetBlock("options")->Get<bool>("nonicknameownership") && na != NULL && na->nc == source.GetAccount() && na->nc->HasExt("UNCONFIRMED") == false)
source.GetUser()->SetMode(NickServ, "REGISTERED");
}
}
@@ -101,7 +105,7 @@ class CommandNSRegister : public Command
CommandNSRegister(Module *creator) : Command(creator, "nickserv/register", 1, 2)
{
this->SetDesc(_("Register a nickname"));
- if (Config->NSForceEmail)
+ if (Config->GetModule("nickserv")->Get<bool>("forceemail", "yes"))
this->SetSyntax(_("\037password\037 \037email\037"));
else
this->SetSyntax(_("\037password\037 \037[email]\037"));
@@ -111,12 +115,12 @@ class CommandNSRegister : public Command
void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
{
NickAlias *na;
- size_t prefixlen = Config->NSGuestNickPrefix.length();
User *u = source.GetUser();
Anope::string u_nick = source.GetNick();
size_t nicklen = u_nick.length();
Anope::string pass = params[0];
Anope::string email = params.size() > 1 ? params[1] : "";
+ const Anope::string &nsregister = Config->GetModule(this->owner)->Get<const Anope::string &>("registration");
if (Anope::ReadOnly)
{
@@ -124,15 +128,17 @@ class CommandNSRegister : public Command
return;
}
- if (Config->NSRegistration.equals_ci("disable"))
+ if (nsregister.equals_ci("disable"))
{
source.Reply(_("Registration is currently disabled."));
return;
}
- if (u && !u->HasMode("OPER") && Config->NickRegDelay && Anope::CurTime - u->timestamp < Config->NickRegDelay)
+ time_t nickregdelay = Config->GetModule(this->owner)->Get<time_t>("nickregdelay");
+ time_t reg_delay = Config->GetModule("nickserv")->Get<time_t>("regdelay");
+ if (u && !u->HasMode("OPER") && nickregdelay && Anope::CurTime - u->timestamp < nickregdelay)
{
- source.Reply(_("You must have been using this nick for at least %d seconds to register."), Config->NickRegDelay);
+ source.Reply(_("You must have been using this nick for at least %d seconds to register."), nickregdelay);
return;
}
@@ -141,7 +147,8 @@ class CommandNSRegister : public Command
/* Guest nick can now have a series of between 1 and 7 digits.
* --lara
*/
- if (nicklen <= prefixlen + 7 && nicklen >= prefixlen + 1 && !u_nick.find_ci(Config->NSGuestNickPrefix) && u_nick.substr(prefixlen).find_first_not_of("1234567890") == Anope::string::npos)
+ const Anope::string &guestnick = Config->GetBlock("options")->Get<const Anope::string &>("guestnickprefix");
+ if (nicklen <= guestnick.length() + 7 && nicklen >= guestnick.length() + 1 && !u_nick.find_ci(guestnick) && u_nick.substr(guestnick.length()).find_first_not_of("1234567890") == Anope::string::npos)
{
source.Reply(NICK_CANNOT_BE_REGISTERED, u_nick.c_str());
return;
@@ -153,7 +160,7 @@ class CommandNSRegister : public Command
return;
}
- if (Config->RestrictOperNicks)
+ if (Config->GetBlock("nickserv")->Get<bool>("restrictopernicks"))
for (unsigned i = 0; i < Config->Opers.size(); ++i)
{
Oper *o = Config->Opers[i];
@@ -165,15 +172,15 @@ class CommandNSRegister : public Command
}
}
- if (Config->NSForceEmail && email.empty())
+ if (Config->GetModule("nickserv")->Get<bool>("forceemail", "yes") && email.empty())
this->OnSyntaxError(source, "");
- else if (u && Anope::CurTime < u->lastnickreg + Config->NSRegDelay)
- source.Reply(_("Please wait %d seconds before using the REGISTER command again."), (u->lastnickreg + Config->NSRegDelay) - Anope::CurTime);
+ else if (u && Anope::CurTime < u->lastnickreg + reg_delay)
+ source.Reply(_("Please wait %d seconds before using the REGISTER command again."), (u->lastnickreg + reg_delay) - Anope::CurTime);
else if ((na = NickAlias::Find(u_nick)))
source.Reply(NICK_ALREADY_REGISTERED, u_nick.c_str());
- else if (pass.equals_ci(u_nick) || (Config->StrictPasswords && pass.length() < 5))
+ else if (pass.equals_ci(u_nick) || (Config->GetBlock("options")->Get<bool>("strictpasswords") && pass.length() < 5))
source.Reply(MORE_OBSCURE_PASSWORD);
- else if (pass.length() > Config->PassLen)
+ else if (pass.length() > Config->GetBlock("options")->Get<unsigned>("passlen"))
source.Reply(PASSWORD_TOO_LONG);
else if (!email.empty() && !Mail::Validate(email))
source.Reply(MAIL_X_INVALID, email.c_str());
@@ -191,16 +198,13 @@ class CommandNSRegister : public Command
na->last_realname = u->realname;
u->Login(nc);
-
- if (Config->NSAddAccessOnReg)
- nc->AddAccess(u->Mask());
}
Log(LOG_COMMAND, source, this) << "to register " << na->nick << " (email: " << (!na->nc->email.empty() ? na->nc->email : "none") << ")";
- FOREACH_MOD(I_OnNickRegister, OnNickRegister(na));
+ FOREACH_MOD(I_OnNickRegister, OnNickRegister(source.GetUser(), na));
- if (Config->NSAddAccessOnReg)
+ if (na->nc->GetAccessCount())
source.Reply(_("Nickname \002%s\002 registered under your user@host-mask: %s"), u_nick.c_str(), na->nc->GetAccess(0).c_str());
else
source.Reply(_("Nickname \002%s\002 registered."), u_nick.c_str());
@@ -209,26 +213,27 @@ class CommandNSRegister : public Command
if (Anope::Decrypt(na->nc->pass, tmp_pass) == 1)
source.Reply(_("Your password is \002%s\002 - remember this for later use."), tmp_pass.c_str());
- if (Config->NSRegistration.equals_ci("admin"))
+ if (nsregister.equals_ci("admin"))
{
nc->ExtendMetadata("UNCONFIRMED");
source.Reply(_("All new accounts must be validated by an administrator. Please wait for your registration to be confirmed."));
}
- else if (Config->NSRegistration.equals_ci("mail"))
+ else if (nsregister.equals_ci("mail"))
{
nc->ExtendMetadata("UNCONFIRMED");
if (SendRegmail(u, na, source.service))
{
- source.Reply(_("A passcode has been sent to %s, please type \002%s%s CONFIRM <passcode>\002 to confirm your email address."), email.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str());
- source.Reply(_("If you do not confirm your email address within %s your account will expire."), Anope::Duration(Config->NSUnconfirmedExpire).c_str());
+ time_t unconfirmed_expire = Config->GetModule("nickserv")->Get<time_t>("unconfirmedexpire", "1d");
+ source.Reply(_("A passcode has been sent to %s, please type \002%s%s CONFIRM <passcode>\002 to confirm your email address."), email.c_str(), Config->StrictPrivmsg.c_str(), NickServ->nick.c_str());
+ source.Reply(_("If you do not confirm your email address within %s your account will expire."), Anope::Duration(unconfirmed_expire).c_str());
}
}
- else if (Config->NSRegistration.equals_ci("none"))
+ else if (nsregister.equals_ci("none"))
{
if (u)
{
IRCD->SendLogin(u);
- if (!Config->NoNicknameOwnership && na->nc == u->Account() && na->nc->HasExt("UNCONFIRMED") == false)
+ if (!Config->GetBlock("options")->Get<bool>("nonicknameownership") && na->nc == u->Account() && na->nc->HasExt("UNCONFIRMED") == false)
u->SetMode(NickServ, "REGISTERED");
}
}
@@ -259,9 +264,9 @@ class CommandNSRegister : public Command
"passwords are vulnerable to trial-and-error searches, so\n"
"you should choose a password at least 5 characters long.\n"
"Finally, the space character cannot be used in passwords."),
- Config->NickServ.c_str(), Config->NickServ.c_str());
+ source.service->nick.c_str(), source.service->nick.c_str());
- if (!Config->NSForceEmail)
+ if (!Config->GetModule("nickserv")->Get<bool>("forceemail", "yes"))
{
source.Reply(" ");
source.Reply(_("The \037email\037 parameter is optional and will set the email\n"
@@ -289,7 +294,7 @@ class CommandNSResend : public Command
void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
{
- if (!Config->NSRegistration.equals_ci("mail"))
+ if (!Config->GetModule(this->owner)->Get<const Anope::string &>("registration").equals_ci("mail"))
return;
const NickAlias *na = NickAlias::Find(source.GetNick());
@@ -300,7 +305,7 @@ class CommandNSResend : public Command
source.Reply(_("Your account is already confirmed."));
else
{
- if (Anope::CurTime < source.nc->lastmail + Config->NSResendDelay)
+ if (Anope::CurTime < source.nc->lastmail + Config->GetModule(this->owner)->Get<time_t>("resenddelay"))
source.Reply(_("Cannot send mail now; please retry a little later."));
else if (SendRegmail(source.GetUser(), na, source.service))
{
@@ -317,7 +322,7 @@ class CommandNSResend : public Command
bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
{
- if (!Config->NSRegistration.equals_ci("mail"))
+ if (!Config->GetModule(this->owner)->Get<const Anope::string &>("registration").equals_ci("mail"))
return false;
this->SendSyntax(source);
@@ -329,7 +334,7 @@ class CommandNSResend : public Command
void OnServHelp(CommandSource &source) anope_override
{
- if (Config->NSRegistration.equals_ci("mail"))
+ if (Config->GetModule(this->owner)->Get<const Anope::string &>("registration").equals_ci("mail"))
Command::OnServHelp(source);
}
};
@@ -344,9 +349,8 @@ class NSRegister : public Module
NSRegister(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
commandnsregister(this), commandnsconfirm(this), commandnsrsend(this)
{
-
- if (Config->NSRegistration.equals_ci("disable"))
- throw ModuleException("Module will not load with nickserv:registration disabled.");
+ if (Config->GetModule(this)->Get<const Anope::string &>("registration").equals_ci("disable"))
+ throw ModuleException("Module " + this->name + " will not load with registration disabled.");
}
};
@@ -373,15 +377,15 @@ static bool SendRegmail(User *u, const NickAlias *na, const BotInfo *bi)
else
codebuf = *code;
- Anope::string subject = Language::Translate(na->nc, Config->MailRegistrationSubject.c_str());
- Anope::string message = Language::Translate(na->nc, Config->MailRegistrationMessage.c_str());
+ Anope::string subject = Language::Translate(na->nc, Config->GetBlock("mail")->Get<const char *>("registration_subject")),
+ message = Language::Translate(na->nc, Config->GetBlock("mail")->Get<const char *>("registration_message"));
subject = subject.replace_all_cs("%n", na->nick);
- subject = subject.replace_all_cs("%N", Config->NetworkName);
+ subject = subject.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string &>("networkname"));
subject = subject.replace_all_cs("%c", codebuf);
message = message.replace_all_cs("%n", na->nick);
- message = message.replace_all_cs("%N", Config->NetworkName);
+ message = message.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string &>("networkname"));
message = message.replace_all_cs("%c", codebuf);
return Mail::Send(u, nc, bi, subject, message);
diff --git a/modules/commands/ns_resetpass.cpp b/modules/commands/ns_resetpass.cpp
index 3ccb41ec1..f4516c5a6 100644
--- a/modules/commands/ns_resetpass.cpp
+++ b/modules/commands/ns_resetpass.cpp
@@ -29,7 +29,7 @@ class CommandNSResetPass : public Command
{
const NickAlias *na;
- if (Config->RestrictMail && !source.HasCommand("nickserv/resetpass"))
+ if (Config->GetBlock("mail")->Get<bool>("restrict") && !source.HasCommand("nickserv/resetpass"))
source.Reply(ACCESS_DENIED);
else if (!(na = NickAlias::Find(params[0])))
source.Reply(NICK_X_NOT_REGISTERED, params[0].c_str());
@@ -69,8 +69,7 @@ class NSResetPass : public Module
NSResetPass(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
commandnsresetpass(this)
{
-
- if (!Config->UseMail)
+ if (!Config->GetBlock("mail")->Get<bool>("usemail"))
throw ModuleException("Not using mail.");
@@ -140,15 +139,15 @@ static bool SendResetEmail(User *u, const NickAlias *na, const BotInfo *bi)
for (idx = 0; idx < 20; ++idx)
passcode += chars[1 + static_cast<int>((static_cast<float>(max - min)) * static_cast<uint16_t>(rand()) / 65536.0) + min];
- Anope::string subject = Language::Translate(na->nc, Config->MailResetSubject.c_str());
- Anope::string message = Language::Translate(na->nc, Config->MailResetMessage.c_str());
+ Anope::string subject = Language::Translate(na->nc, Config->GetBlock("mail")->Get<const char *>("reset_subject")),
+ message = Language::Translate(na->nc, Config->GetBlock("mail")->Get<const char *>("reset_message"));
subject = subject.replace_all_cs("%n", na->nick);
- subject = subject.replace_all_cs("%N", Config->NetworkName);
+ subject = subject.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string &>("networkname"));
subject = subject.replace_all_cs("%c", passcode);
message = message.replace_all_cs("%n", na->nick);
- message = message.replace_all_cs("%N", Config->NetworkName);
+ message = message.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string &>("networkname"));
message = message.replace_all_cs("%c", passcode);
ResetInfo *ri = new ResetInfo;
diff --git a/modules/commands/ns_set.cpp b/modules/commands/ns_set.cpp
index 793b99fd1..fdc3aaac6 100644
--- a/modules/commands/ns_set.cpp
+++ b/modules/commands/ns_set.cpp
@@ -11,6 +11,8 @@
#include "module.h"
+static ServiceReference<NickServService> nickserv("NickServService", "NickServ");
+
class CommandNSSet : public Command
{
public:
@@ -50,7 +52,7 @@ class CommandNSSet : public Command
}
source.Reply(_("Type \002%s%s HELP %s \037option\037\002 for more information\n"
- "on a specific option."), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str(), this_name.c_str());
+ "on a specific option."), Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), this_name.c_str());
return true;
}
@@ -96,7 +98,7 @@ class CommandNSSASet : public Command
source.Reply(_("Type \002%s%s HELP %s \037option\037\002 for more information\n"
"on a specific option. The options will be set on the given\n"
- "\037nickname\037."), Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str(), this_name.c_str());
+ "\037nickname\037."), Config->StrictPrivmsg.c_str(), NickServ->nick.c_str(), this_name.c_str());
return true;
}
};
@@ -115,12 +117,12 @@ class CommandNSSetPassword : public Command
const Anope::string &param = params[1];
unsigned len = param.length();
- if (source.GetNick().equals_ci(param) || (Config->StrictPasswords && len < 5))
+ if (source.GetNick().equals_ci(param) || (Config->GetBlock("options")->Get<bool>("strictpasswords") && len < 5))
{
source.Reply(MORE_OBSCURE_PASSWORD);
return;
}
- else if (len > Config->PassLen)
+ else if (len > Config->GetBlock("options")->Get<unsigned>("passlen"))
{
source.Reply(PASSWORD_TOO_LONG);
return;
@@ -167,17 +169,17 @@ class CommandNSSASetPassword : public Command
size_t len = params[1].length();
- if (Config->NSSecureAdmins && source.nc != nc && nc->IsServicesOper())
+ if (Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && source.nc != nc && nc->IsServicesOper())
{
source.Reply(_("You may not change the password of other Services Operators."));
return;
}
- else if (nc->display.equals_ci(params[1]) || (Config->StrictPasswords && len < 5))
+ else if (nc->display.equals_ci(params[1]) || (Config->GetBlock("options")->Get<bool>("strictpasswords") && len < 5))
{
source.Reply(MORE_OBSCURE_PASSWORD);
return;
}
- else if (len > Config->PassLen)
+ else if (len > Config->GetBlock("options")->Get<unsigned>("passlen"))
{
source.Reply(PASSWORD_TOO_LONG);
return;
@@ -378,7 +380,7 @@ class CommandNSSetDisplay : public Command
{
const NickAlias *user_na = NickAlias::Find(user), *na = NickAlias::Find(param);
- if (Config->NoNicknameOwnership)
+ if (Config->GetBlock("options")->Get<bool>("nonicknameownership"))
{
source.Reply(_("This command may not be used on this network because nickname ownership is disabled."));
return;
@@ -462,15 +464,15 @@ class CommandNSSetEmail : public Command
u->Account()->Extend("ns_set_email_passcode", new ExtensibleItemClass<Anope::string>(code));
- Anope::string subject = Config->MailEmailchangeSubject;
- Anope::string message = Config->MailEmailchangeMessage;
+ Anope::string subject = Config->GetBlock("mail")->Get<const char *>("emailchange_subject"),
+ message = Config->GetBlock("mail")->Get<const char *>("emailchange_message");
subject = subject.replace_all_cs("%e", u->Account()->email);
- subject = subject.replace_all_cs("%N", Config->NetworkName);
+ subject = subject.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string &>("networkname"));
subject = subject.replace_all_cs("%c", code);
message = message.replace_all_cs("%e", u->Account()->email);
- message = message.replace_all_cs("%N", Config->NetworkName);
+ message = message.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string &>("networkname"));
message = message.replace_all_cs("%c", code);
return Mail::Send(u, u->Account(), bi, subject, message);
@@ -493,12 +495,12 @@ class CommandNSSetEmail : public Command
}
NickCore *nc = na->nc;
- if (param.empty() && Config->NSForceEmail)
+ if (param.empty() && Config->GetModule("nickserv")->Get<bool>("forceemail", "yes"))
{
source.Reply(_("You cannot unset the e-mail on this network."));
return;
}
- else if (Config->NSSecureAdmins && source.nc != nc && nc->IsServicesOper())
+ else if (Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && source.nc != nc && nc->IsServicesOper())
{
source.Reply(_("You may not change the e-mail of other Services Operators."));
return;
@@ -514,7 +516,7 @@ class CommandNSSetEmail : public Command
if (MOD_RESULT == EVENT_STOP)
return;
- if (!param.empty() && Config->NSConfirmEmailChanges && !source.IsServicesOper())
+ if (!param.empty() && Config->GetModule("nickserv")->Get<bool>("forceemail", "yes") && !source.IsServicesOper())
{
source.nc->Extend("ns_set_email", new ExtensibleItemClass<Anope::string>(param));
Anope::string old = source.nc->email;
@@ -722,13 +724,13 @@ class CommandNSSetHide : public Command
{
Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to change hide " << param << " to " << arg << " for " << nc->display;
nc->ExtendMetadata(flag);
- source.Reply(onmsg.c_str(), nc->display.c_str(), Config->NickServ.c_str());
+ source.Reply(onmsg.c_str(), nc->display.c_str(), NickServ->nick.c_str());
}
else if (arg.equals_ci("OFF"))
{
Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to change hide " << param << " to " << arg << " for " << nc->display;
nc->Shrink(flag);
- source.Reply(offmsg.c_str(), nc->display.c_str(), Config->NickServ.c_str());
+ source.Reply(offmsg.c_str(), nc->display.c_str(), NickServ->nick.c_str());
}
else
this->OnSyntaxError(source, "HIDE");
@@ -751,7 +753,7 @@ class CommandNSSetHide : public Command
"user@host mask (\002USERMASK\002), your services access status\n"
"(\002STATUS\002) and last quit message (\002QUIT\002).\n"
"The second parameter specifies whether the information should\n"
- "be displayed (\002OFF\002) or hidden (\002ON\002)."), Config->NickServ.c_str());
+ "be displayed (\002OFF\002) or hidden (\002ON\002)."), NickServ->nick.c_str());
return true;
}
};
@@ -780,7 +782,7 @@ class CommandNSSASetHide : public CommandNSSetHide
"user@host mask (\002USERMASK\002), the services access status\n"
"(\002STATUS\002) and last quit message (\002QUIT\002).\n"
"The second parameter specifies whether the information should\n"
- "be displayed (\002OFF\002) or hidden (\002ON\002)."), Config->NickServ.c_str());
+ "be displayed (\002OFF\002) or hidden (\002ON\002)."), NickServ->nick.c_str());
return true;
}
};
@@ -796,7 +798,7 @@ class CommandNSSetKill : public Command
void Run(CommandSource &source, const Anope::string &user, const Anope::string &param)
{
- if (Config->NoNicknameOwnership)
+ if (Config->GetBlock("options")->Get<bool>("nonicknameownership"))
{
source.Reply(_("This command may not be used on this network because nickname ownership is disabled."));
return;
@@ -833,7 +835,7 @@ class CommandNSSetKill : public Command
}
else if (param.equals_ci("IMMED"))
{
- if (Config->NSAllowKillImmed)
+ if (Config->GetModule(this->owner)->Get<bool>("allowkillimmed"))
{
nc->ExtendMetadata("KILLPROTECT");
nc->ExtendMetadata("KILL_IMMED");
@@ -878,7 +880,7 @@ class CommandNSSetKill : public Command
"\002IMMED\002, user's nick will be changed immediately \037without\037 being\n"
"warned first or given a chance to change their nick; please\n"
"do not use this option unless necessary. Also, your\n"
- "network's administrators may have disabled this option."), Config->NickServ.c_str());
+ "network's administrators may have disabled this option."), NickServ->nick.c_str());
return true;
}
};
@@ -912,7 +914,7 @@ class CommandNSSASetKill : public CommandNSSetKill
"\002IMMED\002, the user's nick will be changed immediately \037without\037 being\n"
"warned first or given a chance to change their nick; please\n"
"do not use this option unless necessary. Also, your\n"
- "network's administrators may have disabled this option."), Config->NickServ.c_str());
+ "network's administrators may have disabled this option."), NickServ->nick.c_str());
return true;
}
};
@@ -956,8 +958,6 @@ class CommandNSSetLanguage : public Command
nc->language = param != "en" ? param : "";
source.Reply(_("Language changed to \002English\002."));
-
- return;
}
void Execute(CommandSource &source, const std::vector<Anope::string> &param) anope_override
@@ -1040,7 +1040,7 @@ class CommandNSSetMessage : public Command
}
NickCore *nc = na->nc;
- if (!Config->UsePrivmsg)
+ if (!Config->GetBlock("options")->Get<bool>("useprivmsg"))
{
source.Reply(_("You cannot %s on this network."), source.command.c_str());
return;
@@ -1086,7 +1086,7 @@ class CommandNSSetMessage : public Command
void OnServHelp(CommandSource &source) anope_override
{
- if (Config->UsePrivmsg)
+ if (!Config->GetBlock("options")->Get<bool>("useprivmsg"))
Command::OnServHelp(source);
}
};
@@ -1121,7 +1121,7 @@ class CommandNSSetPrivate : public Command
public:
CommandNSSetPrivate(Module *creator, const Anope::string &sname = "nickserv/set/private", size_t min = 1) : Command(creator, sname, min, min + 1)
{
- this->SetDesc(Anope::printf(_("Prevent the nickname from appearing in a \002%s%s LIST\002"), Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str()));
+ this->SetDesc(_("Prevent the nickname from appearing in the LIST command"));
this->SetSyntax(_("{ON | OFF}"));
}
@@ -1172,7 +1172,7 @@ class CommandNSSetPrivate : public Command
"nickname lists generated with %s's \002LIST\002 command.\n"
"(However, anyone who knows your nickname can still get\n"
"information on it using the \002INFO\002 command.)"),
- Config->NickServ.c_str(), Config->NickServ.c_str());
+ NickServ->nick.c_str(), NickServ->nick.c_str());
return true;
}
};
@@ -1200,7 +1200,7 @@ class CommandNSSASetPrivate : public CommandNSSetPrivate
"nickname lists generated with %s's \002LIST\002 command.\n"
"(However, anyone who knows the nickname can still get\n"
"information on it using the \002INFO\002 command.)"),
- Config->NickServ.c_str(), Config->NickServ.c_str());
+ NickServ->nick.c_str(), NickServ->nick.c_str());
return true;
}
};
@@ -1260,7 +1260,7 @@ class CommandNSSetSecure : public Command
"regardless of whether your address is on the access\n"
"list. However, if you are on the access list, %s\n"
"will not auto-kill you regardless of the setting of the\n"
- "\002KILL\002 option."), Config->NickServ.c_str(), Config->NickServ.c_str());
+ "\002KILL\002 option."), NickServ->nick.c_str(), NickServ->nick.c_str());
return true;
}
};
@@ -1289,7 +1289,7 @@ class CommandNSSASetSecure : public CommandNSSetSecure
"regardless of whether your address is on the access\n"
"list. However, if you are on the access list, %s\n"
"will not auto-kill you regardless of the setting of the\n"
- "\002KILL\002 option."), Config->NickServ.c_str(), Config->NickServ.c_str());
+ "\002KILL\002 option."), NickServ->nick.c_str(), NickServ->nick.c_str());
return true;
}
};
@@ -1402,21 +1402,10 @@ class NSSet : public Module
commandnssasetnoexpire(this)
{
- Implementation i[] = { I_OnReload, I_OnNickRegister, I_OnPreCommand };
+ Implementation i[] = { I_OnPreCommand };
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
}
- void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override
- {
- NSDefChanstats = reader.ReadFlag("chanstats", "NSDefChanstats", "0", 0);
- }
-
- void OnNickRegister(NickAlias *na) anope_override
- {
- if (NSDefChanstats)
- na->nc->ExtendMetadata("STATS");
- }
-
EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> &params) anope_override
{
NickCore *uac = source.nc;
diff --git a/modules/commands/ns_set_misc.cpp b/modules/commands/ns_set_misc.cpp
index 5ee77a938..871a1191f 100644
--- a/modules/commands/ns_set_misc.cpp
+++ b/modules/commands/ns_set_misc.cpp
@@ -161,17 +161,21 @@ class NSSetMisc : public Module
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
}
- void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override
+ void OnReload(Configuration::Conf *conf) anope_override
{
descriptions.clear();
- for (int i = 0; i < reader.Enumerate("command"); ++i)
+ for (int i = 0; i < conf->CountBlock("command"); ++i)
{
- if (reader.ReadValue("command", "command", "", i) != "nickserv/set/misc" && reader.ReadValue("command", "command", "", i) != "nickserv/saset/misc")
+ Configuration::Block *block = conf->GetBlock("command", i);
+
+ const Anope::string &cmd = block->Get<const Anope::string &>("command");
+
+ if (cmd != "nickserv/set/misc" && cmd != "nickserv/saset/misc")
continue;
- Anope::string cname = reader.ReadValue("command", "name", "", i);
- Anope::string desc = reader.ReadValue("command", "misc_description", "", i);
+ Anope::string cname = block->Get<const Anope::string &>("name");
+ Anope::string desc = block->Get<const Anope::string &>("misc_description");
if (cname.empty() || desc.empty())
continue;
diff --git a/modules/commands/ns_suspend.cpp b/modules/commands/ns_suspend.cpp
index dabd47a7e..e0bb6bf93 100644
--- a/modules/commands/ns_suspend.cpp
+++ b/modules/commands/ns_suspend.cpp
@@ -13,6 +13,8 @@
#include "module.h"
+static ServiceReference<NickServService> nickserv("NickServService", "NickServ");
+
class CommandNSSuspend : public Command
{
public:
@@ -28,7 +30,7 @@ class CommandNSSuspend : public Command
const Anope::string &nick = params[0];
Anope::string expiry = params[1];
Anope::string reason = params.size() > 2 ? params[2] : "";
- time_t expiry_secs = Config->NSSuspendExpire;
+ time_t expiry_secs = Config->GetModule(this->owner)->Get<time_t>("suspendexpire");
if (Anope::ReadOnly)
{
@@ -52,7 +54,7 @@ class CommandNSSuspend : public Command
return;
}
- if (Config->NSSecureAdmins && na->nc->IsServicesOper())
+ if (Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && na->nc->IsServicesOper())
{
source.Reply(_("You may not suspend other Services Operators' nicknames."));
return;
@@ -173,7 +175,6 @@ class NSSuspend : public Module
NSSuspend(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
commandnssuspend(this), commandnsunsuspend(this)
{
-
Implementation i[] = { I_OnPreNickExpire };
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
}
diff --git a/modules/commands/ns_update.cpp b/modules/commands/ns_update.cpp
index 115d4f2b9..ee8a2c8cb 100644
--- a/modules/commands/ns_update.cpp
+++ b/modules/commands/ns_update.cpp
@@ -35,7 +35,7 @@ class CommandNSUpdate : public Command
FOREACH_MOD(I_OnNickUpdate, OnNickUpdate(u));
- source.Reply(_("Status updated (memos, vhost, chmodes, flags)."), Config->NickServ.c_str());
+ source.Reply(_("Status updated (memos, vhost, chmodes, flags)."));
}
bool OnHelp(CommandSource &source, const Anope::string &) anope_override
diff --git a/modules/commands/os_akill.cpp b/modules/commands/os_akill.cpp
index 47121c51f..c90dd096f 100644
--- a/modules/commands/os_akill.cpp
+++ b/modules/commands/os_akill.cpp
@@ -76,7 +76,7 @@ class CommandOSAKill : public Command
sep.GetToken(mask);
}
- time_t expires = !expiry.empty() ? Anope::DoTime(expiry) : Config->AutokillExpiry;
+ time_t expires = !expiry.empty() ? Anope::DoTime(expiry) : Config->GetModule("operserv")->Get<time_t>("autokillexpiry", "30d");
/* If the expiry given does not contain a final letter, it's in days,
* said the doc. Ah well.
*/
@@ -121,16 +121,18 @@ class CommandOSAKill : public Command
if (mask[0] == '/' && mask[mask.length() - 1] == '/')
{
- if (Config->RegexEngine.empty())
+ const Anope::string &regexengine = Config->GetBlock("options")->Get<const Anope::string &>("regexengine");
+
+ if (regexengine.empty())
{
- source.Reply(_("Regex is enabled."));
+ source.Reply(_("Regex is disabled."));
return;
}
- ServiceReference<RegexProvider> provider("Regex", Config->RegexEngine);
+ ServiceReference<RegexProvider> provider("Regex", regexengine);
if (!provider)
{
- source.Reply(_("Unable to find regex engine %s."), Config->RegexEngine.c_str());
+ source.Reply(_("Unable to find regex engine %s."), regexengine.c_str());
return;
}
@@ -158,8 +160,11 @@ class CommandOSAKill : public Command
return;
}
+ if (Config->GetModule("operserv")->Get<bool>("addakiller", "yes") && !source.GetNick().empty())
+ reason = "[" + source.GetNick() + "] " + reason;
+
XLine *x = new XLine(mask, source.GetNick(), expires, reason);
- if (Config->AkillIds)
+ if (Config->GetBlock("operserv")->Get<bool>("akilids"))
x->id = XLineManager::GenerateUID();
unsigned int affected = 0;
@@ -185,7 +190,7 @@ class CommandOSAKill : public Command
}
akills->AddXLine(x);
- if (Config->AkillOnAdd)
+ if (Config->GetModule("operserv")->Get<bool>("akillonadd"))
akills->Send(NULL, x);
source.Reply(_("\002%s\002 added to the AKILL list."), mask.c_str());
@@ -414,11 +419,12 @@ class CommandOSAKill : public Command
"be given, even if it is the same as the default. The\n"
"current AKILL default expiry time can be found with the\n"
"\002STATS AKILL\002 command."));
- if (!Config->RegexEngine.empty())
+ const Anope::string &regexengine = Config->GetBlock("options")->Get<const Anope::string &>("regexengine");
+ if (!regexengine.empty())
{
source.Reply(" ");
source.Reply(_("Regex matches are also supported using the %s engine.\n"
- "Enclose your mask in // if this is desired."), Config->RegexEngine.c_str());
+ "Enclose your mask in // if this is desired."), regexengine.c_str());
}
source.Reply(_(
" \n"
diff --git a/modules/commands/os_chankill.cpp b/modules/commands/os_chankill.cpp
index 8253742a6..713b5922f 100644
--- a/modules/commands/os_chankill.cpp
+++ b/modules/commands/os_chankill.cpp
@@ -30,7 +30,6 @@ class CommandOSChanKill : public Command
return;
Anope::string expiry, channel;
- time_t expires;
unsigned last_param = 1;
Channel *c;
@@ -42,7 +41,7 @@ class CommandOSChanKill : public Command
last_param = 2;
}
- expires = !expiry.empty() ? Anope::DoTime(expiry) : Config->ChankillExpiry;
+ time_t expires = !expiry.empty() ? Anope::DoTime(expiry) : Config->GetModule("operserv")->Get<time_t>("autokillexpiry", "30d");
if (!expiry.empty() && isdigit(expiry[expiry.length() - 1]))
expires *= 86400;
if (expires && expires < 60)
@@ -65,7 +64,7 @@ class CommandOSChanKill : public Command
if (!reason.empty())
{
Anope::string realreason;
- if (Config->AddAkiller)
+ if (Config->GetBlock("operserv")->Get<bool>("addakiller") && !source.GetNick().empty())
realreason = "[" + source.GetNick() + "] " + reason;
else
realreason = reason;
diff --git a/modules/commands/os_config.cpp b/modules/commands/os_config.cpp
index 0517f28d7..391d36157 100644
--- a/modules/commands/os_config.cpp
+++ b/modules/commands/os_config.cpp
@@ -15,22 +15,6 @@
class CommandOSConfig : public Command
{
- void ChangeHash(ConfigDataHash &hash, const Anope::string &block, const Anope::string &iname, const Anope::string &value)
- {
- ConfigDataHash::iterator it = hash.find(block);
-
- KeyValList &list = it->second;
- for (unsigned i = 0; i < list.size(); ++i)
- {
- const Anope::string &item = list[i].first;
- if (item == iname)
- {
- list[i] = std::make_pair(item, value);
- break;
- }
- }
- }
-
public:
CommandOSConfig(Module *creator) : Command(creator, "operserv/config", 1, 4)
{
@@ -44,110 +28,17 @@ class CommandOSConfig : public Command
if (what.equals_ci("MODIFY") && params.size() > 3)
{
- ConfigItems configitems(Config);
-
- for (unsigned i = 0; !configitems.Values[i].tag.empty(); ++i)
+ Configuration::Block *block = Config->GetBlock(params[1]);
+ if (!block)
{
- ConfigItems::Item *v = &configitems.Values[i];
- if (v->tag.equals_cs(params[1]) && v->value.equals_cs(params[2]))
- {
- try
- {
- ValueItem vi(params[3]);
- if (!v->validation_function(Config, v->tag, v->value, vi))
- throw ConfigException("Parameter failed to validate.");
-
- int dt = v->datatype;
-
- if (dt & DT_NORELOAD)
- throw ConfigException("This item can not be changed while Anope is running.");
- bool allow_wild = dt & DT_ALLOW_WILD;
- dt &= ~(DT_ALLOW_NEWLINE | DT_ALLOW_WILD);
-
- /* Yay for *massive* copypaste from reader.cpp */
- switch (dt)
- {
- case DT_NOSPACES:
- {
- ValueContainerString *vcs = anope_dynamic_static_cast<ValueContainerString *>(v->val);
- Config->ValidateNoSpaces(vi.GetValue(), v->tag, v->value);
- vcs->Set(vi.GetValue());
- break;
- }
- case DT_HOSTNAME:
- {
- ValueContainerString *vcs = anope_dynamic_static_cast<ValueContainerString *>(v->val);
- Config->ValidateHostname(vi.GetValue(), v->tag, v->value);
- vcs->Set(vi.GetValue());
- break;
- }
- case DT_IPADDRESS:
- {
- ValueContainerString *vcs = anope_dynamic_static_cast<ValueContainerString *>(v->val);
- Config->ValidateIP(vi.GetValue(), v->tag, v->value, allow_wild);
- vcs->Set(vi.GetValue());
- break;
- }
- case DT_STRING:
- {
- ValueContainerString *vcs = anope_dynamic_static_cast<ValueContainerString *>(v->val);
- vcs->Set(vi.GetValue());
- break;
- }
- case DT_INTEGER:
- {
- int val = vi.GetInteger();
- ValueContainerInt *vci = anope_dynamic_static_cast<ValueContainerInt *>(v->val);
- vci->Set(&val, sizeof(int));
- break;
- }
- case DT_UINTEGER:
- {
- unsigned val = vi.GetInteger();
- ValueContainerUInt *vci = anope_dynamic_static_cast<ValueContainerUInt *>(v->val);
- vci->Set(&val, sizeof(unsigned));
- break;
- }
- case DT_LUINTEGER:
- {
- unsigned long val = vi.GetInteger();
- ValueContainerLUInt *vci = anope_dynamic_static_cast<ValueContainerLUInt *>(v->val);
- vci->Set(&val, sizeof(unsigned long));
- break;
- }
- case DT_TIME:
- {
- time_t time = Anope::DoTime(vi.GetValue());
- ValueContainerTime *vci = anope_dynamic_static_cast<ValueContainerTime *>(v->val);
- vci->Set(&time, sizeof(time_t));
- break;
- }
- case DT_BOOLEAN:
- {
- bool val = vi.GetBool();
- ValueContainerBool *vcb = anope_dynamic_static_cast<ValueContainerBool *>(v->val);
- vcb->Set(&val, sizeof(bool));
- break;
- }
- default:
- break;
- }
- }
- catch (const ConfigException &ex)
- {
- source.Reply(_("Error changing configuration value: ") + ex.GetReason());
- return;
- }
-
- ChangeHash(Config->config_data, params[1], params[2], params[3]);
-
- Log(LOG_ADMIN, source, this) << "to change the configuration value of " << params[1] << ":" << params[2] << " to " << params[3];
- source.Reply(_("Value of %s:%s changed to %s"), params[1].c_str(), params[2].c_str(), params[3].c_str());
- return;
- }
+ source.Reply(_("There is no such configuration block %s."), params[1].c_str());
+ return;
}
- source.Reply("There is no configuration value named %s:%s", params[1].c_str(), params[2].c_str());
+ block->Set(params[2], params[3]);
+
+ Log(LOG_ADMIN, source, this) << "to change the configuration value of " << params[1] << ":" << params[2] << " to " << params[3];
+ source.Reply(_("Value of %s:%s changed to %s"), params[1].c_str(), params[2].c_str(), params[3].c_str());
}
else if (what.equals_ci("VIEW"))
{
@@ -155,35 +46,30 @@ class CommandOSConfig : public Command
const Anope::string show_blocks[] = { "botserv", "chanserv", "defcon", "global", "memoserv", "nickserv", "networkinfo", "operserv", "options", "" };
Log(LOG_ADMIN, source, this) << "VIEW";
-
- for (ConfigDataHash::const_iterator it = Config->config_data.begin(), it_end = Config->config_data.end(); it != it_end; ++it)
+
+ for (unsigned i = 0; !show_blocks[i].empty(); ++i)
{
- const Anope::string &bname = it->first;
- const KeyValList &list = it->second;
-
- bool ok = false;
- for (unsigned i = 0; !show_blocks[i].empty(); ++i)
- if (bname == show_blocks[i])
- ok = true;
- if (ok == false)
+ Configuration::Block *block = Config->GetBlock(show_blocks[i]);
+ const Configuration::Block::item_map *items = block->GetItems();
+
+ if (!items)
continue;
ListFormatter lflist;
lflist.AddColumn("Name").AddColumn("Value");
- for (unsigned i = 0; i < list.size(); ++i)
- {
- const Anope::string &first = list[i].first, second = list[i].second;
+ for (Configuration::Block::item_map::const_iterator it = items->begin(), it_end = items->end(); it != it_end; ++it)
+ {
ListFormatter::ListEntry entry;
- entry["Name"] = first;
- entry["Value"] = second;
+ entry["Name"] = it->first;
+ entry["Value"] = it->second;
lflist.AddEntry(entry);
}
std::vector<Anope::string> replies;
lflist.Process(replies);
- source.Reply(_("%s settings:"), bname.c_str());
+ source.Reply(_("%s settings:"), block->GetName().c_str());
for (unsigned i = 0; i < replies.size(); ++i)
source.Reply(replies[i]);
@@ -193,8 +79,6 @@ class CommandOSConfig : public Command
}
else
this->OnSyntaxError(source, what);
-
- return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
diff --git a/modules/commands/os_defcon.cpp b/modules/commands/os_defcon.cpp
index dd45856fb..0fd3a1700 100644
--- a/modules/commands/os_defcon.cpp
+++ b/modules/commands/os_defcon.cpp
@@ -43,6 +43,10 @@ struct DefconConfig
time_t akillexpire, timeout;
bool globalondefcon;
+ unsigned max_session_kill;
+ time_t session_autokill_expiry;
+ Anope::string sle_reason, sle_detailsloc;
+
DefconConfig()
{
this->DefCon.resize(6);
@@ -336,23 +340,32 @@ class OSDefcon : public Module
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
}
- void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override
+ void OnReload(Configuration::Conf *conf) anope_override
{
+ Configuration::Block *block = conf->GetModule(this);
DefconConfig dconfig;
- dconfig.defaultlevel = reader.ReadInteger("defcon", "defaultlevel", 0, 0);
- dconfig.defcons[4] = reader.ReadValue("defcon", "level4", 0);
- dconfig.defcons[3] = reader.ReadValue("defcon", "level3", 0);
- dconfig.defcons[2] = reader.ReadValue("defcon", "level2", 0);
- dconfig.defcons[1] = reader.ReadValue("defcon", "level1", 0);
- dconfig.sessionlimit = reader.ReadInteger("defcon", "sessionlimit", 0, 0);
- dconfig.akillreason = reader.ReadValue("defcon", "akillreason", 0);
- dconfig.akillexpire = Anope::DoTime(reader.ReadValue("defcon", "akillexpire", 0));
- dconfig.chanmodes = reader.ReadValue("defcon", "chanmodes", 0);
- dconfig.timeout = Anope::DoTime(reader.ReadValue("defcon", "timeout", 0));
- dconfig.globalondefcon = reader.ReadFlag("defcon", "globalondefcon", 0);
- dconfig.message = reader.ReadValue("defcon", "message", 0);
- dconfig.offmessage = reader.ReadValue("defcon", "offmessage", 0);
+ dconfig.defaultlevel = block->Get<int>("defaultlevel");
+ dconfig.defcons[4] = block->Get<const Anope::string &>("level4");
+ dconfig.defcons[3] = block->Get<const Anope::string &>("level3");
+ dconfig.defcons[2] = block->Get<const Anope::string &>("level2");
+ dconfig.defcons[1] = block->Get<const Anope::string &>("level1");
+ dconfig.sessionlimit = block->Get<int>("sessionlimit");
+ dconfig.akillreason = block->Get<const Anope::string &>("akillreason");
+ dconfig.akillexpire = block->Get<time_t>("akillexpire");
+ dconfig.chanmodes = block->Get<const Anope::string &>("chanmodes");
+ dconfig.timeout = block->Get<time_t>("timeout");
+ dconfig.globalondefcon = block->Get<bool>("globalondefcon");
+ dconfig.message = block->Get<const Anope::string &>("message");
+ dconfig.offmessage = block->Get<const Anope::string &>("offmessage");
+
+ Module *session = ModuleManager::FindModule("os_session");
+ block = conf->GetModule(session);
+
+ dconfig.max_session_kill = block->Get<int>("maxsessionkill");
+ dconfig.session_autokill_expiry = block->Get<time_t>("sessionautokillexpiry");
+ dconfig.sle_reason = block->Get<const Anope::string &>("sessionlimitexceeded");
+ dconfig.sle_detailsloc = block->Get<const Anope::string &>("sessionlimitdetailsloc");
if (dconfig.defaultlevel < 1 || dconfig.defaultlevel > 5)
throw ConfigException("The value for <defcon:defaultlevel> must be between 1 and 5");
@@ -479,19 +492,18 @@ class OSDefcon : public Module
if (DConfig.Check(DEFCON_AKILL_NEW_CLIENTS) && akills)
{
Log(OperServ, "operserv/defcon") << "DEFCON: adding akill for *@" << u->host;
- XLine x("*@" + u->host, Config->OperServ, Anope::CurTime + DConfig.akillexpire, DConfig.akillreason, XLineManager::GenerateUID());
- x.by = Config->OperServ;
+ XLine x("*@" + u->host, OperServ ? OperServ->nick : "defcon", Anope::CurTime + DConfig.akillexpire, DConfig.akillreason, XLineManager::GenerateUID());
akills->Send(NULL, &x);
}
if (DConfig.Check(DEFCON_NO_NEW_CLIENTS) || DConfig.Check(DEFCON_AKILL_NEW_CLIENTS))
{
- u->Kill(Config->OperServ, DConfig.akillreason);
+ u->Kill(OperServ ? OperServ->nick : "", DConfig.akillreason);
return;
}
if (DConfig.Check(DEFCON_NO_NEW_CLIENTS) || DConfig.Check(DEFCON_AKILL_NEW_CLIENTS))
{
- u->Kill(Config->OperServ, DConfig.akillreason);
+ u->Kill(OperServ ? OperServ->nick : "", DConfig.akillreason);
return;
}
@@ -513,22 +525,24 @@ class OSDefcon : public Module
{
if (session && session->count > static_cast<unsigned>(DConfig.sessionlimit))
{
- if (!Config->SessionLimitExceeded.empty())
- IRCD->SendMessage(OperServ, u->nick, Config->SessionLimitExceeded.c_str(), u->host.c_str());
- if (!Config->SessionLimitDetailsLoc.empty())
- IRCD->SendMessage(OperServ, u->nick, "%s", Config->SessionLimitDetailsLoc.c_str());
+ if (!DConfig.sle_reason.empty())
+ {
+ Anope::string message = DConfig.sle_reason.replace_all_cs("%IP%", u->ip);
+ u->SendMessage(OperServ, message);
+ }
+ if (!DConfig.sle_detailsloc.empty())
+ u->SendMessage(OperServ, DConfig.sle_detailsloc);
++session->hits;
- if (akills && Config->MaxSessionKill && session->hits >= Config->MaxSessionKill)
+ if (akills && DConfig.max_session_kill && session->hits >= DConfig.max_session_kill)
{
- XLine x("*@" + u->host, Config->OperServ, Anope::CurTime + Config->SessionAutoKillExpiry, "Defcon session limit exceeded", XLineManager::GenerateUID());
+ XLine x("*@" + u->host, OperServ ? OperServ->nick : "", Anope::CurTime + DConfig.session_autokill_expiry, "Defcon session limit exceeded", XLineManager::GenerateUID());
akills->Send(NULL, &x);
Log(OperServ, "akill/defcon") << "[DEFCON] Added a temporary AKILL for \002*@" << u->host << "\002 due to excessive connections";
}
else
{
- u->Kill(Config->OperServ, "Defcon session limit exceeded");
- u = NULL; /* No guarentee u still exists */
+ u->Kill(OperServ ? OperServ->nick : "", "Defcon session limit exceeded");
}
}
}
diff --git a/modules/commands/os_dns.cpp b/modules/commands/os_dns.cpp
index 346ff4727..9d1a12eb6 100644
--- a/modules/commands/os_dns.cpp
+++ b/modules/commands/os_dns.cpp
@@ -686,15 +686,15 @@ class ModuleDNS : public Module
delete dns_servers->at(i - 1);
}
- void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override
- {
-
- this->ttl = Anope::DoTime(reader.ReadValue("os_dns", "ttl", 0));
- this->user_drop_mark = reader.ReadInteger("os_dns", "user_drop_mark", 0, false);
- this->user_drop_time = Anope::DoTime(reader.ReadValue("os_dns", "user_drop_time", 0, false));
- this->user_drop_readd_time = Anope::DoTime(reader.ReadValue("os_dns", "user_drop_readd_time", 0, false));
- this->remove_split_servers = reader.ReadFlag("os_dns", "remove_split_servers", 0);
- this->readd_connected_servers = reader.ReadFlag("os_dns", "readd_connected_servers", 0);
+ void OnReload(Configuration::Conf *conf) anope_override
+ {
+ Configuration::Block *block = conf->GetModule(this);
+ this->ttl = block->Get<time_t>("ttl");
+ this->user_drop_mark = block->Get<int>("user_drop_mark");
+ this->user_drop_time = block->Get<time_t>("user_drop_time");
+ this->user_drop_readd_time = block->Get<time_t>("user_drop_readd_time");
+ this->remove_split_servers = block->Get<bool>("remove_split_servers");
+ this->readd_connected_servers = block->Get<bool>("readd_connected_servers");
}
void OnNewServer(Server *s) anope_override
diff --git a/modules/commands/os_forbid.cpp b/modules/commands/os_forbid.cpp
index 2144aa591..1d99d47b4 100644
--- a/modules/commands/os_forbid.cpp
+++ b/modules/commands/os_forbid.cpp
@@ -14,6 +14,8 @@
#include "module.h"
#include "os_forbid.h"
+static ServiceReference<NickServService> nickserv("NickServService", "NickServ");
+
class MyForbidService : public ForbidService
{
Serialize::Checker<std::vector<ForbidData *>[FT_SIZE - 1]> forbid_data;
@@ -121,12 +123,6 @@ class CommandOSForbid : public Command
time_t expiryt = 0;
- if (Config->ForceForbidReason && reason.empty())
- {
- this->OnSyntaxError(source, "");
- return;
- }
-
if (!expiry.empty())
{
expiryt = Anope::DoTime(expiry);
@@ -135,7 +131,7 @@ class CommandOSForbid : public Command
}
NickAlias *target = NickAlias::Find(entry);
- if (target != NULL && Config->NSSecureAdmins && target->nc->IsServicesOper())
+ if (target != NULL && Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && target->nc->IsServicesOper())
{
source.Reply(ACCESS_DENIED);
return;
@@ -234,11 +230,12 @@ class CommandOSForbid : public Command
source.Reply(_("Forbid allows you to forbid usage of certain nicknames, channels,\n"
"and email addresses. Wildcards are accepted for all entries."));
- if (!Config->RegexEngine.empty())
+ const Anope::string &regexengine = Config->GetBlock("options")->Get<const Anope::string &>("regexengine");
+ if (!regexengine.empty())
{
source.Reply(" ");
source.Reply(_("Regex matches are also supported using the %s engine.\n"
- "Enclose your pattern in // if this is desired."), Config->RegexEngine.c_str());
+ "Enclose your pattern in // if this is desired."), regexengine.c_str());
}
return true;
@@ -295,21 +292,19 @@ class OSForbid : public Module
ForbidData *d = this->forbidService.FindForbid(c->name, FT_CHAN);
if (d != NULL)
{
- if (IRCD->CanSQLineChannel)
+ ServiceReference<ChanServService> chanserv("ChanServService", "ChanServ");
+ if (!chanserv)
+ ;
+ else if (IRCD->CanSQLineChannel)
{
- XLine x(c->name, OperServ->nick, Anope::CurTime + Config->CSInhabit, d->reason);
+ time_t inhabit = Config->GetModule("chanserv")->Get<time_t>("inhabit", "15s");
+ XLine x(c->name, OperServ->nick, Anope::CurTime + inhabit, d->reason);
IRCD->SendSQLine(NULL, &x);
}
- else if (!c->HasExt("INHABIT"))
+ else
{
- /* Join ChanServ and set a timer for this channel to part ChanServ later */
- c->Hold();
-
- /* Set +si to prevent rejoin */
- c->SetMode(NULL, "NOEXTERNAL");
- c->SetMode(NULL, "TOPIC");
- c->SetMode(NULL, "SECRET");
- c->SetMode(NULL, "INVITE");
+ if (chanserv)
+ chanserv->Hold(c);
}
if (d->reason.empty())
diff --git a/modules/commands/os_ignore.cpp b/modules/commands/os_ignore.cpp
index 1b7ae61c5..073101066 100644
--- a/modules/commands/os_ignore.cpp
+++ b/modules/commands/os_ignore.cpp
@@ -299,11 +299,12 @@ class CommandOSIgnore : public Command
" \n"
"Ignores will not be enforced on IRC Operators."));
- if (!Config->RegexEngine.empty())
+ const Anope::string &regexengine = Config->GetBlock("options")->Get<const Anope::string &>("regexengine");
+ if (!regexengine.empty())
{
source.Reply(" ");
source.Reply(_("Regex matches are also supported using the %s engine.\n"
- "Enclose your pattern in // if this is desired."), Config->RegexEngine.c_str());
+ "Enclose your pattern in // if this is desired."), regexengine.c_str());
}
return true;
diff --git a/modules/commands/os_kill.cpp b/modules/commands/os_kill.cpp
index d3eeedda5..99a65ae4b 100644
--- a/modules/commands/os_kill.cpp
+++ b/modules/commands/os_kill.cpp
@@ -36,10 +36,10 @@ class CommandOSKill : public Command
{
if (reason.empty())
reason = "No reason specified";
- if (Config->AddAkiller)
+ if (Config->GetBlock("operserv")->Get<bool>("addakiller"))
reason = "(" + source.GetNick() + ") " + reason;
Log(LOG_ADMIN, source, this) << "on " << u2->nick << " for " << reason;
- u2->Kill(Config->OperServ, reason);
+ u2->Kill(source.service->nick, reason);
}
}
diff --git a/modules/commands/os_list.cpp b/modules/commands/os_list.cpp
index e8092cb4d..6692f52fd 100644
--- a/modules/commands/os_list.cpp
+++ b/modules/commands/os_list.cpp
@@ -103,11 +103,12 @@ class CommandOSChanList : public Command
"specified, lists only channels matching \002pattern\002 that have the +s or\n"
"+p mode."));
- if (!Config->RegexEngine.empty())
+ const Anope::string &regexengine = Config->GetBlock("options")->Get<const Anope::string &>("regexengine");
+ if (!regexengine.empty())
{
source.Reply(" ");
source.Reply(_("Regex matches are also supported using the %s engine.\n"
- "Enclose your pattern in // if this is desired."), Config->RegexEngine.c_str());
+ "Enclose your pattern in // if this is desired."), regexengine.c_str());
}
return true;
@@ -208,11 +209,12 @@ class CommandOSUserList : public Command
"that are on the given channel. If INVISIBLE is specified, only users\n"
"with the +i flag will be listed."));
- if (!Config->RegexEngine.empty())
+ const Anope::string &regexengine = Config->GetBlock("options")->Get<const Anope::string &>("regexengine");
+ if (!regexengine.empty())
{
source.Reply(" ");
source.Reply(_("Regex matches are also supported using the %s engine.\n"
- "Enclose your pattern in // if this is desired."), Config->RegexEngine.c_str());
+ "Enclose your pattern in // if this is desired."), regexengine.c_str());
}
return true;
diff --git a/modules/commands/os_login.cpp b/modules/commands/os_login.cpp
index 36d772aa2..30172a0f3 100644
--- a/modules/commands/os_login.cpp
+++ b/modules/commands/os_login.cpp
@@ -19,7 +19,6 @@ class CommandOSLogin : public Command
public:
CommandOSLogin(Module *creator) : Command(creator, "operserv/login", 1, 1)
{
- this->SetDesc(Anope::printf(_("Login to %s"), Config->OperServ.c_str()));
this->SetSyntax(_("\037password\037"));
this->RequireUser(true);
}
@@ -60,6 +59,11 @@ class CommandOSLogin : public Command
"configured without a password."), source.service->nick.c_str());
return true;
}
+
+ const Anope::string GetDesc(CommandSource &source) const anope_override
+ {
+ return Anope::printf(_("Login to %s"), source.service->nick.c_str());
+ }
};
class CommandOSLogout : public Command
@@ -67,7 +71,6 @@ class CommandOSLogout : public Command
public:
CommandOSLogout(Module *creator) : Command(creator, "operserv/logout", 0, 0)
{
- this->SetDesc(Anope::printf(_("Logout from %s"), Config->OperServ.c_str()));
this->RequireUser(true);
}
@@ -98,6 +101,11 @@ class CommandOSLogout : public Command
"with a password."), source.service->nick.c_str());
return true;
}
+
+ const Anope::string GetDesc(CommandSource &source) const anope_override
+ {
+ return Anope::printf(_("Logout from %s"), source.service->nick.c_str());
+ }
};
class OSLogin : public Module
diff --git a/modules/commands/os_logsearch.cpp b/modules/commands/os_logsearch.cpp
index c033c6bb5..5bc11a6c9 100644
--- a/modules/commands/os_logsearch.cpp
+++ b/modules/commands/os_logsearch.cpp
@@ -11,8 +11,6 @@
#include "module.h"
-static Anope::string logfile_name;
-
class CommandOSLogSearch : public Command
{
static inline Anope::string CreateLogName(const Anope::string &file, time_t t = Anope::CurTime)
@@ -91,6 +89,7 @@ class CommandOSLogSearch : public Command
Log(LOG_ADMIN, source, this) << "for " << search_string;
+ const Anope::string &logfile_name = Config->GetModule(this->owner)->Get<const Anope::string &>("logname");
std::list<Anope::string> matches;
for (int d = days - 1; d >= 0; --d)
{
@@ -151,13 +150,6 @@ class OSLogSearch : public Module
OSLogSearch(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
commandoslogsearch(this)
{
- Implementation i[] = { I_OnReload };
- ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
- }
-
- void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override
- {
- logfile_name = reader.ReadValue("logsearch", "name", "services.log", 0);
}
};
diff --git a/modules/commands/os_news.cpp b/modules/commands/os_news.cpp
index f72273104..7292b6471 100644
--- a/modules/commands/os_news.cpp
+++ b/modules/commands/os_news.cpp
@@ -271,10 +271,8 @@ class CommandOSLogonNews : public NewsBase
"user connects to the network, these messages will be sent\n"
"to them. (However, no more than \002%d\002 messages will be\n"
"sent in order to avoid flooding the user. If there are\n"
- "more news messages, only the most recent will be sent.)\n"
- "NewsCount can be configured in services.conf.\n"
- " \n"
- "LOGONNEWS may only be used by Services Operators."), Config->NewsCount);
+ "more news messages, only the most recent will be sent."),
+ Config->GetModule(this->owner)->Get<unsigned>("newscount", "3"));
return true;
}
};
@@ -300,10 +298,8 @@ class CommandOSOperNews : public NewsBase
"user opers up (with the /OPER command), these messages will\n"
"be sent to them. (However, no more than \002%d\002 messages will\n"
"be sent in order to avoid flooding the user. If there are\n"
- "more news messages, only the most recent will be sent.)\n"
- "NewsCount can be configured in services.conf.\n"
- " \n"
- "OPERNEWS may only be used by Services Operators."), Config->NewsCount);
+ "more news messages, only the most recent will be sent."),
+ Config->GetModule(this->owner)->Get<unsigned>("newscount", "3"));
return true;
}
};
@@ -327,9 +323,7 @@ class CommandOSRandomNews : public NewsBase
source.Reply(" ");
source.Reply(_("Edits or displays the list of random news messages. When a\n"
"user connects to the network, one (and only one) of the\n"
- "random news will be randomly chosen and sent to them.\n"
- " \n"
- "RANDOMNEWS may only be used by Services Operators."));
+ "random news will be randomly chosen and sent to them.\n"));
return true;
}
};
@@ -358,7 +352,7 @@ class OSNews : public Module
msg = _("[\002Random News\002 - %s] %s");
static unsigned cur_rand_news = 0;
- unsigned displayed = 0;
+ unsigned displayed = 0, news_count = Config->GetModule(this)->Get<unsigned>("newscount", "3");
for (unsigned i = 0, end = newsList.size(); i < end; ++i)
{
if (Type == NEWS_RANDOM && i != cur_rand_news)
@@ -380,7 +374,7 @@ class OSNews : public Module
++cur_rand_news;
break;
}
- else if (displayed >= Config->NewsCount)
+ else if (displayed >= news_count)
break;
}
@@ -393,7 +387,6 @@ class OSNews : public Module
OSNews(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
newsitem_type("NewsItem", NewsItem::Unserialize), newsservice(this), commandoslogonnews(this), commandosopernews(this), commandosrandomnews(this)
{
-
Implementation i[] = { I_OnUserModeSet, I_OnUserConnect };
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
}
diff --git a/modules/commands/os_noop.cpp b/modules/commands/os_noop.cpp
index 1d619dbb6..204b0e6e8 100644
--- a/modules/commands/os_noop.cpp
+++ b/modules/commands/os_noop.cpp
@@ -49,7 +49,7 @@ class CommandOSNOOP : public Command
User *u2 = it->second;
if (u2->server == s && u2->HasMode("OPER"))
- u2->Kill(Config->OperServ, reason);
+ u2->Kill(source.service->nick, reason);
}
}
else if (cmd.equals_ci("REVOKE"))
@@ -95,7 +95,7 @@ class OSNOOP : public Module
if (setter)
{
Anope::string reason = "NOOP command used by " + *setter;
- u->Kill(Config->OperServ, reason);
+ u->Kill(OperServ ? OperServ->nick : "", reason);
}
}
}
diff --git a/modules/commands/os_reload.cpp b/modules/commands/os_reload.cpp
index 00e649ed7..ed04fbea3 100644
--- a/modules/commands/os_reload.cpp
+++ b/modules/commands/os_reload.cpp
@@ -25,10 +25,10 @@ class CommandOSReload : public Command
{
try
{
- ServerConfig *new_config = new ServerConfig();
+ Configuration::Conf *new_config = new Configuration::Conf();
delete Config;
Config = new_config;
- source.Reply(_("Services' configuration file has been reloaded."));
+ source.Reply(_("Services' configuration has been reloaded."));
}
catch (const ConfigException &ex)
{
diff --git a/modules/commands/os_session.cpp b/modules/commands/os_session.cpp
index 67d1b79a3..74f6c2f7e 100644
--- a/modules/commands/os_session.cpp
+++ b/modules/commands/os_session.cpp
@@ -14,6 +14,29 @@
#include "module.h"
#include "os_session.h"
+namespace
+{
+ /* The default session limit */
+ unsigned session_limit;
+ /* How many times to kill before adding an AKILL */
+ unsigned max_session_kill;
+ /* How long session akills should last */
+ time_t session_autokill_expiry;
+ /* Reason to use for session kills */
+ Anope::string sle_reason;
+ /* Optional second reason */
+ Anope::string sle_detailsloc;
+
+ /* Max limit that can be used for exceptions */
+ unsigned max_exception_limit;
+ /* How long before exceptions expire by default */
+ time_t exception_expiry;
+
+ /* Number of bits to use when comparing session IPs */
+ unsigned ipv4_cidr;
+ unsigned ipv6_cidr;
+}
+
class MySessionService : public SessionService
{
SessionMap Sessions;
@@ -68,7 +91,7 @@ class MySessionService : public SessionService
Session *FindSession(const Anope::string &ip) anope_override
{
- cidr c(ip, ip.find(':') != Anope::string::npos ? Config->SessionIPv6CIDR : Config->SessionIPv4CIDR);
+ cidr c(ip, ip.find(':') != Anope::string::npos ? ipv6_cidr : ipv4_cidr);
SessionMap::iterator it = this->Sessions.find(c);
if (it != this->Sessions.end())
return it->second;
@@ -77,13 +100,13 @@ class MySessionService : public SessionService
SessionMap::iterator FindSessionIterator(const Anope::string &ip)
{
- cidr c(ip, ip.find(':') != Anope::string::npos ? Config->SessionIPv6CIDR : Config->SessionIPv4CIDR);
+ cidr c(ip, ip.find(':') != Anope::string::npos ? ipv6_cidr : ipv4_cidr);
return this->Sessions.find(c);
}
Session* &FindOrCreateSession(const Anope::string &ip)
{
- cidr c(ip, ip.find(':') != Anope::string::npos ? Config->SessionIPv6CIDR : Config->SessionIPv4CIDR);
+ cidr c(ip, ip.find(':') != Anope::string::npos ? ipv6_cidr : ipv4_cidr);
return this->Sessions[c];
}
@@ -96,7 +119,7 @@ class MySessionService : public SessionService
class ExpireTimer : public Timer
{
public:
- ExpireTimer() : Timer(Config->ExpireTimeout, Anope::CurTime, true) { }
+ ExpireTimer() : Timer(Config->GetBlock("options")->Get<time_t>("expiretimeout"), Anope::CurTime, true) { }
void Tick(time_t) anope_override
{
@@ -218,10 +241,16 @@ class CommandOSSession : public Command
else
{
Exception *exception = session_service->FindException(param);
- source.Reply(_("The host \002%s\002 currently has \002%d\002 sessions with a limit of \002%d\002."), session->addr.mask().c_str(), session->count, exception && exception->limit > Config->DefSessionLimit ? exception->limit : Config->DefSessionLimit);
+ unsigned limit = session_limit;
+ if (exception)
+ {
+ if (!exception->limit)
+ limit = 0;
+ else if (exception->limit > limit)
+ limit = exception->limit;
+ }
+ source.Reply(_("The host \002%s\002 currently has \002%d\002 sessions with a limit of \002%d\002."), session->addr.mask().c_str(), session->count, limit);
}
-
- return;
}
public:
CommandOSSession(Module *creator) : Command(creator, "operserv/session", 2, 2)
@@ -235,20 +264,14 @@ class CommandOSSession : public Command
{
const Anope::string &cmd = params[0];
- if (!Config->LimitSessions)
- {
+ if (!session_limit)
source.Reply(_("Session limiting is disabled."));
- return;
- }
-
- if (cmd.equals_ci("LIST"))
+ else if (cmd.equals_ci("LIST"))
return this->DoList(source, params);
else if (cmd.equals_ci("VIEW"))
return this->DoView(source, params);
else
this->OnSyntaxError(source, "");
-
- return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
@@ -303,7 +326,7 @@ class CommandOSException : public Command
return;
}
- time_t expires = !expiry.empty() ? Anope::DoTime(expiry) : Config->ExceptionExpiry;
+ time_t expires = !expiry.empty() ? Anope::DoTime(expiry) : exception_expiry;
if (expires < 0)
{
source.Reply(BAD_EXPIRY_TIME);
@@ -319,9 +342,9 @@ class CommandOSException : public Command
}
catch (const ConvertException &) { }
- if (limit > Config->MaxSessionLimit)
+ if (limit > max_exception_limit)
{
- source.Reply(_("Invalid session limit. It must be a valid integer greater than or equal to zero and less than \002%d\002."), Config->MaxSessionLimit);
+ source.Reply(_("Invalid session limit. It must be a valid integer greater than or equal to zero and less than \002%d\002."), max_exception_limit);
return;
}
else
@@ -548,13 +571,9 @@ class CommandOSException : public Command
{
const Anope::string &cmd = params[0];
- if (!Config->LimitSessions)
- {
+ if (!session_limit)
source.Reply(_("Session limiting is disabled."));
- return;
- }
-
- if (cmd.equals_ci("ADD"))
+ else if (cmd.equals_ci("ADD"))
return this->DoAdd(source, params);
else if (cmd.equals_ci("DEL"))
return this->DoDel(source, params);
@@ -566,8 +585,6 @@ class CommandOSException : public Command
return this->DoView(source, params);
else
this->OnSyntaxError(source, "");
-
- return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
@@ -579,10 +596,9 @@ class CommandOSException : public Command
"such as shell servers, to carry more than the default number\n"
"of clients at a time. Once a host reaches its session limit,\n"
"all clients attempting to connect from that host will be\n"
- "killed. Before the user is killed, they are notified, via a\n"
- "/NOTICE from %s, of a source of help regarding session\n"
- "limiting. The content of this notice is a config setting.\n"),
- Config->OperServ.c_str());
+ "killed. Before the user is killed, they are notified, of a\n"
+ "source of help regarding session limiting. The content of\n"
+ "this notice is a config setting.\n"));
source.Reply(" ");
source.Reply(_("\002EXCEPTION ADD\002 adds the given host mask to the exception list.\n"
"Note that \002nick!user@host\002 and \002user@host\002 masks are invalid!\n"
@@ -624,14 +640,34 @@ class OSSession : public Module
{
this->SetPermanent(true);
- Implementation i[] = { I_OnUserConnect, I_OnPreUserLogoff };
+ Implementation i[] = { I_OnReload, I_OnUserConnect, I_OnPreUserLogoff };
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
ModuleManager::SetPriority(this, PRIORITY_FIRST);
}
+ void OnReload(Configuration::Conf *conf) anope_override
+ {
+ Configuration::Block *block = Config->GetModule(this);
+
+ session_limit = block->Get<int>("defaultsessionlimit");
+ max_session_kill = block->Get<int>("maxsessionkill");
+ session_autokill_expiry = block->Get<time_t>("sessionautokillexpiry");
+ sle_reason = block->Get<const Anope::string &>("sessionlimitexceeded");
+ sle_detailsloc = block->Get<const Anope::string &>("sessionlimitdetailsloc");
+
+ max_exception_limit = block->Get<int>("maxsessionlimit");
+ exception_expiry = block->Get<time_t>("exceptionexpiry");
+
+ ipv4_cidr = block->Get<unsigned>("session_ipv4_cidr", "32");
+ ipv6_cidr = block->Get<unsigned>("session_ipv6_cidr", "128");
+
+ if (ipv4_cidr > 32 || ipv6_cidr > 128)
+ throw ConfigException(this->name + ": session CIDR value out of range");
+ }
+
void OnUserConnect(User *u, bool &exempt) anope_override
{
- if (u->Quitting() || !Config->LimitSessions || exempt || !u->server || u->server->IsULined())
+ if (u->Quitting() || !session_limit || exempt || !u->server || u->server->IsULined())
return;
try
@@ -641,7 +677,7 @@ class OSSession : public Module
if (session)
{
bool kill = false;
- if (Config->DefSessionLimit && session->count >= Config->DefSessionLimit)
+ if (session->count >= session_limit)
{
kill = true;
Exception *exception = this->ss.FindException(u);
@@ -658,7 +694,7 @@ class OSSession : public Module
*
* Now, we create the user struture before calling this to fix some user tracking issues,
* so we must increment this here no matter what because it will either be
- * decremented in do_kill or in do_quit - Adam
+ * decremented when the user is killed or quits - Adam
*/
++session->count;
@@ -666,30 +702,33 @@ class OSSession : public Module
{
if (OperServ)
{
- if (!Config->SessionLimitExceeded.empty())
- u->SendMessage(OperServ, Config->SessionLimitExceeded.c_str(), u->ip.c_str());
- if (!Config->SessionLimitDetailsLoc.empty())
- u->SendMessage(OperServ, "%s", Config->SessionLimitDetailsLoc.c_str());
+ if (!sle_reason.empty())
+ {
+ Anope::string message = sle_reason.replace_all_cs("%IP%", u->ip);
+ u->SendMessage(OperServ, message);
+ }
+ if (!sle_detailsloc.empty())
+ u->SendMessage(OperServ, sle_detailsloc);
}
++session->hits;
- if (Config->MaxSessionKill && session->hits >= Config->MaxSessionKill && akills)
+ if (max_session_kill && session->hits >= max_session_kill && akills)
{
const Anope::string &akillmask = "*@" + u->ip;
- XLine *x = new XLine(akillmask, Config->OperServ, Anope::CurTime + Config->SessionAutoKillExpiry, "Session limit exceeded", XLineManager::GenerateUID());
+ XLine *x = new XLine(akillmask, OperServ ? OperServ->nick : "", Anope::CurTime + session_autokill_expiry, "Session limit exceeded", XLineManager::GenerateUID());
akills->AddXLine(x);
akills->Send(NULL, x);
Log(OperServ, "akill/session") << "Added a temporary AKILL for \002" << akillmask << "\002 due to excessive connections";
}
else
{
- u->Kill(Config->OperServ, "Session limit exceeded");
+ u->Kill(OperServ ? OperServ->nick : "", "Session limit exceeded");
}
}
}
else
{
- session = new Session(u->ip, u->ip.find(':') != Anope::string::npos ? Config->SessionIPv6CIDR : Config->SessionIPv4CIDR);
+ session = new Session(u->ip, u->ip.find(':') != Anope::string::npos ? ipv6_cidr : ipv4_cidr);
}
}
catch (const SocketException &) { }
@@ -697,7 +736,7 @@ class OSSession : public Module
void OnPreUserLogoff(User *u) anope_override
{
- if (!Config->LimitSessions || !u->server || u->server->IsULined())
+ if (!session_limit || !u->server || u->server->IsULined())
return;
SessionService::SessionMap::iterator sit;
diff --git a/modules/commands/os_set.cpp b/modules/commands/os_set.cpp
index 6d701dd11..6fc05ab60 100644
--- a/modules/commands/os_set.cpp
+++ b/modules/commands/os_set.cpp
@@ -78,22 +78,23 @@ class CommandOSSet : public Command
*
* Rob
**/
- if (!Config->SuperAdmin)
- source.Reply(_("SuperAdmin can not be set because it is not enabled in the configuration."));
+ bool super_admin = Config->GetModule(this->owner)->Get<bool>("superadmin");
+ if (!super_admin)
+ source.Reply(_("Super admin can not be set because it is not enabled in the configuration."));
else if (setting.equals_ci("ON"))
{
source.GetUser()->super_admin = true;
- source.Reply(_("You are now a SuperAdmin."));
+ source.Reply(_("You are now a super admin."));
Log(LOG_ADMIN, source, this) << "SUPERADMIN ON";
}
else if (setting.equals_ci("OFF"))
{
source.GetUser()->super_admin = false;
- source.Reply(_("You are no longer a SuperAdmin."));
+ source.Reply(_("You are no longer a super admin."));
Log(LOG_ADMIN, source, this) << "SUPERADMIN OFF";
}
else
- source.Reply(_("Setting for SuperAdmin must be \002ON\002 or \002OFF\002."));
+ source.Reply(_("Setting for super admin must be \002ON\002 or \002OFF\002."));
return;
}
@@ -202,12 +203,12 @@ class CommandOSSet : public Command
" READONLY Set read-only or read-write mode\n"
" DEBUG Activate or deactivate debug mode\n"
" NOEXPIRE Activate or deactivate no expire mode\n"
- " SUPERADMIN Activate or deactivate SuperAdmin mode\n"
+ " SUPERADMIN Activate or deactivate super admin mode\n"
" LIST List the options"));
}
else if (subcommand.equals_ci("LIST"))
source.Reply(_("Syntax: \002LIST\n"
- "Display the various %s settings"), Config->OperServ.c_str());
+ "Display the various %s settings"), source.service->nick.c_str());
else if (subcommand.equals_ci("READONLY"))
source.Reply(_("Syntax: \002READONLY {ON | OFF}\002\n"
" \n"
@@ -249,7 +250,6 @@ class OSSet : public Module
OSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
commandosset(this)
{
-
}
};
diff --git a/modules/commands/os_stats.cpp b/modules/commands/os_stats.cpp
index 7aa8740c7..04bd6e60d 100644
--- a/modules/commands/os_stats.cpp
+++ b/modules/commands/os_stats.cpp
@@ -62,7 +62,7 @@ class CommandOSStats : public Command
{
/* AKILLs */
source.Reply(_("Current number of AKILLs: \002%d\002"), akills->GetCount());
- timeout = Config->AutokillExpiry + 59;
+ timeout = Config->GetModule("operserv")->Get<time_t>("autokillexpiry", "30d") + 59;
if (timeout >= 172800)
source.Reply(_("Default AKILL expiry time: \002%d days\002"), timeout / 86400);
else if (timeout >= 86400)
@@ -82,7 +82,7 @@ class CommandOSStats : public Command
{
/* SNLINEs */
source.Reply(_("Current number of SNLINEs: \002%d\002"), snlines->GetCount());
- timeout = Config->SNLineExpiry + 59;
+ timeout = Config->GetModule("operserv")->Get<time_t>("snlineexpiry", "30d") + 59;
if (timeout >= 172800)
source.Reply(_("Default SNLINE expiry time: \002%d days\002"), timeout / 86400);
else if (timeout >= 86400)
@@ -102,7 +102,7 @@ class CommandOSStats : public Command
{
/* SQLINEs */
source.Reply(_("Current number of SQLINEs: \002%d\002"), sqlines->GetCount());
- timeout = Config->SQLineExpiry + 59;
+ timeout = Config->GetModule("operserv")->Get<time_t>("sglineexpiry", "30d") + 59;
if (timeout >= 172800)
source.Reply(_("Default SQLINE expiry time: \002%d days\002"), timeout / 86400);
else if (timeout >= 86400)
@@ -118,7 +118,6 @@ class CommandOSStats : public Command
else
source.Reply(_("Default SQLINE expiry time: \002No expiration\002"));
}
- return;
}
void DoStatsReset(CommandSource &source)
diff --git a/modules/commands/os_svs.cpp b/modules/commands/os_svs.cpp
index 13b29e84c..9fb1d63c3 100644
--- a/modules/commands/os_svs.cpp
+++ b/modules/commands/os_svs.cpp
@@ -34,11 +34,12 @@ class CommandOSSVSNick : public Command
return;
}
- /* Truncate long nicknames to Config->NickLen characters */
- if (newnick.length() > Config->NickLen)
+ /* Truncate long nicknames to nicklen characters */
+ unsigned nicklen = Config->GetBlock("networkinfo")->Get<unsigned>("nicklen");
+ if (newnick.length() > nicklen)
{
- source.Reply(_("Nick \002%s\002 was truncated to %d characters."), newnick.c_str(), Config->NickLen, newnick.c_str());
- newnick = params[1].substr(0, Config->NickLen);
+ source.Reply(_("Nick \002%s\002 was truncated to %d characters."), newnick.c_str(), nicklen, newnick.c_str());
+ newnick = params[1].substr(0, nicklen);
}
/* Check for valid characters */
diff --git a/modules/commands/os_sxline.cpp b/modules/commands/os_sxline.cpp
index 1cf921467..efe81955d 100644
--- a/modules/commands/os_sxline.cpp
+++ b/modules/commands/os_sxline.cpp
@@ -258,7 +258,6 @@ class CommandOSSNLine : public CommandOSSXLineBase
unsigned last_param = 2;
Anope::string param, expiry;
- time_t expires;
param = params.size() > 1 ? params[1] : "";
if (!param.empty() && param[0] == '+')
@@ -268,7 +267,7 @@ class CommandOSSNLine : public CommandOSSXLineBase
last_param = 3;
}
- expires = !expiry.empty() ? Anope::DoTime(expiry) : Config->SNLineExpiry;
+ time_t expires = !expiry.empty() ? Anope::DoTime(expiry) : Config->GetModule("operserv")->Get<time_t>("snlineexpiry", "30d");
/* If the expiry given does not contain a final letter, it's in days,
* said the doc. Ah well.
*/
@@ -312,16 +311,18 @@ class CommandOSSNLine : public CommandOSSXLineBase
if (mask[0] == '/' && mask[mask.length() - 1] == '/')
{
- if (Config->RegexEngine.empty())
+ const Anope::string &regexengine = Config->GetBlock("options")->Get<const Anope::string &>("regexengine");
+
+ if (regexengine.empty())
{
- source.Reply(_("Regex is enabled."));
+ source.Reply(_("Regex is disabled."));
return;
}
- ServiceReference<RegexProvider> provider("Regex", Config->RegexEngine);
+ ServiceReference<RegexProvider> provider("Regex", regexengine);
if (!provider)
{
- source.Reply(_("Unable to find regex engine %s."), Config->RegexEngine.c_str());
+ source.Reply(_("Unable to find regex engine %s."), regexengine.c_str());
return;
}
@@ -352,8 +353,11 @@ class CommandOSSNLine : public CommandOSSXLineBase
if (mask[masklen - 1] == ' ')
mask.erase(masklen - 1);
+ if (Config->GetModule("operserv")->Get<bool>("addakiller", "yes") && !source.GetNick().empty())
+ reason = "[" + source.GetNick() + "] " + reason;
+
XLine *x = new XLine(mask, source.GetNick(), expires, reason);
- if (Config->AkillIds)
+ if (Config->GetBlock("operserv")->Get<bool>("akilids"))
x->id = XLineManager::GenerateUID();
unsigned int affected = 0;
@@ -380,7 +384,7 @@ class CommandOSSNLine : public CommandOSSXLineBase
this->xlm()->AddXLine(x);
- if (Config->KillonSNline)
+ if (Config->GetModule("operserv")->Get<bool>("killonsnline", "yes"))
{
this->xlm()->Send(source.GetUser(), x);
@@ -391,7 +395,7 @@ class CommandOSSNLine : public CommandOSSXLineBase
User *user = it->second;
if (!user->HasMode("OPER") && user->server != Me && Anope::Match(user->realname, x->mask, false, true))
- user->Kill(Config->ServerName, rreason);
+ user->Kill(Me->GetName(), rreason);
}
}
@@ -434,11 +438,12 @@ class CommandOSSNLine : public CommandOSSXLineBase
"\002STATS AKILL\002 command.\n"
"Note: because the realname mask may contain spaces, the\n"
"separator between it and the reason is a colon."));
- if (!Config->RegexEngine.empty())
+ const Anope::string &regexengine = Config->GetBlock("options")->Get<const Anope::string &>("regexengine");
+ if (!regexengine.empty())
{
source.Reply(" ");
source.Reply(_("Regex matches are also supported using the %s engine.\n"
- "Enclose your mask in // if this is desired."), Config->RegexEngine.c_str());
+ "Enclose your mask in // if this is desired."), regexengine.c_str());
}
source.Reply(_(" \n"
"The \002SNLINE DEL\002 command removes the given mask from the\n"
@@ -480,7 +485,6 @@ class CommandOSSQLine : public CommandOSSXLineBase
unsigned last_param = 2;
Anope::string expiry, mask;
- time_t expires;
mask = params.size() > 1 ? params[1] : "";
if (!mask.empty() && mask[0] == '+')
@@ -490,7 +494,7 @@ class CommandOSSQLine : public CommandOSSXLineBase
last_param = 3;
}
- expires = !expiry.empty() ? Anope::DoTime(expiry) : Config->SQLineExpiry;
+ time_t expires = !expiry.empty() ? Anope::DoTime(expiry) : Config->GetModule("operserv")->Get<time_t>("sqlineexpiry", "30d");
/* If the expiry given does not contain a final letter, it's in days,
* said the doc. Ah well.
*/
@@ -523,16 +527,18 @@ class CommandOSSQLine : public CommandOSSXLineBase
if (mask[0] == '/' && mask[mask.length() - 1] == '/')
{
- if (Config->RegexEngine.empty())
+ const Anope::string &regexengine = Config->GetBlock("options")->Get<const Anope::string &>("regexengine");
+
+ if (regexengine.empty())
{
- source.Reply(_("Regex is enabled."));
+ source.Reply(_("Regex is disabled."));
return;
}
- ServiceReference<RegexProvider> provider("Regex", Config->RegexEngine);
+ ServiceReference<RegexProvider> provider("Regex", regexengine);
if (!provider)
{
- source.Reply(_("Unable to find regex engine %s."), Config->RegexEngine.c_str());
+ source.Reply(_("Unable to find regex engine %s."), regexengine.c_str());
return;
}
@@ -556,8 +562,11 @@ class CommandOSSQLine : public CommandOSSXLineBase
return;
}
+ if (Config->GetModule("operserv")->Get<bool>("addakiller", "yes") && !source.GetNick().empty())
+ reason = "[" + source.GetNick() + "] " + reason;
+
XLine *x = new XLine(mask, source.GetNick(), expires, reason);
- if (Config->AkillIds)
+ if (Config->GetBlock("operserv")->Get<bool>("akilids"))
x->id = XLineManager::GenerateUID();
unsigned int affected = 0;
@@ -583,7 +592,8 @@ class CommandOSSQLine : public CommandOSSXLineBase
}
this->xlm()->AddXLine(x);
- if (Config->KillonSQline)
+
+ if (Config->GetModule("operserv")->Get<bool>("killonsqline", "yes"))
{
Anope::string rreason = "Q-Lined: " + reason;
@@ -617,7 +627,7 @@ class CommandOSSQLine : public CommandOSSXLineBase
User *user = it->second;
if (!user->HasMode("OPER") && user->server != Me && Anope::Match(user->nick, x->mask, false, true))
- user->Kill(Config->ServerName, rreason);
+ user->Kill(Me->GetName(), rreason);
}
}
@@ -664,11 +674,12 @@ class CommandOSSQLine : public CommandOSSXLineBase
"must be given, even if it is the same as the default. The\n"
"current SQLINE default expiry time can be found with the\n"
"\002STATS AKILL\002 command."));
- if (!Config->RegexEngine.empty())
+ const Anope::string &regexengine = Config->GetBlock("options")->Get<const Anope::string &>("regexengine");
+ if (!regexengine.empty())
{
source.Reply(" ");
source.Reply(_("Regex matches are also supported using the %s engine.\n"
- "Enclose your mask in // if this is desired."), Config->RegexEngine.c_str());
+ "Enclose your mask in // if this is desired."), regexengine.c_str());
}
source.Reply(_(" \n"
"The \002SQLINE DEL\002 command removes the given mask from the\n"
diff --git a/modules/database/db_flatfile.cpp b/modules/database/db_flatfile.cpp
index dcf4a5aa4..8cede5394 100644
--- a/modules/database/db_flatfile.cpp
+++ b/modules/database/db_flatfile.cpp
@@ -102,12 +102,10 @@ class LoadData : public Serialize::Data
class DBFlatFile : public Module, public Pipe
{
- Anope::string database_file;
/* Day the last backup was on */
int last_day;
/* Backup file names */
std::map<Anope::string, std::list<Anope::string> > backups;
- bool use_fork;
bool loaded;
void BackupDatabase()
@@ -121,7 +119,7 @@ class DBFlatFile : public Module, public Pipe
const std::vector<Anope::string> &type_order = Serialize::Type::GetTypeOrder();
std::set<Anope::string> dbs;
- dbs.insert(database_file);
+ dbs.insert(Config->GetModule(this)->Get<const Anope::string &>("database"));
for (unsigned i = 0; i < type_order.size(); ++i)
{
@@ -146,7 +144,7 @@ class DBFlatFile : public Module, public Pipe
{
Log(this) << "Unable to back up database " << *it << "!";
- if (!Config->NoBackupOkay)
+ if (!Config->GetModule(this)->Get<bool>("nobackupok"))
Anope::Quitting = true;
continue;
@@ -154,7 +152,8 @@ class DBFlatFile : public Module, public Pipe
backups[*it].push_back(newname);
- if (Config->KeepBackups > 0 && backups[*it].size() > static_cast<unsigned>(Config->KeepBackups))
+ unsigned keepbackups = Config->GetModule(this)->Get<unsigned>("keepbackups");
+ if (keepbackups > 0 && backups[*it].size() > keepbackups)
{
unlink(backups[*it].front().c_str());
backups[*it].pop_front();
@@ -164,10 +163,10 @@ class DBFlatFile : public Module, public Pipe
}
public:
- DBFlatFile(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, DATABASE | VENDOR), last_day(0), use_fork(false), loaded(false)
+ DBFlatFile(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, DATABASE | VENDOR), last_day(0), loaded(false)
{
- Implementation i[] = { I_OnReload, I_OnLoadDatabase, I_OnSaveDatabase, I_OnSerializeTypeCreate };
+ Implementation i[] = { I_OnLoadDatabase, I_OnSaveDatabase, I_OnSerializeTypeCreate };
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
}
@@ -187,22 +186,16 @@ class DBFlatFile : public Module, public Pipe
Log(this) << "Error saving databases: " << buf;
- if (!Config->NoBackupOkay)
+ if (!Config->GetModule(this)->Get<bool>("nobackupok"))
Anope::Quitting = true;
}
- void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override
- {
- database_file = reader.ReadValue("db_flatfile", "database", "anope.db", 0);
- use_fork = reader.ReadFlag("db_flatfile", "fork", "no", 0);
- }
-
EventReturn OnLoadDatabase() anope_override
{
const std::vector<Anope::string> &type_order = Serialize::Type::GetTypeOrder();
std::set<Anope::string> tried_dbs;
- const Anope::string &db_name = Anope::DataDir + "/" + database_file;
+ const Anope::string &db_name = Anope::DataDir + "/" + Config->GetModule(this)->Get<const Anope::string &>("database");
std::fstream fd(db_name.c_str(), std::ios_base::in);
if (!fd.is_open())
@@ -253,7 +246,7 @@ class DBFlatFile : public Module, public Pipe
int i = -1;
#ifndef _WIN32
- if (use_fork)
+ if (Config->GetModule(this)->Get<bool>("fork"))
{
i = fork();
if (i > 0)
@@ -279,7 +272,7 @@ class DBFlatFile : public Module, public Pipe
if (s_type->GetOwner())
db_name = Anope::DataDir + "/module_" + s_type->GetOwner()->name + ".db";
else
- db_name = Anope::DataDir + "/" + database_file;
+ db_name = Anope::DataDir + "/" + Config->GetModule(this)->Get<const Anope::string &>("database");
if (Anope::IsFile(db_name))
rename(db_name.c_str(), (db_name + ".tmp").c_str());
@@ -311,7 +304,7 @@ class DBFlatFile : public Module, public Pipe
for (std::map<Module *, std::fstream *>::iterator it = databases.begin(), it_end = databases.end(); it != it_end; ++it)
{
std::fstream *f = it->second;
- const Anope::string &db_name = Anope::DataDir + "/" + (it->first ? (it->first->name + ".db") : database_file);
+ const Anope::string &db_name = Anope::DataDir + "/" + (it->first ? (it->first->name + ".db") : Config->GetModule(this)->Get<const Anope::string &>("database"));
if (!f->is_open() || !f->good())
{
@@ -356,7 +349,7 @@ class DBFlatFile : public Module, public Pipe
if (stype->GetOwner())
db_name = Anope::DataDir + "/module_" + stype->GetOwner()->name + ".db";
else
- db_name = Anope::DataDir + "/" + database_file;
+ db_name = Anope::DataDir + "/" + Config->GetModule(this)->Get<const Anope::string &>("database");
std::fstream fd(db_name.c_str(), std::ios_base::in);
if (!fd.is_open())
diff --git a/modules/database/db_old.cpp b/modules/database/db_old.cpp
index 6eba8a2a9..52d61bfad 100644
--- a/modules/database/db_old.cpp
+++ b/modules/database/db_old.cpp
@@ -1098,8 +1098,7 @@ class DBOld : public Module
Implementation i[] = { I_OnLoadDatabase, I_OnUplinkSync };
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
- ConfigReader conf;
- hashm = conf.ReadValue("db_old", "hash", "", 0);
+ hashm = Config->GetModule(this)->Get<const Anope::string &>("hash");
if (hashm != "md5" && hashm != "oldmd5" && hashm != "sha1" && hashm != "plain" && hashm != "sha256")
throw ModuleException("Invalid hash method");
diff --git a/modules/database/db_plain.cpp b/modules/database/db_plain.cpp
index 11274c593..76a2aa455 100644
--- a/modules/database/db_plain.cpp
+++ b/modules/database/db_plain.cpp
@@ -136,7 +136,7 @@ EventReturn OnDatabaseReadMetadata(ChannelInfo *ci, const Anope::string &key, co
try
{
if (key.equals_ci("BANTYPE"))
- ci->bantype = params[0].is_pos_number_only() ? convertTo<int16_t>(params[0]) : Config->CSDefBantype;
+ ci->bantype = params[0].is_pos_number_only() ? convertTo<int16_t>(params[0]) : 2;
else if (key.equals_ci("MEMOMAX"))
ci->memos.memomax = params[0].is_pos_number_only() ? convertTo<int16_t>(params[0]) : -1;
else if (key.equals_ci("FOUNDER"))
@@ -618,7 +618,7 @@ class DBPlain : public Module
{
Log() << "Unable to back up database!";
- if (!Config->NoBackupOkay)
+ if (!Config->GetModule(this)->Get<bool>("nobackupok"))
Anope::Quitting = true;
return;
@@ -626,7 +626,7 @@ class DBPlain : public Module
Backups.push_back(newname);
- unsigned KeepBackups = Config->KeepBackups;
+ unsigned KeepBackups = Config->GetModule(this)->Get<unsigned>("keepbackups");
if (KeepBackups && Backups.size() > KeepBackups)
{
unlink(Backups.front().c_str());
@@ -635,10 +635,12 @@ class DBPlain : public Module
}
}
- void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override
+ void OnReload(Configuration::Conf *conf) anope_override
{
- DatabaseFile = Anope::DataDir + "/" + reader.ReadValue("db_plain", "database", "anope.db", 0);
- BackupFile = Anope::DataDir + "/backups/" + reader.ReadValue("db_plain", "database", "anope.db", 0);
+ DatabaseFile = Anope::DataDir + "/" + conf->GetModule(this)->Get<const Anope::string &>("database");
+ if (DatabaseFile.empty())
+ DatabaseFile = "anope.db";
+ BackupFile = Anope::DataDir + "/backups/" + DatabaseFile;
}
EventReturn OnLoadDatabase() anope_override
diff --git a/modules/database/db_sql.cpp b/modules/database/db_sql.cpp
index 894037026..400619159 100644
--- a/modules/database/db_sql.cpp
+++ b/modules/database/db_sql.cpp
@@ -146,12 +146,12 @@ class DBSQL : public Module, public Pipe
this->imported = true;
}
- void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override
+ void OnReload(Configuration::Conf *conf) anope_override
{
- Anope::string engine = reader.ReadValue("db_sql", "engine", "", 0);
- this->sql = ServiceReference<Provider>("SQL::Provider", engine);
- this->prefix = reader.ReadValue("db_sql", "prefix", "anope_db_", 0);
- this->import = reader.ReadFlag("db_sql", "import", "false", 0);
+ Configuration::Block *block = conf->GetModule(this);
+ this->sql = ServiceReference<Provider>("SQL::Provider", block->Get<const Anope::string &>("engine"));
+ this->prefix = block->Get<const Anope::string &>("prefix", "anope_db_");
+ this->import = block->Get<bool>("import");
}
void OnShutdown() anope_override
diff --git a/modules/database/db_sql_live.cpp b/modules/database/db_sql_live.cpp
index 239c543c2..a7116892d 100644
--- a/modules/database/db_sql_live.cpp
+++ b/modules/database/db_sql_live.cpp
@@ -7,7 +7,6 @@ using namespace SQL;
class DBMySQL : public Module, public Pipe
{
private:
- Anope::string engine;
Anope::string prefix;
ServiceReference<Provider> SQL;
time_t lastwarn;
@@ -29,7 +28,7 @@ class DBMySQL : public Module, public Pipe
}
else
{
- if (Anope::CurTime - Config->UpdateTimeout > lastwarn)
+ if (Anope::CurTime - Config->GetBlock("options")->Get<time_t>("updatetimeout") > lastwarn)
{
Log() << "Unable to locate SQL reference, going to readonly...";
Anope::ReadOnly = this->ro = true;
@@ -130,11 +129,11 @@ class DBMySQL : public Module, public Pipe
init = false;
}
- void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override
+ void OnReload(Configuration::Conf *conf) anope_override
{
- this->engine = reader.ReadValue("db_sql", "engine", "", 0);
- this->SQL = ServiceReference<Provider>("SQL::Provider", this->engine);
- this->prefix = reader.ReadValue("db_sql", "prefix", "anope_db_", 0);
+ Configuration::Block *block = conf->GetModule(this);
+ this->SQL = ServiceReference<Provider>("SQL::Provider", block->Get<const Anope::string &>("engine"));
+ this->prefix = block->Get<const Anope::string &>("prefix", "anope_db_");
}
void OnSerializableConstruct(Serializable *obj) anope_override
diff --git a/modules/extra/m_chanstats.cpp b/modules/extra/m_chanstats.cpp
index caa20aacb..f5e20646b 100644
--- a/modules/extra/m_chanstats.cpp
+++ b/modules/extra/m_chanstats.cpp
@@ -1,5 +1,5 @@
#include "module.h"
-#include "../extra/sql.h"
+#include "sql.h"
class MySQLInterface : public SQL::Interface
{
@@ -338,7 +338,7 @@ class MChanstats : public Module
{
Implementation i[] = { I_OnPrivmsg,
- I_OnUserKicked,
+ I_OnPreUserKicked,
I_OnChannelModeSet,
I_OnChannelModeUnset,
I_OnTopicUpdated,
@@ -349,14 +349,15 @@ class MChanstats : public Module
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
}
- void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override
+ void OnReload(Configuration::Conf *conf) anope_override
{
- prefix = reader.ReadValue("chanstats", "prefix", "anope_", 0);
- SmileysHappy = reader.ReadValue("chanstats", "SmileysHappy", ":) :-) ;) :D :-D", 0);
- SmileysSad = reader.ReadValue("chanstats", "SmileysSad", ":( :-( ;( ;-(", 0);
- SmileysOther = reader.ReadValue("chanstats", "SmileysOther", ":/", 0);
+ Configuration::Block *block = conf->GetModule(this);
+ prefix = block->Get<const Anope::string &>("prefix", "anope_");
+ SmileysHappy = block->Get<const Anope::string &>("SmileysHappy");
+ SmileysSad = block->Get<const Anope::string &>("SmileysSad");
+ SmileysOther = block->Get<const Anope::string &>("SmileysOther");
- Anope::string engine = reader.ReadValue("chanstats", "engine", "", 0);
+ Anope::string engine = block->Get<const Anope::string &>("engine");
this->sql = ServiceReference<SQL::Provider>("SQL::Provider", engine);
if (sql)
this->CheckTables();
@@ -399,24 +400,24 @@ class MChanstats : public Module
this->RunQuery(query);
}
public:
- void OnUserKicked(Channel *c, User *target, MessageSource &source, const Anope::string &kickmsg) anope_override
+ void OnPreUserKicked(MessageSource &source, ChanUserContainer *cu, const Anope::string &kickmsg) anope_override
{
- if (!c->ci || !c->ci->HasExt("STATS"))
+ if (!cu->chan->ci || !cu->chan->ci->HasExt("STATS"))
return;
query = "CALL " + prefix + "chanstats_proc_update(@channel@, @nick@, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0);";
- query.SetValue("channel", c->name);
- query.SetValue("nick", GetDisplay(target));
+ query.SetValue("channel", cu->chan->name);
+ query.SetValue("nick", GetDisplay(cu->user));
this->RunQuery(query);
query = "CALL " + prefix + "chanstats_proc_update(@channel@, @nick@, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0);";
- query.SetValue("channel", c->name);
+ query.SetValue("channel", cu->chan->name);
query.SetValue("nick", GetDisplay(source.GetUser()));
this->RunQuery(query);
}
void OnPrivmsg(User *u, Channel *c, Anope::string &msg) anope_override
{
- if (!c->ci || !c->ci->HasExt("STATS") || (msg[0] == Config->BSFantasyCharacter[0]))
+ if (!c->ci || !c->ci->HasExt("STATS"))
return;
size_t letters = msg.length();
diff --git a/modules/extra/m_httpd.cpp b/modules/extra/m_httpd.cpp
index 5e643d942..87d1ad6a1 100644
--- a/modules/extra/m_httpd.cpp
+++ b/modules/extra/m_httpd.cpp
@@ -352,21 +352,24 @@ class HTTPD : public Module
this->providers.clear();
}
- void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override
+ void OnReload(Configuration::Conf *conf) anope_override
{
std::set<Anope::string> existing;
- for (int i = 0, num = reader.Enumerate("httpd"); i < num; ++i)
+ for (int i = 0; i < conf->CountBlock("httpd"); ++i)
{
- Anope::string hname = reader.ReadValue("httpd", "name", "httpd/main", i);
+ Configuration::Block *block = conf->GetBlock("httpd", i);
+
+
+ const Anope::string &hname = block->Get<const Anope::string &>("name", "httpd/main");
existing.insert(hname);
- Anope::string ip = reader.ReadValue("httpd", "ip", "", i);
- int port = reader.ReadInteger("httpd", "port", "8080", i, true);
- int timeout = reader.ReadInteger("httpd", "timeout", "30", i, true);
- bool ssl = reader.ReadFlag("httpd", "ssl", "no", i);
- Anope::string ext_ip = reader.ReadValue("httpd", "extforward_ip", "", i);
- Anope::string ext_header = reader.ReadValue("httpd", "extforward_header", "", i);
+ Anope::string ip = block->Get<const Anope::string &>("ip");
+ int port = block->Get<int>("port", "8080");
+ int timeout = block->Get<int>("timeout", "30");
+ bool ssl = block->Get<bool>("ssl", "no");
+ Anope::string ext_ip = block->Get<const Anope::string &>("extforward_ip");
+ Anope::string ext_header = block->Get<const Anope::string &>("extforward_header");
if (ip.empty())
{
diff --git a/modules/extra/m_ldap.cpp b/modules/extra/m_ldap.cpp
index 3200d3e38..a6066c008 100644
--- a/modules/extra/m_ldap.cpp
+++ b/modules/extra/m_ldap.cpp
@@ -1,7 +1,7 @@
/* RequiredLibraries: ldap,lber */
#include "module.h"
-#include "ldap.h"
+#include "ldapapi.h"
#include <ldap.h>
static Pipe *me;
@@ -423,7 +423,7 @@ class ModuleLDAP : public Module, public Pipe
LDAPServices.clear();
}
- void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override
+ void OnReload(Configuration::Conf *conf) anope_override
{
int i, num;
@@ -433,13 +433,9 @@ class ModuleLDAP : public Module, public Pipe
LDAPService *s = it->second;
++it;
- for (i = 0, num = reader.Enumerate("ldap"); i < num; ++i)
- {
- if (reader.ReadValue("ldap", "name", "main", i) == cname)
- {
+ for (i = 0; i < Config->CountBlock("ldap"); ++i)
+ if (Config->GetBlock("ldap", i)->Get<const Anope::string &>("name", "ldap/main") == cname)
break;
- }
- }
if (i == num)
{
@@ -451,16 +447,16 @@ class ModuleLDAP : public Module, public Pipe
}
}
- for (i = 0, num = reader.Enumerate("ldap"); i < num; ++i)
+ for (i = 0; i < Config->CountBlock("ldap"); ++i)
{
- Anope::string connname = reader.ReadValue("ldap", "name", "main", i);
+ const Anope::string &connname = Config->GetBlock("ldap", i)->Get<const Anope::string &>("name", "ldap/main");
if (this->LDAPServices.find(connname) == this->LDAPServices.end())
{
- Anope::string server = reader.ReadValue("ldap", "server", "127.0.0.1", i);
- int port = reader.ReadInteger("ldap", "port", "389", i, true);
- Anope::string admin_binddn = reader.ReadValue("ldap", "admin_binddn", "", i);
- Anope::string admin_password = reader.ReadValue("ldap", "admin_password", "", i);
+ const Anope::string &server = Config->GetBlock("ldap", i)->Get<const Anope::string &>("server", "127.0.0.1");
+ int port = Config->GetBlock("ldap", i)->Get<int>("port", "389");
+ const Anope::string &admin_binddn = Config->GetBlock("ldap", i)->Get<const Anope::string &>("admin_binddn");
+ const Anope::string &admin_password = Config->GetBlock("ldap", i)->Get<const Anope::string &>("admin_password");
try
{
diff --git a/modules/extra/m_ldap_authentication.cpp b/modules/extra/m_ldap_authentication.cpp
index f39bb43e8..a8ece73ff 100644
--- a/modules/extra/m_ldap_authentication.cpp
+++ b/modules/extra/m_ldap_authentication.cpp
@@ -1,6 +1,6 @@
#include "module.h"
#include "nickserv.h"
-#include "ldap.h"
+#include "ldapapi.h"
static Module *me;
@@ -104,14 +104,9 @@ class IdentifyInterface : public LDAPInterface
if (na == NULL)
{
na = new NickAlias(ii->req->GetAccount(), new NickCore(ii->req->GetAccount()));
- if (ii->user)
- {
- if (Config->NSAddAccessOnReg)
- na->nc->AddAccess(ii->user->Mask());
-
- if (NickServ)
- ii->user->SendMessage(NickServ, _("Your account \002%s\002 has been successfully created."), na->nick.c_str());
- }
+ FOREACH_MOD(I_OnNickRegister, OnNickRegister(ii->user, na));
+ if (ii->user && NickServ)
+ ii->user->SendMessage(NickServ, _("Your account \002%s\002 has been successfully created."), na->nick.c_str());
}
// encrypt and store the password in the nickcore
Anope::Encrypt(ii->req->GetPassword(), na->nc->pass);
@@ -226,21 +221,22 @@ class NSIdentifyLDAP : public Module
ModuleManager::SetPriority(this, PRIORITY_FIRST);
}
- void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override
+ void OnReload(Configuration::Conf *conf) anope_override
{
+ Configuration::Block *config = Config->GetModule(this);
- basedn = reader.ReadValue("m_ldap_authentication", "basedn", "", 0);
- search_filter = reader.ReadValue("m_ldap_authentication", "search_filter", "", 0);
- object_class = reader.ReadValue("m_ldap_authentication", "object_class", "", 0);
- username_attribute = reader.ReadValue("m_ldap_authentication", "username_attribute", "", 0);
- this->password_attribute = reader.ReadValue("m_ldap_authentication", "password_attribute", "", 0);
- email_attribute = reader.ReadValue("m_ldap_authentication", "email_attribute", "", 0);
- this->disable_register_reason = reader.ReadValue("m_ldap_authentication", "disable_register_reason", "", 0);
- this->disable_email_reason = reader.ReadValue("m_ldap_authentication", "disable_email_reason", "", 0);
+ basedn = conf->Get<const Anope::string &>("basedn");
+ search_filter = conf->Get<const Anope::string &>("search_filter");
+ object_class = conf->Get<const Anope::string &>("object_class");
+ username_attribute = conf->Get<const Anope::string &>("username_attribute");
+ this->password_attribute = conf->Get<const Anope::string &>("password_attribute");
+ email_attribute = conf->Get<const Anope::string &>("email_attribute");
+ this->disable_register_reason = conf->Get<const Anope::string &>("disable_register_reason");
+ this->disable_email_reason = conf->Get<const Anope::string &>("disable_email_reason");
if (!email_attribute.empty())
/* Don't complain to users about how they need to update their email, we will do it for them */
- Config->NSForceEmail = false;
+ Config->GetBlock("nickserv")->Set("forceemail", "false");
}
EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> &params) anope_override
@@ -297,7 +293,7 @@ class NSIdentifyLDAP : public Module
}
}
- void OnNickRegister(NickAlias *na) anope_override
+ void OnNickRegister(User *, NickAlias *na) anope_override
{
if (!this->disable_register_reason.empty() || !this->ldap)
return;
diff --git a/modules/extra/m_ldap_oper.cpp b/modules/extra/m_ldap_oper.cpp
index afe3fde48..4324a7bc0 100644
--- a/modules/extra/m_ldap_oper.cpp
+++ b/modules/extra/m_ldap_oper.cpp
@@ -1,5 +1,5 @@
#include "module.h"
-#include "ldap.h"
+#include "ldapapi.h"
static std::set<Oper *> my_opers;
static Anope::string opertype_attribute;
@@ -93,13 +93,15 @@ class LDAPOper : public Module
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
}
- void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override
+ void OnReload(Configuration::Conf *conf) anope_override
{
- this->binddn = reader.ReadValue("m_ldap_oper", "binddn", "", 0);
- this->password = reader.ReadValue("m_ldap_oper", "password", "", 0);
- this->basedn = reader.ReadValue("m_ldap_oper", "basedn", "", 0);
- this->filter = reader.ReadValue("m_ldap_oper", "filter", "", 0);
- opertype_attribute = reader.ReadValue("m_ldap_oper", "opertype_attribute", "", 0);
+ Configuration::Block *config = Config->GetModule(this);
+
+ this->binddn = config->Get<const Anope::string &>("binddn");
+ this->password = config->Get<const Anope::string &>("password");
+ this->basedn = config->Get<const Anope::string &>("basedn");
+ this->filter = config->Get<const Anope::string &>("filter");
+ opertype_attribute = config->Get<const Anope::string &>("opertype_attribute");
for (std::set<Oper *>::iterator it = my_opers.begin(), it_end = my_opers.end(); it != it_end; ++it)
delete *it;
diff --git a/modules/extra/m_mysql.cpp b/modules/extra/m_mysql.cpp
index c41ba37a8..372cb6982 100644
--- a/modules/extra/m_mysql.cpp
+++ b/modules/extra/m_mysql.cpp
@@ -188,8 +188,9 @@ class ModuleSQL : public Module, public Pipe
delete DThread;
}
- void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override
+ void OnReload(Configuration::Conf *conf) anope_override
{
+ Configuration::Block *config = Config->GetModule(this);
int i, num;
for (std::map<Anope::string, MySQLService *>::iterator it = this->MySQLServices.begin(); it != this->MySQLServices.end();)
@@ -198,13 +199,9 @@ class ModuleSQL : public Module, public Pipe
MySQLService *s = it->second;
++it;
- for (i = 0, num = reader.Enumerate("mysql"); i < num; ++i)
- {
- if (reader.ReadValue("mysql", "name", "main", i) == cname)
- {
+ for (i = 0; i < Config->CountBlock("mysql"); ++i)
+ if (Config->GetBlock("mysql", i)->Get<const Anope::string &>("name", "main") == cname)
break;
- }
- }
if (i == num)
{
@@ -215,17 +212,18 @@ class ModuleSQL : public Module, public Pipe
}
}
- for (i = 0, num = reader.Enumerate("mysql"); i < num; ++i)
+ for (i = 0; i < Config->CountBlock("mysql"); ++i)
{
- Anope::string connname = reader.ReadValue("mysql", "name", "mysql/main", i);
+ Configuration::Block *block = Config->GetBlock("mysql", i);
+ const Anope::string &connname = block->Get<const Anope::string &>("name", "mysql/main");
if (this->MySQLServices.find(connname) == this->MySQLServices.end())
{
- Anope::string database = reader.ReadValue("mysql", "database", "anope", i);
- Anope::string server = reader.ReadValue("mysql", "server", "127.0.0.1", i);
- Anope::string user = reader.ReadValue("mysql", "username", "anope", i);
- Anope::string password = reader.ReadValue("mysql", "password", "", i);
- int port = reader.ReadInteger("mysql", "port", "3306", i, true);
+ const Anope::string &database = block->Get<const Anope::string &>("database", "anope");
+ const Anope::string &server = block->Get<const Anope::string &>("server", "127.0.0.1");
+ const Anope::string &user = block->Get<const Anope::string &>("username", "anope");
+ const Anope::string &password = block->Get<const Anope::string &>("password");
+ int port = block->Get<int>("port", "3306");
try
{
diff --git a/modules/extra/m_proxyscan.cpp b/modules/extra/m_proxyscan.cpp
index 9dd3f8884..c77f0f9cd 100644
--- a/modules/extra/m_proxyscan.cpp
+++ b/modules/extra/m_proxyscan.cpp
@@ -86,7 +86,7 @@ class ProxyConnect : public ConnectionSocket
reason = reason.replace_all_cs("%p", stringify(this->conaddr.port()));
Log(OperServ) << "PROXYSCAN: Open " << this->GetType() << " proxy found on " << this->conaddr.addr() << ":" << this->conaddr.port() << " (" << reason << ")";
- XLine *x = new XLine("*@" + this->conaddr.addr(), Config->OperServ, Anope::CurTime + this->proxy.duration, reason, XLineManager::GenerateUID());
+ XLine *x = new XLine("*@" + this->conaddr.addr(), OperServ ? OperServ->nick : "", Anope::CurTime + this->proxy.duration, reason, XLineManager::GenerateUID());
if (add_to_akill && akills)
{
akills->AddXLine(x);
@@ -253,34 +253,36 @@ class ModuleProxyScan : public Module
delete this->listener;
}
- void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override
+ void OnReload(Configuration::Conf *conf) anope_override
{
- Anope::string s_target_ip = reader.ReadValue("m_proxyscan", "target_ip", "", 0);
+ Configuration::Block *config = Config->GetModule(this);
+
+ Anope::string s_target_ip = config->Get<const Anope::string &>("target_ip");
if (s_target_ip.empty())
- throw ConfigException("m_proxyscan:target_ip may not be empty");
+ throw ConfigException(this->name + " target_ip may not be empty");
- int s_target_port = reader.ReadInteger("m_proxyscan", "target_port", "-1", 0, true);
+ int s_target_port = config->Get<int>("target_port", "-1");
if (s_target_port <= 0)
- throw ConfigException("m_proxyscan:target_port may not be empty and must be a positive number");
+ throw ConfigException(this->name + " target_port may not be empty and must be a positive number");
- Anope::string s_listen_ip = reader.ReadValue("m_proxyscan", "listen_ip", "", 0);
+ Anope::string s_listen_ip = config->Get<const Anope::string &>("listen_ip");
if (s_listen_ip.empty())
- throw ConfigException("m_proxyscan:listen_ip may not be empty");
+ throw ConfigException(this->name + " listen_ip may not be empty");
- int s_listen_port = reader.ReadInteger("m_proxyscan", "listen_port", "-1", 0, true);
+ int s_listen_port = config->Get<int>("listen_port", "-1");
if (s_listen_port <= 0)
- throw ConfigException("m_proxyscan:listen_port may not be empty and must be a positive number");
+ throw ConfigException(this->name + " listen_port may not be empty and must be a positive number");
target_ip = s_target_ip;
target_port = s_target_port;
this->listen_ip = s_listen_ip;
this->listen_port = s_listen_port;
- this->con_notice = reader.ReadValue("m_proxyscan", "connect_notice", "", 0);
- this->con_source = reader.ReadValue("m_proxyscan", "connect_source", "", 0);
- add_to_akill = reader.ReadFlag("m_proxyscan", "add_to_akill", "true", 0);
- this->connectionTimeout.SetSecs(reader.ReadInteger("m_proxyscan", "timeout", "5", 0, true));
+ this->con_notice = config->Get<const Anope::string &>("connect_notice");
+ this->con_source = config->Get<const Anope::string &>("connect_source");
+ add_to_akill = config->Get<bool>("add_to_akill", "true");
+ this->connectionTimeout.SetSecs(config->Get<time_t>("timeout", "5s"));
- ProxyCheckString = Config->NetworkName + " proxy check";
+ ProxyCheckString = Config->GetBlock("networkinfo")->Get<const Anope::string &>("networkname") + " proxy check";
delete this->listener;
this->listener = NULL;
try
@@ -293,12 +295,13 @@ class ModuleProxyScan : public Module
}
this->proxyscans.clear();
- for (int i = 0; i < reader.Enumerate("proxyscan"); ++i)
+ for (int i = 0; i < conf->CountBlock("proxyscan"); ++i)
{
+ Configuration::Block *block = conf->GetBlock("proxyscan", i);
ProxyCheck p;
Anope::string token;
- commasepstream sep(reader.ReadValue("proxyscan", "type", "", i));
+ commasepstream sep(block->Get<const Anope::string &>("type"));
while (sep.GetToken(token))
{
if (!token.equals_ci("HTTP") && !token.equals_ci("SOCKS5"))
@@ -308,7 +311,7 @@ class ModuleProxyScan : public Module
if (p.types.empty())
continue;
- commasepstream sep2(reader.ReadValue("proxyscan", "port", "", i));
+ commasepstream sep2(block->Get<const Anope::string &>("port"));
while (sep2.GetToken(token))
{
try
@@ -321,8 +324,8 @@ class ModuleProxyScan : public Module
if (p.ports.empty())
continue;
- p.duration = Anope::DoTime(reader.ReadValue("proxyscan", "time", "4h", i));
- p.reason = reader.ReadValue("proxyscan", "reason", "", i);
+ p.duration = block->Get<time_t>("time", "4h");
+ p.reason = block->Get<const Anope::string &>("reason");
if (p.reason.empty())
continue;
diff --git a/modules/extra/m_sql_authentication.cpp b/modules/extra/m_sql_authentication.cpp
index 027b0bbcc..98fd4c2e9 100644
--- a/modules/extra/m_sql_authentication.cpp
+++ b/modules/extra/m_sql_authentication.cpp
@@ -2,6 +2,7 @@
#include "sql.h"
static Module *me;
+static ServiceReference<NickServService> nickserv("NickServService", "NickServ");
class SQLAuthenticationResult : public SQL::Interface
{
@@ -41,14 +42,9 @@ class SQLAuthenticationResult : public SQL::Interface
if (na == NULL)
{
na = new NickAlias(req->GetAccount(), new NickCore(req->GetAccount()));
- if (user)
- {
- if (Config->NSAddAccessOnReg)
- na->nc->AddAccess(user->Mask());
-
- if (NickServ)
- user->SendMessage(NickServ, _("Your account \002%s\002 has been successfully created."), na->nick.c_str());
- }
+ FOREACH_MOD(I_OnNickRegister, OnNickRegister(user, na));
+ if (user && nickserv)
+ user->SendMessage(NickServ, _("Your account \002%s\002 has been successfully created."), na->nick.c_str());
}
if (!email.empty() && email != na->nc->email)
@@ -80,18 +76,18 @@ class ModuleSQLAuthentication : public Module
public:
ModuleSQLAuthentication(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR)
{
-
me = this;
Implementation i[] = { I_OnReload, I_OnPreCommand, I_OnCheckAuthentication };
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
}
- void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override
+ void OnReload(Configuration::Conf *conf) anope_override
{
- this->engine = reader.ReadValue("m_sql_authentication", "engine", "", 0);
- this->query = reader.ReadValue("m_sql_authentication", "query", "", 0);
- this->disable_reason = reader.ReadValue("m_sql_authentication", "disable_reason", "", 0);
+ Configuration::Block *config = conf->GetModule(this);
+ this->engine = config->Get<const Anope::string &>("engine");
+ this->query = config->Get<const Anope::string &>("query");
+ this->disable_reason = config->Get<const Anope::string &>("disable_reason");
this->SQL = ServiceReference<SQL::Provider>("SQL::Provider", this->engine);
}
diff --git a/modules/extra/m_sql_oper.cpp b/modules/extra/m_sql_oper.cpp
index 4f982e1d8..480bcf5a0 100644
--- a/modules/extra/m_sql_oper.cpp
+++ b/modules/extra/m_sql_oper.cpp
@@ -101,10 +101,12 @@ class ModuleSQLOper : public Module
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
}
- void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override
+ void OnReload(Configuration::Conf *conf) anope_override
{
- this->engine = reader.ReadValue("m_sql_oper", "engine", "", 0);
- this->query = reader.ReadValue("m_sql_oper", "query", "", 0);
+ Configuration::Block *config = conf->GetModule(this);
+
+ this->engine = config->Get<const Anope::string &>("engine");
+ this->query = config->Get<const Anope::string &>("query");
this->SQL = ServiceReference<SQL::Provider>("SQL::Provider", this->engine);
}
diff --git a/modules/extra/m_sqlite.cpp b/modules/extra/m_sqlite.cpp
index 9626741a0..b0f947985 100644
--- a/modules/extra/m_sqlite.cpp
+++ b/modules/extra/m_sqlite.cpp
@@ -77,18 +77,19 @@ class ModuleSQLite : public Module
SQLiteServices.clear();
}
- void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override
+ void OnReload(Configuration::Conf *conf) anope_override
{
- int i, num;
+ Configuration::Block *config = conf->GetModule(this);
for (std::map<Anope::string, SQLiteService *>::iterator it = this->SQLiteServices.begin(); it != this->SQLiteServices.end();)
{
const Anope::string &cname = it->first;
SQLiteService *s = it->second;
+ int i, num;
++it;
- for (i = 0, num = reader.Enumerate("sqlite"); i < num; ++i)
- if (reader.ReadValue("sqlite", "name", "sqlite/main", i) == cname)
+ for (i = 0, num = config->CountBlock("sqlite"); i < num; ++i)
+ if (config->GetBlock("sqlite", i)->Get<const Anope::string &>("name", "sqlite/main") == cname)
break;
if (i == num)
@@ -100,13 +101,14 @@ class ModuleSQLite : public Module
}
}
- for (i = 0, num = reader.Enumerate("sqlite"); i < num; ++i)
+ for (int i = 0; i < config->CountBlock("sqlite"); ++i)
{
- Anope::string connname = reader.ReadValue("sqlite", "name", "sqlite/main", i);
+ Configuration::Block *block = config->GetBlock("sqlite", i);
+ Anope::string connname = block->Get<const Anope::string &>("name", "sqlite/main");
if (this->SQLiteServices.find(connname) == this->SQLiteServices.end())
{
- Anope::string database = Anope::DataDir + "/" + reader.ReadValue("sqlite", "database", "anope", i);
+ Anope::string database = Anope::DataDir + "/" + block->Get<const Anope::string &>("database", "anope");
try
{
diff --git a/modules/extra/m_ssl.cpp b/modules/extra/m_ssl.cpp
index 95de6694a..3219830e7 100644
--- a/modules/extra/m_ssl.cpp
+++ b/modules/extra/m_ssl.cpp
@@ -136,10 +136,12 @@ class SSLModule : public Module
SSL_CTX_free(server_ctx);
}
- void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override
+ void OnReload(Configuration::Conf *conf) anope_override
{
- this->certfile = reader.ReadValue("ssl", "cert", "data/anope.crt", 0);
- this->keyfile = reader.ReadValue("ssl", "key", "data/anope.key", 0);
+ Configuration::Block *config = conf->GetModule(this);
+
+ this->certfile = config->Get<const Anope::string &>("cert", "data/anope.crt");
+ this->keyfile = config->Get<const Anope::string &>("key", "data/anope.key");
if (Anope::IsFile(this->certfile.c_str()))
{
@@ -182,9 +184,9 @@ class SSLModule : public Module
void OnPreServerConnect() anope_override
{
- ConfigReader reader;
+ Configuration::Block *config = Config->GetBlock("uplink", Anope::CurrentUplink);
- if (reader.ReadFlag("uplink", "ssl", "no", Anope::CurrentUplink))
+ if (config->Get<bool>("ssl"))
{
this->service.Init(UplinkSock);
}
diff --git a/modules/extra/m_xmlrpc_main.cpp b/modules/extra/m_xmlrpc_main.cpp
index 0ba748f0b..8016d620e 100644
--- a/modules/extra/m_xmlrpc_main.cpp
+++ b/modules/extra/m_xmlrpc_main.cpp
@@ -239,14 +239,15 @@ class MyXMLRPCEvent : public XMLRPCEvent
void DoOperType(XMLRPCServiceInterface *iface, HTTPClient *client, XMLRPCRequest &request)
{
- for (std::list<OperType *>::const_iterator it = Config->MyOperTypes.begin(), it_end = Config->MyOperTypes.end(); it != it_end; ++it)
+ for (unsigned i = 0; i < Config->MyOperTypes.size(); ++i)
{
+ OperType *ot = Config->MyOperTypes[i];
Anope::string perms;
- for (std::list<Anope::string>::const_iterator it2 = (*it)->GetPrivs().begin(), it2_end = (*it)->GetPrivs().end(); it2 != it2_end; ++it2)
+ for (std::list<Anope::string>::const_iterator it2 = ot->GetPrivs().begin(), it2_end = ot->GetPrivs().end(); it2 != it2_end; ++it2)
perms += " " + *it2;
- for (std::list<Anope::string>::const_iterator it2 = (*it)->GetCommands().begin(), it2_end = (*it)->GetCommands().end(); it2 != it2_end; ++it2)
+ for (std::list<Anope::string>::const_iterator it2 = ot->GetCommands().begin(), it2_end = ot->GetCommands().end(); it2 != it2_end; ++it2)
perms += " " + *it2;
- request.reply((*it)->GetName(), perms);
+ request.reply(ot->GetName(), perms);
}
}
};
diff --git a/modules/extra/webcpanel/pages/chanserv/access.cpp b/modules/extra/webcpanel/pages/chanserv/access.cpp
index 33250035e..0df2ecfc1 100644
--- a/modules/extra/webcpanel/pages/chanserv/access.cpp
+++ b/modules/extra/webcpanel/pages/chanserv/access.cpp
@@ -44,7 +44,7 @@ bool WebCPanel::ChanServ::Access::OnRequest(HTTPProvider *server, const Anope::s
params.push_back("DEL");
params.push_back(message.get_data["mask"]);
- WebPanel::RunCommand(na->nc->display, na->nc, Config->ChanServ, "chanserv/access", params, replacements);
+ WebPanel::RunCommand(na->nc->display, na->nc, ::ChanServ->nick, "chanserv/access", params, replacements);
}
else if (message.post_data["mask"].empty() == false && message.post_data["access"].empty() == false && message.post_data["provider"].empty() == false)
{
@@ -75,8 +75,10 @@ bool WebCPanel::ChanServ::Access::OnRequest(HTTPProvider *server, const Anope::s
}
}
- if (ci->GetAccessCount() >= Config->CSAccessMax)
- replacements["MESSAGES"] = "Sorry, you can only have " + stringify(Config->CSAccessMax) + " access entries on a channel.";
+
+ unsigned access_max = Config->GetModule("chanserv")->Get<unsigned>("accessmax", "1024");
+ if (access_max && ci->GetAccessCount() >= access_max)
+ replacements["MESSAGES"] = "Sorry, you can only have " + stringify(access_max) + " access entries on a channel.";
else if (!denied)
{
ChanAccess *new_acc = a->Create();
diff --git a/modules/extra/webcpanel/pages/chanserv/akick.cpp b/modules/extra/webcpanel/pages/chanserv/akick.cpp
index 95fb8fb30..06aede8e7 100644
--- a/modules/extra/webcpanel/pages/chanserv/akick.cpp
+++ b/modules/extra/webcpanel/pages/chanserv/akick.cpp
@@ -40,7 +40,7 @@ bool WebCPanel::ChanServ::Akick::OnRequest(HTTPProvider *server, const Anope::st
params.push_back("DEL");
params.push_back(message.get_data["mask"]);
- WebPanel::RunCommand(na->nc->display, na->nc, Config->ChanServ, "chanserv/akick", params, replacements);
+ WebPanel::RunCommand(na->nc->display, na->nc, ::ChanServ->nick, "chanserv/akick", params, replacements);
}
else if (message.post_data["mask"].empty() == false)
{
@@ -51,7 +51,7 @@ bool WebCPanel::ChanServ::Akick::OnRequest(HTTPProvider *server, const Anope::st
if (message.post_data["reason"].empty() == false)
params.push_back(message.get_data["reason"]);
- WebPanel::RunCommand(na->nc->display, na->nc, Config->ChanServ, "chanserv/akick", params, replacements);
+ WebPanel::RunCommand(na->nc->display, na->nc, ::ChanServ->nick, "chanserv/akick", params, replacements);
}
replacements["ESCAPED_CHANNEL"] = HTTPUtils::URLEncode(chname);
diff --git a/modules/extra/webcpanel/pages/chanserv/drop.cpp b/modules/extra/webcpanel/pages/chanserv/drop.cpp
index 5462aa131..f18700651 100644
--- a/modules/extra/webcpanel/pages/chanserv/drop.cpp
+++ b/modules/extra/webcpanel/pages/chanserv/drop.cpp
@@ -21,7 +21,7 @@ bool WebCPanel::ChanServ::Drop::OnRequest(HTTPProvider *server, const Anope::str
std::vector<Anope::string> params;
params.push_back(HTTPUtils::URLDecode(message.post_data["channel"]));
- WebPanel::RunCommand(na->nc->display, na->nc, Config->ChanServ, "chanserv/drop", params, replacements);
+ WebPanel::RunCommand(na->nc->display, na->nc, ::ChanServ->nick, "chanserv/drop", params, replacements);
}
else replacements["MESSAGES"] = "Invalid Confirmation";
}
diff --git a/modules/extra/webcpanel/pages/confirm.cpp b/modules/extra/webcpanel/pages/confirm.cpp
index 1f5d61cc1..ab86ee5c9 100644
--- a/modules/extra/webcpanel/pages/confirm.cpp
+++ b/modules/extra/webcpanel/pages/confirm.cpp
@@ -21,7 +21,7 @@ bool WebCPanel::Confirm::OnRequest(HTTPProvider *server, const Anope::string &pa
if (!email.empty())
params.push_back(email);
- WebPanel::RunCommand(user, NULL, Config->NickServ, "nickserv/register", params, replacements);
+ WebPanel::RunCommand(user, NULL, ::NickServ->nick, "nickserv/register", params, replacements);
}
TemplateFileServer page("confirm.html");
diff --git a/modules/extra/webcpanel/pages/hostserv/request.cpp b/modules/extra/webcpanel/pages/hostserv/request.cpp
index 6335b1a56..30a396a9b 100644
--- a/modules/extra/webcpanel/pages/hostserv/request.cpp
+++ b/modules/extra/webcpanel/pages/hostserv/request.cpp
@@ -18,7 +18,7 @@ bool WebCPanel::HostServ::Request::OnRequest(HTTPProvider *server, const Anope::
std::vector<Anope::string> params;
params.push_back(HTTPUtils::URLDecode(message.post_data["req"]));
- WebPanel::RunCommand(na->nc->display, na->nc, Config->HostServ, "hostserv/request", params, replacements, "CMDR");
+ WebPanel::RunCommand(na->nc->display, na->nc, ::HostServ->nick, "hostserv/request", params, replacements, "CMDR");
}
if (na->HasVhost())
diff --git a/modules/extra/webcpanel/pages/memoserv/memos.cpp b/modules/extra/webcpanel/pages/memoserv/memos.cpp
index 671820ced..9324bea56 100644
--- a/modules/extra/webcpanel/pages/memoserv/memos.cpp
+++ b/modules/extra/webcpanel/pages/memoserv/memos.cpp
@@ -57,7 +57,7 @@ bool WebCPanel::MemoServ::Memos::OnRequest(HTTPProvider *server, const Anope::st
params.push_back(HTTPUtils::URLDecode(message.post_data["receiver"]));
params.push_back(HTTPUtils::URLDecode(message.post_data["message"]));
- WebPanel::RunCommand(na->nc->display, na->nc, Config->MemoServ, "memoserv/send", params, replacements, "CMDR");
+ WebPanel::RunCommand(na->nc->display, na->nc, ::MemoServ->nick, "memoserv/send", params, replacements, "CMDR");
}
if (message.get_data.count("del") > 0 && message.get_data.count("number") > 0)
{
@@ -66,7 +66,7 @@ bool WebCPanel::MemoServ::Memos::OnRequest(HTTPProvider *server, const Anope::st
params.push_back(chname);
params.push_back(message.get_data["number"]);
- WebPanel::RunCommand(na->nc->display, na->nc, Config->MemoServ, "memoserv/del", params, replacements, "CMDR");
+ WebPanel::RunCommand(na->nc->display, na->nc, ::MemoServ->nick, "memoserv/del", params, replacements, "CMDR");
}
if (message.get_data.count("read") > 0 && message.get_data.count("number") > 0)
{
diff --git a/modules/extra/webcpanel/pages/nickserv/access.cpp b/modules/extra/webcpanel/pages/nickserv/access.cpp
index de0e544f7..41dc0f429 100644
--- a/modules/extra/webcpanel/pages/nickserv/access.cpp
+++ b/modules/extra/webcpanel/pages/nickserv/access.cpp
@@ -19,7 +19,7 @@ bool WebCPanel::NickServ::Access::OnRequest(HTTPProvider *server, const Anope::s
params.push_back("ADD");
params.push_back(message.post_data["access"]);
- WebPanel::RunCommand(na->nc->display, na->nc, Config->NickServ, "nickserv/access", params, replacements);
+ WebPanel::RunCommand(na->nc->display, na->nc, ::NickServ->nick, "nickserv/access", params, replacements);
}
else if (message.get_data.count("del") > 0 && message.get_data.count("mask") > 0)
{
@@ -27,7 +27,7 @@ bool WebCPanel::NickServ::Access::OnRequest(HTTPProvider *server, const Anope::s
params.push_back("DEL");
params.push_back(message.get_data["mask"]);
- WebPanel::RunCommand(na->nc->display, na->nc, Config->NickServ, "nickserv/access", params, replacements);
+ WebPanel::RunCommand(na->nc->display, na->nc, ::NickServ->nick, "nickserv/access", params, replacements);
}
for (unsigned i = 0; i < na->nc->access.size(); ++i)
diff --git a/modules/extra/webcpanel/pages/nickserv/cert.cpp b/modules/extra/webcpanel/pages/nickserv/cert.cpp
index fc13e2ce5..44849a302 100644
--- a/modules/extra/webcpanel/pages/nickserv/cert.cpp
+++ b/modules/extra/webcpanel/pages/nickserv/cert.cpp
@@ -19,7 +19,7 @@ bool WebCPanel::NickServ::Cert::OnRequest(HTTPProvider *server, const Anope::str
params.push_back("ADD");
params.push_back(message.post_data["certfp"]);
- WebPanel::RunCommand(na->nc->display, na->nc, Config->NickServ, "nickserv/cert", params, replacements);
+ WebPanel::RunCommand(na->nc->display, na->nc, ::NickServ->nick, "nickserv/cert", params, replacements);
}
else if (message.get_data.count("del") > 0 && message.get_data.count("mask") > 0)
{
@@ -27,7 +27,7 @@ bool WebCPanel::NickServ::Cert::OnRequest(HTTPProvider *server, const Anope::str
params.push_back("DEL");
params.push_back(message.get_data["mask"]);
- WebPanel::RunCommand(na->nc->display, na->nc, Config->NickServ, "nickserv/cert", params, replacements);
+ WebPanel::RunCommand(na->nc->display, na->nc, ::NickServ->nick, "nickserv/cert", params, replacements);
}
for (unsigned i = 0; i < na->nc->cert.size(); ++i)
diff --git a/modules/extra/webcpanel/pages/operserv/akill.cpp b/modules/extra/webcpanel/pages/operserv/akill.cpp
index 87b8f94fb..ae9824bce 100644
--- a/modules/extra/webcpanel/pages/operserv/akill.cpp
+++ b/modules/extra/webcpanel/pages/operserv/akill.cpp
@@ -34,7 +34,7 @@ bool WebCPanel::OperServ::Akill::OnRequest(HTTPProvider *server, const Anope::st
cmdstr << " " << HTTPUtils::URLDecode(message.post_data["mask"]);
cmdstr << " " << HTTPUtils::URLDecode(message.post_data["reason"]);
params.push_back(cmdstr.str());
- WebPanel::RunCommand(na->nc->display, na->nc, Config->OperServ, "operserv/akill", params, replacements);
+ WebPanel::RunCommand(na->nc->display, na->nc, ::OperServ->nick, "operserv/akill", params, replacements);
}
if (message.get_data["del"] == "1" && message.get_data.count("number") > 0)
@@ -42,7 +42,7 @@ bool WebCPanel::OperServ::Akill::OnRequest(HTTPProvider *server, const Anope::st
std::vector<Anope::string> params;
params.push_back("DEL");
params.push_back(HTTPUtils::URLDecode(message.get_data["number"]));
- WebPanel::RunCommand(na->nc->display, na->nc, Config->OperServ, "operserv/akill", params, replacements);
+ WebPanel::RunCommand(na->nc->display, na->nc, ::OperServ->nick, "operserv/akill", params, replacements);
}
for (unsigned i = 0, end = akills->GetCount(); i < end; ++i)
diff --git a/modules/extra/webcpanel/pages/register.cpp b/modules/extra/webcpanel/pages/register.cpp
index 409069348..730db612d 100644
--- a/modules/extra/webcpanel/pages/register.cpp
+++ b/modules/extra/webcpanel/pages/register.cpp
@@ -13,7 +13,7 @@ bool WebCPanel::Register::OnRequest(HTTPProvider *server, const Anope::string &p
replacements["TITLE"] = page_title;
- if (!Config->NSForceEmail)
+ if (!Config->GetModule("nickserv")->Get<bool>("forceemail", "yes"))
replacements["EMAIL_TYPE"] = "hidden";
TemplateFileServer page("register.html");
diff --git a/modules/extra/webcpanel/webcpanel.cpp b/modules/extra/webcpanel/webcpanel.cpp
index e2a026559..ca0b2f93d 100644
--- a/modules/extra/webcpanel/webcpanel.cpp
+++ b/modules/extra/webcpanel/webcpanel.cpp
@@ -45,19 +45,19 @@ class ModuleWebCPanel : public Module
panel(this, "webcpanel"),
style_css("style.css", "/static/style.css", "text/css"), logo_png("logo.png", "/static/logo.png", "image/png"), favicon_ico("favicon.ico", "/favicon.ico", "image/x-icon"),
index("/"), logout("/logout"), _register("/register"), confirm("/confirm"),
- nickserv_info(Config->NickServ, "/nickserv/info"), nickserv_cert(Config->NickServ, "/nickserv/cert"), nickserv_access(Config->NickServ, "/nickserv/access"), nickserv_alist(Config->NickServ, "/nickserv/alist"),
- chanserv_info(Config->ChanServ, "/chanserv/info"), chanserv_set(Config->ChanServ, "/chanserv/set"), chanserv_access(Config->ChanServ, "/chanserv/access"), chanserv_akick(Config->ChanServ, "/chanserv/akick"),
- chanserv_drop(Config->ChanServ, "/chanserv/drop"), memoserv_memos(Config->MemoServ, "/memoserv/memos"), hostserv_request(Config->HostServ, "/hostserv/request"), operserv_akill(Config->OperServ, "/operserv/akill")
+ nickserv_info("NickServ", "/nickserv/info"), nickserv_cert("NickServ", "/nickserv/cert"), nickserv_access("NickServ", "/nickserv/access"), nickserv_alist("NickServ", "/nickserv/alist"),
+ chanserv_info("ChanServ", "/chanserv/info"), chanserv_set("ChanServ", "/chanserv/set"), chanserv_access("ChanServ", "/chanserv/access"), chanserv_akick("ChanServ", "/chanserv/akick"),
+ chanserv_drop("ChanServ", "/chanserv/drop"), memoserv_memos("MemoServ", "/memoserv/memos"), hostserv_request("HostServ", "/hostserv/request"), operserv_akill("OperServ", "/operserv/akill")
{
me = this;
- ConfigReader reader;
- provider_name = reader.ReadValue("webcpanel", "server", "httpd/main", 0);
- template_name = reader.ReadValue("webcpanel", "template", "template", 0);
+ Configuration::Block *block = Config->GetModule(this);
+ provider_name = block->Get<const Anope::string &>("server", "httpd/main");
+ template_name = block->Get<const Anope::string &>("template", "default");
template_base = Anope::DataDir + "/modules/webcpanel/templates/" + template_name;
- page_title = reader.ReadValue("webcpanel", "title", "Anope IRC Services", 0);
- use_ssl = reader.ReadFlag("webcpanel", "ssl", "no", 0); // This is dumb, is there a better way to do this?
+ page_title = block->Get<const Anope::string &>("title", "Anope IRC Services");
+ use_ssl = block->Get<bool>("ssl", "no"); // This is dumb, is there a better way to do this?
ServiceReference<HTTPProvider> provider("HTTPProvider", provider_name);
if (!provider)
@@ -72,10 +72,10 @@ class ModuleWebCPanel : public Module
provider->RegisterPage(&this->_register);
provider->RegisterPage(&this->confirm);
- if (Config->NickServ.empty() == false)
+ if (NickServ)
{
Section s;
- s.name = Config->NickServ;
+ s.name = NickServ->nick;
SubSection ss;
ss.name = "Information";
@@ -103,10 +103,11 @@ class ModuleWebCPanel : public Module
panel.sections.push_back(s);
}
- if (Config->ChanServ.empty() == false)
+
+ if (ChanServ)
{
Section s;
- s.name = Config->ChanServ;
+ s.name = ChanServ->nick;
SubSection ss;
ss.name = "Channels";
@@ -137,10 +138,10 @@ class ModuleWebCPanel : public Module
panel.sections.push_back(s);
}
- if (Config->MemoServ.empty() == false)
+ if (MemoServ)
{
Section s;
- s.name = Config->MemoServ;
+ s.name = MemoServ->nick;
SubSection ss;
ss.name = "Memos";
@@ -151,10 +152,10 @@ class ModuleWebCPanel : public Module
panel.sections.push_back(s);
}
- if (Config->HostServ.empty() == false)
+ if (HostServ)
{
Section s;
- s.name = Config->HostServ;
+ s.name = HostServ->nick;
SubSection ss;
ss.name = "vHost Request";
@@ -165,10 +166,10 @@ class ModuleWebCPanel : public Module
panel.sections.push_back(s);
}
- if (Config->OperServ.empty() == false)
+ if (OperServ)
{
Section s;
- s.name = Config->OperServ;
+ s.name = OperServ->nick;
SubSection ss;
ss.name = "Akill";
diff --git a/modules/ldap.h b/modules/ldapapi.h
index 65be27687..65be27687 100644
--- a/modules/ldap.h
+++ b/modules/ldapapi.h
diff --git a/modules/m_dns.cpp b/modules/m_dns.cpp
index e8f3bd758..af16e3be3 100644
--- a/modules/m_dns.cpp
+++ b/modules/m_dns.cpp
@@ -940,16 +940,17 @@ class ModuleDNS : public Module
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
}
- void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override
+ void OnReload(Configuration::Conf *conf) anope_override
{
-
- nameserver = reader.ReadValue("dns", "nameserver", "127.0.0.1", 0);
- timeout = Anope::DoTime(reader.ReadValue("dns", "timeout", "5", 0));
- ip = reader.ReadValue("dns", "ip", "0.0.0.0", 0);
- port = reader.ReadInteger("dns", "port", "53", 0, false);
- admin = reader.ReadValue("dns", "admin", "admin@example.com", 0);
- nameservers = reader.ReadValue("dns", "nameservers", "ns1.example.com", 0);
- refresh = reader.ReadInteger("dns", "refresh", "3600", 0, false);
+ Configuration::Block *block = conf->GetModule(this);
+
+ nameserver = block->Get<const Anope::string &>("nameserver", "127.0.0.1");
+ timeout = block->Get<time_t>("timeout", "5");
+ ip = block->Get<const Anope::string &>("ip", "0.0.0.0");
+ port = block->Get<int>("port", "53");
+ admin = block->Get<const Anope::string &>("admin", "admin@example.com");
+ nameservers = block->Get<const Anope::string &>("nameservers", "ns1.example.com");
+ refresh = block->Get<int>("refresh", "3600");
if (Anope::IsFile(nameserver))
{
diff --git a/modules/m_dnsbl.cpp b/modules/m_dnsbl.cpp
index bf7c02fa0..5b46410d0 100644
--- a/modules/m_dnsbl.cpp
+++ b/modules/m_dnsbl.cpp
@@ -63,10 +63,10 @@ class DNSBLResolver : public Request
reason = reason.replace_all_cs("%h", user->host);
reason = reason.replace_all_cs("%i", user->ip);
reason = reason.replace_all_cs("%r", record_reason);
- reason = reason.replace_all_cs("%N", Config->NetworkName);
+ reason = reason.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string &>("networkname"));
Log(OperServ) << "DNSBL: " << user->GetMask() << " (" << user->ip << ") appears in " << this->blacklist.name;
- XLine *x = new XLine("*@" + user->ip, Config->OperServ, Anope::CurTime + this->blacklist.bantime, reason, XLineManager::GenerateUID());
+ XLine *x = new XLine("*@" + user->ip, OperServ ? OperServ->nick : "m_dnsbl", Anope::CurTime + this->blacklist.bantime, reason, XLineManager::GenerateUID());
if (this->add_to_akill && akills)
{
akills->AddXLine(x);
@@ -95,27 +95,27 @@ class ModuleDNSBL : public Module
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
}
- void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override
+ void OnReload(Configuration::Conf *conf) anope_override
{
- this->check_on_connect = reader.ReadFlag("m_dnsbl", "check_on_connect", "no", 0);
- this->check_on_netburst = reader.ReadFlag("m_dnsbl", "check_on_netburst", "no", 0);
- this->add_to_akill = reader.ReadFlag("m_dnsbl", "add_to_akill", "yes", 0);
+ Configuration::Block *block = conf->GetModule(this);
+ this->check_on_connect = block->Get<bool>("check_on_connect");
+ this->check_on_netburst = block->Get<bool>("check_on_netburst");
+ this->add_to_akill = block->Get<bool>("add_to_akill", "yes");
this->blacklists.clear();
- for (int i = 0, num = reader.Enumerate("blacklist"); i < num; ++i)
+ for (int i = 0, num = conf->CountBlock("blacklist"); i < num; ++i)
{
- Anope::string bname = reader.ReadValue("blacklist", "name", "", i);
+ Configuration::Block *bl = conf->GetBlock("blacklist", i);
+
+ Anope::string bname = bl->Get<const Anope::string &>("name");
if (bname.empty())
continue;
- Anope::string sbantime = reader.ReadValue("blacklist", "time", "4h", i);
- time_t bantime = Anope::DoTime(sbantime);
- if (bantime < 0)
- bantime = 9000;
- Anope::string reason = reader.ReadValue("blacklist", "reason", "", i);
+ time_t bantime = bl->Get<time_t>("time", "4h");
+ Anope::string reason = bl->Get<const Anope::string &>("reason");
std::map<int, Anope::string> replies;
for (int j = 0; j < 256; ++j)
{
- Anope::string k = reader.ReadValue("blacklist", stringify(j), "", i);
+ Anope::string k = bl->Get<const Anope::string &>(stringify(j));
if (!k.empty())
replies[j] = k;
}
diff --git a/modules/m_helpchan.cpp b/modules/m_helpchan.cpp
index d39b5afd9..4768fec71 100644
--- a/modules/m_helpchan.cpp
+++ b/modules/m_helpchan.cpp
@@ -9,18 +9,16 @@
class HelpChannel : public Module
{
- Anope::string HelpChan;
-
public:
HelpChannel(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
{
- Implementation i[] = { I_OnChannelModeSet, I_OnReload };
+ Implementation i[] = { I_OnChannelModeSet };
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
}
EventReturn OnChannelModeSet(Channel *c, MessageSource &setter, const Anope::string &mname, const Anope::string &param) anope_override
{
- if (mname == "OP" && c && c->ci && c->name.equals_ci(this->HelpChan))
+ if (mname == "OP" && c && c->ci && c->name.equals_ci(Config->GetModule(this)->Get<const Anope::string &>("helpchannel")))
{
User *u = User::Find(param);
@@ -30,11 +28,6 @@ class HelpChannel : public Module
return EVENT_CONTINUE;
}
-
- void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override
- {
- this->HelpChan = reader.ReadValue("m_helpchan", "helpchannel", "", 0);
- }
};
MODULE_INIT(HelpChannel)
diff --git a/modules/m_rewrite.cpp b/modules/m_rewrite.cpp
index fb7fe46ed..dfa8a9162 100644
--- a/modules/m_rewrite.cpp
+++ b/modules/m_rewrite.cpp
@@ -159,22 +159,23 @@ class ModuleRewrite : public Module
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
}
- void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override
+ void OnReload(Configuration::Conf *conf) anope_override
{
-
Rewrite::rewrites.clear();
- for (int i = 0; i < reader.Enumerate("command"); ++i)
+ for (int i = 0; i < conf->CountBlock("command"); ++i)
{
- if (!reader.ReadFlag("command", "rewrite", "no", i))
+ Configuration::Block *block = conf->GetBlock("command", i);
+
+ if (!block->Get<bool>("rewrite"))
continue;
Rewrite rw;
- rw.client = reader.ReadValue("command", "service", "", i);
- rw.source_message = reader.ReadValue("command", "rewrite_source", "", i),
- rw.target_message = reader.ReadValue("command", "rewrite_target", "", i);
- rw.desc = reader.ReadValue("command", "rewrite_description", "", i);
+ rw.client = block->Get<const Anope::string &>("service");
+ rw.source_message = block->Get<const Anope::string &>("rewrite_source");
+ rw.target_message = block->Get<const Anope::string &>("rewrite_target");
+ rw.desc = block->Get<const Anope::string &>("rewrite_description");
if (rw.client.empty() || rw.source_message.empty() || rw.target_message.empty())
continue;
diff --git a/modules/ns_maxemail.cpp b/modules/ns_maxemail.cpp
index 530ca5fe4..fc678e8a5 100644
--- a/modules/ns_maxemail.cpp
+++ b/modules/ns_maxemail.cpp
@@ -14,20 +14,20 @@
class NSMaxEmail : public Module
{
- int NSEmailMax;
-
bool CheckLimitReached(CommandSource &source, const Anope::string &email)
{
- if (this->NSEmailMax < 1 || email.empty())
+ int NSEmailMax = Config->GetModule(this)->Get<int>("maxemails");
+
+ if (NSEmailMax < 1 || email.empty())
return false;
- if (this->CountEmail(email, source.nc) < this->NSEmailMax)
+ if (this->CountEmail(email, source.nc) < NSEmailMax)
return false;
- if (this->NSEmailMax == 1)
+ if (NSEmailMax == 1)
source.Reply(_("The given email address has reached its usage limit of 1 user."));
else
- source.Reply(_("The given email address has reached its usage limit of %d users."), this->NSEmailMax);
+ source.Reply(_("The given email address has reached its usage limit of %d users."), NSEmailMax);
return true;
}
@@ -53,14 +53,6 @@ class NSMaxEmail : public Module
public:
NSMaxEmail(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
{
-
- Implementation i[] = { I_OnReload, I_OnPreCommand };
- ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
- }
-
- void OnReload(ServerConfig *conf, ConfigReader &reader) anope_override
- {
- this->NSEmailMax = reader.ReadInteger("ns_maxemail", "maxemails", "0", 0, false);
}
EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> &params) anope_override
diff --git a/modules/protocol/bahamut.cpp b/modules/protocol/bahamut.cpp
index 458602d3b..6aa097433 100644
--- a/modules/protocol/bahamut.cpp
+++ b/modules/protocol/bahamut.cpp
@@ -79,9 +79,9 @@ class BahamutIRCdProto : public IRCDProto
}
/* SVSHOLD - set */
- void SendSVSHold(const Anope::string &nick) anope_override
+ void SendSVSHold(const Anope::string &nick, time_t time) anope_override
{
- UplinkSocket::Message(Me) << "SVSHOLD " << nick << " " << Config->NSReleaseTimeout << " :Being held for registered user";
+ UplinkSocket::Message(Me) << "SVSHOLD " << nick << " " << time << " :Being held for registered user";
}
/* SVSHOLD - release */
@@ -265,7 +265,7 @@ class BahamutIRCdProto : public IRCDProto
void SendConnect() anope_override
{
- UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink]->password << " :TS";
+ UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink].password << " :TS";
UplinkSocket::Message() << "CAPAB SSJOIN NOQUIT BURST UNCONNECT NICKIP TSMODE TS3";
SendServer(Me);
/*
diff --git a/modules/protocol/charybdis.cpp b/modules/protocol/charybdis.cpp
index 374111f44..1fb017fef 100644
--- a/modules/protocol/charybdis.cpp
+++ b/modules/protocol/charybdis.cpp
@@ -11,6 +11,7 @@
#include "module.h"
+static bool sasl = true;
static Anope::string UplinkSID;
static ServiceReference<IRCDProto> ratbox("IRCDProto", "ratbox");
@@ -64,7 +65,7 @@ class CharybdisProto : public IRCDProto
void SendConnect() anope_override
{
- UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink]->password << " TS 6 :" << Me->GetSID();
+ UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink].password << " TS 6 :" << Me->GetSID();
/*
* Received: CAPAB :BAN CHW CLUSTER ENCAP EOPMOD EUID EX IE KLN
* KNOCK MLOCK QS RSFNC SAVE SERVICES TB UNKLN
@@ -128,12 +129,12 @@ class CharybdisProto : public IRCDProto
<< " " << newnick << " " << when << " " << u->timestamp;
}
- void SendSVSHold(const Anope::string &nick)
+ void SendSVSHold(const Anope::string &nick, time_t delay) anope_override
{
- UplinkSocket::Message(Me) << "ENCAP * NICKDELAY " << Config->NSReleaseTimeout << " " << nick;
+ UplinkSocket::Message(Me) << "ENCAP * NICKDELAY " << delay << " " << nick;
}
- void SendSVSHoldDel(const Anope::string &nick)
+ void SendSVSHoldDel(const Anope::string &nick) anope_override
{
UplinkSocket::Message(Me) << "ENCAP * NICKDELAY 0 " << nick;
}
@@ -183,7 +184,7 @@ struct IRCDMessageEncap : IRCDMessage
*
* Charybdis only accepts messages from SASL agents; these must have umode +S
*/
- if (params[1] == "SASL" && Config->NSSASL && params.size() == 6)
+ if (params[1] == "SASL" && sasl && params.size() == 6)
{
class CharybdisSASLIdentifyRequest : public IdentifyRequest
{
@@ -298,7 +299,7 @@ struct IRCDMessageServer : IRCDMessage
if (params[1] != "1")
return;
new Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], 1, params[2], UplinkSID);
- IRCD->SendPing(Config->ServerName, params[0]);
+ IRCD->SendPing(Me->GetName(), params[0]);
}
};
@@ -350,6 +351,8 @@ class ProtoCharybdis : public Module
IRCDMessagePass message_pass;
IRCDMessageServer message_server;
+ bool use_server_side_mlock;
+
void AddModes()
{
/* Add user modes */
@@ -403,7 +406,7 @@ class ProtoCharybdis : public Module
{
- Implementation i[] = { I_OnChannelCreate, I_OnMLock, I_OnUnMLock };
+ Implementation i[] = { I_OnReload, I_OnChannelCreate, I_OnMLock, I_OnUnMLock };
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
if (ModuleManager::LoadModule("ratbox", User::Find(creator)) != MOD_ERR_OK)
@@ -422,9 +425,15 @@ class ProtoCharybdis : public Module
ModuleManager::UnloadModule(m_ratbox, NULL);
}
+ void OnReload(Configuration::Conf *conf) anope_override
+ {
+ use_server_side_mlock = conf->GetModule(this)->Get<bool>("use_server_side_mlock");
+ sasl = conf->GetModule(this)->Get<bool>("sasl");
+ }
+
void OnChannelCreate(Channel *c) anope_override
{
- if (c->ci && Config->UseServerSideMLock && Servers::Capab.count("MLOCK") > 0)
+ if (use_server_side_mlock && c->ci && Servers::Capab.count("MLOCK") > 0)
{
Anope::string modes = c->ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "");
UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(c->creation_time) << " " << c->ci->name << " " << modes;
@@ -434,7 +443,7 @@ class ProtoCharybdis : public Module
EventReturn OnMLock(ChannelInfo *ci, ModeLock *lock) anope_override
{
ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name);
- if (cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0 && Config->UseServerSideMLock)
+ if (use_server_side_mlock && cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0)
{
Anope::string modes = ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "") + cm->mchar;
UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(ci->c->creation_time) << " " << ci->name << " " << modes;
@@ -446,7 +455,7 @@ class ProtoCharybdis : public Module
EventReturn OnUnMLock(ChannelInfo *ci, ModeLock *lock) anope_override
{
ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name);
- if (cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0 && Config->UseServerSideMLock)
+ if (use_server_side_mlock && cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0)
{
Anope::string modes = ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "").replace_all_cs(cm->mchar, "");
UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(ci->c->creation_time) << " " << ci->name << " " << modes;
diff --git a/modules/protocol/hybrid.cpp b/modules/protocol/hybrid.cpp
index a00158bf8..1a50b89a6 100644
--- a/modules/protocol/hybrid.cpp
+++ b/modules/protocol/hybrid.cpp
@@ -160,7 +160,7 @@ class HybridProto : public IRCDProto
void SendConnect() anope_override
{
- UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink]->password << " TS 6 :" << Me->GetSID();
+ UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink].password << " TS 6 :" << Me->GetSID();
/*
* As of October 13, 2012, ircd-hybrid-8 does support the following capabilities
@@ -249,9 +249,9 @@ class HybridProto : public IRCDProto
UplinkSocket::Message(Me) << "SVSNICK " << u->nick << " " << newnick << " " << when;
}
- void SendSVSHold(const Anope::string &nick) anope_override
+ void SendSVSHold(const Anope::string &nick, time_t t) anope_override
{
- XLine x(nick, OperServ->nick, Anope::CurTime + Config->NSReleaseTimeout, "Being held for registered user");
+ XLine x(nick, OperServ->nick, Anope::CurTime + t, "Being held for registered user");
this->SendSQLine(NULL, &x);
}
@@ -357,7 +357,7 @@ struct IRCDMessageServer : IRCDMessage
new Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], 1, params[2], UplinkSID);
- IRCD->SendPing(Config->ServerName, params[0]);
+ IRCD->SendPing(Me->GetName(), params[0]);
}
};
@@ -372,7 +372,7 @@ struct IRCDMessageSID : IRCDMessage
unsigned int hops = params[1].is_pos_number_only() ? convertTo<unsigned>(params[1]) : 0;
new Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], hops, params[3], params[2]);
- IRCD->SendPing(Config->ServerName, params[0]);
+ IRCD->SendPing(Me->GetName(), params[0]);
}
};
@@ -608,12 +608,8 @@ public:
ModuleManager::Attach(I_OnUserNickChange, this);
- if (Config->Numeric.empty())
- {
- Anope::string numeric = Servers::TS6_SID_Retrieve();
- Me->SetSID(numeric);
- Config->Numeric = numeric;
- }
+ if (Me->GetSID() == Me->GetName())
+ Me->SetSID(Servers::TS6_SID_Retrieve());
for (botinfo_map::iterator it = BotListByNick->begin(), it_end = BotListByNick->end(); it != it_end; ++it)
it->second->GenerateUID();
diff --git a/modules/protocol/inspircd11.cpp b/modules/protocol/inspircd11.cpp
index eeb1e17e1..12a22e724 100644
--- a/modules/protocol/inspircd11.cpp
+++ b/modules/protocol/inspircd11.cpp
@@ -239,7 +239,7 @@ class InspIRCdProto : public IRCDProto
void SendConnect() anope_override
{
- current_pass = Config->Uplinks[Anope::CurrentUplink]->password;
+ current_pass = Config->Uplinks[Anope::CurrentUplink].password;
SendServer(Me);
UplinkSocket::Message() << "BURST";
Module *enc = ModuleManager::FindFirstOf(ENCRYPTION);
@@ -247,9 +247,9 @@ class InspIRCdProto : public IRCDProto
}
/* SVSHOLD - set */
- void SendSVSHold(const Anope::string &nick) anope_override
+ void SendSVSHold(const Anope::string &nick, time_t t) anope_override
{
- UplinkSocket::Message(OperServ) << "SVSHOLD " << nick << " " << Config->NSReleaseTimeout << "s :Being held for registered user";
+ UplinkSocket::Message(OperServ) << "SVSHOLD " << nick << " " << t << "s :Being held for registered user";
}
/* SVSHOLD - release */
@@ -790,7 +790,7 @@ struct IRCDMessageRSQuit : IRCDMessage
Server *s;
/* Horrible workaround to an insp bug (#) in how RSQUITs are sent - mark */
- if (params.size() > 1 && Config->ServerName.equals_cs(params[0]))
+ if (params.size() > 1 && params[0] == Me->GetName())
s = Server::Find(params[1]);
else
s = Server::Find(params[0]);
diff --git a/modules/protocol/inspircd12.cpp b/modules/protocol/inspircd12.cpp
index 80f21c3da..c3fa04b85 100644
--- a/modules/protocol/inspircd12.cpp
+++ b/modules/protocol/inspircd12.cpp
@@ -211,7 +211,7 @@ class InspIRCd12Proto : public IRCDProto
/* SERVER services-dev.chatspike.net password 0 :Description here */
void SendServer(const Server *server) anope_override
{
- UplinkSocket::Message() << "SERVER " << server->GetName() << " " << Config->Uplinks[Anope::CurrentUplink]->password << " " << server->GetHops() << " " << server->GetSID() << " :" << server->GetDescription();
+ UplinkSocket::Message() << "SERVER " << server->GetName() << " " << Config->Uplinks[Anope::CurrentUplink].password << " " << server->GetHops() << " " << server->GetSID() << " :" << server->GetDescription();
}
/* JOIN */
@@ -270,13 +270,13 @@ class InspIRCd12Proto : public IRCDProto
SendServer(Me);
UplinkSocket::Message(Me) << "BURST";
Module *enc = ModuleManager::FindFirstOf(ENCRYPTION);
- UplinkSocket::Message(Me) << "VERSION :Anope-" << Anope::Version() << " " << Config->ServerName << " :" << IRCD->GetProtocolName() << " - (" << (enc ? enc->name : "none") << ") -- " << Anope::VersionBuildString();
+ UplinkSocket::Message(Me) << "VERSION :Anope-" << Anope::Version() << " " << Me->GetName() << " :" << IRCD->GetProtocolName() << " - (" << (enc ? enc->name : "none") << ") -- " << Anope::VersionBuildString();
}
/* SVSHOLD - set */
- void SendSVSHold(const Anope::string &nick) anope_override
+ void SendSVSHold(const Anope::string &nick, time_t t) anope_override
{
- UplinkSocket::Message(NickServ) << "SVSHOLD " << nick << " " << Config->NSReleaseTimeout << " :Being held for registered user";
+ UplinkSocket::Message(NickServ) << "SVSHOLD " << nick << " " << t << " :Being held for registered user";
}
/* SVSHOLD - release */
@@ -929,7 +929,7 @@ struct IRCDMessageMetadata : IRCDMessage
u->Login(nc);
const NickAlias *user_na = NickAlias::Find(u->nick);
- if (!Config->NoNicknameOwnership && user_na && user_na->nc == nc && user_na->nc->HasExt("UNCONFIRMED") == false)
+ if (!Config->GetBlock("options")->Get<bool>("nonicknameownership") && user_na && user_na->nc == nc && user_na->nc->HasExt("UNCONFIRMED") == false)
u->SetMode(NickServ, "REGISTERED");
/* Sometimes a user connects, we send them the usual "this nickname is registered" mess (if
@@ -1221,12 +1221,8 @@ class ProtoInspIRCd : public Module
Servers::Capab.insert("NOQUIT");
- if (Config->Numeric.empty())
- {
- Anope::string numeric = Servers::TS6_SID_Retrieve();
- Me->SetSID(numeric);
- Config->Numeric = numeric;
- }
+ if (Me->GetSID() == Me->GetName())
+ Me->SetSID(Servers::TS6_SID_Retrieve());
for (botinfo_map::iterator it = BotListByNick->begin(), it_end = BotListByNick->end(); it != it_end; ++it)
it->second->GenerateUID();
diff --git a/modules/protocol/inspircd20.cpp b/modules/protocol/inspircd20.cpp
index 7b21c2b08..3884862d9 100644
--- a/modules/protocol/inspircd20.cpp
+++ b/modules/protocol/inspircd20.cpp
@@ -13,6 +13,7 @@
#include "module.h"
+static bool sasl = true;
static unsigned int spanningtree_proto_ver = 0;
static ServiceReference<IRCDProto> insp12("IRCDProto", "inspircd12");
@@ -58,7 +59,7 @@ class InspIRCd20Proto : public IRCDProto
void SendSQLineDel(const XLine *x) anope_override { insp12->SendSQLineDel(x); }
void SendSQLine(User *u, const XLine *x) anope_override { insp12->SendSQLine(u, x); }
void SendVhost(User *u, const Anope::string &vident, const Anope::string &vhost) anope_override { insp12->SendVhost(u, vident, vhost); }
- void SendSVSHold(const Anope::string &nick) anope_override { insp12->SendSVSHold(nick); }
+ void SendSVSHold(const Anope::string &nick, time_t t) anope_override { insp12->SendSVSHold(nick, t); }
void SendSVSHoldDel(const Anope::string &nick) anope_override { insp12->SendSVSHoldDel(nick); }
void SendSZLineDel(const XLine *x) anope_override { insp12->SendSZLineDel(x); }
void SendSZLine(User *u, const XLine *x) anope_override { insp12->SendSZLine(u, x); }
@@ -367,8 +368,9 @@ struct IRCDMessageCapab : Message::Capab
else if (module.find("m_rline.so") == 0)
{
Servers::Capab.insert("RLINE");
- if (!Config->RegexEngine.empty() && module.length() > 11 && Config->RegexEngine != module.substr(11))
- Log() << "Warning: InspIRCd is using regex engine " << module.substr(11) << ", but we have " << Config->RegexEngine << ". This may cause inconsistencies.";
+ const Anope::string &regexengine = Config->GetBlock("options")->Get<const Anope::string &>("regexengine");
+ if (!regexengine.empty() && module.length() > 11 && regexengine != module.substr(11))
+ Log() << "Warning: InspIRCd is using regex engine " << module.substr(11) << ", but we have " << regexengine << ". This may cause inconsistencies.";
}
else if (module.equals_cs("m_topiclock.so"))
Servers::Capab.insert("TOPICLOCK");
@@ -502,8 +504,6 @@ struct IRCDMessageCapab : Message::Capab
Log() << "CHGHOST missing, Usage disabled until module is loaded.";
if (!Servers::Capab.count("CHGIDENT"))
Log() << "CHGIDENT missing, Usage disabled until module is loaded.";
- if (!Servers::Capab.count("TOPICLOCK") && Config->UseServerSideTopicLock)
- Log() << "m_topiclock missing, server side topic locking disabled until module is loaded.";
chmodes.clear();
umodes.clear();
@@ -549,7 +549,7 @@ struct IRCDMessageEncap : IRCDMessage
u->SetRealname(params[3]);
UplinkSocket::Message(u) << "FNAME " << params[3];
}
- else if (Config->NSSASL && params[1] == "SASL" && params.size() == 6)
+ else if (sasl && params[1] == "SASL" && params.size() == 6)
{
class InspIRCDSASLIdentifyRequest : public IdentifyRequest
{
@@ -656,6 +656,8 @@ class ProtoInspIRCd : public Module
IRCDMessageEncap message_encap;
IRCDMessageFIdent message_fident;
+ bool use_server_side_topiclock, use_server_side_mlock;
+
void SendChannelMetadata(Channel *c, const Anope::string &metadataname, const Anope::string &value)
{
UplinkSocket::Message(Me) << "METADATA " << c->name << " " << metadataname << " :" << value;
@@ -695,7 +697,7 @@ class ProtoInspIRCd : public Module
throw ModuleException("No protocol interface for insp12");
ModuleManager::DetachAll(m_insp12);
- Implementation i[] = { I_OnUserNickChange, I_OnChannelCreate, I_OnChanRegistered, I_OnDelChan, I_OnMLock, I_OnUnMLock, I_OnSetChannelOption };
+ Implementation i[] = { I_OnReload, I_OnUserNickChange, I_OnChannelCreate, I_OnChanRegistered, I_OnDelChan, I_OnMLock, I_OnUnMLock, I_OnSetChannelOption };
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
}
@@ -704,6 +706,13 @@ class ProtoInspIRCd : public Module
ModuleManager::UnloadModule(m_insp12, NULL);
}
+ void OnReload(Configuration::Conf *conf) anope_override
+ {
+ use_server_side_topiclock = conf->GetModule(this)->Get<bool>("use_server_side_topiclock");
+ use_server_side_mlock = conf->GetModule(this)->Get<bool>("use_server_side_mlock");
+ sasl = conf->GetModule(this)->Get<bool>("sasl");
+ }
+
void OnUserNickChange(User *u, const Anope::string &) anope_override
{
u->RemoveModeInternal(ModeManager::FindUserModeByName("REGISTERED"));
@@ -711,19 +720,18 @@ class ProtoInspIRCd : public Module
void OnChannelCreate(Channel *c) anope_override
{
- if (c->ci && (Config->UseServerSideMLock || Config->UseServerSideTopicLock))
- this->OnChanRegistered(c->ci);
+ this->OnChanRegistered(c->ci);
}
void OnChanRegistered(ChannelInfo *ci) anope_override
{
- if (Config->UseServerSideMLock && ci->c)
+ if (use_server_side_mlock && ci->c)
{
Anope::string modes = ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "");
SendChannelMetadata(ci->c, "mlock", modes);
}
- if (Config->UseServerSideTopicLock && Servers::Capab.count("TOPICLOCK") && ci->c)
+ if (use_server_side_topiclock && Servers::Capab.count("TOPICLOCK") && ci->c)
{
Anope::string on = ci->HasExt("TOPICLOCK") ? "1" : "";
SendChannelMetadata(ci->c, "topiclock", on);
@@ -732,17 +740,17 @@ class ProtoInspIRCd : public Module
void OnDelChan(ChannelInfo *ci) anope_override
{
- if (Config->UseServerSideMLock && ci->c)
+ if (use_server_side_mlock && ci->c)
SendChannelMetadata(ci->c, "mlock", "");
- if (Config->UseServerSideTopicLock && Servers::Capab.count("TOPICLOCK") && ci->c)
+ if (use_server_side_topiclock && Servers::Capab.count("TOPICLOCK") && ci->c)
SendChannelMetadata(ci->c, "topiclock", "");
}
EventReturn OnMLock(ChannelInfo *ci, ModeLock *lock) anope_override
{
ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name);
- if (cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Config->UseServerSideMLock)
+ if (use_server_side_mlock && cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM))
{
Anope::string modes = ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "") + cm->mchar;
SendChannelMetadata(ci->c, "mlock", modes);
@@ -754,7 +762,7 @@ class ProtoInspIRCd : public Module
EventReturn OnUnMLock(ChannelInfo *ci, ModeLock *lock) anope_override
{
ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name);
- if (cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Config->UseServerSideMLock)
+ if (use_server_side_mlock && cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM))
{
Anope::string modes = ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "").replace_all_cs(cm->mchar, "");
SendChannelMetadata(ci->c, "mlock", modes);
@@ -767,7 +775,6 @@ class ProtoInspIRCd : public Module
{
if (cmd->name == "chanserv/topic" && ci->c)
{
-
if (setting == "topiclock on")
SendChannelMetadata(ci->c, "topiclock", "1");
else if (setting == "topiclock off")
diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
index c749a2d7d..3d1a727e7 100644
--- a/modules/protocol/ngircd.cpp
+++ b/modules/protocol/ngircd.cpp
@@ -53,7 +53,7 @@ class ngIRCdProto : public IRCDProto
void SendConnect() anope_override
{
- UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink]->password << " 0210-IRC+ Anope|" << Anope::VersionShort() << ":CLHMSo P";
+ UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink].password << " 0210-IRC+ Anope|" << Anope::VersionShort() << ":CLHMSo P";
/* Make myself known to myself in the serverlist */
SendServer(Me);
/* finish the enhanced server handshake and register the connection */
@@ -184,11 +184,10 @@ struct IRCDMessage005 : IRCDMessage
}
else if (parameter == "NICKLEN")
{
- unsigned newlen = convertTo<unsigned>(data);
- if (Config->NickLen != newlen)
+ unsigned newlen = convertTo<unsigned>(data), len = Config->GetBlock("networkinfo")->Get<unsigned>("nicklen");
+ if (len != newlen)
{
- Log() << "NickLen changed from " << Config->NickLen << " to " << newlen;
- Config->NickLen = newlen;
+ Log() << "Warning: NICKLEN is " << newlen << " but networkinfo:nicklen is " << len;
}
}
}
@@ -540,7 +539,7 @@ struct IRCDMessageServer : IRCDMessage
* when receiving a new server and then finish sync once we
* get a pong back from that server.
*/
- IRCD->SendPing(Config->ServerName, params[0]);
+ IRCD->SendPing(Me->GetName(), params[0]);
}
};
diff --git a/modules/protocol/plexus.cpp b/modules/protocol/plexus.cpp
index b256afc36..484f6a4bc 100644
--- a/modules/protocol/plexus.cpp
+++ b/modules/protocol/plexus.cpp
@@ -45,7 +45,7 @@ class PlexusProto : public IRCDProto
void SendAkill(User *u, XLine *x) anope_override { hybrid->SendAkill(u, x); }
void SendServer(const Server *server) anope_override { hybrid->SendServer(server); }
void SendChannel(Channel *c) anope_override { hybrid->SendChannel(c); }
- void SendSVSHold(const Anope::string &nick) anope_override { hybrid->SendSVSHold(nick); }
+ void SendSVSHold(const Anope::string &nick, time_t t) anope_override { hybrid->SendSVSHold(nick, t); }
void SendSVSHoldDel(const Anope::string &nick) anope_override { hybrid->SendSVSHoldDel(nick); }
void SendJoin(User *user, Channel *c, const ChannelStatus *status) anope_override
@@ -90,7 +90,7 @@ class PlexusProto : public IRCDProto
void SendConnect() anope_override
{
- UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink]->password << " TS 6 :" << Me->GetSID();
+ UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink].password << " TS 6 :" << Me->GetSID();
/* CAPAB
* QS - Can handle quit storm removal
* EX - Can do channel +e exemptions
@@ -186,7 +186,7 @@ struct IRCDMessageEncap : IRCDMessage
if (u && nc)
{
u->Login(nc);
- if (!Config->NoNicknameOwnership && user_na && user_na->nc == nc && user_na->nc->HasExt("UNCONFIRMED") == false)
+ if (!Config->GetBlock("options")->Get<bool>("nonicknameownership") && user_na && user_na->nc == nc && user_na->nc->HasExt("UNCONFIRMED") == false)
u->SetMode(NickServ, "REGISTERED");
}
}
diff --git a/modules/protocol/ratbox.cpp b/modules/protocol/ratbox.cpp
index 2d01605bb..2b971b23f 100644
--- a/modules/protocol/ratbox.cpp
+++ b/modules/protocol/ratbox.cpp
@@ -45,7 +45,7 @@ class RatboxProto : public IRCDProto
void SendConnect() anope_override
{
- UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink]->password << " TS 6 :" << Me->GetSID();
+ UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink].password << " TS 6 :" << Me->GetSID();
/*
QS - Can handle quit storm removal
EX - Can do channel +e exemptions
@@ -107,7 +107,7 @@ struct IRCDMessageEncap : IRCDMessage
u->Login(nc);
const NickAlias *user_na = NickAlias::Find(u->nick);
- if (!Config->NoNicknameOwnership && user_na && user_na->nc == nc && user_na->nc->HasExt("UNCONFIRMED") == false)
+ if (!Config->GetBlock("options")->Get<bool>("nonicknameownership") && user_na && user_na->nc == nc && user_na->nc->HasExt("UNCONFIRMED") == false)
u->SetMode(NickServ, "REGISTERED");
}
}
@@ -134,7 +134,7 @@ struct IRCDMessageServer : IRCDMessage
if (params[1] != "1")
return;
new Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], 1, params[2], UplinkSID);
- IRCD->SendPing(Config->ServerName, params[0]);
+ IRCD->SendPing(Me->GetName(), params[0]);
}
};
@@ -217,6 +217,7 @@ class ProtoRatbox : public Module
/* user modes */
ModeManager::RemoveUserMode(ModeManager::FindUserModeByName("HIDEOPER"));
ModeManager::RemoveUserMode(ModeManager::FindUserModeByName("REGPRIV"));
+ ModeManager::AddUserMode(new UserMode("PROTECTED", 'S'));
/* v/h/o/a/q */
ModeManager::RemoveChannelMode(ModeManager::FindChannelModeByName("HALFOP"));
diff --git a/modules/protocol/unreal.cpp b/modules/protocol/unreal.cpp
index 7a7847972..4186ee5d0 100644
--- a/modules/protocol/unreal.cpp
+++ b/modules/protocol/unreal.cpp
@@ -13,6 +13,8 @@
#include "module.h"
+static bool sasl = true;
+
class UnrealIRCdProto : public IRCDProto
{
public:
@@ -53,7 +55,7 @@ class UnrealIRCdProto : public IRCDProto
}
catch (const SocketException &) { }
- UplinkSocket::Message() << "TKL - G " << x->GetUser() << " " << x->GetHost() << " " << Config->OperServ;
+ UplinkSocket::Message() << "TKL - G " << x->GetUser() << " " << x->GetHost() << " " << x->by;
}
void SendTopic(BotInfo *whosets, Channel *c) anope_override
@@ -143,8 +145,8 @@ class UnrealIRCdProto : public IRCDProto
/* Unreal 3.2 actually sends some info about itself in the descript area */
void SendServer(const Server *server) anope_override
{
- if (!Config->Numeric.empty())
- UplinkSocket::Message() << "SERVER " << server->GetName() << " " << server->GetHops() << " :U0-*-" << Config->Numeric << " " << server->GetDescription();
+ if (!server->GetSID().empty() && server == Me)
+ UplinkSocket::Message() << "SERVER " << server->GetName() << " " << server->GetHops() << " :U0-*-" << server->GetSID() << " " << server->GetDescription();
else
UplinkSocket::Message() << "SERVER " << server->GetName() << " " << server->GetHops() << " :" << server->GetDescription();
}
@@ -225,24 +227,24 @@ class UnrealIRCdProto : public IRCDProto
VL = Version Info
NS = Config->Numeric Server
*/
- if (!Config->Numeric.empty())
- UplinkSocket::Message() << "PROTOCTL NICKv2 VHP UMODE2 NICKIP SJOIN SJOIN2 SJ3 NOQUIT TKLEXT ESVID MLOCK VL";
- else
- UplinkSocket::Message() << "PROTOCTL NICKv2 VHP UMODE2 NICKIP SJOIN SJOIN2 SJ3 NOQUIT TKLEXT ESVID MLOCK";
- UplinkSocket::Message() << "PASS :" << Config->Uplinks[Anope::CurrentUplink]->password;
+ Anope::string protoctl = "NICKv2 VHP UMODE2 NICKIP SJOIN SJOIN2 SJ3 NOQUIT TKLEXT ESVID MLOCK VL";
+ if (!Me->GetSID().empty())
+ protoctl += " VL";
+ UplinkSocket::Message() << "PROTOCTL " << protoctl;
+ UplinkSocket::Message() << "PASS :" << Config->Uplinks[Anope::CurrentUplink].password;
SendServer(Me);
}
/* SVSHOLD - set */
- void SendSVSHold(const Anope::string &nick) anope_override
+ void SendSVSHold(const Anope::string &nick, time_t t) anope_override
{
- UplinkSocket::Message() << "TKL + Q H " << nick << " " << Config->ServerName << " " << Anope::CurTime + Config->NSReleaseTimeout << " " << Anope::CurTime << " :Being held for registered user";
+ UplinkSocket::Message() << "TKL + Q H " << nick << " " << Me->GetName() << " " << Anope::CurTime + t << " " << Anope::CurTime << " :Being held for registered user";
}
/* SVSHOLD - release */
void SendSVSHoldDel(const Anope::string &nick) anope_override
{
- UplinkSocket::Message() << "TKL - Q * " << nick << " " << Config->ServerName;
+ UplinkSocket::Message() << "TKL - Q * " << nick << " " << Me->GetName();
}
/* UNSGLINE */
@@ -257,7 +259,7 @@ class UnrealIRCdProto : public IRCDProto
/* UNSZLINE */
void SendSZLineDel(const XLine *x) anope_override
{
- UplinkSocket::Message() << "TKL - Z * " << x->GetHost() << " " << Config->OperServ;
+ UplinkSocket::Message() << "TKL - Z * " << x->GetHost() << " " << x->by;
}
/* SZLINE */
@@ -892,7 +894,7 @@ struct IRCDMessageSASL : IRCDMessage
void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
{
size_t p = params[1].find('!');
- if (!Config->NSSASL || p == Anope::string::npos)
+ if (!sasl || p == Anope::string::npos)
return;
if (params[2] == "S")
@@ -996,7 +998,7 @@ struct IRCDMessageServer : IRCDMessage
else
new Server(source.GetServer(), params[0], hops, params[2]);
- IRCD->SendPing(Config->ServerName, params[0]);
+ IRCD->SendPing(Me->GetName(), params[0]);
}
};
@@ -1158,6 +1160,8 @@ class ProtoUnreal : public Module
IRCDMessageTopic message_topic;
IRCDMessageUmode2 message_umode2;
+ bool use_server_side_mlock;
+
void AddModes()
{
ModeManager::AddChannelMode(new ChannelModeStatus("VOICE", 'v', '+', 0));
@@ -1212,11 +1216,17 @@ class ProtoUnreal : public Module
this->AddModes();
- Implementation i[] = { I_OnUserNickChange, I_OnChannelCreate, I_OnChanRegistered, I_OnDelChan, I_OnMLock, I_OnUnMLock };
+ Implementation i[] = { I_OnReload, I_OnUserNickChange, I_OnChannelCreate, I_OnChanRegistered, I_OnDelChan, I_OnMLock, I_OnUnMLock };
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
ModuleManager::SetPriority(this, PRIORITY_FIRST);
}
+ void OnReload(Configuration::Conf *conf) anope_override
+ {
+ use_server_side_mlock = conf->GetModule(this)->Get<bool>("use_server_side_mlock");
+ sasl = conf->GetModule(this)->Get<bool>("sasl");
+ }
+
void OnUserNickChange(User *u, const Anope::string &) anope_override
{
u->RemoveModeInternal(ModeManager::FindUserModeByName("REGISTERED"));
@@ -1226,7 +1236,7 @@ class ProtoUnreal : public Module
void OnChannelCreate(Channel *c) anope_override
{
- if (Config->UseServerSideMLock && Servers::Capab.count("MLOCK") > 0 && c->ci)
+ if (use_server_side_mlock && Servers::Capab.count("MLOCK") > 0 && c->ci)
{
Anope::string modes = c->ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "");
UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(c->creation_time) << " " << c->ci->name << " " << modes;
@@ -1235,7 +1245,7 @@ class ProtoUnreal : public Module
void OnChanRegistered(ChannelInfo *ci) anope_override
{
- if (!ci->c || !Config->UseServerSideMLock)
+ if (!ci->c || !use_server_side_mlock || !Servers::Capab.count("MLOCK"))
return;
Anope::string modes = ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "");
UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(ci->c->creation_time) << " " << ci->name << " " << modes;
@@ -1243,7 +1253,7 @@ class ProtoUnreal : public Module
void OnDelChan(ChannelInfo *ci) anope_override
{
- if (!ci->c || !Config->UseServerSideMLock)
+ if (!ci->c || !use_server_side_mlock || !Servers::Capab.count("MLOCK"))
return;
UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(ci->c->creation_time) << " " << ci->name << " :";
}
@@ -1251,7 +1261,7 @@ class ProtoUnreal : public Module
EventReturn OnMLock(ChannelInfo *ci, ModeLock *lock) anope_override
{
ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name);
- if (cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0 && Config->UseServerSideMLock)
+ if (use_server_side_mlock && cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0)
{
Anope::string modes = ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "") + cm->mchar;
UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(ci->c->creation_time) << " " << ci->name << " " << modes;
@@ -1263,7 +1273,7 @@ class ProtoUnreal : public Module
EventReturn OnUnMLock(ChannelInfo *ci, ModeLock *lock) anope_override
{
ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name);
- if (cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0 && Config->UseServerSideMLock)
+ if (use_server_side_mlock && cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0)
{
Anope::string modes = ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "").replace_all_cs(cm->mchar, "");
UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(ci->c->creation_time) << " " << ci->name << " " << modes;
diff --git a/modules/pseudoclients/botserv.cpp b/modules/pseudoclients/botserv.cpp
index 29c1b1143..c33a8eeb5 100644
--- a/modules/pseudoclients/botserv.cpp
+++ b/modules/pseudoclients/botserv.cpp
@@ -18,13 +18,8 @@ class BotServCore : public Module
public:
BotServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR)
{
-
- BotServ = BotInfo::Find(Config->BotServ);
- if (!BotServ)
- throw ModuleException("No bot named " + Config->BotServ);
-
- Implementation i[] = { I_OnBotDelete, I_OnPrivmsg, I_OnJoinChannel, I_OnLeaveChannel,
- I_OnPreHelp, I_OnPostHelp, I_OnChannelModeSet };
+ Implementation i[] = { I_OnReload, I_OnSetCorrectModes, I_OnBotAssign, I_OnBotDelete, I_OnPrivmsg, I_OnJoinChannel, I_OnLeaveChannel,
+ I_OnPreHelp, I_OnPostHelp, I_OnChannelModeSet, I_OnCreateChan, I_OnUserKicked };
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
}
@@ -33,6 +28,40 @@ class BotServCore : public Module
BotServ = NULL;
}
+ void OnReload(Configuration::Conf *conf) anope_override
+ {
+ const Anope::string &bsnick = conf->GetModule(this)->Get<const Anope::string &>("client");
+
+ if (bsnick.empty())
+ throw ConfigException(this->name + ": <client> must be defined");
+
+ BotInfo *bi = BotInfo::Find(bsnick, true);
+ if (!bi)
+ throw ConfigException(this->name + ": no bot named " + bsnick);
+
+ BotServ = bi;
+ }
+
+ void OnSetCorrectModes(User *user, Channel *chan, AccessGroup &access, bool give_modes) anope_override
+ {
+ /* Do not allow removing bot modes on our service bots */
+ if (chan->ci && chan->ci->bi == user)
+ {
+ const Anope::string &botmodes = Config->GetModule(this)->Get<const Anope::string &>("botmodes");
+ for (unsigned i = 0; i < botmodes.length(); ++i)
+ chan->SetMode(chan->ci->bi, ModeManager::FindChannelModeByChar(botmodes[i]), chan->ci->bi->GetUID());
+ }
+ }
+
+ void OnBotAssign(User *sender, ChannelInfo *ci, BotInfo *bi) anope_override
+ {
+ if (Me->IsSynced() && ci->c && ci->c->users.size() >= Config->GetModule(this)->Get<unsigned>("minusers"))
+ {
+ ChannelStatus status(Config->GetModule(this)->Get<const Anope::string &>("botmodes"));
+ bi->Join(ci->c, &status);
+ }
+ }
+
void OnBotDelete(BotInfo *bi) anope_override
{
if (bi == BotServ)
@@ -70,9 +99,7 @@ class BotServCore : public Module
if (!realbuf.find(c->ci->bi->nick))
params.erase(params.begin());
- else if (Config->BSFantasyCharacter.empty())
- ;
- else if (!realbuf.find_first_of(Config->BSFantasyCharacter))
+ else if (!realbuf.find_first_of(Config->GetModule(this)->Get<const Anope::string &>("fantasycharacter", "!")))
params[0].erase(params[0].begin());
else
return;
@@ -158,6 +185,42 @@ class BotServCore : public Module
void OnJoinChannel(User *user, Channel *c) anope_override
{
+ if (!Config || !IRCD)
+ return;
+
+ BotInfo *bi = user->server == Me ? dynamic_cast<BotInfo *>(user) : NULL;
+ if (bi && Config->GetModule(this)->Get<bool>("smartjoin"))
+ {
+ std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> bans = c->GetModeList("BAN");
+
+ /* We check for bans */
+ for (; bans.first != bans.second; ++bans.first)
+ {
+ Entry ban("BAN", bans.first->second);
+ if (ban.Matches(user))
+ c->RemoveMode(NULL, "BAN", ban.GetMask());
+ }
+
+ Anope::string Limit;
+ unsigned limit = 0;
+ try
+ {
+ if (c->GetParam("LIMIT", Limit))
+ limit = convertTo<unsigned>(Limit);
+ }
+ catch (const ConvertException &) { }
+
+ /* Should we be invited? */
+ if (c->HasMode("INVITE") || (limit && c->users.size() >= limit))
+ {
+ ChannelMode *cm = ModeManager::FindChannelModeByName("OP");
+ char symbol = cm ? anope_dynamic_static_cast<ChannelModeStatus *>(cm)->symbol : 0;
+ IRCD->SendNotice(bi, (symbol ? Anope::string(symbol) : "") + c->name, "%s invited %s into the channel.", user->nick.c_str(), user->nick.c_str());
+ }
+
+ ModeManager::ProcessModes();
+ }
+
if (user->server != Me && c->ci && c->ci->bi)
{
/**
@@ -166,8 +229,11 @@ class BotServCore : public Module
* make it into the channel, leaving the channel botless even for
* legit users - Rob
**/
- if (c->users.size() >= Config->BSMinUsers && !c->FindUser(c->ci->bi))
- c->ci->bi->Join(c, &ModeManager::DefaultBotModes);
+ if (c->users.size() >= Config->GetModule(this)->Get<unsigned>("minusers") && !c->FindUser(c->ci->bi))
+ {
+ ChannelStatus status(Config->GetModule(this)->Get<const Anope::string &>("botmodes"));
+ c->ci->bi->Join(c, &status);
+ }
/* Only display the greet if the main uplink we're connected
* to has synced, or we'll get greet-floods when the net
* recovers from a netsplit. -GD
@@ -197,7 +263,7 @@ class BotServCore : public Module
return;
/* This is called prior to removing the user from the channnel, so c->users.size() - 1 should be safe */
- if (c->ci && c->ci->bi && u != *c->ci->bi && c->users.size() - 1 <= Config->BSMinUsers && c->FindUser(c->ci->bi))
+ if (c->ci && c->ci->bi && u != *c->ci->bi && c->users.size() - 1 <= Config->GetModule(this)->Get<unsigned>("minusers") && c->FindUser(c->ci->bi))
c->ci->bi->Part(c->ci->c);
}
@@ -209,17 +275,18 @@ class BotServCore : public Module
if (source.c)
{
source.Reply(_("\002%s\002 allows you to execute \"fantasy\" commands in the channel.\n"
- "Fantasy commands are tied to existing commands, usually on \002%s\002,\n"
- "and provide a more convenient way to execute commands. Commands that\n"
+ "Fantasy commands are commands that can be executed from messaging a\n"
+ "channel, and provide a more convenient way to execute commands. Commands that\n"
"require a channel as a parameter will automatically have that parameter\n"
- "given.\n"), source.service->nick.c_str(), Config->ChanServ.c_str());
- if (!Config->BSFantasyCharacter.empty())
+ "given.\n"), source.service->nick.c_str());
+ const Anope::string &fantasycharacters = Config->GetModule(this)->Get<const Anope::string &>("fantasycharacter", "!");
+ if (!fantasycharacters.empty())
source.Reply(_(" \n"
- "Fantasy commands may be prefixed with one of the following characters: %s\n"), Config->BSFantasyCharacter.c_str());
+ "Fantasy commands may be prefixed with one of the following characters: %s\n"), fantasycharacters.c_str());
source.Reply(_(" \n"
"Available commands are:"));
}
- else if (source.service->nick == Config->BotServ)
+ else if (*source.service == BotServ)
{
source.Reply(_("\002%s\002 allows you to have a bot on your own channel.\n"
"It has been created for users that can't host or\n"
@@ -228,8 +295,8 @@ class BotServCore : public Module
"below; to use them, type \002%s%s \037command\037\002. For\n"
"more information on a specific command, type\n"
"\002%s%s %s \037command\037\002.\n "),
- Config->BotServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->BotServ.c_str(),
- Config->UseStrictPrivMsgString.c_str(), Config->BotServ.c_str(), source.command.c_str());
+ BotServ->nick.c_str(), Config->StrictPrivmsg.c_str(), BotServ->nick.c_str(),
+ Config->StrictPrivmsg.c_str(), BotServ->nick.c_str(), source.command.c_str());
}
return EVENT_CONTINUE;
@@ -237,21 +304,22 @@ class BotServCore : public Module
void OnPostHelp(CommandSource &source, const std::vector<Anope::string> &params) anope_override
{
- if (!params.empty() || source.c || source.service->nick != Config->BotServ)
+ if (!params.empty() || source.c || source.service != BotServ)
return;
source.Reply(_(" \n"
"Bot will join a channel whenever there is at least\n"
- "\002%d\002 user(s) on it."), Config->BSMinUsers);
- if (!Config->BSFantasyCharacter.empty())
- source.Reply(_("Additionally, all %s commands can be used if fantasy\n"
- "is enabled by prefixing the command name with one of\n"
- "the following characters: %s"), Config->ChanServ.c_str(), Config->BSFantasyCharacter.c_str());
+ "\002%d\002 user(s) on it."), Config->GetModule(this)->Get<unsigned>("minusers"));
+ const Anope::string &fantasycharacters = Config->GetModule(this)->Get<const Anope::string &>("fantasycharacter", "!");
+ if (!fantasycharacters.empty())
+ source.Reply(_("Additionally, if fantasy is enabled fantasy commands\n"
+ "can be executed by prefixing the command name with\n"
+ "one of the following characters: %s"), fantasycharacters.c_str());
}
EventReturn OnChannelModeSet(Channel *c, MessageSource &, const Anope::string &mname, const Anope::string &param) anope_override
{
- if (Config->BSSmartJoin && mname == "BAN" && c->ci && c->ci->bi && c->FindUser(c->ci->bi))
+ if (Config->GetModule(this)->Get<bool>("smartjoin") && mname == "BAN" && c->ci && c->ci->bi && c->FindUser(c->ci->bi))
{
BotInfo *bi = c->ci->bi;
@@ -262,6 +330,26 @@ class BotServCore : public Module
return EVENT_CONTINUE;
}
+
+ void OnCreateChan(ChannelInfo *ci) anope_override
+ {
+ /* Set default bot flags */
+ spacesepstream sep(Config->GetModule(this)->Get<const Anope::string &>("defaults", "greet fantasy"));
+ for (Anope::string token; sep.GetToken(token);)
+ this->ExtendMetadata("BS_" + token);
+ }
+
+ void OnPreUserKicked(MessageSource &source, ChanUserContainer *cu, const Anope::string &kickmsg) anope_override
+ {
+ }
+
+ void OnUserKicked(MessageSource &source, User *target, const Anope::string &channel, ChannelStatus &status, const Anope::string &kickmsg) anope_override
+ {
+ BotInfo *bi = BotInfo::Find(target->nick);
+ if (bi)
+ /* Bots get rejoined */
+ bi->Join(channel, &status);
+ }
};
MODULE_INIT(BotServCore)
diff --git a/modules/pseudoclients/chanserv.cpp b/modules/pseudoclients/chanserv.cpp
index 2c5cffcea..e34cd56e8 100644
--- a/modules/pseudoclients/chanserv.cpp
+++ b/modules/pseudoclients/chanserv.cpp
@@ -16,11 +16,13 @@
class ExpireCallback : public Timer
{
public:
- ExpireCallback(Module *o) : Timer(o, Config->ExpireTimeout, Anope::CurTime, true) { }
+ ExpireCallback(Module *o) : Timer(o, Config->GetBlock("options")->Get<time_t>("expiretimeout"), Anope::CurTime, true) { }
void Tick(time_t) anope_override
{
- if (!Config->CSExpire || Anope::NoExpire || Anope::ReadOnly)
+ time_t chanserv_expire = Config->GetModule("chanserv")->Get<time_t>("expire", "14d");
+
+ if (!chanserv_expire || Anope::NoExpire || Anope::ReadOnly)
return;
for (registered_channel_map::const_iterator it = RegisteredChannelList->begin(), it_end = RegisteredChannelList->end(); it != it_end; )
@@ -30,7 +32,7 @@ class ExpireCallback : public Timer
bool expire = false;
- if (Anope::CurTime - ci->last_used >= Config->CSExpire)
+ if (Anope::CurTime - ci->last_used >= chanserv_expire)
{
if (ci->c)
{
@@ -62,19 +64,81 @@ class ExpireCallback : public Timer
}
};
+class MyChanServService : public ChanServService
+{
+ public:
+ MyChanServService(Module *m) : ChanServService(m) { }
+
+ void Hold(Channel *c) anope_override
+ {
+ /** A timer used to keep the BotServ bot/ChanServ in the channel
+ * after kicking the last user in a channel
+ */
+ class ChanServTimer : public Timer
+ {
+ Reference<Channel> c;
+
+ public:
+ /** Constructor
+ * @param chan The channel
+ */
+ ChanServTimer(Module *m, Channel *chan) : Timer(m, Config->GetModule(this->GetOwner())->Get<time_t>("inhabit", "15s")), c(chan)
+ {
+ if (!ChanServ || !c)
+ return;
+ c->Extend("INHABIT");
+ if (!c->ci || !c->ci->bi)
+ ChanServ->Join(c);
+ else if (!c->FindUser(c->ci->bi))
+ c->ci->bi->Join(c);
+
+ /* Set +ntsi to prevent rejoin */
+ c->SetMode(NULL, "NOEXTERNAL");
+ c->SetMode(NULL, "TOPIC");
+ c->SetMode(NULL, "SECRET");
+ c->SetMode(NULL, "INVITE");
+ }
+
+ /** Called when the delay is up
+ * @param The current time
+ */
+ void Tick(time_t) anope_override
+ {
+ if (!c)
+ return;
+
+ c->Shrink("INHABIT");
+
+ if (!c->ci || !c->ci->bi)
+ {
+ if (ChanServ)
+ ChanServ->Part(c);
+ }
+ else
+ c->ci->bi->Part(c);
+ }
+ };
+
+ if (c->HasExt("INHABIT"))
+ return;
+
+ new ChanServTimer(this->owner, c);
+ }
+};
+
class ChanServCore : public Module
{
+ MyChanServService chanserv;
ExpireCallback expires;
+ std::vector<Anope::string> defaults;
public:
- ChanServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR), expires(this)
+ ChanServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR),
+ chanserv(this), expires(this)
{
-
- ChanServ = BotInfo::Find(Config->ChanServ);
- if (!ChanServ)
- throw ModuleException("No bot named " + Config->ChanServ);
-
- Implementation i[] = { I_OnBotDelete, I_OnBotPrivmsg, I_OnDelCore, I_OnPreHelp, I_OnPostHelp, I_OnCheckModes };
+ Implementation i[] = { I_OnReload, I_OnBotDelete, I_OnBotPrivmsg, I_OnDelCore,
+ I_OnPreHelp, I_OnPostHelp, I_OnCheckModes, I_OnCreateChan, I_OnCanSet,
+ I_OnChannelSync, I_OnBotKick };
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
}
@@ -83,6 +147,31 @@ class ChanServCore : public Module
ChanServ = NULL;
}
+ void OnReload(Configuration::Conf *conf) anope_override
+ {
+ const Anope::string &channick = conf->GetModule(this)->Get<const Anope::string &>("client");
+
+ if (channick.empty())
+ throw ConfigException(this->name + ": <client> must be defined");
+
+ BotInfo *bi = BotInfo::Find(channick, true);
+ if (!bi)
+ throw ConfigException(this->name + ": no bot named " + channick);
+
+ ChanServ = bi;
+
+ spacesepstream(conf->GetModule(this)->Get<const Anope::string &>("defaults", "greet fantasy")).GetTokens(defaults);
+ if (defaults.empty())
+ {
+ defaults.push_back("KEEPTOPIC");
+ defaults.push_back("SECURE");
+ defaults.push_back("SECUREFOUNDER");
+ defaults.push_back("SIGNKICK");
+ }
+ else if (defaults[0].equals_ci("none"))
+ defaults.erase(defaults.begin());
+ }
+
void OnBotDelete(BotInfo *bi) anope_override
{
if (bi == ChanServ)
@@ -91,7 +180,7 @@ class ChanServCore : public Module
EventReturn OnBotPrivmsg(User *u, BotInfo *bi, Anope::string &message) anope_override
{
- if (Config->CSOpersOnly && bi == ChanServ && !u->HasMode("OPER"))
+ if (bi == ChanServ && Config->GetModule(this)->Get<bool>("operonly") && !u->HasMode("OPER"))
{
u->SendMessage(bi, ACCESS_DENIED);
return EVENT_STOP;
@@ -104,6 +193,7 @@ class ChanServCore : public Module
{
std::deque<ChannelInfo *> chans;
nc->GetChannelReferences(chans);
+ int max_reg = Config->GetModule(this)->Get<int>("maxregistered");
for (unsigned i = 0; i < chans.size(); ++i)
{
@@ -112,7 +202,7 @@ class ChanServCore : public Module
if (ci->GetFounder() == nc)
{
NickCore *newowner = NULL;
- if (ci->GetSuccessor() && ci->GetSuccessor() != nc && (ci->GetSuccessor()->IsServicesOper() || !Config->CSMaxReg || ci->GetSuccessor()->channelcount < Config->CSMaxReg))
+ if (ci->GetSuccessor() && ci->GetSuccessor() != nc && (ci->GetSuccessor()->IsServicesOper() || !max_reg || ci->GetSuccessor()->channelcount < max_reg))
newowner = ci->GetSuccessor();
else
{
@@ -122,7 +212,7 @@ class ChanServCore : public Module
const ChanAccess *ca = ci->GetAccess(j);
const NickCore *anc = NickCore::Find(ca->mask);
- if (!anc || (!anc->IsServicesOper() && Config->CSMaxReg && anc->channelcount >= Config->CSMaxReg) || (anc == nc))
+ if (!anc || (!anc->IsServicesOper() && max_reg && anc->channelcount >= max_reg) || (anc == nc))
continue;
if (!highest || *ca > *highest)
highest = ca;
@@ -175,7 +265,7 @@ class ChanServCore : public Module
EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> &params) anope_override
{
- if (!params.empty() || source.c || source.service->nick != Config->ChanServ)
+ if (!params.empty() || source.c || source.service != ChanServ)
return EVENT_CONTINUE;
source.Reply(_("\002%s\002 allows you to register and control various\n"
"aspects of channels. %s can often prevent\n"
@@ -184,19 +274,20 @@ class ChanServCore : public Module
"commands are listed below; to use them, type\n"
"\002%s%s \037command\037\002. For more information on a\n"
"specific command, type \002%s%s HELP \037command\037\002.\n "),
- Config->ChanServ.c_str(), Config->ChanServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->ChanServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->ChanServ.c_str(), Config->ChanServ.c_str(), source.command.c_str());
+ ChanServ->nick.c_str(), ChanServ->nick.c_str(), Config->StrictPrivmsg.c_str(), ChanServ->nick.c_str(), Config->StrictPrivmsg.c_str(), ChanServ->nick.c_str(), ChanServ->nick.c_str(), source.command.c_str());
return EVENT_CONTINUE;
}
void OnPostHelp(CommandSource &source, const std::vector<Anope::string> &params) anope_override
{
- if (!params.empty() || source.c || source.service->nick != Config->ChanServ)
+ if (!params.empty() || source.c || source.service != ChanServ)
return;
- if (Config->CSExpire >= 86400)
+ time_t expire = Config->GetModule(this)->Get<time_t>("expire", "14d");
+ if (expire >= 86400)
source.Reply(_(" \n"
"Note that any channel which is not used for %d days\n"
"(i.e. which no user on the channel's access list enters\n"
- "for that period of time) will be automatically dropped."), Config->CSExpire / 86400);
+ "for that period of time) will be automatically dropped."), expire / 86400);
if (source.IsServicesOper())
source.Reply(_(" \n"
"Services Operators can also, depending on their access drop\n"
@@ -206,12 +297,84 @@ class ChanServCore : public Module
EventReturn OnCheckModes(Channel *c) anope_override
{
- if (!Config->CSRequire.empty())
+ const Anope::string &require = Config->GetModule(this)->Get<const Anope::string &>("require", "r");
+ if (!require.empty())
{
if (c->ci)
- c->SetModes(NULL, false, "+%s", Config->CSRequire.c_str());
+ c->SetModes(NULL, false, "+%s", require.c_str());
else
- c->SetModes(NULL, false, "-%s", Config->CSRequire.c_str());
+ c->SetModes(NULL, false, "-%s", require.c_str());
+ }
+
+ return EVENT_CONTINUE;
+ }
+
+ void OnCreateChan(ChannelInfo *ci) anope_override
+ {
+ ci->bantype = Config->GetModule(this)->Get<int>("defbantype", "2");
+
+ /* Set default chan flags */
+ for (unsigned i = 0; i < defaults.size(); ++i)
+ this->ExtendMetadata(defaults[i]);
+
+ {
+ Anope::string modes;
+ spacesepstream sep(Config->GetModule(this)->Get<const Anope::string &>("mlock", "+nrt"));
+ if (sep.GetToken(modes))
+ {
+ bool add = true;
+ for (unsigned i = 0; i < modes.length(); ++i)
+ {
+ if (modes[i] == '+')
+ add = true;
+ else if (modes[i] == '-')
+ add = false;
+ else
+ {
+ ChannelMode *cm = ModeManager::FindChannelModeByChar(modes[i]);
+ Anope::string param;
+ if (cm && (cm->type == MODE_REGULAR || sep.GetToken(param)))
+ ci->SetMLock(cm, add, param);
+ }
+ }
+ }
+ }
+ }
+
+ EventReturn OnCanSet(User *u, const ChannelMode *cm) anope_override
+ {
+ if (Config->GetModule(this)->Get<const Anope::string &>("nomlock").find(cm->mchar) != Anope::string::npos
+ || Config->GetModule(this)->Get<const Anope::string &>("require", "r").find(cm->mchar) || Anope::string::npos)
+ return EVENT_STOP;
+ return EVENT_CONTINUE;
+ }
+
+ void OnChannelSync(Channel *c) anope_override
+ {
+ if (!c->HasMode("PERM") && (c->users.empty() || (c->users.size() == 1 && c->ci && c->ci->bi && *c->ci->bi == c->users.begin()->second->user)))
+ {
+ chanserv.Hold(c);
+ }
+ if (c->ci)
+ {
+ c->CheckModes();
+
+ if (Me && Me->IsSynced())
+ c->ci->RestoreTopic();
+ }
+ }
+
+ EventReturn OnBotKick(BotInfo *bi, Channel *c, User *u, const Anope::string &reason)
+ {
+ /* If the channel isn't syncing and doesn't have any users, join ChanServ
+ * Note that the user AND POSSIBLY the botserv bot exist here
+ * ChanServ always enforces channels like this to keep people from deleting bots etc
+ * that are holding channels.
+ */
+ if (c->ci && c->users.size() == (c->ci->bi && c->FindUser(c->ci->bi) ? 2 : 1) && !c->HasExt("INHABIT") && !c->HasExt("SYNCING"))
+ {
+ /* Join ChanServ and set a timer for this channel to part ChanServ later */
+ chanserv.Hold(c);
}
return EVENT_CONTINUE;
diff --git a/modules/pseudoclients/chanserv.h b/modules/pseudoclients/chanserv.h
new file mode 100644
index 000000000..e1c3849fd
--- /dev/null
+++ b/modules/pseudoclients/chanserv.h
@@ -0,0 +1,18 @@
+#ifndef CHANSERV_H
+#define CHANSERV_H
+
+class ChanServService : public Service
+{
+ public:
+ ChanServService(Module *m) : Service(m, "ChanServService", "ChanServ")
+ {
+ }
+
+ /* Have ChanServ hold the channel, that is, join and set +nsti and wait
+ * for a few minutes so no one can join or rejoin.
+ */
+ virtual void Hold(Channel *c) = 0;
+};
+
+#endif // CHANSERV_H
+
diff --git a/modules/pseudoclients/global.cpp b/modules/pseudoclients/global.cpp
index 02b199afa..837200e5d 100644
--- a/modules/pseudoclients/global.cpp
+++ b/modules/pseudoclients/global.cpp
@@ -34,29 +34,24 @@ class MyGlobalService : public GlobalService
Anope::string rmessage;
- if (!source.empty() && !Config->AnonymousGlobal)
+ if (!source.empty() && !Config->GetModule("global")->Get<bool>("anonymousglobal"))
rmessage = "[" + source + "] " + message;
else
rmessage = message;
- this->ServerGlobal(sender, Me->GetLinks().front(), rmessage);
+ this->ServerGlobal(sender, Servers::GetUplink(), rmessage);
}
};
class GlobalCore : public Module
{
- MyGlobalService myglobalservice;
+ MyGlobalService global;
public:
GlobalCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR),
- myglobalservice(this)
+ global(this)
{
-
- Global = BotInfo::Find(Config->Global);
- if (!Global)
- throw ModuleException("No bot named " + Config->Global);
-
- Implementation i[] = { I_OnBotDelete, I_OnRestart, I_OnShutdown, I_OnNewServer, I_OnPreHelp };
+ Implementation i[] = { I_OnReload, I_OnBotDelete, I_OnRestart, I_OnShutdown, I_OnNewServer, I_OnPreHelp };
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
}
@@ -65,6 +60,20 @@ class GlobalCore : public Module
Global = NULL;
}
+ void OnReload(Configuration::Conf *conf) anope_override
+ {
+ const Anope::string &glnick = conf->GetModule(this)->Get<const Anope::string &>("client");
+
+ if (glnick.empty())
+ throw ConfigException(this->name + ": <client> must be defined");
+
+ BotInfo *bi = BotInfo::Find(glnick, true);
+ if (!bi)
+ throw ConfigException(this->name + ": no bot named " + glnick);
+
+ Global = bi;
+ }
+
void OnBotDelete(BotInfo *bi) anope_override
{
if (bi == Global)
@@ -73,27 +82,30 @@ class GlobalCore : public Module
void OnRestart() anope_override
{
- if (Config->GlobalOnCycle)
- this->myglobalservice.SendGlobal(Global, "", Config->GlobalOnCycleMessage);
+ const Anope::string &gl = Config->GetModule(this)->Get<const Anope::string &>("globaloncycledown");
+ if (!gl.empty())
+ this->global.SendGlobal(Global, "", gl);
}
void OnShutdown() anope_override
{
- if (Config->GlobalOnCycle)
- this->myglobalservice.SendGlobal(Global, "", Config->GlobalOnCycleMessage);
+ const Anope::string &gl = Config->GetModule(this)->Get<const Anope::string &>("globaloncycledown");
+ if (!gl.empty())
+ this->global.SendGlobal(Global, "", gl);
}
void OnNewServer(Server *s) anope_override
{
- if (Config->GlobalOnCycle && !Config->GlobalOnCycleUP.empty())
- s->Notice(Global, Config->GlobalOnCycleUP);
+ const Anope::string &gl = Config->GetModule(this)->Get<const Anope::string &>("globaloncycleup");
+ if (!gl.empty() && !Me->IsSynced())
+ s->Notice(Global, gl);
}
EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> &params) anope_override
{
- if (!params.empty() || source.c || source.service->nick != Config->Global)
+ if (!params.empty() || source.c || source.service != Global)
return EVENT_CONTINUE;
- source.Reply(_("%s commands:"), Config->Global.c_str());
+ source.Reply(_("%s commands:"), Global->nick.c_str());
return EVENT_CONTINUE;
}
};
diff --git a/modules/pseudoclients/global.h b/modules/pseudoclients/global.h
index fccd96558..52afc4a23 100644
--- a/modules/pseudoclients/global.h
+++ b/modules/pseudoclients/global.h
@@ -4,7 +4,9 @@
class GlobalService : public Service
{
public:
- GlobalService(Module *m) : Service(m, "GlobalService", "Global") { }
+ GlobalService(Module *m) : Service(m, "GlobalService", "Global")
+ {
+ }
/** Send out a global message to all users
* @param sender Our client which should send the global
diff --git a/modules/pseudoclients/hostserv.cpp b/modules/pseudoclients/hostserv.cpp
index d8cd74d69..acca6f7ff 100644
--- a/modules/pseudoclients/hostserv.cpp
+++ b/modules/pseudoclients/hostserv.cpp
@@ -22,11 +22,7 @@ class HostServCore : public Module
if (!IRCD || !IRCD->CanSetVHost)
throw ModuleException("Your IRCd does not support vhosts");
- HostServ = BotInfo::Find(Config->HostServ);
- if (!HostServ)
- throw ModuleException("No bot named " + Config->HostServ);
-
- Implementation i[] = { I_OnBotDelete, I_OnNickIdentify, I_OnNickUpdate, I_OnPreHelp };
+ Implementation i[] = { I_OnReload, I_OnBotDelete, I_OnNickIdentify, I_OnNickUpdate, I_OnPreHelp };
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
}
@@ -35,6 +31,20 @@ class HostServCore : public Module
HostServ = NULL;
}
+ void OnReload(Configuration::Conf *conf) anope_override
+ {
+ const Anope::string &hsnick = conf->GetModule(this)->Get<const Anope::string &>("client");
+
+ if (hsnick.empty())
+ throw ConfigException(this->name + ": <client> must be defined");
+
+ BotInfo *bi = BotInfo::Find(hsnick, true);
+ if (!bi)
+ throw ConfigException(this->name + ": no bot named " + hsnick);
+
+ HostServ = bi;
+ }
+
void OnBotDelete(BotInfo *bi) anope_override
{
if (bi == HostServ)
@@ -76,9 +86,9 @@ class HostServCore : public Module
EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> &params) anope_override
{
- if (!params.empty() || source.c || source.service->nick != Config->HostServ)
+ if (!params.empty() || source.c || source.service != HostServ)
return EVENT_CONTINUE;
- source.Reply(_("%s commands:"), Config->HostServ.c_str());
+ source.Reply(_("%s commands:"), HostServ->nick.c_str());
return EVENT_CONTINUE;
}
};
diff --git a/modules/pseudoclients/memoserv.cpp b/modules/pseudoclients/memoserv.cpp
index 5eca5cd4e..46ad82194 100644
--- a/modules/pseudoclients/memoserv.cpp
+++ b/modules/pseudoclients/memoserv.cpp
@@ -16,20 +16,20 @@
static bool SendMemoMail(NickCore *nc, MemoInfo *mi, Memo *m)
{
- Anope::string subject = Language::Translate(nc, Config->MailMemoSubject.c_str());
- Anope::string message = Language::Translate(nc, Config->MailMemoMessage.c_str());
+ Anope::string subject = Language::Translate(nc, Config->GetBlock("mail")->Get<const char *>("memo_subject")),
+ message = Language::Translate(Config->GetBlock("mail")->Get<const char *>("memo_message"));
subject = subject.replace_all_cs("%n", nc->display);
subject = subject.replace_all_cs("%s", m->sender);
subject = subject.replace_all_cs("%d", stringify(mi->GetIndex(m) + 1));
subject = subject.replace_all_cs("%t", m->text);
- subject = subject.replace_all_cs("%N", Config->NetworkName);
+ subject = subject.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string &>("networkname"));
message = message.replace_all_cs("%n", nc->display);
message = message.replace_all_cs("%s", m->sender);
message = message.replace_all_cs("%d", stringify(mi->GetIndex(m) + 1));
message = message.replace_all_cs("%t", m->text);
- message = message.replace_all_cs("%N", Config->NetworkName);
+ message = message.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string &>("networkname"));
return Mail::Send(nc, subject, message);
}
@@ -50,7 +50,8 @@ class MyMemoServService : public MemoServService
User *sender = User::Find(source);
if (sender != NULL && !sender->HasPriv("memoserv/no-limit") && !force)
{
- if (Config->MSSendDelay > 0 && sender->lastmemosend + Config->MSSendDelay > Anope::CurTime)
+ time_t send_delay = Config->GetModule("memoserv")->Get<time_t>("senddelay");
+ if (send_delay > 0 && sender->lastmemosend + send_delay > Anope::CurTime)
return MEMO_TOO_FAST;
else if (!mi->memomax)
return MEMO_TARGET_FULL;
@@ -86,7 +87,7 @@ class MyMemoServService : public MemoServService
if (ci->AccessFor(cu->user).HasPriv("MEMO"))
{
if (cu->user->Account() && cu->user->Account()->HasExt("MEMO_RECEIVE"))
- cu->user->SendMessage(MemoServ, MEMO_NEW_X_MEMO_ARRIVED, ci->name.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->MemoServ.c_str(), ci->name.c_str(), mi->memos->size());
+ cu->user->SendMessage(MemoServ, MEMO_NEW_X_MEMO_ARRIVED, ci->name.c_str(), Config->StrictPrivmsg.c_str(), MemoServ->nick.c_str(), ci->name.c_str(), mi->memos->size());
}
}
}
@@ -102,7 +103,7 @@ class MyMemoServService : public MemoServService
const NickAlias *na = nc->aliases->at(i);
User *user = User::Find(na->nick);
if (user && user->IsIdentified())
- user->SendMessage(MemoServ, MEMO_NEW_MEMO_ARRIVED, source.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->MemoServ.c_str(), mi->memos->size());
+ user->SendMessage(MemoServ, MEMO_NEW_MEMO_ARRIVED, source.c_str(), Config->StrictPrivmsg.c_str(), MemoServ->nick.c_str(), mi->memos->size());
}
}
@@ -138,17 +139,12 @@ class MyMemoServService : public MemoServService
class MemoServCore : public Module
{
- MyMemoServService mymemoserv;
+ MyMemoServService memoserv;
public:
MemoServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR),
- mymemoserv(this)
+ memoserv(this)
{
-
- MemoServ = BotInfo::Find(Config->MemoServ);
- if (!MemoServ)
- throw ModuleException("No bot named " + Config->MemoServ);
-
- Implementation i[] = { I_OnBotDelete, I_OnNickIdentify, I_OnJoinChannel, I_OnUserAway, I_OnNickUpdate, I_OnPreHelp, I_OnPostHelp };
+ Implementation i[] = { I_OnNickCoreCreate, I_OnCreateChan, I_OnReload, I_OnBotDelete, I_OnNickIdentify, I_OnJoinChannel, I_OnUserAway, I_OnNickUpdate, I_OnPreHelp, I_OnPostHelp };
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
}
@@ -157,6 +153,30 @@ class MemoServCore : public Module
MemoServ = NULL;
}
+ void OnReload(Configuration::Conf *conf) anope_override
+ {
+ const Anope::string &msnick = conf->GetModule(this)->Get<const Anope::string &>("client");
+
+ if (msnick.empty())
+ throw ConfigException(this->name + ": <client> must be defined");
+
+ BotInfo *bi = BotInfo::Find(msnick, true);
+ if (!bi)
+ throw ConfigException(this->name + ": no bot named " + msnick);
+
+ MemoServ = bi;
+ }
+
+ void OnNickCoreCreate(NickCore *nc) anope_override
+ {
+ nc->memos.memomax = Config->GetModule(this)->Get<int>("maxmemos");
+ }
+
+ void OnCreateChan(ChannelInfo *ci) anope_override
+ {
+ ci->memos.memomax = Config->GetModule(this)->Get<int>("maxmemos");
+ }
+
void OnBotDelete(BotInfo *bi) anope_override
{
if (bi == MemoServ)
@@ -165,7 +185,7 @@ class MemoServCore : public Module
void OnNickIdentify(User *u) anope_override
{
- this->mymemoserv.Check(u);
+ this->memoserv.Check(u);
}
void OnJoinChannel(User *u, Channel *c) anope_override
@@ -182,37 +202,37 @@ class MemoServCore : public Module
void OnUserAway(User *u, const Anope::string &message) anope_override
{
if (message.empty())
- this->mymemoserv.Check(u);
+ this->memoserv.Check(u);
}
void OnNickUpdate(User *u) anope_override
{
- this->mymemoserv.Check(u);
+ this->memoserv.Check(u);
}
EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> &params) anope_override
{
- if (!params.empty() || source.c || source.service->nick != Config->MemoServ)
+ if (!params.empty() || source.c || source.service != MemoServ)
return EVENT_CONTINUE;
source.Reply(_("\002%s\002 is a utility allowing IRC users to send short\n"
"messages to other IRC users, whether they are online at\n"
"the time or not, or to channels(*). Both the sender's\n"
"nickname and the target nickname or channel must be\n"
"registered in order to send a memo.\n"
- "%s's commands include:"), Config->MemoServ.c_str(), Config->MemoServ.c_str());
+ "%s's commands include:"), MemoServ->nick.c_str(), MemoServ->nick.c_str());
return EVENT_CONTINUE;
}
void OnPostHelp(CommandSource &source, const std::vector<Anope::string> &params) anope_override
{
- if (!params.empty() || source.c || source.service->nick != Config->MemoServ)
+ if (!params.empty() || source.c || source.service != MemoServ)
return;
source.Reply(_(" \n"
"Type \002%s%s HELP \037command\037\002 for help on any of the\n"
"above commands.\n"
"(*) By default, any user with at least level 10 access on a\n"
" channel can read that channel's memos. This can be\n"
- " changed with the %s \002LEVELS\002 command."), Config->UseStrictPrivMsgString.c_str(), Config->MemoServ.c_str(), Config->ChanServ.c_str());
+ " changed with the %s \002LEVELS\002 command."), Config->StrictPrivmsg.c_str(), MemoServ->nick.c_str(), ChanServ->nick.c_str());
}
};
diff --git a/modules/pseudoclients/memoserv.h b/modules/pseudoclients/memoserv.h
index 71ca064de..d35d3f8a0 100644
--- a/modules/pseudoclients/memoserv.h
+++ b/modules/pseudoclients/memoserv.h
@@ -12,7 +12,9 @@ class MemoServService : public Service
MEMO_TARGET_FULL
};
- MemoServService(Module *m) : Service(m, "MemoServService", "MemoServ") { }
+ MemoServService(Module *m) : Service(m, "MemoServService", "MemoServ")
+ {
+ }
/** Sends a memo.
* @param source The source of the memo, can be anythin.
diff --git a/modules/pseudoclients/nickserv.cpp b/modules/pseudoclients/nickserv.cpp
index cde1fbbf7..3f4250fb6 100644
--- a/modules/pseudoclients/nickserv.cpp
+++ b/modules/pseudoclients/nickserv.cpp
@@ -18,6 +18,7 @@ class NickServCollide;
typedef std::map<Anope::string, NickServCollide *> nickservcollides_map;
+static ServiceReference<NickServService> nickserv("NickServService", "NickServ");
static nickservcollides_map NickServCollides;
/** Timer for colliding nicks to force people off of nicknames
@@ -98,15 +99,15 @@ class MyNickServService : public NickServService
return;
}
- if (Config->NoNicknameOwnership)
+ if (Config->GetBlock("options")->Get<bool>("nonicknameownership"))
return;
if (u->IsRecognized(false) || !na->nc->HasExt("KILL_IMMED"))
{
if (na->nc->HasExt("SECURE"))
- u->SendMessage(NickServ, NICK_IS_SECURE, Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str());
+ u->SendMessage(NickServ, NICK_IS_SECURE, Config->StrictPrivmsg.c_str(), NickServ->nick.c_str());
else
- u->SendMessage(NickServ, NICK_IS_REGISTERED, Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str());
+ u->SendMessage(NickServ, NICK_IS_REGISTERED, Config->StrictPrivmsg.c_str(), NickServ->nick.c_str());
}
if (na->nc->HasExt("KILLPROTECT") && !u->IsRecognized(false))
@@ -118,13 +119,15 @@ class MyNickServService : public NickServService
}
else if (na->nc->HasExt("KILL_QUICK"))
{
- u->SendMessage(NickServ, _("If you do not change within %s, I will change your nick."), Anope::Duration(Config->NSKillQuick, u->Account()).c_str());
- new NickServCollide(u, Config->NSKillQuick);
+ time_t killquick = Config->GetModule("nickserv")->Get<time_t>("killquick", "60s");
+ u->SendMessage(NickServ, _("If you do not change within %s, I will change your nick."), Anope::Duration(killquick, u->Account()).c_str());
+ new NickServCollide(u, killquick);
}
else
{
- u->SendMessage(NickServ, _("If you do not change within %s, I will change your nick."), Anope::Duration(Config->NSKill, u->Account()).c_str());
- new NickServCollide(u, Config->NSKill);
+ time_t kill = Config->GetModule("nickserv")->Get<time_t>("kill", "20s");
+ u->SendMessage(NickServ, _("If you do not change within %s, I will change your nick."), Anope::Duration(kill, u->Account()).c_str());
+ new NickServCollide(u, kill);
}
}
@@ -134,7 +137,7 @@ class MyNickServService : public NickServService
{
const NickAlias *u_na = NickAlias::Find(user->nick);
user->Login(na->nc);
- if (u_na && *u_na->nc == *na->nc && !Config->NoNicknameOwnership && na->nc->HasExt("UNCONFIRMED") == false)
+ if (u_na && *u_na->nc == *na->nc && !Config->GetBlock("options")->Get<bool>("nonicknameownership") && na->nc->HasExt("UNCONFIRMED") == false)
user->SetMode(NickServ, "REGISTERED");
}
};
@@ -142,13 +145,16 @@ class MyNickServService : public NickServService
class ExpireCallback : public Timer
{
public:
- ExpireCallback(Module *o) : Timer(o, Config->ExpireTimeout, Anope::CurTime, true) { }
+ ExpireCallback(Module *o) : Timer(o, Config->GetBlock("options")->Get<time_t>("expiretimeout"), Anope::CurTime, true) { }
void Tick(time_t) anope_override
{
if (Anope::NoExpire || Anope::ReadOnly)
return;
+ time_t unconfirmed_expire = Config->GetModule(this->GetOwner())->Get<time_t>("unconfirmedexpire", "1d");
+ time_t nickserv_expire = Config->GetModule(this->GetOwner())->Get<time_t>("expire");
+
for (nickalias_map::const_iterator it = NickAliasList->begin(), it_end = NickAliasList->end(); it != it_end; )
{
NickAlias *na = it->second;
@@ -161,9 +167,9 @@ class ExpireCallback : public Timer
bool expire = false;
if (na->nc->HasExt("UNCONFIRMED"))
- if (Config->NSUnconfirmedExpire && Anope::CurTime - na->time_registered >= Config->NSUnconfirmedExpire)
+ if (unconfirmed_expire && Anope::CurTime - na->time_registered >= unconfirmed_expire)
expire = true;
- if (Config->NSExpire && Anope::CurTime - na->last_seen >= Config->NSExpire)
+ if (nickserv_expire && Anope::CurTime - na->last_seen >= nickserv_expire)
expire = true;
if (na->HasExt("NO_EXPIRE"))
expire = false;
@@ -185,19 +191,16 @@ class ExpireCallback : public Timer
class NickServCore : public Module
{
- MyNickServService mynickserv;
+ MyNickServService nickserv;
ExpireCallback expires;
+ std::vector<Anope::string> defaults;
public:
- NickServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR), mynickserv(this), expires(this)
+ NickServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR), nickserv(this), expires(this)
{
-
- NickServ = BotInfo::Find(Config->NickServ);
- if (!NickServ)
- throw ModuleException("No bot named " + Config->NickServ);
-
- Implementation i[] = { I_OnBotDelete, I_OnDelNick, I_OnDelCore, I_OnChangeCoreDisplay, I_OnNickIdentify, I_OnNickGroup,
- I_OnNickUpdate, I_OnUserConnect, I_OnPostUserLogoff, I_OnServerSync, I_OnUserNickChange, I_OnPreHelp, I_OnPostHelp };
+ Implementation i[] = { I_OnReload, I_OnBotDelete, I_OnDelNick, I_OnDelCore, I_OnChangeCoreDisplay, I_OnNickIdentify, I_OnNickGroup,
+ I_OnNickUpdate, I_OnUserConnect, I_OnPostUserLogoff, I_OnServerSync, I_OnUserNickChange, I_OnPreHelp, I_OnPostHelp,
+ I_OnNickCoreCreate, I_OnUserQuit };
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
}
@@ -206,6 +209,28 @@ class NickServCore : public Module
NickServ = NULL;
}
+ void OnReload(Configuration::Conf *conf) anope_override
+ {
+ const Anope::string &nsnick = conf->GetModule(this)->Get<const Anope::string &>("client");
+
+ if (nsnick.empty())
+ throw ConfigException(this->name + ": <client> must be defined");
+
+ BotInfo *bi = BotInfo::Find(nsnick, true);
+ if (!bi)
+ throw ConfigException(this->name + ": no bot named " + nsnick);
+
+ NickServ = bi;
+
+ spacesepstream(conf->GetModule(this)->Get<const Anope::string &>("defaults", "secure memo_signon memo_receive")).GetTokens(defaults);
+ if (defaults.empty())
+ {
+ defaults.push_back("SECURE");
+ defaults.push_back("MEMO_SIGNON");
+ defaults.push_back("MEMO_RECEIVE");
+ }
+ }
+
void OnBotDelete(BotInfo *bi) anope_override
{
if (bi == NickServ)
@@ -246,14 +271,16 @@ class NickServCore : public Module
void OnNickIdentify(User *u) anope_override
{
- if (!Config->NoNicknameOwnership)
+ Configuration::Block *block = Config->GetModule(this);
+
+ if (!Config->GetBlock("options")->Get<bool>("nonicknameownership"))
{
const NickAlias *this_na = NickAlias::Find(u->nick);
if (this_na && this_na->nc == u->Account() && u->Account()->HasExt("UNCONFIRMED") == false)
u->SetMode(NickServ, "REGISTERED");
}
- if (Config->NSModeOnID)
+ if (block->Get<bool>("modeonid", "yes"))
for (User::ChanUserList::iterator it = u->chans.begin(), it_end = u->chans.end(); it != it_end; ++it)
{
ChanUserContainer *cc = it->second;
@@ -262,17 +289,18 @@ class NickServCore : public Module
c->SetCorrectModes(u, true, true);
}
- if (!Config->NSModesOnID.empty())
- u->SetModes(NickServ, "%s", Config->NSModesOnID.c_str());
+ const Anope::string &modesonid = block->Get<const Anope::string &>("modesonid");
+ if (!modesonid.empty())
+ u->SetModes(NickServ, "%s", modesonid.c_str());
- if (Config->NSForceEmail && u->Account()->email.empty())
+ if (block->Get<bool>("forceemail") && u->Account()->email.empty())
{
u->SendMessage(NickServ, _("You must now supply an e-mail for your nick.\n"
"This e-mail will allow you to retrieve your password in\n"
"case you forget it."));
u->SendMessage(NickServ, _("Type \002%s%s SET EMAIL \037e-mail\037\002 in order to set your e-mail.\n"
"Your privacy is respected; this e-mail won't be given to\n"
- "any third-party person."), Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str());
+ "any third-party person."), Config->StrictPrivmsg.c_str(), NickServ->nick.c_str());
}
if (u->Account()->HasExt("UNCONFIRMED"))
@@ -280,8 +308,9 @@ class NickServCore : public Module
u->SendMessage(NickServ, _("Your email address is not confirmed. To confirm it, follow the instructions that were emailed to you when you registered."));
const NickAlias *this_na = NickAlias::Find(u->Account()->display);
time_t time_registered = Anope::CurTime - this_na->time_registered;
- if (Config->NSUnconfirmedExpire > time_registered)
- u->SendMessage(NickServ, _("Your account will expire, if not confirmed, in %s"), Anope::Duration(Config->NSUnconfirmedExpire - time_registered).c_str());
+ time_t unconfirmed_expire = Config->GetModule(this)->Get<time_t>("unconfirmedexpire", "1d");
+ if (unconfirmed_expire > time_registered)
+ u->SendMessage(NickServ, _("Your account will expire, if not confirmed, in %s"), Anope::Duration(unconfirmed_expire - time_registered).c_str());
}
}
@@ -308,10 +337,11 @@ class NickServCore : public Module
return;
const NickAlias *na = NickAlias::Find(u->nick);
- if (!Config->NoNicknameOwnership && !Config->NSUnregisteredNotice.empty() && !na)
- u->SendMessage(NickServ, Config->NSUnregisteredNotice);
+ const Anope::string &unregistered_notice = Config->GetModule(this)->Get<const Anope::string &>("unregistered_notice");
+ if (!Config->GetBlock("options")->Get<bool>("nonicknameownership") && !unregistered_notice.empty() && !na)
+ u->SendMessage(NickServ, unregistered_notice);
else if (na)
- this->mynickserv.Validate(u);
+ this->nickserv.Validate(u);
}
void OnPostUserLogoff(User *u) anope_override
@@ -327,7 +357,7 @@ class NickServCore : public Module
{
User *u = it->second;
if (u->server == s && !u->IsIdentified())
- this->mynickserv.Validate(u);
+ this->nickserv.Validate(u);
}
}
@@ -340,13 +370,13 @@ class NickServCore : public Module
/* Remove +r, but keep an account associated with the user */
u->RemoveMode(NickServ, "REGISTERED");
- this->mynickserv.Validate(u);
+ this->nickserv.Validate(u);
}
else
{
/* Reset +r and re-send account (even though it really should be set at this point) */
IRCD->SendLogin(u);
- if (!Config->NoNicknameOwnership && na->nc == u->Account() && na->nc->HasExt("UNCONFIRMED") == false)
+ if (!Config->GetBlock("options")->Get<bool>("nonicknameownership") && na->nc == u->Account() && na->nc->HasExt("UNCONFIRMED") == false)
u->SetMode(NickServ, "REGISTERED");
Log(NickServ) << u->GetMask() << " automatically identified for group " << u->Account()->display;
}
@@ -363,45 +393,67 @@ class NickServCore : public Module
EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> &params) anope_override
{
- if (!params.empty() || source.c || source.service->nick != Config->NickServ)
+ if (!params.empty() || source.c || source.service != NickServ)
return EVENT_CONTINUE;
- if (!Config->NoNicknameOwnership)
+ if (!Config->GetBlock("options")->Get<bool>("nonicknameownership"))
source.Reply(_("\002%s\002 allows you to register a nickname and\n"
"prevent others from using it. The following\n"
"commands allow for registration and maintenance of\n"
"nicknames; to use them, type \002%s%s \037command\037\002.\n"
"For more information on a specific command, type\n"
- "\002%s%s %s \037command\037\002.\n "), Config->NickServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str(), source.command.c_str());
+ "\002%s%s %s \037command\037\002.\n "), NickServ->nick.c_str(), Config->StrictPrivmsg.c_str(), NickServ->nick.c_str(), Config->StrictPrivmsg.c_str(), NickServ->nick.c_str(), source.command.c_str());
else
source.Reply(_("\002%s\002 allows you to register an account.\n"
"The following commands allow for registration and maintenance of\n"
"accounts; to use them, type \002%s%s \037command\037\002.\n"
"For more information on a specific command, type\n"
- "\002%s%s %s \037command\037\002.\n "), Config->NickServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str(), source.command.c_str());
+ "\002%s%s %s \037command\037\002.\n "), NickServ->nick.c_str(), Config->StrictPrivmsg.c_str(), NickServ->nick.c_str(), Config->StrictPrivmsg.c_str(), NickServ->nick.c_str(), source.command.c_str());
return EVENT_CONTINUE;
}
void OnPostHelp(CommandSource &source, const std::vector<Anope::string> &params) anope_override
{
- if (!params.empty() || source.c || source.service->nick != Config->NickServ)
+ if (!params.empty() || source.c || source.service != NickServ)
return;
if (source.IsServicesOper())
source.Reply(_(" \n"
"Services Operators can also drop any nickname without needing\n"
"to identify for the nick, and may view the access list for\n"
"any nickname."));
- if (Config->NSExpire >= 86400)
+ time_t nickserv_expire = Config->GetModule(this)->Get<time_t>("expire");
+ if (nickserv_expire >= 86400)
source.Reply(_(" \n"
"Accounts that are not used anymore are subject to \n"
"the automatic expiration, i.e. they will be deleted\n"
- "after %d days if not used."), Config->NSExpire / 86400);
+ "after %d days if not used."), nickserv_expire / 86400);
source.Reply(_(" \n"
"\002NOTICE:\002 This service is intended to provide a way for\n"
"IRC users to ensure their identity is not compromised.\n"
"It is \002NOT\002 intended to facilitate \"stealing\" of\n"
"nicknames or other malicious actions. Abuse of %s\n"
"will result in, at minimum, loss of the abused\n"
- "nickname(s)."), Config->NickServ.c_str());
+ "nickname(s)."), NickServ->nick.c_str());
+ }
+
+ void OnNickCoreCreate(NickCore *nc)
+ {
+ /* Set default flags */
+ for (unsigned i = 0; i < defaults.size(); ++i)
+ this->ExtendMetadata(defaults[i].upper());
+ }
+
+ void OnUserQuit(User *u, const Anope::string &msg)
+ {
+ if (u->server && !u->server->GetQuitReason().empty() && Config->GetModule(this)->Get<bool>("hidenetsplitquit"))
+ return;
+
+ /* Update last quit and last seen for the user */
+ NickAlias *na = NickAlias::Find(u->nick);
+ if (na && !na->nc->HasExt("SUSPENDED") && (u->IsRecognized() || u->IsIdentified(true)))
+ {
+ na->last_seen = Anope::CurTime;
+ na->last_quit = msg;
+ }
}
};
diff --git a/modules/pseudoclients/nickserv.h b/modules/pseudoclients/nickserv.h
index 63923de2b..b20d6ebd1 100644
--- a/modules/pseudoclients/nickserv.h
+++ b/modules/pseudoclients/nickserv.h
@@ -4,7 +4,9 @@
class NickServService : public Service
{
public:
- NickServService(Module *m) : Service(m, "NickServService", "NickServ") { }
+ NickServService(Module *m) : Service(m, "NickServService", "NickServ")
+ {
+ }
virtual void Validate(User *u) = 0;
virtual void Login(User *u, NickAlias *na) = 0;
diff --git a/modules/pseudoclients/operserv.cpp b/modules/pseudoclients/operserv.cpp
index ab67ceb47..a3a384cea 100644
--- a/modules/pseudoclients/operserv.cpp
+++ b/modules/pseudoclients/operserv.cpp
@@ -161,12 +161,7 @@ class OperServCore : public Module
OperServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR),
sglines(this), sqlines(this), snlines(this)
{
-
- OperServ = BotInfo::Find(Config->OperServ);
- if (!OperServ)
- throw ModuleException("No bot named " + Config->OperServ);
-
- Implementation i[] = { I_OnBotDelete, I_OnBotPrivmsg, I_OnServerQuit, I_OnUserModeSet, I_OnUserModeUnset, I_OnUserConnect, I_OnUserNickChange, I_OnPreHelp };
+ Implementation i[] = { I_OnReload, I_OnBotDelete, I_OnBotPrivmsg, I_OnServerQuit, I_OnUserModeSet, I_OnUserModeUnset, I_OnUserConnect, I_OnUserNickChange, I_OnPreHelp };
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
/* Yes, these are in this order for a reason. Most violent->least violent. */
@@ -188,6 +183,20 @@ class OperServCore : public Module
XLineManager::UnregisterXLineManager(&snlines);
}
+ void OnReload(Configuration::Conf *conf) anope_override
+ {
+ const Anope::string &osnick = conf->GetModule(this)->Get<const Anope::string &>("client");
+
+ if (osnick.empty())
+ throw ConfigException(this->name + ": <client> must be defined");
+
+ BotInfo *bi = BotInfo::Find(osnick, true);
+ if (!bi)
+ throw ConfigException(this->name + ": no bot named " + osnick);
+
+ OperServ = bi;
+ }
+
void OnBotDelete(BotInfo *bi) anope_override
{
if (bi == OperServ)
@@ -196,10 +205,10 @@ class OperServCore : public Module
EventReturn OnBotPrivmsg(User *u, BotInfo *bi, Anope::string &message) anope_override
{
- if (Config->OSOpersOnly && !u->HasMode("OPER") && bi->nick == Config->OperServ)
+ if (bi == OperServ && !u->HasMode("OPER") && Config->GetModule(this)->Get<bool>("opersonly"))
{
u->SendMessage(bi, ACCESS_DENIED);
- Log(OperServ, "bados") << "Denied access to " << Config->OperServ << " from " << u->GetMask() << " (non-oper)";
+ Log(OperServ, "bados") << "Denied access to " << bi->nick << " from " << u->GetMask() << " (non-oper)";
return EVENT_STOP;
}
@@ -243,9 +252,9 @@ class OperServCore : public Module
EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> &params) anope_override
{
- if (!params.empty() || source.c || source.service->nick != Config->OperServ)
+ if (!params.empty() || source.c || source.service != OperServ)
return EVENT_CONTINUE;
- source.Reply(_("%s commands:"), Config->OperServ.c_str());
+ source.Reply(_("%s commands:"), OperServ->nick.c_str());
return EVENT_CONTINUE;
}
};
diff --git a/src/bots.cpp b/src/bots.cpp
index f1a96eacf..fcbedeeb3 100644
--- a/src/bots.cpp
+++ b/src/bots.cpp
@@ -23,7 +23,7 @@ Serialize::Checker<botinfo_map> BotListByNick("BotInfo"), BotListByUID("BotInfo"
BotInfo *BotServ = NULL, *ChanServ = NULL, *Global = NULL, *HostServ = NULL, *MemoServ = NULL, *NickServ = NULL, *OperServ = NULL;
-BotInfo::BotInfo(const Anope::string &nnick, const Anope::string &nuser, const Anope::string &nhost, const Anope::string &nreal, const Anope::string &bmodes) : User(nnick, nuser, nhost, "", "", Me, nreal, Anope::CurTime, "", Servers::TS6_UID_Retrieve()), Serializable("BotInfo"), botmodes(bmodes)
+BotInfo::BotInfo(const Anope::string &nnick, const Anope::string &nuser, const Anope::string &nhost, const Anope::string &nreal, const Anope::string &bmodes) : User(nnick, nuser, nhost, "", "", Me, nreal, Anope::CurTime, "", Servers::TS6_UID_Retrieve()), Serializable("BotInfo"), channels("ChannelInfo"), botmodes(bmodes)
{
this->lastmsg = this->created = Anope::CurTime;
this->introduced = false;
@@ -58,15 +58,10 @@ BotInfo::~BotInfo()
IRCD->SendSQLineDel(&x);
}
- for (registered_channel_map::const_iterator it = RegisteredChannelList->begin(), it_end = RegisteredChannelList->end(); it != it_end; ++it)
+ for (std::set<ChannelInfo *>::iterator it = this->channels->begin(), it_end = this->channels->end(); it != it_end; ++it)
{
- ChannelInfo *ci = it->second;
-
- if (ci->bi == this)
- {
- ci->QueueUpdate();
- ci->bi = NULL;
- }
+ ChannelInfo *ci = *it;
+ this->UnAssign(NULL, ci);
}
BotListByNick->erase(this->nick);
@@ -129,21 +124,15 @@ void BotInfo::SetNewNick(const Anope::string &newnick)
(*BotListByNick)[this->nick] = this;
}
-void BotInfo::RejoinAll()
+const std::set<ChannelInfo *> &BotInfo::GetChannels() const
{
- for (registered_channel_map::const_iterator it = RegisteredChannelList->begin(), it_end = RegisteredChannelList->end(); it != it_end; ++it)
- {
- const ChannelInfo *ci = it->second;
-
- if (ci->bi == this && ci->c && ci->c->users.size() >= Config->BSMinUsers)
- this->Join(ci->c);
- }
+ return this->channels;
}
void BotInfo::Assign(User *u, ChannelInfo *ci)
{
EventReturn MOD_RESULT = EVENT_CONTINUE;
- FOREACH_RESULT(I_OnBotAssign, OnBotAssign(u, ci, this));
+ FOREACH_RESULT(I_OnPreBotAssign, OnPreBotAssign(u, ci, this));
if (MOD_RESULT == EVENT_STOP)
return;
@@ -151,8 +140,10 @@ void BotInfo::Assign(User *u, ChannelInfo *ci)
ci->bi->UnAssign(u, ci);
ci->bi = this;
- if (Me->IsSynced() && ci->c && ci->c->users.size() >= Config->BSMinUsers)
- this->Join(ci->c, &ModeManager::DefaultBotModes);
+ this->channels->insert(ci);
+
+ ChannelStatus status;
+ FOREACH_MOD(I_OnBotAssign, OnBotAssign(u, ci, this));
}
void BotInfo::UnAssign(User *u, ChannelInfo *ci)
@@ -171,19 +162,12 @@ void BotInfo::UnAssign(User *u, ChannelInfo *ci)
}
ci->bi = NULL;
+ this->channels->erase(ci);
}
unsigned BotInfo::GetChannelCount() const
{
- unsigned count = 0;
- for (registered_channel_map::const_iterator it = RegisteredChannelList->begin(), it_end = RegisteredChannelList->end(); it != it_end; ++it)
- {
- const ChannelInfo *ci = it->second;
-
- if (ci->bi == this)
- ++count;
- }
- return count;
+ return this->channels->size();
}
void BotInfo::Join(Channel *c, ChannelStatus *status)
@@ -191,35 +175,9 @@ void BotInfo::Join(Channel *c, ChannelStatus *status)
if (c->FindUser(this) != NULL)
return;
- if (Config && IRCD && Config->BSSmartJoin)
- {
- std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> bans = c->GetModeList("BAN");
-
- /* We check for bans */
- for (; bans.first != bans.second; ++bans.first)
- {
- Entry ban("BAN", bans.first->second);
- if (ban.Matches(this))
- c->RemoveMode(NULL, "BAN", ban.GetMask());
- }
-
- Anope::string Limit;
- unsigned limit = 0;
- if (c->GetParam("LIMIT", Limit) && Limit.is_pos_number_only())
- limit = convertTo<unsigned>(Limit);
-
- /* Should we be invited? */
- if (c->HasMode("INVITE") || (limit && c->users.size() >= limit))
- IRCD->SendNotice(this, "@" + c->name, "%s invited %s into the channel.", this->nick.c_str(), this->nick.c_str());
-
- ModeManager::ProcessModes();
- }
-
c->JoinUser(this);
if (IRCD)
IRCD->SendJoin(this, c, status);
-
- FOREACH_MOD(I_OnBotJoin, OnBotJoin(c, this));
}
void BotInfo::Join(const Anope::string &chname, ChannelStatus *status)
diff --git a/src/channels.cpp b/src/channels.cpp
index 4d08661ef..5001869da 100644
--- a/src/channels.cpp
+++ b/src/channels.cpp
@@ -89,17 +89,7 @@ void Channel::Reset()
void Channel::Sync()
{
- if (!this->HasMode("PERM") && (this->users.empty() || (this->users.size() == 1 && this->ci && this->ci->bi && *this->ci->bi == this->users.begin()->second->user)))
- {
- this->Hold();
- }
- if (this->ci)
- {
- this->CheckModes();
-
- if (Me && Me->IsSynced())
- this->ci->RestoreTopic();
- }
+ FOREACH_MOD(I_OnChannelSync, OnChannelSync(this));
}
void Channel::CheckModes()
@@ -168,6 +158,8 @@ ChanUserContainer* Channel::JoinUser(User *user)
if (user->server && user->server->IsSynced())
Log(user, this, "join");
+ FOREACH_MOD(I_OnJoinChannel, OnJoinChannel(user, this));
+
ChanUserContainer *cuc = new ChanUserContainer(user, this);
user->chans[this] = cuc;
this->users[user] = cuc;
@@ -401,16 +393,8 @@ void Channel::RemoveModeInternal(MessageSource &setter, ChannelMode *cm, const A
FOREACH_RESULT(I_OnChannelModeUnset, OnChannelModeUnset(this, setter, cm->name, param));
if (enforce_mlock && MOD_RESULT != EVENT_STOP)
- {
- /* Reset modes on bots if we're supposed to */
- if (this->ci && this->ci->bi && this->ci->bi == bi)
- {
- if (ModeManager::DefaultBotModes.HasMode(cm->mchar))
- this->SetMode(bi, cm, bi->GetUID());
- }
-
this->SetCorrectModes(u, false, false);
- }
+
return;
}
@@ -790,22 +774,19 @@ void Channel::KickInternal(MessageSource &source, const Anope::string &nick, con
Anope::string chname = this->name;
- if (target->FindChannel(this))
+ ChanUserContainer *cu = target->FindChannel(this);
+ if (cu == NULL)
{
- FOREACH_MOD(I_OnUserKicked, OnUserKicked(this, target, source, reason));
- if (bi)
- this->Extend("INHABIT");
- this->DeleteUser(target);
- }
- else
Log() << "Channel::KickInternal got kick for user " << target->nick << " from " << source.GetSource() << " who isn't on channel " << this->name;
-
- /* Bots get rejoined */
- if (bi)
- {
- bi->Join(this, &ModeManager::DefaultBotModes);
- this->Shrink("INHABIT");
+ return;
}
+
+ Anope::string this_name = this->name;
+ ChannelStatus status = cu->status;
+
+ FOREACH_MOD(I_OnPreUserKicked, OnPreUserKicked(source, cu, reason));
+ this->DeleteUser(target); /* This can delete this; */
+ FOREACH_MOD(I_OnUserKicked, OnUserKicked(source, target, this_name, status, reason));
}
bool Channel::Kick(BotInfo *bi, User *u, const char *reason, ...)
@@ -873,54 +854,6 @@ void Channel::ChangeTopic(const Anope::string &user, const Anope::string &newtop
this->ci->CheckTopic();
}
-void Channel::Hold()
-{
- /** A timer used to keep the BotServ bot/ChanServ in the channel
- * after kicking the last user in a channel
- */
- class ChanServTimer : public Timer
- {
- private:
- Reference<Channel> c;
-
- public:
- /** Constructor
- * @param chan The channel
- */
- ChanServTimer(Channel *chan) : Timer(Config->CSInhabit), c(chan)
- {
- if (!ChanServ || !c)
- return;
- c->Extend("INHABIT");
- if (!c->ci || !c->ci->bi)
- ChanServ->Join(c);
- else if (!c->FindUser(c->ci->bi))
- c->ci->bi->Join(c);
- }
-
- /** Called when the delay is up
- * @param The current time
- */
- void Tick(time_t) anope_override
- {
- if (!c)
- return;
-
- c->Shrink("INHABIT");
-
- if (!c->ci || !c->ci->bi)
- {
- if (ChanServ)
- ChanServ->Part(c);
- }
- else if (c->users.size() == 1 || c->users.size() < Config->BSMinUsers)
- c->ci->bi->Part(c);
- }
- };
-
- new ChanServTimer(this);
-}
-
void Channel::SetCorrectModes(User *user, bool give_modes, bool check_noop)
{
if (user == NULL)
@@ -980,6 +913,8 @@ void Channel::SetCorrectModes(User *user, bool give_modes, bool check_noop)
}
}
}
+
+ FOREACH_MOD(I_OnSetCorrectModes, OnSetCorrectModes(user, this, u_access, give_modes));
}
bool Channel::Unban(User *u, bool full)
diff --git a/src/command.cpp b/src/command.cpp
index dc095fdd8..db4bb9996 100644
--- a/src/command.cpp
+++ b/src/command.cpp
@@ -191,7 +191,7 @@ void Command::OnSyntaxError(CommandSource &source, const Anope::string &subcomma
this->SendSyntax(source);
bool has_help = source.service->commands.find("HELP") != source.service->commands.end();
if (has_help)
- source.Reply(MORE_INFO, Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str(), source.command.c_str());
+ source.Reply(MORE_INFO, Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), source.command.c_str());
}
void RunCommand(CommandSource &source, const Anope::string &message)
@@ -216,7 +216,7 @@ void RunCommand(CommandSource &source, const Anope::string &message)
if (it == source.service->commands.end())
{
if (has_help)
- source.Reply(_("Unknown command \002%s\002. \"%s%s HELP\" for help."), message.c_str(), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str());
+ source.Reply(_("Unknown command \002%s\002. \"%s %s HELP\" for help."), message.c_str(), Config->StrictPrivmsg.c_str(), source.service->nick.c_str());
else
source.Reply(_("Unknown command \002%s\002."), message.c_str());
return;
@@ -227,7 +227,7 @@ void RunCommand(CommandSource &source, const Anope::string &message)
if (!c)
{
if (has_help)
- source.Reply(_("Unknown command \002%s\002. \"%s%s HELP\" for help."), message.c_str(), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str());
+ source.Reply(_("Unknown command \002%s\002. \"%s%s HELP\" for help."), message.c_str(), Config->StrictPrivmsg.c_str(), source.service->nick.c_str());
else
source.Reply(_("Unknown command \002%s\002."), message.c_str());
Log(source.service) << "Command " << it->first << " exists on me, but its service " << info.name << " was not found!";
diff --git a/src/config.cpp b/src/config.cpp
index bc01a1589..38e072de8 100644
--- a/src/config.cpp
+++ b/src/config.cpp
@@ -25,1020 +25,588 @@
#include <grp.h>
#endif
-/*************************************************************************/
+using namespace Configuration;
-ConfigurationFile ServicesConf("services.conf", false); // Services configuration file name
-ServerConfig *Config = NULL;
+File ServicesConf("services.conf", false); // Services configuration file name
+Conf *Config = NULL;
-static Anope::string UlineServers;
-static Anope::string BSDefaults;
-static Anope::string CSDefaults;
-static Anope::string NSDefaults;
-
-/*************************************************************************/
-
-ServerConfig::ServerConfig()
+Block::Block(const Anope::string &n) : name(n)
{
- this->Read();
-
- if (NSDefaults.empty())
- {
- this->NSDefFlags.insert("SECURE");
- this->NSDefFlags.insert("MEMO_SIGNON");
- this->NSDefFlags.insert("MEMO_RECEIVE");
- }
- else if (!NSDefaults.equals_ci("none"))
- {
- spacesepstream options(NSDefaults);
- Anope::string option;
- while (options.GetToken(option))
- {
- if (option.equals_ci("msg"))
- {
- if (!this->UsePrivmsg)
- Log() << "msg in <nickserv:defaults> can only be used when options:useprivmsg is set";
- else
- this->NSDefFlags.insert(option.upper());
- }
- else
- this->NSDefFlags.insert(option.upper());
- }
- }
-
- if (this->CSDefBantype < 0 || this->CSDefBantype > 3)
- {
- throw ConfigException("Value of CSDefBantype must be between 0 and 3 included");
- }
-
- if (CSDefaults.empty())
- {
- this->CSDefFlags.insert("KEEPTOPIC");
- this->CSDefFlags.insert("SECURE");
- this->CSDefFlags.insert("SECUREFOUNDER");
- this->CSDefFlags.insert("SIGNKICK");
- }
- else if (!CSDefaults.equals_ci("none"))
- {
- spacesepstream options(CSDefaults);
- Anope::string option;
- while (options.GetToken(option))
- this->CSDefFlags.insert(option.upper());
- }
-
- if (UseStrictPrivMsg)
- UseStrictPrivMsgString = "/";
- else
- UseStrictPrivMsgString ="/msg ";
-
-
- if (!BSDefaults.empty())
- {
- spacesepstream options(BSDefaults);
- Anope::string option;
- while (options.GetToken(option))
- this->BSDefFlags.insert("BS_" + option.upper());
- }
-
- /* Ulines */
- if (!UlineServers.empty())
- {
- this->Ulines.clear();
-
- spacesepstream ulines(UlineServers);
- Anope::string uline;
- while (ulines.GetToken(uline))
- this->Ulines.push_back(uline);
- }
-
- if (this->LimitSessions)
- {
- if (this->MaxSessionKill && !this->SessionAutoKillExpiry)
- this->SessionAutoKillExpiry = 1800; /* 30 minutes */
- }
-
- /* Check the user keys */
- if (this->Seed == 0)
- Log() << "Configuration option options:seed should be set. It's for YOUR safety! Remember that!";
-
- ModeManager::UpdateDefaultMLock(this);
-
- if (this->CaseMap == "ascii")
- Anope::casemap = std::locale(std::locale(), new Anope::ascii_ctype<char>());
- else if (this->CaseMap == "rfc1459")
- Anope::casemap = std::locale(std::locale(), new Anope::rfc1459_ctype<char>());
- else
- {
- try
- {
- Anope::casemap = std::locale(this->CaseMap.c_str());
- }
- catch (const std::runtime_error &)
- {
- Log() << "Unknown casemap " << this->CaseMap << " - casemap not changed";
- }
- }
- Anope::CaseMapRebuild();
-
- if (this->SessionIPv4CIDR > 32 || this->SessionIPv6CIDR > 128)
- throw ConfigException("Session CIDR value out of range");
-
- ConfigReader reader(this);
- FOREACH_MOD(I_OnReload, OnReload(this, reader));
-
-#ifndef _WIN32
- if (!this->User.empty())
- {
- errno = 0;
- struct passwd *u = getpwnam(this->User.c_str());
- if (u == NULL)
- Log() << "Unable to setuid to " << this->User << ": " << Anope::LastError();
- else if (setuid(u->pw_uid) == -1)
- Log() << "Unable to setuid to " << this->User << ": " << Anope::LastError();
- else
- Log() << "Successfully set user to " << this->User;
- }
- if (!this->Group.empty())
- {
- errno = 0;
- struct group *g = getgrnam(this->Group.c_str());
- if (g == NULL)
- Log() << "Unable to setgid to " << this->Group << ": " << Anope::LastError();
- else if (setuid(g->gr_gid) == -1)
- Log() << "Unable to setgid to " << this->Group << ": " << Anope::LastError();
- else
- Log() << "Successfully set group to " << this->Group;
- }
-#endif
}
-bool ServerConfig::CheckOnce(const Anope::string &tag)
+const Anope::string &Block::GetName() const
{
- int count = ConfValueEnum(config_data, tag);
- if (count > 1)
- throw ConfigException("You have more than one <" + tag + "> tag, this is not permitted.");
- if (count < 1)
- throw ConfigException("You have not defined a <" + tag + "> tag, this is required.");
- return true;
+ return name;
}
-bool NoValidation(ServerConfig *, const Anope::string &, const Anope::string &, ValueItem &)
+int Block::CountBlock(const Anope::string &bname)
{
- return true;
-}
-
-void ServerConfig::ValidateNoSpaces(const Anope::string &p, const Anope::string &tag, const Anope::string &val) const
-{
- for (Anope::string::const_iterator ptr = p.begin(), end = p.end(); ptr != end; ++ptr)
- if (*ptr == ' ')
- throw ConfigException("The value of <" + tag + ":" + val + "> cannot contain spaces");
+ if (!this)
+ return 0;
+
+ return blocks.count(bname);
}
-/* NOTE: Before anyone asks why we're not using inet_pton for this, it is because inet_pton and friends do not return so much detail,
- * even in LastError(). They just return 'yes' or 'no' to an address without such detail as to whats WRONG with the address.
- * Because ircd users arent as technical as they used to be (;)) we are going to give more of a useful error message.
- */
-void ServerConfig::ValidateIP(const Anope::string &p, const Anope::string &tag, const Anope::string &val, bool wild) const
+Block* Block::GetBlock(const Anope::string &bname, int num)
{
- int num_dots = 0, num_seps = 0;
- bool not_numbers = false, not_hex = false;
-
- if (!p.empty())
- {
- if (p[0] == '.')
- throw ConfigException("The value of <" + tag + ":" + val + "> is not an IP address");
-
- for (Anope::string::const_iterator ptr = p.begin(), end = p.end(); ptr != end; ++ptr)
- {
- if (wild && (*ptr == '*' || *ptr == '?' || *ptr == '/'))
- continue;
-
- if (*ptr != ':' && *ptr != '.' && (*ptr < '0' || *ptr > '9'))
- {
- not_numbers = true;
- if (toupper(*ptr) < 'A' || toupper(*ptr) > 'F')
- not_hex = true;
- }
- switch (*ptr)
- {
- case ' ':
- throw ConfigException("The value of <" + tag + ":" + val + "> is not an IP address");
- case '.':
- ++num_dots;
- break;
- case ':':
- ++num_seps;
- }
- }
- if (num_dots > 3)
- throw ConfigException("The value of <" + tag + ":" + val + "> is an IPv4 address with too many fields!");
-
- if (num_seps > 8)
- throw ConfigException("The value of <" + tag + ":" + val + "> is an IPv6 address with too many fields!");
-
- if (!num_seps && num_dots < 3 && !wild)
- throw ConfigException("The value of <" + tag + ":" + val + "> looks to be a malformed IPv4 address");
-
- if (!num_seps && num_dots == 3 && not_numbers)
- throw ConfigException("The value of <" + tag + ":" + val + "> contains non-numeric characters in an IPv4 address");
-
- if (num_seps && not_hex)
- throw ConfigException("The value of <" + tag + ":" + val + "> contains non-hexdecimal characters in an IPv6 address");
+ if (!this)
+ return NULL;
+
+ std::pair<block_map::iterator, block_map::iterator> it = blocks.equal_range(bname);
- if (num_seps && num_dots != 3 && num_dots && !wild)
- throw ConfigException("The value of <" + tag + ":" + val + "> is a malformed IPv6 4in6 address");
- }
+ for (int i = 0; it.first != it.second; ++it.first, ++i)
+ if (i == num)
+ return &it.first->second;
+ return NULL;
}
-void ServerConfig::ValidateHostname(const Anope::string &p, const Anope::string &tag, const Anope::string &val) const
+bool Block::Set(const Anope::string &tag, const Anope::string &value)
{
- if (p.equals_ci("localhost"))
- return;
-
- int num_dots = 0, num_seps = 0;
- if (!p.empty())
- {
- if (p[0] == '.')
- throw ConfigException("The value of <" + tag + ":" + val + "> is not a valid hostname");
- for (unsigned i = 0, end = p.length(); i < end; ++i)
- {
- switch (p[i])
- {
- case ' ':
- throw ConfigException("The value of <" + tag + ":" + val + "> is not a valid hostname");
- case '.':
- ++num_dots;
- break;
- case ':':
- ++num_seps;
- break;
- }
- }
- if (!num_dots && !num_seps)
- throw ConfigException("The value of <" + tag + ":" + val + "> is not a valid hostname");
- }
-}
+ if (!this)
+ return false;
-static bool ValidateNotEmpty(ServerConfig *, const Anope::string &tag, const Anope::string &value, ValueItem &data)
-{
- if (data.GetValue().empty())
- throw ConfigException("The value for <" + tag + ":" + value + "> cannot be empty!");
+ items[tag] = value;
return true;
}
-static bool ValidateNotZero(ServerConfig *, const Anope::string &tag, const Anope::string &value, ValueItem &data)
+const Block::item_map* Block::GetItems() const
{
- if (!data.GetInteger() && Anope::DoTime(data.GetValue()) <= 0)
- throw ConfigException("The value for <" + tag + ":" + value + "> must be non-zero!");
- return true;
+ if (this)
+ return &items;
+ else
+ return NULL;
}
-static bool ValidateEmailReg(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data)
+template<> const Anope::string& Block::Get(const Anope::string &tag, const Anope::string& def) const
{
- if (!config->NSRegistration.equals_ci("none") && !config->NSRegistration.equals_ci("disable"))
- {
- if (value.equals_ci("unconfirmedexpire"))
- {
- if (!data.GetInteger() && Anope::DoTime(data.GetValue()) <= 0)
- throw ConfigException("The value for <" + tag + ":" + value + "> must be non-zero when e-mail or admin registration is enabled!");
- }
- else
- {
- if (!data.GetBool())
- throw ConfigException("The value for <" + tag + ":" + value + "> must be set to yes when e-mail or admin registrations is enabled!");
- }
- }
- return true;
-}
+ if (!this)
+ return def;
-static bool ValidatePort(ServerConfig *, const Anope::string &tag, const Anope::string &value, ValueItem &data)
-{
- int port = data.GetInteger();
- if (!port)
- return true;
- if (port < 1 || port > 65535)
- throw ConfigException("The value for <" + tag + ":" + value + "> is not a value port, it must be between 1 and 65535!");
- return true;
-}
+ Anope::map<Anope::string>::const_iterator it = items.find(tag);
+ if (it != items.end())
+ return it->second;
-static bool ValidateBantype(ServerConfig *, const Anope::string &, const Anope::string &, ValueItem &data)
-{
- int bantype = data.GetInteger();
- if (bantype < 0 || bantype > 3)
- throw ConfigException("The value for <chanserv:defbantype> must be between 0 and 3!");
- return true;
+ return def;
}
-static bool ValidateNickServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data)
+template<> time_t Block::Get(const Anope::string &tag, const Anope::string &def) const
{
- if (!config->NickServ.empty())
- {
- if (value.equals_ci("releasetimeout") || value.equals_ci("accessmax") || value.equals_ci("listmax"))
- return ValidateNotZero(config, tag, value, data);
- else if (value.equals_ci("enforceruser") || value.equals_ci("enforcerhost"))
- return ValidateNotEmpty(config, tag, value, data);
- else if (value.equals_ci("guestnickprefix"))
- {
- ValidateNotEmpty(config, tag, value, data);
- if (data.GetValue().length() > 21)
- throw ConfigException("The value for <nickserv:guestnickprefix> cannot exceed 21 characters in length!");
- }
- else if (value.equals_ci("registration"))
- if (!data.GetValue().equals_ci("none") && !data.GetValue().equals_ci("mail") && !data.GetValue().equals_ci("admin") && !data.GetValue().equals_ci("disable"))
- throw ConfigException("The value for <nickserv:registration> must be one of \"none\", \"mail\", \"admin\", or \"disable\"");
- }
- return true;
+ return Anope::DoTime(Get<const Anope::string &>(tag, def));
}
-static bool ValidateChanServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data)
+template<> const char* Block::Get(const Anope::string &tag, const Anope::string &def) const
{
- if (!config->ChanServ.empty())
- {
- if ((value.equals_ci("decription") || value.equals_ci("autokickreason")) && data.GetValue().empty())
- throw ConfigException("The value for <" + tag + ":" + value + "> cannot be empty when ChanServ is enabled!");
- else if (value.equals_ci("defbantype"))
- return ValidateBantype(config, tag, value, data);
- else if (value.equals_ci("accessmax") || value.equals_ci("autokickmax") || value.equals_ci("inhabit") || value.equals_ci("listmax"))
- return ValidateNotZero(config, tag, value, data);
- }
- return true;
+ return this->Get<const Anope::string &>(tag, def).c_str();
}
-static bool ValidateBotServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data)
+template<> bool Block::Get(const Anope::string &tag, const Anope::string &def) const
{
- if (!config->BotServ.empty())
- {
- if (value.equals_ci("badwordsmax") || value.equals_ci("keepdata"))
- {
- if (!data.GetInteger() && Anope::DoTime(data.GetValue()) <= 0)
- throw ConfigException("The value for <" + tag + ":" + value + "> must be non-zero when BotServ is enabled!");
- }
- else if (value.equals_ci("minusers"))
- {
- if (data.GetInteger() < 0)
- throw ConfigException("The value for <" + tag + ":" + value + "> must be greater than or equal to zero!");
- }
- }
- return true;
+ const Anope::string &str = Get<const Anope::string &>(tag, def);
+ return str.equals_ci("yes") || str.equals_ci("on") || str.equals_ci("true");
}
-static bool ValidateLimitSessions(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data)
+static void ValidateNotEmpty(const Anope::string &block, const Anope::string &name, const Anope::string &value)
{
- if (config->LimitSessions)
- {
- if (value.equals_ci("maxsessionlimit") || value.equals_ci("exceptionexpiry"))
- {
- if (!data.GetInteger() && Anope::DoTime(data.GetValue()) <= 0)
- throw ConfigException("The value for <" + tag + ":" + value + "> must be non-zero when session limiting is enabled!");
- }
- }
- return true;
+ if (value.empty())
+ throw ConfigException("The value for <" + block + ":" + name + "> cannot be empty!");
}
-static bool ValidateOperServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data)
+template<typename T> static void ValidateNotZero(const Anope::string &block, const Anope::string &name, T value)
{
- if (!config->OperServ.empty())
- {
- if (value.equals_ci("autokillexpiry") || value.equals_ci("chankillexpiry") || value.equals_ci("snlineexpiry") || value.equals_ci("sqlineexpiry"))
- return ValidateNotZero(config, tag, value, data);
- else if (value.equals_ci("maxsessionlimit") || value.equals_ci("exceptionexpiry"))
- return ValidateLimitSessions(config, tag, value, data);
- }
- return true;
+ if (!value)
+ throw ConfigException("The value for <" + block + ":" + name + "> cannot be zero!");
}
-static bool ValidateNickLen(ServerConfig *, const Anope::string &, const Anope::string &, ValueItem &data)
+Conf::Conf() : Block("")
{
- int nicklen = data.GetInteger();
- if (!nicklen)
- {
- Log() << "You have not defined the <networkinfo:nicklen> directive. It is strongly";
- Log() << "adviced that you do configure this correctly in your services.conf";
- data.Set(31);
- }
- else if (nicklen < 1)
- {
- Log() << "<networkinfo:nicklen> has an invalid value; setting to 31";
- data.Set(31);
- }
- return true;
-}
+ ReadTimeout = 0;
+ UsePrivmsg = DefPrivmsg = false;
-static bool ValidateMail(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data)
-{
- if (config->UseMail)
- {
- Anope::string check[] = { "sendmailpath", "sendfrom", "registration_subject", "registration_message", "emailchange_subject", "emailchange_message", "memo_subject", "memo_message", "" };
- for (int i = 0; !check[i].empty(); ++i)
- if (value.equals_ci(check[i]))
- if (data.GetValue().empty())
- throw ConfigException("The value for <" + tag + ":" + value + "> cannot be empty when e-mail is enabled!");
- }
- return true;
-}
+ this->LoadConf(ServicesConf);
-static bool ValidateGlobalOnCycle(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data)
-{
- if (config->GlobalOnCycle)
+ for (int i = 0; i < this->CountBlock("include"); ++i)
{
- if (data.GetValue().empty())
- {
- Log() << "<" << tag << ":" << value << "> was undefined, disabling <options:globaloncycle>";
- config->GlobalOnCycle = false;
- }
- }
- return true;
-}
+ Block *include = this->GetBlock("include", i);
-static bool InitUplinks(ServerConfig *config, const Anope::string &)
-{
- if (!config->Uplinks.empty())
- {
- std::vector<ServerConfig::Uplink *>::iterator curr_uplink = config->Uplinks.begin(), end_uplink = config->Uplinks.end();
- for (; curr_uplink != end_uplink; ++curr_uplink)
- delete *curr_uplink;
- }
- config->Uplinks.clear();
- return true;
-}
+ const Anope::string &type = include->Get<const Anope::string &>("type"),
+ &file = include->Get<const Anope::string &>("name");
-static bool DoUplink(ServerConfig *config, const Anope::string &, const Anope::string *, ValueList &values, int *)
-{
- // Validation variables
- Anope::string host = values[0].GetValue(), password = values[3].GetValue();
- int port = values[2].GetInteger();
- bool ipv6 = values[1].GetBool();
- ValueItem vi_host(host), vi_port(port), vi_password(password);
- // Validate the host to make sure it is not empty
- if (!ValidateNotEmpty(config, "uplink", "host", vi_host))
- throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
- // Validate the port to make sure it is a valid port
- if (!ValidatePort(config, "uplink", "port", vi_port))
- throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
- // Validate the password to make sure it is not empty
- if (!ValidateNotEmpty(config, "uplink", "password", vi_password))
- throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
- // If we get here, all the values are valid, we'll add it to the Uplinks list
- config->Uplinks.push_back(new ServerConfig::Uplink(host, port, password, ipv6));
- return true;
-}
-
-static bool DoneUplinks(ServerConfig *config, const Anope::string &)
-{
- if (config->Uplinks.empty())
- throw ConfigException("You must define at least one uplink block!");
- return true;
-}
-
-static bool InitOperTypes(ServerConfig *config, const Anope::string &)
-{
- for (std::list<OperType *>::iterator it = config->MyOperTypes.begin(), it_end = config->MyOperTypes.end(); it != it_end; ++it)
- delete *it;
+ File f(file, type == "executable");
+ this->LoadConf(f);
+ }
- config->MyOperTypes.clear();
- return true;
-}
+ FOREACH_MOD(I_OnReload, OnReload(this));
-static bool DoOperType(ServerConfig *config, const Anope::string &, const Anope::string *, ValueList &values, int *)
-{
- Anope::string name = values[0].GetValue();
- Anope::string inherits = values[1].GetValue();
- Anope::string commands = values[2].GetValue();
- Anope::string privs = values[3].GetValue();
- Anope::string modes = values[4].GetValue();
-
- ValueItem vi(name);
- if (!ValidateNotEmpty(config, "opertype", "name", vi))
- throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
-
- OperType *ot = new OperType(name);
- ot->modes = modes;
-
- Anope::string tok;
- spacesepstream cmdstr(commands);
- while (cmdstr.GetToken(tok))
- ot->AddCommand(tok);
-
- spacesepstream privstr(privs);
- while (privstr.GetToken(tok))
- ot->AddPriv(tok);
-
- commasepstream inheritstr(inherits);
- while (inheritstr.GetToken(tok))
+ /* Check for modified values that aren't allowed to be modified */
+ if (Config)
{
- /* Strip leading ' ' after , */
- if (tok.length() > 1 && tok[0] == ' ')
- tok.erase(tok.begin());
- for (std::list<OperType *>::iterator it = config->MyOperTypes.begin(), it_end = config->MyOperTypes.end(); it != it_end; ++it)
+ struct
{
- if ((*it)->GetName().equals_ci(tok))
- {
- Log() << "Inheriting commands and privs from " << (*it)->GetName() << " to " << ot->GetName();
- ot->Inherits(*it);
- break;
- }
- }
+ Anope::string block;
+ Anope::string name;
+ Anope::string def;
+ } noreload[] = {
+ {"serverinfo", "name", ""},
+ {"serverinfo", "description", ""},
+ {"serverinfo", "localhost", ""},
+ {"serverinfo", "id", ""},
+ {"serverinfo", "pid", ""},
+ {"networkinfo", "nicklen", "31"},
+ {"networkinfo", "userlen", "10"},
+ {"networkinfo", "hostlen", "64"},
+ {"networkinfo", "chanlen", "32"},
+ {"options", "passlen", "32"},
+ };
+
+ for (unsigned i = 0; i < sizeof(noreload) / sizeof(noreload[0]); ++i)
+ if (this->GetBlock(noreload[i].block)->Get<const Anope::string &>(noreload[i].name, noreload[i].def) != Config->GetBlock(noreload[i].block)->Get<const Anope::string &>(noreload[i].name, noreload[i].def))
+ throw ConfigException("<" + noreload[i].block + ":" + noreload[i].name + "> can not be modified once set");
}
- config->MyOperTypes.push_back(ot);
- return true;
-}
+ Block *options = this->GetBlock("options"), *mail = this->GetBlock("mail");
-static bool DoneOperTypes(ServerConfig *, const Anope::string &)
-{
- return true;
-}
+ ValidateNotZero("options", "releasetimeout", options->Get<time_t>("releasetimeout"));
+ ValidateNotEmpty("options", "enforceruser", options->Get<const Anope::string &>("enforceruser"));
+ ValidateNotEmpty("options", "enforcerhost", options->Get<const Anope::string &>("enforcerhost"));
+ ValidateNotEmpty("options", "guestnickprefix", options->Get<const Anope::string &>("guestnickprefix"));
+ spacesepstream(options->Get<const Anope::string &>("ulineservers")).GetTokens(this->Ulines);
-/*************************************************************************/
+ if (mail->Get<bool>("usemail"))
+ {
+ Anope::string check[] = { "sendmailpath", "sendfrom", "registration_subject", "registration_message", "emailchange_subject", "emailchange_message", "memo_subject", "memo_message" };
+ for (unsigned i = 0; i < sizeof(check) / sizeof(Anope::string); ++i)
+ ValidateNotEmpty("mail", check[i], mail->Get<const Anope::string &>(check[i]));
+ }
-static bool InitOpers(ServerConfig *config, const Anope::string &)
-{
- for (nickcore_map::const_iterator it = NickCoreList->begin(), it_end = NickCoreList->end(); it != it_end; ++it)
+ this->ReadTimeout = options->Get<unsigned>("readtimeout");
+ this->UsePrivmsg = options->Get<bool>("useprivmsg");
+ this->StrictPrivmsg = options->Get<bool>("usestrictprivmsg") ? "/msg " : "/";
{
- NickCore *nc = it->second;
- nc->QueueUpdate();
- if (nc->o && nc->o->config)
- nc->o = NULL;
+ std::vector<Anope::string> defaults;
+ spacesepstream(this->GetModule("nickserv")->Get<const Anope::string &>("defaults")).GetTokens(defaults);
+ this->DefPrivmsg = std::find(defaults.begin(), defaults.end(), "msg") != defaults.end();
}
+ this->DefLanguage = options->Get<const Anope::string &>("defaultlanguage");
- for (unsigned i = 0; i < config->Opers.size(); ++i)
- delete config->Opers[i];
- config->Opers.clear();
+ for (int i = 0; i < this->CountBlock("uplink"); ++i)
+ {
+ Block *uplink = this->GetBlock("uplink", i);
- return true;
-}
+ const Anope::string &host = uplink->Get<const Anope::string &>("host");
+ bool ipv6 = uplink->Get<bool>("ipv6");
+ int port = uplink->Get<int>("port");
+ const Anope::string &password = uplink->Get<const Anope::string &>("password");
-static bool DoOper(ServerConfig *config, const Anope::string &, const Anope::string *, ValueList &values, int *)
-{
- Anope::string name = values[0].GetValue();
- Anope::string type = values[1].GetValue();
- bool require_oper = values[2].GetBool();
- Anope::string password = values[3].GetValue();
- Anope::string certfp = values[4].GetValue();
- Anope::string host = values[5].GetValue();
- Anope::string vhost = values[6].GetValue();
-
- ValueItem vi(name);
- if (!ValidateNotEmpty(config, "oper", "name", vi))
- throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
-
- ValueItem vi2(type);
- if (!ValidateNotEmpty(config, "oper", "type", vi2))
- throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
-
- OperType *ot = NULL;
- for (std::list<OperType *>::iterator it = config->MyOperTypes.begin(), it_end = config->MyOperTypes.end(); it != it_end; ++it)
- if ((*it)->GetName() == type)
- ot = *it;
- if (ot == NULL)
- throw ConfigException("Oper block for " + name + " has invalid oper type " + type);
-
- Oper *o = new Oper(name, ot);
- o->require_oper = require_oper;
- o->config = true;
- o->password = password;
- o->certfp = certfp;
- spacesepstream(host).GetTokens(o->hosts);
- o->vhost = vhost;
- config->Opers.push_back(o);
+ ValidateNotEmpty("uplink", "host", host);
+ ValidateNotEmpty("uplink", "password", password);
- return true;
-}
+ this->Uplinks.push_back(Uplink(host, port, password, ipv6));
+ }
-static bool DoneOpers(ServerConfig *config, const Anope::string &)
-{
- for (unsigned i = 0; i < config->Opers.size(); ++i)
+ for (int i = 0; i < this->CountBlock("module"); ++i)
{
- Oper *o = config->Opers[i];
+ Block *module = this->GetBlock("module", i);
- const NickAlias *na = NickAlias::Find(o->name);
- if (!na)
- // Nonexistant nick
- continue;
+ const Anope::string &modname = module->Get<const Anope::string &>("name");
- na->nc->o = o;
- Log() << "Tied oper " << na->nc->display << " to type " << o->ot->GetName();
+ ValidateNotEmpty("module", "name", modname);
+
+ this->ModulesAutoLoad.push_back(modname);
}
- return true;
-}
+ for (int i = 0; i < this->CountBlock("opertype"); ++i)
+ {
+ Block *opertype = this->GetBlock("opertype", i);
-/*************************************************************************/
+ const Anope::string &oname = opertype->Get<const Anope::string &>("name"),
+ &modes = opertype->Get<const Anope::string &>("modes"),
+ &inherits = opertype->Get<const Anope::string &>("inherits"),
+ &commands = opertype->Get<const Anope::string &>("commands"),
+ &privs = opertype->Get<const Anope::string &>("privs");
-static std::map<Anope::string, Anope::string> defines;
-static bool InitDefine(ServerConfig *config, const Anope::string &)
-{
- defines.clear();
- return true;
-}
+ ValidateNotEmpty("opertype", "name", oname);
-static bool DoDefine(ServerConfig *config, const Anope::string &, const Anope::string *, ValueList &values, int *)
-{
- Anope::string name = values[0].GetValue(), value = values[1].GetValue();
- defines[name] = value;
- return true;
-}
+ OperType *ot = new OperType(oname);
+ ot->modes = modes;
-static bool DoneDefine(ServerConfig *config, const Anope::string &)
-{
- return true;
-}
+ spacesepstream cmdstr(commands);
+ for (Anope::string str; cmdstr.GetToken(str);)
+ ot->AddCommand(str);
-/*************************************************************************/
+ spacesepstream privstr(privs);
+ for (Anope::string str; cmdstr.GetToken(str);)
+ ot->AddPriv(str);
-static bool InitInclude(ServerConfig *config, const Anope::string &)
-{
- return true;
-}
+ commasepstream inheritstr(inherits);
+ for (Anope::string str; inheritstr.GetToken(str);)
+ {
+ /* Strip leading ' ' after , */
+ if (str.length() > 1 && str[0] == ' ')
+ str.erase(str.begin());
+ for (unsigned j = 0; j < this->MyOperTypes.size(); ++j)
+ {
+ OperType *ot2 = this->MyOperTypes[j];
-static bool DoInclude(ServerConfig *config, const Anope::string &, const Anope::string *, ValueList &values, int *)
-{
- Anope::string type = values[0].GetValue();
- Anope::string file = values[1].GetValue();
+ if (ot2->GetName().equals_ci(str))
+ {
+ Log() << "Inheriting commands and privs from " << ot2->GetName() << " to " << ot->GetName();
+ ot->Inherits(ot2);
+ break;
+ }
+ }
+ }
- if (type != "file" && type != "executable")
- throw ConfigException("include:type must be either \"file\" or \"executable\"");
-
- ConfigurationFile f(file, type == "executable");
- config->LoadConf(f);
+ this->MyOperTypes.push_back(ot);
+ }
- return true;
-}
+ for (int i = 0; i < this->CountBlock("oper"); ++i)
+ {
+ Block *oper = this->GetBlock("oper", i);
-static bool DoneInclude(ServerConfig *config, const Anope::string &)
-{
- return true;
-}
+ const Anope::string &nname = oper->Get<const Anope::string &>("name"),
+ &type = oper->Get<const Anope::string &>("type"),
+ &password = oper->Get<const Anope::string &>("password"),
+ &certfp = oper->Get<const Anope::string &>("certfp"),
+ &host = oper->Get<const Anope::string &>("host"),
+ &vhost = oper->Get<const Anope::string &>("vhost");
+ bool require_oper = oper->Get<bool>("require_oper");
-/*************************************************************************/
+ ValidateNotEmpty("oper", "name", nname);
+ ValidateNotEmpty("oper", "type", type);
+
+ OperType *ot = NULL;
+ for (unsigned j = 0; j < this->MyOperTypes.size(); ++j)
+ if (this->MyOperTypes[j]->GetName() == type)
+ ot = this->MyOperTypes[j];
+ if (ot == NULL)
+ throw ConfigException("Oper block for " + nname + " has invalid oper type " + type);
-static bool InitModules(ServerConfig *, const Anope::string &)
-{
- return true;
-}
+ Oper *o = new Oper(nname, ot);
+ o->require_oper = require_oper;
+ o->config = true;
+ o->password = password;
+ o->certfp = certfp;
+ spacesepstream(host).GetTokens(o->hosts);
+ o->vhost = vhost;
-static bool DoModule(ServerConfig *conf, const Anope::string &, const Anope::string *, ValueList &values, int *)
-{
- // First we validate that there was a name in the module block
- Anope::string module = values[0].GetValue();
- ValueItem vi(module);
- if (!ValidateNotEmpty(conf, "module", "name", vi))
- throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
- conf->ModulesAutoLoad.push_back(module);
- return true;
-}
+ this->Opers.push_back(o);
+ }
-static bool DoneModules(ServerConfig *config, const Anope::string &)
-{
- if (Config)
- {
- for (std::list<Anope::string>::iterator it = Config->ModulesAutoLoad.begin(); it != Config->ModulesAutoLoad.end(); ++it)
- if (std::find(config->ModulesAutoLoad.begin(), config->ModulesAutoLoad.end(), *it) == config->ModulesAutoLoad.end())
- ModuleManager::UnloadModule(ModuleManager::FindModule(*it), NULL);
- for (std::list<Anope::string>::iterator it = config->ModulesAutoLoad.begin(); it != config->ModulesAutoLoad.end(); ++it)
- if (std::find(Config->ModulesAutoLoad.begin(), Config->ModulesAutoLoad.end(), *it) == Config->ModulesAutoLoad.end())
- ModuleManager::LoadModule(*it, NULL);
+ for (botinfo_map::const_iterator it = BotListByNick->begin(), it_end = BotListByNick->end(); it != it_end; ++it)
+ it->second->conf = false;
+ for (int i = 0; i < this->CountBlock("service"); ++i)
+ {
+ Block *service = this->GetBlock("service", i);
+
+ const Anope::string &nick = service->Get<const Anope::string &>("nick"),
+ &user = service->Get<const Anope::string &>("user"),
+ &host = service->Get<const Anope::string &>("host"),
+ &gecos = service->Get<const Anope::string &>("gecos"),
+ &modes = service->Get<const Anope::string &>("modes"),
+ &channels = service->Get<const Anope::string &>("channels");
+
+ ValidateNotEmpty("service", "nick", nick);
+ ValidateNotEmpty("service", "user", user);
+ ValidateNotEmpty("service", "host", host);
+ ValidateNotEmpty("service", "gecos", gecos);
+
+ BotInfo *bi = BotInfo::Find(nick, true);
+ if (!bi)
+ bi = new BotInfo(nick, user, host, gecos, modes);
+ bi->conf = true;
+
+ std::vector<Anope::string> oldchannels = bi->botchannels;
+ bi->botchannels.clear();
+ commasepstream sep(channels);
+ for (Anope::string token; sep.GetToken(token);)
+ {
+ bi->botchannels.push_back(token);
+ size_t ch = token.find('#');
+ Anope::string chname, want_modes;
+ if (ch == Anope::string::npos)
+ chname = token;
+ else
+ {
+ want_modes = token.substr(0, ch);
+ chname = token.substr(ch);
+ }
+ bi->Join(chname);
+ Channel *c = Channel::Find(chname);
+ if (!c)
+ continue; // Can't happen
+
+ /* Remove all existing modes */
+ ChanUserContainer *cu = c->FindUser(bi);
+ if (cu != NULL)
+ for (size_t j = 0; j < cu->status.Modes().length(); ++j)
+ c->RemoveMode(bi, ModeManager::FindChannelModeByChar(cu->status.Modes()[j]), bi->GetUID());
+ /* Set the new modes */
+ for (unsigned j = 0; j < want_modes.length(); ++j)
+ {
+ ChannelMode *cm = ModeManager::FindChannelModeByChar(want_modes[j]);
+ if (cm == NULL)
+ cm = ModeManager::FindChannelModeByChar(ModeManager::GetStatusChar(want_modes[j]));
+ if (cm && cm->type == MODE_STATUS)
+ c->SetMode(bi, cm, bi->GetUID());
+ }
+ }
+ for (unsigned k = 0; k < oldchannels.size(); ++k)
+ {
+ size_t ch = oldchannels[k].find('#');
+ Anope::string chname = oldchannels[k].substr(ch != Anope::string::npos ? ch : 0);
+
+ bool found = false;
+ for (unsigned j = 0; j < bi->botchannels.size(); ++j)
+ {
+ ch = bi->botchannels[j].find('#');
+ Anope::string ochname = bi->botchannels[j].substr(ch != Anope::string::npos ? ch : 0);
+
+ if (chname.equals_ci(ochname))
+ found = true;
+ }
+
+ if (found)
+ continue;
+
+ Channel *c = Channel::Find(chname);
+ if (c)
+ bi->Part(c);
+ }
+ }
+
+ for (int i = 0; i < this->CountBlock("log"); ++i)
+ {
+ Block *log = this->GetBlock("log", i);
+
+ int logage = log->Get<int>("logage");
+ bool rawio = log->Get<bool>("rawio");
+ bool debug = log->Get<bool>("debug");
+
+ LogInfo l(logage, rawio, debug);
+
+ spacesepstream(log->Get<const Anope::string &>("target")).GetTokens(l.targets);
+ spacesepstream(log->Get<const Anope::string &>("source")).GetTokens(l.sources);
+ spacesepstream(log->Get<const Anope::string &>("admin")).GetTokens(l.admin);
+ spacesepstream(log->Get<const Anope::string &>("override")).GetTokens(l.override);
+ spacesepstream(log->Get<const Anope::string &>("commands")).GetTokens(l.commands);
+ spacesepstream(log->Get<const Anope::string &>("servers")).GetTokens(l.servers);
+ spacesepstream(log->Get<const Anope::string &>("channels")).GetTokens(l.channels);
+ spacesepstream(log->Get<const Anope::string &>("users")).GetTokens(l.users);
+ spacesepstream(log->Get<const Anope::string &>("normal")).GetTokens(l.normal);
+
+ this->LogInfos.push_back(l);
}
- return true;
-}
-static bool InitLogs(ServerConfig *config, const Anope::string &)
-{
- config->LogInfos.clear();
- return true;
-}
+ for (botinfo_map::const_iterator it = BotListByNick->begin(), it_end = BotListByNick->end(); it != it_end; ++it)
+ it->second->commands.clear();
+ for (int i = 0; i < this->CountBlock("command"); ++i)
+ {
+ Block *command = this->GetBlock("command", i);
-static bool DoLogs(ServerConfig *config, const Anope::string &, const Anope::string *, ValueList &values, int *)
-{
- //{"target", "source", "logage", "inhabit", "admin", "override", "commands", "servers", "channels", "users", "other", "rawio", "debug"},
- Anope::string targets = values[0].GetValue();
- ValueItem vi(targets);
- if (!ValidateNotEmpty(config, "log", "target", vi))
- throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
-
- Anope::string source = values[1].GetValue();
- int logage = values[2].GetInteger();
- Anope::string admin = values[3].GetValue();
- Anope::string override = values[4].GetValue();
- Anope::string commands = values[5].GetValue();
- Anope::string servers = values[6].GetValue();
- Anope::string channels = values[7].GetValue();
- Anope::string users = values[8].GetValue();
- Anope::string normal = values[9].GetValue();
- bool rawio = values[10].GetBool();
- bool ldebug = values[11].GetBool();
-
- LogInfo *l = new LogInfo(logage, rawio, ldebug);
- spacesepstream(targets).GetTokens(l->targets);
- spacesepstream(source).GetTokens(l->sources);
- spacesepstream(admin).GetTokens(l->admin);
- spacesepstream(override).GetTokens(l->override);
- spacesepstream(commands).GetTokens(l->commands);
- spacesepstream(servers).GetTokens(l->servers);
- spacesepstream(channels).GetTokens(l->channels);
- spacesepstream(users).GetTokens(l->users);
- spacesepstream(normal).GetTokens(l->normal);
-
- config->LogInfos.push_back(l);
+ const Anope::string &service = command->Get<const Anope::string &>("service"),
+ &nname = command->Get<const Anope::string &>("name"),
+ &cmd = command->Get<const Anope::string &>("command"),
+ &permission = command->Get<const Anope::string &>("permission"),
+ &group = command->Get<const Anope::string &>("group");
+ bool hide = command->Get<bool>("hide");
- return true;
-}
+ ValidateNotEmpty("command", "service", service);
+ ValidateNotEmpty("command", "name", nname);
+ ValidateNotEmpty("command", "command", cmd);
-static bool DoneLogs(ServerConfig *config, const Anope::string &)
-{
- Log() << "Loaded " << config->LogInfos.size() << " log blocks";
- return true;
-}
+ BotInfo *bi = BotInfo::Find(service, true);
+ if (!bi)
+ continue;
-/*************************************************************************/
+ CommandInfo &ci = bi->SetCommand(nname, cmd, permission);
+ ci.group = group;
+ ci.hide = hide;
+ }
-static bool InitCommands(ServerConfig *config, const Anope::string &)
-{
- for (botinfo_map::const_iterator it = BotListByNick->begin(), it_end = BotListByNick->end(); it != it_end; ++it)
+ PrivilegeManager::ClearPrivileges();
+ for (int i = 0; i < this->CountBlock("privilege"); ++i)
{
- BotInfo *bi = it->second;
- if (bi)
- {
- bi->QueueUpdate();
- bi->commands.clear();
- }
+ Block *privilege = this->GetBlock("privilege", i);
+
+ const Anope::string &nname = privilege->Get<const Anope::string &>("name"),
+ &desc = privilege->Get<const Anope::string &>("desc");
+ int rank = privilege->Get<int>("rank");
+
+ PrivilegeManager::AddPrivilege(Privilege(nname, desc, rank));
}
- return true;
-}
-static bool DoCommands(ServerConfig *config, const Anope::string &, const Anope::string *, ValueList &values, int *)
-{
- Anope::string service = values[0].GetValue();
- Anope::string name = values[1].GetValue();
- Anope::string command = values[2].GetValue();
- Anope::string permission = values[3].GetValue();
- Anope::string group = values[4].GetValue();
- bool hide = values[5].GetBool();
-
- ValueItem vi(service);
- if (!ValidateNotEmpty(config, "command", "service", vi))
- throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
-
- vi = ValueItem(name);
- if (!ValidateNotEmpty(config, "command", "name", vi))
- throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
-
- vi = ValueItem(command);
- if (!ValidateNotEmpty(config, "command", "command", vi))
- throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
-
- BotInfo *bi = BotInfo::Find(service);
- if (bi == NULL)
- throw ConfigException("Command " + name + " exists for nonexistant service " + service);
+ for (int i = 0; i < this->CountBlock("fantasy"); ++i)
+ {
+ Block *fantasy = this->GetBlock("fantasy", i);
- if (bi->commands.count(name))
- throw ConfigException("Command name " + name + " already exists on " + bi->nick);
+ const Anope::string &nname = fantasy->Get<const Anope::string &>("name"),
+ &service = fantasy->Get<const Anope::string &>("command"),
+ &permission = fantasy->Get<const Anope::string &>("permission"),
+ &group = fantasy->Get<const Anope::string &>("group");
+ bool hide = fantasy->Get<bool>("hide"),
+ prepend_channel = fantasy->Get<bool>("prepend_channel");
- CommandInfo &ci = bi->SetCommand(name, command, permission);
- ci.group = group;
- ci.hide = hide;
- return true;
-}
+ ValidateNotEmpty("fantasy", "name", nname);
+ ValidateNotEmpty("fantasy", "command", service);
-static bool DoneCommands(ServerConfig *config, const Anope::string &)
-{
- return true;
-}
+ CommandInfo &c = this->Fantasy[name];
+ c.name = service;
+ c.permission = permission;
+ c.group = group;
+ c.hide = hide;
+ c.prepend_channel = prepend_channel;
+ }
-/*************************************************************************/
+ for (int i = 0; i < this->CountBlock("command_group"); ++i)
+ {
+ Block *command_group = this->GetBlock("command_group", i);
-static bool InitPrivileges(ServerConfig *config, const Anope::string &)
-{
- PrivilegeManager::ClearPrivileges();
- return true;
-}
+ const Anope::string &nname = command_group->Get<const Anope::string &>("name"),
+ &description = command_group->Get<const Anope::string &>("description");
-static bool DoPrivileges(ServerConfig *config, const Anope::string &, const Anope::string *, ValueList &values, int *)
-{
- Anope::string name = values[0].GetValue();
- Anope::string desc = values[1].GetValue();
- int rank = values[2].GetInteger();
+ CommandGroup gr;
+ gr.name = nname;
+ gr.description = description;
- ValueItem vi(name);
- if (!ValidateNotEmpty(config, "privilege", "name", vi))
- throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
+ this->CommandGroups.push_back(gr);
+ }
- PrivilegeManager::AddPrivilege(Privilege(name, desc, rank));
- return true;
-}
+ /* Below here can't throw */
-static bool DonePrivileges(ServerConfig *config, const Anope::string &)
-{
- Log(LOG_DEBUG) << "Loaded " << PrivilegeManager::GetPrivileges().size() << " privileges";
- return true;
-}
+ for (nickcore_map::const_iterator it = NickCoreList->begin(), it_end = NickCoreList->end(); it != it_end; ++it)
+ {
+ NickCore *nc = it->second;
+ if (nc->o && nc->o->config)
+ nc->o = NULL;
+ }
+ for (unsigned i = 0; i < this->Opers.size(); ++i)
+ {
+ Oper *o = this->Opers[i];
-/*************************************************************************/
+ NickAlias *na = NickAlias::Find(o->name);
+ if (!na)
+ continue;
-static std::set<Anope::string> services;
-static bool InitServices(ServerConfig *config, const Anope::string &)
-{
- services.clear();
- return true;
-}
+ na->nc->o = o;
+ Log() << "Tied oper " << na->nc->display << " to type " << o->ot->GetName();
+ }
-static bool DoServices(ServerConfig *config, const Anope::string &, const Anope::string *, ValueList &values, int *)
-{
- Anope::string nick = values[0].GetValue();
- Anope::string user = values[1].GetValue();
- Anope::string host = values[2].GetValue();
- Anope::string gecos = values[3].GetValue();
- Anope::string modes = values[4].GetValue();
- Anope::string channels = values[5].GetValue();
-
- ValueItem vi(nick);
- if (!ValidateNotEmpty(config, "service", "nick", vi))
- throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
-
- vi = ValueItem(user);
- if (!ValidateNotEmpty(config, "service", "user", vi))
- throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
-
- vi = ValueItem(host);
- if (!ValidateNotEmpty(config, "service", "host", vi))
- throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
-
- vi = ValueItem(gecos);
- if (!ValidateNotEmpty(config, "service", "gecos", vi))
- throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
-
- services.insert(nick);
- BotInfo* bi = BotInfo::Find(nick);
- if (!bi)
- bi = new BotInfo(nick, user, host, gecos, modes);
- bi->conf = true;
-
- Anope::string token;
- commasepstream sep(channels);
- std::vector<Anope::string> oldchannels = bi->botchannels;
- bi->botchannels.clear();
- while (sep.GetToken(token))
+ if (options->Get<const Anope::string &>("casemap", "ascii") == "ascii")
+ Anope::casemap = std::locale(std::locale(), new Anope::ascii_ctype<char>());
+ else if (options->Get<const Anope::string &>("casemap") == "rfc1459")
+ Anope::casemap = std::locale(std::locale(), new Anope::rfc1459_ctype<char>());
+ else
{
- bi->botchannels.push_back(token);
- size_t ch = token.find('#');
- Anope::string chname, want_modes;
- if (ch == Anope::string::npos)
- chname = token;
- else
+ try
{
- want_modes = token.substr(0, ch);
- chname = token.substr(ch);
+ Anope::casemap = std::locale(options->Get<const char *>("casemap"));
}
- bi->Join(chname);
- Channel *c = Channel::Find(chname);
- if (!c)
- continue; // Can't happen
-
- /* Remove all existing modes */
- ChanUserContainer *cu = c->FindUser(bi);
- if (cu != NULL)
- for (size_t i = 0; i < cu->status.Modes().length(); ++i)
- c->RemoveMode(bi, ModeManager::FindChannelModeByChar(cu->status.Modes()[i]), bi->GetUID());
- /* Set the new modes */
- for (unsigned j = 0; j < want_modes.length(); ++j)
+ catch (const std::runtime_error &)
{
- ChannelMode *cm = ModeManager::FindChannelModeByChar(want_modes[j]);
- if (cm == NULL)
- cm = ModeManager::FindChannelModeByChar(ModeManager::GetStatusChar(want_modes[j]));
- if (cm && cm->type == MODE_STATUS)
- c->SetMode(bi, cm, bi->GetUID());
+ Log() << "Unknown casemap " << options->Get<const Anope::string &>("casemap") << " - casemap not changed";
}
}
- for (unsigned i = 0; i < oldchannels.size(); ++i)
- {
- size_t ch = oldchannels[i].find('#');
- Anope::string chname = oldchannels[i].substr(ch != Anope::string::npos ? ch : 0);
-
- bool found = false;
- for (unsigned j = 0; j < bi->botchannels.size(); ++j)
- {
- ch = bi->botchannels[j].find('#');
- Anope::string ochname = bi->botchannels[j].substr(ch != Anope::string::npos ? ch : 0);
-
- if (chname.equals_ci(ochname))
- found = true;
- }
+ Anope::CaseMapRebuild();
- if (found)
- continue;
+ /* Check the user keys */
+ if (!options->Get<unsigned>("seed"))
+ Log() << "Configuration option options:seed should be set. It's for YOUR safety! Remember that!";
- Channel *c = Channel::Find(chname);
- if (c)
- bi->Part(c);
+#ifndef _WIN32
+ if (!options->Get<const Anope::string &>("user").empty())
+ {
+ errno = 0;
+ struct passwd *u = getpwnam(options->Get<const char *>("user"));
+ if (u == NULL)
+ Log() << "Unable to setuid to " << options->Get<const Anope::string &>("user") << ": " << Anope::LastError();
+ else if (setuid(u->pw_uid) == -1)
+ Log() << "Unable to setuid to " << options->Get<const Anope::string &>("user") << ": " << Anope::LastError();
+ else
+ Log() << "Successfully set user to " << options->Get<const Anope::string &>("user");
}
-
- return true;
-}
-
-static bool DoneServices(ServerConfig *config, const Anope::string &)
-{
- for (botinfo_map::const_iterator it = BotListByNick->begin(), it_end = BotListByNick->end(); it != it_end;)
+ if (!options->Get<const Anope::string &>("group").empty())
{
- BotInfo *bi = it->second;
- ++it;
-
- if (bi->conf && services.count(bi->nick) == 0)
- delete bi;
+ errno = 0;
+ struct group *g = getgrnam(options->Get<const char *>("group"));
+ if (g == NULL)
+ Log() << "Unable to setgid to " << options->Get<const Anope::string &>("group") << ": " << Anope::LastError();
+ else if (setuid(g->gr_gid) == -1)
+ Log() << "Unable to setgid to " << options->Get<const Anope::string &>("group") << ": " << Anope::LastError();
+ else
+ Log() << "Successfully set group to " << options->Get<const Anope::string &>("group");
}
- services.clear();
- return true;
-}
-
-/*************************************************************************/
-
-static bool InitFantasy(ServerConfig *config, const Anope::string &)
-{
- config->Fantasy.clear();
- return true;
-}
-
-static bool DoFantasy(ServerConfig *config, const Anope::string &, const Anope::string *, ValueList &values, int *)
-{
- Anope::string name = values[0].GetValue();
- Anope::string service = values[1].GetValue();
- Anope::string permission = values[2].GetValue();
- Anope::string group = values[3].GetValue();
- bool hide = values[4].GetBool();
- bool prepend_channel = values[5].GetBool();
-
- CommandInfo &c = config->Fantasy[name];
-
- c.name = service;
- c.permission = permission;
- c.group = group;
- c.hide = hide;
- c.prepend_channel = prepend_channel;
-
- return true;
-}
+#endif
-static bool DoneFantasy(ServerConfig *config, const Anope::string &)
-{
- return true;
+ /* Apply module chnages */
+ if (Config)
+ {
+ for (unsigned i = 0; i < Config->ModulesAutoLoad.size(); ++i)
+ if (std::find(this->ModulesAutoLoad.begin(), this->ModulesAutoLoad.end(), Config->ModulesAutoLoad[i]) == this->ModulesAutoLoad.end())
+ ModuleManager::UnloadModule(ModuleManager::FindModule(Config->ModulesAutoLoad[i]), NULL);
+ for (unsigned i = 0; i < this->ModulesAutoLoad.size(); ++i)
+ if (std::find(Config->ModulesAutoLoad.begin(), Config->ModulesAutoLoad.end(), this->ModulesAutoLoad[i]) == Config->ModulesAutoLoad.end())
+ ModuleManager::LoadModule(this->ModulesAutoLoad[i], NULL);
+ }
}
-/*************************************************************************/
-
-static bool InitCommandGroups(ServerConfig *config, const Anope::string &)
+Block *Conf::GetModule(Module *m)
{
- config->CommandGroups.clear();
- return true;
+ if (!m)
+ return NULL;
+
+ return GetModule(m->name);
}
-static bool DoCommandGroups(ServerConfig *config, const Anope::string &, const Anope::string *, ValueList &values, int *)
+Block *Conf::GetModule(const Anope::string &mname)
{
- Anope::string name = values[0].GetValue();
- Anope::string description = values[1].GetValue();
+ std::map<Anope::string, Block *>::iterator it = modules.find(mname);
+ if (it != modules.end())
+ return it->second;
- if (name.empty() || description.empty())
- return true;
+ Block* &block = modules[mname];
+
+ /* Search for the block */
+ for (std::pair<block_map::iterator, block_map::iterator> iters = blocks.equal_range("module"); iters.first != iters.second; ++iters.first)
+ {
+ Block *b = &iters.first->second;
- CommandGroup gr;
- gr.name = name;
- gr.description = description;
+ if (b->Get<const Anope::string &>("name") == mname)
+ {
+ block = b;
+ break;
+ }
+ }
- config->CommandGroups.push_back(gr);
- return true;
+ return GetModule(mname);
}
-static bool DoneCommandGroups(ServerConfig *config, const Anope::string &)
+File::File(const Anope::string &n, bool e) : name(n), executable(e), fp(NULL)
{
- return true;
}
-/*************************************************************************/
-
-ConfigurationFile::ConfigurationFile(const Anope::string &n, bool e) : name(n), executable(e), fp(NULL)
-{
-}
-
-ConfigurationFile::~ConfigurationFile()
+File::~File()
{
this->Close();
}
-const Anope::string &ConfigurationFile::GetName() const
+const Anope::string &File::GetName() const
{
return this->name;
}
-bool ConfigurationFile::IsOpen() const
+bool File::IsOpen() const
{
return this->fp != NULL;
}
-bool ConfigurationFile::Open()
+bool File::Open()
{
this->Close();
this->fp = (this->executable ? popen(this->name.c_str(), "r") : fopen((Anope::ConfigDir + "/" + this->name).c_str(), "r"));
return this->fp != NULL;
}
-void ConfigurationFile::Close()
+void File::Close()
{
if (this->fp != NULL)
{
@@ -1050,12 +618,12 @@ void ConfigurationFile::Close()
}
}
-bool ConfigurationFile::End() const
+bool File::End() const
{
return !this->IsOpen() || feof(this->fp);
}
-Anope::string ConfigurationFile::Read()
+Anope::string File::Read()
{
Anope::string ret;
char buf[BUFSIZE];
@@ -1077,552 +645,50 @@ Anope::string ConfigurationFile::Read()
return ret;
}
-ConfigItems::ConfigItems(ServerConfig *conf)
+void Conf::LoadConf(File &file)
{
- // These tags can occur ONCE or not at all
- const Item Items[] = {
- /* The following comments are from CyberBotX to w00t as examples to use:
- *
- * The last argument, for validation, must use one of the functions with the following signature:
- * bool <function>(ServerConfig *, const char *, const char *, ValueItem &)
- * Examples are: NoValidation, ValidateNotEmpty, etc.
- *
- * If you want to create a directive using an integer:
- * int blarg;
- * {"tag", "value", "0", new ValueContainerInt(&conf->blarg), DT_INTEGER, <validation>},
- *
- * If you want to create a directive using an unsigned integer:
- * unsigned blarg;
- * {"tag", "value", "0", new ValueContainerUInt(&conf->blarg), DT_UINTEGER, <validation>},
- *
- * If you want to create a directive using a string:
- * Anope::string blarg;
- * {"tag", "value", "", new ValueContainerString(&conf->blarg), DT_STRING, <validation>},
- *
- * If you want to create a directive using a boolean:
- * bool blarg;
- * {"tag", "value", "no", new ValueContainerBool(&conf->blarg), DT_BOOLEAN, <validation>},
- *
- * If you want to create a directive using a character pointer specifically to hold a hostname (this will call ValidateHostname automatically):
- * char *blarg;
- * {"tag", "value", "", new ValueContainerChar(&conf->blarg), DT_HOSTNAME, <validation>},
- *
- * If you want to create a directive using a character pointer that specifically can not have spaces in it (this will call ValidateNoSpaces automatically):
- * char *blarg;
- * {"tag", "value", "", new ValueContainerChar(&conf->blarg), DT_NOSPACES, <validation>},
- *
- * If you want to create a directive using a character pointer specifically to hold an IP address (this will call ValidateIP automatically):
- * char *blarg;
- * {"tag", "value", "", new ValueContainerChar(&conf->blarg), DT_IPADDRESS, <validation>},
- *
- * If you want to create a directive using a time (a time_t variable converted from a string):
- * time_t blarg;
- * {"tag", "value", "", new ValueContainterTime(&conf->blarg), DT_TIME, <validation>},
- *
- * For the second-to-last argument, you can or (|) in the following values:
- * DT_NORELOAD - The variable can't be changed on a reload of the configuration
- * DT_ALLOW_WILD - Allows wildcards/CIDR in DT_IPADDRESS
- * DT_ALLOW_NEWLINE - Allows new line characters in DT_STRING
- *
- * We may need to add some other validation functions to handle certain things, we can handle that later.
- * Any questions about these, w00t, feel free to ask. */
- {"serverinfo", "name", "", new ValueContainerString(&conf->ServerName), DT_HOSTNAME | DT_NORELOAD, ValidateNotEmpty},
- {"serverinfo", "description", "", new ValueContainerString(&conf->ServerDesc), DT_STRING | DT_NORELOAD, ValidateNotEmpty},
- {"serverinfo", "localhost", "", new ValueContainerString(&conf->LocalHost), DT_HOSTNAME | DT_NORELOAD, NoValidation},
- {"serverinfo", "id", "", new ValueContainerString(&conf->Numeric), DT_NOSPACES | DT_NORELOAD, NoValidation},
- {"serverinfo", "pid", "data/services.pid", new ValueContainerString(&conf->PIDFilename), DT_STRING | DT_NORELOAD, ValidateNotEmpty},
- {"serverinfo", "motd", "conf/services.motd", new ValueContainerString(&conf->MOTDFilename), DT_STRING, ValidateNotEmpty},
- {"networkinfo", "networkname", "", new ValueContainerString(&conf->NetworkName), DT_STRING, ValidateNotEmpty},
- {"networkinfo", "nicklen", "31", new ValueContainerUInt(&conf->NickLen), DT_UINTEGER | DT_NORELOAD, ValidateNickLen},
- {"networkinfo", "userlen", "10", new ValueContainerUInt(&conf->UserLen), DT_UINTEGER | DT_NORELOAD, NoValidation},
- {"networkinfo", "hostlen", "64", new ValueContainerUInt(&conf->HostLen), DT_UINTEGER | DT_NORELOAD, NoValidation},
- {"networkinfo", "chanlen", "32", new ValueContainerUInt(&conf->ChanLen), DT_UINTEGER | DT_NORELOAD, NoValidation},
- {"networkinfo", "modelistsize", "0", new ValueContainerUInt(&conf->ListSize), DT_UINTEGER, NoValidation},
- {"options", "user", "", new ValueContainerString(&conf->User), DT_STRING, NoValidation},
- {"options", "group", "", new ValueContainerString(&conf->Group), DT_STRING, NoValidation},
- {"options", "casemap", "ascii", new ValueContainerString(&conf->CaseMap), DT_STRING, NoValidation},
- {"options", "passlen", "32", new ValueContainerUInt(&conf->PassLen), DT_UINTEGER | DT_NORELOAD, NoValidation},
- {"options", "seed", "0", new ValueContainerLUInt(&conf->Seed), DT_LUINTEGER, NoValidation},
- {"options", "nobackupokay", "no", new ValueContainerBool(&conf->NoBackupOkay), DT_BOOLEAN, NoValidation},
- {"options", "strictpasswords", "no", new ValueContainerBool(&conf->StrictPasswords), DT_BOOLEAN, NoValidation},
- {"options", "badpasslimit", "0", new ValueContainerUInt(&conf->BadPassLimit), DT_UINTEGER, NoValidation},
- {"options", "badpasstimeout", "0", new ValueContainerTime(&conf->BadPassTimeout), DT_TIME, NoValidation},
- {"options", "updatetimeout", "0", new ValueContainerTime(&conf->UpdateTimeout), DT_TIME, ValidateNotZero},
- {"options", "expiretimeout", "0", new ValueContainerTime(&conf->ExpireTimeout), DT_TIME, ValidateNotZero},
- {"options", "readtimeout", "0", new ValueContainerTime(&conf->ReadTimeout), DT_TIME, ValidateNotZero},
- {"options", "warningtimeout", "0", new ValueContainerTime(&conf->WarningTimeout), DT_TIME, ValidateNotZero},
- {"options", "timeoutcheck", "0", new ValueContainerTime(&conf->TimeoutCheck), DT_TIME, NoValidation},
- {"options", "keepbackups", "0", new ValueContainerInt(&conf->KeepBackups), DT_INTEGER, NoValidation},
- {"options", "forceforbidreason", "no", new ValueContainerBool(&conf->ForceForbidReason), DT_BOOLEAN, NoValidation},
- {"options", "useprivmsg", "no", new ValueContainerBool(&conf->UsePrivmsg), DT_BOOLEAN, NoValidation},
- {"options", "usestrictprivmsg", "no", new ValueContainerBool(&conf->UseStrictPrivMsg), DT_BOOLEAN, NoValidation},
- {"options", "hidestatso", "no", new ValueContainerBool(&conf->HideStatsO), DT_BOOLEAN, NoValidation},
- {"options", "nickregdelay", "0", new ValueContainerUInt(&conf->NickRegDelay), DT_UINTEGER, NoValidation},
- {"options", "restrictopernicks", "no", new ValueContainerBool(&conf->RestrictOperNicks), DT_BOOLEAN, NoValidation},
- {"options", "newscount", "3", new ValueContainerUInt(&conf->NewsCount), DT_UINTEGER, NoValidation},
- {"options", "ulineservers", "", new ValueContainerString(&UlineServers), DT_STRING, NoValidation},
- {"options", "botmodes", "", new ValueContainerString(&conf->BotModes), DT_STRING, NoValidation},
- {"options", "retrywait", "60", new ValueContainerInt(&conf->RetryWait), DT_INTEGER, ValidateNotZero},
- {"options", "hideprivilegedcommands", "yes", new ValueContainerBool(&conf->HidePrivilegedCommands), DT_BOOLEAN, NoValidation},
- {"options", "nonicknameownership", "no", new ValueContainerBool(&conf->NoNicknameOwnership), DT_BOOLEAN | DT_NORELOAD, NoValidation},
- {"options", "regexengine", "", new ValueContainerString(&conf->RegexEngine), DT_STRING, NoValidation},
- {"nickserv", "name", "", new ValueContainerString(&conf->NickServ), DT_STRING, NoValidation},
- {"nickserv", "registration", "none", new ValueContainerString(&conf->NSRegistration), DT_STRING, ValidateNickServ},
- {"nickserv", "unregistered_notice", "", new ValueContainerString(&conf->NSUnregisteredNotice), DT_STRING, NoValidation},
- {"nickserv", "forceemail", "no", new ValueContainerBool(&conf->NSForceEmail), DT_BOOLEAN, ValidateEmailReg},
- {"nickserv", "confirmemailchanges", "no", new ValueContainerBool(&conf->NSConfirmEmailChanges), DT_BOOLEAN, NoValidation},
- {"nickserv", "defaults", "secure memo_signon memo_receive", new ValueContainerString(&NSDefaults), DT_STRING, NoValidation},
- {"nickserv", "languages", "", new ValueContainerString(&conf->Languages), DT_STRING, NoValidation},
- {"nickserv", "defaultlanguage", "0", new ValueContainerString(&conf->NSDefLanguage), DT_STRING, NoValidation},
- {"nickserv", "regdelay", "0", new ValueContainerTime(&conf->NSRegDelay), DT_TIME, NoValidation},
- {"nickserv", "resenddelay", "0", new ValueContainerTime(&conf->NSResendDelay), DT_TIME, NoValidation},
- {"nickserv", "expire", "21d", new ValueContainerTime(&conf->NSExpire), DT_TIME, NoValidation},
- {"nickserv", "suspendexpire", "0", new ValueContainerTime(&conf->NSSuspendExpire), DT_TIME, NoValidation},
- {"nickserv", "unconfirmedexpire", "0", new ValueContainerTime(&conf->NSUnconfirmedExpire), DT_TIME, ValidateEmailReg},
- {"nickserv", "maxaliases", "0", new ValueContainerUInt(&conf->NSMaxAliases), DT_UINTEGER, NoValidation},
- {"nickserv", "accessmax", "0", new ValueContainerUInt(&conf->NSAccessMax), DT_UINTEGER, ValidateNickServ},
- {"nickserv", "enforceruser", "", new ValueContainerString(&conf->NSEnforcerUser), DT_STRING, ValidateNickServ},
- {"nickserv", "enforcerhost", "", new ValueContainerString(&conf->NSEnforcerHost), DT_STRING, ValidateNickServ},
- {"nickserv", "releasetimeout", "0", new ValueContainerTime(&conf->NSReleaseTimeout), DT_TIME, ValidateNickServ},
- {"nickserv", "allowkillimmed", "no", new ValueContainerBool(&conf->NSAllowKillImmed), DT_BOOLEAN | DT_NORELOAD, NoValidation},
- {"nickserv", "nogroupchange", "no", new ValueContainerBool(&conf->NSNoGroupChange), DT_BOOLEAN, NoValidation},
- {"nickserv", "listmax", "0", new ValueContainerUInt(&conf->NSListMax), DT_UINTEGER, ValidateNickServ},
- {"nickserv", "guestnickprefix", "", new ValueContainerString(&conf->NSGuestNickPrefix), DT_STRING, ValidateNickServ},
- {"nickserv", "secureadmins", "no", new ValueContainerBool(&conf->NSSecureAdmins), DT_BOOLEAN, NoValidation},
- {"nickserv", "strictprivileges", "no", new ValueContainerBool(&conf->NSStrictPrivileges), DT_BOOLEAN, NoValidation},
- {"nickserv", "modeonid", "no", new ValueContainerBool(&conf->NSModeOnID), DT_BOOLEAN, NoValidation},
- {"nickserv", "addaccessonreg", "no", new ValueContainerBool(&conf->NSAddAccessOnReg), DT_BOOLEAN, NoValidation},
- {"nickserv", "ajoinmax", "10", new ValueContainerUInt(&conf->AJoinMax), DT_UINTEGER, NoValidation},
- {"nickserv", "killquick", "20", new ValueContainerTime(&conf->NSKillQuick), DT_TIME, NoValidation},
- {"nickserv", "kill", "60", new ValueContainerTime(&conf->NSKill), DT_TIME, NoValidation},
- {"nickserv", "modesonid", "", new ValueContainerString(&conf->NSModesOnID), DT_STRING, NoValidation},
- {"nickserv", "restoreonrecover", "yes", new ValueContainerBool(&conf->NSRestoreOnRecover), DT_BOOLEAN, NoValidation},
- {"nickserv", "sasl", "yes", new ValueContainerBool(&conf->NSSASL), DT_BOOLEAN, NoValidation},
- {"nickserv", "hidenetsplitquit", "no", new ValueContainerBool(&conf->NSHideNetSplitQuit), DT_BOOLEAN, NoValidation},
- {"mail", "usemail", "no", new ValueContainerBool(&conf->UseMail), DT_BOOLEAN, ValidateEmailReg},
- {"mail", "sendmailpath", "", new ValueContainerString(&conf->SendMailPath), DT_STRING, ValidateMail},
- {"mail", "sendfrom", "", new ValueContainerString(&conf->SendFrom), DT_STRING, ValidateMail},
- {"mail", "restrict", "no", new ValueContainerBool(&conf->RestrictMail), DT_BOOLEAN, NoValidation},
- {"mail", "delay", "0", new ValueContainerTime(&conf->MailDelay), DT_TIME, NoValidation},
- {"mail", "dontquoteaddresses", "no", new ValueContainerBool(&conf->DontQuoteAddresses), DT_BOOLEAN, NoValidation},
- {"mail", "registration_subject", "", new ValueContainerString(&conf->MailRegistrationSubject), DT_STRING, ValidateMail},
- {"mail", "registration_message", "", new ValueContainerString(&conf->MailRegistrationMessage), DT_STRING | DT_ALLOW_NEWLINE, ValidateMail},
- {"mail", "reset_subject", "", new ValueContainerString(&conf->MailResetSubject), DT_STRING, ValidateMail},
- {"mail", "reset_message", "", new ValueContainerString(&conf->MailResetMessage), DT_STRING | DT_ALLOW_NEWLINE, ValidateMail},
- {"mail", "emailchange_subject", "", new ValueContainerString(&conf->MailEmailchangeSubject), DT_STRING, ValidateMail},
- {"mail", "emailchange_message", "", new ValueContainerString(&conf->MailEmailchangeMessage), DT_STRING | DT_ALLOW_NEWLINE, ValidateMail},
- {"mail", "memo_subject", "", new ValueContainerString(&conf->MailMemoSubject), DT_STRING, ValidateMail},
- {"mail", "memo_message", "", new ValueContainerString(&conf->MailMemoMessage), DT_STRING | DT_ALLOW_NEWLINE, ValidateMail},
- {"chanserv", "name", "", new ValueContainerString(&conf->ChanServ), DT_STRING, NoValidation},
- {"chanserv", "defaults", "keeptopic secure securefounder signkick", new ValueContainerString(&CSDefaults), DT_STRING, ValidateChanServ},
- {"chanserv", "maxregistered", "0", new ValueContainerUInt(&conf->CSMaxReg), DT_UINTEGER, ValidateChanServ},
- {"chanserv", "expire", "14d", new ValueContainerTime(&conf->CSExpire), DT_TIME, ValidateChanServ},
- {"chanserv", "suspendexpire", "0", new ValueContainerTime(&conf->CSSuspendExpire), DT_TIME, NoValidation},
- {"chanserv", "forbidexpire", "0", new ValueContainerTime(&conf->CSForbidExpire), DT_TIME, NoValidation},
- {"chanserv", "defbantype", "2", new ValueContainerInt(&conf->CSDefBantype), DT_INTEGER, ValidateChanServ},
- {"chanserv", "accessmax", "0", new ValueContainerUInt(&conf->CSAccessMax), DT_UINTEGER, ValidateChanServ},
- {"chanserv", "autokickmax", "0", new ValueContainerUInt(&conf->CSAutokickMax), DT_UINTEGER, ValidateChanServ},
- {"chanserv", "autokickreason", "User has been banned from the channel", new ValueContainerString(&conf->CSAutokickReason), DT_STRING, ValidateChanServ},
- {"chanserv", "inhabit", "0", new ValueContainerTime(&conf->CSInhabit), DT_TIME, ValidateChanServ},
- {"chanserv", "listmax", "0", new ValueContainerUInt(&conf->CSListMax), DT_UINTEGER, ValidateChanServ},
- {"chanserv", "opersonly", "no", new ValueContainerBool(&conf->CSOpersOnly), DT_BOOLEAN, ValidateChanServ},
- {"chanserv", "mlock", "+nrt", new ValueContainerString(&conf->MLock), DT_STRING | DT_ALLOW_EMPTY, NoValidation},
- {"chanserv", "nomlock", "", new ValueContainerString(&conf->NoMLock), DT_STRING, NoValidation},
- {"chanserv", "require", "", new ValueContainerString(&conf->CSRequire), DT_STRING, NoValidation},
- {"chanserv", "use_server_side_mlock", "yes", new ValueContainerBool(&conf->UseServerSideMLock), DT_BOOLEAN, NoValidation},
- {"chanserv", "use_server_side_topiclock", "yes", new ValueContainerBool(&conf->UseServerSideTopicLock), DT_BOOLEAN, NoValidation},
- {"chanserv", "reasonmax", "200", new ValueContainerUInt(&conf->CSReasonMax), DT_UINTEGER, NoValidation},
- {"memoserv", "name", "", new ValueContainerString(&conf->MemoServ), DT_STRING, NoValidation},
- {"memoserv", "maxmemos", "0", new ValueContainerUInt(&conf->MSMaxMemos), DT_UINTEGER, NoValidation},
- {"memoserv", "senddelay", "0", new ValueContainerTime(&conf->MSSendDelay), DT_TIME, NoValidation},
- {"memoserv", "notifyall", "no", new ValueContainerBool(&conf->MSNotifyAll), DT_BOOLEAN, NoValidation},
- {"memoserv", "memoreceipt", "0", new ValueContainerUInt(&conf->MSMemoReceipt), DT_UINTEGER, NoValidation},
- {"hostserv", "name", "", new ValueContainerString(&conf->HostServ), DT_STRING, NoValidation},
- {"hostserv", "vhost_chars", "abcdefghijklmnopqrstuvwxyzABCDEFGHIJMLMNOPQRSTUVWXYZ0123456789.-", new ValueContainerString(&conf->VhostChars), DT_STRING, NoValidation},
- {"hostserv", "allow_undotted_vhosts", "false", new ValueContainerBool(&conf->VhostUndotted), DT_BOOLEAN, NoValidation},
- {"hostserv", "disallow_start_or_end", "", new ValueContainerString(&conf->VhostDisallowBE), DT_STRING, NoValidation},
- {"botserv", "name", "", new ValueContainerString(&conf->BotServ), DT_STRING, NoValidation},
- {"botserv", "defaults", "", new ValueContainerString(&BSDefaults), DT_STRING, NoValidation},
- {"botserv", "minusers", "0", new ValueContainerUInt(&conf->BSMinUsers), DT_UINTEGER, ValidateBotServ},
- {"botserv", "badwordsmax", "0", new ValueContainerUInt(&conf->BSBadWordsMax), DT_UINTEGER, ValidateBotServ},
- {"botserv", "keepdata", "0", new ValueContainerTime(&conf->BSKeepData), DT_TIME, ValidateBotServ},
- {"botserv", "smartjoin", "no", new ValueContainerBool(&conf->BSSmartJoin), DT_BOOLEAN, NoValidation},
- {"botserv", "gentlebadwordreason", "no", new ValueContainerBool(&conf->BSGentleBWReason), DT_BOOLEAN, NoValidation},
- {"botserv", "casesensitive", "no", new ValueContainerBool(&conf->BSCaseSensitive), DT_BOOLEAN, NoValidation},
- {"botserv", "fantasycharacter", "!", new ValueContainerString(&conf->BSFantasyCharacter), DT_STRING | DT_ALLOW_EMPTY, NoValidation},
- {"operserv", "name", "", new ValueContainerString(&conf->OperServ), DT_STRING, NoValidation},
- {"operserv", "superadmin", "no", new ValueContainerBool(&conf->SuperAdmin), DT_BOOLEAN, NoValidation},
- {"operserv", "autokillexpiry", "0", new ValueContainerTime(&conf->AutokillExpiry), DT_TIME, ValidateOperServ},
- {"operserv", "chankillexpiry", "0", new ValueContainerTime(&conf->ChankillExpiry), DT_TIME, ValidateOperServ},
- {"operserv", "snlineexpiry", "0", new ValueContainerTime(&conf->SNLineExpiry), DT_TIME, ValidateOperServ},
- {"operserv", "sqlineexpiry", "0", new ValueContainerTime(&conf->SQLineExpiry), DT_TIME, ValidateOperServ},
- {"operserv", "akillonadd", "no", new ValueContainerBool(&conf->AkillOnAdd), DT_BOOLEAN, NoValidation},
- {"operserv", "killonsnline", "no", new ValueContainerBool(&conf->KillonSNline), DT_BOOLEAN, NoValidation},
- {"operserv", "killonsqline", "no", new ValueContainerBool(&conf->KillonSQline), DT_BOOLEAN, NoValidation},
- {"operserv", "limitsessions", "no", new ValueContainerBool(&conf->LimitSessions), DT_BOOLEAN, NoValidation},
- {"operserv", "defaultsessionlimit", "0", new ValueContainerUInt(&conf->DefSessionLimit), DT_UINTEGER, NoValidation},
- {"operserv", "maxsessionlimit", "0", new ValueContainerUInt(&conf->MaxSessionLimit), DT_UINTEGER, ValidateOperServ},
- {"operserv", "exceptionexpiry", "0", new ValueContainerTime(&conf->ExceptionExpiry), DT_TIME, ValidateOperServ},
- {"operserv", "sessionlimitexceeded", "", new ValueContainerString(&conf->SessionLimitExceeded), DT_STRING, NoValidation},
- {"operserv", "sessionlimitdetailsloc", "", new ValueContainerString(&conf->SessionLimitDetailsLoc), DT_STRING, NoValidation},
- {"operserv", "maxsessionkill", "0", new ValueContainerUInt(&conf->MaxSessionKill), DT_UINTEGER, NoValidation},
- {"operserv", "sessionautokillexpiry", "0", new ValueContainerTime(&conf->SessionAutoKillExpiry), DT_TIME, NoValidation},
- {"operserv", "session_ipv4_cidr", "32", new ValueContainerUInt(&conf->SessionIPv4CIDR), DT_UINTEGER | DT_NORELOAD, NoValidation},
- {"operserv", "session_ipv6_cidr", "128", new ValueContainerUInt(&conf->SessionIPv6CIDR), DT_UINTEGER | DT_NORELOAD, NoValidation},
- {"operserv", "addakiller", "no", new ValueContainerBool(&conf->AddAkiller), DT_BOOLEAN, NoValidation},
- {"operserv", "akillids", "no", new ValueContainerBool(&conf->AkillIds), DT_BOOLEAN, NoValidation},
- {"operserv", "opersonly", "no", new ValueContainerBool(&conf->OSOpersOnly), DT_BOOLEAN, NoValidation},
- {"global", "name", "", new ValueContainerString(&conf->Global), DT_STRING, NoValidation},
- {"global", "globaloncycle", "no", new ValueContainerBool(&conf->GlobalOnCycle), DT_BOOLEAN, NoValidation},
- {"global", "globaloncycledown", "", new ValueContainerString(&conf->GlobalOnCycleMessage), DT_STRING, ValidateGlobalOnCycle},
- {"global", "globaloncycleup", "", new ValueContainerString(&conf->GlobalOnCycleUP), DT_STRING, ValidateGlobalOnCycle},
- {"global", "anonymousglobal", "no", new ValueContainerBool(&conf->AnonymousGlobal), DT_BOOLEAN, NoValidation},
- {"", "", "", NULL, DT_NOTHING, NoValidation}
- };
-
- /* These tags can occur multiple times, and therefore they have special code to read them
- * which is different to the code for reading the singular tags listed above. */
- MultiItem MultiItems[] = {
- /* Include must be first so we can pull in the extra files before processing
- * anything else! */
- {"include",
- {"type", "name", ""},
- {"", "", ""},
- {DT_STRING, DT_STRING},
- InitInclude, DoInclude, DoneInclude},
- {"define",
- {"name", "value", ""},
- {"", "", ""},
- {DT_STRING, DT_STRING},
- InitDefine, DoDefine, DoneDefine},
- {"uplink",
- {"host", "ipv6", "port", "password", ""},
- {"", "no", "0", "", ""},
- {DT_HOSTNAME | DT_NORELOAD, DT_BOOLEAN | DT_NORELOAD, DT_UINTEGER | DT_NORELOAD, DT_NOSPACES | DT_NORELOAD},
- InitUplinks, DoUplink, DoneUplinks},
- {"module",
- {"name", ""},
- {"", ""},
- {DT_STRING},
- InitModules, DoModule, DoneModules},
- {"opertype",
- {"name", "inherits", "commands", "privs", "modes", ""},
- {"", "", "", "", "", ""},
- {DT_STRING, DT_STRING, DT_STRING, DT_STRING, DT_STRING},
- InitOperTypes, DoOperType, DoneOperTypes},
- {"oper",
- {"name", "type", "require_oper", "password", "certfp", "host", "vhost", ""},
- {"", "", "yes", "", "", "", "", ""},
- {DT_STRING, DT_STRING, DT_BOOLEAN, DT_STRING, DT_STRING, DT_STRING, DT_STRING},
- InitOpers, DoOper, DoneOpers},
- {"service",
- {"nick", "user", "host", "gecos", "modes", "channels", ""},
- {"", "", "", "", "", "", ""},
- {DT_STRING, DT_STRING, DT_STRING, DT_STRING, DT_STRING, DT_STRING},
- InitServices, DoServices, DoneServices},
- {"log",
- {"target", "source", "logage", "admin", "override", "commands", "servers", "channels", "users", "other", "rawio", "debug", ""},
- {"", "", "7", "", "", "", "", "", "", "", "no", "no", ""},
- {DT_STRING, DT_STRING, DT_INTEGER, DT_STRING, DT_STRING, DT_STRING, DT_STRING, DT_STRING, DT_STRING, DT_STRING, DT_BOOLEAN, DT_BOOLEAN},
- InitLogs, DoLogs, DoneLogs},
- {"command",
- {"service", "name", "command", "permission", "group", "hide", ""},
- {"", "", "", "", "", "no", ""},
- {DT_STRING, DT_STRING, DT_STRING, DT_STRING, DT_STRING, DT_BOOLEAN},
- InitCommands, DoCommands, DoneCommands},
- {"privilege",
- {"name", "desc", "rank", ""},
- {"", "", "", ""},
- {DT_STRING, DT_STRING, DT_INTEGER, DT_STRING},
- InitPrivileges, DoPrivileges, DonePrivileges},
- {"fantasy",
- {"name", "command", "permission", "group", "hide", "prepend_channel", ""},
- {"", "", "", "", "no", "yes", ""},
- {DT_STRING, DT_STRING, DT_STRING, DT_STRING, DT_BOOLEAN, DT_BOOLEAN},
- InitFantasy, DoFantasy, DoneFantasy},
- {"command_group",
- {"name", "description", ""},
- {"", "", ""},
- {DT_STRING, DT_STRING},
- InitCommandGroups, DoCommandGroups, DoneCommandGroups},
- {"",
- {""},
- {""},
- {0},
- NULL, NULL, NULL}
- };
-
- this->Values = new Item[sizeof(Items) / sizeof(Item)];
- for (unsigned i = 0; i < sizeof(Items) / sizeof(Item); ++i)
- this->Values[i] = Items[i];
-
- this->MultiValues = new MultiItem[sizeof(MultiItems) / sizeof(MultiItem)];
- for (unsigned i = 0; i < sizeof(MultiItems) / sizeof(MultiItem); ++i)
- this->MultiValues[i] = MultiItems[i];
-}
-
-ConfigItems::~ConfigItems()
-{
- for (unsigned i = 0; !this->Values[i].tag.empty(); ++i)
- delete this->Values[i].val;
- delete [] this->Values;
- delete [] this->MultiValues;
-}
-
-void ServerConfig::Read()
-{
- // These tags MUST occur and must ONLY occur once in the config file
- static const Anope::string Once[] = {"serverinfo", "networkinfo", "options", ""};
-
- this->LoadConf(ServicesConf);
-
- ConfigItems configitems(this);
-
- /* Read the multiple-tag items (class tags, connect tags, etc)
- * and call the callbacks associated with them. We have three
- * callbacks for these, a 'start', 'item' and 'end' callback. */
- for (int Index = 0; !configitems.MultiValues[Index].tag.empty(); ++Index)
- {
- configitems.MultiValues[Index].init_function(this, configitems.MultiValues[Index].tag);
- int number_of_tags = ConfValueEnum(config_data, configitems.MultiValues[Index].tag);
- for (int tagnum = 0; tagnum < number_of_tags; ++tagnum)
- {
- ValueList vl;
- vl.clear();
- for (int valuenum = 0; !configitems.MultiValues[Index].items[valuenum].empty(); ++valuenum)
- {
- int dt = configitems.MultiValues[Index].datatype[valuenum];
- bool allow_newlines = dt & DT_ALLOW_NEWLINE, allow_wild = dt & DT_ALLOW_WILD, noreload = dt & DT_NORELOAD, allow_empty = dt & DT_ALLOW_EMPTY;
- dt &= ~DT_ALLOW_NEWLINE;
- dt &= ~DT_ALLOW_WILD;
- dt &= ~DT_NORELOAD;
- dt &= ~DT_ALLOW_EMPTY;
-
- ConfigDataHash &hash = (noreload && Config ? Config->config_data : this->config_data);
- Anope::string item;
- bool has_value = ConfValue(hash, configitems.MultiValues[Index].tag, configitems.MultiValues[Index].items[valuenum], configitems.MultiValues[Index].items_default[valuenum], tagnum, item, allow_newlines);
- if (defines.count(item) > 0)
- item = defines[item];
-
- if (has_value && item.empty() && !allow_empty)
- throw ConfigException("Item without value: " + configitems.MultiValues[Index].tag + ":" + configitems.MultiValues[Index].items[valuenum]);
-
- switch (dt)
- {
- case DT_NOSPACES:
- {
- if (has_value)
- vl.push_back(ValueItem(item));
- else
- vl.push_back(ValueItem());
- ValidateNoSpaces(vl[vl.size() - 1].GetValue(), configitems.MultiValues[Index].tag, configitems.MultiValues[Index].items[valuenum]);
- break;
- }
- case DT_HOSTNAME:
- {
- if (has_value)
- vl.push_back(ValueItem(item));
- else
- vl.push_back(ValueItem());
- ValidateHostname(vl[vl.size() - 1].GetValue(), configitems.MultiValues[Index].tag, configitems.MultiValues[Index].items[valuenum]);
- break;
- }
- case DT_IPADDRESS:
- {
- if (has_value)
- vl.push_back(ValueItem(item));
- else
- vl.push_back(ValueItem());
- ValidateIP(vl[vl.size() - 1].GetValue(), configitems.MultiValues[Index].tag, configitems.MultiValues[Index].items[valuenum], allow_wild);
- break;
- }
- case DT_STRING:
- {
- if (has_value)
- vl.push_back(ValueItem(item));
- else
- vl.push_back(ValueItem());
- break;
- }
- case DT_INTEGER:
- case DT_UINTEGER:
- case DT_LUINTEGER:
- {
- int titem = 0;
- if (ConfValueInteger(hash, configitems.MultiValues[Index].tag, configitems.MultiValues[Index].items[valuenum], configitems.MultiValues[Index].items_default[valuenum], tagnum, titem))
- vl.push_back(ValueItem(titem));
- else
- vl.push_back(ValueItem(0));
- break;
- }
- case DT_TIME:
- {
- if (has_value)
- {
-#ifdef _WIN32
- long time = static_cast<long>(Anope::DoTime(item));
-#else
- time_t time = Anope::DoTime(item);
-#endif
- vl.push_back(ValueItem(time));
- }
- else
- vl.push_back(ValueItem(0));
- break;
- }
- case DT_BOOLEAN:
- {
- bool titem = ConfValueBool(hash, configitems.MultiValues[Index].tag, configitems.MultiValues[Index].items[valuenum], configitems.MultiValues[Index].items_default[valuenum], tagnum);
- vl.push_back(ValueItem(titem));
- }
- }
- }
- configitems.MultiValues[Index].validation_function(this, configitems.MultiValues[Index].tag, configitems.MultiValues[Index].items, vl, configitems.MultiValues[Index].datatype);
- }
- configitems.MultiValues[Index].finish_function(this, configitems.MultiValues[Index].tag);
- }
-
- // Read the values of all the tags which occur once or not at all, and call their callbacks.
- for (int Index = 0; !configitems.Values[Index].tag.empty(); ++Index)
- {
- Anope::string item;
- int dt = configitems.Values[Index].datatype;
- bool allow_newlines = dt & DT_ALLOW_NEWLINE, allow_wild = dt & DT_ALLOW_WILD, noreload = dt & DT_NORELOAD, allow_empty = dt & DT_ALLOW_EMPTY;
- dt &= ~DT_ALLOW_NEWLINE;
- dt &= ~DT_ALLOW_WILD;
- dt &= ~DT_NORELOAD;
- dt &= ~DT_ALLOW_EMPTY;
-
- ConfigDataHash &hash = (noreload && Config ? Config->config_data : this->config_data);
- bool has_value = ConfValue(hash, configitems.Values[Index].tag, configitems.Values[Index].value, configitems.Values[Index].default_value, 0, item, allow_newlines);
- if (defines.count(item) > 0)
- item = defines[item];
-
- if (has_value && item.empty() && !allow_empty)
- throw ConfigException("Item without value: " + configitems.Values[Index].tag + ":" + configitems.Values[Index].value);
-
- ValueItem vi(item);
-
- if (!configitems.Values[Index].validation_function(this, configitems.Values[Index].tag, configitems.Values[Index].value, vi))
- throw ConfigException("One or more values in your configuration file failed to validate. Please see your logfiles for more information.");
-
- switch (dt)
- {
- case DT_NOSPACES:
- {
- ValueContainerString *vcs = anope_dynamic_static_cast<ValueContainerString *>(configitems.Values[Index].val);
- ValidateNoSpaces(vi.GetValue(), configitems.Values[Index].tag, configitems.Values[Index].value);
- vcs->Set(vi.GetValue());
- break;
- }
- case DT_HOSTNAME:
- {
- ValueContainerString *vcs = anope_dynamic_static_cast<ValueContainerString *>(configitems.Values[Index].val);
- ValidateHostname(vi.GetValue(), configitems.Values[Index].tag, configitems.Values[Index].value);
- vcs->Set(vi.GetValue());
- break;
- }
- case DT_IPADDRESS:
- {
- ValueContainerString *vcs = anope_dynamic_static_cast<ValueContainerString *>(configitems.Values[Index].val);
- ValidateIP(vi.GetValue(), configitems.Values[Index].tag, configitems.Values[Index].value, allow_wild);
- vcs->Set(vi.GetValue());
- break;
- }
- case DT_STRING:
- {
- ValueContainerString *vcs = anope_dynamic_static_cast<ValueContainerString *>(configitems.Values[Index].val);
- vcs->Set(vi.GetValue());
- break;
- }
- case DT_INTEGER:
- {
- int val = vi.GetInteger();
- ValueContainerInt *vci = anope_dynamic_static_cast<ValueContainerInt *>(configitems.Values[Index].val);
- vci->Set(&val, sizeof(int));
- break;
- }
- case DT_UINTEGER:
- {
- unsigned val = vi.GetInteger();
- ValueContainerUInt *vci = anope_dynamic_static_cast<ValueContainerUInt *>(configitems.Values[Index].val);
- vci->Set(&val, sizeof(unsigned));
- break;
- }
- case DT_LUINTEGER:
- {
- unsigned long val = vi.GetInteger();
- ValueContainerLUInt *vci = anope_dynamic_static_cast<ValueContainerLUInt *>(configitems.Values[Index].val);
- vci->Set(&val, sizeof(unsigned long));
- break;
- }
- case DT_TIME:
- {
- time_t time = Anope::DoTime(vi.GetValue());
- ValueContainerTime *vci = anope_dynamic_static_cast<ValueContainerTime *>(configitems.Values[Index].val);
- vci->Set(&time, sizeof(time_t));
- break;
- }
- case DT_BOOLEAN:
- {
- bool val = vi.GetBool();
- ValueContainerBool *vcb = anope_dynamic_static_cast<ValueContainerBool *>(configitems.Values[Index].val);
- vcb->Set(&val, sizeof(bool));
- break;
- }
- default:
- break;
- }
- }
-
- Log(LOG_DEBUG) << "End config " << ServicesConf.GetName();
- for (int Index = 0; !Once[Index].empty(); ++Index)
- CheckOnce(Once[Index]);
- Log() << "Done reading configuration file " << ServicesConf.GetName();
-}
-
-void ServerConfig::LoadConf(ConfigurationFile &file)
-{
- Anope::string section, wordbuffer, itemname;
- int linenumber = 0;
- bool in_word = false, in_quote = false, in_ml_comment = false;
- KeyValList sectiondata;
if (!file.Open())
- {
throw ConfigException("File " + file.GetName() + " could not be opened.");
- }
+
+ Anope::string itemname, wordbuffer;
+ std::stack<Block *> block_stack;
+ int linenumber = 0;
+ bool in_word = false, in_quote = false, in_comment = false;
+
Log(LOG_DEBUG) << "Start to read conf " << file.GetName();
// Start reading characters...
while (!file.End())
{
Anope::string line = file.Read();
++linenumber;
- unsigned c = 0, len = line.length();
- for (; c < len; ++c)
+
+ for (unsigned c = 0, len = line.length(); c < len; ++c)
{
char ch = line[c];
if (in_quote)
{
- /* Strip leading white spaces from multi line comments */
+ /* Strip leading white spaces from multi line quotes */
if (c == 0)
{
+ wordbuffer += "\n";
while (c < len && isspace(line[c]))
++c;
ch = line[c];
}
+
/* Allow \" in quotes */
if (ch == '\\' && c + 1 < len && line[c + 1] == '"')
wordbuffer += line[++c];
else if (ch == '"')
in_quote = in_word = false;
- else
+ else if (ch)
wordbuffer += ch;
}
- else if (in_ml_comment)
+ else if (in_comment)
{
if (ch == '*' && c + 1 < len && line[c + 1] == '/')
{
- in_ml_comment = false;
+ in_comment = false;
++c;
}
continue;
@@ -1632,7 +698,7 @@ void ServerConfig::LoadConf(ConfigurationFile &file)
else if (ch == '/' && c + 1 < len && line[c + 1] == '*')
{
// Multiline (or less than one line) comment
- in_ml_comment = true;
+ in_comment = true;
++c;
continue;
}
@@ -1641,7 +707,7 @@ void ServerConfig::LoadConf(ConfigurationFile &file)
else if (ch == '"')
{
// Quotes are valid only in the value position
- if (section.empty() || itemname.empty())
+ if (block_stack.empty() || itemname.empty())
{
file.Close();
throw ConfigException("Unexpected quoted string: " + file.GetName() + ":" + stringify(linenumber));
@@ -1655,36 +721,45 @@ void ServerConfig::LoadConf(ConfigurationFile &file)
}
else if (ch == '=')
{
- if (section.empty())
+ if (block_stack.empty())
{
file.Close();
throw ConfigException("Config item outside of section (or stray '='): " + file.GetName() + ":" + stringify(linenumber));
}
- if (!itemname.empty())
+
+ if (!itemname.empty() || wordbuffer.empty())
{
file.Close();
throw ConfigException("Stray '=' sign or item without value: " + file.GetName() + ":" + stringify(linenumber));
}
- if (in_word)
- in_word = false;
+
+ in_word = false;
itemname = wordbuffer;
wordbuffer.clear();
}
else if (ch == '{')
{
- if (!section.empty())
- {
- file.Close();
- throw ConfigException("Section inside another section: " + file.GetName() + ":" + stringify(linenumber));
- }
if (wordbuffer.empty())
{
- file.Close();
- throw ConfigException("Section without a name or unexpected '{': " + file.GetName() + ":" + stringify(linenumber));
+ block_stack.push(NULL);
+ // Commented or unnamed section
+ continue;
}
- if (in_word)
+
+ if (!block_stack.empty() && !block_stack.top())
+ {
+ // Named block inside of a commented block
in_word = false;
- section = wordbuffer;
+ wordbuffer.clear();
+ block_stack.push(NULL);
+ continue;
+ }
+
+ Block *b = block_stack.empty() ? this : block_stack.top();
+ block_map::iterator it = b->blocks.insert(std::make_pair(wordbuffer, Configuration::Block(wordbuffer)));
+ block_stack.push(&it->second);
+
+ in_word = false;
wordbuffer.clear();
continue;
}
@@ -1720,30 +795,59 @@ void ServerConfig::LoadConf(ConfigurationFile &file)
wordbuffer += "\n";
continue;
}
+
in_word = false;
if (!itemname.empty())
{
- Log(LOG_DEBUG) << "ln " << linenumber << " EOL: s='" << section << "' '" << itemname << "' set to '" << wordbuffer << "'";
- sectiondata.push_back(KeyVal(itemname, wordbuffer));
+ if (block_stack.empty())
+ {
+ file.Close();
+ throw ConfigException("Stray ';' outside of block: " + file.GetName() + ":" + stringify(linenumber));
+ }
+
+ Block *b = block_stack.top();
+
+ if (b)
+ Log(LOG_DEBUG) << "ln " << linenumber << " EOL: s='" << b->name << "' '" << itemname << "' set to '" << wordbuffer << "'";
+
+ if (itemname.empty())
+ {
+ file.Close();
+ throw ConfigException("Item without a name: " + file.GetName() + ":" + stringify(linenumber));
+ }
+
+ /* Check defines */
+ for (int i = 0; i < this->CountBlock("define"); ++i)
+ {
+ Block *define = this->GetBlock("define", i);
+
+ const Anope::string &dname = define->Get<const Anope::string &>("name");
+
+ if (dname == wordbuffer)
+ wordbuffer = define->Get<const Anope::string &>("value");
+ }
+
+ if (b)
+ b->items[itemname] = wordbuffer;
+
wordbuffer.clear();
itemname.clear();
}
if (ch == '}')
{
- if (section.empty())
+ if (block_stack.empty())
{
file.Close();
throw ConfigException("Stray '}': " + file.GetName() + ":" + stringify(linenumber));
}
- this->config_data.insert(std::pair<Anope::string, KeyValList>(section, sectiondata));
- section.clear();
- sectiondata.clear();
+
+ block_stack.pop();
}
}
}
}
- if (in_ml_comment)
+ if (in_comment)
{
file.Close();
throw ConfigException("Unterminated multiline comment at end of file: " + file.GetName());
@@ -1758,212 +862,7 @@ void ServerConfig::LoadConf(ConfigurationFile &file)
file.Close();
throw ConfigException("Unexpected garbage at end of file: " + file.GetName());
}
- if (!section.empty())
- {
- file.Close();
- throw ConfigException("Unterminated section at end of file: " + file.GetName());
- }
file.Close();
}
-bool ServerConfig::ConfValue(ConfigDataHash &target, const Anope::string &tag, const Anope::string &var, int index, Anope::string &result, bool allow_linefeeds)
-{
- return ConfValue(target, tag, var, "", index, result, allow_linefeeds);
-}
-
-bool ServerConfig::ConfValue(ConfigDataHash &target, const Anope::string &tag, const Anope::string &var, const Anope::string &default_value, int index, Anope::string &result, bool allow_linefeeds)
-{
- ConfigDataHash::size_type pos = index;
- if (pos < target.count(tag))
- {
- ConfigDataHash::iterator iter = target.find(tag);
-
- for (int i = 0; i < index; ++i)
- ++iter;
-
- KeyValList::iterator j = iter->second.begin(), jend = iter->second.end();
- for (; j != jend; ++j)
- {
- if (j->first.equals_ci(var))
- {
- if (!allow_linefeeds && j->second.find('\n') != Anope::string::npos)
- {
- Log(LOG_DEBUG) << "Value of <" << tag << ":" << var << "> contains a linefeed, and linefeeds in this value are not permitted -- stripped to spaces.";
- j->second.replace_all_cs("\n", " ");
- }
- else
- {
- result = j->second;
- return true;
- }
- }
- }
- if (!default_value.empty())
- {
- result = default_value;
- return true;
- }
- }
- else if (!pos)
- {
- if (!default_value.empty())
- {
- result = default_value;
- return true;
- }
- }
- return false;
-}
-
-bool ServerConfig::ConfValueInteger(ConfigDataHash &target, const Anope::string &tag, const Anope::string &var, int index, int &result)
-{
- return ConfValueInteger(target, tag, var, "", index, result);
-}
-
-bool ServerConfig::ConfValueInteger(ConfigDataHash &target, const Anope::string &tag, const Anope::string &var, const Anope::string &default_value, int index, int &result)
-{
- Anope::string value;
- std::istringstream stream;
- bool r = ConfValue(target, tag, var, default_value, index, value);
- stream.str(value.str());
- if (!(stream >> result))
- return false;
- else
- {
- if (!value.empty())
- {
- if (value.substr(0, 2).equals_ci("0x"))
- {
- char *endptr;
-
- value.erase(0, 2);
- result = strtol(value.c_str(), &endptr, 16);
-
- /* No digits found */
- if (endptr == value.c_str())
- return false;
- }
- else
- {
- char denominator = *(value.end() - 1);
- switch (toupper(denominator))
- {
- case 'K':
- // Kilobytes -> bytes
- result = result * 1024;
- break;
- case 'M':
- // Megabytes -> bytes
- result = result * 1048576;
- break;
- case 'G':
- // Gigabytes -> bytes
- result = result * 1073741824;
- }
- }
- }
- }
- return r;
-}
-
-bool ServerConfig::ConfValueBool(ConfigDataHash &target, const Anope::string &tag, const Anope::string &var, int index)
-{
- return ConfValueBool(target, tag, var, "", index);
-}
-
-bool ServerConfig::ConfValueBool(ConfigDataHash &target, const Anope::string &tag, const Anope::string &var, const Anope::string &default_value, int index)
-{
- Anope::string result;
- if (!ConfValue(target, tag, var, default_value, index, result))
- return false;
-
- return result.equals_ci("yes") || result.equals_ci("true") || result.equals_ci("1");
-}
-
-int ServerConfig::ConfValueEnum(const ConfigDataHash &target, const Anope::string &tag)
-{
- return target.count(tag);
-}
-
-int ServerConfig::ConfVarEnum(ConfigDataHash &target, const Anope::string &tag, int index)
-{
- ConfigDataHash::size_type pos = index;
-
- if (pos < target.count(tag))
- {
- ConfigDataHash::const_iterator iter = target.find(tag);
-
- for (int i = 0; i < index; ++i)
- ++iter;
-
- return iter->second.size();
- }
-
- return 0;
-}
-
-ValueItem::ValueItem() { }
-
-ValueItem::ValueItem(int value) : v("")
-{
- std::stringstream n;
- n << value;
- v = n.str();
-}
-
-ValueItem::ValueItem(long value) : v("")
-{
- std::stringstream n;
- n << value;
- v = n.str();
-}
-
-ValueItem::ValueItem(bool value) : v("")
-{
- std::stringstream n;
- n << value;
- v = n.str();
-}
-
-ValueItem::ValueItem(const Anope::string &value) : v(value) { }
-
-void ValueItem::Set(const Anope::string &value)
-{
- v = value;
-}
-
-void ValueItem::Set(int value)
-{
- std::stringstream n;
- n << value;
- v = n.str();
-}
-
-int ValueItem::GetInteger() const
-{
- if (v.empty() || !v.is_number_only())
- return 0;
- try
- {
- return convertTo<int>(v);
- }
- catch (const ConvertException &)
- {
- Log() << "Unable to convert configuration value " << this->v << " to an integer. Value too large?";
- }
-
- return 0;
-}
-
-const char *ValueItem::GetString() const
-{
- return v.c_str();
-}
-
-bool ValueItem::GetBool() const
-{
- return GetInteger() || v == "yes" || v == "true";
-}
-
-
diff --git a/src/configreader.cpp b/src/configreader.cpp
deleted file mode 100644
index ca5a64a60..000000000
--- a/src/configreader.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-/* Configuration file handling.
- *
- * (C) 2003-2013 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- *
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
- *
- */
-
-/* Taken from:
- * +------------------------------------+
- * | Inspire Internet Relay Chat Daemon |
- * +------------------------------------+
- *
- * InspIRCd: (C) 2002-2011 InspIRCd Development Team
- * See: http://www.inspircd.org/wiki/index.php/Credits
- *
- * This program is free but copyrighted software; see
- * the file COPYING for details.
- *
- * ---------------------------------------------------
- */
-
-#include "services.h"
-#include "config.h"
-
-ConfigReader::ConfigReader() : conf(Config), error(CONF_NO_ERROR)
-{
-}
-
-ConfigReader::ConfigReader(const Anope::string &filename) : conf(Config), error(CONF_NO_ERROR)
-{
-}
-
-ConfigReader::ConfigReader(ServerConfig *c) : conf(c), error(CONF_NO_ERROR)
-{
-}
-
-ConfigReader::~ConfigReader()
-{
-}
-
-Anope::string ConfigReader::ReadValue(const Anope::string &tag, const Anope::string &name, const Anope::string &default_value, int index, bool allow_linefeeds)
-{
- /* Don't need to strlcpy() tag and name anymore, ReadConf() takes const char* */
- Anope::string result;
-
- if (!conf->ConfValue(conf->config_data, tag, name, default_value, index, result, allow_linefeeds))
- this->error = CONF_VALUE_NOT_FOUND;
-
- return result;
-}
-
-Anope::string ConfigReader::ReadValue(const Anope::string &tag, const Anope::string &name, int index, bool allow_linefeeds)
-{
- return ReadValue(tag, name, "", index, allow_linefeeds);
-}
-
-bool ConfigReader::ReadFlag(const Anope::string &tag, const Anope::string &name, const Anope::string &default_value, int index)
-{
- return conf->ConfValueBool(conf->config_data, tag, name, default_value, index);
-}
-
-bool ConfigReader::ReadFlag(const Anope::string &tag, const Anope::string &name, int index)
-{
- return ReadFlag(tag, name, "", index);
-}
-
-int ConfigReader::ReadInteger(const Anope::string &tag, const Anope::string &name, const Anope::string &default_value, int index, bool need_positive)
-{
- int result;
-
- if (!conf->ConfValueInteger(conf->config_data, tag, name, default_value, index, result))
- {
- this->error = CONF_VALUE_NOT_FOUND;
- return 0;
- }
-
- if (need_positive && result < 0)
- {
- this->error = CONF_INT_NEGATIVE;
- return 0;
- }
-
- return result;
-}
-
-int ConfigReader::ReadInteger(const Anope::string &tag, const Anope::string &name, int index, bool need_positive)
-{
- return ReadInteger(tag, name, "", index, need_positive);
-}
-
-long ConfigReader::GetError()
-{
- long olderr = this->error;
- this->error = 0;
- return olderr;
-}
-
-int ConfigReader::Enumerate(const Anope::string &tag) const
-{
- return conf->ConfValueEnum(conf->config_data, tag);
-}
-
-int ConfigReader::EnumerateValues(const Anope::string &tag, int index)
-{
- return conf->ConfVarEnum(conf->config_data, tag, index);
-}
-
-bool ConfigReader::Verify()
-{
- return this->readerror;
-}
diff --git a/src/init.cpp b/src/init.cpp
index b0812fedc..27f0a8689 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -120,8 +120,8 @@ void Anope::HandleSignal()
try
{
- ServerConfig *new_config = new ServerConfig();
- delete Config;
+ Configuration::Conf *new_config = new Configuration::Conf();
+ delete new_config;
Config = new_config;
}
catch (const ConfigException &ex)
@@ -197,14 +197,14 @@ static void InitSignals()
static void remove_pidfile()
{
- remove(Config->PIDFilename.c_str());
+ remove(Config->GetBlock("serverinfo")->Get<const char *>("pid"));
}
/* Create our PID file and write the PID to it. */
static void write_pidfile()
{
- FILE *pidfile = fopen(Config->PIDFilename.c_str(), "w");
+ FILE *pidfile = fopen(Config->GetBlock("serverinfo")->Get<const char *>("pid"), "w");
if (pidfile)
{
#ifdef _WIN32
@@ -216,7 +216,7 @@ static void write_pidfile()
atexit(remove_pidfile);
}
else
- throw CoreException("Can not write to PID file " + Config->PIDFilename);
+ throw CoreException("Can not write to PID file " + Config->GetBlock("serverinfo")->Get<const Anope::string &>("pid"));
}
void Anope::Init(int ac, char **av)
@@ -303,7 +303,7 @@ void Anope::Init(int ac, char **av)
{
if (arg.empty())
throw CoreException("The --config option requires a file name");
- ServicesConf = ConfigurationFile(arg, false);
+ ServicesConf = Configuration::File(arg, false);
}
if (GetCommandLineArgument("confdir", 0, arg))
@@ -413,7 +413,7 @@ void Anope::Init(int ac, char **av)
/* Read configuration file; exit if there are problems. */
try
{
- Config = new ServerConfig();
+ Config = new Configuration::Conf();
}
catch (const ConfigException &ex)
{
@@ -429,7 +429,8 @@ void Anope::Init(int ac, char **av)
write_pidfile();
/* Create me */
- Me = new Server(NULL, Config->ServerName, 0, Config->ServerDesc, Config->Numeric);
+ Configuration::Block *block = Config->GetBlock("serverinfo");
+ Me = new Server(NULL, block->Get<const Anope::string &>("name"), 0, block->Get<const Anope::string &>("description"), block->Get<const Anope::string &>("id"));
for (botinfo_map::const_iterator it = BotListByNick->begin(), it_end = BotListByNick->end(); it != it_end; ++it)
{
it->second->server = Me;
@@ -445,12 +446,13 @@ void Anope::Init(int ac, char **av)
Language::InitLanguages();
/* Initialize random number generator */
- srand(Config->Seed);
+ block = Config->GetBlock("options");
+ srand(block->Get<unsigned>("seed"));
/* load modules */
Log() << "Loading modules...";
- for (std::list<Anope::string>::iterator it = Config->ModulesAutoLoad.begin(), it_end = Config->ModulesAutoLoad.end(); it != it_end; ++it)
- ModuleManager::LoadModule(*it, NULL);
+ for (int i = 0; i < Config->CountBlock("module"); ++i)
+ ModuleManager::LoadModule(Config->GetBlock("module", i)->Get<const Anope::string &>("name"), NULL);
Module *protocol = ModuleManager::FindFirstOf(PROTOCOL);
if (protocol == NULL)
diff --git a/src/language.cpp b/src/language.cpp
index ec2e0e39b..80f4477c2 100644
--- a/src/language.cpp
+++ b/src/language.cpp
@@ -37,7 +37,7 @@ void Language::InitLanguages()
setlocale(LC_ALL, "");
- spacesepstream sep(Config->Languages);
+ spacesepstream sep(Config->GetBlock("options")->Get<const Anope::string &>("languages"));
Anope::string language;
while (sep.GetToken(language))
{
@@ -58,7 +58,7 @@ void Language::InitLanguages()
const char *Language::Translate(const char *string)
{
- return Translate(Config->NSDefLanguage.c_str(), string);
+ return Translate("", string);
}
const char *Language::Translate(User *u, const char *string)
@@ -66,12 +66,12 @@ const char *Language::Translate(User *u, const char *string)
if (u && u->Account())
return Translate(u->Account(), string);
else
- return Translate(string);
+ return Translate("", string);
}
const char *Language::Translate(const NickCore *nc, const char *string)
{
- return Translate(nc ? nc->language.c_str() : Config->NSDefLanguage.c_str(), string);
+ return Translate(nc ? nc->language.c_str() : "", string);
}
#if GETTEXT_FOUND
@@ -81,8 +81,11 @@ extern "C" int _nl_msg_cat_cntr;
const char *Language::Translate(const char *lang, const char *string)
{
- if (!string || !*string || !lang || !*lang)
- return string ? string : "";
+ if (!string || !*string)
+ return "";
+
+ if (!lang || !*lang)
+ lang = Config->DefLanguage.c_str();
++_nl_msg_cat_cntr;
#ifdef _WIN32
diff --git a/src/logger.cpp b/src/logger.cpp
index f738cb2e1..d071b7cc3 100644
--- a/src/logger.cpp
+++ b/src/logger.cpp
@@ -21,7 +21,6 @@
#include "servers.h"
#include "uplink.h"
#include "protocol.h"
-#include "global.h"
#ifndef _WIN32
#include <sys/time.h>
@@ -149,8 +148,8 @@ Log::~Log()
if (Config)
for (unsigned i = 0; i < Config->LogInfos.size(); ++i)
- if (Config->LogInfos[i]->HasType(this->type, this->category))
- Config->LogInfos[i]->ProcessMessage(this);
+ if (Config->LogInfos[i].HasType(this->type, this->category))
+ Config->LogInfos[i].ProcessMessage(this);
FOREACH_MOD(I_OnLog, OnLog(this));
}
diff --git a/src/mail.cpp b/src/mail.cpp
index 851fe6d4e..3b2b1272f 100644
--- a/src/mail.cpp
+++ b/src/mail.cpp
@@ -14,7 +14,7 @@
#include "mail.h"
#include "config.h"
-Mail::Message::Message(const Anope::string &sf, const Anope::string &mailto, const Anope::string &a, const Anope::string &s, const Anope::string &m) : Thread(), sendmail_path(Config->SendMailPath), send_from(sf), mail_to(mailto), addr(a), subject(s), message(m), dont_quote_addresses(Config->DontQuoteAddresses), success(false)
+Mail::Message::Message(const Anope::string &sf, const Anope::string &mailto, const Anope::string &a, const Anope::string &s, const Anope::string &m) : Thread(), sendmail_path(Config->GetBlock("mail")->Get<const Anope::string &>("sendmailpath")), send_from(sf), mail_to(mailto), addr(a), subject(s), message(m), dont_quote_addresses(Config->GetBlock("mail")->Get<bool>("dontquoteaddresses")), success(false)
{
}
@@ -55,31 +55,33 @@ bool Mail::Send(User *u, NickCore *nc, const BotInfo *service, const Anope::stri
{
if (!nc || !service || subject.empty() || message.empty())
return false;
+
+ Configuration::Block *b = Config->GetBlock("mail");
if (!u)
{
- if (!Config->UseMail)
+ if (!b->Get<bool>("usemail") || b->Get<const Anope::string &>("sendfrom").empty())
return false;
else if (nc->email.empty())
return false;
nc->lastmail = Anope::CurTime;
- Thread *t = new Mail::Message(Config->SendFrom, nc->display, nc->email, subject, message);
+ Thread *t = new Mail::Message(b->Get<const Anope::string &>("sendfrom"), nc->display, nc->email, subject, message);
t->Start();
return true;
}
else
{
- if (!Config->UseMail)
+ if (!b->Get<bool>("usemail") || b->Get<const Anope::string &>("sendfrom").empty())
u->SendMessage(service, _("Services have been configured to not send mail."));
- else if (Anope::CurTime - u->lastmail < Config->MailDelay)
- u->SendMessage(service, _("Please wait \002%d\002 seconds and retry."), Config->MailDelay - (Anope::CurTime - u->lastmail));
+ else if (Anope::CurTime - u->lastmail < b->Get<time_t>("delay"))
+ u->SendMessage(service, _("Please wait \002%d\002 seconds and retry."), b->Get<time_t>("delay") - (Anope::CurTime - u->lastmail));
else if (nc->email.empty())
u->SendMessage(service, _("E-mail for \002%s\002 is invalid."), nc->display.c_str());
else
{
u->lastmail = nc->lastmail = Anope::CurTime;
- Thread *t = new Mail::Message(Config->SendFrom, nc->display, nc->email, subject, message);
+ Thread *t = new Mail::Message(b->Get<const Anope::string &>("sendfrom"), nc->display, nc->email, subject, message);
t->Start();
return true;
}
@@ -90,11 +92,12 @@ bool Mail::Send(User *u, NickCore *nc, const BotInfo *service, const Anope::stri
bool Mail::Send(NickCore *nc, const Anope::string &subject, const Anope::string &message)
{
- if (!Config->UseMail || !nc || nc->email.empty() || subject.empty() || message.empty())
+ Configuration::Block *b = Config->GetBlock("mail");
+ if (!b->Get<bool>("usemail") || b->Get<const Anope::string &>("sendfrom").empty() || !nc || nc->email.empty() || subject.empty() || message.empty())
return false;
nc->lastmail = Anope::CurTime;
- Thread *t = new Mail::Message(Config->SendFrom, nc->display, nc->email, subject, message);
+ Thread *t = new Mail::Message(b->Get<const Anope::string &>("sendfrom"), nc->display, nc->email, subject, message);
t->Start();
return true;
diff --git a/src/main.cpp b/src/main.cpp
index 059650df0..12fc1335c 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -144,12 +144,12 @@ int main(int ac, char **av, char **envp)
}
catch (const SocketException &ex)
{
- Log(LOG_TERMINAL) << "Unable to connect to uplink #" << Anope::CurrentUplink << " (" << Config->Uplinks[Anope::CurrentUplink]->host << ":" << Config->Uplinks[Anope::CurrentUplink]->port << "): " << ex.GetReason();
+ Log(LOG_TERMINAL) << "Unable to connect to uplink #" << (Anope::CurrentUplink + 1) << " (" << Config->Uplinks[Anope::CurrentUplink].host << ":" << Config->Uplinks[Anope::CurrentUplink].port << "): " << ex.GetReason();
}
/* Set up timers */
time_t last_check = Anope::CurTime;
- UpdateTimer updateTimer(Config->UpdateTimeout);
+ UpdateTimer updateTimer(Config->GetBlock("options")->Get<time_t>("updatetimeout"));
/*** Main loop. ***/
while (!Anope::Quitting)
@@ -157,7 +157,7 @@ int main(int ac, char **av, char **envp)
Log(LOG_DEBUG_2) << "Top of main loop";
/* Process timers */
- if (Anope::CurTime - last_check >= Config->TimeoutCheck)
+ if (Anope::CurTime - last_check >= Config->GetBlock("options")->Get<time_t>("timeoutcheck"))
{
TimerManager::TickTimers(Anope::CurTime);
last_check = Anope::CurTime;
diff --git a/src/messages.cpp b/src/messages.cpp
index c9ffd3c59..9bbfb42c0 100644
--- a/src/messages.cpp
+++ b/src/messages.cpp
@@ -126,9 +126,6 @@ void Join::SJoin(MessageSource &source, const Anope::string &chan, time_t ts, co
const ChannelStatus &status = it->first;
User *u = it->second;
- EventReturn MOD_RESULT;
- FOREACH_RESULT(I_OnPreJoinChannel, OnPreJoinChannel(u, c));
-
/* Add the user to the channel */
ChanUserContainer *cc = c->JoinUser(u);
@@ -141,14 +138,8 @@ void Join::SJoin(MessageSource &source, const Anope::string &chan, time_t ts, co
*/
c->SetCorrectModes(u, true, true);
- /* Check to see if modules want the user to join, if they do
- * check to see if they are allowed to join (CheckKick will kick/ban them
- * if they aren't).
- */
- if (MOD_RESULT != EVENT_STOP && c->ci && c->ci->CheckKick(u))
- continue;
-
- FOREACH_MOD(I_OnJoinChannel, OnJoinChannel(u, c));
+ if (c->ci)
+ c->ci->CheckKick(u);
}
/* Channel is done syncing */
@@ -234,10 +225,10 @@ void MOTD::Run(MessageSource &source, const std::vector<Anope::string> &params)
if (s != Me)
return;
- FILE *f = fopen(Config->MOTDFilename.c_str(), "r");
+ FILE *f = fopen(Config->GetBlock("serverinfo")->Get<const char *>("motd"), "r");
if (f)
{
- IRCD->SendNumeric(375, source.GetSource(), ":- %s Message of the Day", Config->ServerName.c_str());
+ IRCD->SendNumeric(375, source.GetSource(), ":- %s Message of the Day", s->GetName().c_str());
char buf[BUFSIZE];
while (fgets(buf, sizeof(buf), f))
{
@@ -304,16 +295,16 @@ void Privmsg::Run(MessageSource &source, const std::vector<Anope::string> &param
{
Anope::string servername(receiver.begin() + s + 1, receiver.end());
botname = botname.substr(0, s);
- if (!servername.equals_ci(Config->ServerName))
+ if (!servername.equals_ci(Me->GetName()))
return;
}
- else if (Config->UseStrictPrivMsg)
+ else if (Config->GetBlock("options")->Get<bool>("usestrictprivmsg"))
{
const BotInfo *bi = BotInfo::Find(receiver);
if (!bi)
return;
Log(LOG_DEBUG) << "Ignored PRIVMSG without @ from " << u->nick;
- u->SendMessage(bi, _("\"/msg %s\" is no longer supported. Use \"/msg %s@%s\" or \"/%s\" instead."), bi->nick.c_str(), bi->nick.c_str(), Config->ServerName.c_str(), bi->nick.c_str());
+ u->SendMessage(bi, _("\"/msg %s\" is no longer supported. Use \"/msg %s@%s\" or \"/%s\" instead."), bi->nick.c_str(), bi->nick.c_str(), Me->GetName().c_str(), bi->nick.c_str());
return;
}
@@ -338,7 +329,7 @@ void Privmsg::Run(MessageSource &source, const std::vector<Anope::string> &param
else if (message.substr(0, 9).equals_ci("\1VERSION\1"))
{
Module *enc = ModuleManager::FindFirstOf(ENCRYPTION);
- IRCD->SendCTCP(bi, u->nick, "VERSION Anope-%s %s :%s - (%s) -- %s", Anope::Version().c_str(), Config->ServerName.c_str(), IRCD->GetProtocolName().c_str(), enc ? enc->name.c_str() : "(none)", Anope::VersionBuildString().c_str());
+ IRCD->SendCTCP(bi, u->nick, "VERSION Anope-%s %s :%s - (%s) -- %s", Anope::Version().c_str(), Me->GetName().c_str(), IRCD->GetProtocolName().c_str(), enc ? enc->name.c_str() : "(none)", Anope::VersionBuildString().c_str());
}
return;
}
@@ -357,16 +348,7 @@ void Quit::Run(MessageSource &source, const std::vector<Anope::string> &params)
Log(user, "quit") << "quit (Reason: " << (!reason.empty() ? reason : "no reason") << ")";
- NickAlias *na = NickAlias::Find(user->nick);
- if (na && !na->nc->HasExt("SUSPENDED") && (user->IsRecognized() || user->IsIdentified(true)))
- {
- na->last_seen = Anope::CurTime;
- na->last_quit = reason;
- }
- FOREACH_MOD(I_OnUserQuit, OnUserQuit(user, reason));
user->Quit(reason);
-
- return;
}
void SQuit::Run(MessageSource &source, const std::vector<Anope::string> &params)
@@ -382,8 +364,6 @@ void SQuit::Run(MessageSource &source, const std::vector<Anope::string> &params)
FOREACH_MOD(I_OnServerQuit, OnServerQuit(s));
s->Delete(s->GetName() + " " + s->GetUplink()->GetName());
-
- return;
}
void Stats::Run(MessageSource &source, const std::vector<Anope::string> &params)
@@ -396,7 +376,7 @@ void Stats::Run(MessageSource &source, const std::vector<Anope::string> &params)
if (u->HasMode("OPER"))
{
IRCD->SendNumeric(211, source.GetSource(), "Server SendBuf SentBytes SentMsgs RecvBuf RecvBytes RecvMsgs ConnTime");
- IRCD->SendNumeric(211, source.GetSource(), "%s %d %d %d %d %d %d %ld", Config->Uplinks[Anope::CurrentUplink]->host.c_str(), UplinkSock->WriteBufferLen(), TotalWritten, -1, UplinkSock->ReadBufferLen(), TotalRead, -1, static_cast<long>(Anope::CurTime - Anope::StartTime));
+ IRCD->SendNumeric(211, source.GetSource(), "%s %d %d %d %d %d %d %ld", Config->Uplinks[Anope::CurrentUplink].host.c_str(), UplinkSock->WriteBufferLen(), TotalWritten, -1, UplinkSock->ReadBufferLen(), TotalRead, -1, static_cast<long>(Anope::CurTime - Anope::StartTime));
}
IRCD->SendNumeric(219, source.GetSource(), "%c :End of /STATS report.", params[0][0]);
@@ -404,7 +384,7 @@ void Stats::Run(MessageSource &source, const std::vector<Anope::string> &params)
case 'o':
case 'O':
/* Check whether the user is an operator */
- if (!u->HasMode("OPER") && Config->HideStatsO)
+ if (!u->HasMode("OPER") && Config->GetBlock("options")->Get<bool>("hidestatso"))
IRCD->SendNumeric(219, source.GetSource(), "%c :End of /STATS report.", params[0][0]);
else
{
@@ -444,7 +424,7 @@ void Time::Run(MessageSource &source, const std::vector<Anope::string> &params)
struct tm *tm = localtime(&t);
char buf[64];
strftime(buf, sizeof(buf), "%a %b %d %H:%M:%S %Y %Z", tm);
- IRCD->SendNumeric(391, source.GetSource(), "%s :%s", Config->ServerName.c_str(), buf);
+ IRCD->SendNumeric(391, source.GetSource(), "%s :%s", Me->GetName().c_str(), buf);
return;
}
@@ -460,7 +440,7 @@ void Topic::Run(MessageSource &source, const std::vector<Anope::string> &params)
void Version::Run(MessageSource &source, const std::vector<Anope::string> &params)
{
Module *enc = ModuleManager::FindFirstOf(ENCRYPTION);
- IRCD->SendNumeric(351, source.GetSource(), "Anope-%s %s :%s -(%s) -- %s", Anope::Version().c_str(), Config->ServerName.c_str(), IRCD->GetProtocolName().c_str(), enc ? enc->name.c_str() : "(none)", Anope::VersionBuildString().c_str());
+ IRCD->SendNumeric(351, source.GetSource(), "Anope-%s %s :%s -(%s) -- %s", Anope::Version().c_str(), Me->GetName().c_str(), IRCD->GetProtocolName().c_str(), enc ? enc->name.c_str() : "(none)", Anope::VersionBuildString().c_str());
return;
}
@@ -474,7 +454,7 @@ void Whois::Run(MessageSource &source, const std::vector<Anope::string> &params)
IRCD->SendNumeric(311, source.GetSource(), "%s %s %s * :%s", u->nick.c_str(), u->GetIdent().c_str(), u->host.c_str(), u->realname.c_str());
if (bi)
IRCD->SendNumeric(307, source.GetSource(), "%s :is a registered nick", bi->nick.c_str());
- IRCD->SendNumeric(312, source.GetSource(), "%s %s :%s", u->nick.c_str(), Config->ServerName.c_str(), Config->ServerDesc.c_str());
+ IRCD->SendNumeric(312, source.GetSource(), "%s %s :%s", u->nick.c_str(), Me->GetName().c_str(), Config->GetBlock("serverinfo")->Get<const char *>("description"));
if (bi)
IRCD->SendNumeric(317, source.GetSource(), "%s %ld %ld :seconds idle, signon time", bi->nick.c_str(), static_cast<long>(Anope::CurTime - bi->lastmsg), static_cast<long>(bi->signon));
IRCD->SendNumeric(318, source.GetSource(), "%s :End of /WHOIS list.", params[0].c_str());
diff --git a/src/misc.cpp b/src/misc.cpp
index 20a53e7cc..86328b6b3 100644
--- a/src/misc.cpp
+++ b/src/misc.cpp
@@ -43,10 +43,18 @@ NumberList::NumberList(const Anope::string &list, bool descending) : is_valid(tr
if (t == Anope::string::npos)
{
- unsigned num = convertTo<unsigned>(token, error, false);
- if (error.empty())
- numbers.insert(num);
- else
+ try
+ {
+ unsigned num = convertTo<unsigned>(token, error, false);
+ if (error.empty())
+ numbers.insert(num);
+ }
+ catch (const ConvertException &)
+ {
+ error = "1";
+ }
+
+ if (!error.empty())
{
if (!this->InvalidRange(list))
{
@@ -58,14 +66,20 @@ NumberList::NumberList(const Anope::string &list, bool descending) : is_valid(tr
else
{
Anope::string error2;
- unsigned num1 = convertTo<unsigned>(token.substr(0, t), error, false);
- unsigned num2 = convertTo<unsigned>(token.substr(t + 1), error2, false);
- if (error.empty() && error2.empty())
+ try
{
- for (unsigned i = num1; i <= num2; ++i)
- numbers.insert(i);
+ unsigned num1 = convertTo<unsigned>(token.substr(0, t), error, false);
+ unsigned num2 = convertTo<unsigned>(token.substr(t + 1), error2, false);
+ if (error.empty() && error2.empty())
+ for (unsigned i = num1; i <= num2; ++i)
+ numbers.insert(i);
}
- else
+ catch (const ConvertException &)
+ {
+ error = "1";
+ }
+
+ if (!error.empty() || !error2.empty())
{
if (!this->InvalidRange(list))
{
@@ -232,7 +246,7 @@ bool Anope::IsFile(const Anope::string &filename)
time_t Anope::DoTime(const Anope::string &s)
{
if (s.empty())
- return -1;
+ return 0;
int amount = 0;
Anope::string end;
@@ -257,7 +271,7 @@ time_t Anope::DoTime(const Anope::string &s)
case 'y':
return amount * 86400 * 365;
default:
- return -1;
+ break;
}
}
}
@@ -368,7 +382,7 @@ bool Anope::Match(const Anope::string &str, const Anope::string &mask, bool case
if (r == NULL || r->GetExpression() != stripped_mask)
{
- ServiceReference<RegexProvider> provider("Regex", Config->RegexEngine);
+ ServiceReference<RegexProvider> provider("Regex", Config->GetBlock("options")->Get<const Anope::string &>("regexengine"));
if (provider)
{
try
diff --git a/src/modes.cpp b/src/modes.cpp
index 6cdeb6565..9481f570e 100644
--- a/src/modes.cpp
+++ b/src/modes.cpp
@@ -31,12 +31,13 @@ static std::vector<ChannelModeStatus *> ChannelModesByStatus;
/* Number of generic modes we support */
unsigned ModeManager::GenericChannelModes = 0, ModeManager::GenericUserModes = 0;
-/* Default channel mode lock */
-std::list<std::pair<Anope::string, Anope::string> > ModeManager::ModeLockOn;
-std::list<Anope::string> ModeManager::ModeLockOff;
+ChannelStatus::ChannelStatus()
+{
+}
-/* Default modes bots have on channels */
-ChannelStatus ModeManager::DefaultBotModes;
+ChannelStatus::ChannelStatus(const Anope::string &m) : modes(m)
+{
+}
void ChannelStatus::AddMode(char c)
{
@@ -75,7 +76,7 @@ Anope::string ChannelStatus::BuildModePrefixList() const
for (size_t i = 0; i < modes.length(); ++i)
{
- ChannelMode *cm = ModeManager::FindChannelModeByName(modes[i]);
+ ChannelMode *cm = ModeManager::FindChannelModeByChar(modes[i]);
if (cm != NULL && cm->type == MODE_STATUS)
{
ChannelModeStatus *cms = anope_dynamic_static_cast<ChannelModeStatus *>(cm);
@@ -117,9 +118,9 @@ ChannelMode::~ChannelMode()
bool ChannelMode::CanSet(User *u) const
{
- if (Config->NoMLock.find(this->mchar) != Anope::string::npos || Config->CSRequire.find(this->mchar) != Anope::string::npos)
- return false;
- return true;
+ EventReturn MOD_RESULT;
+ FOREACH_RESULT(I_OnCanSet, OnCanSet(u, this));
+ return MOD_RESULT == EVENT_ALLOW;
}
ChannelModeList::ChannelModeList(const Anope::string &cm, char mch) : ChannelMode(cm, mch)
@@ -358,9 +359,6 @@ bool ModeManager::AddChannelMode(ChannelMode *cm)
ChannelModesByName[cm->name] = cm;
- /* Apply this mode to the new default mlock if its used */
- UpdateDefaultMLock(Config);
-
FOREACH_MOD(I_OnChannelModeAdd, OnChannelModeAdd(cm));
return true;
@@ -621,66 +619,6 @@ void ModeManager::StackerDel(Mode *m)
}
}
-void ModeManager::UpdateDefaultMLock(ServerConfig *config)
-{
- ModeLockOn.clear();
- ModeLockOff.clear();
-
- Anope::string modes;
- spacesepstream sep(config->MLock);
- sep.GetToken(modes);
-
- int adding = -1;
- for (unsigned i = 0, end_mode = modes.length(); i < end_mode; ++i)
- {
- if (modes[i] == '+')
- adding = 1;
- else if (modes[i] == '-')
- adding = 0;
- else if (adding != -1)
- {
- ChannelMode *cm = ModeManager::FindChannelModeByChar(modes[i]);
-
- if (cm && cm->type != MODE_STATUS)
- {
- Anope::string param;
- if (adding == 1 && cm->type != MODE_REGULAR && !sep.GetToken(param)) // MODE_LIST OR MODE_PARAM
- {
- Log() << "Warning: Got default mlock mode " << cm->mchar << " with no param?";
- continue;
- }
-
- if (cm->type != MODE_LIST) // Only MODE_LIST can have duplicates
- {
- for (std::list<std::pair<Anope::string, Anope::string> >::iterator it = ModeLockOn.begin(), it_end = ModeLockOn.end(); it != it_end; ++it)
- if (it->first == cm->name)
- {
- ModeLockOn.erase(it);
- break;
- }
-
- for (std::list<Anope::string>::iterator it = ModeLockOff.begin(), it_end = ModeLockOff.end(); it != it_end; ++it)
- if (*it == cm->name)
- {
- ModeLockOff.erase(it);
- break;
- }
- }
-
- if (adding)
- ModeLockOn.push_back(std::make_pair(cm->name, param));
- else
- ModeLockOff.push_back(cm->name);
- }
- }
- }
-
- /* Set Bot Modes */
- DefaultBotModes.Clear();
- for (unsigned i = 0; i < config->BotModes.length(); ++i)
- DefaultBotModes.AddMode(config->BotModes[i]);
-}
-
Entry::Entry(const Anope::string &m, const Anope::string &fh) : name(m), mask(fh), cidr_len(0)
{
Anope::string n, u, h;
diff --git a/src/modulemanager.cpp b/src/modulemanager.cpp
index 82691822f..211304cae 100644
--- a/src/modulemanager.cpp
+++ b/src/modulemanager.cpp
@@ -229,10 +229,9 @@ ModuleReturn ModuleManager::LoadModule(const Anope::string &modname, User *u)
/* If the module is hooked to the reload event it wants to initialize its config here */
if (std::find(EventHandlers[I_OnReload].begin(), EventHandlers[I_OnReload].end(), m) != EventHandlers[I_OnReload].end())
{
- ConfigReader reader;
try
{
- m->OnReload(Config, reader);
+ m->OnReload(Config);
}
catch (const ConfigException &ex)
{
diff --git a/src/nickalias.cpp b/src/nickalias.cpp
index 5e6960cc6..0de2f6d0a 100644
--- a/src/nickalias.cpp
+++ b/src/nickalias.cpp
@@ -139,7 +139,8 @@ class CoreExport NickServRelease : public User, public Timer
* @param na The nick
* @param delay The delay before the nick is released
*/
- NickServRelease(NickAlias *na, time_t delay) : User(na->nick, Config->NSEnforcerUser, Config->NSEnforcerHost, "", "", Me, "Services Enforcer", Anope::CurTime, "", Servers::TS6_UID_Retrieve()), Timer(delay), nick(na->nick)
+ NickServRelease(NickAlias *na, time_t delay) : User(na->nick, Config->GetBlock("options")->Get<const Anope::string &>("enforceruser"),
+ Config->GetBlock("options")->Get<const Anope::string &>("enforcerhost"), "", "", Me, "Services Enforcer", Anope::CurTime, "", Servers::TS6_UID_Retrieve()), Timer(delay), nick(na->nick)
{
/* Erase the current release timer and use the new one */
std::map<Anope::string, NickServRelease *>::iterator nit = NickServReleases.find(this->nick);
@@ -176,12 +177,12 @@ void NickAlias::OnCancel(User *)
this->Extend("HELD");
this->Shrink("COLLIDED");
- new NickServHeld(this, Config->NSReleaseTimeout);
+ new NickServHeld(this, Config->GetBlock("options")->Get<time_t>("releasetimeout"));
if (IRCD->CanSVSHold)
- IRCD->SendSVSHold(this->nick);
+ IRCD->SendSVSHold(this->nick, Config->GetBlock("options")->Get<time_t>("releasetimeout"));
else
- new NickServRelease(this, Config->NSReleaseTimeout);
+ new NickServRelease(this, Config->GetBlock("options")->Get<time_t>("releasetimeout"));
}
}
diff --git a/src/nickcore.cpp b/src/nickcore.cpp
index dcd324846..e2b47e953 100644
--- a/src/nickcore.cpp
+++ b/src/nickcore.cpp
@@ -25,19 +25,16 @@ NickCore::NickCore(const Anope::string &coredisplay) : Serializable("NickCore"),
this->o = NULL;
this->channelcount = 0;
this->lastmail = 0;
- this->memos.memomax = Config->MSMaxMemos;
- this->language = Config->NSDefLanguage;
+ this->memos.memomax = 0;
this->display = coredisplay;
- /* Set default nick core flags */
- for (std::set<Anope::string>::const_iterator it = Config->NSDefFlags.begin(), it_end = Config->NSDefFlags.end(); it != it_end; ++it)
- this->ExtendMetadata(*it);
-
size_t old = NickCoreList->size();
(*NickCoreList)[this->display] = this;
if (old == NickCoreList->size())
Log(LOG_DEBUG) << "Duplicate account " << coredisplay << " in nickcore table?";
+
+ FOREACH_MOD(I_OnNickCoreCreate, OnNickCoreCreate(this));
}
NickCore::~NickCore()
@@ -174,6 +171,11 @@ Anope::string NickCore::GetAccess(unsigned entry) const
return this->access[entry];
}
+unsigned NickCore::GetAccessCount() const
+{
+ return this->access.size();
+}
+
bool NickCore::FindAccess(const Anope::string &entry)
{
for (unsigned i = 0, end = this->access.size(); i < end; ++i)
diff --git a/src/opertype.cpp b/src/opertype.cpp
index eb73c20f4..0db17464d 100644
--- a/src/opertype.cpp
+++ b/src/opertype.cpp
@@ -27,9 +27,9 @@ Oper *Oper::Find(const Anope::string &name)
OperType *OperType::Find(const Anope::string &name)
{
- for (std::list<OperType *>::iterator it = Config->MyOperTypes.begin(), it_end = Config->MyOperTypes.end(); it != it_end; ++it)
+ for (unsigned i = 0; i < Config->MyOperTypes.size(); ++i)
{
- OperType *ot = *it;
+ OperType *ot = Config->MyOperTypes[i];
if (ot->GetName() == name)
return ot;
diff --git a/src/protocol.cpp b/src/protocol.cpp
index a66bf8227..14739d24b 100644
--- a/src/protocol.cpp
+++ b/src/protocol.cpp
@@ -67,14 +67,6 @@ void IRCDProto::SendKickInternal(const BotInfo *bi, const Channel *c, const User
UplinkSocket::Message(bi) << "KICK " << c->name << " " << u->GetUID();
}
-void IRCDProto::SendMessageInternal(const BotInfo *bi, const Anope::string &dest, const Anope::string &buf)
-{
- if (Config->NSDefFlags.count("msg"))
- SendPrivmsgInternal(bi, dest, buf);
- else
- SendNoticeInternal(bi, dest, buf);
-}
-
void IRCDProto::SendNoticeInternal(const BotInfo *bi, const Anope::string &dest, const Anope::string &msg)
{
UplinkSocket::Message(bi) << "NOTICE " << dest << " :" << msg;
@@ -176,16 +168,6 @@ void IRCDProto::SendKick(const BotInfo *bi, const Channel *chan, const User *use
SendKickInternal(bi, chan, user, buf);
}
-void IRCDProto::SendMessage(const BotInfo *bi, const Anope::string &dest, const char *fmt, ...)
-{
- va_list args;
- char buf[BUFSIZE] = "";
- va_start(args, fmt);
- vsnprintf(buf, BUFSIZE - 1, fmt, args);
- va_end(args);
- SendMessageInternal(bi, dest, buf);
-}
-
void IRCDProto::SendNotice(const BotInfo *bi, const Anope::string &dest, const char *fmt, ...)
{
va_list args;
@@ -339,7 +321,7 @@ bool IRCDProto::IsNickValid(const Anope::string &nick)
bool IRCDProto::IsChannelValid(const Anope::string &chan)
{
- if (chan.empty() || chan[0] != '#' || chan.length() > Config->ChanLen)
+ if (chan.empty() || chan[0] != '#' || chan.length() > Config->GetBlock("networkinfo")->Get<unsigned>("chanlen"))
return false;
return true;
@@ -347,7 +329,7 @@ bool IRCDProto::IsChannelValid(const Anope::string &chan)
bool IRCDProto::IsIdentValid(const Anope::string &ident)
{
- if (ident.empty() || ident.length() > Config->UserLen)
+ if (ident.empty() || ident.length() > Config->GetBlock("networkinfo")->Get<unsigned>("chanlen"))
return false;
for (unsigned i = 0; i < ident.length(); ++i)
@@ -364,12 +346,15 @@ bool IRCDProto::IsIdentValid(const Anope::string &ident)
bool IRCDProto::IsHostValid(const Anope::string &host)
{
- if (host.empty() || host.length() > Config->HostLen)
+ if (host.empty() || host.length() > Config->GetBlock("networkinfo")->Get<unsigned>("hostlen"))
return false;
- if (Config->VhostDisallowBE.find_first_of(host[0]) != Anope::string::npos)
+ const Anope::string &vhostdisablebe = Config->GetBlock("networkinfo")->Get<const Anope::string &>("disallow_start_or_end"),
+ vhostchars = Config->GetBlock("networkinfo")->Get<const Anope::string &>("vhost_chars");
+
+ if (vhostdisablebe.find_first_of(host[0]) != Anope::string::npos)
return false;
- else if (Config->VhostDisallowBE.find_first_of(host[host.length() - 1]) != Anope::string::npos)
+ else if (vhostdisablebe.find_first_of(host[host.length() - 1]) != Anope::string::npos)
return false;
int dots = 0;
@@ -377,11 +362,11 @@ bool IRCDProto::IsHostValid(const Anope::string &host)
{
if (host[i] == '.')
++dots;
- if (Config->VhostChars.find_first_of(host[i]) == Anope::string::npos)
+ if (vhostchars.find_first_of(host[i]) == Anope::string::npos)
return false;
}
- return Config->VhostUndotted || dots > 0;
+ return dots > 0 || Config->GetBlock("networkinfo")->Get<bool>("allow_undotted_vhosts");
}
void IRCDProto::SendOper(User *u)
@@ -392,7 +377,7 @@ void IRCDProto::SendOper(User *u)
unsigned IRCDProto::GetMaxListFor(Channel *c)
{
- return c->HasMode("LBAN") ? 0 : Config->ListSize;
+ return c->HasMode("LBAN") ? 0 : Config->GetBlock("networkinfo")->Get<int>("modelistsize");
}
MessageSource::MessageSource(const Anope::string &src) : source(src), u(NULL), s(NULL)
diff --git a/src/regchannel.cpp b/src/regchannel.cpp
index 48d039be3..12655533b 100644
--- a/src/regchannel.cpp
+++ b/src/regchannel.cpp
@@ -276,22 +276,12 @@ ChannelInfo::ChannelInfo(const Anope::string &chname) : Serializable("ChannelInf
this->repeattimes = 0;
this->banexpire = 0;
this->bi = NULL;
-
- this->last_topic_setter = Config->ChanServ;
- this->last_topic_time = Anope::CurTime;
+ this->last_topic_time = 0;
this->name = chname;
- /* Set default channel flags */
- for (std::set<Anope::string>::const_iterator it = Config->CSDefFlags.begin(), it_end = Config->CSDefFlags.end(); it != it_end; ++it)
- this->ExtendMetadata(*it);
-
- /* Set default bot flags */
- for (std::set<Anope::string>::const_iterator it = Config->BSDefFlags.begin(), it_end = Config->BSDefFlags.end(); it != it_end; ++it)
- this->ExtendMetadata(*it);
-
- this->bantype = Config->CSDefBantype;
- this->memos.memomax = Config->MSMaxMemos;
+ this->bantype = 2;
+ this->memos.memomax = 0;
this->last_used = this->time_registered = Anope::CurTime;
for (int i = 0; i < TTB_SIZE; ++i)
@@ -357,6 +347,8 @@ ChannelInfo::ChannelInfo(const ChannelInfo &ci) : Serializable("ChannelInfo"),
l->ci = this;
this->log_settings->push_back(l);
}
+
+ FOREACH_MOD(I_OnCreateChan, OnCreateChan(this));
}
ChannelInfo::~ChannelInfo()
@@ -474,11 +466,10 @@ Serializable* ChannelInfo::Unserialize(Serializable *obj, Serialize::Data &data)
BotInfo *bi = BotInfo::Find(sbi);
if (*ci->bi != bi)
{
- if (ci->bi)
+ if (bi)
+ bi->Assign(NULL, ci);
+ else if (ci->bi)
ci->bi->UnAssign(NULL, ci);
- ci->bi = bi;
- if (ci->bi)
- ci->bi->Assign(NULL, ci);
}
{
Anope::string ttb, tok;
@@ -1035,23 +1026,6 @@ bool ChannelInfo::CheckKick(User *user)
Log(LOG_DEBUG) << "Autokicking " << user->nick << " (" << mask << ") from " << this->name;
- /* If the channel isn't syncing and doesn't have any users, join ChanServ
- * Note that the user AND POSSIBLY the botserv bot exist here
- * ChanServ always enforces channels like this to keep people from deleting bots etc
- * that are holding channels.
- */
- if (this->c->users.size() == (this->bi && this->c->FindUser(this->bi) ? 2 : 1) && !this->c->HasExt("INHABIT") && !this->c->HasExt("SYNCING"))
- {
- /* Set +ntsi to prevent rejoin */
- c->SetMode(NULL, "NOEXTERNAL");
- c->SetMode(NULL, "TOPIC");
- c->SetMode(NULL, "SECRET");
- c->SetMode(NULL, "INVITE");
-
- /* Join ChanServ and set a timer for this channel to part ChanServ later */
- this->c->Hold();
- }
-
this->c->SetMode(NULL, "BAN", mask);
this->c->Kick(NULL, user, "%s", reason.c_str());
diff --git a/src/servers.cpp b/src/servers.cpp
index 28ff7bf17..2f87d66e4 100644
--- a/src/servers.cpp
+++ b/src/servers.cpp
@@ -127,21 +127,12 @@ Server::~Server()
if (Servers::Capab.count("NOQUIT") > 0 || Servers::Capab.count("QS") > 0)
{
- for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end();)
+ for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
{
User *u = it->second;
- ++it;
if (u->server == this)
{
- NickAlias *na = NickAlias::Find(u->nick);
- if (na && !na->nc->HasExt("SUSPENDED") && (u->IsRecognized() || u->IsIdentified()))
- {
- na->last_seen = Anope::CurTime;
- if (!Config->NSHideNetSplitQuit)
- na->last_quit = this->quit_reason;
- }
-
u->Quit(this->quit_reason);
u->server = NULL;
}
@@ -201,6 +192,11 @@ const Anope::string &Server::GetSID() const
return this->name;
}
+const Anope::string &Server::GetQuitReason() const
+{
+ return this->quit_reason;
+}
+
const std::vector<Server *> &Server::GetLinks() const
{
return this->links;
@@ -313,8 +309,8 @@ bool Server::IsULined() const
if (this == Me)
return true;
- for (std::list<Anope::string>::const_iterator it = Config->Ulines.begin(), it_end = Config->Ulines.end(); it != it_end; ++it)
- if (it->equals_ci(this->GetName()))
+ for (unsigned i = 0; i < Config->Ulines.size(); ++i)
+ if (Config->Ulines[i].equals_ci(this->GetName()))
return true;
return false;
}
@@ -326,7 +322,7 @@ bool Server::IsJuped() const
void Server::Notice(const BotInfo *source, const Anope::string &message)
{
- if (Config->NSDefFlags.count("MSG"))
+ if (Config->UsePrivmsg && Config->DefPrivmsg)
IRCD->SendGlobalPrivmsg(source, this, message);
else
IRCD->SendGlobalNotice(source, this, message);
@@ -370,13 +366,13 @@ const Anope::string Servers::TS6_UID_Retrieve()
static Anope::string current_uid = "AAAAAA";
- while (User::Find(Config->Numeric + current_uid) != NULL)
+ while (User::Find(Me->GetSID() + current_uid) != NULL)
{
int current_len = current_uid.length() - 1;
while (current_len >= 0 && nextID(current_uid[current_len--]) == 'A');
}
- return Config->Numeric + current_uid;
+ return Me->GetSID() + current_uid;
}
const Anope::string Servers::TS6_SID_Retrieve()
@@ -384,13 +380,9 @@ const Anope::string Servers::TS6_SID_Retrieve()
if (!IRCD || !IRCD->RequiresID)
return "";
- static Anope::string current_sid;
+ static Anope::string current_sid = Config->GetBlock("options")->Get<const Anope::string &>("id");
if (current_sid.empty())
- {
- current_sid = Config->Numeric;
- if (current_sid.empty())
- current_sid = "00A";
- }
+ current_sid = "00A";
while (Server::Find(current_sid) != NULL)
{
diff --git a/src/uplink.cpp b/src/uplink.cpp
index f8841c58f..ff90ee53c 100644
--- a/src/uplink.cpp
+++ b/src/uplink.cpp
@@ -31,7 +31,7 @@ class ReconnectTimer : public Timer
}
catch (const SocketException &ex)
{
- Log(LOG_TERMINAL) << "Unable to connect to uplink #" << (Anope::CurrentUplink + 1) << " (" << Config->Uplinks[Anope::CurrentUplink]->host << ":" << Config->Uplinks[Anope::CurrentUplink]->port << "): " << ex.GetReason();
+ Log(LOG_TERMINAL) << "Unable to connect to uplink #" << (Anope::CurrentUplink + 1) << " (" << Config->Uplinks[Anope::CurrentUplink].host << ":" << Config->Uplinks[Anope::CurrentUplink].port << "): " << ex.GetReason();
}
}
};
@@ -41,19 +41,19 @@ void Uplink::Connect()
if (static_cast<unsigned>(++Anope::CurrentUplink) >= Config->Uplinks.size())
Anope::CurrentUplink = 0;
- ServerConfig::Uplink *u = Config->Uplinks[Anope::CurrentUplink];
+ Configuration::Uplink &u = Config->Uplinks[Anope::CurrentUplink];
new UplinkSocket();
- if (!Config->LocalHost.empty())
- UplinkSock->Bind(Config->LocalHost);
+ if (!Config->GetBlock("serverinfo")->Get<const Anope::string &>("localhost").empty())
+ UplinkSock->Bind(Config->GetBlock("serverinfo")->Get<const Anope::string &>("localhost"));
FOREACH_MOD(I_OnPreServerConnect, OnPreServerConnect());
- Anope::string ip = Anope::Resolve(u->host, u->ipv6 ? AF_INET6 : AF_INET);
- Log(LOG_TERMINAL) << "Attempting to connect to uplink #" << (Anope::CurrentUplink + 1) << " " << u->host << " (" << ip << "), port " << u->port;
- UplinkSock->Connect(ip, u->port);
+ Anope::string ip = Anope::Resolve(u.host, u.ipv6 ? AF_INET6 : AF_INET);
+ Log(LOG_TERMINAL) << "Attempting to connect to uplink #" << (Anope::CurrentUplink + 1) << " " << u.host << " (" << ip << "), port " << u.port;
+ UplinkSock->Connect(ip, u.port);
}
-UplinkSocket::UplinkSocket() : Socket(-1, Config->Uplinks[Anope::CurrentUplink]->ipv6), ConnectionSocket(), BufferedSocket()
+UplinkSocket::UplinkSocket() : Socket(-1, Config->Uplinks[Anope::CurrentUplink].ipv6), ConnectionSocket(), BufferedSocket()
{
UplinkSock = this;
}
@@ -107,9 +107,7 @@ UplinkSocket::~UplinkSocket()
}
else if (!Anope::Quitting)
{
- int retry = Config->RetryWait;
- if (retry <= 0)
- retry = 60;
+ time_t retry = Config->GetBlock("options")->Get<time_t>("retrywait");
Log() << "Disconnected, retrying in " << retry << " seconds";
new ReconnectTimer(retry);
@@ -129,14 +127,14 @@ bool UplinkSocket::ProcessRead()
void UplinkSocket::OnConnect()
{
- Log(LOG_TERMINAL) << "Successfully connected to uplink #" << (Anope::CurrentUplink + 1) << " " << Config->Uplinks[Anope::CurrentUplink]->host << ":" << Config->Uplinks[Anope::CurrentUplink]->port;
+ Log(LOG_TERMINAL) << "Successfully connected to uplink #" << (Anope::CurrentUplink + 1) << " " << Config->Uplinks[Anope::CurrentUplink].host << ":" << Config->Uplinks[Anope::CurrentUplink].port;
IRCD->SendConnect();
FOREACH_MOD(I_OnServerConnect, OnServerConnect());
}
void UplinkSocket::OnError(const Anope::string &error)
{
- Log(LOG_TERMINAL) << "Unable to connect to uplink #" << (Anope::CurrentUplink + 1) << " (" << Config->Uplinks[Anope::CurrentUplink]->host << ":" << Config->Uplinks[Anope::CurrentUplink]->port << ")" << (!error.empty() ? (": " + error) : "");
+ Log(LOG_TERMINAL) << "Unable to connect to uplink #" << (Anope::CurrentUplink + 1) << " (" << Config->Uplinks[Anope::CurrentUplink].host << ":" << Config->Uplinks[Anope::CurrentUplink].port << ")" << (!error.empty() ? (": " + error) : "");
}
UplinkSocket::Message::Message() : server(NULL), user(NULL)
diff --git a/src/users.cpp b/src/users.cpp
index 691653055..26d5b31c5 100644
--- a/src/users.cpp
+++ b/src/users.cpp
@@ -279,10 +279,9 @@ void User::SendMessage(const BotInfo *source, const Anope::string &msg)
* - The user is registered and has set /ns set msg on
*/
sepstream sep(translated_message, '\n');
- Anope::string tok;
- while (sep.GetToken(tok))
+ for (Anope::string tok; sep.GetToken(tok);)
{
- if (Config->UsePrivmsg && ((!this->nc && Config->NSDefFlags.count("msg")) || (this->nc && this->nc->HasExt("MSG"))))
+ if (Config->UsePrivmsg && ((!this->nc && Config->DefPrivmsg) || (this->nc && this->nc->HasExt("MSG"))))
IRCD->SendPrivmsg(source, this->GetUID(), "%s", tok.c_str());
else
IRCD->SendNotice(source, this->GetUID(), "%s", tok.c_str());
@@ -291,17 +290,16 @@ void User::SendMessage(const BotInfo *source, const Anope::string &msg)
/** Collides a nick.
*
- * First, it marks the nick (if the user is on a registered nick, we don't use it without but it could be)
- * as COLLIDED, this is checked in NickAlias::OnCancel.
+ * First, it marks the nick as COLLIDED, this is checked in NickAlias::OnCancel.
*
* Then it does one of two things.
*
* 1. This will force change the users nick to the guest nick. This gets processed by the IRCd and comes
- * back to call do_nick. do_nick changes the nick of the use to the new one, then calls NickAlias::OnCancel
+ * back as a nick change, which calls NickAlias::OnCancel
* with the users old nick's nickalias (if there is one).
*
- * 2. Calls User::Kill, which will either delete the user immediatly or kill them, wait for the QUIT,
- * then delete the user then. Users destructor then calls NickAlias::OnCancel
+ * 2. Calls User::Kill, which kills the user and deletes the user at the end of the I/O loop.
+ * Users destructor then calls NickAlias::OnCancel
*
* NickAlias::OnCancel checks for NS_COLLIDED, it then does one of two things.
*
@@ -309,40 +307,13 @@ void User::SendMessage(const BotInfo *source, const Anope::string &msg)
*
* 2. We create a new client with SendClientIntroduction(). Note that is it important that this is called either after the
* user has been removed from our internal list of user or after the users nick has been updated completely internally.
- * This is beacuse SendClientIntroduction will destroy any users we think are currently on the nickname (which causes a
- * lot of problems, eg, deleting the user which recalls OnCancel), whether they really are or not. We then create a
- * release timer for this new client that waits and later on sends a QUIT for the client. Release timers are never used
- * for SVSHolds. Ever.
+ * We then create a release timer for this new client that waits and later on sends a QUIT for the client. Release timers
+ * are never used for SVSHolds. Ever.
*
*
* Note that now for the timers we only store the users name, not the NickAlias* pointer. We never remove timers when
* a user changes nick or a nick is deleted, the timers must assume that either of these may have happend.
*
- * Storing NickAlias* pointers caused quite a problem, some of which are:
- *
- * Having a valid timer alive that calls User::Collide would either:
- *
- * 1. Kill the user, causing users destructor to cancel all timers for the nick (as it should, it has no way of knowing
- * if we are in a timer or not) which would delete the currently active timer while it was running, causing TimerManager
- * to explode.
- *
- * 2. Force a user off of their nick, this would call NickAlias::Cancel before updating the user internally (to cancel the
- * current nicks timers, granted we could have easially saved this and called it after) which could possibly try to
- * introduce an enforcer nick. We would then check to see if the nick is already in use (it is, internally) and send
- * a kill for that nick. That may in turn delete the user immediatly, calling users destructor, which would attempt to
- * delete the timer, causing TimerManager to explode.
- *
- * Additionally, if we marked the timer as "in use" so that calling the ClearTimer function wouldn't delete them, users
- * destructor would then call NickAlias::OnCancel, which would (at this point, it was unsetting GUESTED after introducing
- * the new client) introduce the same new client again, without actually deleting the originial user, causing an infinite
- * loop.
- *
- * This is why we remove NS_GUESTED first in NickAlias::OnCancel before introducing a new client, although this should
- * not happen anymore. If I must emphasize this again, users need to be GONE from the internal list before calling
- * NickAlias::OnCancel. NickAlias::OnCancel intentionally reffers to this->nick, not the user passed to it. They *can*
- * (but not always) be different, depending if the user changed nicks or disconnected.
- *
- *
* Adam
*/
void User::Collide(NickAlias *na)
@@ -352,16 +323,18 @@ void User::Collide(NickAlias *na)
if (IRCD->CanSVSNick)
{
+ const Anope::string &guestprefix = Config->GetBlock("options")->Get<const Anope::string &>("guestnickprefix");
+
Anope::string guestnick;
int i = 0;
do
{
- guestnick = Config->NSGuestNickPrefix + stringify(static_cast<uint16_t>(rand()));
+ guestnick = guestprefix + stringify(static_cast<uint16_t>(rand()));
} while (User::Find(guestnick) && i++ < 10);
if (i == 11)
- this->Kill(Config->NickServ, "Services nickname-enforcer kill");
+ this->Kill(NickServ ? NickServ->nick : "", "Services nickname-enforcer kill");
else
{
if (NickServ)
@@ -370,7 +343,7 @@ void User::Collide(NickAlias *na)
}
}
else
- this->Kill(Config->NickServ, "Services nickname-enforcer kill");
+ this->Kill(NickServ ? NickServ->nick : "", "Services nickname-enforcer kill");
}
void User::Identify(NickAlias *na)
@@ -395,7 +368,7 @@ void User::Identify(NickAlias *na)
IRCD->SendLogin(this);
const NickAlias *this_na = NickAlias::Find(this->nick);
- if (!Config->NoNicknameOwnership && this_na && this_na->nc == *na->nc && na->nc->HasExt("UNCONFIRMED") == false)
+ if (!Config->GetBlock("options")->Get<bool>("nonicknameownership") && this_na && this_na->nc == *na->nc && na->nc->HasExt("UNCONFIRMED") == false)
this->SetMode(NickServ, "REGISTERED");
FOREACH_MOD(I_OnNickIdentify, OnNickIdentify(this));
@@ -738,8 +711,7 @@ bool User::IsProtected() const
void User::Kill(const Anope::string &source, const Anope::string &reason)
{
- Anope::string real_source = source.empty() ? Config->ServerName : source;
- Anope::string real_reason = real_source + " (" + reason + ")";
+ Anope::string real_reason = (source.empty() ? Me->GetName() : source) + " (" + reason + ")";
IRCD->SendSVSKill(BotInfo::Find(source), this, "%s", real_reason.c_str());
}
@@ -754,12 +726,7 @@ void User::KillInternal(const Anope::string &source, const Anope::string &reason
Log(this, "killed") << "was killed by " << source << " (Reason: " << reason << ")";
- NickAlias *na = NickAlias::Find(this->nick);
- if (na && !na->nc->HasExt("SUSPENDED") && (this->IsRecognized() || this->IsIdentified(true)))
- {
- na->last_seen = Anope::CurTime;
- na->last_quit = reason;
- }
+ this->Quit(reason);
this->quit = true;
quitting_users.push_back(this);
@@ -773,6 +740,8 @@ void User::Quit(const Anope::string &reason)
return;
}
+ FOREACH_MOD(I_OnUserQuit, OnUserQuit(this, reason));
+
this->quit = true;
quitting_users.push_back(this);
}
@@ -813,16 +782,16 @@ Anope::string User::Mask() const
bool User::BadPassword()
{
- if (!Config->BadPassLimit)
+ if (!Config->GetBlock("options")->Get<int>("badpasslimit"))
return false;
- if (Config->BadPassTimeout > 0 && this->invalid_pw_time > 0 && this->invalid_pw_time < Anope::CurTime - Config->BadPassTimeout)
+ if (Config->GetBlock("options")->Get<time_t>("badpasstimeout") > 0 && this->invalid_pw_time > 0 && this->invalid_pw_time < Anope::CurTime - Config->GetBlock("options")->Get<time_t>("badpasstimeout"))
this->invalid_pw_count = 0;
++this->invalid_pw_count;
this->invalid_pw_time = Anope::CurTime;
- if (this->invalid_pw_count >= Config->BadPassLimit)
+ if (this->invalid_pw_count >= Config->GetBlock("options")->Get<int>("badpasslimit"))
{
- this->Kill(Config->ServerName, "Too many invalid passwords");
+ this->Kill(Me->GetName(), "Too many invalid passwords");
return true;
}
diff --git a/src/xline.cpp b/src/xline.cpp
index 67f976d9a..0ba3d6557 100644
--- a/src/xline.cpp
+++ b/src/xline.cpp
@@ -25,11 +25,11 @@ Serialize::Checker<std::multimap<Anope::string, XLine *, ci::less> > XLineManage
void XLine::InitRegex()
{
- if (!Config->RegexEngine.empty() && this->mask.length() >= 2 && this->mask[0] == '/' && this->mask[this->mask.length() - 1] == '/')
+ if (this->mask.length() >= 2 && this->mask[0] == '/' && this->mask[this->mask.length() - 1] == '/' && !Config->GetBlock("options")->Get<const Anope::string &>("regexengine").empty())
{
Anope::string stripped_mask = this->mask.substr(1, this->mask.length() - 2);
- ServiceReference<RegexProvider> provider("Regex", Config->RegexEngine);
+ ServiceReference<RegexProvider> provider("Regex", Config->GetBlock("options")->Get<const Anope::string &>("regexengine"));
if (provider)
{
try
@@ -44,7 +44,7 @@ void XLine::InitRegex()
}
}
-XLine::XLine(const Anope::string &ma, const Anope::string &r, const Anope::string &uid) : Serializable("XLine"), mask(ma), by(Config->OperServ), created(0), expires(0), reason(r), id(uid)
+XLine::XLine(const Anope::string &ma, const Anope::string &r, const Anope::string &uid) : Serializable("XLine"), mask(ma), by(OperServ ? OperServ->nick : ""), created(0), expires(0), reason(r), id(uid)
{
regex = NULL;
manager = NULL;
@@ -118,8 +118,6 @@ Anope::string XLine::GetReal() const
Anope::string XLine::GetReason() const
{
Anope::string r = this->reason;
- if (Config->AddAkiller && !this->by.empty())
- r = "[" + this->by + "] " + r;
if (!this->id.empty())
r += " (ID: " + this->id + ")";
return r;