summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/ISSUE_TEMPLATE.md40
-rwxr-xr-xconfigure71
-rw-r--r--docs/Doxyfile2
-rw-r--r--docs/conf/filter.conf.example7
-rw-r--r--docs/conf/inspircd.conf.example5
-rw-r--r--docs/conf/modules.conf.example22
-rw-r--r--docs/conf/services/atheme.conf.example2
-rw-r--r--include/base.h2
-rw-r--r--include/builtinmodes.h6
-rw-r--r--include/commands/cmd_whowas.h1
-rw-r--r--include/extensible.h2
-rw-r--r--include/inspsocket.h4
-rw-r--r--include/logger.h8
-rw-r--r--include/mode.h4
-rw-r--r--include/modules.h2
-rw-r--r--include/modules/dns.h2
-rw-r--r--include/numerics.h3
-rw-r--r--include/socketengine.h16
-rw-r--r--include/users.h50
-rwxr-xr-xmake/calcdep.pl2
-rw-r--r--make/common.pm37
-rw-r--r--make/configure.pm69
-rw-r--r--make/console.pm55
-rw-r--r--make/directive.pm6
-rw-r--r--make/test/clock_gettime.cpp1
-rw-r--r--make/test/compiler.cpp2
-rw-r--r--make/test/compiler_info.cpp41
-rwxr-xr-xmodulemanager79
-rw-r--r--src/coremods/core_dns.cpp27
-rw-r--r--src/coremods/core_hostname_lookup.cpp6
-rw-r--r--src/coremods/core_loadmodule.cpp2
-rw-r--r--src/coremods/core_lusers.cpp6
-rw-r--r--src/coremods/core_privmsg.cpp2
-rw-r--r--src/coremods/core_stub.cpp2
-rw-r--r--src/coremods/core_user/cmd_mode.cpp33
-rw-r--r--src/coremods/core_who.cpp11
-rw-r--r--src/coremods/core_whois.cpp4
-rw-r--r--src/coremods/core_whowas.cpp6
-rw-r--r--src/coremods/core_xline/cmd_gline.cpp1
-rw-r--r--src/coremods/core_xline/cmd_kline.cpp1
-rw-r--r--src/coremods/core_xline/cmd_qline.cpp1
-rw-r--r--src/coremods/core_xline/cmd_zline.cpp1
-rw-r--r--src/coremods/core_xline/core_xline.h1
-rw-r--r--src/inspircd.cpp2
-rw-r--r--src/logger.cpp10
-rw-r--r--src/mode.cpp2
-rw-r--r--src/modes/umode_s.cpp2
-rw-r--r--src/modmanager_static.cpp2
-rw-r--r--src/modules/extra/m_pgsql.cpp8
-rw-r--r--src/modules/m_abbreviation.cpp2
-rw-r--r--src/modules/m_alias.cpp2
-rw-r--r--src/modules/m_bcrypt.cpp2
-rw-r--r--src/modules/m_cgiirc.cpp10
-rw-r--r--src/modules/m_check.cpp2
-rw-r--r--src/modules/m_clearchan.cpp2
-rw-r--r--src/modules/m_cloaking.cpp11
-rw-r--r--src/modules/m_conn_join.cpp2
-rw-r--r--src/modules/m_conn_umodes.cpp2
-rw-r--r--src/modules/m_connectban.cpp2
-rw-r--r--src/modules/m_dnsbl.cpp10
-rw-r--r--src/modules/m_filter.cpp2
-rw-r--r--src/modules/m_flashpolicyd.cpp2
-rw-r--r--src/modules/m_hostcycle.cpp2
-rw-r--r--src/modules/m_httpd.cpp4
-rw-r--r--src/modules/m_httpd_stats.cpp4
-rw-r--r--src/modules/m_ircv3.cpp2
-rw-r--r--src/modules/m_ldapauth.cpp15
-rw-r--r--src/modules/m_md5.cpp26
-rw-r--r--src/modules/m_messageflood.cpp2
-rw-r--r--src/modules/m_mlock.cpp2
-rw-r--r--src/modules/m_namedmodes.cpp2
-rw-r--r--src/modules/m_nicklock.cpp2
-rw-r--r--src/modules/m_ojoin.cpp4
-rw-r--r--src/modules/m_operprefix.cpp4
-rw-r--r--src/modules/m_override.cpp3
-rw-r--r--src/modules/m_permchannels.cpp6
-rw-r--r--src/modules/m_rline.cpp2
-rw-r--r--src/modules/m_sajoin.cpp2
-rw-r--r--src/modules/m_sakick.cpp2
-rw-r--r--src/modules/m_samode.cpp4
-rw-r--r--src/modules/m_sanick.cpp2
-rw-r--r--src/modules/m_sapart.cpp2
-rw-r--r--src/modules/m_saquit.cpp2
-rw-r--r--src/modules/m_sasl.cpp61
-rw-r--r--src/modules/m_satopic.cpp2
-rw-r--r--src/modules/m_sha1.cpp2
-rw-r--r--src/modules/m_shun.cpp2
-rw-r--r--src/modules/m_spanningtree/main.h4
-rw-r--r--src/modules/m_spanningtree/protocolinterface.h6
-rw-r--r--src/modules/m_spanningtree/servercommand.h2
-rw-r--r--src/modules/m_spanningtree/treeserver.h2
-rw-r--r--src/modules/m_spanningtree/treesocket.h10
-rw-r--r--src/modules/m_spanningtree/uid.cpp10
-rw-r--r--src/modules/m_spanningtree/utils.h2
-rw-r--r--src/modules/m_timedbans.cpp2
-rw-r--r--src/socketengine.cpp36
-rw-r--r--src/socketengines/socketengine_epoll.cpp12
-rw-r--r--src/socketengines/socketengine_kqueue.cpp2
-rw-r--r--src/socketengines/socketengine_ports.cpp2
-rw-r--r--src/socketengines/socketengine_select.cpp2
-rw-r--r--src/users.cpp53
-rwxr-xr-xtools/genssl2
-rw-r--r--win/CMakeLists.txt1
103 files changed, 645 insertions, 386 deletions
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
new file mode 100644
index 000000000..6fdf33bba
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE.md
@@ -0,0 +1,40 @@
+<!--
+---------------------------------------------------
+GENERAL SUPPORT INFORMATION
+---------------------------------------------------
+
+The GitHub issue tracker is for bug reports and feature requests.
+General support can be found at the following locations:
+
+IRC:
+irc.inspircd.org #inspircd
+
+Example configs:
+2.0 - https://github.com/inspircd/inspircd/tree/insp20/docs/conf
+3.0 (alpha) - https://github.com/inspircd/inspircd/tree/master/docs/conf
+
+Wiki:
+https://wiki.inspircd.org/
+-->
+
+**Description**
+
+<!--
+Briefly describe the problem you are having in a few paragraphs.
+-->
+
+**Steps to reproduce the issue:**
+1.
+2.
+3.
+
+**Describe the results you received:**
+
+
+**Describe the results you expected:**
+
+
+**Additional information you deem important (e.g. issue happens only occasionally):**
+
+**Output of `./bin/inspircd --version`:**
+
diff --git a/configure b/configure
index 696d94886..ca2e2f19b 100755
--- a/configure
+++ b/configure
@@ -3,6 +3,7 @@
#
# InspIRCd -- Internet Relay Chat Daemon
#
+# Copyright (C) 2012-2017 Peter Powell <petpow@saberuk.com>
# Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
# Copyright (C) 2007, 2009 Dennis Friis <peavey@inspircd.org>
# Copyright (C) 2003, 2006-2008 Craig Edwards <craigedwards@brainbox.cc>
@@ -129,9 +130,9 @@ our $interactive = !(
my %version = get_version $opt_distribution_label;
print_format "<|BOLD Configuring InspIRCd $version{FULL} on $^O.|>\n";
-our %config;
+my %config;
if ($interactive) {
- %config = read_configure_cache();
+ %config = read_config_file(CONFIGURE_CACHE_FILE);
run_test CONFIGURE_CACHE_FILE, %config;
if (!defined $config{VERSION}) {
$config{VERSION} = CONFIGURE_CACHE_VERSION;
@@ -143,50 +144,37 @@ if ($interactive) {
$config{CXX} = find_compiler($config{CXX} // $ENV{CXX});
unless ($config{CXX}) {
- print "A suitable C++ compiler could not be detected on your system!\n";
- print "Set the CXX environment variable to the compiler binary path if this is incorrect.\n";
- exit 1;
+ say 'A suitable C++ compiler could not be detected on your system!';
+ unless ($interactive) {
+ say 'Set the CXX environment variable to the path to a C++ compiler binary if this is incorrect.';
+ exit 1;
+ }
+ until ($config{CXX}) {
+ my $compiler_path = prompt_string 1, 'Please enter the path to a C++ compiler binary:', 'c++';
+ $config{CXX} = find_compiler $compiler_path;
+ }
}
my %compiler = get_compiler_info($config{CXX});
-$config{HAS_CLOCK_GETTIME} = run_test 'clock_gettime()', test_file($config{CXX}, 'clock_gettime.cpp', '-lrt');
+$config{HAS_CLOCK_GETTIME} = run_test 'clock_gettime()', test_file($config{CXX}, 'clock_gettime.cpp', $^O eq 'darwin' ? undef : '-lrt');
$config{HAS_EVENTFD} = run_test 'eventfd()', test_file($config{CXX}, 'eventfd.cpp');
-if ($config{HAS_EPOLL} = run_test 'epoll', test_header($config{CXX}, 'sys/epoll.h')) {
- $config{SOCKETENGINE} //= 'epoll';
-}
-
-if ($config{HAS_KQUEUE} = run_test 'kqueue', test_file($config{CXX}, 'kqueue.cpp')) {
- $config{SOCKETENGINE} //= 'kqueue';
-}
-
-if ($config{HAS_PORTS} = run_test 'Solaris IOCP', test_header($config{CXX}, 'port.h')) {
- $config{SOCKETENGINE} //= 'ports';
-}
-
-if ($config{HAS_POLL} = run_test 'poll', test_header($config{CXX}, 'poll.h')) {
- $config{SOCKETENGINE} //= 'poll';
-}
-
-# Select is available on all platforms
-$config{HAS_SELECT} = 1;
-$config{SOCKETENGINE} //= 'select';
+my @socketengines;
+push @socketengines, 'epoll' if run_test 'epoll', test_header $config{CXX}, 'sys/epoll.h';
+push @socketengines, 'kqueue' if run_test 'kqueue', test_file $config{CXX}, 'kqueue.cpp';
+push @socketengines, 'ports' if run_test 'Solaris IOCP', test_header $config{CXX}, 'port.h';
+push @socketengines, 'poll' if run_test 'poll', test_header $config{CXX}, 'poll.h';
+push @socketengines, 'select';
if (defined $opt_socketengine) {
- my $cfgkey = 'HAS_' . uc $opt_socketengine;
- if ($config{$cfgkey} && -f "src/socketengines/socketengine_$opt_socketengine.cpp") {
- $config{SOCKETENGINE} = $opt_socketengine;
- } else {
- print "Unable to use a socket engine which is not supported on this platform ($opt_socketengine)!\n";
- print "Available socket engines are:";
- foreach (<src/socketengines/socketengine_*.cpp>) {
- s/src\/socketengines\/socketengine_(\w+)\.cpp/$1/;
- print " $1" if $config{'HAS_' . uc $1};
- }
- print "\n";
- exit 1;
+ unless (grep { $_ eq $opt_socketengine } @socketengines) {
+ my $reason = -f "src/socketengines/socketengine_$opt_socketengine.cpp" ? 'is not available on this platform' : 'does not exist';
+ print_error "The socket engine you requested ($opt_socketengine) $reason!",
+ 'Available socket engines are:',
+ map { " * $_" } @socketengines;
}
}
+$config{SOCKETENGINE} = $opt_socketengine // $socketengines[0];
if (defined $opt_system) {
$config{BASE_DIR} = $opt_prefix // '/var/lib/inspircd';
@@ -233,6 +221,15 @@ $config{UID} = $user[2];
# Clear the screen.
system 'tput', 'clear' if $interactive;
+# Warn the user about clock drifting when running on OpenVZ.
+if (-e '/proc/user_beancounters' || -e '/proc/vz/vzaquota') {
+ print_warning <<'EOW';
+You are building InspIRCd inside of an an OpenVZ container. If you
+plan to use InspIRCd in this container then you should make sure that NTP is
+configured on the Hardware Node. Failure to do so may result in clock drifting!
+EOW
+}
+
# Check that the user actually wants this version.
if ($version{LABEL} ne 'release') {
print_warning <<'EOW';
diff --git a/docs/Doxyfile b/docs/Doxyfile
index 807020af5..f4e526bc7 100644
--- a/docs/Doxyfile
+++ b/docs/Doxyfile
@@ -1,6 +1,6 @@
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = InspIRCd
-PROJECT_NUMBER = 2.0
+PROJECT_NUMBER = 3.0
PROJECT_BRIEF =
PROJECT_LOGO =
OUTPUT_DIRECTORY = docs/doxygen
diff --git a/docs/conf/filter.conf.example b/docs/conf/filter.conf.example
index cc72fe9a2..ea62efd1f 100644
--- a/docs/conf/filter.conf.example
+++ b/docs/conf/filter.conf.example
@@ -6,7 +6,7 @@
# reason="reason for filtering"
# action="action to take"
# flags="filter flags"
-# duration="optional length of gline">
+# duration="optional length of gline">
#
# Valid actions for 'action' are:
#
@@ -40,11 +40,6 @@
# c: Strip color codes from text before trying to match
# *: Represents all of the above flags
# -: Does nothing, a no-op for when you do not want to specify any flags
-#
-# IMPORTANT NOTE: Because the InspIRCd config reader places special meaning on the
-# '\' character, you must use '\\' if you wish to specify a '\' character in a regular
-# expression. For example, to indicate numbers, use \\d and not \d. This does not
-# apply when adding a regular expression over irc with the /FILTER command.
# Example filters:
#
diff --git a/docs/conf/inspircd.conf.example b/docs/conf/inspircd.conf.example
index 79a127d5a..7ba324e47 100644
--- a/docs/conf/inspircd.conf.example
+++ b/docs/conf/inspircd.conf.example
@@ -838,6 +838,11 @@
# - USERINPUT
# - USEROUTPUT
#
+# If your server is producing a high levels of log messages you can also set the
+# flush="[positive number]" attribute to specify how many log messages should be
+# buffered before flushing to disk. You should probably not specify this unless
+# you are having problems.
+#
# The following log tag is highly default and uncustomised. It is recommended you
# sort out your own log tags. This is just here so you get some output.
diff --git a/docs/conf/modules.conf.example b/docs/conf/modules.conf.example
index 020a15ded..93e26059c 100644
--- a/docs/conf/modules.conf.example
+++ b/docs/conf/modules.conf.example
@@ -1059,7 +1059,8 @@
# allowpattern="Guest* Bot*" #
# killreason="Access denied" #
# verbose="yes" #
-# host="$uid.$ou.inspircd.org"> #
+# host="$uid.$ou.inspircd.org" #
+# useusername="no"> #
# #
# <ldapwhitelist cidr="10.42.0.0/16"> #
# #
@@ -1076,6 +1077,10 @@
# regardless of if they have an account, for example guest and bot #
# users. #
# #
+# The useusername setting chooses whether the user's username or #
+# nickname is used when locating a user account, if a username isn't #
+# provided in PASS. #
+# #
# Killreason indicates the QUIT reason to give to users if they fail #
# to authenticate. #
# #
@@ -1434,7 +1439,6 @@
#<include file="permchannels.conf">
#
# You may also create channels on startup by using the <permchannels> block.
-# Don't forget to set them +P in the modes, or they won't stay permanent.
#<permchannels channel="#opers" modes="isP" topic="Opers only.">
#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
@@ -1683,13 +1687,12 @@
#
#-#-#-#-#-#-#-#-#-# SECURELIST CONFIGURATION -#-#-#-#-#-#-#-#-#-#-#-#-#
# #
-# Securelist can be harmful to some IRC search engines such as #
-# netsplit.de and searchirc.com. To prevent securelist blocking these #
-# sites from listing, define exception tags as shown below: #
-#<securehost exception="*@*.searchirc.org">
+# Securelist can be harmful to some IRC search engines. To prevent #
+# securelist blocking these sites from listing, define exception tags #
+# as shown below: #
#<securehost exception="*@*.netsplit.de">
-#<securehost exception="*@echo940.server4you.de">
#<securehost exception="*@*.ircdriven.com">
+#<securehost exception="*@*.irc-source.com">
# #
# Define the following variable to change how long a user must wait #
# before issuing a LIST. If not defined, defaults to 60 seconds. #
@@ -1827,7 +1830,8 @@
# SSL channel mode module: Adds support for SSL-only channels via
# channel mode +z and the 'z' extban which matches SSL client
# certificate fingerprints.
-# Does not do anything useful without a working SSL module (see below).
+# Does not do anything useful without a working SSL module and the
+# sslinfo module (see below).
#<module name="sslmodes">
#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
@@ -2035,7 +2039,7 @@
#<module name="xline_db">
# Specify the filename for the xline database here.
-#<xlinedb filename="data/xline.db">
+#<xlinedb filename="xline.db">
#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
# ____ _ _____ _ _ ____ _ _ _ #
diff --git a/docs/conf/services/atheme.conf.example b/docs/conf/services/atheme.conf.example
index dae1dfce2..037087998 100644
--- a/docs/conf/services/atheme.conf.example
+++ b/docs/conf/services/atheme.conf.example
@@ -11,7 +11,7 @@
<alias text="GLOBAL" replace="PRIVMSG $requirement :$2-" requires="Global" uline="yes" operonly="yes">
<alias text="GROUPSERV" replace="PRIVMSG $requirement :$2-" requires="GroupServ" uline="yes">
<alias text="HELPSERV" replace="PRIVMSG $requirement :$2-" requires="HelpServ" uline="yes">
-<alias text="INFOSERV" replace="PRIVMSG $requirement :$2-" requires="GroupServ" uline="yes">
+<alias text="INFOSERV" replace="PRIVMSG $requirement :$2-" requires="InfoServ" uline="yes">
<alias text="PROXYSCAN" replace="PRIVMSG $requirement :$2-" requires="Proxyscan" uline="yes" operonly="yes">
<alias text="RPGSERV" replace="PRIVMSG $requirement :$2-" requires="RPGServ" uline="yes">
diff --git a/include/base.h b/include/base.h
index c378afc1c..d8781f796 100644
--- a/include/base.h
+++ b/include/base.h
@@ -202,7 +202,7 @@ class CoreExport CoreException : public std::exception
* Actually no, it does nothing. Never mind.
* @throws Nothing!
*/
- virtual ~CoreException() throw() {};
+ virtual ~CoreException() throw() {}
/** Returns the reason for the exception.
* @return Human readable description of the error
*/
diff --git a/include/builtinmodes.h b/include/builtinmodes.h
index 62ccaf62d..bfb46823f 100644
--- a/include/builtinmodes.h
+++ b/include/builtinmodes.h
@@ -97,14 +97,14 @@ class ModeUserServerNoticeMask : public ModeHandler
public:
ModeUserServerNoticeMask();
- ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string &parameter, bool adding);
- void OnParameterMissing(User* user, User* dest, Channel* channel);
+ ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string &parameter, bool adding) CXX11_OVERRIDE;
+ void OnParameterMissing(User* user, User* dest, Channel* channel) CXX11_OVERRIDE;
/** Create a displayable mode string of the snomasks set on a given user
* @param user The user whose notice masks to format
* @return The notice mask character sequence
*/
- std::string GetUserParameter(User* user);
+ std::string GetUserParameter(const User* user) const CXX11_OVERRIDE;
};
/** User mode +o
diff --git a/include/commands/cmd_whowas.h b/include/commands/cmd_whowas.h
index aaea31864..070858cc5 100644
--- a/include/commands/cmd_whowas.h
+++ b/include/commands/cmd_whowas.h
@@ -200,7 +200,6 @@ class CommandWhowas : public Command
CommandWhowas(Module* parent);
/** Handle command.
* @param parameters The parameters to the comamnd
- * @param pcnt The number of parameters passed to teh command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
diff --git a/include/extensible.h b/include/extensible.h
index 07756fb59..1da45cee6 100644
--- a/include/extensible.h
+++ b/include/extensible.h
@@ -111,7 +111,7 @@ class CoreExport Extensible : public classbase
inline const ExtensibleStore& GetExtList() const { return extensions; }
Extensible();
- virtual CullResult cull();
+ virtual CullResult cull() CXX11_OVERRIDE;
virtual ~Extensible();
void doUnhookExtensions(const std::vector<reference<ExtensionItem> >& toRemove);
diff --git a/include/inspsocket.h b/include/inspsocket.h
index 751374fdf..95f29ff11 100644
--- a/include/inspsocket.h
+++ b/include/inspsocket.h
@@ -312,7 +312,7 @@ class CoreExport StreamSocket : public EventHandler
*/
virtual void Close();
/** This ensures that close is called prior to destructor */
- virtual CullResult cull();
+ virtual CullResult cull() CXX11_OVERRIDE;
/** Get the IOHook of a module attached to this socket
* @param mod Module whose IOHook to return
@@ -372,7 +372,7 @@ class CoreExport BufferedSocket : public StreamSocket
/** When there is data waiting to be read on a socket, the OnDataReady()
* method is called.
*/
- virtual void OnDataReady() = 0;
+ virtual void OnDataReady() CXX11_OVERRIDE = 0;
/**
* When an outbound connection fails, and the attempt times out, you
diff --git a/include/logger.h b/include/logger.h
index c56859a62..5d4a80d9f 100644
--- a/include/logger.h
+++ b/include/logger.h
@@ -41,14 +41,18 @@ class CoreExport FileWriter
*/
FILE* log;
+ /** The number of write operations after which we should flush.
+ */
+ unsigned int flush;
+
/** Number of write operations that have occured
*/
- int writeops;
+ unsigned int writeops;
public:
/** The constructor takes an already opened logfile.
*/
- FileWriter(FILE* logfile);
+ FileWriter(FILE* logfile, unsigned int flushcount);
/** Write one or more preformatted log lines.
* If the data cannot be written immediately,
diff --git a/include/mode.h b/include/mode.h
index 35af68685..2e9ed22f3 100644
--- a/include/mode.h
+++ b/include/mode.h
@@ -166,7 +166,7 @@ class CoreExport ModeHandler : public ServiceProvider
* @param mclass The object type of this mode handler, one of ModeHandler::Class
*/
ModeHandler(Module* me, const std::string& name, char modeletter, ParamSpec params, ModeType type, Class mclass = MC_OTHER);
- virtual CullResult cull();
+ virtual CullResult cull() CXX11_OVERRIDE;
virtual ~ModeHandler();
/** Register this object in the ModeParser
@@ -241,7 +241,7 @@ class CoreExport ModeHandler : public ServiceProvider
/** For user modes, return the current parameter, if any
*/
- virtual std::string GetUserParameter(User* useor);
+ virtual std::string GetUserParameter(const User* user) const;
/**
* Called when a channel mode change access check for your mode occurs.
diff --git a/include/modules.h b/include/modules.h
index 5deed943a..d9d05a396 100644
--- a/include/modules.h
+++ b/include/modules.h
@@ -276,7 +276,7 @@ class CoreExport Module : public classbase, public usecountbase
/** Clean up prior to destruction
* If you override, you must call this AFTER your module's cleanup
*/
- virtual CullResult cull();
+ virtual CullResult cull() CXX11_OVERRIDE;
/** Default destructor.
* destroys a module class
diff --git a/include/modules/dns.h b/include/modules/dns.h
index 5f2836761..61abd7144 100644
--- a/include/modules/dns.h
+++ b/include/modules/dns.h
@@ -33,6 +33,8 @@ namespace DNS
QUERY_CNAME = 5,
/* Reverse DNS lookup */
QUERY_PTR = 12,
+ /* TXT */
+ QUERY_TXT = 16,
/* IPv6 AAAA lookup */
QUERY_AAAA = 28
};
diff --git a/include/numerics.h b/include/numerics.h
index 606e23819..0d5537278 100644
--- a/include/numerics.h
+++ b/include/numerics.h
@@ -195,6 +195,9 @@ enum
ERR_CHANOPEN = 713,
ERR_KNOCKONCHAN = 714,
+ RPL_OTHERUMODEIS = 803, // insp-specific
+ RPL_OTHERSNOMASKIS = 804, // insp-specific
+
ERR_WORDFILTERED = 936, // insp-specific, would be nice if we could get rid of this..
ERR_CANTUNLOADMODULE = 972, // insp-specific
RPL_UNLOADEDMODULE = 973, // insp-specific
diff --git a/include/socketengine.h b/include/socketengine.h
index c0026bfc6..b00643952 100644
--- a/include/socketengine.h
+++ b/include/socketengine.h
@@ -244,11 +244,19 @@ class CoreExport SocketEngine
*/
Statistics() : lastempty(0), TotalEvents(0), ReadEvents(0), WriteEvents(0), ErrorEvents(0) { }
- /** Increase the counters for bytes sent/received in this second.
- * @param len_in Bytes received, 0 if updating number of bytes written.
- * @param len_out Bytes sent, 0 if updating number of bytes read.
+ /** Update counters for network data received.
+ * This should be called after every read-type syscall.
+ * @param len_in Number of bytes received, or -1 for error, as typically
+ * returned by a read-style syscall.
*/
- void Update(size_t len_in, size_t len_out);
+ void UpdateReadCounters(int len_in);
+
+ /** Update counters for network data sent.
+ * This should be called after every write-type syscall.
+ * @param len_out Number of bytes sent, or -1 for error, as typically
+ * returned by a read-style syscall.
+ */
+ void UpdateWriteCounters(int len_out);
/** Get data transfer statistics.
* @param kbitspersec_in Filled with incoming traffic in this second in kbit/s.
diff --git a/include/users.h b/include/users.h
index fc31a8297..4c8df549d 100644
--- a/include/users.h
+++ b/include/users.h
@@ -418,19 +418,21 @@ class CoreExport User : public Extensible
*/
bool IsNoticeMaskSet(unsigned char sm);
- /** Create a displayable mode string for this users umodes
- * @param showparameters The mode string
+ /** Get the mode letters of modes set on the user as a string.
+ * @param includeparams True to get the parameters of the modes as well. Defaults to false.
+ * @return Mode letters of modes set on the user and optionally the parameters of those modes, if any.
+ * The returned string always begins with a '+' character. If the user has no modes set, "+" is returned.
*/
- const char* FormatModes(bool showparameters = false);
+ std::string GetModeLetters(bool includeparams = false) const;
/** Returns true if a specific mode is set
* @param m The user mode
* @return True if the mode is set
*/
- bool IsModeSet(unsigned char m);
- bool IsModeSet(ModeHandler* mh);
- bool IsModeSet(ModeHandler& mh) { return IsModeSet(&mh); }
- bool IsModeSet(UserModeReference& moderef);
+ bool IsModeSet(unsigned char m) const;
+ bool IsModeSet(const ModeHandler* mh) const;
+ bool IsModeSet(const ModeHandler& mh) const { return IsModeSet(&mh); }
+ bool IsModeSet(UserModeReference& moderef) const;
/** Set a specific usermode to on or off
* @param m The user mode
@@ -715,7 +717,7 @@ class CoreExport User : public Extensible
/** Default destructor
*/
virtual ~User();
- virtual CullResult cull();
+ virtual CullResult cull() CXX11_OVERRIDE;
};
class CoreExport UserIOHandler : public StreamSocket
@@ -740,7 +742,7 @@ class CoreExport LocalUser : public User, public insp::intrusive_list_node<Local
{
public:
LocalUser(int fd, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server);
- CullResult cull();
+ CullResult cull() CXX11_OVERRIDE;
UserIOHandler eh;
@@ -834,12 +836,12 @@ class CoreExport LocalUser : public User, public insp::intrusive_list_node<Local
*/
void SetClass(const std::string &explicit_name = "");
- bool SetClientIP(const char* sip, bool recheck_eline = true);
+ bool SetClientIP(const char* sip, bool recheck_eline = true) CXX11_OVERRIDE;
- void SetClientIP(const irc::sockets::sockaddrs& sa, bool recheck_eline = true);
+ void SetClientIP(const irc::sockets::sockaddrs& sa, bool recheck_eline = true) CXX11_OVERRIDE;
- void Write(const std::string& text);
- void Write(const char*, ...) CUSTOM_PRINTF(2, 3);
+ void Write(const std::string& text) CXX11_OVERRIDE;
+ void Write(const char*, ...) CXX11_OVERRIDE CUSTOM_PRINTF(2, 3);
/** Send a NOTICE message from the local server to the user.
* The message will be sent even if the user is connected to a remote server.
@@ -853,7 +855,7 @@ class CoreExport LocalUser : public User, public insp::intrusive_list_node<Local
* @param command A command (should be all CAPS)
* @return True if this user can execute the command
*/
- bool HasPermission(const std::string &command);
+ bool HasPermission(const std::string &command) CXX11_OVERRIDE;
/** Returns true if a user has a given permission.
* This is used to check whether or not users may perform certain actions which admins may not wish to give to
@@ -863,7 +865,7 @@ class CoreExport LocalUser : public User, public insp::intrusive_list_node<Local
* @param noisy If set to true, the user is notified that they do not have the specified permission where applicable. If false, no notification is sent.
* @return True if this user has the permission in question.
*/
- bool HasPrivPermission(const std::string &privstr, bool noisy = false);
+ bool HasPrivPermission(const std::string &privstr, bool noisy = false) CXX11_OVERRIDE;
/** Returns true or false if a user can set a privileged user or channel mode.
* This is done by looking up their oper type from User::oper, then referencing
@@ -871,7 +873,13 @@ class CoreExport LocalUser : public User, public insp::intrusive_list_node<Local
* @param mh Mode to check
* @return True if the user can set or unset this mode.
*/
- bool HasModePermission(const ModeHandler* mh) const;
+ bool HasModePermission(const ModeHandler* mh) const CXX11_OVERRIDE;
+
+ /** Change nick to uuid, unset REG_NICK and send a nickname overruled numeric.
+ * This is called when another user (either local or remote) needs the nick of this user and this user
+ * isn't registered.
+ */
+ void OverruleNick();
};
class RemoteUser : public User
@@ -896,9 +904,9 @@ class CoreExport FakeUser : public User
nick = sname;
}
- virtual CullResult cull();
- virtual const std::string& GetFullHost();
- virtual const std::string& GetFullRealHost();
+ virtual CullResult cull() CXX11_OVERRIDE;
+ virtual const std::string& GetFullHost() CXX11_OVERRIDE;
+ virtual const std::string& GetFullRealHost() CXX11_OVERRIDE;
};
/* Faster than dynamic_cast */
@@ -918,12 +926,12 @@ inline FakeUser* IS_SERVER(User* u)
return u->usertype == USERTYPE_SERVER ? static_cast<FakeUser*>(u) : NULL;
}
-inline bool User::IsModeSet(ModeHandler* mh)
+inline bool User::IsModeSet(const ModeHandler* mh) const
{
return (modes[mh->GetId()]);
}
-inline bool User::IsModeSet(UserModeReference& moderef)
+inline bool User::IsModeSet(UserModeReference& moderef) const
{
if (!moderef)
return false;
diff --git a/make/calcdep.pl b/make/calcdep.pl
index 882e75f22..99355efa4 100755
--- a/make/calcdep.pl
+++ b/make/calcdep.pl
@@ -166,7 +166,7 @@ END
obj/ld-extra.cmd: $core_src
\@\$(SOURCEPATH)/make/unit-cc.pl gen-ld \$\@ \$^ \$>
-bin/inspircd: obj/ld-extra.cmd $core_mk
+bin/inspircd: $core_mk obj/ld-extra.cmd
\@\$(SOURCEPATH)/make/unit-cc.pl static-ld \$\@ \$^ \$>
inspircd: bin/inspircd
diff --git a/make/common.pm b/make/common.pm
index b1608db56..6ca280bec 100644
--- a/make/common.pm
+++ b/make/common.pm
@@ -1,7 +1,7 @@
#
# InspIRCd -- Internet Relay Chat Daemon
#
-# Copyright (C) 2013-2014 Peter Powell <petpow@saberuk.com>
+# Copyright (C) 2013-2017 Peter Powell <petpow@saberuk.com>
#
# This file is part of InspIRCd. InspIRCd is free software: you can
# redistribute it and/or modify it under the terms of the GNU General Public
@@ -31,10 +31,13 @@ use Exporter qw(import);
use File::Path qw(mkpath);
use File::Spec::Functions qw(rel2abs);
+use make::console;
+
our @EXPORT = qw(create_directory
get_cpu_count
get_version
- module_installed);
+ read_config_file
+ write_config_file);
sub create_directory($$) {
my ($location, $permissions) = @_;
@@ -86,12 +89,6 @@ sub get_version {
return %version;
}
-sub module_installed($) {
- my $module = shift;
- eval("use $module;");
- return !$@;
-}
-
sub get_cpu_count {
my $count = 1;
if ($^O =~ /bsd/) {
@@ -107,4 +104,28 @@ sub get_cpu_count {
return $count;
}
+sub read_config_file($) {
+ my $path = shift;
+ my %config;
+ open(my $fh, $path) or return %config;
+ while (my $line = <$fh>) {
+ next if $line =~ /^\s*($|\#)/;
+ my ($key, $value) = ($line =~ /^(\S+)(?:\s(.*))?$/);
+ $config{$key} = $value;
+ }
+ close $fh;
+ return %config;
+}
+
+sub write_config_file($%) {
+ my $path = shift;
+ my %config = @_;
+ open(my $fh, '>', $path) or print_error "unable to write to $path: $!";
+ while (my ($key, $value) = each %config) {
+ $value //= '';
+ say $fh "$key $value";
+ }
+ close $fh;
+}
+
1;
diff --git a/make/configure.pm b/make/configure.pm
index 6b4693d45..dbbbf6509 100644
--- a/make/configure.pm
+++ b/make/configure.pm
@@ -1,7 +1,7 @@
#
# InspIRCd -- Internet Relay Chat Daemon
#
-# Copyright (C) 2012-2014 Peter Powell <petpow@saberuk.com>
+# Copyright (C) 2012-2017 Peter Powell <petpow@saberuk.com>
# Copyright (C) 2008 Robin Burchell <robin+git@viroteck.net>
# Copyright (C) 2007-2008 Craig Edwards <craigedwards@brainbox.cc>
# Copyright (C) 2008 Thomas Stagner <aquanight@inspircd.org>
@@ -42,6 +42,7 @@ use make::console;
use constant CONFIGURE_DIRECTORY => '.configure';
use constant CONFIGURE_CACHE_FILE => catfile(CONFIGURE_DIRECTORY, 'cache.cfg');
use constant CONFIGURE_CACHE_VERSION => '1';
+use constant CONFIGURE_ERROR_PIPE => $ENV{INSPIRCD_VERBOSE} ? '' : '1>/dev/null 2>/dev/null';
our @EXPORT = qw(CONFIGURE_CACHE_FILE
CONFIGURE_CACHE_VERSION
@@ -51,7 +52,6 @@ our @EXPORT = qw(CONFIGURE_CACHE_FILE
run_test
test_file
test_header
- read_configure_cache
write_configure_cache
get_compiler_info
find_compiler
@@ -97,7 +97,7 @@ sub __get_template_settings($$$) {
sub __test_compiler($) {
my $compiler = shift;
- return 0 unless run_test("`$compiler`", !system "$compiler -v >/dev/null 2>&1");
+ return 0 unless run_test("`$compiler`", !system "$compiler -v ${\CONFIGURE_ERROR_PIPE}");
return 0 unless run_test("`$compiler`", test_file($compiler, 'compiler.cpp', '-fno-rtti'), 'compatible');
return 1;
}
@@ -179,7 +179,7 @@ EOH
sub cmd_update {
print_error "You have not run $0 before. Please do this before trying to update the generated files." unless -f CONFIGURE_CACHE_FILE;
say 'Updating...';
- my %config = read_configure_cache();
+ my %config = read_config_file(CONFIGURE_CACHE_FILE);
my %compiler = get_compiler_info($config{CXX});
my %version = get_version $config{DISTRIBUTION};
parse_templates(\%config, \%compiler, \%version);
@@ -199,8 +199,8 @@ sub test_file($$;$) {
my ($compiler, $file, $args) = @_;
my $status = 0;
$args //= '';
- $status ||= system "$compiler -o __test_$file make/test/$file $args >/dev/null 2>&1";
- $status ||= system "./__test_$file >/dev/null 2>&1";
+ $status ||= system "$compiler -o __test_$file make/test/$file $args ${\CONFIGURE_ERROR_PIPE}";
+ $status ||= system "./__test_$file ${\CONFIGURE_ERROR_PIPE}";
unlink "./__test_$file";
return !$status;
}
@@ -208,24 +208,12 @@ sub test_file($$;$) {
sub test_header($$;$) {
my ($compiler, $header, $args) = @_;
$args //= '';
- open(COMPILER, "| $compiler -E - $args >/dev/null 2>&1") or return 0;
- print COMPILER "#include <$header>";
- close(COMPILER);
+ open(my $fh, "| $compiler -E - $args ${\CONFIGURE_ERROR_PIPE}") or return 0;
+ print $fh "#include <$header>";
+ close $fh;
return !$?;
}
-sub read_configure_cache {
- my %config;
- open(CACHE, CONFIGURE_CACHE_FILE) or return %config;
- while (my $line = <CACHE>) {
- next if $line =~ /^\s*($|\#)/;
- my ($key, $value) = ($line =~ /^(\S+)(?:\s(.*))?$/);
- $config{$key} = $value;
- }
- close(CACHE);
- return %config;
-}
-
sub write_configure_cache(%) {
unless (-e CONFIGURE_DIRECTORY) {
print_format "Creating <|GREEN ${\CONFIGURE_DIRECTORY}|> ...\n";
@@ -234,29 +222,20 @@ sub write_configure_cache(%) {
print_format "Writing <|GREEN ${\CONFIGURE_CACHE_FILE}|> ...\n";
my %config = @_;
- open(CACHE, '>', CONFIGURE_CACHE_FILE) or print_error "unable to write ${\CONFIGURE_CACHE_FILE}: $!";
- while (my ($key, $value) = each %config) {
- $value //= '';
- say CACHE "$key $value";
- }
- close(CACHE);
+ write_config_file CONFIGURE_CACHE_FILE, %config;
}
sub get_compiler_info($) {
my $binary = shift;
- my $version = `$binary -v 2>&1`;
- if ($version =~ /Apple\sLLVM\sversion\s(\d+\.\d+)/i) {
- # Apple version their LLVM releases slightly differently to the mainline LLVM.
- # See https://trac.macports.org/wiki/XcodeVersionInfo for more information.
- return (NAME => 'AppleClang', VERSION => $1);
- } elsif ($version =~ /clang\sversion\s(\d+\.\d+)/i) {
- return (NAME => 'Clang', VERSION => $1);
- } elsif ($version =~ /gcc\sversion\s(\d+\.\d+)/i) {
- return (NAME => 'GCC', VERSION => $1);
- } elsif ($version =~ /(?:icc|icpc)\sversion\s(\d+\.\d+).\d+\s\(gcc\sversion\s(\d+\.\d+).\d+/i) {
- return (NAME => 'ICC', VERSION => $1);
+ my %info = (NAME => 'Unknown', VERSION => '0.0');
+ return %info if system "$binary -o __compiler_info make/test/compiler_info.cpp ${\CONFIGURE_ERROR_PIPE}";
+ open(my $fh, '-|', './__compiler_info 2>/dev/null');
+ while (my $line = <$fh>) {
+ $info{$1} = $2 if $line =~ /^([A-Z]+)\s(.+)$/;
}
- return (NAME => $binary, VERSION => '0.0');
+ close $fh;
+ unlink './__compiler_info';
+ return %info;
}
sub find_compiler {
@@ -278,11 +257,11 @@ sub parse_templates($$$) {
# Iterate through files in make/template.
foreach (<make/template/*>) {
print_format "Parsing <|GREEN $_|> ...\n";
- open(TEMPLATE, $_) or print_error "unable to read $_: $!";
+ open(my $fh, $_) or print_error "unable to read $_: $!";
my (@lines, $mode, @platforms, %targets);
# First pass: parse template variables and directives.
- while (my $line = <TEMPLATE>) {
+ while (my $line = <$fh>) {
chomp $line;
# Does this line match a variable?
@@ -322,7 +301,7 @@ sub parse_templates($$$) {
}
push @lines, $line;
}
- close(TEMPLATE);
+ close $fh;
# Only proceed if this file should be templated on this platform.
if ($#platforms < 0 || grep { $_ eq $^O } @platforms) {
@@ -418,11 +397,11 @@ sub parse_templates($$$) {
# Write the template file.
print_format "Writing <|GREEN $target|> ...\n";
- open(TARGET, '>', $target) or print_error "unable to write $target: $!";
+ open(my $fh, '>', $target) or print_error "unable to write $target: $!";
foreach (@final_lines) {
- say TARGET $_;
+ say $fh $_;
}
- close(TARGET);
+ close $fh;
# Set file permissions.
if (defined $mode) {
diff --git a/make/console.pm b/make/console.pm
index 84fbaae4a..0d3c1b38d 100644
--- a/make/console.pm
+++ b/make/console.pm
@@ -1,7 +1,7 @@
#
# InspIRCd -- Internet Relay Chat Daemon
#
-# Copyright (C) 2014 Peter Powell <petpow@saberuk.com>
+# Copyright (C) 2014-2017 Peter Powell <petpow@saberuk.com>
#
# This file is part of InspIRCd. InspIRCd is free software: you can
# redistribute it and/or modify it under the terms of the GNU General Public
@@ -27,11 +27,14 @@ use feature ':5.10';
use strict;
use warnings FATAL => qw(all);
+use Class::Struct qw(struct);
+use Exporter qw(import);
use File::Path qw(mkpath);
use File::Spec::Functions qw(rel2abs);
-use Exporter qw(import);
-our @EXPORT = qw(print_format
+our @EXPORT = qw(command
+ execute_command
+ print_format
print_error
print_warning
prompt_bool
@@ -39,8 +42,9 @@ our @EXPORT = qw(print_format
prompt_string);
my %FORMAT_CODES = (
- DEFAULT => "\e[0m",
- BOLD => "\e[1m",
+ DEFAULT => "\e[0m",
+ BOLD => "\e[1m",
+ UNDERLINE => "\e[4m",
RED => "\e[1;31m",
GREEN => "\e[1;32m",
@@ -48,6 +52,13 @@ my %FORMAT_CODES = (
BLUE => "\e[1;34m"
);
+my %commands;
+
+struct 'command' => {
+ 'callback' => '$',
+ 'description' => '$',
+};
+
sub __console_format($$) {
my ($name, $data) = @_;
return $data unless -t STDOUT;
@@ -111,4 +122,38 @@ sub prompt_string($$$) {
return $answer ? $answer : $default;
}
+sub command($$$) {
+ my ($name, $description, $callback) = @_;
+ $commands{$name} = command->new;
+ $commands{$name}->callback($callback);
+ $commands{$name}->description($description);
+}
+
+sub command_alias($$) {
+ my ($source, $target) = @_;
+ command $source, undef, sub(@) {
+ execute_command $target, @_;
+ };
+}
+
+sub execute_command(@) {
+ my $command = defined $_[0] ? lc shift : 'help';
+ if ($command eq 'help') {
+ print_format "<|GREEN Usage:|> $0 <<|UNDERLINE COMMAND|>> [<|UNDERLINE OPTIONS...|>]\n\n";
+ print_format "<|GREEN Commands:|>\n";
+ for my $key (sort keys %commands) {
+ next unless defined $commands{$key}->description;
+ my $name = sprintf "%-15s", $key;
+ my $description = $commands{$key}->description;
+ print_format " <|BOLD $name|> # $description\n";
+ }
+ exit 0;
+ } elsif (!$commands{$command}) {
+ print_error "no command called <|BOLD $command|> exists!",
+ "See <|BOLD $0 help|> for a list of commands.";
+ } else {
+ return $commands{$command}->callback->(@_);
+ }
+}
+
1;
diff --git a/make/directive.pm b/make/directive.pm
index 4501fc5ec..2e9e7ed61 100644
--- a/make/directive.pm
+++ b/make/directive.pm
@@ -41,16 +41,16 @@ our @EXPORT = qw(get_directive
sub get_directive($$;$)
{
my ($file, $property, $default) = @_;
- open(MODULE, $file) or return $default;
+ open(my $fh, $file) or return $default;
my $value = '';
- while (<MODULE>) {
+ while (<$fh>) {
if ($_ =~ /^\/\* \$(\S+): (.+) \*\/$/ || $_ =~ /^\/\/\/ \$(\S+): (.+)/) {
next unless $1 eq $property;
$value .= ' ' . execute_functions($file, $1, $2);
}
}
- close(MODULE);
+ close $fh;
# Strip all extraneous whitespace.
$value =~ s/^\s+|\s+$//g;
diff --git a/make/test/clock_gettime.cpp b/make/test/clock_gettime.cpp
index 91d8cd412..d111d591f 100644
--- a/make/test/clock_gettime.cpp
+++ b/make/test/clock_gettime.cpp
@@ -1,6 +1,7 @@
/*
* InspIRCd -- Internet Relay Chat Daemon
*
+ * Copyright (C) 2013 Peter Powell <petpow@saberuk.com>
*
* This file is part of InspIRCd. InspIRCd is free software: you can
* redistribute it and/or modify it under the terms of the GNU General Public
diff --git a/make/test/compiler.cpp b/make/test/compiler.cpp
index e2cbd9f64..f01423325 100644
--- a/make/test/compiler.cpp
+++ b/make/test/compiler.cpp
@@ -1,6 +1,8 @@
/*
* InspIRCd -- Internet Relay Chat Daemon
*
+ * Copyright (C) 2016 Attila Molnar <attilamolnar@hush.com>
+ * Copyright (C) 2014-2015 Peter Powell <petpow@saberuk.com>
*
* This file is part of InspIRCd. InspIRCd is free software: you can
* redistribute it and/or modify it under the terms of the GNU General Public
diff --git a/make/test/compiler_info.cpp b/make/test/compiler_info.cpp
new file mode 100644
index 000000000..10b156fc8
--- /dev/null
+++ b/make/test/compiler_info.cpp
@@ -0,0 +1,41 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ * Copyright (C) 2017 Peter Powell <petpow@saberuk.com>
+ *
+ * This file is part of InspIRCd. InspIRCd is free software: you can
+ * redistribute it and/or modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include <iostream>
+
+#if defined __INTEL_COMPILER // Also defines __clang__ and __GNUC__
+# define INSPIRCD_COMPILER_NAME "Intel"
+# define INSPIRCD_COMPILER_VERSION (__INTEL_COMPILER / 100) << '.' << (__INTEL_COMPILER % 100)
+#elif defined __clang__ // Also defines __GNUC__
+# if defined __apple_build_version__
+# define INSPIRCD_COMPILER_NAME "AppleClang"
+# else
+# define INSPIRCD_COMPILER_NAME "Clang"
+# endif
+# define INSPIRCD_COMPILER_VERSION __clang_major__ << '.' << __clang_minor__
+#elif defined __GNUC__
+# define INSPIRCD_COMPILER_NAME "GCC"
+# define INSPIRCD_COMPILER_VERSION __GNUC__ << '.' << __GNUC_MINOR__
+#endif
+
+int main() {
+ std::cout << "NAME " << INSPIRCD_COMPILER_NAME << std::endl
+ << "VERSION " << INSPIRCD_COMPILER_VERSION << std::endl;
+ return 0;
+}
diff --git a/modulemanager b/modulemanager
index e859f683b..7471dcc77 100755
--- a/modulemanager
+++ b/modulemanager
@@ -3,6 +3,7 @@
#
# InspIRCd -- Internet Relay Chat Daemon
#
+# Copyright (C) 2012-2017 Peter Powell <petpow@saberuk.com>
# Copyright (C) 2008-2009 Robin Burchell <robin+git@viroteck.net>
#
# This file is part of InspIRCd. InspIRCd is free software: you can
@@ -19,23 +20,26 @@
#
-use strict;
-use warnings FATAL => qw(all);
-
-use make::common;
-
BEGIN {
- unless (module_installed("LWP::Simple")) {
+ require 5.10.0;
+ unless (eval "use LWP::Simple; 1") {
die "Your system is missing the LWP::Simple Perl module!";
}
- unless (module_installed("Crypt::SSLeay") || module_installed("IO::Socket::SSL")) {
+ unless (eval "use Crypt::SSLeay; 1" || eval "use IO::Socket::SSL; 1") {
die "Your system is missing the Crypt::SSLeay or IO::Socket::SSL Perl modules!";
}
-
}
-use File::Basename;
-use LWP::Simple;
+use feature ':5.10';
+use strict;
+use warnings FATAL => qw(all);
+
+use File::Basename qw(basename);
+use FindBin qw($RealDir);
+
+use lib $RealDir;
+use make::common;
+use make::console;
my %installed;
# $installed{name} = $version
@@ -102,7 +106,7 @@ sub parse_url {
}
# hash of installed module versions from our mini-database, key (m_foobar) to version (00abacca..).
-my %mod_versions;
+my %mod_versions = read_config_file '.modulemanager';
# useless helper stub
sub getmodversion {
@@ -110,19 +114,6 @@ sub getmodversion {
return $mod_versions{$file};
}
-# read in installed versions
-if (-e '.modulemanager')
-{
- open SRC, '.modulemanager' or die ".modulemanager exists but i can't read it: $!";
- while (<SRC>)
- {
- s/\n//;
- (my $mod, my $ver) = split(/ /, $_);
- $mod_versions{$mod} = $ver;
- }
- close SRC;
-}
-
# read in external URL sources
open SRC, 'sources.list' or die "Could not open sources.list: $!";
while (<SRC>) {
@@ -262,10 +253,8 @@ sub resolve_deps {
}
}
-my $action = $#ARGV >= 0 ? lc shift @ARGV : 'help';
-
-if ($action eq 'install') {
- for my $mod (@ARGV) {
+command 'install', 'Install a third-party module', sub {
+ for my $mod (@_) {
my $vers = $mod =~ s/=([-0-9.]+)// ? $1 : undef;
$mod = lc $mod;
unless ($modules{$mod}) {
@@ -279,7 +268,9 @@ if ($action eq 'install') {
}
$todo{$mod} = $ver;
}
-} elsif ($action eq 'upgrade') {
+};
+
+command 'upgrade', 'Upgrade a third-party module', sub {
my @installed = sort keys %installed;
for my $mod (@installed) {
next unless $mod =~ /^m_/;
@@ -289,7 +280,9 @@ if ($action eq 'install') {
%todo = %saved;
}
}
-} elsif ($action eq 'list') {
+};
+
+command 'list', 'List available third-party modules', sub {
my @all = sort keys %modules;
for my $mod (@all) {
my @vers = sort { ver_cmp() } keys %{$modules{$mod}};
@@ -303,25 +296,16 @@ if ($action eq 'install') {
my $vers = join ' ', map { $_ eq $instver ? "\e[1m$_\e[m" : $_ } @vers;
print "$mod ($vers) - $desc\n";
}
-} else {
- print <<ENDUSAGE
-Use: $0 <action> <args>
-Action is one of the following
- install install new modules
- upgrade upgrade installed modules
- list lists available modules
-
-For installing a package, specify its name or name=version to force the
-installation of a specific version.
-ENDUSAGE
-;exit 1;
-}
+ exit 0;
+};
+
+execute_command @ARGV;
resolve_deps(0);
$| = 1; # immediate print of lines without \n
-print "Processing changes for $action...\n";
+print "Processing changes...\n";
for my $mod (keys %installed) {
next if $todo{$mod};
print "Uninstalling $mod $installed{$mod}\n";
@@ -359,11 +343,6 @@ for my $mod (sort keys %todo) {
}
# write database of installed versions
-open SRC, '>.modulemanager' or die "can't write installed versions to .modulemanager, won't be able to track upgrades properly: $!";
-foreach my $key (keys %mod_versions)
-{
- print SRC "$key $mod_versions{$key}\n";
-}
-close SRC;
+write_config_file '.modulemanager', %mod_versions;
print "Finished!\n";
diff --git a/src/coremods/core_dns.cpp b/src/coremods/core_dns.cpp
index 753b41f43..1040bb036 100644
--- a/src/coremods/core_dns.cpp
+++ b/src/coremods/core_dns.cpp
@@ -154,7 +154,7 @@ class Packet : public Query
record.ttl = (input[pos] << 24) | (input[pos + 1] << 16) | (input[pos + 2] << 8) | input[pos + 3];
pos += 4;
- //record.rdlength = input[pos] << 8 | input[pos + 1];
+ uint16_t rdlength = input[pos] << 8 | input[pos + 1];
pos += 2;
switch (record.type)
@@ -200,6 +200,19 @@ class Packet : public Query
break;
}
+ case QUERY_TXT:
+ {
+ if (pos + rdlength > input_size)
+ throw Exception("Unable to unpack txt resource record");
+
+ record.rdata = std::string(reinterpret_cast<const char *>(input + pos), rdlength);
+ pos += rdlength;
+
+ if (record.rdata.find_first_of("\r\n\0", 0, 3) != std::string::npos)
+ throw Exception("Invalid character in txt record");
+
+ break;
+ }
default:
break;
}
@@ -429,7 +442,7 @@ class MyManager : public Manager, public Timer, public EventHandler
}
}
- void Process(DNS::Request* req)
+ void Process(DNS::Request* req) CXX11_OVERRIDE
{
if ((unloading) || (req->creator->dying))
throw Exception("Module is being unloaded");
@@ -496,13 +509,13 @@ class MyManager : public Manager, public Timer, public EventHandler
ServerInstance->Timers.AddTimer(req);
}
- void RemoveRequest(DNS::Request* req)
+ void RemoveRequest(DNS::Request* req) CXX11_OVERRIDE
{
if (requests[req->id] == req)
requests[req->id] = NULL;
}
- std::string GetErrorStr(Error e)
+ std::string GetErrorStr(Error e) CXX11_OVERRIDE
{
switch (e)
{
@@ -651,7 +664,7 @@ class MyManager : public Manager, public Timer, public EventHandler
delete request;
}
- bool Tick(time_t now)
+ bool Tick(time_t now) CXX11_OVERRIDE
{
ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "cache: purging DNS cache");
@@ -813,7 +826,7 @@ class ModuleDNS : public Module
this->manager.Rehash(DNSServer, SourceIP, SourcePort);
}
- void OnUnloadModule(Module* mod)
+ void OnUnloadModule(Module* mod) CXX11_OVERRIDE
{
for (unsigned int i = 0; i <= MAX_REQUEST_ID; ++i)
{
@@ -832,7 +845,7 @@ class ModuleDNS : public Module
}
}
- Version GetVersion()
+ Version GetVersion() CXX11_OVERRIDE
{
return Version("DNS support", VF_CORE|VF_VENDOR);
}
diff --git a/src/coremods/core_hostname_lookup.cpp b/src/coremods/core_hostname_lookup.cpp
index b9adc9c2e..d150b8551 100644
--- a/src/coremods/core_hostname_lookup.cpp
+++ b/src/coremods/core_hostname_lookup.cpp
@@ -195,7 +195,7 @@ class ModuleHostnameLookup : public Module
ph = &ptrHosts;
}
- void OnUserInit(LocalUser *user)
+ void OnUserInit(LocalUser *user) CXX11_OVERRIDE
{
if (!DNS || !user->MyClass->resolvehostnames)
{
@@ -222,12 +222,12 @@ class ModuleHostnameLookup : public Module
}
}
- ModResult OnCheckReady(LocalUser* user)
+ ModResult OnCheckReady(LocalUser* user) CXX11_OVERRIDE
{
return this->dnsLookup.get(user) ? MOD_RES_DENY : MOD_RES_PASSTHRU;
}
- Version GetVersion()
+ Version GetVersion() CXX11_OVERRIDE
{
return Version("Provides support for DNS lookups on connecting clients", VF_CORE|VF_VENDOR);
}
diff --git a/src/coremods/core_loadmodule.cpp b/src/coremods/core_loadmodule.cpp
index 09c044198..fde149587 100644
--- a/src/coremods/core_loadmodule.cpp
+++ b/src/coremods/core_loadmodule.cpp
@@ -116,7 +116,7 @@ class CoreModLoadModule : public Module
{
}
- Version GetVersion()
+ Version GetVersion() CXX11_OVERRIDE
{
return Version("Provides the LOADMODULE and UNLOADMODULE commands", VF_VENDOR|VF_CORE);
}
diff --git a/src/coremods/core_lusers.cpp b/src/coremods/core_lusers.cpp
index a0d0d0205..7f1903dd0 100644
--- a/src/coremods/core_lusers.cpp
+++ b/src/coremods/core_lusers.cpp
@@ -151,20 +151,20 @@ class ModuleLusers : public Module
{
}
- void OnPostConnect(User* user)
+ void OnPostConnect(User* user) CXX11_OVERRIDE
{
counters.UpdateMaxUsers();
if (user->IsModeSet(invisiblemode))
counters.invisible++;
}
- void OnUserQuit(User* user, const std::string& message, const std::string& oper_message)
+ void OnUserQuit(User* user, const std::string& message, const std::string& oper_message) CXX11_OVERRIDE
{
if (user->IsModeSet(invisiblemode))
counters.invisible--;
}
- Version GetVersion()
+ Version GetVersion() CXX11_OVERRIDE
{
return Version("LUSERS", VF_VENDOR | VF_CORE);
}
diff --git a/src/coremods/core_privmsg.cpp b/src/coremods/core_privmsg.cpp
index cccba0850..449097a75 100644
--- a/src/coremods/core_privmsg.cpp
+++ b/src/coremods/core_privmsg.cpp
@@ -280,7 +280,7 @@ class ModuleCoreMessage : public Module
{
}
- Version GetVersion()
+ Version GetVersion() CXX11_OVERRIDE
{
return Version("PRIVMSG, NOTICE", VF_CORE|VF_VENDOR);
}
diff --git a/src/coremods/core_stub.cpp b/src/coremods/core_stub.cpp
index 91fc16241..71b0ddaea 100644
--- a/src/coremods/core_stub.cpp
+++ b/src/coremods/core_stub.cpp
@@ -147,7 +147,7 @@ class CoreModStub : public Module
{
}
- Version GetVersion()
+ Version GetVersion() CXX11_OVERRIDE
{
return Version("Provides the stub commands CONNECT, LINKS, SERVER and SQUIT", VF_VENDOR|VF_CORE);
}
diff --git a/src/coremods/core_user/cmd_mode.cpp b/src/coremods/core_user/cmd_mode.cpp
index b1790bb89..2b2652606 100644
--- a/src/coremods/core_user/cmd_mode.cpp
+++ b/src/coremods/core_user/cmd_mode.cpp
@@ -130,6 +130,17 @@ void CommandMode::DisplayListModes(User* user, Channel* chan, const std::string&
}
}
+static std::string GetSnomasks(const User* user)
+{
+ ModeHandler* const snomask = ServerInstance->Modes.FindMode('s', MODETYPE_USER);
+ std::string snomaskstr = snomask->GetUserParameter(user);
+ // snomaskstr is empty if the snomask mode isn't set, otherwise it begins with a '+'.
+ // In the former case output a "+", not an empty string.
+ if (snomaskstr.empty())
+ snomaskstr.push_back('+');
+ return snomaskstr;
+}
+
void CommandMode::DisplayCurrentModes(User* user, User* targetuser, Channel* targetchannel)
{
if (targetchannel)
@@ -140,20 +151,20 @@ void CommandMode::DisplayCurrentModes(User* user, User* targetuser, Channel* tar
}
else
{
- if (targetuser == user || user->HasPrivPermission("users/auspex"))
+ if (targetuser == user)
{
// Display user's current mode string
- // XXX: Use WriteServ() because WriteNumeric() assumes the target (i.e. next word after the number)
- // is 'user' and puts his nick there which is not what we want
- user->WriteServ("%03d %s :+%s", RPL_UMODEIS, targetuser->nick.c_str(), targetuser->FormatModes());
+ user->WriteNumeric(RPL_UMODEIS, targetuser->GetModeLetters());
if (targetuser->IsOper())
- {
- ModeHandler* snomask = ServerInstance->Modes->FindMode('s', MODETYPE_USER);
- std::string snomaskstr = snomask->GetUserParameter(user);
- // snomaskstr is empty if the snomask mode isn't set, otherwise it begins with a '+'.
- // In the former case output a "+", not an empty string.
- user->WriteServ("%03d %s %s%s :Server notice mask", RPL_SNOMASKIS, targetuser->nick.c_str(), (snomaskstr.empty() ? "+" : ""), snomaskstr.c_str());
- }
+ user->WriteNumeric(RPL_SNOMASKIS, GetSnomasks(targetuser), "Server notice mask");
+ }
+ else if (user->HasPrivPermission("users/auspex"))
+ {
+ // Querying the modes of another user.
+ // We cannot use RPL_UMODEIS because that's only for showing the user's own modes.
+ user->WriteNumeric(RPL_OTHERUMODEIS, targetuser->nick, targetuser->GetModeLetters());
+ if (targetuser->IsOper())
+ user->WriteNumeric(RPL_OTHERSNOMASKIS, targetuser->nick, GetSnomasks(targetuser), "Server notice mask");
}
else
{
diff --git a/src/coremods/core_who.cpp b/src/coremods/core_who.cpp
index 739c675a9..677a1eb6d 100644
--- a/src/coremods/core_who.cpp
+++ b/src/coremods/core_who.cpp
@@ -38,14 +38,18 @@ class CommandWho : public Command
bool opt_time;
ChanModeReference secretmode;
ChanModeReference privatemode;
+ UserModeReference hidechansmode;
UserModeReference invisiblemode;
- Membership* get_first_visible_channel(User* u)
+ Membership* get_first_visible_channel(User* source, User* u)
{
for (User::ChanList::iterator i = u->chans.begin(); i != u->chans.end(); ++i)
{
Membership* memb = *i;
- if (!memb->chan->IsModeSet(secretmode))
+
+ /* XXX move the +I check into m_hidechans */
+ bool has_modes = memb->chan->IsModeSet(secretmode) || memb->chan->IsModeSet(privatemode) || u->IsModeSet(hidechansmode);
+ if (source == u || !has_modes || memb->chan->HasUser(source))
return memb;
}
return NULL;
@@ -58,6 +62,7 @@ class CommandWho : public Command
: Command(parent, "WHO", 1)
, secretmode(parent, "secret")
, privatemode(parent, "private")
+ , hidechansmode(parent, "hidechans")
, invisiblemode(parent, "invisible")
{
syntax = "<server>|<nickname>|<channel>|<realname>|<host>|0 [ohurmMiaplf]";
@@ -189,7 +194,7 @@ bool CommandWho::CanView(Channel* chan, User* user)
void CommandWho::SendWhoLine(User* user, const std::vector<std::string>& parms, Membership* memb, User* u, std::vector<Numeric::Numeric>& whoresults)
{
if (!memb)
- memb = get_first_visible_channel(u);
+ memb = get_first_visible_channel(user, u);
Numeric::Numeric wholine(RPL_WHOREPLY);
wholine.push(memb ? memb->chan->name : "*").push(u->ident);
diff --git a/src/coremods/core_whois.cpp b/src/coremods/core_whois.cpp
index ed5c1cda0..81e62c8e5 100644
--- a/src/coremods/core_whois.cpp
+++ b/src/coremods/core_whois.cpp
@@ -211,11 +211,11 @@ void CommandWhois::DoWhois(LocalUser* user, User* dest, unsigned long signon, un
{
if (dest->IsModeSet(snomaskmode))
{
- whois.SendLine(379, InspIRCd::Format("is using modes +%s %s", dest->FormatModes(), snomaskmode->GetUserParameter(dest).c_str()));
+ whois.SendLine(379, InspIRCd::Format("is using modes %s %s", dest->GetModeLetters().c_str(), snomaskmode->GetUserParameter(dest).c_str()));
}
else
{
- whois.SendLine(379, InspIRCd::Format("is using modes +%s", dest->FormatModes()));
+ whois.SendLine(379, InspIRCd::Format("is using modes %s", dest->GetModeLetters().c_str()));
}
}
diff --git a/src/coremods/core_whowas.cpp b/src/coremods/core_whowas.cpp
index f52fb0174..0bb47b273 100644
--- a/src/coremods/core_whowas.cpp
+++ b/src/coremods/core_whowas.cpp
@@ -259,13 +259,13 @@ class ModuleWhoWas : public Module
{
}
- void OnGarbageCollect()
+ void OnGarbageCollect() CXX11_OVERRIDE
{
// Remove all entries older than MaxKeep
cmd.manager.Maintain();
}
- void OnUserQuit(User* user, const std::string& message, const std::string& oper_message)
+ void OnUserQuit(User* user, const std::string& message, const std::string& oper_message) CXX11_OVERRIDE
{
cmd.manager.Add(user);
}
@@ -288,7 +288,7 @@ class ModuleWhoWas : public Module
cmd.manager.UpdateConfig(NewGroupSize, NewMaxGroups, NewMaxKeep);
}
- Version GetVersion()
+ Version GetVersion() CXX11_OVERRIDE
{
return Version("WHOWAS", VF_VENDOR);
}
diff --git a/src/coremods/core_xline/cmd_gline.cpp b/src/coremods/core_xline/cmd_gline.cpp
index 3f042c366..49932ba9d 100644
--- a/src/coremods/core_xline/cmd_gline.cpp
+++ b/src/coremods/core_xline/cmd_gline.cpp
@@ -26,7 +26,6 @@ CommandGline::CommandGline(Module* parent)
: Command(parent, "GLINE", 1, 3)
{
flags_needed = 'o';
- Penalty = 0;
syntax = "<ident@host> [<duration> :<reason>]";
}
diff --git a/src/coremods/core_xline/cmd_kline.cpp b/src/coremods/core_xline/cmd_kline.cpp
index ee85fdd1d..db8862d37 100644
--- a/src/coremods/core_xline/cmd_kline.cpp
+++ b/src/coremods/core_xline/cmd_kline.cpp
@@ -26,7 +26,6 @@ CommandKline::CommandKline(Module* parent)
: Command(parent, "KLINE", 1, 3)
{
flags_needed = 'o';
- Penalty = 0;
syntax = "<ident@host> [<duration> :<reason>]";
}
diff --git a/src/coremods/core_xline/cmd_qline.cpp b/src/coremods/core_xline/cmd_qline.cpp
index 955efeaf0..6dc0da9ba 100644
--- a/src/coremods/core_xline/cmd_qline.cpp
+++ b/src/coremods/core_xline/cmd_qline.cpp
@@ -27,7 +27,6 @@ CommandQline::CommandQline(Module* parent)
: Command(parent, "QLINE", 1, 3)
{
flags_needed = 'o';
- Penalty = 0;
syntax = "<nick> [<duration> :<reason>]";
}
diff --git a/src/coremods/core_xline/cmd_zline.cpp b/src/coremods/core_xline/cmd_zline.cpp
index 859be1004..1bc7e8afd 100644
--- a/src/coremods/core_xline/cmd_zline.cpp
+++ b/src/coremods/core_xline/cmd_zline.cpp
@@ -27,7 +27,6 @@ CommandZline::CommandZline(Module* parent)
: Command(parent, "ZLINE", 1, 3)
{
flags_needed = 'o';
- Penalty = 0;
syntax = "<ipmask> [<duration> :<reason>]";
}
diff --git a/src/coremods/core_xline/core_xline.h b/src/coremods/core_xline/core_xline.h
index d4ad498a0..5b34e7a4d 100644
--- a/src/coremods/core_xline/core_xline.h
+++ b/src/coremods/core_xline/core_xline.h
@@ -133,7 +133,6 @@ class CommandQline : public Command
/** Handle command.
* @param parameters The parameters to the command
- * @param pcnt The number of parameters passed to the command
* @param user The user issuing the command
* @return A value from CmdResult to indicate command success or failure.
*/
diff --git a/src/inspircd.cpp b/src/inspircd.cpp
index 5fe2ef076..0c9b67910 100644
--- a/src/inspircd.cpp
+++ b/src/inspircd.cpp
@@ -343,7 +343,7 @@ InspIRCd::InspIRCd(int argc, char** argv) :
if (do_debug)
{
- FileWriter* fw = new FileWriter(stdout);
+ FileWriter* fw = new FileWriter(stdout, 1);
FileLogStream* fls = new FileLogStream(LOG_RAWIO, fw);
Logs->AddLogTypes("*", fls, true);
}
diff --git a/src/logger.cpp b/src/logger.cpp
index 5b4a948ee..e3e956325 100644
--- a/src/logger.cpp
+++ b/src/logger.cpp
@@ -120,7 +120,7 @@ void LogManager::OpenFileLogs()
struct tm *mytime = gmtime(&time);
strftime(realtarget, sizeof(realtarget), target.c_str(), mytime);
FILE* f = fopen(realtarget, "a");
- fw = new FileWriter(f);
+ fw = new FileWriter(f, static_cast<unsigned int>(tag->getInt("flush", 20, 1, INT_MAX)));
logmap.insert(std::make_pair(target, fw));
}
else
@@ -309,8 +309,10 @@ void LogManager::Log(const std::string &type, LogLevel loglevel, const std::stri
}
-FileWriter::FileWriter(FILE* logfile)
-: log(logfile), writeops(0)
+FileWriter::FileWriter(FILE* logfile, unsigned int flushcount)
+ : log(logfile)
+ , flush(flushcount)
+ , writeops(0)
{
}
@@ -322,7 +324,7 @@ void FileWriter::WriteLogLine(const std::string &line)
// throw CoreException("FileWriter::WriteLogLine called with a closed logfile");
fputs(line.c_str(), log);
- if (++writeops % 20 == 0)
+ if (++writeops % flush == 0)
{
fflush(log);
}
diff --git a/src/mode.cpp b/src/mode.cpp
index fec614ab4..22173c189 100644
--- a/src/mode.cpp
+++ b/src/mode.cpp
@@ -58,7 +58,7 @@ bool ModeHandler::NeedsParam(bool adding) const
return false;
}
-std::string ModeHandler::GetUserParameter(User* user)
+std::string ModeHandler::GetUserParameter(const User* user) const
{
return "";
}
diff --git a/src/modes/umode_s.cpp b/src/modes/umode_s.cpp
index f0fa5e94b..ffad21662 100644
--- a/src/modes/umode_s.cpp
+++ b/src/modes/umode_s.cpp
@@ -50,7 +50,7 @@ ModeAction ModeUserServerNoticeMask::OnModeChange(User* source, User* dest, Chan
return MODEACTION_DENY;
}
-std::string ModeUserServerNoticeMask::GetUserParameter(User* user)
+std::string ModeUserServerNoticeMask::GetUserParameter(const User* user) const
{
std::string ret;
if (!user->IsModeSet(this))
diff --git a/src/modmanager_static.cpp b/src/modmanager_static.cpp
index 5c04a7680..9a385dd3c 100644
--- a/src/modmanager_static.cpp
+++ b/src/modmanager_static.cpp
@@ -72,7 +72,7 @@ class AllModule : public Module
stdalgo::delete_all(cmds);
}
- Version GetVersion()
+ Version GetVersion() CXX11_OVERRIDE
{
return Version("All commands", VF_VENDOR|VF_CORE);
}
diff --git a/src/modules/extra/m_pgsql.cpp b/src/modules/extra/m_pgsql.cpp
index 5f6f6e30f..6835cb558 100644
--- a/src/modules/extra/m_pgsql.cpp
+++ b/src/modules/extra/m_pgsql.cpp
@@ -159,7 +159,7 @@ class SQLConn : public SQLProvider, public EventHandler
}
}
- CullResult cull()
+ CullResult cull() CXX11_OVERRIDE
{
this->SQLProvider::cull();
ServerInstance->Modules->DelService(*this);
@@ -389,7 +389,7 @@ restart:
}
}
- void submit(SQLQuery *req, const std::string& q)
+ void submit(SQLQuery *req, const std::string& q) CXX11_OVERRIDE
{
if (qinprog.q.empty())
{
@@ -402,7 +402,7 @@ restart:
}
}
- void submit(SQLQuery *req, const std::string& q, const ParamL& p)
+ void submit(SQLQuery *req, const std::string& q, const ParamL& p) CXX11_OVERRIDE
{
std::string res;
unsigned int param = 0;
@@ -427,7 +427,7 @@ restart:
submit(req, res);
}
- void submit(SQLQuery *req, const std::string& q, const ParamM& p)
+ void submit(SQLQuery *req, const std::string& q, const ParamM& p) CXX11_OVERRIDE
{
std::string res;
for(std::string::size_type i = 0; i < q.length(); i++)
diff --git a/src/modules/m_abbreviation.cpp b/src/modules/m_abbreviation.cpp
index 85709080f..2a38bd3a6 100644
--- a/src/modules/m_abbreviation.cpp
+++ b/src/modules/m_abbreviation.cpp
@@ -22,7 +22,7 @@
class ModuleAbbreviation : public Module
{
public:
- void Prioritize()
+ void Prioritize() CXX11_OVERRIDE
{
ServerInstance->Modules->SetPriority(this, I_OnPreCommand, PRIORITY_FIRST);
}
diff --git a/src/modules/m_alias.cpp b/src/modules/m_alias.cpp
index c6e53f0cf..e99d9dab5 100644
--- a/src/modules/m_alias.cpp
+++ b/src/modules/m_alias.cpp
@@ -352,7 +352,7 @@ class ModuleAlias : public Module
ServerInstance->Parser.CallHandler(command, pars, user);
}
- void Prioritize()
+ void Prioritize() CXX11_OVERRIDE
{
// Prioritise after spanningtree so that channel aliases show the alias before the effects.
Module* linkmod = ServerInstance->Modules->Find("m_spanningtree.so");
diff --git a/src/modules/m_bcrypt.cpp b/src/modules/m_bcrypt.cpp
index 8a025a0d6..1698b0727 100644
--- a/src/modules/m_bcrypt.cpp
+++ b/src/modules/m_bcrypt.cpp
@@ -978,7 +978,7 @@ class ModuleBCrypt : public Module
bcrypt.rounds = conf->getInt("rounds", 10, 1);
}
- Version GetVersion()
+ Version GetVersion() CXX11_OVERRIDE
{
return Version("Implements bcrypt hashing", VF_VENDOR);
}
diff --git a/src/modules/m_cgiirc.cpp b/src/modules/m_cgiirc.cpp
index 09d6e5fdf..5eba5ce35 100644
--- a/src/modules/m_cgiirc.cpp
+++ b/src/modules/m_cgiirc.cpp
@@ -77,6 +77,7 @@ class CommandWebirc : public Command
realhost("cgiirc_realhost", ExtensionItem::EXT_USER, Creator)
, realip("cgiirc_realip", ExtensionItem::EXT_USER, Creator)
{
+ allow_empty_last_param = false;
works_before_reg = true;
this->syntax = "password client hostname ip";
}
@@ -85,6 +86,14 @@ class CommandWebirc : public Command
if(user->registered == REG_ALL)
return CMD_FAILURE;
+ irc::sockets::sockaddrs ipaddr;
+ if (!irc::sockets::aptosa(parameters[3], 0, ipaddr))
+ {
+ IS_LOCAL(user)->CommandFloodPenalty += 5000;
+ ServerInstance->SNO->WriteGlobalSno('a', "Connecting user %s tried to use WEBIRC but gave an invalid IP address.", user->GetFullRealHost().c_str());
+ return CMD_FAILURE;
+ }
+
for(CGIHostlist::iterator iter = Hosts.begin(); iter != Hosts.end(); iter++)
{
if(InspIRCd::Match(user->host, iter->hostmask, ascii_case_insensitive_map) || InspIRCd::MatchCIDR(user->GetIPString(), iter->hostmask, ascii_case_insensitive_map))
@@ -112,6 +121,7 @@ class CommandWebirc : public Command
}
}
+ IS_LOCAL(user)->CommandFloodPenalty += 5000;
ServerInstance->SNO->WriteGlobalSno('w', "Connecting user %s tried to use WEBIRC, but didn't match any configured webirc blocks.", user->GetFullRealHost().c_str());
return CMD_FAILURE;
}
diff --git a/src/modules/m_check.cpp b/src/modules/m_check.cpp
index f4123466e..2cb45ad43 100644
--- a/src/modules/m_check.cpp
+++ b/src/modules/m_check.cpp
@@ -169,7 +169,7 @@ class CommandCheck : public Command
context.Write("nuh", targuser->GetFullHost());
context.Write("realnuh", targuser->GetFullRealHost());
context.Write("realname", targuser->fullname);
- context.Write("modes", std::string("+") + targuser->FormatModes());
+ context.Write("modes", targuser->GetModeLetters());
context.Write("snomasks", GetSnomasks(targuser));
context.Write("server", targuser->server->GetName());
context.Write("uid", targuser->uuid);
diff --git a/src/modules/m_clearchan.cpp b/src/modules/m_clearchan.cpp
index 4142f81d1..1b4b8724a 100644
--- a/src/modules/m_clearchan.cpp
+++ b/src/modules/m_clearchan.cpp
@@ -150,7 +150,7 @@ class ModuleClearChan : public Module
{
}
- void init()
+ void init() CXX11_OVERRIDE
{
// Only attached while we are working; don't react to events otherwise
ServerInstance->Modules->DetachAll(this);
diff --git a/src/modules/m_cloaking.cpp b/src/modules/m_cloaking.cpp
index 890c799f2..c114516c9 100644
--- a/src/modules/m_cloaking.cpp
+++ b/src/modules/m_cloaking.cpp
@@ -89,6 +89,10 @@ class CloakUser : public ModeHandler
if (adding)
{
+ // assume this is more correct
+ if (user->registered != REG_ALL && user->host != user->dhost)
+ return MODEACTION_DENY;
+
std::string* cloak = ext.get(user);
if (!cloak)
@@ -286,7 +290,7 @@ class ModuleCloaking : public Module
return MOD_RES_PASSTHRU;
}
- void Prioritize()
+ void Prioritize() CXX11_OVERRIDE
{
/* Needs to be after m_banexception etc. */
ServerInstance->Modules->SetPriority(this, I_OnCheckBan, PRIORITY_LAST);
@@ -343,11 +347,14 @@ class ModuleCloaking : public Module
{
std::string chost;
+ irc::sockets::sockaddrs hostip;
+ bool host_is_ip = irc::sockets::aptosa(host, ip.port(), hostip) && hostip == ip;
+
switch (mode)
{
case MODE_HALF_CLOAK:
{
- if (ipstr != host)
+ if (!host_is_ip)
chost = prefix + SegmentCloak(host, 1, 6) + LastTwoDomainParts(host);
if (chost.empty() || chost.length() > 50)
chost = SegmentIP(ip, false);
diff --git a/src/modules/m_conn_join.cpp b/src/modules/m_conn_join.cpp
index b22dbdf4d..bd8d89dc9 100644
--- a/src/modules/m_conn_join.cpp
+++ b/src/modules/m_conn_join.cpp
@@ -78,7 +78,7 @@ class ModuleConnJoin : public Module
defdelay = tag->getInt("delay", 0, 0, 60);
}
- void Prioritize()
+ void Prioritize() CXX11_OVERRIDE
{
ServerInstance->Modules->SetPriority(this, I_OnPostConnect, PRIORITY_LAST);
}
diff --git a/src/modules/m_conn_umodes.cpp b/src/modules/m_conn_umodes.cpp
index 7a8d66ae7..0b708641e 100644
--- a/src/modules/m_conn_umodes.cpp
+++ b/src/modules/m_conn_umodes.cpp
@@ -25,7 +25,7 @@
class ModuleModesOnConnect : public Module
{
public:
- void Prioritize()
+ void Prioritize() CXX11_OVERRIDE
{
// for things like +x on connect, important, otherwise we have to resort to config order (bleh) -- w00t
ServerInstance->Modules->SetPriority(this, I_OnUserConnect, PRIORITY_FIRST);
diff --git a/src/modules/m_connectban.cpp b/src/modules/m_connectban.cpp
index fcb4b09ed..e0f9717c4 100644
--- a/src/modules/m_connectban.cpp
+++ b/src/modules/m_connectban.cpp
@@ -95,7 +95,7 @@ class ModuleConnectBan : public Module
}
}
- void OnGarbageCollect()
+ void OnGarbageCollect() CXX11_OVERRIDE
{
ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Clearing map.");
connects.clear();
diff --git a/src/modules/m_dnsbl.cpp b/src/modules/m_dnsbl.cpp
index 73ecd02a6..752a0d7a5 100644
--- a/src/modules/m_dnsbl.cpp
+++ b/src/modules/m_dnsbl.cpp
@@ -70,6 +70,14 @@ class DNSBLResolver : public DNS::Request
if (!ans_record)
return;
+ // All replies should be in 127.0.0.0/8
+ if (ans_record->rdata.compare(0, 4, "127.") != 0)
+ {
+ ServerInstance->SNO->WriteGlobalSno('a', "DNSBL: %s returned address outside of acceptable subnet 127.0.0.0/8: %s", ConfEntry->domain.c_str(), ans_record->rdata.c_str());
+ ConfEntry->stats_misses++;
+ return;
+ }
+
int i = countExt.get(them);
if (i)
countExt.set(them, i - 1);
@@ -175,7 +183,7 @@ class DNSBLResolver : public DNS::Request
if (ServerInstance->XLines->AddLine(zl,NULL))
{
std::string timestr = InspIRCd::TimeString(zl->expiry);
- ServerInstance->SNO->WriteGlobalSno('x',"Z:line added due to DNSBL match on *@%s to expire on %s: %s",
+ ServerInstance->SNO->WriteGlobalSno('x',"Z:line added due to DNSBL match on %s to expire on %s: %s",
them->GetIPString().c_str(), timestr.c_str(), reason.c_str());
ServerInstance->XLines->ApplyLines();
}
diff --git a/src/modules/m_filter.cpp b/src/modules/m_filter.cpp
index bd19a60ba..0badd1377 100644
--- a/src/modules/m_filter.cpp
+++ b/src/modules/m_filter.cpp
@@ -176,7 +176,7 @@ class ModuleFilter : public Module
ExemptTargetSet exemptednicks;
ModuleFilter();
- CullResult cull();
+ CullResult cull() CXX11_OVERRIDE;
ModResult OnUserPreMessage(User* user, void* dest, int target_type, std::string& text, char status, CUList& exempt_list, MessageType msgtype) CXX11_OVERRIDE;
FilterResult* FilterMatch(User* user, const std::string &text, int flags);
bool DeleteFilter(const std::string &freeform);
diff --git a/src/modules/m_flashpolicyd.cpp b/src/modules/m_flashpolicyd.cpp
index 8f847e111..38b7be73f 100644
--- a/src/modules/m_flashpolicyd.cpp
+++ b/src/modules/m_flashpolicyd.cpp
@@ -146,7 +146,7 @@ class ModuleFlashPD : public Module
</cross-domain-policy>";
}
- CullResult cull()
+ CullResult cull() CXX11_OVERRIDE
{
for (insp::intrusive_list<FlashPDSocket>::const_iterator i = sockets.begin(); i != sockets.end(); ++i)
{
diff --git a/src/modules/m_hostcycle.cpp b/src/modules/m_hostcycle.cpp
index b33c101ef..621f06a27 100644
--- a/src/modules/m_hostcycle.cpp
+++ b/src/modules/m_hostcycle.cpp
@@ -40,6 +40,8 @@ class ModuleHostCycle : public Module
FOREACH_MOD(OnBuildNeighborList, (user, include_chans, exceptions));
+ // Users shouldn't see themselves quitting when host cycling
+ exceptions.erase(user);
for (std::map<User*,bool>::iterator i = exceptions.begin(); i != exceptions.end(); ++i)
{
LocalUser* u = IS_LOCAL(i->first);
diff --git a/src/modules/m_httpd.cpp b/src/modules/m_httpd.cpp
index 6055d1f77..35ae9abe5 100644
--- a/src/modules/m_httpd.cpp
+++ b/src/modules/m_httpd.cpp
@@ -224,7 +224,7 @@ class HttpServerSocket : public BufferedSocket, public Timer, public insp::intru
WriteData("\r\n");
}
- void OnDataReady()
+ void OnDataReady() CXX11_OVERRIDE
{
if (InternalState == HTTP_SERVE_RECV_POSTDATA)
{
@@ -415,7 +415,7 @@ class ModuleHttpServer : public Module
return MOD_RES_ALLOW;
}
- void OnUnloadModule(Module* mod)
+ void OnUnloadModule(Module* mod) CXX11_OVERRIDE
{
for (insp::intrusive_list<HttpServerSocket>::const_iterator i = sockets.begin(); i != sockets.end(); )
{
diff --git a/src/modules/m_httpd_stats.cpp b/src/modules/m_httpd_stats.cpp
index eb8e856ac..62ae0c204 100644
--- a/src/modules/m_httpd_stats.cpp
+++ b/src/modules/m_httpd_stats.cpp
@@ -189,7 +189,7 @@ class ModuleHttpStats : public Module, public HTTPRequestEventListener
data << "<away>" << Sanitize(u->awaymsg) << "</away><awaytime>" << u->awaytime << "</awaytime>";
if (u->IsOper())
data << "<opertype>" << Sanitize(u->oper->name) << "</opertype>";
- data << "<modes>" << u->FormatModes() << "</modes><ident>" << Sanitize(u->ident) << "</ident>";
+ data << "<modes>" << u->GetModeLetters().substr(1) << "</modes><ident>" << Sanitize(u->ident) << "</ident>";
LocalUser* lu = IS_LOCAL(u);
if (lu)
data << "<port>" << lu->GetServerPort() << "</port><servaddr>"
@@ -211,7 +211,7 @@ class ModuleHttpStats : public Module, public HTTPRequestEventListener
data << "<server>";
data << "<servername>" << b->servername << "</servername>";
data << "<parentname>" << b->parentname << "</parentname>";
- data << "<gecos>" << b->gecos << "</gecos>";
+ data << "<gecos>" << Sanitize(b->gecos) << "</gecos>";
data << "<usercount>" << b->usercount << "</usercount>";
// This is currently not implemented, so, commented out.
// data << "<opercount>" << b->opercount << "</opercount>";
diff --git a/src/modules/m_ircv3.cpp b/src/modules/m_ircv3.cpp
index 9e94e556d..543fb49a4 100644
--- a/src/modules/m_ircv3.cpp
+++ b/src/modules/m_ircv3.cpp
@@ -169,7 +169,7 @@ class ModuleIRCv3 : public Module, public AccountEventListener
last_excepts.clear();
}
- void Prioritize()
+ void Prioritize() CXX11_OVERRIDE
{
ServerInstance->Modules->SetPriority(this, I_OnUserJoin, PRIORITY_LAST);
}
diff --git a/src/modules/m_ldapauth.cpp b/src/modules/m_ldapauth.cpp
index 7da63284a..fedf02b4d 100644
--- a/src/modules/m_ldapauth.cpp
+++ b/src/modules/m_ldapauth.cpp
@@ -406,9 +406,22 @@ public:
return MOD_RES_DENY;
}
+ std::string what;
+ std::string::size_type pos = user->password.find(':');
+ if (pos != std::string::npos)
+ {
+ what = attribute + "=" + user->password.substr(0, pos);
+
+ // Trim the user: prefix, leaving just 'pass' for later password check
+ user->password = user->password.substr(pos + 1);
+ }
+ else
+ {
+ what = attribute + "=" + (useusername ? user->ident : user->nick);
+ }
+
try
{
- std::string what = attribute + "=" + (useusername ? user->ident : user->nick);
LDAP->BindAsManager(new AdminBindInterface(this, LDAP.GetProvider(), user->uuid, base, what));
}
catch (LDAPException &ex)
diff --git a/src/modules/m_md5.cpp b/src/modules/m_md5.cpp
index 6cec05a18..26ff4cffc 100644
--- a/src/modules/m_md5.cpp
+++ b/src/modules/m_md5.cpp
@@ -61,23 +61,13 @@ class MD5Provider : public HashProvider
} while (--words);
}
- void MD5Init(MD5Context *ctx, unsigned int* ikey = NULL)
+ void MD5Init(MD5Context *ctx)
{
/* These are the defaults for md5 */
- if (!ikey)
- {
- ctx->buf[0] = 0x67452301;
- ctx->buf[1] = 0xefcdab89;
- ctx->buf[2] = 0x98badcfe;
- ctx->buf[3] = 0x10325476;
- }
- else
- {
- ctx->buf[0] = ikey[0];
- ctx->buf[1] = ikey[1];
- ctx->buf[2] = ikey[2];
- ctx->buf[3] = ikey[3];
- }
+ ctx->buf[0] = 0x67452301;
+ ctx->buf[1] = 0xefcdab89;
+ ctx->buf[2] = 0x98badcfe;
+ ctx->buf[3] = 0x10325476;
ctx->bytes[0] = 0;
ctx->bytes[1] = 0;
@@ -236,10 +226,10 @@ class MD5Provider : public HashProvider
}
- void MyMD5(void *dest, void *orig, int len, unsigned int* ikey)
+ void MyMD5(void *dest, void *orig, int len)
{
MD5Context context;
- MD5Init(&context, ikey);
+ MD5Init(&context);
MD5Update(&context, (const unsigned char*)orig, len);
MD5Final((unsigned char*)dest, &context);
}
@@ -248,7 +238,7 @@ class MD5Provider : public HashProvider
std::string GenerateRaw(const std::string& data)
{
char res[16];
- MyMD5(res, (void*)data.data(), data.length(), NULL);
+ MyMD5(res, (void*)data.data(), data.length());
return std::string(res, 16);
}
diff --git a/src/modules/m_messageflood.cpp b/src/modules/m_messageflood.cpp
index 7323605cb..d89de49eb 100644
--- a/src/modules/m_messageflood.cpp
+++ b/src/modules/m_messageflood.cpp
@@ -150,7 +150,7 @@ class ModuleMsgFlood : public Module
return MOD_RES_PASSTHRU;
}
- void Prioritize()
+ void Prioritize() CXX11_OVERRIDE
{
// we want to be after all modules that might deny the message (e.g. m_muteban, m_noctcp, m_blockcolor, etc.)
ServerInstance->Modules->SetPriority(this, I_OnUserPreMessage, PRIORITY_LAST);
diff --git a/src/modules/m_mlock.cpp b/src/modules/m_mlock.cpp
index d3ab5b9fd..2a0410bed 100644
--- a/src/modules/m_mlock.cpp
+++ b/src/modules/m_mlock.cpp
@@ -34,7 +34,7 @@ class ModuleMLock : public Module
return Version("Implements the ability to have server-side MLOCK enforcement.", VF_VENDOR);
}
- ModResult OnRawMode(User* source, Channel* channel, ModeHandler* mh, const std::string& parameter, bool adding)
+ ModResult OnRawMode(User* source, Channel* channel, ModeHandler* mh, const std::string& parameter, bool adding) CXX11_OVERRIDE
{
if (!channel)
return MOD_RES_PASSTHRU;
diff --git a/src/modules/m_namedmodes.cpp b/src/modules/m_namedmodes.cpp
index 7a86c9e3c..7f2687d66 100644
--- a/src/modules/m_namedmodes.cpp
+++ b/src/modules/m_namedmodes.cpp
@@ -124,7 +124,7 @@ class ModuleNamedModes : public Module
return Version("Provides the ability to manipulate modes via long names.",VF_VENDOR);
}
- void Prioritize()
+ void Prioritize() CXX11_OVERRIDE
{
ServerInstance->Modules->SetPriority(this, I_OnPreMode, PRIORITY_FIRST);
}
diff --git a/src/modules/m_nicklock.cpp b/src/modules/m_nicklock.cpp
index 35845c8d8..6e22a69bb 100644
--- a/src/modules/m_nicklock.cpp
+++ b/src/modules/m_nicklock.cpp
@@ -157,7 +157,7 @@ class ModuleNickLock : public Module
return MOD_RES_PASSTHRU;
}
- void Prioritize()
+ void Prioritize() CXX11_OVERRIDE
{
Module *nflood = ServerInstance->Modules->Find("m_nickflood.so");
ServerInstance->Modules->SetPriority(this, I_OnUserPreNick, PRIORITY_BEFORE, nflood);
diff --git a/src/modules/m_ojoin.cpp b/src/modules/m_ojoin.cpp
index 2573e8b78..76e66bdc2 100644
--- a/src/modules/m_ojoin.cpp
+++ b/src/modules/m_ojoin.cpp
@@ -34,7 +34,7 @@ class CommandOjoin : public SplitCommand
: SplitCommand(parent, "OJOIN", 1)
, npmh(&mode)
{
- flags_needed = 'o'; Penalty = 0; syntax = "<channel>";
+ flags_needed = 'o'; syntax = "<channel>";
active = false;
}
@@ -150,7 +150,7 @@ class ModuleOjoin : public Module
return MOD_RES_DENY;
}
- void Prioritize()
+ void Prioritize() CXX11_OVERRIDE
{
ServerInstance->Modules->SetPriority(this, I_OnUserPreJoin, PRIORITY_FIRST);
}
diff --git a/src/modules/m_operprefix.cpp b/src/modules/m_operprefix.cpp
index d66f99450..b355047ee 100644
--- a/src/modules/m_operprefix.cpp
+++ b/src/modules/m_operprefix.cpp
@@ -72,7 +72,7 @@ class ModuleOperPrefixMode : public Module
return MOD_RES_PASSTHRU;
}
- void OnPostJoin(Membership* memb)
+ void OnPostJoin(Membership* memb) CXX11_OVERRIDE
{
if ((!IS_LOCAL(memb->user)) || (!memb->user->IsOper()) || (memb->user->IsModeSet(hideopermode)))
return;
@@ -105,7 +105,7 @@ class ModuleOperPrefixMode : public Module
return Version("Gives opers cmode +y which provides a staff prefix.", VF_VENDOR);
}
- void Prioritize()
+ void Prioritize() CXX11_OVERRIDE
{
// m_opermodes may set +H on the oper to hide him, we don't want to set the oper prefix in that case
Module* opermodes = ServerInstance->Modules->Find("m_opermodes.so");
diff --git a/src/modules/m_override.cpp b/src/modules/m_override.cpp
index 9cfc3aed0..fd09dd6ec 100644
--- a/src/modules/m_override.cpp
+++ b/src/modules/m_override.cpp
@@ -121,7 +121,8 @@ class ModuleOverride : public Module
if (source->IsOper() && CanOverride(source,"KICK"))
{
// If the kicker's status is less than the target's, or the kicker's status is less than or equal to voice
- if ((memb->chan->GetPrefixValue(source) < memb->getRank()) || (memb->chan->GetPrefixValue(source) <= VOICE_VALUE))
+ if ((memb->chan->GetPrefixValue(source) < memb->getRank()) || (memb->chan->GetPrefixValue(source) <= VOICE_VALUE) ||
+ (memb->chan->GetPrefixValue(source) == HALFOP_VALUE && memb->getRank() == HALFOP_VALUE))
{
ServerInstance->SNO->WriteGlobalSno('v',source->nick+" used oper override to kick "+memb->user->nick+" on "+memb->chan->name+" ("+reason+")");
return MOD_RES_ALLOW;
diff --git a/src/modules/m_permchannels.cpp b/src/modules/m_permchannels.cpp
index 9e77bd60e..0f2a2ef6f 100644
--- a/src/modules/m_permchannels.cpp
+++ b/src/modules/m_permchannels.cpp
@@ -244,6 +244,10 @@ public:
mode->OnModeChange(ServerInstance->FakeClient, ServerInstance->FakeClient, c, par, true);
}
}
+
+ // We always apply the permchannels mode to permanent channels.
+ par.clear();
+ p.OnModeChange(ServerInstance->FakeClient, ServerInstance->FakeClient, c, par, true);
}
}
}
@@ -269,7 +273,7 @@ public:
dirty = false;
}
- void Prioritize()
+ void Prioritize() CXX11_OVERRIDE
{
// XXX: Load the DB here because the order in which modules are init()ed at boot is
// alphabetical, this means we must wait until all modules have done their init()
diff --git a/src/modules/m_rline.cpp b/src/modules/m_rline.cpp
index 97fbf169a..e77a00b6d 100644
--- a/src/modules/m_rline.cpp
+++ b/src/modules/m_rline.cpp
@@ -333,7 +333,7 @@ class ModuleRLine : public Module
}
}
- void Prioritize()
+ void Prioritize() CXX11_OVERRIDE
{
Module* mod = ServerInstance->Modules->Find("m_cgiirc.so");
ServerInstance->Modules->SetPriority(this, I_OnUserRegister, PRIORITY_AFTER, mod);
diff --git a/src/modules/m_sajoin.cpp b/src/modules/m_sajoin.cpp
index 9d87360ec..8bf865319 100644
--- a/src/modules/m_sajoin.cpp
+++ b/src/modules/m_sajoin.cpp
@@ -29,7 +29,7 @@ class CommandSajoin : public Command
CommandSajoin(Module* Creator) : Command(Creator,"SAJOIN", 1)
{
allow_empty_last_param = false;
- flags_needed = 'o'; Penalty = 0; syntax = "[<nick>] <channel>[,<channel>]";
+ flags_needed = 'o'; syntax = "[<nick>] <channel>[,<channel>]";
TRANSLATE2(TR_NICK, TR_TEXT);
}
diff --git a/src/modules/m_sakick.cpp b/src/modules/m_sakick.cpp
index ab168ca68..81a74502b 100644
--- a/src/modules/m_sakick.cpp
+++ b/src/modules/m_sakick.cpp
@@ -27,7 +27,7 @@ class CommandSakick : public Command
public:
CommandSakick(Module* Creator) : Command(Creator,"SAKICK", 2, 3)
{
- flags_needed = 'o'; Penalty = 0; syntax = "<channel> <nick> [reason]";
+ flags_needed = 'o'; syntax = "<channel> <nick> [reason]";
TRANSLATE3(TR_TEXT, TR_NICK, TR_TEXT);
}
diff --git a/src/modules/m_samode.cpp b/src/modules/m_samode.cpp
index bcb876d5b..394cea722 100644
--- a/src/modules/m_samode.cpp
+++ b/src/modules/m_samode.cpp
@@ -31,7 +31,7 @@ class CommandSamode : public Command
CommandSamode(Module* Creator) : Command(Creator,"SAMODE", 2)
{
allow_empty_last_param = false;
- flags_needed = 'o'; Penalty = 0; syntax = "<target> <modes> {<mode-parameters>}";
+ flags_needed = 'o'; syntax = "<target> <modes> {<mode-parameters>}";
active = false;
}
@@ -96,7 +96,7 @@ class ModuleSaMode : public Module
return MOD_RES_PASSTHRU;
}
- void Prioritize()
+ void Prioritize() CXX11_OVERRIDE
{
Module *override = ServerInstance->Modules->Find("m_override.so");
ServerInstance->Modules->SetPriority(this, I_OnPreMode, PRIORITY_BEFORE, override);
diff --git a/src/modules/m_sanick.cpp b/src/modules/m_sanick.cpp
index 3dc89b4f6..c9ceba78e 100644
--- a/src/modules/m_sanick.cpp
+++ b/src/modules/m_sanick.cpp
@@ -29,7 +29,7 @@ class CommandSanick : public Command
CommandSanick(Module* Creator) : Command(Creator,"SANICK", 2)
{
allow_empty_last_param = false;
- flags_needed = 'o'; Penalty = 0; syntax = "<nick> <new-nick>";
+ flags_needed = 'o'; syntax = "<nick> <new-nick>";
TRANSLATE2(TR_NICK, TR_TEXT);
}
diff --git a/src/modules/m_sapart.cpp b/src/modules/m_sapart.cpp
index db1e6fdee..b51316dc5 100644
--- a/src/modules/m_sapart.cpp
+++ b/src/modules/m_sapart.cpp
@@ -28,7 +28,7 @@ class CommandSapart : public Command
public:
CommandSapart(Module* Creator) : Command(Creator,"SAPART", 2, 3)
{
- flags_needed = 'o'; Penalty = 0; syntax = "<nick> <channel>[,<channel>] [reason]";
+ flags_needed = 'o'; syntax = "<nick> <channel>[,<channel>] [reason]";
TRANSLATE3(TR_NICK, TR_TEXT, TR_TEXT);
}
diff --git a/src/modules/m_saquit.cpp b/src/modules/m_saquit.cpp
index c3895ec12..9f700ec5f 100644
--- a/src/modules/m_saquit.cpp
+++ b/src/modules/m_saquit.cpp
@@ -28,7 +28,7 @@ class CommandSaquit : public Command
public:
CommandSaquit(Module* Creator) : Command(Creator, "SAQUIT", 2, 2)
{
- flags_needed = 'o'; Penalty = 0; syntax = "<nick> <reason>";
+ flags_needed = 'o'; syntax = "<nick> <reason>";
TRANSLATE2(TR_NICK, TR_TEXT);
}
diff --git a/src/modules/m_sasl.cpp b/src/modules/m_sasl.cpp
index 2b247a198..9f7e1527b 100644
--- a/src/modules/m_sasl.cpp
+++ b/src/modules/m_sasl.cpp
@@ -153,10 +153,63 @@ class SaslAuthenticator
SaslResult result;
bool state_announced;
+ /* taken from m_services_account */
+ static bool ReadCGIIRCExt(const char* extname, User* user, std::string& out)
+ {
+ ExtensionItem* wiext = ServerInstance->Extensions.GetItem(extname);
+ if (!wiext)
+ return false;
+
+ if (wiext->creator->ModuleSourceFile != "m_cgiirc.so")
+ return false;
+
+ StringExtItem* stringext = static_cast<StringExtItem*>(wiext);
+ std::string* addr = stringext->get(user);
+ if (!addr)
+ return false;
+
+ out = *addr;
+ return true;
+ }
+
+
+ void SendHostIP()
+ {
+ std::string host, ip;
+
+ if (!ReadCGIIRCExt("cgiirc_webirc_hostname", user, host))
+ {
+ host = user->host;
+ }
+ if (!ReadCGIIRCExt("cgiirc_webirc_ip", user, ip))
+ {
+ ip = user->GetIPString();
+ }
+ else
+ {
+ /* IP addresses starting with a : on irc are a Bad Thing (tm) */
+ if (ip.c_str()[0] == ':')
+ ip.insert(ip.begin(),1,'0');
+ }
+
+ parameterlist params;
+ params.push_back(sasl_target);
+ params.push_back("SASL");
+ params.push_back(user->uuid);
+ params.push_back("*");
+ params.push_back("H");
+ params.push_back(host);
+ params.push_back(ip);
+
+ SendSASL(params);
+ }
+
public:
SaslAuthenticator(User* user_, const std::string& method)
: user(user_), state(SASL_INIT), state_announced(false)
{
+ SendHostIP();
+
parameterlist params;
params.push_back(user->uuid);
params.push_back("*");
@@ -287,6 +340,7 @@ class CommandAuthenticate : public Command
: Command(Creator, "AUTHENTICATE", 1), authExt(ext), cap(Cap)
{
works_before_reg = true;
+ allow_empty_last_param = false;
}
CmdResult Handle (const std::vector<std::string>& parameters, User *user)
@@ -295,6 +349,9 @@ class CommandAuthenticate : public Command
if (!cap.get(user))
return CMD_FAILURE;
+ if (parameters[0].find(' ') != std::string::npos || parameters[0][0] == ':')
+ return CMD_FAILURE;
+
SaslAuthenticator *sasl = authExt.get(user);
if (!sasl)
authExt.set(user, new SaslAuthenticator(user, parameters[0]));
@@ -378,7 +435,7 @@ class ModuleSASL : public Module
servertracker.Reset();
}
- ModResult OnUserRegister(LocalUser *user) CXX11_OVERRIDE
+ void OnUserConnect(LocalUser *user) CXX11_OVERRIDE
{
SaslAuthenticator *sasl_ = authExt.get(user);
if (sasl_)
@@ -386,8 +443,6 @@ class ModuleSASL : public Module
sasl_->Abort();
authExt.unset(user);
}
-
- return MOD_RES_PASSTHRU;
}
void OnDecodeMetaData(Extensible* target, const std::string& extname, const std::string& extdata) CXX11_OVERRIDE
diff --git a/src/modules/m_satopic.cpp b/src/modules/m_satopic.cpp
index f966d6a5a..f45d9c8cd 100644
--- a/src/modules/m_satopic.cpp
+++ b/src/modules/m_satopic.cpp
@@ -26,7 +26,7 @@ class CommandSATopic : public Command
public:
CommandSATopic(Module* Creator) : Command(Creator,"SATOPIC", 2, 2)
{
- flags_needed = 'o'; Penalty = 0; syntax = "<target> <topic>";
+ flags_needed = 'o'; syntax = "<target> <topic>";
}
CmdResult Handle (const std::vector<std::string>& parameters, User *user)
diff --git a/src/modules/m_sha1.cpp b/src/modules/m_sha1.cpp
index 5926e4926..798539d91 100644
--- a/src/modules/m_sha1.cpp
+++ b/src/modules/m_sha1.cpp
@@ -190,7 +190,7 @@ class ModuleSHA1 : public Module
big_endian = (htonl(1337) == 1337);
}
- Version GetVersion()
+ Version GetVersion() CXX11_OVERRIDE
{
return Version("Implements SHA-1 hashing", VF_VENDOR);
}
diff --git a/src/modules/m_shun.cpp b/src/modules/m_shun.cpp
index 022726524..28faf898b 100644
--- a/src/modules/m_shun.cpp
+++ b/src/modules/m_shun.cpp
@@ -191,7 +191,7 @@ class ModuleShun : public Module
ServerInstance->XLines->UnregisterFactory(&f);
}
- void Prioritize()
+ void Prioritize() CXX11_OVERRIDE
{
Module* alias = ServerInstance->Modules->Find("m_alias.so");
ServerInstance->Modules->SetPriority(this, I_OnPreCommand, PRIORITY_BEFORE, alias);
diff --git a/src/modules/m_spanningtree/main.h b/src/modules/m_spanningtree/main.h
index 46c21b4e9..00cbd3dcd 100644
--- a/src/modules/m_spanningtree/main.h
+++ b/src/modules/m_spanningtree/main.h
@@ -168,8 +168,8 @@ class ModuleSpanningTree : public Module
void OnUnloadModule(Module* mod) CXX11_OVERRIDE;
ModResult OnAcceptConnection(int newsock, ListenSocket* from, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server) CXX11_OVERRIDE;
void OnMode(User* source, User* u, Channel* c, const Modes::ChangeList& modes, ModeParser::ModeProcessFlag processflags, const std::string& output_mode) CXX11_OVERRIDE;
- CullResult cull();
+ CullResult cull() CXX11_OVERRIDE;
~ModuleSpanningTree();
Version GetVersion() CXX11_OVERRIDE;
- void Prioritize();
+ void Prioritize() CXX11_OVERRIDE;
};
diff --git a/src/modules/m_spanningtree/protocolinterface.h b/src/modules/m_spanningtree/protocolinterface.h
index e7fed5475..b0609005c 100644
--- a/src/modules/m_spanningtree/protocolinterface.h
+++ b/src/modules/m_spanningtree/protocolinterface.h
@@ -37,7 +37,7 @@ class SpanningTreeProtocolInterface : public ProtocolInterface
void SendMetaData(Channel* chan, const std::string& key, const std::string& data) CXX11_OVERRIDE;
void SendMetaData(const std::string& key, const std::string& data) CXX11_OVERRIDE;
void SendSNONotice(char snomask, const std::string& text) CXX11_OVERRIDE;
- void SendMessage(Channel* target, char status, const std::string& text, MessageType msgtype);
- void SendMessage(User* target, const std::string& text, MessageType msgtype);
- void GetServerList(ServerList& sl);
+ void SendMessage(Channel* target, char status, const std::string& text, MessageType msgtype) CXX11_OVERRIDE;
+ void SendMessage(User* target, const std::string& text, MessageType msgtype) CXX11_OVERRIDE;
+ void GetServerList(ServerList& sl) CXX11_OVERRIDE;
};
diff --git a/src/modules/m_spanningtree/servercommand.h b/src/modules/m_spanningtree/servercommand.h
index 07dfc4898..ee7766764 100644
--- a/src/modules/m_spanningtree/servercommand.h
+++ b/src/modules/m_spanningtree/servercommand.h
@@ -43,7 +43,7 @@ class ServerCommand : public CommandBase
void RegisterService() CXX11_OVERRIDE;
virtual CmdResult Handle(User* user, std::vector<std::string>& parameters) = 0;
- virtual RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters);
+ virtual RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters) CXX11_OVERRIDE;
/**
* Extract the TS from a string.
diff --git a/src/modules/m_spanningtree/treeserver.h b/src/modules/m_spanningtree/treeserver.h
index b7e9ee9d9..f75adf54c 100644
--- a/src/modules/m_spanningtree/treeserver.h
+++ b/src/modules/m_spanningtree/treeserver.h
@@ -219,7 +219,7 @@ class TreeServer : public Server
*/
void OnPong() { pingtimer.OnPong(); }
- CullResult cull();
+ CullResult cull() CXX11_OVERRIDE;
/** Destructor, deletes ServerUser unless IsRoot()
*/
diff --git a/src/modules/m_spanningtree/treesocket.h b/src/modules/m_spanningtree/treesocket.h
index 4887623c1..3571f2816 100644
--- a/src/modules/m_spanningtree/treesocket.h
+++ b/src/modules/m_spanningtree/treesocket.h
@@ -200,7 +200,7 @@ class TreeSocket : public BufferedSocket
*/
void CleanNegotiationInfo();
- CullResult cull();
+ CullResult cull() CXX11_OVERRIDE;
/** Destructor
*/
~TreeSocket();
@@ -216,7 +216,7 @@ class TreeSocket : public BufferedSocket
* to server docs on the inspircd.org site, the other side
* will then send back its own server string.
*/
- void OnConnected();
+ void OnConnected() CXX11_OVERRIDE;
/** Handle socket error event
*/
@@ -270,7 +270,7 @@ class TreeSocket : public BufferedSocket
/** This function is called when we receive data from a remote
* server.
*/
- void OnDataReady();
+ void OnDataReady() CXX11_OVERRIDE;
/** Send one or more complete lines down the socket
*/
@@ -299,10 +299,10 @@ class TreeSocket : public BufferedSocket
/** Handle socket timeout from connect()
*/
- void OnTimeout();
+ void OnTimeout() CXX11_OVERRIDE;
/** Handle server quit on close
*/
- void Close();
+ void Close() CXX11_OVERRIDE;
/** Fixes messages coming from old servers so the new command handlers understand them
*/
diff --git a/src/modules/m_spanningtree/uid.cpp b/src/modules/m_spanningtree/uid.cpp
index a41fe408d..91c9f3ca8 100644
--- a/src/modules/m_spanningtree/uid.cpp
+++ b/src/modules/m_spanningtree/uid.cpp
@@ -50,12 +50,8 @@ CmdResult CommandUID::HandleServer(TreeServer* remoteserver, std::vector<std::st
{
// User that the incoming user is colliding with is not fully registered, we force nick change the
// unregistered user to their uuid and tell them what happened
- collideswith->WriteFrom(collideswith, "NICK %s", collideswith->uuid.c_str());
- collideswith->WriteNumeric(ERR_NICKNAMEINUSE, collideswith->nick, "Nickname overruled.");
-
- // Clear the bit before calling User::ChangeNick() to make it NOT run the OnUserPostNick() hook
- collideswith->registered &= ~REG_NICK;
- collideswith->ChangeNick(collideswith->uuid);
+ LocalUser* const localuser = static_cast<LocalUser*>(collideswith);
+ localuser->OverruleNick();
}
else if (collideswith)
{
@@ -166,6 +162,6 @@ CommandUID::Builder::Builder(User* user)
push(user->ident);
push(user->GetIPString());
push_int(user->signon);
- push('+').push_raw(user->FormatModes(true));
+ push(user->GetModeLetters(true));
push_last(user->fullname);
}
diff --git a/src/modules/m_spanningtree/utils.h b/src/modules/m_spanningtree/utils.h
index a2f7212f6..f262f9a48 100644
--- a/src/modules/m_spanningtree/utils.h
+++ b/src/modules/m_spanningtree/utils.h
@@ -108,7 +108,7 @@ class SpanningTreeUtilities : public classbase
/** Prepare for class destruction
*/
- CullResult cull();
+ CullResult cull() CXX11_OVERRIDE;
/** Destroy class and free listeners etc
*/
diff --git a/src/modules/m_timedbans.cpp b/src/modules/m_timedbans.cpp
index 874e6440f..44c6c4c4f 100644
--- a/src/modules/m_timedbans.cpp
+++ b/src/modules/m_timedbans.cpp
@@ -218,7 +218,7 @@ class ModuleTimedBans : public Module
}
}
- void OnChannelDelete(Channel* chan)
+ void OnChannelDelete(Channel* chan) CXX11_OVERRIDE
{
// Remove all timed bans affecting the channel from internal bookkeeping
TimedBanList.erase(std::remove_if(TimedBanList.begin(), TimedBanList.end(), ChannelMatcher(chan)), TimedBanList.end());
diff --git a/src/socketengine.cpp b/src/socketengine.cpp
index 4183488b7..3735e7530 100644
--- a/src/socketengine.cpp
+++ b/src/socketengine.cpp
@@ -203,40 +203,35 @@ void SocketEngine::SetReuse(int fd)
int SocketEngine::RecvFrom(EventHandler* fd, void *buf, size_t len, int flags, sockaddr *from, socklen_t *fromlen)
{
int nbRecvd = recvfrom(fd->GetFd(), (char*)buf, len, flags, from, fromlen);
- if (nbRecvd > 0)
- stats.Update(nbRecvd, 0);
+ stats.UpdateReadCounters(nbRecvd);
return nbRecvd;
}
int SocketEngine::Send(EventHandler* fd, const void *buf, size_t len, int flags)
{
int nbSent = send(fd->GetFd(), (const char*)buf, len, flags);
- if (nbSent > 0)
- stats.Update(0, nbSent);
+ stats.UpdateWriteCounters(nbSent);
return nbSent;
}
int SocketEngine::Recv(EventHandler* fd, void *buf, size_t len, int flags)
{
int nbRecvd = recv(fd->GetFd(), (char*)buf, len, flags);
- if (nbRecvd > 0)
- stats.Update(nbRecvd, 0);
+ stats.UpdateReadCounters(nbRecvd);
return nbRecvd;
}
int SocketEngine::SendTo(EventHandler* fd, const void *buf, size_t len, int flags, const sockaddr *to, socklen_t tolen)
{
int nbSent = sendto(fd->GetFd(), (const char*)buf, len, flags, to, tolen);
- if (nbSent > 0)
- stats.Update(0, nbSent);
+ stats.UpdateWriteCounters(nbSent);
return nbSent;
}
int SocketEngine::WriteV(EventHandler* fd, const IOVector* iovec, int count)
{
int sent = writev(fd->GetFd(), iovec, count);
- if (sent > 0)
- stats.Update(0, sent);
+ stats.UpdateWriteCounters(sent);
return sent;
}
@@ -289,11 +284,26 @@ int SocketEngine::Shutdown(int fd, int how)
return shutdown(fd, how);
}
-void SocketEngine::Statistics::Update(size_t len_in, size_t len_out)
+void SocketEngine::Statistics::UpdateReadCounters(int len_in)
{
CheckFlush();
- indata += len_in;
- outdata += len_out;
+
+ ReadEvents++;
+ if (len_in > 0)
+ indata += len_in;
+ else if (len_in < 0)
+ ErrorEvents++;
+}
+
+void SocketEngine::Statistics::UpdateWriteCounters(int len_out)
+{
+ CheckFlush();
+
+ WriteEvents++;
+ if (len_out > 0)
+ outdata += len_out;
+ else if (len_out < 0)
+ ErrorEvents++;
}
void SocketEngine::Statistics::CheckFlush() const
diff --git a/src/socketengines/socketengine_epoll.cpp b/src/socketengines/socketengine_epoll.cpp
index 7602dd201..c442e340d 100644
--- a/src/socketengines/socketengine_epoll.cpp
+++ b/src/socketengines/socketengine_epoll.cpp
@@ -22,7 +22,7 @@
#include "exitcodes.h"
#include <sys/epoll.h>
-#include <ulimit.h>
+#include <sys/resource.h>
#include <iostream>
/** A specialisation of the SocketEngine class, designed to use linux 2.6 epoll().
@@ -38,8 +38,12 @@ namespace
void SocketEngine::Init()
{
- // MAX_DESCRIPTORS is mainly used for display purposes, no problem if ulimit() fails and returns a negative number
- MAX_DESCRIPTORS = ulimit(4, 0);
+ // MAX_DESCRIPTORS is mainly used for display purposes, no problem if getrlimit() fails
+ struct rlimit limit;
+ if (!getrlimit(RLIMIT_NOFILE, &limit))
+ {
+ MAX_DESCRIPTORS = limit.rlim_cur;
+ }
// 128 is not a maximum, just a hint at the eventual number of sockets that may be polled,
// and it is completely ignored by 2.6.8 and later kernels, except it must be larger than zero.
@@ -213,7 +217,6 @@ int SocketEngine::DispatchEvents()
eh->SetEventMask(mask);
if (ev.events & EPOLLIN)
{
- stats.ReadEvents++;
eh->OnEventHandlerRead();
if (eh != GetRef(fd))
// whoa! we got deleted, better not give out the write event
@@ -221,7 +224,6 @@ int SocketEngine::DispatchEvents()
}
if (ev.events & EPOLLOUT)
{
- stats.WriteEvents++;
eh->OnEventHandlerWrite();
}
}
diff --git a/src/socketengines/socketengine_kqueue.cpp b/src/socketengines/socketengine_kqueue.cpp
index 922cb7f2d..9db902314 100644
--- a/src/socketengines/socketengine_kqueue.cpp
+++ b/src/socketengines/socketengine_kqueue.cpp
@@ -199,7 +199,6 @@ int SocketEngine::DispatchEvents()
}
if (filter == EVFILT_WRITE)
{
- stats.WriteEvents++;
/* When mask is FD_WANT_FAST_WRITE or FD_WANT_SINGLE_WRITE,
* we set a one-shot write, so we need to clear that bit
* to detect when it set again.
@@ -210,7 +209,6 @@ int SocketEngine::DispatchEvents()
}
else if (filter == EVFILT_READ)
{
- stats.ReadEvents++;
eh->SetEventMask(eh->GetEventMask() & ~FD_READ_WILL_BLOCK);
eh->OnEventHandlerRead();
}
diff --git a/src/socketengines/socketengine_ports.cpp b/src/socketengines/socketengine_ports.cpp
index d94d02664..68fa70e3b 100644
--- a/src/socketengines/socketengine_ports.cpp
+++ b/src/socketengines/socketengine_ports.cpp
@@ -159,14 +159,12 @@ int SocketEngine::DispatchEvents()
port_associate(EngineHandle, PORT_SOURCE_FD, fd, mask_to_events(mask), eh);
if (portev_events & POLLRDNORM)
{
- stats.ReadEvents++;
eh->OnEventHandlerRead();
if (eh != GetRef(fd))
continue;
}
if (portev_events & POLLWRNORM)
{
- stats.WriteEvents++;
eh->OnEventHandlerWrite();
}
}
diff --git a/src/socketengines/socketengine_select.cpp b/src/socketengines/socketengine_select.cpp
index 6dfbae88e..42f634db1 100644
--- a/src/socketengines/socketengine_select.cpp
+++ b/src/socketengines/socketengine_select.cpp
@@ -147,7 +147,6 @@ int SocketEngine::DispatchEvents()
if (has_read)
{
- stats.ReadEvents++;
ev->SetEventMask(ev->GetEventMask() & ~FD_READ_WILL_BLOCK);
ev->OnEventHandlerRead();
if (ev != GetRef(i))
@@ -156,7 +155,6 @@ int SocketEngine::DispatchEvents()
if (has_write)
{
- stats.WriteEvents++;
int newmask = (ev->GetEventMask() & ~(FD_WRITE_WILL_BLOCK | FD_WANT_SINGLE_WRITE));
SocketEngine::OnSetEvent(ev, ev->GetEventMask(), newmask);
ev->SetEventMask(newmask);
diff --git a/src/users.cpp b/src/users.cpp
index 498a27d58..d54931644 100644
--- a/src/users.cpp
+++ b/src/users.cpp
@@ -33,34 +33,34 @@ bool User::IsNoticeMaskSet(unsigned char sm)
return (snomasks[sm-65]);
}
-bool User::IsModeSet(unsigned char m)
+bool User::IsModeSet(unsigned char m) const
{
ModeHandler* mh = ServerInstance->Modes->FindMode(m, MODETYPE_USER);
return (mh && modes[mh->GetId()]);
}
-const char* User::FormatModes(bool showparameters)
+std::string User::GetModeLetters(bool includeparams) const
{
- static std::string data;
+ std::string ret(1, '+');
std::string params;
- data.clear();
- for (unsigned char n = 0; n < 64; n++)
+ for (unsigned char i = 'A'; i < 'z'; i++)
{
- ModeHandler* mh = ServerInstance->Modes->FindMode(n + 65, MODETYPE_USER);
- if (mh && IsModeSet(mh))
+ const ModeHandler* const mh = ServerInstance->Modes.FindMode(i, MODETYPE_USER);
+ if ((!mh) || (!IsModeSet(mh)))
+ continue;
+
+ ret.push_back(mh->GetModeChar());
+ if ((includeparams) && (mh->NeedsParam(true)))
{
- data.push_back(n + 65);
- if (showparameters && mh->NeedsParam(true))
- {
- std::string p = mh->GetUserParameter(this);
- if (p.length())
- params.append(" ").append(p);
- }
+ const std::string val = mh->GetUserParameter(this);
+ if (!val.empty())
+ params.append(1, ' ').append(val);
}
}
- data += params;
- return data.c_str();
+
+ ret += params;
+ return ret;
}
User::User(const std::string& uid, Server* srv, int type)
@@ -588,6 +588,7 @@ void LocalUser::FullConnect()
void User::InvalidateCache()
{
/* Invalidate cache */
+ cachedip.clear();
cached_fullhost.clear();
cached_hostip.clear();
cached_makehost.clear();
@@ -627,11 +628,8 @@ bool User::ChangeNick(const std::string& newnick, time_t newts)
if (InUse->registered != REG_ALL)
{
/* force the camper to their UUID, and ask them to re-send a NICK. */
- InUse->WriteFrom(InUse, "NICK %s", InUse->uuid.c_str());
- InUse->WriteNumeric(ERR_NICKNAMEINUSE, InUse->nick, "Nickname overruled.");
-
- InUse->registered &= ~REG_NICK;
- InUse->ChangeNick(InUse->uuid);
+ LocalUser* const localuser = static_cast<LocalUser*>(InUse);
+ localuser->OverruleNick();
}
else
{
@@ -659,6 +657,16 @@ bool User::ChangeNick(const std::string& newnick, time_t newts)
return true;
}
+void LocalUser::OverruleNick()
+{
+ this->WriteFrom(this, "NICK %s", this->uuid.c_str());
+ this->WriteNumeric(ERR_NICKNAMEINUSE, this->nick, "Nickname overruled.");
+
+ // Clear the bit before calling ChangeNick() to make it NOT run the OnUserPostNick() hook
+ this->registered &= ~REG_NICK;
+ this->ChangeNick(this->uuid);
+}
+
int LocalUser::GetServerPort()
{
switch (this->server_sa.sa.sa_family)
@@ -702,8 +710,7 @@ irc::sockets::cidr_mask User::GetCIDRMask()
bool User::SetClientIP(const char* sip, bool recheck_eline)
{
- cachedip.clear();
- cached_hostip.clear();
+ this->InvalidateCache();
return irc::sockets::aptosa(sip, 0, client_sa);
}
diff --git a/tools/genssl b/tools/genssl
index b824f4ebe..189311c1a 100755
--- a/tools/genssl
+++ b/tools/genssl
@@ -45,7 +45,7 @@ sub prompt($$) {
}
if ($#ARGV != 0 || $ARGV[0] !~ /^(?:auto|gnutls|openssl)$/i) {
- say 'Syntax: genssl <auto|gnutls|openssl>';
+ say STDERR "Usage: $0 <auto|gnutls|openssl>";
exit 1;
}
diff --git a/win/CMakeLists.txt b/win/CMakeLists.txt
index 768270696..b5812b0c2 100644
--- a/win/CMakeLists.txt
+++ b/win/CMakeLists.txt
@@ -89,6 +89,7 @@ file(MAKE_DIRECTORY ${LOG_DIR})
install(DIRECTORY ${LOG_DIR} DESTINATION .)
if(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake")
+ set(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION ".") # place runtime libraries next to InspIRCd binary
include(InstallRequiredSystemLibraries)
set(CPACK_PACKAGE_NAME "InspIRCd IRC Daemon")