diff options
| author | Adam <Adam@anope.org> | 2015-10-27 18:57:37 -0400 |
|---|---|---|
| committer | Adam <Adam@anope.org> | 2015-10-27 18:58:48 -0400 |
| commit | 64dac60071fab652745a6e7a06cf6b7bdbbd3625 (patch) | |
| tree | f8f30161150451672b381f6370a8fdcab654bbb8 | |
| parent | 162fdbe5815bbdf187f549fefac94ff476d72e62 (diff) | |
| parent | 830361e97d03c74e54cb1cf1bbf329dffdeb66f7 (diff) | |
Merge branch '2.0' into 2.1
101 files changed, 1672 insertions, 1482 deletions
@@ -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") @@ -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 Binary files differdeleted file mode 100644 index 3be910bb0..000000000 --- a/Config.exe +++ /dev/null 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 ¶m); @@ -210,9 +212,11 @@ class CoreExport ChannelModeVirtual : public T ~ChannelModeVirtual(); + void Check() override; + ChannelMode *Wrap(Anope::string ¶m) override; - ChannelMode *Unwrap(ChannelMode *cm, Anope::string ¶m) = 0; + ChannelMode *Unwrap(ChannelMode *cm, Anope::string ¶m) 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 ¶m = "") 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 ¶m) override; EventReturn OnChannelModeUnset(Channel *c, const MessageSource &setter, ChannelMode *mode, const Anope::string ¶m) 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> ¶ms) override + void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) 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> ¶ms) 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> ¶ms) 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> ¶ms) 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 ¶m) 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> ¶ms) 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> ¶ms) { - 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> ¶ms) @@ -78,12 +85,12 @@ void Join::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) 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> ¶ms) 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> ¶ms) { 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 ¶m) +void ChannelModeVirtual<T>::Check() { if (basech == NULL) { @@ -231,7 +231,11 @@ ChannelMode *ChannelModeVirtual<T>::Wrap(Anope::string ¶m) if (basech) basech->listeners.push_back(this); } +} +template<typename T> +ChannelMode *ChannelModeVirtual<T>::Wrap(Anope::string ¶m) +{ return basech; } @@ -268,7 +272,7 @@ void StackerInfo::AddMode(Mode *mode, bool set, const Anope::string ¶m) 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; } |
