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