diff options
119 files changed, 1229 insertions, 1479 deletions
@@ -625,8 +625,8 @@ should NOT be used. You should probably specify a newer compiler.\n\n"; } else { - print "\nCould not detect OpenSSL or GnuTLS. Make sure pkg-config is installed if\n"; - print "you intend to use OpenSSL, or that GnuTLS is in your path if you intend\nto use GnuTLS.\n\n"; + print "\nCould not detect OpenSSL or GnuTLS. Make sure pkg-config is installed and\n"; + print "is in your path.\n\n"; } yesno('MODUPDATE',"Would you like to check for updates to third-party modules?"); diff --git a/docs/Doxyfile b/docs/Doxyfile index dd74f58ab..c2abe85d8 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -1,4 +1,4 @@ -# Doxyfile 1.8.0 +# Doxyfile 1.8.1 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. @@ -553,12 +553,6 @@ MAX_INITIALIZER_LINES = 30 SHOW_USED_FILES = YES -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy -# in the documentation. The default is NO. - -SHOW_DIRECTORIES = NO - # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. @@ -707,7 +701,11 @@ EXCLUDE_SYMLINKS = YES # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* -EXCLUDE_PATTERNS = */.git/* */doxygen/* +EXCLUDE_PATTERNS = */.git/* \ + */doxygen/* \ + */commands/* \ + */modes/* \ + */modules/* # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the @@ -947,20 +945,23 @@ HTML_COLORSTYLE_GAMMA = 80 HTML_TIMESTAMP = NO -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the -# page has loaded. For this to work a browser that supports -# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox -# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). +# page has loaded. HTML_DYNAMIC_SECTIONS = NO +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of +# entries shown in the various tree structured indices initially; the user +# can expand and collapse entries dynamically later on. Doxygen will expand +# the tree to such a level that at most the specified number of entries are +# visible (unless a fully collapsed tree already exceeds this amount). +# So setting the number of entries 1 will produce a full collapsed tree by +# default. 0 is a special value representing an infinite number of entries +# and will result in a full expanded tree by default. + +HTML_INDEX_NUM_ENTRIES = 100 + # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). @@ -1139,11 +1140,6 @@ GENERATE_TREEVIEW = NO ENUM_VALUES_PER_LINE = 4 -# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, -# and Class Hierarchy pages using a tree view instead of an ordered list. - -USE_INLINE_TREES = NO - # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. @@ -1711,7 +1707,7 @@ CALLER_GRAPH = NO GRAPHICAL_HIERARCHY = YES -# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. diff --git a/docs/conf/inspircd.conf.example b/docs/conf/inspircd.conf.example index d1293be25..f483e6692 100644 --- a/docs/conf/inspircd.conf.example +++ b/docs/conf/inspircd.conf.example @@ -297,6 +297,14 @@ # specified using <files secretmotd="filename"> or <execfiles ...> motd="secretmotd" + # Allow color codes to be processed in the message of the day file. + # the following characters are valid color code escapes: + # \002 or \b = Bold + # \037 or \u = Underline + # \003 or \c = Color (with a code postfixed to this char) + # \017 or \x = Stop all color sequences + allowmotdcolors="false" + # port: What port this user is allowed to connect on. (optional) # The port MUST be set to listen in the bind blocks above. port="6697"> diff --git a/docs/conf/modules.conf.example b/docs/conf/modules.conf.example index e987f4878..f86ebfa6c 100644 --- a/docs/conf/modules.conf.example +++ b/docs/conf/modules.conf.example @@ -1340,8 +1340,17 @@ #<randquote file="randquotes.conf"> #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# -# Redirect module: Adds channel redirection (mode +L) +# Redirect module: Adds channel redirection (mode +L) # +# Optional: <redirect:antiredirect> to add usermode +L to stop forced # +# redirection and instead print an error. # +# # +# Note: You can not update this with a simple rehash, it requires # +# reloading the module for it to take effect. # +# This also breaks linking to servers that do not have the option. # +# This defaults to false for the 2.0 version, it will be enabled in # +# all the future versions. # #<module name="m_redirect.so"> +#<redirect antiredirect="true"> #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# # Regular Expression Provider for Glob or wildcard (?/*) matching. diff --git a/include/caller.h b/include/caller.h index 88e7df4a1..64b37611f 100644 --- a/include/caller.h +++ b/include/caller.h @@ -44,7 +44,7 @@ * * MyNewFunction replaceme(ServerInstance); * - * someclass->MyFunction = &replaceme; + * someclass->MyFunction = \&replaceme; * * After this point, calls to someclass->MyFunction will call the new code in your * replacement functor. diff --git a/include/channelmanager.h b/include/channelmanager.h deleted file mode 100644 index 58d4fcef8..000000000 --- a/include/channelmanager.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * InspIRCd -- Internet Relay Chat Daemon - * - * Copyright (C) 2008 Robin Burchell <robin+git@viroteck.net> - * - * 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/>. - */ - - -#ifndef CHANNELMANAGER_H -#define CHANNELMANAGER_H - -/** THe channel manager class allocates and deallocates channels and manages - * the container which holds them. For some reason, nobody finished this. - * TODO: Finish in future release! - */ -class CoreExport ChannelManager -{ - public: - /** Constructor - */ - ChannelManager() - { - } -}; - -#endif diff --git a/include/channels.h b/include/channels.h index 89ac6b86c..dda53f69d 100644 --- a/include/channels.h +++ b/include/channels.h @@ -56,7 +56,7 @@ class BanItem : public HostItem * This class represents a channel, and contains its name, modes, topic, topic set time, * etc, and an instance of the BanList type. */ -class CoreExport Channel : public Extensible +class CoreExport Channel : public Extensible, public InviteBase { /** Connect a Channel to a User */ @@ -122,7 +122,7 @@ class CoreExport Channel : public Extensible /** Sets or unsets a custom mode in the channels info * @param mode The mode character to set or unset - * @param mode_on True if you want to set the mode or false if you want to remove it + * @param value True if you want to set the mode or false if you want to remove it */ void SetMode(ModeHandler* mode, bool value); void SetMode(char mode,bool mode_on); @@ -147,7 +147,7 @@ class CoreExport Channel : public Extensible * @param mode The mode character you wish to query * * For example if "+L #foo" is set, and you pass this method - * 'L', it will return '#foo'. If the mode is not set on the + * 'L', it will return '\#foo'. If the mode is not set on the * channel, or the mode has no parameters associated with it, * it will return an empty string. * @@ -199,7 +199,7 @@ class CoreExport Channel : public Extensible const UserMembList* GetUsers(); /** Returns true if the user given is on the given channel. - * @param The user to look for + * @param user The user to look for * @return True if the user is on this channel */ bool HasUser(User* user); @@ -261,7 +261,7 @@ class CoreExport Channel : public Extensible * Internally, this calls WriteAllExcept(). * @param user User whos details to prefix the line with, and to omit from receipt of the message * @param serversource If this parameter is true, use the local server name as the source of the text, otherwise, - * use the nick!user@host of the user. + * use the nick!user\@host of the user. * @param status The status of the users to write to, e.g. '@' or '%'. Use a value of 0 to write to everyone * @param text A printf-style format string which builds the output line without prefix * @param ... Zero or more POD type @@ -271,7 +271,7 @@ class CoreExport Channel : public Extensible /** Write to all users on a channel except a list of users, using va_args for text * @param user User whos details to prefix the line with, and to omit from receipt of the message * @param serversource If this parameter is true, use the local server name as the source of the text, otherwise, - * use the nick!user@host of the user. + * use the nick!user\@host of the user. * @param status The status of the users to write to, e.g. '@' or '%'. Use a value of 0 to write to everyone * @param except_list A list of users NOT to send the text to * @param text A printf-style format string which builds the output line without prefix @@ -283,7 +283,7 @@ class CoreExport Channel : public Extensible * Internally, this calls WriteAllExcept(). * @param user User whos details to prefix the line with, and to omit from receipt of the message * @param serversource If this parameter is true, use the local server name as the source of the text, otherwise, - * use the nick!user@host of the user. + * use the nick!user\@host of the user. * @param status The status of the users to write to, e.g. '@' or '%'. Use a value of 0 to write to everyone * @param text A std::string containing the output line without prefix */ @@ -292,7 +292,7 @@ class CoreExport Channel : public Extensible /** Write to all users on a channel except a list of users, using std::string for text * @param user User whos details to prefix the line with, and to omit from receipt of the message * @param serversource If this parameter is true, use the local server name as the source of the text, otherwise, - * use the nick!user@host of the user. + * use the nick!user\@host of the user. * @param status The status of the users to write to, e.g. '@' or '%'. Use a value of 0 to write to everyone * @param except_list A list of users NOT to send the text to * @param text A std::string containing the output line without prefix diff --git a/include/command_parse.h b/include/command_parse.h index 35d4be2b0..f6ff588e1 100644 --- a/include/command_parse.h +++ b/include/command_parse.h @@ -60,7 +60,6 @@ class CoreExport CommandParser Commandtable cmdlist; /** Default constructor. - * @param Instance The creator of this class */ CommandParser(); @@ -97,7 +96,7 @@ class CoreExport CommandParser * We need a version which takes two potential lists for JOIN, because a JOIN may contain two lists of items at once, * the channel names and their keys as follows: * - * JOIN #chan1,#chan2,#chan3 key1,,key3 + * JOIN \#chan1,\#chan2,\#chan3 key1,,key3 * * Therefore, we need to deal with both lists concurrently. The first instance of this method does that by creating * two instances of irc::commasepstream and reading them both together until the first runs out of tokens. @@ -107,7 +106,6 @@ class CoreExport CommandParser * @param user The user who sent the command * @param CommandObj the command object to call for each parameter in the list * @param parameters Parameter list as an array of array of char (that's not a typo). - * @param The number of items in the parameters list * @param splithere The first parameter index to split as a comma seperated list * @param extra The second parameter index to split as a comma seperated list * @param usemax Limit the command to MaxTargets targets diff --git a/include/configparser.h b/include/configparser.h index 478899ed9..4b83d26d7 100644 --- a/include/configparser.h +++ b/include/configparser.h @@ -61,13 +61,19 @@ struct ParseStack struct FileWrapper { FILE* const f; - FileWrapper(FILE* file) : f(file) {} + bool close_with_pclose; + FileWrapper(FILE* file, bool use_pclose = false) : f(file), close_with_pclose(use_pclose) {} operator bool() { return f; } operator FILE*() { return f; } ~FileWrapper() { if (f) - fclose(f); + { + if (close_with_pclose) + pclose(f); + else + fclose(f); + } } }; diff --git a/include/configreader.h b/include/configreader.h index f42bf67fe..e360d3917 100644 --- a/include/configreader.h +++ b/include/configreader.h @@ -33,7 +33,7 @@ #include "socketengine.h" #include "socket.h" -/** Structure representing a single <tag> in config */ +/** Structure representing a single \<tag> in config */ class CoreExport ConfigTag : public refcountbase { std::vector<KeyVal> items; @@ -174,11 +174,11 @@ class CoreExport OperInfo : public refcountbase /** Allowed channel modes from oper classes. */ std::bitset<64> AllowedChanModes; - /** <oper> block used for this oper-up. May be NULL. */ + /** \<oper> block used for this oper-up. May be NULL. */ reference<ConfigTag> oper_block; - /** <type> block used for this oper-up. Valid for local users, may be NULL on remote */ + /** \<type> block used for this oper-up. Valid for local users, may be NULL on remote */ reference<ConfigTag> type_block; - /** <class> blocks referenced from the <type> block. These define individual permissions */ + /** \<class> blocks referenced from the \<type> block. These define individual permissions */ std::vector<reference<ConfigTag> > class_blocks; /** Name of the oper type; i.e. the one shown in WHOIS */ std::string name; @@ -208,7 +208,6 @@ class CoreExport ServerConfig /** Get a configuration tag * @param tag The name of the tag to get - * @param offset get the Nth occurance of the tag */ ConfigTag* ConfValue(const std::string& tag); @@ -375,7 +374,7 @@ class CoreExport ServerConfig /** The full path to the modules directory. * This is either set at compile time, or * overridden in the configuration file via - * the <path> tag. + * the \<path> tag. */ std::string ModPath; @@ -391,7 +390,7 @@ class CoreExport ServerConfig bool RestrictBannedUsers; /** If this is set to true, then mode lists (e.g - * MODE #chan b) are hidden from unprivileged + * MODE \#chan b) are hidden from unprivileged * users. */ bool HideModeLists[256]; @@ -515,7 +514,7 @@ class CoreExport ServerConfig */ bool UndernetMsgPrefix; - /** If set to true, the full nick!user@host will be shown in the TOPIC command + /** If set to true, the full nick!user\@host will be shown in the TOPIC command * for who set the topic last. If false, only the nick is shown. */ bool FullHostInTopic; @@ -569,7 +568,11 @@ class CoreExport ServerConfig void Fill(); - /* Returns true if the given string starts with a windows drive letter + /** Parses color codes from string values to actual color codes + */ + void ProcessColors(ConfigFileCache::iterator &file); + + /** Returns true if the given string starts with a windows drive letter */ bool StartsWithWindowsDriveLetter(const std::string &path); diff --git a/include/ctables.h b/include/ctables.h index 0bd8f360c..f016dd4c5 100644 --- a/include/ctables.h +++ b/include/ctables.h @@ -147,15 +147,11 @@ class CoreExport Command : public ServiceProvider int Penalty; /** Create a new command. - * @param Instance Pointer to creator class + * @param me The module which created this command. * @param cmd Command name. This must be UPPER CASE. - * @param flags User mode required to execute the command. May ONLY be one mode - it's a string to give warnings if people mix params up. - * For oper only commands, set this to 'o', otherwise use 0. * @param minpara Minimum parameters required for the command. - * @param maxpara Maximum number of parameters this command may have - extra parameters will be tossed into one last space-seperated param. - * @param before_reg If this is set to true, the command will - * be allowed before the user is 'registered' (has sent USER, - * NICK, optionally PASS, and been resolved). + * @param maxpara Maximum number of parameters this command may have - extra parameters + * will be tossed into one last space-seperated param. */ Command(Module* me, const std::string &cmd, int minpara = 0, int maxpara = 0) : ServiceProvider(me, cmd, SERVICE_COMMAND), flags_needed(0), min_params(minpara), max_params(maxpara), diff --git a/include/extensible.h b/include/extensible.h index 40e820d68..f327cf75c 100644 --- a/include/extensible.h +++ b/include/extensible.h @@ -17,6 +17,11 @@ */ +#ifndef EXTENSIBLE_H +#define EXTENSIBLE_H + +#include <stdint.h> + enum SerializeFormat { /** Shown to a human (does not need to be unserializable) */ @@ -185,3 +190,5 @@ class CoreExport StringExtItem : public ExtensionItem void unset(Extensible* container); void free(void* item); }; + +#endif diff --git a/include/hashcomp.h b/include/hashcomp.h index d9516e7fa..59986e66f 100644 --- a/include/hashcomp.h +++ b/include/hashcomp.h @@ -157,7 +157,7 @@ namespace irc /** Compose a hex string from raw data. * @param raw The raw data to compose hex from - * @pram rawsz The size of the raw data buffer + * @param rawsz The size of the raw data buffer * @return The hex string. */ CoreExport std::string hex(const unsigned char *raw, size_t rawsz); @@ -441,7 +441,7 @@ namespace irc /** Used to split on commas */ - commasepstream* sep; + commasepstream sep; /** Current position in a range of ports */ @@ -462,7 +462,7 @@ namespace irc /** Used to determine overlapping of ports * without O(n) algorithm being used */ - std::map<long, bool> overlap_set; + std::set<long> overlap_set; /** Returns true if val overlaps an existing range */ @@ -475,10 +475,6 @@ namespace irc */ portparser(const std::string &source, bool allow_overlapped = true); - /** Frees the internal commasepstream object - */ - ~portparser(); - /** Fetch the next token from the stream * @return The next port number is returned, or 0 if none remain */ @@ -596,7 +592,7 @@ inline std::string& trim(std::string &str) } /** Hashing stuff is totally different on vc++'s hash_map implementation, so to save a buttload of - * #ifdefs we'll just do it all at once. Except, of course, with TR1, when it's the same as GCC. + * \#ifdefs we'll just do it all at once. Except, of course, with TR1, when it's the same as GCC. */ BEGIN_HASHMAP_NAMESPACE diff --git a/include/inspircd.h b/include/inspircd.h index 9c9609530..c06a28043 100644 --- a/include/inspircd.h +++ b/include/inspircd.h @@ -348,16 +348,16 @@ class CoreExport InspIRCd static const char LogHeader[]; /** Find a user in the UUID hash - * @param nick The nickname to find + * @param uid The UUID to find * @return A pointer to the user, or NULL if the user does not exist */ - User* FindUUID(const std::string &); + User* FindUUID(const std::string &uid); /** Find a user in the UUID hash - * @param nick The nickname to find + * @param uid The UUID to find * @return A pointer to the user, or NULL if the user does not exist */ - User* FindUUID(const char *); + User* FindUUID(const char *uid); /** Build the ISUPPORT string by triggering all modules On005Numeric events */ @@ -460,10 +460,6 @@ class CoreExport InspIRCd */ LocalStringExt OperQuit; - /** Holds whether the MOTD has been parsed for color codes - */ - bool ProcessedMotdEscapes; - /** Get the current time * Because this only calls time() once every time around the mainloop, * it is much faster than calling time() directly. @@ -498,6 +494,7 @@ class CoreExport InspIRCd * @param sockfd A valid file descriptor of an open socket * @param port The port number to bind to * @param addr The address to bind to (IP only) + * @param dolisten Should this port be listened on? * @return True if the port was bound successfully */ bool BindSocket(int sockfd, int port, const char* addr, bool dolisten = true); @@ -585,7 +582,7 @@ class CoreExport InspIRCd /** Causes the server to exit after unloading modules and * closing all open file descriptors. * - * @param The exit code to give to the operating system + * @param status The exit code to give to the operating system * (See the ExitStatus enum for valid values) */ void Exit(int status); @@ -664,6 +661,7 @@ class CoreExport InspIRCd * to check case against (may be NULL). If map is null, match will be case insensitive. * @param str The literal string to match against * @param mask The glob pattern to match against. + * @param map The character map to use when matching. */ static bool Match(const std::string &str, const std::string &mask, unsigned const char *map = NULL); static bool Match(const char *str, const char *mask, unsigned const char *map = NULL); @@ -673,6 +671,7 @@ class CoreExport InspIRCd * Supports CIDR patterns as well as globs. * @param str The literal string to match against * @param mask The glob or CIDR pattern to match against. + * @param map The character map to use when matching. */ static bool MatchCIDR(const std::string &str, const std::string &mask, unsigned const char *map = NULL); static bool MatchCIDR(const char *str, const char *mask, unsigned const char *map = NULL); @@ -680,15 +679,14 @@ class CoreExport InspIRCd /** Call the handler for a given command. * @param commandname The command whos handler you wish to call * @param parameters The mode parameters - * @param pcnt The number of items you have given in the first parameter * @param user The user to execute the command as * @return True if the command handler was called successfully */ CmdResult CallCommandHandler(const std::string &commandname, const std::vector<std::string>& parameters, User* user); /** Return true if the command is a module-implemented command and the given parameters are valid for it - * @param parameters The mode parameters - * @param pcnt The number of items you have given in the first parameter + * @param commandname The command name to check + * @param pcnt The parameter count * @param user The user to test-execute the command as * @return True if the command handler is a module command, and there are enough parameters and the user has permission to the command */ @@ -792,10 +790,6 @@ class CoreExport InspIRCd */ void SendWhoisLine(User* user, User* dest, int numeric, const char* format, ...) CUSTOM_PRINTF(5, 6); - /** Handle /STATS - */ - void DoStats(char statschar, User* user, string_list &results); - /** Handle /WHOIS */ void DoWhois(User* user, User* dest,unsigned long signon, unsigned long idle, const char* nick); diff --git a/include/inspsocket.h b/include/inspsocket.h index f00d6a96a..6eb7eb584 100644 --- a/include/inspsocket.h +++ b/include/inspsocket.h @@ -85,7 +85,6 @@ class CoreExport SocketTimeout : public Timer public: /** Create a socket timeout class * @param fd File descriptor of BufferedSocket - * @pram Instance server instance to attach to * @param thesock BufferedSocket to attach to * @param secs_from_now Seconds from now to time out * @param now The current time @@ -195,9 +194,10 @@ class CoreExport BufferedSocket : public StreamSocket * This will create a socket, register with socket engine, and start the asynchronous * connection process. If an error is detected at this point (such as out of file descriptors), * OnError will be called; otherwise, the state will become CONNECTING. - * @param dest Address to connect to - * @param bind Address to bind to (if NULL, no bind will be done) - * @param timeout Time to wait for connection + * @param ipaddr Address to connect to + * @param aport Port to connect on + * @param maxtime Time to wait for connection + * @param connectbindip Address to bind to (if NULL, no bind will be done) */ void DoConnect(const std::string &ipaddr, int aport, unsigned long maxtime, const std::string &connectbindip); diff --git a/include/logger.h b/include/logger.h index 6c4acb41b..0fa4bc7cd 100644 --- a/include/logger.h +++ b/include/logger.h @@ -160,7 +160,7 @@ class CoreExport LogManager } } - /** Opens all logfiles defined in the configuration file using <log method="file">. + /** Opens all logfiles defined in the configuration file using \<log method="file">. */ void OpenFileLogs(); @@ -207,7 +207,7 @@ class CoreExport LogManager /** Logs an event, sending it to all LogStreams registered for the type. * @param type Log message type (ex: "USERINPUT", "MODULE", ...) * @param loglevel Log message level (DEBUG, VERBOSE, DEFAULT, SPARSE, NONE) - * @param msg The format of the message to be logged. See your C manual on printf() for details. + * @param fmt The format of the message to be logged. See your C manual on printf() for details. */ void Log(const std::string &type, int loglevel, const char *fmt, ...) CUSTOM_PRINTF(4, 5); }; diff --git a/include/membership.h b/include/membership.h index 281d04f70..436a9371c 100644 --- a/include/membership.h +++ b/include/membership.h @@ -35,4 +35,29 @@ class CoreExport Membership : public Extensible unsigned int getRank(); }; +class CoreExport InviteBase +{ + protected: + InviteList invites; + + public: + void ClearInvites(); + + friend class Invitation; +}; + +class Invitation : public classbase +{ + Invitation(Channel* c, LocalUser* u, time_t timeout) : user(u), chan(c), expiry(timeout) {} + + public: + LocalUser* const user; + Channel* const chan; + time_t expiry; + + ~Invitation(); + static void Create(Channel* c, LocalUser* u, time_t timeout); + static Invitation* Find(Channel* c, LocalUser* u, bool check_expired = true); +}; + #endif diff --git a/include/mode.h b/include/mode.h index 501d04aae..1dab442d4 100644 --- a/include/mode.h +++ b/include/mode.h @@ -154,6 +154,7 @@ class CoreExport ModeHandler : public ServiceProvider * The constructor for ModeHandler initalizes the mode handler. * The constructor of any class you derive from ModeHandler should * probably call this constructor with the parameters set correctly. + * @param me The module which created this mode * @param name A one-word name for the mode * @param modeletter The mode letter you wish to handle * @param params Parameters taken by the mode @@ -233,7 +234,7 @@ class CoreExport ModeHandler : public ServiceProvider */ virtual ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string ¶meter, bool adding); /* Can change the mode parameter as its a ref */ /** - * If your mode is a listmode, then this method will be called for displaying an item list, e.g. on MODE #channel +modechar + * If your mode is a listmode, then this method will be called for displaying an item list, e.g. on MODE \#channel +modechar * without any parameter or other modes in the command. * @param user The user issuing the command * @param channel The channel they're requesting an item list of (e.g. a banlist, or an exception list etc) @@ -274,6 +275,7 @@ class CoreExport ModeHandler : public ServiceProvider * and can be used when your mode is of this type, otherwise you must implement a more advanced version of it to remove * your mode properly from each user. * @param user The user which the server wants to remove your mode from + * @param stack The mode stack to add the mode change to */ virtual void RemoveMode(User* user, irc::modestacker* stack = NULL); @@ -284,6 +286,7 @@ class CoreExport ModeHandler : public ServiceProvider * and can be used when your mode is of this type, otherwise you must implement a more advanced version of it to remove * your mode properly from each channel. Note that in the case of listmodes, you should remove the entire list of items. * @param channel The channel which the server wants to remove your mode from + * @param stack The mode stack to add the mode change to */ virtual void RemoveMode(Channel* channel, irc::modestacker* stack = NULL); @@ -342,7 +345,7 @@ class CoreExport ModeWatcher : public classbase */ char mode; /** - * The mode type being watched (user or channel) + * The mode type being watched (user or channel) */ ModeType m_type; @@ -377,7 +380,7 @@ class CoreExport ModeWatcher : public classbase * If you alter the parameter you are given, the mode handler will see your atered version * when it handles the mode. * @param adding True if the mode is being added and false if it is being removed - * @type The mode type, either MODETYPE_USER or MODETYPE_CHANNEL + * @param type The mode type, either MODETYPE_USER or MODETYPE_CHANNEL * @return True to allow the mode change to go ahead, false to abort it. If you abort the * change, the mode handler (and ModeWatcher::AfterMode()) will never see the mode change. */ @@ -390,7 +393,7 @@ class CoreExport ModeWatcher : public classbase * @param parameter The parameter of the mode, if the mode is supposed to have a parameter. * You cannot alter the parameter here, as the mode handler has already processed it. * @param adding True if the mode is being added and false if it is being removed - * @type The mode type, either MODETYPE_USER or MODETYPE_CHANNEL + * @param type The mode type, either MODETYPE_USER or MODETYPE_CHANNEL */ virtual void AfterMode(User* source, User* dest, Channel* channel, const std::string ¶meter, bool adding, ModeType type); }; @@ -459,9 +462,9 @@ class CoreExport ModeParser * * nick!ident -> nick!ident@* * - * host.name -> *!*@host.name + * host.name -> *!*\@host.name * - * ident@host.name -> *!ident@host.name + * ident@host.name -> *!ident\@host.name * * This method can be used on both IPV4 and IPV6 user masks. */ @@ -508,14 +511,15 @@ class CoreExport ModeParser * @param parameters The parameters of the mode change, in the format * they would be from a MODE command. * @param user The user setting or removing the modes. When the modes are set - * by a server, an 'uninitialized' User is used, where *user::nick == NULL + * by a server, an 'uninitialized' User is used, where *user\::nick == NULL * and *user->server == NULL. + * @param merge Should the mode parameters be merged? */ void Process(const std::vector<std::string>& parameters, User *user, bool merge = false); /** Find the mode handler for a given mode and type. * @param modeletter mode letter to search for - * @param type of mode to search for, user or channel + * @param mt type of mode to search for, user or channel * @returns a pointer to a ModeHandler class, or NULL of there isnt a handler for the given mode */ ModeHandler* FindMode(unsigned const char modeletter, ModeType mt); diff --git a/include/modules.h b/include/modules.h index 7cd6bbeab..49c16ae61 100644 --- a/include/modules.h +++ b/include/modules.h @@ -116,7 +116,7 @@ struct ModResult { * and numerical comparisons in preprocessor macros if they wish to support * multiple versions of InspIRCd in one file. */ -#define INSPIRCD_VERSION_API 2 +#define INSPIRCD_VERSION_API 1 /** * This #define allows us to call a method in all @@ -339,7 +339,6 @@ enum Implementation I_OnWhoisLine, I_OnBuildNeighborList, I_OnGarbageCollect, I_OnSetConnectClass, I_OnText, I_OnPassCompare, I_OnRunTestSuite, I_OnNamesListItem, I_OnNumeric, I_OnHookIO, I_OnPreRehash, I_OnModuleRehash, I_OnSendWhoLine, I_OnChangeIdent, - I_OnSetClientIP, I_END }; @@ -431,6 +430,7 @@ class CoreExport Module : public classbase, public usecountbase * @param sync This is set to true if the JOIN is the result of a network sync and the remote user is being introduced * to a channel due to the network sync. * @param created This is true if the join created the channel + * @param except_list A list of users not to send to. */ virtual void OnUserJoin(Membership* memb, bool sync, bool created, CUList& except_list); @@ -439,13 +439,14 @@ class CoreExport Module : public classbase, public usecountbase * seen the join. * @param memb The channel membership created */ - virtual void OnPostJoin(Membership*); + virtual void OnPostJoin(Membership* memb); /** Called when a user parts a channel. * The details of the leaving user are available to you in the parameter User *user, * and the details of the channel they have left is available in the variable Channel *channel * @param memb The channel membership being destroyed * @param partmessage The part message, or an empty string (may be modified) + * @param except_list A list of users to not send to. */ virtual void OnUserPart(Membership* memb, std::string &partmessage, CUList& except_list); @@ -515,8 +516,7 @@ class CoreExport Module : public classbase, public usecountbase * output to be sent to the user by the core. If you do this you must produce your own numerics, * notices etc. * @param source The user issuing the kick - * @param user The user being kicked - * @param chan The channel the user is being kicked from + * @param memb The channel membership of the user who is being kicked. * @param reason The kick reason * @return 1 to prevent the kick, 0 to continue normally, -1 to explicitly allow the kick regardless of normal operation */ @@ -526,9 +526,9 @@ class CoreExport Module : public classbase, public usecountbase * If this method is called, the kick is already underway and cannot be prevented, so * to prevent a kick, please use Module::OnUserPreKick instead of this method. * @param source The user issuing the kick - * @param user The user being kicked - * @param chan The channel the user is being kicked from + * @param memb The channel membership of the user who was kicked. * @param reason The kick reason + * @param except_list A list of users to not send to. */ virtual void OnUserKick(User* source, Membership* memb, const std::string &reason, CUList& except_list); @@ -662,6 +662,7 @@ class CoreExport Module : public classbase, public usecountbase * @param target_type The type of target (TYPE_USER or TYPE_CHANNEL) * @param text the text being sent by the user * @param status The status being used, e.g. PRIVMSG @#chan has status== '@', 0 to send to everyone. + * @param exempt_list A list of users to not send to. */ virtual void OnUserMessage(User* user, void* dest, int target_type, const std::string &text, char status, const CUList &exempt_list); @@ -673,6 +674,7 @@ class CoreExport Module : public classbase, public usecountbase * @param target_type The type of target (TYPE_USER or TYPE_CHANNEL) * @param text the text being sent by the user * @param status The status being used, e.g. NOTICE @#chan has status== '@', 0 to send to everyone. + * @param exempt_list A list of users to not send to. */ virtual void OnUserNotice(User* user, void* dest, int target_type, const std::string &text, char status, const CUList &exempt_list); @@ -687,6 +689,7 @@ class CoreExport Module : public classbase, public usecountbase * @param target_type The type of target (TYPE_USER or TYPE_CHANNEL) * @param text the text being sent by the user * @param status The status being used, e.g. NOTICE @#chan has status== '@', 0 to send to everyone. + * @param exempt_list A list of users not to send to. For channel messages, this will usually contain just the sender. */ virtual void OnText(User* user, void* dest, int target_type, const std::string &text, char status, CUList &exempt_list); @@ -756,7 +759,6 @@ class CoreExport Module : public classbase, public usecountbase /** Allows module data, sent via ProtoSendMetaData, to be decoded again by a receiving module. * Please see src/modules/m_swhois.cpp for a working example of how to use this method call. - * @param target_type The type of item to decode data for, TYPE_USER or TYPE_CHANNEL * @param target The Channel* or User* that data should be added to * @param extname The extension name which is being sent * @param extdata The extension data, encoded at the other end by an identical module through OnSyncChannelMetaData or OnSyncUserMetaData @@ -788,7 +790,6 @@ class CoreExport Module : public classbase, public usecountbase * More documentation to follow soon. Please see src/modules/m_swhois.cpp for example of * how to use this function. * @param opaque An opaque pointer set by the protocol module, should not be modified! - * @param target_type The type of item to decode data for, TYPE_USER or TYPE_CHANNEL * @param target The Channel* or User* that metadata should be sent for * @param extname The extension name to send metadata for * @param extdata Encoded data for this extension name, which will be encoded at the oppsite end by an identical module using OnDecodeMetaData @@ -818,7 +819,7 @@ class CoreExport Module : public classbase, public usecountbase /** Called whenever a user's IDENT is changed. * This event triggers after the name has been set. * @param user The user who's IDENT is being changed - * @param gecos The new IDENT being set on the user + * @param ident The new IDENT being set on the user */ virtual void OnChangeIdent(User* user, const std::string &ident); @@ -902,6 +903,7 @@ class CoreExport Module : public classbase, public usecountbase * @param source The user sending the KILL * @param dest The user being killed * @param reason The kill reason + * @param operreason The oper kill reason */ virtual void OnRemoteKill(User* source, User* dest, const std::string &reason, const std::string &operreason); @@ -928,7 +930,6 @@ class CoreExport Module : public classbase, public usecountbase * absolutely neccessary (e.g. a module that extends the features of another * module). * @param mod Pointer to the module being unloaded (still valid) - * @param name The filename of the module being unloaded */ virtual void OnUnloadModule(Module* mod); @@ -951,7 +952,6 @@ class CoreExport Module : public classbase, public usecountbase * method returns, it will be passed an invalid pointer to the user object and crash!) * @param command The command being executed * @param parameters An array of array of characters containing the parameters for the command - * @param pcnt The nuimber of parameters passed to the command * @param user the user issuing the command * @param validated True if the command has passed all checks, e.g. it is recognised, has enough parameters, the user has permission to execute it, etc. * You should only change the parameter list and command string if validated == false (e.g. before the command lookup occurs). @@ -967,7 +967,6 @@ class CoreExport Module : public classbase, public usecountbase * provided. * @param command The command being executed * @param parameters An array of array of characters containing the parameters for the command - * @param pcnt The nuimber of parameters passed to the command * @param user the user issuing the command * @param result The return code given by the command handler, one of CMD_SUCCESS or CMD_FAILURE * @param original_line The entire original line as passed to the parser from the user @@ -1033,6 +1032,7 @@ class CoreExport Module : public classbase, public usecountbase * return 1 to explicitly allow the join to go ahead or 0 to ignore the event. * @param user The user joining the channel * @param chan The channel being joined + * @param keygiven The key given on joining the channel. * @return 1 to explicitly allow the join, 0 to proceed as normal */ virtual ModResult OnCheckKey(User* user, Channel* chan, const std::string &keygiven); @@ -1105,7 +1105,7 @@ class CoreExport Module : public classbase, public usecountbase * @param user The user changing the topic * @param chan The channels who's topic is being changed * @param topic The actual topic text - * @param 1 to block the topic change, 0 to allow + * @return 1 to block the topic change, 0 to allow */ virtual ModResult OnPreTopicChange(User* user, Channel* chan, const std::string &topic); @@ -1133,7 +1133,7 @@ class CoreExport Module : public classbase, public usecountbase * The password field (from the config file) is in 'password' and is to be compared against * 'input'. This method allows for encryption of passwords (oper, connect:allow, die/restart, etc). * You should return a nonzero value to override the normal comparison, or zero to pass it on. - * @param ex The object that's causing the authentication (User* for <oper> <connect:allow> etc, Server* for <link>). + * @param ex The object that's causing the authentication (User* for \<oper> \<connect:allow> etc, Server* for \<link>). * @param password The password from the configuration file (the password="" value). * @param input The password entered by the user or whoever. * @param hashtype The hash value from the config @@ -1176,62 +1176,61 @@ class CoreExport Module : public classbase, public usecountbase virtual ModResult OnDelBan(User* source, Channel* channel,const std::string &banmask); /** Called to install an I/O hook on an event handler - * @param user The item to possibly install the I/O hook on - * @param via The port that <user> connected on + * @param user The socket to possibly install the I/O hook on + * @param via The port that the user connected on */ - virtual void OnHookIO(StreamSocket*, ListenSocket* via); + virtual void OnHookIO(StreamSocket* user, ListenSocket* via); /** Called when a port accepts a connection * Return MOD_RES_ACCEPT if you have used the file descriptor. * @param fd The file descriptor returned from accept() - * @param from The local port the user connected to + * @param sock The socket connection for the new user * @param client The client IP address and port * @param server The server IP address and port */ - virtual ModResult OnAcceptConnection(int fd, ListenSocket* from, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server); + virtual ModResult OnAcceptConnection(int fd, ListenSocket* sock, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server); /** Called immediately after any connection is accepted. This is intended for raw socket * processing (e.g. modules which wrap the tcp connection within another library) and provides * no information relating to a user record as the connection has not been assigned yet. * There are no return values from this call as all modules get an opportunity if required to * process the connection. - * @param fd The file descriptor returned from accept() + * @param sock The socket in question * @param client The client IP address and port * @param server The server IP address and port - * @param localport The local port number the user connected to */ - virtual void OnStreamSocketAccept(StreamSocket*, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server); + virtual void OnStreamSocketAccept(StreamSocket* sock, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server); /** * Called when a hooked stream has data to write, or when the socket * engine returns it as writable - * @param socket The socket in question + * @param sock The socket in question * @param sendq Data to send to the socket * @return 1 if the sendq has been completely emptied, 0 if there is * still data to send, and -1 if there was an error */ - virtual int OnStreamSocketWrite(StreamSocket*, std::string& sendq); + virtual int OnStreamSocketWrite(StreamSocket* sock, std::string& sendq); /** Called immediately before any socket is closed. When this event is called, shutdown() * has not yet been called on the socket. - * @param fd The file descriptor of the socket prior to close() + * @param sock The socket in question */ - virtual void OnStreamSocketClose(StreamSocket*); + virtual void OnStreamSocketClose(StreamSocket* sock); /** Called immediately upon connection of an outbound BufferedSocket which has been hooked * by a module. - * @param fd The file descriptor of the socket immediately after connect() + * @param sock The socket in question */ - virtual void OnStreamSocketConnect(StreamSocket*); + virtual void OnStreamSocketConnect(StreamSocket* sock); /** * Called when the stream socket has data to read - * @param socket The socket that is ready + * @param sock The socket that is ready * @param recvq The receive queue that new data should be appended to * @return 1 if new data has been read, 0 if no new data is ready (but the * socket is still connected), -1 if there was an error or close */ - virtual int OnStreamSocketRead(StreamSocket*, std::string& recvq); + virtual int OnStreamSocketRead(StreamSocket* sock, std::string& recvq); /** Called whenever a user sets away or returns from being away. * The away message is available as a parameter, but should not be modified. @@ -1289,11 +1288,6 @@ class CoreExport Module : public classbase, public usecountbase * @param line The raw line to send; modifiable, if empty no line will be returned. */ virtual void OnSendWhoLine(User* source, const std::vector<std::string>& params, User* user, std::string& line); - - /** Called whenever a User's ip changes. - * @param user The user whose ip changed. - */ - virtual void OnSetClientIP(User *user); }; @@ -1564,13 +1558,14 @@ class CoreExport ModuleManager * automatically detatch your module from all events it is attached to. * @param i Event type to detach * @param mod Module to detach event from - * @param Detach true if the event was detached + * @return True if the event was detached */ bool Detach(Implementation i, Module* mod); /** Attach an array of events to a module * @param i Event types (array) to attach * @param mod Module to attach events to + * @param sz The size of the implementation array */ void Attach(Implementation* i, Module* mod, size_t sz); diff --git a/include/protocol.h b/include/protocol.h index c880eee23..aabb5b022 100644 --- a/include/protocol.h +++ b/include/protocol.h @@ -70,7 +70,8 @@ class ProtocolInterface /** Send mode changes for an object. * @param target The channel name or user to send mode changes for. - * @param The mode changes to send. + * @param modedata The mode changes to send. + * @param translate A list of translation types */ virtual void SendMode(const std::string &target, const parameterlist &modedata, const std::vector<TranslateType> &translate) { } diff --git a/include/socket.h b/include/socket.h index 7fa58f8ad..16809c3f8 100644 --- a/include/socket.h +++ b/include/socket.h @@ -105,6 +105,7 @@ namespace irc * IPV6 addresses. * @param address The human readable address, e.g. fred\@1.2.3.4 * @param cidr_mask The human readable mask, e.g. *\@1.2.0.0/16 + * @param match_with_username Does the mask include a nickname segment? * @return True if the mask matches the address */ CoreExport bool MatchCIDR(const std::string &address, const std::string &cidr_mask, bool match_with_username); diff --git a/include/socketengine.h b/include/socketengine.h index 7e089da6b..b790f6d77 100644 --- a/include/socketengine.h +++ b/include/socketengine.h @@ -202,7 +202,9 @@ class CoreExport EventHandler : public classbase * class, and it will be called whenever read or write * events are received. * @param et either one of EVENT_READ for read events, - * and EVENT_WRITE for write events. + * EVENT_WRITE for write events and EVENT_ERROR for + * error events. + * @param errornum The error code which goes with an EVENT_ERROR. */ virtual void HandleEvent(EventType et, int errornum = 0) = 0; @@ -358,6 +360,8 @@ public: /** Abstraction for BSD sockets accept(2). * This function should emulate its namesake system call exactly. * @param fd This version of the call takes an EventHandler instead of a bare file descriptor. + * @param addr The client IP address and port + * @param addrlen The size of the sockaddr parameter. * @return This method should return exactly the same values as the system call it emulates. */ int Accept(EventHandler* fd, sockaddr *addr, socklen_t *addrlen); @@ -379,6 +383,9 @@ public: /** Abstraction for BSD sockets send(2). * This function should emulate its namesake system call exactly. * @param fd This version of the call takes an EventHandler instead of a bare file descriptor. + * @param buf The buffer in which the data that is sent is stored. + * @param len The size of the buffer. + * @param flags A flag value that controls the sending of the data. * @return This method should return exactly the same values as the system call it emulates. */ int Send(EventHandler* fd, const void *buf, size_t len, int flags); @@ -386,6 +393,9 @@ public: /** Abstraction for BSD sockets recv(2). * This function should emulate its namesake system call exactly. * @param fd This version of the call takes an EventHandler instead of a bare file descriptor. + * @param buf The buffer in which the data that is read is stored. + * @param len The size of the buffer. + * @param flags A flag value that controls the reception of the data. * @return This method should return exactly the same values as the system call it emulates. */ int Recv(EventHandler* fd, void *buf, size_t len, int flags); @@ -393,6 +403,11 @@ public: /** Abstraction for BSD sockets recvfrom(2). * This function should emulate its namesake system call exactly. * @param fd This version of the call takes an EventHandler instead of a bare file descriptor. + * @param buf The buffer in which the data that is read is stored. + * @param len The size of the buffer. + * @param flags A flag value that controls the reception of the data. + * @param from The remote IP address and port. + * @param fromlen The size of the from parameter. * @return This method should return exactly the same values as the system call it emulates. */ int RecvFrom(EventHandler* fd, void *buf, size_t len, int flags, sockaddr *from, socklen_t *fromlen); @@ -400,6 +415,11 @@ public: /** Abstraction for BSD sockets sendto(2). * This function should emulate its namesake system call exactly. * @param fd This version of the call takes an EventHandler instead of a bare file descriptor. + * @param buf The buffer in which the data that is sent is stored. + * @param len The size of the buffer. + * @param flags A flag value that controls the sending of the data. + * @param to The remote IP address and port. + * @param tolen The size of the to parameter. * @return This method should return exactly the same values as the system call it emulates. */ int SendTo(EventHandler* fd, const void *buf, size_t len, int flags, const sockaddr *to, socklen_t tolen); @@ -407,6 +427,8 @@ public: /** Abstraction for BSD sockets connect(2). * This function should emulate its namesake system call exactly. * @param fd This version of the call takes an EventHandler instead of a bare file descriptor. + * @param serv_addr The server IP address and port. + * @param addrlen The size of the sockaddr parameter. * @return This method should return exactly the same values as the system call it emulates. */ int Connect(EventHandler* fd, const sockaddr *serv_addr, socklen_t addrlen); @@ -426,6 +448,7 @@ public: /** Abstraction for BSD sockets shutdown(2). * This function should emulate its namesake system call exactly. * @param fd This version of the call takes an EventHandler instead of a bare file descriptor. + * @param how What part of the socket to shut down * @return This method should return exactly the same values as the system call it emulates. */ int Shutdown(EventHandler* fd, int how); diff --git a/include/threadengines/threadengine_pthread.h b/include/threadengines/threadengine_pthread.h index 9ae5fb3cb..5168ed238 100644 --- a/include/threadengines/threadengine_pthread.h +++ b/include/threadengines/threadengine_pthread.h @@ -39,7 +39,6 @@ class CoreExport ThreadEngine public: /** Constructor. - * @param Instance Creator object */ ThreadEngine(); diff --git a/include/timer.h b/include/timer.h index 0de6710ac..9bb7128b8 100644 --- a/include/timer.h +++ b/include/timer.h @@ -137,11 +137,6 @@ class CoreExport TimerManager /** Add an Timer * @param T an Timer derived class to add - * @param secs_from_now You may set this to the number of seconds - * from the current time when the timer will tick, or you may just - * leave this unset and the values set by the Timers constructor - * will be used. This is used internally for re-triggering repeating - * timers. */ void AddTimer(Timer *T); diff --git a/include/typedefs.h b/include/typedefs.h index 615af6c9c..7659628d2 100644 --- a/include/typedefs.h +++ b/include/typedefs.h @@ -34,6 +34,8 @@ class DNSRequest; class Extensible; class FakeUser; class InspIRCd; +class Invitation; +class InviteBase; class LocalUser; class Membership; class Module; @@ -72,7 +74,7 @@ typedef std::vector<std::pair<std::string, std::string> > FailedPortList; /** Holds a complete list of all channels to which a user has been invited and has not yet joined, and the time at which they'll expire. */ -typedef std::vector< std::pair<irc::string, time_t> > InvitedList; +typedef std::vector<Invitation*> InviteList; /** Holds a complete list of all allow and deny tags from the configuration file (connection classes) */ diff --git a/include/usermanager.h b/include/usermanager.h index b549edb10..92b40b373 100644 --- a/include/usermanager.h +++ b/include/usermanager.h @@ -73,7 +73,6 @@ class CoreExport UserManager /** Add a client to the system. * This will create a new User, insert it into the user_hash, * initialize it as not yet registered, and add it to the socket engine. - * @param Instance a pointer to the server instance * @param socket The socket id (file descriptor) this user is on * @param via The socket that this user connected using * @param client The IP address and client port of the user @@ -84,8 +83,8 @@ class CoreExport UserManager /** Disconnect a user gracefully * @param user The user to remove - * @param r The quit reason to show to normal users - * @param oreason The quit reason to show to opers + * @param quitreason The quit reason to show to normal users + * @param operreason The quit reason to show to opers * @return Although this function has no return type, on exit the user provided will no longer exist. */ void QuitUser(User *user, const std::string &quitreason, const char* operreason = ""); diff --git a/include/users.h b/include/users.h index cdc0d8078..57dea3fa5 100644 --- a/include/users.h +++ b/include/users.h @@ -29,6 +29,7 @@ #include "inspsocket.h" #include "dns.h" #include "mode.h" +#include "membership.h" /** connect class types */ @@ -394,11 +395,6 @@ class CoreExport User : public Extensible */ bool SetClientIP(const char* sip); - /** Sets the client IP for this user - * @return true always - */ - bool SetClientIP(irc::sockets::sockaddrs *sa); - /** Constructor * @throw CoreException if the UID allocated to the user already exists */ @@ -412,14 +408,14 @@ class CoreExport User : public Extensible /** Returns the full displayed host of the user * This member function returns the hostname of the user as seen by other users - * on the server, in nick!ident&at;host form. + * on the server, in nick!ident\@host form. * @return The full masked host of the user */ virtual const std::string& GetFullHost(); /** Returns the full real host of the user * This member function returns the hostname of the user as seen by other users - * on the server, in nick!ident&at;host form. If any form of hostname cloaking is in operation, + * on the server, in nick!ident\@host form. If any form of hostname cloaking is in operation, * e.g. through a module, then this method will ignore it and return the true hostname. * @return The full real host of the user */ @@ -456,7 +452,7 @@ class CoreExport User : public Extensible void SetNoticeMask(unsigned char sm, bool value); /** Create a displayable mode string for this users umodes - * @param The mode string + * @param showparameters The mode string */ const char* FormatModes(bool showparameters = false); @@ -500,20 +496,20 @@ class CoreExport User : public Extensible virtual bool HasModePermission(unsigned char mode, ModeType type); /** Creates a wildcard host. - * Takes a buffer to use and fills the given buffer with the host in the format *!*@hostname - * @return The wildcarded hostname in *!*@host form + * Takes a buffer to use and fills the given buffer with the host in the format *!*\@hostname + * @return The wildcarded hostname in *!*\@host form */ char* MakeWildHost(); /** Creates a usermask with real host. - * Takes a buffer to use and fills the given buffer with the hostmask in the format user@host - * @return the usermask in the format user@host + * Takes a buffer to use and fills the given buffer with the hostmask in the format user\@host + * @return the usermask in the format user\@host */ const std::string& MakeHost(); /** Creates a usermask with real ip. - * Takes a buffer to use and fills the given buffer with the ipmask in the format user@ip - * @return the usermask in the format user@ip + * Takes a buffer to use and fills the given buffer with the ipmask in the format user\@ip + * @return the usermask in the format user\@ip */ const std::string& MakeHostIP(); @@ -569,34 +565,35 @@ class CoreExport User : public Extensible void WriteNumeric(unsigned int numeric, const std::string &text); - /** Write text to this user, appending CR/LF and prepending :nick!user@host of the user provided in the first parameter. - * @param user The user to prepend the :nick!user@host of + /** Write text to this user, appending CR/LF and prepending :nick!user\@host of the user provided in the first parameter. + * @param user The user to prepend the :nick!user\@host of * @param text A std::string to send to the user */ void WriteFrom(User *user, const std::string &text); - /** Write text to this user, appending CR/LF and prepending :nick!user@host of the user provided in the first parameter. - * @param user The user to prepend the :nick!user@host of + /** Write text to this user, appending CR/LF and prepending :nick!user\@host of the user provided in the first parameter. + * @param user The user to prepend the :nick!user\@host of * @param text The format string for text to send to the user * @param ... POD-type format arguments */ void WriteFrom(User *user, const char* text, ...) CUSTOM_PRINTF(3, 4); - /** Write text to the user provided in the first parameter, appending CR/LF, and prepending THIS user's :nick!user@host. + /** Write text to the user provided in the first parameter, appending CR/LF, and prepending THIS user's :nick!user\@host. * @param dest The user to route the message to - * @param text A std::string to send to the user + * @param data A std::string to send to the user */ void WriteTo(User *dest, const std::string &data); - /** Write text to the user provided in the first parameter, appending CR/LF, and prepending THIS user's :nick!user@host. + /** Write text to the user provided in the first parameter, appending CR/LF, and prepending THIS user's :nick!user\@host. * @param dest The user to route the message to - * @param text The format string for text to send to the user + * @param data The format string for text to send to the user * @param ... POD-type format arguments */ void WriteTo(User *dest, const char *data, ...) CUSTOM_PRINTF(3, 4); - /** Write to all users that can see this user (including this user in the list), appending CR/LF - * @param text A std::string to send to the users + /** Write to all users that can see this user (including this user in the list if include_self is true), appending CR/LF + * @param line A std::string to send to the users + * @param include_self Should the message be sent back to the author? */ void WriteCommonRaw(const std::string &line, bool include_self = true); @@ -643,7 +640,7 @@ class CoreExport User : public Extensible * Run this after the item in question has changed. * You should not need to use this function, call ChangeDisplayedHost instead * - * @param The entire QUIT line, including the source using the old value + * @param quitline The entire QUIT line, including the source using the old value */ void DoHostCycle(const std::string &quitline); @@ -661,7 +658,7 @@ class CoreExport User : public Extensible * ALWAYS use this function, rather than writing User::ident directly, * as this correctly causes the user to seem to quit (where configured) * before setting their ident field. - * @param host The new ident to set + * @param newident The new ident to set * @return True if the change succeeded, false if it didn't */ bool ChangeIdent(const char* newident); @@ -740,14 +737,8 @@ class CoreExport UserIOHandler : public StreamSocket typedef unsigned int already_sent_t; -class CoreExport LocalUser : public User +class CoreExport LocalUser : public User, public InviteBase { - /** A list of channels the user has a pending invite to. - * Upon INVITE channels are added, and upon JOIN, the - * channels are removed from this list. - */ - InvitedList invites; - public: LocalUser(int fd, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server); CullResult cull(); @@ -771,7 +762,7 @@ class CoreExport LocalUser : public User int cmds_out; /** Password specified by the user when they registered (if any). - * This is stored even if the <connect> block doesnt need a password, so that + * This is stored even if the \<connect> block doesnt need a password, so that * modules may check it. */ std::string password; @@ -782,7 +773,7 @@ class CoreExport LocalUser : public User ConnectClass* GetClass(); - /** Call this method to find the matching <connect> for a user, and to check them against it. + /** Call this method to find the matching \<connect> for a user, and to check them against it. */ void CheckClass(); @@ -823,7 +814,7 @@ class CoreExport LocalUser : public User void FullConnect(); /** Set the connect class to which this user belongs to. - * @param explicit_name Set this string to tie the user to a specific class name. Otherwise, the class is fitted by checking <connect> tags from the configuration file. + * @param explicit_name Set this string to tie the user to a specific class name. Otherwise, the class is fitted by checking \<connect> tags from the configuration file. * @return A reference to this user's current connect class. */ void SetClass(const std::string &explicit_name = ""); @@ -835,7 +826,7 @@ class CoreExport LocalUser : public User /** Returns the list of channels this user has been invited to but has not yet joined. * @return A list of channels the user is invited to */ - InvitedList* GetInviteList(); + InviteList& GetInviteList(); /** Returns true if a user is invited to a channel. * @param channel A channel name to look up @@ -856,6 +847,8 @@ class CoreExport LocalUser : public User */ void RemoveInvite(const irc::string &channel); + void RemoveExpiredInvites(); + /** Returns true or false for if a user can execute a privilaged oper command. * This is done by looking up their oper type from User::oper, then referencing * this to their oper classes and checking the commands they can execute. @@ -940,7 +933,6 @@ class CoreExport UserResolver : public Resolver bool fwd; public: /** Create a resolver. - * @param Instance The creating instance * @param user The user to begin lookup on * @param to_resolve The IP or host to resolve * @param qt The query type diff --git a/include/xline.h b/include/xline.h index bde3d3fda..2a49d8b80 100644 --- a/include/xline.h +++ b/include/xline.h @@ -104,10 +104,10 @@ class CoreExport XLine : public classbase virtual void DisplayExpiry() = 0; /** Returns the displayable form of the pattern for this xline, - * e.g. '*@foo' or '*baz*'. This must always return the full pattern + * e.g. '*\@foo' or '*baz*'. This must always return the full pattern * in a form which can be used to construct an entire derived xline, * even if it is stored differently internally (e.g. GLine stores the - * ident and host parts seperately but will still return ident@host + * ident and host parts seperately but will still return ident\@host * for its Displayable() method) */ virtual const char* Displayable() = 0; @@ -376,7 +376,6 @@ class CoreExport XLineFactory public: /** Create an XLine factory - * @param Instance creator * @param t Type of XLine this factory generates */ XLineFactory(const std::string &t) : type(t) { } @@ -428,7 +427,6 @@ class CoreExport XLineManager public: /** Constructor - * @param Instance A pointer to the creator object */ XLineManager(); @@ -448,7 +446,7 @@ class CoreExport XLineManager /** Get all lines of a certain type to an XLineLookup (std::map<std::string, XLine*>). * NOTE: When this function runs any expired items are removed from the list before it * is returned to the caller. - * @param The type to look up + * @param type The type to look up * @return A list of all XLines of the given type. */ XLineLookup* GetAll(const std::string &type); @@ -531,6 +529,7 @@ class CoreExport XLineManager /** Handle /STATS for a given type. * NOTE: Any items in the list for this particular line type which have expired * will be expired and removed before the list is displayed. + * @param type The type of stats to show * @param numeric The numeric to give to each result line * @param user The username making the query * @param results The string_list to receive the results diff --git a/make/gnutlscert.pm b/make/gnutlscert.pm index 1621c2c27..ab8aae427 100644 --- a/make/gnutlscert.pm +++ b/make/gnutlscert.pm @@ -36,7 +36,7 @@ sub make_gnutls_cert() my $timestr = time(); my $org = promptstring_s("Please enter the organization name", "My IRC Network"); my $unit = promptstring_s("Please enter the unit Name", "Server Admins"); - my $state = promptstring_s("Pleae enter your state (two letter code)", "CA"); + my $state = promptstring_s("Please enter your state (two letter code)", "CA"); my $country = promptstring_s("Please enter your country", "Oompa Loompa Land"); my $commonname = promptstring_s("Please enter the certificate common name (hostname)", "irc.mynetwork.com"); my $email = promptstring_s("Please enter a contact email address", "oompa\@loompa.com"); diff --git a/src/channelmanager.cpp b/src/channelmanager.cpp deleted file mode 100644 index c9aff2b56..000000000 --- a/src/channelmanager.cpp +++ /dev/null @@ -1,22 +0,0 @@ -/* - * InspIRCd -- Internet Relay Chat Daemon - * - * - * 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/>. - */ - - -/* $Core */ - -#include "inspircd.h" - diff --git a/src/channels.cpp b/src/channels.cpp index 4a927cedb..c265171b5 100644 --- a/src/channels.cpp +++ b/src/channels.cpp @@ -172,6 +172,8 @@ void Channel::DelUser(User* user) FOREACH_MOD(I_OnChannelDelete, OnChannelDelete(this)); ServerInstance->chanlist->erase(iter); } + + ClearInvites(); ServerInstance->GlobalCulls.AddItem(this); } } @@ -969,3 +971,89 @@ void Channel::RemoveAllPrefixes(User* user) m->second->modes.clear(); } } + +void Invitation::Create(Channel* c, LocalUser* u, time_t timeout) +{ + if ((timeout != 0) && (ServerInstance->Time() >= timeout)) + // Expired, don't bother + return; + + ServerInstance->Logs->Log("INVITATION", DEBUG, "Invitation::Create chan=%s user=%s", c->name.c_str(), u->uuid.c_str()); + + Invitation* inv = Invitation::Find(c, u, false); + if (inv) + { + if ((inv->expiry == 0) || (inv->expiry > timeout)) + return; + inv->expiry = timeout; + ServerInstance->Logs->Log("INVITATION", DEBUG, "Invitation::Create changed expiry in existing invitation %p", (void*) inv); + } + else + { + inv = new Invitation(c, u, timeout); + c->invites.push_back(inv); + u->invites.push_back(inv); + ServerInstance->Logs->Log("INVITATION", DEBUG, "Invitation::Create created new invitation %p", (void*) inv); + } +} + +Invitation* Invitation::Find(Channel* c, LocalUser* u, bool check_expired) +{ + ServerInstance->Logs->Log("INVITATION", DEBUG, "Invitation::Find chan=%s user=%s check_expired=%d", c ? c->name.c_str() : "NULL", u ? u->uuid.c_str() : "NULL", check_expired); + if (!u || u->invites.empty()) + return NULL; + + InviteList locallist; + locallist.swap(u->invites); + + Invitation* result = NULL; + for (InviteList::iterator i = locallist.begin(); i != locallist.end(); ) + { + Invitation* inv = *i; + if ((check_expired) && (inv->expiry != 0) && (inv->expiry <= ServerInstance->Time())) + { + /* Expired invite, remove it. */ + ServerInstance->Logs->Log("INVITATION", DEBUG, "Invitation::Find ecountered expired entry: %p expired %s", (void*) inv, ServerInstance->TimeString(inv->expiry).c_str()); + i = locallist.erase(i); + inv->cull(); + delete inv; + } + else + { + /* Is it what we're searching for? */ + if (inv->chan == c) + { + result = inv; + break; + } + ++i; + } + } + + locallist.swap(u->invites); + ServerInstance->Logs->Log("INVITATION", DEBUG, "Invitation::Find result=%p", (void*) result); + return result; +} + +Invitation::~Invitation() +{ + // Remove this entry from both lists + InviteList::iterator it = std::find(chan->invites.begin(), chan->invites.end(), this); + if (it != chan->invites.end()) + chan->invites.erase(it); + it = std::find(user->invites.begin(), user->invites.end(), this); + if (it != user->invites.end()) + user->invites.erase(it); +} + +void InviteBase::ClearInvites() +{ + ServerInstance->Logs->Log("INVITEBASE", DEBUG, "InviteBase::ClearInvites %p", (void*) this); + InviteList locallist; + locallist.swap(invites); + for (InviteList::const_iterator i = locallist.begin(); i != locallist.end(); ++i) + { + (*i)->cull(); + delete *i; + } +} diff --git a/src/commands/cmd_away.cpp b/src/commands/cmd_away.cpp index cd47e49ef..fa3f7fae9 100644 --- a/src/commands/cmd_away.cpp +++ b/src/commands/cmd_away.cpp @@ -20,14 +20,6 @@ #include "inspircd.h" -#ifndef CMD_AWAY_H -#define CMD_AWAY_H - -// include the common header files - -#include "users.h" -#include "channels.h" - /** Handle /AWAY. These command handlers can be reloaded by the core, * and handle basic RFC1459 commands. Commands within modules work * the same way, however, they can be fully unloaded, where these @@ -48,9 +40,6 @@ class CommandAway : public Command CmdResult Handle(const std::vector<std::string>& parameters, User *user); }; -#endif - - /** Handle /AWAY */ CmdResult CommandAway::Handle (const std::vector<std::string>& parameters, User *user) diff --git a/src/commands/cmd_clearcache.cpp b/src/commands/cmd_clearcache.cpp index b47017c07..5914f9a8f 100644 --- a/src/commands/cmd_clearcache.cpp +++ b/src/commands/cmd_clearcache.cpp @@ -20,10 +20,6 @@ #include "inspircd.h" -#include "users.h" -#include "channels.h" -#include "ctables.h" - /** Handle /CLEARCACHE. These command handlers can be reloaded by the core, * and handle basic RFC1459 commands. Commands within modules work * the same way, however, they can be fully unloaded, where these diff --git a/src/commands/cmd_commands.cpp b/src/commands/cmd_commands.cpp index 2d4d42a1f..36408b363 100644 --- a/src/commands/cmd_commands.cpp +++ b/src/commands/cmd_commands.cpp @@ -20,14 +20,6 @@ #include "inspircd.h" -#ifndef CMD_COMMANDS_H -#define CMD_COMMANDS_H - -// include the common header files - -#include "users.h" -#include "channels.h" - /** Handle /COMMANDS. These command handlers can be reloaded by the core, * and handle basic RFC1459 commands. Commands within modules work * the same way, however, they can be fully unloaded, where these @@ -48,9 +40,6 @@ class CommandCommands : public Command CmdResult Handle(const std::vector<std::string>& parameters, User *user); }; -#endif - - /** Handle /COMMANDS */ CmdResult CommandCommands::Handle (const std::vector<std::string>&, User *user) @@ -59,6 +48,10 @@ CmdResult CommandCommands::Handle (const std::vector<std::string>&, User *user) list.reserve(ServerInstance->Parser->cmdlist.size()); for (Commandtable::iterator i = ServerInstance->Parser->cmdlist.begin(); i != ServerInstance->Parser->cmdlist.end(); i++) { + // Don't show S2S commands to users + if (i->second->flags_needed == FLAG_SERVERONLY) + continue; + Module* src = i->second->creator; char buffer[MAXBUF]; snprintf(buffer, MAXBUF, ":%s %03d %s :%s %s %d %d", diff --git a/src/commands/cmd_eline.cpp b/src/commands/cmd_eline.cpp index 0523d052f..15487bd8e 100644 --- a/src/commands/cmd_eline.cpp +++ b/src/commands/cmd_eline.cpp @@ -21,14 +21,6 @@ #include "inspircd.h" #include "xline.h" -#ifndef CMD_ELINE_H -#define CMD_ELINE_H - -// include the common header files - -#include "users.h" -#include "channels.h" - /** Handle /ELINE. These command handlers can be reloaded by the core, * and handle basic RFC1459 commands. Commands within modules work * the same way, however, they can be fully unloaded, where these @@ -49,9 +41,6 @@ class CommandEline : public Command CmdResult Handle(const std::vector<std::string>& parameters, User *user); }; -#endif - - /** Handle /ELINE */ CmdResult CommandEline::Handle (const std::vector<std::string>& parameters, User *user) diff --git a/src/commands/cmd_invite.cpp b/src/commands/cmd_invite.cpp index 3baa9cb03..200cce4a3 100644 --- a/src/commands/cmd_invite.cpp +++ b/src/commands/cmd_invite.cpp @@ -132,10 +132,10 @@ CmdResult CommandInvite::Handle (const std::vector<std::string>& parameters, Use { // pinched from ircu - invite with not enough parameters shows channels // youve been invited to but haven't joined yet. - InvitedList* il = IS_LOCAL(user)->GetInviteList(); - for (InvitedList::iterator i = il->begin(); i != il->end(); i++) + InviteList& il = IS_LOCAL(user)->GetInviteList(); + for (InviteList::const_iterator i = il.begin(); i != il.end(); ++i) { - user->WriteNumeric(RPL_INVITELIST, "%s :%s",user->nick.c_str(),i->first.c_str()); + user->WriteNumeric(RPL_INVITELIST, "%s :%s",user->nick.c_str(), (*i)->chan->name.c_str()); } user->WriteNumeric(RPL_ENDOFINVITELIST, "%s :End of INVITE list",user->nick.c_str()); } diff --git a/src/commands/cmd_ison.cpp b/src/commands/cmd_ison.cpp index 978c1ad5b..1a50239ee 100644 --- a/src/commands/cmd_ison.cpp +++ b/src/commands/cmd_ison.cpp @@ -20,14 +20,6 @@ #include "inspircd.h" -#ifndef CMD_ISON_H -#define CMD_ISON_H - -// include the common header files - -#include "users.h" -#include "channels.h" - /** Handle /ISON. These command handlers can be reloaded by the core, * and handle basic RFC1459 commands. Commands within modules work * the same way, however, they can be fully unloaded, where these @@ -38,7 +30,9 @@ class CommandIson : public Command public: /** Constructor for ison. */ - CommandIson ( Module* parent) : Command(parent,"ISON",0,0) { syntax = "<nick> {nick}"; } + CommandIson ( Module* parent) : Command(parent,"ISON", 1) { + syntax = "<nick> {nick}"; + } /** Handle command. * @param parameters The parameters to the comamnd * @param pcnt The number of parameters passed to teh command @@ -48,9 +42,6 @@ class CommandIson : public Command CmdResult Handle(const std::vector<std::string>& parameters, User *user); }; -#endif - - /** Handle /ISON */ CmdResult CommandIson::Handle (const std::vector<std::string>& parameters, User *user) diff --git a/src/commands/cmd_join.cpp b/src/commands/cmd_join.cpp index 1dc1d7f92..6124fcc1c 100644 --- a/src/commands/cmd_join.cpp +++ b/src/commands/cmd_join.cpp @@ -20,14 +20,6 @@ #include "inspircd.h" -#ifndef CMD_JOIN_H -#define CMD_JOIN_H - -// include the common header files - -#include "users.h" -#include "channels.h" - /** Handle /JOIN. These command handlers can be reloaded by the core, * and handle basic RFC1459 commands. Commands within modules work * the same way, however, they can be fully unloaded, where these @@ -48,9 +40,6 @@ class CommandJoin : public Command CmdResult Handle(const std::vector<std::string>& parameters, User *user); }; -#endif - - /** Handle /JOIN */ CmdResult CommandJoin::Handle (const std::vector<std::string>& parameters, User *user) diff --git a/src/commands/cmd_kick.cpp b/src/commands/cmd_kick.cpp index f4001d7db..3c5fb0052 100644 --- a/src/commands/cmd_kick.cpp +++ b/src/commands/cmd_kick.cpp @@ -40,7 +40,6 @@ class CommandKick : public Command CmdResult Handle(const std::vector<std::string>& parameters, User *user); }; - /** Handle /KICK */ CmdResult CommandKick::Handle (const std::vector<std::string>& parameters, User *user) diff --git a/src/commands/cmd_links.cpp b/src/commands/cmd_links.cpp index 80b8d7f56..f4152ebc5 100644 --- a/src/commands/cmd_links.cpp +++ b/src/commands/cmd_links.cpp @@ -20,14 +20,6 @@ #include "inspircd.h" -#ifndef CMD_LINKS_H -#define CMD_LINKS_H - -// include the common header files - -#include "users.h" -#include "channels.h" - /** Handle /LINKS. These command handlers can be reloaded by the core, * and handle basic RFC1459 commands. Commands within modules work * the same way, however, they can be fully unloaded, where these @@ -48,9 +40,6 @@ class CommandLinks : public Command CmdResult Handle(const std::vector<std::string>& parameters, User *user); }; -#endif - - /** Handle /LINKS */ CmdResult CommandLinks::Handle (const std::vector<std::string>&, User *user) diff --git a/src/commands/cmd_loadmodule.cpp b/src/commands/cmd_loadmodule.cpp index 74bd74dd3..9d60613a2 100644 --- a/src/commands/cmd_loadmodule.cpp +++ b/src/commands/cmd_loadmodule.cpp @@ -40,7 +40,6 @@ class CommandLoadmodule : public Command CmdResult Handle(const std::vector<std::string>& parameters, User *user); }; - /** Handle /LOADMODULE */ CmdResult CommandLoadmodule::Handle (const std::vector<std::string>& parameters, User *user) diff --git a/src/commands/cmd_lusers.cpp b/src/commands/cmd_lusers.cpp index a3892dbce..e9e36b3d1 100644 --- a/src/commands/cmd_lusers.cpp +++ b/src/commands/cmd_lusers.cpp @@ -20,14 +20,6 @@ #include "inspircd.h" -#ifndef CMD_LUSERS_H -#define CMD_LUSERS_H - -// include the common header files - -#include "users.h" -#include "channels.h" - /** Handle /LUSERS. These command handlers can be reloaded by the core, * and handle basic RFC1459 commands. Commands within modules work * the same way, however, they can be fully unloaded, where these @@ -51,9 +43,6 @@ class CommandLusers : public Command CmdResult Handle(const std::vector<std::string>& parameters, User *user); }; -#endif - - /** Handle /LUSERS */ CmdResult CommandLusers::Handle (const std::vector<std::string>&, User *user) diff --git a/src/commands/cmd_motd.cpp b/src/commands/cmd_motd.cpp index 9a236137d..8e227723e 100644 --- a/src/commands/cmd_motd.cpp +++ b/src/commands/cmd_motd.cpp @@ -30,7 +30,7 @@ class CommandMotd : public Command public: /** Constructor for motd. */ - CommandMotd ( Module* parent) : Command(parent,"MOTD",0,1) { ServerInstance->ProcessedMotdEscapes = false; syntax = "[<servername>]"; } + CommandMotd ( Module* parent) : Command(parent,"MOTD",0,1) { syntax = "[<servername>]"; } /** Handle command. * @param parameters The parameters to the comamnd * @param pcnt The number of parameters passed to teh command @@ -46,61 +46,6 @@ class CommandMotd : public Command } }; -/* - * Replace all color codes from the special[] array to actual - * color code chars using C++ style escape sequences. You - * can append other chars to replace if you like (such as %U - * being underline). -- Justasic - */ -void ProcessColors(ConfigFileCache::iterator &file) -{ - static struct special_chars - { - std::string character; - std::string replace; - special_chars(const std::string &c, const std::string &r) : character(c), replace(r) { } - } - - special[] = { - special_chars("\\002", "\002"), // Bold - special_chars("\\037", "\037"), // underline - special_chars("\\003", "\003"), // Color - special_chars("\\0017", "\017"), // Stop colors - special_chars("\\u", "\037"), // Alias for underline - special_chars("\\b", "\002"), // Alias for Bold - special_chars("\\x", "\017"), // Alias for stop - special_chars("\\c", "\003"), // Alias for color - special_chars("", "") - }; - - for(file_cache::iterator it = file->second.begin(); it != file->second.end(); it++) - { - std::string ret = *it; - for(int i = 0; special[i].character.empty() == false; ++i) - { - std::string::size_type pos = ret.find(special[i].character); - if(pos != std::string::npos && ret[pos-1] == '\\' && ret[pos] == '\\') - continue; // Skip double slashes. - - // Replace all our characters in the array - while(pos != std::string::npos) - { - ret = ret.substr(0, pos) + special[i].replace + ret.substr(pos + special[i].character.size()); - pos = ret.find(special[i].character, pos + special[i].replace.size()); - } - } - - // Replace double slashes with a single slash before we return - std::string::size_type pos = ret.find("\\\\"); - while(pos != std::string::npos) - { - ret = ret.substr(0, pos) + "\\" + ret.substr(pos + 2); - pos = ret.find("\\\\", pos + 1); - } - *it = ret; - } -} - /** Handle /MOTD */ CmdResult CommandMotd::Handle (const std::vector<std::string>& parameters, User *user) @@ -120,12 +65,6 @@ CmdResult CommandMotd::Handle (const std::vector<std::string>& parameters, User return CMD_SUCCESS; } - if(!ServerInstance->ProcessedMotdEscapes) - { - ProcessColors(motd); - ServerInstance->ProcessedMotdEscapes = true; - } - user->SendText(":%s %03d %s :%s message of the day", ServerInstance->Config->ServerName.c_str(), RPL_MOTDSTART, user->nick.c_str(), ServerInstance->Config->ServerName.c_str()); diff --git a/src/commands/cmd_names.cpp b/src/commands/cmd_names.cpp index f34afb361..0c06b636f 100644 --- a/src/commands/cmd_names.cpp +++ b/src/commands/cmd_names.cpp @@ -20,14 +20,6 @@ #include "inspircd.h" -#ifndef CMD_NAMES_H -#define CMD_NAMES_H - -// include the common header files - -#include "users.h" -#include "channels.h" - /** Handle /NAMES. These command handlers can be reloaded by the core, * and handle basic RFC1459 commands. Commands within modules work * the same way, however, they can be fully unloaded, where these @@ -48,9 +40,6 @@ class CommandNames : public Command CmdResult Handle(const std::vector<std::string>& parameters, User *user); }; -#endif - - /** Handle /NAMES */ CmdResult CommandNames::Handle (const std::vector<std::string>& parameters, User *user) diff --git a/src/commands/cmd_nick.cpp b/src/commands/cmd_nick.cpp index 5e600ad1c..a079e59d0 100644 --- a/src/commands/cmd_nick.cpp +++ b/src/commands/cmd_nick.cpp @@ -21,7 +21,6 @@ #include "inspircd.h" -#include "xline.h" /** Handle /NICK. These command handlers can be reloaded by the core, * and handle basic RFC1459 commands. Commands within modules work diff --git a/src/commands/cmd_oper.cpp b/src/commands/cmd_oper.cpp index 2fd7744ee..e3f79d347 100644 --- a/src/commands/cmd_oper.cpp +++ b/src/commands/cmd_oper.cpp @@ -20,7 +20,6 @@ #include "inspircd.h" -#include "hashcomp.h" bool OneOfMatches(const char* host, const char* ip, const char* hostlist); diff --git a/src/commands/cmd_rehash.cpp b/src/commands/cmd_rehash.cpp index ff326faf2..1fa6e5731 100644 --- a/src/commands/cmd_rehash.cpp +++ b/src/commands/cmd_rehash.cpp @@ -20,7 +20,7 @@ #include "inspircd.h" -#include "xline.h" + /** Handle /REHASH. These command handlers can be reloaded by the core, * and handle basic RFC1459 commands. Commands within modules work * the same way, however, they can be fully unloaded, where these @@ -88,8 +88,6 @@ CmdResult CommandRehash::Handle (const std::vector<std::string>& parameters, Use /* Don't do anything with the logs here -- logs are restarted * after the config thread has completed. */ - - ServerInstance->ProcessedMotdEscapes = false; // Reprocess our motd file --Justasic ServerInstance->RehashUsersAndChans(); FOREACH_MOD(I_OnGarbageCollect, OnGarbageCollect()); diff --git a/src/commands/cmd_stats.cpp b/src/commands/cmd_stats.cpp index 2ed5eedcd..6b21d0db6 100644 --- a/src/commands/cmd_stats.cpp +++ b/src/commands/cmd_stats.cpp @@ -20,19 +20,8 @@ #include "inspircd.h" -#ifndef WIN32 - #include <sys/resource.h> - /* This is just to be completely certain that the change which fixed getrusage on RH7 doesn't break anything else -- Om */ - #ifndef RUSAGE_SELF - #define RUSAGE_SELF 0 - #endif -#else - #include <psapi.h> - #include "inspircd_win32wrapper.h" - #pragma comment(lib, "psapi.lib") -#endif - #include "xline.h" +#include "commands/cmd_whowas.h" /** Handle /STATS. These command handlers can be reloaded by the core, * and handle basic RFC1459 commands. Commands within modules work @@ -41,6 +30,7 @@ */ class CommandStats : public Command { + void DoStats(char statschar, User* user, string_list &results); public: /** Constructor for stats. */ @@ -60,13 +50,349 @@ class CommandStats : public Command } }; +void CommandStats::DoStats(char statschar, User* user, string_list &results) +{ + std::string sn(ServerInstance->Config->ServerName); + + bool isPublic = ServerInstance->Config->UserStats.find(statschar) != std::string::npos; + bool isRemoteOper = IS_REMOTE(user) && IS_OPER(user); + bool isLocalOperWithPrivs = IS_LOCAL(user) && user->HasPrivPermission("servers/auspex"); + + if (!isPublic && !isRemoteOper && !isLocalOperWithPrivs) + { + ServerInstance->SNO->WriteToSnoMask('t', + "%s '%c' denied for %s (%s@%s)", + (IS_LOCAL(user) ? "Stats" : "Remote stats"), + statschar, user->nick.c_str(), user->ident.c_str(), user->host.c_str()); + results.push_back(sn + " 481 " + user->nick + " :Permission denied - STATS " + statschar + " requires the servers/auspex priv."); + return; + } + + ModResult MOD_RESULT; + FIRST_MOD_RESULT(OnStats, MOD_RESULT, (statschar, user, results)); + if (MOD_RESULT == MOD_RES_DENY) + { + results.push_back(sn+" 219 "+user->nick+" "+statschar+" :End of /STATS report"); + ServerInstance->SNO->WriteToSnoMask('t',"%s '%c' requested by %s (%s@%s)", + (IS_LOCAL(user) ? "Stats" : "Remote stats"), statschar, user->nick.c_str(), user->ident.c_str(), user->host.c_str()); + return; + } + + switch (statschar) + { + /* stats p (show listening ports) */ + case 'p': + { + for (std::vector<ListenSocket*>::const_iterator i = ServerInstance->ports.begin(); i != ServerInstance->ports.end(); ++i) + { + ListenSocket* ls = *i; + std::string ip = ls->bind_addr; + if (ip.empty()) + ip.assign("*"); + std::string type = ls->bind_tag->getString("type", "clients"); + std::string hook = ls->bind_tag->getString("ssl", "plaintext"); + + results.push_back(sn+" 249 "+user->nick+" :"+ ip + ":"+ConvToStr(ls->bind_port)+ + " (" + type + ", " + hook + ")"); + } + } + break; + + /* These stats symbols must be handled by a linking module */ + case 'n': + case 'c': + break; + + case 'i': + { + for (ClassVector::iterator i = ServerInstance->Config->Classes.begin(); i != ServerInstance->Config->Classes.end(); i++) + { + ConnectClass* c = *i; + std::stringstream res; + res << sn << " 215 " << user->nick << " I " << c->name << ' '; + if (c->type == CC_ALLOW) + res << '+'; + if (c->type == CC_DENY) + res << '-'; + + if (c->type == CC_NAMED) + res << '*'; + else + res << c->host; + + res << ' ' << c->config->getString("port", "*") << ' '; + + res << c->GetRecvqMax() << ' ' << c->GetSendqSoftMax() << ' ' << c->GetSendqHardMax() + << ' ' << c->GetCommandRate() << ' ' << c->GetPenaltyThreshold(); + if (c->fakelag) + res << '*'; + results.push_back(res.str()); + } + } + break; + + case 'Y': + { + int idx = 0; + for (ClassVector::iterator i = ServerInstance->Config->Classes.begin(); i != ServerInstance->Config->Classes.end(); i++) + { + ConnectClass* c = *i; + results.push_back(sn+" 215 "+user->nick+" i NOMATCH * "+c->GetHost()+" "+ConvToStr(c->limit ? c->limit : ServerInstance->SE->GetMaxFds())+" "+ConvToStr(idx)+" "+ServerInstance->Config->ServerName+" *"); + results.push_back(sn+" 218 "+user->nick+" Y "+ConvToStr(idx)+" "+ConvToStr(c->GetPingTime())+" 0 "+ConvToStr(c->GetSendqHardMax())+" :"+ + ConvToStr(c->GetRecvqMax())+" "+ConvToStr(c->GetRegTimeout())); + idx++; + } + } + break; + + case 'U': + { + for(std::map<irc::string, bool>::iterator i = ServerInstance->Config->ulines.begin(); i != ServerInstance->Config->ulines.end(); ++i) + { + results.push_back(sn+" 248 "+user->nick+" U "+std::string(i->first.c_str())); + } + } + break; + + case 'P': + { + int idx = 0; + for (user_hash::iterator i = ServerInstance->Users->clientlist->begin(); i != ServerInstance->Users->clientlist->end(); i++) + { + if (IS_OPER(i->second) && !ServerInstance->ULine(i->second->server)) + { + results.push_back(sn+" 249 "+user->nick+" :"+i->second->nick+" ("+i->second->ident+"@"+i->second->dhost+") Idle: "+ + (IS_LOCAL(i->second) ? ConvToStr(ServerInstance->Time() - i->second->idle_lastmsg) + " secs" : "unavailable")); + idx++; + } + } + results.push_back(sn+" 249 "+user->nick+" :"+ConvToStr(idx)+" OPER(s)"); + } + break; + + case 'k': + ServerInstance->XLines->InvokeStats("K",216,user,results); + break; + case 'g': + ServerInstance->XLines->InvokeStats("G",223,user,results); + break; + case 'q': + ServerInstance->XLines->InvokeStats("Q",217,user,results); + break; + case 'Z': + ServerInstance->XLines->InvokeStats("Z",223,user,results); + break; + case 'e': + ServerInstance->XLines->InvokeStats("E",223,user,results); + break; + case 'E': + results.push_back(sn+" 249 "+user->nick+" :Total events: "+ConvToStr(ServerInstance->SE->TotalEvents)); + results.push_back(sn+" 249 "+user->nick+" :Read events: "+ConvToStr(ServerInstance->SE->ReadEvents)); + results.push_back(sn+" 249 "+user->nick+" :Write events: "+ConvToStr(ServerInstance->SE->WriteEvents)); + results.push_back(sn+" 249 "+user->nick+" :Error events: "+ConvToStr(ServerInstance->SE->ErrorEvents)); + break; + + /* stats m (list number of times each command has been used, plus bytecount) */ + case 'm': + for (Commandtable::iterator i = ServerInstance->Parser->cmdlist.begin(); i != ServerInstance->Parser->cmdlist.end(); i++) + { + if (i->second->use_count) + { + /* RPL_STATSCOMMANDS */ + results.push_back(sn+" 212 "+user->nick+" "+i->second->name+" "+ConvToStr(i->second->use_count)+" "+ConvToStr(i->second->total_bytes)); + } + } + break; + + /* stats z (debug and memory info) */ + case 'z': + { + results.push_back(sn+" 249 "+user->nick+" :Users: "+ConvToStr(ServerInstance->Users->clientlist->size())); + results.push_back(sn+" 249 "+user->nick+" :Channels: "+ConvToStr(ServerInstance->chanlist->size())); + results.push_back(sn+" 249 "+user->nick+" :Commands: "+ConvToStr(ServerInstance->Parser->cmdlist.size())); + + if (!ServerInstance->Config->WhoWasGroupSize == 0 && !ServerInstance->Config->WhoWasMaxGroups == 0) + { + Module* whowas = ServerInstance->Modules->Find("cmd_whowas.so"); + if (whowas) + { + WhowasRequest req(NULL, whowas, WhowasRequest::WHOWAS_STATS); + req.user = user; + req.Send(); + results.push_back(sn+" 249 "+user->nick+" :"+req.value); + } + } + + float kbitpersec_in, kbitpersec_out, kbitpersec_total; + char kbitpersec_in_s[30], kbitpersec_out_s[30], kbitpersec_total_s[30]; + + ServerInstance->SE->GetStats(kbitpersec_in, kbitpersec_out, kbitpersec_total); + + snprintf(kbitpersec_total_s, 30, "%03.5f", kbitpersec_total); + snprintf(kbitpersec_out_s, 30, "%03.5f", kbitpersec_out); + snprintf(kbitpersec_in_s, 30, "%03.5f", kbitpersec_in); + + results.push_back(sn+" 249 "+user->nick+" :Bandwidth total: "+ConvToStr(kbitpersec_total_s)+" kilobits/sec"); + results.push_back(sn+" 249 "+user->nick+" :Bandwidth out: "+ConvToStr(kbitpersec_out_s)+" kilobits/sec"); + results.push_back(sn+" 249 "+user->nick+" :Bandwidth in: "+ConvToStr(kbitpersec_in_s)+" kilobits/sec"); + +#ifndef WIN32 + /* Moved this down here so all the not-windows stuff (look w00tie, I didn't say win32!) is in one ifndef. + * Also cuts out some identical code in both branches of the ifndef. -- Om + */ + rusage R; + + /* Not sure why we were doing '0' with a RUSAGE_SELF comment rather than just using RUSAGE_SELF -- Om */ + if (!getrusage(RUSAGE_SELF,&R)) /* RUSAGE_SELF */ + { + results.push_back(sn+" 249 "+user->nick+" :Total allocation: "+ConvToStr(R.ru_maxrss)+"K"); + results.push_back(sn+" 249 "+user->nick+" :Signals: "+ConvToStr(R.ru_nsignals)); + results.push_back(sn+" 249 "+user->nick+" :Page faults: "+ConvToStr(R.ru_majflt)); + results.push_back(sn+" 249 "+user->nick+" :Swaps: "+ConvToStr(R.ru_nswap)); + results.push_back(sn+" 249 "+user->nick+" :Context Switches: Voluntary; "+ConvToStr(R.ru_nvcsw)+" Involuntary; "+ConvToStr(R.ru_nivcsw)); + + char percent[30]; + + float n_elapsed = (ServerInstance->Time() - ServerInstance->stats->LastSampled.tv_sec) * 1000000 + + (ServerInstance->Time_ns() - ServerInstance->stats->LastSampled.tv_nsec) / 1000; + float n_eaten = ((R.ru_utime.tv_sec - ServerInstance->stats->LastCPU.tv_sec) * 1000000 + R.ru_utime.tv_usec - ServerInstance->stats->LastCPU.tv_usec); + float per = (n_eaten / n_elapsed) * 100; + + snprintf(percent, 30, "%03.5f%%", per); + results.push_back(sn+" 249 "+user->nick+" :CPU Use (now): "+percent); + + n_elapsed = ServerInstance->Time() - ServerInstance->startup_time; + n_eaten = (float)R.ru_utime.tv_sec + R.ru_utime.tv_usec / 100000.0; + per = (n_eaten / n_elapsed) * 100; + snprintf(percent, 30, "%03.5f%%", per); + results.push_back(sn+" 249 "+user->nick+" :CPU Use (total): "+percent); + } +#else + PROCESS_MEMORY_COUNTERS MemCounters; + if (GetProcessMemoryInfo(GetCurrentProcess(), &MemCounters, sizeof(MemCounters))) + { + results.push_back(sn+" 249 "+user->nick+" :Total allocation: "+ConvToStr((MemCounters.WorkingSetSize + MemCounters.PagefileUsage) / 1024)+"K"); + results.push_back(sn+" 249 "+user->nick+" :Pagefile usage: "+ConvToStr(MemCounters.PagefileUsage / 1024)+"K"); + results.push_back(sn+" 249 "+user->nick+" :Page faults: "+ConvToStr(MemCounters.PageFaultCount)); + results.push_back(sn+" 249 "+user->nick+" :CPU Usage: " + ConvToStr(getcpu()) + "%"); + } +#endif + } + break; + + case 'T': + { + char buffer[MAXBUF]; + results.push_back(sn+" 249 "+user->nick+" :accepts "+ConvToStr(ServerInstance->stats->statsAccept)+" refused "+ConvToStr(ServerInstance->stats->statsRefused)); + results.push_back(sn+" 249 "+user->nick+" :unknown commands "+ConvToStr(ServerInstance->stats->statsUnknown)); + results.push_back(sn+" 249 "+user->nick+" :nick collisions "+ConvToStr(ServerInstance->stats->statsCollisions)); + results.push_back(sn+" 249 "+user->nick+" :dns requests "+ConvToStr(ServerInstance->stats->statsDnsGood+ServerInstance->stats->statsDnsBad)+" succeeded "+ConvToStr(ServerInstance->stats->statsDnsGood)+" failed "+ConvToStr(ServerInstance->stats->statsDnsBad)); + results.push_back(sn+" 249 "+user->nick+" :connection count "+ConvToStr(ServerInstance->stats->statsConnects)); + snprintf(buffer,MAXBUF," 249 %s :bytes sent %5.2fK recv %5.2fK", + user->nick.c_str(),ServerInstance->stats->statsSent / 1024.0,ServerInstance->stats->statsRecv / 1024.0); + results.push_back(sn+buffer); + } + break; + + /* stats o */ + case 'o': + { + ConfigTagList tags = ServerInstance->Config->ConfTags("oper"); + for(ConfigIter i = tags.first; i != tags.second; ++i) + { + ConfigTag* tag = i->second; + results.push_back(sn+" 243 "+user->nick+" O "+tag->getString("host")+" * "+ + tag->getString("name") + " " + tag->getString("type")+" 0"); + } + } + break; + case 'O': + { + for(OperIndex::iterator i = ServerInstance->Config->oper_blocks.begin(); i != ServerInstance->Config->oper_blocks.end(); i++) + { + // just the types, not the actual oper blocks... + if (i->first[0] != ' ') + continue; + OperInfo* tag = i->second; + tag->init(); + std::string umodes; + std::string cmodes; + for(char c='A'; c < 'z'; c++) + { + ModeHandler* mh = ServerInstance->Modes->FindMode(c, MODETYPE_USER); + if (mh && mh->NeedsOper() && tag->AllowedUserModes[c - 'A']) + umodes.push_back(c); + mh = ServerInstance->Modes->FindMode(c, MODETYPE_CHANNEL); + if (mh && mh->NeedsOper() && tag->AllowedChanModes[c - 'A']) + cmodes.push_back(c); + } + results.push_back(sn+" 243 "+user->nick+" O "+tag->NameStr() + " " + umodes + " " + cmodes); + } + } + break; + + /* stats l (show user I/O stats) */ + case 'l': + results.push_back(sn+" 211 "+user->nick+" :nick[ident@host] sendq cmds_out bytes_out cmds_in bytes_in time_open"); + for (std::vector<LocalUser*>::iterator n = ServerInstance->Users->local_users.begin(); n != ServerInstance->Users->local_users.end(); n++) + { + LocalUser* i = *n; + results.push_back(sn+" 211 "+user->nick+" "+i->nick+"["+i->ident+"@"+i->dhost+"] "+ConvToStr(i->eh.getSendQSize())+" "+ConvToStr(i->cmds_out)+" "+ConvToStr(i->bytes_out)+" "+ConvToStr(i->cmds_in)+" "+ConvToStr(i->bytes_in)+" "+ConvToStr(ServerInstance->Time() - i->age)); + } + break; + + /* stats L (show user I/O stats with IP addresses) */ + case 'L': + results.push_back(sn+" 211 "+user->nick+" :nick[ident@ip] sendq cmds_out bytes_out cmds_in bytes_in time_open"); + for (std::vector<LocalUser*>::iterator n = ServerInstance->Users->local_users.begin(); n != ServerInstance->Users->local_users.end(); n++) + { + LocalUser* i = *n; + results.push_back(sn+" 211 "+user->nick+" "+i->nick+"["+i->ident+"@"+i->GetIPString()+"] "+ConvToStr(i->eh.getSendQSize())+" "+ConvToStr(i->cmds_out)+" "+ConvToStr(i->bytes_out)+" "+ConvToStr(i->cmds_in)+" "+ConvToStr(i->bytes_in)+" "+ConvToStr(ServerInstance->Time() - i->age)); + } + break; + + /* stats u (show server uptime) */ + case 'u': + { + time_t current_time = 0; + current_time = ServerInstance->Time(); + time_t server_uptime = current_time - ServerInstance->startup_time; + struct tm* stime; + stime = gmtime(&server_uptime); + /* i dont know who the hell would have an ircd running for over a year nonstop, but + * Craig suggested this, and it seemed a good idea so in it went */ + if (stime->tm_year > 70) + { + char buffer[MAXBUF]; + snprintf(buffer,MAXBUF," 242 %s :Server up %d years, %d days, %.2d:%.2d:%.2d",user->nick.c_str(),(stime->tm_year-70),stime->tm_yday,stime->tm_hour,stime->tm_min,stime->tm_sec); + results.push_back(sn+buffer); + } + else + { + char buffer[MAXBUF]; + snprintf(buffer,MAXBUF," 242 %s :Server up %d days, %.2d:%.2d:%.2d",user->nick.c_str(),stime->tm_yday,stime->tm_hour,stime->tm_min,stime->tm_sec); + results.push_back(sn+buffer); + } + } + break; + + default: + break; + } + + results.push_back(sn+" 219 "+user->nick+" "+statschar+" :End of /STATS report"); + ServerInstance->SNO->WriteToSnoMask('t',"%s '%c' requested by %s (%s@%s)", + (IS_LOCAL(user) ? "Stats" : "Remote stats"), statschar, user->nick.c_str(), user->ident.c_str(), user->host.c_str()); + return; +} + CmdResult CommandStats::Handle (const std::vector<std::string>& parameters, User *user) { if (parameters.size() > 1 && parameters[1] != ServerInstance->Config->ServerName) return CMD_SUCCESS; string_list values; char search = parameters[0][0]; - ServerInstance->DoStats(search, user, values); + DoStats(search, user, values); for (size_t i = 0; i < values.size(); i++) user->SendText(":%s", values[i].c_str()); diff --git a/src/commands/cmd_userhost.cpp b/src/commands/cmd_userhost.cpp index c19ad5b6f..af7d3ceca 100644 --- a/src/commands/cmd_userhost.cpp +++ b/src/commands/cmd_userhost.cpp @@ -20,14 +20,6 @@ #include "inspircd.h" -#ifndef CMD_USERHOST_H -#define CMD_USERHOST_H - -// include the common header files - -#include "users.h" -#include "channels.h" - /** Handle /USERHOST. These command handlers can be reloaded by the core, * and handle basic RFC1459 commands. Commands within modules work * the same way, however, they can be fully unloaded, where these @@ -38,7 +30,9 @@ class CommandUserhost : public Command public: /** Constructor for userhost. */ - CommandUserhost ( Module* parent) : Command(parent,"USERHOST",0,1) { syntax = "<nick>{,<nick>}"; } + CommandUserhost ( Module* parent) : Command(parent,"USERHOST", 1, 5) { + syntax = "<nick> {<nick>}"; + } /** Handle command. * @param parameters The parameters to the comamnd * @param pcnt The number of parameters passed to teh command @@ -48,9 +42,6 @@ class CommandUserhost : public Command CmdResult Handle(const std::vector<std::string>& parameters, User *user); }; -#endif - - CmdResult CommandUserhost::Handle (const std::vector<std::string>& parameters, User *user) { std::string retbuf = std::string("302 ") + user->nick + " :"; @@ -64,13 +55,9 @@ CmdResult CommandUserhost::Handle (const std::vector<std::string>& parameters, U retbuf = retbuf + u->nick; if (IS_OPER(u)) - { - retbuf = retbuf + "*="; - } - else - { - retbuf = retbuf + "="; - } + retbuf = retbuf + "*"; + + retbuf = retbuf + "="; if (IS_AWAY(u)) retbuf += "-"; diff --git a/src/commands/cmd_version.cpp b/src/commands/cmd_version.cpp index 9b19c0ee0..6fae329bd 100644 --- a/src/commands/cmd_version.cpp +++ b/src/commands/cmd_version.cpp @@ -20,14 +20,6 @@ #include "inspircd.h" -#ifndef CMD_VERSION_H -#define CMD_VERSION_H - -// include the common header files - -#include "users.h" -#include "channels.h" - /** Handle /VERSION. These command handlers can be reloaded by the core, * and handle basic RFC1459 commands. Commands within modules work * the same way, however, they can be fully unloaded, where these @@ -48,11 +40,6 @@ class CommandVersion : public Command CmdResult Handle(const std::vector<std::string>& parameters, User *user); }; -#endif - - - - CmdResult CommandVersion::Handle (const std::vector<std::string>&, User *user) { user->WriteNumeric(RPL_VERSION, "%s :%s",user->nick.c_str(),ServerInstance->GetVersionString(IS_OPER(user)).c_str()); diff --git a/src/configparser.cpp b/src/configparser.cpp index a8e36f6e0..b6e3f7187 100644 --- a/src/configparser.cpp +++ b/src/configparser.cpp @@ -307,7 +307,7 @@ void ParseStack::DoReadFile(const std::string& key, const std::string& name, int if (exec && (flags & FLAG_NO_EXEC)) throw CoreException("Invalid <execfiles> tag in file included with noexec=\"yes\""); - FileWrapper file(exec ? popen(name.c_str(), "r") : fopen(name.c_str(), "r")); + FileWrapper file(exec ? popen(name.c_str(), "r") : fopen(name.c_str(), "r"), exec); if (!file) throw CoreException("Could not read \"" + name + "\" for \"" + key + "\" file"); @@ -364,7 +364,7 @@ bool ParseStack::ParseExec(const std::string& name, int flags) /* It's not already included, add it to the list of files we've loaded */ - FileWrapper file(popen(name.c_str(), "r")); + FileWrapper file(popen(name.c_str(), "r"), true); if (!file) throw CoreException("Could not open executable \"" + name + "\" for include"); diff --git a/src/configreader.cpp b/src/configreader.cpp index b0bb6a92f..166e124ca 100644 --- a/src/configreader.cpp +++ b/src/configreader.cpp @@ -436,8 +436,11 @@ static const Deprecated ChangedConfig[] = { {"options", "somaxconn", "has been moved to <performance:somaxconn> as of 1.2a3"}, {"options", "netbuffersize", "has been moved to <performance:netbuffersize> as of 1.2a3"}, {"options", "maxwho", "has been moved to <performance:maxwho> as of 1.2a3"}, - {"options", "loglevel", "1.2 does not use the loglevel value. Please define <log> tags instead."}, + {"options", "loglevel", "1.2+ does not use the loglevel value. Please define <log> tags instead."}, {"die", "value", "you need to reread your config"}, + {"bind", "transport", "has been moved to <bind:ssl> as of 2.0a1"}, + {"link", "transport", "has been moved to <link:ssl> as of 2.0a1"}, + }; void ServerConfig::Fill() @@ -720,6 +723,24 @@ void ServerConfig::Apply(ServerConfig* old, const std::string &useruid) errstr.clear(); errstr.str(std::string()); + // Re-parse our MOTD and RULES files for colors -- Justasic + for (ClassVector::const_iterator it = this->Classes.begin(), it_end = this->Classes.end(); it != it_end; ++it) + { + ConfigTag *tag = (*it)->config; + // Make sure our connection class allows motd colors + if(!tag->getBool("allowmotdcolors")) + continue; + + ConfigFileCache::iterator motdfile = this->Files.find(tag->getString("motd", "motd")); + ConfigFileCache::iterator rulesfile = this->Files.find(tag->getString("rules", "rules")); + + if(motdfile != this->Files.end()) + this->ProcessColors(motdfile); + + if(rulesfile != this->Files.end()) + this->ProcessColors(rulesfile); + } + /* No old configuration -> initial boot, nothing more to do here */ if (!old) { @@ -731,6 +752,7 @@ void ServerConfig::Apply(ServerConfig* old, const std::string &useruid) return; } + // If there were errors processing configuration, don't touch modules. if (!valid) return; @@ -837,6 +859,63 @@ ConfigTagList ServerConfig::ConfTags(const std::string& tag) return config_data.equal_range(tag); } +/* + * Replace all color codes from the special[] array to actual + * color code chars using C++ style escape sequences. You + * can append other chars to replace if you like -- Justasic + */ +void ServerConfig::ProcessColors(ConfigFileCache::iterator &file) +{ + static struct special_chars + { + std::string character; + std::string replace; + special_chars(const std::string &c, const std::string &r) : character(c), replace(r) { } + } + + special[] = { + special_chars("\\002", "\002"), // Bold + special_chars("\\037", "\037"), // underline + special_chars("\\003", "\003"), // Color + special_chars("\\017", "\017"), // Stop colors + special_chars("\\u", "\037"), // Alias for underline + special_chars("\\b", "\002"), // Alias for Bold + special_chars("\\x", "\017"), // Alias for stop + special_chars("\\c", "\003"), // Alias for color + special_chars("", "") + }; + + for(file_cache::iterator it = file->second.begin(), it_end = file->second.end(); it != it_end; it++) + { + std::string ret = *it; + for(int i = 0; special[i].character.empty() == false; ++i) + { + std::string::size_type pos = ret.find(special[i].character); + if(pos == std::string::npos) // Couldn't find the character, skip this line + continue; + + if((pos > 0) && (ret[pos-1] == '\\') && (ret[pos] == '\\')) + continue; // Skip double slashes. + + // Replace all our characters in the array + while(pos != std::string::npos) + { + ret = ret.substr(0, pos) + special[i].replace + ret.substr(pos + special[i].character.size()); + pos = ret.find(special[i].character, pos + special[i].replace.size()); + } + } + + // Replace double slashes with a single slash before we return + std::string::size_type pos = ret.find("\\\\"); + while(pos != std::string::npos) + { + ret = ret.substr(0, pos) + "\\" + ret.substr(pos + 2); + pos = ret.find("\\\\", pos + 1); + } + *it = ret; + } +} + bool ServerConfig::FileExists(const char* file) { struct stat sb; diff --git a/src/hashcomp.cpp b/src/hashcomp.cpp index 8c34c8a56..2cb6fb972 100644 --- a/src/hashcomp.cpp +++ b/src/hashcomp.cpp @@ -451,7 +451,7 @@ int irc::modestacker::GetStackedLine(std::vector<std::string> &result, int max_l irc::stringjoiner::stringjoiner(const std::string &seperator, const std::vector<std::string> &sequence, int begin, int end) { if (end < begin) - throw "stringjoiner logic error, this causes problems."; + return; // nothing to do here for (int v = begin; v < end; v++) joined.append(sequence[v]).append(seperator); @@ -461,7 +461,7 @@ irc::stringjoiner::stringjoiner(const std::string &seperator, const std::vector< irc::stringjoiner::stringjoiner(const std::string &seperator, const std::deque<std::string> &sequence, int begin, int end) { if (end < begin) - throw "stringjoiner logic error, this causes problems."; + return; // nothing to do here for (int v = begin; v < end; v++) joined.append(sequence[v]).append(seperator); @@ -471,7 +471,7 @@ irc::stringjoiner::stringjoiner(const std::string &seperator, const std::deque<s irc::stringjoiner::stringjoiner(const std::string &seperator, const char* const* sequence, int begin, int end) { if (end < begin) - throw "stringjoiner logic error, this causes problems."; + return; // nothing to do here for (int v = begin; v < end; v++) joined.append(sequence[v]).append(seperator); @@ -483,29 +483,17 @@ std::string& irc::stringjoiner::GetJoined() return joined; } -irc::portparser::portparser(const std::string &source, bool allow_overlapped) : in_range(0), range_begin(0), range_end(0), overlapped(allow_overlapped) +irc::portparser::portparser(const std::string &source, bool allow_overlapped) + : sep(source), in_range(0), range_begin(0), range_end(0), overlapped(allow_overlapped) { - sep = new irc::commasepstream(source); - overlap_set.clear(); -} - -irc::portparser::~portparser() -{ - delete sep; } bool irc::portparser::Overlaps(long val) { - if (!overlapped) + if (overlapped) return false; - if (overlap_set.find(val) == overlap_set.end()) - { - overlap_set[val] = true; - return false; - } - else - return true; + return (!overlap_set.insert(val).second); } long irc::portparser::GetToken() @@ -533,14 +521,14 @@ long irc::portparser::GetToken() } std::string x; - sep->GetToken(x); + sep.GetToken(x); if (x.empty()) return 0; while (Overlaps(atoi(x.c_str()))) { - if (!sep->GetToken(x)) + if (!sep.GetToken(x)) return 0; } diff --git a/src/inspircd.cpp b/src/inspircd.cpp index 005a11dd7..aa03d62de 100644 --- a/src/inspircd.cpp +++ b/src/inspircd.cpp @@ -195,24 +195,21 @@ void InspIRCd::ResetMaxBans() void InspIRCd::RehashUsersAndChans() { user_hash* old_users = Users->clientlist; - user_hash* old_uuid = Users->uuidlist; - chan_hash* old_chans = chanlist; - - Users->clientlist = new user_hash(); - Users->uuidlist = new user_hash(); - chanlist = new chan_hash(); - + Users->clientlist = new user_hash; for (user_hash::const_iterator n = old_users->begin(); n != old_users->end(); n++) Users->clientlist->insert(*n); + delete old_users; + user_hash* old_uuid = Users->uuidlist; + Users->uuidlist = new user_hash; for (user_hash::const_iterator n = old_uuid->begin(); n != old_uuid->end(); n++) Users->uuidlist->insert(*n); + delete old_uuid; + chan_hash* old_chans = chanlist; + chanlist = new chan_hash; for (chan_hash::const_iterator n = old_chans->begin(); n != old_chans->end(); n++) chanlist->insert(*n); - - delete old_users; - delete old_uuid; delete old_chans; // Reset the already_sent IDs so we don't wrap it around and drop a message @@ -220,6 +217,7 @@ void InspIRCd::RehashUsersAndChans() for (std::vector<LocalUser*>::const_iterator i = Users->local_users.begin(); i != Users->local_users.end(); i++) { (**i).already_sent = 0; + (**i).RemoveExpiredInvites(); } } diff --git a/src/mode.cpp b/src/mode.cpp index 5efc98250..083445cef 100644 --- a/src/mode.cpp +++ b/src/mode.cpp @@ -1,6 +1,7 @@ /* * InspIRCd -- Internet Relay Chat Daemon * + * Copyright (C) 2012 Shawn Smith <shawn@inspircd.org> * Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org> * Copyright (C) 2007, 2009 Dennis Friis <peavey@inspircd.org> * Copyright (C) 2006-2008 Robin Burchell <robin+git@viroteck.net> @@ -132,47 +133,39 @@ bool ModeHandler::ResolveModeConflict(std::string& theirs, const std::string& ou ModeAction SimpleUserModeHandler::OnModeChange(User* source, User* dest, Channel* channel, std::string ¶meter, bool adding) { - if (adding) - { - if (!dest->IsModeSet(this->GetModeChar())) - { - dest->SetMode(this->GetModeChar(),true); - return MODEACTION_ALLOW; - } - } - else - { - if (dest->IsModeSet(this->GetModeChar())) - { - dest->SetMode(this->GetModeChar(),false); - return MODEACTION_ALLOW; - } - } + /* We're either trying to add a mode we already have or + remove a mode we don't have, deny. */ + if (dest->IsModeSet(this->GetModeChar()) == adding) + return MODEACTION_DENY; - return MODEACTION_DENY; + /* adding will be either true or false, depending on if we + are adding or removing the mode, since we already checked + to make sure we aren't adding a mode we have or that we + aren't removing a mode we don't have, we don't have to do any + other checks here to see if it's true or false, just add or + remove the mode */ + dest->SetMode(this->GetModeChar(), adding); + + return MODEACTION_ALLOW; } ModeAction SimpleChannelModeHandler::OnModeChange(User* source, User* dest, Channel* channel, std::string ¶meter, bool adding) { - if (adding) - { - if (!channel->IsModeSet(this->GetModeChar())) - { - channel->SetMode(this->GetModeChar(),true); - return MODEACTION_ALLOW; - } - } - else - { - if (channel->IsModeSet(this->GetModeChar())) - { - channel->SetMode(this->GetModeChar(),false); - return MODEACTION_ALLOW; - } - } + /* We're either trying to add a mode we already have or + remove a mode we don't have, deny. */ + if (channel->IsModeSet(this->GetModeChar()) == adding) + return MODEACTION_DENY; - return MODEACTION_DENY; + /* adding will be either true or false, depending on if we + are adding or removing the mode, since we already checked + to make sure we aren't adding a mode we have or that we + aren't removing a mode we don't have, we don't have to do any + other checks here to see if it's true or false, just add or + remove the mode */ + channel->SetMode(this->GetModeChar(), adding); + + return MODEACTION_ALLOW; } ModeAction ParamChannelModeHandler::OnModeChange(User* source, User* dest, Channel* channel, std::string ¶meter, bool adding) diff --git a/src/modes/cmode_b.cpp b/src/modes/cmode_b.cpp index 034a93a85..660b0c275 100644 --- a/src/modes/cmode_b.cpp +++ b/src/modes/cmode_b.cpp @@ -116,7 +116,7 @@ std::string& ModeChannelBan::AddBan(User *user, std::string &dest, Channel *chan return dest; long maxbans = chan->GetMaxBans(); - if (!IS_LOCAL(user) && ((unsigned)chan->bans.size() > (unsigned)maxbans)) + if (IS_LOCAL(user) && ((unsigned)chan->bans.size() > (unsigned)maxbans)) { user->WriteServ("478 %s %s :Channel ban list for %s is full (maximum entries for this channel is %ld)",user->nick.c_str(), chan->name.c_str(), chan->name.c_str(), maxbans); dest = ""; diff --git a/src/modules.cpp b/src/modules.cpp index 8306ff6af..ccd78a8f0 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -176,7 +176,6 @@ ModResult Module::OnNumeric(User*, unsigned int, const std::string&) { return MO void Module::OnHookIO(StreamSocket*, ListenSocket*) { } ModResult Module::OnAcceptConnection(int, ListenSocket*, irc::sockets::sockaddrs*, irc::sockets::sockaddrs*) { return MOD_RES_PASSTHRU; } void Module::OnSendWhoLine(User*, const std::vector<std::string>&, User*, std::string&) { } -void Module::OnSetClientIP(User *) { } ModuleManager::ModuleManager() : ModCount(0) { diff --git a/src/modules/extra/m_ldapoper.cpp b/src/modules/extra/m_ldapoper.cpp index 6bd834dc8..6eade1fbd 100644 --- a/src/modules/extra/m_ldapoper.cpp +++ b/src/modules/extra/m_ldapoper.cpp @@ -32,7 +32,7 @@ # pragma comment(lib, "lber.lib") #endif -/* $ModDesc: Allow/Deny connections based upon answer from LDAP server */ +/* $ModDesc: Adds the ability to authenticate opers via LDAP */ /* $LinkerFlags: -lldap */ class ModuleLDAPAuth : public Module @@ -181,7 +181,7 @@ public: virtual Version GetVersion() { - return Version("Allow/Deny connections based upon answer from LDAP server", VF_VENDOR); + return Version("Adds the ability to authenticate opers via LDAP", VF_VENDOR); } }; diff --git a/src/modules/extra/m_ssl_gnutls.cpp b/src/modules/extra/m_ssl_gnutls.cpp index 6ca876d4c..c631642ce 100644 --- a/src/modules/extra/m_ssl_gnutls.cpp +++ b/src/modules/extra/m_ssl_gnutls.cpp @@ -28,6 +28,17 @@ #include "ssl.h" #include "m_cap.h" +#ifdef WINDOWS +# pragma comment(lib, "libgnutls.lib") +# pragma comment(lib, "libgcrypt.lib") +# pragma comment(lib, "libgpg-error.lib") +# pragma comment(lib, "user32.lib") +# pragma comment(lib, "advapi32.lib") +# pragma comment(lib, "libgcc.lib") +# pragma comment(lib, "libmingwex.lib") +# pragma comment(lib, "gdi32.lib") +#endif + /* $ModDesc: Provides SSL support for clients */ /* $CompileFlags: pkgconfincludes("gnutls","/gnutls/gnutls.h","") */ /* $LinkerFlags: rpath("pkg-config --libs gnutls") pkgconflibs("gnutls","/libgnutls.so","-lgnutls") -lgcrypt */ diff --git a/src/modules/m_alltime.cpp b/src/modules/m_alltime.cpp index aba8fe7fe..7012fde7e 100644 --- a/src/modules/m_alltime.cpp +++ b/src/modules/m_alltime.cpp @@ -38,7 +38,7 @@ class CommandAlltime : public Command time_t now = ServerInstance->Time(); strftime(fmtdate, sizeof(fmtdate), "%Y-%m-%d %H:%M:%S", gmtime(&now)); - std::string msg = ":" + std::string(ServerInstance->Config->ServerName.c_str()) + " NOTICE " + user->nick + " :System time is " + fmtdate + "(" + ConvToStr(ServerInstance->Time()) + ") on " + ServerInstance->Config->ServerName; + std::string msg = ":" + std::string(ServerInstance->Config->ServerName.c_str()) + " NOTICE " + user->nick + " :System time is " + fmtdate + " (" + ConvToStr(ServerInstance->Time()) + ") on " + ServerInstance->Config->ServerName; user->SendText(msg); diff --git a/src/modules/m_blockamsg.cpp b/src/modules/m_blockamsg.cpp index 1d26b7639..8160fcf54 100644 --- a/src/modules/m_blockamsg.cpp +++ b/src/modules/m_blockamsg.cpp @@ -98,8 +98,8 @@ class ModuleBlockAmsg : public Module virtual ModResult OnPreCommand(std::string &command, std::vector<std::string> ¶meters, LocalUser *user, bool validated, const std::string &original_line) { - // Don't do anything with unregistered users, or remote ones. - if(!user || (user->registered != REG_ALL) || !IS_LOCAL(user)) + // Don't do anything with unregistered users + if (user->registered != REG_ALL) return MOD_RES_PASSTHRU; // We want case insensitive command comparison. diff --git a/src/modules/m_blockcolor.cpp b/src/modules/m_blockcolor.cpp index f2ba0603f..19b5c9231 100644 --- a/src/modules/m_blockcolor.cpp +++ b/src/modules/m_blockcolor.cpp @@ -23,7 +23,7 @@ #include "inspircd.h" -/* $ModDesc: Provides support for unreal-style channel mode +c */ +/* $ModDesc: Provides channel mode +c to block color */ /** Handles the +c channel mode */ @@ -95,7 +95,7 @@ class ModuleBlockColor : public Module virtual Version GetVersion() { - return Version("Provides support for unreal-style channel mode +c",VF_VENDOR); + return Version("Provides channel mode +c to block color",VF_VENDOR); } }; diff --git a/src/modules/m_botmode.cpp b/src/modules/m_botmode.cpp index c7a51beb9..5871b9227 100644 --- a/src/modules/m_botmode.cpp +++ b/src/modules/m_botmode.cpp @@ -21,7 +21,7 @@ #include "inspircd.h" -/* $ModDesc: Provides support for unreal-style umode +B */ +/* $ModDesc: Provides user mode +B to mark the user as a bot */ /** Handles user mode +B */ @@ -51,7 +51,7 @@ class ModuleBotMode : public Module virtual Version GetVersion() { - return Version("Provides support for unreal-style umode +B",VF_VENDOR); + return Version("Provides user mode +B to mark the user as a bot",VF_VENDOR); } virtual void OnWhois(User* src, User* dst) diff --git a/src/modules/m_callerid.cpp b/src/modules/m_callerid.cpp index 416ede9a1..f24c38b65 100644 --- a/src/modules/m_callerid.cpp +++ b/src/modules/m_callerid.cpp @@ -21,11 +21,8 @@ #include "inspircd.h" -#include <set> -#include <sstream> -#include <algorithm> -/* $ModDesc: Implementation of callerid (umode +g & /accept, ala hybrid etc) */ +/* $ModDesc: Implementation of callerid, usermode +g, /accept */ class callerid_data { @@ -57,11 +54,8 @@ class callerid_data } User *u = ServerInstance->FindNick(tok); - if (!u) - { - continue; - } - accepting.insert(u); + if ((u) && (u->registered == REG_ALL) && (!u->quitting) && (!IS_SERVER(u))) + accepting.insert(u); } } @@ -121,14 +115,9 @@ struct CallerIDExtInfo : public ExtensionItem if (!targ) continue; // shouldn't happen, but oh well. - for (std::list<callerid_data *>::iterator it2 = targ->wholistsme.begin(); it2 != targ->wholistsme.end(); it2++) - { - if (*it2 == dat) - { - targ->wholistsme.erase(it2); - break; - } - } + std::list<callerid_data*>::iterator it2 = std::find(targ->wholistsme.begin(), targ->wholistsme.end(), dat); + if (it2 != targ->wholistsme.end()) + targ->wholistsme.erase(it2); } } }; @@ -173,18 +162,12 @@ public: tok.erase(0, 1); // Remove the dash. } User* u = ServerInstance->FindNick(tok); - if (u) - { - if (dash) - out.append("-"); - out.append(u->uuid); - } - else - { - if (dash) - out.append("-"); - out.append(tok); - } + if ((!u) || (u->registered != REG_ALL) || (u->quitting) || (IS_SERVER(u))) + continue; + + if (dash) + out.append("-"); + out.append(u->uuid); } parameter = out; } @@ -213,15 +196,15 @@ public: { User* whotoremove = ServerInstance->FindNick(tok.substr(1)); if (whotoremove) - return (RemoveAccept(user, whotoremove, false) ? CMD_SUCCESS : CMD_FAILURE); + return (RemoveAccept(user, whotoremove) ? CMD_SUCCESS : CMD_FAILURE); else return CMD_FAILURE; } else { User* whotoadd = ServerInstance->FindNick(tok[0] == '+' ? tok.substr(1) : tok); - if (whotoadd) - return (AddAccept(user, whotoadd, false) ? CMD_SUCCESS : CMD_FAILURE); + if ((whotoadd) && (whotoadd->registered == REG_ALL) && (!whotoadd->quitting) && (!IS_SERVER(whotoadd))) + return (AddAccept(user, whotoadd) ? CMD_SUCCESS : CMD_FAILURE); else { user->WriteNumeric(401, "%s %s :No such nick/channel", user->nick.c_str(), tok.c_str()); @@ -246,22 +229,18 @@ public: user->WriteNumeric(282, "%s :End of ACCEPT list", user->nick.c_str()); } - bool AddAccept(User* user, User* whotoadd, bool quiet) + bool AddAccept(User* user, User* whotoadd) { // Add this user to my accept list first, so look me up.. callerid_data* dat = extInfo.get(user, true); if (dat->accepting.size() >= maxaccepts) { - if (!quiet) - user->WriteNumeric(456, "%s :Accept list is full (limit is %d)", user->nick.c_str(), maxaccepts); - + user->WriteNumeric(456, "%s :Accept list is full (limit is %d)", user->nick.c_str(), maxaccepts); return false; } if (!dat->accepting.insert(whotoadd).second) { - if (!quiet) - user->WriteNumeric(457, "%s %s :is already on your accept list", user->nick.c_str(), whotoadd->nick.c_str()); - + user->WriteNumeric(457, "%s %s :is already on your accept list", user->nick.c_str(), whotoadd->nick.c_str()); return false; } @@ -273,23 +252,19 @@ public: return true; } - bool RemoveAccept(User* user, User* whotoremove, bool quiet) + bool RemoveAccept(User* user, User* whotoremove) { // Remove them from my list, so look up my list.. callerid_data* dat = extInfo.get(user, false); if (!dat) { - if (!quiet) - user->WriteNumeric(458, "%s %s :is not on your accept list", user->nick.c_str(), whotoremove->nick.c_str()); - + user->WriteNumeric(458, "%s %s :is not on your accept list", user->nick.c_str(), whotoremove->nick.c_str()); return false; } std::set<User*>::iterator i = dat->accepting.find(whotoremove); if (i == dat->accepting.end()) { - if (!quiet) - user->WriteNumeric(458, "%s %s :is not on your accept list", user->nick.c_str(), whotoremove->nick.c_str()); - + user->WriteNumeric(458, "%s %s :is not on your accept list", user->nick.c_str(), whotoremove->nick.c_str()); return false; } @@ -303,15 +278,10 @@ public: return false; } - for (std::list<callerid_data *>::iterator it = dat2->wholistsme.begin(); it != dat2->wholistsme.end(); it++) - { + std::list<callerid_data*>::iterator it = std::find(dat2->wholistsme.begin(), dat2->wholistsme.end(), dat); + if (it != dat2->wholistsme.end()) // Found me! - if (*it == dat) - { - dat2->wholistsme.erase(it); - break; - } - } + dat2->wholistsme.erase(it); user->WriteServ("NOTICE %s :%s is no longer on your accept list", user->nick.c_str(), whotoremove->nick.c_str()); return true; @@ -367,7 +337,7 @@ public: ServerInstance->Modules->AddService(cmd); ServerInstance->Modules->AddService(cmd.extInfo); - Implementation eventlist[] = { I_OnRehash, I_OnUserPreNick, I_OnUserQuit, I_On005Numeric, I_OnUserPreNotice, I_OnUserPreMessage }; + Implementation eventlist[] = { I_OnRehash, I_OnUserPostNick, I_OnUserQuit, I_On005Numeric, I_OnUserPreNotice, I_OnUserPreMessage }; ServerInstance->Modules->Attach(eventlist, this, 6); } @@ -377,7 +347,7 @@ public: virtual Version GetVersion() { - return Version("Implementation of callerid (umode +g & /accept, ala hybrid etc)", VF_COMMON | VF_VENDOR); + return Version("Implementation of callerid, usermode +g, /accept", VF_COMMON | VF_VENDOR); } virtual void On005Numeric(std::string& output) @@ -385,7 +355,7 @@ public: output += " CALLERID=g"; } - ModResult PreText(User* user, User* dest, std::string& text, bool notice) + ModResult PreText(User* user, User* dest, std::string& text) { if (!dest->IsModeSet('g')) return MOD_RES_PASSTHRU; @@ -416,7 +386,7 @@ public: virtual ModResult OnUserPreMessage(User* user, void* dest, int target_type, std::string& text, char status, CUList &exempt_list) { if (IS_LOCAL(user) && target_type == TYPE_USER) - return PreText(user, (User*)dest, text, true); + return PreText(user, (User*)dest, text); return MOD_RES_PASSTHRU; } @@ -424,16 +394,15 @@ public: virtual ModResult OnUserPreNotice(User* user, void* dest, int target_type, std::string& text, char status, CUList &exempt_list) { if (IS_LOCAL(user) && target_type == TYPE_USER) - return PreText(user, (User*)dest, text, true); + return PreText(user, (User*)dest, text); return MOD_RES_PASSTHRU; } - ModResult OnUserPreNick(User* user, const std::string& newnick) + void OnUserPostNick(User* user, const std::string& oldnick) { if (!tracknick) RemoveFromAllAccepts(user); - return MOD_RES_PASSTHRU; } void OnUserQuit(User* user, const std::string& message, const std::string& oper_message) diff --git a/src/modules/m_cap.cpp b/src/modules/m_cap.cpp index 36674b9c5..662e128a4 100644 --- a/src/modules/m_cap.cpp +++ b/src/modules/m_cap.cpp @@ -55,19 +55,14 @@ class CommandCAP : public Command if (subcommand == "REQ") { - CapEvent Data(creator, "cap_req"); - - Data.type = subcommand; - Data.user = user; - Data.creator = this->creator; - if (parameters.size() < 2) return CMD_FAILURE; + CapEvent Data(creator, user, CapEvent::CAPEVENT_REQ); + // tokenize the input into a nice list of requested caps - std::string param = parameters[1]; std::string cap_; - irc::spacesepstream cap_stream(param); + irc::spacesepstream cap_stream(parameters[1]); while (cap_stream.GetToken(cap_)) { @@ -95,11 +90,7 @@ class CommandCAP : public Command } else if ((subcommand == "LS") || (subcommand == "LIST")) { - CapEvent Data(creator, subcommand == "LS" ? "cap_ls" : "cap_list"); - - Data.type = subcommand; - Data.user = user; - Data.creator = this->creator; + CapEvent Data(creator, user, subcommand == "LS" ? CapEvent::CAPEVENT_LS : CapEvent::CAPEVENT_LIST); reghold.set(user, 1); Data.Send(); @@ -107,31 +98,28 @@ class CommandCAP : public Command std::string Result; if (Data.wanted.size() > 0) Result = irc::stringjoiner(" ", Data.wanted, 0, Data.wanted.size() - 1).GetJoined(); - else - Result = ""; user->WriteServ("CAP %s %s :%s", user->nick.c_str(), subcommand.c_str(), Result.c_str()); } else if (subcommand == "CLEAR") { - CapEvent Data(creator, "cap_clear"); - - Data.type = subcommand; - Data.user = user; - Data.creator = this->creator; + CapEvent Data(creator, user, CapEvent::CAPEVENT_CLEAR); reghold.set(user, 1); Data.Send(); - std::string Result = irc::stringjoiner(" ", Data.ack, 0, Data.ack.size() - 1).GetJoined(); + std::string Result; + if (!Data.ack.empty()) + Result = irc::stringjoiner(" ", Data.ack, 0, Data.ack.size() - 1).GetJoined(); user->WriteServ("CAP %s ACK :%s", user->nick.c_str(), Result.c_str()); } else { user->WriteNumeric(ERR_INVALIDCAPSUBCOMMAND, "%s %s :Invalid CAP subcommand", user->nick.c_str(), subcommand.c_str()); + return CMD_FAILURE; } - return CMD_FAILURE; + return CMD_SUCCESS; } }; diff --git a/src/modules/m_cap.h b/src/modules/m_cap.h index 604fdb0ef..ce7e7f394 100644 --- a/src/modules/m_cap.h +++ b/src/modules/m_cap.h @@ -21,18 +21,22 @@ #ifndef M_CAP_H #define M_CAP_H -#include <map> -#include <string> - class CapEvent : public Event { public: - irc::string type; + enum CapEventType + { + CAPEVENT_REQ, + CAPEVENT_LS, + CAPEVENT_LIST, + CAPEVENT_CLEAR + }; + + CapEventType type; std::vector<std::string> wanted; std::vector<std::string> ack; User* user; - Module* creator; - CapEvent(Module* sender, const std::string& t) : Event(sender, t) {} + CapEvent(Module* sender, User* u, CapEventType capevtype) : Event(sender, "cap_request"), type(capevtype), user(u) {} }; class GenericCap @@ -47,28 +51,37 @@ class GenericCap void HandleEvent(Event& ev) { + if (ev.id != "cap_request") + return; + CapEvent *data = static_cast<CapEvent*>(&ev); - if (ev.id == "cap_req") + if (data->type == CapEvent::CAPEVENT_REQ) { - std::vector<std::string>::iterator it; - if ((it = std::find(data->wanted.begin(), data->wanted.end(), cap)) != data->wanted.end()) + for (std::vector<std::string>::iterator it = data->wanted.begin(); it != data->wanted.end(); ++it) { - // we can handle this, so ACK it, and remove it from the wanted list - data->ack.push_back(*it); - data->wanted.erase(it); - ext.set(data->user, 1); + if (it->empty()) + continue; + bool enablecap = ((*it)[0] != '-'); + if (((enablecap) && (*it == cap)) || (*it == "-" + cap)) + { + // we can handle this, so ACK it, and remove it from the wanted list + data->ack.push_back(*it); + data->wanted.erase(it); + ext.set(data->user, enablecap ? 1 : 0); + break; + } } } - else if (ev.id == "cap_ls") + else if (data->type == CapEvent::CAPEVENT_LS) { data->wanted.push_back(cap); } - else if (ev.id == "cap_list") + else if (data->type == CapEvent::CAPEVENT_LIST) { if (ext.get(data->user)) data->wanted.push_back(cap); } - else if (ev.id == "cap_clear") + else if (data->type == CapEvent::CAPEVENT_CLEAR) { data->ack.push_back("-" + cap); ext.set(data->user, 0); diff --git a/src/modules/m_chanhistory.cpp b/src/modules/m_chanhistory.cpp index 9275152ea..16eba953f 100644 --- a/src/modules/m_chanhistory.cpp +++ b/src/modules/m_chanhistory.cpp @@ -37,9 +37,23 @@ struct HistoryList class HistoryMode : public ModeHandler { + bool IsValidDuration(const std::string duration) + { + for (std::string::const_iterator i = duration.begin(); i != duration.end(); ++i) + { + unsigned char c = *i; + if (((c >= '0') && (c <= '9')) || (c == 's') || (c != 'S')) + continue; + + if (duration_multi[c] == 1) + return false; + } + return true; + } + public: SimpleExtItem<HistoryList> ext; - int maxlines; + unsigned int maxlines; HistoryMode(Module* Creator) : ModeHandler(Creator, "history", 'H', PARAM_SETONLY, MODETYPE_CHANNEL), ext("history", Creator) { } @@ -50,9 +64,14 @@ class HistoryMode : public ModeHandler std::string::size_type colon = parameter.find(':'); if (colon == std::string::npos) return MODEACTION_DENY; - int len = atoi(parameter.substr(0, colon).c_str()); - int time = ServerInstance->Duration(parameter.substr(colon+1)); - if (len <= 0 || time < 0) + + std::string duration = parameter.substr(colon+1); + if ((IS_LOCAL(source)) && ((duration.length() > 10) || (!IsValidDuration(duration)))) + return MODEACTION_DENY; + + unsigned int len = ConvToInt(parameter.substr(0, colon)); + int time = ServerInstance->Duration(duration); + if (len == 0 || time < 0) return MODEACTION_DENY; if (len > maxlines && IS_LOCAL(source)) return MODEACTION_DENY; @@ -60,7 +79,21 @@ class HistoryMode : public ModeHandler len = maxlines; if (parameter == channel->GetModeParameter(this)) return MODEACTION_DENY; - ext.set(channel, new HistoryList(len, time)); + + HistoryList* history = ext.get(channel); + if (history) + { + // Shrink the list if the new line number limit is lower than the old one + if (len < history->lines.size()) + history->lines.erase(history->lines.begin(), history->lines.begin() + (history->lines.size() - len)); + + history->maxlen = len; + history->maxtime = time; + } + else + { + ext.set(channel, new HistoryList(len, time)); + } channel->SetModeParam('H', parameter); } else @@ -77,6 +110,7 @@ class HistoryMode : public ModeHandler class ModuleChanHistory : public Module { HistoryMode m; + bool sendnotice; public: ModuleChanHistory() : m(this) { @@ -93,12 +127,9 @@ class ModuleChanHistory : public Module void OnRehash(User*) { - m.maxlines = ServerInstance->Config->ConfValue("chanhistory")->getInt("maxlines", 50); - } - - ~ModuleChanHistory() - { - ServerInstance->Modes->DelMode(&m); + ConfigTag* tag = ServerInstance->Config->ConfValue("chanhistory"); + m.maxlines = tag->getInt("maxlines", 50); + sendnotice = tag->getBool("notice", true); } void OnUserMessage(User* user,void* dest,int target_type, const std::string &text, char status, const CUList&) @@ -121,14 +152,22 @@ class ModuleChanHistory : public Module void OnPostJoin(Membership* memb) { + if (IS_REMOTE(memb->user)) + return; + HistoryList* list = m.ext.get(memb->chan); if (!list) return; time_t mintime = 0; if (list->maxtime) mintime = ServerInstance->Time() - list->maxtime; - memb->user->WriteServ("NOTICE %s :Replaying up to %d lines of pre-join history spanning up to %d seconds", - memb->chan->name.c_str(), list->maxlen, list->maxtime); + + if (sendnotice) + { + memb->user->WriteServ("NOTICE %s :Replaying up to %d lines of pre-join history spanning up to %d seconds", + memb->chan->name.c_str(), list->maxlen, list->maxtime); + } + for(std::deque<HistoryItem>::iterator i = list->lines.begin(); i != list->lines.end(); ++i) { if (i->ts >= mintime) diff --git a/src/modules/m_chanlog.cpp b/src/modules/m_chanlog.cpp index ed5063fad..29385b8e2 100644 --- a/src/modules/m_chanlog.cpp +++ b/src/modules/m_chanlog.cpp @@ -28,7 +28,8 @@ class ModuleChanLog : public Module /* * Multimap so people can redirect a snomask to multiple channels. */ - std::multimap<char, std::string> logstreams; + typedef std::multimap<char, std::string> ChanLogTargets; + ChanLogTargets logstreams; public: ModuleChanLog() { @@ -72,30 +73,21 @@ class ModuleChanLog : public Module virtual ModResult OnSendSnotice(char &sno, std::string &desc, const std::string &msg) { - std::multimap<char, std::string>::const_iterator it = logstreams.find(sno); - char buf[MAXBUF]; - - if (it == logstreams.end()) + std::pair<ChanLogTargets::const_iterator, ChanLogTargets::const_iterator> itpair = logstreams.equal_range(sno); + if (itpair.first == itpair.second) return MOD_RES_PASSTHRU; + char buf[MAXBUF]; snprintf(buf, MAXBUF, "\2%s\2: %s", desc.c_str(), msg.c_str()); - while (it != logstreams.end()) + for (ChanLogTargets::const_iterator it = itpair.first; it != itpair.second; ++it) { - if (it->first != sno) - { - it++; - continue; - } - Channel *c = ServerInstance->FindChan(it->second); if (c) { c->WriteChannelWithServ(ServerInstance->Config->ServerName.c_str(), "PRIVMSG %s :%s", c->name.c_str(), buf); ServerInstance->PI->SendChannelPrivmsg(c, 0, buf); } - - it++; } return MOD_RES_PASSTHRU; diff --git a/src/modules/m_chgname.cpp b/src/modules/m_chgname.cpp index 194ecf80e..2ac24c5d5 100644 --- a/src/modules/m_chgname.cpp +++ b/src/modules/m_chgname.cpp @@ -44,16 +44,22 @@ class CommandChgname : public Command return CMD_FAILURE; } + if (parameters[1].empty()) + { + user->WriteServ("NOTICE %s :*** CHGNAME: GECOS must be specified", user->nick.c_str()); + return CMD_FAILURE; + } + if (parameters[1].length() > ServerInstance->Config->Limits.MaxGecos) { - user->WriteServ("NOTICE %s :*** GECOS too long", user->nick.c_str()); + user->WriteServ("NOTICE %s :*** CHGNAME: GECOS too long", user->nick.c_str()); return CMD_FAILURE; } if (IS_LOCAL(dest)) { dest->ChangeName(parameters[1].c_str()); - ServerInstance->SNO->WriteGlobalSno('a', "%s used CHGNAME to change %s's real name to '%s'", user->nick.c_str(), dest->nick.c_str(), dest->fullname.c_str()); + ServerInstance->SNO->WriteGlobalSno('a', "%s used CHGNAME to change %s's GECOS to '%s'", user->nick.c_str(), dest->nick.c_str(), dest->fullname.c_str()); } return CMD_SUCCESS; diff --git a/src/modules/m_commonchans.cpp b/src/modules/m_commonchans.cpp index ac8a7ba29..877ba87d7 100644 --- a/src/modules/m_commonchans.cpp +++ b/src/modules/m_commonchans.cpp @@ -23,32 +23,10 @@ /** Handles user mode +c */ -class PrivacyMode : public ModeHandler +class PrivacyMode : public SimpleUserModeHandler { public: - PrivacyMode(Module* Creator) : ModeHandler(Creator, "deaf_commonchan", 'c', PARAM_NONE, MODETYPE_USER) { } - - ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string ¶meter, bool adding) - { - if (adding) - { - if (!dest->IsModeSet('c')) - { - dest->SetMode('c',true); - return MODEACTION_ALLOW; - } - } - else - { - if (dest->IsModeSet('c')) - { - dest->SetMode('c',false); - return MODEACTION_ALLOW; - } - } - - return MODEACTION_DENY; - } + PrivacyMode(Module* Creator) : SimpleUserModeHandler(Creator, "deaf_commonchan", 'c') { } }; class ModulePrivacyMode : public Module diff --git a/src/modules/m_dccallow.cpp b/src/modules/m_dccallow.cpp index 8c2a5f73e..0cea96154 100644 --- a/src/modules/m_dccallow.cpp +++ b/src/modules/m_dccallow.cpp @@ -102,7 +102,7 @@ class CommandDccallow : public Command std::string nick = parameters[0].substr(1); User *target = ServerInstance->FindNickOnly(nick); - if (target) + if ((target) && (!IS_SERVER(target)) && (!target->quitting) && (target->registered == REG_ALL)) { if (action == '-') @@ -257,7 +257,7 @@ class ModuleDCCAllow : public Module ServerInstance->Extensions.Register(ext); ServerInstance->AddCommand(&cmd); ReadFileConf(); - Implementation eventlist[] = { I_OnUserPreMessage, I_OnUserPreNotice, I_OnUserQuit, I_OnUserPreNick, I_OnRehash }; + Implementation eventlist[] = { I_OnUserPreMessage, I_OnUserPreNotice, I_OnUserQuit, I_OnUserPostNick, I_OnRehash }; ServerInstance->Modules->Attach(eventlist, this, 5); } @@ -274,7 +274,9 @@ class ModuleDCCAllow : public Module // remove their DCCALLOW list if they have one if (udl) { - RemoveFromUserlist(user); + userlist::iterator it = std::find(ul.begin(), ul.end(), user); + if (it != ul.end()) + ul.erase(it); } // remove them from any DCCALLOW lists @@ -282,10 +284,9 @@ class ModuleDCCAllow : public Module RemoveNick(user); } - virtual ModResult OnUserPreNick(User* user, const std::string &newnick) + virtual void OnUserPostNick(User* user, const std::string &oldnick) { RemoveNick(user); - return MOD_RES_PASSTHRU; } virtual ModResult OnUserPreMessage(User* user, void* dest, int target_type, std::string &text, char status, CUList &exempt_list) @@ -381,7 +382,7 @@ class ModuleDCCAllow : public Module void Expire() { - for (userlist::iterator iter = ul.begin(); iter != ul.end(); ++iter) + for (userlist::iterator iter = ul.begin(); iter != ul.end();) { User* u = (User*)(*iter); dl = ext->get(u); @@ -403,10 +404,11 @@ class ModuleDCCAllow : public Module } } } + ++iter; } else { - RemoveFromUserlist(u); + iter = ul.erase(iter); } } } @@ -414,7 +416,7 @@ class ModuleDCCAllow : public Module void RemoveNick(User* user) { /* Iterate through all DCCALLOW lists and remove user */ - for (userlist::iterator iter = ul.begin(); iter != ul.end(); ++iter) + for (userlist::iterator iter = ul.begin(); iter != ul.end();) { User *u = (User*)(*iter); dl = ext->get(u); @@ -434,10 +436,11 @@ class ModuleDCCAllow : public Module } } } + ++iter; } else { - RemoveFromUserlist(u); + iter = ul.erase(iter); } } } diff --git a/src/modules/m_deaf.cpp b/src/modules/m_deaf.cpp index 0a002bd07..3e0d205ba 100644 --- a/src/modules/m_deaf.cpp +++ b/src/modules/m_deaf.cpp @@ -21,7 +21,7 @@ #include "inspircd.h" -/* $ModDesc: Provides support for ircu style usermode +d (deaf to channel messages and channel notices) */ +/* $ModDesc: Provides usermode +d to block channel messages and channel notices */ /** User mode +d - filter out channel messages and channel notices */ @@ -163,7 +163,7 @@ class ModuleDeaf : public Module virtual Version GetVersion() { - return Version("Provides support for ircu style usermode +d (deaf to channel messages and channel notices)", VF_VENDOR); + return Version("Provides usermode +d to block channel messages and channel notices", VF_VENDOR); } }; diff --git a/src/modules/m_delaymsg.cpp b/src/modules/m_delaymsg.cpp index 6ef955a9f..1a0734ed9 100644 --- a/src/modules/m_delaymsg.cpp +++ b/src/modules/m_delaymsg.cpp @@ -18,14 +18,11 @@ #include "inspircd.h" -#include <stdarg.h> /* $ModDesc: Provides channelmode +d <int>, to deny messages to a channel until <int> seconds. */ class DelayMsgMode : public ModeHandler { - private: - CUList empty; public: LocalIntExt jointime; DelayMsgMode(Module* Parent) : ModeHandler(Parent, "delaymsg", 'd', PARAM_SETONLY, MODETYPE_CHANNEL) @@ -55,7 +52,6 @@ class ModuleDelayMsg : public Module Implementation eventlist[] = { I_OnUserJoin, I_OnUserPreMessage}; ServerInstance->Modules->Attach(eventlist, this, 2); } - ~ModuleDelayMsg(); Version GetVersion(); void OnUserJoin(Membership* memb, bool sync, bool created, CUList&); ModResult OnUserPreMessage(User* user, void* dest, int target_type, std::string &text, char status, CUList &exempt_list); @@ -65,6 +61,9 @@ ModeAction DelayMsgMode::OnModeChange(User* source, User* dest, Channel* channel { if (adding) { + if ((channel->IsModeSet('d')) && (channel->GetModeParameter('d') == parameter)) + return MODEACTION_DENY; + /* Setting a new limit, sanity check */ long limit = atoi(parameter.c_str()); @@ -76,6 +75,9 @@ ModeAction DelayMsgMode::OnModeChange(User* source, User* dest, Channel* channel } else { + if (!channel->IsModeSet('d')) + return MODEACTION_DENY; + /* * Clean up metadata */ @@ -87,10 +89,6 @@ ModeAction DelayMsgMode::OnModeChange(User* source, User* dest, Channel* channel return MODEACTION_ALLOW; } -ModuleDelayMsg::~ModuleDelayMsg() -{ -} - Version ModuleDelayMsg::GetVersion() { return Version("Provides channelmode +d <int>, to deny messages to a channel until <int> seconds.", VF_VENDOR); @@ -98,7 +96,7 @@ Version ModuleDelayMsg::GetVersion() void ModuleDelayMsg::OnUserJoin(Membership* memb, bool sync, bool created, CUList&) { - if (memb->chan->IsModeSet('d')) + if ((IS_LOCAL(memb->user)) && (memb->chan->IsModeSet('d'))) { djm.jointime.set(memb, ServerInstance->Time()); } @@ -107,7 +105,7 @@ void ModuleDelayMsg::OnUserJoin(Membership* memb, bool sync, bool created, CULis ModResult ModuleDelayMsg::OnUserPreMessage(User* user, void* dest, int target_type, std::string &text, char status, CUList &exempt_list) { /* Server origin */ - if (!user) + if ((!user) || (!IS_LOCAL(user))) return MOD_RES_PASSTHRU; if (target_type != TYPE_CHANNEL) @@ -118,7 +116,7 @@ ModResult ModuleDelayMsg::OnUserPreMessage(User* user, void* dest, int target_ty if (!memb) return MOD_RES_PASSTHRU; - + time_t ts = djm.jointime.get(memb); if (ts == 0) diff --git a/src/modules/m_dnsbl.cpp b/src/modules/m_dnsbl.cpp index 6a41c484f..2160b02dc 100644 --- a/src/modules/m_dnsbl.cpp +++ b/src/modules/m_dnsbl.cpp @@ -243,7 +243,7 @@ class ModuleDNSBL : public Module ReadConf(); ServerInstance->Modules->AddService(nameExt); ServerInstance->Modules->AddService(countExt); - Implementation eventlist[] = { I_OnRehash, I_OnSetClientIP, I_OnStats, I_OnSetConnectClass, I_OnCheckReady }; + Implementation eventlist[] = { I_OnRehash, I_OnUserInit, I_OnStats, I_OnSetConnectClass, I_OnCheckReady }; ServerInstance->Modules->Attach(eventlist, this, 5); } @@ -348,24 +348,22 @@ class ModuleDNSBL : public Module ReadConf(); } - void OnSetClientIP(User* user) + void OnUserInit(LocalUser* user) { - LocalUser *luser = IS_LOCAL(user); - - if (!luser || luser->exempt) + if (user->exempt) return; unsigned char a, b, c, d; char reversedipbuf[128]; std::string reversedip; - if (luser->client_sa.sa.sa_family != AF_INET) + if (user->client_sa.sa.sa_family != AF_INET) return; - d = (unsigned char) (luser->client_sa.in4.sin_addr.s_addr >> 24) & 0xFF; - c = (unsigned char) (luser->client_sa.in4.sin_addr.s_addr >> 16) & 0xFF; - b = (unsigned char) (luser->client_sa.in4.sin_addr.s_addr >> 8) & 0xFF; - a = (unsigned char) luser->client_sa.in4.sin_addr.s_addr & 0xFF; + d = (unsigned char) (user->client_sa.in4.sin_addr.s_addr >> 24) & 0xFF; + c = (unsigned char) (user->client_sa.in4.sin_addr.s_addr >> 16) & 0xFF; + b = (unsigned char) (user->client_sa.in4.sin_addr.s_addr >> 8) & 0xFF; + a = (unsigned char) user->client_sa.in4.sin_addr.s_addr & 0xFF; snprintf(reversedipbuf, 128, "%d.%d.%d.%d", d, c, b, a); reversedip = std::string(reversedipbuf); @@ -379,11 +377,11 @@ class ModuleDNSBL : public Module /* now we'd need to fire off lookups for `hostname'. */ bool cached; - DNSBLResolver *r = new DNSBLResolver(this, nameExt, countExt, hostname, luser, DNSBLConfEntries[i], cached); + DNSBLResolver *r = new DNSBLResolver(this, nameExt, countExt, hostname, user, DNSBLConfEntries[i], cached); ServerInstance->AddResolver(r, cached); i++; } - countExt.set(luser, i); + countExt.set(user, i); } ModResult OnSetConnectClass(LocalUser* user, ConnectClass* myclass) diff --git a/src/modules/m_globops.cpp b/src/modules/m_globops.cpp index db55858d6..d9dd8f2ac 100644 --- a/src/modules/m_globops.cpp +++ b/src/modules/m_globops.cpp @@ -38,13 +38,7 @@ class CommandGlobops : public Command CmdResult Handle (const std::vector<std::string> ¶meters, User *user) { - std::string line = "From " + std::string(user->nick) + ": "; - for (int i = 0; i < (int)parameters.size(); i++) - { - line = line + parameters[i] + " "; - } - ServerInstance->SNO->WriteGlobalSno('g',line); - + ServerInstance->SNO->WriteGlobalSno('g', "From " + user->nick + ": " + parameters[0]); return CMD_SUCCESS; } }; diff --git a/src/modules/m_halfop.cpp b/src/modules/m_halfop.cpp index f0eda3e56..7a43f0241 100644 --- a/src/modules/m_halfop.cpp +++ b/src/modules/m_halfop.cpp @@ -92,11 +92,6 @@ class ModuleHalfop : public Module throw ModuleException("Could not add new modes!"); } - ~ModuleHalfop() - { - ServerInstance->Modes->DelMode(&mh); - } - Version GetVersion() { return Version("Channel half-operator mode provider", VF_VENDOR); diff --git a/src/modules/m_helpop.cpp b/src/modules/m_helpop.cpp index a7bd4a8c5..60c23f45b 100644 --- a/src/modules/m_helpop.cpp +++ b/src/modules/m_helpop.cpp @@ -21,7 +21,7 @@ */ -/* $ModDesc: Provides the /HELPOP command, works like UnrealIRCd's helpop */ +/* $ModDesc: Provides the /HELPOP command for useful information */ #include "inspircd.h" @@ -29,35 +29,13 @@ static std::map<irc::string, std::string> helpop_map; /** Handles user mode +h */ -class Helpop : public ModeHandler +class Helpop : public SimpleUserModeHandler { public: - Helpop(Module* Creator) : ModeHandler(Creator, "helpop", 'h', PARAM_NONE, MODETYPE_USER) + Helpop(Module* Creator) : SimpleUserModeHandler(Creator, "helpop", 'h') { oper = true; } - - ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string ¶meter, bool adding) - { - if (adding) - { - if (!dest->IsModeSet('h')) - { - dest->SetMode('h',true); - return MODEACTION_ALLOW; - } - } - else - { - if (dest->IsModeSet('h')) - { - dest->SetMode('h',false); - return MODEACTION_ALLOW; - } - } - - return MODEACTION_DENY; - } }; /** Handles /HELPOP @@ -188,7 +166,7 @@ class ModuleHelpop : public Module Version GetVersion() { - return Version("Provides the /HELPOP command, works like UnrealIRCd's helpop", VF_VENDOR); + return Version("Provides the /HELPOP command for useful information", VF_VENDOR); } }; diff --git a/src/modules/m_hidechans.cpp b/src/modules/m_hidechans.cpp index 17e2e8605..9c582551b 100644 --- a/src/modules/m_hidechans.cpp +++ b/src/modules/m_hidechans.cpp @@ -24,32 +24,10 @@ /** Handles user mode +I */ -class HideChans : public ModeHandler +class HideChans : public SimpleUserModeHandler { public: - HideChans(Module* Creator) : ModeHandler(Creator, "hidechans", 'I', PARAM_NONE, MODETYPE_USER) { } - - ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string ¶meter, bool adding) - { - if (adding) - { - if (!dest->IsModeSet('I')) - { - dest->SetMode('I',true); - return MODEACTION_ALLOW; - } - } - else - { - if (dest->IsModeSet('I')) - { - dest->SetMode('I',false); - return MODEACTION_ALLOW; - } - } - - return MODEACTION_DENY; - } + HideChans(Module* Creator) : SimpleUserModeHandler(Creator, "hidechans", 'I') { } }; class ModuleHideChans : public Module diff --git a/src/modules/m_hideoper.cpp b/src/modules/m_hideoper.cpp index cde50b1a9..998a57bb3 100644 --- a/src/modules/m_hideoper.cpp +++ b/src/modules/m_hideoper.cpp @@ -25,35 +25,13 @@ /** Handles user mode +H */ -class HideOper : public ModeHandler +class HideOper : public SimpleUserModeHandler { public: - HideOper(Module* Creator) : ModeHandler(Creator, "hideoper", 'H', PARAM_NONE, MODETYPE_USER) + HideOper(Module* Creator) : SimpleUserModeHandler(Creator, "hideoper", 'H') { oper = true; } - - ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string ¶meter, bool adding) - { - if (adding) - { - if (!dest->IsModeSet('H')) - { - dest->SetMode('H',true); - return MODEACTION_ALLOW; - } - } - else - { - if (dest->IsModeSet('H')) - { - dest->SetMode('H',false); - return MODEACTION_ALLOW; - } - } - - return MODEACTION_DENY; - } }; class ModuleHideOper : public Module diff --git a/src/modules/m_ident.cpp b/src/modules/m_ident.cpp index b7c9c1cfd..c30e4d200 100644 --- a/src/modules/m_ident.cpp +++ b/src/modules/m_ident.cpp @@ -216,15 +216,17 @@ class IdentRequestSocket : public EventHandler char ibuf[MAXBUF]; int recvresult = ServerInstance->SE->Recv(this, ibuf, MAXBUF-1, 0); + /* Close (but don't delete from memory) our socket + * and flag as done since the ident lookup has finished + */ + Close(); + done = true; + /* Cant possibly be a valid response shorter than 3 chars, * because the shortest possible response would look like: '1,1' */ if (recvresult < 3) - { - Close(); - done = true; return; - } ServerInstance->Logs->Log("m_ident",DEBUG,"ReadResponse()"); @@ -263,13 +265,6 @@ class IdentRequestSocket : public EventHandler break; } - - /* Close (but dont delete from memory) our socket - * and flag as done - */ - Close(); - done = true; - return; } }; @@ -388,7 +383,11 @@ class ModuleIdent : public Module { /* Module unloading, tidy up users */ if (target_type == TYPE_USER) - OnUserDisconnect((LocalUser*)item); + { + LocalUser* user = IS_LOCAL((User*) item); + if (user) + OnUserDisconnect(user); + } } virtual void OnUserDisconnect(LocalUser *user) diff --git a/src/modules/m_inviteexception.cpp b/src/modules/m_inviteexception.cpp index 1ecec735e..5e6628e6d 100644 --- a/src/modules/m_inviteexception.cpp +++ b/src/modules/m_inviteexception.cpp @@ -47,6 +47,7 @@ class InviteException : public ListModeBase class ModuleInviteException : public Module { + bool invite_bypass_key; InviteException ie; public: ModuleInviteException() : ie(this) @@ -54,9 +55,10 @@ public: if (!ServerInstance->Modes->AddMode(&ie)) throw ModuleException("Could not add new modes!"); + OnRehash(NULL); ie.DoImplements(this); - Implementation eventlist[] = { I_On005Numeric, I_OnCheckInvite, I_OnCheckKey }; - ServerInstance->Modules->Attach(eventlist, this, 3); + Implementation eventlist[] = { I_On005Numeric, I_OnCheckInvite, I_OnCheckKey, I_OnRehash }; + ServerInstance->Modules->Attach(eventlist, this, 4); } void On005Numeric(std::string &output) @@ -66,17 +68,14 @@ public: ModResult OnCheckInvite(User* user, Channel* chan) { - if(chan != NULL) + modelist* list = ie.extItem.get(chan); + if (list) { - modelist* list = ie.extItem.get(chan); - if (list) + for (modelist::iterator it = list->begin(); it != list->end(); it++) { - for (modelist::iterator it = list->begin(); it != list->end(); it++) + if (chan->CheckBan(user, it->mask)) { - if (chan->CheckBan(user, it->mask)) - { - return MOD_RES_ALLOW; - } + return MOD_RES_ALLOW; } } } @@ -86,7 +85,7 @@ public: ModResult OnCheckKey(User* user, Channel* chan, const std::string& key) { - if (ServerInstance->Config->ConfValue("inviteexception")->getBool("bypasskey", true)) + if (invite_bypass_key) return OnCheckInvite(user, chan); return MOD_RES_PASSTHRU; } @@ -103,6 +102,7 @@ public: void OnRehash(User* user) { + invite_bypass_key = ServerInstance->Config->ConfValue("inviteexception")->getBool("bypasskey", true); ie.DoRehash(); } diff --git a/src/modules/m_lockserv.cpp b/src/modules/m_lockserv.cpp index cc2e25308..3408e4621 100644 --- a/src/modules/m_lockserv.cpp +++ b/src/modules/m_lockserv.cpp @@ -34,15 +34,20 @@ class CommandLockserv : public Command public: CommandLockserv(Module* Creator, bool& lock) : Command(Creator, "LOCKSERV", 0), locked(lock) { - flags_needed = 'o'; syntax.clear(); + flags_needed = 'o'; } CmdResult Handle (const std::vector<std::string> ¶meters, User *user) { + if (locked) + { + user->WriteServ("NOTICE %s :The server is already locked.", user->nick.c_str()); + return CMD_FAILURE; + } + locked = true; user->WriteNumeric(988, "%s %s :Closed for new connections", user->nick.c_str(), user->server.c_str()); - ServerInstance->SNO->WriteGlobalSno('a', "Oper %s used LOCKSERV to temporarily close for new connections", user->nick.c_str()); - /* Dont send to the network */ + ServerInstance->SNO->WriteGlobalSno('a', "Oper %s used LOCKSERV to temporarily disallow new connections", user->nick.c_str()); return CMD_SUCCESS; } }; @@ -55,15 +60,20 @@ private: public: CommandUnlockserv(Module* Creator, bool &lock) : Command(Creator, "UNLOCKSERV", 0), locked(lock) { - flags_needed = 'o'; syntax.clear(); + flags_needed = 'o'; } CmdResult Handle (const std::vector<std::string> ¶meters, User *user) { + if (!locked) + { + user->WriteServ("NOTICE %s :The server isn't locked.", user->nick.c_str()); + return CMD_FAILURE; + } + locked = false; user->WriteNumeric(989, "%s %s :Open for new connections", user->nick.c_str(), user->server.c_str()); - ServerInstance->SNO->WriteGlobalSno('a', "Oper %s used UNLOCKSERV to allow for new connections", user->nick.c_str()); - /* Dont send to the network */ + ServerInstance->SNO->WriteGlobalSno('a', "Oper %s used UNLOCKSERV to allow new connections", user->nick.c_str()); return CMD_SUCCESS; } }; diff --git a/src/modules/m_mlock.cpp b/src/modules/m_mlock.cpp index e9ca3bfd0..3fb60a3d2 100644 --- a/src/modules/m_mlock.cpp +++ b/src/modules/m_mlock.cpp @@ -54,17 +54,15 @@ public: return MOD_RES_PASSTHRU; std::string *mlock_str = mlock.get(channel); - if (!mlock_str || mlock_str->empty()) + if (!mlock_str) return MOD_RES_PASSTHRU; - for (const char *modes = parameters[1].c_str(); *modes; modes++) + std::string::size_type p = parameters[1].find_first_of(*mlock_str); + if (p != std::string::npos) { - if (mlock_str->find(*modes) != std::string::npos) - { - source->WriteNumeric(742, "%s %c %s :MODE cannot be set due to channel having an active MLOCK restriction policy", - channel->name.c_str(), *modes, mlock_str->c_str()); - return MOD_RES_DENY; - } + source->WriteNumeric(742, "%s %c %s :MODE cannot be set due to channel having an active MLOCK restriction policy", + channel->name.c_str(), parameters[1][p], mlock_str->c_str()); + return MOD_RES_DENY; } return MOD_RES_PASSTHRU; diff --git a/src/modules/m_noctcp.cpp b/src/modules/m_noctcp.cpp index 0b4e39764..8c8e1c473 100644 --- a/src/modules/m_noctcp.cpp +++ b/src/modules/m_noctcp.cpp @@ -21,34 +21,12 @@ #include "inspircd.h" -/* $ModDesc: Provides support for unreal-style channel mode +C */ +/* $ModDesc: Provides channel mode +C to block CTCPs */ -class NoCTCP : public ModeHandler +class NoCTCP : public SimpleChannelModeHandler { public: - NoCTCP(Module* Creator) : ModeHandler(Creator, "noctcp", 'C', PARAM_NONE, MODETYPE_CHANNEL) { } - - ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string ¶meter, bool adding) - { - if (adding) - { - if (!channel->IsModeSet('C')) - { - channel->SetMode('C',true); - return MODEACTION_ALLOW; - } - } - else - { - if (channel->IsModeSet('C')) - { - channel->SetMode('C',false); - return MODEACTION_ALLOW; - } - } - - return MODEACTION_DENY; - } + NoCTCP(Module* Creator) : SimpleChannelModeHandler(Creator, "noctcp", 'C') { } }; class ModuleNoCTCP : public Module @@ -73,7 +51,7 @@ class ModuleNoCTCP : public Module virtual Version GetVersion() { - return Version("Provides support for unreal-style channel mode +C", VF_VENDOR); + return Version("Provides channel mode +C to block CTCPs", VF_VENDOR); } virtual ModResult OnUserPreMessage(User* user,void* dest,int target_type, std::string &text, char status, CUList &exempt_list) @@ -86,21 +64,20 @@ class ModuleNoCTCP : public Module if ((target_type == TYPE_CHANNEL) && (IS_LOCAL(user))) { Channel* c = (Channel*)dest; - ModResult res = ServerInstance->OnCheckExemption(user,c,"noctcp"); + if (!c->IsModeSet('C')) + return MOD_RES_PASSTHRU; + + if ((text.empty()) || (text[0] != '\001') || (strncmp(text.c_str(),"\1ACTION ",8))) + return MOD_RES_PASSTHRU; + ModResult res = ServerInstance->OnCheckExemption(user,c,"noctcp"); if (res == MOD_RES_ALLOW) return MOD_RES_PASSTHRU; - if (!c->GetExtBanStatus(user, 'C').check(!c->IsModeSet('C'))) + if (!c->GetExtBanStatus(user, 'C')) { - if ((text.length()) && (text[0] == '\1')) - { - if (strncmp(text.c_str(),"\1ACTION ",8)) - { - user->WriteNumeric(ERR_NOCTCPALLOWED, "%s %s :Can't send CTCP to channel (+C set)",user->nick.c_str(), c->name.c_str()); - return MOD_RES_DENY; - } - } + user->WriteNumeric(ERR_NOCTCPALLOWED, "%s %s :Can't send CTCP to channel (+C set)",user->nick.c_str(), c->name.c_str()); + return MOD_RES_DENY; } } return MOD_RES_PASSTHRU; diff --git a/src/modules/m_nonicks.cpp b/src/modules/m_nonicks.cpp index 4d56ad35f..f5c404682 100644 --- a/src/modules/m_nonicks.cpp +++ b/src/modules/m_nonicks.cpp @@ -23,32 +23,10 @@ /* $ModDesc: Provides support for channel mode +N & extban +b N: which prevents nick changes on channel */ -class NoNicks : public ModeHandler +class NoNicks : public SimpleChannelModeHandler { public: - NoNicks(Module* Creator) : ModeHandler(Creator, "nonick", 'N', PARAM_NONE, MODETYPE_CHANNEL) { } - - ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string ¶meter, bool adding) - { - if (adding) - { - if (!channel->IsModeSet('N')) - { - channel->SetMode('N',true); - return MODEACTION_ALLOW; - } - } - else - { - if (channel->IsModeSet('N')) - { - channel->SetMode('N',false); - return MODEACTION_ALLOW; - } - } - - return MODEACTION_DENY; - } + NoNicks(Module* Creator) : SimpleChannelModeHandler(Creator, "nonick", 'N') { } }; class ModuleNoNickChange : public Module diff --git a/src/modules/m_nonotice.cpp b/src/modules/m_nonotice.cpp index 4aa51ef48..ccb44ccde 100644 --- a/src/modules/m_nonotice.cpp +++ b/src/modules/m_nonotice.cpp @@ -21,7 +21,7 @@ #include "inspircd.h" -/* $ModDesc: Provides support for unreal-style channel mode +T */ +/* $ModDesc: Provides channel mode +T to block notices to the channel */ class NoNotice : public SimpleChannelModeHandler { @@ -80,7 +80,7 @@ class ModuleNoNotice : public Module virtual Version GetVersion() { - return Version("Provides support for unreal-style channel mode +T", VF_VENDOR); + return Version("Provides channel mode +T to block notices to the channel", VF_VENDOR); } }; diff --git a/src/modules/m_operchans.cpp b/src/modules/m_operchans.cpp index 074c644e1..2e6fad79f 100644 --- a/src/modules/m_operchans.cpp +++ b/src/modules/m_operchans.cpp @@ -24,32 +24,13 @@ /* $ModDesc: Provides support for oper-only chans via the +O channel mode */ -class OperChans : public ModeHandler +class OperChans : public SimpleChannelModeHandler { public: /* This is an oper-only mode */ - OperChans(Module* Creator) : ModeHandler(Creator, "operonly", 'O', PARAM_NONE, MODETYPE_CHANNEL) { oper = true; } - - ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string ¶meter, bool adding) + OperChans(Module* Creator) : SimpleChannelModeHandler(Creator, "operonly", 'O') { - if (adding) - { - if (!channel->IsModeSet('O')) - { - channel->SetMode('O',true); - return MODEACTION_ALLOW; - } - } - else - { - if (channel->IsModeSet('O')) - { - channel->SetMode('O',false); - return MODEACTION_ALLOW; - } - } - - return MODEACTION_DENY; + oper = true; } }; diff --git a/src/modules/m_operlevels.cpp b/src/modules/m_operlevels.cpp index da506dd58..7e28f6c21 100644 --- a/src/modules/m_operlevels.cpp +++ b/src/modules/m_operlevels.cpp @@ -29,17 +29,7 @@ class ModuleOperLevels : public Module public: ModuleOperLevels() { - Implementation eventlist[] = { I_OnRehash, I_OnKill }; - ServerInstance->Modules->Attach(eventlist, this, 2); - } - - virtual ~ModuleOperLevels() - { - } - - - virtual void OnRehash(User* user) - { + ServerInstance->Modules->Attach(I_OnKill, this); } virtual Version GetVersion() @@ -64,7 +54,6 @@ class ModuleOperLevels : public Module } return MOD_RES_PASSTHRU; } - }; MODULE_INIT(ModuleOperLevels) diff --git a/src/modules/m_opermodes.cpp b/src/modules/m_opermodes.cpp index d029fda64..0b04ff576 100644 --- a/src/modules/m_opermodes.cpp +++ b/src/modules/m_opermodes.cpp @@ -29,13 +29,7 @@ class ModuleModesOnOper : public Module public: ModuleModesOnOper() { - Implementation eventlist[] = { I_OnPostOper, I_OnRehash }; - ServerInstance->Modules->Attach(eventlist, this, 2); - } - - - virtual void OnRehash(User* user) - { + ServerInstance->Modules->Attach(I_OnPostOper, this); } virtual ~ModuleModesOnOper() @@ -49,6 +43,9 @@ class ModuleModesOnOper : public Module virtual void OnPostOper(User* user, const std::string &opertype, const std::string &opername) { + if (!IS_LOCAL(user)) + return; + // whenever a user opers, go through the oper types, find their <type:modes>, // and if they have one apply their modes. The mode string can contain +modes // to add modes to the user or -modes to take modes from the user. @@ -67,22 +64,14 @@ class ModuleModesOnOper : public Module std::string buf; std::stringstream ss(smodes); - std::vector<std::string> tokens; + std::vector<std::string> modes; + modes.push_back(u->nick); // split into modes and mode params while (ss >> buf) - tokens.push_back(buf); - - std::vector<std::string> modes; - modes.push_back(u->nick); - - // process mode params - for (unsigned int k = 0; k < tokens.size(); k++) - { - modes.push_back(tokens[k]); - } + modes.push_back(buf); - ServerInstance->SendGlobalMode(modes, u); + ServerInstance->SendMode(modes, u); } }; diff --git a/src/modules/m_override.cpp b/src/modules/m_override.cpp index 1e875a3d6..76d6ee469 100644 --- a/src/modules/m_override.cpp +++ b/src/modules/m_override.cpp @@ -26,7 +26,7 @@ #include "inspircd.h" -/* $ModDesc: Provides support for unreal-style oper-override */ +/* $ModDesc: Provides support for allowing opers to override certain things. */ class ModuleOverride : public Module { @@ -194,7 +194,7 @@ class ModuleOverride : public Module Version GetVersion() { - return Version("Provides support for unreal-style oper-override",VF_VENDOR); + return Version("Provides support for allowing opers to override certain things",VF_VENDOR); } }; diff --git a/src/modules/m_redirect.cpp b/src/modules/m_redirect.cpp index 9ea3f72f1..6830f18ce 100644 --- a/src/modules/m_redirect.cpp +++ b/src/modules/m_redirect.cpp @@ -1,6 +1,7 @@ /* * InspIRCd -- Internet Relay Chat Daemon * + * Copyright (C) 2012 Shawn Smith <ShawnSmith0828@gmail.com> * Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org> * Copyright (C) 2007-2008 Robin Burchell <robin+git@viroteck.net> * Copyright (C) 2007 Dennis Friis <peavey@inspircd.org> @@ -23,7 +24,7 @@ #include "inspircd.h" -/* $ModDesc: Provides channel mode +L (limit redirection) */ +/* $ModDesc: Provides channel mode +L (limit redirection) and usermode +L (no forced redirection) */ /** Handle channel mode +L */ @@ -86,19 +87,44 @@ class Redirect : public ModeHandler } }; +/** Handles usermode +L to stop forced redirection and print an error. +*/ +class AntiRedirect : public SimpleUserModeHandler +{ + public: + AntiRedirect(Module* Creator) : SimpleUserModeHandler(Creator, "antiredirect", 'L') {} +}; + class ModuleRedirect : public Module { Redirect re; + AntiRedirect re_u; + bool UseUsermode; public: ModuleRedirect() - : re(this) + : re(this), re_u(this) { + /* Setting this here so it isn't changable by rehasing the config later. */ + UseUsermode = ServerInstance->Config->ConfValue("redirect")->getBool("antiredirect"); + /* Channel mode */ if (!ServerInstance->Modes->AddMode(&re)) throw ModuleException("Could not add new modes!"); + + /* Check to see if the usermode is enabled in the config */ + if (UseUsermode) + { + /* Log noting that this breaks compatability. */ + ServerInstance->Logs->Log("m_redirect", DEFAULT, "REDIRECT: Enabled usermode +L. This breaks linking with servers that do not have this enabled. This is disabled by default in the 2.0 branch but will be enabled in the next version."); + + /* Try to add the usermode */ + if (!ServerInstance->Modes->AddMode(&re_u)) + throw ModuleException("Could not add new modes!"); + } + Implementation eventlist[] = { I_OnUserPreJoin }; ServerInstance->Modules->Attach(eventlist, this, 1); } @@ -122,10 +148,20 @@ class ModuleRedirect : public Module user->WriteNumeric(470, "%s %s * :You may not join this channel. A redirect is set, but you may not be redirected as it is a circular loop.", user->nick.c_str(), cname); return MOD_RES_DENY; } - - user->WriteNumeric(470, "%s %s %s :You may not join this channel, so you are automatically being transferred to the redirect channel.", user->nick.c_str(), cname, channel.c_str()); - Channel::JoinUser(user, channel.c_str(), false, "", false, ServerInstance->Time()); - return MOD_RES_DENY; + /* We check the bool value here to make sure we have it enabled, if we don't then + usermode +L might be assigned to something else. */ + if (UseUsermode && user->IsModeSet('L')) + { + user->WriteNumeric(470, "%s %s %s :Force redirection stopped.", + user->nick.c_str(), cname, channel.c_str()); + return MOD_RES_DENY; + } + else + { + user->WriteNumeric(470, "%s %s %s :You may not join this channel, so you are automatically being transferred to the redirect channel.", user->nick.c_str(), cname, channel.c_str()); + Channel::JoinUser(user, channel.c_str(), false, "", false, ServerInstance->Time()); + return MOD_RES_DENY; + } } } } @@ -138,7 +174,7 @@ class ModuleRedirect : public Module virtual Version GetVersion() { - return Version("Provides channel mode +L (limit redirection)", VF_VENDOR); + return Version("Provides channel mode +L (limit redirection) and user mode +L (no forced redirection)", VF_VENDOR); } }; diff --git a/src/modules/m_sajoin.cpp b/src/modules/m_sajoin.cpp index 3d351313d..46732b6a6 100644 --- a/src/modules/m_sajoin.cpp +++ b/src/modules/m_sajoin.cpp @@ -21,7 +21,7 @@ #include "inspircd.h" -/* $ModDesc: Provides support for unreal-style SAJOIN command */ +/* $ModDesc: Provides command SAJOIN to allow opers to force-join users to channels */ /** Handle /SAJOIN */ @@ -117,7 +117,7 @@ class ModuleSajoin : public Module virtual Version GetVersion() { - return Version("Provides support for unreal-style SAJOIN command", VF_OPTCOMMON | VF_VENDOR); + return Version("Provides command SAJOIN to allow opers to force-join users to channels", VF_OPTCOMMON | VF_VENDOR); } }; diff --git a/src/modules/m_samode.cpp b/src/modules/m_samode.cpp index 5d088cf12..d9c75adf7 100644 --- a/src/modules/m_samode.cpp +++ b/src/modules/m_samode.cpp @@ -20,7 +20,7 @@ */ -/* $ModDesc: Provides more advanced UnrealIRCd SAMODE command */ +/* $ModDesc: Provides command SAMODE to allow opers to change modes on channels and users */ #include "inspircd.h" @@ -64,7 +64,7 @@ class ModuleSaMode : public Module Version GetVersion() { - return Version("Provides more advanced UnrealIRCd SAMODE command", VF_VENDOR); + return Version("Provides command SAMODE to allow opers to change modes on channels and users", VF_VENDOR); } ModResult OnPreMode(User* source,User* dest,Channel* channel, const std::vector<std::string>& parameters) diff --git a/src/modules/m_satopic.cpp b/src/modules/m_satopic.cpp index bf65cc5d5..a0e3319af 100644 --- a/src/modules/m_satopic.cpp +++ b/src/modules/m_satopic.cpp @@ -44,8 +44,7 @@ class CommandSATopic : public Command // 3rd parameter overrides access checks target->SetTopic(user, newTopic, true); - ServerInstance->SNO->WriteToSnoMask('a', user->nick + " used SATOPIC on " + target->name + ", new topic: " + newTopic); - ServerInstance->PI->SendSNONotice("A", user->nick + " used SATOPIC on " + target->name + ", new topic: " + newTopic); + ServerInstance->SNO->WriteGlobalSno('a', user->nick + " used SATOPIC on " + target->name + ", new topic: " + newTopic); return CMD_SUCCESS; } diff --git a/src/modules/m_services_account.cpp b/src/modules/m_services_account.cpp index cd34e955a..a28be61dc 100644 --- a/src/modules/m_services_account.cpp +++ b/src/modules/m_services_account.cpp @@ -39,19 +39,17 @@ class Channel_r : public ModeHandler if (!IS_LOCAL(source) || ServerInstance->ULine(source->nick.c_str()) || ServerInstance->ULine(source->server)) { // Only change the mode if it's not redundant - if ((adding && !channel->IsModeSet('r')) || (!adding && channel->IsModeSet('r'))) + if ((adding != channel->IsModeSet('r'))) { channel->SetMode('r',adding); return MODEACTION_ALLOW; } - - return MODEACTION_DENY; } else { source->WriteNumeric(500, "%s :Only a server may modify the +r channel mode", source->nick.c_str()); - return MODEACTION_DENY; } + return MODEACTION_DENY; } }; @@ -67,18 +65,17 @@ class User_r : public ModeHandler { if (!IS_LOCAL(source) || ServerInstance->ULine(source->nick.c_str()) || ServerInstance->ULine(source->server)) { - if ((adding && !dest->IsModeSet('r')) || (!adding && dest->IsModeSet('r'))) + if ((adding != dest->IsModeSet('r'))) { dest->SetMode('r',adding); return MODEACTION_ALLOW; } - return MODEACTION_DENY; } else { source->WriteNumeric(500, "%s :Only a server may modify the +r user mode", source->nick.c_str()); - return MODEACTION_DENY; } + return MODEACTION_DENY; } }; diff --git a/src/modules/m_setname.cpp b/src/modules/m_setname.cpp index 0d6b1d9f3..32c1d5dc3 100644 --- a/src/modules/m_setname.cpp +++ b/src/modules/m_setname.cpp @@ -36,7 +36,7 @@ class CommandSetname : public Command CmdResult Handle (const std::vector<std::string>& parameters, User *user) { - if (parameters.size() == 0) + if (parameters[0].empty()) { user->WriteServ("NOTICE %s :*** SETNAME: GECOS must be specified", user->nick.c_str()); return CMD_FAILURE; @@ -50,8 +50,7 @@ class CommandSetname : public Command if (user->ChangeName(parameters[0].c_str())) { - ServerInstance->SNO->WriteGlobalSno('a', "%s used SETNAME to change their GECOS to %s", user->nick.c_str(), parameters[0].c_str()); - return CMD_SUCCESS; + ServerInstance->SNO->WriteGlobalSno('a', "%s used SETNAME to change their GECOS to '%s'", user->nick.c_str(), parameters[0].c_str()); } return CMD_SUCCESS; diff --git a/src/modules/m_showwhois.cpp b/src/modules/m_showwhois.cpp index 6eec64bd5..d81dd553d 100644 --- a/src/modules/m_showwhois.cpp +++ b/src/modules/m_showwhois.cpp @@ -27,35 +27,13 @@ /** Handle user mode +W */ -class SeeWhois : public ModeHandler +class SeeWhois : public SimpleUserModeHandler { public: - SeeWhois(Module* Creator, bool IsOpersOnly) : ModeHandler(Creator, "showwhois", 'W', PARAM_NONE, MODETYPE_USER) + SeeWhois(Module* Creator, bool IsOpersOnly) : SimpleUserModeHandler(Creator, "showwhois", 'W') { oper = IsOpersOnly; } - - ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string ¶meter, bool adding) - { - if (adding) - { - if (!dest->IsModeSet('W')) - { - dest->SetMode('W',true); - return MODEACTION_ALLOW; - } - } - else - { - if (dest->IsModeSet('W')) - { - dest->SetMode('W',false); - return MODEACTION_ALLOW; - } - } - - return MODEACTION_DENY; - } }; class WhoisNoticeCmd : public Command diff --git a/src/modules/m_shun.cpp b/src/modules/m_shun.cpp index fe1c41162..197bbc1bf 100644 --- a/src/modules/m_shun.cpp +++ b/src/modules/m_shun.cpp @@ -158,7 +158,7 @@ class CommandShun : public Command else { delete r; - user->WriteServ("NOTICE %s :*** Shun for %s already exists", user->nick.c_str(), expr.c_str()); + user->WriteServ("NOTICE %s :*** Shun for %s already exists", user->nick.c_str(), target.c_str()); return CMD_FAILURE; } } diff --git a/src/modules/m_spanningtree/addline.cpp b/src/modules/m_spanningtree/addline.cpp index db9a7f2d6..5c3ad548d 100644 --- a/src/modules/m_spanningtree/addline.cpp +++ b/src/modules/m_spanningtree/addline.cpp @@ -30,7 +30,7 @@ bool TreeSocket::AddLine(const std::string &prefix, parameterlist ¶ms) { if (params.size() < 6) { - ServerInstance->SNO->WriteToSnoMask('d',"%s sent me a malformed ADDLINE of type %s.",prefix.c_str(),params[0].c_str()); + ServerInstance->SNO->WriteToSnoMask('d', "%s sent me a malformed ADDLINE", MyRoot->GetName().c_str()); return true; } diff --git a/src/modules/m_spanningtree/fjoin.cpp b/src/modules/m_spanningtree/fjoin.cpp index 50775be1d..929ace474 100644 --- a/src/modules/m_spanningtree/fjoin.cpp +++ b/src/modules/m_spanningtree/fjoin.cpp @@ -105,6 +105,7 @@ CmdResult CommandFJoin::Handle(const std::vector<std::string>& params, User *src // while the name is equal in case-insensitive compare, it might differ in case; use the remote version chan->name = channel; chan->age = TS; + chan->ClearInvites(); param_list.push_back(channel); this->RemoveStatus(ServerInstance->FakeClient, param_list); } diff --git a/src/modules/m_spanningtree/svspart.cpp b/src/modules/m_spanningtree/svspart.cpp index 7edc720af..35bce781d 100644 --- a/src/modules/m_spanningtree/svspart.cpp +++ b/src/modules/m_spanningtree/svspart.cpp @@ -30,17 +30,19 @@ CmdResult CommandSVSPart::Handle(const std::vector<std::string>& parameters, User *user) { - std::string reason = "Services forced part"; + User* u = ServerInstance->FindUUID(parameters[0]); + if (!u) + return CMD_FAILURE; - if (parameters.size() == 3) - reason = parameters[2]; - - User* u = ServerInstance->FindNick(parameters[0]); Channel* c = ServerInstance->FindChan(parameters[1]); + if (!c) + return CMD_FAILURE; - if (u && IS_LOCAL(u)) + if (IS_LOCAL(u)) + { + std::string reason = (parameters.size() == 3) ? parameters[2] : "Services forced part"; c->PartUser(u, reason); - + } return CMD_SUCCESS; } diff --git a/src/modules/m_spanningtree/treesocket.h b/src/modules/m_spanningtree/treesocket.h index be5455bce..13dfad3f1 100644 --- a/src/modules/m_spanningtree/treesocket.h +++ b/src/modules/m_spanningtree/treesocket.h @@ -315,6 +315,10 @@ class TreeSocket : public BufferedSocket /** Handle server quit on close */ virtual void Close(); + + /** Returns true if this server was introduced to the rest of the network + */ + bool Introduced(); }; #endif diff --git a/src/modules/m_spanningtree/treesocket1.cpp b/src/modules/m_spanningtree/treesocket1.cpp index dcb35af31..7804c870d 100644 --- a/src/modules/m_spanningtree/treesocket1.cpp +++ b/src/modules/m_spanningtree/treesocket1.cpp @@ -183,7 +183,7 @@ void TreeSocket::Squit(TreeServer* Current, const std::string &reason) { DelServerEvent(Utils->Creator, Current->GetName()); - if (!Current->GetSocket() || Current->GetSocket()->GetLinkState() == CONNECTED) + if (!Current->GetSocket() || Current->GetSocket()->Introduced()) { parameterlist params; params.push_back(Current->GetName()); @@ -245,3 +245,8 @@ void TreeSocket::OnDataReady() SendError("RecvQ overrun (line too long)"); Utils->Creator->loopCall = false; } + +bool TreeSocket::Introduced() +{ + return (capab == NULL); +} diff --git a/src/modules/m_spanningtree/treesocket2.cpp b/src/modules/m_spanningtree/treesocket2.cpp index cb49d92c9..e6fbad4c6 100644 --- a/src/modules/m_spanningtree/treesocket2.cpp +++ b/src/modules/m_spanningtree/treesocket2.cpp @@ -440,6 +440,7 @@ void TreeSocket::ProcessConnectedLine(std::string& prefix, std::string& command, ServerInstance->Logs->Log("m_spanningtree", SPARSE, "Unrecognised S2S command :%s %s %s", who->uuid.c_str(), command.c_str(), pmlist.GetJoined().c_str()); SendError("Unrecognised command '" + command + "' -- possibly loaded mismatched modules"); + return; } if (params.size() < cmd->min_params) @@ -448,6 +449,7 @@ void TreeSocket::ProcessConnectedLine(std::string& prefix, std::string& command, ServerInstance->Logs->Log("m_spanningtree", SPARSE, "Insufficient parameters for S2S command :%s %s %s", who->uuid.c_str(), command.c_str(), pmlist.GetJoined().c_str()); SendError("Insufficient parameters for command '" + command + "'"); + return; } CmdResult res = cmd->Handle(params, who); @@ -459,7 +461,7 @@ void TreeSocket::ProcessConnectedLine(std::string& prefix, std::string& command, who->uuid.c_str(), command.c_str(), pmlist.GetJoined().c_str()); SendError("Error handling '" + command + "' -- possibly loaded mismatched modules"); } - if (res == CMD_SUCCESS) + else if (res == CMD_SUCCESS) Utils->RouteCommand(route_back_again, command, params, who); } } diff --git a/src/modules/m_spanningtree/uid.cpp b/src/modules/m_spanningtree/uid.cpp index 0a8f4dbfc..7dd2cad1d 100644 --- a/src/modules/m_spanningtree/uid.cpp +++ b/src/modules/m_spanningtree/uid.cpp @@ -67,7 +67,7 @@ CmdResult CommandUID::Handle(const parameterlist ¶ms, User* serversrc) /* * Nick collision. */ - int collide = sock->DoCollision(iter->second, age_t, params[5], modestr, params[0]); + int collide = sock->DoCollision(iter->second, age_t, params[5], params[6], params[0]); ServerInstance->Logs->Log("m_spanningtree",DEBUG,"*** Collision on %s, collide=%d", params[2].c_str(), collide); if (collide != 1) diff --git a/src/modules/m_sslmodes.cpp b/src/modules/m_sslmodes.cpp index 504f1840b..ef63b2511 100644 --- a/src/modules/m_sslmodes.cpp +++ b/src/modules/m_sslmodes.cpp @@ -24,7 +24,7 @@ #include "inspircd.h" #include "ssl.h" -/* $ModDesc: Provides support for unreal-style channel mode +z */ +/* $ModDesc: Provides channel mode +z to allow for Secure/SSL only channels */ /** Handle channel mode +z */ @@ -134,7 +134,7 @@ class ModuleSSLModes : public Module Version GetVersion() { - return Version("Provides support for unreal-style channel mode +z", VF_VENDOR); + return Version("Provides channel mode +z to allow for Secure/SSL only channels", VF_VENDOR); } }; diff --git a/src/modules/m_stripcolor.cpp b/src/modules/m_stripcolor.cpp index cd4f35c4b..86f307bae 100644 --- a/src/modules/m_stripcolor.cpp +++ b/src/modules/m_stripcolor.cpp @@ -72,8 +72,8 @@ class ModuleStripColor : public Module { /* refactor this completely due to SQUIT bug since the old code would strip last char and replace with \0 --peavey */ int seq = 0; - std::string::iterator i,safei; - for (i = sentence.begin(); i != sentence.end();) + + for (std::string::iterator i = sentence.begin(); i != sentence.end();) { if (*i == 3) seq = 1; @@ -89,20 +89,7 @@ class ModuleStripColor : public Module seq = 0; if (seq || ((*i == 2) || (*i == 15) || (*i == 22) || (*i == 21) || (*i == 31))) - { - if (i != sentence.begin()) - { - safei = i; - --i; - sentence.erase(safei); - ++i; - } - else - { - sentence.erase(i); - i = sentence.begin(); - } - } + i = sentence.erase(i); else ++i; } diff --git a/src/modules/m_swhois.cpp b/src/modules/m_swhois.cpp index dc53f2f0c..a98c06c75 100644 --- a/src/modules/m_swhois.cpp +++ b/src/modules/m_swhois.cpp @@ -90,7 +90,7 @@ class ModuleSWhois : public Module ModuleSWhois() : cmd(this) { ServerInstance->AddCommand(&cmd); - Implementation eventlist[] = { I_OnWhoisLine, I_OnPostCommand }; + Implementation eventlist[] = { I_OnWhoisLine, I_OnPostOper }; ServerInstance->Modules->Attach(eventlist, this, 2); } @@ -112,11 +112,10 @@ class ModuleSWhois : public Module return MOD_RES_PASSTHRU; } - void OnPostCommand(const std::string &command, const std::vector<std::string> ¶ms, LocalUser *user, CmdResult result, const std::string &original_line) + void OnPostOper(User* user, const std::string &opertype, const std::string &opername) { - if ((command != "OPER") || (result != CMD_SUCCESS)) + if (!IS_LOCAL(user)) return; - ConfigReader Conf; std::string swhois = user->oper->getConfig("swhois"); diff --git a/src/modules/m_xline_db.cpp b/src/modules/m_xline_db.cpp index 365602b7e..683c14afa 100644 --- a/src/modules/m_xline_db.cpp +++ b/src/modules/m_xline_db.cpp @@ -235,6 +235,8 @@ class ModuleXLineDB : public Module { ServerInstance->SNO->WriteToSnoMask('x', "database: Added a line of type %s", command_p[1].c_str()); } + else + delete xl; } } diff --git a/src/server.cpp b/src/server.cpp index adaaa7d2c..4bd81a6d1 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -86,7 +86,7 @@ void InspIRCd::BuildISupport() std::stringstream v; v << "WALLCHOPS WALLVOICES MODES=" << Config->Limits.MaxModes << " CHANTYPES=# PREFIX=" << this->Modes->BuildPrefixes() << " MAP MAXCHANNELS=" << Config->MaxChans << " MAXBANS=60 VBANLIST NICKLEN=" << Config->Limits.NickMax; v << " CASEMAPPING=rfc1459 STATUSMSG=" << Modes->BuildPrefixes(false) << " CHARSET=ascii TOPICLEN=" << Config->Limits.MaxTopic << " KICKLEN=" << Config->Limits.MaxKick << " MAXTARGETS=" << Config->MaxTargets; - v << " AWAYLEN=" << Config->Limits.MaxAway << " CHANMODES=" << this->Modes->GiveModeList(MASK_CHANNEL) << " FNC NETWORK=" << Config->Network << " MAXPARA=32 ELIST=MU"; + v << " AWAYLEN=" << Config->Limits.MaxAway << " CHANMODES=" << this->Modes->GiveModeList(MASK_CHANNEL) << " FNC NETWORK=" << Config->Network << " MAXPARA=32 ELIST=MU" << " CHANNELLEN=" << Config->Limits.ChanMax; Config->data005 = v.str(); FOREACH_MOD(I_On005Numeric,On005Numeric(Config->data005)); Config->Update005(); diff --git a/src/socketengines/socketengine_ports.cpp b/src/socketengines/socketengine_ports.cpp index 648ad3ac1..5fc645bb1 100644 --- a/src/socketengines/socketengine_ports.cpp +++ b/src/socketengines/socketengine_ports.cpp @@ -47,7 +47,6 @@ private: port_event_t* events; public: /** Create a new PortsEngine - * @param Instance The creator of this object */ PortsEngine(); /** Delete a PortsEngine diff --git a/src/stats.cpp b/src/stats.cpp deleted file mode 100644 index e5ea94b9c..000000000 --- a/src/stats.cpp +++ /dev/null @@ -1,357 +0,0 @@ -/* - * InspIRCd -- Internet Relay Chat Daemon - * - * Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org> - * - * 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 "inspircd.h" -#include "xline.h" -#include "commands/cmd_whowas.h" - -void InspIRCd::DoStats(char statschar, User* user, string_list &results) -{ - std::string sn(this->Config->ServerName); - - bool isPublic = Config->UserStats.find(statschar) != std::string::npos; - bool isRemoteOper = IS_REMOTE(user) && IS_OPER(user); - bool isLocalOperWithPrivs = IS_LOCAL(user) && user->HasPrivPermission("servers/auspex"); - - if (!isPublic && !isRemoteOper && !isLocalOperWithPrivs) - { - this->SNO->WriteToSnoMask('t', - "%s '%c' denied for %s (%s@%s)", - (IS_LOCAL(user) ? "Stats" : "Remote stats"), - statschar, user->nick.c_str(), user->ident.c_str(), user->host.c_str()); - results.push_back(sn + " 481 " + user->nick + " :Permission denied - STATS " + statschar + " requires the servers/auspex priv."); - return; - } - - ModResult MOD_RESULT; - FIRST_MOD_RESULT(OnStats, MOD_RESULT, (statschar, user, results)); - if (MOD_RESULT == MOD_RES_DENY) - { - results.push_back(sn+" 219 "+user->nick+" "+statschar+" :End of /STATS report"); - this->SNO->WriteToSnoMask('t',"%s '%c' requested by %s (%s@%s)", - (IS_LOCAL(user) ? "Stats" : "Remote stats"), statschar, user->nick.c_str(), user->ident.c_str(), user->host.c_str()); - return; - } - - switch (statschar) - { - /* stats p (show listening ports) */ - case 'p': - { - for (size_t i = 0; i < this->ports.size(); i++) - { - std::string ip = this->ports[i]->bind_addr; - if (ip.empty()) - ip.assign("*"); - std::string type = ports[i]->bind_tag->getString("type", "clients"); - std::string hook = ports[i]->bind_tag->getString("ssl", "plaintext"); - - results.push_back(sn+" 249 "+user->nick+" :"+ ip + ":"+ConvToStr(ports[i]->bind_port)+ - " (" + type + ", " + hook + ")"); - } - } - break; - - /* These stats symbols must be handled by a linking module */ - case 'n': - case 'c': - break; - - case 'i': - { - for (ClassVector::iterator i = this->Config->Classes.begin(); i != this->Config->Classes.end(); i++) - { - ConnectClass* c = *i; - std::stringstream res; - res << sn << " 215 " << user->nick << " I " << c->name << ' '; - if (c->type == CC_ALLOW) - res << '+'; - if (c->type == CC_DENY) - res << '-'; - - if (c->type == CC_NAMED) - res << '*'; - else - res << c->host; - - res << ' ' << c->config->getString("port", "*") << ' '; - - res << c->GetRecvqMax() << ' ' << c->GetSendqSoftMax() << ' ' << c->GetSendqHardMax() - << ' ' << c->GetCommandRate() << ' ' << c->GetPenaltyThreshold(); - if (c->fakelag) - res << '*'; - results.push_back(res.str()); - } - } - break; - - case 'Y': - { - int idx = 0; - for (ClassVector::iterator i = this->Config->Classes.begin(); i != this->Config->Classes.end(); i++) - { - ConnectClass* c = *i; - results.push_back(sn+" 215 "+user->nick+" i NOMATCH * "+c->GetHost()+" "+ConvToStr(c->limit ? c->limit : this->SE->GetMaxFds())+" "+ConvToStr(idx)+" "+this->Config->ServerName+" *"); - results.push_back(sn+" 218 "+user->nick+" Y "+ConvToStr(idx)+" "+ConvToStr(c->GetPingTime())+" 0 "+ConvToStr(c->GetSendqHardMax())+" :"+ - ConvToStr(c->GetRecvqMax())+" "+ConvToStr(c->GetRegTimeout())); - idx++; - } - } - break; - - case 'U': - { - for(std::map<irc::string, bool>::iterator i = Config->ulines.begin(); i != Config->ulines.end(); ++i) - { - results.push_back(sn+" 248 "+user->nick+" U "+std::string(i->first.c_str())); - } - } - break; - - case 'P': - { - int idx = 0; - for (user_hash::iterator i = this->Users->clientlist->begin(); i != this->Users->clientlist->end(); i++) - { - if (IS_OPER(i->second) && !this->ULine(i->second->server)) - { - results.push_back(sn+" 249 "+user->nick+" :"+i->second->nick+" ("+i->second->ident+"@"+i->second->dhost+") Idle: "+ - (IS_LOCAL(i->second) ? ConvToStr(this->Time() - i->second->idle_lastmsg) + " secs" : "unavailable")); - idx++; - } - } - results.push_back(sn+" 249 "+user->nick+" :"+ConvToStr(idx)+" OPER(s)"); - } - break; - - case 'k': - this->XLines->InvokeStats("K",216,user,results); - break; - case 'g': - this->XLines->InvokeStats("G",223,user,results); - break; - case 'q': - this->XLines->InvokeStats("Q",217,user,results); - break; - case 'Z': - this->XLines->InvokeStats("Z",223,user,results); - break; - case 'e': - this->XLines->InvokeStats("E",223,user,results); - break; - case 'E': - results.push_back(sn+" 249 "+user->nick+" :Total events: "+ConvToStr(this->SE->TotalEvents)); - results.push_back(sn+" 249 "+user->nick+" :Read events: "+ConvToStr(this->SE->ReadEvents)); - results.push_back(sn+" 249 "+user->nick+" :Write events: "+ConvToStr(this->SE->WriteEvents)); - results.push_back(sn+" 249 "+user->nick+" :Error events: "+ConvToStr(this->SE->ErrorEvents)); - break; - - /* stats m (list number of times each command has been used, plus bytecount) */ - case 'm': - for (Commandtable::iterator i = this->Parser->cmdlist.begin(); i != this->Parser->cmdlist.end(); i++) - { - if (i->second->use_count) - { - /* RPL_STATSCOMMANDS */ - results.push_back(sn+" 212 "+user->nick+" "+i->second->name+" "+ConvToStr(i->second->use_count)+" "+ConvToStr(i->second->total_bytes)); - } - } - break; - - /* stats z (debug and memory info) */ - case 'z': - { - results.push_back(sn+" 249 "+user->nick+" :Users: "+ConvToStr(this->Users->clientlist->size())); - results.push_back(sn+" 249 "+user->nick+" :Channels: "+ConvToStr(this->chanlist->size())); - results.push_back(sn+" 249 "+user->nick+" :Commands: "+ConvToStr(this->Parser->cmdlist.size())); - - if (!this->Config->WhoWasGroupSize == 0 && !this->Config->WhoWasMaxGroups == 0) - { - Module* whowas = Modules->Find("cmd_whowas.so"); - if (whowas) - { - WhowasRequest req(NULL, whowas, WhowasRequest::WHOWAS_STATS); - req.user = user; - req.Send(); - results.push_back(sn+" 249 "+user->nick+" :"+req.value); - } - } - - float kbitpersec_in, kbitpersec_out, kbitpersec_total; - char kbitpersec_in_s[30], kbitpersec_out_s[30], kbitpersec_total_s[30]; - - this->SE->GetStats(kbitpersec_in, kbitpersec_out, kbitpersec_total); - - snprintf(kbitpersec_total_s, 30, "%03.5f", kbitpersec_total); - snprintf(kbitpersec_out_s, 30, "%03.5f", kbitpersec_out); - snprintf(kbitpersec_in_s, 30, "%03.5f", kbitpersec_in); - - results.push_back(sn+" 249 "+user->nick+" :Bandwidth total: "+ConvToStr(kbitpersec_total_s)+" kilobits/sec"); - results.push_back(sn+" 249 "+user->nick+" :Bandwidth out: "+ConvToStr(kbitpersec_out_s)+" kilobits/sec"); - results.push_back(sn+" 249 "+user->nick+" :Bandwidth in: "+ConvToStr(kbitpersec_in_s)+" kilobits/sec"); - -#ifndef WIN32 - /* Moved this down here so all the not-windows stuff (look w00tie, I didn't say win32!) is in one ifndef. - * Also cuts out some identical code in both branches of the ifndef. -- Om - */ - rusage R; - - /* Not sure why we were doing '0' with a RUSAGE_SELF comment rather than just using RUSAGE_SELF -- Om */ - if (!getrusage(RUSAGE_SELF,&R)) /* RUSAGE_SELF */ - { - results.push_back(sn+" 249 "+user->nick+" :Total allocation: "+ConvToStr(R.ru_maxrss)+"K"); - results.push_back(sn+" 249 "+user->nick+" :Signals: "+ConvToStr(R.ru_nsignals)); - results.push_back(sn+" 249 "+user->nick+" :Page faults: "+ConvToStr(R.ru_majflt)); - results.push_back(sn+" 249 "+user->nick+" :Swaps: "+ConvToStr(R.ru_nswap)); - results.push_back(sn+" 249 "+user->nick+" :Context Switches: Voluntary; "+ConvToStr(R.ru_nvcsw)+" Involuntary; "+ConvToStr(R.ru_nivcsw)); - - char percent[30]; - - float n_elapsed = (ServerInstance->Time() - this->stats->LastSampled.tv_sec) * 1000000 - + (ServerInstance->Time_ns() - this->stats->LastSampled.tv_nsec) / 1000; - float n_eaten = ((R.ru_utime.tv_sec - this->stats->LastCPU.tv_sec) * 1000000 + R.ru_utime.tv_usec - this->stats->LastCPU.tv_usec); - float per = (n_eaten / n_elapsed) * 100; - - snprintf(percent, 30, "%03.5f%%", per); - results.push_back(sn+" 249 "+user->nick+" :CPU Use (now): "+percent); - - n_elapsed = ServerInstance->Time() - ServerInstance->startup_time; - n_eaten = (float)R.ru_utime.tv_sec + R.ru_utime.tv_usec / 100000.0; - per = (n_eaten / n_elapsed) * 100; - snprintf(percent, 30, "%03.5f%%", per); - results.push_back(sn+" 249 "+user->nick+" :CPU Use (total): "+percent); - } -#else - PROCESS_MEMORY_COUNTERS MemCounters; - if (GetProcessMemoryInfo(GetCurrentProcess(), &MemCounters, sizeof(MemCounters))) - { - results.push_back(sn+" 249 "+user->nick+" :Total allocation: "+ConvToStr((MemCounters.WorkingSetSize + MemCounters.PagefileUsage) / 1024)+"K"); - results.push_back(sn+" 249 "+user->nick+" :Pagefile usage: "+ConvToStr(MemCounters.PagefileUsage / 1024)+"K"); - results.push_back(sn+" 249 "+user->nick+" :Page faults: "+ConvToStr(MemCounters.PageFaultCount)); - results.push_back(sn+" 249 "+user->nick+" :CPU Usage: " + ConvToStr(getcpu()) + "%"); - } -#endif - } - break; - - case 'T': - { - char buffer[MAXBUF]; - results.push_back(sn+" 249 "+user->nick+" :accepts "+ConvToStr(this->stats->statsAccept)+" refused "+ConvToStr(this->stats->statsRefused)); - results.push_back(sn+" 249 "+user->nick+" :unknown commands "+ConvToStr(this->stats->statsUnknown)); - results.push_back(sn+" 249 "+user->nick+" :nick collisions "+ConvToStr(this->stats->statsCollisions)); - results.push_back(sn+" 249 "+user->nick+" :dns requests "+ConvToStr(this->stats->statsDnsGood+this->stats->statsDnsBad)+" succeeded "+ConvToStr(this->stats->statsDnsGood)+" failed "+ConvToStr(this->stats->statsDnsBad)); - results.push_back(sn+" 249 "+user->nick+" :connection count "+ConvToStr(this->stats->statsConnects)); - snprintf(buffer,MAXBUF," 249 %s :bytes sent %5.2fK recv %5.2fK", - user->nick.c_str(),this->stats->statsSent / 1024.0,this->stats->statsRecv / 1024.0); - results.push_back(sn+buffer); - } - break; - - /* stats o */ - case 'o': - { - ConfigTagList tags = ServerInstance->Config->ConfTags("oper"); - for(ConfigIter i = tags.first; i != tags.second; ++i) - { - ConfigTag* tag = i->second; - results.push_back(sn+" 243 "+user->nick+" O "+tag->getString("host")+" * "+ - tag->getString("name") + " " + tag->getString("type")+" 0"); - } - } - break; - case 'O': - { - for(OperIndex::iterator i = ServerInstance->Config->oper_blocks.begin(); i != ServerInstance->Config->oper_blocks.end(); i++) - { - // just the types, not the actual oper blocks... - if (i->first[0] != ' ') - continue; - OperInfo* tag = i->second; - tag->init(); - std::string umodes; - std::string cmodes; - for(char c='A'; c < 'z'; c++) - { - ModeHandler* mh = ServerInstance->Modes->FindMode(c, MODETYPE_USER); - if (mh && mh->NeedsOper() && tag->AllowedUserModes[c - 'A']) - umodes.push_back(c); - mh = ServerInstance->Modes->FindMode(c, MODETYPE_CHANNEL); - if (mh && mh->NeedsOper() && tag->AllowedChanModes[c - 'A']) - cmodes.push_back(c); - } - results.push_back(sn+" 243 "+user->nick+" O "+tag->NameStr() + " " + umodes + " " + cmodes); - } - } - break; - - /* stats l (show user I/O stats) */ - case 'l': - results.push_back(sn+" 211 "+user->nick+" :nick[ident@host] sendq cmds_out bytes_out cmds_in bytes_in time_open"); - for (std::vector<LocalUser*>::iterator n = this->Users->local_users.begin(); n != this->Users->local_users.end(); n++) - { - LocalUser* i = *n; - results.push_back(sn+" 211 "+user->nick+" "+i->nick+"["+i->ident+"@"+i->dhost+"] "+ConvToStr(i->eh.getSendQSize())+" "+ConvToStr(i->cmds_out)+" "+ConvToStr(i->bytes_out)+" "+ConvToStr(i->cmds_in)+" "+ConvToStr(i->bytes_in)+" "+ConvToStr(this->Time() - i->age)); - } - break; - - /* stats L (show user I/O stats with IP addresses) */ - case 'L': - results.push_back(sn+" 211 "+user->nick+" :nick[ident@ip] sendq cmds_out bytes_out cmds_in bytes_in time_open"); - for (std::vector<LocalUser*>::iterator n = this->Users->local_users.begin(); n != this->Users->local_users.end(); n++) - { - LocalUser* i = *n; - results.push_back(sn+" 211 "+user->nick+" "+i->nick+"["+i->ident+"@"+i->GetIPString()+"] "+ConvToStr(i->eh.getSendQSize())+" "+ConvToStr(i->cmds_out)+" "+ConvToStr(i->bytes_out)+" "+ConvToStr(i->cmds_in)+" "+ConvToStr(i->bytes_in)+" "+ConvToStr(this->Time() - i->age)); - } - break; - - /* stats u (show server uptime) */ - case 'u': - { - time_t current_time = 0; - current_time = this->Time(); - time_t server_uptime = current_time - this->startup_time; - struct tm* stime; - stime = gmtime(&server_uptime); - /* i dont know who the hell would have an ircd running for over a year nonstop, but - * Craig suggested this, and it seemed a good idea so in it went */ - if (stime->tm_year > 70) - { - char buffer[MAXBUF]; - snprintf(buffer,MAXBUF," 242 %s :Server up %d years, %d days, %.2d:%.2d:%.2d",user->nick.c_str(),(stime->tm_year-70),stime->tm_yday,stime->tm_hour,stime->tm_min,stime->tm_sec); - results.push_back(sn+buffer); - } - else - { - char buffer[MAXBUF]; - snprintf(buffer,MAXBUF," 242 %s :Server up %d days, %.2d:%.2d:%.2d",user->nick.c_str(),stime->tm_yday,stime->tm_hour,stime->tm_min,stime->tm_sec); - results.push_back(sn+buffer); - } - } - break; - - default: - break; - } - - results.push_back(sn+" 219 "+user->nick+" "+statschar+" :End of /STATS report"); - this->SNO->WriteToSnoMask('t',"%s '%c' requested by %s (%s@%s)", - (IS_LOCAL(user) ? "Stats" : "Remote stats"), statschar, user->nick.c_str(), user->ident.c_str(), user->host.c_str()); - return; -} diff --git a/src/usermanager.cpp b/src/usermanager.cpp index 7da57646f..785d23625 100644 --- a/src/usermanager.cpp +++ b/src/usermanager.cpp @@ -37,7 +37,7 @@ void UserManager::AddUser(int socket, ListenSocket* via, irc::sockets::sockaddrs } catch (...) { - ServerInstance->Logs->Log("USERS", DEFAULT,"*** WTF *** Duplicated UUID! -- Crack smoking monkies have been unleashed."); + ServerInstance->Logs->Log("USERS", DEFAULT,"*** WTF *** Duplicated UUID! -- Crack smoking monkeys have been unleashed."); ServerInstance->SNO->WriteToSnoMask('a', "WARNING *** Duplicate UUID allocated!"); return; } diff --git a/src/users.cpp b/src/users.cpp index 39be81272..9c3d645f7 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -224,8 +224,7 @@ LocalUser::LocalUser(int myfd, irc::sockets::sockaddrs* client, irc::sockets::so { lastping = 0; eh.SetFd(myfd); - - SetClientIP(client); + memcpy(&client_sa, client, sizeof(irc::sockets::sockaddrs)); memcpy(&server_sa, servaddr, sizeof(irc::sockets::sockaddrs)); } @@ -333,75 +332,45 @@ const std::string& User::GetFullRealHost() bool LocalUser::IsInvited(const irc::string &channel) { - time_t now = ServerInstance->Time(); - InvitedList::iterator safei; - for (InvitedList::iterator i = invites.begin(); i != invites.end(); ++i) - { - if (channel == i->first) - { - if (i->second != 0 && now > i->second) - { - /* Expired invite, remove it. */ - safei = i; - --i; - invites.erase(safei); - continue; - } - return true; - } - } - return false; + Channel* chan = ServerInstance->FindChan(channel.c_str()); + if (!chan) + return false; + + return (Invitation::Find(chan, this) != NULL); } -InvitedList* LocalUser::GetInviteList() +InviteList& LocalUser::GetInviteList() { - time_t now = ServerInstance->Time(); - /* Weed out expired invites here. */ - InvitedList::iterator safei; - for (InvitedList::iterator i = invites.begin(); i != invites.end(); ++i) - { - if (i->second != 0 && now > i->second) - { - /* Expired invite, remove it. */ - safei = i; - --i; - invites.erase(safei); - } - } - return &invites; + RemoveExpiredInvites(); + return invites; } void LocalUser::InviteTo(const irc::string &channel, time_t invtimeout) { - time_t now = ServerInstance->Time(); - if (invtimeout != 0 && now > invtimeout) return; /* Don't add invites that are expired from the get-go. */ - for (InvitedList::iterator i = invites.begin(); i != invites.end(); ++i) - { - if (channel == i->first) - { - if (i->second != 0 && invtimeout > i->second) - { - i->second = invtimeout; - } - - return; - } - } - invites.push_back(std::make_pair(channel, invtimeout)); + Channel* chan = ServerInstance->FindChan(channel.c_str()); + if (chan) + Invitation::Create(chan, this, invtimeout); } void LocalUser::RemoveInvite(const irc::string &channel) { - for (InvitedList::iterator i = invites.begin(); i != invites.end(); i++) + Channel* chan = ServerInstance->FindChan(channel.c_str()); + if (chan) { - if (channel == i->first) + Invitation* inv = Invitation::Find(chan, this); + if (inv) { - invites.erase(i); - return; - } + inv->cull(); + delete inv; + } } } +void LocalUser::RemoveExpiredInvites() +{ + Invitation::Find(NULL, this); +} + bool User::HasModePermission(unsigned char, ModeType) { return true; @@ -560,8 +529,6 @@ CullResult User::cull() ServerInstance->Users->QuitUser(this, "Culled without QuitUser"); PurgeEmptyChannels(); - this->InvalidateCache(); - if (client_sa.sa.sa_family != AF_UNSPEC) ServerInstance->Users->RemoveCloneCounts(this); @@ -576,6 +543,7 @@ CullResult LocalUser::cull() else ServerInstance->Logs->Log("USERS", DEBUG, "Failed to remove user from vector"); + ClearInvites(); eh.cull(); return User::cull(); } @@ -1009,24 +977,10 @@ irc::sockets::cidr_mask User::GetCIDRMask() return irc::sockets::cidr_mask(client_sa, range); } -bool User::SetClientIP(irc::sockets::sockaddrs *sa) -{ - memcpy(&client_sa, sa, sizeof(irc::sockets::sockaddrs)); - - FOREACH_MOD(I_OnSetClientIP, OnSetClientIP(this)); - - return true; -} - bool User::SetClientIP(const char* sip) { - irc::sockets::sockaddrs sa; - this->cachedip = ""; - if (!irc::sockets::aptosa(sip, 0, sa)) - return false; - - return SetClientIP(&sa); + return irc::sockets::aptosa(sip, 0, client_sa); } static std::string wide_newline("\r\n"); diff --git a/src/version.sh b/src/version.sh index ce9cc035d..08ee17904 100755 --- a/src/version.sh +++ b/src/version.sh @@ -1,2 +1,2 @@ #!/bin/sh -echo "InspIRCd-2.0.5" +echo "InspIRCd-2.0.8" diff --git a/win/inspircd.nsi b/win/inspircd.nsi index 78f73ef09..1fa21c6f9 100644 --- a/win/inspircd.nsi +++ b/win/inspircd.nsi @@ -152,7 +152,11 @@ SectionEnd Section "Config Files" SEC02 SetOutPath "$INSTDIR\conf" - File "..\docs\*.example" + File "..\docs\conf\*.example" + SetOutPath "$INSTDIR\conf\aliases" + File "..\docs\conf\aliases\*.example" + SetOutPath "$INSTDIR\conf\modules" + File "..\docs\conf\modules\modules.*" SectionEnd Section "Command Handlers" SEC03 @@ -163,6 +167,10 @@ SectionEnd Section "Modules" SEC04 SetOutPath "$INSTDIR\modules" File "..\bin\${BUILD}\modules\m_*.so" + ; Copy DLLs required for modules + SetOutPath "$INSTDIR" + File /nonfatal "*.dll" + File "make_gnutls_cert.bat" SectionEnd Section -AdditionalIcons @@ -216,9 +224,13 @@ Section Uninstall Delete "$INSTDIR\uninst.exe" Delete "$INSTDIR\modules\*.so" Delete "$INSTDIR\conf\*.example" + Delete "$INSTDIR\conf\aliases\*.example" + Delete "$INSTDIR\conf\modules\*.example" Delete "$INSTDIR\*.log" Delete "$INSTDIR\logs\*" Delete "$INSTDIR\data\*" + Delete "$INSTDIR\*.dll" + Delete "$INSTDIR\make_gnutls_cert.bat" Delete "$INSTDIR\inspircd.exe" Delete "$SMPROGRAMS\InspIRCd\Uninstall.lnk" Delete "$SMPROGRAMS\InspIRCd\InspIRCd Website.lnk" diff --git a/win/inspircd.vcxproj b/win/inspircd.vcxproj index e77a918a0..03bacaad3 100644 --- a/win/inspircd.vcxproj +++ b/win/inspircd.vcxproj @@ -268,7 +268,6 @@ nmake -f modules.mak <ItemGroup> <ClCompile Include="..\src\bancache.cpp" /> <ClCompile Include="..\src\base.cpp" /> - <ClCompile Include="..\src\channelmanager.cpp" /> <ClCompile Include="..\src\channels.cpp" /> <ClCompile Include="..\src\cidr.cpp" /> <ClCompile Include="..\src\commands.cpp" /> @@ -335,7 +334,6 @@ nmake -f modules.mak <ClInclude Include="..\include\bancache.h" /> <ClInclude Include="..\include\base.h" /> <ClInclude Include="..\include\caller.h" /> - <ClInclude Include="..\include\channelmanager.h" /> <ClInclude Include="..\include\channels.h" /> <ClInclude Include="..\include\command_parse.h" /> <ClInclude Include="..\include\configreader.h" /> diff --git a/win/inspircd_win32wrapper.h b/win/inspircd_win32wrapper.h index 85572fd64..bc7165262 100644 --- a/win/inspircd_win32wrapper.h +++ b/win/inspircd_win32wrapper.h @@ -231,7 +231,6 @@ CoreExport int clock_gettime(int clock, struct timespec * tv); typedef unsigned char uint8_t; typedef unsigned long long uint64_t; typedef signed char int8_t; -typedef signed long int32_t; typedef signed long long int64_t; typedef signed long ssize_t; diff --git a/win/make_gnutls_cert.bat b/win/make_gnutls_cert.bat new file mode 100644 index 000000000..97792cc29 --- /dev/null +++ b/win/make_gnutls_cert.bat @@ -0,0 +1,14 @@ +@echo off
+
+echo This program will generate SSL certificates for m_ssl_gnutls.so
+echo Ensure certtool.exe is in your system path. It can be downloaded
+echo at ftp://ftp.gnu.org/gnu/gnutls/w32/. If you do not know the answer
+echo to one of the questions just press enter.
+echo.
+
+pause
+
+certtool --generate-privkey --outfile conf/key.pem
+certtool --generate-self-signed --load-privkey conf/key.pem --outfile conf/cert.pem
+
+pause
\ No newline at end of file |