]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - include/inspircd.h
Make error reporting work properly, it seemed to loose errors.
[user/henk/code/inspircd.git] / include / inspircd.h
index f0f5a1d1fc54ab888759f3c845bcec893d8cbd26..d9918aa737087fd0b466d47e99936c59bcc6f544 100644 (file)
@@ -2,14 +2,11 @@
  *       | Inspire Internet Relay Chat Daemon |
  *       +------------------------------------+
  *
- *  InspIRCd is copyright (C) 2002-2006 ChatSpike-Dev.
- *                    E-mail:
- *             <brain@chatspike.net>
- *               <Craig@chatspike.net>
- *     
- * Written by Craig Edwards, Craig McLure, and others.
+ *  InspIRCd: (C) 2002-2007 InspIRCd Development Team
+ * See: http://www.inspircd.org/wiki/index.php/Credits
+ *
  * This program is free but copyrighted software; see
- *         the file COPYING for details.
+ *            the file COPYING for details.
  *
  * ---------------------------------------------------
  */
 #include "socketengine.h"
 #include "command_parse.h"
 #include "snomasks.h"
+#include "cull_list.h"
 
-/** Returned by some functions to indicate failure,
- * and the exit code of the program if it terminates.
+/** Returned by some functions to indicate failure.
  */
 #define ERROR -1
 
-/** Crucial defines
+/** Support for librodent -
+ * see http://www.chatspike.net/index.php?z=64
  */
-#define ETIREDGERBILS EAGAIN
+#define ETIREDHAMSTERS EAGAIN
 
 /** Debug levels for use with InspIRCd::Log()
  */
@@ -50,7 +48,7 @@ enum DebugLevel
 };
 
 /**
- * This define is used in place of strcmp when we 
+ * This define is used in place of strcmp when we
  * want to check if a char* string contains only one
  * letter. Pretty fast, its just two compares and an
  * addition.
@@ -65,15 +63,89 @@ template<typename T> inline void DELETE(T* x)
        x = NULL;
 }
 
-/** Template function to convert any input type to std::string
+/** Template functions to convert any input type to std::string
  */
-template<typename T> inline std::string ConvToStr(const T &in)
+template<typename T> inline std::string ConvNumeric(const T &in)
+{
+       if (in == 0) return "0";
+       char res[MAXBUF];
+       char* out = res;
+       T quotient = in;
+       while (quotient) {
+               *out = "0123456789"[ std::abs( (long)quotient % 10 ) ];
+               ++out;
+               quotient /= 10;
+       }
+       if ( in < 0)
+               *out++ = '-';
+       *out = 0;
+       std::reverse(res,out);
+       return res;
+}
+
+inline std::string ConvToStr(const int in)
+{
+       return ConvNumeric(in);
+}
+
+inline std::string ConvToStr(const long in)
+{
+       return ConvNumeric(in);
+}
+
+inline std::string ConvToStr(const unsigned long in)
+{
+       return ConvNumeric(in);
+}
+
+inline std::string ConvToStr(const char* in)
+{
+       return in;
+}
+
+inline std::string ConvToStr(const bool in)
+{
+       return (in ? "1" : "0");
+}
+
+inline std::string ConvToStr(char in)
+{
+       return std::string(in,1);
+}
+
+template <class T> inline std::string ConvToStr(const T &in)
 {
        std::stringstream tmp;
        if (!(tmp << in)) return std::string();
        return tmp.str();
 }
 
+template<typename T> inline long ConvToInt(const T &in)
+{
+       std::stringstream tmp;
+       if (!(tmp << in)) return 0;
+       return atoi(tmp.str().c_str());
+}
+
+/** Template function to convert integer to char, storing result in *res and
+ * also returning the pointer to res. Based on Stuart Lowe's C/C++ Pages.
+ */
+template<typename T, typename V, typename R> inline char* itoa(const T &in, V *res, R base)
+{
+       if (base < 2 || base > 16) { *res = 0; return res; }
+       char* out = res;
+       int quotient = in;
+       while (quotient) {
+               *out = "0123456789abcdef"[ std::abs( quotient % base ) ];
+               ++out;
+               quotient /= base;
+       }
+       if ( in < 0 && base == 10) *out++ = '-';
+       std::reverse( res, out );
+       *out = 0;
+       return res;
+}
+
 /** This class contains various STATS counters
  * It is used by the InspIRCd class, which internally
  * has an instance of it.
@@ -119,6 +191,14 @@ class serverstats : public classbase
         */
        unsigned long BoundPortCount;
 
+       /** Cpu usage at last sample
+        */
+       timeval LastCPU;
+
+       /** Time last sample was read
+        */
+       timeval LastSampled;
+
        /** The constructor initializes all the counts to zero
         */
        serverstats()
@@ -193,6 +273,9 @@ class FileLogger : public EventHandler
 /** A list of failed port bindings, used for informational purposes on startup */
 typedef std::vector<std::pair<std::string, long> > FailedPortList;
 
+/** A list of ip addresses cross referenced against clone counts */
+typedef std::map<irc::string, unsigned int> clonemap;
+
 class XLineManager;
 
 /** The main class of the irc server.
@@ -214,7 +297,7 @@ class InspIRCd : public classbase
        /** Holds a string describing the last module error to occur
         */
        char MODERR[MAXBUF];
+
        /** Remove a ModuleFactory pointer
         * @param j Index number of the ModuleFactory to remove
         */
@@ -225,10 +308,6 @@ class InspIRCd : public classbase
         */
        void EraseModule(int j);
 
-       /** Build the ISUPPORT string by triggering all modules On005Numeric events
-        */
-       void BuildISupport();
-
        /** Move a given module to a specific slot in the list
         * @param modulename The module name to relocate
         * @param slot The slot to move the module into
@@ -298,6 +377,10 @@ class InspIRCd : public classbase
         */
        featurelist Features;
 
+       /** The interface names published by various modules
+        */
+       interfacelist Interfaces;
+
        /** The current time, updated in the mainloop
         */
        time_t TIME;
@@ -348,6 +431,18 @@ class InspIRCd : public classbase
        int time_delta;
 
  public:
+
+       std::map<InspSocket*,InspSocket*> SocketCull;
+
+       /** Build the ISUPPORT string by triggering all modules On005Numeric events
+        */
+       void BuildISupport();
+
+       /** Number of unregistered users online right now.
+        * (Unregistered means before USER/NICK/dns)
+        */
+       int unregistered_count;
+
         /** List of server names we've seen.
         */
        servernamelist servernames;
@@ -356,6 +451,10 @@ class InspIRCd : public classbase
         */
        time_t startup_time;
 
+       /** Config file pathname specified on the commandline or via ./configure
+        */
+       char ConfigFileName[MAXBUF];
+
        /** Mode handler, handles mode setting and removal
         */
        ModeParser* Modes;
@@ -383,11 +482,11 @@ class InspIRCd : public classbase
 
        /** Client list, a hash_map containing all clients, local and remote
         */
-       user_hash clientlist;
+       user_hash* clientlist;
 
        /** Channel list, a hash_map containing all channels
         */
-       chan_hash chanlist;
+       chan_hash* chanlist;
 
        /** Local client list, a vector containing only local clients
         */
@@ -397,13 +496,9 @@ class InspIRCd : public classbase
         */
        std::vector<userrec*> all_opers;
 
-       /** Whowas container, contains a map of vectors of users tracked by WHOWAS
-        */
-       irc::whowas::whowas_users whowas;
+       clonemap local_clones;
 
-       /** Whowas container, contains a map of time_t to users tracked by WHOWAS
-        */
-       irc::whowas::whowas_users_fifo whowas_fifo;
+       clonemap global_clones;
 
        /** DNS class, provides resolver facilities to the core and modules
         */
@@ -433,6 +528,10 @@ class InspIRCd : public classbase
         */
        time_t next_call;
 
+       /** Global cull list, will be processed on next iteration
+        */
+       CullList GlobalCulls;
+
        /** Get the current time
         * Because this only calls time() once every time around the mainloop,
         * it is much faster than calling time() directly.
@@ -449,6 +548,14 @@ class InspIRCd : public classbase
         */
        int SetTimeDelta(int delta);
 
+       void AddLocalClone(userrec* user);
+
+       void AddGlobalClone(userrec* user);
+
+       /** Number of users with a certain mode set on them
+        */
+       int ModeCount(const char mode);
+
        /** Get the time offset in seconds
         * @return The current time delta (in seconds)
         */
@@ -488,13 +595,11 @@ class InspIRCd : public classbase
 
        /** Binds a socket on an already open file descriptor
         * @param sockfd A valid file descriptor of an open socket
-        * @param client A sockaddr to use as temporary storage
-        * @param server A sockaddr to use as temporary storage
         * @param port The port number to bind to
         * @param addr The address to bind to (IP only)
         * @return True if the port was bound successfully
         */
-       bool BindSocket(int sockfd, insp_sockaddr client, insp_sockaddr server, int port, char* addr);
+       bool BindSocket(int sockfd, int port, char* addr, bool dolisten = true);
 
        /** Adds a server name to the list of servers we've seen
         * @param The servername to add
@@ -533,7 +638,7 @@ class InspIRCd : public classbase
         * @param text The text to send
         */
        void WriteOpers(const std::string &text);
-       
+
        /** Find a nickname in the nick hash
         * @param nick The nickname to find
         * @return A pointer to the user, or NULL if the user does not exist
@@ -578,6 +683,8 @@ class InspIRCd : public classbase
         */
        void OpenLog(char** argv, int argc);
 
+       void CloseLog();
+
        /** Convert a user to a pseudoclient, disconnecting the real user
         * @param user The user to convert
         * @param message The quit message to display when exiting the user
@@ -607,7 +714,7 @@ class InspIRCd : public classbase
 
        /** Send text to all users with a specific set of modes
         * @param modes The modes to check against, without a +, e.g. 'og'
-        * @param flags one of WM_OR or WM_AND. If you specify WM_OR, any one of the 
+        * @param flags one of WM_OR or WM_AND. If you specify WM_OR, any one of the
         * mode characters in the first parameter causes receipt of the message, and
         * if you specify WM_OR, all the modes must be present.
         * @param text The text format string to send
@@ -626,11 +733,19 @@ class InspIRCd : public classbase
         */
        static void Rehash(int status);
 
-       /** Causes the server to exit immediately
+       /** Causes the server to exit after unloading modules and
+        * closing all open file descriptors.
+        *
         * @param The exit code to give to the operating system
+        * (See the ExitStatus enum for valid values)
         */
        static void Exit(int status);
 
+       /** Causes the server to exit immediately with exit code 0.
+        * The status code is required for signal handlers, and ignored.
+        */
+       static void QuickExit(int status);
+
        /** Return a count of users, unknown and known connections
         * @return The number of users
         */
@@ -669,7 +784,7 @@ class InspIRCd : public classbase
        /** Send an error notice to all local users, opered and unopered
         * @param s The error string to send
         */
-       void SendError(const char *s);
+       void SendError(const std::string &s);
 
        /** For use with Module::Prioritize().
         * When the return value of this function is returned from
@@ -707,6 +822,47 @@ class InspIRCd : public classbase
         */
        bool PublishFeature(const std::string &FeatureName, Module* Mod);
 
+       /** Publish a module to an 'interface'.
+        * Modules which implement the same interface (the same way of communicating
+        * with other modules) can publish themselves to an interface, using this
+        * method. When they do so, they become part of a list of related or
+        * compatible modules, and a third module may then query for that list
+        * and know that all modules within that list offer the same API.
+        * A prime example of this is the hashing modules, which all accept the
+        * same types of Request class. Consider this to be similar to PublishFeature,
+        * except for that multiple modules may publish the same 'feature'.
+        * @param InterfaceName The case sensitive interface name to make available
+        * @param Mod a pointer to your module class
+        * @returns True on success, false on failure (there are currently no failure
+        * cases)
+        */
+       bool PublishInterface(const std::string &InterfaceName, Module* Mod);
+
+       /** Return a pair saying how many other modules are currently using the
+        * interfaces provided by module m.
+        * @param m The module to count usage for
+        * @return A pair, where the first value is the number of uses of the interface,
+        * and the second value is the interface name being used.
+        */
+       std::pair<int,std::string> GetInterfaceInstanceCount(Module* m);
+
+       /** Mark your module as using an interface.
+        * If you mark your module as using an interface, then that interface
+        * module may not unload until your module has unloaded first.
+        * This can be used to prevent crashes by ensuring code you depend on
+        * is always in memory while your module is active.
+        * @param InterfaceName The interface to use
+        */
+       void UseInterface(const std::string &InterfaceName);
+
+       /** Mark your module as finished with an interface.
+        * If you used UseInterface() above, you should use this method when
+        * your module is finished with the interface (usually in its destructor)
+        * to allow the modules which implement the given interface to be unloaded.
+        * @param InterfaceName The interface you are finished with using.
+        */
+       void DoneWithInterface(const std::string &InterfaceName);
+
        /** Unpublish a 'feature'.
         * When your module exits, it must call this method for every feature it
         * is providing so that the feature table is cleaned up.
@@ -714,6 +870,16 @@ class InspIRCd : public classbase
         */
        bool UnpublishFeature(const std::string &FeatureName);
 
+       /** Unpublish your module from an interface
+        * When your module exits, it must call this method for every interface
+        * it is part of so that the interfaces table is cleaned up. Only when
+        * the last item is deleted from an interface does the interface get
+        * removed.
+        * @param InterfaceName the interface to be removed from
+        * @param Mod The module to remove from the interface list
+        */
+       bool UnpublishInterface(const std::string &InterfaceName, Module* Mod);
+
        /** Find a 'feature'.
         * There are two ways for a module to find another module it depends on.
         * Either by name, using InspIRCd::FindModule, or by feature, using the
@@ -728,6 +894,15 @@ class InspIRCd : public classbase
         */
        Module* FindFeature(const std::string &FeatureName);
 
+       /** Find an 'interface'.
+        * An interface is a list of modules which all implement the same API.
+        * @param InterfaceName The Interface you wish to obtain the module
+        * list of.
+        * @return A pointer to a deque of Module*, or NULL if the interface
+        * does not exist.
+        */
+       modulelist* FindInterface(const std::string &InterfaceName);
+
        /** Given a pointer to a Module, return its filename
         * @param m The module pointer to identify
         * @return The module name or an empty string
@@ -774,9 +949,21 @@ class InspIRCd : public classbase
 
        /** Add a dns Resolver class to this server's active set
         * @param r The resolver to add
-        * @return True if the resolver was added
-        */
-        bool AddResolver(Resolver* r);
+        * @param cached If this value is true, then the cache will
+        * be searched for the DNS result, immediately. If the value is
+        * false, then a request will be sent to the nameserver, and the
+        * result will not be immediately available. You should usually
+        * use the boolean value which you passed to the Resolver
+        * constructor, which Resolver will set appropriately depending
+        * on if cached results are available and haven't expired. It is
+        * however safe to force this value to false, forcing a remote DNS
+        * lookup, but not an update of the cache.
+        * @return True if the operation completed successfully. Note that
+        * if this method returns true, you should not attempt to access
+        * the resolver class you pass it after this call, as depending upon
+        * the request given, the object may be deleted!
+        */
+        bool AddResolver(Resolver* r, bool cached);
 
        /** Add a command to this server's command parser
         * @param f A command_t command handler object to add
@@ -890,7 +1077,7 @@ class InspIRCd : public classbase
         bool DelELine(const std::string &hostmask);
 
        /** Return true if the given parameter is a valid nick!user\@host mask
-        * @param mask A nick!user\@host masak to match against 
+        * @param mask A nick!user\@host masak to match against
         * @return True i the mask is valid
         */
         bool IsValidMask(const std::string &mask);
@@ -957,6 +1144,11 @@ class InspIRCd : public classbase
         */
        bool ULine(const char* server);
 
+       /** Returns true if the uline is 'silent' (doesnt generate
+        * remote connect notices etc).
+        */
+       bool SilentULine(const char* server);
+
        /** Returns the subversion revision ID of this ircd
         * @return The revision ID or an empty string
         */
@@ -1026,6 +1218,35 @@ class InspIRCd : public classbase
 
        void SendWhoisLine(userrec* user, userrec* dest, int numeric, const char* format, ...);
 
+       /** Restart the server.
+        * This function will not return. If an error occurs,
+        * it will throw an instance of CoreException.
+        * @param reason The restart reason to show to all clients
+        * @throw CoreException An instance of CoreException indicating the error from execv().
+        */
+       void Restart(const std::string &reason);
+
+       /** Prepare the ircd for restart or shutdown.
+        * This function unloads all modules which can be unloaded,
+        * closes all open sockets, and closes the logfile.
+        */
+       void Cleanup();
+
+       /** This copies the user and channel hash_maps into new hash maps.
+        * This frees memory used by the hash_map allocator (which it neglects
+        * to free, most of the time, using tons of ram)
+        */
+       void RehashUsersAndChans();
+
+       /** Resets the cached max bans value on all channels.
+        * Called by rehash.
+        */
+       void ResetMaxBans();
+
+       /** Return a time_t as a human-readable string.
+        */
+       std::string TimeString(time_t curtime);
+
        /** Begin execution of the server.
         * NOTE: this function NEVER returns. Internally,
         * after performing some initialisation routines,