/** * server.h * This is the header file for the server itself. * This class originally created by Orlando Bassotto. * * This program 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; either version 2 * of the License, or (at your option) any later version. * * 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, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. * * $Id: server.h,v 1.107 2010/08/31 21:16:45 denspike Exp $ */ #ifndef __SERVER_H #define __SERVER_H "$Id: server.h,v 1.107 2010/08/31 21:16:45 denspike Exp $" #include #include #include #include #include #include #include #include #include #include "NetworkTarget.h" #include "iServer.h" #include "iClient.h" #include "Buffer.h" #include "events.h" #include "Gline.h" #include "misc.h" #include "moduleLoader.h" #include "TimerHandler.h" #include "ServerCommandHandler.h" #include "ConnectionManager.h" #include "ConnectionHandler.h" #include "Connection.h" namespace gnuworld { /// Forward declaration of xClient class xClient ; /// Forward declaration of Channel class Channel ; /** * This class is the server proper; it is responsible for the connection * to the IRC network, and for maintaining the services clients. */ class xServer : public ConnectionManager, public ConnectionHandler, public NetworkTarget { protected: /** * The type of the structure to hold Gline's internally. */ typedef std::map< std::string, Gline*, noCaseCompare > glineListType ; public: /** * The xServer constructor. It takes the arguments * from the command line. */ xServer( int, char** ) ; /** * Destroy the server and its clients, disconnect * from network. */ virtual ~xServer() ; /** * The actual run method. This method is invoked by main(), * and contains the xServer's main loop. */ void run() ; /** * This type is used for passing information to handler * methods for channel op mode changes. */ typedef std::vector< std::pair< bool, ChannelUser* > > opVectorType ; /** * This type is used for passing information to handler * methods for channel voice mode changes. */ typedef opVectorType voiceVectorType ; /** * This type is used for passing information to handler * methods for channel ban changes. */ typedef std::vector< std::pair< bool, std::string > > banVectorType ; /** * This type is used for passing multiple argument-less modes * to handler methods of simple channel modes. */ typedef std::vector< std::pair< bool, Channel::modeType > > modeVectorType ; /** * The iterator type used to iterate through the * structure of glines. */ typedef glineListType::iterator glineIterator ; /** * The const iterator type used to iterate through the * structure of glines. */ typedef glineListType::const_iterator const_glineIterator ; /** * Return a const iterator to the beginning of the gline * structure. */ inline const_glineIterator glines_begin() const { return glineList.begin() ; } /** * Return a const iterator to the end of the gline * structure. */ inline const_glineIterator glines_end() const { return glineList.end() ; } /** * Return an iterator to the beginning of the gline structure. */ inline glineIterator glines_begin() { return glineList.begin() ; } /** * Return an iterator to the end of the gline structure. */ inline glineIterator glines_end() { return glineList.end() ; } /** * This method is called when a Connection is disconnected. * Inherited from ConnectionHandler. */ virtual void OnDisconnect( Connection* ) ; /** * This method is called when a Connection attempt succeeds. * Inherited from ConnectionHandler. */ virtual void OnConnect( Connection* ) ; /** * This method is called when a Connection attempt fails. * Inherited from ConnectionHandler. */ virtual void OnConnectFail( Connection* ) ; /** * This method is called when a line of data is read from * Connection. * Inherited from ConnectionHandler. */ virtual void OnRead( Connection*, const std::string& ) ; /** * Request that all data in the output buffer be flushed to * the network connection. This will possibly block the * the server in the network send, so be careful about using * it. * The flush request is valid only for the next call to * the main process loop, it is reset after that. */ virtual void FlushData() ; /** * Attach a fake server to this services server. * Use this method to jupe a server, just set the iServer's * JUPE flag. */ virtual bool AttachServer( iServer*, xClient* ) ; /** * Detach a fake server from the services server. */ virtual bool DetachServer( iServer* ) ; /** * Squit a server from the network and remove it * from the network tables. */ virtual bool SquitServer( const std::string& name, const std::string& reason ) ; /** * Append a std::string to the output buffer. * The second argument determines if data should be written * during burst time. */ virtual bool Write( const std::string& ) ; /** * Similar to the above signature of Write() except that data * will be written to the normal output buffer even during * burst time. */ virtual bool WriteDuringBurst( const std::string& ) ; /** * Append a C variable argument list/character array to the output * buffer. * Since this method uses a variable argument list, this * method cannot support a final default argument -- this method * defaults to NOT writing during burst. */ virtual bool Write( const char*, ... ) ; /** * This method is similar to the above Write(), except * that the data will be written to the normal output * buffer even during burst time. */ virtual bool WriteDuringBurst( const char*, ... ) ; /** * Append a std::stringstream to the output buffer. * The second argument determines if data should be written * during burst time. */ virtual bool Write( const std::stringstream& ) ; /** * This method is similar to the above Write(), except * that the data will be written to the normal output * buffer even during burst time. */ virtual bool WriteDuringBurst( const std::stringstream& ) ; /** * Process is responsible for parsing lines of data. */ virtual void Process( char* String ) ; /** * Add a network gline and update glines table. */ virtual bool setGline( const std::string& setBy, const std::string& userHost, const std::string& reason, const time_t& duration, const time_t& lastmod = ::time(0), const xClient* setClient = NULL, const std::string& server = "*") ; /** * Remove a network gline and update internal gline table. */ virtual bool removeGline( const std::string& userHost, const xClient* remClient = NULL) ; /** * Erase a gline from the internal data structures. This does * NOT send a message to the network; for that functionality, * use RemoveGline() instead. * The caller of this method must also be sure to deallocate * the internal Gline associated with the iterator. */ virtual void eraseGline( glineIterator removeMe ) { glineList.erase( removeMe ) ; } /** * Add a gline to the internal data structures. This does * NOT send a message to the network; for that functionality, * use SetGline() instead. */ virtual void addGline( Gline* newGline ) ; /** * Find a gline by lexical searching, case insensitive. */ virtual const Gline* findGline( const std::string& userHost ) const ; /** * Find a gline by userHost (exact match only), and return * an interator to that gline. */ virtual glineIterator findGlineIterator( const std::string& userHost ) ; /** * Find one or more glines matching a given userHost string. */ virtual std::vector< const Gline* > matchGline( const std::string& userHost ) const ; /** * Send all glines to the network. */ virtual void sendGlinesToNetwork() ; /* Client stuff */ /** * Attach a fake client to a this or a fake (juped) server. * The server must exist and must already be attached * to this server. Otherwise, if attaching to the current * server, it already exists :) * All integrity of the iClient will be verified: non-empty * nick/user/hostname, etc. Also, if the nickname * is already in use on the network, then false will be * returned. * The client's intXXX/charXXX will be set by this method. * The xClient* is the owner to whom messages will be sent. */ virtual bool AttachClient( iClient* Client, xClient* ) ; /** * Quit a hosted client from the network with the given * quit message. */ virtual bool DetachClient( iClient*, const std::string& = std::string( "Exiting, moo" ) ) ; /** * Attempt to load a client given its client module name. */ virtual void LoadClient( const std::string& moduleName, const std::string& configFileName ) ; /** * Attempt to unload a client given its module name. * Be sure that you have the proper fully qualified * moduleName. If uncertain, use the other form of * the UnloadClient() method. */ virtual void UnloadClient( const std::string& moduleName, const std::string& reason ) ; /** * Attempt to unload a client given its pointer. */ virtual void UnloadClient( xClient*, const std::string& reason ) ; /** * Attach a client to the server. This will add the client * to the internal table, and call the client's ImplementServer() * method. * Clients must *not* call this method, use LoadClient() * instead. */ virtual bool AttachClient( xClient* Client, bool doBurst = false ) ; /** * Attach a client to the server. This will add the client * to the internal table, and call the client's ImplementServer() * method. * Locate the client by its module name. * Clients must *not* call this method, use LoadClient() * instead. */ virtual bool AttachClient( const std::string& moduleName, const std::string& configFileName, bool doBurst = false ) ; /** * Detach a client from the server. This will call the * client's Exit() method and remove the client from the * internal tables. * Clients must *not* call this method, use UnloadClient() * instead. */ virtual bool DetachClient( const std::string& moduleName, const std::string& reason ) ; /** * Detach a client from the server. This will call the * client's Exit() method and remove the client from the * internal tables. * Clients must *not* call this method, use UnloadClient() * instead. */ virtual bool DetachClient( xClient* Client, const std::string& reason ) ; /** * Output the information for a channel, and make the given * xClient operator in that channel. * This works at all times, bursting or not. */ virtual bool JoinChannel( xClient*, const std::string& chanName, const std::string& chanModes = "+tn", const time_t& joinTime = 0, bool getOps = true ) ; /** * Similar to JoinChannel, except that the server will just * burst the channel, without joining a client. * - The channel must already exist * - The burst time must be older than the existing channel's * creation time. All modes will be removed from the channel * without generating any events. * - chanModes cannot contain any '-' polarity modes. */ virtual bool BurstChannel( const std::string& chanName, const std::string& chanModes, const time_t& burstTime ) ; /** * Have a fake (only) client join a channel. * This will NOT create the channel if it does not already exist. */ virtual bool JoinChannel( iClient*, const std::string& chanName ) ; /** * Notify the network that one of the services clients has * parted a channel. */ virtual void PartChannel( xClient* theClient, const std::string& chanName, const std::string& reason = std::string() ) ; /** * Notify the network that a fake client has parted a channel. */ virtual void PartChannel( iClient* theClient, const std::string& chanName, const std::string& reason = std::string() ) ; /** * Notify the network that one of the services clients has * parted a channel. */ virtual void PartChannel( xClient* theClient, Channel* theChan, const std::string& reason = std::string() ) ; /** * Handle the parting of a services client from a channel. This * method updates internal tables. */ virtual void OnPartChannel( xClient* theClient, const std::string& chanName ) ; /** * Handle the parting of a services client from a channel. This * method updates internal tables. */ virtual void OnPartChannel( xClient* theClient, Channel* theChan ) ; /** * Handle the parting of a network client from a channel. This method * updates internal tables. */ virtual void OnPartChannel( iClient* theClient, const std::string& chanName ) ; /** * Handle the parting of a network client from a channel. This method * updates internal tables. */ virtual void OnPartChannel( iClient* theClient, Channel* theChan ) ; /** * OnXQuery is called when an XQ command * is received. */ virtual void OnXQuery( iServer* Sender, const std::string& Token, const std::string& Message ) ; /** * OnXReply is called when an XR command * is received. */ virtual void OnXReply( iServer* Sender, const std::string& Token, const std::string& Message ) ; /** * Output the information about an xClient to the network. * (localClient) is true when the xClient is to appear to * reside on this xServer, false when it is to reside on * a juped/fake server. */ virtual void BurstClient( xClient* ) ; /** * Burst a (fake) client to the network. */ virtual void BurstClient( iClient* ) ; /** * Burst a (fake) server to the network. */ virtual void BurstServer( iServer* ) ; /** * Send a wallops to the network as the server. */ virtual int Wallops( const std::string& ) ; /** * Sent a notice to a client as the server. */ virtual bool Notice( iClient*, const std::string& ) ; /** * Sending XQuery and XReply as a server to a server. */ virtual bool XQuery( iServer*, const std::string&, const std::string& ) ; virtual bool XReply( iServer*, const std::string&, const std::string& ) ; /** * Set modes as the server, update internal tables, and notify * all clients of the mode change(s). * The first argument is the xClient requesting the mode * change(s). If this argument is NULL, then the modes are * set as the server, otherwise the modes are set as the * client. * Note that this method is used by xClient::Mode(), but the * argument semantics are a bit different because of the addition * of the xClient*. */ virtual bool Mode( xClient*, Channel*, const std::string& modes, const std::string& args ) ; /* Event registration stuff */ /** * RegisterEvent is called by xClient's wishing * to receive a particular event. * When a particular event occurs, the server will call * OnEvent for each xClient registered to receive that * event. */ virtual bool RegisterEvent( const eventType&, xClient* ) ; /** * Halt delivery of the given event to the given xClient. */ virtual bool UnRegisterEvent( const eventType&, xClient* ) ; /** * The channel event distribution system is rather * expensive...such is the nature of IRC. * Each channel name is converted to lower case. * When a channel event occurs, the server will call * each OnChannelEvent() with the event type * and channel name for each xClient registered for * that pair. */ virtual bool RegisterChannelEvent( const std::string&, xClient* ) ; /** * Halt delivery of any channel event for the particular channel * to the particular xClient. */ virtual bool UnRegisterChannelEvent( const std::string&, xClient* ) ; /** * The type used to represent client timer events. */ typedef TimerHandler::timerID timerID ; /** * Register for a timer event. The first argument is the * absolute time at which the timed event is to occur. * The second argument is a pointer to an argument to be * passed to the timer handler. * Returns 0 on failure, a valid timerID otherwise. */ virtual timerID RegisterTimer( const time_t& absoluteTime, TimerHandler* theHandler, void* data = 0 ) ; /** * Remove a timed event from the timer system. * If data is non-NULL, the timer argument passed to * RegisterTimer() will be returned through data. * Return true if successful, false otherwise. */ virtual bool UnRegisterTimer( const timerID&, void* data ) ; /** * This method is called by the xClient's to notify the network * that an iClient has logged into that particular service. * The iClient's internal state will be updated to reflect this * login, and the message will be sent to the network. * The third argument (the source xClient) is the xClient issuing * the login event. If this argument is NULL, then all xClients * will receive the EVT_ACCOUNT event. If the argument is non-NULL, * then all but the sourceClient will receive the event. */ virtual void UserLogin( iClient*, const std::string&, xClient* = 0 ) ; /** * Send out the 'FA' fake host handler to the network */ virtual void SendOutFakeHost( iClient*, const std::string&, xClient* = 0 ) ; /** * Post a system event to the rest of the system. Note * that this method is public, so xClients may post * events. * The last argument is the an exclude xClient -- the * event will NOT be sent to that client (in the case that * an xClient calls PostEvent(), it may not want to receive * that event back). */ virtual void PostEvent( const eventType&, void* = 0, void* = 0, void* = 0, void* = 0 , const xClient* ourClient = 0) ; /** * Post a channel event to the rest of the system. Note * that this method is public, so xClients may post * channel events. */ virtual void PostChannelEvent( const channelEventType&, Channel* theChan, void* = 0, void* = 0, void* = 0, void* = 0 ) ; /** * This method is called when a kick occurs on a channel * for which this client is registered to receive events. * The srcClient may be NULL, as the ircu protocol still * allows servers to issue KICK commands. * The authoritative variable is true if the kick * transaction is complete, false otherwise. If it is false, * then the destClient is still on the channel pending * a PART from its server, and it is in the ZOMBIE state. */ virtual void PostChannelKick( Channel* theChan, iClient* srcClient, // may be NULL iClient* destClient, const std::string& kickMessage, bool authoritative ) ; /** * This variable represents "all channels." Clients may * register for events of this channel, and each will receive * this event for every channel in existence on the network. */ static const std::string CHANNEL_ALL ; /** * Post a signal to the server and all clients. * Returns true if the signal was handled, false * otherwise. */ virtual bool PostSignal( int ) ; /* Utility methods */ /** * Return true if no BURST state exists, false otherwise. */ virtual bool IsEndOfBurst() const { return !bursting ; } /** * Return true if this server is currently bursting, false * otherwise. */ inline bool isBursting() const { return bursting ; } /** * Return true if there is one more iteration of the main * processing loop to be performed before shutting down. */ inline bool isLastLoop() const { return lastLoop ; } /** * Return true if an EA will be sent after the EB. * Some modules may want the "endless" burst effect. * Default value is true. */ inline bool getSendEA() const { return sendEA ; } /** * Invoke this method with the value 'true' if you want * the EA token to be sent. Setting to * false will create the endless burst effect, and bursting * will always be true. * Default value is true. * Only modify this variable if you know what youre doing. */ inline void setSendEA( bool newVal = true ) { sendEA = newVal ; } /** * Return true if an EB will be sent after the EB. * Some modules may want the "endless" burst effect. * Default value is true. */ inline bool getSendEB() const { return sendEB ; } /** * Invoke this method with the value 'true' if you want * the EB token to be sent. Setting to * false will create the endless burst effect, and bursting * will always be true. * Default value is true. * Only modify this variable if you know what youre doing. */ inline void setSendEB( bool newVal = true ) { sendEB = newVal ; } /** * Set the bursting value to the given argument, with default * argument set to true. * This method should NOT be called by anything other than the * server command handlers. */ virtual void setBursting( bool newVal = true ) ; /** * Return true if the server has a valid connection to * its uplink, false otherwise. */ virtual bool isConnected() const { return (serverConnection != 0) ; } /** * Return true if verbosity is enabled. */ virtual bool isVerbose() const { return verbose ; } /** * Return true if the server is to auto reconnect on * connection termination, false otherwise. */ virtual bool getAutoConnect() const { return autoConnect ; } /* Numeric utility methods */ /** * Return an unsigned int representation of this server's uplink's * server numeric. */ inline unsigned int getUplinkIntYY() const { return Uplink->getIntYY() ; } /** * Return a string representation of this server's uplink's * server numeric. */ inline const std::string getUplinkCharYY() const { return Uplink->getCharYY() ; } /* General server utility methods */ /** * Return this server's name, as the network sees it. */ inline const std::string& getName() const { return ServerName ; } /** * Return a description of this server. */ inline const std::string& getDescription() const { return ServerDescription ; } /** * Return this server's uplink password. */ inline const std::string& getPassword() const { return Password ; } /** * Return the time at which this server was instantiated. */ inline const time_t& getStartTime() const { return StartTime ; } /** * Return the time this server last connected to its uplink. */ inline const time_t& getConnectionTime() const { return ConnectionTime ; } /** * Return a pointer to this server's uplink. */ inline iServer* getUplink() const { return Uplink ; } /** * Return a pointer to this server's iServer representation. */ inline iServer* getMe() const { return me ; } /** * Set this server's uplink. * This method should ONLY be called by the server command * handlers. */ inline void setUplink( iServer* newUplink ) { Uplink = newUplink ; } /** * Enable or disable the burstBuffer. * This method should ONLY be called by the server command * handlers. */ inline void setUseHoldBuffer( bool newVal ) { useHoldBuffer = newVal ; } /** * Set the time of the most recent end of burst. * This method should ONLY be called by the server command * handlers. */ inline void setBurstEnd( const time_t newVal ) { burstEnd = newVal ; } /** * Set the time of the most recent start of burst. * This method should ONLY be called by the server command * handlers. */ inline void setBurstStart( const time_t newVal ) { burstStart = newVal ; } /** * Transfer the burstHoldBuffer data to the outputBuffer. * This method should ONLY be called by the server command * handlers. */ virtual void WriteBurstBuffer() ; /** * Shutdown the server. */ virtual void Shutdown( const std::string& reason = std::string( "Server Shutdown" ) ) ; /** * Set the reason for the server shutdown, to be displayed in * the SQ message. */ inline void setShutDownReason( const std::string& newReason ) { shutDownReason = newReason ; } /** * Return the reason for the server shutdown. */ inline const std::string& getShutDownReason() const { return shutDownReason ; } /** * Output server statistics to the console (clog). */ virtual void dumpStats() ; /** * Execute any waiting client timers. * Return the number of timers executed. */ virtual unsigned int CheckTimers() ; /** * The main loop which runs the server. This contains * all of the server essential logic. */ void mainLoop() ; /** * This method is invoked when one or more channels modes * are set. Each mode does NOT have an argument. This * simplifies handling of simple modes such as t, i, n, etc. */ virtual void OnChannelMode( Channel*, ChannelUser*, const modeVectorType& ) ; /** * This method is called when a channel mode 'l' change is * detected. * Keep in mind that the source ChannelUser may be NULL * if the mode is being set/unset by a server. */ virtual void OnChannelModeL( Channel*, bool, ChannelUser*, unsigned int ) ; /** * This method is called when a channel mode 'k' change is * detected. * Keep in mind that the source ChannelUser may be NULL * if the mode is being set/unset by a server. */ virtual void OnChannelModeK( Channel*, bool, ChannelUser*, const std::string& ) ; /** * This method is called when a channel mode 'A' change is * detected. * Keep in mind that the source ChannelUser may be NULL * if the mode is being set/unset by a server. */ virtual void OnChannelModeA( Channel*, bool, ChannelUser*, const std::string& ) ; /** * This method is called when a channel mode 'U' change is * detected. * Keep in mind that the source ChannelUser may be NULL * if the mode is being set/unset by a server. */ virtual void OnChannelModeU( Channel*, bool, ChannelUser*, const std::string& ) ; /** * This method is called when one or more mode 'o' changes * are set/unset on a particular channel. * Keep in mind that the source ChannelUser may be NULL * if the mode is being set/unset by a server. */ virtual void OnChannelModeO( Channel*, ChannelUser*, const opVectorType& ) ; /** * This method is called when one or more mode 'h' changes * are set/unset on a particular channel. * Keep in mind that the source ChannelUser may be NULL * if the mode is being set/unset by a server. */ virtual void OnChannelModeH( Channel*, ChannelUser*, const opVectorType& ) ; /** * This method is called when one or more mode 'v' changes * are set/unset on a particular channel. * Keep in mind that the source ChannelUser may be NULL * if the mode is being set/unset by a server. */ virtual void OnChannelModeV( Channel*, ChannelUser*, const voiceVectorType& ) ; /** * This method is called when one or more mode 'b' changes * are set/unset on a particular channel. * Keep in mind that the source ChannelUser may be NULL * if the mode is being set/unset by a server. */ virtual void OnChannelModeB( Channel*, ChannelUser*, banVectorType& ) ; /** * Check the list of glines for any that are about to * expire. */ virtual void updateGlines() ; /** * Burst out information about all xClients on this server. */ virtual void BurstClients() ; /** * Output channel information for each client on this server. */ virtual void BurstChannels() ; /** * Output glines information for each client on this server. */ virtual void BurstGlines() ; /** * Return the length of time needed for the last burst. */ virtual time_t getLastBurstDuration() const { return (burstEnd - burstStart) ; } /** * Return the number of bytes since the beginning of the * last burst. */ virtual size_t getBurstBytes() const { return burstBytes ; } /** * Return the number of commands processed since the beginning * of the last burst. */ virtual size_t getBurstLines() const { return burstLines ; } /** * Return true if the given nickname corresponds to a * server control nickname. * Return false otherwise. */ virtual bool findControlNick( const std::string& ) const ; /** * Handle a control message. */ virtual void ControlCommand( iClient* srcClient, const std::string& message ) ; protected: /** * Allow only subclasses to call the default * constructor. */ xServer() {} /** * Disable copy constructor, this method is declared but * NOT defined. */ xServer( const xServer& ) ; /** * Disable assignment, this method is declared but NOT * defined. */ xServer operator=( const xServer& ) ; /** * This will remove all clients and clear the internal * tables nicely, and do all functions necessary * shutdown the server. */ virtual void doShutdown() ; /** * Remove glines which match the given userHost, post event. */ virtual void removeMatchingGlines( const std::string& ) ; /** * This method is responsible for updating the systems internal * data structures, and deallocating the given xClient when it * is being removed from the server. */ virtual void removeClient( xClient* ) ; /** * Remove all modes from a channel, used when bursting an * older timestamp into a channel. */ virtual void removeAllChanModes( Channel* ) ; /** * Returns true if the given mask uses the nick!user@host syntax. */ virtual bool banSyntax( const std::string& ) const ; /** * Read the config file. Return true if success, false * otherwise. */ virtual bool readConfigFile( const std::string& ) ; /** * Parses a config file and attempts to load all modules * specified therein. If any part of the process fails, * false is returned. Otherwise, true is returned. */ virtual bool loadClients( const std::string& ) ; /** * Signal handler for the server itself. * Returns true if the signal was handled. */ virtual bool OnSignal( int ) ; /** * Return true if the given AC username has access enough to * issue server control commands. */ virtual bool hasControlAccess( const std::string& ) const ; /** * The structure type holds information about client timed * events. */ struct timerInfo { /// Instantiate a new timerInfo structure. timerInfo( const timerID& _ID, const time_t& _absTime, TimerHandler* _theHandler, void* _data = 0 ) : ID( _ID ), absTime( _absTime ), theHandler( _theHandler ), data( _data ) {} /// The unique identifier of this timer timerID ID ; /// The absolute time at which the timer expires time_t absTime ; /// The handler for this timed event TimerHandler* theHandler ; /// The argument to pass to the handler void* data ; } ; /** * This structure is used as a comparator functor for * the timerQueue. */ struct timerGreater { inline bool operator()( const std::pair< time_t, timerInfo* >& lhs, const std::pair< time_t, timerInfo* >& rhs ) const { return lhs.first > rhs.first ; } } ; /** * Register the timers that the server uses. */ virtual void registerServerTimers() ; /** * Return a unique timerID. */ virtual timerID getUniqueTimerID() ; /** * Remove all timers registered by the given xClient. * Note that this does not attempt to deallocate any * heap space allocated to the argument. * Instead, that data is returned to the xClient in question * by calling its OnTimerDestroy() method. */ virtual void removeAllTimers( TimerHandler* ) ; /** * Bounds checker for events. */ inline bool validEvent( const eventType& theEvent ) const { return (theEvent >= 0 && theEvent < EVT_NOOP) ; } /** * The server's uplink to the network. */ Connection *serverConnection ; /** * The name of the server, as the network sees it. */ std::string ServerName ; /** * This server's description line. */ std::string ServerDescription ; /** * The password for our uplink server. */ std::string Password ; /** * The hostname/IP of our uplink */ std::string UplinkName ; /** * The type used to store the system event map. */ typedef std::vector< std::list< xClient* > > eventListType ; /** * This is the vector of lists of xClient pointers. * When clients register to receive an event, that xClient's * pointer is added to eventListType[ theEvent ]. * When an event of that type occurs, each xClient in the * list is called (OnEvent()). */ eventListType eventList ; /** * Type used to store the channel event map. */ typedef std::map< std::string, std::list< xClient* >*, noCaseCompare > channelEventMapType ; /** * The structure used to maintain xClient registrations for * channel events. */ channelEventMapType channelEventMap ; /** * This structure holds the current network glines. */ glineListType glineList ; /** * This is the time this xServer was instantiated. */ time_t StartTime ; /** * This is the time that we last connected to our uplink. */ time_t ConnectionTime ; /** * Time at which we began the last burst. */ time_t burstStart ; /** * Time at which we ended the last burst. */ time_t burstEnd ; /** * The timer interval for the glineUpdateTimer timer. */ time_t glineUpdateInterval ; /** * The timer interval for the PINGTimer timer. */ time_t pingUpdateInterval ; /** * This is the version of the xServer, pretty useless. */ long Version ; /** * This variable is true when this server is bursting. */ bool bursting ; /** * This variable is set to true to indicate that the server * will send EA. Some modules may want * the "endless" burst effect. * Default value is true. * Only modify this variable if you know what youre doing. */ bool sendEA ; /** * This variable is set to true to indicate that the server * will send EB. Some modules may want * the "endless" burst effect. * Default value is true. * Only modify this variable if you know what youre doing. */ bool sendEB ; /** * This variable is used during a requested shutdown to * allow one last iteration of the main processing loop. * This will give xClient's a chance to request flushing * of output data, and timers to expire. */ bool lastLoop ; /** * This variable will be true when the default behavior * of Write() is to write to the burstHoldBuffer. */ bool useHoldBuffer ; /** * This variable remains true while the server should continue * running. It may be set false by user input, or caught * signals. */ bool keepRunning ; /** * This is the port number to which we connect on our uplink. */ unsigned short int Port ; /** * This is a pointer into the network table to our uplink * server. It is kept here for convenience. */ iServer* Uplink ; /** * A pointer to the iServer* representation of this server. */ iServer* me ; /** * This buffer will hold data to be written during burst time. */ Buffer burstHoldBuffer ; /** * The name of the file which contains the command handler * mapping from network message to handler. */ std::string commandMapFileName ; /** * The path prefix to the gnuworld libraries, of the form * "/path/to/lib/dir" */ std::string libPrefix ; /** * Burst() is called when the network connection is * established. Its purpose is to call each xClient's * Connect() method so that each client may burst itself * and its channels. * NOTE: The scope of this method will be altered in * the future to reduce the requirements of xClient * when bursting its information. */ void Burst() ; /** * Type used to store runtime client modules. */ typedef std::vector< moduleLoader< xClient* >* > clientModuleListType; /** * Structure used to store runtime client modules. */ clientModuleListType clientModuleList; /** * The type of the modules used to load ServerCommandHandlers * from dynamically loadable libraries. * This is stored here in order to properly close them when * needed, including reloading command handlers. */ typedef moduleLoader< ServerCommandHandler*, xServer* > commandModuleType ; /** * A vector of modules representing ServerCommandHandlers. */ typedef std::vector< commandModuleType* > commandModuleListType ; /** * The structure of moduleLoader's, each representing a * ServerCommandHandler. */ commandModuleListType commandModuleList ; /** * The type used to store ServerCommandHandlers, each * associated with a particular server message (key). */ typedef std::map< std::string, ServerCommandHandler*, noCaseCompare > commandMapType ; /** * The structure used to store ServerCommandHandlers, each * associated with a particular server message (key). */ commandMapType commandMap ; /** * Attempt to locate a commandModuleType by its key. This is * used to reload a module, and to ensure that a module is * not accidentally loaded more than once. */ commandModuleType* lookupCommandModule( const std::string& ) const ; /** * The type used to store timed events. */ typedef std::priority_queue< std::pair< time_t, timerInfo* >, std::vector< std::pair< time_t, timerInfo* > >, timerGreater > timerQueueType ; /** * The structure used to store timed events. */ timerQueueType timerQueue ; /** * The type used to store timer ID's currently in use. */ typedef std::map< timerID, bool > uniqueTimerMapType ; /** * The structure used to store timer ID's current in use. */ uniqueTimerMapType uniqueTimerMap ; /** * The last unique timerID to be used. */ timerID lastTimerID ; /** * The output file to which to write raw data read from * the network. */ std::ofstream socketFile ; /** * The name of the file for which elog to write all * debugging information. */ std::string elogFileName ; /** * The name of the server config file. */ std::string configFileName ; /** * The name of the simulation file from which to read all * simulation data, empty if in real mode. */ std::string simFileName ; /** * The reason used to shutdown the server, displayed in * the SQ message. */ std::string shutDownReason ; /** * The char array to be used to read in network data. * This is allocated only once in the server for * performance reasons. * It is of fixed size since this buffer isn't used for * actual reading from the network connection, only for * handling a single network message a time (max 512 bytes). */ char inputCharBuffer[ 1024 ] ; /** * True if logging of raw input data to file is enabled. */ bool logSocket ; /** * True if all elog data should be output to clog. */ bool verbose ; /** * True if autoreconnect is enabled, false otherwise. */ bool autoConnect ; /** * This method initializes the entire server. */ void initializeSystem() ; /** * This method initializes all server variables. */ void initializeVariables() ; /** * This method loads all command handlers. */ bool loadCommandHandlers() ; /** * Load an individual command handler from a file (fileName), * and associate that handler with the network message * (commandKey). */ bool loadCommandHandler( const std::string& fileName, const std::string& symbolName, const std::string& commandKey ) ; /// Some debugging information, just a curiosity /// burstLines is the total number of lines that have been /// processed since the beginning of the last burst. size_t burstLines ; /// burstBytes is the total number of bytes that have been /// processed since the beginning of the last burst. size_t burstBytes ; /** * The type used to store the nicknames of control clients. */ typedef std::set< std::string, noCaseCompare > controlNickSetType ; /** * The structure used to store the nicknames of control clients. */ controlNickSetType controlNickSet ; /** * The type used to store the AC account usernames allowed to * issue control commands. * AC account usernames are case sensitive, so cannot use * noCaseCompare here. */ typedef std::set< std::string > allowControlSetType ; /** * The structure used to store the AC account usernames allowed to * issue control commands. */ allowControlSetType allowControlSet ; } ; } // namespace gnuworld #endif // __SERVER_H