summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2015-10-27 18:57:37 -0400
committerAdam <Adam@anope.org>2015-10-27 18:58:48 -0400
commit64dac60071fab652745a6e7a06cf6b7bdbbd3625 (patch)
treef8f30161150451672b381f6370a8fdcab654bbb8
parent162fdbe5815bbdf187f549fefac94ff476d72e62 (diff)
parent830361e97d03c74e54cb1cf1bbf329dffdeb66f7 (diff)
Merge branch '2.0' into 2.1
-rw-r--r--.mailmap2
-rw-r--r--CMakeLists.txt70
-rwxr-xr-xConfig34
-rw-r--r--Config.exebin18432 -> 0 bytes
-rwxr-xr-xcmake/run-cc.pl226
-rw-r--r--data/chanserv.example.conf9
-rw-r--r--data/example.conf18
-rw-r--r--data/hybrid.example.conf7
-rw-r--r--data/modules.example.conf13
-rw-r--r--data/nickserv.example.conf12
-rw-r--r--data/unreal.example.conf1
-rw-r--r--docs/Changes27
-rw-r--r--docs/Changes.conf9
-rw-r--r--docs/README2
-rw-r--r--docs/XMLRPC/XMLRPC4
-rw-r--r--docs/XMLRPC/xmlrpc.php183
-rw-r--r--include/CMakeLists.txt3
-rw-r--r--include/anope.h6
-rw-r--r--include/channels.h6
-rw-r--r--include/config.h2
-rw-r--r--include/event.h3
-rw-r--r--include/hashcomp.h2
-rw-r--r--include/modes.h6
-rw-r--r--include/modules.h33
-rw-r--r--include/modules/chanserv.h4
-rw-r--r--include/modules/cs_mode.h2
-rw-r--r--include/modules/ldap.h42
-rw-r--r--include/sockets.h2
-rw-r--r--include/users.h4
-rw-r--r--include/version.cpp122
-rw-r--r--language/anope.de_DE.po2
-rw-r--r--language/anope.fr_FR.po2
-rw-r--r--language/anope.nl_NL.po625
-rw-r--r--modules/commands/bs_bot.cpp12
-rw-r--r--modules/commands/cs_access.cpp12
-rw-r--r--modules/commands/cs_ban.cpp39
-rw-r--r--modules/commands/cs_clone.cpp16
-rw-r--r--modules/commands/cs_entrymsg.cpp12
-rw-r--r--modules/commands/cs_kick.cpp28
-rw-r--r--modules/commands/cs_mode.cpp40
-rw-r--r--modules/commands/cs_set.cpp26
-rw-r--r--modules/commands/cs_topic.cpp6
-rw-r--r--modules/commands/hs_del.cpp3
-rw-r--r--modules/commands/hs_group.cpp2
-rw-r--r--modules/commands/hs_list.cpp2
-rw-r--r--modules/commands/hs_off.cpp4
-rw-r--r--modules/commands/hs_on.cpp3
-rw-r--r--modules/commands/hs_set.cpp3
-rw-r--r--modules/commands/ms_read.cpp4
-rw-r--r--modules/commands/ms_set.cpp2
-rw-r--r--modules/commands/ns_alist.cpp2
-rw-r--r--modules/commands/ns_identify.cpp8
-rw-r--r--modules/commands/ns_logout.cpp2
-rw-r--r--modules/commands/ns_register.cpp8
-rw-r--r--modules/commands/ns_set.cpp2
-rw-r--r--modules/commands/os_mode.cpp14
-rw-r--r--modules/database/db_flatfile.cpp2
-rw-r--r--modules/database/db_old.cpp2
-rw-r--r--modules/extra/m_ldap.cpp665
-rw-r--r--modules/extra/m_ldap_authentication.cpp152
-rw-r--r--modules/extra/m_ldap_oper.cpp43
-rw-r--r--modules/extra/m_ssl_openssl.cpp18
-rw-r--r--modules/extra/stats/irc2sql/irc2sql.cpp11
-rw-r--r--modules/extra/stats/irc2sql/irc2sql.h3
-rw-r--r--modules/extra/stats/m_chanstats.cpp9
-rw-r--r--modules/fantasy.cpp28
-rw-r--r--modules/m_dns.cpp16
-rw-r--r--modules/m_xmlrpc.cpp50
-rw-r--r--modules/protocol/bahamut.cpp8
-rw-r--r--modules/protocol/charybdis.cpp4
-rw-r--r--modules/protocol/hybrid.cpp27
-rw-r--r--modules/protocol/inspircd20.cpp58
-rw-r--r--modules/protocol/ngircd.cpp14
-rw-r--r--modules/protocol/ratbox.cpp4
-rw-r--r--modules/protocol/unreal.cpp10
-rw-r--r--modules/pseudoclients/botserv/botserv.cpp6
-rw-r--r--modules/pseudoclients/chanserv/channel.cpp17
-rw-r--r--modules/pseudoclients/chanserv/channel.h4
-rw-r--r--modules/pseudoclients/nickserv/nickserv.cpp44
-rw-r--r--modules/pseudoclients/operserv.cpp8
-rw-r--r--modules/webcpanel/pages/index.cpp6
-rw-r--r--src/CMakeLists.txt4
-rw-r--r--src/bots.cpp5
-rw-r--r--src/channels.cpp55
-rw-r--r--src/config.cpp1
-rw-r--r--src/extensible.cpp2
-rw-r--r--src/init.cpp2
-rw-r--r--src/language.cpp2
-rw-r--r--src/messages.cpp23
-rw-r--r--src/misc.cpp7
-rw-r--r--src/modes.cpp13
-rw-r--r--src/module.cpp5
-rw-r--r--src/modulemanager.cpp70
-rw-r--r--src/protocol.cpp6
-rw-r--r--src/tools/CMakeLists.txt2
-rw-r--r--src/tools/geoipupdate.sh2
-rw-r--r--src/uplink.cpp1
-rw-r--r--src/version.sh6
-rw-r--r--src/win32/Config.cs2
-rw-r--r--src/win32/socket.cpp2
-rw-r--r--src/win32/windows.cpp2
101 files changed, 1672 insertions, 1482 deletions
diff --git a/.mailmap b/.mailmap
index 427a943b5..dac503a70 100644
--- a/.mailmap
+++ b/.mailmap
@@ -28,7 +28,9 @@ Naram Qashat <cyberbotx@anope.org> <cyberbotx@5417fbe8-f217-4b02-8779-1006273d78
Naram Qashat <cyberbotx@anope.org> <cyberbotx@cyberbotx.com>
Naram Qashat <cyberbotx@anope.org> <Naram Qashat cyberbotx@cyberbotx.com@5417fbe8-f217-4b02-8779-1006273d7864>
Pieter Bootsma <geniusdex@anope.org> <geniusdex geniusdex@31f1291d-b8d6-0310-a050-a5561fc1590b@5417fbe8-f217-4b02-8779-1006273d7864>
+Robby <robby@anope.org>
Robby <robby@chat.be>
+Robby <robby@chatbelgie.be>
Robin Burchell <w00t@inspircd.org> <rburchell@5417fbe8-f217-4b02-8779-1006273d7864>
Robin Burchell <w00t@inspircd.org> <Robin Burchell w00t@inspircd.org@5417fbe8-f217-4b02-8779-1006273d7864>
Sebastian V. <hal9000@denorastats.org>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 70ad660bd..974988b67 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,10 +1,13 @@
# This usage of CMake requires at least version 2.8
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
-# If the Source dir and the Binary dir are the same, we are building in-source, which we will disallow due to Autotools being there (but only on non-Windows)
-if(${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_BINARY_DIR} AND NOT WIN32)
- message(FATAL_ERROR "You can not use CMake to build Anope from the root of it's source tree! Remove the CMakeCache.txt file from this directory, then create a separate directory (either below this directory or elsewhere), and then re-run CMake from there.")
-endif(${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_BINARY_DIR} AND NOT WIN32)
+cmake_policy(SET CMP0003 NEW)
+if(POLICY CMP0026)
+ cmake_policy(SET CMP0026 OLD)
+endif(POLICY CMP0026)
+if(POLICY CMP0007)
+ cmake_policy(SET CMP0007 OLD)
+endif(POLICY CMP0007)
# Set the project as C++ primarily, but have C enabled for the checks required later
project(Anope CXX)
@@ -58,9 +61,6 @@ endif(EXTRA_LIBS)
# Find gettext
find_package(Gettext)
-# Add an optional variable for using run-cc.pl for building, Perl will be checked later regardless of this setting
-option(USE_RUN_CC_PL "Use run-cc.pl for building" OFF)
-
# Use the following directories as includes
# Note that it is important the binary include directory comes before the
# source include directory so the precompiled headers work correctly.
@@ -100,13 +100,15 @@ if(CMAKE_DL_LIBS)
list(APPEND LINK_LIBS ${CMAKE_DL_LIBS})
endif(CMAKE_DL_LIBS)
-# Under Windows, we set the executable name for Anope to be anope
-if(WIN32)
- set(PROGRAM_NAME anope)
-# Under *nix, we set the executable name for Anope to be services
-else(WIN32)
- set(PROGRAM_NAME services)
-endif(WIN32)
+if(NOT PROGRAM_NAME)
+ # Under Windows, we set the executable name for Anope to be anope
+ if(WIN32)
+ set(PROGRAM_NAME anope)
+ # Under *nix, we set the executable name for Anope to be services
+ else(WIN32)
+ set(PROGRAM_NAME services)
+ endif(WIN32)
+endif(NOT PROGRAM_NAME)
# If we are not using Visual Studio, we'll run the following checks
if(NOT MSVC)
@@ -173,19 +175,11 @@ endif(LDFLAGS)
# Search for the following programs
find_program(CHGRP chgrp)
find_program(CHMOD chmod)
-find_program(PERL perl)
-
-# If perl is included on the system and the user wants to use run-cc.pl, change the commands for compiling and linking
-if(PERL AND USE_RUN_CC_PL)
- set(CMAKE_CXX_COMPILE_OBJECT "${PERL} ${Anope_SOURCE_DIR}/cmake/run-cc.pl -q ${CMAKE_CXX_COMPILE_OBJECT}")
- set(CMAKE_CXX_LINK_EXECUTABLE "${PERL} ${Anope_SOURCE_DIR}/cmake/run-cc.pl -q ${CMAKE_CXX_LINK_EXECUTABLE}")
- set(CMAKE_CXX_CREATE_SHARED_MODULE "${PERL} ${Anope_SOURCE_DIR}/cmake/run-cc.pl -q ${CMAKE_CXX_CREATE_SHARED_MODULE}")
-endif(PERL AND USE_RUN_CC_PL)
# If a INSTDIR was passed in to CMake, use it as the install prefix, otherwise set the default install prefix to the services directory under the user's home directory
if(INSTDIR)
set(CMAKE_INSTALL_PREFIX "${INSTDIR}")
-else(INSTDIR)
+elseif(NOT CMAKE_INSTALL_PREFIX)
set(CMAKE_INSTALL_PREFIX "$ENV{HOME}/services")
endif(INSTDIR)
@@ -217,16 +211,14 @@ endif(NOT LOGS_DIR)
file(STRINGS ${Anope_SOURCE_DIR}/src/version.sh VERSIONS REGEX "^VERSION_")
# Iterate through the strings found
foreach(VERSION_STR ${VERSIONS})
- # Get the length of the string
- string(LENGTH ${VERSION_STR} VERSION_LEN)
- # Subtract 16 from the string's length (8 for VERSION_, 5 more for the type, 2 for the space and leading quote, 1 for the trailing quote)
- math(EXPR VERSION_NUM_LEN "${VERSION_LEN} - 16")
- # Extract the type from the string
- string(SUBSTRING ${VERSION_STR} 8 5 VERSION_TYPE)
- # Extract the actual value from the string
- string(SUBSTRING ${VERSION_STR} 15 ${VERSION_NUM_LEN} VERSION)
- # Set the version type to the value extract from above
- set(VERSION_${VERSION_TYPE} ${VERSION})
+ string(REGEX REPLACE "^VERSION_([A-Z]+)=\"?([^\"]*)\"?$" "\\1;\\2" VERSION_OUT ${VERSION_STR})
+ # Depends on CMP0007 OLD
+ list(LENGTH VERSION_OUT VERSION_LEN)
+ list(GET VERSION_OUT 0 VERSION_TYPE)
+ if(${VERSION_LEN} GREATER 1)
+ list(GET VERSION_OUT 1 VERSION_DATA)
+ set(VERSION_${VERSION_TYPE} ${VERSION_DATA})
+ endif(${VERSION_LEN} GREATER 1)
endforeach(VERSION_STR ${VERSIONS})
# Default build version to 0
@@ -290,16 +282,16 @@ get_target_property(SERVICES_BINARY ${PROGRAM_NAME} LOCATION)
get_filename_component(SERVICES_BINARY ${SERVICES_BINARY} NAME)
# At install time, create the following additional directories
-install(CODE "file(MAKE_DIRECTORY \"\${CMAKE_INSTALL_PREFIX}/${DB_DIR}/backups\")")
-install(CODE "file(MAKE_DIRECTORY \"\${CMAKE_INSTALL_PREFIX}/${LOGS_DIR}\")")
+install(CODE "file(MAKE_DIRECTORY \"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/${DB_DIR}/backups\")")
+install(CODE "file(MAKE_DIRECTORY \"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/${LOGS_DIR}\")")
if(WIN32)
install(CODE "file(MAKE_DIRECTORY \"\${CMAKE_INSTALL_PREFIX}/${DB_DIR}/runtime\")")
endif(WIN32)
# On non-Windows platforms, if RUNGROUP is set, change the permissions of the below directories, as well as the group of the data directory
if(NOT WIN32 AND RUNGROUP)
- install(CODE "execute_process(COMMAND ${CHMOD} 2775 \"\${CMAKE_INSTALL_PREFIX}/\${DB_DIR}/backups\")")
- install(CODE "execute_process(COMMAND ${CHMOD} 2775 \"\${CMAKE_INSTALL_PREFIX}/\${LOGS_DIR}\")")
- install(CODE "execute_process(COMMAND ${CHGRP} -R ${RUNGROUP} \"\${CMAKE_INSTALL_PREFIX}\")")
+ install(CODE "execute_process(COMMAND ${CHMOD} 2775 \"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/\${DB_DIR}/backups\")")
+ install(CODE "execute_process(COMMAND ${CHMOD} 2775 \"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/\${LOGS_DIR}\")")
+ install(CODE "execute_process(COMMAND ${CHGRP} -R ${RUNGROUP} \"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}\")")
endif(NOT WIN32 AND RUNGROUP)
# On Windows platforms, install extra files
if(WIN32)
@@ -312,7 +304,7 @@ if(WIN32)
install(FILES ${EXTRA_DLLS} DESTINATION ${BIN_DIR})
endif(WIN32)
-install(CODE "file(REMOVE_RECURSE \"${CMAKE_INSTALL_PREFIX}/${LIB_DIR}/modules\")")
+install(CODE "file(REMOVE_RECURSE \"$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/${LIB_DIR}/modules\")")
# Only process the CPack section if we have CPack
if(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake")
diff --git a/Config b/Config
index 3bd1ed976..1b869cdd0 100755
--- a/Config
+++ b/Config
@@ -61,12 +61,6 @@ Run_Build_System () {
BUILD_TYPE="-DCMAKE_BUILD_TYPE:STRING=RELEASE"
fi
- if [ "$USE_RUN_CC_PL" = "yes" ] ; then
- RUN_CC_PL="-DUSE_RUN_CC_PL:BOOLEAN=ON"
- else
- RUN_CC_PL="-DUSE_RUN_CC_PL:BOOLEAN=OFF"
- fi
-
if [ "$EXTRA_INCLUDE_DIRS" != "" ] ; then
EXTRA_INCLUDE="-DEXTRA_INCLUDE:STRING=$EXTRA_INCLUDE_DIRS"
fi
@@ -118,7 +112,6 @@ INSTDIR=$HOME/services
RUNGROUP=
UMASK=
DEBUG="no"
-USE_RUN_CC_PL="no"
EXTRA_INCLUDE_DIRS=
EXTRA_LIB_DIRS=
EXTRA_CONFIG_ARGS=
@@ -307,30 +300,6 @@ echo ""
####
-TEMP_YN="n"
-if [ "$USE_RUN_CC_PL" = "yes" ] ; then
- TEMP_YN="y"
-fi
-echo "You can optionally have the build run through run-cc.pl, which will"
-echo "cause warnings and errors (if any) to be colored yellow and red,"
-echo "respectively. This relies on Perl being installed, so if you say yes"
-echo "to this without Perl, the option will be ignored."
-echo "NOTE: If you are using MinGW, it is NOT recommended to say yes to"
-echo "this, it may fail."
-echo "Would you like to utilize run-cc.pl?"
-echo2 "[$TEMP_YN] "
-read YN
-if [ "$YN" ] ; then
- if [ "$YN" = "y" ] ; then
- USE_RUN_CC_PL="yes"
- else
- USE_RUN_CC_PL="no"
- fi
-fi
-echo ""
-
-####
-
echo "Are there any extra include directories you wish to use?"
echo "You may only need to do this if CMake is unable to locate"
echo "missing dependencies without hints."
@@ -368,7 +337,7 @@ echo ""
####
echo "Are there any extra arguments you wish to pass to CMake?"
-echo "If you need no extra arugments to CMake, enter NONE in all caps."
+echo "If you need no extra arguments to CMake, enter NONE in all caps."
echo2 "[$EXTRA_CONFIG_ARGS] "
if read INPUT ; then : ; else echo "" ; exit 1 ; fi
if [ "$INPUT" ] ; then
@@ -393,7 +362,6 @@ INSTDIR="$INSTDIR"
RUNGROUP="$RUNGROUP"
UMASK=$UMASK
DEBUG="$DEBUG"
-USE_RUN_CC_PL="$USE_RUN_CC_PL"
EXTRA_INCLUDE_DIRS="$EXTRA_INCLUDE_DIRS"
EXTRA_LIB_DIRS="$EXTRA_LIB_DIRS"
EXTRA_CONFIG_ARGS="$EXTRA_CONFIG_ARGS"
diff --git a/Config.exe b/Config.exe
deleted file mode 100644
index 3be910bb0..000000000
--- a/Config.exe
+++ /dev/null
Binary files differ
diff --git a/cmake/run-cc.pl b/cmake/run-cc.pl
deleted file mode 100755
index fe28dee10..000000000
--- a/cmake/run-cc.pl
+++ /dev/null
@@ -1,226 +0,0 @@
-#!/usr/bin/env perl
-
-### THIS IS DESIGNED TO BE RUN BY MAKE! DO NOT RUN FROM THE SHELL (because it MIGHT sigterm the shell)! ###
-
-use strict;
-use warnings FATAL => qw(all);
-
-use POSIX ();
-
-# Runs the compiler, passing it the given arguments.
-# Filters select output from the compiler's standard error channel and
-# can take different actions as a result.
-
-# NOTE: this is *NOT* a hash (sadly: a hash would stringize all the regexes and thus render them useless, plus you can't index a hash based on regexes anyway)
-# even though we use the => in it.
-
-# The subs are passed the message, and anything the regex captured.
-
-my $flag = shift(@ARGV);
-my $quiet = 0;
-my $cc;
-if ($flag eq "-q") {
- $quiet = 1;
- $cc = shift(@ARGV);
-}
-else {
- $cc = $flag;
-}
-
-my $showncmdline = 0;
-
-# GCC's "location of error stuff", which accumulates the "In file included from" include stack
-my $location = "";
-
-my @msgfilters = (
- [ qr/^(.*) warning: cannot pass objects of non-POD type `(.*)' through `\.\.\.'; call will abort at runtime/ => sub {
- my ($msg, $where, $type) = @_;
- my $errstr = $location . "$where error: cannot pass objects of non-POD type `$type' through `...'\n";
- $location = "";
- if ($type =~ m/::(basic_)?string/) {
- $errstr .= "$where (Did you forget to call c_str()?)\n";
- }
- die $errstr;
- } ],
-
- # Start of an include stack.
- [ qr/^In file included from .*[,:]$/ => sub {
- my ($msg) = @_;
- $location = "$msg\n";
- return undef;
- } ],
-
- # Continuation of an include stack.
- [ qr/^ from .*[,:]$/ => sub {
- my ($msg) = @_;
- $location .= "$msg\n";
- return undef;
- } ],
-
- # A function, method, constructor, or destructor is the site of a problem
- [ qr/In ((con|de)structor|(member )?function)/ => sub {
- my ($msg) = @_;
- # If a complete location string is waiting then probably we dropped an error, so drop the location for a new one.
- if ($location =~ m/In ((con|de)structor|(member )?function)/) {
- $location = "$msg\n";
- } else {
- $location .= "$msg\n";
- }
- return undef;
- } ],
-
- [ qr/^.* warning: / => sub {
- my ($msg) = @_;
- my $str = $location . "\e[33;1m$msg\e[0m\n";
- $showncmdline = 1;
- $location = "";
- return $str;
- } ],
-
- [ qr/^.* error: / => sub {
- my ($msg) = @_;
- my $str = "";
- $str = "An error occured when executing:\e[37;1m $cc " . join(' ', @ARGV) . "\n" unless $showncmdline;
- $showncmdline = 1;
- $str .= $location . "\e[31;1m$msg\e[0m\n";
- $location = "";
- return $str;
- } ],
-
- [ qr/./ => sub {
- my ($msg) = @_;
- $msg = $location . $msg;
- $location = "";
- $msg =~ s/std::basic_string\<char\, std\:\:char_traits\<char\>, std::allocator\<char\> \>(\s+|)/std::string/g;
- $msg =~ s/std::basic_string\<char\, .*?irc_char_traits, std::allocator\<char\> \>(\s+|)/irc::string/g;
- $msg =~ s/std::basic_string\<char\, .*?ci_char_traits, std::allocator\<char\> \>(\s+|)/ci::string/g;
- for my $stl (qw(deque vector list)) {
- $msg =~ s/std::$stl\<(\S+), std::allocator\<\1\> \>/std::$stl\<$1\>/g;
- $msg =~ s/std::$stl\<(std::pair\<\S+, \S+\>), std::allocator\<\1 \> \>/std::$stl<$1 >/g;
- }
- $msg =~ s/std::map\<(\S+), (\S+), std::less\<\1\>, std::allocator\<std::pair\<const \1, \2\> \> \>/std::map<$1, $2>/g;
- # Warning: These filters are GNU C++ specific!
- $msg =~ s/__gnu_cxx::__normal_iterator\<(\S+)\*, std::vector\<\1\> \>/std::vector<$1>::iterator/g;
- $msg =~ s/__gnu_cxx::__normal_iterator\<(std::pair\<\S+, \S+\>)\*, std::vector\<\1 \> \>/std::vector<$1 >::iterator/g;
- $msg =~ s/__gnu_cxx::__normal_iterator\<char\*, std::string\>/std::string::iterator/g;
- $msg =~ s/__gnu_cxx::__normal_iterator\<char\*, irc::string\>/irc::string::iterator/g;
- $msg =~ s/__gnu_cxx::__normal_iterator\<char\*, ci::string\>/ci::string::iterator/g;
- return $msg;
- } ],
-);
-
-my $pid;
-
-my ($r_stderr, $w_stderr);
-
-my $name = "";
-my $action = "";
-
-if ($cc eq "ar") {
- $name = $ARGV[1];
- $action = "ARCHIVE";
-} else {
- foreach my $n (@ARGV)
- {
- if ($n =~ /\.cpp|\.c$/)
- {
- if ($action eq "BUILD")
- {
- $name .= " " . $n;
- }
- else
- {
- $action = "BUILD";
- $name = $n;
- }
- }
- elsif ($action eq "BUILD") # .cpp has priority.
- {
- next;
- }
- elsif ($n eq "-o")
- {
- $action = $name = $n;
- }
- elsif ($name eq "-o")
- {
- $action = "LINK";
- $name = $n;
- }
- }
-}
-
-if (!defined($cc) || $cc eq "") {
- die "Compiler not specified!\n";
-}
-
-pipe($r_stderr, $w_stderr) or die "pipe stderr: $!\n";
-
-$pid = fork;
-
-die "Cannot fork to start $cc! $!\n" unless defined($pid);
-
-if ($pid) {
-
- if ($quiet == 0) {
- printf "\t\e[1;32m%-20s\e[0m%s\n", $action . ":", $name unless $name eq "";
- }
-
- my $fail = 0;
- # Parent - Close child-side pipes.
- close $w_stderr;
- # Close STDIN to ensure no conflicts with child.
- close STDIN;
- # Now read each line of stderr
-LINE: while (defined(my $line = <$r_stderr>)) {
- chomp $line;
-
- for my $filter (@msgfilters) {
- my @caps;
- if (@caps = ($line =~ $filter->[0])) {
- $@ = "";
- $line = eval {
- $filter->[1]->($line, @caps);
- };
- if ($@) {
- # Note that $line is undef now.
- $fail = 1;
- print STDERR $@;
- }
- next LINE unless defined($line);
- }
- }
- # Chomp off newlines again, in case the filters put some back in.
- chomp $line;
- print STDERR "$line\n";
- }
- waitpid $pid, 0;
- close $r_stderr;
- my $exit = $?;
- # Simulate the same exit, so make gets the right termination info.
- if (POSIX::WIFSIGNALED($exit)) {
- # Make won't get the right termination info (it gets ours, not the compiler's), so we must tell the user what really happened ourselves!
- print STDERR "$cc killed by signal " . POSIX::WTERMSIGN($exit) . "\n";
- kill "TERM", getppid(); # Needed for bsd make.
- kill "TERM", $$;
- }
- else {
- if (POSIX::WEXITSTATUS($exit) == 0) {
- if ($fail) {
- kill "TERM", getppid(); # Needed for bsd make.
- kill "TERM", $$;
- }
- exit 0;
- } else {
- exit POSIX::WEXITSTATUS($exit);
- }
- }
-} else {
- # Child - Close parent-side pipes.
- close $r_stderr;
- # Divert stderr
- open STDERR, ">&", $w_stderr or die "Cannot divert STDERR: $!\n";
- # Run the compiler!
- exec { $cc } $cc, @ARGV;
- die "exec $cc: $!\n";
-}
diff --git a/data/chanserv.example.conf b/data/chanserv.example.conf
index aa336f1e4..86ca969fc 100644
--- a/data/chanserv.example.conf
+++ b/data/chanserv.example.conf
@@ -143,6 +143,13 @@ module
reasonmax = 200
/*
+ * The message formatting to use for signed kick messages.
+ * %n is the nick of the kicker
+ * %m is the message specified
+ */
+ signkickformat = "%m (%n)"
+
+ /*
* If set, prevents channel access entries from containing hostmasks.
*/
disallow_hostmask_access = false
@@ -1159,7 +1166,7 @@ command { service = "ChanServ"; name = "SET"; command = "chanserv/set"; group =
command { service = "ChanServ"; name = "SET AUTOOP"; command = "chanserv/set/autoop"; }
command { service = "ChanServ"; name = "SET BANTYPE"; command = "chanserv/set/bantype"; }
command { service = "ChanServ"; name = "SET DESCRIPTION"; command = "chanserv/set/description"; }
-command { service = "ChanServ"; name = "SET DESC"; command = "chanserv/set/description"; }
+command { service = "ChanServ"; name = "SET DESC"; command = "chanserv/set/description"; hide = yes; }
command { service = "ChanServ"; name = "SET FOUNDER"; command = "chanserv/set/founder"; }
command { service = "ChanServ"; name = "SET KEEPMODES"; command = "chanserv/set/keepmodes"; }
command { service = "ChanServ"; name = "SET PEACE"; command = "chanserv/set/peace"; }
diff --git a/data/example.conf b/data/example.conf
index ccaaf799b..02f7f9016 100644
--- a/data/example.conf
+++ b/data/example.conf
@@ -304,6 +304,16 @@ networkinfo
modelistsize = 100
/*
+ * Characters allowed in nicknames. This always includes the characters described
+ * in RFC1459, and so does not need to be set for normal behavior. Changing this to
+ * include characters your IRCd doesn't support will cause your IRCd and/or Services
+ * to break. Multibyte characters are not supported, nor are escape sequences.
+ *
+ * It is recommended you DON'T change this.
+ */
+ #nick_chars = ""
+
+ /*
* The characters allowed in hostnames. This is used for validating hostnames given
* to services, such as BotServ bot hostnames and user vhosts. Changing this is not
* recommended unless you know for sure your IRCd supports whatever characters you are
@@ -693,7 +703,7 @@ log
* create, destroy, join, part, kick, leave, mode
*
* Valid user options are:
- * connect, disconnect, quit, nick, ident, host, mode, maxusers, oper
+ * connect, disconnect, quit, nick, ident, host, mode, maxusers, oper, away
*
* Rawio and debug are simple yes/no answers, there are no types for them.
*
@@ -815,7 +825,7 @@ opertype
/* The name of this opertype */
name = "Services Operator"
- /* What opertype(s) this inherits from. Seperate with a comma. */
+ /* What opertype(s) this inherits from. Separate with a comma. */
inherits = "Helper, Another Helper"
/* What commands (see above) this opertype may use */
@@ -841,7 +851,7 @@ opertype
inherits = "Services Operator"
- commands = "chanserv/access/list chanserv/drop chanserv/getkey chanserv/saset/noexpire memoserv/sendall nickserv/saset/* nickserv/getemail operserv/news operserv/jupe operserv/svs operserv/stats operserv/oline operserv/noop operserv/forbid global/*"
+ commands = "botserv/* chanserv/access/list chanserv/drop chanserv/getkey chanserv/saset/noexpire memoserv/sendall nickserv/saset/* nickserv/getemail operserv/news operserv/jupe operserv/svs operserv/stats operserv/oline operserv/noop operserv/forbid global/*"
privs = "*"
}
@@ -998,7 +1008,7 @@ mail
emailchange_subject = "Email confirmation"
emailchange_message = "Hi,
- You have requested to change your email address to %e.
+ You have requested to change your email address from %e to %E.
Please type \" /msg NickServ CONFIRM %c \" to confirm this change.
If you don't know why this mail was sent to you, please ignore it silently.
diff --git a/data/hybrid.example.conf b/data/hybrid.example.conf
index ce285b30c..2af525c28 100644
--- a/data/hybrid.example.conf
+++ b/data/hybrid.example.conf
@@ -59,13 +59,6 @@ usermode
usermode
{
- name = "OPERWALL"
- character = "z"
- oper_only = yes
-}
-
-usermode
-{
name = "DEAF"
character = "D"
}
diff --git a/data/modules.example.conf b/data/modules.example.conf
index 4d3894bef..c5d8fb3a4 100644
--- a/data/modules.example.conf
+++ b/data/modules.example.conf
@@ -243,7 +243,6 @@ module { name = "help" }
ldap
{
server = "ldap://127.0.0.1"
- port = 389
/*
* Admin credentials used for performing searches and adding users.
@@ -299,7 +298,9 @@ module { name = "help" }
password_attribute = "userPassword"
/*
- * If set, the reason to give the users who try to "/msg NickServ REGISTER".
+ * If set, the reason to give the users who try to register with nickserv,
+ * including nick registration from grouping.
+ *
* If not set, then registration is not blocked.
*/
#disable_register_reason = "To register on this network visit http://some.misconfigured.site/register"
@@ -598,6 +599,14 @@ module { name = "help" }
*/
cert = "data/anope.crt"
key = "data/anope.key"
+
+ /*
+ * As of 2014 SSL 3.0 is considered insecure, but it might be enabled
+ * on some systems by default for compatibility reasons.
+ * You can use the following option to enable or disable it explicitly.
+ * Leaving this option not set defaults to the default system behavior.
+ */
+ #sslv3 = no
}
/*
diff --git a/data/nickserv.example.conf b/data/nickserv.example.conf
index f23361eee..f8ffade33 100644
--- a/data/nickserv.example.conf
+++ b/data/nickserv.example.conf
@@ -372,7 +372,15 @@ command { service = "NickServ"; name = "UNGROUP"; command = "nickserv/ungroup";
*
* Used for identifying to accounts.
*/
-module { name = "ns_identify" }
+module
+{
+ name = "ns_identify"
+
+ /*
+ * If set, limits the number of concurrent users that can be logged in as a given account at once.
+ */
+ maxlogins = 10
+}
command { service = "NickServ"; name = "ID"; command = "nickserv/identify"; hide = true; }
command { service = "NickServ"; name = "IDENTIFY"; command = "nickserv/identify"; }
@@ -381,7 +389,7 @@ command { service = "NickServ"; name = "IDENTIFY"; command = "nickserv/identify"
*
* Provides the commands:
* nickserv/info. - Used for gathering information about an account.
- * nickserv/set/hide, nickserv/saset/hide - Used for configuring which options are publically shown in nickserv/info.
+ * nickserv/set/hide, nickserv/saset/hide - Used for configuring which options are publicly shown in nickserv/info.
*
*/
module { name = "ns_info" }
diff --git a/data/unreal.example.conf b/data/unreal.example.conf
index 35a4210e6..d46f118c2 100644
--- a/data/unreal.example.conf
+++ b/data/unreal.example.conf
@@ -48,6 +48,7 @@ usermode
{
name = "HIDEIDLE"
character = "I"
+ oper_only = yes
}
usermode
diff --git a/docs/Changes b/docs/Changes
index 6280734c3..62242d7c0 100644
--- a/docs/Changes
+++ b/docs/Changes
@@ -1,3 +1,26 @@
+Anope Version 2.0.2
+-------------------
+Fix keepmodes preventing the first user of a channel from being deopped
+Fix SQlines that don't begin with # from matching channels
+Made cs_clone behave like the help describes, copying many settings and lists by default
+Allow cs_clone to clone levels, too
+Update Hybrid protocol module for 8.2
+Fix not unescaping all characters sent over XMLRPC
+Fix crash when os_mode is used to destroy channels, like when unsetting permanent channel mode from an empty channel
+Allow users with topic change privilege to change the topic instead of requiring them to use ChanServ's topic command
+Fix negatively locking param modes in default mlock
+Change entrymsg to check for the SET privilege, not real founder
+Allow configuring characters allowed in nicknames
+Fix crash when non users register channels externally (like XMLRPC)
+Remove operserv/exception MOVE, it did not function correctly. Instead reorder the list by deleting/adding entries.
+Allow flood ttb to be 0.
+Enforce mlock when disabling defcon modes
+Fix cs_mode not being able to apply mlock on register
+Add log message when users send memos
+Fix old collide timers from staying around after successful identify. Fixes being able to identify and logout and still being hit by the old timers.
+Fix undefined behavior in cs_mode which usually crashes when clearing large list modes
+Show all opertypes in operserv/info, even if no opers use them
+
Anope Version 2.0.1
-------------------
Fix access entries on accounts sometimes not updating when a user's display name changes
@@ -150,8 +173,8 @@ A Added ns_resetpass module to the core
A CS ACCESS VIEW which shows who added the access and last time used
A Last used time to CS AKICK VIEW
A Added a sha_256 encryption module
-A Added the ability to load multiple encryption modules, and the ability to seamlessly convert your database between diferent encryptions
-A Added configuration options to allow Anope to reconnect if it disconnects from the uplink instead of dieing
+A Added the ability to load multiple encryption modules, and the ability to seamlessly convert your database between different encryptions
+A Added configuration options to allow Anope to reconnect if it disconnects from the uplink instead of dying
A Added support for linking with IPv6
F Unban command to accept an optional nick arg
F Some typos in services.conf
diff --git a/docs/Changes.conf b/docs/Changes.conf
index c4a5d8ff7..5e813b3e4 100644
--- a/docs/Changes.conf
+++ b/docs/Changes.conf
@@ -1,8 +1,17 @@
+Anope Version 2.0.3-git
+-------------------
+Add ns_identify:maxlogins to limit the max number of concurrent logins per account
+
Anope Version 2.0.2
-------------------
Add an operserv/oper/modify privilege, required to use oper add and oper del
Add a chanserv/access/list privilege, which allow readonly access to ChanServ access and akick lists
Changed m_dnsbl's result configuration to be more extensible
+Add 'max' setting to cs_mode
+Add 'nickchars' setting to networkinfo
+Add 'botserv/fantasy', 'chanserv/access/list', and 'operserv/oper/modify' oper privileges
+Fix 'emailchange_message' to include the proper email address
+Set a default permission on operserv/defcon
Anope Version 2.0.1
-------------------
diff --git a/docs/README b/docs/README
index f1340f020..62569443b 100644
--- a/docs/README
+++ b/docs/README
@@ -107,7 +107,7 @@ Table of Contents
Anope Translations:
- * Robby <robby@chat.be> (nl_NL)
+ * Robby <robby@chatbelgie.be> (nl_NL)
* Kein <kein-of@yandex.ru> (ru_RU)
* Maik Funke <Han@mefalcon.org> (de_DE)
* Isaac Fontal <i_fontal@hotmail.com> (es_ES)
diff --git a/docs/XMLRPC/XMLRPC b/docs/XMLRPC/XMLRPC
index a183af097..95a18abc4 100644
--- a/docs/XMLRPC/XMLRPC
+++ b/docs/XMLRPC/XMLRPC
@@ -3,8 +3,8 @@ This allows external applications, such as websites, to execute remote procedure
Currently there are 5 supported XMLRPC calls, provided by m_xmlrpc_main:
-checkAuthetication - Takes two parameters, an account name and a password. Checks if the account name is valid and the password
- is correct for the account name, useful for making login pages on websites.
+checkAuthentication - Takes two parameters, an account name and a password. Checks if the account name is valid and the password
+ is correct for the account name, useful for making login pages on websites.
command - Takes three parameters, a service name (BotServ, ChanServ, NickServ), a user name (whether online or not), and the command
to execute. This will execute a the given command to Anope using the given service name. If the user given is online, the
diff --git a/docs/XMLRPC/xmlrpc.php b/docs/XMLRPC/xmlrpc.php
index c469ab05a..2b5645ca7 100644
--- a/docs/XMLRPC/xmlrpc.php
+++ b/docs/XMLRPC/xmlrpc.php
@@ -1,90 +1,129 @@
<?php
-/* XMLRPC Functions
+
+/**
+ * XMLRPC Functions
*
- * (C) 2003-2014 Anope Team
+ * (C) 2003-2015 Anope Team
* Contact us at team@anope.org
- *
*/
-
class AnopeXMLRPC
{
- private $Host;
+ /**
+ * The XMLRPC host
+ *
+ * @var string
+ */
+ private $host;
- function __construct($Host)
- {
- $this->Host = $Host;
- }
+ /**
+ * Initiate a new AnopeXMLRPC instance
+ *
+ * @param $host
+ */
+ public function __construct($host)
+ {
+ $this->host = $host;
+ }
- /** Run an XMLRPC command. Name should be a query name and params an array of parameters, eg:
- * $this->RunXMLRPC("checkAuthentication", array("adam", "qwerty"));
- * If successful returns back an array of useful information.
- *
- * Note that $params["id"] is reserved for query ID, you may set it to something if you wish.
- * If you do, the same ID will be passed back with the reply from Anope.
- */
- function RunXMLRPC($name, $params)
- {
- $xmlquery = xmlrpc_encode_request($name, $params);
- $context = stream_context_create(array("http" => array(
- "method" => "POST",
- "header" => "Content-Type: text/xml",
- "content" => $xmlquery)));
+ /**
+ * Run an XMLRPC command. Name should be a query name and params an array of parameters, eg:
+ * $this->raw("checkAuthentication", ["adam", "qwerty"]);
+ * If successful returns back an array of useful information.
+ *
+ * Note that $params["id"] is reserved for query ID, you may set it to something if you wish.
+ * If you do, the same ID will be passed back with the reply from Anope.
+ *
+ * @param $name
+ * @param $params
+ * @return array|null
+ */
+ public function run($name, $params)
+ {
+ $xmlquery = xmlrpc_encode_request($name, $params);
+ $context = stream_context_create(["http" => [
+ "method" => "POST",
+ "header" => "Content-Type: text/xml",
+ "content" => $xmlquery]]);
- $inbuf = file_get_contents($this->Host, false, $context);
- $response = xmlrpc_decode($inbuf);
+ $inbuf = file_get_contents($this->host, false, $context);
+ $response = xmlrpc_decode($inbuf);
- if (isset($response[0]))
- return $response[0];
- return NULL;
- }
+ if ($response) {
+ return $response;
+ }
- /** Do Command on Service as User, eg:
- * $anope->DoCommand("ChanServ", "Adam", "REGISTER #adam");
- * Returns an array of information regarding the command execution, if
- * If 'online' is set to yes, then the reply to the command was sent to the user on IRC.
- * If 'online' is set to no, then the reply to the command is in the array member 'return'
- */
- function DoCommand($Service, $User, $Command)
- {
- return $this->RunXMLRPC("command", array($Service, $User, $Command));
- }
+ return null;
+ }
- /** Check an account/nick name and password to see if they are valid
- * Returns the account display name if valid
- */
- function CheckAuthentication($Account, $Pass)
- {
- $ret = $this->RunXMLRPC("checkAuthentication", array($Account, $Pass));
+ /**
+ * Do Command on Service as User, eg:
+ * $anope->command("ChanServ", "Adam", "REGISTER #adam");
+ * Returns an array of information regarding the command execution, if
+ * If 'online' is set to yes, then the reply to the command was sent to the user on IRC.
+ * If 'online' is set to no, then the reply to the command is in the array member 'return'
+ *
+ * @param $service
+ * @param $user
+ * @param $command
+ * @return array|null
+ */
+ public function command($service, $user, $command)
+ {
+ return $this->run("command", [$service, $user, $command]);
+ }
- if ($ret && $ret["result"] == "Success")
- return $ret["account"];
- return NULL;
- }
+ /**
+ * Check an account/nick name and password to see if they are valid
+ * Returns the account display name if valid
+ *
+ * @param $account
+ * @param $pass
+ * @return string|null
+ */
+ public function auth($account, $pass)
+ {
+ $ret = $this->run("checkAuthentication", [$account, $pass]);
- /* Returns an array of misc stats regarding Anope
- */
- function DoStats()
- {
- return $this->RunXMLRPC("stats", NULL);
- }
+ if ($ret && $ret["result"] == "Success") {
+ return $ret["account"];
+ }
- /* Look up data for a channel
- * Returns an array containing channel information, or an array of size one
- * (just containing the name) if the channel does not exist
- */
- function DoChannel($Channel)
- {
- return $this->RunXMLRPC("channel", array($Channel));
- }
+ return null;
+ }
- /* Like DoChannel(), but different.
- */
- function DoUser($User)
- {
- return $this->RunXMLRPC("user", array($User));
- }
-}
+ /**
+ * Returns an array of misc stats regarding Anope
+ *
+ * @return array|null
+ */
+ public function stats()
+ {
+ return $this->run("stats", null);
+ }
+
+ /**
+ * Look up data for a channel
+ * Returns an array containing channel information, or an array of size one
+ * (just containing the name) if the channel does not exist
+ *
+ * @param $channel
+ * @return array|null
+ */
+ public function channel($channel)
+ {
+ return $this->run("channel", [$channel]);
+ }
-$anopexmlrpc = new AnopeXMLRPC("http://127.0.0.1:8080/xmlrpc");
+ /**
+ * Like channel(), but different.
+ *
+ * @param $user
+ * @return array|null
+ */
+ public function user($user)
+ {
+ return $this->run("user", [$user]);
+ }
+}
-?>
+$anope = new AnopeXMLRPC("http://127.0.0.1:8080/xmlrpc");
diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt
index 7476edfe7..72bfdfba1 100644
--- a/include/CMakeLists.txt
+++ b/include/CMakeLists.txt
@@ -7,7 +7,7 @@ get_target_property(version_BINARY version LOCATION)
# Modify version.h from the above executable, with dependencies to version.cpp
# and all of the source files in the main build
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/version_build
- COMMAND ${version_BINARY} ${Anope_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/version.h
+ COMMAND ${version_BINARY} ${Anope_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/version.h ${CMAKE_CURRENT_BINARY_DIR}/build.h
DEPENDS version ${SRC_SRCS}
)
# Add version to list of files for CPack to ignore
@@ -15,6 +15,7 @@ get_filename_component(version_BINARY ${version_BINARY} NAME)
add_to_cpack_ignored_files("${version_BINARY}$" TRUE)
if(NOT WIN32)
add_to_cpack_ignored_files("version.h$" TRUE)
+ add_to_cpack_ignored_files("build.h$" TRUE)
endif(NOT WIN32)
# Add a custom target to the above file
diff --git a/include/anope.h b/include/anope.h
index 218e75d47..f6e864300 100644
--- a/include/anope.h
+++ b/include/anope.h
@@ -542,7 +542,7 @@ namespace Anope
extern CoreExport Anope::string Random(size_t len);
}
-/** sepstream allows for splitting token seperated lists.
+/** sepstream allows for splitting token separated lists.
* Each successive call to sepstream::GetToken() returns
* the next token, until none remain, at which point the method returns
* an empty string.
@@ -614,7 +614,7 @@ class CoreExport sepstream
bool StreamEnd();
};
-/** A derived form of sepstream, which seperates on commas
+/** A derived form of sepstream, which separates on commas
*/
class commasepstream : public sepstream
{
@@ -624,7 +624,7 @@ class commasepstream : public sepstream
commasepstream(const Anope::string &source, bool allowempty = false) : sepstream(source, ',', allowempty) { }
};
-/** A derived form of sepstream, which seperates on spaces
+/** A derived form of sepstream, which separates on spaces
*/
class spacesepstream : public sepstream
{
diff --git a/include/channels.h b/include/channels.h
index f2dc9e182..4b814c8bd 100644
--- a/include/channels.h
+++ b/include/channels.h
@@ -31,6 +31,8 @@ struct ChanUserContainer : public Extensible
class CoreExport Channel : public Base, public Extensible
{
+ static std::vector<Channel *> deleting;
+
public:
typedef std::multimap<Anope::string, Anope::string> ModeList;
private:
@@ -258,7 +260,7 @@ class CoreExport Channel : public Base, public Extensible
* @param newtopic The new topic
* @param ts The time the new topic is being set
*/
- void ChangeTopicInternal(const Anope::string &user, const Anope::string &newtopic, time_t ts = Anope::CurTime);
+ void ChangeTopicInternal(User *u, const Anope::string &user, const Anope::string &newtopic, time_t ts = Anope::CurTime);
/** Update the topic of the channel, and reset it if topiclock etc says to
* @param user The user setting the topic
@@ -300,5 +302,7 @@ class CoreExport Channel : public Base, public Extensible
* @param ts The time the channel was created
*/
static Channel *FindOrCreate(const Anope::string &name, bool &created, time_t ts = Anope::CurTime);
+
+ static void DeleteChannels();
};
diff --git a/include/config.h b/include/config.h
index 65a8bf55d..4fe5a94d5 100644
--- a/include/config.h
+++ b/include/config.h
@@ -104,6 +104,8 @@ namespace Configuration
bool UseStrictPrivmsg;
/* flag for options:regexengine */
std::regex::flag_type regex_flags;
+ /* networkinfo:nickchars */
+ Anope::string NickChars;
/* either "/msg " or "/" */
Anope::string StrictPrivmsg;
diff --git a/include/event.h b/include/event.h
index 1cc39a67e..f7934b84a 100644
--- a/include/event.h
+++ b/include/event.h
@@ -358,11 +358,12 @@ namespace Event
struct CoreExport TopicUpdated : Events
{
/** Called when a new topic is set
+ * @param source
* @param c The channel
* @param setter The user who set the new topic
* @param topic The new topic
*/
- virtual void OnTopicUpdated(Channel *c, const Anope::string &user, const Anope::string &topic) anope_abstract;
+ virtual void OnTopicUpdated(User *source, Channel *c, const Anope::string &user, const Anope::string &topic) anope_abstract;
};
extern CoreExport EventHandlers<TopicUpdated> OnTopicUpdated;
diff --git a/include/hashcomp.h b/include/hashcomp.h
index a9a1105ee..43440453c 100644
--- a/include/hashcomp.h
+++ b/include/hashcomp.h
@@ -67,7 +67,7 @@ namespace ci
* @param s1 String to find in
* @param n Position to search up to
* @param c Character to search for
- * @return Pointer to the first occurance of c in s1
+ * @return Pointer to the first occurrence of c in s1
*/
static const char *find(const char *s1, int n, char c);
};
diff --git a/include/modes.h b/include/modes.h
index c010700ca..bc69f77d0 100644
--- a/include/modes.h
+++ b/include/modes.h
@@ -112,6 +112,8 @@ class CoreExport ChannelMode : public Mode
bool CanSet(User *u) const override;
+ virtual void Check() { }
+
/** 'wrap' this channel mode and param to the underlying mode and param
*/
virtual ChannelMode *Wrap(Anope::string &param);
@@ -210,9 +212,11 @@ class CoreExport ChannelModeVirtual : public T
~ChannelModeVirtual();
+ void Check() override;
+
ChannelMode *Wrap(Anope::string &param) override;
- ChannelMode *Unwrap(ChannelMode *cm, Anope::string &param) = 0;
+ ChannelMode *Unwrap(ChannelMode *cm, Anope::string &param) anope_abstract;
};
/* The status a user has on a channel (+v, +h, +o) etc */
diff --git a/include/modules.h b/include/modules.h
index 87051704b..e885a800e 100644
--- a/include/modules.h
+++ b/include/modules.h
@@ -18,13 +18,22 @@
#include "timers.h"
#include "logger.h"
#include "extensible.h"
+#include "version.h"
class ModuleDef;
+struct ModuleVersionC;
+
+enum
+{
+ ANOPE_MODAPI_VER = 1
+};
struct AnopeModule
{
+ unsigned int api_version;
ModuleDef* (*init)();
void (*fini)(ModuleDef *);
+ ModuleVersionC (*version)();
};
class ModuleDef
@@ -70,10 +79,20 @@ template<class ModuleClass> void ModuleInfo(ModuleDef *moddef) { }
{ \
delete def; \
} \
+ static ModuleVersionC ModuleVersion() \
+ { \
+ ModuleVersionC ver; \
+ ver.version_major = VERSION_MAJOR; \
+ ver.version_minor = VERSION_MINOR; \
+ ver.version_patch = VERSION_PATCH; \
+ return ver; \
+ } \
extern "C" DllExport struct AnopeModule AnopeMod = \
{ \
+ ANOPE_MODAPI_VER, \
CreateModuleDef, \
- DeleteModuleDef \
+ DeleteModuleDef, \
+ ModuleVersion \
};
enum ModuleReturn
@@ -113,6 +132,11 @@ enum
};
typedef unsigned short ModType;
+struct ModuleVersionC
+{
+ int version_major, version_minor, version_patch;
+};
+
/** Returned by Module::GetVersion, used to see what version of Anope
* a module is compiled against.
*/
@@ -124,12 +148,7 @@ class ModuleVersion
int version_patch;
public:
- /** Constructor
- * @param major The major version number
- * @param minor The minor version number
- * @param patch The patch version number
- */
- ModuleVersion(int major, int minor, int patch);
+ ModuleVersion(const ModuleVersionC &);
/** Get the major version of Anope this was built against
* @return The major version
diff --git a/include/modules/chanserv.h b/include/modules/chanserv.h
index f0c396d39..35fc3c332 100644
--- a/include/modules/chanserv.h
+++ b/include/modules/chanserv.h
@@ -266,8 +266,8 @@ namespace ChanServ
/** Retrieve the access for a user or group in the form of a vector of access entries
* (as multiple entries can affect a single user).
*/
- virtual AccessGroup AccessFor(const User *u) anope_abstract;
- virtual AccessGroup AccessFor(NickServ::Account *nc) anope_abstract;
+ virtual AccessGroup AccessFor(const User *u, bool updateLastUsed = true) anope_abstract;
+ virtual AccessGroup AccessFor(NickServ::Account *nc, bool updateLastUsed = true) anope_abstract;
/** Get the size of the accss vector for this channel
* @return The access vector size
diff --git a/include/modules/cs_mode.h b/include/modules/cs_mode.h
index 4d5f9dd2f..4c7965e2a 100644
--- a/include/modules/cs_mode.h
+++ b/include/modules/cs_mode.h
@@ -92,7 +92,7 @@ class ModeLocks : public Service
virtual ModeLock *GetMLock(ChanServ::Channel *, const Anope::string &mname, const Anope::string &param = "") anope_abstract;
/** Get the current mode locks as a string
- * @param complete True to show mlock parameters aswell
+ * @param complete True to show mlock parameters as well
* @return A string of mode locks, eg: +nrt
*/
virtual Anope::string GetMLockAsString(ChanServ::Channel *, bool complete) const anope_abstract;
diff --git a/include/modules/ldap.h b/include/modules/ldap.h
index e3897b8cc..51ef842c8 100644
--- a/include/modules/ldap.h
+++ b/include/modules/ldap.h
@@ -1,8 +1,6 @@
#ifndef ANOPE_LDAP_H
#define ANOPE_LDAP_H
-typedef int LDAPQuery;
-
class LDAPException : public ModuleException
{
public:
@@ -59,28 +57,26 @@ struct LDAPAttributes : public std::map<Anope::string, std::vector<Anope::string
}
};
+enum QueryType
+{
+ QUERY_UNKNOWN,
+ QUERY_BIND,
+ QUERY_SEARCH,
+ QUERY_ADD,
+ QUERY_DELETE,
+ QUERY_MODIFY
+};
+
struct LDAPResult
{
std::vector<LDAPAttributes> messages;
Anope::string error;
- enum QueryType
- {
- QUERY_UNKNOWN,
- QUERY_BIND,
- QUERY_SEARCH,
- QUERY_ADD,
- QUERY_DELETE,
- QUERY_MODIFY
- };
-
QueryType type;
- LDAPQuery id;
LDAPResult()
{
this->type = QUERY_UNKNOWN;
- this->id = -1;
}
size_t size() const
@@ -126,48 +122,42 @@ class LDAPProvider : public Service
/** Attempt to bind to the LDAP server as an admin
* @param i The LDAPInterface the result is sent to
- * @return The query ID
*/
- virtual LDAPQuery BindAsAdmin(LDAPInterface *i) anope_abstract;
+ virtual void BindAsAdmin(LDAPInterface *i) anope_abstract;
/** Bind to LDAP
* @param i The LDAPInterface the result is sent to
* @param who The binddn
* @param pass The password
- * @return The query ID
*/
- virtual LDAPQuery Bind(LDAPInterface *i, const Anope::string &who, const Anope::string &pass) anope_abstract;
+ virtual void Bind(LDAPInterface *i, const Anope::string &who, const Anope::string &pass) anope_abstract;
/** Search ldap for the specified filter
* @param i The LDAPInterface the result is sent to
* @param base The base DN to search
* @param filter The filter to apply
- * @return The query ID
*/
- virtual LDAPQuery Search(LDAPInterface *i, const Anope::string &base, const Anope::string &filter) anope_abstract;
+ virtual void Search(LDAPInterface *i, const Anope::string &base, const Anope::string &filter) anope_abstract;
/** Add an entry to LDAP
* @param i The LDAPInterface the result is sent to
* @param dn The dn of the entry to add
* @param attributes The attributes
- * @return The query ID
*/
- virtual LDAPQuery Add(LDAPInterface *i, const Anope::string &dn, LDAPMods &attributes) anope_abstract;
+ virtual void Add(LDAPInterface *i, const Anope::string &dn, LDAPMods &attributes) anope_abstract;
/** Delete an entry from LDAP
* @param i The LDAPInterface the result is sent to
* @param dn The dn of the entry to delete
- * @return The query ID
*/
- virtual LDAPQuery Del(LDAPInterface *i, const Anope::string &dn) anope_abstract;
+ virtual void Del(LDAPInterface *i, const Anope::string &dn) anope_abstract;
/** Modify an existing entry in LDAP
* @param i The LDAPInterface the result is sent to
* @param base The base DN to modify
* @param attributes The attributes to modify
- * @return The query ID
*/
- virtual LDAPQuery Modify(LDAPInterface *i, const Anope::string &base, LDAPMods &attributes) anope_abstract;
+ virtual void Modify(LDAPInterface *i, const Anope::string &base, LDAPMods &attributes) anope_abstract;
};
#endif // ANOPE_LDAP_H
diff --git a/include/sockets.h b/include/sockets.h
index a0e310885..49e9d1fcd 100644
--- a/include/sockets.h
+++ b/include/sockets.h
@@ -371,7 +371,7 @@ class CoreExport ListenSocket : public virtual Socket
virtual ~ListenSocket();
/** Process what has come in from the connection
- * @return false to destory this socket
+ * @return false to destroy this socket
*/
bool ProcessRead();
diff --git a/include/users.h b/include/users.h
index 2942c91a8..656ab667c 100644
--- a/include/users.h
+++ b/include/users.h
@@ -49,7 +49,7 @@ class CoreExport User : public virtual Base, public virtual Extensible, public C
Anope::string vident;
Anope::string ident;
Anope::string uid;
- /* If the user is on the access list of the nick theyre on */
+ /* If the user is on the access list of the nick they're on */
bool on_access;
/* Map of user modes and the params this user has (if any) */
ModeList modes;
@@ -110,7 +110,7 @@ class CoreExport User : public virtual Base, public virtual Extensible, public C
* @param svhost The vhost of the user
* @param sip The ip of the user
* @param sserver The server of the user
- * @param srealname The realname/gecos of teh user
+ * @param srealname The realname/gecos of the user
* @param ts User's timestamp
* @param smodes User's modes
* @param suid The unique identifier of the user.
diff --git a/include/version.cpp b/include/version.cpp
index 5432188fe..c688c07e8 100644
--- a/include/version.cpp
+++ b/include/version.cpp
@@ -13,7 +13,7 @@
#include <iostream>
#include <fstream>
#include <sstream>
-#include <list>
+#include <map>
static std::string get_git_hash(const std::string &git_dir)
{
@@ -45,29 +45,16 @@ static std::string get_git_hash(const std::string &git_dir)
return "g" + filebuf.substr(0, 7);
}
-int main(int argc, char *argv[])
+static bool read_version_sh(const std::string &version_sh, std::map<std::string, std::string> &versions)
{
- if (argc < 3)
- {
- std::cerr << "Syntax: " << argv[0] << " <base> <version.h>" << std::endl;
- return 1;
- }
-
- std::string version_sh = std::string(argv[1]) + "/src/version.sh";
- std::string git_dir = std::string(argv[1]) + "/.git";
-
- std::fstream fd;
-
- fd.clear();
- fd.open(version_sh.c_str(), std::ios::in);
+ std::fstream fd(version_sh.c_str(), std::ios::in);
if (!fd.is_open())
{
std::cerr << "Error: Unable to open src/version.sh for reading: " << version_sh << std::endl;
- return 1;
+ return false;
}
std::string filebuf;
- std::list<std::pair<std::string, std::string> > versions;
while (getline(fd, filebuf))
{
if (!filebuf.find("VERSION_"))
@@ -75,24 +62,25 @@ int main(int argc, char *argv[])
size_t eq = filebuf.find('=');
std::string type = filebuf.substr(0, eq);
- std::string value = filebuf.substr(eq + 2, filebuf.length() - eq - 3);
- versions.push_back(std::make_pair(type, value));
+ std::string value = filebuf.substr(eq + 1);
+
+ versions[type] = value;
}
}
fd.close();
- std::string git_version = get_git_hash(git_dir);
- if (!git_version.empty())
- versions.push_back(std::make_pair("VERSION_GIT", git_version));
+ return true;
+}
- fd.clear();
- fd.open(argv[2], std::ios::in);
+static bool write_build_h(const std::string &buildh, const std::string &git_version)
+{
+ std::fstream fd(buildh.c_str(), std::ios::in);
std::string build = "#define BUILD 1";
if (fd.is_open())
{
- while (getline(fd, filebuf))
+ for (std::string filebuf; getline(fd, filebuf);)
{
if (!filebuf.find("#define BUILD"))
{
@@ -110,27 +98,91 @@ int main(int argc, char *argv[])
}
fd.clear();
- fd.open(argv[2], std::ios::out);
-
+ fd.open(buildh.c_str(), std::ios::out);
if (!fd.is_open())
{
- std::cerr << "Error: Unable to include/version.h for writing: " << argv[2] << std::endl;
- return 1;
+ std::cerr << "Error: Unable to open build.h for writing: " << buildh << std::endl;
+ return false;
}
fd << "/* This file is automatically generated by version.cpp - do not edit it! */" << std::endl;
+ fd << build << std::endl;
+ if (!git_version.empty())
+ fd << "#define VERSION_GIT \"" << git_version << "\"" << std::endl;
+ fd.close();
- for (std::list<std::pair<std::string, std::string> >::iterator it = versions.begin(), it_end = versions.end(); it != it_end; ++it)
+ return true;
+}
+
+static void read_version_h(const std::string &versionh, std::map<std::string, std::string> &versions)
+{
+ std::fstream fd(versionh.c_str(), std::ios::in);
+
+ if (!fd.is_open())
+ return;
+
+ for (std::string filebuf; getline(fd, filebuf);)
{
- if (it->first == "VERSION_EXTRA" || it->first == "VERSION_GIT")
- fd << "#define " << it->first << " \"" << it->second << "\"" << std::endl;
- else
- fd << "#define " << it->first << " " << it->second << std::endl;
+ if (!filebuf.find("#define VERSION_"))
+ {
+ size_t space = filebuf.substr(8).find(' ');
+
+ std::string name = filebuf.substr(8).substr(0, space),
+ version = filebuf.substr(8).substr(space + 1);
+
+ versions[name] = version;
+ }
}
- fd << build << std::endl;
+ fd.close();
+}
+
+static bool write_version_h(const std::string &versionh, const std::map<std::string, std::string> &versions)
+{
+ std::fstream fd(versionh.c_str(), std::ios::out);
+
+ if (!fd.is_open())
+ return false;
+
+ for (std::map<std::string, std::string>::const_iterator it = versions.begin(); it != versions.end(); ++it)
+ {
+ fd << "#define " << it->first << " " << it->second << std::endl;
+ }
fd.close();
+ return true;
+}
+
+int main(int argc, char *argv[])
+{
+ if (argc < 4)
+ {
+ std::cerr << "Syntax: " << argv[0] << " <base> <version.h> <build.h>" << std::endl;
+ return 1;
+ }
+
+ std::string version_sh = std::string(argv[1]) + "/src/version.sh";
+ std::string git_dir = std::string(argv[1]) + "/.git";
+ std::string versionh = argv[2];
+ std::string buildh = argv[3];
+
+ std::map<std::string, std::string> versions, old_versions;
+
+ if (!read_version_sh(version_sh, versions))
+ return -1;
+
+ std::string git_version = get_git_hash(git_dir);
+ if (!write_build_h(buildh, git_version))
+ return -1;
+
+ read_version_h(versionh, old_versions);
+
+ if (versions == old_versions)
+ return 0;
+
+ if (!write_version_h(versionh, versions))
+ return -1;
+
return 0;
}
diff --git a/language/anope.de_DE.po b/language/anope.de_DE.po
index c57d4b698..af6a0102c 100644
--- a/language/anope.de_DE.po
+++ b/language/anope.de_DE.po
@@ -6389,7 +6389,7 @@ msgstr "%s ist ein services operator vom Typ %s."
#: modules/commands/ns_info.cpp:34
#, c-format
msgid "Nick %s is part of this Network's Services."
-msgstr "Der Nickname %s ist ein teil der Network Services."
+msgstr "Der Nickname %s ist ein Teil der Netzwerkdienste."
#: include/language.h:80
#, fuzzy, c-format
diff --git a/language/anope.fr_FR.po b/language/anope.fr_FR.po
index d48a2221c..4059d8790 100644
--- a/language/anope.fr_FR.po
+++ b/language/anope.fr_FR.po
@@ -6922,7 +6922,7 @@ msgstr "Lit un ou plusieurs mémos"
#: modules/commands/bs_info.cpp:57
msgid "Real name"
-msgstr "Vrai nom : %s"
+msgstr "Vrai nom"
#: modules/commands/os_session.cpp:552 modules/commands/os_ignore.cpp:266
#: modules/commands/cs_akick.cpp:367 modules/commands/cs_akick.cpp:380
diff --git a/language/anope.nl_NL.po b/language/anope.nl_NL.po
index 1d560b297..d000bf320 100644
--- a/language/anope.nl_NL.po
+++ b/language/anope.nl_NL.po
@@ -1,15 +1,15 @@
# Anope IRC Services language file
-# Copyright (C) 2013-2014
+# Copyright (C) 2013-2015
# This file is distributed under the same license as the Anope IRC Services package.
-# Robby <robby@chat.be>, 2013-2014.
+# Robby <robby@chatbelgie.be>, 2013-2015.
#
msgid ""
msgstr ""
"Project-Id-Version: Anope\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2014-12-07 17:23+0100\n"
-"PO-Revision-Date: 2014-12-07 17:36+0100\n"
-"Last-Translator: Robby <robby@chat.be>\n"
+"POT-Creation-Date: 2015-09-18 05:40+0200\n"
+"PO-Revision-Date: 2015-09-18 05:56+0200\n"
+"Last-Translator: Robby <robby@chatbelgie.be>\n"
"Language-Team: Dutch\n"
"Language: nl_NL\n"
"MIME-Version: 1.0\n"
@@ -111,7 +111,7 @@ msgstr ""
"%s%s commando. Voor meer informatie over een\n"
"specifiek commando, typ %s%s %s commando.\n"
-#: modules/pseudoclients/nickserv.cpp:461
+#: modules/pseudoclients/nickserv.cpp:466
#, c-format
msgid ""
"%s allows you to register a nickname and\n"
@@ -128,7 +128,7 @@ msgstr ""
"Voor meer informatie over een specifiek commando, typ\n"
"%s%s %s commando.\n"
-#: modules/pseudoclients/nickserv.cpp:468
+#: modules/pseudoclients/nickserv.cpp:473
#, c-format
msgid ""
"%s allows you to register an account.\n"
@@ -183,7 +183,7 @@ msgstr "%s bestaat al op de uitzonderingenlijst."
msgid "%s cannot be taken as times to ban."
msgstr "%s kan niet worden ingesteld als aantal keer om dan te bannen."
-#: modules/commands/os_mode.cpp:157
+#: modules/commands/os_mode.cpp:163
#, c-format
msgid "%s changed your usermodes to %s."
msgstr "%s heeft je gebruikersmodes veranderd naar %s."
@@ -338,7 +338,7 @@ msgstr "%s is geen geldige bot of geregistreerd kanaal."
#: include/language.h:87
#, c-format
msgid "%s is not a valid e-mail address."
-msgstr "%s is geen geldig e-mail adres."
+msgstr "%s is geen geldig e-mailadres."
#: include/language.h:81
#, c-format
@@ -478,19 +478,19 @@ msgstr "%s zal nu permanent genegeerd worden."
msgid "%s%s HELP %s for more information."
msgstr "%s%s HELP %s voor meer informatie."
-#: modules/commands/bs_bot.cpp:254
+#: modules/commands/bs_bot.cpp:270
msgid "ADD nick user host real"
msgstr "ADD nick ident host naam"
-#: modules/commands/bs_bot.cpp:255
+#: modules/commands/bs_bot.cpp:271
msgid "CHANGE oldnick newnick [user [host [real]]]"
msgstr "CHANGE oudenick nieuwenick [ident [host [naam]]]"
-#: modules/commands/bs_bot.cpp:256
+#: modules/commands/bs_bot.cpp:272
msgid "DEL nick"
msgstr "DEL nick"
-#: modules/commands/os_session.cpp:601
+#: modules/commands/os_session.cpp:560
msgid ""
"EXCEPTION ADD adds the given host mask to the exception list.\n"
"Note that nick!user@host and user@host masks are invalid!\n"
@@ -504,9 +504,6 @@ msgid ""
" \n"
"EXCEPTION DEL removes the given mask from the exception list.\n"
" \n"
-"EXCEPTION MOVE moves exception num to position. The\n"
-"sessions inbetween will be shifted up or down to fill the gap.\n"
-" \n"
"EXCEPTION LIST and EXCEPTION VIEW show all current\n"
"sessions if the optional mask is given, the list is limited\n"
"to those sessions matching the mask. The difference is that\n"
@@ -531,10 +528,6 @@ msgstr ""
"EXCEPTION DEL verwijdert het gegeven masker van de\n"
"uitzonderingenlijst.\n"
" \n"
-"EXCEPTION MOVE verplaatst uitzondering nr naar positie.\n"
-"De tussenliggende uitzonderingen worden omhoog of omlaag\n"
-"geschoven om het gat op te vullen.\n"
-" \n"
"EXCEPTION LIST en EXCEPTION VIEW geven alle huidige\n"
"uitzonderingen weer; als het optionele masker is gegeven wordt de\n"
"lijst gelimiteerd tot uitzonderingen overeenkomend met het\n"
@@ -578,7 +571,7 @@ msgstr "[auto-memo] De memo die je naar %s gestuurd hebt is bekeken."
msgid "[target] [password]"
msgstr "[doel] [wachtwoord]"
-#: modules/commands/ns_set.cpp:435
+#: modules/commands/ns_set.cpp:442
msgid "address"
msgstr "adres"
@@ -623,7 +616,7 @@ msgstr "kanaal nick"
msgid "channel nick [reason]"
msgstr "kanaal nick [reden]"
-#: modules/commands/cs_clone.cpp:21
+#: modules/commands/cs_clone.cpp:115
msgid "channel target [what]"
msgstr "kanaal doel [wat]"
@@ -673,7 +666,7 @@ msgstr "kanaal APPEND topic"
msgid "channel CLEAR"
msgstr "kanaal CLEAR"
-#: modules/commands/cs_mode.cpp:678
+#: modules/commands/cs_mode.cpp:679
msgid "channel CLEAR [what]"
msgstr "kanaal CLEAR [wat]"
@@ -718,7 +711,7 @@ msgstr "kanaal LIST [masker | lijst]"
msgid "channel LIST [mask | +flags]"
msgstr "kanaal LIST [masker | +vlaggen]"
-#: modules/commands/cs_mode.cpp:676
+#: modules/commands/cs_mode.cpp:677
msgid "channel LOCK {ADD|DEL|SET|LIST} [what]"
msgstr "kanaal LOCK {ADD|DEL|SET|LIST} [wat]"
@@ -726,7 +719,7 @@ msgstr "kanaal LOCK {ADD|DEL|SET|LIST} [wat]"
msgid "channel RESET"
msgstr "kanaal RESET"
-#: modules/commands/cs_mode.cpp:677
+#: modules/commands/cs_mode.cpp:678
msgid "channel SET modes"
msgstr "kanaal SET modes"
@@ -754,7 +747,7 @@ msgstr "kanaal [nick]"
msgid "channel [parameters]"
msgstr "kanaal [parameters]"
-#: modules/commands/cs_mode.cpp:749 modules/commands/cs_status.cpp:20
+#: modules/commands/cs_mode.cpp:750 modules/commands/cs_status.cpp:20
msgid "channel [user]"
msgstr "kanaal [nick]"
@@ -824,7 +817,7 @@ msgstr "kanaal {ON | OFF}"
msgid "email"
msgstr "e-mail"
-#: modules/commands/ns_set.cpp:773
+#: modules/commands/ns_set.cpp:780
msgid "language"
msgstr "taal"
@@ -841,7 +834,7 @@ msgstr "bericht"
msgid "modname"
msgstr "modnaam"
-#: modules/commands/ns_set.cpp:322
+#: modules/commands/ns_set.cpp:327
msgid "new-display"
msgstr "nieuwe-weergave"
@@ -884,7 +877,7 @@ msgstr "nick [reden]"
msgid "nickname"
msgstr "nick"
-#: modules/commands/ns_set.cpp:525
+#: modules/commands/ns_set.cpp:532
msgid "nickname address"
msgstr "nickname adres"
@@ -892,7 +885,7 @@ msgstr "nickname adres"
msgid "nickname email"
msgstr "nick e-mail"
-#: modules/commands/ns_set.cpp:848
+#: modules/commands/ns_set.cpp:855
msgid "nickname language"
msgstr "nickname taal"
@@ -900,11 +893,11 @@ msgstr "nickname taal"
msgid "nickname message"
msgstr "nickname bericht"
-#: modules/commands/ns_set.cpp:385
+#: modules/commands/ns_set.cpp:390
msgid "nickname new-display"
msgstr "nickname nieuwe-weergave"
-#: modules/commands/ns_set.cpp:168
+#: modules/commands/ns_set.cpp:170
msgid "nickname new-password"
msgstr "nickname nieuw-wachtwoord"
@@ -924,14 +917,14 @@ msgstr "nick [+verlooptijd] [reden]"
msgid "nickname {EMAIL | STATUS | USERMASK | QUIT} {ON | OFF}"
msgstr "nick {EMAIL | STATUS | USERMASK | QUIT} {ON | OFF}"
-#: modules/extra/stats/m_chanstats.cpp:122 modules/commands/ns_set.cpp:294
-#: modules/commands/ns_set.cpp:610 modules/commands/ns_set.cpp:961
-#: modules/commands/ns_set.cpp:1052 modules/commands/ns_set.cpp:1081
+#: modules/extra/stats/m_chanstats.cpp:122 modules/commands/ns_set.cpp:299
+#: modules/commands/ns_set.cpp:617 modules/commands/ns_set.cpp:968
+#: modules/commands/ns_set.cpp:1059 modules/commands/ns_set.cpp:1088
#: modules/commands/ns_list.cpp:252
msgid "nickname {ON | OFF}"
msgstr "nickname {ON | OFF}"
-#: modules/commands/ns_set.cpp:739
+#: modules/commands/ns_set.cpp:746
msgid "nickname {ON | QUICK | IMMED | OFF}"
msgstr "nickname {ON | QUICK | IMMED | OFF}"
@@ -987,7 +980,7 @@ msgstr "patroon [SUSPENDED] [NOEXPIRE] [UNCONFIRMED]"
msgid "server [reason]"
msgstr "server [reden]"
-#: modules/commands/os_mode.cpp:141
+#: modules/commands/os_mode.cpp:147
msgid "user modes"
msgstr "nick modes"
@@ -995,7 +988,7 @@ msgstr "nick modes"
msgid "user [reason]"
msgstr "nick [reden]"
-#: modules/pseudoclients/nickserv.cpp:491
+#: modules/pseudoclients/nickserv.cpp:496
#, c-format
msgid ""
" \n"
@@ -1047,7 +1040,7 @@ msgstr ""
"Let op: omdat het naam masker spaties mag bevatten, is de scheiding\n"
"tussen het masker en de reden een dubbele punt (:)."
-#: modules/commands/os_sxline.cpp:668
+#: modules/commands/os_sxline.cpp:670
msgid ""
" \n"
"SQLINE ADD adds the given (nick's) mask to the SQLINE\n"
@@ -1075,7 +1068,7 @@ msgstr ""
"standaard verlooptijd kan gevonden worden met het\n"
"STATS AKILL commando."
-#: modules/pseudoclients/nickserv.cpp:487
+#: modules/pseudoclients/nickserv.cpp:492
#, c-format
msgid ""
" \n"
@@ -1216,7 +1209,7 @@ msgstr ""
"informatie over het geven van privileges aan andere kanaal-\n"
"gebruikers.\n"
-#: modules/pseudoclients/nickserv.cpp:481
+#: modules/pseudoclients/nickserv.cpp:486
msgid ""
" \n"
"Services Operators can also drop any nickname without needing\n"
@@ -1420,7 +1413,7 @@ msgstr ""
" \n"
"SNLINE CLEAR verwijdert alle vermeldingen van de SNLINE lijst."
-#: modules/commands/os_sxline.cpp:687
+#: modules/commands/os_sxline.cpp:689
msgid ""
" \n"
"The SQLINE DEL command removes the given mask from the\n"
@@ -1525,7 +1518,7 @@ msgstr " Geladen op: %p"
msgid " but %s mysteriously dematerialized."
msgstr " maar %s is in rook opgegaan."
-#: src/messages.cpp:335
+#: src/messages.cpp:340
#, c-format
msgid ""
"\"/msg %s\" is no longer supported. Use \"/msg %s@%s\" or \"/%s\" instead."
@@ -1556,17 +1549,17 @@ msgstr "%b %d %H:%M:%S %Y %Z"
msgid "%c is an unknown status mode."
msgstr "%c is een onbekende status mode."
-#: modules/commands/cs_mode.cpp:415
+#: modules/commands/cs_mode.cpp:416
#, c-format
msgid "%c%c is not locked on %s."
msgstr "%c%c is niet vergrendeld op %s."
-#: modules/commands/cs_mode.cpp:411
+#: modules/commands/cs_mode.cpp:412
#, c-format
msgid "%c%c%s has been unlocked from %s."
msgstr "%c%c%s werd ontgrendeld op %s."
-#: modules/commands/cs_clone.cpp:140
+#: modules/commands/cs_clone.cpp:56
#, c-format
msgid "%d access entries from %s have been cloned to %s."
msgstr "%d toegangsvermeldingen van %s zijn gekopiëerd naar %s."
@@ -1728,7 +1721,7 @@ msgstr ""
"%s kan de opvolger niet zijn op kanaal %s omdat hij/zij de stichter is."
#: modules/pseudoclients/global.cpp:90 modules/pseudoclients/hostserv.cpp:78
-#: modules/pseudoclients/operserv.cpp:272
+#: modules/pseudoclients/operserv.cpp:279
#, c-format
msgid "%s commands:"
msgstr "%s commando's:"
@@ -1926,7 +1919,7 @@ msgstr "%s lijst voor %s"
msgid "%s list is empty."
msgstr "%s lijst is leeg."
-#: modules/commands/cs_mode.cpp:360
+#: modules/commands/cs_mode.cpp:361
#, c-format
msgid "%s locked on %s."
msgstr "%s vergrendeld op %s."
@@ -1982,7 +1975,7 @@ msgid "%s will now notify you of memos when you log on or unset /AWAY."
msgstr ""
"%s zal je nu informeren over memo's wanneer je inlogt of /AWAY uitschakelt."
-#: modules/commands/bs_bot.cpp:82
+#: modules/commands/bs_bot.cpp:89
#, c-format
msgid "%s!%s@%s (%s) added to the bot list."
msgstr "%s!%s@%s (%s) toegevoegd aan de botlijst."
@@ -2104,7 +2097,7 @@ msgstr "%s is nog steeds online."
msgid "<unknown>"
msgstr "<onbekend>"
-#: modules/commands/ns_set.cpp:484
+#: modules/commands/ns_set.cpp:491
#, c-format
msgid ""
"A confirmation e-mail has been sent to %s. Follow the instructions in it to "
@@ -2162,7 +2155,7 @@ msgstr "ADD doel info"
msgid "ADD text"
msgstr "ADD tekst"
-#: modules/commands/os_session.cpp:561
+#: modules/commands/os_session.cpp:523
msgid "ADD [+expiry] mask limit reason"
msgstr "ADD [+verlooptijd] masker limiet reden"
@@ -2267,6 +2260,14 @@ msgstr ""
"Toegang tot dit commando vereist dat het %s recht in jouw opertype aanwezig "
"is."
+#: modules/commands/ns_identify.cpp:94
+#, c-format
+msgid ""
+"Account %s has already reached the maximum number of simultaneous logins "
+"(%u)."
+msgstr ""
+"Account %s heeft reeds het maximum aantal gelijktijdige logins bereikt (%u)."
+
#: modules/commands/cs_set.cpp:694
msgid "Activate security features"
msgstr "Activeer veiligheidsopties"
@@ -2339,6 +2340,15 @@ msgstr "Server %s toegevoegd."
msgid "Added zone %s."
msgstr "Domein %s toegevoegd."
+#: modules/commands/cs_entrymsg.cpp:257
+msgid ""
+"Adding, deleting, or clearing entry messages requires the\n"
+"SET permission."
+msgstr ""
+"Toevoegen, verwijderen, of leegmaken van de welkomstberichtenlijst vereist "
+"het\n"
+"SET recht."
+
#: modules/commands/ns_register.cpp:90
msgid ""
"Additionally, Services Operators with the nickserv/confirm permission can\n"
@@ -2363,7 +2373,7 @@ msgstr ""
msgid "All O:lines of %s have been reset."
msgstr "Alle O:lines van %s zijn hersteld."
-#: modules/commands/cs_clone.cpp:154
+#: modules/commands/cs_clone.cpp:71
#, c-format
msgid "All akick entries from %s have been cloned to %s."
msgstr "Alle autokicks van %s zijn gekopiëerd naar %s."
@@ -2373,11 +2383,16 @@ msgstr "Alle autokicks van %s zijn gekopiëerd naar %s."
msgid "All available commands for %s:"
msgstr "Alle beschikbare commando's voor %s:"
-#: modules/commands/cs_clone.cpp:178
+#: modules/commands/cs_clone.cpp:96
#, c-format
msgid "All badword entries from %s have been cloned to %s."
msgstr "Alle slechte woorden van %s zijn gekopiëerd naar %s."
+#: modules/commands/cs_clone.cpp:108
+#, c-format
+msgid "All level entries from %s have been cloned into %s."
+msgstr "Alle toegangsniveaus van %s zijn gekopiëerd naar %s."
+
#: modules/commands/os_news.cpp:38
msgid "All logon news items deleted."
msgstr "Alle login nieuwsberichten zijn verwijderd."
@@ -2387,12 +2402,12 @@ msgstr "Alle login nieuwsberichten zijn verwijderd."
msgid "All memos for channel %s have been deleted."
msgstr "Alle memo's voor kanaal %s zijn verwijderd."
-#: modules/commands/os_mode.cpp:55
+#: modules/commands/os_mode.cpp:61
#, c-format
msgid "All modes cleared on %s."
msgstr "Alle modes verwijderd op %s."
-#: modules/commands/ns_register.cpp:360
+#: modules/commands/ns_register.cpp:368
msgid ""
"All new accounts must be validated by an administrator. Please wait for your "
"registration to be confirmed."
@@ -2417,7 +2432,7 @@ msgstr "Alle operators van %s zijn verwijderd."
msgid "All random news items deleted."
msgstr "Alle willekeurige nieuwsberichten zijn verwijderd."
-#: modules/commands/cs_clone.cpp:105
+#: modules/commands/cs_clone.cpp:210
#, c-format
msgid "All settings from %s have been cloned to %s."
msgstr "Alle instellingen van %s zijn gekopiëerd naar %s."
@@ -2559,7 +2574,7 @@ msgstr ""
"naar alle gebruikers op het netwerk. Berichten zullen\n"
"verstuurd worden vanaf de nick %s."
-#: modules/commands/os_mode.cpp:127
+#: modules/commands/os_mode.cpp:133
msgid ""
"Allows Services Operators to change modes for any channel.\n"
"Parameters are the same as for the standard /MODE command.\n"
@@ -2573,7 +2588,7 @@ msgstr ""
"dan zullen alle modes, inclusief gebruikersstatus modes, weggehaald\n"
"worden."
-#: modules/commands/os_mode.cpp:167
+#: modules/commands/os_mode.cpp:173
msgid ""
"Allows Services Operators to change modes for any user.\n"
"Parameters are the same as for the standard /MODE command."
@@ -2582,7 +2597,7 @@ msgstr ""
"iemand aan te passen. De parameters zijn dezelfde als bij\n"
"het standaard /MODE commando."
-#: modules/commands/bs_bot.cpp:336
+#: modules/commands/bs_bot.cpp:352
msgid ""
"Allows Services Operators to create, modify, and delete\n"
"bots that users will be able to use on their own\n"
@@ -2725,7 +2740,9 @@ msgid ""
"connect, Services will not allow it to pursue his IRC\n"
"session.\n"
"If the first character of the mask is #, services will\n"
-"prevent the use of matching channels."
+"prevent the use of matching channels. If the mask is a\n"
+"regular expression, the expression will be matched against\n"
+"channels too."
msgstr ""
"Stelt Services Operators in staat de SQLINE lijst te beheren.\n"
"Als een gebruiker probeert te verbinden met een nick die\n"
@@ -2733,9 +2750,10 @@ msgstr ""
"die gebruiker verwijderen.\n"
"Indien de eerste karakter van een masker begint met een #,\n"
"dan zal Services het gebruik van overeenkomende kanalen\n"
-"verbieden."
+"verbieden. Als het masker een reguliere expressie is, dan zal\n"
+"deze expressie ook op kanalen van toepassing zijn."
-#: modules/commands/os_session.cpp:592
+#: modules/commands/os_session.cpp:551
msgid ""
"Allows Services Operators to manipulate the list of hosts that\n"
"have specific session limits - allowing certain machines,\n"
@@ -2794,19 +2812,20 @@ msgid ""
"the given topic to the existing topic.\n"
" \n"
"LOCK and UNLOCK may be used to enable and disable topic lock. When\n"
-"topic lock is set, the channel topic will be unchangeable except via this "
-"command."
+"topic lock is set, the channel topic will be unchangeable by users who do "
+"not have\n"
+"the TOPIC privilege."
msgstr ""
"Maakt het mogelijk de topic van een kanaal aan te passen en te beheren.\n"
"Het SET commando verandert de topic van het kanaal naar het opgegeven\n"
-"topic, of maakt deze leeg indien geen topic is opgegeven.\n"
+"topic, of verwijdert deze indien geen topic is opgegeven.\n"
"Het APPEND commando voegt de gegeven topic toe aan de reeds bestaande\n"
"topic.\n"
" \n"
"LOCK en UNLOCK kunnen gebruikt worden om de topic te vergrendelen\n"
-"of ontgrendelen, wanneer de topic vergrendeld is kan de topic niet "
+"of ontgrendelen. Wanneer de topic vergrendeld is kan de topic niet "
"gewijzigd\n"
-"worden, behalve via dit commando."
+"worden door gebruikers die niet beschikken over het TOPIC privilege."
#: modules/commands/os_kick.cpp:62
#, c-format
@@ -2868,7 +2887,7 @@ msgstr ""
"Voorbeeld:\n"
" MODIFY nickserv forcemail no"
-#: modules/commands/ns_set.cpp:968
+#: modules/commands/ns_set.cpp:975
msgid ""
"Allows you to choose the way Services are communicating with\n"
"the given user. With MSG set, Services will use messages,\n"
@@ -2878,7 +2897,7 @@ msgstr ""
"gebruiker stuurt. Als MSG ingesteld is zal Services privé-\n"
"berichten gebruiken, anders zullen ze notice's gebruiken."
-#: modules/commands/ns_set.cpp:942
+#: modules/commands/ns_set.cpp:949
#, c-format
msgid ""
"Allows you to choose the way Services are communicating with\n"
@@ -2925,7 +2944,7 @@ msgid ""
msgstr ""
"Stelt je in staat te voorkomen dat bepaalde informatie getoont wordt\n"
"wanneer iemand een %s INFO doet op de nick. Je kan\n"
-"het e-mail adres (EMAIL), laatst geziene ident@host (USERMASK),\n"
+"het e-mailadres (EMAIL), laatst geziene ident@host (USERMASK),\n"
"de Services toegangsniveau (STATUS) en het laatste quit\n"
"bericht (QUIT) verbergen. De tweede parameter geeft aan of\n"
"de informatie moet getoont (OFF) of verborgen (ON) worden."
@@ -2943,7 +2962,7 @@ msgid ""
msgstr ""
"Stelt je in staat te voorkomen dat bepaalde informatie getoont wordt\n"
"wanneer iemand een %s INFO doet op je nick. Je kan\n"
-"het e-mail adres (EMAIL), laatst geziene ident@host (USERMASK),\n"
+"het e-mailadres (EMAIL), laatst geziene ident@host (USERMASK),\n"
"je Services toegangsniveau (STATUS) en het laatste quit\n"
"bericht (QUIT) verbergen. De tweede parameter geeft aan of\n"
"de informatie moet getoont (OFF) of verborgen (ON) worden."
@@ -2998,15 +3017,15 @@ msgstr ""
"Hierna kun je de bot voor het kanaal instellen zoals je\n"
"wil."
-#: data/chanserv.example.conf:1193
+#: data/chanserv.example.conf:1200
msgid "Associate a URL with the channel"
msgstr "Koppel een URL aan het kanaal"
-#: data/nickserv.example.conf:584
+#: data/nickserv.example.conf:592
msgid "Associate a URL with this account"
msgstr "Koppel een URL aan dit account"
-#: data/nickserv.example.conf:583
+#: data/nickserv.example.conf:591
msgid "Associate a URL with your account"
msgstr "Koppel een URL aan jouw account"
@@ -3014,33 +3033,33 @@ msgstr "Koppel een URL aan jouw account"
msgid "Associate a greet message with your nickname"
msgstr "Koppel een begroeting aan je nick"
-#: data/chanserv.example.conf:1194
+#: data/chanserv.example.conf:1201
msgid "Associate an E-mail address with the channel"
-msgstr "Koppel een e-mail adres aan het kanaal"
+msgstr "Koppel een e-mailadres aan het kanaal"
-#: modules/commands/ns_set.cpp:434
+#: modules/commands/ns_set.cpp:441
msgid "Associate an E-mail address with your nickname"
-msgstr "Koppel een e-mail adres aan jouw nick"
+msgstr "Koppel een e-mailadres aan jouw nick"
#: modules/commands/os_info.cpp:101
msgid "Associate oper info with a nick or channel"
msgstr "Koppel oper informatie aan een nick of kanaal"
-#: modules/commands/ns_set.cpp:537
+#: modules/commands/ns_set.cpp:544
msgid "Associates the given E-mail address with the nickname."
-msgstr "Koppel het opgegeven e-mail adres aan de nick"
+msgstr "Koppel het opgegeven e-mailadres aan de nick"
-#: modules/commands/ns_set.cpp:512
+#: modules/commands/ns_set.cpp:519
msgid ""
"Associates the given E-mail address with your nickname.\n"
"This address will be displayed whenever someone requests\n"
"information on the nickname with the INFO command."
msgstr ""
-"Koppel het opgegeven e-mail adres aan jouw nick. Dit adres\n"
+"Koppel het opgegeven e-mailadres aan jouw nick. Dit adres\n"
"zal worden weergegeven wanneer iemand informatie over je\n"
"nick opvraagt met het INFO commando."
-#: modules/commands/ns_set.cpp:1290
+#: modules/commands/ns_set.cpp:1297
msgid "Auto-op"
msgstr "Auto-op"
@@ -3105,7 +3124,7 @@ msgstr "Slechtewoordenlijst is nu leeg."
msgid "Ban expiry may not be longer than 1 day."
msgstr "Ban verlooptijd mag niet langer dan 1 dag zijn."
-#: modules/commands/cs_ban.cpp:138 modules/commands/cs_ban.cpp:167
+#: modules/commands/cs_ban.cpp:141 modules/commands/cs_ban.cpp:176
#, c-format
msgid "Ban on %s expires in %s."
msgstr "Ban op %s verloopt over %s."
@@ -3123,7 +3142,7 @@ msgstr "Ban type voor kanaal %s is nu #%d."
msgid "Bans a given nick or mask on a channel"
msgstr "Ban een opgegeven nick of masker op een kanaal"
-#: modules/commands/cs_ban.cpp:214
+#: modules/commands/cs_ban.cpp:228
msgid ""
"Bans a given nick or mask on a channel. An optional expiry may\n"
"be given to cause services to remove the ban after a set amount\n"
@@ -3150,7 +3169,7 @@ msgstr "Bans afgedwongen op %s."
msgid "Bolds kicker"
msgstr "Vetkicker"
-#: modules/commands/bs_bot.cpp:26 modules/commands/bs_bot.cpp:166
+#: modules/commands/bs_bot.cpp:26 modules/commands/bs_bot.cpp:175
#, c-format
msgid "Bot %s already exists."
msgstr "Bot %s bestaat al."
@@ -3165,12 +3184,12 @@ msgstr "Bot %s bestaat niet."
msgid "Bot %s has been assigned to %s."
msgstr "Bot %s toegewezen aan %s."
-#: modules/commands/bs_bot.cpp:212
+#: modules/commands/bs_bot.cpp:228
#, c-format
msgid "Bot %s has been changed to %s!%s@%s (%s)."
msgstr "Bot %s is veranderd in %s!%s@%s (%s)."
-#: modules/commands/bs_bot.cpp:246
+#: modules/commands/bs_bot.cpp:262
#, c-format
msgid "Bot %s has been deleted."
msgstr "Bot %s is verwijderd."
@@ -3200,12 +3219,12 @@ msgstr "Bot zal geen ops kicken op kanaal %s."
msgid "Bot won't kick voices on channel %s."
msgstr "Bot zal geen voices kicken op kanaal %s."
-#: modules/commands/bs_bot.cpp:111
+#: modules/commands/bs_bot.cpp:118
#, c-format
msgid "Bot %s is not changeable."
msgstr "Bot %s is niet te wijzigen."
-#: modules/commands/bs_bot.cpp:238
+#: modules/commands/bs_bot.cpp:254
#, c-format
msgid "Bot %s is not deletable."
msgstr "Bot %s is niet te verwijderen."
@@ -3219,21 +3238,21 @@ msgstr "Bot bans verlopen automatisch na %s."
msgid "Bot bans will no longer automatically expire."
msgstr "Bot bans zullen niet langer automatisch verlopen."
-#: modules/commands/bs_bot.cpp:46 modules/commands/bs_bot.cpp:131
+#: modules/commands/bs_bot.cpp:46 modules/commands/bs_bot.cpp:138
#, c-format
msgid "Bot hosts may only be %d characters long."
msgstr "Bot hosts mogen maximaal %d karakters bevatten."
-#: modules/commands/bs_bot.cpp:64 modules/commands/bs_bot.cpp:160
+#: modules/commands/bs_bot.cpp:64 modules/commands/bs_bot.cpp:167
msgid "Bot hosts may only contain valid host characters."
msgstr "Bot hosts mogen alleen geldige host-karakters bevatten."
-#: modules/commands/bs_bot.cpp:40 modules/commands/bs_bot.cpp:125
+#: modules/commands/bs_bot.cpp:40 modules/commands/bs_bot.cpp:132
#, c-format
msgid "Bot idents may only be %d characters long."
msgstr "Bot idents mogen maximaal %d karakters bevatten."
-#: modules/commands/bs_bot.cpp:58 modules/commands/bs_bot.cpp:154
+#: modules/commands/bs_bot.cpp:58 modules/commands/bs_bot.cpp:161
msgid "Bot idents may only contain valid ident characters."
msgstr "Bot idents mogen alleen geldige ident-karakters bevatten."
@@ -3250,12 +3269,12 @@ msgstr "Botlijst:"
msgid "Bot nick"
msgstr "Bot nick"
-#: modules/commands/bs_bot.cpp:34 modules/commands/bs_bot.cpp:119
+#: modules/commands/bs_bot.cpp:34 modules/commands/bs_bot.cpp:126
#, c-format
msgid "Bot nicks may only be %d characters long."
msgstr "Bot nicks mogen maximaal %d karakters bevatten."
-#: modules/commands/bs_bot.cpp:52 modules/commands/bs_bot.cpp:148
+#: modules/commands/bs_bot.cpp:52 modules/commands/bs_bot.cpp:155
msgid "Bot nicks may only contain valid nick characters."
msgstr "Bot nicks mogen alleen geldige nick-karakters bevatten."
@@ -3345,7 +3364,7 @@ msgid "Bot won't kick for repeats anymore."
msgstr "Bot zal niet meer kicken voor herhalingen."
#: modules/commands/cs_access.cpp:472 modules/commands/os_sxline.cpp:199
-#: modules/commands/os_session.cpp:552
+#: modules/commands/os_session.cpp:514
msgid "By"
msgstr "Door"
@@ -3378,12 +3397,12 @@ msgstr ""
"nick of kanaal, indien deze nog niet gelezen is op het moment\n"
"dat je dit commando gebruikt."
-#: modules/commands/cs_clone.cpp:55
+#: modules/commands/cs_clone.cpp:149
#, c-format
msgid "Cannot clone channel %s to itself!"
msgstr "Kan kanaal %s niet naar zichzelf clonen!"
-#: modules/commands/ns_register.cpp:303
+#: modules/commands/ns_register.cpp:311
msgid "Cannot send mail now; please retry a little later."
msgstr "Onmogelijk e-mail te sturen; probeer later opnieuw."
@@ -3449,20 +3468,20 @@ msgstr "ChanServ is vereist om PERSIST te activeren op dit netwerk."
msgid "Change channel modes"
msgstr "Wijzig kanaalmodes"
-#: modules/commands/ns_set.cpp:881
+#: modules/commands/ns_set.cpp:888
msgid "Change the communication method of Services"
msgstr "Verander de communicatiemethode van Services"
-#: modules/commands/os_mode.cpp:140
+#: modules/commands/os_mode.cpp:146
msgid "Change user modes"
msgstr "Wijzig gebruikersmodes"
-#: modules/commands/os_mode.cpp:155
+#: modules/commands/os_mode.cpp:161
#, c-format
msgid "Changed usermodes of %s to %s."
msgstr "Gebruikersmodes van %s veranderd naar %s."
-#: modules/commands/ns_set.cpp:397
+#: modules/commands/ns_set.cpp:402
msgid ""
"Changes the display used to refer to the nickname group in\n"
"Services. The new display MUST be a nick of the group."
@@ -3470,7 +3489,7 @@ msgstr ""
"Verandert de weergegeven nick van de nick-groep in Services.\n"
"De nieuwe weergave MOET een nick in de groep zijn."
-#: modules/commands/ns_set.cpp:373
+#: modules/commands/ns_set.cpp:378
msgid ""
"Changes the display used to refer to your nickname group in\n"
"Services. The new display MUST be a nick of your group."
@@ -3486,7 +3505,7 @@ msgstr ""
"Verandert de stichter van een kanaal. De nieuwe nick moet\n"
"een geregistreerde nick zijn."
-#: modules/commands/ns_set.cpp:860
+#: modules/commands/ns_set.cpp:867
msgid ""
"Changes the language Services uses when sending messages to\n"
"the given user (for example, when responding to a command they send).\n"
@@ -3498,7 +3517,7 @@ msgstr ""
"op een commando dat werd verzonden). taal moet gekozen\n"
"worden uit de volgende lijst van ondersteunde talen:"
-#: modules/commands/ns_set.cpp:824
+#: modules/commands/ns_set.cpp:831
msgid ""
"Changes the language Services uses when sending messages to\n"
"you (for example, when responding to a command you send).\n"
@@ -3510,13 +3529,13 @@ msgstr ""
"op een commando dat je hebt verzonden). taal moet gekozen\n"
"worden uit de volgende lijst van ondersteunde talen:"
-#: modules/commands/ns_set.cpp:219
+#: modules/commands/ns_set.cpp:224
msgid "Changes the password used to identify as the nick's owner."
msgstr ""
"Verandert het wachtwoord dat gebruikt wordt om te identificeren\n"
"als de eigenaar van de nick."
-#: modules/commands/ns_set.cpp:156
+#: modules/commands/ns_set.cpp:158
msgid ""
"Changes the password used to identify you as the nick's\n"
"owner."
@@ -3631,7 +3650,7 @@ msgstr "Kanaal %s toegangslijst is leeggemaakt."
msgid "Channel %s akick list has been cleared."
msgstr "Kanaal %s autokicklijst is leeggemaakt."
-#: modules/commands/cs_mode.cpp:428
+#: modules/commands/cs_mode.cpp:429
#, c-format
msgid "Channel %s has no mode locks."
msgstr "Kanaal %s heeft geen vergrendelde modes."
@@ -3813,7 +3832,7 @@ msgstr "Configureert onderlijningskicker"
msgid "Confirm a passcode"
msgstr "Gebruik een bevestigingscode"
-#: modules/commands/cs_mode.cpp:675
+#: modules/commands/cs_mode.cpp:676
msgid "Control modes and mode locks on a channel"
msgstr "Beheer modes en vergrendelde modes op een kanaal"
@@ -3824,33 +3843,33 @@ msgstr ""
"Beheer welke berichten verstuurd worden naar gebruikers wanneer ze het "
"kanaal betreden."
-#: modules/commands/cs_clone.cpp:193
+#: modules/commands/cs_clone.cpp:241
msgid ""
"Copies all settings, access, akicks, etc from channel to the\n"
-"target channel. If what is ACCESS, AKICK, or BADWORDS\n"
-"then only the respective settings are cloned.\n"
+"target channel. If what is ACCESS, AKICK, BADWORDS,\n"
+"or LEVELS then only the respective settings are cloned.\n"
"You must be the founder of channel and target."
msgstr ""
"Kopiëert alle instellingen, toegangen, autokicks, enz. van kanaal naar het\n"
-"doel kanaal. Als wat één van ACCESS, AKICK, or BADWORDS\n"
-"is, dan worden enkel de respectievelijke instellingen gekopiëerd.\n"
+"doel kanaal. Als wat één van ACCESS, AKICK, BADWORDS of\n"
+"LEVELS is, dan worden enkel de respectievelijke instellingen gekopiëerd.\n"
"Je moet de stichter zijn van zowel kanaal als doel."
-#: modules/commands/cs_clone.cpp:20
+#: modules/commands/cs_clone.cpp:114
msgid "Copy all settings from one channel to another"
msgstr "Kopiëer alle instellingen van het ene kanaal naar het andere"
#: modules/commands/hs_list.cpp:58 modules/commands/cs_flags.cpp:301
-#: modules/commands/cs_mode.cpp:433 modules/commands/cs_entrymsg.cpp:116
+#: modules/commands/cs_mode.cpp:434 modules/commands/cs_entrymsg.cpp:116
#: modules/commands/os_sxline.cpp:199 modules/commands/os_news.cpp:156
#: modules/commands/hs_request.cpp:306 modules/commands/cs_akick.cpp:380
-#: modules/commands/os_session.cpp:552 modules/commands/bs_info.cpp:58
+#: modules/commands/os_session.cpp:514 modules/commands/bs_info.cpp:58
#: modules/commands/os_akill.cpp:355
msgid "Created"
msgstr "Gemaakt"
#: modules/commands/hs_list.cpp:58 modules/commands/cs_flags.cpp:301
-#: modules/commands/cs_mode.cpp:433 modules/commands/cs_entrymsg.cpp:116
+#: modules/commands/cs_mode.cpp:434 modules/commands/cs_entrymsg.cpp:116
#: modules/commands/os_ignore.cpp:266 modules/commands/os_forbid.cpp:346
#: modules/commands/os_news.cpp:156 modules/commands/cs_akick.cpp:380
#: modules/commands/os_akill.cpp:355
@@ -3866,7 +3885,7 @@ msgstr "Huidige %s lijst:"
msgid "Current AKILL list:"
msgstr "Huidige AKILL lijst:"
-#: modules/commands/os_session.cpp:531
+#: modules/commands/os_session.cpp:493
msgid "Current Session Limit Exception list:"
msgstr "Huidige uitzonderingenlijst voor sessielimieten:"
@@ -3919,7 +3938,7 @@ msgstr "DEL [nick] masker"
msgid "DEL {mask | entry-num | list | id}"
msgstr "DEL {masker | nr | lijst | id}"
-#: modules/commands/os_session.cpp:562
+#: modules/commands/os_session.cpp:524
msgid "DEL {mask | entry-num | list}"
msgstr "DEL {masker | nr | lijst}"
@@ -3960,7 +3979,7 @@ msgstr "Database opgekuist, %lu nicks verwijderd die werden toegevoegd na %s."
msgid "Date/Time"
msgstr "Datum/Tijd"
-#: modules/commands/hs_off.cpp:44
+#: modules/commands/hs_off.cpp:46
msgid ""
"Deactivates the vhost currently assigned to the nick in use.\n"
"When you use this command any user who performs a /whois\n"
@@ -4222,7 +4241,7 @@ msgstr ""
msgid "Depooled %s."
msgstr "Depooled %s."
-#: modules/commands/cs_access.cpp:791 modules/commands/ns_alist.cpp:48
+#: modules/commands/cs_access.cpp:799 modules/commands/ns_alist.cpp:48
#: modules/commands/cs_list.cpp:75 modules/commands/cs_info.cpp:53
msgid "Description"
msgstr "Beschrijving"
@@ -4375,15 +4394,15 @@ msgstr ""
"is kan je al je toegangen en kanalen verliezen dat u bezit.\n"
"Iedereen kan dan deze nick opnieuw registreren."
-#: modules/commands/ns_set.cpp:492
+#: modules/commands/ns_set.cpp:499
#, c-format
msgid "E-mail address for %s changed to %s."
-msgstr "E-mail adres voor %s gewijzigd naar %s."
+msgstr "E-mailadres voor %s gewijzigd naar %s."
-#: modules/commands/ns_set.cpp:498
+#: modules/commands/ns_set.cpp:505
#, c-format
msgid "E-mail address for %s unset."
-msgstr "E-mail adres voor %s verwijderd."
+msgstr "E-mailadres voor %s verwijderd."
#: src/mail.cpp:80
#, c-format
@@ -4436,7 +4455,7 @@ msgstr ""
#: modules/commands/ns_info.cpp:98
msgid "Email address"
-msgstr "E-mail adres"
+msgstr "E-mailadres"
#: modules/commands/ns_getemail.cpp:41
#, c-format
@@ -4451,7 +4470,7 @@ msgstr "Activeer fantasie commando's"
msgid "Enable greet messages"
msgstr "Activeer begroetingen"
-#: modules/commands/ns_set.cpp:547
+#: modules/commands/ns_set.cpp:554
msgid "Enable or disable keep modes"
msgstr "Activeer of deactiveer KEEPMODES"
@@ -4481,7 +4500,7 @@ msgstr ""
"onthouden en pogen deze terug te zetten wanneer het kanaal\n"
"de volgende keer weer aangemaakt wordt."
-#: modules/commands/ns_set.cpp:622
+#: modules/commands/ns_set.cpp:629
msgid ""
"Enables or disables keepmodes for the given nick. If keep\n"
"modes is enabled, services will remember users' usermodes\n"
@@ -4492,7 +4511,7 @@ msgstr ""
"onthouden en pogen deze terug te zetten wanneer ze de\n"
"volgende keer identificeren."
-#: modules/commands/ns_set.cpp:597
+#: modules/commands/ns_set.cpp:604
msgid ""
"Enables or disables keepmodes for your nick. If keep\n"
"modes is enabled, services will remember your usermodes\n"
@@ -4584,8 +4603,8 @@ msgstr ""
#: modules/commands/cs_set.cpp:872
msgid ""
"Enables or disables the secure ops option for a channel.\n"
-"When secure ops is set, users who are not on the userlist\n"
-"will not be allowed chanop status."
+"When secure ops is set, users who are not on the access list\n"
+"will not be allowed channel operator status."
msgstr ""
"Zet de veilige ops optie aan of uit voor een kanaal.\n"
"Wanneer veilige ops aan staat mogen gebruikers die niet\n"
@@ -4626,7 +4645,7 @@ msgid ""
" \n"
"If your IRCd has a permanent (persistent) channel mode\n"
"and it is set or unset (for any reason, including MODE LOCK),\n"
-"persist is automatically set and unset for the channel aswell.\n"
+"persist is automatically set and unset for the channel as well.\n"
"Additionally, services will set or unset this mode when you\n"
"set persist on or off."
msgstr ""
@@ -4752,8 +4771,8 @@ msgstr ""
"die ermee overeenstemmen, en LIMIT zal gebruikers kicken tot het\n"
"gebruikersaantal onder de kanaallimiet zakt, indien ingesteld."
-#: src/language.cpp:44 modules/commands/ns_set.cpp:832
-#: modules/commands/ns_set.cpp:867
+#: src/language.cpp:44 modules/commands/ns_set.cpp:839
+#: modules/commands/ns_set.cpp:874
msgid "English"
msgstr "Nederlands"
@@ -4838,21 +4857,16 @@ msgstr ""
" CERT LIST\n"
" Toont de huidige certificaatlijst."
-#: modules/commands/os_session.cpp:454
-#, c-format
-msgid "Exception for %s (#%d) moved to position %d."
-msgstr "Uitzondering voor %s (#%d) verplaatst naar positie %d."
-
#: modules/commands/os_session.cpp:358
#, c-format
msgid "Exception for %s has been updated to %d."
msgstr "Uitzondering voor %s is geüpdatet naar %d."
-#: modules/pseudoclients/chanserv.cpp:460
-#: modules/pseudoclients/nickserv.cpp:559
-#: modules/pseudoclients/nickserv.cpp:564 modules/commands/os_ignore.cpp:266
+#: modules/pseudoclients/chanserv.cpp:456
+#: modules/pseudoclients/nickserv.cpp:564
+#: modules/pseudoclients/nickserv.cpp:569 modules/commands/os_ignore.cpp:266
#: modules/commands/os_sxline.cpp:199 modules/commands/os_forbid.cpp:346
-#: modules/commands/os_session.cpp:552 modules/commands/ns_group.cpp:315
+#: modules/commands/os_session.cpp:514 modules/commands/ns_group.cpp:315
#: modules/commands/os_akill.cpp:355
msgid "Expires"
msgstr "Verloopt"
@@ -4867,7 +4881,7 @@ msgstr "Verlooptijd en reden voor %s geüpdatet."
msgid "Expiry for %s updated."
msgstr "Verlooptijd voor %s geüpdatet."
-#: modules/fantasy.cpp:198
+#: modules/fantasy.cpp:214
msgid "Fantasy"
msgstr "Fantasie"
@@ -4919,7 +4933,7 @@ msgid ""
"Forbid allows you to forbid usage of certain nicknames, channels,\n"
"and email addresses. Wildcards are accepted for all entries."
msgstr ""
-"Stelt je in staat bepaalde nicks, kanalen of e-mail adressen te\n"
+"Stelt je in staat bepaalde nicks, kanalen of e-mailadressen te\n"
"verbieden. Jokertekens worden aanvaard voor alle vermeldingen."
#: modules/commands/os_forbid.cpp:342
@@ -4988,7 +5002,7 @@ msgstr "Ghost met jouw nick is gekilld."
msgid "Give Operflags to a certain user"
msgstr "Geef Operflags aan een bepaalde gebruiker"
-#: modules/commands/cs_mode.cpp:847
+#: modules/commands/cs_mode.cpp:848
#, c-format
msgid ""
"Gives %s status to the selected nick on a channel. If nick is\n"
@@ -4997,7 +5011,7 @@ msgstr ""
"Geeft %s status aan de gegeven nick op een kanaal. Als nick\n"
"niet gegeven, zal het jou %s status geven of afnemen."
-#: modules/commands/cs_mode.cpp:830
+#: modules/commands/cs_mode.cpp:831
#, c-format
msgid "Gives you or the specified nick %s status on a channel"
msgstr "Geeft jou of een gegeven nick %s status op een kanaal"
@@ -5094,8 +5108,8 @@ msgstr "IP %s bestaat niet voor %s."
msgid "Identify yourself with your password"
msgstr "Identificeer jezelf met je wachtwoord"
-#: modules/pseudoclients/nickserv.cpp:200
-#: modules/pseudoclients/nickserv.cpp:206
+#: modules/pseudoclients/nickserv.cpp:205
+#: modules/pseudoclients/nickserv.cpp:211
#, c-format
msgid "If you do not change within %s, I will change your nick."
msgstr "Als je niet binnen %s je nick verandert, verander ik je nick."
@@ -5112,13 +5126,13 @@ msgstr "Negeerlijst is leeg."
msgid "Ignore list:"
msgstr "Negeerlijst:"
-#: modules/commands/ns_set.cpp:1280
+#: modules/commands/ns_set.cpp:1287
msgid "Immediate protection"
msgstr "Onmiddellijke berscherming"
#: modules/commands/ns_resetpass.cpp:33
msgid "Incorrect email address."
-msgstr "Onjuist e-mail adres."
+msgstr "Onjuist e-mailadres."
#: include/language.h:90
msgid "Incorrect range specified. The correct syntax is #from-to."
@@ -5201,16 +5215,16 @@ msgstr "Cursiefkicker"
msgid "Join a group"
msgstr "Bij een groep aanmelden"
-#: modules/commands/cs_set.cpp:1358 modules/commands/ns_set.cpp:1294
+#: modules/commands/cs_set.cpp:1351 modules/commands/ns_set.cpp:1301
msgid "Keep modes"
msgstr "Behoud modes"
-#: modules/commands/cs_set.cpp:374 modules/commands/ns_set.cpp:582
+#: modules/commands/cs_set.cpp:374 modules/commands/ns_set.cpp:589
#, c-format
msgid "Keep modes for %s is now off."
msgstr "Modes behouden voor %s is nu uit."
-#: modules/commands/cs_set.cpp:366 modules/commands/ns_set.cpp:576
+#: modules/commands/cs_set.cpp:366 modules/commands/ns_set.cpp:583
#, c-format
msgid "Keep modes for %s is now on."
msgstr "Modes behouden voor %s is nu aan."
@@ -5228,7 +5242,7 @@ msgstr "Sleutel voor kanaal %s is %s."
msgid "Kick a user from a channel"
msgstr "Kick een gebruiker uit een kanaal"
-#: modules/commands/cs_ban.cpp:204 modules/commands/cs_kick.cpp:103
+#: modules/commands/cs_ban.cpp:218 modules/commands/cs_kick.cpp:116
#, c-format
msgid "Kicked %d/%d users matching %s from %s."
msgstr "%d/%d gebruikers gekickd die overeenstemden met %s uit %s."
@@ -5237,7 +5251,7 @@ msgstr "%d/%d gebruikers gekickd die overeenstemden met %s uit %s."
msgid "Kicks a specified nick from a channel"
msgstr "Kick een gegeven nick uit een kanaal"
-#: modules/commands/cs_kick.cpp:115
+#: modules/commands/cs_kick.cpp:128
msgid ""
"Kicks a specified nick from a channel.\n"
" \n"
@@ -5272,7 +5286,7 @@ msgstr "LIST aantal"
msgid "LIST [mask | list | id]"
msgstr "LIST [masker | lijst | id]"
-#: modules/commands/os_session.cpp:564
+#: modules/commands/os_session.cpp:525
msgid "LIST [mask | list]"
msgstr "LIST [masker | lijst]"
@@ -5285,7 +5299,7 @@ msgstr "LIST [nick]"
msgid "LOGONNEWS {ADD|DEL|LIST} [text|num]"
msgstr "LOGONNEWS {ADD|DEL|LIST} [text|nr]"
-#: modules/commands/ns_set.cpp:812
+#: modules/commands/ns_set.cpp:819
msgid "Language changed to English."
msgstr "Taal gewijzigd naar Nederlands."
@@ -5306,7 +5320,7 @@ msgstr "Laatst gezien"
msgid "Last seen address"
msgstr "Laatst bekende adres"
-#: modules/commands/cs_topic.cpp:263
+#: modules/commands/cs_topic.cpp:264
msgid "Last topic"
msgstr "Laatste topic"
@@ -5338,8 +5352,8 @@ msgstr "Niveau voor %s op kanaal %s gewijzigd naar enkel-stichter."
msgid "Level must be between %d and %d inclusive."
msgstr "Niveau moet tussen de %d en %d inclusief zijn."
-#: modules/commands/os_dns.cpp:217 modules/commands/os_session.cpp:544
-#: modules/commands/os_session.cpp:552
+#: modules/commands/os_dns.cpp:217 modules/commands/os_session.cpp:506
+#: modules/commands/os_session.cpp:514
msgid "Limit"
msgstr "Limiet"
@@ -5352,7 +5366,7 @@ msgstr ""
msgid "List channels you have access on"
msgstr "Toon kanalen waar je toegang in hebt"
-#: modules/commands/cs_mode.cpp:329
+#: modules/commands/cs_mode.cpp:330
#, c-format
msgid "List for mode %c is full."
msgstr "Lijst voor mode %c is vol."
@@ -5708,11 +5722,7 @@ msgstr ""
msgid "Looking for yourself, eh %s?"
msgstr "Zoek je jezelf, %s?"
-#: modules/commands/os_session.cpp:563
-msgid "MOVE num position"
-msgstr "MOVE nr positie"
-
-#: modules/commands/cs_mode.cpp:715
+#: modules/commands/cs_mode.cpp:716
#, c-format
msgid ""
"Mainly controls mode locks and mode access (which is different from channel "
@@ -5780,7 +5790,7 @@ msgstr ""
msgid "Maintain the AutoKick list"
msgstr "Beheer de AutoKicklijst"
-#: modules/commands/bs_bot.cpp:253
+#: modules/commands/bs_bot.cpp:269
msgid "Maintains network bot list"
msgstr "Beheer de lijst met bots op het netwerk"
@@ -5965,7 +5975,7 @@ msgstr "Pas de topic van het gegeven kanaal aan"
#: modules/commands/os_sxline.cpp:191 modules/commands/os_sxline.cpp:199
#: modules/commands/os_forbid.cpp:346 modules/commands/cs_akick.cpp:367
#: modules/commands/cs_akick.cpp:380 modules/commands/ms_ignore.cpp:86
-#: modules/commands/os_session.cpp:544 modules/commands/os_session.cpp:552
+#: modules/commands/os_session.cpp:506 modules/commands/os_session.cpp:514
#: modules/commands/os_list.cpp:147 modules/commands/bs_info.cpp:56
#: modules/commands/os_akill.cpp:341 modules/commands/os_akill.cpp:355
msgid "Mask"
@@ -6043,7 +6053,7 @@ msgstr "Memo's voor %s:"
msgid "Message"
msgstr "Bericht"
-#: modules/commands/ns_set.cpp:1288
+#: modules/commands/ns_set.cpp:1295
msgid "Message mode"
msgstr "Berichtenmodus"
@@ -6051,25 +6061,25 @@ msgstr "Berichtenmodus"
msgid "Method"
msgstr "Methode"
-#: modules/commands/cs_mode.cpp:327 modules/commands/cs_mode.cpp:404
+#: modules/commands/cs_mode.cpp:328 modules/commands/cs_mode.cpp:405
#, c-format
msgid "Missing parameter for mode %c."
msgstr "Ontbrekende parameter voor mode %c."
-#: modules/commands/cs_mode.cpp:433
+#: modules/commands/cs_mode.cpp:434
msgid "Mode"
msgstr "Mode"
-#: modules/commands/cs_mode.cpp:660
+#: modules/commands/cs_mode.cpp:661
#, c-format
msgid "Mode %s is not a status or list mode."
msgstr "Mode %s is geen status- of lijst-mode."
-#: modules/commands/cs_mode.cpp:983
+#: modules/commands/cs_mode.cpp:1008
msgid "Mode lock"
msgstr "Mode-vergrendeling"
-#: modules/commands/cs_mode.cpp:450
+#: modules/commands/cs_mode.cpp:451
#, c-format
msgid "Mode locks for %s:"
msgstr "Mode-vergrendelingen voor %s:"
@@ -6078,6 +6088,11 @@ msgstr "Mode-vergrendelingen voor %s:"
msgid "Modes"
msgstr "Modes"
+#: modules/commands/os_mode.cpp:44
+#, c-format
+msgid "Modes cleared on %s and the channel destroyed."
+msgstr "Modes verwijderd op %s en het kanaal vernietigd."
+
#: modules/commands/ns_access.cpp:166
#, c-format
msgid ""
@@ -6158,7 +6173,7 @@ msgstr "Wijzig de lijst van gebruikers met privileges"
msgid "Modify the nickname client certificate list"
msgstr "Wijzig de certificaatlijst"
-#: modules/commands/os_session.cpp:560
+#: modules/commands/os_session.cpp:522
msgid "Modify the session-limit exception list"
msgstr "Wijzig de uitzonderingenlijst voor sessielimieten"
@@ -6205,7 +6220,7 @@ msgstr "Module: %s Versie: %s Auteur: %s Geladen: %s"
msgid "Module: %s [%s] [%s]"
msgstr "Module: %s [%s] [%s]"
-#: modules/commands/cs_access.cpp:697 modules/commands/cs_access.cpp:791
+#: modules/commands/cs_access.cpp:697 modules/commands/cs_access.cpp:799
#: modules/commands/os_config.cpp:66 modules/commands/os_config.cpp:88
#: modules/commands/cs_list.cpp:75 modules/commands/os_list.cpp:42
#: modules/commands/os_list.cpp:147
@@ -6251,6 +6266,7 @@ msgstr "Nick %s is reeds bevestigd."
msgid "Nick %s is an illegal nickname and cannot be used."
msgstr "Nick %s is een illegale nick en mag niet worden gebruikt."
+#: modules/commands/bs_bot.cpp:81 modules/commands/bs_bot.cpp:181
#: modules/commands/os_svs.cpp:54
#, c-format
msgid "Nick %s is currently in use."
@@ -6291,12 +6307,12 @@ msgstr "Nick %s is niet geregistreerd."
msgid "Nick %s was truncated to %d characters."
msgstr "Nick %s werd verkort naar %d tekens."
-#: modules/commands/ns_set.cpp:1111
+#: modules/commands/ns_set.cpp:1118
#, c-format
msgid "Nick %s will expire."
msgstr "Nick %s zal verlopen."
-#: modules/commands/ns_set.cpp:1105
+#: modules/commands/ns_set.cpp:1112
#, c-format
msgid "Nick %s will not expire."
msgstr "Nick %s zal niet verlopen."
@@ -6361,17 +6377,17 @@ msgstr "Nick %s is al geregistreerd!"
msgid "Nickname %s may not be registered."
msgstr "Nick %s mag niet geregistreerd worden."
-#: modules/commands/ns_register.cpp:204
+#: modules/commands/ns_register.cpp:212
#, c-format
msgid "Nickname %s registered under your user@host-mask: %s"
msgstr "Nick %s is geregistreerd onder jouw gebruikersmasker: %s"
-#: modules/commands/ns_register.cpp:206
+#: modules/commands/ns_register.cpp:214
#, c-format
msgid "Nickname %s registered."
msgstr "Nick %s is geregistreerd."
-#: modules/commands/cs_set.cpp:1360
+#: modules/commands/cs_set.cpp:1353
msgid "No auto-op"
msgstr "Geen auto-op"
@@ -6379,7 +6395,7 @@ msgstr "Geen auto-op"
msgid "No bot"
msgstr "Geen bot"
-#: modules/commands/cs_set.cpp:1356 modules/commands/ns_set.cpp:1292
+#: modules/commands/cs_set.cpp:1349 modules/commands/ns_set.cpp:1299
msgid "No expire"
msgstr "Verloopt niet"
@@ -6428,7 +6444,7 @@ msgstr "Geen overeenkomsten op %s autokicklijst."
msgid "No matching entries on %s bad words list."
msgstr "Geen overeenkomsten op %s slechtewoordenlijst."
-#: modules/commands/os_session.cpp:145 modules/commands/os_session.cpp:528
+#: modules/commands/os_session.cpp:145 modules/commands/os_session.cpp:490
msgid "No matching entries on session-limit exception list."
msgstr "Geen overeenkomsten op de uitzonderingenlijst voor sessielimieten."
@@ -6495,7 +6511,7 @@ msgstr "Geen statistieken voor %s."
msgid "No such info \"%s\" on %s."
msgstr "Geen zulke info \"%s\" over %s."
-#: modules/commands/cs_ban.cpp:206 modules/commands/cs_kick.cpp:105
+#: modules/commands/cs_ban.cpp:220 modules/commands/cs_kick.cpp:118
#, c-format
msgid "No users on %s match %s."
msgstr "Geen gebruikers op %s die overeenkomen met %s."
@@ -6510,7 +6526,7 @@ msgstr "Geen-botmodus staat nu uit op kanaal %s."
msgid "No-bot mode is now on on channel %s."
msgstr "Geen-botmodus staat nu aan op kanaal %s."
-#: modules/commands/os_mode.cpp:58
+#: modules/commands/os_mode.cpp:64
#, c-format
msgid "Non-status modes cleared on %s."
msgstr "Niet-statusmodes weggehaald op %s."
@@ -6519,7 +6535,7 @@ msgstr "Niet-statusmodes weggehaald op %s."
msgid "None"
msgstr "Geen"
-#: modules/commands/cs_mode.cpp:364 modules/commands/cs_mode.cpp:421
+#: modules/commands/cs_mode.cpp:365 modules/commands/cs_mode.cpp:422
msgid "Nothing to do."
msgstr "Niets te doen."
@@ -6531,7 +6547,7 @@ msgstr "Niets te doen."
#: modules/commands/bs_badwords.cpp:194 modules/commands/os_news.cpp:156
#: modules/commands/hs_request.cpp:306 modules/commands/cs_akick.cpp:367
#: modules/commands/cs_akick.cpp:380 modules/commands/cs_log.cpp:127
-#: modules/commands/os_session.cpp:544 modules/commands/os_session.cpp:552
+#: modules/commands/os_session.cpp:506 modules/commands/os_session.cpp:514
#: modules/commands/os_akill.cpp:341 modules/commands/os_akill.cpp:355
#: modules/commands/ns_ajoin.cpp:100
msgid "Number"
@@ -6615,7 +6631,7 @@ msgstr "Opties"
msgid "POOL server.name"
msgstr "POOL server.naam"
-#: modules/commands/cs_mode.cpp:433
+#: modules/commands/cs_mode.cpp:434
msgid "Param"
msgstr "Param"
@@ -6631,12 +6647,12 @@ msgstr "Wachtwoord aanvaard."
msgid "Password authentication required for that command."
msgstr "Wachtwoord authenticatie vereist voor dat commando."
-#: modules/commands/ns_set.cpp:147 modules/commands/ns_set.cpp:210
+#: modules/commands/ns_set.cpp:149 modules/commands/ns_set.cpp:215
#, c-format
msgid "Password for %s changed to %s."
msgstr "Wachtwoord voor %s gewijzigd naar %s."
-#: modules/commands/ns_set.cpp:149 modules/commands/ns_set.cpp:212
+#: modules/commands/ns_set.cpp:151 modules/commands/ns_set.cpp:217
#, c-format
msgid "Password for %s changed."
msgstr "Wachtwoord voor %s gewijzigd."
@@ -6655,7 +6671,7 @@ msgstr "Fout wachtwoord."
msgid "Password reset email for %s has been sent."
msgstr "Wachtwoord reset e-mail voor %s werd verstuurd."
-#: modules/commands/cs_set.cpp:1342
+#: modules/commands/cs_set.cpp:1335
msgid "Peace"
msgstr "Vrede"
@@ -6669,7 +6685,7 @@ msgstr "Vrede-optie voor %s is nu uit."
msgid "Peace option for %s is now on."
msgstr "Vrede-optie voor %s is nu aan."
-#: modules/commands/cs_set.cpp:1354
+#: modules/commands/cs_set.cpp:1347
msgid "Persistent"
msgstr "Permanent"
@@ -6724,7 +6740,7 @@ msgstr ""
"Gelieve %d seconden te wachten alvorens het GROUP commando opnieuw te "
"gebruiken."
-#: modules/commands/ns_register.cpp:176
+#: modules/commands/ns_register.cpp:184
#, c-format
msgid "Please wait %d seconds before using the REGISTER command again."
msgstr ""
@@ -6766,7 +6782,7 @@ msgstr "Voorkom dat het kanaal verloopt"
msgid "Prevent the nickname from appearing in the LIST command"
msgstr "Voorkom dat de nick in het LIST commando verschijnt"
-#: modules/commands/ns_set.cpp:1080
+#: modules/commands/ns_set.cpp:1087
msgid "Prevent the nickname from expiring"
msgstr "Voorkom dat de nick verloopt"
@@ -6819,26 +6835,26 @@ msgstr "Privilege %s toegevoegd bij %s op %s, nieuwe vlaggen zijn +%s"
msgid "Privilege %s removed from %s on %s, new flags are +%s"
msgstr "Privilege %s verwijderd van %s op %s, nieuwe vlaggen zijn +%s"
-#: modules/commands/ns_set.cpp:1284
+#: modules/commands/ns_set.cpp:1291
msgid "Protection"
msgstr "Bescherming"
-#: modules/commands/ns_set.cpp:700
+#: modules/commands/ns_set.cpp:707
#, c-format
msgid "Protection is now off for %s."
msgstr "Bescherming is nu uit voor %s."
-#: modules/commands/ns_set.cpp:679
+#: modules/commands/ns_set.cpp:686
#, c-format
msgid "Protection is now on for %s, with a reduced delay."
msgstr "Bescherming is nu aan voor %s, met een kortere vertraging."
-#: modules/commands/ns_set.cpp:689
+#: modules/commands/ns_set.cpp:696
#, c-format
msgid "Protection is now on for %s, with no delay."
msgstr "Bescherming is nu aan voor %s, zonder vertraging."
-#: modules/commands/ns_set.cpp:671
+#: modules/commands/ns_set.cpp:678
#, c-format
msgid "Protection is now on for %s."
msgstr "Bescherming is nu aan voor %s."
@@ -6853,7 +6869,7 @@ msgstr ""
"gebruikt de volledige echte ident@host voor elke nick,\n"
"en dwingt dan de AKILL af."
-#: modules/commands/ns_set.cpp:1282
+#: modules/commands/ns_set.cpp:1289
msgid "Quick protection"
msgstr "Snelle bescherming"
@@ -6898,7 +6914,7 @@ msgstr "Echte naam"
#: modules/commands/os_ignore.cpp:266 modules/commands/os_sxline.cpp:191
#: modules/commands/os_sxline.cpp:199 modules/commands/os_forbid.cpp:346
#: modules/commands/cs_akick.cpp:367 modules/commands/cs_akick.cpp:380
-#: modules/commands/os_session.cpp:552 modules/commands/os_akill.cpp:341
+#: modules/commands/os_session.cpp:514 modules/commands/os_akill.cpp:341
#: modules/commands/os_akill.cpp:355
msgid "Reason"
msgstr "Reden"
@@ -6937,7 +6953,7 @@ msgstr "Neemt de controle van je nick weer over"
msgid "Regex is disabled."
msgstr "Regex is uitgeschakeld."
-#: modules/commands/os_sxline.cpp:452 modules/commands/os_sxline.cpp:684
+#: modules/commands/os_sxline.cpp:452 modules/commands/os_sxline.cpp:686
#: modules/commands/os_akill.cpp:438
#, c-format
msgid ""
@@ -7021,7 +7037,7 @@ msgstr ""
"%s zal ook automatisch de stichter kanaaloperator\n"
"status geven wanneer deze het kanaal binnenkomt."
-#: modules/commands/ns_register.cpp:240
+#: modules/commands/ns_register.cpp:248
#, c-format
msgid ""
"Registers your nickname in the %s database. Once\n"
@@ -7124,7 +7140,7 @@ msgstr "Server %s verwijderd van domein %s."
msgid "Removed server %s."
msgstr "Server %s verwijderd."
-#: modules/commands/cs_mode.cpp:851
+#: modules/commands/cs_mode.cpp:852
#, c-format
msgid ""
"Removes %s status from the selected nick on a channel. If nick is\n"
@@ -7133,7 +7149,7 @@ msgstr ""
"Verwijdert %s status van de gegeven nick op een channel. Als nick\n"
"niet gegeven is, dan zal het bij jou de %s status weghalen."
-#: modules/commands/cs_mode.cpp:832
+#: modules/commands/cs_mode.cpp:833
#, c-format
msgid "Removes %s status from you or the specified nick on a channel"
msgstr "Verwijdert %s status van jou of de gegeven nick op een kanaal"
@@ -7145,12 +7161,12 @@ msgstr "Verwijder een opgegeven nick's status van een kanaal"
#: modules/commands/cs_updown.cpp:223
msgid ""
"Removes a selected nicks status modes on a channel. If nick is\n"
-"ommited then your status is removed. If channel is ommited then\n"
+"omitted then your status is removed. If channel is omitted then\n"
"your channel status is removed on every channel you are in."
msgstr ""
-"Verwijder een opgegeven nick's status modes van een kanaal.\n"
+"Verwijder een opgegeven nick's status modes in een kanaal.\n"
"Als nick niet is opgegeven, dan worden jouw status modes\n"
-"verwijderd. Indien kanaal niet opgegeven is, dan word je\n"
+"verwijderd. Indien kanaal niet is opgegeven, dan word je\n"
"status op elk kanaal waar je aanwezig bent verwijderd."
#: src/xline.cpp:383
@@ -7177,7 +7193,7 @@ msgstr ""
"door de netwerkbeheerders. Gelieve geduldig te wachten\n"
"terwijl uw aanvraag lopende is."
-#: modules/commands/ns_register.cpp:283
+#: modules/commands/ns_register.cpp:291
msgid "Resend registration confirmation email"
msgstr "Registratiebevestigings-e-mail opnieuw verzenden"
@@ -7185,7 +7201,7 @@ msgstr "Registratiebevestigings-e-mail opnieuw verzenden"
msgid "Restrict access to the channel"
msgstr "Beperk de toegang tot het kanaal"
-#: modules/commands/cs_set.cpp:1344
+#: modules/commands/cs_set.cpp:1337
msgid "Restricted access"
msgstr "Beperkte toegang"
@@ -7239,7 +7255,7 @@ msgstr ""
"Merk op dat er geen jokertekens mogen worden gebruikt.\n"
"Elke keer als dit commando wordt gebruikt wordt er een bericht\n"
"gelogd met de persoon die dit commando uitvoerde samen met\n"
-"het e-mail adres waarop het werd gebruikt."
+"het e-mailadres waarop het werd gebruikt."
#: modules/commands/ns_status.cpp:19
msgid "Returns the owner status of the given nickname"
@@ -7337,7 +7353,7 @@ msgstr "Sla de database op en herstart Services"
msgid "Searches logs for a matching pattern"
msgstr "Doorzoekt logs voor een overeenstemmend patroon"
-#: modules/commands/cs_set.cpp:1348
+#: modules/commands/cs_set.cpp:1341
msgid "Secure founder"
msgstr "Strikte stichter controle"
@@ -7351,7 +7367,7 @@ msgstr "Strikte stichter controle-optie voor %s is nu uit."
msgid "Secure founder option for %s is now on."
msgstr "Strikte stichter controle-optie voor %s is nu aan."
-#: modules/commands/cs_set.cpp:1350
+#: modules/commands/cs_set.cpp:1343
msgid "Secure ops"
msgstr "Strikte operator controle"
@@ -7375,12 +7391,12 @@ msgstr "Veiligheidsoptie voor %s is nu uit."
msgid "Secure option for %s is now on."
msgstr "Veiligheidsoptie voor %s is nu aan."
-#: modules/commands/ns_set.cpp:1020
+#: modules/commands/ns_set.cpp:1027
#, c-format
msgid "Secure option is now off for %s."
msgstr "Veiligheidsoptie is nu uit voor %s."
-#: modules/commands/ns_set.cpp:1014
+#: modules/commands/ns_set.cpp:1021
#, c-format
msgid "Secure option is now on for %s."
msgstr "Veiligheidsoptie is nu aan voor %s."
@@ -7390,7 +7406,7 @@ msgstr "Veiligheidsoptie is nu aan voor %s."
msgid "Secureops enforced on %s."
msgstr "SECUREOPS afgedwongen op %s."
-#: modules/commands/cs_set.cpp:1346 modules/commands/ns_set.cpp:1286
+#: modules/commands/cs_set.cpp:1339 modules/commands/ns_set.cpp:1293
msgid "Security"
msgstr "Veiligheid"
@@ -7443,7 +7459,7 @@ msgid ""
"to the nickname."
msgstr ""
"Stuurt een bevestigingscode naar de nick met instructies om hun\n"
-"wachtwoord te resetten. E-mail moet het e-mail adres zijn die bij\n"
+"wachtwoord te resetten. E-mail moet het e-mailadres zijn die bij\n"
"deze nick hoort."
#: modules/commands/ms_sendall.cpp:52
@@ -7584,7 +7600,7 @@ msgstr "Service"
msgid "Service's hold on %s has been released."
msgstr "Nick %s werd vrijgegeven."
-#: data/nickserv.example.conf:234 data/chanserv.example.conf:820
+#: data/nickserv.example.conf:234 data/chanserv.example.conf:827
msgid "Services Operator commands"
msgstr "Services Operator commando's"
@@ -7653,7 +7669,7 @@ msgstr ""
msgid "Services up %s."
msgstr "Services draaien reeds %s."
-#: modules/commands/ns_set.cpp:258
+#: modules/commands/ns_set.cpp:263
#, c-format
msgid "Services will from now on set status modes on %s in channels."
msgstr "Services zal vanaf nu status modes geven aan %s in kanalen."
@@ -7664,7 +7680,7 @@ msgid "Services will no longer automatically give modes to users in %s."
msgstr ""
"Services zal nu niet langer automatisch modes geven aan gebruikers in %s."
-#: modules/commands/ns_set.cpp:264
+#: modules/commands/ns_set.cpp:269
#, c-format
msgid "Services will no longer set status modes on %s in channels."
msgstr "Services zal niet langer status modes geven aan %s in kanalen."
@@ -7674,12 +7690,12 @@ msgstr "Services zal niet langer status modes geven aan %s in kanalen."
msgid "Services will now automatically give modes to users in %s."
msgstr "Services zal nu automatisch modes geven aan gebruikers in %s."
-#: modules/commands/ns_set.cpp:916
+#: modules/commands/ns_set.cpp:923
#, c-format
msgid "Services will now reply to %s with messages."
msgstr "Services zal nu antwoorden sturen naar %s via privé berichten."
-#: modules/commands/ns_set.cpp:922
+#: modules/commands/ns_set.cpp:929
#, c-format
msgid "Services will now reply to %s with notices."
msgstr "Services zal nu antwoorden sturen naar %s via notice."
@@ -7697,7 +7713,7 @@ msgstr "Sessie"
msgid "Session limit for %s set to %d."
msgstr "Sessielimiet voor %s veranderd naar %d."
-#: modules/commands/os_session.cpp:257 modules/commands/os_session.cpp:573
+#: modules/commands/os_session.cpp:257 modules/commands/os_session.cpp:534
msgid "Session limiting is disabled."
msgstr "Sessielimitering is uitgeschakeld."
@@ -7734,7 +7750,7 @@ msgstr "Stel het kanaal als permanent in"
msgid "Set the channel description"
msgstr "Stelt de kanaalbeschrijving in"
-#: modules/commands/ns_set.cpp:321
+#: modules/commands/ns_set.cpp:326
msgid "Set the display of your group in Services"
msgstr "Stel de weergave van je groep in Services in"
@@ -7742,13 +7758,13 @@ msgstr "Stel de weergave van je groep in Services in"
msgid "Set the founder of a channel"
msgstr "Stelt de stichter van een kanaal in"
-#: modules/commands/ns_set.cpp:772
+#: modules/commands/ns_set.cpp:779
msgid "Set the language Services will use when messaging you"
msgstr ""
"Selecteer de taal die Services zal gebruiken voor het versturen van "
"berichten naar jou"
-#: modules/commands/ns_set.cpp:167
+#: modules/commands/ns_set.cpp:169
msgid "Set the nickname password"
msgstr "Verander het wachtwoord van de nick"
@@ -8068,7 +8084,7 @@ msgstr ""
msgid "Sets various nickname options. option can be one of:"
msgstr "Stelt verscheidene nick opties in. optie kan een van de volgende zijn:"
-#: modules/commands/ns_set.cpp:229
+#: modules/commands/ns_set.cpp:234
msgid ""
"Sets whether services should set channel status modes on you automatically."
msgstr ""
@@ -8082,7 +8098,7 @@ msgstr ""
"Stelt in of het gegeven kanaal zal verlopen. Door deze optie\n"
"AAN te zetten kun je verhinderen dat het kanaal verloopt."
-#: modules/commands/ns_set.cpp:307
+#: modules/commands/ns_set.cpp:312
#, c-format
msgid ""
"Sets whether the given nickname will be given its status modes\n"
@@ -8096,7 +8112,7 @@ msgstr ""
"te zetten wanneer de nick kanalen betreed. Let op dat afhankelijk van de\n"
"kanaalinstellingen sommige modes niet automatisch gezet kunnen worden."
-#: modules/commands/ns_set.cpp:1121
+#: modules/commands/ns_set.cpp:1128
msgid ""
"Sets whether the given nickname will expire. Setting this\n"
"to ON prevents the nickname from expiring."
@@ -8104,7 +8120,7 @@ msgstr ""
"Stelt in of de gegeven nick zal verlopen of niet.\n"
"Dit aan zetten voorkomt dat de nick zal verlopen."
-#: modules/commands/ns_set.cpp:280
+#: modules/commands/ns_set.cpp:285
#, c-format
msgid ""
"Sets whether you will be given your channel status modes automatically.\n"
@@ -8177,7 +8193,7 @@ msgstr ""
msgid "Signed kick option for %s is now on."
msgstr "Ondertekende kicks-optie voor %s is nu aan."
-#: modules/commands/cs_set.cpp:1352
+#: modules/commands/cs_set.cpp:1345
msgid "Signed kicks"
msgstr "Ondertekende kicks"
@@ -8201,7 +8217,7 @@ msgstr ""
msgid "Sorry, bot assignment is temporarily disabled."
msgstr "Sorry, bot toewijzing is tijdelijk uitgeschakeld."
-#: modules/commands/bs_bot.cpp:265 modules/commands/bs_assign.cpp:164
+#: modules/commands/bs_bot.cpp:281 modules/commands/bs_assign.cpp:164
msgid "Sorry, bot modification is temporarily disabled."
msgstr "Sorry, bot wijzigingen zijn tijdelijk uitgeschakeld."
@@ -8570,7 +8586,7 @@ msgid ""
" on or when you unset /AWAY.\n"
" NEW You will only be notified of memos when they\n"
" are sent to you.\n"
-" MAIL You will be notified of memos by email aswell as\n"
+" MAIL You will be notified of memos by email as well as\n"
" any other settings you have.\n"
" NOMAIL You will not be notified of memos by email.\n"
" OFF You will not receive any notification of memos.\n"
@@ -8645,7 +8661,7 @@ msgstr ""
"wanneer het echt nodig is, en terug op OFF gezet worden als het\n"
"niet meer nodig is."
-#: modules/commands/ns_identify.cpp:96
+#: modules/commands/ns_identify.cpp:107
#, c-format
msgid ""
"Tells %s that you are really the owner of this\n"
@@ -8894,11 +8910,11 @@ msgstr ""
"Het ENTRYMSG LIST commando toont een lijst van berichten\n"
"die naar gebruikers gestuurd worden wanneer ze het kanaal betreden."
-#: modules/commands/ns_set.cpp:692
+#: modules/commands/ns_set.cpp:699
msgid "The IMMED option is not available on this network."
msgstr "De IMMED optie is niet beschikbaar op dit netwerk."
-#: modules/commands/cs_access.cpp:813
+#: modules/commands/cs_access.cpp:821
#, c-format
msgid ""
"The LEVELS command allows fine control over the meaning of\n"
@@ -8988,7 +9004,7 @@ msgstr ""
"Het STATS commando toont statistieken over opgeslagen nicks en "
"geheugenverbruik."
-#: modules/commands/ns_register.cpp:262
+#: modules/commands/ns_register.cpp:270
msgid ""
"The email parameter is optional and will set the email\n"
"for your nick immediately.\n"
@@ -8998,7 +9014,7 @@ msgid ""
msgstr ""
"Het email parameter is optioneel en stelt onmiddellijk het e-mail\n"
"adres voor je nick in.\n"
-"Je privacy wordt gerespecteerd; dit e-mail adres wordt niet aan\n"
+"Je privacy wordt gerespecteerd; dit e-mailadres wordt niet aan\n"
"een derde partij doorgegeven. Je zal mogelijks ook SET HIDE\n"
"willen doen na het registreren, als het al niet de standaard instelling is."
@@ -9070,13 +9086,13 @@ msgstr "Het Defcon niveau staat nu op: %d"
#, c-format
msgid "The E-mail address of %s will now be hidden from %s INFO displays."
msgstr ""
-"Het e-mail adres van %s zal vanaf nu verborgen worden in %s INFO opvragingen."
+"Het e-mailadres van %s zal vanaf nu verborgen worden in %s INFO opvragingen."
#: modules/commands/ns_info.cpp:172
#, c-format
msgid "The E-mail address of %s will now be shown in %s INFO displays."
msgstr ""
-"Het e-mail adres van %s zal vanaf nu getoond worden in %s INFO opvragingen."
+"Het e-mailadres van %s zal vanaf nu getoond worden in %s INFO opvragingen."
#: modules/commands/cs_flags.cpp:449
msgid "The available flags are:"
@@ -9095,19 +9111,19 @@ msgstr ""
#: modules/ns_maxemail.cpp:30
#, c-format
msgid "The email address %s has reached its usage limit of %d users."
-msgstr "Het e-mail adres %s heeft de limiet bereikt van %d gebruikers."
+msgstr "Het e-mailadres %s heeft de limiet bereikt van %d gebruikers."
#: modules/ns_maxemail.cpp:28
#, c-format
msgid "The email address %s has reached its usage limit of 1 user."
-msgstr "Het e-mail adres %s heeft de limiet bereikt van 1 gebruiker."
+msgstr "Het e-mailadres %s heeft de limiet bereikt van 1 gebruiker."
#: modules/commands/cs_entrymsg.cpp:142
#, c-format
msgid "The entry message list for %s is full."
msgstr "De welkomstberichtenlijst voor %s is vol."
-#: modules/commands/cs_access.cpp:788
+#: modules/commands/cs_access.cpp:796
msgid "The following feature/function names are available:"
msgstr "De volgende privilege/functie namen zijn beschikbaar:"
@@ -9183,12 +9199,12 @@ msgstr "Het masker moet tenminste één niet-jokerteken bevatten."
msgid "The memo limit for %s may not be changed."
msgstr "De memolimiet voor %s mag niet worden veranderd."
-#: modules/commands/cs_mode.cpp:331
+#: modules/commands/cs_mode.cpp:332
#, c-format
msgid "The mode lock list of %s is full."
msgstr "De mode blokkeerlijst van %s is vol."
-#: modules/commands/ns_set.cpp:347
+#: modules/commands/ns_set.cpp:352
#, c-format
msgid "The new display MUST be a nickname of the nickname group %s."
msgstr "De nieuwe weergave MOET een nick zijn van de nick-groep %s."
@@ -9203,7 +9219,7 @@ msgstr "De nieuwe weergave is nu %s."
msgid "The nick %s is now being changed to %s."
msgstr "De nick %s wordt nu veranderd naar %s."
-#: modules/commands/bs_bot.cpp:142
+#: modules/commands/bs_bot.cpp:149
msgid "The old information is the same as the new information specified."
msgstr "De oude informatie is dezelfde als de nieuw opgegeven informatie."
@@ -9232,7 +9248,7 @@ msgstr ""
"Het services toegangsniveau van %s zal vanaf nu getoond worden in %s INFO "
"opvragingen."
-#: modules/commands/os_session.cpp:471
+#: modules/commands/os_session.cpp:433
msgid "The session exception list is empty."
msgstr "De uitzonderingenlijst voor sessielimieten is leeg."
@@ -9311,14 +9327,14 @@ msgstr "Er is geen willekeurig nieuws."
msgid "There is no such configuration block %s."
msgstr "Onbestaand configuratie blok %s."
-#: modules/commands/cs_mode.cpp:654
+#: modules/commands/cs_mode.cpp:655
#, c-format
msgid "There is no such mode %s."
msgstr "Mode %s bestaat niet."
#: modules/commands/ms_set.cpp:52
msgid "There's no email address set for your nick."
-msgstr "Er is geen e-mail adres ingesteld voor jouw nick."
+msgstr "Er is geen e-mailadres ingesteld voor jouw nick."
#: modules/commands/os_forbid.cpp:292 modules/commands/os_forbid.cpp:484
#, c-format
@@ -9386,7 +9402,7 @@ msgstr ""
"HUIDIGE nick de vHost van alle nicks in dezelfde groep te\n"
"laten zijn."
-#: modules/commands/ns_register.cpp:270
+#: modules/commands/ns_register.cpp:278
msgid ""
"This command also creates a new group for your nickname,\n"
"that will allow you to register other nicks later sharing\n"
@@ -9416,7 +9432,7 @@ msgstr ""
"Dit commando wordt gebruikt door een aantal commando's als een\n"
"manier om wijzigingen aan je nick/login te bevestigen.\n"
" \n"
-"Dit commando wordt het vaakst gebruikt om je e-mail adres te\n"
+"Dit commando wordt het vaakst gebruikt om je e-mailadres te\n"
"bevestigen als je je registreert, of als je deze wijzigt.\n"
" \n"
"Dit wordt ook gebruikt nadat het RESETPASS commando gebruikt is\n"
@@ -9519,7 +9535,7 @@ msgstr ""
"Services Operators kunnen een nick opgeven om anderen hun\n"
"autojoinlijsten aan te passen."
-#: modules/commands/ns_set.cpp:337 modules/commands/ns_set.cpp:648
+#: modules/commands/ns_set.cpp:342 modules/commands/ns_set.cpp:655
msgid ""
"This command may not be used on this network because nickname ownership is "
"disabled."
@@ -9591,7 +9607,7 @@ msgstr ""
msgid "This command unloads the module named modname."
msgstr "Dit commando ontlaadt de module genaamd modnaam."
-#: modules/commands/ns_register.cpp:324
+#: modules/commands/ns_register.cpp:332
msgid "This command will resend you the registration confirmation email."
msgstr ""
"Dit commando zal je de registratiebevestigings-e-mail opnieuw toezenden."
@@ -9679,7 +9695,7 @@ msgstr "Top %i van %s"
msgid "Topic"
msgstr "Topic"
-#: modules/commands/cs_topic.cpp:257
+#: modules/commands/cs_topic.cpp:258
msgid "Topic lock"
msgstr "Topicvergrendeling"
@@ -9693,7 +9709,7 @@ msgstr "Topicvergrendeling-optie voor %s is nu gedeactiveerd."
msgid "Topic lock option for %s is now on."
msgstr "Topicvergrendeling-optie voor %s is nu geactiveerd."
-#: modules/commands/cs_topic.cpp:255
+#: modules/commands/cs_topic.cpp:256
msgid "Topic retention"
msgstr "Topicbehoud"
@@ -9707,7 +9723,7 @@ msgstr "Topicbehoud-optie voor %s is nu gedeactiveerd."
msgid "Topic retention option for %s is now on."
msgstr "Topicbehoud-optie voor %s is nu geactiveerd."
-#: modules/commands/cs_topic.cpp:264
+#: modules/commands/cs_topic.cpp:265
msgid "Topic set by"
msgstr "Topic gezet door"
@@ -9720,11 +9736,11 @@ msgstr "Zet hoofdletters UIT!"
msgid "Turn chanstats statistics on or off"
msgstr "Zet chanstats statistieken aan of uit"
-#: modules/commands/ns_set.cpp:985
+#: modules/commands/ns_set.cpp:992
msgid "Turn nickname security on or off"
msgstr "Zet nickname beveiliging aan of uit"
-#: modules/commands/ns_set.cpp:634
+#: modules/commands/ns_set.cpp:641
msgid "Turn protection on or off"
msgstr "Zet bescherming aan of uit"
@@ -9758,7 +9774,7 @@ msgstr ""
"iedereen die je nick weet kan nog steeds informatie krijgen\n"
"via het INFO commando."
-#: modules/commands/ns_set.cpp:1035 modules/commands/ns_set.cpp:1064
+#: modules/commands/ns_set.cpp:1042 modules/commands/ns_set.cpp:1071
#, c-format
msgid ""
"Turns %s's security features on or off for your\n"
@@ -9785,7 +9801,7 @@ msgstr "Zet chanstats statistieken aan of uit."
msgid "Turns chanstats channel statistics ON or OFF for this user."
msgstr "Zet chanstats kanaal statistieken aan of uit voor deze gebruiker."
-#: modules/commands/ns_set.cpp:751
+#: modules/commands/ns_set.cpp:758
#, c-format
msgid ""
"Turns the automatic protection option for the nick\n"
@@ -9815,7 +9831,7 @@ msgstr ""
"Deze optie kan ook uitgeschakeld zijn door de netwerk\n"
"administrators."
-#: modules/commands/ns_set.cpp:717
+#: modules/commands/ns_set.cpp:724
#, c-format
msgid ""
"Turns the automatic protection option for your nick\n"
@@ -9893,7 +9909,7 @@ msgstr ""
"Typ %s%s HELP %s optie voor meer informatie over een\n"
"specifieke optie."
-#: modules/pseudoclients/nickserv.cpp:356
+#: modules/pseudoclients/nickserv.cpp:361
#, c-format
msgid ""
"Type %s%s SET EMAIL e-mail in order to set your e-mail.\n"
@@ -9967,7 +9983,7 @@ msgstr "Onbekend commando %s."
msgid "Unknown command %s. \"%s%s HELP\" for help."
msgstr "Onbekend commando %s. \"%s%s HELP\" voor hulp."
-#: modules/commands/cs_mode.cpp:316 modules/commands/cs_mode.cpp:393
+#: modules/commands/cs_mode.cpp:317 modules/commands/cs_mode.cpp:394
#, c-format
msgid "Unknown mode character %c ignored."
msgstr "Onbekende mode karakter %c genegeerd."
@@ -10009,7 +10025,7 @@ msgstr "Heft de schorsing op een nick op zodat deze weer kan gebruikt worden."
#: modules/commands/cs_updown.cpp:126
msgid ""
"Updates a selected nicks status modes on a channel. If nick is\n"
-"ommited then your status is updated. If channel is ommited then\n"
+"omitted then your status is updated. If channel is omitted then\n"
"your channel status is updated on every channel you are in."
msgstr ""
"Werkt de gegeven nick's status modes bij op een kanaal.\n"
@@ -10060,15 +10076,15 @@ msgstr ""
msgid "Used on"
msgstr "Gebruikt op"
-#: data/chanserv.example.conf:814
+#: data/chanserv.example.conf:821
msgid "Used to manage channels"
msgstr "Dient om kanalen te beheren"
-#: data/chanserv.example.conf:802
+#: data/chanserv.example.conf:809
msgid "Used to manage the list of privileged users"
msgstr "Dient om de lijst van gebruikers met privileges te beheren"
-#: data/chanserv.example.conf:808
+#: data/chanserv.example.conf:815
msgid "Used to modify the channel status of you or other users"
msgstr "Dient om de kanaalstatus van jezelf of anderen aan te passen"
@@ -10137,7 +10153,7 @@ msgstr "VIEW host"
msgid "VIEW [mask | list | id]"
msgstr "VIEW [masker | lijst | id]"
-#: modules/commands/os_session.cpp:565
+#: modules/commands/os_session.cpp:526
msgid "VIEW [mask | list]"
msgstr "VIEW [masker | lijst]"
@@ -10278,7 +10294,7 @@ msgstr "Woord"
msgid "You are already a member of the group of %s."
msgstr "Je bent al lid van de groep van %s."
-#: modules/commands/os_login.cpp:35 modules/commands/ns_identify.cpp:82
+#: modules/commands/os_login.cpp:35 modules/commands/ns_identify.cpp:87
msgid "You are already identified."
msgstr "Je bent al geïdentificeerd."
@@ -10380,7 +10396,7 @@ msgstr "Je kan geen kanaal toevoegen op zijn eigen toegangslijst."
msgid "You can't logout %s, they are a Services Operator."
msgstr "Je kan %s niet uitloggen omdat hij een Services Operator is."
-#: modules/commands/ns_set.cpp:903
+#: modules/commands/ns_set.cpp:910
#, c-format
msgid "You cannot %s on this network."
msgstr "Je kan geen %s doen op dit netwerk."
@@ -10406,9 +10422,9 @@ msgstr ""
"Je kan geen bottoewijzingen ongedaan maken zolang persist geactiveerd is op "
"het kanaal."
-#: modules/commands/ns_set.cpp:462
+#: modules/commands/ns_set.cpp:469
msgid "You cannot unset the e-mail on this network."
-msgstr "Je kan het e-mail adres niet verwijderen op dit netwerk."
+msgstr "Je kan het e-mailadres niet verwijderen op dit netwerk."
#: modules/commands/help.cpp:177
msgid "You cannot use this command."
@@ -10446,12 +10462,12 @@ msgstr "Je hebt momenteel 1 memo."
msgid "You currently have no memos."
msgstr "Je hebt momenteel geen memo's."
-#: modules/commands/cs_mode.cpp:543 modules/commands/cs_mode.cpp:580
+#: modules/commands/cs_mode.cpp:544 modules/commands/cs_mode.cpp:581
#, c-format
msgid "You do not have access to set mode %c."
msgstr "Je hebt geen toegang om mode %c te zetten."
-#: modules/commands/cs_mode.cpp:556 modules/commands/cs_mode.cpp:589
+#: modules/commands/cs_mode.cpp:557 modules/commands/cs_mode.cpp:590
#, c-format
msgid "You do not have the access to change %s's modes."
msgstr "Je hebt geen toegang om %s's modes te veranderen."
@@ -10538,20 +10554,20 @@ msgstr "Je hebt weer de controle over %s en bent nu geïdentificeerd als %s.
msgid "You may drop any nick within your group."
msgstr "Je kan de registraties van nicks in je groep verwijderen."
-#: modules/commands/cs_mode.cpp:321 modules/commands/cs_mode.cpp:398
+#: modules/commands/cs_mode.cpp:322 modules/commands/cs_mode.cpp:399
#, c-format
msgid "You may not (un)lock mode %c."
msgstr "Je mag mode %c niet (de)blokkeren."
-#: modules/commands/ns_set.cpp:467
+#: modules/commands/ns_set.cpp:474
msgid "You may not change the e-mail of other Services Operators."
-msgstr "Je mag het e-mail adres van andere Services Operators niet wijzigen."
+msgstr "Je mag het e-mailadres van andere Services Operators niet wijzigen."
-#: modules/commands/ns_set.cpp:456
+#: modules/commands/ns_set.cpp:463
msgid "You may not change the email of an unconfirmed account."
-msgstr "Je mag het e-mail adres van een onbevestigde account niet wijzigen."
+msgstr "Je mag het e-mailadres van een onbevestigde account niet wijzigen."
-#: modules/commands/ns_set.cpp:191
+#: modules/commands/ns_set.cpp:193
msgid "You may not change the password of other Services Operators."
msgstr "Je mag het wachtwoord van andere Services Operators niet wijzigen."
@@ -10627,20 +10643,20 @@ msgstr ""
msgid "You must have been using this nick for at least %d seconds to register."
msgstr "Je moet deze nick tenminste %d seconden gebruiken om te registreren."
-#: modules/commands/cs_mode.cpp:855
+#: modules/commands/cs_mode.cpp:856
#, c-format
msgid "You must have the %s(ME) privilege on the channel to use this command."
msgstr ""
"Je moet het %s(ME) privilege hebben op het kanaal om dit commando te "
"gebruiken."
-#: modules/pseudoclients/nickserv.cpp:353
+#: modules/pseudoclients/nickserv.cpp:358
msgid ""
"You must now supply an e-mail for your nick.\n"
"This e-mail will allow you to retrieve your password in\n"
"case you forget it."
msgstr ""
-"Je moet nu een e-mail adres opgeven voor je nick.\n"
+"Je moet nu een e-mailadres opgeven voor je nick.\n"
"Dit stelt je in staat je wachtwoord terug te halen in\n"
"het geval dat je het vergeet."
@@ -10699,44 +10715,44 @@ msgstr ""
"Je IRCd ondersteunt geen vIdent's, indien dit niet klopt, gelieve dit dan te "
"melden als een fout"
-#: modules/extra/m_ldap_authentication.cpp:110
+#: modules/extra/m_ldap_authentication.cpp:102
#: modules/extra/m_sql_authentication.cpp:47
#, c-format
msgid "Your account %s has been successfully created."
msgstr "Je account %s is succesvol aangemaakt."
-#: modules/commands/ns_register.cpp:299
+#: modules/commands/ns_register.cpp:307
msgid "Your account is already confirmed."
msgstr "Je account is reeds bevestigd."
-#: modules/commands/ns_register.cpp:367
+#: modules/commands/ns_register.cpp:375
#, c-format
msgid "Your account will expire, if not confirmed, in %s."
msgstr "Je account verloopt, indien niet bevestigd, over %s."
-#: modules/commands/ns_set.cpp:1249
+#: modules/commands/ns_set.cpp:1256
#, c-format
msgid "Your email address has been changed to %s."
-msgstr "Je e-mail adres werd gewijzigd naar %s."
+msgstr "Je e-mailadres werd gewijzigd naar %s."
#: modules/commands/os_forbid.cpp:532 modules/commands/os_forbid.cpp:541
msgid "Your email address is not allowed, choose a different one."
-msgstr "Je e-mail adres is niet toegelaten, kies een andere."
+msgstr "Je e-mailadres is niet toegelaten, kies een andere."
-#: modules/commands/ns_register.cpp:362
+#: modules/commands/ns_register.cpp:370
msgid ""
"Your email address is not confirmed. To confirm it, follow the instructions "
"that were emailed to you."
msgstr ""
-"Je e-mail adres is niet bevestigd. Om deze te bevestigen dien je de "
+"Je e-mailadres is niet bevestigd. Om deze te bevestigen dien je de "
"instructies te volgen in de toegezonden e-mail."
#: modules/commands/ns_register.cpp:53
#, c-format
msgid "Your email address of %s has been confirmed."
-msgstr "Je e-mail adres %s werd bevestigd."
+msgstr "Je e-mailadres %s werd bevestigd."
-#: modules/extra/m_ldap_authentication.cpp:171
+#: modules/extra/m_ldap_authentication.cpp:151
#, c-format
msgid "Your email has been updated to %s"
msgstr "Je e-mail werd geüpdatet naar %s."
@@ -10793,7 +10809,7 @@ msgstr "Je nick behoort tot geen enkele groep, je kan dit dus niet uitvoeren."
msgid "Your nick isn't registered."
msgstr "Je nickname is niet geregistreerd."
-#: modules/pseudoclients/nickserv.cpp:249
+#: modules/pseudoclients/nickserv.cpp:254
#, c-format
msgid "Your nickname is now being changed to %s"
msgstr "Je nickname wordt nu veranderd in %s"
@@ -10802,21 +10818,20 @@ msgstr "Je nickname wordt nu veranderd in %s"
msgid "Your oper block doesn't require logging in."
msgstr "Je oper blok vereist geen aanmelding."
-#: modules/commands/ns_register.cpp:307
+#: modules/commands/ns_register.cpp:315
#, c-format
msgid "Your passcode has been re-sent to %s."
msgstr "Je bevestingscode is opnieuw gestuurd naar %s."
-#: modules/commands/ns_register.cpp:210
+#: modules/commands/ns_register.cpp:218
#, c-format
msgid "Your password is %s - remember this for later use."
msgstr "Je wachtwoord is %s - onthoudt dit voor later gebruik."
#: include/language.h:77
-msgid "Your password is too long. Please try again with a shorter password."
-msgstr ""
-"Je wachtwoord is te lang. Gelieve opnieuw te proberen met een korter "
-"wachtwoord."
+#, c-format
+msgid "Your password is too long. It must not exceed %u characters."
+msgstr "Je wachtwoord is te lang. Het mag niet langer zijn dan %u karakters."
#: modules/commands/ns_resetpass.cpp:96
msgid "Your password reset request has expired."
@@ -10838,7 +10853,7 @@ msgstr "Je vHost %s is nu geactiveerd."
msgid "Your vhost of %s@%s is now activated."
msgstr "Je vHost %s@%s is nu geactiveerd."
-#: modules/commands/hs_off.cpp:34
+#: modules/commands/hs_off.cpp:36
msgid "Your vhost was removed and the normal cloaking restored."
msgstr "Je vHost werd verwijderd en de normale cloaking hersteld."
@@ -10975,7 +10990,7 @@ msgstr "[auto memo] Uw aanvraag voor de vHost werd geweigerd."
msgid "[auto memo] Your requested vHost has been rejected. Reason: %s"
msgstr "[auto memo] Uw aanvraag voor de vHost werd geweigerd. Reden: %s"
-#: modules/commands/hs_request.cpp:390
+#: modules/commands/hs_request.cpp:389
#, c-format
msgid "[auto memo] vHost %s has been requested by %s."
msgstr "[auto memo] vHost %s aangevraagd door %s."
diff --git a/modules/commands/bs_bot.cpp b/modules/commands/bs_bot.cpp
index 1ba22531e..726c02ab2 100644
--- a/modules/commands/bs_bot.cpp
+++ b/modules/commands/bs_bot.cpp
@@ -82,7 +82,10 @@ class CommandBSBot : public Command
User *targ = User::Find(nick, true);
if (targ)
- targ->Kill(Me, "Nickname is reserved for services");
+ {
+ source.Reply(_("\002{0}\002 is currently in use."), targ->nick);
+ return;
+ }
ServiceBot *bi = new ServiceBot(nick, user, host, real);
@@ -179,6 +182,13 @@ class CommandBSBot : public Command
return;
}
+ User *target = User::Find(nick, true);
+ if (target)
+ {
+ source.Reply(_("\002{0}\002 is currently in use."), target->nick);
+ return;
+ }
+
if (!nick.equals_ci(bi->nick))
{
/* We check whether the nick is registered, and inform the user
diff --git a/modules/commands/cs_access.cpp b/modules/commands/cs_access.cpp
index 982d5763f..f8ecc6c38 100644
--- a/modules/commands/cs_access.cpp
+++ b/modules/commands/cs_access.cpp
@@ -704,7 +704,7 @@ class CommandCSLevels : public Command
{
const Anope::string &what = params[2];
- /* Don't allow disabling of the founder level. It would be hard to change it back if you dont have access to use this command */
+ /* Don't allow disabling of the founder level. It would be hard to change it back if you don't have access to use this command */
if (what.equals_ci("FOUNDER"))
{
source.Reply(_("You can not disable the founder privilege because it would be impossible to reenable it at a later time."));
@@ -804,6 +804,14 @@ class CommandCSLevels : public Command
return;
}
+ bool has_access = false;
+ if (source.HasPriv("chanserv/access/modify"))
+ has_access = true;
+ else if (cmd.equals_ci("LIST") && source.HasPriv("chanserv/access/list"))
+ has_access = true;
+ else if (source.AccessFor(ci).HasPriv("FOUNDER"))
+ has_access = true;
+
/* If SET, we want two extra parameters; if DIS[ABLE] or FOUNDER, we want only
* one; else, we want none.
*/
@@ -813,7 +821,7 @@ class CommandCSLevels : public Command
return;
}
- if (!source.AccessFor(ci).HasPriv("FOUNDER") && !source.HasPriv("chanserv/access/modify"))
+ if (!has_access)
{
source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "FOUNDER", ci->GetName());
return;
diff --git a/modules/commands/cs_ban.cpp b/modules/commands/cs_ban.cpp
index a17ae48a0..f797eda0f 100644
--- a/modules/commands/cs_ban.cpp
+++ b/modules/commands/cs_ban.cpp
@@ -102,6 +102,9 @@ class CommandCSBan : public Command
if (reason.length() > reasonmax)
reason = reason.substr(0, reasonmax);
+ Anope::string signkickformat = Config->GetModule("chanserv")->Get<Anope::string>("signkickformat", "%m (%n)");
+ signkickformat = signkickformat.replace_all_cs("%n", source.GetNick());
+
User *u = source.GetUser();
User *u2 = User::Find(target, true);
@@ -124,7 +127,7 @@ class CommandCSBan : public Command
}
/*
- * Dont ban/kick the user on channels where he is excepted
+ * Don't ban/kick the user on channels where he is excepted
* to prevent services <-> server wars.
*/
if (c->MatchesList(u2, "EXCEPT"))
@@ -161,7 +164,10 @@ class CommandCSBan : public Command
if (block->Get<bool>("kick", "yes"))
{
if (ci->HasFieldS("SIGNKICK") || (ci->HasFieldS("SIGNKICK_LEVEL") && !source.AccessFor(ci).HasPriv("SIGNKICK")))
- c->Kick(ci->WhoSends(), u2, "%s (%s)", reason.c_str(), source.GetNick().c_str());
+ {
+ signkickformat = signkickformat.replace_all_cs("%m", reason);
+ c->Kick(ci->WhoSends(), u2, "%s", signkickformat.c_str());
+ }
else
c->Kick(ci->WhoSends(), u2, "%s", reason.c_str());
}
@@ -170,15 +176,18 @@ class CommandCSBan : public Command
{
bool founder = u_access.HasPriv("FOUNDER");
bool override = !founder && !u_access.HasPriv("BAN");
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "for " << target;
- if (!c->HasMode(mode, target))
+ Anope::string mask = IRCD->NormalizeMask(target);
+
+ Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "for " << mask;
+
+ if (!c->HasMode(mode, mask))
{
- c->SetMode(NULL, mode, target);
+ c->SetMode(NULL, mode, mask);
if (ban_time)
{
- new TempBan(ban_time, c, target, mode);
- source.Reply(_("Ban on \002{0}\002 expires in \002{1}\002."), target, Anope::Duration(ban_time, source.GetAccount()));
+ new TempBan(ban_time, c, mask, mode);
+ source.Reply(_("Ban on \002{0}\002 expires in \002{1}\002."), mask, Anope::Duration(ban_time, source.GetAccount()));
}
}
@@ -188,7 +197,8 @@ class CommandCSBan : public Command
ChanUserContainer *uc = it->second;
++it;
- if (Anope::Match(uc->user->nick, target) || Anope::Match(uc->user->GetDisplayedMask(), target))
+ Entry e(mode, mask);
+ if (e.Matches(uc->user))
{
++matched;
@@ -206,18 +216,23 @@ class CommandCSBan : public Command
if (block->Get<bool>("kick", "yes"))
{
++kicked;
+
if (ci->HasFieldS("SIGNKICK") || (ci->HasFieldS("SIGNKICK_LEVEL") && !u_access.HasPriv("SIGNKICK")))
- c->Kick(ci->WhoSends(), uc->user, "%s (Matches %s) (%s)", reason.c_str(), target.c_str(), source.GetNick().c_str());
+ {
+ reason += " (Matches " + mask + ")";
+ signkickformat = signkickformat.replace_all_cs("%m", reason);
+ c->Kick(ci->WhoSends(), uc->user, "%s", signkickformat.c_str());
+ }
else
- c->Kick(ci->WhoSends(), uc->user, "%s (Matches %s)", reason.c_str(), target.c_str());
+ c->Kick(ci->WhoSends(), uc->user, "%s (Matches %s)", reason.c_str(), mask.c_str());
}
}
}
if (matched)
- source.Reply(_("Kicked \002{0}/{1}\002 users matching \002{2}\002 from \002{3}\002."), kicked, matched, target, c->name);
+ source.Reply(_("Kicked \002{0}/{1}\002 users matching \002{2}\002 from \002{3}\002."), kicked, matched, mask, c->name);
else
- source.Reply(_("No users on \002{0}\002 match \002{1}\002."), c->name, target);
+ source.Reply(_("No users on \002{0}\002 match \002{1}\002."), c->name, mask);
}
}
diff --git a/modules/commands/cs_clone.cpp b/modules/commands/cs_clone.cpp
index 69dc70bea..256446bd1 100644
--- a/modules/commands/cs_clone.cpp
+++ b/modules/commands/cs_clone.cpp
@@ -15,6 +15,20 @@
class CommandCSClone : public Command
{
+#if 0
+ void CopyLevels(CommandSource &source, ChannelInfo *ci, ChannelInfo *target_ci)
+ {
+ const Anope::map<int16_t> &cilevels = ci->GetLevelEntries();
+
+ for (Anope::map<int16_t>::const_iterator it = cilevels.begin(); it != cilevels.end(); ++it)
+ {
+ target_ci->SetLevel(it->first, it->second);
+ }
+
+ source.Reply(_("All level entries from \002%s\002 have been cloned into \002%s\002."), ci->name.c_str(), target_ci->name.c_str());
+ }
+#endif
+
public:
CommandCSClone(Module *creator) : Command(creator, "chanserv/clone", 2, 3)
{
@@ -73,7 +87,7 @@ public:
if (what.empty())
{
- delete target_ci;
+ target_ci->Delete();
target_ci = ChanServ::channel.Create();
target_ci->SetName(target);
ChanServ::registered_channel_map& map = ChanServ::service->GetChannels();
diff --git a/modules/commands/cs_entrymsg.cpp b/modules/commands/cs_entrymsg.cpp
index 4a646b3b3..31253599e 100644
--- a/modules/commands/cs_entrymsg.cpp
+++ b/modules/commands/cs_entrymsg.cpp
@@ -138,7 +138,7 @@ class CommandEntryMessage : public Command
msg->SetChannel(ci);
msg->SetCreator(source.GetNick());
msg->SetMessage(message);
- Log(source.IsFounder(ci) ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to add a message";
+ Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to add a message";
source.Reply(_("Entry message added to \002{0}\002"), ci->GetName());
}
@@ -157,8 +157,8 @@ class CommandEntryMessage : public Command
unsigned i = convertTo<unsigned>(message);
if (i > 0 && i <= messages.size())
{
- delete messages[i - 1];
- Log(source.IsFounder(ci) ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to remove a message";
+ messages[i - 1]->Delete();
+ Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to remove a message";
source.Reply(_("Entry message \002{0}\002 for \002{1]\002 deleted."), i, ci->GetName());
}
else
@@ -176,7 +176,7 @@ class CommandEntryMessage : public Command
for (EntryMsg *e : ci->GetRefs<EntryMsg *>(entrymsg))
delete e;
- Log(source.IsFounder(ci) ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to remove all messages";
+ Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to remove all messages";
source.Reply(_("Entry messages for \002{0}\002 have been cleared."), ci->GetName());
}
@@ -207,7 +207,7 @@ class CommandEntryMessage : public Command
return;
}
- if (!source.IsFounder(ci) && !source.HasPriv("chanserv/administration"))
+ if (!source.AccessFor(ci).HasPriv("SET") && !source.HasPriv("chanserv/administration"))
{
source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "FOUNDER", ci->GetName());
return;
@@ -240,7 +240,7 @@ class CommandEntryMessage : public Command
"\n"
"The \002{0} CLEAR\002 command clears the entry message list.\n"
"\n"
- "Use of this command requires being the founder of \037channel\037."),
+ "Use of this command requires the \002SET\002 privilege on \037channel\037."),
source.command);
return true;
}
diff --git a/modules/commands/cs_kick.cpp b/modules/commands/cs_kick.cpp
index 679ccfe06..89536df7f 100644
--- a/modules/commands/cs_kick.cpp
+++ b/modules/commands/cs_kick.cpp
@@ -50,6 +50,9 @@ class CommandCSKick : public Command
ChanServ::AccessGroup u_access = source.AccessFor(ci);
+ Anope::string signkickformat = Config->GetModule("chanserv")->Get<Anope::string>("signkickformat", "%m (%n)");
+ signkickformat = signkickformat.replace_all_cs("%n", source.GetNick());
+
if (!u_access.HasPriv("KICK") && !source.HasPriv("chanserv/kick"))
{
source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "KICK", ci->GetName());
@@ -71,14 +74,19 @@ class CommandCSKick : public Command
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "for " << u2->nick;
if (ci->HasFieldS("SIGNKICK") || (ci->HasFieldS("SIGNKICK_LEVEL") && !u_access.HasPriv("SIGNKICK")))
- c->Kick(ci->WhoSends(), u2, "%s (%s)", reason.c_str(), source.GetNick().c_str());
+ {
+ signkickformat = signkickformat.replace_all_cs("%m", reason);
+ c->Kick(ci->WhoSends(), u2, "%s", signkickformat.c_str());
+ }
else
c->Kick(ci->WhoSends(), u2, "%s", reason.c_str());
}
}
else if (u_access.HasPriv("FOUNDER"))
{
- Log(LOG_COMMAND, source, this, ci) << "for " << target;
+ Anope::string mask = IRCD->NormalizeMask(target);
+
+ Log(LOG_COMMAND, source, this, ci) << "for " << mask;
int matched = 0, kicked = 0;
for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end;)
@@ -86,7 +94,8 @@ class CommandCSKick : public Command
ChanUserContainer *uc = it->second;
++it;
- if (Anope::Match(uc->user->nick, target) || Anope::Match(uc->user->GetDisplayedMask(), target))
+ Entry e("", mask);
+ if (e.Matches(uc->user))
{
++matched;
@@ -97,17 +106,22 @@ class CommandCSKick : public Command
continue;
++kicked;
+
if (ci->HasFieldS("SIGNKICK") || (ci->HasFieldS("SIGNKICK_LEVEL") && !u_access.HasPriv("SIGNKICK")))
- c->Kick(ci->WhoSends(), uc->user, "%s (Matches %s) (%s)", reason.c_str(), target.c_str(), source.GetNick().c_str());
+ {
+ reason += " (Matches " + mask + ")";
+ signkickformat = signkickformat.replace_all_cs("%m", reason);
+ c->Kick(ci->WhoSends(), uc->user, "%s", signkickformat.c_str());
+ }
else
- c->Kick(ci->WhoSends(), uc->user, "%s (Matches %s)", reason.c_str(), target.c_str());
+ c->Kick(ci->WhoSends(), uc->user, "%s (Matches %s)", reason.c_str(), mask.c_str());
}
}
if (matched)
- source.Reply(_("Kicked \002{0}/{1}\002 users matching \002{2}\002 from \002{3}\002."), kicked, matched, target, c->name);
+ source.Reply(_("Kicked \002{0}/{1}\002 users matching \002{2}\002 from \002{3}\002."), kicked, matched, mask, c->name);
else
- source.Reply(_("No users on\002{0}\002 match \002{1}\002."), c->name, target);
+ source.Reply(_("No users on\002{0}\002 match \002{1}\002."), c->name, mask);
}
else
source.Reply(_("\002{0}\002 isn't currently in use."), target);
diff --git a/modules/commands/cs_mode.cpp b/modules/commands/cs_mode.cpp
index 67d1e5faa..121179a58 100644
--- a/modules/commands/cs_mode.cpp
+++ b/modules/commands/cs_mode.cpp
@@ -479,7 +479,7 @@ class CommandCSMode : public Command
case '*':
if (adding == -1 || !has_access)
break;
- for (unsigned j = 0; j < ModeManager::GetChannelModes().size(); ++j)
+ for (unsigned j = 0; j < ModeManager::GetChannelModes().size() && ci->c; ++j)
{
ChannelMode *cm = ModeManager::GetChannelModes()[j];
@@ -912,7 +912,7 @@ class CSMode : public Module
}
else if (cm->type == MODE_PARAM)
{
- /* If the channel doesnt have the mode, or it does and it isn't set correctly */
+ /* If the channel doesn't have the mode, or it does and it isn't set correctly */
if (ml->GetSet())
{
Anope::string param;
@@ -947,16 +947,40 @@ class CSMode : public Module
for (unsigned i = 0; i < mlock.length(); ++i)
{
if (mlock[i] == '+')
+ {
add = true;
- else if (mlock[i] == '-')
+ continue;
+ }
+
+ if (mlock[i] == '-')
+ {
add = false;
- else
+ continue;
+ }
+
+ ChannelMode *cm = ModeManager::FindChannelModeByChar(mlock[i]);
+ if (!cm)
+ continue;
+
+ Anope::string param;
+ if (cm->type == MODE_PARAM)
{
- ChannelMode *cm = ModeManager::FindChannelModeByChar(mlock[i]);
- Anope::string param;
- if (cm && (cm->type == MODE_REGULAR || sep.GetToken(param)))
- mlocks->SetMLock(ci, cm, add, param);
+ ChannelModeParam *cmp = anope_dynamic_static_cast<ChannelModeParam *>(cm);
+ if (add || !cmp->minus_no_arg)
+ {
+ sep.GetToken(param);
+ if (param.empty() || !cmp->IsValid(param))
+ continue;
+ }
}
+ else if (cm->type != MODE_REGULAR)
+ {
+ sep.GetToken(param);
+ if (param.empty())
+ continue;
+ }
+
+ mlocks->SetMLock(ci, cm, add, param);
}
}
}
diff --git a/modules/commands/cs_set.cpp b/modules/commands/cs_set.cpp
index f7ee80050..06c996f52 100644
--- a/modules/commands/cs_set.cpp
+++ b/modules/commands/cs_set.cpp
@@ -850,7 +850,7 @@ class CommandCSSetSecureOps : public Command
bool OnHelp(CommandSource &source, const Anope::string &) override
{
source.Reply(_("Enables or disables the \002secure ops\002 option for \037channel\037."
- " When \002secure ops\002 is set, users will not be allowed to have channel operator status if they do not have the privileges to have it."));
+ " When \002secure ops\002 is set, users will not be allowed to have channel operator status if they do not have the privileges for it."));
return true;
}
};
@@ -1066,13 +1066,11 @@ class CommandCSSetNoexpire : public Command
class CSSet : public Module
, public EventHook<Event::CreateChan>
- , public EventHook<Event::ChannelCreate>
, public EventHook<Event::ChannelSync>
, public EventHook<Event::CheckKick>
, public EventHook<Event::DelChan>
, public EventHook<Event::ChannelModeSet>
, public EventHook<Event::ChannelModeUnset>
- , public EventHook<Event::CheckDelete>
, public EventHook<Event::JoinChannel>
, public EventHook<Event::SetCorrectModes>
, public EventHook<ChanServ::Event::PreChanExpire>
@@ -1097,6 +1095,8 @@ class CSSet : public Module
CommandCSSetSuccessor commandcssetsuccessor;
CommandCSSetNoexpire commandcssetnoexpire;
+ ExtensibleRef<bool> inhabit;
+
bool persist_lower_ts;
public:
@@ -1129,6 +1129,8 @@ class CSSet : public Module
, commandcssetsignkick(this)
, commandcssetsuccessor(this)
, commandcssetnoexpire(this)
+
+ , inhabit("inhabit")
{
}
@@ -1142,18 +1144,13 @@ class CSSet : public Module
ci->SetBanType(Config->GetModule(this)->Get<int>("defbantype", "2"));
}
- void OnChannelCreate(Channel *c) override
+ void OnChannelSync(Channel *c) override
{
if (c->ci && keep_modes.HasExt(c->ci))
for (ChanServ::Mode *m : c->ci->GetRefs<ChanServ::Mode *>(ChanServ::mode))
c->SetMode(c->ci->WhoSends(), m->GetMode(), m->GetParam());
}
- void OnChannelSync(Channel *c) override
- {
- OnChannelCreate(c);
- }
-
EventReturn OnCheckKick(User *u, Channel *c, Anope::string &mask, Anope::string &reason) override
{
if (!c->ci || !restricted.HasExt(c->ci) || c->MatchesList(u, "EXCEPT"))
@@ -1180,7 +1177,7 @@ class CSSet : public Module
if (mode->name == "PERM")
persist.Set(c->ci, true);
- if (mode->type != MODE_STATUS && !c->syncing && Me->IsSynced() && ChanServ::mode)
+ if (mode->type != MODE_STATUS && !c->syncing && Me->IsSynced() && ChanServ::mode && (!inhabit || !inhabit->HasExt(c)))
{
ChanServ::Mode *m = ChanServ::mode.Create();
m->SetChannel(c->ci);
@@ -1200,7 +1197,7 @@ class CSSet : public Module
persist.Unset(c->ci);
}
- if (c->ci && mode->type != MODE_STATUS && !c->syncing && Me->IsSynced())
+ if (c->ci && mode->type != MODE_STATUS && !c->syncing && Me->IsSynced() && (!inhabit || !inhabit->HasExt(c)))
for (ChanServ::Mode *m : c->ci->GetRefs<ChanServ::Mode *>(ChanServ::mode))
if (m->GetMode() == mode->name && m->GetParam().equals_ci(param))
m->Delete();
@@ -1208,13 +1205,6 @@ class CSSet : public Module
return EVENT_CONTINUE;
}
- EventReturn OnCheckDelete(Channel *c) override
- {
- if (c->ci && persist.HasExt(c->ci))
- return EVENT_STOP;
- return EVENT_CONTINUE;
- }
-
void OnJoinChannel(User *u, Channel *c) override
{
if (persist_lower_ts && c->ci && persist.HasExt(c->ci) && c->creation_time > c->ci->GetTimeRegistered())
diff --git a/modules/commands/cs_topic.cpp b/modules/commands/cs_topic.cpp
index 9e8b3764a..a132900a6 100644
--- a/modules/commands/cs_topic.cpp
+++ b/modules/commands/cs_topic.cpp
@@ -195,7 +195,7 @@ class CommandCSTopic : public Command
" The \002APPEND\002 command appends the given topic to the existing topic.\n"
"\n"
"\002LOCK\002 and \002UNLOCK\002 may be used to enable and disable topic lock."
- " When topic lock is set, the channel topic will be unchangeable except via this command.\n"
+ " When topic lock is set, the channel topic will be unchangeable by users who do not have the \002TOPIC\002 privilege.\n"
"\n"
"Use of this command requires the \002{0}\002 privilege on \037channel\037."),
"TOPIC");
@@ -235,7 +235,7 @@ class CSTopic : public Module
}
}
- void OnTopicUpdated(Channel *c, const Anope::string &user, const Anope::string &topic) override
+ void OnTopicUpdated(User *source, Channel *c, const Anope::string &user, const Anope::string &topic) override
{
if (!c->ci)
return;
@@ -245,7 +245,7 @@ class CSTopic : public Module
* This desyncs what is really set with what we have stored, and we end up resetting the topic often when
* it is not required
*/
- if (topiclock.HasExt(c->ci) && c->ci->GetLastTopic() != c->topic)
+ if (topiclock.HasExt(c->ci) && c->ci->GetLastTopic() != c->topic && (!source || !c->ci->AccessFor(source).HasPriv("TOPIC")))
{
c->ChangeTopic(c->ci->GetLastTopicSetter(), c->ci->GetLastTopic(), c->ci->GetLastTopicTime());
}
diff --git a/modules/commands/hs_del.cpp b/modules/commands/hs_del.cpp
index 4d7e7aac9..b45c10a61 100644
--- a/modules/commands/hs_del.cpp
+++ b/modules/commands/hs_del.cpp
@@ -101,7 +101,8 @@ class HSDel : public Module
, commandhsdelall(this, ondeletevhost)
, ondeletevhost(this)
{
-
+ if (!IRCD || !IRCD->CanSetVHost)
+ throw ModuleException("Your IRCd does not support vhosts");
}
};
diff --git a/modules/commands/hs_group.cpp b/modules/commands/hs_group.cpp
index 8a7a208a6..c3971fdea 100644
--- a/modules/commands/hs_group.cpp
+++ b/modules/commands/hs_group.cpp
@@ -86,6 +86,8 @@ class HSGroup : public Module
HSGroup(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
, commandhsgroup(this)
{
+ if (!IRCD || !IRCD->CanSetVHost)
+ throw ModuleException("Your IRCd does not support vhosts");
}
void OnSetVhost(NickServ::Nick *na) override
diff --git a/modules/commands/hs_list.cpp b/modules/commands/hs_list.cpp
index f363c81f7..738f9f1bd 100644
--- a/modules/commands/hs_list.cpp
+++ b/modules/commands/hs_list.cpp
@@ -151,6 +151,8 @@ class HSList : public Module
HSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
, commandhslist(this)
{
+ if (!IRCD || !IRCD->CanSetVHost)
+ throw ModuleException("Your IRCd does not support vhosts");
}
};
diff --git a/modules/commands/hs_off.cpp b/modules/commands/hs_off.cpp
index 6f88de67e..8f3c7e3da 100644
--- a/modules/commands/hs_off.cpp
+++ b/modules/commands/hs_off.cpp
@@ -31,6 +31,7 @@ class CommandHSOff : public Command
return;
}
+ u->vhost.clear();
IRCD->SendVhostDel(u);
Log(LOG_COMMAND, source, this) << "to disable their vhost";
source.Reply(_("Your vhost was removed and the normal cloaking restored."));
@@ -51,7 +52,8 @@ class HSOff : public Module
HSOff(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
, commandhsoff(this)
{
-
+ if (!IRCD || !IRCD->CanSetVHost)
+ throw ModuleException("Your IRCd does not support vhosts");
}
};
diff --git a/modules/commands/hs_on.cpp b/modules/commands/hs_on.cpp
index dcc134eef..409d56ac5 100644
--- a/modules/commands/hs_on.cpp
+++ b/modules/commands/hs_on.cpp
@@ -62,7 +62,8 @@ class HSOn : public Module
HSOn(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR)
, commandhson(this)
{
-
+ if (!IRCD || !IRCD->CanSetVHost)
+ throw ModuleException("Your IRCd does not support vhosts");
}
};
diff --git a/modules/commands/hs_set.cpp b/modules/commands/hs_set.cpp
index 33fa39950..a86afead4 100644
--- a/modules/commands/hs_set.cpp
+++ b/modules/commands/hs_set.cpp
@@ -208,7 +208,8 @@ class HSSet : public Module
, commandhsset(this)
, commandhssetall(this)
{
-
+ if (!IRCD || !IRCD->CanSetVHost)
+ throw ModuleException("Your IRCd does not support vhosts");
}
};
diff --git a/modules/commands/ms_read.cpp b/modules/commands/ms_read.cpp
index 9af997789..687843124 100644
--- a/modules/commands/ms_read.cpp
+++ b/modules/commands/ms_read.cpp
@@ -29,14 +29,14 @@ static void rsend_notify(CommandSource &source, MemoServ::MemoInfo *mi, MemoServ
if (!nc)
return;
- /* Text of the memo varies if the recepient was a
+ /* Text of the memo varies if the recipient was a
nick or channel */
Anope::string text = Anope::printf(Language::Translate(na->GetAccount(), _("\002[auto-memo]\002 The memo you sent to \002%s\002 has been viewed.")), targ.c_str());
/* Send notification */
MemoServ::service->Send(source.GetNick(), m->GetSender(), text, true);
- /* Notify recepient of the memo that a notification has
+ /* Notify recipient of the memo that a notification has
been sent to the sender */
source.Reply(_("A notification memo has been sent to \002{0}\002 informing him/her you have read his/her memo."), nc->GetDisplay());
}
diff --git a/modules/commands/ms_set.cpp b/modules/commands/ms_set.cpp
index 94e7f2e26..c924d0ea0 100644
--- a/modules/commands/ms_set.cpp
+++ b/modules/commands/ms_set.cpp
@@ -254,7 +254,7 @@ class CommandMSSet : public Command
" NEW You will only be notified of memos when they\n"
" are sent to you.\n"
"\n"
- " MAIL You will be notified of memos by email aswell as\n"
+ " MAIL You will be notified of memos by email as well as\n"
" any other settings you have.\n"
"\n"
" NOMAIL You will not be notified of memos by email.\n"
diff --git a/modules/commands/ns_alist.cpp b/modules/commands/ns_alist.cpp
index 01a0419b7..e4aaff38b 100644
--- a/modules/commands/ns_alist.cpp
+++ b/modules/commands/ns_alist.cpp
@@ -75,7 +75,7 @@ class CommandNSAList : public Command
continue;
}
- ChanServ::AccessGroup access = ci->AccessFor(nc);
+ ChanServ::AccessGroup access = ci->AccessFor(nc, false);
if (access.empty())
continue;
diff --git a/modules/commands/ns_identify.cpp b/modules/commands/ns_identify.cpp
index 2a2b468bf..122378d8a 100644
--- a/modules/commands/ns_identify.cpp
+++ b/modules/commands/ns_identify.cpp
@@ -89,8 +89,16 @@ class CommandNSIdentify : public Command
return;
}
+ unsigned int maxlogins = Config->GetModule(this->owner)->Get<unsigned int>("maxlogins");
+ if (na && maxlogins && na->GetAccount()->users.size() >= maxlogins)
+ {
+ source.Reply(_("Account \002{0}\002 has already reached the maximum number of simultaneous logins ({1})."), na->GetAccount()->GetDisplay(), maxlogins);
+ return;
+ }
+
NickServ::IdentifyRequest *req = NickServ::service->CreateIdentifyRequest(new NSIdentifyRequestListener(source, this), owner, na ? na->GetAccount()->GetDisplay() : nick, pass);
Event::OnCheckAuthentication(&Event::CheckAuthentication::OnCheckAuthentication, u, req);
+
req->Dispatch();
}
diff --git a/modules/commands/ns_logout.cpp b/modules/commands/ns_logout.cpp
index f63086789..9bcb543fc 100644
--- a/modules/commands/ns_logout.cpp
+++ b/modules/commands/ns_logout.cpp
@@ -46,8 +46,10 @@ class CommandNSLogout : public Command
return;
}
+#if 0
if (!nick.empty() && !param.empty() && param.equals_ci("REVALIDATE") && NickServ::service)
NickServ::service->Validate(u2);
+#endif
u2->super_admin = false; /* Dont let people logout and remain a SuperAdmin */
Log(LOG_COMMAND, source, this) << "to logout " << u2->nick;
diff --git a/modules/commands/ns_register.cpp b/modules/commands/ns_register.cpp
index 5d52feda4..c7e6e5af2 100644
--- a/modules/commands/ns_register.cpp
+++ b/modules/commands/ns_register.cpp
@@ -155,6 +155,12 @@ class CommandNSRegister : public Command
return;
}
+ if (ServiceBot::Find(u_nick, true))
+ {
+ source.Reply(_("\002{0}\002 may not be registered."), u_nick);
+ return;
+ }
+
if (Config->GetModule("nickserv")->Get<bool>("restrictopernicks"))
for (Oper *o : Serialize::GetObjects<Oper *>(operblock))
{
@@ -165,6 +171,8 @@ class CommandNSRegister : public Command
}
}
+ unsigned int passlen = Config->GetModule("nickserv")->Get<unsigned>("passlen", "32");
+
if (Config->GetModule("nickserv")->Get<bool>("forceemail", "yes") && email.empty())
{
this->OnSyntaxError(source, "");
diff --git a/modules/commands/ns_set.cpp b/modules/commands/ns_set.cpp
index 9f1e16778..a75386743 100644
--- a/modules/commands/ns_set.cpp
+++ b/modules/commands/ns_set.cpp
@@ -404,10 +404,12 @@ class CommandNSSetEmail : public Command
message = Config->GetBlock("mail")->Get<Anope::string>("emailchange_message");
subject = subject.replace_all_cs("%e", u->Account()->GetEmail());
+ subject = subject.replace_all_cs("%E", new_email);
subject = subject.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<Anope::string>("networkname"));
subject = subject.replace_all_cs("%c", code);
message = message.replace_all_cs("%e", u->Account()->GetEmail());
+ message = message.replace_all_cs("%E", new_email);
message = message.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<Anope::string>("networkname"));
message = message.replace_all_cs("%c", code);
diff --git a/modules/commands/os_mode.cpp b/modules/commands/os_mode.cpp
index d4551e69f..30e1d502b 100644
--- a/modules/commands/os_mode.cpp
+++ b/modules/commands/os_mode.cpp
@@ -26,7 +26,7 @@ class CommandOSMode : public Command
const Anope::string &target = params[0];
const Anope::string &modes = params[1];
- Channel *c = Channel::Find(target);
+ Reference<Channel> c = Channel::Find(target);
if (!c)
source.Reply(_("Channel \002{0}\002 doesn't exist."), target);
else if (c->bouncy_modes)
@@ -36,9 +36,15 @@ class CommandOSMode : public Command
bool all = params.size() > 2 && params[2].equals_ci("ALL");
const Channel::ModeList chmodes = c->GetModes();
- for (Channel::ModeList::const_iterator it = chmodes.begin(), it_end = chmodes.end(); it != it_end; ++it)
+ for (Channel::ModeList::const_iterator it = chmodes.begin(), it_end = chmodes.end(); it != it_end && c; ++it)
c->RemoveMode(c->ci->WhoSends(), it->first, it->second, false);
+ if (!c)
+ {
+ source.Reply(_("Modes cleared on %s and the channel destroyed."), target.c_str());
+ return;
+ }
+
if (all)
{
for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; ++it)
@@ -65,7 +71,7 @@ class CommandOSMode : public Command
Anope::string log_modes, log_params;
sep.GetToken(mode);
- for (unsigned i = 0; i < mode.length(); ++i)
+ for (unsigned i = 0; i < mode.length() && c; ++i)
{
char ch = mode[i];
@@ -116,7 +122,7 @@ class CommandOSMode : public Command
}
if (!log_modes.replace_all_cs("+", "").replace_all_cs("-", "").empty())
- Log(LOG_ADMIN, source, this) << log_modes << log_params << " on " << c->name;
+ Log(LOG_ADMIN, source, this) << log_modes << log_params << " on " << (c ? c->name : target);
}
}
diff --git a/modules/database/db_flatfile.cpp b/modules/database/db_flatfile.cpp
index 2486a2307..122134960 100644
--- a/modules/database/db_flatfile.cpp
+++ b/modules/database/db_flatfile.cpp
@@ -57,7 +57,7 @@ class DBFlatFile : public Module
Anope::string err = Anope::LastError();
Log(this) << "Unable to back up database " << *it << " (" << err << ")!";
- if (!Config->GetModule(this)->Get<bool>("nobackupok"))
+ if (!Config->GetModule(this)->Get<bool>("nobackupokay"))
{
Anope::Quitting = true;
Anope::QuitReason = "Unable to back up database " + *it + " (" + err + ")";
diff --git a/modules/database/db_old.cpp b/modules/database/db_old.cpp
index dff08250e..3d9b92922 100644
--- a/modules/database/db_old.cpp
+++ b/modules/database/db_old.cpp
@@ -723,7 +723,7 @@ static void LoadVHosts()
NickServ::Nick *na = NickServ::FindNick(nick);
if (na == NULL)
{
- Log() << "Removing vhost for nonexistant nick " << nick;
+ Log() << "Removing vhost for non-existent nick " << nick;
continue;
}
diff --git a/modules/extra/m_ldap.cpp b/modules/extra/m_ldap.cpp
index 8309a5cc5..71c31b9ac 100644
--- a/modules/extra/m_ldap.cpp
+++ b/modules/extra/m_ldap.cpp
@@ -1,3 +1,14 @@
+/*
+ *
+ * (C) 2011-2015 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ */
+
/* RequiredLibraries: ldap_r,lber */
/* RequiredWindowsLibraries: libldap_r,liblber */
@@ -5,21 +16,136 @@
#include "modules/ldap.h"
#include <ldap.h>
+class LDAPService;
static Pipe *me;
+class LDAPRequest
+{
+ public:
+ LDAPService *service;
+ LDAPInterface *inter;
+ LDAPMessage *message; /* message returned by ldap_ */
+ LDAPResult *result; /* final result */
+ struct timeval tv;
+ QueryType type;
+
+ LDAPRequest(LDAPService *s, LDAPInterface *i)
+ : service(s)
+ , inter(i)
+ , message(NULL)
+ , result(NULL)
+ {
+ type = QUERY_UNKNOWN;
+ tv.tv_sec = 0;
+ tv.tv_usec = 100000;
+ }
+
+ virtual ~LDAPRequest()
+ {
+ delete result;
+ if (inter != NULL)
+ inter->OnDelete();
+ if (message != NULL)
+ ldap_msgfree(message);
+ }
+
+ virtual int run() = 0;
+};
+
+class LDAPBind : public LDAPRequest
+{
+ Anope::string who, pass;
+
+ public:
+ LDAPBind(LDAPService *s, LDAPInterface *i, const Anope::string &w, const Anope::string &p)
+ : LDAPRequest(s, i)
+ , who(w)
+ , pass(p)
+ {
+ type = QUERY_BIND;
+ }
+
+ int run() anope_override;
+};
+
+class LDAPSearch : public LDAPRequest
+{
+ Anope::string base;
+ Anope::string filter;
+
+ public:
+ LDAPSearch(LDAPService *s, LDAPInterface *i, const Anope::string &b, const Anope::string &f)
+ : LDAPRequest(s, i)
+ , base(b)
+ , filter(f)
+ {
+ type = QUERY_SEARCH;
+ }
+
+ int run() anope_override;
+};
+
+class LDAPAdd : public LDAPRequest
+{
+ Anope::string dn;
+ LDAPMods attributes;
+
+ public:
+ LDAPAdd(LDAPService *s, LDAPInterface *i, const Anope::string &d, const LDAPMods &attr)
+ : LDAPRequest(s, i)
+ , dn(d)
+ , attributes(attr)
+ {
+ type = QUERY_ADD;
+ }
+
+ int run() anope_override;
+};
+
+class LDAPDel : public LDAPRequest
+{
+ Anope::string dn;
+
+ public:
+ LDAPDel(LDAPService *s, LDAPInterface *i, const Anope::string &d)
+ : LDAPRequest(s, i)
+ , dn(d)
+ {
+ type = QUERY_DELETE;
+ }
+
+ int run() anope_override;
+};
+
+class LDAPModify : public LDAPRequest
+{
+ Anope::string base;
+ LDAPMods attributes;
+
+ public:
+ LDAPModify(LDAPService *s, LDAPInterface *i, const Anope::string &b, const LDAPMods &attr)
+ : LDAPRequest(s, i)
+ , base(b)
+ , attributes(attr)
+ {
+ type = QUERY_MODIFY;
+ }
+
+ int run() anope_override;
+};
+
class LDAPService : public LDAPProvider, public Thread, public Condition
{
Anope::string server;
- int port;
Anope::string admin_binddn;
Anope::string admin_pass;
- time_t timeout;
LDAP *con;
time_t last_connect;
- LDAPMod **BuildMods(const LDAPMods &attributes)
+ public:
+ static LDAPMod **BuildMods(const LDAPMods &attributes)
{
LDAPMod **mods = new LDAPMod*[attributes.size() + 1];
memset(mods, 0, sizeof(LDAPMod*) * (attributes.size() + 1));
@@ -46,7 +172,7 @@ class LDAPService : public LDAPProvider, public Thread, public Condition
return mods;
}
- void FreeMods(LDAPMod **mods)
+ static void FreeMods(LDAPMod **mods)
{
for (int i = 0; mods[i] != NULL; ++i)
{
@@ -58,26 +184,8 @@ class LDAPService : public LDAPProvider, public Thread, public Condition
delete [] mods;
}
- void Reconnect()
- {
- /* Only try one connect a minute. It is an expensive blocking operation */
- if (last_connect > Anope::CurTime - 60)
- throw LDAPException("Unable to connect to LDAP service " + this->name + ": reconnecting too fast");
- last_connect = Anope::CurTime;
-
- ldap_unbind_ext(this->con, NULL, NULL);
- int i = ldap_initialize(&this->con, this->server.c_str());
- if (i != LDAP_SUCCESS)
- throw LDAPException("Unable to connect to LDAP service " + this->name + ": " + ldap_err2string(i));
- }
-
- public:
- typedef std::map<LDAPQuery, std::pair<time_t, LDAPInterface *> > query_queue;
- typedef std::vector<std::pair<LDAPInterface *, LDAPResult *> > result_queue;
- query_queue queries;
- result_queue results;
-
- LDAPService(Module *o, const Anope::string &n, const Anope::string &s, int po, const Anope::string &b, const Anope::string &p, time_t t) : LDAPProvider(o, n), server(s), port(po), admin_binddn(b), admin_pass(p), timeout(t), last_connect(0)
+ private:
+ void Connect()
{
int i = ldap_initialize(&this->con, this->server.c_str());
if (i != LDAP_SUCCESS)
@@ -94,366 +202,243 @@ class LDAPService : public LDAPProvider, public Thread, public Condition
throw LDAPException("Unable to set timeout for " + this->name + ": " + ldap_err2string(i));
}
+ void Reconnect()
+ {
+ /* Only try one connect a minute. It is an expensive blocking operation */
+ if (last_connect > Anope::CurTime - 60)
+ throw LDAPException("Unable to connect to LDAP service " + this->name + ": reconnecting too fast");
+ last_connect = Anope::CurTime;
+
+ ldap_unbind_ext(this->con, NULL, NULL);
+
+ Connect();
+ }
+
+ void QueueRequest(LDAPRequest *r)
+ {
+ this->Lock();
+ this->queries.push_back(r);
+ this->Wakeup();
+ this->Unlock();
+ }
+
+ public:
+ typedef std::vector<LDAPRequest *> query_queue;
+ query_queue queries, results;
+ Mutex process_mutex; /* held when processing requests not in either queue */
+
+ LDAPService(Module *o, const Anope::string &n, const Anope::string &s, const Anope::string &b, const Anope::string &p) : LDAPProvider(o, n), server(s), admin_binddn(b), admin_pass(p), last_connect(0)
+ {
+ Connect();
+ }
+
~LDAPService()
{
+ /* At this point the thread has stopped so we don't need to hold process_mutex */
+
this->Lock();
- for (query_queue::iterator it = this->queries.begin(), it_end = this->queries.end(); it != it_end; ++it)
+ for (unsigned int i = 0; i < this->queries.size(); ++i)
{
- LDAPQuery msgid = it->first;
- LDAPInterface *i = it->second.second;
+ LDAPRequest *req = this->queries[i];
+
+ /* queries have no results yet */
+ req->result = new LDAPResult();
+ req->result->type = req->type;
+ req->result->error = "LDAP Interface is going away";
+ if (req->inter)
+ req->inter->OnError(*req->result);
- ldap_abandon_ext(this->con, msgid, NULL, NULL);
- if (i)
- i->OnDelete();
+ delete req;
}
this->queries.clear();
- for (result_queue::iterator it = this->results.begin(), it_end = this->results.end(); it != it_end; ++it)
+ for (unsigned int i = 0; i < this->results.size(); ++i)
{
- LDAPInterface *i = it->first;
- LDAPResult *r = it->second;
+ LDAPRequest *req = this->results[i];
- r->error = "LDAP Interface is going away";
- if (i)
- i->OnError(*r);
+ /* even though this may have already finished successfully we return that it didn't */
+ req->result->error = "LDAP Interface is going away";
+ if (req->inter)
+ req->inter->OnError(*req->result);
- delete r;
+ delete req;
}
- this->results.clear();
this->Unlock();
ldap_unbind_ext(this->con, NULL, NULL);
}
-
- LDAPQuery BindAsAdmin(LDAPInterface *i)
+
+ void BindAsAdmin(LDAPInterface *i) override
{
- return this->Bind(i, this->admin_binddn, this->admin_pass);
+ this->Bind(i, this->admin_binddn, this->admin_pass);
}
- LDAPQuery Bind(LDAPInterface *i, const Anope::string &who, const Anope::string &pass) override
+ void Bind(LDAPInterface *i, const Anope::string &who, const Anope::string &pass) override
{
- berval cred;
- cred.bv_val = strdup(pass.c_str());
- cred.bv_len = pass.length();
-
- LDAPQuery msgid;
- int ret = ldap_sasl_bind(con, who.c_str(), LDAP_SASL_SIMPLE, &cred, NULL, NULL, &msgid);
- free(cred.bv_val);
- if (ret != LDAP_SUCCESS)
- {
- if (ret == LDAP_SERVER_DOWN || ret == LDAP_TIMEOUT)
- {
- this->Reconnect();
- return this->Bind(i, who, pass);
- }
- else
- throw LDAPException(ldap_err2string(ret));
- }
-
- if (i != NULL)
- {
- this->Lock();
- this->queries[msgid] = std::make_pair(Anope::CurTime, i);
- this->Unlock();
- }
- this->Wakeup();
-
- return msgid;
+ LDAPBind *b = new LDAPBind(this, i, who, pass);
+ QueueRequest(b);
}
- LDAPQuery Search(LDAPInterface *i, const Anope::string &base, const Anope::string &filter) override
+ void Search(LDAPInterface *i, const Anope::string &base, const Anope::string &filter) override
{
if (i == NULL)
throw LDAPException("No interface");
- LDAPQuery msgid;
- int ret = ldap_search_ext(this->con, base.c_str(), LDAP_SCOPE_SUBTREE, filter.c_str(), NULL, 0, NULL, NULL, NULL, 0, &msgid);
- if (ret != LDAP_SUCCESS)
- {
- if (ret == LDAP_SERVER_DOWN || ret == LDAP_TIMEOUT)
- {
- this->Reconnect();
- return this->Search(i, base, filter);
- }
- else
- throw LDAPException(ldap_err2string(ret));
- }
-
- this->Lock();
- this->queries[msgid] = std::make_pair(Anope::CurTime, i);
- this->Unlock();
- this->Wakeup();
-
- return msgid;
+ LDAPSearch *s = new LDAPSearch(this, i, base, filter);
+ QueueRequest(s);
}
- LDAPQuery Add(LDAPInterface *i, const Anope::string &dn, LDAPMods &attributes) override
+ void Add(LDAPInterface *i, const Anope::string &dn, LDAPMods &attributes) override
{
- LDAPMod **mods = this->BuildMods(attributes);
- LDAPQuery msgid;
- int ret = ldap_add_ext(this->con, dn.c_str(), mods, NULL, NULL, &msgid);
- this->FreeMods(mods);
-
- if (ret != LDAP_SUCCESS)
- {
- if (ret == LDAP_SERVER_DOWN || ret == LDAP_TIMEOUT)
- {
- this->Reconnect();
- return this->Add(i, dn, attributes);
- }
- else
- throw LDAPException(ldap_err2string(ret));
- }
+ LDAPAdd *add = new LDAPAdd(this, i, dn, attributes);
+ QueueRequest(add);
+ }
- if (i != NULL)
- {
- this->Lock();
- this->queries[msgid] = std::make_pair(Anope::CurTime, i);
- this->Unlock();
- }
- this->Wakeup();
+ void Del(LDAPInterface *i, const Anope::string &dn) anope_override
+ {
+ LDAPDel *del = new LDAPDel(this, i, dn);
+ QueueRequest(del);
+ }
- return msgid;
+ void Modify(LDAPInterface *i, const Anope::string &base, LDAPMods &attributes) anope_override
+ {
+ LDAPModify *mod = new LDAPModify(this, i, base, attributes);
+ QueueRequest(mod);
}
- LDAPQuery Del(LDAPInterface *i, const Anope::string &dn) override
+ private:
+ void BuildReply(int res, LDAPRequest *req)
{
- LDAPQuery msgid;
- int ret = ldap_delete_ext(this->con, dn.c_str(), NULL, NULL, &msgid);
+ LDAPResult *ldap_result = req->result = new LDAPResult();
+ req->result->type = req->type;
- if (ret != LDAP_SUCCESS)
+ if (res != LDAP_SUCCESS)
{
- if (ret == LDAP_SERVER_DOWN || ret == LDAP_TIMEOUT)
- {
- this->Reconnect();
- return this->Del(i, dn);
- }
- else
- throw LDAPException(ldap_err2string(ret));
+ ldap_result->error = ldap_err2string(res);
+ return;
}
- if (i != NULL)
+ if (req->message == NULL)
{
- this->Lock();
- this->queries[msgid] = std::make_pair(Anope::CurTime, i);
- this->Unlock();
+ return;
}
- this->Wakeup();
- return msgid;
- }
+ /* a search result */
- LDAPQuery Modify(LDAPInterface *i, const Anope::string &base, LDAPMods &attributes) override
- {
- LDAPMod **mods = this->BuildMods(attributes);
- LDAPQuery msgid;
- int ret = ldap_modify_ext(this->con, base.c_str(), mods, NULL, NULL, &msgid);
- this->FreeMods(mods);
-
- if (ret != LDAP_SUCCESS)
+ for (LDAPMessage *cur = ldap_first_message(this->con, req->message); cur; cur = ldap_next_message(this->con, cur))
{
- if (ret == LDAP_SERVER_DOWN || ret == LDAP_TIMEOUT)
+ LDAPAttributes attributes;
+
+ char *dn = ldap_get_dn(this->con, cur);
+ if (dn != NULL)
{
- this->Reconnect();
- return this->Modify(i, base, attributes);
+ attributes["dn"].push_back(dn);
+ ldap_memfree(dn);
+ dn = NULL;
}
- else
- throw LDAPException(ldap_err2string(ret));
- }
-
- if (i != NULL)
- {
- this->Lock();
- this->queries[msgid] = std::make_pair(Anope::CurTime, i);
- this->Unlock();
- }
- this->Wakeup();
-
- return msgid;
- }
- private:
- void Timeout()
- {
- this->Lock();
- for (query_queue::iterator it = this->queries.begin(), it_end = this->queries.end(); it != it_end;)
- {
- LDAPQuery msgid = it->first;
- time_t created = it->second.first;
- LDAPInterface *i = it->second.second;
- ++it;
+ BerElement *ber = NULL;
- if (Anope::CurTime > created + timeout)
+ for (char *attr = ldap_first_attribute(this->con, cur, &ber); attr; attr = ldap_next_attribute(this->con, cur, ber))
{
- LDAPResult *ldap_result = new LDAPResult();
- ldap_result->id = msgid;
- ldap_result->error = "Query timed out";
+ berval **vals = ldap_get_values_len(this->con, cur, attr);
+ int count = ldap_count_values_len(vals);
- this->queries.erase(msgid);
- this->results.push_back(std::make_pair(i, ldap_result));
+ std::vector<Anope::string> attrs;
+ for (int j = 0; j < count; ++j)
+ attrs.push_back(vals[j]->bv_val);
+ attributes[attr] = attrs;
- me->Notify();
+ ldap_value_free_len(vals);
+ ldap_memfree(attr);
}
+
+ if (ber != NULL)
+ ber_free(ber, 0);
+
+ ldap_result->messages.push_back(attributes);
}
- this->Unlock();
}
- public:
- void Run() override
+ void SendRequests()
{
- while (!this->GetExitState())
- {
- if (this->queries.empty())
- {
- this->Lock();
- this->Wait();
- this->Unlock();
- continue;
- }
- else
- this->Timeout();
-
- struct timeval tv = { 1, 0 };
- LDAPMessage *result;
- int rtype = ldap_result(this->con, LDAP_RES_ANY, 1, &tv, &result);
- if (rtype <= 0)
- continue;
-
- int cur_id = ldap_msgid(result);
-
- this->Lock();
+ process_mutex.Lock();
- query_queue::iterator it = this->queries.find(cur_id);
- if (it == this->queries.end())
- {
- this->Unlock();
- ldap_msgfree(result);
- continue;
- }
- LDAPInterface *i = it->second.second;
- this->queries.erase(it);
+ query_queue q;
+ this->Lock();
+ queries.swap(q);
+ this->Unlock();
- this->Unlock();
+ if (q.empty())
+ {
+ process_mutex.Unlock();
+ return;
+ }
- LDAPResult *ldap_result = new LDAPResult();
- ldap_result->id = cur_id;
+ for (unsigned int i = 0; i < q.size(); ++i)
+ {
+ LDAPRequest *req = q[i];
+ int ret = req->run();
- for (LDAPMessage *cur = ldap_first_message(this->con, result); cur; cur = ldap_next_message(this->con, cur))
+ if (ret == LDAP_SERVER_DOWN || ret == LDAP_TIMEOUT)
{
- int cur_type = ldap_msgtype(cur);
-
- LDAPAttributes attributes;
-
- char *dn = ldap_get_dn(this->con, cur);
- if (dn != NULL)
- {
- attributes["dn"].push_back(dn);
- ldap_memfree(dn);
- dn = NULL;
- }
-
- switch (cur_type)
+ /* try again */
+ try
{
- case LDAP_RES_BIND:
- ldap_result->type = LDAPResult::QUERY_BIND;
- break;
- case LDAP_RES_SEARCH_ENTRY:
- ldap_result->type = LDAPResult::QUERY_SEARCH;
- break;
- case LDAP_RES_ADD:
- ldap_result->type = LDAPResult::QUERY_ADD;
- break;
- case LDAP_RES_DELETE:
- ldap_result->type = LDAPResult::QUERY_DELETE;
- break;
- case LDAP_RES_MODIFY:
- ldap_result->type = LDAPResult::QUERY_MODIFY;
- break;
- case LDAP_RES_SEARCH_RESULT:
- // If we get here and ldap_result->type is LDAPResult::QUERY_UNKNOWN
- // then the result set is empty
- ldap_result->type = LDAPResult::QUERY_SEARCH;
- break;
- default:
- Log(LOG_DEBUG) << "m_ldap: Unknown msg type " << cur_type;
- continue;
+ Reconnect();
}
-
- switch (cur_type)
+ catch (const LDAPException &)
{
- case LDAP_RES_BIND:
- {
- int errcode = -1;
- int parse_result = ldap_parse_result(this->con, cur, &errcode, NULL, NULL, NULL, NULL, 0);
- if (parse_result != LDAP_SUCCESS)
- ldap_result->error = ldap_err2string(parse_result);
- else if (errcode != LDAP_SUCCESS)
- ldap_result->error = ldap_err2string(errcode);
- break;
- }
- case LDAP_RES_SEARCH_ENTRY:
- {
- BerElement *ber = NULL;
- for (char *attr = ldap_first_attribute(this->con, cur, &ber); attr; attr = ldap_next_attribute(this->con, cur, ber))
- {
- berval **vals = ldap_get_values_len(this->con, cur, attr);
- int count = ldap_count_values_len(vals);
-
- std::vector<Anope::string> attrs;
- for (int j = 0; j < count; ++j)
- attrs.push_back(vals[j]->bv_val);
- attributes[attr] = attrs;
-
- ldap_value_free_len(vals);
- ldap_memfree(attr);
- }
- if (ber != NULL)
- ber_free(ber, 0);
-
- break;
- }
- case LDAP_RES_ADD:
- case LDAP_RES_DELETE:
- case LDAP_RES_MODIFY:
- {
- int errcode = -1;
- int parse_result = ldap_parse_result(this->con, cur, &errcode, NULL, NULL, NULL, NULL, 0);
- if (parse_result != LDAP_SUCCESS)
- ldap_result->error = ldap_err2string(parse_result);
- else if (errcode != LDAP_SUCCESS)
- ldap_result->error = ldap_err2string(errcode);
- break;
- }
- default:
- continue;
}
- ldap_result->messages.push_back(attributes);
+ ret = req->run();
}
- ldap_msgfree(result);
+ BuildReply(ret, req);
+
+ this->Lock();
+ results.push_back(req);
+ this->Unlock();
+ }
+
+ me->Notify();
+
+ process_mutex.Unlock();
+ }
+ public:
+ void Run() anope_override
+ {
+ while (!this->GetExitState())
+ {
this->Lock();
- this->results.push_back(std::make_pair(i, ldap_result));
+ /* Queries can be non empty if one is pushed during SendRequests() */
+ if (queries.empty())
+ this->Wait();
this->Unlock();
- me->Notify();
+ SendRequests();
}
}
+
+ LDAP* GetConnection()
+ {
+ return con;
+ }
};
class ModuleLDAP : public Module, public Pipe
, public EventHook<Event::ModuleUnload>
{
std::map<Anope::string, LDAPService *> LDAPServices;
+
public:
ModuleLDAP(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR)
{
me = this;
-
}
~ModuleLDAP()
@@ -490,6 +475,8 @@ class ModuleLDAP : public Module, public Pipe
s->SetExitState();
s->Wakeup();
+ s->Join();
+ delete s;
this->LDAPServices.erase(cname);
}
}
@@ -503,14 +490,12 @@ class ModuleLDAP : public Module, public Pipe
if (this->LDAPServices.find(connname) == this->LDAPServices.end())
{
const Anope::string &server = ldap->Get<Anope::string>("server", "127.0.0.1");
- int port = ldap->Get<int>("port", "389");
const Anope::string &admin_binddn = ldap->Get<Anope::string>("admin_binddn");
- const Anope::string &admin_password = ldap->Get<Anope::string>("admin_password");
- time_t timeout = ldap->Get<time_t>("timeout", "5");
+ const Anope::string &admin_password = ldap->GetAnope::string>("admin_password");
try
{
- LDAPService *ss = new LDAPService(this, connname, server, port, admin_binddn, admin_password, timeout);
+ LDAPService *ss = new LDAPService(this, connname, server, admin_binddn, admin_password);
ss->Start();
this->LDAPServices.insert(std::make_pair(connname, ss));
@@ -529,31 +514,35 @@ class ModuleLDAP : public Module, public Pipe
for (std::map<Anope::string, LDAPService *>::iterator it = this->LDAPServices.begin(); it != this->LDAPServices.end(); ++it)
{
LDAPService *s = it->second;
+
+ s->process_mutex.Lock();
s->Lock();
- for (LDAPService::query_queue::iterator it2 = s->queries.begin(); it2 != s->queries.end();)
+
+ for (unsigned int i = s->queries.size(); i > 0; --i)
{
- LDAPQuery msgid = it2->first;
- LDAPInterface *i = it2->second.second;
- ++it2;
+ LDAPRequest *req = s->queries[i - 1];
+ LDAPInterface *li = req->inter;
- if (i && i->owner == m)
+ if (li && li->owner == m)
{
- i->OnDelete();
- s->queries.erase(msgid);
+ s->queries.erase(s->queries.begin() + i - 1);
+ delete req;
}
}
- for (unsigned i = s->results.size(); i > 0; --i)
+ for (unsigned int i = s->results.size(); i > 0; --i)
{
- LDAPInterface *li = s->results[i - 1].first;
- LDAPResult *r = s->results[i - 1].second;
+ LDAPRequest *req = s->results[i - 1];
+ LDAPInterface *li = req->inter;
if (li && li->owner == m)
{
s->results.erase(s->results.begin() + i - 1);
- delete r;
+ delete req;
}
}
+
s->Unlock();
+ s->process_mutex.Unlock();
}
}
@@ -563,15 +552,16 @@ class ModuleLDAP : public Module, public Pipe
{
LDAPService *s = it->second;
- LDAPService::result_queue results;
+ LDAPService::query_queue results;
s->Lock();
results.swap(s->results);
s->Unlock();
- for (unsigned i = 0; i < results.size(); ++i)
+ for (unsigned int i = 0; i < results.size(); ++i)
{
- LDAPInterface *li = results[i].first;
- LDAPResult *r = results[i].second;
+ LDAPRequest *req = results[i];
+ LDAPInterface *li = req->inter;
+ LDAPResult *r = req->result;
if (li != NULL)
{
@@ -584,11 +574,50 @@ class ModuleLDAP : public Module, public Pipe
li->OnResult(*r);
}
- delete r;
+ delete req;
}
}
}
};
+int LDAPBind::run()
+{
+ berval cred;
+ cred.bv_val = strdup(pass.c_str());
+ cred.bv_len = pass.length();
+
+ int i = ldap_sasl_bind_s(service->GetConnection(), who.c_str(), LDAP_SASL_SIMPLE, &cred, NULL, NULL, NULL);
+
+ free(cred.bv_val);
+
+ return i;
+}
+
+int LDAPSearch::run()
+{
+ return ldap_search_ext_s(service->GetConnection(), base.c_str(), LDAP_SCOPE_SUBTREE, filter.c_str(), NULL, 0, NULL, NULL, &tv, 0, &message);
+}
+
+int LDAPAdd::run()
+{
+ LDAPMod **mods = LDAPService::BuildMods(attributes);
+ int i = ldap_add_ext_s(service->GetConnection(), dn.c_str(), mods, NULL, NULL);
+ LDAPService::FreeMods(mods);
+ return i;
+}
+
+int LDAPDel::run()
+{
+ return ldap_delete_ext_s(service->GetConnection(), dn.c_str(), NULL, NULL);
+}
+
+int LDAPModify::run()
+{
+ LDAPMod **mods = LDAPService::BuildMods(attributes);
+ int i = ldap_modify_ext_s(service->GetConnection(), base.c_str(), mods, NULL, NULL);
+ LDAPService::FreeMods(mods);
+ return i;
+}
+
MODULE_INIT(ModuleLDAP)
diff --git a/modules/extra/m_ldap_authentication.cpp b/modules/extra/m_ldap_authentication.cpp
index f5b03a606..dd63fd3fb 100644
--- a/modules/extra/m_ldap_authentication.cpp
+++ b/modules/extra/m_ldap_authentication.cpp
@@ -31,36 +31,29 @@ struct IdentifyInfo
class IdentifyInterface : public LDAPInterface
{
- std::map<LDAPQuery, IdentifyInfo *> requests;
+ IdentifyInfo *ii;
public:
- IdentifyInterface(Module *m) : LDAPInterface(m) { }
+ IdentifyInterface(Module *m, IdentifyInfo *i) : LDAPInterface(m), ii(i) { }
- void Add(LDAPQuery id, IdentifyInfo *ii)
+ ~IdentifyInterface()
{
- std::map<LDAPQuery, IdentifyInfo *>::iterator it = this->requests.find(id);
- if (it != this->requests.end())
- delete it->second;
- this->requests[id] = ii;
+ delete ii;
}
- void OnResult(const LDAPResult &r) override
+ void OnDelete() anope_override
{
- std::map<LDAPQuery, IdentifyInfo *>::iterator it = this->requests.find(r.id);
- if (it == this->requests.end())
- return;
- IdentifyInfo *ii = it->second;
- this->requests.erase(it);
+ delete this;
+ }
+ void OnResult(const LDAPResult &r) override
+ {
if (!ii->lprov)
- {
- delete ii;
return;
- }
switch (r.type)
{
- case LDAPResult::QUERY_SEARCH:
+ case QUERY_SEARCH:
{
if (!r.empty())
{
@@ -69,9 +62,9 @@ class IdentifyInterface : public LDAPInterface
const LDAPAttributes &attr = r.get(0);
ii->dn = attr.get("dn");
Log(LOG_DEBUG) << "m_ldap_authenticationn: binding as " << ii->dn;
- LDAPQuery id = ii->lprov->Bind(this, ii->dn, ii->req->GetPassword());
- this->Add(id, ii);
- return;
+
+ ii->lprov->Bind(new IdentifyInterface(this->owner, ii), ii->dn, ii->req->GetPassword());
+ ii = NULL;
}
catch (const LDAPException &ex)
{
@@ -80,7 +73,7 @@ class IdentifyInterface : public LDAPInterface
}
break;
}
- case LDAPResult::QUERY_BIND:
+ case QUERY_BIND:
{
if (ii->admin_bind)
{
@@ -88,10 +81,9 @@ class IdentifyInterface : public LDAPInterface
try
{
Log(LOG_DEBUG) << "m_ldap_authentication: searching for " << sf;
- LDAPQuery id = ii->lprov->Search(this, basedn, sf);
- this->Add(id, ii);
+ ii->lprov->Search(new IdentifyInterface(this->owner, ii), basedn, sf);
ii->admin_bind = false;
- return;
+ ii = NULL;
}
catch (const LDAPException &ex)
{
@@ -121,40 +113,28 @@ class IdentifyInterface : public LDAPInterface
default:
break;
}
-
- delete ii;
}
void OnError(const LDAPResult &r) override
{
- std::map<LDAPQuery, IdentifyInfo *>::iterator it = this->requests.find(r.id);
- if (it == this->requests.end())
- return;
- IdentifyInfo *ii = it->second;
- this->requests.erase(it);
- delete ii;
}
};
class OnIdentifyInterface : public LDAPInterface
{
- std::map<LDAPQuery, Anope::string> requests;
+ Anope::string uid;
public:
- OnIdentifyInterface(Module *m) : LDAPInterface(m) { }
+ OnIdentifyInterface(Module *m, const Anope::string &i) : LDAPInterface(m), uid(i) { }
- void Add(LDAPQuery id, const Anope::string &nick)
+ void OnDelete() anope_override
{
- this->requests[id] = nick;
+ delete this;
}
void OnResult(const LDAPResult &r) override
{
- std::map<LDAPQuery, Anope::string>::iterator it = this->requests.find(r.id);
- if (it == this->requests.end())
- return;
- User *u = User::Find(it->second);
- this->requests.erase(it);
+ User *u = User::Find(uid);
if (!u || !u->Account() || r.empty())
return;
@@ -181,7 +161,6 @@ class OnIdentifyInterface : public LDAPInterface
void OnError(const LDAPResult &r) override
{
- this->requests.erase(r.id);
Log(this->owner) << r.error;
}
};
@@ -202,15 +181,13 @@ class OnRegisterInterface : public LDAPInterface
}
};
-class NSIdentifyLDAP : public Module
+class ModuleLDAPAuthentication : public Module
, public EventHook<Event::PreCommand>
, public EventHook<Event::CheckAuthentication>
, public EventHook<Event::NickIdentify>
, public EventHook<NickServ::Event::NickRegister>
{
ServiceReference<LDAPProvider> ldap;
- IdentifyInterface iinterface;
- OnIdentifyInterface oninterface;
OnRegisterInterface orinterface;
PrimitiveExtensibleItem<Anope::string> dn;
@@ -218,29 +195,18 @@ class NSIdentifyLDAP : public Module
Anope::string password_attribute;
Anope::string disable_register_reason;
Anope::string disable_email_reason;
- public:
- NSIdentifyLDAP(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR)
+ public:
+ ModuleLDAPAuthentication(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR)
, EventHook<Event::PreCommand>("OnPreCommand", EventHook<Event::PreCommand>::Priority::FIRST)
, EventHook<Event::CheckAuthentication>("OnCheckAuthentication", EventHook<Event::CheckAuthentication>::Priority::FIRST)
, EventHook<Event::NickIdentify>("OnNickIdentify", EventHook<Event::NickIdentify>::Priority::FIRST)
, EventHook<NickServ::Event::NickRegister>("OnNickRegister", EventHook<NickServ::Event::NickRegister>::Priority::FIRST)
, ldap("LDAPProvider", "ldap/main")
- , iinterface(this)
- , oninterface(this)
, orinterface(this)
, dn(this, "m_ldap_authentication_dn")
{
-
me = this;
-<<<<<<< HEAD
-=======
- }
-
- void Prioritize() anope_override
- {
- ModuleManager::SetPriority(this, PRIORITY_FIRST);
->>>>>>> 2.0
}
void OnReload(Configuration::Conf *config) override
@@ -287,16 +253,7 @@ class NSIdentifyLDAP : public Module
return;
IdentifyInfo *ii = new IdentifyInfo(u, req, this->ldap);
- try
- {
- LDAPQuery id = this->ldap->BindAsAdmin(&this->iinterface);
- this->iinterface.Add(id, ii);
- }
- catch (const LDAPException &ex)
- {
- delete ii;
- Log(this) << ex.GetReason();
- }
+ this->ldap->BindAsAdmin(new IdentifyInterface(this, ii));
}
void OnNickIdentify(User *u) override
@@ -308,57 +265,38 @@ class NSIdentifyLDAP : public Module
if (!d || d->empty())
return;
- try
- {
- LDAPQuery id = this->ldap->Search(&this->oninterface, *d, "(" + email_attribute + "=*)");
- this->oninterface.Add(id, u->nick);
- }
- catch (const LDAPException &ex)
- {
- Log(this) << ex.GetReason();
- }
+ this->ldap->Search(new OnIdentifyInterface(this, u->GetUID()), *d, "(" + email_attribute + "=*)");
}
-<<<<<<< HEAD
- void OnNickRegister(User *, NickServ::Nick *na) override
-=======
- void OnNickRegister(User *, NickAlias *na, const Anope::string &pass) anope_override
->>>>>>> 2.0
+ void OnNickRegister(User *, NickServ::Nick *na, const Anope::string &pass) override
{
if (!this->disable_register_reason.empty() || !this->ldap)
return;
- try
- {
- this->ldap->BindAsAdmin(NULL);
-
- LDAPMods attributes;
- attributes.resize(4);
+ this->ldap->BindAsAdmin(NULL);
- attributes[0].name = "objectClass";
- attributes[0].values.push_back("top");
- attributes[0].values.push_back(object_class);
+ LDAPMods attributes;
+ attributes.resize(4);
- attributes[1].name = username_attribute;
- attributes[1].values.push_back(na->GetNick());
-
- if (!na->GetAccount()->GetEmail().empty())
- {
- attributes[2].name = email_attribute;
- attributes[2].values.push_back(na->GetAccount()->GetEmail());
- }
+ attributes[0].name = "objectClass";
+ attributes[0].values.push_back("top");
+ attributes[0].values.push_back(object_class);
- attributes[3].name = this->password_attribute;
- attributes[3].values.push_back(pass);
+ attributes[1].name = username_attribute;
+ attributes[1].values.push_back(na->GetNick());
- Anope::string new_dn = username_attribute + "=" + na->GetNick() + "," + basedn;
- this->ldap->Add(&this->orinterface, new_dn, attributes);
- }
- catch (const LDAPException &ex)
+ if (!na->GetAccount()->GetEmail().empty())
{
- Log(this) << ex.GetReason();
+ attributes[2].name = email_attribute;
+ attributes[2].values.push_back(na->GetAccount()->GetEmail());
}
+
+ attributes[3].name = this->password_attribute;
+ attributes[3].values.push_back(pass);
+
+ Anope::string new_dn = username_attribute + "=" + na->GetNick() + "," + basedn;
+ this->ldap->Add(&this->orinterface, new_dn, attributes);
}
};
-MODULE_INIT(NSIdentifyLDAP)
+MODULE_INIT(ModuleLDAPAuthentication)
diff --git a/modules/extra/m_ldap_oper.cpp b/modules/extra/m_ldap_oper.cpp
index 221e16f98..31653544e 100644
--- a/modules/extra/m_ldap_oper.cpp
+++ b/modules/extra/m_ldap_oper.cpp
@@ -6,27 +6,15 @@ static Anope::string opertype_attribute;
class IdentifyInterface : public LDAPInterface
{
- std::map<LDAPQuery, Anope::string> requests;
+ Reference<User> u;
public:
- IdentifyInterface(Module *m) : LDAPInterface(m)
+ IdentifyInterface(Module *m, User *user) : LDAPInterface(m), u(user)
{
}
- void Add(LDAPQuery id, const Anope::string &nick)
- {
- this->requests[id] = nick;
- }
-
void OnResult(const LDAPResult &r) override
{
- std::map<LDAPQuery, Anope::string>::iterator it = this->requests.find(r.id);
- if (it == this->requests.end())
- return;
- User *u = User::Find(it->second);
- this->requests.erase(it);
-
-
if (!u || !u->Account())
return;
@@ -50,11 +38,8 @@ class IdentifyInterface : public LDAPInterface
o = new Oper(u->nick, ot);
my_opers.insert(o);
nc->o = o;
-<<<<<<< HEAD
- Log(this->owner) << "m_ldap_oper: Tied " << u->nick << " (" << nc->GetDisplay() << ") to opertype " << ot->GetName();
-=======
- Log(this->owner) << "Tied " << u->nick << " (" << nc->display << ") to opertype " << ot->GetName();
->>>>>>> 2.0
+
+ Log(this->owner) << "Tied " << u->nick << " (" << nc->GetDisplay() << ") to opertype " << ot->GetName();
}
}
catch (const LDAPException &ex)
@@ -68,18 +53,18 @@ class IdentifyInterface : public LDAPInterface
}
nc->o = NULL;
-<<<<<<< HEAD
- Log() << "Removed services operator from " << u->nick << " (" << nc->GetDisplay() << ")";
-=======
- Log(this->owner) << "Removed services operator from " << u->nick << " (" << nc->display << ")";
->>>>>>> 2.0
+ Log(this->owner) << "Removed services operator from " << u->nick << " (" << nc->GetDisplay() << ")";
}
}
}
void OnError(const LDAPResult &r) override
{
- this->requests.erase(r.id);
+ }
+
+ void OnDelete() anope_override
+ {
+ delete this;
}
};
@@ -88,16 +73,15 @@ class LDAPOper : public Module
, public EventHook<Event::DelCore>
{
ServiceReference<LDAPProvider> ldap;
- IdentifyInterface iinterface;
Anope::string binddn;
Anope::string password;
Anope::string basedn;
Anope::string filter;
public:
- LDAPOper(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR)
+ LDAPOper(const Anope::string &modname, const Anope::string &creator)
+ : Module(modname, creator, EXTRA | VENDOR)
, ldap("LDAPProvider", "ldap/main")
- , iinterface(this)
{
}
@@ -128,8 +112,7 @@ class LDAPOper : public Module
if (!this->binddn.empty())
this->ldap->Bind(NULL, this->binddn.replace_all_cs("%a", u->Account()->GetDisplay()), this->password.c_str());
- LDAPQuery id = this->ldap->Search(&this->iinterface, this->basedn, this->filter.replace_all_cs("%a", u->Account()->GetDisplay()));
- this->iinterface.Add(id, u->nick);
+ this->ldap->Search(new IdentifyInterface(this, u), this->basedn, this->filter.replace_all_cs("%a", u->Account()->GetDisplay()));
}
catch (const LDAPException &ex)
{
diff --git a/modules/extra/m_ssl_openssl.cpp b/modules/extra/m_ssl_openssl.cpp
index 748f467cf..c5e2feefc 100644
--- a/modules/extra/m_ssl_openssl.cpp
+++ b/modules/extra/m_ssl_openssl.cpp
@@ -105,6 +105,10 @@ class SSLModule : public Module
if (!client_ctx || !server_ctx)
throw ModuleException("Error initializing SSL CTX");
+ long opts = SSL_OP_NO_SSLv2 | SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION | SSL_OP_CIPHER_SERVER_PREFERENCE;
+ SSL_CTX_set_options(client_ctx, opts);
+ SSL_CTX_set_options(server_ctx, opts);
+
SSL_CTX_set_mode(client_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
SSL_CTX_set_mode(server_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
@@ -160,6 +164,20 @@ class SSLModule : public Module
Log() << "Unable to open private key " << this->keyfile;
}
+ // Allow disabling SSLv3
+ if (!config->Get<Anope::string>("sslv3").empty())
+ {
+ if (config->Get<bool>("sslv3"))
+ {
+ SSL_CTX_clear_options(client_ctx, SSL_OP_NO_SSLv3);
+ SSL_CTX_clear_options(server_ctx, SSL_OP_NO_SSLv3);
+ }
+ else
+ {
+ SSL_CTX_set_options(client_ctx, SSL_OP_NO_SSLv3);
+ SSL_CTX_set_options(server_ctx, SSL_OP_NO_SSLv3);
+ }
+ }
}
void OnPreServerConnect() override
diff --git a/modules/extra/stats/irc2sql/irc2sql.cpp b/modules/extra/stats/irc2sql/irc2sql.cpp
index fbb56f4a7..e0c03edbd 100644
--- a/modules/extra/stats/irc2sql/irc2sql.cpp
+++ b/modules/extra/stats/irc2sql/irc2sql.cpp
@@ -131,6 +131,15 @@ void IRC2SQL::OnUserNickChange(User *u, const Anope::string &oldnick)
this->RunQuery(query);
}
+void IRC2SQL::OnUserAway(User *u, const Anope::string &message)
+{
+ query = "UPDATE `" + prefix + "user` SET away=@away@, awaymsg=@awaymsg@ WHERE nick=@nick@";
+ query.SetValue("away", (!message.empty()) ? "Y" : "N");
+ query.SetValue("awaymsg", message);
+ query.SetValue("nick", u->nick);
+ this->RunQuery(query);
+}
+
void IRC2SQL::OnFingerprint(User *u)
{
query = "UPDATE `" + prefix + "user` SET secure=@secure@, fingerprint=@fingerprint@ WHERE nick=@nick@";
@@ -243,7 +252,7 @@ void IRC2SQL::OnLeaveChannel(User *u, Channel *c)
this->RunQuery(query);
}
-void IRC2SQL::OnTopicUpdated(Channel *c, const Anope::string &user, const Anope::string &topic)
+void IRC2SQL::OnTopicUpdated(User *source, Channel *c, const Anope::string &user, const Anope::string &topic)
{
query = "UPDATE `" + prefix + "chan` "
"SET topic=@topic@, topicauthor=@author@, topictime=FROM_UNIXTIME(@time@) "
diff --git a/modules/extra/stats/irc2sql/irc2sql.h b/modules/extra/stats/irc2sql/irc2sql.h
index 175e37681..b73e95cf1 100644
--- a/modules/extra/stats/irc2sql/irc2sql.h
+++ b/modules/extra/stats/irc2sql/irc2sql.h
@@ -55,6 +55,7 @@ class IRC2SQL : public Module
void OnUserConnect(User *u, bool &exempt) override;
void OnUserQuit(User *u, const Anope::string &msg) override;
void OnUserNickChange(User *u, const Anope::string &oldnick) override;
+ void OnUserAway(User *u, const Anope::string &message) override;
void OnFingerprint(User *u) override;
void OnUserModeSet(const MessageSource &setter, User *u, const Anope::string &mname) override;
void OnUserModeUnset(const MessageSource &setter, User *u, const Anope::string &mname) override;
@@ -69,7 +70,7 @@ class IRC2SQL : public Module
EventReturn OnChannelModeSet(Channel *c, const MessageSource &setter, ChannelMode *mode, const Anope::string &param) override;
EventReturn OnChannelModeUnset(Channel *c, const MessageSource &setter, ChannelMode *mode, const Anope::string &param) override;
- void OnTopicUpdated(Channel *c, const Anope::string &user, const Anope::string &topic) override;
+ void OnTopicUpdated(User *source, Channel *c, const Anope::string &user, const Anope::string &topic) override;
void OnBotNotice(User *u, ServiceBot *bi, Anope::string &message) override;
};
diff --git a/modules/extra/stats/m_chanstats.cpp b/modules/extra/stats/m_chanstats.cpp
index 0278f7805..687c077b5 100644
--- a/modules/extra/stats/m_chanstats.cpp
+++ b/modules/extra/stats/m_chanstats.cpp
@@ -424,7 +424,7 @@ class MChanstats : public Module
"END;";
this->RunQuery(query);
- /* dont prepend any database prefix to events so we can always delete/change old events */
+ /* don't prepend any database prefix to events so we can always delete/change old events */
if (this->HasEvent("chanstats_event_cleanup_daily"))
{
query = "DROP EVENT chanstats_event_cleanup_daily";
@@ -517,14 +517,13 @@ class MChanstats : public Module
info.AddOption(_("Chanstats"));
}
- void OnTopicUpdated(Channel *c, const Anope::string &user, const Anope::string &topic) override
+ void OnTopicUpdated(User *source, Channel *c, const Anope::string &user, const Anope::string &topic) override
{
- User *u = User::Find(user);
- if (!u || !u->Account() || !c->ci || !cs_stats.HasExt(c->ci))
+ if (!source || !source->Account() || !c->ci || !cs_stats.HasExt(c->ci))
return;
query = "CALL " + prefix + "chanstats_proc_update(@channel@, @nick@, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);";
query.SetValue("channel", c->name);
- query.SetValue("nick", GetDisplay(u));
+ query.SetValue("nick", GetDisplay(source));
this->RunQuery(query);
}
diff --git a/modules/fantasy.cpp b/modules/fantasy.cpp
index 53cc03e17..3781b5b83 100644
--- a/modules/fantasy.cpp
+++ b/modules/fantasy.cpp
@@ -113,13 +113,29 @@ class Fantasy : public Module
std::vector<Anope::string> params;
spacesepstream(msg).GetTokens(params);
- if (!msg.find(c->ci->GetBot()->nick))
+ if (params.empty())
+ return;
+
+ Anope::string normalized_param0 = Anope::NormalizeBuffer(params[0]);
+ Anope::string fantasy_chars = Config->GetModule(this)->Get<Anope::string>("fantasycharacter", "!");
+
+ if (!normalized_param0.find(c->ci->GetBot()->nick))
+ {
params.erase(params.begin());
- else if (!msg.find_first_of(Config->GetModule(this)->Get<Anope::string>("fantasycharacter", "!")))
- params[0].erase(params[0].begin());
+ }
+ else if (!normalized_param0.find_first_of(fantasy_chars))
+ {
+ size_t sz = params[0].find_first_of(fantasy_chars);
+ if (sz == Anope::string::npos)
+ return; /* normalized_param0 is a subset of params[0] so this can't happen */
+
+ params[0].erase(0, sz + 1);
+ }
else
+ {
return;
-
+ }
+
if (params.empty())
return;
@@ -133,7 +149,7 @@ class Fantasy : public Module
full_command.erase(full_command.begin());
++count;
- it = Config->Fantasy.find(full_command);
+ it = Config->Fantasy.find(Anope::NormalizeBuffer(full_command));
}
if (it == Config->Fantasy.end())
@@ -143,7 +159,7 @@ class Fantasy : public Module
ServiceReference<Command> cmd("Command", info.name);
if (!cmd)
{
- Log(LOG_DEBUG) << "Fantasy command " << it->first << " exists for nonexistant service " << info.name << "!";
+ Log(LOG_DEBUG) << "Fantasy command " << it->first << " exists for non-existent service " << info.name << "!";
return;
}
diff --git a/modules/m_dns.cpp b/modules/m_dns.cpp
index c5fe8a767..1ea70a6ed 100644
--- a/modules/m_dns.cpp
+++ b/modules/m_dns.cpp
@@ -22,10 +22,15 @@ namespace
time_t timeout;
}
-/** A full packet sent or recieved to/from the nameserver
+/** A full packet sent or received to/from the nameserver
*/
class Packet : public Query
{
+ static bool IsValidName(const Anope::string &name)
+ {
+ return name.find_first_not_of("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-") == Anope::string::npos;
+ }
+
void PackName(unsigned char *output, unsigned short output_size, unsigned short &pos, const Anope::string &name)
{
if (pos + name.length() + 2 > output_size)
@@ -116,6 +121,9 @@ class Packet : public Query
if (pos + 4 > input_size)
throw SocketException("Unable to unpack question");
+ if (!IsValidName(question.name))
+ throw SocketException("Invalid question name");
+
question.type = static_cast<QueryType>(input[pos] << 8 | input[pos + 1]);
pos += 2;
@@ -179,6 +187,10 @@ class Packet : public Query
case QUERY_PTR:
{
record.rdata = this->UnpackName(input, input_size, pos);
+
+ if (!IsValidName(record.rdata))
+ throw SocketException("Invalid cname/ptr record data");
+
break;
}
default:
@@ -792,7 +804,7 @@ class MyManager : public Manager, public Timer
}
Packet *packet = new Packet(recv_packet);
- packet->flags |= QUERYFLAGS_QR; /* This is a reponse */
+ packet->flags |= QUERYFLAGS_QR; /* This is a response */
packet->flags |= QUERYFLAGS_AA; /* And we are authoritative */
packet->answers.clear();
diff --git a/modules/m_xmlrpc.cpp b/modules/m_xmlrpc.cpp
index 3830b2ac8..2d1cd2c0e 100644
--- a/modules/m_xmlrpc.cpp
+++ b/modules/m_xmlrpc.cpp
@@ -53,6 +53,39 @@ class MyXMLRPCServiceInterface : public XMLRPCServiceInterface, public HTTPPage
return ret;
}
+ static Anope::string Unescape(const Anope::string &string)
+ {
+ Anope::string ret = string;
+ for (int i = 0; special[i].character.empty() == false; ++i)
+ if (!special[i].replace.empty())
+ ret = ret.replace_all_cs(special[i].replace, special[i].character);
+
+ for (size_t i, last = 0; (i = string.find("&#", last)) != Anope::string::npos;)
+ {
+ last = i + 1;
+
+ size_t end = string.find(';', i);
+ if (end == Anope::string::npos)
+ break;
+
+ Anope::string ch = string.substr(i + 2, end - (i + 2));
+
+ if (ch.empty())
+ continue;
+
+ long l;
+ if (!ch.empty() && ch[0] == 'x')
+ l = strtol(ch.substr(1).c_str(), NULL, 16);
+ else
+ l = strtol(ch.c_str(), NULL, 10);
+
+ if (l > 0 && l < 256)
+ ret = ret.replace_all_cs("&#" + ch + ";", Anope::string(l));
+ }
+
+ return ret;
+ }
+
private:
static bool GetData(Anope::string &content, Anope::string &tag, Anope::string &data)
{
@@ -98,8 +131,8 @@ class MyXMLRPCServiceInterface : public XMLRPCServiceInterface, public HTTPPage
}
while (istag && !content.empty());
- tag = prev;
- data = cur;
+ tag = Unescape(prev);
+ data = Unescape(cur);
return !istag && !data.empty();
}
@@ -146,10 +179,10 @@ class MyXMLRPCServiceInterface : public XMLRPCServiceInterface, public HTTPPage
if (!request.id.empty())
request.reply("id", request.id);
- Anope::string r = "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n<methodCall>\n<methodName>" + request.name + "</methodName>\n<params>\n<param>\n<value>\n<struct>\n";
+ Anope::string r = "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n<methodResponse>\n<params>\n<param>\n<value>\n<struct>\n";
for (std::map<Anope::string, Anope::string>::const_iterator it = request.get_replies().begin(); it != request.get_replies().end(); ++it)
r += "<member>\n<name>" + it->first + "</name>\n<value>\n<string>" + this->Sanitize(it->second) + "</string>\n</value>\n</member>\n";
- r += "</struct>\n</value>\n</param>\n</params>\n</methodCall>";
+ r += "</struct>\n</value>\n</param>\n</params>\n</methodResponse>";
request.r.Write(r);
}
@@ -162,12 +195,8 @@ class ModuleXMLRPC : public Module
MyXMLRPCServiceInterface xmlrpcinterface;
ModuleXMLRPC(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR)
- , httpref("HTTPProvider", "httpd/main")
, xmlrpcinterface(this, "xmlrpc")
{
- if (!httpref)
- throw ModuleException("Unable to find http reference, is m_httpd loaded?");
- httpref->RegisterPage(&xmlrpcinterface);
}
@@ -179,7 +208,12 @@ class ModuleXMLRPC : public Module
void OnReload(Configuration::Conf *conf) override
{
+ if (httpref)
+ httpref->UnregisterPage(&xmlrpcinterface);
this->httpref = ServiceReference<HTTPProvider>("HTTPProvider", conf->GetModule(this)->Get<Anope::string>("server", "httpd/main"));
+ if (!httpref)
+ throw ConfigException("Unable to find http reference, is m_httpd loaded?");
+ httpref->RegisterPage(&xmlrpcinterface);
}
};
diff --git a/modules/protocol/bahamut.cpp b/modules/protocol/bahamut.cpp
index 52786b361..c320f3a3e 100644
--- a/modules/protocol/bahamut.cpp
+++ b/modules/protocol/bahamut.cpp
@@ -378,7 +378,7 @@ struct IRCDMessageNick : IRCDMessage
Server *s = Server::Find(params[6]);
if (s == NULL)
{
- Log(LOG_DEBUG) << "User " << params[0] << " introduced from nonexistant server " << params[6] << "?";
+ Log(LOG_DEBUG) << "User " << params[0] << " introduced from non-existent server " << params[6] << "?";
return;
}
@@ -449,7 +449,7 @@ struct IRCDMessageSJoin : IRCDMessage
sju.second = User::Find(buf);
if (!sju.second)
{
- Log(LOG_DEBUG) << "SJOIN for nonexistant user " << buf << " on " << params[1];
+ Log(LOG_DEBUG) << "SJOIN for non-existent user " << buf << " on " << params[1];
continue;
}
@@ -466,11 +466,11 @@ struct IRCDMessageTopic : IRCDMessage
{
IRCDMessageTopic(Module *creator) : IRCDMessage(creator, "TOPIC", 4) { }
- void Run(MessageSource &, const std::vector<Anope::string> &params) override
+ void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
Channel *c = Channel::Find(params[0]);
if (c)
- c->ChangeTopicInternal(params[1], params[3], Anope::string(params[2]).is_pos_number_only() ? convertTo<time_t>(params[2]) : Anope::CurTime);
+ c->ChangeTopicInternal(source.GetUser(), params[1], params[3], Anope::string(params[2]).is_pos_number_only() ? convertTo<time_t>(params[2]) : Anope::CurTime);
}
};
diff --git a/modules/protocol/charybdis.cpp b/modules/protocol/charybdis.cpp
index 8477bc30e..50da90902 100644
--- a/modules/protocol/charybdis.cpp
+++ b/modules/protocol/charybdis.cpp
@@ -230,7 +230,7 @@ struct IRCDMessageEUID : IRCDMessage
}
};
-// we cant use this function from ratbox because we set a local variable here
+// we can't use this function from ratbox because we set a local variable here
struct IRCDMessageServer : IRCDMessage
{
IRCDMessageServer(Module *creator) : IRCDMessage(creator, "SERVER", 3) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
@@ -246,7 +246,7 @@ struct IRCDMessageServer : IRCDMessage
}
};
-// we cant use this function from ratbox because we set a local variable here
+// we can't use this function from ratbox because we set a local variable here
struct IRCDMessagePass : IRCDMessage
{
IRCDMessagePass(Module *creator) : IRCDMessage(creator, "PASS", 4) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
diff --git a/modules/protocol/hybrid.cpp b/modules/protocol/hybrid.cpp
index 772b9e0d9..b5c524530 100644
--- a/modules/protocol/hybrid.cpp
+++ b/modules/protocol/hybrid.cpp
@@ -1,7 +1,7 @@
/* ircd-hybrid-8 protocol module
*
* (C) 2003-2014 Anope Team
- * (C) 2012-2014 ircd-hybrid development team
+ * (C) 2012-2015 ircd-hybrid development team
*
* Please read COPYING and README for further details.
*
@@ -43,7 +43,7 @@ class HybridProto : public IRCDProto
}
public:
- HybridProto(Module *creator) : IRCDProto(creator, "Hybrid 8.1.x")
+ HybridProto(Module *creator) : IRCDProto(creator, "Hybrid 8.2.x")
{
DefaultPseudoclientModes = "+oi";
CanSVSNick = true;
@@ -55,7 +55,7 @@ class HybridProto : public IRCDProto
CanCertFP = true;
CanSetVHost = true;
RequiresID = true;
- MaxModes = 4;
+ MaxModes = 6;
}
void SendInvite(const MessageSource &source, const Channel *c, User *u) override
@@ -73,11 +73,6 @@ class HybridProto : public IRCDProto
UplinkSocket::Message(bi) << "PRIVMSG $$" << dest->GetName() << " :" << msg;
}
- void SendGlobopsInternal(const MessageSource &source, const Anope::string &buf) override
- {
- UplinkSocket::Message(source) << "GLOBOPS :" << buf;
- }
-
void SendSQLine(User *, XLine *x) override
{
UplinkSocket::Message(FindIntroduced()) << "ENCAP * RESV " << (x->GetExpires() ? x->GetExpires() - Anope::CurTime : 0) << " " << x->GetMask() << " 0 :" << x->GetReason();
@@ -216,7 +211,7 @@ class HybridProto : public IRCDProto
SendServer(Me);
- UplinkSocket::Message() << "SVINFO 6 5 0 :" << Anope::CurTime;
+ UplinkSocket::Message() << "SVINFO 6 6 0 :" << Anope::CurTime;
}
void SendClientIntroduction(User *u) override
@@ -224,7 +219,7 @@ class HybridProto : public IRCDProto
Anope::string modes = "+" + u->GetModes();
UplinkSocket::Message(Me) << "UID " << u->nick << " 1 " << u->timestamp << " " << modes << " "
- << u->GetIdent() << " " << u->host << " 0 " << u->GetUID() << " 0 :" << u->realname;
+ << u->GetIdent() << " " << u->host << " 0 " << u->GetUID() << " * :" << u->realname;
}
void SendEOB() override
@@ -244,7 +239,7 @@ class HybridProto : public IRCDProto
void SendLogout(User *u) override
{
- IRCD->SendMode(Config->GetClient("NickServ"), u, "+d 0");
+ IRCD->SendMode(Config->GetClient("NickServ"), u, "+d *");
}
void SendChannel(Channel *c) override
@@ -264,7 +259,7 @@ class HybridProto : public IRCDProto
void SendForceNickChange(User *u, const Anope::string &newnick, time_t when) override
{
- UplinkSocket::Message(Me) << "SVSNICK " << u->nick << " " << newnick << " " << when;
+ UplinkSocket::Message(Me) << "SVSNICK " << u->GetUID() << " " << newnick << " " << when;
}
void SendSVSJoin(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string &) override
@@ -472,7 +467,7 @@ struct IRCDMessageSJoin : IRCDMessage
sju.second = User::Find(buf);
if (!sju.second)
{
- Log(LOG_DEBUG) << "SJOIN for nonexistant user " << buf << " on " << params[1];
+ Log(LOG_DEBUG) << "SJOIN for non-existent user " << buf << " on " << params[1];
continue;
}
@@ -519,7 +514,7 @@ struct IRCDMessageTBurst : IRCDMessage
Channel *c = Channel::Find(params[1]);
if (c)
- c->ChangeTopicInternal(setter, params[4], topic_time);
+ c->ChangeTopicInternal(NULL, setter, params[4], topic_time);
}
};
@@ -553,7 +548,7 @@ struct IRCDMessageUID : IRCDMessage
IRCDMessageUID(Module *creator) : IRCDMessage(creator, "UID", 10) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
/* 0 1 2 3 4 5 6 7 8 9 */
- /* :0MC UID Steve 1 1350157102 +oi ~steve resolved.host 10.0.0.1 0MCAAAAAB 1350157108 :Mining all the time */
+ /* :0MC UID Steve 1 1350157102 +oi ~steve resolved.host 10.0.0.1 0MCAAAAAB Steve :Mining all the time */
void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
Anope::string ip = params[6];
@@ -562,7 +557,7 @@ struct IRCDMessageUID : IRCDMessage
ip.clear();
NickServ::Nick *na = NULL;
- if (params[8] != "0")
+ if (params[8] != "0" && params[8] != "*")
na = NickServ::FindNick(params[8]);
/* Source is always the server */
diff --git a/modules/protocol/inspircd20.cpp b/modules/protocol/inspircd20.cpp
index 4a74995a2..63cdc1973 100644
--- a/modules/protocol/inspircd20.cpp
+++ b/modules/protocol/inspircd20.cpp
@@ -219,6 +219,8 @@ class InspIRCd20Proto : public IRCDProto
{
Anope::string modes = "+" + u->GetModes();
UplinkSocket::Message(Me) << "UID " << u->GetUID() << " " << u->timestamp << " " << u->nick << " " << u->host << " " << u->host << " " << u->GetIdent() << " 0.0.0.0 " << u->timestamp << " " << modes << " :" << u->realname;
+ if (modes.find('o') != Anope::string::npos)
+ UplinkSocket::Message(u) << "OPERTYPE :services";
}
/* SERVER services-dev.chatspike.net password 0 :Description here */
@@ -816,7 +818,10 @@ struct IRCDMessageFHost : IRCDMessage
void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
- source.GetUser()->SetDisplayedHost(params[0]);
+ User *u = source.GetUser();
+ if (u->HasMode("CLOAK"))
+ u->RemoveModeInternal(source, ModeManager::FindUserModeByName("CLOAK"));
+ u->SetDisplayedHost(params[0]);
}
};
@@ -866,7 +871,7 @@ struct IRCDMessageFJoin : IRCDMessage
sju.second = User::Find(buf);
if (!sju.second)
{
- Log(LOG_DEBUG) << "FJOIN for nonexistant user " << buf << " on " << params[0];
+ Log(LOG_DEBUG) << "FJOIN for non-existent user " << buf << " on " << params[0];
continue;
}
@@ -917,7 +922,7 @@ struct IRCDMessageFTopic : IRCDMessage
Channel *c = Channel::Find(params[0]);
if (c)
- c->ChangeTopicInternal(params[2], params[3], Anope::string(params[1]).is_pos_number_only() ? convertTo<time_t>(params[1]) : Anope::CurTime);
+ c->ChangeTopicInternal(NULL, params[2], params[3], Anope::string(params[1]).is_pos_number_only() ? convertTo<time_t>(params[1]) : Anope::CurTime);
}
};
@@ -947,7 +952,15 @@ struct IRCDMessageIdle : IRCDMessage
*/
struct IRCDMessageMetadata : IRCDMessage
{
- IRCDMessageMetadata(Module *creator) : IRCDMessage(creator, "METADATA", 3) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
+ const bool &do_topiclock, &do_mlock;
+
+ IRCDMessageMetadata(Module *creator, const bool &handle_topiclock, const bool &handle_mlock)
+ : IRCDMessage(creator, "METADATA", 3)
+ , do_topiclock(handle_topiclock)
+ , do_mlock(handle_mlock)
+ {
+ SetFlag(IRCDMESSAGE_REQUIRE_SERVER);
+ }
void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
@@ -982,8 +995,31 @@ struct IRCDMessageMetadata : IRCDMessage
Event::OnFingerprint(&Event::Fingerprint::OnFingerprint, u);
}
}
- else if (params[0][0] == '#')
+ // We deliberately ignore non-bursting servers to avoid pseudoserver fights
+ else if ((params[0][0] == '#') && (!source.GetServer()->IsSynced()))
{
+ Channel *c = Channel::Find(params[0]);
+ if (c && c->ci)
+ {
+ if ((do_mlock) && (params[1] == "mlock"))
+ {
+ ModeLocks *modelocks = c->ci->GetExt<ModeLocks>("modelocks");
+ Anope::string modes;
+ if (modelocks)
+ modes = modelocks->GetMLockAsString(c->ci, false).replace_all_cs("+", "").replace_all_cs("-", "");
+
+ // Mode lock string is not what we say it is?
+ if (modes != params[2])
+ UplinkSocket::Message(Me) << "METADATA " << c->name << " mlock :" << modes;
+ }
+ else if ((do_topiclock) && (params[1] == "topiclock"))
+ {
+ bool mystate = c->ci->GetExt<bool>("TOPICLOCK");
+ bool serverstate = (params[2] == "1");
+ if (mystate != serverstate)
+ UplinkSocket::Message(Me) << "METADATA " << c->name << " topiclock :" << (mystate ? "1" : "");
+ }
+ }
}
else if (params[0] == "*")
{
@@ -1263,7 +1299,6 @@ class ProtoInspIRCd20 : public Module
, public EventHook<Event::DelChan>
, public EventHook<Event::MLockEvents>
, public EventHook<Event::SetChannelOption>
- , public EventHook<Event::ChannelModeUnset>
{
InspIRCd20Proto ircd_proto;
ExtensibleItem<bool> ssl;
@@ -1340,7 +1375,7 @@ class ProtoInspIRCd20 : public Module
, message_fmode(this)
, message_ftopic(this)
, message_idle(this)
- , message_metadata(this)
+ , message_metadata(this, use_server_side_topiclock, use_server_side_mlock)
, message_mode(this)
, message_nick(this)
, message_opertype(this)
@@ -1464,15 +1499,6 @@ class ProtoInspIRCd20 : public Module
return EVENT_CONTINUE;
}
-
- EventReturn OnChannelModeUnset(Channel *c, const MessageSource &setter, ChannelMode *mode, const Anope::string &param) override
- {
- if ((setter.GetUser() && setter.GetUser()->server == Me) || setter.GetServer() == Me || !setter.GetServer())
- if (mode->name == "OPERPREFIX")
- c->SetMode(c->ci->WhoSends(), mode, param, false);
-
- return EVENT_CONTINUE;
- }
};
MODULE_INIT(ProtoInspIRCd20)
diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
index 6981e32bc..b80f600e3 100644
--- a/modules/protocol/ngircd.cpp
+++ b/modules/protocol/ngircd.cpp
@@ -257,7 +257,7 @@ struct IRCDMessageChaninfo : IRCDMessage
if (params.size() == 3)
{
- c->ChangeTopicInternal(source.GetName(), params[2], Anope::CurTime);
+ c->ChangeTopicInternal(NULL, source.GetName(), params[2], Anope::CurTime);
}
else if (params.size() == 5)
{
@@ -271,9 +271,9 @@ struct IRCDMessageChaninfo : IRCDMessage
case 'l':
modes += " " + params[3];
continue;
+ }
}
- }
- c->ChangeTopicInternal(source.GetName(), params[4], Anope::CurTime);
+ c->ChangeTopicInternal(NULL, source.GetName(), params[4], Anope::CurTime);
}
c->SetModesInternal(source, modes);
@@ -451,7 +451,7 @@ struct IRCDMessageNick : IRCDMessage
Server *s = Server::Find(params[4]);
if (s == NULL)
{
- Log(LOG_DEBUG) << "User " << params[0] << " introduced from nonexistant server " << params[4] << "?";
+ Log(LOG_DEBUG) << "User " << params[0] << " introduced from non-existent server " << params[4] << "?";
return;
}
User::OnIntroduce(params[0], params[2], params[3], "", "", s, params[6], Anope::CurTime, params[5], "", NULL);
@@ -500,7 +500,7 @@ struct IRCDMessageNJoin : IRCDMessage
sju.second = User::Find(buf);
if (!sju.second)
{
- Log(LOG_DEBUG) << "NJOIN for nonexistant user " << buf << " on " << params[0];
+ Log(LOG_DEBUG) << "NJOIN for non-existent user " << buf << " on " << params[0];
continue;
}
users.push_back(sju);
@@ -587,10 +587,10 @@ struct IRCDMessageTopic : IRCDMessage
Channel *c = Channel::Find(params[0]);
if (!c)
{
- Log(LOG_DEBUG) << "TOPIC for nonexistant channel " << params[0];
+ Log(LOG_DEBUG) << "TOPIC for non-existent channel " << params[0];
return;
}
- c->ChangeTopicInternal(source.GetName(), params[1], Anope::CurTime);
+ c->ChangeTopicInternal(source.GetUser(), source.GetName(), params[1], Anope::CurTime);
}
};
diff --git a/modules/protocol/ratbox.cpp b/modules/protocol/ratbox.cpp
index ec3e406b1..9e1ea0710 100644
--- a/modules/protocol/ratbox.cpp
+++ b/modules/protocol/ratbox.cpp
@@ -172,7 +172,7 @@ struct IRCDMessageTBurst : IRCDMessage
* params[0] = channel
* params[1] = ts
* params[2] = topic OR who set the topic
- * params[3] = topic if params[2] isnt the topic
+ * params[3] = topic if params[2] isn't the topic
*/
void Run(MessageSource &source, const std::vector<Anope::string> &params) override
{
@@ -185,7 +185,7 @@ struct IRCDMessageTBurst : IRCDMessage
const Anope::string &setter = params.size() == 4 ? params[2] : "",
topic = params.size() == 4 ? params[3] : params[2];
- c->ChangeTopicInternal(setter, topic, topic_time);
+ c->ChangeTopicInternal(NULL, setter, topic, topic_time);
}
};
diff --git a/modules/protocol/unreal.cpp b/modules/protocol/unreal.cpp
index b4b9893d3..6bcaaab26 100644
--- a/modules/protocol/unreal.cpp
+++ b/modules/protocol/unreal.cpp
@@ -576,7 +576,7 @@ class ChannelModeFlood : public ChannelModeParam
while (p < arg.length() && isdigit(arg[p]))
++p;
if (p == arg.length() || !(arg[p] == 'c' || arg[p] == 'j' || arg[p] == 'k' || arg[p] == 'm' || arg[p] == 'n' || arg[p] == 't'))
- continue; /* continue instead of break for forward compatability. */
+ continue; /* continue instead of break for forward compatibility. */
try
{
int v = arg.substr(0, p).is_number_only() ? convertTo<int>(arg.substr(0, p)) : 0;
@@ -745,7 +745,7 @@ struct IRCDMessageNick : IRCDMessage
Server *s = Server::Find(params[5]);
if (s == NULL)
{
- Log(LOG_DEBUG) << "User " << params[0] << " introduced from nonexistant server " << params[5] << "?";
+ Log(LOG_DEBUG) << "User " << params[0] << " introduced from non-existent server " << params[5] << "?";
return;
}
@@ -829,7 +829,7 @@ struct IRCDMessageSetHost : IRCDMessage
{
User *u = source.GetUser();
- /* When a user sets +x we recieve the new host and then the mode change */
+ /* When a user sets +x we receive the new host and then the mode change */
if (u->HasMode("CLOAK"))
u->SetDisplayedHost(params[0]);
else
@@ -933,7 +933,7 @@ struct IRCDMessageSJoin : IRCDMessage
sju.second = User::Find(buf);
if (!sju.second)
{
- Log(LOG_DEBUG) << "SJOIN for nonexistant user " << buf << " on " << params[1];
+ Log(LOG_DEBUG) << "SJOIN for non-existent user " << buf << " on " << params[1];
continue;
}
@@ -983,7 +983,7 @@ struct IRCDMessageTopic : IRCDMessage
{
Channel *c = Channel::Find(params[0]);
if (c)
- c->ChangeTopicInternal(params[1], params[3], Anope::string(params[2]).is_pos_number_only() ? convertTo<time_t>(params[2]) : Anope::CurTime);
+ c->ChangeTopicInternal(source.GetUser(), params[1], params[3], Anope::string(params[2]).is_pos_number_only() ? convertTo<time_t>(params[2]) : Anope::CurTime);
}
};
diff --git a/modules/pseudoclients/botserv/botserv.cpp b/modules/pseudoclients/botserv/botserv.cpp
index 0042b6267..0b51691fc 100644
--- a/modules/pseudoclients/botserv/botserv.cpp
+++ b/modules/pseudoclients/botserv/botserv.cpp
@@ -103,7 +103,7 @@ class BotServCore : public Module, public BotServ::BotServService
{
/**
* We let the bot join even if it was an ignored user, as if we don't,
- * and the ignored user doesnt just leave, the bot will never
+ * and the ignored user doesn't just leave, the bot will never
* make it into the channel, leaving the channel botless even for
* legit users - Rob
**/
@@ -121,8 +121,8 @@ class BotServCore : public Module, public BotServ::BotServService
/* Channel is persistent, it shouldn't be deleted and the service bot should stay */
if (c->ci && persist && persist->HasExt(c->ci))
return;
-
- /* Channel is syncing from a netburst, don't destroy it as more users are probably wanting to join immediatly
+
+ /* Channel is syncing from a netburst, don't destroy it as more users are probably wanting to join immediately
* We also don't part the bot here either, if necessary we will part it after the sync
*/
if (c->syncing)
diff --git a/modules/pseudoclients/chanserv/channel.cpp b/modules/pseudoclients/chanserv/channel.cpp
index 8b349dc1f..b24edcc0c 100644
--- a/modules/pseudoclients/chanserv/channel.cpp
+++ b/modules/pseudoclients/chanserv/channel.cpp
@@ -194,7 +194,7 @@ ChanServ::ChanAccess *ChannelImpl::GetAccess(unsigned index)
return a.size() > index ? a[index] : nullptr;
}
-ChanServ::AccessGroup ChannelImpl::AccessFor(const User *u)
+ChanServ::AccessGroup ChannelImpl::AccessFor(const User *u, bool updateLastUsed)
{
ChanServ::AccessGroup group;
@@ -223,7 +223,8 @@ ChanServ::AccessGroup ChannelImpl::AccessFor(const User *u)
if (group.founder || !group.empty())
{
- this->SetLastUsed(Anope::CurTime);
+ if (updateLastUsed)
+ this->SetLastUsed(Anope::CurTime);
for (unsigned i = 0; i < group.size(); ++i)
group[i]->SetLastSeen(Anope::CurTime);
@@ -232,7 +233,7 @@ ChanServ::AccessGroup ChannelImpl::AccessFor(const User *u)
return group;
}
-ChanServ::AccessGroup ChannelImpl::AccessFor(NickServ::Account *nc)
+ChanServ::AccessGroup ChannelImpl::AccessFor(NickServ::Account *nc, bool updateLastUsed)
{
ChanServ::AccessGroup group;
@@ -248,7 +249,8 @@ ChanServ::AccessGroup ChannelImpl::AccessFor(NickServ::Account *nc)
}
if (group.founder || !group.empty())
- this->SetLastUsed(Anope::CurTime);
+ if (updateLastUsed)
+ this->SetLastUsed(Anope::CurTime);
/* don't update access last seen here, this isn't the user requesting access */
@@ -362,6 +364,13 @@ void ChannelImpl::SetLevel(const Anope::string &priv, int16_t level)
return;
}
+ ChanServ::Privilege *p = ChanServ::service ? ChanServ::service->FindPrivilege(priv) : nullptr;
+ if (!p)
+ {
+ Log(LOG_DEBUG) << "Unknown privilege " + priv;
+ return;
+ }
+
ChanServ::Level *l = ChanServ::level.Create();
l->SetChannel(this);
l->SetName(priv);
diff --git a/modules/pseudoclients/chanserv/channel.h b/modules/pseudoclients/chanserv/channel.h
index 18a4be5d6..86e42a8f9 100644
--- a/modules/pseudoclients/chanserv/channel.h
+++ b/modules/pseudoclients/chanserv/channel.h
@@ -50,8 +50,8 @@ class ChannelImpl : public ChanServ::Channel
void SetSuccessor(NickServ::Account *nc) override;
NickServ::Account *GetSuccessor() override;
ChanServ::ChanAccess *GetAccess(unsigned index) /*const*/ override;
- ChanServ::AccessGroup AccessFor(const User *u) override;
- ChanServ::AccessGroup AccessFor(NickServ::Account *nc) override;
+ ChanServ::AccessGroup AccessFor(const User *u, bool = true) override;
+ ChanServ::AccessGroup AccessFor(NickServ::Account *nc, bool = true) override;
unsigned GetAccessCount()/* const*/ override;
unsigned GetDeepAccessCount() const override;
void ClearAccess() override;
diff --git a/modules/pseudoclients/nickserv/nickserv.cpp b/modules/pseudoclients/nickserv/nickserv.cpp
index ee6068ef1..26f1457cc 100644
--- a/modules/pseudoclients/nickserv/nickserv.cpp
+++ b/modules/pseudoclients/nickserv/nickserv.cpp
@@ -20,6 +20,9 @@
#include "accounttype.h"
#include "modetype.h"
+class NickServCollide;
+static std::set<NickServCollide *> collides;
+
/** Timer for colliding nicks to force people off of nicknames
*/
class NickServCollide : public Timer
@@ -32,6 +35,22 @@ class NickServCollide : public Timer
public:
NickServCollide(Module *me, NickServ::NickServService *nss, User *user, NickServ::Nick *nick, time_t delay) : Timer(me, delay), service(nss), u(user), ts(user->timestamp), na(nick)
{
+ collides.insert(this);
+ }
+
+ ~NickServCollide()
+ {
+ collides.erase(this);
+ }
+
+ NickServ::Nick *GetNick()
+ {
+ return na;
+ }
+
+ User *GetUser()
+ {
+ return u;
}
void Tick(time_t t) override
@@ -429,6 +448,16 @@ class NickServCore : public Module, public NickServ::NickServService
"Your privacy is respected; this e-mail won't be given to\n"
"any third-party person."), Config->StrictPrivmsg.c_str(), NickServ->nick.c_str());
}
+
+ for (std::set<NickServCollide *>::iterator it = collides.begin(); it != collides.end(); ++it)
+ {
+ NickServCollide *c = *it;
+ if (c->GetUser() == u && c->GetNick() && c->GetNick()->GetAccount() == u->Account())
+ {
+ delete c;
+ break;
+ }
+ }
}
void OnNickGroup(User *u, NickServ::Nick *target) override
@@ -632,8 +661,23 @@ class NickServCore : public Module, public NickServ::NickServService
++it;
ir->Release(m);
+#if 0
+ ir->holds.erase(m);
+ if (ir->holds.empty() && ir->dispatched)
+ {
+ if (!ir->success)
+ ir->OnFail();
+ delete ir;
+ continue;
+ }
+
if (ir->GetOwner() == m)
+ {
+ if (!ir->success)
+ ir->OnFail();
delete ir;
+ }
+#endif
}
}
};
diff --git a/modules/pseudoclients/operserv.cpp b/modules/pseudoclients/operserv.cpp
index fe187b70c..0a4f1b692 100644
--- a/modules/pseudoclients/operserv.cpp
+++ b/modules/pseudoclients/operserv.cpp
@@ -139,9 +139,13 @@ class SQLineManager : public XLineManager
if (std::regex_match(c->name.str(), *x->regex))
return x;
}
- else if (Anope::Match(c->name, x->GetMask(), false, true))
+ else
{
- return x;
+ if (x->GetMask().empty() || x->GetMask()[0] != '#')
+ continue;
+
+ if (Anope::Match(c->name, x->GetMask(), false, true))
+ return x;
}
}
return nullptr;
diff --git a/modules/webcpanel/pages/index.cpp b/modules/webcpanel/pages/index.cpp
index e3a8de96c..551b73a0e 100644
--- a/modules/webcpanel/pages/index.cpp
+++ b/modules/webcpanel/pages/index.cpp
@@ -31,6 +31,12 @@ class WebpanelRequest : public NickServ::IdentifyRequestListener
return;
}
+ if (na->GetAccount()->HasFieldS("NS_SUSPENDED"))
+ {
+ this->OnFail(req);
+ return;
+ }
+
Anope::string id;
for (int i = 0; i < 64; ++i)
{
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 7f43fcd30..b32c1d9c0 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -75,7 +75,9 @@ add_to_cpack_ignored_files("${SERVICES_BINARY}$" TRUE)
configure_file(${Anope_SOURCE_DIR}/include/sysconf.h.cmake ${Anope_BINARY_DIR}/include/sysconf.h)
# Go into the following directories and run their CMakeLists.txt as well
-add_subdirectory(tools)
+if(NOT DISABLE_TOOLS)
+ add_subdirectory(tools)
+endif(NOT DISABLE_TOOLS)
# Set Anope to be installed to the bin directory
install(TARGETS ${PROGRAM_NAME}
diff --git a/src/bots.cpp b/src/bots.cpp
index 205b0841c..f934676bb 100644
--- a/src/bots.cpp
+++ b/src/bots.cpp
@@ -174,12 +174,9 @@ void ServiceBot::Part(Channel *c, const Anope::string &reason)
IRCD->SendPart(this, c, "%s", !reason.empty() ? reason.c_str() : "");
- Anope::string cname = c->name;
- Reference<Channel> cref = c;
-
c->DeleteUser(this);
- Event::OnPartChannel(&Event::PartChannel::OnPartChannel, this, cref, cname, reason);
+ Event::OnPartChannel(&Event::PartChannel::OnPartChannel, this, c, c->name, reason);
}
void ServiceBot::OnMessage(User *u, const Anope::string &message)
diff --git a/src/channels.cpp b/src/channels.cpp
index f77f1f4bc..e1529b270 100644
--- a/src/channels.cpp
+++ b/src/channels.cpp
@@ -26,6 +26,7 @@
#include "modules/chanserv.h"
channel_map ChannelList;
+std::vector<Channel *> Channel::deleting;
Channel::Channel(const Anope::string &nname, time_t ts)
{
@@ -116,7 +117,7 @@ void Channel::CheckModes()
bool Channel::CheckDelete()
{
- /* Channel is syncing from a netburst, don't destroy it as more users are probably wanting to join immediatly
+ /* Channel is syncing from a netburst, don't destroy it as more users are probably wanting to join immediately
* We also don't part the bot here either, if necessary we will part it after the sync
*/
if (this->syncing)
@@ -155,14 +156,14 @@ void Channel::DeleteUser(User *user)
ChanUserContainer *cu = user->FindChannel(this);
if (!this->users.erase(user))
- Log(LOG_DEBUG) << "Channel::DeleteUser() tried to delete nonexistant user " << user->nick << " from channel " << this->name;
+ Log(LOG_DEBUG) << "Channel::DeleteUser() tried to delete non-existent user " << user->nick << " from channel " << this->name;
if (!user->chans.erase(this))
- Log(LOG_DEBUG) << "Channel::DeleteUser() tried to delete nonexistant channel " << this->name << " from " << user->nick << "'s channel list";
+ Log(LOG_DEBUG) << "Channel::DeleteUser() tried to delete non-existent channel " << this->name << " from " << user->nick << "'s channel list";
delete cu;
- if (this->CheckDelete())
- delete this;
+ if (std::find(deleting.begin(), deleting.end(), this) == deleting.end())
+ deleting.push_back(this);
}
ChanUserContainer *Channel::FindUser(User *u) const
@@ -274,7 +275,7 @@ void Channel::SetModeInternal(const MessageSource &setter, ChannelMode *ocm, con
if (!u)
{
- Log() << "MODE " << this->name << " +" << cm->mchar << " for nonexistant user " << param;
+ Log() << "MODE " << this->name << " +" << cm->mchar << " for non-existent user " << param;
return;
}
@@ -338,7 +339,7 @@ void Channel::RemoveModeInternal(const MessageSource &setter, ChannelMode *ocm,
if (!u)
{
- Log() << "Channel::RemoveModeInternal() MODE " << this->name << "-" << cm->mchar << " for nonexistant user " << param;
+ Log() << "Channel::RemoveModeInternal() MODE " << this->name << "-" << cm->mchar << " for non-existent user " << param;
return;
}
@@ -636,7 +637,7 @@ void Channel::SetModesInternal(MessageSource &source, const Anope::string &mode,
if (cm->type == MODE_REGULAR)
{
- /* something changed if we are adding a mode we dont have, or removing one we have */
+ /* something changed if we are adding a mode we don't have, or removing one we have */
changed |= !!add != this->HasMode(cm->name);
if (add)
this->SetModeInternal(source, cm, "", false);
@@ -671,7 +672,7 @@ void Channel::SetModesInternal(MessageSource &source, const Anope::string &mode,
this->RemoveModeInternal(source, cm, token, enforce_mlock);
}
else
- Log() << "warning: Channel::SetModesInternal() recieved more modes requiring params than params, modes: " << mode;
+ Log() << "warning: Channel::SetModesInternal() received more modes requiring params than params, modes: " << mode;
}
if (!this_reference)
@@ -726,7 +727,7 @@ bool Channel::KickInternal(const MessageSource &source, const Anope::string &nic
if (sender)
Log(sender, this, "kick") << "kicked " << target->nick << " (" << reason << ")";
else
- Log(target, this, "kick") << "was kicked by " << source.GetSource() << " (" << reason << ")";
+ Log(target, this, "kick") << "was kicked by " << source.GetName() << " (" << reason << ")";
Anope::string chname = this->name;
@@ -737,7 +738,6 @@ bool Channel::KickInternal(const MessageSource &source, const Anope::string &nic
return false;
}
- Anope::string this_name = this->name;
ChannelStatus status = cu->status;
EventReturn MOD_RESULT = Event::OnPreUserKicked(&Event::PreUserKicked::OnPreUserKicked, source, cu, reason);
@@ -745,8 +745,8 @@ bool Channel::KickInternal(const MessageSource &source, const Anope::string &nic
if (MOD_RESULT == EVENT_STOP)
return false;
- this->DeleteUser(target); /* This can delete this; */
- Event::OnUserKicked(&Event::UserKicked::OnUserKicked, source, target, this_name, status, reason);
+ this->DeleteUser(target);
+ Event::OnUserKicked(&Event::UserKicked::OnUserKicked, source, target, this->name, status, reason);
return true;
}
@@ -771,26 +771,22 @@ bool Channel::Kick(User *source, User *u, const char *reason, ...)
return true;
}
-void Channel::ChangeTopicInternal(const Anope::string &user, const Anope::string &newtopic, time_t ts)
+void Channel::ChangeTopicInternal(User *u, const Anope::string &user, const Anope::string &newtopic, time_t ts)
{
- User *u = User::Find(user);
-
this->topic = newtopic;
this->topic_setter = u ? u->nick : user;
this->topic_ts = ts;
this->topic_time = Anope::CurTime;
- Log(LOG_DEBUG) << "Topic of " << this->name << " changed by " << (u ? u->nick : user) << " to " << newtopic;
+ Log(LOG_DEBUG) << "Topic of " << this->name << " changed by " << this->topic_setter << " to " << newtopic;
- Event::OnTopicUpdated(&Event::TopicUpdated::OnTopicUpdated, this, user, this->topic);
+ Event::OnTopicUpdated(&Event::TopicUpdated::OnTopicUpdated, u, this, user, this->topic);
}
void Channel::ChangeTopic(const Anope::string &user, const Anope::string &newtopic, time_t ts)
{
- User *u = User::Find(user);
-
this->topic = newtopic;
- this->topic_setter = u ? u->nick : user;
+ this->topic_setter = user;
this->topic_ts = ts;
IRCD->SendTopic(this->ci->WhoSends(), this);
@@ -798,7 +794,7 @@ void Channel::ChangeTopic(const Anope::string &user, const Anope::string &newtop
/* Now that the topic is set update the time set. This is *after* we set it so the protocol modules are able to tell the old last set time */
this->topic_time = Anope::CurTime;
- Event::OnTopicUpdated(&Event::TopicUpdated::OnTopicUpdated, this, user, this->topic);
+ Event::OnTopicUpdated(&Event::TopicUpdated::OnTopicUpdated, nullptr, this, user, this->topic);
}
void Channel::SetCorrectModes(User *user, bool give_modes)
@@ -842,7 +838,8 @@ void Channel::SetCorrectModes(User *user, bool give_modes)
given = true;
}
}
- else if (take_modes && !has_priv && !u_access.HasPriv(cm->name + "ME"))
+ /* modes that have no privileges assigned shouldn't be removed (like operprefix, ojoin) */
+ else if (take_modes && !has_priv && ci->GetLevel(cm->name + "ME") != ChanServ::ACCESS_INVALID && !u_access.HasPriv(cm->name + "ME"))
{
/* Only remove modes if they are > voice */
if (cm->name == "VOICE")
@@ -922,3 +919,15 @@ Channel *Channel::FindOrCreate(const Anope::string &name, bool &created, time_t
return chan;
}
+void Channel::DeleteChannels()
+{
+ for (unsigned int i = 0; i < deleting.size(); ++i)
+ {
+ Channel *c = deleting[i];
+
+ if (c->CheckDelete())
+ delete c;
+ }
+ deleting.clear();
+}
+
diff --git a/src/config.cpp b/src/config.cpp
index 47a9d8580..2fe8dd74f 100644
--- a/src/config.cpp
+++ b/src/config.cpp
@@ -219,6 +219,7 @@ Conf::Conf() : Block("")
}
this->DefLanguage = options->Get<Anope::string>("defaultlanguage");
this->TimeoutCheck = options->Get<time_t>("timeoutcheck");
+ this->NickChars = networkinfo->Get<Anope::string>("nick_chars");
for (int i = 0; i < this->CountBlock("uplink"); ++i)
{
diff --git a/src/extensible.cpp b/src/extensible.cpp
index e0e35e6ea..c3c56abf8 100644
--- a/src/extensible.cpp
+++ b/src/extensible.cpp
@@ -24,8 +24,6 @@ ExtensibleBase::~ExtensibleBase()
Extensible::~Extensible()
{
- while (!extension_items.empty())
- extension_items[0]->Unset(this);
}
bool Extensible::HasExtOK(const Anope::string &name)
diff --git a/src/init.cpp b/src/init.cpp
index d649a2f6e..124181d2b 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -1,4 +1,4 @@
-/* Initalization and related routines.
+/* Initialization and related routines.
*
* (C) 2003-2014 Anope Team
* Contact us at team@anope.org
diff --git a/src/language.cpp b/src/language.cpp
index d73074df4..cfc531a81 100644
--- a/src/language.cpp
+++ b/src/language.cpp
@@ -89,7 +89,7 @@ const char *Language::Translate(const char *lang, const char *string)
SetThreadLocale(MAKELCID(MAKELANGID(WindowsGetLanguage(lang), SUBLANG_DEFAULT), SORT_DEFAULT));
#else
/* First, set LANG and LANGUAGE env variables.
- * Some systems (Debian) don't care about this, so we must setlocale LC_ALL aswell.
+ * Some systems (Debian) don't care about this, so we must setlocale LC_ALL as well.
* BUT if this call fails because the LANGUAGE env variable is set, setlocale resets
* the locale to "C", which short circuits gettext and causes it to fail on systems that
* use the LANGUAGE env variable. We must reset the locale to en_US (or, anything not
diff --git a/src/messages.cpp b/src/messages.cpp
index 6a9945336..a6ccbe324 100644
--- a/src/messages.cpp
+++ b/src/messages.cpp
@@ -27,7 +27,14 @@ using namespace Message;
void Away::Run(MessageSource &source, const std::vector<Anope::string> &params)
{
- Event::OnUserAway(&Event::UserAway::OnUserAway, source.GetUser(), params.empty() ? "" : params[0]);
+ const Anope::string &msg = !params.empty() ? params[0] : "";
+
+ Event::OnUserAway(&Event::UserAway::OnUserAway, source.GetUser(), msg);
+
+ if (!msg.empty())
+ Log(source.GetUser(), "away") << "is now away: " << msg;
+ else
+ Log(source.GetUser(), "away") << "is no longer away";
}
void Capab::Run(MessageSource &source, const std::vector<Anope::string> &params)
@@ -78,12 +85,12 @@ void Join::Run(MessageSource &source, const std::vector<Anope::string> &params)
for (User::ChanUserList::iterator it = user->chans.begin(), it_end = user->chans.end(); it != it_end; )
{
ChanUserContainer *cc = it->second;
+ Channel *c = cc->chan;
++it;
- Anope::string channame = cc->chan->name;
- Event::OnPrePartChannel(&Event::PrePartChannel::OnPrePartChannel, user, cc->chan);
+ Event::OnPrePartChannel(&Event::PrePartChannel::OnPrePartChannel, user, c);
cc->chan->DeleteUser(user);
- Event::OnPartChannel(&Event::PartChannel::OnPartChannel, user, Channel::Find(channame), channame, "");
+ Event::OnPartChannel(&Event::PartChannel::OnPartChannel, user, c, c->name, "");
}
continue;
}
@@ -280,16 +287,16 @@ void Part::Run(MessageSource &source, const std::vector<Anope::string> &params)
while (sep.GetToken(channel))
{
- Reference<Channel> c = Channel::Find(channel);
+ Channel *c = Channel::Find(channel);
if (!c || !u->FindChannel(c))
continue;
Log(u, c, "part") << "Reason: " << (!reason.empty() ? reason : "No reason");
+
Event::OnPrePartChannel(&Event::PrePartChannel::OnPrePartChannel, u, c);
- Anope::string ChannelName = c->name;
c->DeleteUser(u);
- Event::OnPartChannel(&Event::PartChannel::OnPartChannel, u, c, ChannelName, !reason.empty() ? reason : "");
+ Event::OnPartChannel(&Event::PartChannel::OnPartChannel, u, c, c->name, !reason.empty() ? reason : "");
}
}
@@ -462,7 +469,7 @@ void Topic::Run(MessageSource &source, const std::vector<Anope::string> &params)
{
Channel *c = Channel::Find(params[0]);
if (c)
- c->ChangeTopicInternal(source.GetSource(), params[1], Anope::CurTime);
+ c->ChangeTopicInternal(source.GetUser(), source.GetSource(), params[1], Anope::CurTime);
return;
}
diff --git a/src/misc.cpp b/src/misc.cpp
index 27be43a96..436ac2261 100644
--- a/src/misc.cpp
+++ b/src/misc.cpp
@@ -11,7 +11,7 @@
*/
#include "services.h"
-#include "version.h"
+#include "build.h"
#include "modules.h"
#include "lists.h"
#include "config.h"
@@ -587,11 +587,6 @@ const Anope::string Anope::LastError()
#endif
}
-ModuleVersion Module::GetVersion() const
-{
- return ModuleVersion(VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH);
-}
-
Anope::string Anope::Version()
{
#ifdef VERSION_GIT
diff --git a/src/modes.cpp b/src/modes.cpp
index 2ea11d3a3..b2c76bdff 100644
--- a/src/modes.cpp
+++ b/src/modes.cpp
@@ -223,7 +223,7 @@ ChannelModeVirtual<T>::~ChannelModeVirtual()
}
template<typename T>
-ChannelMode *ChannelModeVirtual<T>::Wrap(Anope::string &param)
+void ChannelModeVirtual<T>::Check()
{
if (basech == NULL)
{
@@ -231,7 +231,11 @@ ChannelMode *ChannelModeVirtual<T>::Wrap(Anope::string &param)
if (basech)
basech->listeners.push_back(this);
}
+}
+template<typename T>
+ChannelMode *ChannelModeVirtual<T>::Wrap(Anope::string &param)
+{
return basech;
}
@@ -268,7 +272,7 @@ void StackerInfo::AddMode(Mode *mode, bool set, const Anope::string &param)
break;
}
}
- /* If the mode is on the other list, remove it from there (eg, we dont want +o-o Adam Adam) */
+ /* If the mode is on the other list, remove it from there (eg, we don't want +o-o Adam Adam) */
for (it = otherlist->begin(), it_end = otherlist->end(); it != it_end; ++it)
{
/* The param must match too (can have multiple status or list modes), but
@@ -298,7 +302,7 @@ static class ModePipe : public Pipe
}
} *modePipe;
-/** Get the stacker info for an item, if one doesnt exist it is created
+/** Get the stacker info for an item, if one doesn't exist it is created
* @param Item The user/channel etc
* @return The stacker info
*/
@@ -424,6 +428,9 @@ bool ModeManager::AddChannelMode(ChannelMode *cm)
Event::OnChannelModeAdd(&Event::ChannelModeAdd::OnChannelModeAdd, cm);
+ for (unsigned int i = 0; i < ChannelModes.size(); ++i)
+ ChannelModes[i]->Check();
+
return true;
}
diff --git a/src/module.cpp b/src/module.cpp
index 1b19c976c..283445ece 100644
--- a/src/module.cpp
+++ b/src/module.cpp
@@ -97,8 +97,11 @@ void Module::SetAuthor(const Anope::string &nauthor)
this->author = nauthor;
}
-ModuleVersion::ModuleVersion(int maj, int min, int pa) : version_major(maj), version_minor(min), version_patch(pa)
+ModuleVersion::ModuleVersion(const ModuleVersionC &ver)
{
+ version_major = ver.version_major;
+ version_minor = ver.version_minor;
+ version_patch = ver.version_patch;
}
int ModuleVersion::GetMajor() const
diff --git a/src/modulemanager.cpp b/src/modulemanager.cpp
index 9e70ab088..76cec0b57 100644
--- a/src/modulemanager.cpp
+++ b/src/modulemanager.cpp
@@ -162,7 +162,7 @@ ModuleReturn ModuleManager::LoadModule(const Anope::string &modname, User *u)
dlerror();
AnopeModule *module = static_cast<AnopeModule *>(dlsym(handle, "AnopeMod"));
err = dlerror();
- if (!module || !module->init || !module->fini)
+ if (!module || module->api_version != ANOPE_MODAPI_VER)
{
Log() << "No module symbols function found, not an Anope module";
if (err && *err)
@@ -171,6 +171,46 @@ ModuleReturn ModuleManager::LoadModule(const Anope::string &modname, User *u)
return MOD_ERR_NOLOAD;
}
+ try
+ {
+ ModuleVersion v = module->version();
+
+ if (v.GetMajor() < Anope::VersionMajor() || (v.GetMajor() == Anope::VersionMajor() && v.GetMinor() < Anope::VersionMinor()))
+ {
+ Log() << "Module " << modname << " is compiled against an older version of Anope " << v.GetMajor() << "." << v.GetMinor() << ", this is " << Anope::VersionShort();
+ dlclose(handle);
+ return MOD_ERR_VERSION;
+ }
+ else if (v.GetMajor() > Anope::VersionMajor() || (v.GetMajor() == Anope::VersionMajor() && v.GetMinor() > Anope::VersionMinor()))
+ {
+ Log() << "Module " << modname << " is compiled against a newer version of Anope " << v.GetMajor() << "." << v.GetMinor() << ", this is " << Anope::VersionShort();
+ dlclose(handle);
+ return MOD_ERR_VERSION;
+ }
+ else if (v.GetPatch() < Anope::VersionPatch())
+ {
+ Log() << "Module " << modname << " is compiled against an older version of Anope, " << v.GetMajor() << "." << v.GetMinor() << "." << v.GetPatch() << ", this is " << Anope::VersionShort();
+ dlclose(handle);
+ return MOD_ERR_VERSION;
+ }
+ else if (v.GetPatch() > Anope::VersionPatch())
+ {
+ Log() << "Module " << modname << " is compiled against a newer version of Anope, " << v.GetMajor() << "." << v.GetMinor() << "." << v.GetPatch() << ", this is " << Anope::VersionShort();
+ dlclose(handle);
+ return MOD_ERR_VERSION;
+ }
+ else
+ {
+ Log(LOG_DEBUG_2) << "Module " << modname << " is compiled against current version of Anope " << Anope::VersionShort();
+ }
+ }
+ catch (const ModuleException &ex)
+ {
+ /* this error has already been logged */
+ dlclose(handle);
+ return MOD_ERR_NOLOAD;
+ }
+
ModuleDef *def = module->init();
/* Create module. */
@@ -203,34 +243,6 @@ ModuleReturn ModuleManager::LoadModule(const Anope::string &modname, User *u)
m->def = def;
m->module = module;
- ModuleVersion v = m->GetVersion();
- if (v.GetMajor() < Anope::VersionMajor() || (v.GetMajor() == Anope::VersionMajor() && v.GetMinor() < Anope::VersionMinor()))
- {
- Log() << "Module " << modname << " is compiled against an older version of Anope " << v.GetMajor() << "." << v.GetMinor() << ", this is " << Anope::VersionShort();
- DeleteModule(m);
- return MOD_ERR_VERSION;
- }
- else if (v.GetMajor() > Anope::VersionMajor() || (v.GetMajor() == Anope::VersionMajor() && v.GetMinor() > Anope::VersionMinor()))
- {
- Log() << "Module " << modname << " is compiled against a newer version of Anope " << v.GetMajor() << "." << v.GetMinor() << ", this is " << Anope::VersionShort();
- DeleteModule(m);
- return MOD_ERR_VERSION;
- }
- else if (v.GetPatch() < Anope::VersionPatch())
- {
- Log() << "Module " << modname << " is compiled against an older version of Anope, " << v.GetMajor() << "." << v.GetMinor() << "." << v.GetPatch() << ", this is " << Anope::VersionShort();
- DeleteModule(m);
- return MOD_ERR_VERSION;
- }
- else if (v.GetPatch() > Anope::VersionPatch())
- {
- Log() << "Module " << modname << " is compiled against a newer version of Anope, " << v.GetMajor() << "." << v.GetMinor() << "." << v.GetPatch() << ", this is " << Anope::VersionShort();
- DeleteModule(m);
- return MOD_ERR_VERSION;
- }
- else
- Log(LOG_DEBUG_2) << "Module " << modname << " is compiled against current version of Anope " << Anope::VersionShort();
-
/* Initialize config */
try
{
diff --git a/src/protocol.cpp b/src/protocol.cpp
index f71b3f8b5..75a32c8a7 100644
--- a/src/protocol.cpp
+++ b/src/protocol.cpp
@@ -365,8 +365,10 @@ bool IRCDProto::IsNickValid(const Anope::string &nick)
Anope::string special = "[]\\`_^{|}";
for (unsigned i = 0; i < nick.length(); ++i)
- if (!(nick[i] >= 'A' && nick[i] <= 'Z') && !(nick[i] >= 'a' && nick[i] <= 'z') && special.find(nick[i]) == Anope::string::npos
- && (!i || (!(nick[i] >= '0' && nick[i] <= '9') && nick[i] != '-')))
+ if (!(nick[i] >= 'A' && nick[i] <= 'Z') && !(nick[i] >= 'a' && nick[i] <= 'z')
+ && special.find(nick[i]) == Anope::string::npos
+ && (Config && Config->NickChars.find(nick[i]) == Anope::string::npos)
+ && (!i || (!(nick[i] >= '0' && nick[i] <= '9') && nick[i] != '-')))
return false;
return true;
diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt
index 394d2fc51..ec3f40d07 100644
--- a/src/tools/CMakeLists.txt
+++ b/src/tools/CMakeLists.txt
@@ -43,5 +43,5 @@ endif(NOT WIN32)
# On non-Windows platforms, if RUNGROUP is set, change the permissions of the tools directory
if(NOT WIN32 AND RUNGROUP)
- install(CODE "execute_process(COMMAND ${CHMOD} 2770 \"\${CMAKE_INSTALL_PREFIX}/bin\")")
+ install(CODE "execute_process(COMMAND ${CHMOD} 2770 \"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin\")")
endif(NOT WIN32 AND RUNGROUP)
diff --git a/src/tools/geoipupdate.sh b/src/tools/geoipupdate.sh
index 0b02dae36..641ac3259 100644
--- a/src/tools/geoipupdate.sh
+++ b/src/tools/geoipupdate.sh
@@ -5,7 +5,7 @@
# them into existing mysql tables. The tables are created
# by the irc2sql module on the first load.
-# Dont forget to rename this file or your changes
+# Don't forget to rename this file or your changes
# will be overwritte on the next 'make install'
############################
diff --git a/src/uplink.cpp b/src/uplink.cpp
index 214de53be..de5232152 100644
--- a/src/uplink.cpp
+++ b/src/uplink.cpp
@@ -140,6 +140,7 @@ bool UplinkSocket::ProcessRead()
{
Anope::Process(buf);
User::QuitUsers();
+ Channel::DeleteChannels();
}
return b;
}
diff --git a/src/version.sh b/src/version.sh
index d9033df0f..db1881df3 100644
--- a/src/version.sh
+++ b/src/version.sh
@@ -1,7 +1,7 @@
#!/bin/sh
-VERSION_MAJOR="2"
-VERSION_MINOR="1"
-VERSION_PATCH="0"
+VERSION_MAJOR=2
+VERSION_MINOR=1
+VERSION_PATCH=0
VERSION_EXTRA="-exploding-tacos"
diff --git a/src/win32/Config.cs b/src/win32/Config.cs
index 8fbf31a65..ea94e338a 100644
--- a/src/win32/Config.cs
+++ b/src/win32/Config.cs
@@ -257,7 +257,7 @@ namespace Config
if (!string.IsNullOrWhiteSpace(CacheResponse) && string.IsNullOrWhiteSpace(InstallerResponse))
InstallerResponse = CacheResponse;
- // Question 4-6 are optional
+ // Question 4+ are optional
if (i < 3 && string.IsNullOrWhiteSpace(InstallerResponse))
{
Console.WriteLine("Invalid option");
diff --git a/src/win32/socket.cpp b/src/win32/socket.cpp
index 320e46f48..7f6ef4df1 100644
--- a/src/win32/socket.cpp
+++ b/src/win32/socket.cpp
@@ -51,7 +51,7 @@ int windows_accept(int fd, struct sockaddr *addr, int *addrlen)
* @param af The protocol type, AF_INET or AF_INET6
* @param src The address
* @param dst Struct to put results in
- * @return 1 on sucess, -1 on error
+ * @return 1 on success, -1 on error
*/
int windows_inet_pton(int af, const char *src, void *dst)
{
diff --git a/src/win32/windows.cpp b/src/win32/windows.cpp
index a70ff53c3..f5bbde2f8 100644
--- a/src/win32/windows.cpp
+++ b/src/win32/windows.cpp
@@ -194,7 +194,7 @@ Anope::string GetWindowsVersion()
buf = "Microsoft Windows 98" + extra;
}
if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90)
- buf = "Microsoft Windows Millenium Edition";
+ buf = "Microsoft Windows Millennium Edition";
}
return buf;
}